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