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