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