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_basic.hxx" 26 #include <basic/basicmanagerrepository.hxx> 27 #include <basic/basmgr.hxx> 28 #include "scriptcont.hxx" 29 #include "dlgcont.hxx" 30 #include <basic/sbuno.hxx> 31 #include "sbintern.hxx" 32 33 /** === begin UNO includes === **/ 34 #include <com/sun/star/beans/XPropertySet.hpp> 35 #include <com/sun/star/document/XStorageBasedDocument.hpp> 36 #include <com/sun/star/document/XEmbeddedScripts.hpp> 37 /** === end UNO includes === **/ 38 #include <svtools/ehdl.hxx> 39 #include <svtools/sfxecode.hxx> 40 #include <unotools/pathoptions.hxx> 41 #include <svl/smplhint.hxx> 42 #include <vcl/svapp.hxx> 43 #include <tools/debug.hxx> 44 #include <tools/diagnose_ex.h> 45 #include <tools/urlobj.hxx> 46 #include <comphelper/stl_types.hxx> 47 #include <comphelper/processfactory.hxx> 48 #include <comphelper/documentinfo.hxx> 49 #include <unotools/eventlisteneradapter.hxx> 50 51 #ifndef INCLUDED_OSL_DOUBLECHECKEDLOCKING_H 52 #include <rtl/instance.hxx> 53 #endif 54 55 #include <map> 56 57 //........................................................................ 58 namespace basic 59 { 60 //........................................................................ 61 62 /** === begin UNO using === **/ 63 using ::com::sun::star::uno::Reference; 64 using ::com::sun::star::frame::XModel; 65 using ::com::sun::star::uno::XInterface; 66 using ::com::sun::star::uno::UNO_QUERY; 67 using ::com::sun::star::embed::XStorage; 68 using ::com::sun::star::script::XPersistentLibraryContainer; 69 using ::com::sun::star::uno::Any; 70 using ::com::sun::star::lang::XMultiServiceFactory; 71 using ::com::sun::star::uno::UNO_QUERY_THROW; 72 using ::com::sun::star::beans::XPropertySet; 73 using ::com::sun::star::uno::Exception; 74 using ::com::sun::star::document::XStorageBasedDocument; 75 using ::com::sun::star::lang::XComponent; 76 using ::com::sun::star::document::XEmbeddedScripts; 77 /** === end UNO using === **/ 78 79 typedef BasicManager* BasicManagerPointer; 80 typedef ::std::map< Reference< XInterface >, BasicManagerPointer, ::comphelper::OInterfaceCompare< XInterface > > BasicManagerStore; 81 82 typedef ::std::vector< BasicManagerCreationListener* > CreationListeners; 83 84 //==================================================================== 85 //= BasicManagerCleaner 86 //==================================================================== 87 /// is the only instance which is allowed to delete a BasicManager instance 88 class BasicManagerCleaner 89 { 90 public: deleteBasicManager(BasicManager * & _rpManager)91 static void deleteBasicManager( BasicManager*& _rpManager ) 92 { 93 delete _rpManager; 94 _rpManager = NULL; 95 } 96 }; 97 98 //==================================================================== 99 //= ImplRepository 100 //==================================================================== 101 class ImplRepository : public ::utl::OEventListenerAdapter, public SfxListener 102 { 103 private: 104 friend struct CreateImplRepository; 105 ImplRepository(); 106 107 private: 108 ::osl::Mutex m_aMutex; 109 BasicManagerStore m_aStore; 110 CreationListeners m_aCreationListeners; 111 112 public: 113 static ImplRepository& Instance(); 114 115 BasicManager* getDocumentBasicManager( const Reference< XModel >& _rxDocumentModel ); 116 BasicManager* getApplicationBasicManager( bool _bCreate ); 117 void setApplicationBasicManager( BasicManager* _pBasicManager ); 118 void registerCreationListener( BasicManagerCreationListener& _rListener ); 119 void revokeCreationListener( BasicManagerCreationListener& _rListener ); 120 121 private: 122 /** retrieves the location at which the BasicManager for the given model 123 is stored. 124 125 If previously, the BasicManager for this model has never been requested, 126 then the model is added to the map, with an initial NULL BasicManager. 127 128 @param _rxDocumentModel 129 the model whose BasicManager's location is to be retrieved. Must not be <NULL/>. 130 131 @precond 132 our mutex is locked 133 */ 134 BasicManagerPointer& 135 impl_getLocationForModel( const Reference< XModel >& _rxDocumentModel ); 136 137 /** creates a new BasicManager instance for the given model 138 139 @param _out_rpBasicManager 140 reference to the pointer variable that will hold the new 141 BasicManager. 142 143 @param _rxDocumentModel 144 the model whose BasicManager will be created. Must not be <NULL/>. 145 */ 146 void impl_createManagerForModel( 147 BasicManagerPointer& _out_rpBasicManager, 148 const Reference< XModel >& _rxDocumentModel ); 149 150 /** creates the application-wide BasicManager 151 */ 152 BasicManagerPointer impl_createApplicationBasicManager(); 153 154 /** notifies all listeners which expressed interest in the creation of BasicManager instances. 155 */ 156 void impl_notifyCreationListeners( 157 const Reference< XModel >& _rxDocumentModel, 158 BasicManager& _rManager 159 ); 160 161 /** retrieves the current storage of a given document 162 163 @param _rxDocument 164 the document whose storage is to be retrieved. 165 166 @param _out_rStorage 167 takes the storage upon successful return. Note that this might be <NULL/> even 168 if <TRUE/> is returned. In this case, the document has not yet been saved. 169 170 @return 171 <TRUE/> if the storage could be successfully retrieved (in which case 172 <arg>_out_rStorage</arg> might or might not be <NULL/>), <FALSE/> otherwise. 173 In the latter case, processing this document should stop. 174 */ 175 bool impl_getDocumentStorage_nothrow( const Reference< XModel >& _rxDocument, Reference< XStorage >& _out_rStorage ); 176 177 /** retrieves the containers for Basic and Dialog libraries for a given document 178 179 @param _rxDocument 180 the document whose containers are to be retrieved. 181 182 @param _out_rxBasicLibraries 183 takes the basic library container upon successful return 184 185 @param _out_rxDialogLibraries 186 takes the dialog library container upon successful return 187 188 @return 189 <TRUE/> if and only if both containers exist, and could successfully be retrieved 190 */ 191 bool impl_getDocumentLibraryContainers_nothrow( 192 const Reference< XModel >& _rxDocument, 193 Reference< XPersistentLibraryContainer >& _out_rxBasicLibraries, 194 Reference< XPersistentLibraryContainer >& _out_rxDialogLibraries 195 ); 196 197 /** initializes the given library containers, which belong to a document 198 */ 199 void impl_initDocLibraryContainers_nothrow( 200 const Reference< XPersistentLibraryContainer >& _rxBasicLibraries, 201 const Reference< XPersistentLibraryContainer >& _rxDialogLibraries 202 ); 203 204 // OEventListenerAdapter overridables 205 virtual void _disposing( const ::com::sun::star::lang::EventObject& _rSource ); 206 207 // SfxListener overridables 208 virtual void Notify( SfxBroadcaster& _rBC, const SfxHint& _rHint ); 209 210 /** removes the Model/BasicManager pair given by iterator from our store 211 */ 212 void impl_removeFromRepository( BasicManagerStore::iterator _pos ); 213 214 private: 215 StarBASIC* impl_getDefaultAppBasicLibrary(); 216 }; 217 218 //==================================================================== 219 //= CreateImplRepository 220 //==================================================================== 221 struct CreateImplRepository 222 { operator ()basic::CreateImplRepository223 ImplRepository* operator()() 224 { 225 static ImplRepository* pRepository = new ImplRepository; 226 return pRepository; 227 } 228 }; 229 230 231 //==================================================================== 232 //= ImplRepository 233 //==================================================================== 234 //-------------------------------------------------------------------- ImplRepository()235 ImplRepository::ImplRepository() 236 { 237 } 238 239 //-------------------------------------------------------------------- Instance()240 ImplRepository& ImplRepository::Instance() 241 { 242 return *rtl_Instance< ImplRepository, CreateImplRepository, ::osl::MutexGuard, ::osl::GetGlobalMutex >:: 243 create( CreateImplRepository(), ::osl::GetGlobalMutex() ); 244 } 245 246 //-------------------------------------------------------------------- getDocumentBasicManager(const Reference<XModel> & _rxDocumentModel)247 BasicManager* ImplRepository::getDocumentBasicManager( const Reference< XModel >& _rxDocumentModel ) 248 { 249 ::osl::MutexGuard aGuard( m_aMutex ); 250 251 /* #163556# (DR) - This function may be called recursively while 252 constructing the Basic manager and loading the Basic storage. By 253 passing the map entry received from impl_getLocationForModel() to 254 the function impl_createManagerForModel(), the new Basic manager 255 will be put immediately into the map of existing Basic managers, 256 thus a recursive call of this function will find and return it 257 without creating another instance. 258 */ 259 BasicManagerPointer& pBasicManager = impl_getLocationForModel( _rxDocumentModel ); 260 if ( pBasicManager == NULL ) 261 impl_createManagerForModel( pBasicManager, _rxDocumentModel ); 262 263 return pBasicManager; 264 } 265 266 //-------------------------------------------------------------------- getApplicationBasicManager(bool _bCreate)267 BasicManager* ImplRepository::getApplicationBasicManager( bool _bCreate ) 268 { 269 ::osl::MutexGuard aGuard( m_aMutex ); 270 271 BasicManager* pAppManager = GetSbData()->pAppBasMgr; 272 if ( ( pAppManager == NULL ) && _bCreate ) 273 pAppManager = impl_createApplicationBasicManager(); 274 275 return pAppManager; 276 } 277 278 //-------------------------------------------------------------------- setApplicationBasicManager(BasicManager * _pBasicManager)279 void ImplRepository::setApplicationBasicManager( BasicManager* _pBasicManager ) 280 { 281 ::osl::MutexGuard aGuard( m_aMutex ); 282 283 BasicManager* pPreviousManager = getApplicationBasicManager( false ); 284 BasicManagerCleaner::deleteBasicManager( pPreviousManager ); 285 286 GetSbData()->pAppBasMgr = _pBasicManager; 287 } 288 289 //-------------------------------------------------------------------- impl_createApplicationBasicManager()290 BasicManager* ImplRepository::impl_createApplicationBasicManager() 291 { 292 ::osl::MutexGuard aGuard( m_aMutex ); 293 OSL_PRECOND( getApplicationBasicManager( false ) == NULL, "ImplRepository::impl_createApplicationBasicManager: there already is one!" ); 294 295 // Determine Directory 296 SvtPathOptions aPathCFG; 297 String aAppBasicDir( aPathCFG.GetBasicPath() ); 298 if ( !aAppBasicDir.Len() ) 299 aPathCFG.SetBasicPath( String::CreateFromAscii("$(prog)") ); 300 301 // #58293# soffice.new search only in user dir => first dir 302 String aAppFirstBasicDir = aAppBasicDir.GetToken(1); 303 304 // Create basic and load it 305 // MT: #47347# AppBasicDir is now a PATH 306 INetURLObject aAppBasic( SvtPathOptions().SubstituteVariable( String::CreateFromAscii("$(progurl)") ) ); 307 aAppBasic.insertName( Application::GetAppName() ); 308 309 BasicManager* pBasicManager = new BasicManager( new StarBASIC, &aAppBasicDir ); 310 setApplicationBasicManager( pBasicManager ); 311 312 // Als Destination das erste Dir im Pfad: 313 String aFileName( aAppBasic.getName() ); 314 aAppBasic = INetURLObject( aAppBasicDir.GetToken(1) ); 315 DBG_ASSERT( aAppBasic.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); 316 aAppBasic.insertName( aFileName ); 317 pBasicManager->SetStorageName( aAppBasic.PathToFileName() ); 318 319 // Basic container 320 SfxScriptLibraryContainer* pBasicCont = new SfxScriptLibraryContainer( Reference< XStorage >() ); 321 Reference< XPersistentLibraryContainer > xBasicCont( pBasicCont ); 322 pBasicCont->setBasicManager( pBasicManager ); 323 324 // Dialog container 325 SfxDialogLibraryContainer* pDialogCont = new SfxDialogLibraryContainer( Reference< XStorage >() ); 326 Reference< XPersistentLibraryContainer > xDialogCont( pDialogCont ); 327 328 LibraryContainerInfo aInfo( xBasicCont, xDialogCont, static_cast< OldBasicPassword* >( pBasicCont ) ); 329 pBasicManager->SetLibraryContainerInfo( aInfo ); 330 331 // global constants 332 333 // StarDesktop 334 Reference< XMultiServiceFactory > xSMgr = ::comphelper::getProcessServiceFactory(); 335 pBasicManager->SetGlobalUNOConstant( 336 "StarDesktop", 337 makeAny( xSMgr->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ) ) ) 338 ); 339 340 // (BasicLibraries and DialogLibraries have automatically been added in SetLibraryContainerInfo) 341 342 // notify 343 impl_notifyCreationListeners( NULL, *pBasicManager ); 344 345 // outta here 346 return pBasicManager; 347 } 348 349 //-------------------------------------------------------------------- registerCreationListener(BasicManagerCreationListener & _rListener)350 void ImplRepository::registerCreationListener( BasicManagerCreationListener& _rListener ) 351 { 352 ::osl::MutexGuard aGuard( m_aMutex ); 353 m_aCreationListeners.push_back( &_rListener ); 354 } 355 356 //-------------------------------------------------------------------- revokeCreationListener(BasicManagerCreationListener & _rListener)357 void ImplRepository::revokeCreationListener( BasicManagerCreationListener& _rListener ) 358 { 359 ::osl::MutexGuard aGuard( m_aMutex ); 360 CreationListeners::iterator pos = ::std::find( m_aCreationListeners.begin(), m_aCreationListeners.end(), &_rListener ); 361 if ( pos != m_aCreationListeners.end() ) 362 m_aCreationListeners.erase( pos ); 363 else { 364 DBG_ERROR( "ImplRepository::revokeCreationListener: listener is not registered!" ); 365 } 366 } 367 368 //-------------------------------------------------------------------- impl_notifyCreationListeners(const Reference<XModel> & _rxDocumentModel,BasicManager & _rManager)369 void ImplRepository::impl_notifyCreationListeners( const Reference< XModel >& _rxDocumentModel, BasicManager& _rManager ) 370 { 371 for ( CreationListeners::const_iterator loop = m_aCreationListeners.begin(); 372 loop != m_aCreationListeners.end(); 373 ++loop 374 ) 375 { 376 (*loop)->onBasicManagerCreated( _rxDocumentModel, _rManager ); 377 } 378 } 379 380 //-------------------------------------------------------------------- impl_getDefaultAppBasicLibrary()381 StarBASIC* ImplRepository::impl_getDefaultAppBasicLibrary() 382 { 383 BasicManager* pAppManager = getApplicationBasicManager( true ); 384 385 StarBASIC* pAppBasic = pAppManager ? pAppManager->GetLib(0) : NULL; 386 DBG_ASSERT( pAppBasic != NULL, "impl_getApplicationBasic: unable to determine the default application's Basic library!" ); 387 return pAppBasic; 388 } 389 390 //-------------------------------------------------------------------- impl_getLocationForModel(const Reference<XModel> & _rxDocumentModel)391 BasicManagerPointer& ImplRepository::impl_getLocationForModel( const Reference< XModel >& _rxDocumentModel ) 392 { 393 Reference< XInterface > xNormalized( _rxDocumentModel, UNO_QUERY ); 394 DBG_ASSERT( xNormalized.is(), "ImplRepository::impl_getLocationForModel: invalid model!" ); 395 396 BasicManagerPointer& location = m_aStore[ xNormalized ]; 397 return location; 398 } 399 400 //-------------------------------------------------------------------- impl_initDocLibraryContainers_nothrow(const Reference<XPersistentLibraryContainer> & _rxBasicLibraries,const Reference<XPersistentLibraryContainer> & _rxDialogLibraries)401 void ImplRepository::impl_initDocLibraryContainers_nothrow( const Reference< XPersistentLibraryContainer >& _rxBasicLibraries, const Reference< XPersistentLibraryContainer >& _rxDialogLibraries ) 402 { 403 OSL_PRECOND( _rxBasicLibraries.is() && _rxDialogLibraries.is(), 404 "ImplRepository::impl_initDocLibraryContainers_nothrow: illegal library containers, this will crash!" ); 405 406 try 407 { 408 // ensure there's a standard library in the basic container 409 ::rtl::OUString aStdLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) ); 410 if ( !_rxBasicLibraries->hasByName( aStdLibName ) ) 411 _rxBasicLibraries->createLibrary( aStdLibName ); 412 // as well as in the dialog container 413 if ( !_rxDialogLibraries->hasByName( aStdLibName ) ) 414 _rxDialogLibraries->createLibrary( aStdLibName ); 415 } 416 catch( const Exception& ) 417 { 418 DBG_UNHANDLED_EXCEPTION(); 419 } 420 } 421 422 //-------------------------------------------------------------------- impl_createManagerForModel(BasicManagerPointer & _out_rpBasicManager,const Reference<XModel> & _rxDocumentModel)423 void ImplRepository::impl_createManagerForModel( BasicManagerPointer& _out_rpBasicManager, const Reference< XModel >& _rxDocumentModel ) 424 { 425 StarBASIC* pAppBasic = impl_getDefaultAppBasicLibrary(); 426 427 _out_rpBasicManager = 0; 428 Reference< XStorage > xStorage; 429 if ( !impl_getDocumentStorage_nothrow( _rxDocumentModel, xStorage ) ) 430 // the document is not able to provide the storage it is based on. 431 return; 432 433 Reference< XPersistentLibraryContainer > xBasicLibs; 434 Reference< XPersistentLibraryContainer > xDialogLibs; 435 if ( !impl_getDocumentLibraryContainers_nothrow( _rxDocumentModel, xBasicLibs, xDialogLibs ) ) 436 // the document does not have BasicLibraries and DialogLibraries 437 return; 438 439 if ( xStorage.is() ) 440 { 441 // load BASIC-manager 442 SfxErrorContext aErrContext( ERRCTX_SFX_LOADBASIC, 443 ::comphelper::DocumentInfo::getDocumentTitle( _rxDocumentModel ) ); 444 String aAppBasicDir = SvtPathOptions().GetBasicPath(); 445 446 // Storage and BaseURL are only needed by binary documents! 447 SotStorageRef xDummyStor = new SotStorage( ::rtl::OUString() ); 448 _out_rpBasicManager = new BasicManager( *xDummyStor, String() /* TODO/LATER: xStorage */, 449 pAppBasic, 450 &aAppBasicDir, sal_True ); 451 if ( _out_rpBasicManager->HasErrors() ) 452 { 453 // handle errors 454 BasicError* pErr = _out_rpBasicManager->GetFirstError(); 455 while ( pErr ) 456 { 457 // show message to user 458 if ( ERRCODE_BUTTON_CANCEL == ErrorHandler::HandleError( pErr->GetErrorId() ) ) 459 { 460 // user wants to break loading of BASIC-manager 461 BasicManagerCleaner::deleteBasicManager( _out_rpBasicManager ); 462 xStorage.clear(); 463 break; 464 } 465 pErr = _out_rpBasicManager->GetNextError(); 466 } 467 } 468 } 469 470 // not loaded? 471 if ( !xStorage.is() ) 472 { 473 // create new BASIC-manager 474 StarBASIC* pBasic = new StarBASIC( pAppBasic ); 475 pBasic->SetFlag( SBX_EXTSEARCH ); 476 _out_rpBasicManager = new BasicManager( pBasic, NULL, sal_True ); 477 } 478 479 // knit the containers with the BasicManager 480 LibraryContainerInfo aInfo( xBasicLibs, xDialogLibs, dynamic_cast< OldBasicPassword* >( xBasicLibs.get() ) ); 481 OSL_ENSURE( aInfo.mpOldBasicPassword, "ImplRepository::impl_createManagerForModel: wrong BasicLibraries implementation!" ); 482 _out_rpBasicManager->SetLibraryContainerInfo( aInfo ); 483 //pBasicCont->setBasicManager( _out_rpBasicManager ); 484 // that's not needed anymore today. The containers will retrieve their associated 485 // BasicManager from the BasicManagerRepository, when needed. 486 487 // initialize the containers 488 impl_initDocLibraryContainers_nothrow( xBasicLibs, xDialogLibs ); 489 490 // damit auch Dialoge etc. 'qualifiziert' angesprochen werden k"onnen 491 _out_rpBasicManager->GetLib(0)->SetParent( pAppBasic ); 492 493 // global properties in the document's Basic 494 _out_rpBasicManager->SetGlobalUNOConstant( "ThisComponent", makeAny( _rxDocumentModel ) ); 495 496 // notify 497 impl_notifyCreationListeners( _rxDocumentModel, *_out_rpBasicManager ); 498 499 // register as listener for this model being disposed/closed 500 Reference< XComponent > xDocumentComponent( _rxDocumentModel, UNO_QUERY ); 501 OSL_ENSURE( xDocumentComponent.is(), "ImplRepository::impl_createManagerForModel: the document must be an XComponent!" ); 502 startComponentListening( xDocumentComponent ); 503 504 // register as listener for the BasicManager being destroyed 505 StartListening( *_out_rpBasicManager ); 506 507 // #i104876: Library container must not be modified just after 508 // creation. This happens as side effect when creating default 509 // "Standard" libraries and needs to be corrected here 510 xBasicLibs->setModified( sal_False ); 511 xDialogLibs->setModified( sal_False ); 512 513 } 514 515 //-------------------------------------------------------------------- impl_getDocumentStorage_nothrow(const Reference<XModel> & _rxDocument,Reference<XStorage> & _out_rStorage)516 bool ImplRepository::impl_getDocumentStorage_nothrow( const Reference< XModel >& _rxDocument, Reference< XStorage >& _out_rStorage ) 517 { 518 _out_rStorage.clear(); 519 try 520 { 521 Reference< XStorageBasedDocument > xStorDoc( _rxDocument, UNO_QUERY_THROW ); 522 _out_rStorage.set( xStorDoc->getDocumentStorage() ); 523 } 524 catch( const Exception& ) 525 { 526 DBG_UNHANDLED_EXCEPTION(); 527 return false; 528 } 529 return true; 530 } 531 532 //-------------------------------------------------------------------- impl_getDocumentLibraryContainers_nothrow(const Reference<XModel> & _rxDocument,Reference<XPersistentLibraryContainer> & _out_rxBasicLibraries,Reference<XPersistentLibraryContainer> & _out_rxDialogLibraries)533 bool ImplRepository::impl_getDocumentLibraryContainers_nothrow( const Reference< XModel >& _rxDocument, 534 Reference< XPersistentLibraryContainer >& _out_rxBasicLibraries, Reference< XPersistentLibraryContainer >& _out_rxDialogLibraries ) 535 { 536 _out_rxBasicLibraries.clear(); 537 _out_rxDialogLibraries.clear(); 538 try 539 { 540 Reference< XEmbeddedScripts > xScripts( _rxDocument, UNO_QUERY_THROW ); 541 _out_rxBasicLibraries.set( xScripts->getBasicLibraries(), UNO_QUERY_THROW ); 542 _out_rxDialogLibraries.set( xScripts->getDialogLibraries(), UNO_QUERY_THROW ); 543 } 544 catch( const Exception& ) 545 { 546 DBG_UNHANDLED_EXCEPTION(); 547 } 548 return _out_rxBasicLibraries.is() && _out_rxDialogLibraries.is(); 549 } 550 551 //-------------------------------------------------------------------- impl_removeFromRepository(BasicManagerStore::iterator _pos)552 void ImplRepository::impl_removeFromRepository( BasicManagerStore::iterator _pos ) 553 { 554 OSL_PRECOND( _pos != m_aStore.end(), "ImplRepository::impl_removeFromRepository: invalid position!" ); 555 556 BasicManager* pManager = _pos->second; 557 558 // *first* remove from map (else Notify won't work properly) 559 m_aStore.erase( _pos ); 560 561 // *then* delete the BasicManager 562 EndListening( *pManager ); 563 BasicManagerCleaner::deleteBasicManager( pManager ); 564 } 565 566 //-------------------------------------------------------------------- _disposing(const::com::sun::star::lang::EventObject & _rSource)567 void ImplRepository::_disposing( const ::com::sun::star::lang::EventObject& _rSource ) 568 { 569 ::osl::MutexGuard aGuard( m_aMutex ); 570 571 Reference< XInterface > xNormalizedSource( _rSource.Source, UNO_QUERY ); 572 #if OSL_DEBUG_LEVEL > 0 573 bool bFound = false; 574 #endif 575 576 for ( BasicManagerStore::iterator loop = m_aStore.begin(); 577 loop != m_aStore.end(); 578 ++loop 579 ) 580 { 581 if ( loop->first.get() == xNormalizedSource.get() ) 582 { 583 impl_removeFromRepository( loop ); 584 #if OSL_DEBUG_LEVEL > 0 585 bFound = true; 586 #endif 587 break; 588 } 589 } 590 591 OSL_ENSURE( bFound, "ImplRepository::_disposing: where does this come from?" ); 592 } 593 594 //-------------------------------------------------------------------- Notify(SfxBroadcaster & _rBC,const SfxHint & _rHint)595 void ImplRepository::Notify( SfxBroadcaster& _rBC, const SfxHint& _rHint ) 596 { 597 const SfxSimpleHint* pSimpleHint = dynamic_cast< const SfxSimpleHint* >( &_rHint ); 598 if ( !pSimpleHint || ( pSimpleHint->GetId() != SFX_HINT_DYING ) ) 599 // not interested in 600 return; 601 602 BasicManager* pManager = dynamic_cast< BasicManager* >( &_rBC ); 603 OSL_ENSURE( pManager, "ImplRepository::Notify: where does this come from?" ); 604 605 for ( BasicManagerStore::iterator loop = m_aStore.begin(); 606 loop != m_aStore.end(); 607 ++loop 608 ) 609 { 610 if ( loop->second == pManager ) 611 { 612 // a BasicManager which is still in our repository is being deleted. 613 // That's bad, since by definition, we *own* all instances in our 614 // repository. 615 OSL_ENSURE( false, "ImplRepository::Notify: nobody should tamper with the managers, except ourself!" ); 616 m_aStore.erase( loop ); 617 break; 618 } 619 } 620 } 621 622 //==================================================================== 623 //= BasicManagerRepository 624 //==================================================================== 625 //-------------------------------------------------------------------- getDocumentBasicManager(const Reference<XModel> & _rxDocumentModel)626 BasicManager* BasicManagerRepository::getDocumentBasicManager( const Reference< XModel >& _rxDocumentModel ) 627 { 628 return ImplRepository::Instance().getDocumentBasicManager( _rxDocumentModel ); 629 } 630 631 //-------------------------------------------------------------------- getApplicationBasicManager(bool _bCreate)632 BasicManager* BasicManagerRepository::getApplicationBasicManager( bool _bCreate ) 633 { 634 return ImplRepository::Instance().getApplicationBasicManager( _bCreate ); 635 } 636 637 //-------------------------------------------------------------------- resetApplicationBasicManager()638 void BasicManagerRepository::resetApplicationBasicManager() 639 { 640 return ImplRepository::Instance().setApplicationBasicManager( NULL ); 641 } 642 643 //-------------------------------------------------------------------- registerCreationListener(BasicManagerCreationListener & _rListener)644 void BasicManagerRepository::registerCreationListener( BasicManagerCreationListener& _rListener ) 645 { 646 ImplRepository::Instance().registerCreationListener( _rListener ); 647 } 648 649 //-------------------------------------------------------------------- revokeCreationListener(BasicManagerCreationListener & _rListener)650 void BasicManagerRepository::revokeCreationListener( BasicManagerCreationListener& _rListener ) 651 { 652 ImplRepository::Instance().revokeCreationListener( _rListener ); 653 } 654 655 //........................................................................ 656 } // namespace basic 657 //........................................................................ 658 659