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