1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sfx2.hxx" 30 31 #include "arrdecl.hxx" 32 #include <map> 33 34 #include <cppuhelper/implbase1.hxx> 35 36 #include <com/sun/star/util/XCloseable.hpp> 37 #include <com/sun/star/frame/XComponentLoader.hpp> 38 #include <com/sun/star/util/XCloseBroadcaster.hpp> 39 #include <com/sun/star/util/XCloseListener.hpp> 40 #include <com/sun/star/util/XModifyBroadcaster.hpp> 41 #include <com/sun/star/beans/XPropertySet.hpp> 42 #include <com/sun/star/frame/XTitle.hpp> 43 #include <vos/mutex.hxx> 44 45 #include <tools/resary.hxx> 46 #include <vcl/msgbox.hxx> 47 #include <vcl/wrkwin.hxx> 48 #include <vcl/svapp.hxx> 49 #include <svl/eitem.hxx> 50 #include <tools/rtti.hxx> 51 #include <svl/lstner.hxx> 52 #include <sfx2/sfxhelp.hxx> 53 #include <basic/sbstar.hxx> 54 #include <svl/stritem.hxx> 55 #include <basic/sbx.hxx> 56 #include <unotools/eventcfg.hxx> 57 58 #include <sfx2/objsh.hxx> 59 #include <sfx2/signaturestate.hxx> 60 #include <sfx2/sfxmodelfactory.hxx> 61 62 #include <basic/sbuno.hxx> 63 #include <svtools/sfxecode.hxx> 64 #include <svtools/ehdl.hxx> 65 #include <unotools/printwarningoptions.hxx> 66 #include <comphelper/processfactory.hxx> 67 68 #include <com/sun/star/document/XStorageBasedDocument.hpp> 69 #include <com/sun/star/script/DocumentDialogLibraryContainer.hpp> 70 #include <com/sun/star/script/DocumentScriptLibraryContainer.hpp> 71 #include <com/sun/star/document/XEmbeddedScripts.hpp> 72 #include <com/sun/star/document/XScriptInvocationContext.hpp> 73 74 #include <svl/urihelper.hxx> 75 #include <unotools/pathoptions.hxx> 76 #include <svl/sharecontrolfile.hxx> 77 #include <unotools/localfilehelper.hxx> 78 #include <unotools/ucbhelper.hxx> 79 #include <svtools/asynclink.hxx> 80 #include <tools/diagnose_ex.h> 81 #include <sot/clsids.hxx> 82 83 #include <sfx2/app.hxx> 84 #include <sfx2/docfac.hxx> 85 #include <sfx2/docfile.hxx> 86 #include <sfx2/event.hxx> 87 #include <sfx2/dispatch.hxx> 88 #include <sfx2/viewsh.hxx> 89 #include <sfx2/viewfrm.hxx> 90 #include "sfx2/sfxresid.hxx" 91 #include "objshimp.hxx" 92 #include "appbas.hxx" 93 #include "sfxtypes.hxx" 94 #include <sfx2/evntconf.hxx> 95 #include <sfx2/request.hxx> 96 #include "doc.hrc" 97 #include "sfxlocal.hrc" 98 #include "appdata.hxx" 99 #include <sfx2/appuno.hxx> 100 #include <sfx2/sfxsids.hrc> 101 #include "sfx2/basmgr.hxx" 102 #include "sfx2/QuerySaveDocument.hxx" 103 #include "helpid.hrc" 104 #include <sfx2/msg.hxx> 105 #include "appbaslib.hxx" 106 #include <sfx2/sfxbasemodel.hxx> 107 108 #include <basic/basicmanagerrepository.hxx> 109 110 using namespace ::com::sun::star; 111 using namespace ::com::sun::star::uno; 112 using namespace ::com::sun::star::script; 113 using namespace ::com::sun::star::frame; 114 using namespace ::com::sun::star::document; 115 116 using ::basic::BasicManagerRepository; 117 #include <uno/mapping.hxx> 118 119 //==================================================================== 120 121 DBG_NAME(SfxObjectShell) 122 123 #define DocumentInfo 124 #include "sfxslots.hxx" 125 126 namespace { 127 128 static WeakReference< XInterface > s_xCurrentComponent; 129 130 // remember all registered components for VBA compatibility, to be able to remove them on disposing the model 131 typedef ::std::map< XInterface*, ::rtl::OString > VBAConstantNameMap; 132 static VBAConstantNameMap s_aRegisteredVBAConstants; 133 134 ::rtl::OString lclGetVBAGlobalConstName( const Reference< XInterface >& rxComponent ) 135 { 136 OSL_ENSURE( rxComponent.is(), "lclGetVBAGlobalConstName - missing component" ); 137 138 VBAConstantNameMap::iterator aIt = s_aRegisteredVBAConstants.find( rxComponent.get() ); 139 if( aIt != s_aRegisteredVBAConstants.end() ) 140 return aIt->second; 141 142 uno::Reference< beans::XPropertySet > xProps( rxComponent, uno::UNO_QUERY ); 143 if( xProps.is() ) try 144 { 145 ::rtl::OUString aConstName; 146 xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAGlobalConstantName" ) ) ) >>= aConstName; 147 return ::rtl::OUStringToOString( aConstName, RTL_TEXTENCODING_ASCII_US ); 148 } 149 catch( uno::Exception& ) // not supported 150 { 151 } 152 return ::rtl::OString(); 153 } 154 155 } // namespace 156 157 //========================================================================= 158 159 160 //========================================================================= 161 162 class SfxModelListener_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XCloseListener > 163 { 164 SfxObjectShell* mpDoc; 165 public: 166 SfxModelListener_Impl( SfxObjectShell* pDoc ) : mpDoc(pDoc) {}; 167 virtual void SAL_CALL queryClosing( const com::sun::star::lang::EventObject& aEvent, sal_Bool bDeliverOwnership ) 168 throw ( com::sun::star::uno::RuntimeException, com::sun::star::util::CloseVetoException) ; 169 virtual void SAL_CALL notifyClosing( const com::sun::star::lang::EventObject& aEvent ) throw ( com::sun::star::uno::RuntimeException ) ; 170 virtual void SAL_CALL disposing( const com::sun::star::lang::EventObject& aEvent ) throw ( com::sun::star::uno::RuntimeException ) ; 171 172 }; 173 174 void SAL_CALL SfxModelListener_Impl::queryClosing( const com::sun::star::lang::EventObject& , sal_Bool ) 175 throw ( com::sun::star::uno::RuntimeException, com::sun::star::util::CloseVetoException) 176 { 177 } 178 179 void SAL_CALL SfxModelListener_Impl::notifyClosing( const com::sun::star::lang::EventObject& ) throw ( com::sun::star::uno::RuntimeException ) 180 { 181 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 182 mpDoc->Broadcast( SfxSimpleHint(SFX_HINT_DEINITIALIZING) ); 183 } 184 185 void SAL_CALL SfxModelListener_Impl::disposing( const com::sun::star::lang::EventObject& _rEvent ) throw ( com::sun::star::uno::RuntimeException ) 186 { 187 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 188 189 // am I ThisComponent in AppBasic? 190 if ( SfxObjectShell::GetCurrentComponent() == _rEvent.Source ) 191 { 192 // remove ThisComponent reference from AppBasic 193 SfxObjectShell::SetCurrentComponent( Reference< XInterface >() ); 194 } 195 196 /* Remove VBA component from AppBasic. As every application registers its 197 own current component, the disposed component may not be the "current 198 component" of the SfxObjectShell. */ 199 if ( _rEvent.Source.is() ) 200 { 201 VBAConstantNameMap::iterator aIt = s_aRegisteredVBAConstants.find( _rEvent.Source.get() ); 202 if ( aIt != s_aRegisteredVBAConstants.end() ) 203 { 204 if ( BasicManager* pAppMgr = SFX_APP()->GetBasicManager() ) 205 pAppMgr->SetGlobalUNOConstant( aIt->second.getStr(), Any( Reference< XInterface >() ) ); 206 s_aRegisteredVBAConstants.erase( aIt ); 207 } 208 } 209 210 if ( !mpDoc->Get_Impl()->bClosing ) 211 // GCC stuerzt ab, wenn schon im dtor, also vorher Flag abfragen 212 mpDoc->DoClose(); 213 } 214 215 TYPEINIT1(SfxObjectShell, SfxShell); 216 217 //-------------------------------------------------------------------- 218 SfxObjectShell_Impl::SfxObjectShell_Impl( SfxObjectShell& _rDocShell ) 219 :mpObjectContainer(0) 220 ,pBasicManager( new SfxBasicManagerHolder ) 221 ,rDocShell( _rDocShell ) 222 ,aMacroMode( *this ) 223 ,pProgress( 0) 224 ,nTime() 225 ,nVisualDocumentNumber( USHRT_MAX) 226 ,nDocumentSignatureState( SIGNATURESTATE_UNKNOWN ) 227 ,nScriptingSignatureState( SIGNATURESTATE_UNKNOWN ) 228 ,bInList( sal_False) 229 ,bClosing( sal_False) 230 ,bIsSaving( sal_False) 231 ,bPasswd( sal_False) 232 ,bIsTmp( sal_False) 233 ,bIsNamedVisible( sal_False) 234 ,bIsTemplate(sal_False) 235 ,bIsAbortingImport ( sal_False) 236 ,bImportDone ( sal_False) 237 ,bInPrepareClose( sal_False ) 238 ,bPreparedForClose( sal_False ) 239 ,bWaitingForPicklist( sal_True ) 240 ,bForbidReload( sal_False ) 241 ,bBasicInitialized( sal_False ) 242 ,bIsPrintJobCancelable( sal_True ) 243 ,bOwnsStorage( sal_True ) 244 ,bNoBaseURL( sal_False ) 245 ,bInitialized( sal_False ) 246 ,bSignatureErrorIsShown( sal_False ) 247 ,bModelInitialized( sal_False ) 248 ,bPreserveVersions( sal_True ) 249 ,m_bMacroSignBroken( sal_False ) 250 ,m_bNoBasicCapabilities( sal_False ) 251 ,m_bDocRecoverySupport( sal_True ) 252 ,bQueryLoadTemplate( sal_True ) 253 ,bLoadReadonly( sal_False ) 254 ,bUseUserData( sal_True ) 255 ,bSaveVersionOnClose( sal_False ) 256 ,m_bSharedXMLFlag( sal_False ) 257 ,m_bAllowShareControlFileClean( sal_True ) 258 ,lErr(ERRCODE_NONE) 259 ,nEventId ( 0) 260 ,pReloadTimer ( 0) 261 ,pMarkData( 0 ) 262 ,nLoadedFlags ( SFX_LOADED_ALL ) 263 ,nFlagsInProgress( 0 ) 264 ,bModalMode( sal_False ) 265 ,bRunningMacro( sal_False ) 266 ,bReloadAvailable( sal_False ) 267 ,nAutoLoadLocks( 0 ) 268 ,pModule( 0 ) 269 ,eFlags( SFXOBJECTSHELL_UNDEFINED ) 270 ,bReadOnlyUI( sal_False ) 271 ,bHiddenLockedByAPI( sal_False ) 272 ,nStyleFilter( 0 ) 273 ,bDisposing( sal_False ) 274 ,m_bEnableSetModified( sal_True ) 275 ,m_bIsModified( sal_False ) 276 ,m_nMapUnit( MAP_100TH_MM ) 277 ,m_bCreateTempStor( sal_False ) 278 ,m_bIsInit( sal_False ) 279 ,m_bIncomplEncrWarnShown( sal_False ) 280 ,m_nModifyPasswordHash( 0 ) 281 ,m_bModifyPasswordEntered( sal_False ) 282 { 283 SfxObjectShell* pDoc = &_rDocShell; 284 SfxObjectShellArr_Impl &rArr = SFX_APP()->GetObjectShells_Impl(); 285 rArr.C40_INSERT( SfxObjectShell, pDoc, rArr.Count() ); 286 bInList = sal_True; 287 } 288 289 //-------------------------------------------------------------------- 290 291 SfxObjectShell_Impl::~SfxObjectShell_Impl() 292 { 293 delete pBasicManager; 294 } 295 296 //-------------------------------------------------------------------- 297 298 SfxObjectShell::SfxObjectShell( const sal_uInt64 i_nCreationFlags ) 299 : pImp( new SfxObjectShell_Impl( *this ) ) 300 , pMedium(0) 301 , pStyleSheetPool(0) 302 , eCreateMode( ( i_nCreationFlags & SFXMODEL_EMBEDDED_OBJECT ) ? SFX_CREATE_MODE_EMBEDDED : SFX_CREATE_MODE_STANDARD ) 303 , bHasName( sal_False ) 304 { 305 DBG_CTOR(SfxObjectShell, 0); 306 307 const bool bScriptSupport = ( i_nCreationFlags & SFXMODEL_DISABLE_EMBEDDED_SCRIPTS ) == 0; 308 if ( !bScriptSupport ) 309 SetHasNoBasic(); 310 311 const bool bDocRecovery = ( i_nCreationFlags & SFXMODEL_DISABLE_DOCUMENT_RECOVERY ) == 0; 312 if ( !bDocRecovery ) 313 pImp->m_bDocRecoverySupport = sal_False; 314 } 315 316 //-------------------------------------------------------------------- 317 318 // initializes a document from a file-description 319 320 SfxObjectShell::SfxObjectShell 321 ( 322 SfxObjectCreateMode eMode /* Zweck, zu dem die SfxObjectShell 323 erzeugt wird: 324 325 SFX_CREATE_MODE_EMBEDDED (default) 326 als SO-Server aus einem anderen 327 Dokument heraus 328 329 SFX_CREATE_MODE_STANDARD, 330 als normales, selbst"aendig ge"offnetes 331 Dokument 332 333 SFX_CREATE_MODE_PREVIEW 334 um ein Preview durchzuf"uhren, 335 ggf. werden weniger Daten ben"otigt 336 337 SFX_CREATE_MODE_ORGANIZER 338 um im Organizer dargestellt zu 339 werden, hier werden keine Inhalte 340 ben"otigt */ 341 ) 342 343 /* [Beschreibung] 344 345 Konstruktor der Klasse SfxObjectShell. 346 */ 347 348 : pImp( new SfxObjectShell_Impl( *this ) ), 349 pMedium(0), 350 pStyleSheetPool(0), 351 eCreateMode(eMode), 352 bHasName( sal_False ) 353 { 354 DBG_CTOR(SfxObjectShell, 0); 355 } 356 357 //-------------------------------------------------------------------- 358 359 // virtual dtor of typical base-class SfxObjectShell 360 361 SfxObjectShell::~SfxObjectShell() 362 { 363 DBG_DTOR(SfxObjectShell, 0); 364 365 if ( IsEnableSetModified() ) 366 EnableSetModified( sal_False ); 367 368 // Niemals GetInPlaceObject() aufrufen, der Zugriff auf den 369 // Ableitungszweig SfxInternObject ist wegen eines Compiler Bugs nicht 370 // erlaubt 371 SfxObjectShell::Close(); 372 pImp->pBaseModel.set( NULL ); 373 374 DELETEX(pImp->pReloadTimer ); 375 376 SfxApplication *pSfxApp = SFX_APP(); 377 if ( USHRT_MAX != pImp->nVisualDocumentNumber ) 378 pSfxApp->ReleaseIndex(pImp->nVisualDocumentNumber); 379 380 // Basic-Manager zerst"oren 381 pImp->pBasicManager->reset( NULL ); 382 383 if ( pSfxApp->GetDdeService() ) 384 pSfxApp->RemoveDdeTopic( this ); 385 386 pImp->pBaseModel.set( NULL ); 387 388 // don't call GetStorage() here, in case of Load Failure it's possible that a storage was never assigned! 389 if ( pMedium && pMedium->HasStorage_Impl() && pMedium->GetStorage( sal_False ) == pImp->m_xDocStorage ) 390 pMedium->CanDisposeStorage_Impl( sal_False ); 391 392 if ( pImp->mpObjectContainer ) 393 { 394 pImp->mpObjectContainer->CloseEmbeddedObjects(); 395 delete pImp->mpObjectContainer; 396 } 397 398 if ( pImp->bOwnsStorage && pImp->m_xDocStorage.is() ) 399 pImp->m_xDocStorage->dispose(); 400 401 if ( pMedium ) 402 { 403 pMedium->CloseAndReleaseStreams_Impl(); 404 405 if ( IsDocShared() ) 406 FreeSharedFile(); 407 408 DELETEX( pMedium ); 409 } 410 411 // The removing of the temporary file must be done as the latest step in the document destruction 412 if ( pImp->aTempName.Len() ) 413 { 414 String aTmp; 415 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( pImp->aTempName, aTmp ); 416 ::utl::UCBContentHelper::Kill( aTmp ); 417 } 418 419 delete pImp; 420 } 421 422 //-------------------------------------------------------------------- 423 424 void SfxObjectShell::Stamp_SetPrintCancelState(sal_Bool bState) 425 { 426 pImp->bIsPrintJobCancelable = bState; 427 } 428 429 //-------------------------------------------------------------------- 430 431 sal_Bool SfxObjectShell::Stamp_GetPrintCancelState() const 432 { 433 return pImp->bIsPrintJobCancelable; 434 } 435 436 //-------------------------------------------------------------------- 437 438 void SfxObjectShell::ViewAssigned() 439 440 /* [Beschreibung] 441 442 Diese Methode wird gerufen, wenn eine View zugewiesen wird. 443 */ 444 445 { 446 } 447 448 //-------------------------------------------------------------------- 449 // closes the Object and all its views 450 451 sal_Bool SfxObjectShell::Close() 452 { 453 {DBG_CHKTHIS(SfxObjectShell, 0);} 454 SfxObjectShellRef aRef(this); 455 if ( !pImp->bClosing ) 456 { 457 // falls noch ein Progress l"auft, nicht schlie\sen 458 if ( !pImp->bDisposing && GetProgress() ) 459 return sal_False; 460 461 pImp->bClosing = sal_True; 462 Reference< util::XCloseable > xCloseable( GetBaseModel(), UNO_QUERY ); 463 464 if ( xCloseable.is() ) 465 { 466 try 467 { 468 xCloseable->close( sal_True ); 469 } 470 catch( Exception& ) 471 { 472 pImp->bClosing = sal_False; 473 } 474 } 475 476 if ( pImp->bClosing ) 477 { 478 // aus Document-Liste austragen 479 SfxApplication *pSfxApp = SFX_APP(); 480 SfxObjectShellArr_Impl &rDocs = pSfxApp->GetObjectShells_Impl(); 481 const SfxObjectShell *pThis = this; 482 sal_uInt16 nPos = rDocs.GetPos(pThis); 483 if ( nPos < rDocs.Count() ) 484 rDocs.Remove( nPos ); 485 pImp->bInList = sal_False; 486 } 487 } 488 489 return sal_True; 490 } 491 492 //-------------------------------------------------------------------- 493 494 // returns a pointer the first SfxDocument of specified type 495 496 SfxObjectShell* SfxObjectShell::GetFirst 497 ( 498 const TypeId* pType , 499 sal_Bool bOnlyVisible 500 ) 501 { 502 SfxObjectShellArr_Impl &rDocs = SFX_APP()->GetObjectShells_Impl(); 503 504 // seach for a SfxDocument of the specified type 505 for ( sal_uInt16 nPos = 0; nPos < rDocs.Count(); ++nPos ) 506 { 507 SfxObjectShell* pSh = rDocs.GetObject( nPos ); 508 if ( bOnlyVisible && pSh->IsPreview() && pSh->IsReadOnly() ) 509 continue; 510 511 if ( ( !pType || pSh->IsA(*pType) ) && 512 ( !bOnlyVisible || SfxViewFrame::GetFirst( pSh, sal_True ))) 513 return pSh; 514 } 515 516 return 0; 517 } 518 //-------------------------------------------------------------------- 519 520 // returns a pointer to the next SfxDocument of specified type behind *pDoc 521 522 SfxObjectShell* SfxObjectShell::GetNext 523 ( 524 const SfxObjectShell& rPrev, 525 const TypeId* pType, 526 sal_Bool bOnlyVisible 527 ) 528 { 529 SfxObjectShellArr_Impl &rDocs = SFX_APP()->GetObjectShells_Impl(); 530 531 // refind the specified predecessor 532 sal_uInt16 nPos; 533 for ( nPos = 0; nPos < rDocs.Count(); ++nPos ) 534 if ( rDocs.GetObject(nPos) == &rPrev ) 535 break; 536 537 // search for the next SfxDocument of the specified type 538 for ( ++nPos; nPos < rDocs.Count(); ++nPos ) 539 { 540 SfxObjectShell* pSh = rDocs.GetObject( nPos ); 541 if ( bOnlyVisible && pSh->IsPreview() && pSh->IsReadOnly() ) 542 continue; 543 544 if ( ( !pType || pSh->IsA(*pType) ) && 545 ( !bOnlyVisible || SfxViewFrame::GetFirst( pSh, sal_True ))) 546 return pSh; 547 } 548 return 0; 549 } 550 551 //-------------------------------------------------------------------- 552 553 SfxObjectShell* SfxObjectShell::Current() 554 { 555 SfxViewFrame *pFrame = SfxViewFrame::Current(); 556 return pFrame ? pFrame->GetObjectShell() : 0; 557 } 558 559 //------------------------------------------------------------------------- 560 561 sal_Bool SfxObjectShell::IsInPrepareClose() const 562 { 563 return pImp->bInPrepareClose; 564 } 565 566 //------------------------------------------------------------------------ 567 568 struct BoolEnv_Impl 569 { 570 SfxObjectShell_Impl* pImp; 571 BoolEnv_Impl( SfxObjectShell_Impl* pImpP) : pImp( pImpP ) 572 { pImpP->bInPrepareClose = sal_True; } 573 ~BoolEnv_Impl() { pImp->bInPrepareClose = sal_False; } 574 }; 575 576 577 sal_uInt16 SfxObjectShell::PrepareClose 578 ( 579 sal_Bool bUI, // sal_True: Dialoge etc. erlaubt, sal_False: silent-mode 580 sal_Bool bForBrowsing 581 ) 582 { 583 if( pImp->bInPrepareClose || pImp->bPreparedForClose ) 584 return sal_True; 585 BoolEnv_Impl aBoolEnv( pImp ); 586 587 // DocModalDialog? 588 if ( IsInModalMode() ) 589 return sal_False; 590 591 SfxViewFrame* pFirst = SfxViewFrame::GetFirst( this ); 592 if( pFirst && !pFirst->GetFrame().PrepareClose_Impl( bUI, bForBrowsing ) ) 593 return sal_False; 594 595 // prepare views for closing 596 for ( SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this ); 597 pFrm; pFrm = SfxViewFrame::GetNext( *pFrm, this ) ) 598 { 599 DBG_ASSERT(pFrm->GetViewShell(),"KeineShell"); 600 if ( pFrm->GetViewShell() ) 601 { 602 sal_uInt16 nRet = pFrm->GetViewShell()->PrepareClose( bUI, bForBrowsing ); 603 if ( nRet != sal_True ) 604 return nRet; 605 } 606 } 607 608 SfxApplication *pSfxApp = SFX_APP(); 609 pSfxApp->NotifyEvent( SfxEventHint(SFX_EVENT_PREPARECLOSEDOC, GlobalEventConfig::GetEventName(STR_EVENT_PREPARECLOSEDOC), this) ); 610 611 if( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ) 612 { 613 pImp->bPreparedForClose = sal_True; 614 return sal_True; 615 } 616 617 // ggf. nachfragen, ob gespeichert werden soll 618 // nur fuer in sichtbaren Fenstern dargestellte Dokumente fragen 619 SfxViewFrame *pFrame = SfxObjectShell::Current() == this 620 ? SfxViewFrame::Current() : SfxViewFrame::GetFirst( this ); 621 622 sal_Bool bClose = sal_False; 623 if ( bUI && IsModified() && pFrame ) 624 { 625 // minimierte restoren 626 SfxFrame& rTop = pFrame->GetTopFrame(); 627 SfxViewFrame::SetViewFrame( rTop.GetCurrentViewFrame() ); 628 pFrame->GetFrame().Appear(); 629 630 // fragen, ob gespeichert werden soll 631 short nRet = RET_YES; 632 //TODO/CLEANUP 633 //brauchen wir UI=2 noch? 634 //if( SfxApplication::IsPlugin() == sal_False || bUI == 2 ) 635 { 636 //initiate help agent to inform about "print modifies the document" 637 SvtPrintWarningOptions aPrintOptions; 638 if (aPrintOptions.IsModifyDocumentOnPrintingAllowed() && 639 HasName() && getDocProperties()->getPrintDate().Month > 0) 640 { 641 SfxHelp::OpenHelpAgent( &pFirst->GetFrame(), HID_CLOSE_WARNING ); 642 } 643 const Reference< XTitle > xTitle( *pImp->pBaseModel.get(), UNO_QUERY_THROW ); 644 const ::rtl::OUString sTitle = xTitle->getTitle (); 645 nRet = ExecuteQuerySaveDocument(&pFrame->GetWindow(),sTitle); 646 } 647 /*HACK for plugin::destroy()*/ 648 649 if ( RET_YES == nRet ) 650 { 651 // per Dispatcher speichern 652 const SfxPoolItem *pPoolItem; 653 if ( IsSaveVersionOnClose() ) 654 { 655 SfxStringItem aItem( SID_DOCINFO_COMMENTS, String( SfxResId( STR_AUTOMATICVERSION ) ) ); 656 SfxBoolItem aWarnItem( SID_FAIL_ON_WARNING, bUI ); 657 const SfxPoolItem* ppArgs[] = { &aItem, &aWarnItem, 0 }; 658 pPoolItem = pFrame->GetBindings().ExecuteSynchron( SID_SAVEDOC, ppArgs ); 659 } 660 else 661 { 662 SfxBoolItem aWarnItem( SID_FAIL_ON_WARNING, bUI ); 663 const SfxPoolItem* ppArgs[] = { &aWarnItem, 0 }; 664 pPoolItem = pFrame->GetBindings().ExecuteSynchron( SID_SAVEDOC, ppArgs ); 665 } 666 667 if ( !pPoolItem || pPoolItem->ISA(SfxVoidItem) || ( pPoolItem->ISA(SfxBoolItem) && !( (const SfxBoolItem*) pPoolItem )->GetValue() ) ) 668 return sal_False; 669 else 670 bClose = sal_True; 671 } 672 else if ( RET_CANCEL == nRet ) 673 // abgebrochen 674 return sal_False; 675 else if ( RET_NEWTASK == nRet ) 676 { 677 return RET_NEWTASK; 678 } 679 else 680 { 681 // Bei Nein nicht noch Informationlost 682 bClose = sal_True; 683 } 684 } 685 686 pImp->bPreparedForClose = sal_True; 687 return sal_True; 688 } 689 690 //-------------------------------------------------------------------- 691 namespace 692 { 693 static BasicManager* lcl_getBasicManagerForDocument( const SfxObjectShell& _rDocument ) 694 { 695 if ( !_rDocument.Get_Impl()->m_bNoBasicCapabilities ) 696 { 697 if ( !_rDocument.Get_Impl()->bBasicInitialized ) 698 const_cast< SfxObjectShell& >( _rDocument ).InitBasicManager_Impl(); 699 return _rDocument.Get_Impl()->pBasicManager->get(); 700 } 701 702 // assume we do not have Basic ourself, but we can refer to another 703 // document which does (by our model's XScriptInvocationContext::getScriptContainer). 704 // In this case, we return the BasicManager of this other document. 705 706 OSL_ENSURE( !Reference< XEmbeddedScripts >( _rDocument.GetModel(), UNO_QUERY ).is(), 707 "lcl_getBasicManagerForDocument: inconsistency: no Basic, but an XEmbeddedScripts?" ); 708 Reference< XModel > xForeignDocument; 709 Reference< XScriptInvocationContext > xContext( _rDocument.GetModel(), UNO_QUERY ); 710 if ( xContext.is() ) 711 { 712 xForeignDocument.set( xContext->getScriptContainer(), UNO_QUERY ); 713 OSL_ENSURE( xForeignDocument.is() && xForeignDocument != _rDocument.GetModel(), 714 "lcl_getBasicManagerForDocument: no Basic, but providing ourself as script container?" ); 715 } 716 717 BasicManager* pBasMgr = NULL; 718 if ( xForeignDocument.is() ) 719 pBasMgr = ::basic::BasicManagerRepository::getDocumentBasicManager( xForeignDocument ); 720 721 return pBasMgr; 722 } 723 } 724 725 //-------------------------------------------------------------------- 726 727 BasicManager* SfxObjectShell::GetBasicManager() const 728 { 729 BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this ); 730 if ( !pBasMgr ) 731 pBasMgr = SFX_APP()->GetBasicManager(); 732 return pBasMgr; 733 } 734 735 //-------------------------------------------------------------------- 736 737 void SfxObjectShell::SetHasNoBasic() 738 { 739 pImp->m_bNoBasicCapabilities = sal_True; 740 } 741 742 //-------------------------------------------------------------------- 743 744 sal_Bool SfxObjectShell::HasBasic() const 745 { 746 if ( pImp->m_bNoBasicCapabilities ) 747 return sal_False; 748 749 if ( !pImp->bBasicInitialized ) 750 const_cast< SfxObjectShell* >( this )->InitBasicManager_Impl(); 751 752 return pImp->pBasicManager->isValid(); 753 } 754 755 //-------------------------------------------------------------------- 756 namespace 757 { 758 const Reference< XLibraryContainer >& 759 lcl_getOrCreateLibraryContainer( bool _bScript, Reference< XLibraryContainer >& _rxContainer, 760 const Reference< XModel >& _rxDocument ) 761 { 762 if ( !_rxContainer.is() ) 763 { 764 try 765 { 766 Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, UNO_QUERY ); 767 const Reference< XComponentContext > xContext( 768 ::comphelper::getProcessComponentContext() ); 769 _rxContainer.set ( _bScript 770 ? DocumentScriptLibraryContainer::create( 771 xContext, xStorageDoc ) 772 : DocumentDialogLibraryContainer::create( 773 xContext, xStorageDoc ) 774 , UNO_QUERY_THROW ); 775 } 776 catch( const Exception& ) 777 { 778 DBG_UNHANDLED_EXCEPTION(); 779 } 780 } 781 return _rxContainer; 782 } 783 } 784 785 //-------------------------------------------------------------------- 786 787 Reference< XLibraryContainer > SfxObjectShell::GetDialogContainer() 788 { 789 if ( !pImp->m_bNoBasicCapabilities ) 790 return lcl_getOrCreateLibraryContainer( false, pImp->xDialogLibraries, GetModel() ); 791 792 BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this ); 793 if ( pBasMgr ) 794 return pBasMgr->GetDialogLibraryContainer().get(); 795 796 OSL_ENSURE( false, "SfxObjectShell::GetDialogContainer: falling back to the application - is this really expected here?" ); 797 return SFX_APP()->GetDialogContainer(); 798 } 799 800 //-------------------------------------------------------------------- 801 802 Reference< XLibraryContainer > SfxObjectShell::GetBasicContainer() 803 { 804 if ( !pImp->m_bNoBasicCapabilities ) 805 return lcl_getOrCreateLibraryContainer( true, pImp->xBasicLibraries, GetModel() ); 806 807 BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this ); 808 if ( pBasMgr ) 809 return pBasMgr->GetScriptLibraryContainer().get(); 810 811 OSL_ENSURE( false, "SfxObjectShell::GetBasicContainer: falling back to the application - is this really expected here?" ); 812 return SFX_APP()->GetBasicContainer(); 813 } 814 815 //-------------------------------------------------------------------- 816 817 StarBASIC* SfxObjectShell::GetBasic() const 818 { 819 return GetBasicManager()->GetLib(0); 820 } 821 822 //-------------------------------------------------------------------- 823 824 void SfxObjectShell::InitBasicManager_Impl() 825 /* [Beschreibung] 826 827 creates a document's BasicManager and loads it, if we are already based on 828 a storage. 829 830 [Anmerkung] 831 832 Diese Methode mu"s aus den "Uberladungen von <SvPersist::Load()> (mit 833 dem pStor aus dem Parameter von Load()) sowie aus der "Uberladung 834 von <SvPersist::InitNew()> (mit pStor = 0) gerufen werden. 835 */ 836 837 { 838 /* #163556# (DR) - Handling of recursive calls while creating the Bacic 839 manager. 840 841 It is possible that (while creating the Basic manager) the code that 842 imports the Basic storage wants to access the Basic manager again. 843 Especially in VBA compatibility mode, there is code that wants to 844 access the "VBA Globals" object which is stored as global UNO constant 845 in the Basic manager. 846 847 To achieve correct handling of the recursive calls of this function 848 from lcl_getBasicManagerForDocument(), the implementation of the 849 function BasicManagerRepository::getDocumentBasicManager() has been 850 changed to return the Basic manager currently under construction, when 851 called repeatedly. 852 853 The variable pImp->bBasicInitialized will be set to sal_True after 854 construction now, to ensure that the recursive call of the function 855 lcl_getBasicManagerForDocument() will be routed into this function too. 856 857 Calling BasicManagerHolder::reset() twice is not a big problem, as it 858 does not take ownership but stores only the raw pointer. Owner of all 859 Basic managers is the global BasicManagerRepository instance. 860 */ 861 DBG_ASSERT( !pImp->bBasicInitialized && !pImp->pBasicManager->isValid(), "Lokaler BasicManager bereits vorhanden"); 862 pImp->pBasicManager->reset( BasicManagerRepository::getDocumentBasicManager( GetModel() ) ); 863 DBG_ASSERT( pImp->pBasicManager->isValid(), "SfxObjectShell::InitBasicManager_Impl: did not get a BasicManager!" ); 864 pImp->bBasicInitialized = sal_True; 865 } 866 867 //-------------------------------------------------------------------- 868 869 sal_uInt16 SfxObjectShell::Count() 870 { 871 return SFX_APP()->GetObjectShells_Impl().Count(); 872 } 873 874 //-------------------------------------------------------------------- 875 876 sal_Bool SfxObjectShell::DoClose() 877 { 878 return Close(); 879 } 880 881 //-------------------------------------------------------------------- 882 883 SfxObjectShell* SfxObjectShell::GetObjectShell() 884 { 885 return this; 886 } 887 888 //-------------------------------------------------------------------- 889 890 uno::Sequence< ::rtl::OUString > SfxObjectShell::GetEventNames() 891 { 892 static uno::Sequence< ::rtl::OUString >* pEventNameContainer = NULL; 893 894 if ( !pEventNameContainer ) 895 { 896 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 897 if ( !pEventNameContainer ) 898 { 899 static uno::Sequence< ::rtl::OUString > aEventNameContainer = GlobalEventConfig().getElementNames(); 900 pEventNameContainer = &aEventNameContainer; 901 } 902 } 903 904 return *pEventNameContainer; 905 } 906 907 //-------------------------------------------------------------------- 908 909 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > SfxObjectShell::GetModel() const 910 { 911 return GetBaseModel(); 912 } 913 914 void SfxObjectShell::SetBaseModel( SfxBaseModel* pModel ) 915 { 916 OSL_ENSURE( !pImp->pBaseModel.is() || pModel == NULL, "Model already set!" ); 917 pImp->pBaseModel.set( pModel ); 918 if ( pImp->pBaseModel.is() ) 919 { 920 pImp->pBaseModel->addCloseListener( new SfxModelListener_Impl(this) ); 921 } 922 } 923 924 //-------------------------------------------------------------------- 925 926 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > SfxObjectShell::GetBaseModel() const 927 { 928 return pImp->pBaseModel.get(); 929 } 930 /* -----------------------------10.09.2001 15:56------------------------------ 931 932 ---------------------------------------------------------------------------*/ 933 void SfxObjectShell::SetAutoStyleFilterIndex(sal_uInt16 nSet) 934 { 935 pImp->nStyleFilter = nSet; 936 } 937 938 sal_uInt16 SfxObjectShell::GetAutoStyleFilterIndex() 939 { 940 return pImp->nStyleFilter; 941 } 942 943 944 void SfxObjectShell::SetCurrentComponent( const Reference< XInterface >& _rxComponent ) 945 { 946 Reference< XInterface > xOldCurrentComp(s_xCurrentComponent); 947 if ( _rxComponent == xOldCurrentComp ) 948 // nothing to do 949 return; 950 // note that "_rxComponent.get() == s_xCurrentComponent.get().get()" is /sufficient/, but not 951 // /required/ for "_rxComponent == s_xCurrentComponent.get()". 952 // In other words, it's still possible that we here do something which is not necessary, 953 // but we should have filtered quite some unnecessary calls already. 954 955 BasicManager* pAppMgr = SFX_APP()->GetBasicManager(); 956 s_xCurrentComponent = _rxComponent; 957 if ( pAppMgr ) 958 { 959 // set "ThisComponent" for Basic 960 pAppMgr->SetGlobalUNOConstant( "ThisComponent", Any( _rxComponent ) ); 961 962 // set new current component for VBA compatibility 963 if ( _rxComponent.is() ) 964 { 965 ::rtl::OString aVBAConstName = lclGetVBAGlobalConstName( _rxComponent ); 966 if ( aVBAConstName.getLength() > 0 ) 967 { 968 pAppMgr->SetGlobalUNOConstant( aVBAConstName.getStr(), Any( _rxComponent ) ); 969 s_aRegisteredVBAConstants[ _rxComponent.get() ] = aVBAConstName; 970 } 971 } 972 // no new component passed -> remove last registered VBA component 973 else if ( xOldCurrentComp.is() ) 974 { 975 ::rtl::OString aVBAConstName = lclGetVBAGlobalConstName( xOldCurrentComp ); 976 if ( aVBAConstName.getLength() > 0 ) 977 { 978 pAppMgr->SetGlobalUNOConstant( aVBAConstName.getStr(), Any( Reference< XInterface >() ) ); 979 s_aRegisteredVBAConstants.erase( xOldCurrentComp.get() ); 980 } 981 } 982 } 983 } 984 985 Reference< XInterface > SfxObjectShell::GetCurrentComponent() 986 { 987 return s_xCurrentComponent; 988 } 989 990 991 String SfxObjectShell::GetServiceNameFromFactory( const String& rFact ) 992 { 993 //! Remove everything behind name! 994 String aFact( rFact ); 995 String aPrefix = String::CreateFromAscii( "private:factory/" ); 996 if ( aPrefix.Len() == aFact.Match( aPrefix ) ) 997 aFact.Erase( 0, aPrefix.Len() ); 998 sal_uInt16 nPos = aFact.Search( '?' ); 999 String aParam; 1000 if ( nPos != STRING_NOTFOUND ) 1001 { 1002 aParam = aFact.Copy( nPos, aFact.Len() ); 1003 aFact.Erase( nPos, aFact.Len() ); 1004 aParam.Erase(0,1); 1005 } 1006 aFact.EraseAllChars('4').ToLowerAscii(); 1007 1008 // HACK: sometimes a real document service name is given here instead of 1009 // a factory short name. Set return value directly to this service name as fallback 1010 // in case next lines of code does nothing ... 1011 // use rFact instead of normed aFact value ! 1012 ::rtl::OUString aServiceName = rFact; 1013 1014 if ( aFact.EqualsAscii("swriter") ) 1015 { 1016 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.text.TextDocument"); 1017 } 1018 else if ( aFact.EqualsAscii("sweb") || aFact.EqualsAscii("swriter/web") ) 1019 { 1020 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.text.WebDocument"); 1021 } 1022 else if ( aFact.EqualsAscii("sglobal") || aFact.EqualsAscii("swriter/globaldocument") ) 1023 { 1024 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.text.GlobalDocument"); 1025 } 1026 else if ( aFact.EqualsAscii("scalc") ) 1027 { 1028 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.sheet.SpreadsheetDocument"); 1029 } 1030 else if ( aFact.EqualsAscii("sdraw") ) 1031 { 1032 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.drawing.DrawingDocument"); 1033 } 1034 else if ( aFact.EqualsAscii("simpress") ) 1035 { 1036 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.presentation.PresentationDocument"); 1037 } 1038 else if ( aFact.EqualsAscii("schart") ) 1039 { 1040 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.chart.ChartDocument"); 1041 } 1042 else if ( aFact.EqualsAscii("smath") ) 1043 { 1044 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.formula.FormulaProperties"); 1045 } 1046 else if ( aFact.EqualsAscii("sbasic") ) 1047 { 1048 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.script.BasicIDE"); 1049 } 1050 else if ( aFact.EqualsAscii("sdatabase") ) 1051 { 1052 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.sdb.OfficeDatabaseDocument"); 1053 } 1054 1055 return aServiceName; 1056 } 1057 1058 SfxObjectShell* SfxObjectShell::CreateObjectByFactoryName( const String& rFact, SfxObjectCreateMode eMode ) 1059 { 1060 return CreateObject( GetServiceNameFromFactory( rFact ), eMode ); 1061 } 1062 1063 1064 SfxObjectShell* SfxObjectShell::CreateObject( const String& rServiceName, SfxObjectCreateMode eCreateMode ) 1065 { 1066 if ( rServiceName.Len() ) 1067 { 1068 ::com::sun::star::uno::Reference < ::com::sun::star::frame::XModel > xDoc( 1069 ::comphelper::getProcessServiceFactory()->createInstance( rServiceName ), UNO_QUERY ); 1070 if ( xDoc.is() ) 1071 { 1072 ::com::sun::star::uno::Reference < ::com::sun::star::lang::XUnoTunnel > xObj( xDoc, UNO_QUERY ); 1073 ::com::sun::star::uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() ); 1074 sal_Int64 nHandle = xObj->getSomething( aSeq ); 1075 if ( nHandle ) 1076 { 1077 SfxObjectShell* pRet = reinterpret_cast< SfxObjectShell* >( sal::static_int_cast< sal_IntPtr >( nHandle )); 1078 pRet->SetCreateMode_Impl( eCreateMode ); 1079 return pRet; 1080 } 1081 } 1082 } 1083 1084 return 0; 1085 } 1086 1087 SfxObjectShell* SfxObjectShell::CreateAndLoadObject( const SfxItemSet& rSet, SfxFrame* pFrame ) 1088 { 1089 uno::Sequence < beans::PropertyValue > aProps; 1090 TransformItems( SID_OPENDOC, rSet, aProps ); 1091 SFX_ITEMSET_ARG(&rSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False); 1092 SFX_ITEMSET_ARG(&rSet, pTargetItem, SfxStringItem, SID_TARGETNAME, sal_False); 1093 ::rtl::OUString aURL; 1094 ::rtl::OUString aTarget = rtl::OUString::createFromAscii("_blank"); 1095 if ( pFileNameItem ) 1096 aURL = pFileNameItem->GetValue(); 1097 if ( pTargetItem ) 1098 aTarget = pTargetItem->GetValue(); 1099 1100 uno::Reference < frame::XComponentLoader > xLoader; 1101 if ( pFrame ) 1102 { 1103 xLoader = uno::Reference < frame::XComponentLoader >( pFrame->GetFrameInterface(), uno::UNO_QUERY ); 1104 } 1105 else 1106 xLoader = uno::Reference < frame::XComponentLoader >( comphelper::getProcessServiceFactory()->createInstance( 1107 ::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop") ), uno::UNO_QUERY ); 1108 1109 uno::Reference < lang::XUnoTunnel > xObj; 1110 try 1111 { 1112 xObj = uno::Reference< lang::XUnoTunnel >( xLoader->loadComponentFromURL( aURL, aTarget, 0, aProps ), uno::UNO_QUERY ); 1113 } 1114 catch( uno::Exception& ) 1115 {} 1116 1117 if ( xObj.is() ) 1118 { 1119 ::com::sun::star::uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() ); 1120 sal_Int64 nHandle = xObj->getSomething( aSeq ); 1121 if ( nHandle ) 1122 return reinterpret_cast< SfxObjectShell* >(sal::static_int_cast< sal_IntPtr >( nHandle )); 1123 } 1124 1125 return NULL; 1126 } 1127 1128 void SfxObjectShell::SetInitialized_Impl( const bool i_fromInitNew ) 1129 { 1130 pImp->bInitialized = sal_True; 1131 if ( i_fromInitNew ) 1132 { 1133 SetActivateEvent_Impl( SFX_EVENT_CREATEDOC ); 1134 SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_DOCCREATED, GlobalEventConfig::GetEventName(STR_EVENT_DOCCREATED), this ) ); 1135 } 1136 else 1137 { 1138 SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_LOADFINISHED, GlobalEventConfig::GetEventName(STR_EVENT_LOADFINISHED), this ) ); 1139 } 1140 } 1141 1142 1143 bool SfxObjectShell::IsChangeRecording() const 1144 { 1145 // currently this function needs to be overwritten by Writer and Calc only 1146 DBG_ASSERT( 0, "function not implemented" ); 1147 return false; 1148 } 1149 1150 1151 bool SfxObjectShell::HasChangeRecordProtection() const 1152 { 1153 // currently this function needs to be overwritten by Writer and Calc only 1154 DBG_ASSERT( 0, "function not implemented" ); 1155 return false; 1156 } 1157 1158 1159 void SfxObjectShell::SetChangeRecording( bool /*bActivate*/ ) 1160 { 1161 // currently this function needs to be overwritten by Writer and Calc only 1162 DBG_ASSERT( 0, "function not implemented" ); 1163 } 1164 1165 1166 bool SfxObjectShell::SetProtectionPassword( const String & /*rPassword*/ ) 1167 { 1168 // currently this function needs to be overwritten by Writer and Calc only 1169 DBG_ASSERT( 0, "function not implemented" ); 1170 return false; 1171 } 1172 1173 1174 bool SfxObjectShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence< sal_Int8 > & /*rPasswordHash*/ ) 1175 { 1176 // currently this function needs to be overwritten by Writer and Calc only 1177 DBG_ASSERT( 0, "function not implemented" ); 1178 return false; 1179 } 1180 1181