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