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