bump product version to 4.1.6.2
[LibreOffice.git] / basic / source / uno / namecont.cxx
blob816a542611c4b50a8d52866230e4efdd991856b2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
22 #include <com/sun/star/container/XNameContainer.hpp>
23 #include <com/sun/star/container/XContainer.hpp>
24 #include <com/sun/star/embed/ElementModes.hpp>
25 #include <com/sun/star/embed/XTransactedObject.hpp>
26 #include <com/sun/star/lang/XServiceInfo.hpp>
27 #include <vcl/svapp.hxx>
28 #include <osl/mutex.hxx>
29 #include <tools/errinf.hxx>
30 #include <rtl/ustring.hxx>
31 #include <rtl/uri.hxx>
32 #include <rtl/strbuf.hxx>
33 #include <comphelper/processfactory.hxx>
34 #include <comphelper/anytostring.hxx>
36 #include "namecont.hxx"
37 #include <basic/basicmanagerrepository.hxx>
38 #include <tools/diagnose_ex.h>
39 #include <tools/urlobj.hxx>
40 #include <unotools/streamwrap.hxx>
41 #include <unotools/pathoptions.hxx>
42 #include <svtools/sfxecode.hxx>
43 #include <svtools/ehdl.hxx>
44 #include <basic/basmgr.hxx>
45 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
46 #include <com/sun/star/xml/sax/Parser.hpp>
47 #include <com/sun/star/xml/sax/InputSource.hpp>
48 #include <com/sun/star/io/XOutputStream.hpp>
49 #include <com/sun/star/xml/sax/Writer.hpp>
50 #include <com/sun/star/io/XInputStream.hpp>
51 #include <com/sun/star/io/XActiveDataSource.hpp>
52 #include <com/sun/star/beans/XPropertySet.hpp>
53 #include <com/sun/star/uno/DeploymentException.hpp>
54 #include <com/sun/star/lang/DisposedException.hpp>
55 #include <com/sun/star/script/LibraryNotLoadedException.hpp>
56 #include <com/sun/star/script/vba/VBAScriptEventId.hpp>
57 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
58 #include <com/sun/star/util/PathSubstitution.hpp>
59 #include <com/sun/star/util/theMacroExpander.hpp>
60 #include <com/sun/star/deployment/ExtensionManager.hpp>
61 #include <comphelper/storagehelper.hxx>
62 #include <cppuhelper/exc_hlp.hxx>
63 #include <basic/sbmod.hxx>
64 #include <boost/scoped_ptr.hpp>
66 namespace basic
69 using namespace com::sun::star::document;
70 using namespace com::sun::star::container;
71 using namespace com::sun::star::uno;
72 using namespace com::sun::star::lang;
73 using namespace com::sun::star::io;
74 using namespace com::sun::star::ucb;
75 using namespace com::sun::star::script;
76 using namespace com::sun::star::beans;
77 using namespace com::sun::star::xml::sax;
78 using namespace com::sun::star::util;
79 using namespace com::sun::star::task;
80 using namespace com::sun::star::embed;
81 using namespace com::sun::star::frame;
82 using namespace com::sun::star::deployment;
83 using namespace com::sun::star;
84 using namespace cppu;
85 using namespace osl;
87 using com::sun::star::uno::Reference;
89 using ::rtl::Uri;
91 // #i34411: Flag for error handling during migration
92 static bool GbMigrationSuppressErrors = false;
94 //============================================================================
95 // Implementation class NameContainer
97 // Methods XElementAccess
98 Type NameContainer::getElementType()
99 throw(RuntimeException)
101 return mType;
104 sal_Bool NameContainer::hasElements()
105 throw(RuntimeException)
107 sal_Bool bRet = (mnElementCount > 0);
108 return bRet;
111 // Methods XNameAccess
112 Any NameContainer::getByName( const OUString& aName )
113 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
115 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
116 if( aIt == mHashMap.end() )
118 throw NoSuchElementException();
120 sal_Int32 iHashResult = (*aIt).second;
121 Any aRetAny = mValues.getConstArray()[ iHashResult ];
122 return aRetAny;
125 Sequence< OUString > NameContainer::getElementNames()
126 throw(RuntimeException)
128 return mNames;
131 sal_Bool NameContainer::hasByName( const OUString& aName )
132 throw(RuntimeException)
134 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
135 sal_Bool bRet = ( aIt != mHashMap.end() );
136 return bRet;
140 // Methods XNameReplace
141 void NameContainer::replaceByName( const OUString& aName, const Any& aElement )
142 throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
144 Type aAnyType = aElement.getValueType();
145 if( mType != aAnyType )
147 throw IllegalArgumentException();
149 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
150 if( aIt == mHashMap.end() )
152 throw NoSuchElementException();
154 sal_Int32 iHashResult = (*aIt).second;
155 Any aOldElement = mValues.getConstArray()[ iHashResult ];
156 mValues.getArray()[ iHashResult ] = aElement;
159 // Fire event
160 if( maContainerListeners.getLength() > 0 )
162 ContainerEvent aEvent;
163 aEvent.Source = mpxEventSource;
164 aEvent.Accessor <<= aName;
165 aEvent.Element = aElement;
166 aEvent.ReplacedElement = aOldElement;
167 maContainerListeners.notifyEach( &XContainerListener::elementReplaced, aEvent );
170 /* After the container event has been fired (one listener will update the
171 core Basic manager), fire change event. Listeners can rely that the
172 Basic source code of the core Basic manager is up-to-date. */
173 if( maChangesListeners.getLength() > 0 )
175 ChangesEvent aEvent;
176 aEvent.Source = mpxEventSource;
177 aEvent.Base <<= aEvent.Source;
178 aEvent.Changes.realloc( 1 );
179 aEvent.Changes[ 0 ].Accessor <<= aName;
180 aEvent.Changes[ 0 ].Element <<= aElement;
181 aEvent.Changes[ 0 ].ReplacedElement = aOldElement;
182 maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
187 // Methods XNameContainer
188 void NameContainer::insertByName( const OUString& aName, const Any& aElement )
189 throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
191 Type aAnyType = aElement.getValueType();
192 if( mType != aAnyType )
194 throw IllegalArgumentException();
196 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
197 if( aIt != mHashMap.end() )
199 throw ElementExistException();
202 sal_Int32 nCount = mNames.getLength();
203 mNames.realloc( nCount + 1 );
204 mValues.realloc( nCount + 1 );
205 mNames.getArray()[ nCount ] = aName;
206 mValues.getArray()[ nCount ] = aElement;
208 mHashMap[ aName ] = nCount;
209 mnElementCount++;
211 // Fire event
212 if( maContainerListeners.getLength() > 0 )
214 ContainerEvent aEvent;
215 aEvent.Source = mpxEventSource;
216 aEvent.Accessor <<= aName;
217 aEvent.Element = aElement;
218 maContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
221 /* After the container event has been fired (one listener will update the
222 core Basic manager), fire change event. Listeners can rely that the
223 Basic source code of the core Basic manager is up-to-date. */
224 if( maChangesListeners.getLength() > 0 )
226 ChangesEvent aEvent;
227 aEvent.Source = mpxEventSource;
228 aEvent.Base <<= aEvent.Source;
229 aEvent.Changes.realloc( 1 );
230 aEvent.Changes[ 0 ].Accessor <<= aName;
231 aEvent.Changes[ 0 ].Element <<= aElement;
232 maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
236 void NameContainer::removeByName( const OUString& aName )
237 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
239 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
240 if( aIt == mHashMap.end() )
242 OUString sMessage = "\"" + aName + "\" not found";
243 throw NoSuchElementException(sMessage, uno::Reference< uno::XInterface >());
246 sal_Int32 iHashResult = (*aIt).second;
247 Any aOldElement = mValues.getConstArray()[ iHashResult ];
248 mHashMap.erase( aIt );
249 sal_Int32 iLast = mNames.getLength() - 1;
250 if( iLast != iHashResult )
252 OUString* pNames = mNames.getArray();
253 Any* pValues = mValues.getArray();
254 pNames[ iHashResult ] = pNames[ iLast ];
255 pValues[ iHashResult ] = pValues[ iLast ];
256 mHashMap[ pNames[ iHashResult ] ] = iHashResult;
258 mNames.realloc( iLast );
259 mValues.realloc( iLast );
260 mnElementCount--;
262 // Fire event
263 if( maContainerListeners.getLength() > 0 )
265 ContainerEvent aEvent;
266 aEvent.Source = mpxEventSource;
267 aEvent.Accessor <<= aName;
268 aEvent.Element = aOldElement;
269 maContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvent );
272 /* After the container event has been fired (one listener will update the
273 core Basic manager), fire change event. Listeners can rely that the
274 Basic source code of the core Basic manager is up-to-date. */
275 if( maChangesListeners.getLength() > 0 )
277 ChangesEvent aEvent;
278 aEvent.Source = mpxEventSource;
279 aEvent.Base <<= aEvent.Source;
280 aEvent.Changes.realloc( 1 );
281 aEvent.Changes[ 0 ].Accessor <<= aName;
282 // aEvent.Changes[ 0 ].Element remains empty (meaning "replaced with nothing")
283 aEvent.Changes[ 0 ].ReplacedElement = aOldElement;
284 maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
289 // Methods XContainer
290 void SAL_CALL NameContainer::addContainerListener( const Reference< XContainerListener >& xListener )
291 throw (RuntimeException)
293 if( !xListener.is() )
295 throw RuntimeException("addContainerListener called with null xListener",
296 static_cast< cppu::OWeakObject * >(this));
298 Reference< XInterface > xIface( xListener, UNO_QUERY );
299 maContainerListeners.addInterface( xIface );
302 void SAL_CALL NameContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
303 throw (RuntimeException)
305 if( !xListener.is() )
307 throw RuntimeException();
309 Reference< XInterface > xIface( xListener, UNO_QUERY );
310 maContainerListeners.removeInterface( xIface );
313 // Methods XChangesNotifier
314 void SAL_CALL NameContainer::addChangesListener( const Reference< XChangesListener >& xListener )
315 throw (RuntimeException)
317 if( !xListener.is() )
319 throw RuntimeException();
321 Reference< XInterface > xIface( xListener, UNO_QUERY );
322 maChangesListeners.addInterface( xIface );
325 void SAL_CALL NameContainer::removeChangesListener( const Reference< XChangesListener >& xListener )
326 throw (RuntimeException)
328 if( !xListener.is() )
330 throw RuntimeException();
332 Reference< XInterface > xIface( xListener, UNO_QUERY );
333 maChangesListeners.removeInterface( xIface );
336 //============================================================================
337 // ModifiableHelper
339 void ModifiableHelper::setModified( sal_Bool _bModified )
341 if ( _bModified == mbModified )
343 return;
345 mbModified = _bModified;
347 if ( m_aModifyListeners.getLength() == 0 )
349 return;
351 EventObject aModifyEvent( m_rEventSource );
352 m_aModifyListeners.notifyEach( &XModifyListener::modified, aModifyEvent );
355 //============================================================================
357 VBAScriptListenerContainer::VBAScriptListenerContainer( ::osl::Mutex& rMutex ) :
358 VBAScriptListenerContainer_BASE( rMutex )
362 bool VBAScriptListenerContainer::implTypedNotify( const Reference< vba::XVBAScriptListener >& rxListener, const vba::VBAScriptEvent& rEvent )
363 throw (Exception)
365 rxListener->notifyVBAScriptEvent( rEvent );
366 return true; // notify all other listeners too
369 //============================================================================
371 // Implementation class SfxLibraryContainer
372 DBG_NAME( SfxLibraryContainer )
374 // Ctor
375 SfxLibraryContainer::SfxLibraryContainer( void )
376 : SfxLibraryContainer_BASE( maMutex )
378 , maVBAScriptListeners( maMutex )
379 , mnRunningVBAScripts( 0 )
380 , mbVBACompat( sal_False )
381 , maModifiable( *this, maMutex )
382 , maNameContainer( getCppuType( (Reference< XNameAccess >*) NULL ) )
383 , mbOldInfoFormat( false )
384 , mbOasis2OOoFormat( false )
385 , mpBasMgr( NULL )
386 , mbOwnBasMgr( false )
388 DBG_CTOR( SfxLibraryContainer, NULL );
390 mxContext = comphelper::getProcessComponentContext();
392 mxSFI = ucb::SimpleFileAccess::create( mxContext );
394 mxStringSubstitution = util::PathSubstitution::create( mxContext );
397 SfxLibraryContainer::~SfxLibraryContainer()
399 if( mbOwnBasMgr )
401 BasicManager::LegacyDeleteBasicManager( mpBasMgr );
403 DBG_DTOR( SfxLibraryContainer, NULL );
406 void SfxLibraryContainer::checkDisposed() const
408 if ( isDisposed() )
410 throw DisposedException( OUString(),
411 *const_cast< SfxLibraryContainer* >( this ) );
415 void SfxLibraryContainer::enterMethod()
417 maMutex.acquire();
418 checkDisposed();
421 void SfxLibraryContainer::leaveMethod()
423 maMutex.release();
426 BasicManager* SfxLibraryContainer::getBasicManager( void )
428 if ( mpBasMgr )
430 return mpBasMgr;
432 Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
433 SAL_WARN_IF(
434 !xDocument.is(), "basic",
435 ("SfxLibraryContainer::getBasicManager: cannot obtain a BasicManager"
436 " without document!"));
437 if ( xDocument.is() )
439 mpBasMgr = BasicManagerRepository::getDocumentBasicManager( xDocument );
441 return mpBasMgr;
444 // Methods XStorageBasedLibraryContainer
445 Reference< XStorage > SAL_CALL SfxLibraryContainer::getRootStorage() throw (RuntimeException)
447 LibraryContainerMethodGuard aGuard( *this );
448 return mxStorage;
451 void SAL_CALL SfxLibraryContainer::setRootStorage( const Reference< XStorage >& _rxRootStorage )
452 throw (IllegalArgumentException, RuntimeException)
454 LibraryContainerMethodGuard aGuard( *this );
455 if ( !_rxRootStorage.is() )
457 throw IllegalArgumentException();
459 mxStorage = _rxRootStorage;
460 onNewRootStorage();
463 void SAL_CALL SfxLibraryContainer::storeLibrariesToStorage( const Reference< XStorage >& _rxRootStorage )
464 throw (IllegalArgumentException, WrappedTargetException, RuntimeException)
466 LibraryContainerMethodGuard aGuard( *this );
467 if ( !_rxRootStorage.is() )
469 throw IllegalArgumentException();
473 storeLibraries_Impl( _rxRootStorage, true );
475 catch( const Exception& )
477 throw WrappedTargetException( OUString(),
478 *this, ::cppu::getCaughtException() );
483 // Methods XModifiable
484 sal_Bool SfxLibraryContainer::isModified()
485 throw (RuntimeException)
487 LibraryContainerMethodGuard aGuard( *this );
488 if ( maModifiable.isModified() )
490 return sal_True;
492 // the library container is not modified, go through the libraries and check whether they are modified
493 Sequence< OUString > aNames = maNameContainer.getElementNames();
494 const OUString* pNames = aNames.getConstArray();
495 sal_Int32 nNameCount = aNames.getLength();
497 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
499 OUString aName = pNames[ i ];
500 SfxLibrary* pImplLib = getImplLib( aName );
501 if( pImplLib->isModified() )
503 if ( aName == "Standard" )
505 // this is a workaround that has to be implemented because
506 // empty standard library should stay marked as modified
507 // but should not be treated as modified while it is empty
508 if ( pImplLib->hasElements() )
509 return sal_True;
511 else
513 return sal_True;
518 return sal_False;
521 void SAL_CALL SfxLibraryContainer::setModified( sal_Bool _bModified )
522 throw (PropertyVetoException, RuntimeException)
524 LibraryContainerMethodGuard aGuard( *this );
525 maModifiable.setModified( _bModified );
528 void SAL_CALL SfxLibraryContainer::addModifyListener( const Reference< XModifyListener >& _rxListener )
529 throw (RuntimeException)
531 LibraryContainerMethodGuard aGuard( *this );
532 maModifiable.addModifyListener( _rxListener );
535 void SAL_CALL SfxLibraryContainer::removeModifyListener( const Reference< XModifyListener >& _rxListener )
536 throw (RuntimeException)
538 LibraryContainerMethodGuard aGuard( *this );
539 maModifiable.removeModifyListener( _rxListener );
542 // Methods XPersistentLibraryContainer
543 Any SAL_CALL SfxLibraryContainer::getRootLocation() throw (RuntimeException)
545 LibraryContainerMethodGuard aGuard( *this );
546 return makeAny( getRootStorage() );
549 OUString SAL_CALL SfxLibraryContainer::getContainerLocationName() throw (RuntimeException)
551 LibraryContainerMethodGuard aGuard( *this );
552 return maLibrariesDir;
555 void SAL_CALL SfxLibraryContainer::storeLibraries( )
556 throw (WrappedTargetException, RuntimeException)
558 LibraryContainerMethodGuard aGuard( *this );
561 storeLibraries_Impl( mxStorage, mxStorage.is() );
562 // we need to store *all* libraries if and only if we are based on a storage:
563 // in this case, storeLibraries_Impl will remove the source storage, after loading
564 // all libraries, so we need to force them to be stored, again
566 catch( const Exception& )
568 throw WrappedTargetException( OUString(), *this, ::cppu::getCaughtException() );
572 static void checkAndCopyFileImpl( const INetURLObject& rSourceFolderInetObj,
573 const INetURLObject& rTargetFolderInetObj,
574 const OUString& rCheckFileName,
575 const OUString& rCheckExtension,
576 Reference< XSimpleFileAccess3 > xSFI )
578 INetURLObject aTargetFolderInetObj( rTargetFolderInetObj );
579 aTargetFolderInetObj.insertName( rCheckFileName, sal_True, INetURLObject::LAST_SEGMENT,
580 sal_True, INetURLObject::ENCODE_ALL );
581 aTargetFolderInetObj.setExtension( rCheckExtension );
582 OUString aTargetFile = aTargetFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
583 if( !xSFI->exists( aTargetFile ) )
585 INetURLObject aSourceFolderInetObj( rSourceFolderInetObj );
586 aSourceFolderInetObj.insertName( rCheckFileName, sal_True, INetURLObject::LAST_SEGMENT,
587 sal_True, INetURLObject::ENCODE_ALL );
588 aSourceFolderInetObj.setExtension( rCheckExtension );
589 OUString aSourceFile = aSourceFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
590 xSFI->copy( aSourceFile, aTargetFile );
594 static void createVariableURL( OUString& rStr, const OUString& rLibName,
595 const OUString& rInfoFileName, bool bUser )
597 if( bUser )
599 rStr = OUString("$(USER)/basic/");
601 else
603 rStr = OUString("$(INST)/share/basic/");
605 rStr += rLibName;
606 rStr += "/";
607 rStr += rInfoFileName;
608 rStr += ".xlb/";
611 void SfxLibraryContainer::init( const OUString& rInitialDocumentURL, const uno::Reference< embed::XStorage >& rxInitialStorage )
613 // this might be called from within the ctor, and the impl_init might (indirectly) create
614 // an UNO reference to ourself.
615 // Ensure that we're not destroyed while we're in here
616 osl_atomic_increment( &m_refCount );
617 init_Impl( rInitialDocumentURL, rxInitialStorage );
618 osl_atomic_decrement( &m_refCount );
621 void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL,
622 const uno::Reference< embed::XStorage >& rxInitialStorage )
624 uno::Reference< embed::XStorage > xStorage = rxInitialStorage;
626 maInitialDocumentURL = rInitialDocumentURL;
627 maInfoFileName = OUString::createFromAscii( getInfoFileName() );
628 maOldInfoFileName = OUString::createFromAscii( getOldInfoFileName() );
629 maLibElementFileExtension = OUString::createFromAscii( getLibElementFileExtension() );
630 maLibrariesDir = OUString::createFromAscii( getLibrariesDir() );
632 meInitMode = DEFAULT;
633 INetURLObject aInitUrlInetObj( maInitialDocumentURL );
634 OUString aInitFileName = aInitUrlInetObj.GetMainURL( INetURLObject::NO_DECODE );
635 if( !aInitFileName.isEmpty() )
637 // We need a BasicManager to avoid problems
638 StarBASIC* pBas = new StarBASIC();
639 mpBasMgr = new BasicManager( pBas );
640 mbOwnBasMgr = true;
642 OUString aExtension = aInitUrlInetObj.getExtension();
643 if( aExtension.compareToAscii( "xlc" ) == COMPARE_EQUAL )
645 meInitMode = CONTAINER_INIT_FILE;
646 INetURLObject aLibPathInetObj( aInitUrlInetObj );
647 aLibPathInetObj.removeSegment();
648 maLibraryPath = aLibPathInetObj.GetMainURL( INetURLObject::NO_DECODE );
650 else if( aExtension.compareToAscii( "xlb" ) == COMPARE_EQUAL )
652 meInitMode = LIBRARY_INIT_FILE;
653 uno::Reference< embed::XStorage > xDummyStor;
654 ::xmlscript::LibDescriptor aLibDesc;
655 implLoadLibraryIndexFile( NULL, aLibDesc, xDummyStor, aInitFileName );
656 return;
658 else
660 // Decide between old and new document
661 sal_Bool bOldStorage = SotStorage::IsOLEStorage( aInitFileName );
662 if ( bOldStorage )
664 meInitMode = OLD_BASIC_STORAGE;
665 importFromOldStorage( aInitFileName );
666 return;
668 else
670 meInitMode = OFFICE_DOCUMENT;
673 xStorage = ::comphelper::OStorageHelper::GetStorageFromURL( aInitFileName, embed::ElementModes::READ );
675 catch (const uno::Exception& )
677 // TODO: error handling
682 else
684 // Default paths
685 maLibraryPath = SvtPathOptions().GetBasicPath();
688 Reference< XParser > xParser = xml::sax::Parser::create(mxContext);
690 uno::Reference< io::XInputStream > xInput;
692 mxStorage = xStorage;
693 bool bStorage = mxStorage.is();
696 // #110009: Scope to force the StorageRefs to be destructed and
697 // so the streams to be closed before the preload operation
700 uno::Reference< embed::XStorage > xLibrariesStor;
701 OUString aFileName;
703 int nPassCount = 1;
704 if( !bStorage && meInitMode == DEFAULT )
706 nPassCount = 2;
708 for( int nPass = 0 ; nPass < nPassCount ; nPass++ )
710 if( bStorage )
712 SAL_WARN_IF(
713 meInitMode != DEFAULT && meInitMode != OFFICE_DOCUMENT, "basic",
714 "Wrong InitMode for document");
717 uno::Reference< io::XStream > xStream;
718 xLibrariesStor = xStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
720 if ( xLibrariesStor.is() )
722 aFileName = maInfoFileName;
723 aFileName += "-lc.xml";
727 xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
729 catch(const uno::Exception& )
732 if( !xStream.is() )
734 mbOldInfoFormat = true;
736 // Check old version
737 aFileName = maOldInfoFileName;
738 aFileName += ".xml";
742 xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
744 catch(const uno::Exception& )
747 if( !xStream.is() )
749 // Check for EA2 document version with wrong extensions
750 aFileName = maOldInfoFileName;
751 aFileName += ".xli";
752 xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
757 if ( xStream.is() )
759 xInput = xStream->getInputStream();
762 catch(const uno::Exception& )
764 // TODO: error handling?
767 else
769 INetURLObject* pLibInfoInetObj = NULL;
770 if( meInitMode == CONTAINER_INIT_FILE )
772 aFileName = aInitFileName;
774 else
776 if( nPass == 1 )
778 pLibInfoInetObj = new INetURLObject( maLibraryPath.getToken(0, (sal_Unicode)';') );
780 else
782 pLibInfoInetObj = new INetURLObject( maLibraryPath.getToken(1, (sal_Unicode)';') );
784 pLibInfoInetObj->insertName( maInfoFileName, sal_False, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
785 pLibInfoInetObj->setExtension( OUString("xlc") );
786 aFileName = pLibInfoInetObj->GetMainURL( INetURLObject::NO_DECODE );
791 xInput = mxSFI->openFileRead( aFileName );
793 catch(const Exception& )
795 // Silently tolerate empty or missing files
796 xInput.clear();
799 // Old variant?
800 if( !xInput.is() && nPass == 0 )
802 INetURLObject aLibInfoInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
803 aLibInfoInetObj.insertName( maOldInfoFileName, sal_False, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
804 aLibInfoInetObj.setExtension( OUString( "xli") );
805 aFileName = aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE );
809 xInput = mxSFI->openFileRead( aFileName );
810 mbOldInfoFormat = true;
812 catch(const Exception& )
814 xInput.clear();
818 delete pLibInfoInetObj;
821 if( xInput.is() )
823 InputSource source;
824 source.aInputStream = xInput;
825 source.sSystemId = aFileName;
827 // start parsing
828 ::xmlscript::LibDescriptorArray* pLibArray = new ::xmlscript::LibDescriptorArray();
832 xParser->setDocumentHandler( ::xmlscript::importLibraryContainer( pLibArray ) );
833 xParser->parseStream( source );
835 catch ( const xml::sax::SAXException& e )
837 SAL_WARN("basic", e.Message);
838 return;
840 catch ( const io::IOException& e )
842 SAL_WARN("basic", e.Message);
843 return;
846 sal_Int32 nLibCount = pLibArray->mnLibCount;
847 for( sal_Int32 i = 0 ; i < nLibCount ; i++ )
849 ::xmlscript::LibDescriptor& rLib = pLibArray->mpLibs[i];
851 // Check storage URL
852 OUString aStorageURL = rLib.aStorageURL;
853 if( !bStorage && aStorageURL.isEmpty() && nPass == 0 )
855 OUString aLibraryPath;
856 if( meInitMode == CONTAINER_INIT_FILE )
858 aLibraryPath = maLibraryPath;
860 else
862 aLibraryPath = maLibraryPath.getToken(1, (sal_Unicode)';');
864 INetURLObject aInetObj( aLibraryPath );
866 aInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT,
867 sal_True, INetURLObject::ENCODE_ALL );
868 OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
869 if( mxSFI->isFolder( aLibDirPath ) )
871 createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, true );
872 maModifiable.setModified( sal_True );
874 else if( rLib.bLink )
876 // Check "share" path
877 INetURLObject aShareInetObj( maLibraryPath.getToken(0, (sal_Unicode)';') );
878 aShareInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT,
879 sal_True, INetURLObject::ENCODE_ALL );
880 OUString aShareLibDirPath = aShareInetObj.GetMainURL( INetURLObject::NO_DECODE );
881 if( mxSFI->isFolder( aShareLibDirPath ) )
883 createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, false );
884 maModifiable.setModified( sal_True );
886 else
888 // #i25537: Ignore lib if library folder does not really exist
889 continue;
894 OUString aLibName = rLib.aName;
896 // If the same library name is used by the shared and the
897 // user lib container index files the user file wins
898 if( nPass == 1 && hasByName( aLibName ) )
900 continue;
902 SfxLibrary* pImplLib;
903 if( rLib.bLink )
905 Reference< XNameAccess > xLib =
906 createLibraryLink( aLibName, rLib.aStorageURL, rLib.bReadOnly );
907 pImplLib = static_cast< SfxLibrary* >( xLib.get() );
909 else
911 Reference< XNameContainer > xLib = createLibrary( aLibName );
912 pImplLib = static_cast< SfxLibrary* >( xLib.get() );
913 pImplLib->mbLoaded = sal_False;
914 pImplLib->mbReadOnly = rLib.bReadOnly;
915 if( !bStorage )
917 checkStorageURL( rLib.aStorageURL, pImplLib->maLibInfoFileURL,
918 pImplLib->maStorageURL, pImplLib->maUnexpandedStorageURL );
921 maModifiable.setModified( sal_False );
923 // Read library info files
924 if( !mbOldInfoFormat )
926 uno::Reference< embed::XStorage > xLibraryStor;
927 if( !pImplLib->mbInitialised && bStorage )
931 xLibraryStor = xLibrariesStor->openStorageElement( rLib.aName,
932 embed::ElementModes::READ );
934 catch(const uno::Exception& )
936 #if OSL_DEBUG_LEVEL > 0
937 Any aError( ::cppu::getCaughtException() );
938 SAL_WARN(
939 "basic",
940 "couldn't open sub storage for library \""
941 << rLib.aName << "\". Exception: "
942 << comphelper::anyToString(aError));
943 #endif
947 // Link is already initialised in createLibraryLink()
948 if( !pImplLib->mbInitialised && (!bStorage || xLibraryStor.is()) )
950 OUString aIndexFileName;
951 bool bLoaded = implLoadLibraryIndexFile( pImplLib, rLib, xLibraryStor, aIndexFileName );
952 SAL_WARN_IF(
953 bLoaded && aLibName != rLib.aName, "basic",
954 ("Different library names in library container and"
955 " library info files!"));
956 if( GbMigrationSuppressErrors && !bLoaded )
958 removeLibrary( aLibName );
962 else if( !bStorage )
964 // Write new index file immediately because otherwise
965 // the library elements will be lost when storing into
966 // the new info format
967 uno::Reference< embed::XStorage > xTmpStorage;
968 implStoreLibraryIndexFile( pImplLib, rLib, xTmpStorage );
971 implImportLibDescriptor( pImplLib, rLib );
973 if( nPass == 1 )
975 pImplLib->mbSharedIndexFile = true;
976 pImplLib->mbReadOnly = sal_True;
980 // Keep flag for documents to force writing the new index files
981 if( !bStorage )
983 mbOldInfoFormat = false;
985 delete pLibArray;
989 // #110009: END Scope to force the StorageRefs to be destructed
992 if( !bStorage && meInitMode == DEFAULT )
996 implScanExtensions();
998 catch(const uno::Exception& )
1000 // TODO: error handling?
1001 SAL_WARN("basic", "Cannot access extensions!");
1005 // Preload?
1007 Sequence< OUString > aNames = maNameContainer.getElementNames();
1008 const OUString* pNames = aNames.getConstArray();
1009 sal_Int32 nNameCount = aNames.getLength();
1010 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1012 OUString aName = pNames[ i ];
1013 SfxLibrary* pImplLib = getImplLib( aName );
1014 if( pImplLib->mbPreload )
1016 loadLibrary( aName );
1021 if( meInitMode == DEFAULT )
1023 INetURLObject aUserBasicInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
1024 OUString aStandardStr("Standard");
1026 static char const strPrevFolderName_1[] = "__basic_80";
1027 static char const strPrevFolderName_2[] = "__basic_80_2";
1028 INetURLObject aPrevUserBasicInetObj_1( aUserBasicInetObj );
1029 aPrevUserBasicInetObj_1.removeSegment();
1030 INetURLObject aPrevUserBasicInetObj_2 = aPrevUserBasicInetObj_1;
1031 aPrevUserBasicInetObj_1.Append( OString( strPrevFolderName_1 ));
1032 aPrevUserBasicInetObj_2.Append( OString( strPrevFolderName_2 ));
1034 // #i93163
1035 bool bCleanUp = false;
1038 INetURLObject aPrevUserBasicInetObj = aPrevUserBasicInetObj_1;
1039 OUString aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
1040 if( mxSFI->isFolder( aPrevFolder ) )
1042 // Check if Standard folder exists and is complete
1043 INetURLObject aUserBasicStandardInetObj( aUserBasicInetObj );
1044 aUserBasicStandardInetObj.insertName( aStandardStr, sal_True, INetURLObject::LAST_SEGMENT,
1045 sal_True, INetURLObject::ENCODE_ALL );
1046 INetURLObject aPrevUserBasicStandardInetObj( aPrevUserBasicInetObj );
1047 aPrevUserBasicStandardInetObj.insertName( aStandardStr, sal_True, INetURLObject::LAST_SEGMENT,
1048 sal_True, INetURLObject::ENCODE_ALL );
1049 OUString aPrevStandardFolder = aPrevUserBasicStandardInetObj.GetMainURL( INetURLObject::NO_DECODE );
1050 if( mxSFI->isFolder( aPrevStandardFolder ) )
1052 OUString aXlbExtension( "xlb" );
1053 OUString aCheckFileName;
1055 // Check if script.xlb exists
1056 aCheckFileName = OUString("script");
1057 checkAndCopyFileImpl( aUserBasicStandardInetObj,
1058 aPrevUserBasicStandardInetObj,
1059 aCheckFileName, aXlbExtension, mxSFI );
1061 // Check if dialog.xlb exists
1062 aCheckFileName = OUString("dialog");
1063 checkAndCopyFileImpl( aUserBasicStandardInetObj,
1064 aPrevUserBasicStandardInetObj,
1065 aCheckFileName, aXlbExtension, mxSFI );
1067 // Check if module1.xba exists
1068 OUString aXbaExtension("xba");
1069 aCheckFileName = OUString("Module1");
1070 checkAndCopyFileImpl( aUserBasicStandardInetObj,
1071 aPrevUserBasicStandardInetObj,
1072 aCheckFileName, aXbaExtension, mxSFI );
1074 else
1076 OUString aStandardFolder = aUserBasicStandardInetObj.GetMainURL( INetURLObject::NO_DECODE );
1077 mxSFI->copy( aStandardFolder, aPrevStandardFolder );
1080 OUString aPrevCopyToFolder = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::NO_DECODE );
1081 mxSFI->copy( aPrevFolder, aPrevCopyToFolder );
1083 else
1085 aPrevUserBasicInetObj = aPrevUserBasicInetObj_2;
1086 aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
1088 if( mxSFI->isFolder( aPrevFolder ) )
1090 SfxLibraryContainer* pPrevCont = createInstanceImpl();
1091 Reference< XInterface > xRef = static_cast< XInterface* >( static_cast< OWeakObject* >(pPrevCont) );
1093 // Rename previous basic folder to make storage URLs correct during initialisation
1094 OUString aFolderUserBasic = aUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
1095 INetURLObject aUserBasicTmpInetObj( aUserBasicInetObj );
1096 aUserBasicTmpInetObj.removeSegment();
1097 aUserBasicTmpInetObj.Append( OString( "__basic_tmp" ));
1098 OUString aFolderTmp = aUserBasicTmpInetObj.GetMainURL( INetURLObject::NO_DECODE );
1100 mxSFI->move( aFolderUserBasic, aFolderTmp );
1103 mxSFI->move( aPrevFolder, aFolderUserBasic );
1105 catch(const Exception& )
1107 // Move back user/basic folder
1110 mxSFI->kill( aFolderUserBasic );
1112 catch(const Exception& )
1114 mxSFI->move( aFolderTmp, aFolderUserBasic );
1115 throw;
1118 INetURLObject aPrevUserBasicLibInfoInetObj( aUserBasicInetObj );
1119 aPrevUserBasicLibInfoInetObj.insertName( maInfoFileName, sal_False, INetURLObject::LAST_SEGMENT,
1120 sal_True, INetURLObject::ENCODE_ALL );
1121 aPrevUserBasicLibInfoInetObj.setExtension( OUString("xlc"));
1122 OUString aLibInfoFileName = aPrevUserBasicLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE );
1123 Sequence<Any> aInitSeq( 1 );
1124 aInitSeq.getArray()[0] <<= aLibInfoFileName;
1125 GbMigrationSuppressErrors = true;
1126 pPrevCont->initialize( aInitSeq );
1127 GbMigrationSuppressErrors = false;
1129 // Rename folders back
1130 mxSFI->move( aFolderUserBasic, aPrevFolder );
1131 mxSFI->move( aFolderTmp, aFolderUserBasic );
1133 OUString aUserSearchStr("vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE");
1134 OUString aSharedSearchStr("vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE");
1135 OUString aBundledSearchStr("vnd.sun.star.expand:$BUNDLED_EXTENSIONS");
1136 OUString aInstSearchStr("$(INST)");
1138 Sequence< OUString > aNames = pPrevCont->getElementNames();
1139 const OUString* pNames = aNames.getConstArray();
1140 sal_Int32 nNameCount = aNames.getLength();
1142 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1144 OUString aLibName = pNames[ i ];
1145 if( hasByName( aLibName ) )
1147 if( aLibName == aStandardStr )
1149 SfxLibrary* pImplLib = getImplLib( aStandardStr );
1150 INetURLObject aStandardFolderInetObj( pImplLib->maStorageURL );
1151 OUString aStandardFolder = pImplLib->maStorageURL;
1152 mxSFI->kill( aStandardFolder );
1154 else
1156 continue;
1160 SfxLibrary* pImplLib = pPrevCont->getImplLib( aLibName );
1161 if( pImplLib->mbLink )
1163 OUString aStorageURL = pImplLib->maUnexpandedStorageURL;
1164 bool bCreateLink = true;
1165 if( aStorageURL.indexOf( aUserSearchStr ) != -1 ||
1166 aStorageURL.indexOf( aSharedSearchStr ) != -1 ||
1167 aStorageURL.indexOf( aBundledSearchStr ) != -1 ||
1168 aStorageURL.indexOf( aInstSearchStr ) != -1 )
1170 bCreateLink = false;
1172 if( bCreateLink )
1174 createLibraryLink( aLibName, pImplLib->maStorageURL, pImplLib->mbReadOnly );
1177 else
1179 // Move folder if not already done
1180 INetURLObject aUserBasicLibFolderInetObj( aUserBasicInetObj );
1181 aUserBasicLibFolderInetObj.Append( aLibName );
1182 OUString aLibFolder = aUserBasicLibFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
1184 INetURLObject aPrevUserBasicLibFolderInetObj( aPrevUserBasicInetObj );
1185 aPrevUserBasicLibFolderInetObj.Append( aLibName );
1186 OUString aPrevLibFolder = aPrevUserBasicLibFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
1188 if( mxSFI->isFolder( aPrevLibFolder ) && !mxSFI->isFolder( aLibFolder ) )
1190 mxSFI->move( aPrevLibFolder, aLibFolder );
1193 if( aLibName == aStandardStr )
1195 maNameContainer.removeByName( aLibName );
1198 // Create library
1199 Reference< XNameContainer > xLib = createLibrary( aLibName );
1200 SfxLibrary* pNewLib = static_cast< SfxLibrary* >( xLib.get() );
1201 pNewLib->mbLoaded = false;
1202 pNewLib->implSetModified( sal_False );
1203 checkStorageURL( aLibFolder, pNewLib->maLibInfoFileURL,
1204 pNewLib->maStorageURL, pNewLib->maUnexpandedStorageURL );
1206 uno::Reference< embed::XStorage > xDummyStor;
1207 ::xmlscript::LibDescriptor aLibDesc;
1208 implLoadLibraryIndexFile( pNewLib, aLibDesc, xDummyStor, pNewLib->maLibInfoFileURL );
1209 implImportLibDescriptor( pNewLib, aLibDesc );
1212 mxSFI->kill( aPrevFolder );
1215 catch(const Exception& e)
1217 bCleanUp = true;
1218 SAL_WARN("basic", "Upgrade of Basic installation failed somehow: " << e.Message);
1221 // #i93163
1222 if( bCleanUp )
1224 static const char strErrorSavFolderName[] = "__basic_80_err";
1225 INetURLObject aPrevUserBasicInetObj_Err( aUserBasicInetObj );
1226 aPrevUserBasicInetObj_Err.removeSegment();
1227 aPrevUserBasicInetObj_Err.Append( OString( strErrorSavFolderName ));
1228 OUString aPrevFolder_Err = aPrevUserBasicInetObj_Err.GetMainURL( INetURLObject::NO_DECODE );
1230 bool bSaved = false;
1233 OUString aPrevFolder_1 = aPrevUserBasicInetObj_1.GetMainURL( INetURLObject::NO_DECODE );
1234 if( mxSFI->isFolder( aPrevFolder_1 ) )
1236 mxSFI->move( aPrevFolder_1, aPrevFolder_Err );
1237 bSaved = true;
1240 catch(const Exception& )
1244 OUString aPrevFolder_2 = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::NO_DECODE );
1245 if( !bSaved && mxSFI->isFolder( aPrevFolder_2 ) )
1247 mxSFI->move( aPrevFolder_2, aPrevFolder_Err );
1249 else
1251 mxSFI->kill( aPrevFolder_2 );
1254 catch(const Exception& )
1260 void SfxLibraryContainer::implScanExtensions( void )
1262 #if HAVE_FEATURE_EXTENSIONS
1263 ScriptExtensionIterator aScriptIt;
1264 OUString aLibURL;
1266 bool bPureDialogLib = false;
1267 while ( !(aLibURL = aScriptIt.nextBasicOrDialogLibrary( bPureDialogLib )).isEmpty())
1269 if( bPureDialogLib && maInfoFileName == "script" )
1271 continue;
1273 // Extract lib name
1274 sal_Int32 nLen = aLibURL.getLength();
1275 sal_Int32 indexLastSlash = aLibURL.lastIndexOf( '/' );
1276 sal_Int32 nReduceCopy = 0;
1277 if( indexLastSlash == nLen - 1 )
1279 nReduceCopy = 1;
1280 indexLastSlash = aLibURL.lastIndexOf( '/', nLen - 1 );
1283 OUString aLibName = aLibURL.copy( indexLastSlash + 1, nLen - indexLastSlash - nReduceCopy - 1 );
1285 // If a library of the same exists the existing library wins
1286 if( hasByName( aLibName ) )
1288 continue;
1290 // Add index file to URL
1291 OUString aIndexFileURL = aLibURL;
1292 if( nReduceCopy == 0 )
1294 aIndexFileURL += "/";
1296 aIndexFileURL += maInfoFileName + ".xlb";
1298 // Create link
1299 const bool bReadOnly = false;
1300 Reference< XNameAccess > xLib = createLibraryLink( aLibName, aIndexFileURL, bReadOnly );
1302 #endif
1305 // Handle maLibInfoFileURL and maStorageURL correctly
1306 void SfxLibraryContainer::checkStorageURL( const OUString& aSourceURL,
1307 OUString& aLibInfoFileURL, OUString& aStorageURL,
1308 OUString& aUnexpandedStorageURL )
1310 OUString aExpandedSourceURL = expand_url( aSourceURL );
1311 if( aExpandedSourceURL != aSourceURL )
1313 aUnexpandedStorageURL = aSourceURL;
1315 INetURLObject aInetObj( aExpandedSourceURL );
1316 OUString aExtension = aInetObj.getExtension();
1317 if( aExtension.compareToAscii( "xlb" ) == COMPARE_EQUAL )
1319 // URL to xlb file
1320 aLibInfoFileURL = aExpandedSourceURL;
1321 aInetObj.removeSegment();
1322 aStorageURL = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1324 else
1326 // URL to library folder
1327 aStorageURL = aExpandedSourceURL;
1328 aInetObj.insertName( maInfoFileName, sal_False, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1329 aInetObj.setExtension( OUString("xlb") );
1330 aLibInfoFileURL = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1334 SfxLibrary* SfxLibraryContainer::getImplLib( const OUString& rLibraryName )
1336 Any aLibAny = maNameContainer.getByName( rLibraryName ) ;
1337 Reference< XNameAccess > xNameAccess;
1338 aLibAny >>= xNameAccess;
1339 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
1340 return pImplLib;
1344 // Storing with password encryption
1346 // Empty implementation, avoids unneccesary implementation in dlgcont.cxx
1347 sal_Bool SfxLibraryContainer::implStorePasswordLibrary( SfxLibrary*,
1348 const OUString&,
1349 const uno::Reference< embed::XStorage >&,
1350 const uno::Reference< task::XInteractionHandler >& )
1352 return sal_False;
1355 sal_Bool SfxLibraryContainer::implStorePasswordLibrary(
1356 SfxLibrary* /*pLib*/,
1357 const OUString& /*aName*/,
1358 const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& /*xStorage*/,
1359 const OUString& /*aTargetURL*/,
1360 const Reference< XSimpleFileAccess3 > /*xToUseSFI*/,
1361 const uno::Reference< task::XInteractionHandler >& )
1363 return sal_False;
1366 sal_Bool SfxLibraryContainer::implLoadPasswordLibrary(
1367 SfxLibrary* /*pLib*/,
1368 const OUString& /*Name*/,
1369 sal_Bool /*bVerifyPasswordOnly*/ )
1370 throw(WrappedTargetException, RuntimeException)
1372 return sal_True;
1377 #define EXPAND_PROTOCOL "vnd.sun.star.expand"
1379 OUString SfxLibraryContainer::createAppLibraryFolder( SfxLibrary* pLib, const OUString& aName )
1381 OUString aLibDirPath = pLib->maStorageURL;
1382 if( aLibDirPath.isEmpty() )
1384 INetURLObject aInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
1385 aInetObj.insertName( aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1386 checkStorageURL( aInetObj.GetMainURL( INetURLObject::NO_DECODE ), pLib->maLibInfoFileURL,
1387 pLib->maStorageURL, pLib->maUnexpandedStorageURL );
1388 aLibDirPath = pLib->maStorageURL;
1391 if( !mxSFI->isFolder( aLibDirPath ) )
1395 mxSFI->createFolder( aLibDirPath );
1397 catch(const Exception& )
1401 return aLibDirPath;
1404 // Storing
1405 void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
1406 const OUString& aName,
1407 const uno::Reference< embed::XStorage >& xStorage )
1409 OUString aDummyLocation;
1410 Reference< XSimpleFileAccess3 > xDummySFA;
1411 Reference< XInteractionHandler > xDummyHandler;
1412 implStoreLibrary( pLib, aName, xStorage, aDummyLocation, xDummySFA, xDummyHandler );
1415 // New variant for library export
1416 void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
1417 const OUString& aName,
1418 const uno::Reference< embed::XStorage >& xStorage,
1419 const OUString& aTargetURL,
1420 Reference< XSimpleFileAccess3 > xToUseSFI,
1421 const Reference< XInteractionHandler >& xHandler )
1423 sal_Bool bLink = pLib->mbLink;
1424 bool bStorage = xStorage.is() && !bLink;
1426 Sequence< OUString > aElementNames = pLib->getElementNames();
1427 sal_Int32 nNameCount = aElementNames.getLength();
1428 const OUString* pNames = aElementNames.getConstArray();
1430 if( bStorage )
1432 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1434 OUString aElementName = pNames[ i ];
1435 OUString aStreamName = aElementName;
1436 aStreamName += ".xml";
1438 if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
1440 SAL_WARN(
1441 "basic",
1442 "invalid library element \"" << aElementName << '"');
1443 continue;
1447 uno::Reference< io::XStream > xElementStream = xStorage->openStreamElement(
1448 aStreamName,
1449 embed::ElementModes::READWRITE );
1450 // throw uno::RuntimeException(); // TODO: method must either return the stream or throw an exception
1452 OUString aMime( "text/xml" );
1454 uno::Reference< beans::XPropertySet > xProps( xElementStream, uno::UNO_QUERY );
1455 SAL_WARN_IF(
1456 !xProps.is(), "basic",
1457 "The StorageStream must implement XPropertySet interface!");
1458 //if ( !xProps.is() ) //TODO
1460 if ( xProps.is() )
1462 xProps->setPropertyValue( OUString("MediaType"), uno::makeAny( aMime ) );
1464 // #87671 Allow encryption
1465 xProps->setPropertyValue( OUString("UseCommonStoragePasswordEncryption"), uno::makeAny( sal_True ) );
1467 Reference< XOutputStream > xOutput = xElementStream->getOutputStream();
1468 Reference< XNameContainer > xLib( pLib );
1469 writeLibraryElement( xLib, aElementName, xOutput );
1472 catch(const uno::Exception& )
1474 SAL_WARN("basic", "Problem during storing of library!");
1475 // TODO: error handling?
1478 pLib->storeResourcesToStorage( xStorage );
1480 else
1482 // Export?
1483 bool bExport = !aTargetURL.isEmpty();
1486 Reference< XSimpleFileAccess3 > xSFI = mxSFI;
1487 if( xToUseSFI.is() )
1489 xSFI = xToUseSFI;
1491 OUString aLibDirPath;
1492 if( bExport )
1494 INetURLObject aInetObj( aTargetURL );
1495 aInetObj.insertName( aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1496 aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1498 if( !xSFI->isFolder( aLibDirPath ) )
1500 xSFI->createFolder( aLibDirPath );
1502 pLib->storeResourcesToURL( aLibDirPath, xHandler );
1504 else
1506 aLibDirPath = createAppLibraryFolder( pLib, aName );
1507 pLib->storeResources();
1510 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1512 OUString aElementName = pNames[ i ];
1514 INetURLObject aElementInetObj( aLibDirPath );
1515 aElementInetObj.insertName( aElementName, sal_False,
1516 INetURLObject::LAST_SEGMENT, sal_True,
1517 INetURLObject::ENCODE_ALL );
1518 aElementInetObj.setExtension( maLibElementFileExtension );
1519 OUString aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
1521 if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
1523 SAL_WARN(
1524 "basic",
1525 "invalid library element \"" << aElementName << '"');
1526 continue;
1529 // TODO: Check modified
1532 if( xSFI->exists( aElementPath ) )
1534 xSFI->kill( aElementPath );
1536 Reference< XOutputStream > xOutput = xSFI->openFileWrite( aElementPath );
1537 Reference< XNameContainer > xLib( pLib );
1538 writeLibraryElement( xLib, aElementName, xOutput );
1539 xOutput->closeOutput();
1541 catch(const Exception& )
1543 if( bExport )
1545 throw;
1547 SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aElementPath );
1548 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
1549 ErrorHandler::HandleError( nErrorCode );
1553 catch(const Exception& )
1555 if( bExport )
1557 throw;
1563 void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib,
1564 const ::xmlscript::LibDescriptor& rLib,
1565 const uno::Reference< embed::XStorage >& xStorage )
1567 OUString aDummyLocation;
1568 Reference< XSimpleFileAccess3 > xDummySFA;
1569 implStoreLibraryIndexFile( pLib, rLib, xStorage, aDummyLocation, xDummySFA );
1572 // New variant for library export
1573 void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib,
1574 const ::xmlscript::LibDescriptor& rLib,
1575 const uno::Reference< embed::XStorage >& xStorage,
1576 const OUString& aTargetURL,
1577 Reference< XSimpleFileAccess3 > xToUseSFI )
1579 // Create sax writer
1580 Reference< XWriter > xWriter = xml::sax::Writer::create(mxContext);
1582 sal_Bool bLink = pLib->mbLink;
1583 bool bStorage = xStorage.is() && !bLink;
1585 // Write info file
1586 uno::Reference< io::XOutputStream > xOut;
1587 uno::Reference< io::XStream > xInfoStream;
1588 if( bStorage )
1590 OUString aStreamName( maInfoFileName );
1591 aStreamName += "-lb.xml";
1595 xInfoStream = xStorage->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
1596 SAL_WARN_IF(!xInfoStream.is(), "basic", "No stream!");
1597 uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
1598 // throw uno::RuntimeException(); // TODO
1600 if ( xProps.is() )
1602 OUString aMime("text/xml");
1603 xProps->setPropertyValue( OUString("MediaType"), uno::makeAny( aMime ) );
1605 // #87671 Allow encryption
1606 xProps->setPropertyValue( OUString("UseCommonStoragePasswordEncryption"), uno::makeAny( sal_True ) );
1608 xOut = xInfoStream->getOutputStream();
1611 catch(const uno::Exception& )
1613 SAL_WARN("basic", "Problem during storing of library index file!");
1614 // TODO: error handling?
1617 else
1619 // Export?
1620 bool bExport = !aTargetURL.isEmpty();
1621 Reference< XSimpleFileAccess3 > xSFI = mxSFI;
1622 if( xToUseSFI.is() )
1624 xSFI = xToUseSFI;
1626 OUString aLibInfoPath;
1627 if( bExport )
1629 INetURLObject aInetObj( aTargetURL );
1630 aInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1631 OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1632 if( !xSFI->isFolder( aLibDirPath ) )
1634 xSFI->createFolder( aLibDirPath );
1636 aInetObj.insertName( maInfoFileName, sal_False, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1637 aInetObj.setExtension( OUString( "xlb" ) );
1638 aLibInfoPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1640 else
1642 createAppLibraryFolder( pLib, rLib.aName );
1643 aLibInfoPath = pLib->maLibInfoFileURL;
1648 if( xSFI->exists( aLibInfoPath ) )
1650 xSFI->kill( aLibInfoPath );
1652 xOut = xSFI->openFileWrite( aLibInfoPath );
1654 catch(const Exception& )
1656 if( bExport )
1658 throw;
1660 SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
1661 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
1662 ErrorHandler::HandleError( nErrorCode );
1665 if( !xOut.is() )
1667 SAL_WARN("basic", "couldn't open output stream");
1668 return;
1670 xWriter->setOutputStream( xOut );
1671 xmlscript::exportLibrary( xWriter, rLib );
1675 bool SfxLibraryContainer::implLoadLibraryIndexFile( SfxLibrary* pLib,
1676 ::xmlscript::LibDescriptor& rLib,
1677 const uno::Reference< embed::XStorage >& xStorage,
1678 const OUString& aIndexFileName )
1680 Reference< XParser > xParser = xml::sax::Parser::create(mxContext);
1682 sal_Bool bLink = sal_False;
1683 bool bStorage = false;
1684 if( pLib )
1686 bLink = pLib->mbLink;
1687 bStorage = xStorage.is() && !bLink;
1690 // Read info file
1691 uno::Reference< io::XInputStream > xInput;
1692 OUString aLibInfoPath;
1693 if( bStorage )
1695 aLibInfoPath = maInfoFileName;
1696 aLibInfoPath += String( "-lb.xml" );
1700 uno::Reference< io::XStream > xInfoStream =
1701 xStorage->openStreamElement( aLibInfoPath, embed::ElementModes::READ );
1702 xInput = xInfoStream->getInputStream();
1704 catch(const uno::Exception& )
1707 else
1709 // Create Input stream
1710 //String aLibInfoPath; // attention: THIS PROBLEM MUST BE REVIEWED BY SCRIPTING OWNER!!!
1712 if( pLib )
1714 createAppLibraryFolder( pLib, rLib.aName );
1715 aLibInfoPath = pLib->maLibInfoFileURL;
1717 else
1719 aLibInfoPath = aIndexFileName;
1723 xInput = mxSFI->openFileRead( aLibInfoPath );
1725 catch(const Exception& )
1727 xInput.clear();
1728 if( !GbMigrationSuppressErrors )
1730 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
1731 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
1732 ErrorHandler::HandleError( nErrorCode );
1736 if( !xInput.is() )
1738 return false;
1741 InputSource source;
1742 source.aInputStream = xInput;
1743 source.sSystemId = aLibInfoPath;
1745 // start parsing
1748 xParser->setDocumentHandler( ::xmlscript::importLibrary( rLib ) );
1749 xParser->parseStream( source );
1751 catch(const Exception& )
1753 SAL_WARN("basic", "Parsing error");
1754 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
1755 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
1756 ErrorHandler::HandleError( nErrorCode );
1757 return false;
1760 if( !pLib )
1762 Reference< XNameContainer > xLib = createLibrary( rLib.aName );
1763 pLib = static_cast< SfxLibrary* >( xLib.get() );
1764 pLib->mbLoaded = sal_False;
1765 rLib.aStorageURL = aIndexFileName;
1766 checkStorageURL( rLib.aStorageURL, pLib->maLibInfoFileURL, pLib->maStorageURL,
1767 pLib->maUnexpandedStorageURL );
1769 implImportLibDescriptor( pLib, rLib );
1772 return true;
1775 void SfxLibraryContainer::implImportLibDescriptor( SfxLibrary* pLib,
1776 ::xmlscript::LibDescriptor& rLib )
1778 if( !pLib->mbInitialised )
1780 sal_Int32 nElementCount = rLib.aElementNames.getLength();
1781 const OUString* pElementNames = rLib.aElementNames.getConstArray();
1782 Any aDummyElement = createEmptyLibraryElement();
1783 for( sal_Int32 i = 0 ; i < nElementCount ; i++ )
1785 pLib->maNameContainer.insertByName( pElementNames[i], aDummyElement );
1787 pLib->mbPasswordProtected = rLib.bPasswordProtected;
1788 pLib->mbReadOnly = rLib.bReadOnly;
1789 pLib->mbPreload = rLib.bPreload;
1790 pLib->implSetModified( sal_False );
1791 pLib->mbInitialised = true;
1796 // Methods of new XLibraryStorage interface?
1797 void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XStorage >& i_rStorage,
1798 bool bComplete )
1800 const Sequence< OUString > aNames = maNameContainer.getElementNames();
1801 sal_Int32 nNameCount = aNames.getLength();
1802 const OUString* pName = aNames.getConstArray();
1803 const OUString* pNamesEnd = aNames.getConstArray() + nNameCount;
1805 // Don't count libs from shared index file
1806 sal_Int32 nLibsToSave = nNameCount;
1807 for( ; pName != pNamesEnd; ++pName )
1809 SfxLibrary* pImplLib = getImplLib( *pName );
1810 if( pImplLib->mbSharedIndexFile || pImplLib->mbExtension )
1812 nLibsToSave--;
1815 if( !nLibsToSave )
1817 return;
1819 boost::scoped_ptr< ::xmlscript::LibDescriptorArray > pLibArray(new ::xmlscript::LibDescriptorArray(nLibsToSave));
1821 // Write to storage?
1822 bool bStorage = i_rStorage.is();
1823 uno::Reference< embed::XStorage > xSourceLibrariesStor;
1824 uno::Reference< embed::XStorage > xTargetLibrariesStor;
1825 OUString sTempTargetStorName;
1826 const bool bInplaceStorage = bStorage && ( i_rStorage == mxStorage );
1827 if ( bStorage )
1829 // Don't write if only empty standard lib exists
1830 if ( ( nNameCount == 1 ) && ( aNames[0] == "Standard" ) )
1832 Any aLibAny = maNameContainer.getByName( aNames[0] );
1833 Reference< XNameAccess > xNameAccess;
1834 aLibAny >>= xNameAccess;
1835 if ( ! ( xNameAccess->hasElements() || ( bInplaceStorage && isModified() ) ) )
1837 return;
1841 // create the empty target storage
1844 OUString sTargetLibrariesStoreName;
1845 if ( bInplaceStorage )
1847 // create a temporary target storage
1848 const OUStringBuffer aTempTargetNameBase = maLibrariesDir + OUString( "_temp_" );
1849 sal_Int32 index = 0;
1852 OUStringBuffer aTempTargetName( aTempTargetNameBase );
1853 aTempTargetName.append( index++ );
1855 sTargetLibrariesStoreName = aTempTargetName.makeStringAndClear();
1856 if ( !i_rStorage->hasByName( sTargetLibrariesStoreName ) )
1858 break;
1861 while ( true );
1862 sTempTargetStorName = sTargetLibrariesStoreName;
1864 else
1866 sTargetLibrariesStoreName = maLibrariesDir;
1867 if ( i_rStorage->hasByName( sTargetLibrariesStoreName ) )
1869 i_rStorage->removeElement( sTargetLibrariesStoreName );
1873 xTargetLibrariesStor.set( i_rStorage->openStorageElement( sTargetLibrariesStoreName, embed::ElementModes::READWRITE ), UNO_QUERY_THROW );
1875 catch( const uno::Exception& )
1877 DBG_UNHANDLED_EXCEPTION();
1878 return;
1882 int iArray = 0;
1883 pName = aNames.getConstArray();
1884 ::xmlscript::LibDescriptor aLibDescriptorForExtensionLibs;
1885 for( ; pName != pNamesEnd; ++pName )
1887 SfxLibrary* pImplLib = getImplLib( *pName );
1888 if( pImplLib->mbSharedIndexFile )
1890 continue;
1892 const bool bExtensionLib = pImplLib->mbExtension;
1893 ::xmlscript::LibDescriptor& rLib = bExtensionLib ?
1894 aLibDescriptorForExtensionLibs : pLibArray->mpLibs[iArray];
1895 if( !bExtensionLib )
1897 iArray++;
1899 rLib.aName = *pName;
1901 rLib.bLink = pImplLib->mbLink;
1902 if( !bStorage || pImplLib->mbLink )
1904 rLib.aStorageURL = ( pImplLib->maUnexpandedStorageURL.getLength() ) ?
1905 pImplLib->maUnexpandedStorageURL : pImplLib->maLibInfoFileURL;
1907 rLib.bReadOnly = pImplLib->mbReadOnly;
1908 rLib.bPreload = pImplLib->mbPreload;
1909 rLib.bPasswordProtected = pImplLib->mbPasswordProtected;
1910 rLib.aElementNames = pImplLib->getElementNames();
1912 if( pImplLib->implIsModified() || bComplete )
1915 uno::Reference< embed::XStorage > xLibraryStor;
1916 if( bStorage )
1920 xLibraryStor = xTargetLibrariesStor->openStorageElement(
1921 rLib.aName,
1922 embed::ElementModes::READWRITE );
1924 catch(const uno::Exception& )
1926 #if OSL_DEBUG_LEVEL > 0
1927 Any aError( ::cppu::getCaughtException() );
1928 SAL_WARN(
1929 "basic",
1930 "couldn't create sub storage for library \""
1931 << rLib.aName << "\". Exception: "
1932 << comphelper::anyToString(aError));
1933 #endif
1934 return;
1938 // Maybe lib is not loaded?!
1939 if( bComplete )
1941 loadLibrary( rLib.aName );
1943 if( pImplLib->mbPasswordProtected )
1945 implStorePasswordLibrary( pImplLib, rLib.aName, xLibraryStor, uno::Reference< task::XInteractionHandler >() );
1946 // TODO: Check return value
1948 else
1950 implStoreLibrary( pImplLib, rLib.aName, xLibraryStor );
1952 implStoreLibraryIndexFile( pImplLib, rLib, xLibraryStor );
1953 if( bStorage )
1957 uno::Reference< embed::XTransactedObject > xTransact( xLibraryStor, uno::UNO_QUERY_THROW );
1958 xTransact->commit();
1960 catch(const uno::Exception& )
1962 DBG_UNHANDLED_EXCEPTION();
1963 // TODO: error handling
1967 maModifiable.setModified( sal_True );
1968 pImplLib->implSetModified( sal_False );
1971 // For container info ReadOnly refers to mbReadOnlyLink
1972 rLib.bReadOnly = pImplLib->mbReadOnlyLink;
1975 // if we did an in-place save into a storage (i.e. a save into the storage we were already based on),
1976 // then we need to clean up the temporary storage we used for this
1977 if ( bInplaceStorage && !sTempTargetStorName.isEmpty() )
1979 // open the source storage which might be used to copy yet-unmodified libraries
1982 if ( mxStorage->hasByName( maLibrariesDir ) || bInplaceStorage )
1984 xSourceLibrariesStor = mxStorage->openStorageElement( maLibrariesDir,
1985 bInplaceStorage ? embed::ElementModes::READWRITE : embed::ElementModes::READ );
1988 catch( const uno::Exception& )
1990 DBG_UNHANDLED_EXCEPTION();
1991 return;
1994 SAL_WARN_IF(
1995 !xSourceLibrariesStor.is(), "basic",
1996 ("SfxLibrariesContainer::storeLibraries_impl: unexpected: we should"
1997 " have a source storage here!"));
2000 // for this, we first remove everything from the source storage, then copy the complete content
2001 // from the temporary target storage. From then on, what used to be the "source storage" becomes
2002 // the "targt storage" for all subsequent operations.
2004 // (We cannot simply remove the storage, denoted by maLibrariesDir, from i_rStorage - there might be
2005 // open references to it.)
2007 if ( xSourceLibrariesStor.is() )
2009 // remove
2010 const Sequence< OUString > aRemoveNames( xSourceLibrariesStor->getElementNames() );
2011 for ( const OUString* pRemoveName = aRemoveNames.getConstArray();
2012 pRemoveName != aRemoveNames.getConstArray() + aRemoveNames.getLength();
2013 ++pRemoveName
2016 xSourceLibrariesStor->removeElement( *pRemoveName );
2019 // copy
2020 const Sequence< OUString > aCopyNames( xTargetLibrariesStor->getElementNames() );
2021 for ( const OUString* pCopyName = aCopyNames.getConstArray();
2022 pCopyName != aCopyNames.getConstArray() + aCopyNames.getLength();
2023 ++pCopyName
2026 xTargetLibrariesStor->copyElementTo( *pCopyName, xSourceLibrariesStor, *pCopyName );
2030 // close and remove temp target
2031 xTargetLibrariesStor->dispose();
2032 i_rStorage->removeElement( sTempTargetStorName );
2033 xTargetLibrariesStor.clear();
2034 sTempTargetStorName = OUString();
2036 // adjust target
2037 xTargetLibrariesStor = xSourceLibrariesStor;
2038 xSourceLibrariesStor.clear();
2040 catch( const Exception& )
2042 DBG_UNHANDLED_EXCEPTION();
2046 if( !mbOldInfoFormat && !maModifiable.isModified() )
2048 return;
2050 maModifiable.setModified( sal_False );
2051 mbOldInfoFormat = false;
2053 // Write library container info
2054 // Create sax writer
2055 Reference< XWriter > xWriter = xml::sax::Writer::create(mxContext);
2057 // Write info file
2058 uno::Reference< io::XOutputStream > xOut;
2059 uno::Reference< io::XStream > xInfoStream;
2060 if( bStorage )
2062 OUString aStreamName( maInfoFileName );
2063 aStreamName += "-lc.xml";
2067 xInfoStream = xTargetLibrariesStor->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
2068 uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
2069 SAL_WARN_IF(
2070 !xProps.is(), "basic",
2071 "The stream must implement XPropertySet!");
2072 if ( !xProps.is() )
2074 throw uno::RuntimeException();
2076 OUString aMime( "text/xml" );
2077 xProps->setPropertyValue( OUString("MediaType"), uno::makeAny( aMime ) );
2079 // #87671 Allow encryption
2080 xProps->setPropertyValue( OUString("UseCommonStoragePasswordEncryption"), uno::makeAny( sal_True ) );
2082 xOut = xInfoStream->getOutputStream();
2084 catch(const uno::Exception& )
2086 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
2087 ErrorHandler::HandleError( nErrorCode );
2090 else
2092 // Create Output stream
2093 INetURLObject aLibInfoInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
2094 aLibInfoInetObj.insertName( maInfoFileName, sal_False, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
2095 aLibInfoInetObj.setExtension( OUString("xlc") );
2096 OUString aLibInfoPath( aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2100 if( mxSFI->exists( aLibInfoPath ) )
2102 mxSFI->kill( aLibInfoPath );
2104 xOut = mxSFI->openFileWrite( aLibInfoPath );
2106 catch(const Exception& )
2108 xOut.clear();
2109 SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
2110 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
2111 ErrorHandler::HandleError( nErrorCode );
2115 if( !xOut.is() )
2117 SAL_WARN("basic", "couldn't open output stream");
2118 return;
2121 xWriter->setOutputStream( xOut );
2125 xmlscript::exportLibraryContainer( xWriter, pLibArray.get() );
2126 if ( bStorage )
2128 uno::Reference< embed::XTransactedObject > xTransact( xTargetLibrariesStor, uno::UNO_QUERY );
2129 SAL_WARN_IF(
2130 !xTransact.is(), "basic",
2131 "The storage must implement XTransactedObject!");
2132 if ( !xTransact.is() )
2134 throw uno::RuntimeException();
2136 xTransact->commit();
2139 catch(const uno::Exception& )
2141 SAL_WARN("basic", "Problem during storing of libraries!");
2142 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
2143 ErrorHandler::HandleError( nErrorCode );
2148 // Methods XElementAccess
2149 Type SAL_CALL SfxLibraryContainer::getElementType()
2150 throw(RuntimeException)
2152 LibraryContainerMethodGuard aGuard( *this );
2153 return maNameContainer.getElementType();
2156 sal_Bool SfxLibraryContainer::hasElements()
2157 throw(RuntimeException)
2159 LibraryContainerMethodGuard aGuard( *this );
2160 sal_Bool bRet = maNameContainer.hasElements();
2161 return bRet;
2164 // Methods XNameAccess
2165 Any SfxLibraryContainer::getByName( const OUString& aName )
2166 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2168 LibraryContainerMethodGuard aGuard( *this );
2169 Any aRetAny = maNameContainer.getByName( aName ) ;
2170 return aRetAny;
2173 Sequence< OUString > SfxLibraryContainer::getElementNames()
2174 throw(RuntimeException)
2176 LibraryContainerMethodGuard aGuard( *this );
2177 return maNameContainer.getElementNames();
2180 sal_Bool SfxLibraryContainer::hasByName( const OUString& aName )
2181 throw(RuntimeException)
2183 LibraryContainerMethodGuard aGuard( *this );
2184 return maNameContainer.hasByName( aName ) ;
2187 // Methods XLibraryContainer
2188 Reference< XNameContainer > SAL_CALL SfxLibraryContainer::createLibrary( const OUString& Name )
2189 throw(IllegalArgumentException, ElementExistException, RuntimeException)
2191 LibraryContainerMethodGuard aGuard( *this );
2192 SfxLibrary* pNewLib = implCreateLibrary( Name );
2193 pNewLib->maLibElementFileExtension = maLibElementFileExtension;
2195 createVariableURL( pNewLib->maUnexpandedStorageURL, Name, maInfoFileName, true );
2197 Reference< XNameAccess > xNameAccess = static_cast< XNameAccess* >( pNewLib );
2198 Any aElement;
2199 aElement <<= xNameAccess;
2200 maNameContainer.insertByName( Name, aElement );
2201 maModifiable.setModified( sal_True );
2202 Reference< XNameContainer > xRet( xNameAccess, UNO_QUERY );
2203 return xRet;
2206 Reference< XNameAccess > SAL_CALL SfxLibraryContainer::createLibraryLink
2207 ( const OUString& Name, const OUString& StorageURL, sal_Bool ReadOnly )
2208 throw(IllegalArgumentException, ElementExistException, RuntimeException)
2210 LibraryContainerMethodGuard aGuard( *this );
2211 // TODO: Check other reasons to force ReadOnly status
2212 //if( !ReadOnly )
2216 OUString aLibInfoFileURL;
2217 OUString aLibDirURL;
2218 OUString aUnexpandedStorageURL;
2219 checkStorageURL( StorageURL, aLibInfoFileURL, aLibDirURL, aUnexpandedStorageURL );
2222 SfxLibrary* pNewLib = implCreateLibraryLink( Name, aLibInfoFileURL, aLibDirURL, ReadOnly );
2223 pNewLib->maLibElementFileExtension = maLibElementFileExtension;
2224 pNewLib->maUnexpandedStorageURL = aUnexpandedStorageURL;
2225 pNewLib->maOriginalStorageURL = StorageURL;
2227 OUString aInitFileName;
2228 uno::Reference< embed::XStorage > xDummyStor;
2229 ::xmlscript::LibDescriptor aLibDesc;
2230 implLoadLibraryIndexFile( pNewLib, aLibDesc, xDummyStor, aInitFileName );
2231 implImportLibDescriptor( pNewLib, aLibDesc );
2233 Reference< XNameAccess > xRet = static_cast< XNameAccess* >( pNewLib );
2234 Any aElement;
2235 aElement <<= xRet;
2236 maNameContainer.insertByName( Name, aElement );
2237 maModifiable.setModified( sal_True );
2239 OUString aUserSearchStr("vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE");
2240 OUString aSharedSearchStr("vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE");
2241 OUString aBundledSearchStr("vnd.sun.star.expand:$BUNDLED_EXTENSIONS");
2242 if( StorageURL.indexOf( aUserSearchStr ) != -1 )
2244 pNewLib->mbExtension = true;
2246 else if( StorageURL.indexOf( aSharedSearchStr ) != -1 || StorageURL.indexOf( aBundledSearchStr ) != -1 )
2248 pNewLib->mbExtension = true;
2249 pNewLib->mbReadOnly = sal_True;
2252 return xRet;
2255 void SAL_CALL SfxLibraryContainer::removeLibrary( const OUString& Name )
2256 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2258 LibraryContainerMethodGuard aGuard( *this );
2259 // Get and hold library before removing
2260 Any aLibAny = maNameContainer.getByName( Name ) ;
2261 Reference< XNameAccess > xNameAccess;
2262 aLibAny >>= xNameAccess;
2263 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2264 if( pImplLib->mbReadOnly && !pImplLib->mbLink )
2266 throw IllegalArgumentException();
2268 // Remove from container
2269 maNameContainer.removeByName( Name );
2270 maModifiable.setModified( sal_True );
2272 // Delete library files, but not for linked libraries
2273 if( !pImplLib->mbLink )
2275 if( mxStorage.is() )
2277 return;
2279 if( xNameAccess->hasElements() )
2281 Sequence< OUString > aNames = pImplLib->getElementNames();
2282 sal_Int32 nNameCount = aNames.getLength();
2283 const OUString* pNames = aNames.getConstArray();
2284 for( sal_Int32 i = 0 ; i < nNameCount ; ++i, ++pNames )
2286 pImplLib->removeElementWithoutChecks( *pNames, SfxLibrary::LibraryContainerAccess() );
2290 // Delete index file
2291 createAppLibraryFolder( pImplLib, Name );
2292 OUString aLibInfoPath = pImplLib->maLibInfoFileURL;
2295 if( mxSFI->exists( aLibInfoPath ) )
2297 mxSFI->kill( aLibInfoPath );
2300 catch(const Exception& ) {}
2302 // Delete folder if empty
2303 INetURLObject aInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
2304 aInetObj.insertName( Name, sal_True, INetURLObject::LAST_SEGMENT,
2305 sal_True, INetURLObject::ENCODE_ALL );
2306 OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
2310 if( mxSFI->isFolder( aLibDirPath ) )
2312 Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
2313 sal_Int32 nCount = aContentSeq.getLength();
2314 if( !nCount )
2316 mxSFI->kill( aLibDirPath );
2320 catch(const Exception& )
2326 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLoaded( const OUString& Name )
2327 throw(NoSuchElementException, RuntimeException)
2329 LibraryContainerMethodGuard aGuard( *this );
2330 SfxLibrary* pImplLib = getImplLib( Name );
2331 sal_Bool bRet = pImplLib->mbLoaded;
2332 return bRet;
2336 void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name )
2337 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2339 LibraryContainerMethodGuard aGuard( *this );
2340 Any aLibAny = maNameContainer.getByName( Name ) ;
2341 Reference< XNameAccess > xNameAccess;
2342 aLibAny >>= xNameAccess;
2343 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2345 sal_Bool bLoaded = pImplLib->mbLoaded;
2346 pImplLib->mbLoaded = sal_True;
2347 if( !bLoaded && xNameAccess->hasElements() )
2349 if( pImplLib->mbPasswordProtected )
2351 implLoadPasswordLibrary( pImplLib, Name );
2352 return;
2355 sal_Bool bLink = pImplLib->mbLink;
2356 bool bStorage = mxStorage.is() && !bLink;
2358 uno::Reference< embed::XStorage > xLibrariesStor;
2359 uno::Reference< embed::XStorage > xLibraryStor;
2360 if( bStorage )
2364 xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
2365 SAL_WARN_IF(
2366 !xLibrariesStor.is(), "basic",
2367 ("The method must either throw exception or return a"
2368 " storage!"));
2369 if ( !xLibrariesStor.is() )
2371 throw uno::RuntimeException();
2374 xLibraryStor = xLibrariesStor->openStorageElement( Name, embed::ElementModes::READ );
2375 SAL_WARN_IF(
2376 !xLibraryStor.is(), "basic",
2377 ("The method must either throw exception or return a"
2378 " storage!"));
2379 if ( !xLibrariesStor.is() )
2381 throw uno::RuntimeException();
2384 catch(const uno::Exception& )
2386 #if OSL_DEBUG_LEVEL > 0
2387 Any aError( ::cppu::getCaughtException() );
2388 SAL_WARN(
2389 "basic",
2390 "couldn't open sub storage for library \"" << Name
2391 << "\". Exception: "
2392 << comphelper::anyToString(aError));
2393 #endif
2394 return;
2398 Sequence< OUString > aNames = pImplLib->getElementNames();
2399 sal_Int32 nNameCount = aNames.getLength();
2400 const OUString* pNames = aNames.getConstArray();
2401 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
2403 OUString aElementName = pNames[ i ];
2405 OUString aFile;
2406 uno::Reference< io::XInputStream > xInStream;
2408 if( bStorage )
2410 uno::Reference< io::XStream > xElementStream;
2412 aFile = aElementName;
2413 aFile += ".xml";
2417 xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
2419 catch(const uno::Exception& )
2422 if( !xElementStream.is() )
2424 // Check for EA2 document version with wrong extensions
2425 aFile = aElementName;
2426 aFile += ".";
2427 aFile += maLibElementFileExtension;
2430 xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
2432 catch(const uno::Exception& )
2436 if ( xElementStream.is() )
2438 xInStream = xElementStream->getInputStream();
2440 if ( !xInStream.is() )
2442 SAL_WARN(
2443 "basic",
2444 "couldn't open library element stream - attempted to"
2445 " open library \"" << Name << '"');
2446 return;
2449 else
2451 OUString aLibDirPath = pImplLib->maStorageURL;
2452 INetURLObject aElementInetObj( aLibDirPath );
2453 aElementInetObj.insertName( aElementName, sal_False,
2454 INetURLObject::LAST_SEGMENT, sal_True,
2455 INetURLObject::ENCODE_ALL );
2456 aElementInetObj.setExtension( maLibElementFileExtension );
2457 aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
2460 Reference< XNameContainer > xLib( pImplLib );
2461 Any aAny = importLibraryElement( xLib, aElementName,
2462 aFile, xInStream );
2463 if( pImplLib->hasByName( aElementName ) )
2465 if( aAny.hasValue() )
2467 pImplLib->maNameContainer.replaceByName( aElementName, aAny );
2470 else
2472 pImplLib->maNameContainer.insertByName( aElementName, aAny );
2475 pImplLib->implSetModified( sal_False );
2479 // Methods XLibraryContainer2
2480 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLink( const OUString& Name )
2481 throw (NoSuchElementException, RuntimeException)
2483 LibraryContainerMethodGuard aGuard( *this );
2484 SfxLibrary* pImplLib = getImplLib( Name );
2485 sal_Bool bRet = pImplLib->mbLink;
2486 return bRet;
2489 OUString SAL_CALL SfxLibraryContainer::getLibraryLinkURL( const OUString& Name )
2490 throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
2492 LibraryContainerMethodGuard aGuard( *this );
2493 SfxLibrary* pImplLib = getImplLib( Name );
2494 sal_Bool bLink = pImplLib->mbLink;
2495 if( !bLink )
2497 throw IllegalArgumentException();
2499 OUString aRetStr = pImplLib->maLibInfoFileURL;
2500 return aRetStr;
2503 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryReadOnly( const OUString& Name )
2504 throw (NoSuchElementException, RuntimeException)
2506 LibraryContainerMethodGuard aGuard( *this );
2507 SfxLibrary* pImplLib = getImplLib( Name );
2508 sal_Bool bRet = pImplLib->mbReadOnly || (pImplLib->mbLink && pImplLib->mbReadOnlyLink);
2509 return bRet;
2512 void SAL_CALL SfxLibraryContainer::setLibraryReadOnly( const OUString& Name, sal_Bool bReadOnly )
2513 throw (NoSuchElementException, RuntimeException)
2515 LibraryContainerMethodGuard aGuard( *this );
2516 SfxLibrary* pImplLib = getImplLib( Name );
2517 if( pImplLib->mbLink )
2519 if( pImplLib->mbReadOnlyLink != bReadOnly )
2521 pImplLib->mbReadOnlyLink = bReadOnly;
2522 pImplLib->implSetModified( sal_True );
2523 maModifiable.setModified( sal_True );
2526 else
2528 if( pImplLib->mbReadOnly != bReadOnly )
2530 pImplLib->mbReadOnly = bReadOnly;
2531 pImplLib->implSetModified( sal_True );
2536 void SAL_CALL SfxLibraryContainer::renameLibrary( const OUString& Name, const OUString& NewName )
2537 throw (NoSuchElementException, ElementExistException, RuntimeException)
2539 LibraryContainerMethodGuard aGuard( *this );
2540 if( maNameContainer.hasByName( NewName ) )
2542 throw ElementExistException();
2544 // Get and hold library before removing
2545 Any aLibAny = maNameContainer.getByName( Name ) ;
2547 // #i24094 Maybe lib is not loaded!
2548 Reference< XNameAccess > xNameAccess;
2549 aLibAny >>= xNameAccess;
2550 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2551 if( pImplLib->mbPasswordProtected && !pImplLib->mbPasswordVerified )
2553 return; // Lib with unverified password cannot be renamed
2555 loadLibrary( Name );
2557 // Remove from container
2558 maNameContainer.removeByName( Name );
2559 maModifiable.setModified( sal_True );
2561 // Rename library folder, but not for linked libraries
2562 bool bMovedSuccessful = true;
2564 // Rename files
2565 bool bStorage = mxStorage.is();
2566 if( !bStorage && !pImplLib->mbLink )
2568 bMovedSuccessful = false;
2570 OUString aLibDirPath = pImplLib->maStorageURL;
2572 INetURLObject aDestInetObj( maLibraryPath.getToken(1, (sal_Unicode)';'));
2573 aDestInetObj.insertName( NewName, sal_True, INetURLObject::LAST_SEGMENT,
2574 sal_True, INetURLObject::ENCODE_ALL );
2575 OUString aDestDirPath = aDestInetObj.GetMainURL( INetURLObject::NO_DECODE );
2577 // Store new URL
2578 OUString aLibInfoFileURL = pImplLib->maLibInfoFileURL;
2579 checkStorageURL( aDestDirPath, pImplLib->maLibInfoFileURL, pImplLib->maStorageURL,
2580 pImplLib->maUnexpandedStorageURL );
2584 if( mxSFI->isFolder( aLibDirPath ) )
2586 if( !mxSFI->isFolder( aDestDirPath ) )
2588 mxSFI->createFolder( aDestDirPath );
2590 // Move index file
2593 if( mxSFI->exists( pImplLib->maLibInfoFileURL ) )
2595 mxSFI->kill( pImplLib->maLibInfoFileURL );
2597 mxSFI->move( aLibInfoFileURL, pImplLib->maLibInfoFileURL );
2599 catch(const Exception& )
2603 Sequence< OUString > aElementNames = xNameAccess->getElementNames();
2604 sal_Int32 nNameCount = aElementNames.getLength();
2605 const OUString* pNames = aElementNames.getConstArray();
2606 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
2608 OUString aElementName = pNames[ i ];
2610 INetURLObject aElementInetObj( aLibDirPath );
2611 aElementInetObj.insertName( aElementName, sal_False,
2612 INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
2613 aElementInetObj.setExtension( maLibElementFileExtension );
2614 OUString aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2616 INetURLObject aElementDestInetObj( aDestDirPath );
2617 aElementDestInetObj.insertName( aElementName, sal_False,
2618 INetURLObject::LAST_SEGMENT, sal_True,
2619 INetURLObject::ENCODE_ALL );
2620 aElementDestInetObj.setExtension( maLibElementFileExtension );
2621 OUString aDestElementPath( aElementDestInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2625 if( mxSFI->exists( aDestElementPath ) )
2627 mxSFI->kill( aDestElementPath );
2629 mxSFI->move( aElementPath, aDestElementPath );
2631 catch(const Exception& )
2635 pImplLib->storeResourcesAsURL( aDestDirPath, NewName );
2637 // Delete folder if empty
2638 Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
2639 sal_Int32 nCount = aContentSeq.getLength();
2640 if( !nCount )
2642 mxSFI->kill( aLibDirPath );
2645 bMovedSuccessful = true;
2646 pImplLib->implSetModified( sal_True );
2649 catch(const Exception& )
2651 // Restore old library
2652 maNameContainer.insertByName( Name, aLibAny ) ;
2656 if( bStorage && !pImplLib->mbLink )
2658 pImplLib->implSetModified( sal_True );
2660 if( bMovedSuccessful )
2662 maNameContainer.insertByName( NewName, aLibAny ) ;
2667 // Methods XInitialization
2668 void SAL_CALL SfxLibraryContainer::initialize( const Sequence< Any >& _rArguments )
2669 throw (Exception, RuntimeException)
2671 LibraryContainerMethodGuard aGuard( *this );
2672 sal_Int32 nArgCount = _rArguments.getLength();
2673 if ( nArgCount == 1 )
2675 OUString sInitialDocumentURL;
2676 Reference< XStorageBasedDocument > xDocument;
2677 if ( _rArguments[0] >>= sInitialDocumentURL )
2679 initializeFromDocumentURL( sInitialDocumentURL );
2680 return;
2683 if ( _rArguments[0] >>= xDocument )
2685 initializeFromDocument( xDocument );
2686 return;
2690 throw IllegalArgumentException();
2693 void SAL_CALL SfxLibraryContainer::initializeFromDocumentURL( const OUString& _rInitialDocumentURL )
2695 init( _rInitialDocumentURL, NULL );
2698 void SAL_CALL SfxLibraryContainer::initializeFromDocument( const Reference< XStorageBasedDocument >& _rxDocument )
2700 // check whether this is a valid OfficeDocument, and obtain the document's root storage
2701 Reference< XStorage > xDocStorage;
2704 Reference< XServiceInfo > xSI( _rxDocument, UNO_QUERY_THROW );
2705 if ( xSI->supportsService( OUString("com.sun.star.document.OfficeDocument")))
2707 xDocStorage.set( _rxDocument->getDocumentStorage(), UNO_QUERY_THROW );
2709 Reference< XModel > xDocument( _rxDocument, UNO_QUERY_THROW );
2710 Reference< XComponent > xDocComponent( _rxDocument, UNO_QUERY_THROW );
2712 mxOwnerDocument = xDocument;
2713 startComponentListening( xDocComponent );
2715 catch( const Exception& ) { }
2717 if ( !xDocStorage.is() )
2719 throw IllegalArgumentException();
2721 init( OUString(), xDocStorage );
2724 // OEventListenerAdapter
2725 void SfxLibraryContainer::_disposing( const EventObject& _rSource )
2727 #if OSL_DEBUG_LEVEL > 0
2728 Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
2729 SAL_WARN_IF(
2730 xDocument != _rSource.Source || !xDocument.is(), "basic",
2731 "SfxLibraryContainer::_disposing: where does this come from?");
2732 #else
2733 (void)_rSource;
2734 #endif
2735 dispose();
2738 // OComponentHelper
2739 void SAL_CALL SfxLibraryContainer::disposing()
2741 Reference< XModel > xModel = mxOwnerDocument;
2742 EventObject aEvent( xModel.get() );
2743 maVBAScriptListeners.disposing( aEvent );
2744 stopAllComponentListening();
2745 mxOwnerDocument = WeakReference< XModel >();
2748 // Methods XLibraryContainerPassword
2749 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordProtected( const OUString& )
2750 throw (NoSuchElementException, RuntimeException)
2752 LibraryContainerMethodGuard aGuard( *this );
2753 return sal_False;
2756 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordVerified( const OUString& )
2757 throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
2759 LibraryContainerMethodGuard aGuard( *this );
2760 throw IllegalArgumentException();
2763 sal_Bool SAL_CALL SfxLibraryContainer::verifyLibraryPassword( const OUString&, const OUString& )
2764 throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
2766 LibraryContainerMethodGuard aGuard( *this );
2767 throw IllegalArgumentException();
2770 void SAL_CALL SfxLibraryContainer::changeLibraryPassword(const OUString&, const OUString&, const OUString& )
2771 throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
2773 LibraryContainerMethodGuard aGuard( *this );
2774 throw IllegalArgumentException();
2777 // Methods XContainer
2778 void SAL_CALL SfxLibraryContainer::addContainerListener( const Reference< XContainerListener >& xListener )
2779 throw (RuntimeException)
2781 LibraryContainerMethodGuard aGuard( *this );
2782 maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
2783 maNameContainer.addContainerListener( xListener );
2786 void SAL_CALL SfxLibraryContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
2787 throw (RuntimeException)
2789 LibraryContainerMethodGuard aGuard( *this );
2790 maNameContainer.removeContainerListener( xListener );
2793 // Methods XLibraryContainerExport
2794 void SAL_CALL SfxLibraryContainer::exportLibrary( const OUString& Name, const OUString& URL,
2795 const Reference< XInteractionHandler >& Handler )
2796 throw ( uno::Exception, NoSuchElementException, RuntimeException)
2798 LibraryContainerMethodGuard aGuard( *this );
2799 SfxLibrary* pImplLib = getImplLib( Name );
2801 Reference< XSimpleFileAccess3 > xToUseSFI;
2802 if( Handler.is() )
2804 xToUseSFI = ucb::SimpleFileAccess::create( mxContext );
2805 xToUseSFI->setInteractionHandler( Handler );
2808 // Maybe lib is not loaded?!
2809 loadLibrary( Name );
2811 uno::Reference< ::com::sun::star::embed::XStorage > xDummyStor;
2812 if( pImplLib->mbPasswordProtected )
2814 implStorePasswordLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
2816 else
2818 implStoreLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
2820 ::xmlscript::LibDescriptor aLibDesc;
2821 aLibDesc.aName = Name;
2822 aLibDesc.bLink = false; // Link status gets lost?
2823 aLibDesc.bReadOnly = pImplLib->mbReadOnly;
2824 aLibDesc.bPreload = false; // Preload status gets lost?
2825 aLibDesc.bPasswordProtected = pImplLib->mbPasswordProtected;
2826 aLibDesc.aElementNames = pImplLib->getElementNames();
2828 implStoreLibraryIndexFile( pImplLib, aLibDesc, xDummyStor, URL, xToUseSFI );
2831 OUString SfxLibraryContainer::expand_url( const OUString& url )
2832 throw(::com::sun::star::uno::RuntimeException)
2834 if (url.startsWith( EXPAND_PROTOCOL ":" ))
2836 if( !mxMacroExpander.is() )
2838 Reference< util::XMacroExpander > xExpander = util::theMacroExpander::get(mxContext);
2839 MutexGuard guard( Mutex::getGlobalMutex() );
2840 if( !mxMacroExpander.is() )
2842 mxMacroExpander = xExpander;
2846 if( !mxMacroExpander.is() )
2848 return url;
2850 // cut protocol
2851 OUString macro( url.copy( sizeof (EXPAND_PROTOCOL ":") -1 ) );
2852 // decode uric class chars
2853 macro = Uri::decode( macro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
2854 // expand macro string
2855 OUString ret( mxMacroExpander->expandMacros( macro ) );
2856 return ret;
2858 else if( mxStringSubstitution.is() )
2860 OUString ret( mxStringSubstitution->substituteVariables( url, false ) );
2861 return ret;
2863 else
2865 return url;
2869 //XLibraryContainer3
2870 OUString SAL_CALL SfxLibraryContainer::getOriginalLibraryLinkURL( const OUString& Name )
2871 throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
2873 LibraryContainerMethodGuard aGuard( *this );
2874 SfxLibrary* pImplLib = getImplLib( Name );
2875 sal_Bool bLink = pImplLib->mbLink;
2876 if( !bLink )
2878 throw IllegalArgumentException();
2880 OUString aRetStr = pImplLib->maOriginalStorageURL;
2881 return aRetStr;
2885 // XVBACompatibility
2886 sal_Bool SAL_CALL SfxLibraryContainer::getVBACompatibilityMode() throw (RuntimeException)
2888 return mbVBACompat;
2891 void SAL_CALL SfxLibraryContainer::setVBACompatibilityMode( ::sal_Bool _vbacompatmodeon ) throw (RuntimeException)
2893 /* The member variable mbVBACompat must be set first, the following call
2894 to getBasicManager() may call getVBACompatibilityMode() which returns
2895 this value. */
2896 mbVBACompat = _vbacompatmodeon;
2897 if( BasicManager* pBasMgr = getBasicManager() )
2899 // get the standard library
2900 OUString aLibName = pBasMgr->GetName();
2901 if ( aLibName.isEmpty())
2903 aLibName = "Standard";
2905 if( StarBASIC* pBasic = pBasMgr->GetLib( aLibName ) )
2907 pBasic->SetVBAEnabled( _vbacompatmodeon );
2909 /* If in VBA compatibility mode, force creation of the VBA Globals
2910 object. Each application will create an instance of its own
2911 implementation and store it in its Basic manager. Implementations
2912 will do all necessary additional initialization, such as
2913 registering the global "This***Doc" UNO constant, starting the
2914 document events processor etc.
2916 if( mbVBACompat ) try
2918 Reference< XModel > xModel( mxOwnerDocument ); // weak-ref -> ref
2919 Reference< XMultiServiceFactory > xFactory( xModel, UNO_QUERY_THROW );
2920 xFactory->createInstance( OUString( "ooo.vba.VBAGlobals"));
2922 catch(const Exception& )
2928 void SAL_CALL SfxLibraryContainer::setProjectName( const OUString& _projectname ) throw (RuntimeException)
2930 msProjectName = _projectname;
2931 BasicManager* pBasMgr = getBasicManager();
2932 // Temporary HACK
2933 // Some parts of the VBA handling ( e.g. in core basic )
2934 // code expect the name of the VBA project to be set as the name of
2935 // the basic manager. Provide fail back here.
2936 if( pBasMgr )
2938 pBasMgr->SetName( msProjectName );
2942 sal_Int32 SAL_CALL SfxLibraryContainer::getRunningVBAScripts() throw (RuntimeException)
2944 LibraryContainerMethodGuard aGuard( *this );
2945 return mnRunningVBAScripts;
2948 void SAL_CALL SfxLibraryContainer::addVBAScriptListener( const Reference< vba::XVBAScriptListener >& rxListener ) throw (RuntimeException)
2950 maVBAScriptListeners.addTypedListener( rxListener );
2953 void SAL_CALL SfxLibraryContainer::removeVBAScriptListener( const Reference< vba::XVBAScriptListener >& rxListener ) throw (RuntimeException)
2955 maVBAScriptListeners.removeTypedListener( rxListener );
2958 void SAL_CALL SfxLibraryContainer::broadcastVBAScriptEvent( sal_Int32 nIdentifier, const OUString& rModuleName ) throw (RuntimeException)
2960 // own lock for accessing the number of running scripts
2961 enterMethod();
2962 switch( nIdentifier )
2964 case vba::VBAScriptEventId::SCRIPT_STARTED:
2965 ++mnRunningVBAScripts;
2966 break;
2967 case vba::VBAScriptEventId::SCRIPT_STOPPED:
2968 --mnRunningVBAScripts;
2969 break;
2971 leaveMethod();
2973 Reference< XModel > xModel = mxOwnerDocument; // weak-ref -> ref
2974 Reference< XInterface > xSender( xModel, UNO_QUERY_THROW );
2975 vba::VBAScriptEvent aEvent( xSender, nIdentifier, rModuleName );
2976 maVBAScriptListeners.notify( aEvent );
2979 // Methods XServiceInfo
2980 sal_Bool SAL_CALL SfxLibraryContainer::supportsService( const OUString& _rServiceName )
2981 throw (RuntimeException)
2983 LibraryContainerMethodGuard aGuard( *this );
2984 Sequence< OUString > aSupportedServices( getSupportedServiceNames() );
2985 const OUString* pSupportedServices = aSupportedServices.getConstArray();
2986 for ( sal_Int32 i=0; i<aSupportedServices.getLength(); ++i, ++pSupportedServices )
2988 if ( *pSupportedServices == _rServiceName )
2990 return sal_True;
2993 return sal_False;
2996 //============================================================================
2998 // Implementation class SfxLibrary
3000 // Ctor
3001 SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
3002 const Reference< XComponentContext >& xContext, const Reference< XSimpleFileAccess3 >& xSFI )
3003 : OComponentHelper( m_aMutex )
3004 , mxContext( xContext )
3005 , mxSFI( xSFI )
3006 , mrModifiable( _rModifiable )
3007 , maNameContainer( aType )
3008 , mbLoaded( sal_True )
3009 , mbIsModified( sal_True )
3010 , mbInitialised( false )
3011 , mbLink( sal_False )
3012 , mbReadOnly( sal_False )
3013 , mbReadOnlyLink( sal_False )
3014 , mbPreload( sal_False )
3015 , mbPasswordProtected( sal_False )
3016 , mbPasswordVerified( sal_False )
3017 , mbDoc50Password( false )
3018 , mbSharedIndexFile( false )
3019 , mbExtension( false )
3023 SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
3024 const Reference< XComponentContext >& xContext, const Reference< XSimpleFileAccess3 >& xSFI,
3025 const OUString& aLibInfoFileURL, const OUString& aStorageURL, sal_Bool ReadOnly )
3026 : OComponentHelper( m_aMutex )
3027 , mxContext( xContext )
3028 , mxSFI( xSFI )
3029 , mrModifiable( _rModifiable )
3030 , maNameContainer( aType )
3031 , mbLoaded( sal_False )
3032 , mbIsModified( sal_True )
3033 , mbInitialised( false )
3034 , maLibInfoFileURL( aLibInfoFileURL )
3035 , maStorageURL( aStorageURL )
3036 , mbLink( sal_True )
3037 , mbReadOnly( sal_False )
3038 , mbReadOnlyLink( ReadOnly )
3039 , mbPreload( sal_False )
3040 , mbPasswordProtected( sal_False )
3041 , mbPasswordVerified( sal_False )
3042 , mbDoc50Password( false )
3043 , mbSharedIndexFile( false )
3044 , mbExtension( false )
3048 void SfxLibrary::implSetModified( sal_Bool _bIsModified )
3050 if ( mbIsModified == _bIsModified )
3052 return;
3054 mbIsModified = _bIsModified;
3055 if ( mbIsModified )
3057 mrModifiable.setModified( sal_True );
3061 // Methods XInterface
3062 Any SAL_CALL SfxLibrary::queryInterface( const Type& rType )
3063 throw( RuntimeException )
3065 Any aRet;
3067 aRet = Any(
3068 ::cppu::queryInterface(
3069 rType,
3070 static_cast< XContainer * >( this ),
3071 static_cast< XNameContainer * >( this ),
3072 static_cast< XNameAccess * >( this ),
3073 static_cast< XElementAccess * >( this ),
3074 static_cast< XChangesNotifier * >( this ) ) );
3075 if( !aRet.hasValue() )
3077 aRet = OComponentHelper::queryInterface( rType );
3079 return aRet;
3082 // Methods XElementAccess
3083 Type SfxLibrary::getElementType()
3084 throw(RuntimeException)
3086 return maNameContainer.getElementType();
3089 sal_Bool SfxLibrary::hasElements()
3090 throw(RuntimeException)
3092 sal_Bool bRet = maNameContainer.hasElements();
3093 return bRet;
3096 // Methods XNameAccess
3097 Any SfxLibrary::getByName( const OUString& aName )
3098 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
3100 impl_checkLoaded();
3102 Any aRetAny = maNameContainer.getByName( aName ) ;
3103 return aRetAny;
3106 Sequence< OUString > SfxLibrary::getElementNames()
3107 throw(RuntimeException)
3109 return maNameContainer.getElementNames();
3112 sal_Bool SfxLibrary::hasByName( const OUString& aName )
3113 throw(RuntimeException)
3115 sal_Bool bRet = maNameContainer.hasByName( aName );
3116 return bRet;
3119 void SfxLibrary::impl_checkReadOnly()
3121 if( mbReadOnly || (mbLink && mbReadOnlyLink) )
3123 throw IllegalArgumentException(
3124 OUString("Library is readonly."),
3125 // TODO: resource
3126 *this, 0
3131 void SfxLibrary::impl_checkLoaded()
3133 if ( !mbLoaded )
3135 throw WrappedTargetException(
3136 OUString(),
3137 *this,
3138 makeAny( LibraryNotLoadedException(
3139 OUString(),
3140 *this
3146 // Methods XNameReplace
3147 void SfxLibrary::replaceByName( const OUString& aName, const Any& aElement )
3148 throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
3150 impl_checkReadOnly();
3151 impl_checkLoaded();
3153 SAL_WARN_IF(
3154 !isLibraryElementValid(aElement), "basic",
3155 "SfxLibrary::replaceByName: replacing element is invalid!");
3157 maNameContainer.replaceByName( aName, aElement );
3158 implSetModified( sal_True );
3162 // Methods XNameContainer
3163 void SfxLibrary::insertByName( const OUString& aName, const Any& aElement )
3164 throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
3166 impl_checkReadOnly();
3167 impl_checkLoaded();
3169 SAL_WARN_IF(
3170 !isLibraryElementValid(aElement), "basic",
3171 "SfxLibrary::insertByName: to-be-inserted element is invalid!");
3173 maNameContainer.insertByName( aName, aElement );
3174 implSetModified( sal_True );
3177 void SfxLibrary::impl_removeWithoutChecks( const OUString& _rElementName )
3179 maNameContainer.removeByName( _rElementName );
3180 implSetModified( sal_True );
3182 // Remove element file
3183 if( !maStorageURL.isEmpty() )
3185 INetURLObject aElementInetObj( maStorageURL );
3186 aElementInetObj.insertName( _rElementName, sal_False,
3187 INetURLObject::LAST_SEGMENT, sal_True,
3188 INetURLObject::ENCODE_ALL );
3189 aElementInetObj.setExtension( maLibElementFileExtension );
3190 OUString aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
3194 if( mxSFI->exists( aFile ) )
3196 mxSFI->kill( aFile );
3199 catch(const Exception& )
3201 DBG_UNHANDLED_EXCEPTION();
3206 void SfxLibrary::removeByName( const OUString& Name )
3207 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
3209 impl_checkReadOnly();
3210 impl_checkLoaded();
3211 impl_removeWithoutChecks( Name );
3214 // XTypeProvider
3215 Sequence< Type > SfxLibrary::getTypes()
3216 throw( RuntimeException )
3218 static OTypeCollection * s_pTypes_NameContainer = 0;
3220 if( !s_pTypes_NameContainer )
3222 MutexGuard aGuard( Mutex::getGlobalMutex() );
3223 if( !s_pTypes_NameContainer )
3225 static OTypeCollection s_aTypes_NameContainer(
3226 ::getCppuType( (const Reference< XNameContainer > *)0 ),
3227 ::getCppuType( (const Reference< XContainer > *)0 ),
3228 ::getCppuType( (const Reference< XChangesNotifier > *)0 ),
3229 OComponentHelper::getTypes() );
3230 s_pTypes_NameContainer = &s_aTypes_NameContainer;
3233 return s_pTypes_NameContainer->getTypes();
3238 Sequence< sal_Int8 > SfxLibrary::getImplementationId()
3239 throw( RuntimeException )
3241 static OImplementationId * s_pId_NameContainer = 0;
3243 if( !s_pId_NameContainer )
3245 MutexGuard aGuard( Mutex::getGlobalMutex() );
3246 if( !s_pId_NameContainer )
3248 static OImplementationId s_aId_NameContainer;
3249 s_pId_NameContainer = &s_aId_NameContainer;
3252 return s_pId_NameContainer->getImplementationId();
3256 // Methods XContainer
3257 void SAL_CALL SfxLibrary::addContainerListener( const Reference< XContainerListener >& xListener )
3258 throw (RuntimeException)
3260 maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
3261 maNameContainer.addContainerListener( xListener );
3264 void SAL_CALL SfxLibrary::removeContainerListener( const Reference< XContainerListener >& xListener )
3265 throw (RuntimeException)
3267 maNameContainer.removeContainerListener( xListener );
3270 // Methods XChangesNotifier
3271 void SAL_CALL SfxLibrary::addChangesListener( const Reference< XChangesListener >& xListener )
3272 throw (RuntimeException)
3274 maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
3275 maNameContainer.addChangesListener( xListener );
3278 void SAL_CALL SfxLibrary::removeChangesListener( const Reference< XChangesListener >& xListener )
3279 throw (RuntimeException)
3281 maNameContainer.removeChangesListener( xListener );
3284 //============================================================================
3285 // Implementation class ScriptExtensionIterator
3287 #define sBasicLibMediaType "application/vnd.sun.star.basic-library"
3288 #define sDialogLibMediaType "application/vnd.sun.star.dialog-library"
3290 ScriptExtensionIterator::ScriptExtensionIterator( void )
3291 : m_xContext( comphelper::getProcessComponentContext() )
3292 , m_eState( USER_EXTENSIONS )
3293 , m_bUserPackagesLoaded( false )
3294 , m_bSharedPackagesLoaded( false )
3295 , m_bBundledPackagesLoaded( false )
3296 , m_iUserPackage( 0 )
3297 , m_iSharedPackage( 0 )
3298 , m_iBundledPackage( 0 )
3299 , m_pScriptSubPackageIterator( NULL )
3302 OUString ScriptExtensionIterator::nextBasicOrDialogLibrary( bool& rbPureDialogLib )
3304 OUString aRetLib;
3306 while( aRetLib.isEmpty() && m_eState != END_REACHED )
3308 switch( m_eState )
3310 case USER_EXTENSIONS:
3312 Reference< deployment::XPackage > xScriptPackage =
3313 implGetNextUserScriptPackage( rbPureDialogLib );
3314 if( !xScriptPackage.is() )
3316 break;
3318 aRetLib = xScriptPackage->getURL();
3319 break;
3322 case SHARED_EXTENSIONS:
3324 Reference< deployment::XPackage > xScriptPackage =
3325 implGetNextSharedScriptPackage( rbPureDialogLib );
3326 if( !xScriptPackage.is() )
3328 break;
3330 aRetLib = xScriptPackage->getURL();
3331 break;
3333 case BUNDLED_EXTENSIONS:
3335 Reference< deployment::XPackage > xScriptPackage =
3336 implGetNextBundledScriptPackage( rbPureDialogLib );
3337 if( !xScriptPackage.is() )
3339 break;
3341 aRetLib = xScriptPackage->getURL();
3342 break;
3344 case END_REACHED:
3345 SAL_WARN(
3346 "basic",
3347 ("ScriptExtensionIterator::nextBasicOrDialogLibrary():"
3348 " Invalid case END_REACHED"));
3349 break;
3353 return aRetLib;
3356 ScriptSubPackageIterator::ScriptSubPackageIterator( Reference< deployment::XPackage > xMainPackage )
3357 : m_xMainPackage( xMainPackage )
3358 , m_bIsValid( false )
3359 , m_bIsBundle( false )
3360 , m_nSubPkgCount( 0 )
3361 , m_iNextSubPkg( 0 )
3363 Reference< deployment::XPackage > xScriptPackage;
3364 if( !m_xMainPackage.is() )
3366 return;
3368 // Check if parent package is registered
3369 beans::Optional< beans::Ambiguous<sal_Bool> > option( m_xMainPackage->isRegistered
3370 ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
3371 bool bRegistered = false;
3372 if( option.IsPresent )
3374 beans::Ambiguous<sal_Bool> const & reg = option.Value;
3375 if( !reg.IsAmbiguous && reg.Value )
3377 bRegistered = true;
3380 if( bRegistered )
3382 m_bIsValid = true;
3383 if( m_xMainPackage->isBundle() )
3385 m_bIsBundle = true;
3386 m_aSubPkgSeq = m_xMainPackage->getBundle( Reference<task::XAbortChannel>(),
3387 Reference<ucb::XCommandEnvironment>() );
3388 m_nSubPkgCount = m_aSubPkgSeq.getLength();
3393 Reference< deployment::XPackage > ScriptSubPackageIterator::getNextScriptSubPackage( bool& rbPureDialogLib )
3395 rbPureDialogLib = false;
3397 Reference< deployment::XPackage > xScriptPackage;
3398 if( !m_bIsValid )
3400 return xScriptPackage;
3402 if( m_bIsBundle )
3404 const Reference< deployment::XPackage >* pSeq = m_aSubPkgSeq.getConstArray();
3405 sal_Int32 iPkg;
3406 for( iPkg = m_iNextSubPkg ; iPkg < m_nSubPkgCount ; ++iPkg )
3408 const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
3409 xScriptPackage = implDetectScriptPackage( xSubPkg, rbPureDialogLib );
3410 if( xScriptPackage.is() )
3412 break;
3415 m_iNextSubPkg = iPkg + 1;
3417 else
3419 xScriptPackage = implDetectScriptPackage( m_xMainPackage, rbPureDialogLib );
3420 m_bIsValid = false; // No more script packages
3423 return xScriptPackage;
3426 Reference< deployment::XPackage > ScriptSubPackageIterator::implDetectScriptPackage ( const Reference< deployment::XPackage > xPackage,
3427 bool& rbPureDialogLib )
3429 Reference< deployment::XPackage > xScriptPackage;
3431 if( xPackage.is() )
3433 const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType();
3434 OUString aMediaType = xPackageTypeInfo->getMediaType();
3435 if ( aMediaType == sBasicLibMediaType )
3437 xScriptPackage = xPackage;
3439 else if ( aMediaType == sDialogLibMediaType )
3441 rbPureDialogLib = true;
3442 xScriptPackage = xPackage;
3446 return xScriptPackage;
3449 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextUserScriptPackage( bool& rbPureDialogLib )
3451 Reference< deployment::XPackage > xScriptPackage;
3453 if( !m_bUserPackagesLoaded )
3457 Reference< XExtensionManager > xManager = ExtensionManager::get( m_xContext );
3458 m_aUserPackagesSeq = xManager->getDeployedExtensions(OUString("user"),
3459 Reference< task::XAbortChannel >(),
3460 Reference< ucb::XCommandEnvironment >() );
3462 catch(const com::sun::star::uno::DeploymentException& )
3464 // Special Office installations may not contain deployment code
3465 m_eState = END_REACHED;
3466 return xScriptPackage;
3469 m_bUserPackagesLoaded = true;
3472 if( m_iUserPackage == m_aUserPackagesSeq.getLength() )
3474 m_eState = SHARED_EXTENSIONS; // Later: SHARED_MODULE
3476 else
3478 if( m_pScriptSubPackageIterator == NULL )
3480 const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray();
3481 Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage ];
3482 SAL_WARN_IF(
3483 !xPackage.is(), "basic",
3484 ("ScriptExtensionIterator::implGetNextUserScriptPackage():"
3485 " Invalid package"));
3486 m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3489 if( m_pScriptSubPackageIterator != NULL )
3491 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3492 if( !xScriptPackage.is() )
3494 delete m_pScriptSubPackageIterator;
3495 m_pScriptSubPackageIterator = NULL;
3496 m_iUserPackage++;
3501 return xScriptPackage;
3504 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextSharedScriptPackage( bool& rbPureDialogLib )
3506 Reference< deployment::XPackage > xScriptPackage;
3508 if( !m_bSharedPackagesLoaded )
3512 Reference< XExtensionManager > xSharedManager = ExtensionManager::get( m_xContext );
3513 m_aSharedPackagesSeq = xSharedManager->getDeployedExtensions(OUString("shared"),
3514 Reference< task::XAbortChannel >(),
3515 Reference< ucb::XCommandEnvironment >() );
3517 catch(const com::sun::star::uno::DeploymentException& )
3519 // Special Office installations may not contain deployment code
3520 return xScriptPackage;
3523 m_bSharedPackagesLoaded = true;
3526 if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() )
3528 m_eState = BUNDLED_EXTENSIONS;
3530 else
3532 if( m_pScriptSubPackageIterator == NULL )
3534 const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray();
3535 Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage ];
3536 SAL_WARN_IF(
3537 !xPackage.is(), "basic",
3538 ("ScriptExtensionIterator::implGetNextSharedScriptPackage():"
3539 " Invalid package"));
3540 m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3543 if( m_pScriptSubPackageIterator != NULL )
3545 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3546 if( !xScriptPackage.is() )
3548 delete m_pScriptSubPackageIterator;
3549 m_pScriptSubPackageIterator = NULL;
3550 m_iSharedPackage++;
3555 return xScriptPackage;
3558 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextBundledScriptPackage( bool& rbPureDialogLib )
3560 Reference< deployment::XPackage > xScriptPackage;
3562 if( !m_bBundledPackagesLoaded )
3566 Reference< XExtensionManager > xManager = ExtensionManager::get( m_xContext );
3567 m_aBundledPackagesSeq = xManager->getDeployedExtensions(OUString("bundled"),
3568 Reference< task::XAbortChannel >(),
3569 Reference< ucb::XCommandEnvironment >() );
3571 catch(const com::sun::star::uno::DeploymentException& )
3573 // Special Office installations may not contain deployment code
3574 return xScriptPackage;
3577 m_bBundledPackagesLoaded = true;
3580 if( m_iBundledPackage == m_aBundledPackagesSeq.getLength() )
3582 m_eState = END_REACHED;
3584 else
3586 if( m_pScriptSubPackageIterator == NULL )
3588 const Reference< deployment::XPackage >* pBundledPackages = m_aBundledPackagesSeq.getConstArray();
3589 Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage ];
3590 SAL_WARN_IF(
3591 !xPackage.is(), "basic",
3592 ("ScriptExtensionIterator::implGetNextBundledScriptPackage():"
3593 " Invalid package"));
3594 m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3597 if( m_pScriptSubPackageIterator != NULL )
3599 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3600 if( !xScriptPackage.is() )
3602 delete m_pScriptSubPackageIterator;
3603 m_pScriptSubPackageIterator = NULL;
3604 m_iBundledPackage++;
3609 return xScriptPackage;
3612 } // namespace basic
3614 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */