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 // check flag before entering dtor in order to avoid crash of GCC 209 mpDoc->DoClose(); 210 } 211 212 TYPEINIT1(SfxObjectShell, SfxShell); 213 214 //-------------------------------------------------------------------- 215 SfxObjectShell_Impl::SfxObjectShell_Impl( SfxObjectShell& _rDocShell ) 216 :mpObjectContainer(0) 217 ,pBasicManager( new SfxBasicManagerHolder ) 218 ,rDocShell( _rDocShell ) 219 ,aMacroMode( *this ) 220 ,pProgress( 0) 221 ,nTime() 222 ,nVisualDocumentNumber( USHRT_MAX) 223 ,nDocumentSignatureState( SIGNATURESTATE_UNKNOWN ) 224 ,nScriptingSignatureState( SIGNATURESTATE_UNKNOWN ) 225 ,bInList( sal_False) 226 ,bClosing( sal_False) 227 ,bIsSaving( sal_False) 228 ,bPasswd( sal_False) 229 ,bIsTmp( sal_False) 230 ,bIsNamedVisible( sal_False) 231 ,bIsTemplate(sal_False) 232 ,bIsAbortingImport ( sal_False) 233 ,bImportDone ( sal_False) 234 ,bInPrepareClose( sal_False ) 235 ,bPreparedForClose( sal_False ) 236 ,bWaitingForPicklist( sal_True ) 237 ,bForbidReload( sal_False ) 238 ,bBasicInitialized( sal_False ) 239 ,bIsPrintJobCancelable( sal_True ) 240 ,bOwnsStorage( sal_True ) 241 ,bNoBaseURL( sal_False ) 242 ,bInitialized( sal_False ) 243 ,bSignatureErrorIsShown( sal_False ) 244 ,bModelInitialized( sal_False ) 245 ,bPreserveVersions( sal_True ) 246 ,m_bMacroSignBroken( sal_False ) 247 ,m_bNoBasicCapabilities( sal_False ) 248 ,m_bDocRecoverySupport( sal_True ) 249 ,bQueryLoadTemplate( sal_True ) 250 ,bLoadReadonly( sal_False ) 251 ,bUseUserData( sal_True ) 252 ,bSaveVersionOnClose( sal_False ) 253 ,m_bSharedXMLFlag( sal_False ) 254 ,m_bAllowShareControlFileClean( sal_True ) 255 ,lErr(ERRCODE_NONE) 256 ,nEventId ( 0) 257 ,pReloadTimer ( 0) 258 ,pMarkData( 0 ) 259 ,nLoadedFlags ( SFX_LOADED_ALL ) 260 ,nFlagsInProgress( 0 ) 261 ,bModalMode( sal_False ) 262 ,bRunningMacro( sal_False ) 263 ,bReloadAvailable( sal_False ) 264 ,nAutoLoadLocks( 0 ) 265 ,pModule( 0 ) 266 ,eFlags( SFXOBJECTSHELL_UNDEFINED ) 267 ,bReadOnlyUI( sal_False ) 268 ,bHiddenLockedByAPI( sal_False ) 269 ,nStyleFilter( 0 ) 270 ,bDisposing( sal_False ) 271 ,m_bEnableSetModified( sal_True ) 272 ,m_bIsModified( sal_False ) 273 ,m_nMapUnit( MAP_100TH_MM ) 274 ,m_bCreateTempStor( sal_False ) 275 ,m_bIsInit( sal_False ) 276 ,m_bIncomplEncrWarnShown( sal_False ) 277 ,m_nModifyPasswordHash( 0 ) 278 ,m_bModifyPasswordEntered( sal_False ) 279 { 280 SfxObjectShell* pDoc = &_rDocShell; 281 SfxObjectShellArr_Impl &rArr = SFX_APP()->GetObjectShells_Impl(); 282 rArr.C40_INSERT( SfxObjectShell, pDoc, rArr.Count() ); 283 bInList = sal_True; 284 } 285 286 //-------------------------------------------------------------------- 287 288 SfxObjectShell_Impl::~SfxObjectShell_Impl() 289 { 290 delete pBasicManager; 291 } 292 293 //-------------------------------------------------------------------- 294 295 SfxObjectShell::SfxObjectShell( const sal_uInt64 i_nCreationFlags ) 296 : pImp( new SfxObjectShell_Impl( *this ) ) 297 , pMedium(0) 298 , pStyleSheetPool(0) 299 , eCreateMode( ( i_nCreationFlags & SFXMODEL_EMBEDDED_OBJECT ) ? SFX_CREATE_MODE_EMBEDDED : SFX_CREATE_MODE_STANDARD ) 300 , bHasName( sal_False ) 301 { 302 DBG_CTOR(SfxObjectShell, 0); 303 304 const bool bScriptSupport = ( i_nCreationFlags & SFXMODEL_DISABLE_EMBEDDED_SCRIPTS ) == 0; 305 if ( !bScriptSupport ) 306 SetHasNoBasic(); 307 308 const bool bDocRecovery = ( i_nCreationFlags & SFXMODEL_DISABLE_DOCUMENT_RECOVERY ) == 0; 309 if ( !bDocRecovery ) 310 pImp->m_bDocRecoverySupport = sal_False; 311 } 312 313 //-------------------------------------------------------------------- 314 315 // initializes a document from a file-description 316 317 SfxObjectShell::SfxObjectShell 318 ( 319 SfxObjectCreateMode eMode /* purpose to generate SfxObjectShel: 320 321 SFX_CREATE_MODE_EMBEDDED (default) 322 as SO-Server from a different document 323 324 SFX_CREATE_MODE_STANDARD, 325 as normal, self opening document 326 327 SFX_CREATE_MODE_PREVIEW 328 in order to create a preview, possible 329 less data is needed 330 331 SFX_CREATE_MODE_ORGANIZER 332 as a representation in an Organiser 333 no data needed 334 */ 335 ) 336 337 /* [Description] 338 339 class constructor SfxObjectShell. 340 */ 341 342 : pImp( new SfxObjectShell_Impl( *this ) ), 343 pMedium(0), 344 pStyleSheetPool(0), 345 eCreateMode(eMode), 346 bHasName( sal_False ) 347 { 348 DBG_CTOR(SfxObjectShell, 0); 349 } 350 351 //-------------------------------------------------------------------- 352 353 // virtual dtor of typical base-class SfxObjectShell 354 355 SfxObjectShell::~SfxObjectShell() 356 { 357 DBG_DTOR(SfxObjectShell, 0); 358 359 if ( IsEnableSetModified() ) 360 EnableSetModified( sal_False ); 361 362 // do not call GetInPlaceObject(). Access to the inheritage path of SfxInternObject 363 // is not allowed because of a bug in the compiler 364 SfxObjectShell::Close(); 365 pImp->pBaseModel.set( NULL ); 366 367 DELETEX(pImp->pReloadTimer ); 368 369 SfxApplication *pSfxApp = SFX_APP(); 370 if ( USHRT_MAX != pImp->nVisualDocumentNumber ) 371 pSfxApp->ReleaseIndex(pImp->nVisualDocumentNumber); 372 373 // destroy BasicManager 374 pImp->pBasicManager->reset( NULL ); 375 376 if ( pSfxApp->GetDdeService() ) 377 pSfxApp->RemoveDdeTopic( this ); 378 379 pImp->pBaseModel.set( NULL ); 380 381 // don't call GetStorage() here, in case of Load Failure it's possible that a storage was never assigned! 382 if ( pMedium && pMedium->HasStorage_Impl() && pMedium->GetStorage( sal_False ) == pImp->m_xDocStorage ) 383 pMedium->CanDisposeStorage_Impl( sal_False ); 384 385 if ( pImp->mpObjectContainer ) 386 { 387 pImp->mpObjectContainer->CloseEmbeddedObjects(); 388 delete pImp->mpObjectContainer; 389 } 390 391 if ( pImp->bOwnsStorage && pImp->m_xDocStorage.is() ) 392 pImp->m_xDocStorage->dispose(); 393 394 if ( pMedium ) 395 { 396 pMedium->CloseAndReleaseStreams_Impl(); 397 398 if ( IsDocShared() ) 399 FreeSharedFile(); 400 401 DELETEX( pMedium ); 402 } 403 404 // The removing of the temporary file must be done as the latest step in the document destruction 405 if ( pImp->aTempName.Len() ) 406 { 407 String aTmp; 408 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( pImp->aTempName, aTmp ); 409 ::utl::UCBContentHelper::Kill( aTmp ); 410 } 411 412 delete pImp; 413 } 414 415 //-------------------------------------------------------------------- 416 417 void SfxObjectShell::Stamp_SetPrintCancelState(sal_Bool bState) 418 { 419 pImp->bIsPrintJobCancelable = bState; 420 } 421 422 //-------------------------------------------------------------------- 423 424 sal_Bool SfxObjectShell::Stamp_GetPrintCancelState() const 425 { 426 return pImp->bIsPrintJobCancelable; 427 } 428 429 //-------------------------------------------------------------------- 430 431 void SfxObjectShell::ViewAssigned() 432 433 /* [Description] 434 435 This module is called, when a view is assigned 436 */ 437 438 { 439 } 440 441 //-------------------------------------------------------------------- 442 // closes the Object and all its views 443 444 sal_Bool SfxObjectShell::Close() 445 { 446 {DBG_CHKTHIS(SfxObjectShell, 0);} 447 SfxObjectShellRef aRef(this); 448 if ( !pImp->bClosing ) 449 { 450 // if a process is still running -> dont close 451 if ( !pImp->bDisposing && GetProgress() ) 452 return sal_False; 453 454 pImp->bClosing = sal_True; 455 Reference< util::XCloseable > xCloseable( GetBaseModel(), UNO_QUERY ); 456 457 if ( xCloseable.is() ) 458 { 459 try 460 { 461 xCloseable->close( sal_True ); 462 } 463 catch( Exception& ) 464 { 465 pImp->bClosing = sal_False; 466 } 467 } 468 469 if ( pImp->bClosing ) 470 { 471 // remove from Document-List 472 SfxApplication *pSfxApp = SFX_APP(); 473 SfxObjectShellArr_Impl &rDocs = pSfxApp->GetObjectShells_Impl(); 474 const SfxObjectShell *pThis = this; 475 sal_uInt16 nPos = rDocs.GetPos(pThis); 476 if ( nPos < rDocs.Count() ) 477 rDocs.Remove( nPos ); 478 pImp->bInList = sal_False; 479 } 480 } 481 482 return sal_True; 483 } 484 485 //-------------------------------------------------------------------- 486 487 // returns a pointer the first SfxDocument of specified type 488 489 SfxObjectShell* SfxObjectShell::GetFirst 490 ( 491 const TypeId* pType , 492 sal_Bool bOnlyVisible 493 ) 494 { 495 SfxObjectShellArr_Impl &rDocs = SFX_APP()->GetObjectShells_Impl(); 496 497 // search for a SfxDocument of the specified type 498 for ( sal_uInt16 nPos = 0; nPos < rDocs.Count(); ++nPos ) 499 { 500 SfxObjectShell* pSh = rDocs.GetObject( nPos ); 501 if ( bOnlyVisible && pSh->IsPreview() && pSh->IsReadOnly() ) 502 continue; 503 504 if ( ( !pType || pSh->IsA(*pType) ) && 505 ( !bOnlyVisible || SfxViewFrame::GetFirst( pSh, sal_True ))) 506 return pSh; 507 } 508 509 return 0; 510 } 511 //-------------------------------------------------------------------- 512 513 // returns a pointer to the next SfxDocument of specified type behind *pDoc 514 515 SfxObjectShell* SfxObjectShell::GetNext 516 ( 517 const SfxObjectShell& rPrev, 518 const TypeId* pType, 519 sal_Bool bOnlyVisible 520 ) 521 { 522 SfxObjectShellArr_Impl &rDocs = SFX_APP()->GetObjectShells_Impl(); 523 524 // refind the specified predecessor 525 sal_uInt16 nPos; 526 for ( nPos = 0; nPos < rDocs.Count(); ++nPos ) 527 if ( rDocs.GetObject(nPos) == &rPrev ) 528 break; 529 530 // search for the next SfxDocument of the specified type 531 for ( ++nPos; nPos < rDocs.Count(); ++nPos ) 532 { 533 SfxObjectShell* pSh = rDocs.GetObject( nPos ); 534 if ( bOnlyVisible && pSh->IsPreview() && pSh->IsReadOnly() ) 535 continue; 536 537 if ( ( !pType || pSh->IsA(*pType) ) && 538 ( !bOnlyVisible || SfxViewFrame::GetFirst( pSh, sal_True ))) 539 return pSh; 540 } 541 return 0; 542 } 543 544 //-------------------------------------------------------------------- 545 546 SfxObjectShell* SfxObjectShell::Current() 547 { 548 SfxViewFrame *pFrame = SfxViewFrame::Current(); 549 return pFrame ? pFrame->GetObjectShell() : 0; 550 } 551 552 //------------------------------------------------------------------------- 553 554 sal_Bool SfxObjectShell::IsInPrepareClose() const 555 { 556 return pImp->bInPrepareClose; 557 } 558 559 //------------------------------------------------------------------------ 560 561 struct BoolEnv_Impl 562 { 563 SfxObjectShell_Impl* pImp; 564 BoolEnv_Impl( SfxObjectShell_Impl* pImpP) : pImp( pImpP ) 565 { pImpP->bInPrepareClose = sal_True; } 566 ~BoolEnv_Impl() { pImp->bInPrepareClose = sal_False; } 567 }; 568 569 570 sal_uInt16 SfxObjectShell::PrepareClose 571 ( 572 sal_Bool bUI, // sal_True: Dialoge etc. erlaubt, sal_False: silent-mode 573 sal_Bool bForBrowsing 574 ) 575 { 576 if( pImp->bInPrepareClose || pImp->bPreparedForClose ) 577 return sal_True; 578 BoolEnv_Impl aBoolEnv( pImp ); 579 580 // DocModalDialog? 581 if ( IsInModalMode() ) 582 return sal_False; 583 584 SfxViewFrame* pFirst = SfxViewFrame::GetFirst( this ); 585 if( pFirst && !pFirst->GetFrame().PrepareClose_Impl( bUI, bForBrowsing ) ) 586 return sal_False; 587 588 // prepare views for closing 589 for ( SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this ); 590 pFrm; pFrm = SfxViewFrame::GetNext( *pFrm, this ) ) 591 { 592 DBG_ASSERT(pFrm->GetViewShell(),"KeineShell"); 593 if ( pFrm->GetViewShell() ) 594 { 595 sal_uInt16 nRet = pFrm->GetViewShell()->PrepareClose( bUI, bForBrowsing ); 596 if ( nRet != sal_True ) 597 return nRet; 598 } 599 } 600 601 SfxApplication *pSfxApp = SFX_APP(); 602 pSfxApp->NotifyEvent( SfxEventHint(SFX_EVENT_PREPARECLOSEDOC, GlobalEventConfig::GetEventName(STR_EVENT_PREPARECLOSEDOC), this) ); 603 604 if( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ) 605 { 606 pImp->bPreparedForClose = sal_True; 607 return sal_True; 608 } 609 610 // if applicable ask if save should be executed 611 // ask only for visible documents 612 SfxViewFrame *pFrame = SfxObjectShell::Current() == this 613 ? SfxViewFrame::Current() : SfxViewFrame::GetFirst( this ); 614 615 sal_Bool bClose = sal_False; 616 if ( bUI && IsModified() && pFrame ) 617 { 618 //restore minimized 619 SfxFrame& rTop = pFrame->GetTopFrame(); 620 SfxViewFrame::SetViewFrame( rTop.GetCurrentViewFrame() ); 621 pFrame->GetFrame().Appear(); 622 623 // ask for save 624 short nRet = RET_YES; 625 //TODO/CLEANUP 626 //do we still need UI=2 ? 627 //if( SfxApplication::IsPlugin() == sal_False || bUI == 2 ) 628 { 629 //initiate help agent to inform about "print modifies the document" 630 SvtPrintWarningOptions aPrintOptions; 631 if (aPrintOptions.IsModifyDocumentOnPrintingAllowed() && 632 HasName() && getDocProperties()->getPrintDate().Month > 0) 633 { 634 SfxHelp::OpenHelpAgent( &pFirst->GetFrame(), HID_CLOSE_WARNING ); 635 } 636 const Reference< XTitle > xTitle( *pImp->pBaseModel.get(), UNO_QUERY_THROW ); 637 const ::rtl::OUString sTitle = xTitle->getTitle (); 638 nRet = ExecuteQuerySaveDocument(&pFrame->GetWindow(),sTitle); 639 } 640 /*HACK for plugin::destroy()*/ 641 642 if ( RET_YES == nRet ) 643 { 644 // save by Dispatcher 645 const SfxPoolItem *pPoolItem; 646 if ( IsSaveVersionOnClose() ) 647 { 648 SfxStringItem aItem( SID_DOCINFO_COMMENTS, String( SfxResId( STR_AUTOMATICVERSION ) ) ); 649 SfxBoolItem aWarnItem( SID_FAIL_ON_WARNING, bUI ); 650 const SfxPoolItem* ppArgs[] = { &aItem, &aWarnItem, 0 }; 651 pPoolItem = pFrame->GetBindings().ExecuteSynchron( SID_SAVEDOC, ppArgs ); 652 } 653 else 654 { 655 SfxBoolItem aWarnItem( SID_FAIL_ON_WARNING, bUI ); 656 const SfxPoolItem* ppArgs[] = { &aWarnItem, 0 }; 657 pPoolItem = pFrame->GetBindings().ExecuteSynchron( SID_SAVEDOC, ppArgs ); 658 } 659 660 if ( !pPoolItem || pPoolItem->ISA(SfxVoidItem) || ( pPoolItem->ISA(SfxBoolItem) && !( (const SfxBoolItem*) pPoolItem )->GetValue() ) ) 661 return sal_False; 662 else 663 bClose = sal_True; 664 } 665 else if ( RET_CANCEL == nRet ) 666 // canceled 667 return sal_False; 668 else if ( RET_NEWTASK == nRet ) 669 { 670 return RET_NEWTASK; 671 } 672 else 673 { 674 // At No selection don't loose information 675 bClose = sal_True; 676 } 677 } 678 679 pImp->bPreparedForClose = sal_True; 680 return sal_True; 681 } 682 683 //-------------------------------------------------------------------- 684 namespace 685 { 686 static BasicManager* lcl_getBasicManagerForDocument( const SfxObjectShell& _rDocument ) 687 { 688 if ( !_rDocument.Get_Impl()->m_bNoBasicCapabilities ) 689 { 690 if ( !_rDocument.Get_Impl()->bBasicInitialized ) 691 const_cast< SfxObjectShell& >( _rDocument ).InitBasicManager_Impl(); 692 return _rDocument.Get_Impl()->pBasicManager->get(); 693 } 694 695 // assume we do not have Basic ourself, but we can refer to another 696 // document which does (by our model's XScriptInvocationContext::getScriptContainer). 697 // In this case, we return the BasicManager of this other document. 698 699 OSL_ENSURE( !Reference< XEmbeddedScripts >( _rDocument.GetModel(), UNO_QUERY ).is(), 700 "lcl_getBasicManagerForDocument: inconsistency: no Basic, but an XEmbeddedScripts?" ); 701 Reference< XModel > xForeignDocument; 702 Reference< XScriptInvocationContext > xContext( _rDocument.GetModel(), UNO_QUERY ); 703 if ( xContext.is() ) 704 { 705 xForeignDocument.set( xContext->getScriptContainer(), UNO_QUERY ); 706 OSL_ENSURE( xForeignDocument.is() && xForeignDocument != _rDocument.GetModel(), 707 "lcl_getBasicManagerForDocument: no Basic, but providing ourself as script container?" ); 708 } 709 710 BasicManager* pBasMgr = NULL; 711 if ( xForeignDocument.is() ) 712 pBasMgr = ::basic::BasicManagerRepository::getDocumentBasicManager( xForeignDocument ); 713 714 return pBasMgr; 715 } 716 } 717 718 //-------------------------------------------------------------------- 719 720 BasicManager* SfxObjectShell::GetBasicManager() const 721 { 722 BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this ); 723 if ( !pBasMgr ) 724 pBasMgr = SFX_APP()->GetBasicManager(); 725 return pBasMgr; 726 } 727 728 //-------------------------------------------------------------------- 729 730 void SfxObjectShell::SetHasNoBasic() 731 { 732 pImp->m_bNoBasicCapabilities = sal_True; 733 } 734 735 //-------------------------------------------------------------------- 736 737 sal_Bool SfxObjectShell::HasBasic() const 738 { 739 if ( pImp->m_bNoBasicCapabilities ) 740 return sal_False; 741 742 if ( !pImp->bBasicInitialized ) 743 const_cast< SfxObjectShell* >( this )->InitBasicManager_Impl(); 744 745 return pImp->pBasicManager->isValid(); 746 } 747 748 //-------------------------------------------------------------------- 749 namespace 750 { 751 const Reference< XLibraryContainer >& 752 lcl_getOrCreateLibraryContainer( bool _bScript, Reference< XLibraryContainer >& _rxContainer, 753 const Reference< XModel >& _rxDocument ) 754 { 755 if ( !_rxContainer.is() ) 756 { 757 try 758 { 759 Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, UNO_QUERY ); 760 const Reference< XComponentContext > xContext( 761 ::comphelper::getProcessComponentContext() ); 762 _rxContainer.set ( _bScript 763 ? DocumentScriptLibraryContainer::create( 764 xContext, xStorageDoc ) 765 : DocumentDialogLibraryContainer::create( 766 xContext, xStorageDoc ) 767 , UNO_QUERY_THROW ); 768 } 769 catch( const Exception& ) 770 { 771 DBG_UNHANDLED_EXCEPTION(); 772 } 773 } 774 return _rxContainer; 775 } 776 } 777 778 //-------------------------------------------------------------------- 779 780 Reference< XLibraryContainer > SfxObjectShell::GetDialogContainer() 781 { 782 if ( !pImp->m_bNoBasicCapabilities ) 783 return lcl_getOrCreateLibraryContainer( false, pImp->xDialogLibraries, GetModel() ); 784 785 BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this ); 786 if ( pBasMgr ) 787 return pBasMgr->GetDialogLibraryContainer().get(); 788 789 OSL_ENSURE( false, "SfxObjectShell::GetDialogContainer: falling back to the application - is this really expected here?" ); 790 return SFX_APP()->GetDialogContainer(); 791 } 792 793 //-------------------------------------------------------------------- 794 795 Reference< XLibraryContainer > SfxObjectShell::GetBasicContainer() 796 { 797 if ( !pImp->m_bNoBasicCapabilities ) 798 return lcl_getOrCreateLibraryContainer( true, pImp->xBasicLibraries, GetModel() ); 799 800 BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this ); 801 if ( pBasMgr ) 802 return pBasMgr->GetScriptLibraryContainer().get(); 803 804 OSL_ENSURE( false, "SfxObjectShell::GetBasicContainer: falling back to the application - is this really expected here?" ); 805 return SFX_APP()->GetBasicContainer(); 806 } 807 808 //-------------------------------------------------------------------- 809 810 StarBASIC* SfxObjectShell::GetBasic() const 811 { 812 return GetBasicManager()->GetLib(0); 813 } 814 815 //-------------------------------------------------------------------- 816 817 void SfxObjectShell::InitBasicManager_Impl() 818 /* [Description] 819 820 creates a document's BasicManager and loads it, if we are already based on 821 a storage. 822 823 [Note] 824 825 This method must be called with overloaded 826 <SvPersist::Load()> (with pStor from Parameter from Load()) 827 and <SvPersist::InitNew()> (with pStor = 0) 828 */ 829 830 { 831 /* #163556# (DR) - Handling of recursive calls while creating the Bacic (shouldn't that be Basic?) 832 manager. 833 834 It is possible that (while creating the Basic manager) the code that 835 imports the Basic storage wants to access the Basic manager again. 836 Especially in VBA compatibility mode, there is code that wants to 837 access the "VBA Globals" object which is stored as global UNO constant 838 in the Basic manager. 839 840 To achieve correct handling of the recursive calls of this function 841 from lcl_getBasicManagerForDocument(), the implementation of the 842 function BasicManagerRepository::getDocumentBasicManager() has been 843 changed to return the Basic manager currently under construction, when 844 called repeatedly. 845 846 The variable pImp->bBasicInitialized will be set to sal_True after 847 construction now, to ensure that the recursive call of the function 848 lcl_getBasicManagerForDocument() will be routed into this function too. 849 850 Calling BasicManagerHolder::reset() twice is not a big problem, as it 851 does not take ownership but stores only the raw pointer. Owner of all 852 Basic managers is the global BasicManagerRepository instance. 853 */ 854 DBG_ASSERT( !pImp->bBasicInitialized && !pImp->pBasicManager->isValid(), "Lokaler BasicManager bereits vorhanden"); 855 pImp->pBasicManager->reset( BasicManagerRepository::getDocumentBasicManager( GetModel() ) ); 856 DBG_ASSERT( pImp->pBasicManager->isValid(), "SfxObjectShell::InitBasicManager_Impl: did not get a BasicManager!" ); 857 pImp->bBasicInitialized = sal_True; 858 } 859 860 //-------------------------------------------------------------------- 861 862 sal_uInt16 SfxObjectShell::Count() 863 { 864 return SFX_APP()->GetObjectShells_Impl().Count(); 865 } 866 867 //-------------------------------------------------------------------- 868 869 sal_Bool SfxObjectShell::DoClose() 870 { 871 return Close(); 872 } 873 874 //-------------------------------------------------------------------- 875 876 SfxObjectShell* SfxObjectShell::GetObjectShell() 877 { 878 return this; 879 } 880 881 //-------------------------------------------------------------------- 882 883 uno::Sequence< ::rtl::OUString > SfxObjectShell::GetEventNames() 884 { 885 static uno::Sequence< ::rtl::OUString >* pEventNameContainer = NULL; 886 887 if ( !pEventNameContainer ) 888 { 889 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 890 if ( !pEventNameContainer ) 891 { 892 static uno::Sequence< ::rtl::OUString > aEventNameContainer = GlobalEventConfig().getElementNames(); 893 pEventNameContainer = &aEventNameContainer; 894 } 895 } 896 897 return *pEventNameContainer; 898 } 899 900 //-------------------------------------------------------------------- 901 902 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > SfxObjectShell::GetModel() const 903 { 904 return GetBaseModel(); 905 } 906 907 void SfxObjectShell::SetBaseModel( SfxBaseModel* pModel ) 908 { 909 OSL_ENSURE( !pImp->pBaseModel.is() || pModel == NULL, "Model already set!" ); 910 pImp->pBaseModel.set( pModel ); 911 if ( pImp->pBaseModel.is() ) 912 { 913 pImp->pBaseModel->addCloseListener( new SfxModelListener_Impl(this) ); 914 } 915 } 916 917 //-------------------------------------------------------------------- 918 919 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > SfxObjectShell::GetBaseModel() const 920 { 921 return pImp->pBaseModel.get(); 922 } 923 /* -----------------------------10.09.2001 15:56------------------------------ 924 925 ---------------------------------------------------------------------------*/ 926 void SfxObjectShell::SetAutoStyleFilterIndex(sal_uInt16 nSet) 927 { 928 pImp->nStyleFilter = nSet; 929 } 930 931 sal_uInt16 SfxObjectShell::GetAutoStyleFilterIndex() 932 { 933 return pImp->nStyleFilter; 934 } 935 936 937 void SfxObjectShell::SetCurrentComponent( const Reference< XInterface >& _rxComponent ) 938 { 939 Reference< XInterface > xOldCurrentComp(s_xCurrentComponent); 940 if ( _rxComponent == xOldCurrentComp ) 941 // nothing to do 942 return; 943 // note that "_rxComponent.get() == s_xCurrentComponent.get().get()" is /sufficient/, but not 944 // /required/ for "_rxComponent == s_xCurrentComponent.get()". 945 // In other words, it's still possible that we here do something which is not necessary, 946 // but we should have filtered quite some unnecessary calls already. 947 948 BasicManager* pAppMgr = SFX_APP()->GetBasicManager(); 949 s_xCurrentComponent = _rxComponent; 950 if ( pAppMgr ) 951 { 952 // set "ThisComponent" for Basic 953 pAppMgr->SetGlobalUNOConstant( "ThisComponent", Any( _rxComponent ) ); 954 955 // set new current component for VBA compatibility 956 if ( _rxComponent.is() ) 957 { 958 ::rtl::OString aVBAConstName = lclGetVBAGlobalConstName( _rxComponent ); 959 if ( aVBAConstName.getLength() > 0 ) 960 { 961 pAppMgr->SetGlobalUNOConstant( aVBAConstName.getStr(), Any( _rxComponent ) ); 962 s_aRegisteredVBAConstants[ _rxComponent.get() ] = aVBAConstName; 963 } 964 } 965 // no new component passed -> remove last registered VBA component 966 else if ( xOldCurrentComp.is() ) 967 { 968 ::rtl::OString aVBAConstName = lclGetVBAGlobalConstName( xOldCurrentComp ); 969 if ( aVBAConstName.getLength() > 0 ) 970 { 971 pAppMgr->SetGlobalUNOConstant( aVBAConstName.getStr(), Any( Reference< XInterface >() ) ); 972 s_aRegisteredVBAConstants.erase( xOldCurrentComp.get() ); 973 } 974 } 975 } 976 } 977 978 Reference< XInterface > SfxObjectShell::GetCurrentComponent() 979 { 980 return s_xCurrentComponent; 981 } 982 983 984 String SfxObjectShell::GetServiceNameFromFactory( const String& rFact ) 985 { 986 //! Remove everything behind name! 987 String aFact( rFact ); 988 String aPrefix = String::CreateFromAscii( "private:factory/" ); 989 if ( aPrefix.Len() == aFact.Match( aPrefix ) ) 990 aFact.Erase( 0, aPrefix.Len() ); 991 sal_uInt16 nPos = aFact.Search( '?' ); 992 String aParam; 993 if ( nPos != STRING_NOTFOUND ) 994 { 995 aParam = aFact.Copy( nPos, aFact.Len() ); 996 aFact.Erase( nPos, aFact.Len() ); 997 aParam.Erase(0,1); 998 } 999 aFact.EraseAllChars('4').ToLowerAscii(); 1000 1001 // HACK: sometimes a real document service name is given here instead of 1002 // a factory short name. Set return value directly to this service name as fallback 1003 // in case next lines of code does nothing ... 1004 // use rFact instead of normed aFact value ! 1005 ::rtl::OUString aServiceName = rFact; 1006 1007 if ( aFact.EqualsAscii("swriter") ) 1008 { 1009 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.text.TextDocument"); 1010 } 1011 else if ( aFact.EqualsAscii("sweb") || aFact.EqualsAscii("swriter/web") ) 1012 { 1013 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.text.WebDocument"); 1014 } 1015 else if ( aFact.EqualsAscii("sglobal") || aFact.EqualsAscii("swriter/globaldocument") ) 1016 { 1017 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.text.GlobalDocument"); 1018 } 1019 else if ( aFact.EqualsAscii("scalc") ) 1020 { 1021 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.sheet.SpreadsheetDocument"); 1022 } 1023 else if ( aFact.EqualsAscii("sdraw") ) 1024 { 1025 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.drawing.DrawingDocument"); 1026 } 1027 else if ( aFact.EqualsAscii("simpress") ) 1028 { 1029 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.presentation.PresentationDocument"); 1030 } 1031 else if ( aFact.EqualsAscii("schart") ) 1032 { 1033 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.chart.ChartDocument"); 1034 } 1035 else if ( aFact.EqualsAscii("smath") ) 1036 { 1037 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.formula.FormulaProperties"); 1038 } 1039 else if ( aFact.EqualsAscii("sbasic") ) 1040 { 1041 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.script.BasicIDE"); 1042 } 1043 else if ( aFact.EqualsAscii("sdatabase") ) 1044 { 1045 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.sdb.OfficeDatabaseDocument"); 1046 } 1047 1048 return aServiceName; 1049 } 1050 1051 SfxObjectShell* SfxObjectShell::CreateObjectByFactoryName( const String& rFact, SfxObjectCreateMode eMode ) 1052 { 1053 return CreateObject( GetServiceNameFromFactory( rFact ), eMode ); 1054 } 1055 1056 1057 SfxObjectShell* SfxObjectShell::CreateObject( const String& rServiceName, SfxObjectCreateMode eCreateMode ) 1058 { 1059 if ( rServiceName.Len() ) 1060 { 1061 ::com::sun::star::uno::Reference < ::com::sun::star::frame::XModel > xDoc( 1062 ::comphelper::getProcessServiceFactory()->createInstance( rServiceName ), UNO_QUERY ); 1063 if ( xDoc.is() ) 1064 { 1065 ::com::sun::star::uno::Reference < ::com::sun::star::lang::XUnoTunnel > xObj( xDoc, UNO_QUERY ); 1066 ::com::sun::star::uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() ); 1067 sal_Int64 nHandle = xObj->getSomething( aSeq ); 1068 if ( nHandle ) 1069 { 1070 SfxObjectShell* pRet = reinterpret_cast< SfxObjectShell* >( sal::static_int_cast< sal_IntPtr >( nHandle )); 1071 pRet->SetCreateMode_Impl( eCreateMode ); 1072 return pRet; 1073 } 1074 } 1075 } 1076 1077 return 0; 1078 } 1079 1080 SfxObjectShell* SfxObjectShell::CreateAndLoadObject( const SfxItemSet& rSet, SfxFrame* pFrame ) 1081 { 1082 uno::Sequence < beans::PropertyValue > aProps; 1083 TransformItems( SID_OPENDOC, rSet, aProps ); 1084 SFX_ITEMSET_ARG(&rSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False); 1085 SFX_ITEMSET_ARG(&rSet, pTargetItem, SfxStringItem, SID_TARGETNAME, sal_False); 1086 ::rtl::OUString aURL; 1087 ::rtl::OUString aTarget = rtl::OUString::createFromAscii("_blank"); 1088 if ( pFileNameItem ) 1089 aURL = pFileNameItem->GetValue(); 1090 if ( pTargetItem ) 1091 aTarget = pTargetItem->GetValue(); 1092 1093 uno::Reference < frame::XComponentLoader > xLoader; 1094 if ( pFrame ) 1095 { 1096 xLoader = uno::Reference < frame::XComponentLoader >( pFrame->GetFrameInterface(), uno::UNO_QUERY ); 1097 } 1098 else 1099 xLoader = uno::Reference < frame::XComponentLoader >( comphelper::getProcessServiceFactory()->createInstance( 1100 ::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop") ), uno::UNO_QUERY ); 1101 1102 uno::Reference < lang::XUnoTunnel > xObj; 1103 try 1104 { 1105 xObj = uno::Reference< lang::XUnoTunnel >( xLoader->loadComponentFromURL( aURL, aTarget, 0, aProps ), uno::UNO_QUERY ); 1106 } 1107 catch( uno::Exception& ) 1108 {} 1109 1110 if ( xObj.is() ) 1111 { 1112 ::com::sun::star::uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() ); 1113 sal_Int64 nHandle = xObj->getSomething( aSeq ); 1114 if ( nHandle ) 1115 return reinterpret_cast< SfxObjectShell* >(sal::static_int_cast< sal_IntPtr >( nHandle )); 1116 } 1117 1118 return NULL; 1119 } 1120 1121 void SfxObjectShell::SetInitialized_Impl( const bool i_fromInitNew ) 1122 { 1123 pImp->bInitialized = sal_True; 1124 if ( i_fromInitNew ) 1125 { 1126 SetActivateEvent_Impl( SFX_EVENT_CREATEDOC ); 1127 SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_DOCCREATED, GlobalEventConfig::GetEventName(STR_EVENT_DOCCREATED), this ) ); 1128 } 1129 else 1130 { 1131 SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_LOADFINISHED, GlobalEventConfig::GetEventName(STR_EVENT_LOADFINISHED), this ) ); 1132 } 1133 } 1134 1135 1136 bool SfxObjectShell::IsChangeRecording() const 1137 { 1138 // currently this function needs to be overwritten by Writer and Calc only 1139 DBG_ASSERT( 0, "function not implemented" ); 1140 return false; 1141 } 1142 1143 1144 bool SfxObjectShell::HasChangeRecordProtection() const 1145 { 1146 // currently this function needs to be overwritten by Writer and Calc only 1147 DBG_ASSERT( 0, "function not implemented" ); 1148 return false; 1149 } 1150 1151 1152 void SfxObjectShell::SetChangeRecording( bool /*bActivate*/ ) 1153 { 1154 // currently this function needs to be overwritten by Writer and Calc only 1155 DBG_ASSERT( 0, "function not implemented" ); 1156 } 1157 1158 1159 bool SfxObjectShell::SetProtectionPassword( const String & /*rPassword*/ ) 1160 { 1161 // currently this function needs to be overwritten by Writer and Calc only 1162 DBG_ASSERT( 0, "function not implemented" ); 1163 return false; 1164 } 1165 1166 1167 bool SfxObjectShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence< sal_Int8 > & /*rPasswordHash*/ ) 1168 { 1169 // currently this function needs to be overwritten by Writer and Calc only 1170 DBG_ASSERT( 0, "function not implemented" ); 1171 return false; 1172 } 1173 1174