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