xref: /aoo42x/main/sfx2/source/doc/objcont.cxx (revision 512da7eb)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sfx2.hxx"
26 
27 #include <com/sun/star/uno/Reference.hxx>
28 
29 #include <com/sun/star/document/XDocumentProperties.hpp>
30 #include <com/sun/star/document/UpdateDocMode.hpp>
31 #include <com/sun/star/frame/XLayoutManager.hpp>
32 #include <com/sun/star/embed/ElementModes.hpp>
33 #include <com/sun/star/document/XStandaloneDocumentInfo.hpp>
34 #include <com/sun/star/beans/XFastPropertySet.hpp>
35 #include <tools/cachestr.hxx>
36 #include <vcl/msgbox.hxx>
37 #include <svl/style.hxx>
38 #include <vcl/wrkwin.hxx>
39 
40 #include <svl/stritem.hxx>
41 #include <svl/intitem.hxx>
42 #include <svl/rectitem.hxx>
43 #include <svl/eitem.hxx>
44 #include <svl/urihelper.hxx>
45 #include <svl/ctloptions.hxx>
46 #include <comphelper/storagehelper.hxx>
47 #include <comphelper/processfactory.hxx>
48 #include <unotools/securityoptions.hxx>
49 #include <svtools/sfxecode.hxx>
50 #include <svtools/ehdl.hxx>
51 #include <tools/datetime.hxx>
52 #include <math.h>
53 
54 #include <unotools/saveopt.hxx>
55 #include <unotools/useroptions.hxx>
56 #include <unotools/localfilehelper.hxx>
57 #include <vcl/virdev.hxx>
58 #include <vcl/oldprintadaptor.hxx>
59 
60 #include <sfx2/app.hxx>
61 #include "sfx2/sfxresid.hxx"
62 #include "appdata.hxx"
63 #include <sfx2/dinfdlg.hxx>
64 #include "fltfnc.hxx"
65 #include <sfx2/docfac.hxx>
66 #include <sfx2/viewsh.hxx>
67 #include <sfx2/objsh.hxx>
68 #include "objshimp.hxx"
69 #include <sfx2/evntconf.hxx>
70 #include "sfx2/sfxhelp.hxx"
71 #include <sfx2/dispatch.hxx>
72 #include <sfx2/printer.hxx>
73 #include "sfx2/basmgr.hxx"
74 #include <sfx2/viewfrm.hxx>
75 #include <sfx2/doctempl.hxx>
76 #include "doc.hrc"
77 #include <sfx2/sfxbasemodel.hxx>
78 #include <sfx2/docfile.hxx>
79 #include <sfx2/request.hxx>
80 #include "openflag.hxx"
81 #include "querytemplate.hxx"
82 
83 using namespace ::com::sun::star;
84 using namespace ::com::sun::star::uno;
85 
86 //====================================================================
87 
88 //====================================================================
89 
90 static
91 bool operator> (const util::DateTime& i_rLeft, const util::DateTime& i_rRight)
92 {
93     if ( i_rLeft.Year != i_rRight.Year )
94         return i_rLeft.Year > i_rRight.Year;
95 
96     if ( i_rLeft.Month != i_rRight.Month )
97         return i_rLeft.Month > i_rRight.Month;
98 
99     if ( i_rLeft.Day != i_rRight.Day )
100         return i_rLeft.Day > i_rRight.Day;
101 
102     if ( i_rLeft.Hours != i_rRight.Hours )
103         return i_rLeft.Hours > i_rRight.Hours;
104 
105     if ( i_rLeft.Minutes != i_rRight.Minutes )
106         return i_rLeft.Minutes > i_rRight.Minutes;
107 
108     if ( i_rLeft.Seconds != i_rRight.Seconds )
109         return i_rLeft.Seconds > i_rRight.Seconds;
110 
111     if ( i_rLeft.HundredthSeconds != i_rRight.HundredthSeconds )
112         return i_rLeft.HundredthSeconds > i_rRight.HundredthSeconds;
113 
114     return sal_False;
115 }
116 
117 
118 ::boost::shared_ptr<GDIMetaFile>
119 SfxObjectShell::GetPreviewMetaFile( sal_Bool bFullContent ) const
120 {
121 	return CreatePreviewMetaFile_Impl( bFullContent, sal_False );
122 }
123 
124 
125 ::boost::shared_ptr<GDIMetaFile>
126 SfxObjectShell::CreatePreviewMetaFile_Impl( sal_Bool bFullContent, sal_Bool bHighContrast ) const
127 {
128 	// Nur wenn gerade nicht gedruckt wird, darf DoDraw aufgerufen
129 	// werden, sonst wird u.U. der Printer abgeschossen !
130 	SfxViewFrame *pFrame = SfxViewFrame::GetFirst( this );
131 	if ( pFrame && pFrame->GetViewShell() &&
132 		 pFrame->GetViewShell()->GetPrinter() &&
133 		 pFrame->GetViewShell()->GetPrinter()->IsPrinting() )
134 		 return ::boost::shared_ptr<GDIMetaFile>();
135 
136     ::boost::shared_ptr<GDIMetaFile> pFile(new GDIMetaFile);
137 
138 	VirtualDevice aDevice;
139 	aDevice.EnableOutput( sal_False );
140 
141 	// adjust the output device if HC-metafile is requested
142 	if ( bHighContrast )
143 		aDevice.SetDrawMode( aDevice.GetDrawMode() | DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT );
144 
145     MapMode aMode( ((SfxObjectShell*)this)->GetMapUnit() );
146     aDevice.SetMapMode( aMode );
147     pFile->SetPrefMapMode( aMode );
148 
149     Size aTmpSize;
150     sal_Int8 nAspect;
151     if ( bFullContent )
152     {
153         nAspect = ASPECT_CONTENT;
154         aTmpSize = GetVisArea( nAspect ).GetSize();
155     }
156     else
157     {
158         nAspect = ASPECT_THUMBNAIL;
159         aTmpSize = ((SfxObjectShell*)this)->GetFirstPageSize();
160     }
161 
162     pFile->SetPrefSize( aTmpSize );
163     DBG_ASSERT( aTmpSize.Height()*aTmpSize.Width(),
164                 "size of first page is 0, overload GetFirstPageSize or set vis-area!" );
165 
166     pFile->Record( &aDevice );
167 
168     LanguageType eLang;
169     // #120038# use local incarnation, so deletion cannot be forgotten
170     const SvtCTLOptions aCTLOptions;
171 
172     if ( SvtCTLOptions::NUMERALS_HINDI == aCTLOptions.GetCTLTextNumerals() )
173         eLang = LANGUAGE_ARABIC_SAUDI_ARABIA;
174     else if ( SvtCTLOptions::NUMERALS_ARABIC == aCTLOptions.GetCTLTextNumerals() )
175         eLang = LANGUAGE_ENGLISH;
176     else
177         eLang = (LanguageType) Application::GetSettings().GetLanguage();
178 
179     aDevice.SetDigitLanguage( eLang );
180 
181     ((SfxObjectShell*)this)->DoDraw( &aDevice, Point(0,0), aTmpSize, JobSetup(), nAspect );
182     pFile->Stop();
183 
184 	return pFile;
185 }
186 
187 //====================================================================
188 
189 void SfxObjectShell::UpdateDocInfoForSave()
190 {
191     uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
192 
193 	// clear user data if recommend (see 'Tools - Options - Open/StarOffice - Security')
194 	if ( SvtSecurityOptions().IsOptionSet(
195             SvtSecurityOptions::E_DOCWARN_REMOVEPERSONALINFO ) )
196     {
197 		xDocProps->resetUserData( ::rtl::OUString() );
198     }
199 	else if ( IsModified() )
200 	{
201 		String aUserName = SvtUserOptions().GetFullName();
202 		if ( !IsUseUserData() )
203         {
204 			// remove all data pointing to the current user
205             if (xDocProps->getAuthor().equals(aUserName)) {
206                 xDocProps->setAuthor( ::rtl::OUString() );
207             }
208             xDocProps->setModifiedBy( ::rtl::OUString() );
209             if (xDocProps->getPrintedBy().equals(aUserName)) {
210                 xDocProps->setPrintedBy( ::rtl::OUString() );
211             }
212         }
213 		else
214 		{
215 			// update ModificationAuthor, revision and editing time
216             ::DateTime now;
217             xDocProps->setModificationDate( util::DateTime(
218                 now.Get100Sec(), now.GetSec(), now.GetMin(),
219                 now.GetHour(), now.GetDay(), now.GetMonth(),
220                 now.GetYear() ) );
221             xDocProps->setModifiedBy( aUserName );
222 			if ( !HasName() || pImp->bIsSaving )
223 				// QUESTION: not in case of "real" SaveAs as this is meant to create a new document
224 				UpdateTime_Impl( xDocProps );
225 		}
226 	}
227 }
228 
229 //--------------------------------------------------------------------
230 
231 static void
232 lcl_add(util::Duration & rDur, Time const& rTime)
233 {
234     // here we don't care about overflow: rDur is converted back to seconds
235     // anyway, and Time cannot store more than ~4000 hours
236     rDur.Hours   += rTime.GetHour();
237     rDur.Minutes += rTime.GetMin();
238     rDur.Seconds += rTime.GetSec();
239 }
240 
241 // Bearbeitungszeit aktualisieren
242 void SfxObjectShell::UpdateTime_Impl(
243     const uno::Reference<document::XDocumentProperties> & i_xDocProps)
244 {
245 	// Get old time from documentinfo
246     const sal_Int32 secs = i_xDocProps->getEditingDuration();
247     util::Duration editDuration(sal_False, 0, 0, 0,
248             secs/3600, (secs%3600)/60, secs%60, 0);
249 
250 	// Initialize some local member! Its neccessary for wollow operations!
251 	DateTime	aNow					;	// Date and time at current moment
252 	Time		n24Time		(24,0,0,0)	;	// Time-value for 24 hours - see follow calculation
253 	sal_uIntPtr		nDays		= 0			;	// Count of days between now and last editing
254 	Time		nAddTime	(0)			;	// Value to add on aOldTime
255 
256 	// Safe impossible cases!
257 	// User has changed time to the past between last editing and now ... its not possible!!!
258 	DBG_ASSERT( !(aNow.GetDate()<pImp->nTime.GetDate()), "Timestamp of last change is in the past ?!..." );
259 
260 	// Do the follow only, if user has NOT changed time to the past.
261 	// Else add a time of 0 to aOldTime ... !!!
262 	if (aNow.GetDate()>=pImp->nTime.GetDate())
263 	{
264 		// Get count of days last editing.
265 		nDays = aNow.GetSecFromDateTime(pImp->nTime.GetDate())/86400 ;
266 
267 		if (nDays==0)
268 		{
269 			// If no day between now and last editing - calculate time directly.
270             nAddTime    =   (const Time&)aNow - (const Time&)pImp->nTime ;
271 		}
272 		else
273 		// If time of working without save greater then 1 month (!) ....
274 		// we add 0 to aOldTime!
275 		if (nDays<=31)
276 		{
277 			// If 1 or up to 31 days between now and last editing - calculate time indirectly.
278 			// nAddTime = (24h - nTime) + (nDays * 24h) + aNow
279 			--nDays;
280  			nAddTime	 =	nDays*n24Time.GetTime()	;
281 			nAddTime	+=	n24Time-(const Time&)pImp->nTime		;
282 			nAddTime	+=	aNow					;
283 		}
284 
285         lcl_add(editDuration, nAddTime);
286 	}
287 
288 	pImp->nTime = aNow;
289     try {
290         const sal_Int32 newSecs( (editDuration.Hours*3600)
291             + (editDuration.Minutes*60) + editDuration.Seconds);
292         i_xDocProps->setEditingDuration(newSecs);
293         i_xDocProps->setEditingCycles(i_xDocProps->getEditingCycles() + 1);
294     }
295     catch (lang::IllegalArgumentException &)
296     {
297         // ignore overflow
298     }
299 }
300 
301 //--------------------------------------------------------------------
302 
303 SfxDocumentInfoDialog* SfxObjectShell::CreateDocumentInfoDialog
304 (
305 	Window*             pParent,
306 	const SfxItemSet&   rSet
307 )
308 {
309 	return new SfxDocumentInfoDialog(pParent, rSet);
310 }
311 
312 //--------------------------------------------------------------------
313 
314 SfxStyleSheetBasePool* SfxObjectShell::GetStyleSheetPool()
315 {
316 	return 0;
317 }
318 
319 void SfxObjectShell::SetOrganizerSearchMask(
320 	SfxStyleSheetBasePool* pStylePool) const
321 {
322 	pStylePool->SetSearchMask(
323         SFX_STYLE_FAMILY_ALL,
324 		SFXSTYLEBIT_USERDEF | SFXSTYLEBIT_USED);
325 }
326 
327 //--------------------------------------------------------------------
328 
329 sal_uInt16 SfxObjectShell::GetContentCount(
330     sal_uInt16 nIdx1,
331     sal_uInt16 /*nIdx2*/)
332 {
333 	switch(nIdx1)
334 	{
335 		case INDEX_IGNORE:
336 			return DEF_CONTENT_COUNT;
337 		case CONTENT_STYLE:
338 		{
339 			SfxStyleSheetBasePool *pStylePool = GetStyleSheetPool();
340 			if(!pStylePool)
341 				return 0;
342 			SetOrganizerSearchMask(pStylePool);
343 			return pStylePool->Count();
344 		}
345 		case CONTENT_MACRO:
346 			break;
347 /*
348 		case CONTENT_CONFIG:
349 			return ( GetConfigManager() ) ?
350 						GetConfigManager()->GetItemCount() : 0;
351 			break;
352  */
353 	}
354 	return 0;
355 }
356 
357 
358 //--------------------------------------------------------------------
359 //TODO/CLEANUP: remove this method (it's virtual)
360 void  SfxObjectShell::TriggerHelpPI(sal_uInt16 nIdx1, sal_uInt16 nIdx2, sal_uInt16)
361 {
362 	if(nIdx1==CONTENT_STYLE && nIdx2 != INDEX_IGNORE) //StyleSheets
363 	{
364 		SfxStyleSheetBasePool *pStylePool = GetStyleSheetPool();
365 		SetOrganizerSearchMask(pStylePool);
366 	}
367 }
368 
369 sal_Bool   SfxObjectShell::CanHaveChilds(sal_uInt16 nIdx1,
370 									   sal_uInt16 nIdx2)
371 {
372 	switch(nIdx1) {
373 	case INDEX_IGNORE:
374 		return sal_True;
375 	case CONTENT_STYLE:
376 		return INDEX_IGNORE == nIdx2 || !GetStyleSheetPool()? sal_False: sal_True;
377 	case CONTENT_MACRO:
378 //!!    return INDEX_IGNORE == nIdx2? sal_False: sal_True;
379 		return sal_False;
380 /*
381 	case CONTENT_CONFIG:
382 		return INDEX_IGNORE == nIdx2 ? sal_False : sal_True;
383  */
384 	}
385 	return sal_False;
386 }
387 
388 //--------------------------------------------------------------------
389 
390 void SfxObjectShell::GetContent(String &rText,
391 								Bitmap &rClosedBitmap,
392 								Bitmap &rOpenedBitmap,
393 								sal_Bool &bCanDel,
394 								sal_uInt16 i,
395 								sal_uInt16 nIdx1,
396 								sal_uInt16 nIdx2 )
397 {
398 	DBG_ERRORFILE( "Non high contrast method called. Please update calling code!" );
399 	SfxObjectShell::GetContent( rText, rClosedBitmap, rOpenedBitmap, BMP_COLOR_NORMAL, bCanDel, i, nIdx1, nIdx2 );
400 }
401 
402 //--------------------------------------------------------------------
403 
404 void   SfxObjectShell::GetContent(String &rText,
405 								  Bitmap &rClosedBitmap,
406 								  Bitmap &rOpenedBitmap,
407 								  BmpColorMode eColorMode,
408 								  sal_Bool &bCanDel,
409 								  sal_uInt16 i,
410 								  sal_uInt16 nIdx1,
411 								  sal_uInt16 /*nIdx2*/ )
412 {
413 	bCanDel=sal_True;
414 
415 	switch(nIdx1)
416 	{
417 		case INDEX_IGNORE:
418 		{
419 			sal_uInt16 nTextResId = 0;
420 			sal_uInt16 nClosedBitmapResId = 0; // evtl. sp"ater mal unterschiedliche
421 			sal_uInt16 nOpenedBitmapResId = 0; // "     "       "   "
422 			switch(i)
423 			{
424 				case CONTENT_STYLE:
425 					nTextResId = STR_STYLES;
426 					if ( eColorMode == BMP_COLOR_NORMAL )
427 					{
428 						nClosedBitmapResId= BMP_STYLES_CLOSED;
429 						nOpenedBitmapResId= BMP_STYLES_OPENED;
430 					}
431 					else
432 					{
433 						nClosedBitmapResId= BMP_STYLES_CLOSED_HC;
434 						nOpenedBitmapResId= BMP_STYLES_OPENED_HC;
435 					}
436 					break;
437 				case CONTENT_MACRO:
438 					nTextResId = STR_MACROS;
439 					if ( eColorMode == BMP_COLOR_NORMAL )
440 					{
441 						nClosedBitmapResId= BMP_STYLES_CLOSED;
442 						nOpenedBitmapResId= BMP_STYLES_OPENED;
443 					}
444 					else
445 					{
446 						nClosedBitmapResId= BMP_STYLES_CLOSED_HC;
447 						nOpenedBitmapResId= BMP_STYLES_OPENED_HC;
448 					}
449 					break;
450 /*
451 				case CONTENT_CONFIG:
452 					nTextResId = STR_CONFIG;
453 					nClosedBitmapResId= BMP_STYLES_CLOSED;
454 					nOpenedBitmapResId= BMP_STYLES_OPENED;
455 					break;
456  */
457 			}
458 
459 			if ( nTextResId )
460 			{
461 				rText  = String(SfxResId(nTextResId));
462 				rClosedBitmap = Bitmap(SfxResId(nClosedBitmapResId));
463 				rOpenedBitmap = Bitmap(SfxResId(nOpenedBitmapResId));
464 			}
465 			break;
466 		}
467 
468 		case CONTENT_STYLE:
469 		{
470 			SfxStyleSheetBasePool *pStylePool = GetStyleSheetPool();
471 			SetOrganizerSearchMask(pStylePool);
472 			SfxStyleSheetBase *pStyle = (*pStylePool)[i];
473 			rText = pStyle->GetName();
474 			bCanDel=((pStyle->GetMask() & SFXSTYLEBIT_USERDEF)
475 					 == SFXSTYLEBIT_USERDEF);
476 			rClosedBitmap = rOpenedBitmap =
477 				GetStyleFamilyBitmap(pStyle->GetFamily(), eColorMode );
478 		}
479 			break;
480 		case CONTENT_MACRO:
481 			break;
482 /*
483 		case CONTENT_CONFIG:
484 			if ( GetConfigManager() )
485 			{
486 				rText = GetConfigManager()->GetItem(i);
487 				bCanDel = GetConfigManager()->CanDelete(i);
488 			}
489 			else
490 				rText = String();
491 			rClosedBitmap = Bitmap(SfxResId(BMP_STYLES_CLOSED));
492 			rOpenedBitmap = Bitmap(SfxResId(BMP_STYLES_OPENED));
493 			break;
494 */
495 	}
496 }
497 
498 //--------------------------------------------------------------------
499 Bitmap SfxObjectShell::GetStyleFamilyBitmap( SfxStyleFamily eFamily )
500 {
501 	DBG_ERRORFILE( "Non high contrast method called. Please update calling code!" );
502 	return SfxObjectShell::GetStyleFamilyBitmap( eFamily, BMP_COLOR_NORMAL );
503 }
504 
505 //--------------------------------------------------------------------
506 
507 Bitmap SfxObjectShell::GetStyleFamilyBitmap(SfxStyleFamily eFamily, BmpColorMode eColorMode )
508 {
509 	sal_uInt16 nResId = 0;
510 	switch(eFamily)
511 	{
512 		case SFX_STYLE_FAMILY_CHAR:
513 			nResId = ( eColorMode == BMP_COLOR_NORMAL ) ? BMP_STYLES_FAMILY1 : BMP_STYLES_FAMILY1_HC;
514 			break;
515 		case SFX_STYLE_FAMILY_PARA:
516 			nResId = ( eColorMode == BMP_COLOR_NORMAL ) ? BMP_STYLES_FAMILY2 : BMP_STYLES_FAMILY2_HC;
517 			break;
518 		case SFX_STYLE_FAMILY_FRAME:
519 			nResId = ( eColorMode == BMP_COLOR_NORMAL ) ? BMP_STYLES_FAMILY3 : BMP_STYLES_FAMILY3_HC;
520 			break;
521 		case SFX_STYLE_FAMILY_PAGE :
522 			nResId = ( eColorMode == BMP_COLOR_NORMAL ) ? BMP_STYLES_FAMILY4 : BMP_STYLES_FAMILY4_HC;
523 			break;
524 		case SFX_STYLE_FAMILY_PSEUDO:
525 		case SFX_STYLE_FAMILY_ALL:
526 			break;
527 	}
528 
529 	if ( nResId )
530 		return Bitmap(SfxResId(nResId));
531 	else
532 		return Bitmap();
533 }
534 
535 
536 //--------------------------------------------------------------------
537 
538 sal_Bool SfxObjectShell::Insert(SfxObjectShell &rSource,
539 							  sal_uInt16 nSourceIdx1,
540 							  sal_uInt16 nSourceIdx2,
541 							  sal_uInt16 /*nSourceIdx3*/,
542 							  sal_uInt16 &nIdx1,
543 							  sal_uInt16 &nIdx2,
544 							  sal_uInt16 &/*nIdx3*/,
545 							  sal_uInt16 &/*nDeleted*/)
546 {
547 	sal_Bool bRet = sal_False;
548 
549 	if (INDEX_IGNORE == nIdx1 && CONTENT_STYLE == nSourceIdx1)
550 		nIdx1 = CONTENT_STYLE;
551 
552 	if (CONTENT_STYLE == nSourceIdx1 && CONTENT_STYLE == nIdx1)
553 	{
554 		SfxStyleSheetBasePool* pHisPool  = rSource.GetStyleSheetPool();
555 		SfxStyleSheetBasePool* pMyPool   = GetStyleSheetPool();
556 		SetOrganizerSearchMask(pHisPool);
557 		SetOrganizerSearchMask(pMyPool);
558         SfxStyleSheetBase* pHisSheet = NULL;
559 
560         if ( pHisPool && pHisPool->Count() > nSourceIdx2 )
561             pHisSheet = (*pHisPool)[nSourceIdx2];
562 
563 		// Einfuegen ist nur dann noetig, wenn ein StyleSheet
564 		// zwischen unterschiedlichen(!) Pools bewegt wird
565 
566         if ( pHisSheet && pMyPool != pHisPool )
567 		{
568 			if (INDEX_IGNORE == nIdx2)
569 			{
570 				nIdx2 = pMyPool->Count();
571 			}
572 
573 			// wenn so eine Vorlage schon existiert: loeschen!
574 			String aOldName(pHisSheet->GetName());
575 			SfxStyleFamily eOldFamily = pHisSheet->GetFamily();
576 
577 			SfxStyleSheetBase* pExist = pMyPool->Find(aOldName, eOldFamily);
578 			// sal_uInt16 nOldHelpId = pExist->GetHelpId(??? VB ueberlegt sich was);
579 			sal_Bool bUsedOrUserDefined;
580 			if( pExist )
581 			{
582 				bUsedOrUserDefined =
583 					pExist->IsUsed() || pExist->IsUserDefined();
584 				if( ErrorHandler::HandleError(
585 					*new MessageInfo( ERRCODE_SFXMSG_STYLEREPLACE, aOldName ) )
586 					!= ERRCODE_BUTTON_OK )
587 					return sal_False;
588 				else
589 				{
590 					pMyPool->Replace( *pHisSheet, *pExist );
591 					SetModified( sal_True );
592 					nIdx2 = nIdx1 = INDEX_IGNORE;
593 					return sal_True;
594 				}
595 			}
596 
597 			SfxStyleSheetBase& rNewSheet = pMyPool->Make(
598 				aOldName, eOldFamily,
599 				pHisSheet->GetMask(), nIdx2);
600 
601 			// ItemSet der neuen Vorlage fuellen
602 			rNewSheet.GetItemSet().Set(pHisSheet->GetItemSet());
603 
604 			// wer bekommt den Neuen als Parent? wer benutzt den Neuen als Follow?
605 			SfxStyleSheetBase* pTestSheet = pMyPool->First();
606 			while (pTestSheet)
607 			{
608 				if (pTestSheet->GetFamily() == eOldFamily &&
609 					pTestSheet->HasParentSupport() &&
610 					pTestSheet->GetParent() == aOldName)
611 				{
612 					pTestSheet->SetParent(aOldName);
613 					// Verknuepfung neu aufbauen
614 				}
615 
616 				if (pTestSheet->GetFamily() == eOldFamily &&
617 					pTestSheet->HasFollowSupport() &&
618 					pTestSheet->GetFollow() == aOldName)
619 				{
620 					pTestSheet->SetFollow(aOldName);
621 					// Verknuepfung neu aufbauen
622 				}
623 
624 				pTestSheet = pMyPool->Next();
625 			}
626 			bUsedOrUserDefined =
627 				rNewSheet.IsUsed() || rNewSheet.IsUserDefined();
628 
629 
630 			// hat der Neue einen Parent? wenn ja, mit gleichem Namen bei uns suchen
631 			if (pHisSheet->HasParentSupport())
632 			{
633 				const String& rParentName = pHisSheet->GetParent();
634 				if (0 != rParentName.Len())
635 				{
636 					SfxStyleSheetBase* pParentOfNew =
637 						pMyPool->Find(rParentName, eOldFamily);
638 					if (pParentOfNew)
639 						rNewSheet.SetParent(rParentName);
640 				}
641 			}
642 
643 			// hat der Neue einen Follow? wenn ja, mit gleichem
644 			// Namen bei uns suchen
645 			if (pHisSheet->HasFollowSupport())
646 			{
647 				const String& rFollowName = pHisSheet->GetFollow();
648 				if (0 != rFollowName.Len())
649 				{
650 					SfxStyleSheetBase* pFollowOfNew =
651 						pMyPool->Find(rFollowName, eOldFamily);
652 					if (pFollowOfNew)
653 						rNewSheet.SetFollow(rFollowName);
654 				}
655 			}
656 
657 			SetModified( sal_True );
658 			if( !bUsedOrUserDefined ) nIdx2 = nIdx1 = INDEX_IGNORE;
659 
660 			bRet = sal_True;
661 		}
662 		else
663 			bRet = sal_False;
664 	}
665 /*
666 	else if (nSourceIdx1 == CONTENT_CONFIG)
667 	{
668 		nIdx1 = CONTENT_CONFIG;
669 
670 		SfxConfigManager *pCfgMgr = SFX_CFGMANAGER();
671 		if ( !GetConfigManager() )
672 		{
673 			SetConfigManager(new SfxConfigManager(0, pCfgMgr));
674 			SetTemplateConfig(sal_False);
675 			if (this == Current())
676 				GetConfigManager()->Activate(pCfgMgr);
677 		}
678 
679 		if (GetConfigManager()->CopyItem(
680 			nSourceIdx2, nIdx2, rSource.GetConfigManager()))
681 		{
682 			SetModified(sal_True);
683 			bRet = sal_True;
684             SFX_APP()->GetDispatcher_Impl()->Update_Impl(sal_True);
685 		}
686 	}
687 */
688 	return bRet;
689 }
690 
691 //--------------------------------------------------------------------
692 
693 sal_Bool SfxObjectShell::Remove
694 (
695 	sal_uInt16 nIdx1,
696 	sal_uInt16 nIdx2,
697 	sal_uInt16 /*nIdx3*/
698 )
699 {
700 	sal_Bool bRet = sal_False;
701 
702 	if (CONTENT_STYLE == nIdx1)
703 	{
704 		SfxStyleSheetBasePool* pMyPool  = GetStyleSheetPool();
705 
706 		SetOrganizerSearchMask(pMyPool);
707 
708 		SfxStyleSheetBase* pMySheet =  (*pMyPool)[nIdx2];
709 		String aName(pMySheet->GetName());
710 		String aEmpty;
711 		SfxStyleFamily  eFamily = pMySheet->GetFamily();
712 		pMyPool->Remove(pMySheet);
713 		bRet = sal_True;
714 
715 		SfxStyleSheetBase* pTestSheet = pMyPool->First();
716 		while (pTestSheet)
717 		{
718 			if (pTestSheet->GetFamily() == eFamily &&
719 				pTestSheet->HasParentSupport() &&
720 				pTestSheet->GetParent() == aName)
721 			{
722 				pTestSheet->SetParent(aEmpty); // Verknuepfung aufloesen
723 			}
724 
725 			if (pTestSheet->GetFamily() == eFamily &&
726 				pTestSheet->HasFollowSupport() &&
727 				pTestSheet->GetFollow() == aName)
728 			{
729 				pTestSheet->SetFollow(aEmpty); // Verknuepfung aufloesen
730 			}
731 
732 			pTestSheet = pMyPool->Next();
733 		}
734 
735 		SetModified( sal_True );
736 	}
737 
738 	return bRet;
739 }
740 
741 //--------------------------------------------------------------------
742 
743 sal_Bool SfxObjectShell::Print
744 (
745 	Printer&        rPrt,
746 	sal_uInt16          nIdx1,
747 	sal_uInt16          /*nIdx2*/,
748 	sal_uInt16          /*nIdx3*/,
749 	const String*   pObjectName
750 )
751 
752 /*  [Beschreibung]
753 */
754 
755 {
756 	switch(nIdx1)
757 	{
758 	  case CONTENT_STYLE:
759 		{
760 			SfxStyleSheetBasePool *pStylePool = GetStyleSheetPool();
761 			SetOrganizerSearchMask(pStylePool);
762 
763             // memory leak #i120077#
764             SfxStyleSheetIterator aIter(pStylePool, pStylePool->GetSearchFamily(), pStylePool->GetSearchMask());
765 			sal_uInt16 nStyles = aIter.Count();
766 			SfxStyleSheetBase *pStyle = aIter.First();
767 
768             if ( !pStyle )
769             {
770                 return sal_True;
771             }
772 
773             // pepare adaptor for old style StartPage/EndPage printing
774             boost::shared_ptr< Printer > pPrinter( new Printer( rPrt.GetJobSetup() ) );
775             vcl::OldStylePrintAdaptor* pAdaptor = new vcl::OldStylePrintAdaptor( pPrinter );
776             boost::shared_ptr< vcl::PrinterController > pController( pAdaptor );
777 
778             pAdaptor->StartPage();
779 
780             pPrinter->SetMapMode(MapMode(MAP_10TH_MM));
781 			Font aFont( DEFINE_CONST_UNICODE( "Arial" ), Size(0, 64));   // 18pt
782 			aFont.SetWeight(WEIGHT_BOLD);
783 			pPrinter->SetFont(aFont);
784 			const Size aPageSize(pPrinter->GetOutputSize());
785 			const sal_uInt16 nXIndent = 200;
786 			sal_uInt16 nYIndent = 200;
787 			Point aOutPos(nXIndent, nYIndent);
788 			String aHeader(SfxResId(STR_PRINT_STYLES_HEADER));
789 			if ( pObjectName )
790 				aHeader += *pObjectName;
791 			else
792 				aHeader += GetTitle();
793             long nTextHeight( pPrinter->GetTextHeight() );
794 			pPrinter->DrawText(aOutPos, aHeader);
795 			aOutPos.Y() += nTextHeight;
796 			aOutPos.Y() += nTextHeight/2;
797 			aFont.SetSize(Size(0, 35)); // 10pt
798 			nStyles = 1;
799 			while(pStyle)
800 			{
801 				// print template name
802 				String aStr(pStyle->GetName());
803 				aFont.SetWeight(WEIGHT_BOLD);
804 				pPrinter->SetFont(aFont);
805 				nTextHeight = pPrinter->GetTextHeight();
806 				// check for new page
807 				if ( aOutPos.Y() + nTextHeight*2 >
808                     aPageSize.Height() - (long) nYIndent )
809 				{
810 					pAdaptor->EndPage();
811 					pAdaptor->StartPage();
812 					aOutPos.Y() = nYIndent;
813 				}
814 				pPrinter->DrawText(aOutPos, aStr);
815 				aOutPos.Y() += nTextHeight;
816 
817 				// print template description
818 				aFont.SetWeight(WEIGHT_NORMAL);
819 				pPrinter->SetFont(aFont);
820 				aStr = pStyle->GetDescription();
821 				const char cDelim = ' ';
822 				sal_uInt16 nStart = 0, nIdx = 0;
823 
824 				nTextHeight = pPrinter->GetTextHeight();
825 				// break text into lines
826 				while(nIdx < aStr.Len())
827 				{
828 					sal_uInt16	nOld = nIdx;
829                     long nTextWidth;
830 					nIdx = aStr.Search(cDelim, nStart);
831 					nTextWidth = pPrinter->GetTextWidth(aStr, nStart, nIdx-nStart);
832 					while(nIdx != STRING_NOTFOUND &&
833 						  aOutPos.X() + nTextWidth <
834                           aPageSize.Width() - (long) nXIndent)
835 					{
836 						nOld = nIdx;
837 						nIdx = aStr.Search(cDelim, nIdx+1);
838 						nTextWidth = pPrinter->GetTextWidth(aStr, nStart, nIdx-nStart);
839 					}
840 					String aTmp(aStr, nStart, nIdx == STRING_NOTFOUND?
841 								STRING_LEN :
842 								nOld-nStart);
843 					if ( aTmp.Len() )
844 					{
845 						nStart = nOld+1;    // trailing space
846 					}
847 					else
848 					{
849 						sal_uInt16 nChar = 1;
850 						while(
851 							nStart + nChar < aStr.Len() &&
852 							aOutPos.X() + pPrinter->GetTextWidth(
853 								aStr, nStart, nChar) <
854 							aPageSize.Width() - nXIndent)
855 							++nChar;
856 						aTmp = String(aStr, nStart, nChar-1);
857 						nIdx = nStart + nChar;
858 						nStart = nIdx;
859 					}
860 					if ( aOutPos.Y() + nTextHeight*2 >
861 						aPageSize.Height() - nYIndent )
862 					{
863 						pAdaptor->EndPage();
864 						pAdaptor->StartPage();
865 						aOutPos.Y() = nYIndent;
866 					}
867 					pPrinter->DrawText(aOutPos, aTmp);
868 					aOutPos.Y() += pPrinter->GetTextHeight();
869 				}
870 				pStyle = aIter.Next();
871 			}
872 			pAdaptor->EndPage();
873 
874             Printer::PrintJob( pController, rPrt.GetJobSetup() );
875 
876 			break;
877 		}
878 	  default:
879 		  return sal_False;
880 	}
881 	return sal_True;
882 }
883 
884 //--------------------------------------------------------------------
885 
886 void SfxObjectShell::LoadStyles
887 (
888 	SfxObjectShell &rSource         /*  die Dokument-Vorlage, aus der
889 											die Styles geladen werden sollen */
890 )
891 
892 /*  [Beschreibung]
893 
894 	Diese Methode wird vom SFx gerufen, wenn aus einer Dokument-Vorlage
895 	Styles nachgeladen werden sollen. Bestehende Styles soll dabei
896 	"uberschrieben werden. Das Dokument mu"s daher neu formatiert werden.
897 	Daher werden die Applikationen in der Regel diese Methode "uberladen
898 	und in ihrer Implementierung die Implementierung der Basisklasse
899 	rufen.
900 */
901 
902 {
903 	struct Styles_Impl
904 	{
905 		SfxStyleSheetBase *pSource;
906 		SfxStyleSheetBase *pDest;
907 //      Styles_Impl () : pSource(0), pDest(0) {}
908 	};
909 
910 	SfxStyleSheetBasePool *pSourcePool = rSource.GetStyleSheetPool();
911 	DBG_ASSERT(pSourcePool, "Source-DocumentShell ohne StyleSheetPool");
912 	SfxStyleSheetBasePool *pMyPool = GetStyleSheetPool();
913 	DBG_ASSERT(pMyPool, "Dest-DocumentShell ohne StyleSheetPool");
914 	pSourcePool->SetSearchMask(SFX_STYLE_FAMILY_ALL, 0xffff);
915 	Styles_Impl *pFound = new Styles_Impl[pSourcePool->Count()];
916 	sal_uInt16 nFound = 0;
917 
918 	SfxStyleSheetBase *pSource = pSourcePool->First();
919 	while ( pSource )
920 	{
921 		SfxStyleSheetBase *pDest =
922 			pMyPool->Find( pSource->GetName(), pSource->GetFamily() );
923 		if ( !pDest )
924 		{
925 			pDest = &pMyPool->Make( pSource->GetName(),
926 					pSource->GetFamily(), pSource->GetMask());
927 			// Setzen des Parents, der Folgevorlage
928 		}
929 		pFound[nFound].pSource = pSource;
930 		pFound[nFound].pDest = pDest;
931 		++nFound;
932 		pSource = pSourcePool->Next();
933 	}
934 
935 	for ( sal_uInt16 i = 0; i < nFound; ++i )
936 	{
937 		pFound[i].pDest->GetItemSet().PutExtended(pFound[i].pSource->GetItemSet(), SFX_ITEM_DONTCARE, SFX_ITEM_DEFAULT);
938 //      pFound[i].pDest->SetHelpId(pFound[i].pSource->GetHelpId());
939 		if(pFound[i].pSource->HasParentSupport())
940 			pFound[i].pDest->SetParent(pFound[i].pSource->GetParent());
941 		if(pFound[i].pSource->HasFollowSupport())
942 			pFound[i].pDest->SetFollow(pFound[i].pSource->GetParent());
943 	}
944 	delete [] pFound;
945 }
946 
947 //--------------------------------------------------------------------
948 
949 void SfxObjectShell::UpdateFromTemplate_Impl(  )
950 
951 /*  [Beschreibung]
952 
953 	Diese interne Methode pr"uft, ob das Dokument aus einem Template
954 	erzeugt wurde, und ob dieses neuer ist als das Dokument. Ist dies
955 	der Fall, wird der Benutzer gefragt, ob die Vorlagen (StyleSheets)
956 	updated werden sollen. Wird dies positiv beantwortet, werden die
957 	StyleSheets updated.
958 */
959 
960 {
961 	// Storage-medium?
962 	SfxMedium *pFile = GetMedium();
963 	DBG_ASSERT( pFile, "cannot UpdateFromTemplate without medium" );
964 	if ( !pFile )
965 		return;
966 
967 	if ( !::utl::LocalFileHelper::IsLocalFile( pFile->GetName() ) )
968 		// update only for documents loaded from the local file system
969 		return;
970 
971     // only for own storage formats
972 	uno::Reference< embed::XStorage > xDocStor = pFile->GetStorage();
973     if ( !pFile->GetFilter() || !pFile->GetFilter()->IsOwnFormat() )
974 		return;
975 
976 	SFX_ITEMSET_ARG( pFile->GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
977 	sal_Int16 bCanUpdateFromTemplate = pUpdateDocItem ? pUpdateDocItem->GetValue() : document::UpdateDocMode::NO_UPDATE;
978 
979     // created from template?
980     uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
981     ::rtl::OUString aTemplName( xDocProps->getTemplateName() );
982     ::rtl::OUString aTemplURL( xDocProps->getTemplateURL() );
983     String aFoundName;
984 
985     if ( aTemplName.getLength() || (aTemplURL.getLength() && !IsReadOnly()) )
986 	{
987         // try to locate template, first using filename
988         // this must be done because writer global document uses this "great" idea to manage the templates of all parts
989         // in the master document
990         // but it is NOT an error if the template filename points not to a valid file
991         SfxDocumentTemplates aTempl;
992         aTempl.Construct();
993         if ( aTemplURL.getLength() )
994         {
995             String aURL;
996             if( ::utl::LocalFileHelper::ConvertSystemPathToURL( aTemplURL, GetMedium()->GetName(), aURL ) )
997                 aFoundName = aURL;
998         }
999 
1000         if( !aFoundName.Len() && aTemplName.getLength() )
1001             // if the template filename did not lead to success, try to get a file name for the logical template name
1002             aTempl.GetFull( String(), aTemplName, aFoundName );
1003 	}
1004 
1005     if ( aFoundName.Len() )
1006 	{
1007         // check existence of template storage
1008         aTemplURL = aFoundName;
1009 		sal_Bool bLoad = sal_False;
1010 
1011         // should the document checked against changes in the template ?
1012         if ( IsQueryLoadTemplate() )
1013 		{
1014             // load document info of template
1015             sal_Bool bOK = sal_False;
1016 			util::DateTime aTemplDate;
1017             try
1018             {
1019                 Reference < document::XStandaloneDocumentInfo > xDocInfo (
1020                     ::comphelper::getProcessServiceFactory()->createInstance(
1021                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
1022                             "com.sun.star.document.StandaloneDocumentInfo") ) ),
1023                     UNO_QUERY_THROW );
1024                 Reference < beans::XFastPropertySet > xSet( xDocInfo,
1025                     UNO_QUERY_THROW );
1026                 xDocInfo->loadFromURL( aTemplURL );
1027                 Any aAny = xSet->getFastPropertyValue( WID_DATE_MODIFIED );
1028                 ::com::sun::star::util::DateTime aTmp;
1029                 if ( aAny >>= aTemplDate )
1030                 {
1031                     // get modify date from document info
1032                     bOK = sal_True;
1033                 }
1034             }
1035             catch ( Exception& )
1036             {
1037             }
1038 
1039             // if modify date was read successfully
1040             if ( bOK )
1041 			{
1042                 // compare modify data of template with the last check date of the document
1043                 const util::DateTime aInfoDate( xDocProps->getTemplateDate() );
1044 				if ( aTemplDate > aInfoDate )
1045 				{
1046                     // ask user
1047                 	if( bCanUpdateFromTemplate == document::UpdateDocMode::QUIET_UPDATE
1048                 	|| bCanUpdateFromTemplate == document::UpdateDocMode::FULL_UPDATE )
1049 						bLoad = sal_True;
1050 					else if ( bCanUpdateFromTemplate == document::UpdateDocMode::ACCORDING_TO_CONFIG )
1051 					{
1052                         String sMessage( SfxResId( STR_QRYTEMPL_MESSAGE ) );
1053                         sMessage.SearchAndReplace( String::CreateFromAscii("$(ARG1)"), aTemplName );
1054                         sfx2::QueryTemplateBox aBox( GetDialogParent(), sMessage );
1055 						if ( RET_YES == aBox.Execute() )
1056 							bLoad = sal_True;
1057 					}
1058 
1059 					if( !bLoad )
1060 					{
1061                         // user refuses, so don't ask again for this document
1062 						SetQueryLoadTemplate(sal_False);
1063 						SetModified( sal_True );
1064 					}
1065 				}
1066 			}
1067 
1068 			if ( bLoad )
1069 			{
1070                 // styles should be updated, create document in organizer mode to read in the styles
1071                 //TODO: testen!
1072                 SfxObjectShellLock xTemplDoc = CreateObjectByFactoryName( GetFactory().GetFactoryName(), SFX_CREATE_MODE_ORGANIZER );
1073 				xTemplDoc->DoInitNew(0);
1074 
1075                 // TODO/MBA: do we need a BaseURL? Then LoadFrom must be extended!
1076                 //xTemplDoc->SetBaseURL( aFoundName );
1077 
1078                 // TODO/LATER: make sure that we don't use binary templates!
1079                 SfxMedium aMedium( aFoundName, STREAM_STD_READ );
1080                 if ( xTemplDoc->LoadFrom( aMedium ) )
1081 				{
1082                     // transfer styles from xTemplDoc to this document
1083                     // TODO/MBA: make sure that no BaseURL is needed in *this* document
1084 					LoadStyles(*xTemplDoc);
1085 
1086                     // remember date/time of check
1087                     xDocProps->setTemplateDate(aTemplDate);
1088                     // TODO/LATER: new functionality to store document info is required ( didn't work for SO7 XML format )
1089 //REPLACE					pInfo->Save(xDocStor);
1090 				}
1091 			}
1092 		}
1093 	}
1094 }
1095 
1096 sal_Bool SfxObjectShell::IsHelpDocument() const
1097 {
1098     const SfxFilter* pFilter = GetMedium()->GetFilter();
1099     return ( pFilter && pFilter->GetFilterName().CompareToAscii("writer_web_HTML_help") == COMPARE_EQUAL );
1100 }
1101 
1102 void SfxObjectShell::ResetFromTemplate( const String& rTemplateName, const String& rFileName )
1103 {
1104     // only care about reseting this data for openoffice formats otherwise
1105     if ( IsOwnStorageFormat_Impl( *GetMedium())  )
1106     {
1107         uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
1108         xDocProps->setTemplateURL( ::rtl::OUString() );
1109         xDocProps->setTemplateName( ::rtl::OUString() );
1110         xDocProps->setTemplateDate( util::DateTime() );
1111         xDocProps->resetUserData( ::rtl::OUString() );
1112 
1113     	// TODO/REFACTOR:
1114     	// Title?
1115 
1116         if( ::utl::LocalFileHelper::IsLocalFile( rFileName ) )
1117     	{
1118             String aFoundName;
1119             if( SFX_APP()->Get_Impl()->GetDocumentTemplates()->GetFull( String(), rTemplateName, aFoundName ) )
1120             {
1121                 INetURLObject aObj( rFileName );
1122                 xDocProps->setTemplateURL( aObj.GetMainURL(INetURLObject::DECODE_TO_IURI) );
1123                 xDocProps->setTemplateName( rTemplateName );
1124 
1125                 ::DateTime now;
1126                 xDocProps->setTemplateDate( util::DateTime(
1127                     now.Get100Sec(), now.GetSec(), now.GetMin(),
1128                     now.GetHour(), now.GetDay(), now.GetMonth(),
1129                     now.GetYear() ) );
1130 
1131     			SetQueryLoadTemplate( sal_True );
1132             }
1133         }
1134     }
1135 }
1136 
1137 sal_Bool SfxObjectShell::IsQueryLoadTemplate() const
1138 {
1139 	return pImp->bQueryLoadTemplate;
1140 }
1141 
1142 sal_Bool SfxObjectShell::IsUseUserData() const
1143 {
1144 	return pImp->bUseUserData;
1145 }
1146 
1147 void SfxObjectShell::SetQueryLoadTemplate( sal_Bool bNew )
1148 {
1149 	if ( pImp->bQueryLoadTemplate != bNew )
1150 		SetModified( sal_True );
1151 	pImp->bQueryLoadTemplate = bNew;
1152 }
1153 
1154 void SfxObjectShell::SetUseUserData( sal_Bool bNew )
1155 {
1156 	if ( pImp->bUseUserData != bNew )
1157 		SetModified( sal_True );
1158 	pImp->bUseUserData = bNew;
1159 }
1160 
1161 sal_Bool SfxObjectShell::IsLoadReadonly() const
1162 {
1163 	return pImp->bLoadReadonly;
1164 }
1165 
1166 sal_Bool SfxObjectShell::IsSaveVersionOnClose() const
1167 {
1168 	return pImp->bSaveVersionOnClose;
1169 }
1170 
1171 void SfxObjectShell::SetLoadReadonly( sal_Bool bNew )
1172 {
1173 	if ( pImp->bLoadReadonly != bNew )
1174 		SetModified( sal_True );
1175 	pImp->bLoadReadonly = bNew;
1176 }
1177 
1178 void SfxObjectShell::SetSaveVersionOnClose( sal_Bool bNew )
1179 {
1180 	if ( pImp->bSaveVersionOnClose != bNew )
1181 		SetModified( sal_True );
1182 	pImp->bSaveVersionOnClose = bNew;
1183 }
1184 
1185 sal_uInt32 SfxObjectShell::GetModifyPasswordHash() const
1186 {
1187     return pImp->m_nModifyPasswordHash;
1188 }
1189 
1190 sal_Bool SfxObjectShell::SetModifyPasswordHash( sal_uInt32 nHash )
1191 {
1192     if ( ( !IsReadOnly() && !IsReadOnlyUI() )
1193       || !(pImp->nFlagsInProgress & SFX_LOADED_MAINDOCUMENT ) )
1194     {
1195         // the hash can be changed only in editable documents,
1196         // or during loading of document
1197         pImp->m_nModifyPasswordHash = nHash;
1198         return sal_True;
1199     }
1200 
1201     return sal_False;
1202 }
1203 
1204 uno::Sequence< beans::PropertyValue > SfxObjectShell::GetModifyPasswordInfo() const
1205 {
1206     return pImp->m_aModifyPasswordInfo;
1207 }
1208 
1209 sal_Bool SfxObjectShell::SetModifyPasswordInfo( const uno::Sequence< beans::PropertyValue >& aInfo )
1210 {
1211     if ( ( !IsReadOnly() && !IsReadOnlyUI() )
1212       || !(pImp->nFlagsInProgress & SFX_LOADED_MAINDOCUMENT ) )
1213     {
1214         // the hash can be changed only in editable documents,
1215         // or during loading of document
1216         pImp->m_aModifyPasswordInfo = aInfo;
1217         return sal_True;
1218     }
1219 
1220     return sal_False;
1221 }
1222 
1223 void SfxObjectShell::SetModifyPasswordEntered( sal_Bool bEntered )
1224 {
1225     pImp->m_bModifyPasswordEntered = bEntered;
1226 }
1227 
1228 sal_Bool SfxObjectShell::IsModifyPasswordEntered()
1229 {
1230     return pImp->m_bModifyPasswordEntered;
1231 }
1232 
1233