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