1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #include <basic/basicmanagerrepository.hxx> 21 #include <basic/basmgr.hxx> 22 #include <scriptcont.hxx> 23 #include <dlgcont.hxx> 24 #include <sbintern.hxx> 25 #include <sbxbase.hxx> 26 27 #include <com/sun/star/document/XStorageBasedDocument.hpp> 28 #include <com/sun/star/document/XEmbeddedScripts.hpp> 29 #include <com/sun/star/frame/Desktop.hpp> 30 #include <o3tl/string_view.hxx> 31 #include <svtools/ehdl.hxx> 32 #include <svtools/sfxecode.hxx> 33 #include <unotools/pathoptions.hxx> 34 #include <svl/hint.hxx> 35 #include <vcl/svapp.hxx> 36 #include <tools/debug.hxx> 37 #include <comphelper/diagnose_ex.hxx> 38 #include <tools/urlobj.hxx> 39 #include <comphelper/processfactory.hxx> 40 #include <comphelper/documentinfo.hxx> 41 #include <unotools/eventlisteneradapter.hxx> 42 43 #include <sot/storage.hxx> 44 45 #include <map> 46 #include <mutex> 47 48 49 namespace basic 50 { 51 using ::com::sun::star::uno::Reference; 52 using ::com::sun::star::uno::XComponentContext; 53 using ::com::sun::star::frame::XModel; 54 using ::com::sun::star::frame::Desktop; 55 using ::com::sun::star::uno::XInterface; 56 using ::com::sun::star::uno::UNO_QUERY; 57 using ::com::sun::star::embed::XStorage; 58 using ::com::sun::star::script::XStorageBasedLibraryContainer; 59 using ::com::sun::star::uno::UNO_QUERY_THROW; 60 using ::com::sun::star::uno::Exception; 61 using ::com::sun::star::document::XStorageBasedDocument; 62 using ::com::sun::star::document::XEmbeddedScripts; 63 64 typedef std::map< Reference< XInterface >, std::unique_ptr<BasicManager> > BasicManagerStore; 65 66 typedef std::vector< BasicManagerCreationListener* > CreationListeners; 67 68 class ImplRepository : public ::utl::OEventListenerAdapter, public SfxListener, public SvRefBase 69 { 70 private: 71 ImplRepository(); 72 ~ImplRepository(); 73 74 private: 75 BasicManagerStore m_aStore; 76 CreationListeners m_aCreationListeners; 77 78 public: 79 static ImplRepository& Instance(); 80 81 BasicManager* getDocumentBasicManager( const Reference< XModel >& _rxDocumentModel ); 82 BasicManager* getOrCreateApplicationBasicManager(); 83 static BasicManager* getApplicationBasicManager(); 84 static void setApplicationBasicManager( std::unique_ptr<BasicManager> _pBasicManager ); 85 void registerCreationListener( BasicManagerCreationListener& _rListener ); 86 void revokeCreationListener( BasicManagerCreationListener& _rListener ); 87 88 private: 89 /** retrieves the location at which the BasicManager for the given model 90 is stored. 91 92 If previously, the BasicManager for this model has never been requested, 93 then the model is added to the map, with an initial NULL BasicManager. 94 95 @param _rxDocumentModel 96 the model whose BasicManager's location is to be retrieved. Must not be <NULL/>. 97 98 @precond 99 our mutex is locked 100 */ 101 BasicManagerStore::iterator 102 impl_getLocationForModel( const Reference< XModel >& _rxDocumentModel ); 103 104 /** tests if there is a location set at which the BasicManager for the given model 105 is stored. 106 107 @param _rxDocumentModel 108 the model whose BasicManager's location is to be retrieved. Must not be <NULL/>. 109 110 @precond 111 our mutex is locked 112 */ 113 bool impl_hasLocationForModel( const Reference< XModel >& _rxDocumentModel ) const; 114 115 /** creates a new BasicManager instance for the given model 116 117 @param _out_rpBasicManager 118 reference to the pointer variable that will hold the new 119 BasicManager. 120 121 @param _rxDocumentModel 122 the model whose BasicManager will be created. Must not be <NULL/>. 123 */ 124 bool impl_createManagerForModel( 125 BasicManagerStore::iterator location, 126 const Reference< XModel >& _rxDocumentModel ); 127 128 /** creates the application-wide BasicManager 129 */ 130 BasicManager* impl_createApplicationBasicManager(); 131 132 /** notifies all listeners which expressed interest in the creation of BasicManager instances. 133 */ 134 void impl_notifyCreationListeners( 135 const Reference< XModel >& _rxDocumentModel, 136 BasicManager& _rManager 137 ); 138 139 /** retrieves the current storage of a given document 140 141 @param _rxDocument 142 the document whose storage is to be retrieved. 143 144 @param _out_rStorage 145 takes the storage upon successful return. Note that this might be <NULL/> even 146 if <TRUE/> is returned. In this case, the document has not yet been saved. 147 148 @return 149 <TRUE/> if the storage could be successfully retrieved (in which case 150 <arg>_out_rStorage</arg> might or might not be <NULL/>), <FALSE/> otherwise. 151 In the latter case, processing this document should stop. 152 */ 153 static bool impl_getDocumentStorage_nothrow( const Reference< XModel >& _rxDocument, Reference< XStorage >& _out_rStorage ); 154 155 /** retrieves the containers for Basic and Dialog libraries for a given document 156 157 @param _rxDocument 158 the document whose containers are to be retrieved. 159 160 @param _out_rxBasicLibraries 161 takes the basic library container upon successful return 162 163 @param _out_rxDialogLibraries 164 takes the dialog library container upon successful return 165 166 @return 167 <TRUE/> if and only if both containers exist, and could successfully be retrieved 168 */ 169 static bool impl_getDocumentLibraryContainers_nothrow( 170 const Reference< XModel >& _rxDocument, 171 Reference<XStorageBasedLibraryContainer>& _out_rxBasicLibraries, 172 Reference<XStorageBasedLibraryContainer>& _out_rxDialogLibraries 173 ); 174 175 /** initializes the given library containers, which belong to a document 176 */ 177 static void impl_initDocLibraryContainers_nothrow( 178 const Reference<XStorageBasedLibraryContainer>& _rxBasicLibraries, 179 const Reference<XStorageBasedLibraryContainer>& _rxDialogLibraries 180 ); 181 182 // OEventListenerAdapter overridables 183 virtual void _disposing( const css::lang::EventObject& _rSource ) override; 184 185 // SfxListener overridables 186 virtual void Notify( SfxBroadcaster& _rBC, const SfxHint& _rHint ) override; 187 188 /** removes the Model/BasicManager pair given by iterator from our store 189 */ 190 void impl_removeFromRepository( const BasicManagerStore::iterator& _pos ); 191 192 private: 193 StarBASIC* impl_getDefaultAppBasicLibrary(); 194 }; 195 ImplRepository()196 ImplRepository::ImplRepository() 197 { 198 } 199 ~ImplRepository()200 ImplRepository::~ImplRepository() 201 { 202 // Avoid double-delete of managers when they are destroyed in our dtor, and start notify us 203 for (auto& it : m_aStore) 204 EndListening(*it.second); 205 } 206 Instance()207 ImplRepository& ImplRepository::Instance() 208 { 209 tools::SvRef<SvRefBase>& repository = GetSbxData_Impl().mrImplRepository; 210 { 211 static std::mutex aMutex; 212 std::unique_lock aGuard(aMutex); 213 if (!repository) 214 repository = new ImplRepository; 215 } 216 return *static_cast<ImplRepository*>(repository.get()); 217 } 218 getDocumentBasicManager(const Reference<XModel> & _rxDocumentModel)219 BasicManager* ImplRepository::getDocumentBasicManager( const Reference< XModel >& _rxDocumentModel ) 220 { 221 SolarMutexGuard g; 222 223 /* #163556# (DR) - This function may be called recursively while 224 constructing the Basic manager and loading the Basic storage. By 225 passing the map entry received from impl_getLocationForModel() to 226 the function impl_createManagerForModel(), the new Basic manager 227 will be put immediately into the map of existing Basic managers, 228 thus a recursive call of this function will find and return it 229 without creating another instance. 230 */ 231 auto const loc = impl_getLocationForModel( _rxDocumentModel ); 232 if (loc->second != nullptr) 233 return loc->second.get(); 234 if (impl_createManagerForModel(loc, _rxDocumentModel)) 235 return loc->second.get(); 236 return nullptr; 237 } 238 getOrCreateApplicationBasicManager()239 BasicManager* ImplRepository::getOrCreateApplicationBasicManager() 240 { 241 SolarMutexGuard g; 242 243 BasicManager* pAppManager = GetSbData()->pAppBasMgr.get(); 244 if (pAppManager == nullptr) 245 pAppManager = impl_createApplicationBasicManager(); 246 return pAppManager; 247 } 248 getApplicationBasicManager()249 BasicManager* ImplRepository::getApplicationBasicManager() 250 { 251 SolarMutexGuard g; 252 253 return GetSbData()->pAppBasMgr.get(); 254 } 255 setApplicationBasicManager(std::unique_ptr<BasicManager> _pBasicManager)256 void ImplRepository::setApplicationBasicManager( std::unique_ptr<BasicManager> _pBasicManager ) 257 { 258 SolarMutexGuard g; 259 260 GetSbData()->pAppBasMgr = std::move(_pBasicManager); 261 } 262 263 impl_createApplicationBasicManager()264 BasicManager* ImplRepository::impl_createApplicationBasicManager() 265 { 266 SolarMutexGuard g; 267 268 OSL_PRECOND(getApplicationBasicManager() == nullptr, "ImplRepository::impl_createApplicationBasicManager: there already is one!"); 269 270 // Determine Directory 271 SvtPathOptions aPathCFG; 272 OUString aAppBasicDir( aPathCFG.GetBasicPath() ); 273 if ( aAppBasicDir.isEmpty() ) 274 { 275 aPathCFG.SetBasicPath(u"$(prog)"_ustr); 276 } 277 278 // Create basic and load it 279 // AppBasicDir is now a PATH 280 INetURLObject aAppBasic( SvtPathOptions().SubstituteVariable(u"$(progurl)"_ustr) ); 281 aAppBasic.insertName( Application::GetAppName() ); 282 283 BasicManager* pBasicManager = new BasicManager( new StarBASIC, &aAppBasicDir ); 284 setApplicationBasicManager( std::unique_ptr<BasicManager>(pBasicManager) ); 285 286 // The first dir in the path as destination: 287 OUString aFileName( aAppBasic.getName() ); 288 aAppBasic = INetURLObject( o3tl::getToken(aAppBasicDir, 1, ';') ); 289 DBG_ASSERT(aAppBasic.GetProtocol() != INetProtocol::NotValid, 290 OString("Invalid URL: \"" + 291 OUStringToOString(aAppBasicDir, osl_getThreadTextEncoding()) + 292 "\"").getStr()); 293 aAppBasic.insertName( aFileName ); 294 pBasicManager->SetStorageName( aAppBasic.PathToFileName() ); 295 296 // Basic container 297 rtl::Reference<SfxScriptLibraryContainer> pBasicCont = new SfxScriptLibraryContainer( Reference< XStorage >() ); 298 pBasicCont->setBasicManager( pBasicManager ); 299 300 // Dialog container 301 rtl::Reference<SfxDialogLibraryContainer> pDialogCont = new SfxDialogLibraryContainer( Reference< XStorage >() ); 302 303 LibraryContainerInfo aInfo( pBasicCont, pDialogCont, pBasicCont.get() ); 304 pBasicManager->SetLibraryContainerInfo( aInfo ); 305 306 // global constants 307 308 // StarDesktop 309 const Reference< XComponentContext >& xContext = ::comphelper::getProcessComponentContext(); 310 pBasicManager->SetGlobalUNOConstant( u"StarDesktop"_ustr, css::uno::Any( Desktop::create(xContext))); 311 312 // (BasicLibraries and DialogLibraries have automatically been added in SetLibraryContainerInfo) 313 314 // notify 315 impl_notifyCreationListeners( nullptr, *pBasicManager ); 316 317 // outta here 318 return pBasicManager; 319 } 320 321 registerCreationListener(BasicManagerCreationListener & _rListener)322 void ImplRepository::registerCreationListener( BasicManagerCreationListener& _rListener ) 323 { 324 SolarMutexGuard g; 325 326 m_aCreationListeners.push_back( &_rListener ); 327 } 328 329 revokeCreationListener(BasicManagerCreationListener & _rListener)330 void ImplRepository::revokeCreationListener( BasicManagerCreationListener& _rListener ) 331 { 332 SolarMutexGuard g; 333 334 CreationListeners::iterator pos = std::find( m_aCreationListeners.begin(), m_aCreationListeners.end(), &_rListener ); 335 if ( pos != m_aCreationListeners.end() ) 336 m_aCreationListeners.erase( pos ); 337 else { 338 OSL_FAIL( "ImplRepository::revokeCreationListener: listener is not registered!" ); 339 } 340 } 341 342 impl_notifyCreationListeners(const Reference<XModel> & _rxDocumentModel,BasicManager & _rManager)343 void ImplRepository::impl_notifyCreationListeners( const Reference< XModel >& _rxDocumentModel, BasicManager& _rManager ) 344 { 345 for (auto const& creationListener : m_aCreationListeners) 346 { 347 creationListener->onBasicManagerCreated( _rxDocumentModel, _rManager ); 348 } 349 } 350 351 impl_getDefaultAppBasicLibrary()352 StarBASIC* ImplRepository::impl_getDefaultAppBasicLibrary() 353 { 354 BasicManager* pAppManager = getOrCreateApplicationBasicManager(); 355 356 StarBASIC* pAppBasic = pAppManager ? pAppManager->GetLib(0) : nullptr; 357 DBG_ASSERT( pAppBasic != nullptr, "impl_getApplicationBasic: unable to determine the default application's Basic library!" ); 358 return pAppBasic; 359 } 360 impl_getLocationForModel(const Reference<XModel> & _rxDocumentModel)361 BasicManagerStore::iterator ImplRepository::impl_getLocationForModel( const Reference< XModel >& _rxDocumentModel ) 362 { 363 Reference< XInterface > xNormalized( _rxDocumentModel, UNO_QUERY ); 364 DBG_ASSERT( _rxDocumentModel.is(), "ImplRepository::impl_getLocationForModel: invalid model!" ); 365 366 return m_aStore.try_emplace(xNormalized).first; 367 } 368 impl_hasLocationForModel(const Reference<XModel> & _rxDocumentModel) const369 bool ImplRepository::impl_hasLocationForModel( const Reference< XModel >& _rxDocumentModel ) const 370 { 371 Reference< XInterface > xNormalized( _rxDocumentModel, UNO_QUERY ); 372 DBG_ASSERT( _rxDocumentModel.is(), "ImplRepository::impl_getLocationForModel: invalid model!" ); 373 374 return m_aStore.contains(xNormalized); 375 } 376 impl_initDocLibraryContainers_nothrow(const Reference<XStorageBasedLibraryContainer> & _rxBasicLibraries,const Reference<XStorageBasedLibraryContainer> & _rxDialogLibraries)377 void ImplRepository::impl_initDocLibraryContainers_nothrow( const Reference<XStorageBasedLibraryContainer>& _rxBasicLibraries, const Reference<XStorageBasedLibraryContainer>& _rxDialogLibraries ) 378 { 379 OSL_PRECOND( _rxBasicLibraries.is() && _rxDialogLibraries.is(), 380 "ImplRepository::impl_initDocLibraryContainers_nothrow: illegal library containers, this will crash!" ); 381 382 try 383 { 384 // ensure there's a standard library in the basic container 385 static constexpr OUString aStdLibName( u"Standard"_ustr ); 386 if ( !_rxBasicLibraries->hasByName( aStdLibName ) ) 387 { 388 _rxBasicLibraries->createLibrary( aStdLibName ); 389 } 390 // as well as in the dialog container 391 if ( !_rxDialogLibraries->hasByName( aStdLibName ) ) 392 { 393 _rxDialogLibraries->createLibrary( aStdLibName ); 394 } 395 } 396 catch( const Exception& ) 397 { 398 DBG_UNHANDLED_EXCEPTION("basic"); 399 } 400 } 401 impl_createManagerForModel(BasicManagerStore::iterator location,const Reference<XModel> & _rxDocumentModel)402 bool ImplRepository::impl_createManagerForModel( BasicManagerStore::iterator location, const Reference< XModel >& _rxDocumentModel ) 403 { 404 auto & _out_rpBasicManager = location->second; 405 406 StarBASIC* pAppBasic = impl_getDefaultAppBasicLibrary(); 407 408 _out_rpBasicManager = nullptr; 409 Reference< XStorage > xStorage; 410 if ( !impl_getDocumentStorage_nothrow( _rxDocumentModel, xStorage ) ) 411 { 412 m_aStore.erase(location); 413 // the document is not able to provide the storage it is based on. 414 return false; 415 } 416 Reference<XStorageBasedLibraryContainer> xBasicLibs; 417 Reference<XStorageBasedLibraryContainer> xDialogLibs; 418 if ( !impl_getDocumentLibraryContainers_nothrow( _rxDocumentModel, xBasicLibs, xDialogLibs ) ) 419 { 420 m_aStore.erase(location); 421 // the document does not have BasicLibraries and DialogLibraries 422 return false; 423 } 424 425 if ( xStorage.is() ) 426 { 427 // load BASIC-manager 428 SfxErrorContext aErrContext( ERRCTX_SFX_LOADBASIC, 429 ::comphelper::DocumentInfo::getDocumentTitle( _rxDocumentModel ) ); 430 OUString aAppBasicDir = SvtPathOptions().GetBasicPath(); 431 432 // Storage and BaseURL are only needed by binary documents! 433 rtl::Reference<SotStorage> xDummyStor = new SotStorage(OUString()); 434 _out_rpBasicManager.reset(new BasicManager( *xDummyStor, u"" /* TODO/LATER: xStorage */, 435 pAppBasic, 436 &aAppBasicDir, true )); 437 if ( !_out_rpBasicManager->GetErrors().empty() ) 438 { 439 // handle errors 440 std::vector<BasicError>& aErrors = _out_rpBasicManager->GetErrors(); 441 for(const auto& rError : aErrors) 442 { 443 // show message to user 444 if ( ErrorHandler::HandleError( rError.GetErrorId() ) == DialogMask::ButtonsCancel ) 445 { 446 // user wants to break loading of BASIC-manager 447 _out_rpBasicManager.reset(); 448 xStorage.clear(); 449 break; 450 } 451 } 452 } 453 } 454 455 // not loaded? 456 if ( !xStorage.is() ) 457 { 458 // create new BASIC-manager 459 StarBASIC* pBasic = new StarBASIC( pAppBasic ); 460 pBasic->SetFlag( SbxFlagBits::ExtSearch ); 461 _out_rpBasicManager.reset(new BasicManager( pBasic, nullptr, true )); 462 } 463 464 // knit the containers with the BasicManager 465 LibraryContainerInfo aInfo( xBasicLibs, xDialogLibs, dynamic_cast< SfxScriptLibraryContainer* >( xBasicLibs.get() ) ); 466 OSL_ENSURE( aInfo.mpOldBasicPassword, "ImplRepository::impl_createManagerForModel: wrong BasicLibraries implementation!" ); 467 _out_rpBasicManager->SetLibraryContainerInfo( aInfo ); 468 469 // initialize the containers 470 impl_initDocLibraryContainers_nothrow( xBasicLibs, xDialogLibs ); 471 472 // so that also dialogs etc. could be 'qualified' addressed 473 _out_rpBasicManager->GetLib(0)->SetParent( pAppBasic ); 474 475 // global properties in the document's Basic 476 _out_rpBasicManager->SetGlobalUNOConstant( u"ThisComponent"_ustr, css::uno::Any( _rxDocumentModel ) ); 477 478 // notify 479 impl_notifyCreationListeners( _rxDocumentModel, *_out_rpBasicManager ); 480 481 // register as listener for this model being disposed/closed 482 OSL_ENSURE( _rxDocumentModel.is(), "ImplRepository::impl_createManagerForModel: the document must be an XComponent!" ); 483 assert(impl_hasLocationForModel(_rxDocumentModel)); 484 startComponentListening( _rxDocumentModel ); 485 486 bool bOk = false; 487 // startComponentListening may fail in a disposed _rxDocumentModel, in which case _out_rpBasicManager will be removed 488 // from the map and destroyed 489 if (impl_hasLocationForModel(_rxDocumentModel)) 490 { 491 bOk = true; 492 // register as listener for the BasicManager being destroyed 493 StartListening( *_out_rpBasicManager ); 494 } 495 496 // #i104876: Library container must not be modified just after 497 // creation. This happens as side effect when creating default 498 // "Standard" libraries and needs to be corrected here 499 xBasicLibs->setModified( false ); 500 xDialogLibs->setModified( false ); 501 return bOk; 502 } 503 impl_getDocumentStorage_nothrow(const Reference<XModel> & _rxDocument,Reference<XStorage> & _out_rStorage)504 bool ImplRepository::impl_getDocumentStorage_nothrow( const Reference< XModel >& _rxDocument, Reference< XStorage >& _out_rStorage ) 505 { 506 _out_rStorage.clear(); 507 try 508 { 509 Reference< XStorageBasedDocument > xStorDoc( _rxDocument, UNO_QUERY_THROW ); 510 _out_rStorage.set( xStorDoc->getDocumentStorage() ); 511 } 512 catch( const Exception& ) 513 { 514 DBG_UNHANDLED_EXCEPTION("basic"); 515 return false; 516 } 517 return true; 518 } 519 520 impl_getDocumentLibraryContainers_nothrow(const Reference<XModel> & _rxDocument,Reference<XStorageBasedLibraryContainer> & _out_rxBasicLibraries,Reference<XStorageBasedLibraryContainer> & _out_rxDialogLibraries)521 bool ImplRepository::impl_getDocumentLibraryContainers_nothrow( const Reference< XModel >& _rxDocument, 522 Reference<XStorageBasedLibraryContainer>& _out_rxBasicLibraries, Reference<XStorageBasedLibraryContainer>& _out_rxDialogLibraries ) 523 { 524 _out_rxBasicLibraries.clear(); 525 _out_rxDialogLibraries.clear(); 526 try 527 { 528 Reference< XEmbeddedScripts > xScripts( _rxDocument, UNO_QUERY_THROW ); 529 _out_rxBasicLibraries.set( xScripts->getBasicLibraries() ); 530 _out_rxDialogLibraries.set( xScripts->getDialogLibraries() ); 531 } 532 catch( const Exception& ) 533 { 534 DBG_UNHANDLED_EXCEPTION("basic"); 535 } 536 return _out_rxBasicLibraries.is() && _out_rxDialogLibraries.is(); 537 } 538 539 impl_removeFromRepository(const BasicManagerStore::iterator & _pos)540 void ImplRepository::impl_removeFromRepository( const BasicManagerStore::iterator& _pos ) 541 { 542 OSL_PRECOND( _pos != m_aStore.end(), "ImplRepository::impl_removeFromRepository: invalid position!" ); 543 544 std::unique_ptr<BasicManager> pManager = std::move(_pos->second); 545 Reference<XModel> xModel(_pos->first, UNO_QUERY); 546 547 // *first* remove from map (else Notify won't work properly) 548 m_aStore.erase( _pos ); 549 550 EndListening( *pManager ); 551 552 assert(xModel.is()); 553 if (xModel.is()) 554 stopComponentListening(xModel); 555 } 556 557 _disposing(const css::lang::EventObject & _rSource)558 void ImplRepository::_disposing( const css::lang::EventObject& _rSource ) 559 { 560 SolarMutexGuard g; 561 562 Reference< XInterface > xNormalizedSource( _rSource.Source, UNO_QUERY ); 563 564 BasicManagerStore::iterator it = std::find_if(m_aStore.begin(), m_aStore.end(), 565 [&xNormalizedSource](BasicManagerStore::reference rEntry) { 566 return rEntry.first.get() == xNormalizedSource.get(); }); 567 if (it != m_aStore.end()) 568 { 569 impl_removeFromRepository( it ); 570 return; 571 } 572 573 OSL_FAIL( "ImplRepository::_disposing: where does this come from?" ); 574 } 575 576 Notify(SfxBroadcaster & _rBC,const SfxHint & _rHint)577 void ImplRepository::Notify( SfxBroadcaster& _rBC, const SfxHint& _rHint ) 578 { 579 if ( _rHint.GetId() != SfxHintId::Dying ) 580 // not interested in 581 return; 582 583 BasicManager* pManager = dynamic_cast< BasicManager* >( &_rBC ); 584 OSL_ENSURE( pManager, "ImplRepository::Notify: where does this come from?" ); 585 586 BasicManagerStore::iterator it = std::find_if(m_aStore.begin(), m_aStore.end(), 587 [&pManager](BasicManagerStore::reference rEntry) { return rEntry.second.get() == pManager; }); 588 if (it != m_aStore.end()) 589 { 590 // a BasicManager which is still in our repository is being deleted. 591 // That's bad, since by definition, we *own* all instances in our 592 // repository. 593 OSL_FAIL( "ImplRepository::Notify: nobody should tamper with the managers, except ourself!" ); 594 m_aStore.erase( it ); 595 } 596 } 597 getDocumentBasicManager(const Reference<XModel> & _rxDocumentModel)598 BasicManager* BasicManagerRepository::getDocumentBasicManager( const Reference< XModel >& _rxDocumentModel ) 599 { 600 return ImplRepository::Instance().getDocumentBasicManager( _rxDocumentModel ); 601 } 602 getApplicationBasicManager()603 BasicManager* BasicManagerRepository::getApplicationBasicManager() 604 { 605 return ImplRepository::Instance().getOrCreateApplicationBasicManager(); 606 } 607 resetApplicationBasicManager()608 void BasicManagerRepository::resetApplicationBasicManager() 609 { 610 ImplRepository::setApplicationBasicManager( nullptr ); 611 } 612 registerCreationListener(BasicManagerCreationListener & _rListener)613 void BasicManagerRepository::registerCreationListener( BasicManagerCreationListener& _rListener ) 614 { 615 ImplRepository::Instance().registerCreationListener( _rListener ); 616 } 617 revokeCreationListener(BasicManagerCreationListener & _rListener)618 void BasicManagerRepository::revokeCreationListener( BasicManagerCreationListener& _rListener ) 619 { 620 ImplRepository::Instance().revokeCreationListener( _rListener ); 621 } 622 623 } // namespace basic 624 625 626 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 627
