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 SvtCTLOptions* pCTLOptions = new SvtCTLOptions; 170 if ( SvtCTLOptions::NUMERALS_HINDI == pCTLOptions->GetCTLTextNumerals() ) 171 eLang = LANGUAGE_ARABIC_SAUDI_ARABIA; 172 else if ( SvtCTLOptions::NUMERALS_ARABIC == pCTLOptions->GetCTLTextNumerals() ) 173 eLang = LANGUAGE_ENGLISH; 174 else 175 eLang = (LanguageType) Application::GetSettings().GetLanguage(); 176 177 aDevice.SetDigitLanguage( eLang ); 178 179 ((SfxObjectShell*)this)->DoDraw( &aDevice, Point(0,0), aTmpSize, JobSetup(), nAspect ); 180 pFile->Stop(); 181 182 return pFile; 183 } 184 185 //==================================================================== 186 187 void SfxObjectShell::UpdateDocInfoForSave() 188 { 189 uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties()); 190 191 // clear user data if recommend (see 'Tools - Options - Open/StarOffice - Security') 192 if ( SvtSecurityOptions().IsOptionSet( 193 SvtSecurityOptions::E_DOCWARN_REMOVEPERSONALINFO ) ) 194 { 195 xDocProps->resetUserData( ::rtl::OUString() ); 196 } 197 else if ( IsModified() ) 198 { 199 String aUserName = SvtUserOptions().GetFullName(); 200 if ( !IsUseUserData() ) 201 { 202 // remove all data pointing to the current user 203 if (xDocProps->getAuthor().equals(aUserName)) { 204 xDocProps->setAuthor( ::rtl::OUString() ); 205 } 206 xDocProps->setModifiedBy( ::rtl::OUString() ); 207 if (xDocProps->getPrintedBy().equals(aUserName)) { 208 xDocProps->setPrintedBy( ::rtl::OUString() ); 209 } 210 } 211 else 212 { 213 // update ModificationAuthor, revision and editing time 214 ::DateTime now; 215 xDocProps->setModificationDate( util::DateTime( 216 now.Get100Sec(), now.GetSec(), now.GetMin(), 217 now.GetHour(), now.GetDay(), now.GetMonth(), 218 now.GetYear() ) ); 219 xDocProps->setModifiedBy( aUserName ); 220 if ( !HasName() || pImp->bIsSaving ) 221 // QUESTION: not in case of "real" SaveAs as this is meant to create a new document 222 UpdateTime_Impl( xDocProps ); 223 } 224 } 225 } 226 227 //-------------------------------------------------------------------- 228 229 static void 230 lcl_add(util::Duration & rDur, Time const& rTime) 231 { 232 // here we don't care about overflow: rDur is converted back to seconds 233 // anyway, and Time cannot store more than ~4000 hours 234 rDur.Hours += rTime.GetHour(); 235 rDur.Minutes += rTime.GetMin(); 236 rDur.Seconds += rTime.GetSec(); 237 } 238 239 // Bearbeitungszeit aktualisieren 240 void SfxObjectShell::UpdateTime_Impl( 241 const uno::Reference<document::XDocumentProperties> & i_xDocProps) 242 { 243 // Get old time from documentinfo 244 const sal_Int32 secs = i_xDocProps->getEditingDuration(); 245 util::Duration editDuration(sal_False, 0, 0, 0, 246 secs/3600, (secs%3600)/60, secs%60, 0); 247 248 // Initialize some local member! Its neccessary for wollow operations! 249 DateTime aNow ; // Date and time at current moment 250 Time n24Time (24,0,0,0) ; // Time-value for 24 hours - see follow calculation 251 sal_uIntPtr nDays = 0 ; // Count of days between now and last editing 252 Time nAddTime (0) ; // Value to add on aOldTime 253 254 // Safe impossible cases! 255 // User has changed time to the past between last editing and now ... its not possible!!! 256 DBG_ASSERT( !(aNow.GetDate()<pImp->nTime.GetDate()), "Timestamp of last change is in the past ?!..." ); 257 258 // Do the follow only, if user has NOT changed time to the past. 259 // Else add a time of 0 to aOldTime ... !!! 260 if (aNow.GetDate()>=pImp->nTime.GetDate()) 261 { 262 // Get count of days last editing. 263 nDays = aNow.GetSecFromDateTime(pImp->nTime.GetDate())/86400 ; 264 265 if (nDays==0) 266 { 267 // If no day between now and last editing - calculate time directly. 268 nAddTime = (const Time&)aNow - (const Time&)pImp->nTime ; 269 } 270 else 271 // If time of working without save greater then 1 month (!) .... 272 // we add 0 to aOldTime! 273 if (nDays<=31) 274 { 275 // If 1 or up to 31 days between now and last editing - calculate time indirectly. 276 // nAddTime = (24h - nTime) + (nDays * 24h) + aNow 277 --nDays; 278 nAddTime = nDays*n24Time.GetTime() ; 279 nAddTime += n24Time-(const Time&)pImp->nTime ; 280 nAddTime += aNow ; 281 } 282 283 lcl_add(editDuration, nAddTime); 284 } 285 286 pImp->nTime = aNow; 287 try { 288 const sal_Int32 newSecs( (editDuration.Hours*3600) 289 + (editDuration.Minutes*60) + editDuration.Seconds); 290 i_xDocProps->setEditingDuration(newSecs); 291 i_xDocProps->setEditingCycles(i_xDocProps->getEditingCycles() + 1); 292 } 293 catch (lang::IllegalArgumentException &) 294 { 295 // ignore overflow 296 } 297 } 298 299 //-------------------------------------------------------------------- 300 301 SfxDocumentInfoDialog* SfxObjectShell::CreateDocumentInfoDialog 302 ( 303 Window* pParent, 304 const SfxItemSet& rSet 305 ) 306 { 307 return new SfxDocumentInfoDialog(pParent, rSet); 308 } 309 310 //-------------------------------------------------------------------- 311 312 SfxStyleSheetBasePool* SfxObjectShell::GetStyleSheetPool() 313 { 314 return 0; 315 } 316 317 void SfxObjectShell::SetOrganizerSearchMask( 318 SfxStyleSheetBasePool* pStylePool) const 319 { 320 pStylePool->SetSearchMask( 321 SFX_STYLE_FAMILY_ALL, 322 SFXSTYLEBIT_USERDEF | SFXSTYLEBIT_USED); 323 } 324 325 //-------------------------------------------------------------------- 326 327 sal_uInt16 SfxObjectShell::GetContentCount( 328 sal_uInt16 nIdx1, 329 sal_uInt16 /*nIdx2*/) 330 { 331 switch(nIdx1) 332 { 333 case INDEX_IGNORE: 334 return DEF_CONTENT_COUNT; 335 case CONTENT_STYLE: 336 { 337 SfxStyleSheetBasePool *pStylePool = GetStyleSheetPool(); 338 if(!pStylePool) 339 return 0; 340 SetOrganizerSearchMask(pStylePool); 341 return pStylePool->Count(); 342 } 343 case CONTENT_MACRO: 344 break; 345 /* 346 case CONTENT_CONFIG: 347 return ( GetConfigManager() ) ? 348 GetConfigManager()->GetItemCount() : 0; 349 break; 350 */ 351 } 352 return 0; 353 } 354 355 356 //-------------------------------------------------------------------- 357 //TODO/CLEANUP: remove this method (it's virtual) 358 void SfxObjectShell::TriggerHelpPI(sal_uInt16 nIdx1, sal_uInt16 nIdx2, sal_uInt16) 359 { 360 if(nIdx1==CONTENT_STYLE && nIdx2 != INDEX_IGNORE) //StyleSheets 361 { 362 SfxStyleSheetBasePool *pStylePool = GetStyleSheetPool(); 363 SetOrganizerSearchMask(pStylePool); 364 } 365 } 366 367 sal_Bool SfxObjectShell::CanHaveChilds(sal_uInt16 nIdx1, 368 sal_uInt16 nIdx2) 369 { 370 switch(nIdx1) { 371 case INDEX_IGNORE: 372 return sal_True; 373 case CONTENT_STYLE: 374 return INDEX_IGNORE == nIdx2 || !GetStyleSheetPool()? sal_False: sal_True; 375 case CONTENT_MACRO: 376 //!! return INDEX_IGNORE == nIdx2? sal_False: sal_True; 377 return sal_False; 378 /* 379 case CONTENT_CONFIG: 380 return INDEX_IGNORE == nIdx2 ? sal_False : sal_True; 381 */ 382 } 383 return sal_False; 384 } 385 386 //-------------------------------------------------------------------- 387 388 void SfxObjectShell::GetContent(String &rText, 389 Bitmap &rClosedBitmap, 390 Bitmap &rOpenedBitmap, 391 sal_Bool &bCanDel, 392 sal_uInt16 i, 393 sal_uInt16 nIdx1, 394 sal_uInt16 nIdx2 ) 395 { 396 DBG_ERRORFILE( "Non high contrast method called. Please update calling code!" ); 397 SfxObjectShell::GetContent( rText, rClosedBitmap, rOpenedBitmap, BMP_COLOR_NORMAL, bCanDel, i, nIdx1, nIdx2 ); 398 } 399 400 //-------------------------------------------------------------------- 401 402 void SfxObjectShell::GetContent(String &rText, 403 Bitmap &rClosedBitmap, 404 Bitmap &rOpenedBitmap, 405 BmpColorMode eColorMode, 406 sal_Bool &bCanDel, 407 sal_uInt16 i, 408 sal_uInt16 nIdx1, 409 sal_uInt16 /*nIdx2*/ ) 410 { 411 bCanDel=sal_True; 412 413 switch(nIdx1) 414 { 415 case INDEX_IGNORE: 416 { 417 sal_uInt16 nTextResId = 0; 418 sal_uInt16 nClosedBitmapResId = 0; // evtl. sp"ater mal unterschiedliche 419 sal_uInt16 nOpenedBitmapResId = 0; // " " " " 420 switch(i) 421 { 422 case CONTENT_STYLE: 423 nTextResId = STR_STYLES; 424 if ( eColorMode == BMP_COLOR_NORMAL ) 425 { 426 nClosedBitmapResId= BMP_STYLES_CLOSED; 427 nOpenedBitmapResId= BMP_STYLES_OPENED; 428 } 429 else 430 { 431 nClosedBitmapResId= BMP_STYLES_CLOSED_HC; 432 nOpenedBitmapResId= BMP_STYLES_OPENED_HC; 433 } 434 break; 435 case CONTENT_MACRO: 436 nTextResId = STR_MACROS; 437 if ( eColorMode == BMP_COLOR_NORMAL ) 438 { 439 nClosedBitmapResId= BMP_STYLES_CLOSED; 440 nOpenedBitmapResId= BMP_STYLES_OPENED; 441 } 442 else 443 { 444 nClosedBitmapResId= BMP_STYLES_CLOSED_HC; 445 nOpenedBitmapResId= BMP_STYLES_OPENED_HC; 446 } 447 break; 448 /* 449 case CONTENT_CONFIG: 450 nTextResId = STR_CONFIG; 451 nClosedBitmapResId= BMP_STYLES_CLOSED; 452 nOpenedBitmapResId= BMP_STYLES_OPENED; 453 break; 454 */ 455 } 456 457 if ( nTextResId ) 458 { 459 rText = String(SfxResId(nTextResId)); 460 rClosedBitmap = Bitmap(SfxResId(nClosedBitmapResId)); 461 rOpenedBitmap = Bitmap(SfxResId(nOpenedBitmapResId)); 462 } 463 break; 464 } 465 466 case CONTENT_STYLE: 467 { 468 SfxStyleSheetBasePool *pStylePool = GetStyleSheetPool(); 469 SetOrganizerSearchMask(pStylePool); 470 SfxStyleSheetBase *pStyle = (*pStylePool)[i]; 471 rText = pStyle->GetName(); 472 bCanDel=((pStyle->GetMask() & SFXSTYLEBIT_USERDEF) 473 == SFXSTYLEBIT_USERDEF); 474 rClosedBitmap = rOpenedBitmap = 475 GetStyleFamilyBitmap(pStyle->GetFamily(), eColorMode ); 476 } 477 break; 478 case CONTENT_MACRO: 479 break; 480 /* 481 case CONTENT_CONFIG: 482 if ( GetConfigManager() ) 483 { 484 rText = GetConfigManager()->GetItem(i); 485 bCanDel = GetConfigManager()->CanDelete(i); 486 } 487 else 488 rText = String(); 489 rClosedBitmap = Bitmap(SfxResId(BMP_STYLES_CLOSED)); 490 rOpenedBitmap = Bitmap(SfxResId(BMP_STYLES_OPENED)); 491 break; 492 */ 493 } 494 } 495 496 //-------------------------------------------------------------------- 497 Bitmap SfxObjectShell::GetStyleFamilyBitmap( SfxStyleFamily eFamily ) 498 { 499 DBG_ERRORFILE( "Non high contrast method called. Please update calling code!" ); 500 return SfxObjectShell::GetStyleFamilyBitmap( eFamily, BMP_COLOR_NORMAL ); 501 } 502 503 //-------------------------------------------------------------------- 504 505 Bitmap SfxObjectShell::GetStyleFamilyBitmap(SfxStyleFamily eFamily, BmpColorMode eColorMode ) 506 { 507 sal_uInt16 nResId = 0; 508 switch(eFamily) 509 { 510 case SFX_STYLE_FAMILY_CHAR: 511 nResId = ( eColorMode == BMP_COLOR_NORMAL ) ? BMP_STYLES_FAMILY1 : BMP_STYLES_FAMILY1_HC; 512 break; 513 case SFX_STYLE_FAMILY_PARA: 514 nResId = ( eColorMode == BMP_COLOR_NORMAL ) ? BMP_STYLES_FAMILY2 : BMP_STYLES_FAMILY2_HC; 515 break; 516 case SFX_STYLE_FAMILY_FRAME: 517 nResId = ( eColorMode == BMP_COLOR_NORMAL ) ? BMP_STYLES_FAMILY3 : BMP_STYLES_FAMILY3_HC; 518 break; 519 case SFX_STYLE_FAMILY_PAGE : 520 nResId = ( eColorMode == BMP_COLOR_NORMAL ) ? BMP_STYLES_FAMILY4 : BMP_STYLES_FAMILY4_HC; 521 break; 522 case SFX_STYLE_FAMILY_PSEUDO: 523 case SFX_STYLE_FAMILY_ALL: 524 break; 525 } 526 527 if ( nResId ) 528 return Bitmap(SfxResId(nResId)); 529 else 530 return Bitmap(); 531 } 532 533 534 //-------------------------------------------------------------------- 535 536 sal_Bool SfxObjectShell::Insert(SfxObjectShell &rSource, 537 sal_uInt16 nSourceIdx1, 538 sal_uInt16 nSourceIdx2, 539 sal_uInt16 /*nSourceIdx3*/, 540 sal_uInt16 &nIdx1, 541 sal_uInt16 &nIdx2, 542 sal_uInt16 &/*nIdx3*/, 543 sal_uInt16 &/*nDeleted*/) 544 { 545 sal_Bool bRet = sal_False; 546 547 if (INDEX_IGNORE == nIdx1 && CONTENT_STYLE == nSourceIdx1) 548 nIdx1 = CONTENT_STYLE; 549 550 if (CONTENT_STYLE == nSourceIdx1 && CONTENT_STYLE == nIdx1) 551 { 552 SfxStyleSheetBasePool* pHisPool = rSource.GetStyleSheetPool(); 553 SfxStyleSheetBasePool* pMyPool = GetStyleSheetPool(); 554 SetOrganizerSearchMask(pHisPool); 555 SetOrganizerSearchMask(pMyPool); 556 SfxStyleSheetBase* pHisSheet = NULL; 557 558 if ( pHisPool && pHisPool->Count() > nSourceIdx2 ) 559 pHisSheet = (*pHisPool)[nSourceIdx2]; 560 561 // Einfuegen ist nur dann noetig, wenn ein StyleSheet 562 // zwischen unterschiedlichen(!) Pools bewegt wird 563 564 if ( pHisSheet && pMyPool != pHisPool ) 565 { 566 if (INDEX_IGNORE == nIdx2) 567 { 568 nIdx2 = pMyPool->Count(); 569 } 570 571 // wenn so eine Vorlage schon existiert: loeschen! 572 String aOldName(pHisSheet->GetName()); 573 SfxStyleFamily eOldFamily = pHisSheet->GetFamily(); 574 575 SfxStyleSheetBase* pExist = pMyPool->Find(aOldName, eOldFamily); 576 // sal_uInt16 nOldHelpId = pExist->GetHelpId(??? VB ueberlegt sich was); 577 sal_Bool bUsedOrUserDefined; 578 if( pExist ) 579 { 580 bUsedOrUserDefined = 581 pExist->IsUsed() || pExist->IsUserDefined(); 582 if( ErrorHandler::HandleError( 583 *new MessageInfo( ERRCODE_SFXMSG_STYLEREPLACE, aOldName ) ) 584 != ERRCODE_BUTTON_OK ) 585 return sal_False; 586 else 587 { 588 pMyPool->Replace( *pHisSheet, *pExist ); 589 SetModified( sal_True ); 590 nIdx2 = nIdx1 = INDEX_IGNORE; 591 return sal_True; 592 } 593 } 594 595 SfxStyleSheetBase& rNewSheet = pMyPool->Make( 596 aOldName, eOldFamily, 597 pHisSheet->GetMask(), nIdx2); 598 599 // ItemSet der neuen Vorlage fuellen 600 rNewSheet.GetItemSet().Set(pHisSheet->GetItemSet()); 601 602 // wer bekommt den Neuen als Parent? wer benutzt den Neuen als Follow? 603 SfxStyleSheetBase* pTestSheet = pMyPool->First(); 604 while (pTestSheet) 605 { 606 if (pTestSheet->GetFamily() == eOldFamily && 607 pTestSheet->HasParentSupport() && 608 pTestSheet->GetParent() == aOldName) 609 { 610 pTestSheet->SetParent(aOldName); 611 // Verknuepfung neu aufbauen 612 } 613 614 if (pTestSheet->GetFamily() == eOldFamily && 615 pTestSheet->HasFollowSupport() && 616 pTestSheet->GetFollow() == aOldName) 617 { 618 pTestSheet->SetFollow(aOldName); 619 // Verknuepfung neu aufbauen 620 } 621 622 pTestSheet = pMyPool->Next(); 623 } 624 bUsedOrUserDefined = 625 rNewSheet.IsUsed() || rNewSheet.IsUserDefined(); 626 627 628 // hat der Neue einen Parent? wenn ja, mit gleichem Namen bei uns suchen 629 if (pHisSheet->HasParentSupport()) 630 { 631 const String& rParentName = pHisSheet->GetParent(); 632 if (0 != rParentName.Len()) 633 { 634 SfxStyleSheetBase* pParentOfNew = 635 pMyPool->Find(rParentName, eOldFamily); 636 if (pParentOfNew) 637 rNewSheet.SetParent(rParentName); 638 } 639 } 640 641 // hat der Neue einen Follow? wenn ja, mit gleichem 642 // Namen bei uns suchen 643 if (pHisSheet->HasFollowSupport()) 644 { 645 const String& rFollowName = pHisSheet->GetFollow(); 646 if (0 != rFollowName.Len()) 647 { 648 SfxStyleSheetBase* pFollowOfNew = 649 pMyPool->Find(rFollowName, eOldFamily); 650 if (pFollowOfNew) 651 rNewSheet.SetFollow(rFollowName); 652 } 653 } 654 655 SetModified( sal_True ); 656 if( !bUsedOrUserDefined ) nIdx2 = nIdx1 = INDEX_IGNORE; 657 658 bRet = sal_True; 659 } 660 else 661 bRet = sal_False; 662 } 663 /* 664 else if (nSourceIdx1 == CONTENT_CONFIG) 665 { 666 nIdx1 = CONTENT_CONFIG; 667 668 SfxConfigManager *pCfgMgr = SFX_CFGMANAGER(); 669 if ( !GetConfigManager() ) 670 { 671 SetConfigManager(new SfxConfigManager(0, pCfgMgr)); 672 SetTemplateConfig(sal_False); 673 if (this == Current()) 674 GetConfigManager()->Activate(pCfgMgr); 675 } 676 677 if (GetConfigManager()->CopyItem( 678 nSourceIdx2, nIdx2, rSource.GetConfigManager())) 679 { 680 SetModified(sal_True); 681 bRet = sal_True; 682 SFX_APP()->GetDispatcher_Impl()->Update_Impl(sal_True); 683 } 684 } 685 */ 686 return bRet; 687 } 688 689 //-------------------------------------------------------------------- 690 691 sal_Bool SfxObjectShell::Remove 692 ( 693 sal_uInt16 nIdx1, 694 sal_uInt16 nIdx2, 695 sal_uInt16 /*nIdx3*/ 696 ) 697 { 698 sal_Bool bRet = sal_False; 699 700 if (CONTENT_STYLE == nIdx1) 701 { 702 SfxStyleSheetBasePool* pMyPool = GetStyleSheetPool(); 703 704 SetOrganizerSearchMask(pMyPool); 705 706 SfxStyleSheetBase* pMySheet = (*pMyPool)[nIdx2]; 707 String aName(pMySheet->GetName()); 708 String aEmpty; 709 SfxStyleFamily eFamily = pMySheet->GetFamily(); 710 pMyPool->Remove(pMySheet); 711 bRet = sal_True; 712 713 SfxStyleSheetBase* pTestSheet = pMyPool->First(); 714 while (pTestSheet) 715 { 716 if (pTestSheet->GetFamily() == eFamily && 717 pTestSheet->HasParentSupport() && 718 pTestSheet->GetParent() == aName) 719 { 720 pTestSheet->SetParent(aEmpty); // Verknuepfung aufloesen 721 } 722 723 if (pTestSheet->GetFamily() == eFamily && 724 pTestSheet->HasFollowSupport() && 725 pTestSheet->GetFollow() == aName) 726 { 727 pTestSheet->SetFollow(aEmpty); // Verknuepfung aufloesen 728 } 729 730 pTestSheet = pMyPool->Next(); 731 } 732 733 SetModified( sal_True ); 734 } 735 736 return bRet; 737 } 738 739 //-------------------------------------------------------------------- 740 741 sal_Bool SfxObjectShell::Print 742 ( 743 Printer& rPrt, 744 sal_uInt16 nIdx1, 745 sal_uInt16 /*nIdx2*/, 746 sal_uInt16 /*nIdx3*/, 747 const String* pObjectName 748 ) 749 750 /* [Beschreibung] 751 */ 752 753 { 754 switch(nIdx1) 755 { 756 case CONTENT_STYLE: 757 { 758 SfxStyleSheetBasePool *pStylePool = GetStyleSheetPool(); 759 SetOrganizerSearchMask(pStylePool); 760 SfxStyleSheetIterator* pIter = pStylePool->CreateIterator( 761 pStylePool->GetSearchFamily(), pStylePool->GetSearchMask() ); 762 sal_uInt16 nStyles = pIter->Count(); 763 SfxStyleSheetBase *pStyle = pIter->First(); 764 if ( !pStyle ) 765 return sal_True; 766 767 // pepare adaptor for old style StartPage/EndPage printing 768 boost::shared_ptr< Printer > pPrinter( new Printer( rPrt.GetJobSetup() ) ); 769 vcl::OldStylePrintAdaptor* pAdaptor = new vcl::OldStylePrintAdaptor( pPrinter ); 770 boost::shared_ptr< vcl::PrinterController > pController( pAdaptor ); 771 772 pAdaptor->StartPage(); 773 774 pPrinter->SetMapMode(MapMode(MAP_10TH_MM)); 775 Font aFont( DEFINE_CONST_UNICODE( "Arial" ), Size(0, 64)); // 18pt 776 aFont.SetWeight(WEIGHT_BOLD); 777 pPrinter->SetFont(aFont); 778 const Size aPageSize(pPrinter->GetOutputSize()); 779 const sal_uInt16 nXIndent = 200; 780 sal_uInt16 nYIndent = 200; 781 Point aOutPos(nXIndent, nYIndent); 782 String aHeader(SfxResId(STR_PRINT_STYLES_HEADER)); 783 if ( pObjectName ) 784 aHeader += *pObjectName; 785 else 786 aHeader += GetTitle(); 787 long nTextHeight( pPrinter->GetTextHeight() ); 788 pPrinter->DrawText(aOutPos, aHeader); 789 aOutPos.Y() += nTextHeight; 790 aOutPos.Y() += nTextHeight/2; 791 aFont.SetSize(Size(0, 35)); // 10pt 792 nStyles = 1; 793 while(pStyle) 794 { 795 // print template name 796 String aStr(pStyle->GetName()); 797 aFont.SetWeight(WEIGHT_BOLD); 798 pPrinter->SetFont(aFont); 799 nTextHeight = pPrinter->GetTextHeight(); 800 // check for new page 801 if ( aOutPos.Y() + nTextHeight*2 > 802 aPageSize.Height() - (long) nYIndent ) 803 { 804 pAdaptor->EndPage(); 805 pAdaptor->StartPage(); 806 aOutPos.Y() = nYIndent; 807 } 808 pPrinter->DrawText(aOutPos, aStr); 809 aOutPos.Y() += nTextHeight; 810 811 // print template description 812 aFont.SetWeight(WEIGHT_NORMAL); 813 pPrinter->SetFont(aFont); 814 aStr = pStyle->GetDescription(); 815 const char cDelim = ' '; 816 sal_uInt16 nStart = 0, nIdx = 0; 817 818 nTextHeight = pPrinter->GetTextHeight(); 819 // break text into lines 820 while(nIdx < aStr.Len()) 821 { 822 sal_uInt16 nOld = nIdx; 823 long nTextWidth; 824 nIdx = aStr.Search(cDelim, nStart); 825 nTextWidth = pPrinter->GetTextWidth(aStr, nStart, nIdx-nStart); 826 while(nIdx != STRING_NOTFOUND && 827 aOutPos.X() + nTextWidth < 828 aPageSize.Width() - (long) nXIndent) 829 { 830 nOld = nIdx; 831 nIdx = aStr.Search(cDelim, nIdx+1); 832 nTextWidth = pPrinter->GetTextWidth(aStr, nStart, nIdx-nStart); 833 } 834 String aTmp(aStr, nStart, nIdx == STRING_NOTFOUND? 835 STRING_LEN : 836 nOld-nStart); 837 if ( aTmp.Len() ) 838 { 839 nStart = nOld+1; // trailing space 840 } 841 else 842 { 843 sal_uInt16 nChar = 1; 844 while( 845 nStart + nChar < aStr.Len() && 846 aOutPos.X() + pPrinter->GetTextWidth( 847 aStr, nStart, nChar) < 848 aPageSize.Width() - nXIndent) 849 ++nChar; 850 aTmp = String(aStr, nStart, nChar-1); 851 nIdx = nStart + nChar; 852 nStart = nIdx; 853 } 854 if ( aOutPos.Y() + nTextHeight*2 > 855 aPageSize.Height() - nYIndent ) 856 { 857 pAdaptor->EndPage(); 858 pAdaptor->StartPage(); 859 aOutPos.Y() = nYIndent; 860 } 861 pPrinter->DrawText(aOutPos, aTmp); 862 aOutPos.Y() += pPrinter->GetTextHeight(); 863 } 864 pStyle = pIter->Next(); 865 } 866 pAdaptor->EndPage(); 867 868 Printer::PrintJob( pController, rPrt.GetJobSetup() ); 869 870 delete pIter; 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