xref: /AOO41X/main/sfx2/source/doc/objcont.cxx (revision 94a8b355fea931986ddfd4045215536f12f6af8b)
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             SfxStyleSheetIterator* pIter = pStylePool->CreateIterator(
763                 pStylePool->GetSearchFamily(), pStylePool->GetSearchMask() );
764             sal_uInt16 nStyles = pIter->Count();
765             SfxStyleSheetBase *pStyle = pIter->First();
766             if ( !pStyle )
767                 return sal_True;
768 
769             // pepare adaptor for old style StartPage/EndPage printing
770             boost::shared_ptr< Printer > pPrinter( new Printer( rPrt.GetJobSetup() ) );
771             vcl::OldStylePrintAdaptor* pAdaptor = new vcl::OldStylePrintAdaptor( pPrinter );
772             boost::shared_ptr< vcl::PrinterController > pController( pAdaptor );
773 
774             pAdaptor->StartPage();
775 
776             pPrinter->SetMapMode(MapMode(MAP_10TH_MM));
777             Font aFont( DEFINE_CONST_UNICODE( "Arial" ), Size(0, 64));   // 18pt
778             aFont.SetWeight(WEIGHT_BOLD);
779             pPrinter->SetFont(aFont);
780             const Size aPageSize(pPrinter->GetOutputSize());
781             const sal_uInt16 nXIndent = 200;
782             sal_uInt16 nYIndent = 200;
783             Point aOutPos(nXIndent, nYIndent);
784             String aHeader(SfxResId(STR_PRINT_STYLES_HEADER));
785             if ( pObjectName )
786                 aHeader += *pObjectName;
787             else
788                 aHeader += GetTitle();
789             long nTextHeight( pPrinter->GetTextHeight() );
790             pPrinter->DrawText(aOutPos, aHeader);
791             aOutPos.Y() += nTextHeight;
792             aOutPos.Y() += nTextHeight/2;
793             aFont.SetSize(Size(0, 35)); // 10pt
794             nStyles = 1;
795             while(pStyle)
796             {
797                 // print template name
798                 String aStr(pStyle->GetName());
799                 aFont.SetWeight(WEIGHT_BOLD);
800                 pPrinter->SetFont(aFont);
801                 nTextHeight = pPrinter->GetTextHeight();
802                 // check for new page
803                 if ( aOutPos.Y() + nTextHeight*2 >
804                     aPageSize.Height() - (long) nYIndent )
805                 {
806                     pAdaptor->EndPage();
807                     pAdaptor->StartPage();
808                     aOutPos.Y() = nYIndent;
809                 }
810                 pPrinter->DrawText(aOutPos, aStr);
811                 aOutPos.Y() += nTextHeight;
812 
813                 // print template description
814                 aFont.SetWeight(WEIGHT_NORMAL);
815                 pPrinter->SetFont(aFont);
816                 aStr = pStyle->GetDescription();
817                 const char cDelim = ' ';
818                 sal_uInt16 nStart = 0, nIdx = 0;
819 
820                 nTextHeight = pPrinter->GetTextHeight();
821                 // break text into lines
822                 while(nIdx < aStr.Len())
823                 {
824                     sal_uInt16  nOld = nIdx;
825                     long nTextWidth;
826                     nIdx = aStr.Search(cDelim, nStart);
827                     nTextWidth = pPrinter->GetTextWidth(aStr, nStart, nIdx-nStart);
828                     while(nIdx != STRING_NOTFOUND &&
829                           aOutPos.X() + nTextWidth <
830                           aPageSize.Width() - (long) nXIndent)
831                     {
832                         nOld = nIdx;
833                         nIdx = aStr.Search(cDelim, nIdx+1);
834                         nTextWidth = pPrinter->GetTextWidth(aStr, nStart, nIdx-nStart);
835                     }
836                     String aTmp(aStr, nStart, nIdx == STRING_NOTFOUND?
837                                 STRING_LEN :
838                                 nOld-nStart);
839                     if ( aTmp.Len() )
840                     {
841                         nStart = nOld+1;    // trailing space
842                     }
843                     else
844                     {
845                         sal_uInt16 nChar = 1;
846                         while(
847                             nStart + nChar < aStr.Len() &&
848                             aOutPos.X() + pPrinter->GetTextWidth(
849                                 aStr, nStart, nChar) <
850                             aPageSize.Width() - nXIndent)
851                             ++nChar;
852                         aTmp = String(aStr, nStart, nChar-1);
853                         nIdx = nStart + nChar;
854                         nStart = nIdx;
855                     }
856                     if ( aOutPos.Y() + nTextHeight*2 >
857                         aPageSize.Height() - nYIndent )
858                     {
859                         pAdaptor->EndPage();
860                         pAdaptor->StartPage();
861                         aOutPos.Y() = nYIndent;
862                     }
863                     pPrinter->DrawText(aOutPos, aTmp);
864                     aOutPos.Y() += pPrinter->GetTextHeight();
865                 }
866                 pStyle = pIter->Next();
867             }
868             pAdaptor->EndPage();
869 
870             Printer::PrintJob( pController, rPrt.GetJobSetup() );
871 
872             delete pIter;
873             break;
874         }
875       default:
876           return sal_False;
877     }
878     return sal_True;
879 }
880 
881 //--------------------------------------------------------------------
882 
883 void SfxObjectShell::LoadStyles
884 (
885     SfxObjectShell &rSource         /*  die Dokument-Vorlage, aus der
886                                             die Styles geladen werden sollen */
887 )
888 
889 /*  [Beschreibung]
890 
891     Diese Methode wird vom SFx gerufen, wenn aus einer Dokument-Vorlage
892     Styles nachgeladen werden sollen. Bestehende Styles soll dabei
893     "uberschrieben werden. Das Dokument mu"s daher neu formatiert werden.
894     Daher werden die Applikationen in der Regel diese Methode "uberladen
895     und in ihrer Implementierung die Implementierung der Basisklasse
896     rufen.
897 */
898 
899 {
900     struct Styles_Impl
901     {
902         SfxStyleSheetBase *pSource;
903         SfxStyleSheetBase *pDest;
904 //      Styles_Impl () : pSource(0), pDest(0) {}
905     };
906 
907     SfxStyleSheetBasePool *pSourcePool = rSource.GetStyleSheetPool();
908     DBG_ASSERT(pSourcePool, "Source-DocumentShell ohne StyleSheetPool");
909     SfxStyleSheetBasePool *pMyPool = GetStyleSheetPool();
910     DBG_ASSERT(pMyPool, "Dest-DocumentShell ohne StyleSheetPool");
911     pSourcePool->SetSearchMask(SFX_STYLE_FAMILY_ALL, 0xffff);
912     Styles_Impl *pFound = new Styles_Impl[pSourcePool->Count()];
913     sal_uInt16 nFound = 0;
914 
915     SfxStyleSheetBase *pSource = pSourcePool->First();
916     while ( pSource )
917     {
918         SfxStyleSheetBase *pDest =
919             pMyPool->Find( pSource->GetName(), pSource->GetFamily() );
920         if ( !pDest )
921         {
922             pDest = &pMyPool->Make( pSource->GetName(),
923                     pSource->GetFamily(), pSource->GetMask());
924             // Setzen des Parents, der Folgevorlage
925         }
926         pFound[nFound].pSource = pSource;
927         pFound[nFound].pDest = pDest;
928         ++nFound;
929         pSource = pSourcePool->Next();
930     }
931 
932     for ( sal_uInt16 i = 0; i < nFound; ++i )
933     {
934         pFound[i].pDest->GetItemSet().PutExtended(pFound[i].pSource->GetItemSet(), SFX_ITEM_DONTCARE, SFX_ITEM_DEFAULT);
935 //      pFound[i].pDest->SetHelpId(pFound[i].pSource->GetHelpId());
936         if(pFound[i].pSource->HasParentSupport())
937             pFound[i].pDest->SetParent(pFound[i].pSource->GetParent());
938         if(pFound[i].pSource->HasFollowSupport())
939             pFound[i].pDest->SetFollow(pFound[i].pSource->GetParent());
940     }
941     delete [] pFound;
942 }
943 
944 //--------------------------------------------------------------------
945 
946 void SfxObjectShell::UpdateFromTemplate_Impl(  )
947 
948 /*  [Beschreibung]
949 
950     Diese interne Methode pr"uft, ob das Dokument aus einem Template
951     erzeugt wurde, und ob dieses neuer ist als das Dokument. Ist dies
952     der Fall, wird der Benutzer gefragt, ob die Vorlagen (StyleSheets)
953     updated werden sollen. Wird dies positiv beantwortet, werden die
954     StyleSheets updated.
955 */
956 
957 {
958     // Storage-medium?
959     SfxMedium *pFile = GetMedium();
960     DBG_ASSERT( pFile, "cannot UpdateFromTemplate without medium" );
961     if ( !pFile )
962         return;
963 
964     if ( !::utl::LocalFileHelper::IsLocalFile( pFile->GetName() ) )
965         // update only for documents loaded from the local file system
966         return;
967 
968     // only for own storage formats
969     uno::Reference< embed::XStorage > xDocStor = pFile->GetStorage();
970     if ( !pFile->GetFilter() || !pFile->GetFilter()->IsOwnFormat() )
971         return;
972 
973     SFX_ITEMSET_ARG( pFile->GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
974     sal_Int16 bCanUpdateFromTemplate = pUpdateDocItem ? pUpdateDocItem->GetValue() : document::UpdateDocMode::NO_UPDATE;
975 
976     // created from template?
977     uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
978     ::rtl::OUString aTemplName( xDocProps->getTemplateName() );
979     ::rtl::OUString aTemplURL( xDocProps->getTemplateURL() );
980     String aFoundName;
981 
982     if ( aTemplName.getLength() || (aTemplURL.getLength() && !IsReadOnly()) )
983     {
984         // try to locate template, first using filename
985         // this must be done because writer global document uses this "great" idea to manage the templates of all parts
986         // in the master document
987         // but it is NOT an error if the template filename points not to a valid file
988         SfxDocumentTemplates aTempl;
989         aTempl.Construct();
990         if ( aTemplURL.getLength() )
991         {
992             String aURL;
993             if( ::utl::LocalFileHelper::ConvertSystemPathToURL( aTemplURL, GetMedium()->GetName(), aURL ) )
994                 aFoundName = aURL;
995         }
996 
997         if( !aFoundName.Len() && aTemplName.getLength() )
998             // if the template filename did not lead to success, try to get a file name for the logical template name
999             aTempl.GetFull( String(), aTemplName, aFoundName );
1000     }
1001 
1002     if ( aFoundName.Len() )
1003     {
1004         // check existence of template storage
1005         aTemplURL = aFoundName;
1006         sal_Bool bLoad = sal_False;
1007 
1008         // should the document checked against changes in the template ?
1009         if ( IsQueryLoadTemplate() )
1010         {
1011             // load document info of template
1012             sal_Bool bOK = sal_False;
1013             util::DateTime aTemplDate;
1014             try
1015             {
1016                 Reference < document::XStandaloneDocumentInfo > xDocInfo (
1017                     ::comphelper::getProcessServiceFactory()->createInstance(
1018                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
1019                             "com.sun.star.document.StandaloneDocumentInfo") ) ),
1020                     UNO_QUERY_THROW );
1021                 Reference < beans::XFastPropertySet > xSet( xDocInfo,
1022                     UNO_QUERY_THROW );
1023                 xDocInfo->loadFromURL( aTemplURL );
1024                 Any aAny = xSet->getFastPropertyValue( WID_DATE_MODIFIED );
1025                 ::com::sun::star::util::DateTime aTmp;
1026                 if ( aAny >>= aTemplDate )
1027                 {
1028                     // get modify date from document info
1029                     bOK = sal_True;
1030                 }
1031             }
1032             catch ( Exception& )
1033             {
1034             }
1035 
1036             // if modify date was read successfully
1037             if ( bOK )
1038             {
1039                 // compare modify data of template with the last check date of the document
1040                 const util::DateTime aInfoDate( xDocProps->getTemplateDate() );
1041                 if ( aTemplDate > aInfoDate )
1042                 {
1043                     // ask user
1044                     if( bCanUpdateFromTemplate == document::UpdateDocMode::QUIET_UPDATE
1045                     || bCanUpdateFromTemplate == document::UpdateDocMode::FULL_UPDATE )
1046                         bLoad = sal_True;
1047                     else if ( bCanUpdateFromTemplate == document::UpdateDocMode::ACCORDING_TO_CONFIG )
1048                     {
1049                         String sMessage( SfxResId( STR_QRYTEMPL_MESSAGE ) );
1050                         sMessage.SearchAndReplace( String::CreateFromAscii("$(ARG1)"), aTemplName );
1051                         sfx2::QueryTemplateBox aBox( GetDialogParent(), sMessage );
1052                         if ( RET_YES == aBox.Execute() )
1053                             bLoad = sal_True;
1054                     }
1055 
1056                     if( !bLoad )
1057                     {
1058                         // user refuses, so don't ask again for this document
1059                         SetQueryLoadTemplate(sal_False);
1060                         SetModified( sal_True );
1061                     }
1062                 }
1063             }
1064 
1065             if ( bLoad )
1066             {
1067                 // styles should be updated, create document in organizer mode to read in the styles
1068                 //TODO: testen!
1069                 SfxObjectShellLock xTemplDoc = CreateObjectByFactoryName( GetFactory().GetFactoryName(), SFX_CREATE_MODE_ORGANIZER );
1070                 xTemplDoc->DoInitNew(0);
1071 
1072                 // TODO/MBA: do we need a BaseURL? Then LoadFrom must be extended!
1073                 //xTemplDoc->SetBaseURL( aFoundName );
1074 
1075                 // TODO/LATER: make sure that we don't use binary templates!
1076                 SfxMedium aMedium( aFoundName, STREAM_STD_READ );
1077                 if ( xTemplDoc->LoadFrom( aMedium ) )
1078                 {
1079                     // transfer styles from xTemplDoc to this document
1080                     // TODO/MBA: make sure that no BaseURL is needed in *this* document
1081                     LoadStyles(*xTemplDoc);
1082 
1083                     // remember date/time of check
1084                     xDocProps->setTemplateDate(aTemplDate);
1085                     // TODO/LATER: new functionality to store document info is required ( didn't work for SO7 XML format )
1086 //REPLACE                   pInfo->Save(xDocStor);
1087                 }
1088             }
1089         }
1090     }
1091 }
1092 
1093 sal_Bool SfxObjectShell::IsHelpDocument() const
1094 {
1095     const SfxFilter* pFilter = GetMedium()->GetFilter();
1096     return ( pFilter && pFilter->GetFilterName().CompareToAscii("writer_web_HTML_help") == COMPARE_EQUAL );
1097 }
1098 
1099 void SfxObjectShell::ResetFromTemplate( const String& rTemplateName, const String& rFileName )
1100 {
1101     // only care about reseting this data for openoffice formats otherwise
1102     if ( IsOwnStorageFormat_Impl( *GetMedium())  )
1103     {
1104         uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
1105         xDocProps->setTemplateURL( ::rtl::OUString() );
1106         xDocProps->setTemplateName( ::rtl::OUString() );
1107         xDocProps->setTemplateDate( util::DateTime() );
1108         xDocProps->resetUserData( ::rtl::OUString() );
1109 
1110         // TODO/REFACTOR:
1111         // Title?
1112 
1113         if( ::utl::LocalFileHelper::IsLocalFile( rFileName ) )
1114         {
1115             String aFoundName;
1116             if( SFX_APP()->Get_Impl()->GetDocumentTemplates()->GetFull( String(), rTemplateName, aFoundName ) )
1117             {
1118                 INetURLObject aObj( rFileName );
1119                 xDocProps->setTemplateURL( aObj.GetMainURL(INetURLObject::DECODE_TO_IURI) );
1120                 xDocProps->setTemplateName( rTemplateName );
1121 
1122                 ::DateTime now;
1123                 xDocProps->setTemplateDate( util::DateTime(
1124                     now.Get100Sec(), now.GetSec(), now.GetMin(),
1125                     now.GetHour(), now.GetDay(), now.GetMonth(),
1126                     now.GetYear() ) );
1127 
1128                 SetQueryLoadTemplate( sal_True );
1129             }
1130         }
1131     }
1132 }
1133 
1134 sal_Bool SfxObjectShell::IsQueryLoadTemplate() const
1135 {
1136     return pImp->bQueryLoadTemplate;
1137 }
1138 
1139 sal_Bool SfxObjectShell::IsUseUserData() const
1140 {
1141     return pImp->bUseUserData;
1142 }
1143 
1144 void SfxObjectShell::SetQueryLoadTemplate( sal_Bool bNew )
1145 {
1146     if ( pImp->bQueryLoadTemplate != bNew )
1147         SetModified( sal_True );
1148     pImp->bQueryLoadTemplate = bNew;
1149 }
1150 
1151 void SfxObjectShell::SetUseUserData( sal_Bool bNew )
1152 {
1153     if ( pImp->bUseUserData != bNew )
1154         SetModified( sal_True );
1155     pImp->bUseUserData = bNew;
1156 }
1157 
1158 sal_Bool SfxObjectShell::IsLoadReadonly() const
1159 {
1160     return pImp->bLoadReadonly;
1161 }
1162 
1163 sal_Bool SfxObjectShell::IsSaveVersionOnClose() const
1164 {
1165     return pImp->bSaveVersionOnClose;
1166 }
1167 
1168 void SfxObjectShell::SetLoadReadonly( sal_Bool bNew )
1169 {
1170     if ( pImp->bLoadReadonly != bNew )
1171         SetModified( sal_True );
1172     pImp->bLoadReadonly = bNew;
1173 }
1174 
1175 void SfxObjectShell::SetSaveVersionOnClose( sal_Bool bNew )
1176 {
1177     if ( pImp->bSaveVersionOnClose != bNew )
1178         SetModified( sal_True );
1179     pImp->bSaveVersionOnClose = bNew;
1180 }
1181 
1182 sal_uInt32 SfxObjectShell::GetModifyPasswordHash() const
1183 {
1184     return pImp->m_nModifyPasswordHash;
1185 }
1186 
1187 sal_Bool SfxObjectShell::SetModifyPasswordHash( sal_uInt32 nHash )
1188 {
1189     if ( ( !IsReadOnly() && !IsReadOnlyUI() )
1190       || !(pImp->nFlagsInProgress & SFX_LOADED_MAINDOCUMENT ) )
1191     {
1192         // the hash can be changed only in editable documents,
1193         // or during loading of document
1194         pImp->m_nModifyPasswordHash = nHash;
1195         return sal_True;
1196     }
1197 
1198     return sal_False;
1199 }
1200 
1201 uno::Sequence< beans::PropertyValue > SfxObjectShell::GetModifyPasswordInfo() const
1202 {
1203     return pImp->m_aModifyPasswordInfo;
1204 }
1205 
1206 sal_Bool SfxObjectShell::SetModifyPasswordInfo( const uno::Sequence< beans::PropertyValue >& aInfo )
1207 {
1208     if ( ( !IsReadOnly() && !IsReadOnlyUI() )
1209       || !(pImp->nFlagsInProgress & SFX_LOADED_MAINDOCUMENT ) )
1210     {
1211         // the hash can be changed only in editable documents,
1212         // or during loading of document
1213         pImp->m_aModifyPasswordInfo = aInfo;
1214         return sal_True;
1215     }
1216 
1217     return sal_False;
1218 }
1219 
1220 void SfxObjectShell::SetModifyPasswordEntered( sal_Bool bEntered )
1221 {
1222     pImp->m_bModifyPasswordEntered = bEntered;
1223 }
1224 
1225 sal_Bool SfxObjectShell::IsModifyPasswordEntered()
1226 {
1227     return pImp->m_bModifyPasswordEntered;
1228 }
1229 
1230