1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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_extensions.h>
21 #include <config_folders.h>
23 #include <com/sun/star/container/XNameContainer.hpp>
24 #include <com/sun/star/container/XContainer.hpp>
25 #include <com/sun/star/embed/ElementModes.hpp>
26 #include <com/sun/star/embed/XTransactedObject.hpp>
27 #include <com/sun/star/io/IOException.hpp>
28 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
29 #include <com/sun/star/lang/XServiceInfo.hpp>
30 #include <com/sun/star/ucb/ContentCreationException.hpp>
31 #include <com/sun/star/xml/sax/SAXException.hpp>
32 #include <vcl/svapp.hxx>
33 #include <osl/mutex.hxx>
34 #include <vcl/errinf.hxx>
35 #include <rtl/ustring.hxx>
36 #include <sal/log.hxx>
37 #include <sot/storage.hxx>
38 #include <comphelper/getexpandeduri.hxx>
39 #include <comphelper/processfactory.hxx>
40 #include <comphelper/sequence.hxx>
42 #include <namecont.hxx>
43 #include <basic/basicmanagerrepository.hxx>
44 #include <tools/diagnose_ex.h>
45 #include <tools/urlobj.hxx>
46 #include <unotools/pathoptions.hxx>
47 #include <svtools/sfxecode.hxx>
48 #include <svtools/ehdl.hxx>
49 #include <basic/basmgr.hxx>
50 #include <com/sun/star/xml/sax/Parser.hpp>
51 #include <com/sun/star/xml/sax/InputSource.hpp>
52 #include <com/sun/star/io/XOutputStream.hpp>
53 #include <com/sun/star/xml/sax/Writer.hpp>
54 #include <com/sun/star/io/XInputStream.hpp>
55 #include <com/sun/star/beans/XPropertySet.hpp>
56 #include <com/sun/star/uno/DeploymentException.hpp>
57 #include <com/sun/star/lang/DisposedException.hpp>
58 #include <com/sun/star/script/LibraryNotLoadedException.hpp>
59 #include <com/sun/star/script/vba/VBAScriptEventId.hpp>
60 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
61 #include <com/sun/star/util/PathSubstitution.hpp>
62 #include <com/sun/star/deployment/ExtensionManager.hpp>
63 #include <comphelper/storagehelper.hxx>
64 #include <cppuhelper/exc_hlp.hxx>
65 #include <cppuhelper/queryinterface.hxx>
66 #include <cppuhelper/supportsservice.hxx>
67 #include <cppuhelper/typeprovider.hxx>
73 using namespace com::sun::star::document
;
74 using namespace com::sun::star::container
;
75 using namespace com::sun::star::uno
;
76 using namespace com::sun::star::lang
;
77 using namespace com::sun::star::io
;
78 using namespace com::sun::star::ucb
;
79 using namespace com::sun::star::script
;
80 using namespace com::sun::star::beans
;
81 using namespace com::sun::star::xml::sax
;
82 using namespace com::sun::star::util
;
83 using namespace com::sun::star::task
;
84 using namespace com::sun::star::embed
;
85 using namespace com::sun::star::frame
;
86 using namespace com::sun::star::deployment
;
87 using namespace com::sun::star
;
91 using com::sun::star::uno::Reference
;
93 // #i34411: Flag for error handling during migration
94 static bool GbMigrationSuppressErrors
= false;
97 // Implementation class NameContainer
99 // Methods XElementAccess
100 Type
NameContainer::getElementType()
105 sal_Bool
NameContainer::hasElements()
107 bool bRet
= (mnElementCount
> 0);
111 // Methods XNameAccess
112 Any
NameContainer::getByName( const OUString
& aName
)
114 NameContainerNameMap::iterator aIt
= mHashMap
.find( aName
);
115 if( aIt
== mHashMap
.end() )
117 throw NoSuchElementException();
119 sal_Int32 iHashResult
= (*aIt
).second
;
120 Any aRetAny
= mValues
[ iHashResult
];
124 Sequence
< OUString
> NameContainer::getElementNames()
126 return comphelper::containerToSequence(mNames
);
129 sal_Bool
NameContainer::hasByName( const OUString
& aName
)
131 NameContainerNameMap::iterator aIt
= mHashMap
.find( aName
);
132 bool bRet
= ( aIt
!= mHashMap
.end() );
137 // Methods XNameReplace
138 void NameContainer::replaceByName( const OUString
& aName
, const Any
& aElement
)
140 const Type
& aAnyType
= aElement
.getValueType();
141 if( mType
!= aAnyType
)
143 throw IllegalArgumentException();
145 NameContainerNameMap::iterator aIt
= mHashMap
.find( aName
);
146 if( aIt
== mHashMap
.end() )
148 throw NoSuchElementException();
150 sal_Int32 iHashResult
= (*aIt
).second
;
151 Any aOldElement
= mValues
[ iHashResult
];
152 mValues
[ iHashResult
] = aElement
;
156 if( maContainerListeners
.getLength() > 0 )
158 ContainerEvent aEvent
;
159 aEvent
.Source
= mpxEventSource
;
160 aEvent
.Accessor
<<= aName
;
161 aEvent
.Element
= aElement
;
162 aEvent
.ReplacedElement
= aOldElement
;
163 maContainerListeners
.notifyEach( &XContainerListener::elementReplaced
, aEvent
);
166 /* After the container event has been fired (one listener will update the
167 core Basic manager), fire change event. Listeners can rely on that the
168 Basic source code of the core Basic manager is up-to-date. */
169 if( maChangesListeners
.getLength() > 0 )
172 aEvent
.Source
= mpxEventSource
;
173 aEvent
.Base
<<= aEvent
.Source
;
174 aEvent
.Changes
.realloc( 1 );
175 aEvent
.Changes
[ 0 ].Accessor
<<= aName
;
176 aEvent
.Changes
[ 0 ].Element
= aElement
;
177 aEvent
.Changes
[ 0 ].ReplacedElement
= aOldElement
;
178 maChangesListeners
.notifyEach( &XChangesListener::changesOccurred
, aEvent
);
182 void NameContainer::insertCheck(const OUString
& aName
, const Any
& aElement
)
184 NameContainerNameMap::iterator aIt
= mHashMap
.find(aName
);
185 if( aIt
!= mHashMap
.end() )
187 throw ElementExistException();
189 insertNoCheck(aName
, aElement
);
192 void NameContainer::insertNoCheck(const OUString
& aName
, const Any
& aElement
)
194 const Type
& aAnyType
= aElement
.getValueType();
195 if( mType
!= aAnyType
)
197 throw IllegalArgumentException();
200 sal_Int32 nCount
= mNames
.size();
201 mNames
.push_back( aName
);
202 mValues
.push_back( aElement
);
204 mHashMap
[ aName
] = nCount
;
208 if( maContainerListeners
.getLength() > 0 )
210 ContainerEvent aEvent
;
211 aEvent
.Source
= mpxEventSource
;
212 aEvent
.Accessor
<<= aName
;
213 aEvent
.Element
= aElement
;
214 maContainerListeners
.notifyEach( &XContainerListener::elementInserted
, aEvent
);
217 /* After the container event has been fired (one listener will update the
218 core Basic manager), fire change event. Listeners can rely on that the
219 Basic source code of the core Basic manager is up-to-date. */
220 if( maChangesListeners
.getLength() > 0 )
223 aEvent
.Source
= mpxEventSource
;
224 aEvent
.Base
<<= aEvent
.Source
;
225 aEvent
.Changes
.realloc( 1 );
226 aEvent
.Changes
[ 0 ].Accessor
<<= aName
;
227 aEvent
.Changes
[ 0 ].Element
= aElement
;
228 maChangesListeners
.notifyEach( &XChangesListener::changesOccurred
, aEvent
);
232 // Methods XNameContainer
233 void NameContainer::insertByName( const OUString
& aName
, const Any
& aElement
)
235 insertCheck(aName
, aElement
);
238 void NameContainer::removeByName( const OUString
& aName
)
240 NameContainerNameMap::iterator aIt
= mHashMap
.find( aName
);
241 if( aIt
== mHashMap
.end() )
243 OUString sMessage
= "\"" + aName
+ "\" not found";
244 throw NoSuchElementException(sMessage
);
247 sal_Int32 iHashResult
= (*aIt
).second
;
248 Any aOldElement
= mValues
[ iHashResult
];
249 mHashMap
.erase( aIt
);
250 sal_Int32 iLast
= mNames
.size() - 1;
251 if( iLast
!= iHashResult
)
253 mNames
[ iHashResult
] = mNames
[ iLast
];
254 mValues
[ iHashResult
] = mValues
[ iLast
];
255 mHashMap
[ mNames
[ iHashResult
] ] = iHashResult
;
257 mNames
.resize( iLast
);
258 mValues
.resize( iLast
);
262 if( maContainerListeners
.getLength() > 0 )
264 ContainerEvent aEvent
;
265 aEvent
.Source
= mpxEventSource
;
266 aEvent
.Accessor
<<= aName
;
267 aEvent
.Element
= aOldElement
;
268 maContainerListeners
.notifyEach( &XContainerListener::elementRemoved
, aEvent
);
271 /* After the container event has been fired (one listener will update the
272 core Basic manager), fire change event. Listeners can rely on that the
273 Basic source code of the core Basic manager is up-to-date. */
274 if( maChangesListeners
.getLength() > 0 )
277 aEvent
.Source
= mpxEventSource
;
278 aEvent
.Base
<<= aEvent
.Source
;
279 aEvent
.Changes
.realloc( 1 );
280 aEvent
.Changes
[ 0 ].Accessor
<<= aName
;
281 // aEvent.Changes[ 0 ].Element remains empty (meaning "replaced with nothing")
282 aEvent
.Changes
[ 0 ].ReplacedElement
= aOldElement
;
283 maChangesListeners
.notifyEach( &XChangesListener::changesOccurred
, aEvent
);
288 // Methods XContainer
289 void SAL_CALL
NameContainer::addContainerListener( const Reference
< XContainerListener
>& xListener
)
291 if( !xListener
.is() )
293 throw RuntimeException("addContainerListener called with null xListener");
295 maContainerListeners
.addInterface( Reference
<XInterface
>(xListener
, UNO_QUERY
) );
298 void SAL_CALL
NameContainer::removeContainerListener( const Reference
< XContainerListener
>& xListener
)
300 if( !xListener
.is() )
302 throw RuntimeException("removeContainerListener called with null xListener");
304 maContainerListeners
.removeInterface( Reference
<XInterface
>(xListener
, UNO_QUERY
) );
307 // Methods XChangesNotifier
308 void SAL_CALL
NameContainer::addChangesListener( const Reference
< XChangesListener
>& xListener
)
310 if( !xListener
.is() )
312 throw RuntimeException("addChangesListener called with null xListener");
314 maChangesListeners
.addInterface( Reference
<XInterface
>(xListener
, UNO_QUERY
) );
317 void SAL_CALL
NameContainer::removeChangesListener( const Reference
< XChangesListener
>& xListener
)
319 if( !xListener
.is() )
321 throw RuntimeException("removeChangesListener called with null xListener");
323 maChangesListeners
.removeInterface( Reference
<XInterface
>(xListener
, UNO_QUERY
) );
329 void ModifiableHelper::setModified( bool _bModified
)
331 if ( _bModified
== mbModified
)
335 mbModified
= _bModified
;
337 if ( m_aModifyListeners
.getLength() == 0 )
341 EventObject
aModifyEvent( m_rEventSource
);
342 m_aModifyListeners
.notifyEach( &XModifyListener::modified
, aModifyEvent
);
346 VBAScriptListenerContainer::VBAScriptListenerContainer( ::osl::Mutex
& rMutex
) :
347 VBAScriptListenerContainer_BASE( rMutex
)
351 bool VBAScriptListenerContainer::implTypedNotify( const Reference
< vba::XVBAScriptListener
>& rxListener
, const vba::VBAScriptEvent
& rEvent
)
353 rxListener
->notifyVBAScriptEvent( rEvent
);
354 return true; // notify all other listeners too
358 SfxLibraryContainer::SfxLibraryContainer()
359 : SfxLibraryContainer_BASE( m_aMutex
)
360 , maVBAScriptListeners( m_aMutex
)
361 , mnRunningVBAScripts( 0 )
362 , mbVBACompat( false )
363 , maModifiable( *this, m_aMutex
)
364 , maNameContainer( new NameContainer(cppu::UnoType
<XNameAccess
>::get()) )
365 , mbOldInfoFormat( false )
366 , mbOasis2OOoFormat( false )
367 , mpBasMgr( nullptr )
368 , mbOwnBasMgr( false )
369 , meInitMode(DEFAULT
)
371 mxContext
= comphelper::getProcessComponentContext();
373 mxSFI
= ucb::SimpleFileAccess::create( mxContext
);
375 mxStringSubstitution
= util::PathSubstitution::create( mxContext
);
378 SfxLibraryContainer::~SfxLibraryContainer()
386 void SfxLibraryContainer::enterMethod()
388 Application::GetSolarMutex().acquire();
389 if ( rBHelper
.bInDispose
|| rBHelper
.bDisposed
)
391 throw DisposedException( OUString(), *this );
395 void SfxLibraryContainer::leaveMethod()
397 Application::GetSolarMutex().release();
400 BasicManager
* SfxLibraryContainer::getBasicManager()
408 Reference
< XModel
> xDocument( mxOwnerDocument
.get(), UNO_QUERY
);
410 !xDocument
.is(), "basic",
411 ("SfxLibraryContainer::getBasicManager: cannot obtain a BasicManager"
412 " without document!"));
413 if ( xDocument
.is() )
415 mpBasMgr
= BasicManagerRepository::getDocumentBasicManager( xDocument
);
418 catch (const css::ucb::ContentCreationException
&)
420 TOOLS_WARN_EXCEPTION( "basic", "SfxLibraryContainer::getBasicManager:" );
425 // Methods XStorageBasedLibraryContainer
426 Reference
< XStorage
> SAL_CALL
SfxLibraryContainer::getRootStorage()
428 LibraryContainerMethodGuard
aGuard( *this );
432 void SAL_CALL
SfxLibraryContainer::setRootStorage( const Reference
< XStorage
>& _rxRootStorage
)
434 LibraryContainerMethodGuard
aGuard( *this );
435 if ( !_rxRootStorage
.is() )
437 throw IllegalArgumentException();
439 mxStorage
= _rxRootStorage
;
443 void SAL_CALL
SfxLibraryContainer::storeLibrariesToStorage( const Reference
< XStorage
>& _rxRootStorage
)
445 LibraryContainerMethodGuard
aGuard( *this );
446 if ( !_rxRootStorage
.is() )
448 throw IllegalArgumentException();
452 storeLibraries_Impl( _rxRootStorage
, true );
454 catch( const Exception
& )
456 throw WrappedTargetException( OUString(),
457 *this, ::cppu::getCaughtException() );
462 // Methods XModifiable
463 sal_Bool
SfxLibraryContainer::isModified()
465 LibraryContainerMethodGuard
aGuard( *this );
466 if ( maModifiable
.isModified() )
470 // the library container is not modified, go through the libraries and check whether they are modified
471 Sequence
< OUString
> aNames
= maNameContainer
->getElementNames();
472 const OUString
* pNames
= aNames
.getConstArray();
473 sal_Int32 nNameCount
= aNames
.getLength();
475 for( sal_Int32 i
= 0 ; i
< nNameCount
; i
++ )
477 OUString aName
= pNames
[ i
];
480 SfxLibrary
* pImplLib
= getImplLib( aName
);
481 if( pImplLib
->isModified() )
483 if ( aName
== "Standard" )
485 // this is a workaround that has to be implemented because
486 // empty standard library should stay marked as modified
487 // but should not be treated as modified while it is empty
488 if ( pImplLib
->hasElements() )
497 catch(const css::container::NoSuchElementException
&)
505 void SAL_CALL
SfxLibraryContainer::setModified( sal_Bool _bModified
)
507 LibraryContainerMethodGuard
aGuard( *this );
508 maModifiable
.setModified( _bModified
);
511 void SAL_CALL
SfxLibraryContainer::addModifyListener( const Reference
< XModifyListener
>& _rxListener
)
513 LibraryContainerMethodGuard
aGuard( *this );
514 maModifiable
.addModifyListener( _rxListener
);
517 void SAL_CALL
SfxLibraryContainer::removeModifyListener( const Reference
< XModifyListener
>& _rxListener
)
519 LibraryContainerMethodGuard
aGuard( *this );
520 maModifiable
.removeModifyListener( _rxListener
);
523 // Methods XPersistentLibraryContainer
524 Any SAL_CALL
SfxLibraryContainer::getRootLocation()
526 LibraryContainerMethodGuard
aGuard( *this );
527 return Any( getRootStorage() );
530 OUString SAL_CALL
SfxLibraryContainer::getContainerLocationName()
532 LibraryContainerMethodGuard
aGuard( *this );
533 return maLibrariesDir
;
536 void SAL_CALL
SfxLibraryContainer::storeLibraries( )
538 LibraryContainerMethodGuard
aGuard( *this );
541 storeLibraries_Impl( mxStorage
, mxStorage
.is() );
542 // we need to store *all* libraries if and only if we are based on a storage:
543 // in this case, storeLibraries_Impl will remove the source storage, after loading
544 // all libraries, so we need to force them to be stored, again
546 catch( const Exception
& )
548 throw WrappedTargetException( OUString(), *this, ::cppu::getCaughtException() );
552 static void checkAndCopyFileImpl( const INetURLObject
& rSourceFolderInetObj
,
553 const INetURLObject
& rTargetFolderInetObj
,
554 const OUString
& rCheckFileName
,
555 const OUString
& rCheckExtension
,
556 const Reference
< XSimpleFileAccess3
>& xSFI
)
558 INetURLObject
aTargetFolderInetObj( rTargetFolderInetObj
);
559 aTargetFolderInetObj
.insertName( rCheckFileName
, true, INetURLObject::LAST_SEGMENT
,
560 INetURLObject::EncodeMechanism::All
);
561 aTargetFolderInetObj
.setExtension( rCheckExtension
);
562 OUString aTargetFile
= aTargetFolderInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
563 if( !xSFI
->exists( aTargetFile
) )
565 INetURLObject
aSourceFolderInetObj( rSourceFolderInetObj
);
566 aSourceFolderInetObj
.insertName( rCheckFileName
, true, INetURLObject::LAST_SEGMENT
,
567 INetURLObject::EncodeMechanism::All
);
568 aSourceFolderInetObj
.setExtension( rCheckExtension
);
569 OUString aSourceFile
= aSourceFolderInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
570 xSFI
->copy( aSourceFile
, aTargetFile
);
574 static void createVariableURL( OUString
& rStr
, const OUString
& rLibName
,
575 const OUString
& rInfoFileName
, bool bUser
)
579 rStr
= "$(USER)/basic/";
583 rStr
= "$(INST)/" LIBO_SHARE_FOLDER
"/basic/";
585 rStr
+= rLibName
+ "/" + rInfoFileName
+ ".xlb/";
588 void SfxLibraryContainer::init( const OUString
& rInitialDocumentURL
, const uno::Reference
< embed::XStorage
>& rxInitialStorage
)
590 // this might be called from within the ctor, and the impl_init might (indirectly) create
591 // a UNO reference to ourself.
592 // Ensure that we're not destroyed while we're in here
593 osl_atomic_increment( &m_refCount
);
594 init_Impl( rInitialDocumentURL
, rxInitialStorage
);
595 osl_atomic_decrement( &m_refCount
);
598 void SfxLibraryContainer::init_Impl( const OUString
& rInitialDocumentURL
,
599 const uno::Reference
< embed::XStorage
>& rxInitialStorage
)
601 uno::Reference
< embed::XStorage
> xStorage
= rxInitialStorage
;
603 maInitialDocumentURL
= rInitialDocumentURL
;
604 maInfoFileName
= OUString::createFromAscii( getInfoFileName() );
605 maOldInfoFileName
= OUString::createFromAscii( getOldInfoFileName() );
606 maLibElementFileExtension
= OUString::createFromAscii( getLibElementFileExtension() );
607 maLibrariesDir
= OUString::createFromAscii( getLibrariesDir() );
609 meInitMode
= DEFAULT
;
610 INetURLObject
aInitUrlInetObj( maInitialDocumentURL
);
611 OUString aInitFileName
= aInitUrlInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
612 if( !aInitFileName
.isEmpty() )
614 // We need a BasicManager to avoid problems
615 StarBASIC
* pBas
= new StarBASIC();
616 mpBasMgr
= new BasicManager( pBas
);
619 OUString aExtension
= aInitUrlInetObj
.getExtension();
620 if( aExtension
== "xlc" )
622 meInitMode
= CONTAINER_INIT_FILE
;
623 INetURLObject
aLibPathInetObj( aInitUrlInetObj
);
624 aLibPathInetObj
.removeSegment();
625 maLibraryPath
= aLibPathInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
627 else if( aExtension
== "xlb" )
629 meInitMode
= LIBRARY_INIT_FILE
;
630 uno::Reference
< embed::XStorage
> xDummyStor
;
631 ::xmlscript::LibDescriptor aLibDesc
;
632 implLoadLibraryIndexFile( nullptr, aLibDesc
, xDummyStor
, aInitFileName
);
637 // Decide between old and new document
638 bool bOldStorage
= SotStorage::IsOLEStorage( aInitFileName
);
641 meInitMode
= OLD_BASIC_STORAGE
;
642 importFromOldStorage( aInitFileName
);
647 meInitMode
= OFFICE_DOCUMENT
;
650 xStorage
= ::comphelper::OStorageHelper::GetStorageFromURL( aInitFileName
, embed::ElementModes::READ
);
652 catch (const uno::Exception
& )
654 // TODO: error handling
662 maLibraryPath
= SvtPathOptions().GetBasicPath();
665 Reference
< XParser
> xParser
= xml::sax::Parser::create(mxContext
);
667 uno::Reference
< io::XInputStream
> xInput
;
669 mxStorage
= xStorage
;
670 bool bStorage
= mxStorage
.is();
673 // #110009: Scope to force the StorageRefs to be destructed and
674 // so the streams to be closed before the preload operation
677 uno::Reference
< embed::XStorage
> xLibrariesStor
;
681 if( !bStorage
&& meInitMode
== DEFAULT
)
685 for( int nPass
= 0 ; nPass
< nPassCount
; nPass
++ )
690 meInitMode
!= DEFAULT
&& meInitMode
!= OFFICE_DOCUMENT
, "basic",
691 "Wrong InitMode for document");
694 uno::Reference
< io::XStream
> xStream
;
695 xLibrariesStor
= xStorage
->openStorageElement( maLibrariesDir
, embed::ElementModes::READ
);
697 if ( xLibrariesStor
.is() )
699 aFileName
= maInfoFileName
+ "-lc.xml";
702 xStream
= xLibrariesStor
->openStreamElement( aFileName
, embed::ElementModes::READ
);
704 catch(const uno::Exception
& )
709 mbOldInfoFormat
= true;
712 aFileName
= maOldInfoFileName
+ ".xml";
715 xStream
= xLibrariesStor
->openStreamElement( aFileName
, embed::ElementModes::READ
);
717 catch(const uno::Exception
& )
722 // Check for EA2 document version with wrong extensions
723 aFileName
= maOldInfoFileName
+ ".xli";
724 xStream
= xLibrariesStor
->openStreamElement( aFileName
, embed::ElementModes::READ
);
731 xInput
= xStream
->getInputStream();
734 catch(const uno::Exception
& )
736 // TODO: error handling?
741 std::unique_ptr
<INetURLObject
> pLibInfoInetObj
;
742 if( meInitMode
== CONTAINER_INIT_FILE
)
744 aFileName
= aInitFileName
;
750 pLibInfoInetObj
.reset(new INetURLObject( maLibraryPath
.getToken(0, ';') ));
754 pLibInfoInetObj
.reset(new INetURLObject( maLibraryPath
.getToken(1, ';') ));
756 pLibInfoInetObj
->insertName( maInfoFileName
, false, INetURLObject::LAST_SEGMENT
, INetURLObject::EncodeMechanism::All
);
757 pLibInfoInetObj
->setExtension( "xlc" );
758 aFileName
= pLibInfoInetObj
->GetMainURL( INetURLObject::DecodeMechanism::NONE
);
763 xInput
= mxSFI
->openFileRead( aFileName
);
765 catch(const Exception
& )
767 // Silently tolerate empty or missing files
772 if( !xInput
.is() && nPass
== 0 )
774 INetURLObject
aLibInfoInetObj( maLibraryPath
.getToken(1, ';') );
775 aLibInfoInetObj
.insertName( maOldInfoFileName
, false, INetURLObject::LAST_SEGMENT
, INetURLObject::EncodeMechanism::All
);
776 aLibInfoInetObj
.setExtension( "xli" );
777 aFileName
= aLibInfoInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
781 xInput
= mxSFI
->openFileRead( aFileName
);
782 mbOldInfoFormat
= true;
784 catch(const Exception
& )
794 source
.aInputStream
= xInput
;
795 source
.sSystemId
= aFileName
;
798 std::unique_ptr
< ::xmlscript::LibDescriptorArray
> pLibArray(new ::xmlscript::LibDescriptorArray());
802 xParser
->setDocumentHandler( ::xmlscript::importLibraryContainer( pLibArray
.get() ) );
803 xParser
->parseStream( source
);
805 catch ( const xml::sax::SAXException
& )
807 TOOLS_WARN_EXCEPTION( "basic", "" );
810 catch ( const io::IOException
& )
812 TOOLS_WARN_EXCEPTION( "basic", "" );
816 sal_Int32 nLibCount
= pLibArray
->mnLibCount
;
817 for( sal_Int32 i
= 0 ; i
< nLibCount
; i
++ )
819 ::xmlscript::LibDescriptor
& rLib
= pLibArray
->mpLibs
[i
];
822 OUString aStorageURL
= rLib
.aStorageURL
;
823 if( !bStorage
&& aStorageURL
.isEmpty() && nPass
== 0 )
825 OUString aLibraryPath
;
826 if( meInitMode
== CONTAINER_INIT_FILE
)
828 aLibraryPath
= maLibraryPath
;
832 aLibraryPath
= maLibraryPath
.getToken(1, ';');
834 INetURLObject
aInetObj( aLibraryPath
);
836 aInetObj
.insertName( rLib
.aName
, true, INetURLObject::LAST_SEGMENT
,
837 INetURLObject::EncodeMechanism::All
);
838 OUString aLibDirPath
= aInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
839 if( mxSFI
->isFolder( aLibDirPath
) )
841 createVariableURL( rLib
.aStorageURL
, rLib
.aName
, maInfoFileName
, true );
842 maModifiable
.setModified( true );
844 else if( rLib
.bLink
)
846 // Check "share" path
847 INetURLObject
aShareInetObj( maLibraryPath
.getToken(0, ';') );
848 aShareInetObj
.insertName( rLib
.aName
, true, INetURLObject::LAST_SEGMENT
,
849 INetURLObject::EncodeMechanism::All
);
850 OUString aShareLibDirPath
= aShareInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
851 if( mxSFI
->isFolder( aShareLibDirPath
) )
853 createVariableURL( rLib
.aStorageURL
, rLib
.aName
, maInfoFileName
, false );
854 maModifiable
.setModified( true );
858 // #i25537: Ignore lib if library folder does not really exist
864 OUString aLibName
= rLib
.aName
;
866 // If the same library name is used by the shared and the
867 // user lib container index files the user file wins
868 if( nPass
== 1 && hasByName( aLibName
) )
872 SfxLibrary
* pImplLib
;
875 Reference
< XNameAccess
> xLib
=
876 createLibraryLink( aLibName
, rLib
.aStorageURL
, rLib
.bReadOnly
);
877 pImplLib
= static_cast< SfxLibrary
* >( xLib
.get() );
881 Reference
< XNameContainer
> xLib
= createLibrary( aLibName
);
882 pImplLib
= static_cast< SfxLibrary
* >( xLib
.get() );
883 pImplLib
->mbLoaded
= false;
884 pImplLib
->mbReadOnly
= rLib
.bReadOnly
;
887 checkStorageURL( rLib
.aStorageURL
, pImplLib
->maLibInfoFileURL
,
888 pImplLib
->maStorageURL
, pImplLib
->maUnexpandedStorageURL
);
891 maModifiable
.setModified( false );
893 // Read library info files
894 if( !mbOldInfoFormat
)
896 uno::Reference
< embed::XStorage
> xLibraryStor
;
897 if( !pImplLib
->mbInitialised
&& bStorage
)
901 xLibraryStor
= xLibrariesStor
->openStorageElement( rLib
.aName
,
902 embed::ElementModes::READ
);
904 catch(const uno::Exception
& )
906 #if OSL_DEBUG_LEVEL > 0
907 TOOLS_WARN_EXCEPTION(
909 "couldn't open sub storage for library \"" << rLib
.aName
<< "\"");
914 // Link is already initialised in createLibraryLink()
915 if( !pImplLib
->mbInitialised
&& (!bStorage
|| xLibraryStor
.is()) )
917 bool bLoaded
= implLoadLibraryIndexFile( pImplLib
, rLib
, xLibraryStor
, OUString() );
919 bLoaded
&& aLibName
!= rLib
.aName
, "basic",
920 ("Different library names in library container and"
921 " library info files!"));
922 if( GbMigrationSuppressErrors
&& !bLoaded
)
924 removeLibrary( aLibName
);
930 // Write new index file immediately because otherwise
931 // the library elements will be lost when storing into
932 // the new info format
933 uno::Reference
< embed::XStorage
> xTmpStorage
;
934 implStoreLibraryIndexFile( pImplLib
, rLib
, xTmpStorage
);
937 implImportLibDescriptor( pImplLib
, rLib
);
941 pImplLib
->mbSharedIndexFile
= true;
942 pImplLib
->mbReadOnly
= true;
946 // Keep flag for documents to force writing the new index files
949 mbOldInfoFormat
= false;
954 // #110009: END Scope to force the StorageRefs to be destructed
957 if( !bStorage
&& meInitMode
== DEFAULT
)
961 implScanExtensions();
963 catch(const uno::Exception
& )
965 // TODO: error handling?
966 SAL_WARN("basic", "Cannot access extensions!");
972 Sequence
< OUString
> aNames
= maNameContainer
->getElementNames();
973 const OUString
* pNames
= aNames
.getConstArray();
974 sal_Int32 nNameCount
= aNames
.getLength();
975 for( sal_Int32 i
= 0 ; i
< nNameCount
; i
++ )
977 OUString aName
= pNames
[ i
];
978 SfxLibrary
* pImplLib
= getImplLib( aName
);
979 if( pImplLib
->mbPreload
)
981 loadLibrary( aName
);
986 if( meInitMode
== DEFAULT
)
988 INetURLObject
aUserBasicInetObj( maLibraryPath
.getToken(1, ';') );
989 OUString
aStandardStr("Standard");
991 INetURLObject
aPrevUserBasicInetObj_1( aUserBasicInetObj
);
992 aPrevUserBasicInetObj_1
.removeSegment();
993 INetURLObject aPrevUserBasicInetObj_2
= aPrevUserBasicInetObj_1
;
994 aPrevUserBasicInetObj_1
.Append( "__basic_80" );
995 aPrevUserBasicInetObj_2
.Append( "__basic_80_2" );
998 bool bCleanUp
= false;
1001 INetURLObject aPrevUserBasicInetObj
= aPrevUserBasicInetObj_1
;
1002 OUString aPrevFolder
= aPrevUserBasicInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1003 if( mxSFI
->isFolder( aPrevFolder
) )
1005 // Check if Standard folder exists and is complete
1006 INetURLObject
aUserBasicStandardInetObj( aUserBasicInetObj
);
1007 aUserBasicStandardInetObj
.insertName( aStandardStr
, true, INetURLObject::LAST_SEGMENT
,
1008 INetURLObject::EncodeMechanism::All
);
1009 INetURLObject
aPrevUserBasicStandardInetObj( aPrevUserBasicInetObj
);
1010 aPrevUserBasicStandardInetObj
.insertName( aStandardStr
, true, INetURLObject::LAST_SEGMENT
,
1011 INetURLObject::EncodeMechanism::All
);
1012 OUString aPrevStandardFolder
= aPrevUserBasicStandardInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1013 if( mxSFI
->isFolder( aPrevStandardFolder
) )
1015 OUString
aXlbExtension( "xlb" );
1016 OUString aCheckFileName
;
1018 // Check if script.xlb exists
1019 aCheckFileName
= "script";
1020 checkAndCopyFileImpl( aUserBasicStandardInetObj
,
1021 aPrevUserBasicStandardInetObj
,
1022 aCheckFileName
, aXlbExtension
, mxSFI
);
1024 // Check if dialog.xlb exists
1025 aCheckFileName
= "dialog";
1026 checkAndCopyFileImpl( aUserBasicStandardInetObj
,
1027 aPrevUserBasicStandardInetObj
,
1028 aCheckFileName
, aXlbExtension
, mxSFI
);
1030 // Check if module1.xba exists
1031 aCheckFileName
= "Module1";
1032 checkAndCopyFileImpl( aUserBasicStandardInetObj
,
1033 aPrevUserBasicStandardInetObj
,
1034 aCheckFileName
, "xba", mxSFI
);
1038 OUString aStandardFolder
= aUserBasicStandardInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1039 mxSFI
->copy( aStandardFolder
, aPrevStandardFolder
);
1042 OUString aPrevCopyToFolder
= aPrevUserBasicInetObj_2
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1043 mxSFI
->copy( aPrevFolder
, aPrevCopyToFolder
);
1047 aPrevUserBasicInetObj
= aPrevUserBasicInetObj_2
;
1048 aPrevFolder
= aPrevUserBasicInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1050 if( mxSFI
->isFolder( aPrevFolder
) )
1052 rtl::Reference
<SfxLibraryContainer
> pPrevCont
= createInstanceImpl();
1054 // Rename previous basic folder to make storage URLs correct during initialisation
1055 OUString aFolderUserBasic
= aUserBasicInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1056 INetURLObject
aUserBasicTmpInetObj( aUserBasicInetObj
);
1057 aUserBasicTmpInetObj
.removeSegment();
1058 aUserBasicTmpInetObj
.Append( "__basic_tmp" );
1059 OUString aFolderTmp
= aUserBasicTmpInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1061 mxSFI
->move( aFolderUserBasic
, aFolderTmp
);
1064 mxSFI
->move( aPrevFolder
, aFolderUserBasic
);
1066 catch(const Exception
& )
1068 // Move back user/basic folder
1071 mxSFI
->kill( aFolderUserBasic
);
1073 catch(const Exception
& )
1075 mxSFI
->move( aFolderTmp
, aFolderUserBasic
);
1079 INetURLObject
aPrevUserBasicLibInfoInetObj( aUserBasicInetObj
);
1080 aPrevUserBasicLibInfoInetObj
.insertName( maInfoFileName
, false, INetURLObject::LAST_SEGMENT
,
1081 INetURLObject::EncodeMechanism::All
);
1082 aPrevUserBasicLibInfoInetObj
.setExtension( "xlc");
1083 OUString aLibInfoFileName
= aPrevUserBasicLibInfoInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1084 Sequence
<Any
> aInitSeq( 1 );
1085 aInitSeq
.getArray()[0] <<= aLibInfoFileName
;
1086 GbMigrationSuppressErrors
= true;
1087 pPrevCont
->initialize( aInitSeq
);
1088 GbMigrationSuppressErrors
= false;
1090 // Rename folders back
1091 mxSFI
->move( aFolderUserBasic
, aPrevFolder
);
1092 mxSFI
->move( aFolderTmp
, aFolderUserBasic
);
1094 Sequence
< OUString
> aNames
= pPrevCont
->getElementNames();
1095 const OUString
* pNames
= aNames
.getConstArray();
1096 sal_Int32 nNameCount
= aNames
.getLength();
1098 for( sal_Int32 i
= 0 ; i
< nNameCount
; i
++ )
1100 OUString aLibName
= pNames
[ i
];
1101 if( hasByName( aLibName
) )
1103 if( aLibName
== aStandardStr
)
1105 SfxLibrary
* pImplLib
= getImplLib( aStandardStr
);
1106 OUString aStandardFolder
= pImplLib
->maStorageURL
;
1107 mxSFI
->kill( aStandardFolder
);
1115 SfxLibrary
* pImplLib
= pPrevCont
->getImplLib( aLibName
);
1116 if( pImplLib
->mbLink
)
1118 OUString aStorageURL
= pImplLib
->maUnexpandedStorageURL
;
1119 bool bCreateLink
= true;
1120 if( aStorageURL
.indexOf( "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE" ) != -1 ||
1121 aStorageURL
.indexOf( "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE" ) != -1 ||
1122 aStorageURL
.indexOf( "vnd.sun.star.expand:$BUNDLED_EXTENSIONS" ) != -1 ||
1123 aStorageURL
.indexOf( "$(INST)" ) != -1 )
1125 bCreateLink
= false;
1129 createLibraryLink( aLibName
, pImplLib
->maStorageURL
, pImplLib
->mbReadOnly
);
1134 // Move folder if not already done
1135 INetURLObject
aUserBasicLibFolderInetObj( aUserBasicInetObj
);
1136 aUserBasicLibFolderInetObj
.Append( aLibName
);
1137 OUString aLibFolder
= aUserBasicLibFolderInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1139 INetURLObject
aPrevUserBasicLibFolderInetObj( aPrevUserBasicInetObj
);
1140 aPrevUserBasicLibFolderInetObj
.Append( aLibName
);
1141 OUString aPrevLibFolder
= aPrevUserBasicLibFolderInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1143 if( mxSFI
->isFolder( aPrevLibFolder
) && !mxSFI
->isFolder( aLibFolder
) )
1145 mxSFI
->move( aPrevLibFolder
, aLibFolder
);
1148 if( aLibName
== aStandardStr
)
1150 maNameContainer
->removeByName( aLibName
);
1154 Reference
< XNameContainer
> xLib
= createLibrary( aLibName
);
1155 SfxLibrary
* pNewLib
= static_cast< SfxLibrary
* >( xLib
.get() );
1156 pNewLib
->mbLoaded
= false;
1157 pNewLib
->implSetModified( false );
1158 checkStorageURL( aLibFolder
, pNewLib
->maLibInfoFileURL
,
1159 pNewLib
->maStorageURL
, pNewLib
->maUnexpandedStorageURL
);
1161 uno::Reference
< embed::XStorage
> xDummyStor
;
1162 ::xmlscript::LibDescriptor aLibDesc
;
1163 implLoadLibraryIndexFile( pNewLib
, aLibDesc
, xDummyStor
, pNewLib
->maLibInfoFileURL
);
1164 implImportLibDescriptor( pNewLib
, aLibDesc
);
1167 mxSFI
->kill( aPrevFolder
);
1170 catch(const Exception
&)
1172 TOOLS_WARN_EXCEPTION("basic", "Upgrade of Basic installation failed somehow" );
1179 INetURLObject
aPrevUserBasicInetObj_Err( aUserBasicInetObj
);
1180 aPrevUserBasicInetObj_Err
.removeSegment();
1181 aPrevUserBasicInetObj_Err
.Append( "__basic_80_err" );
1182 OUString aPrevFolder_Err
= aPrevUserBasicInetObj_Err
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1184 bool bSaved
= false;
1187 OUString aPrevFolder_1
= aPrevUserBasicInetObj_1
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1188 if( mxSFI
->isFolder( aPrevFolder_1
) )
1190 mxSFI
->move( aPrevFolder_1
, aPrevFolder_Err
);
1194 catch(const Exception
& )
1198 OUString aPrevFolder_2
= aPrevUserBasicInetObj_2
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1199 if( !bSaved
&& mxSFI
->isFolder( aPrevFolder_2
) )
1201 mxSFI
->move( aPrevFolder_2
, aPrevFolder_Err
);
1205 mxSFI
->kill( aPrevFolder_2
);
1208 catch(const Exception
& )
1214 void SfxLibraryContainer::implScanExtensions()
1216 #if HAVE_FEATURE_EXTENSIONS
1217 ScriptExtensionIterator aScriptIt
;
1220 bool bPureDialogLib
= false;
1221 while ( !(aLibURL
= aScriptIt
.nextBasicOrDialogLibrary( bPureDialogLib
)).isEmpty())
1223 if( bPureDialogLib
&& maInfoFileName
== "script" )
1228 sal_Int32 nLen
= aLibURL
.getLength();
1229 sal_Int32 indexLastSlash
= aLibURL
.lastIndexOf( '/' );
1230 sal_Int32 nReduceCopy
= 0;
1231 if( indexLastSlash
== nLen
- 1 )
1234 indexLastSlash
= aLibURL
.lastIndexOf( '/', nLen
- 1 );
1237 OUString aLibName
= aLibURL
.copy( indexLastSlash
+ 1, nLen
- indexLastSlash
- nReduceCopy
- 1 );
1239 // If a library of the same exists the existing library wins
1240 if( hasByName( aLibName
) )
1244 // Add index file to URL
1245 OUString aIndexFileURL
= aLibURL
;
1246 if( nReduceCopy
== 0 )
1248 aIndexFileURL
+= "/";
1250 aIndexFileURL
+= maInfoFileName
+ ".xlb";
1253 const bool bReadOnly
= false;
1254 createLibraryLink( aLibName
, aIndexFileURL
, bReadOnly
);
1261 // Handle maLibInfoFileURL and maStorageURL correctly
1262 void SfxLibraryContainer::checkStorageURL( const OUString
& aSourceURL
,
1263 OUString
& aLibInfoFileURL
, OUString
& aStorageURL
,
1264 OUString
& aUnexpandedStorageURL
)
1266 OUString aExpandedSourceURL
= expand_url( aSourceURL
);
1267 if( aExpandedSourceURL
!= aSourceURL
)
1269 aUnexpandedStorageURL
= aSourceURL
;
1271 INetURLObject
aInetObj( aExpandedSourceURL
);
1272 OUString aExtension
= aInetObj
.getExtension();
1273 if( aExtension
== "xlb" )
1276 aLibInfoFileURL
= aExpandedSourceURL
;
1277 aInetObj
.removeSegment();
1278 aStorageURL
= aInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1282 // URL to library folder
1283 aStorageURL
= aExpandedSourceURL
;
1284 aInetObj
.insertName( maInfoFileName
, false, INetURLObject::LAST_SEGMENT
, INetURLObject::EncodeMechanism::All
);
1285 aInetObj
.setExtension( "xlb" );
1286 aLibInfoFileURL
= aInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1290 SfxLibrary
* SfxLibraryContainer::getImplLib( const OUString
& rLibraryName
)
1292 Any aLibAny
= maNameContainer
->getByName( rLibraryName
) ;
1293 Reference
< XNameAccess
> xNameAccess
;
1294 aLibAny
>>= xNameAccess
;
1295 SfxLibrary
* pImplLib
= static_cast< SfxLibrary
* >( xNameAccess
.get() );
1300 // Storing with password encryption
1302 // Empty implementation, avoids unnecessary implementation in dlgcont.cxx
1303 bool SfxLibraryContainer::implStorePasswordLibrary( SfxLibrary
*,
1305 const uno::Reference
< embed::XStorage
>&,
1306 const uno::Reference
< task::XInteractionHandler
>& )
1311 bool SfxLibraryContainer::implStorePasswordLibrary(
1312 SfxLibrary
* /*pLib*/,
1313 const OUString
& /*aName*/,
1314 const css::uno::Reference
< css::embed::XStorage
>& /*xStorage*/,
1315 const OUString
& /*aTargetURL*/,
1316 const Reference
< XSimpleFileAccess3
>& /*xToUseSFI*/,
1317 const uno::Reference
< task::XInteractionHandler
>& )
1322 bool SfxLibraryContainer::implLoadPasswordLibrary(
1323 SfxLibrary
* /*pLib*/,
1324 const OUString
& /*Name*/,
1325 bool /*bVerifyPasswordOnly*/ )
1330 OUString
SfxLibraryContainer::createAppLibraryFolder( SfxLibrary
* pLib
, const OUString
& aName
)
1332 OUString aLibDirPath
= pLib
->maStorageURL
;
1333 if( aLibDirPath
.isEmpty() )
1335 INetURLObject
aInetObj( maLibraryPath
.getToken(1, ';') );
1336 aInetObj
.insertName( aName
, true, INetURLObject::LAST_SEGMENT
, INetURLObject::EncodeMechanism::All
);
1337 checkStorageURL( aInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), pLib
->maLibInfoFileURL
,
1338 pLib
->maStorageURL
, pLib
->maUnexpandedStorageURL
);
1339 aLibDirPath
= pLib
->maStorageURL
;
1342 if( !mxSFI
->isFolder( aLibDirPath
) )
1346 mxSFI
->createFolder( aLibDirPath
);
1348 catch(const Exception
& )
1356 void SfxLibraryContainer::implStoreLibrary( SfxLibrary
* pLib
,
1357 const OUString
& aName
,
1358 const uno::Reference
< embed::XStorage
>& xStorage
)
1360 Reference
< XSimpleFileAccess3
> xDummySFA
;
1361 Reference
< XInteractionHandler
> xDummyHandler
;
1362 implStoreLibrary( pLib
, aName
, xStorage
, OUString(), xDummySFA
, xDummyHandler
);
1365 // New variant for library export
1366 void SfxLibraryContainer::implStoreLibrary( SfxLibrary
* pLib
,
1367 const OUString
& aName
,
1368 const uno::Reference
< embed::XStorage
>& xStorage
,
1369 const OUString
& aTargetURL
,
1370 const Reference
< XSimpleFileAccess3
>& rToUseSFI
,
1371 const Reference
< XInteractionHandler
>& xHandler
)
1373 bool bLink
= pLib
->mbLink
;
1374 bool bStorage
= xStorage
.is() && !bLink
;
1376 Sequence
< OUString
> aElementNames
= pLib
->getElementNames();
1377 sal_Int32 nNameCount
= aElementNames
.getLength();
1378 const OUString
* pNames
= aElementNames
.getConstArray();
1382 for( sal_Int32 i
= 0 ; i
< nNameCount
; i
++ )
1384 OUString aElementName
= pNames
[ i
];
1385 OUString aStreamName
= aElementName
+ ".xml";
1387 if( !isLibraryElementValid( pLib
->getByName( aElementName
) ) )
1391 "invalid library element \"" << aElementName
<< '"');
1396 uno::Reference
< io::XStream
> xElementStream
= xStorage
->openStreamElement(
1398 embed::ElementModes::READWRITE
);
1399 // throw uno::RuntimeException(); // TODO: method must either return the stream or throw an exception
1401 uno::Reference
< beans::XPropertySet
> xProps( xElementStream
, uno::UNO_QUERY
);
1403 !xProps
.is(), "basic",
1404 "The StorageStream must implement XPropertySet interface!");
1405 //if ( !xProps.is() ) //TODO
1409 xProps
->setPropertyValue("MediaType", uno::Any( OUString( "text/xml" ) ) );
1411 // #87671 Allow encryption
1412 xProps
->setPropertyValue("UseCommonStoragePasswordEncryption", uno::Any( true ) );
1414 Reference
< XOutputStream
> xOutput
= xElementStream
->getOutputStream();
1415 Reference
< XNameContainer
> xLib( pLib
);
1416 writeLibraryElement( xLib
, aElementName
, xOutput
);
1419 catch(const uno::Exception
& )
1421 SAL_WARN("basic", "Problem during storing of library!");
1422 // TODO: error handling?
1425 pLib
->storeResourcesToStorage( xStorage
);
1430 bool bExport
= !aTargetURL
.isEmpty();
1433 Reference
< XSimpleFileAccess3
> xSFI
= mxSFI
;
1434 if( rToUseSFI
.is() )
1438 OUString aLibDirPath
;
1441 INetURLObject
aInetObj( aTargetURL
);
1442 aInetObj
.insertName( aName
, true, INetURLObject::LAST_SEGMENT
, INetURLObject::EncodeMechanism::All
);
1443 aLibDirPath
= aInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1445 if( !xSFI
->isFolder( aLibDirPath
) )
1447 xSFI
->createFolder( aLibDirPath
);
1449 pLib
->storeResourcesToURL( aLibDirPath
, xHandler
);
1453 aLibDirPath
= createAppLibraryFolder( pLib
, aName
);
1454 pLib
->storeResources();
1457 for( sal_Int32 i
= 0 ; i
< nNameCount
; i
++ )
1459 OUString aElementName
= pNames
[ i
];
1461 INetURLObject
aElementInetObj( aLibDirPath
);
1462 aElementInetObj
.insertName( aElementName
, false,
1463 INetURLObject::LAST_SEGMENT
,
1464 INetURLObject::EncodeMechanism::All
);
1465 aElementInetObj
.setExtension( maLibElementFileExtension
);
1466 OUString
aElementPath( aElementInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
1468 if( !isLibraryElementValid( pLib
->getByName( aElementName
) ) )
1472 "invalid library element \"" << aElementName
<< '"');
1476 // TODO: Check modified
1479 if( xSFI
->exists( aElementPath
) )
1481 xSFI
->kill( aElementPath
);
1483 Reference
< XOutputStream
> xOutput
= xSFI
->openFileWrite( aElementPath
);
1484 Reference
< XNameContainer
> xLib( pLib
);
1485 writeLibraryElement( xLib
, aElementName
, xOutput
);
1486 xOutput
->closeOutput();
1488 catch(const Exception
& )
1494 SfxErrorContext
aEc( ERRCTX_SFX_SAVEDOC
, aElementPath
);
1495 ErrorHandler::HandleError( ERRCODE_IO_GENERAL
);
1499 catch(const Exception
& )
1509 void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary
* pLib
,
1510 const ::xmlscript::LibDescriptor
& rLib
,
1511 const uno::Reference
< embed::XStorage
>& xStorage
)
1513 Reference
< XSimpleFileAccess3
> xDummySFA
;
1514 implStoreLibraryIndexFile( pLib
, rLib
, xStorage
, OUString(), xDummySFA
);
1517 // New variant for library export
1518 void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary
* pLib
,
1519 const ::xmlscript::LibDescriptor
& rLib
,
1520 const uno::Reference
< embed::XStorage
>& xStorage
,
1521 const OUString
& aTargetURL
,
1522 const Reference
< XSimpleFileAccess3
>& rToUseSFI
)
1524 // Create sax writer
1525 Reference
< XWriter
> xWriter
= xml::sax::Writer::create(mxContext
);
1527 bool bLink
= pLib
->mbLink
;
1528 bool bStorage
= xStorage
.is() && !bLink
;
1531 uno::Reference
< io::XOutputStream
> xOut
;
1532 uno::Reference
< io::XStream
> xInfoStream
;
1535 OUString aStreamName
= maInfoFileName
+ "-lb.xml";
1539 xInfoStream
= xStorage
->openStreamElement( aStreamName
, embed::ElementModes::READWRITE
);
1540 SAL_WARN_IF(!xInfoStream
.is(), "basic", "No stream!");
1541 uno::Reference
< beans::XPropertySet
> xProps( xInfoStream
, uno::UNO_QUERY
);
1542 // throw uno::RuntimeException(); // TODO
1546 xProps
->setPropertyValue("MediaType", uno::Any( OUString("text/xml") ) );
1548 // #87671 Allow encryption
1549 xProps
->setPropertyValue("UseCommonStoragePasswordEncryption", uno::Any( true ) );
1551 xOut
= xInfoStream
->getOutputStream();
1554 catch(const uno::Exception
& )
1556 SAL_WARN("basic", "Problem during storing of library index file!");
1557 // TODO: error handling?
1563 bool bExport
= !aTargetURL
.isEmpty();
1564 Reference
< XSimpleFileAccess3
> xSFI
= mxSFI
;
1565 if( rToUseSFI
.is() )
1569 OUString aLibInfoPath
;
1572 INetURLObject
aInetObj( aTargetURL
);
1573 aInetObj
.insertName( rLib
.aName
, true, INetURLObject::LAST_SEGMENT
, INetURLObject::EncodeMechanism::All
);
1574 OUString aLibDirPath
= aInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1575 if( !xSFI
->isFolder( aLibDirPath
) )
1577 xSFI
->createFolder( aLibDirPath
);
1579 aInetObj
.insertName( maInfoFileName
, false, INetURLObject::LAST_SEGMENT
, INetURLObject::EncodeMechanism::All
);
1580 aInetObj
.setExtension( "xlb" );
1581 aLibInfoPath
= aInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1585 createAppLibraryFolder( pLib
, rLib
.aName
);
1586 aLibInfoPath
= pLib
->maLibInfoFileURL
;
1591 if( xSFI
->exists( aLibInfoPath
) )
1593 xSFI
->kill( aLibInfoPath
);
1595 xOut
= xSFI
->openFileWrite( aLibInfoPath
);
1597 catch(const Exception
& )
1603 SfxErrorContext
aEc( ERRCTX_SFX_SAVEDOC
, aLibInfoPath
);
1604 ErrorHandler::HandleError( ERRCODE_IO_GENERAL
);
1609 SAL_WARN("basic", "couldn't open output stream");
1612 xWriter
->setOutputStream( xOut
);
1613 xmlscript::exportLibrary( xWriter
, rLib
);
1617 bool SfxLibraryContainer::implLoadLibraryIndexFile( SfxLibrary
* pLib
,
1618 ::xmlscript::LibDescriptor
& rLib
,
1619 const uno::Reference
< embed::XStorage
>& xStorage
,
1620 const OUString
& aIndexFileName
)
1622 Reference
< XParser
> xParser
= xml::sax::Parser::create(mxContext
);
1624 bool bStorage
= false;
1627 bool bLink
= pLib
->mbLink
;
1628 bStorage
= xStorage
.is() && !bLink
;
1632 uno::Reference
< io::XInputStream
> xInput
;
1633 OUString aLibInfoPath
;
1636 aLibInfoPath
= maInfoFileName
+ "-lb.xml";
1640 uno::Reference
< io::XStream
> xInfoStream
=
1641 xStorage
->openStreamElement( aLibInfoPath
, embed::ElementModes::READ
);
1642 xInput
= xInfoStream
->getInputStream();
1644 catch(const uno::Exception
& )
1649 // Create Input stream
1650 //String aLibInfoPath; // attention: THIS PROBLEM MUST BE REVIEWED BY SCRIPTING OWNER!!!
1654 createAppLibraryFolder( pLib
, rLib
.aName
);
1655 aLibInfoPath
= pLib
->maLibInfoFileURL
;
1659 aLibInfoPath
= aIndexFileName
;
1663 xInput
= mxSFI
->openFileRead( aLibInfoPath
);
1665 catch(const Exception
& )
1668 if( !GbMigrationSuppressErrors
)
1670 SfxErrorContext
aEc( ERRCTX_SFX_LOADBASIC
, aLibInfoPath
);
1671 ErrorHandler::HandleError( ERRCODE_IO_GENERAL
);
1681 source
.aInputStream
= xInput
;
1682 source
.sSystemId
= aLibInfoPath
;
1687 xParser
->setDocumentHandler( ::xmlscript::importLibrary( rLib
) );
1688 xParser
->parseStream( source
);
1690 catch(const Exception
& )
1692 SAL_WARN("basic", "Parsing error");
1693 SfxErrorContext
aEc( ERRCTX_SFX_LOADBASIC
, aLibInfoPath
);
1694 ErrorHandler::HandleError( ERRCODE_IO_GENERAL
);
1700 Reference
< XNameContainer
> xLib
= createLibrary( rLib
.aName
);
1701 pLib
= static_cast< SfxLibrary
* >( xLib
.get() );
1702 pLib
->mbLoaded
= false;
1703 rLib
.aStorageURL
= aIndexFileName
;
1704 checkStorageURL( rLib
.aStorageURL
, pLib
->maLibInfoFileURL
, pLib
->maStorageURL
,
1705 pLib
->maUnexpandedStorageURL
);
1707 implImportLibDescriptor( pLib
, rLib
);
1713 void SfxLibraryContainer::implImportLibDescriptor( SfxLibrary
* pLib
,
1714 ::xmlscript::LibDescriptor
const & rLib
)
1716 if( !pLib
->mbInitialised
)
1718 sal_Int32 nElementCount
= rLib
.aElementNames
.getLength();
1719 const OUString
* pElementNames
= rLib
.aElementNames
.getConstArray();
1720 Any aDummyElement
= createEmptyLibraryElement();
1721 for( sal_Int32 i
= 0 ; i
< nElementCount
; i
++ )
1723 pLib
->maNameContainer
->insertByName( pElementNames
[i
], aDummyElement
);
1725 pLib
->mbPasswordProtected
= rLib
.bPasswordProtected
;
1726 pLib
->mbReadOnly
= rLib
.bReadOnly
;
1727 pLib
->mbPreload
= rLib
.bPreload
;
1728 pLib
->implSetModified( false );
1729 pLib
->mbInitialised
= true;
1734 // Methods of new XLibraryStorage interface?
1735 void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference
< embed::XStorage
>& i_rStorage
,
1738 const Sequence
< OUString
> aNames
= maNameContainer
->getElementNames();
1739 const sal_Int32 nNameCount
= aNames
.getLength();
1740 const OUString
* pName
= aNames
.getConstArray();
1741 const OUString
* pNamesEnd
= aNames
.getConstArray() + nNameCount
;
1743 // Don't count libs from shared index file
1744 sal_Int32 nLibsToSave
= nNameCount
;
1745 for( ; pName
!= pNamesEnd
; ++pName
)
1747 SfxLibrary
* pImplLib
= getImplLib( *pName
);
1748 if( pImplLib
->mbSharedIndexFile
|| pImplLib
->mbExtension
)
1753 // Write to storage?
1754 bool bStorage
= i_rStorage
.is();
1755 uno::Reference
< embed::XStorage
> xSourceLibrariesStor
;
1756 uno::Reference
< embed::XStorage
> xTargetLibrariesStor
;
1757 OUString sTempTargetStorName
;
1758 const bool bInplaceStorage
= bStorage
&& ( i_rStorage
== mxStorage
);
1760 if( nLibsToSave
== 0 )
1762 if ( bInplaceStorage
&& mxStorage
->hasByName(maLibrariesDir
) )
1764 mxStorage
->removeElement(maLibrariesDir
);
1771 // Don't write if only empty standard lib exists
1772 if ( ( nLibsToSave
== 1 ) && ( aNames
[0] == "Standard" ) )
1774 Any aLibAny
= maNameContainer
->getByName( aNames
[0] );
1775 Reference
< XNameAccess
> xNameAccess
;
1776 aLibAny
>>= xNameAccess
;
1777 if ( ! xNameAccess
->hasElements() )
1779 if ( bInplaceStorage
&& mxStorage
->hasByName(maLibrariesDir
) )
1781 mxStorage
->removeElement(maLibrariesDir
);
1787 // create the empty target storage
1790 OUString sTargetLibrariesStoreName
;
1791 if ( bInplaceStorage
)
1793 // create a temporary target storage
1794 const OUStringBuffer aTempTargetNameBase
= maLibrariesDir
+ "_temp_";
1795 sal_Int32 index
= 0;
1798 OUStringBuffer
aTempTargetName( aTempTargetNameBase
);
1799 aTempTargetName
.append( index
++ );
1801 sTargetLibrariesStoreName
= aTempTargetName
.makeStringAndClear();
1802 if ( !i_rStorage
->hasByName( sTargetLibrariesStoreName
) )
1808 sTempTargetStorName
= sTargetLibrariesStoreName
;
1812 sTargetLibrariesStoreName
= maLibrariesDir
;
1813 if ( i_rStorage
->hasByName( sTargetLibrariesStoreName
) )
1815 i_rStorage
->removeElement( sTargetLibrariesStoreName
);
1819 xTargetLibrariesStor
.set( i_rStorage
->openStorageElement( sTargetLibrariesStoreName
, embed::ElementModes::READWRITE
), UNO_SET_THROW
);
1821 catch( const uno::Exception
& )
1823 DBG_UNHANDLED_EXCEPTION("basic");
1827 // open the source storage which might be used to copy yet-unmodified libraries
1830 if ( mxStorage
->hasByName( maLibrariesDir
) || bInplaceStorage
)
1832 xSourceLibrariesStor
= mxStorage
->openStorageElement( maLibrariesDir
,
1833 bInplaceStorage
? embed::ElementModes::READWRITE
: embed::ElementModes::READ
);
1836 catch( const uno::Exception
& )
1838 DBG_UNHANDLED_EXCEPTION("basic");
1844 pName
= aNames
.getConstArray();
1845 ::xmlscript::LibDescriptor aLibDescriptorForExtensionLibs
;
1846 std::unique_ptr
< ::xmlscript::LibDescriptorArray
> pLibArray(new ::xmlscript::LibDescriptorArray(nLibsToSave
));
1847 for( ; pName
!= pNamesEnd
; ++pName
)
1849 SfxLibrary
* pImplLib
= getImplLib( *pName
);
1850 if( pImplLib
->mbSharedIndexFile
)
1854 const bool bExtensionLib
= pImplLib
->mbExtension
;
1855 ::xmlscript::LibDescriptor
& rLib
= bExtensionLib
?
1856 aLibDescriptorForExtensionLibs
: pLibArray
->mpLibs
[iArray
];
1857 if( !bExtensionLib
)
1861 rLib
.aName
= *pName
;
1863 rLib
.bLink
= pImplLib
->mbLink
;
1864 if( !bStorage
|| pImplLib
->mbLink
)
1866 rLib
.aStorageURL
= ( pImplLib
->maUnexpandedStorageURL
.getLength() ) ?
1867 pImplLib
->maUnexpandedStorageURL
: pImplLib
->maLibInfoFileURL
;
1869 rLib
.bReadOnly
= pImplLib
->mbReadOnly
;
1870 rLib
.bPreload
= pImplLib
->mbPreload
;
1871 rLib
.bPasswordProtected
= pImplLib
->mbPasswordProtected
;
1872 rLib
.aElementNames
= pImplLib
->getElementNames();
1874 if( pImplLib
->implIsModified() || bComplete
)
1876 // Testing pImplLib->implIsModified() is not reliable,
1877 // IMHO the value of pImplLib->implIsModified() should
1878 // reflect whether the library ( in-memory ) model
1879 // is in sync with the library container's own storage. Currently
1880 // whenever the library model is written to *any* storage
1881 // pImplLib->implSetModified( sal_False ) is called
1882 // The way the code works, especially the way that sfx uses
1883 // temp storage when saving ( and later sets the root storage of the
1884 // library container ) and similar madness in dbaccess means some surgery
1885 // is required to make it possible to successfully use this optimisation
1886 // It would be possible to do the implSetModified() call below only
1887 // conditionally, but that would require an additional boolean to be
1888 // passed in via the XStorageBasedDocument::storeLibrariesToStorage()...
1889 // fdo#68983: If there's a password and the password is not known, only
1890 // copying the storage works!
1891 // Can we simply copy the storage?
1892 bool isCopyStorage
= !mbOldInfoFormat
&& !mbOasis2OOoFormat
1893 && !pImplLib
->isLoadedStorable()
1894 && xSourceLibrariesStor
.is() /* null for user profile */;
1899 (void)xSourceLibrariesStor
->isStorageElement(rLib
.aName
);
1901 catch (container::NoSuchElementException
const&)
1903 isCopyStorage
= false;
1910 xSourceLibrariesStor
->copyElementTo( rLib
.aName
, xTargetLibrariesStor
, rLib
.aName
);
1912 catch( const uno::Exception
& )
1914 DBG_UNHANDLED_EXCEPTION("basic");
1915 // TODO: error handling?
1920 uno::Reference
< embed::XStorage
> xLibraryStor
;
1923 #if OSL_DEBUG_LEVEL > 0
1927 xLibraryStor
= xTargetLibrariesStor
->openStorageElement(
1929 embed::ElementModes::READWRITE
);
1930 #if OSL_DEBUG_LEVEL > 0
1932 catch(const uno::Exception
& )
1934 TOOLS_WARN_EXCEPTION(
1936 "couldn't create sub storage for library \"" << rLib
.aName
<< "\"");
1942 // Maybe lib is not loaded?!
1945 loadLibrary( rLib
.aName
);
1947 if( pImplLib
->mbPasswordProtected
)
1949 implStorePasswordLibrary( pImplLib
, rLib
.aName
, xLibraryStor
, uno::Reference
< task::XInteractionHandler
>() );
1950 // TODO: Check return value
1954 implStoreLibrary( pImplLib
, rLib
.aName
, xLibraryStor
);
1956 implStoreLibraryIndexFile( pImplLib
, rLib
, xLibraryStor
);
1961 uno::Reference
< embed::XTransactedObject
> xTransact( xLibraryStor
, uno::UNO_QUERY_THROW
);
1962 xTransact
->commit();
1964 catch(const uno::Exception
& )
1966 DBG_UNHANDLED_EXCEPTION("basic");
1967 // TODO: error handling
1972 maModifiable
.setModified( true );
1973 pImplLib
->implSetModified( false );
1976 // For container info ReadOnly refers to mbReadOnlyLink
1977 rLib
.bReadOnly
= pImplLib
->mbReadOnlyLink
;
1980 // if we did an in-place save into a storage (i.e. a save into the storage we were already based on),
1981 // then we need to clean up the temporary storage we used for this
1982 if ( bInplaceStorage
&& !sTempTargetStorName
.isEmpty() )
1985 !xSourceLibrariesStor
.is(), "basic",
1986 ("SfxLibrariesContainer::storeLibraries_impl: unexpected: we should"
1987 " have a source storage here!"));
1990 // for this, we first remove everything from the source storage, then copy the complete content
1991 // from the temporary target storage. From then on, what used to be the "source storage" becomes
1992 // the "target storage" for all subsequent operations.
1994 // (We cannot simply remove the storage, denoted by maLibrariesDir, from i_rStorage - there might be
1995 // open references to it.)
1997 if ( xSourceLibrariesStor
.is() )
2000 const Sequence
< OUString
> aRemoveNames( xSourceLibrariesStor
->getElementNames() );
2001 for ( auto const & removeName
: aRemoveNames
)
2003 xSourceLibrariesStor
->removeElement( removeName
);
2007 const Sequence
< OUString
> aCopyNames( xTargetLibrariesStor
->getElementNames() );
2008 for ( auto const & copyName
: aCopyNames
)
2010 xTargetLibrariesStor
->copyElementTo( copyName
, xSourceLibrariesStor
, copyName
);
2014 // close and remove temp target
2015 xTargetLibrariesStor
->dispose();
2016 i_rStorage
->removeElement( sTempTargetStorName
);
2017 xTargetLibrariesStor
.clear();
2018 sTempTargetStorName
.clear();
2021 xTargetLibrariesStor
= xSourceLibrariesStor
;
2022 xSourceLibrariesStor
.clear();
2024 catch( const Exception
& )
2026 DBG_UNHANDLED_EXCEPTION("basic");
2031 if( !mbOldInfoFormat
&& !maModifiable
.isModified() )
2035 maModifiable
.setModified( false );
2036 mbOldInfoFormat
= false;
2038 // Write library container info
2039 // Create sax writer
2040 Reference
< XWriter
> xWriter
= xml::sax::Writer::create(mxContext
);
2043 uno::Reference
< io::XOutputStream
> xOut
;
2044 uno::Reference
< io::XStream
> xInfoStream
;
2047 OUString aStreamName
= maInfoFileName
+ "-lc.xml";
2051 xInfoStream
= xTargetLibrariesStor
->openStreamElement( aStreamName
, embed::ElementModes::READWRITE
);
2052 uno::Reference
< beans::XPropertySet
> xProps( xInfoStream
, uno::UNO_QUERY_THROW
);
2053 xProps
->setPropertyValue("MediaType", uno::Any( OUString( "text/xml" ) ) );
2055 // #87671 Allow encryption
2056 xProps
->setPropertyValue("UseCommonStoragePasswordEncryption", uno::Any( true ) );
2058 xOut
= xInfoStream
->getOutputStream();
2060 catch(const uno::Exception
& )
2062 ErrorHandler::HandleError( ERRCODE_IO_GENERAL
);
2067 // Create Output stream
2068 INetURLObject
aLibInfoInetObj( maLibraryPath
.getToken(1, ';') );
2069 aLibInfoInetObj
.insertName( maInfoFileName
, false, INetURLObject::LAST_SEGMENT
, INetURLObject::EncodeMechanism::All
);
2070 aLibInfoInetObj
.setExtension( "xlc" );
2071 OUString
aLibInfoPath( aLibInfoInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
2075 if( mxSFI
->exists( aLibInfoPath
) )
2077 mxSFI
->kill( aLibInfoPath
);
2079 xOut
= mxSFI
->openFileWrite( aLibInfoPath
);
2081 catch(const Exception
& )
2084 SfxErrorContext
aEc( ERRCTX_SFX_SAVEDOC
, aLibInfoPath
);
2085 ErrorHandler::HandleError( ERRCODE_IO_GENERAL
);
2091 SAL_WARN("basic", "couldn't open output stream");
2095 xWriter
->setOutputStream( xOut
);
2099 xmlscript::exportLibraryContainer( xWriter
, pLibArray
.get() );
2102 uno::Reference
< embed::XTransactedObject
> xTransact( xTargetLibrariesStor
, uno::UNO_QUERY_THROW
);
2103 xTransact
->commit();
2106 catch(const uno::Exception
& )
2108 SAL_WARN("basic", "Problem during storing of libraries!");
2109 ErrorHandler::HandleError( ERRCODE_IO_GENERAL
);
2114 // Methods XElementAccess
2115 Type SAL_CALL
SfxLibraryContainer::getElementType()
2117 LibraryContainerMethodGuard
aGuard( *this );
2118 return maNameContainer
->getElementType();
2121 sal_Bool
SfxLibraryContainer::hasElements()
2123 LibraryContainerMethodGuard
aGuard( *this );
2124 bool bRet
= maNameContainer
->hasElements();
2128 // Methods XNameAccess
2129 Any
SfxLibraryContainer::getByName( const OUString
& aName
)
2131 LibraryContainerMethodGuard
aGuard( *this );
2132 Any aRetAny
= maNameContainer
->getByName( aName
) ;
2136 Sequence
< OUString
> SfxLibraryContainer::getElementNames()
2138 LibraryContainerMethodGuard
aGuard( *this );
2139 return maNameContainer
->getElementNames();
2142 sal_Bool
SfxLibraryContainer::hasByName( const OUString
& aName
)
2144 LibraryContainerMethodGuard
aGuard( *this );
2145 return maNameContainer
->hasByName( aName
) ;
2148 // Methods XLibraryContainer
2149 Reference
< XNameContainer
> SAL_CALL
SfxLibraryContainer::createLibrary( const OUString
& Name
)
2151 LibraryContainerMethodGuard
aGuard( *this );
2152 SfxLibrary
* pNewLib
= implCreateLibrary( Name
);
2153 pNewLib
->maLibElementFileExtension
= maLibElementFileExtension
;
2155 createVariableURL( pNewLib
->maUnexpandedStorageURL
, Name
, maInfoFileName
, true );
2157 Reference
< XNameAccess
> xNameAccess
= static_cast< XNameAccess
* >( pNewLib
);
2159 aElement
<<= xNameAccess
;
2160 maNameContainer
->insertByName( Name
, aElement
);
2161 maModifiable
.setModified( true );
2162 Reference
< XNameContainer
> xRet( xNameAccess
, UNO_QUERY
);
2166 Reference
< XNameAccess
> SAL_CALL
SfxLibraryContainer::createLibraryLink
2167 ( const OUString
& Name
, const OUString
& StorageURL
, sal_Bool ReadOnly
)
2169 LibraryContainerMethodGuard
aGuard( *this );
2170 // TODO: Check other reasons to force ReadOnly status
2175 OUString aLibInfoFileURL
;
2176 OUString aLibDirURL
;
2177 OUString aUnexpandedStorageURL
;
2178 checkStorageURL( StorageURL
, aLibInfoFileURL
, aLibDirURL
, aUnexpandedStorageURL
);
2181 SfxLibrary
* pNewLib
= implCreateLibraryLink( Name
, aLibInfoFileURL
, aLibDirURL
, ReadOnly
);
2182 pNewLib
->maLibElementFileExtension
= maLibElementFileExtension
;
2183 pNewLib
->maUnexpandedStorageURL
= aUnexpandedStorageURL
;
2184 pNewLib
->maOriginalStorageURL
= StorageURL
;
2186 uno::Reference
< embed::XStorage
> xDummyStor
;
2187 ::xmlscript::LibDescriptor aLibDesc
;
2188 implLoadLibraryIndexFile( pNewLib
, aLibDesc
, xDummyStor
, OUString() );
2189 implImportLibDescriptor( pNewLib
, aLibDesc
);
2191 Reference
< XNameAccess
> xRet
= static_cast< XNameAccess
* >( pNewLib
);
2194 maNameContainer
->insertByName( Name
, aElement
);
2195 maModifiable
.setModified( true );
2197 if( StorageURL
.indexOf( "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE" ) != -1 )
2199 pNewLib
->mbExtension
= true;
2201 else if( StorageURL
.indexOf( "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE" ) != -1
2202 || StorageURL
.indexOf( "vnd.sun.star.expand:$BUNDLED_EXTENSIONS" ) != -1 )
2204 pNewLib
->mbExtension
= true;
2205 pNewLib
->mbReadOnly
= true;
2211 void SAL_CALL
SfxLibraryContainer::removeLibrary( const OUString
& Name
)
2213 LibraryContainerMethodGuard
aGuard( *this );
2214 // Get and hold library before removing
2215 Any aLibAny
= maNameContainer
->getByName( Name
) ;
2216 Reference
< XNameAccess
> xNameAccess
;
2217 aLibAny
>>= xNameAccess
;
2218 SfxLibrary
* pImplLib
= static_cast< SfxLibrary
* >( xNameAccess
.get() );
2219 if( pImplLib
->mbReadOnly
&& !pImplLib
->mbLink
)
2221 throw IllegalArgumentException();
2223 // Remove from container
2224 maNameContainer
->removeByName( Name
);
2225 maModifiable
.setModified( true );
2227 // Delete library files, but not for linked libraries
2228 if( !pImplLib
->mbLink
)
2230 if( mxStorage
.is() )
2234 if( xNameAccess
->hasElements() )
2236 Sequence
< OUString
> aNames
= pImplLib
->getElementNames();
2237 sal_Int32 nNameCount
= aNames
.getLength();
2238 const OUString
* pNames
= aNames
.getConstArray();
2239 for( sal_Int32 i
= 0 ; i
< nNameCount
; ++i
, ++pNames
)
2241 pImplLib
->removeElementWithoutChecks( *pNames
, SfxLibrary::LibraryContainerAccess() );
2245 // Delete index file
2246 createAppLibraryFolder( pImplLib
, Name
);
2247 OUString aLibInfoPath
= pImplLib
->maLibInfoFileURL
;
2250 if( mxSFI
->exists( aLibInfoPath
) )
2252 mxSFI
->kill( aLibInfoPath
);
2255 catch(const Exception
& ) {}
2257 // Delete folder if empty
2258 INetURLObject
aInetObj( maLibraryPath
.getToken(1, ';') );
2259 aInetObj
.insertName( Name
, true, INetURLObject::LAST_SEGMENT
,
2260 INetURLObject::EncodeMechanism::All
);
2261 OUString aLibDirPath
= aInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
2265 if( mxSFI
->isFolder( aLibDirPath
) )
2267 Sequence
< OUString
> aContentSeq
= mxSFI
->getFolderContents( aLibDirPath
, true );
2268 sal_Int32 nCount
= aContentSeq
.getLength();
2271 mxSFI
->kill( aLibDirPath
);
2275 catch(const Exception
& )
2281 sal_Bool SAL_CALL
SfxLibraryContainer::isLibraryLoaded( const OUString
& Name
)
2283 LibraryContainerMethodGuard
aGuard( *this );
2284 SfxLibrary
* pImplLib
= getImplLib( Name
);
2285 bool bRet
= pImplLib
->mbLoaded
;
2290 void SAL_CALL
SfxLibraryContainer::loadLibrary( const OUString
& Name
)
2292 LibraryContainerMethodGuard
aGuard( *this );
2293 Any aLibAny
= maNameContainer
->getByName( Name
) ;
2294 Reference
< XNameAccess
> xNameAccess
;
2295 aLibAny
>>= xNameAccess
;
2296 SfxLibrary
* pImplLib
= static_cast< SfxLibrary
* >( xNameAccess
.get() );
2298 bool bLoaded
= pImplLib
->mbLoaded
;
2299 pImplLib
->mbLoaded
= true;
2300 if( !bLoaded
&& xNameAccess
->hasElements() )
2302 if( pImplLib
->mbPasswordProtected
)
2304 implLoadPasswordLibrary( pImplLib
, Name
);
2308 bool bLink
= pImplLib
->mbLink
;
2309 bool bStorage
= mxStorage
.is() && !bLink
;
2311 uno::Reference
< embed::XStorage
> xLibrariesStor
;
2312 uno::Reference
< embed::XStorage
> xLibraryStor
;
2315 #if OSL_DEBUG_LEVEL > 0
2319 xLibrariesStor
= mxStorage
->openStorageElement( maLibrariesDir
, embed::ElementModes::READ
);
2321 !xLibrariesStor
.is(), "basic",
2322 ("The method must either throw exception or return a"
2324 if ( !xLibrariesStor
.is() )
2326 throw uno::RuntimeException("null returned from openStorageElement");
2329 xLibraryStor
= xLibrariesStor
->openStorageElement( Name
, embed::ElementModes::READ
);
2331 !xLibraryStor
.is(), "basic",
2332 ("The method must either throw exception or return a"
2334 if ( !xLibrariesStor
.is() )
2336 throw uno::RuntimeException("null returned from openStorageElement");
2338 #if OSL_DEBUG_LEVEL > 0
2340 catch(const uno::Exception
& )
2342 TOOLS_WARN_EXCEPTION(
2344 "couldn't open sub storage for library \"" << Name
<< "\"");
2350 Sequence
< OUString
> aNames
= pImplLib
->getElementNames();
2351 sal_Int32 nNameCount
= aNames
.getLength();
2352 const OUString
* pNames
= aNames
.getConstArray();
2353 for( sal_Int32 i
= 0 ; i
< nNameCount
; i
++ )
2355 OUString aElementName
= pNames
[ i
];
2358 uno::Reference
< io::XInputStream
> xInStream
;
2362 uno::Reference
< io::XStream
> xElementStream
;
2364 aFile
= aElementName
+ ".xml";
2368 xElementStream
= xLibraryStor
->openStreamElement( aFile
, embed::ElementModes::READ
);
2370 catch(const uno::Exception
& )
2373 if( !xElementStream
.is() )
2375 // Check for EA2 document version with wrong extensions
2376 aFile
= aElementName
+ "." + maLibElementFileExtension
;
2379 xElementStream
= xLibraryStor
->openStreamElement( aFile
, embed::ElementModes::READ
);
2381 catch(const uno::Exception
& )
2385 if ( xElementStream
.is() )
2387 xInStream
= xElementStream
->getInputStream();
2389 if ( !xInStream
.is() )
2393 "couldn't open library element stream - attempted to"
2394 " open library \"" << Name
<< '"');
2395 throw RuntimeException("couldn't open library element stream", *this);
2400 OUString aLibDirPath
= pImplLib
->maStorageURL
;
2401 INetURLObject
aElementInetObj( aLibDirPath
);
2402 aElementInetObj
.insertName( aElementName
, false,
2403 INetURLObject::LAST_SEGMENT
,
2404 INetURLObject::EncodeMechanism::All
);
2405 aElementInetObj
.setExtension( maLibElementFileExtension
);
2406 aFile
= aElementInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
2409 Reference
< XNameContainer
> xLib( pImplLib
);
2410 Any aAny
= importLibraryElement( xLib
, aElementName
,
2412 if( pImplLib
->hasByName( aElementName
) )
2414 if( aAny
.hasValue() )
2416 pImplLib
->maNameContainer
->replaceByName( aElementName
, aAny
);
2421 pImplLib
->maNameContainer
->insertNoCheck(aElementName
, aAny
);
2424 pImplLib
->implSetModified( false );
2428 // Methods XLibraryContainer2
2429 sal_Bool SAL_CALL
SfxLibraryContainer::isLibraryLink( const OUString
& Name
)
2431 LibraryContainerMethodGuard
aGuard( *this );
2432 SfxLibrary
* pImplLib
= getImplLib( Name
);
2433 bool bRet
= pImplLib
->mbLink
;
2437 OUString SAL_CALL
SfxLibraryContainer::getLibraryLinkURL( const OUString
& Name
)
2439 LibraryContainerMethodGuard
aGuard( *this );
2440 SfxLibrary
* pImplLib
= getImplLib( Name
);
2441 bool bLink
= pImplLib
->mbLink
;
2444 throw IllegalArgumentException();
2446 OUString aRetStr
= pImplLib
->maLibInfoFileURL
;
2450 sal_Bool SAL_CALL
SfxLibraryContainer::isLibraryReadOnly( const OUString
& Name
)
2452 LibraryContainerMethodGuard
aGuard( *this );
2453 SfxLibrary
* pImplLib
= getImplLib( Name
);
2454 bool bRet
= pImplLib
->mbReadOnly
|| (pImplLib
->mbLink
&& pImplLib
->mbReadOnlyLink
);
2458 void SAL_CALL
SfxLibraryContainer::setLibraryReadOnly( const OUString
& Name
, sal_Bool bReadOnly
)
2460 LibraryContainerMethodGuard
aGuard( *this );
2461 SfxLibrary
* pImplLib
= getImplLib( Name
);
2462 if( pImplLib
->mbLink
)
2464 if( pImplLib
->mbReadOnlyLink
!= bool(bReadOnly
) )
2466 pImplLib
->mbReadOnlyLink
= bReadOnly
;
2467 pImplLib
->implSetModified( true );
2468 maModifiable
.setModified( true );
2473 if( pImplLib
->mbReadOnly
!= bool(bReadOnly
) )
2475 pImplLib
->mbReadOnly
= bReadOnly
;
2476 pImplLib
->implSetModified( true );
2481 void SAL_CALL
SfxLibraryContainer::renameLibrary( const OUString
& Name
, const OUString
& NewName
)
2483 LibraryContainerMethodGuard
aGuard( *this );
2484 if( maNameContainer
->hasByName( NewName
) )
2486 throw ElementExistException();
2488 // Get and hold library before removing
2489 Any aLibAny
= maNameContainer
->getByName( Name
) ;
2491 // #i24094 Maybe lib is not loaded!
2492 Reference
< XNameAccess
> xNameAccess
;
2493 aLibAny
>>= xNameAccess
;
2494 SfxLibrary
* pImplLib
= static_cast< SfxLibrary
* >( xNameAccess
.get() );
2495 if( pImplLib
->mbPasswordProtected
&& !pImplLib
->mbPasswordVerified
)
2497 return; // Lib with unverified password cannot be renamed
2499 loadLibrary( Name
);
2501 // Remove from container
2502 maNameContainer
->removeByName( Name
);
2503 maModifiable
.setModified( true );
2505 // Rename library folder, but not for linked libraries
2506 bool bMovedSuccessful
= true;
2509 bool bStorage
= mxStorage
.is();
2510 if( !bStorage
&& !pImplLib
->mbLink
)
2512 bMovedSuccessful
= false;
2514 OUString aLibDirPath
= pImplLib
->maStorageURL
;
2516 INetURLObject
aDestInetObj( maLibraryPath
.getToken(1, ';'));
2517 aDestInetObj
.insertName( NewName
, true, INetURLObject::LAST_SEGMENT
,
2518 INetURLObject::EncodeMechanism::All
);
2519 OUString aDestDirPath
= aDestInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
2522 OUString aLibInfoFileURL
= pImplLib
->maLibInfoFileURL
;
2523 checkStorageURL( aDestDirPath
, pImplLib
->maLibInfoFileURL
, pImplLib
->maStorageURL
,
2524 pImplLib
->maUnexpandedStorageURL
);
2528 if( mxSFI
->isFolder( aLibDirPath
) )
2530 if( !mxSFI
->isFolder( aDestDirPath
) )
2532 mxSFI
->createFolder( aDestDirPath
);
2537 if( mxSFI
->exists( pImplLib
->maLibInfoFileURL
) )
2539 mxSFI
->kill( pImplLib
->maLibInfoFileURL
);
2541 mxSFI
->move( aLibInfoFileURL
, pImplLib
->maLibInfoFileURL
);
2543 catch(const Exception
& )
2547 Sequence
< OUString
> aElementNames
= xNameAccess
->getElementNames();
2548 sal_Int32 nNameCount
= aElementNames
.getLength();
2549 const OUString
* pNames
= aElementNames
.getConstArray();
2550 for( sal_Int32 i
= 0 ; i
< nNameCount
; i
++ )
2552 OUString aElementName
= pNames
[ i
];
2554 INetURLObject
aElementInetObj( aLibDirPath
);
2555 aElementInetObj
.insertName( aElementName
, false,
2556 INetURLObject::LAST_SEGMENT
, INetURLObject::EncodeMechanism::All
);
2557 aElementInetObj
.setExtension( maLibElementFileExtension
);
2558 OUString
aElementPath( aElementInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
2560 INetURLObject
aElementDestInetObj( aDestDirPath
);
2561 aElementDestInetObj
.insertName( aElementName
, false,
2562 INetURLObject::LAST_SEGMENT
,
2563 INetURLObject::EncodeMechanism::All
);
2564 aElementDestInetObj
.setExtension( maLibElementFileExtension
);
2565 OUString
aDestElementPath( aElementDestInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
2569 if( mxSFI
->exists( aDestElementPath
) )
2571 mxSFI
->kill( aDestElementPath
);
2573 mxSFI
->move( aElementPath
, aDestElementPath
);
2575 catch(const Exception
& )
2579 pImplLib
->storeResourcesAsURL( aDestDirPath
, NewName
);
2581 // Delete folder if empty
2582 Sequence
< OUString
> aContentSeq
= mxSFI
->getFolderContents( aLibDirPath
, true );
2583 sal_Int32 nCount
= aContentSeq
.getLength();
2586 mxSFI
->kill( aLibDirPath
);
2589 bMovedSuccessful
= true;
2590 pImplLib
->implSetModified( true );
2593 catch(const Exception
& )
2595 // Restore old library
2596 maNameContainer
->insertByName( Name
, aLibAny
) ;
2600 if( bStorage
&& !pImplLib
->mbLink
)
2602 pImplLib
->implSetModified( true );
2604 if( bMovedSuccessful
)
2606 maNameContainer
->insertByName( NewName
, aLibAny
) ;
2611 // Methods XInitialization
2612 void SAL_CALL
SfxLibraryContainer::initialize( const Sequence
< Any
>& _rArguments
)
2614 LibraryContainerMethodGuard
aGuard( *this );
2615 sal_Int32 nArgCount
= _rArguments
.getLength();
2616 if ( nArgCount
== 1 )
2618 OUString sInitialDocumentURL
;
2619 Reference
< XStorageBasedDocument
> xDocument
;
2620 if ( _rArguments
[0] >>= sInitialDocumentURL
)
2622 init( sInitialDocumentURL
, nullptr );
2626 if ( _rArguments
[0] >>= xDocument
)
2628 initializeFromDocument( xDocument
);
2633 throw IllegalArgumentException();
2636 void SfxLibraryContainer::initializeFromDocument( const Reference
< XStorageBasedDocument
>& _rxDocument
)
2638 // check whether this is a valid OfficeDocument, and obtain the document's root storage
2639 Reference
< XStorage
> xDocStorage
;
2642 Reference
< XServiceInfo
> xSI( _rxDocument
, UNO_QUERY_THROW
);
2643 if ( xSI
->supportsService("com.sun.star.document.OfficeDocument"))
2645 xDocStorage
.set( _rxDocument
->getDocumentStorage(), UNO_SET_THROW
);
2647 Reference
< XModel
> xDocument( _rxDocument
, UNO_QUERY_THROW
);
2648 Reference
< XComponent
> xDocComponent( _rxDocument
, UNO_QUERY_THROW
);
2650 mxOwnerDocument
= xDocument
;
2651 startComponentListening( xDocComponent
);
2653 catch( const Exception
& ) { }
2655 if ( !xDocStorage
.is() )
2657 throw IllegalArgumentException();
2659 init( OUString(), xDocStorage
);
2662 // OEventListenerAdapter
2663 void SfxLibraryContainer::_disposing( const EventObject
& _rSource
)
2665 #if OSL_DEBUG_LEVEL > 0
2666 Reference
< XModel
> xDocument( mxOwnerDocument
.get(), UNO_QUERY
);
2668 xDocument
!= _rSource
.Source
|| !xDocument
.is(), "basic",
2669 "SfxLibraryContainer::_disposing: where does this come from?");
2677 void SAL_CALL
SfxLibraryContainer::disposing()
2679 Reference
< XModel
> xModel
= mxOwnerDocument
;
2680 EventObject
aEvent( xModel
.get() );
2681 maVBAScriptListeners
.disposing( aEvent
);
2682 stopAllComponentListening();
2683 mxOwnerDocument
.clear();
2686 // Methods XLibraryContainerPassword
2687 sal_Bool SAL_CALL
SfxLibraryContainer::isLibraryPasswordProtected( const OUString
& )
2692 sal_Bool SAL_CALL
SfxLibraryContainer::isLibraryPasswordVerified( const OUString
& )
2694 throw IllegalArgumentException();
2697 sal_Bool SAL_CALL
SfxLibraryContainer::verifyLibraryPassword( const OUString
&, const OUString
& )
2699 throw IllegalArgumentException();
2702 void SAL_CALL
SfxLibraryContainer::changeLibraryPassword(const OUString
&, const OUString
&, const OUString
& )
2704 throw IllegalArgumentException();
2707 // Methods XContainer
2708 void SAL_CALL
SfxLibraryContainer::addContainerListener( const Reference
< XContainerListener
>& xListener
)
2710 LibraryContainerMethodGuard
aGuard( *this );
2711 maNameContainer
->setEventSource( static_cast< XInterface
* >( static_cast<OWeakObject
*>(this) ) );
2712 maNameContainer
->addContainerListener( xListener
);
2715 void SAL_CALL
SfxLibraryContainer::removeContainerListener( const Reference
< XContainerListener
>& xListener
)
2717 LibraryContainerMethodGuard
aGuard( *this );
2718 maNameContainer
->removeContainerListener( xListener
);
2721 // Methods XLibraryContainerExport
2722 void SAL_CALL
SfxLibraryContainer::exportLibrary( const OUString
& Name
, const OUString
& URL
,
2723 const Reference
< XInteractionHandler
>& Handler
)
2725 LibraryContainerMethodGuard
aGuard( *this );
2726 SfxLibrary
* pImplLib
= getImplLib( Name
);
2728 Reference
< XSimpleFileAccess3
> xToUseSFI
;
2731 xToUseSFI
= ucb::SimpleFileAccess::create( mxContext
);
2732 xToUseSFI
->setInteractionHandler( Handler
);
2735 // Maybe lib is not loaded?!
2736 loadLibrary( Name
);
2738 uno::Reference
< css::embed::XStorage
> xDummyStor
;
2739 if( pImplLib
->mbPasswordProtected
)
2741 implStorePasswordLibrary( pImplLib
, Name
, xDummyStor
, URL
, xToUseSFI
, Handler
);
2745 implStoreLibrary( pImplLib
, Name
, xDummyStor
, URL
, xToUseSFI
, Handler
);
2747 ::xmlscript::LibDescriptor aLibDesc
;
2748 aLibDesc
.aName
= Name
;
2749 aLibDesc
.bLink
= false; // Link status gets lost?
2750 aLibDesc
.bReadOnly
= pImplLib
->mbReadOnly
;
2751 aLibDesc
.bPreload
= false; // Preload status gets lost?
2752 aLibDesc
.bPasswordProtected
= pImplLib
->mbPasswordProtected
;
2753 aLibDesc
.aElementNames
= pImplLib
->getElementNames();
2755 implStoreLibraryIndexFile( pImplLib
, aLibDesc
, xDummyStor
, URL
, xToUseSFI
);
2758 OUString
SfxLibraryContainer::expand_url( const OUString
& url
)
2760 if (url
.startsWithIgnoreAsciiCase( "vnd.sun.star.expand:" ))
2762 return comphelper::getExpandedUri(mxContext
, url
);
2764 else if( mxStringSubstitution
.is() )
2766 OUString
ret( mxStringSubstitution
->substituteVariables( url
, false ) );
2775 //XLibraryContainer3
2776 OUString SAL_CALL
SfxLibraryContainer::getOriginalLibraryLinkURL( const OUString
& Name
)
2778 LibraryContainerMethodGuard
aGuard( *this );
2779 SfxLibrary
* pImplLib
= getImplLib( Name
);
2780 bool bLink
= pImplLib
->mbLink
;
2783 throw IllegalArgumentException();
2785 OUString aRetStr
= pImplLib
->maOriginalStorageURL
;
2790 // XVBACompatibility
2791 sal_Bool SAL_CALL
SfxLibraryContainer::getVBACompatibilityMode()
2796 void SAL_CALL
SfxLibraryContainer::setVBACompatibilityMode( sal_Bool _vbacompatmodeon
)
2798 /* The member variable mbVBACompat must be set first, the following call
2799 to getBasicManager() may call getVBACompatibilityMode() which returns
2801 mbVBACompat
= _vbacompatmodeon
;
2802 if( BasicManager
* pBasMgr
= getBasicManager() )
2804 // get the standard library
2805 OUString aLibName
= pBasMgr
->GetName();
2806 if ( aLibName
.isEmpty())
2808 aLibName
= "Standard";
2810 if( StarBASIC
* pBasic
= pBasMgr
->GetLib( aLibName
) )
2812 pBasic
->SetVBAEnabled( _vbacompatmodeon
);
2814 /* If in VBA compatibility mode, force creation of the VBA Globals
2815 object. Each application will create an instance of its own
2816 implementation and store it in its Basic manager. Implementations
2817 will do all necessary additional initialization, such as
2818 registering the global "This***Doc" UNO constant, starting the
2819 document events processor etc.
2821 if( mbVBACompat
) try
2823 Reference
< XModel
> xModel( mxOwnerDocument
); // weak-ref -> ref
2824 Reference
< XMultiServiceFactory
> xFactory( xModel
, UNO_QUERY_THROW
);
2825 xFactory
->createInstance("ooo.vba.VBAGlobals");
2827 catch(const Exception
& )
2833 void SAL_CALL
SfxLibraryContainer::setProjectName( const OUString
& _projectname
)
2835 msProjectName
= _projectname
;
2836 BasicManager
* pBasMgr
= getBasicManager();
2838 // Some parts of the VBA handling ( e.g. in core basic )
2839 // code expect the name of the VBA project to be set as the name of
2840 // the basic manager. Provide fail back here.
2843 pBasMgr
->SetName( msProjectName
);
2847 sal_Int32 SAL_CALL
SfxLibraryContainer::getRunningVBAScripts()
2849 LibraryContainerMethodGuard
aGuard( *this );
2850 return mnRunningVBAScripts
;
2853 void SAL_CALL
SfxLibraryContainer::addVBAScriptListener( const Reference
< vba::XVBAScriptListener
>& rxListener
)
2855 maVBAScriptListeners
.addTypedListener( rxListener
);
2858 void SAL_CALL
SfxLibraryContainer::removeVBAScriptListener( const Reference
< vba::XVBAScriptListener
>& rxListener
)
2860 maVBAScriptListeners
.removeTypedListener( rxListener
);
2863 void SAL_CALL
SfxLibraryContainer::broadcastVBAScriptEvent( sal_Int32 nIdentifier
, const OUString
& rModuleName
)
2865 // own lock for accessing the number of running scripts
2867 switch( nIdentifier
)
2869 case vba::VBAScriptEventId::SCRIPT_STARTED
:
2870 ++mnRunningVBAScripts
;
2872 case vba::VBAScriptEventId::SCRIPT_STOPPED
:
2873 --mnRunningVBAScripts
;
2878 Reference
< XModel
> xModel
= mxOwnerDocument
; // weak-ref -> ref
2879 vba::VBAScriptEvent
aEvent( Reference
<XInterface
>(xModel
, UNO_QUERY
), nIdentifier
, rModuleName
);
2880 maVBAScriptListeners
.notify( aEvent
);
2883 // Methods XServiceInfo
2884 sal_Bool SAL_CALL
SfxLibraryContainer::supportsService( const OUString
& _rServiceName
)
2886 return cppu::supportsService(this, _rServiceName
);
2889 // Implementation class SfxLibrary
2892 SfxLibrary::SfxLibrary( ModifiableHelper
& _rModifiable
, const Type
& aType
,
2893 const Reference
< XSimpleFileAccess3
>& xSFI
)
2894 : OComponentHelper( m_aMutex
)
2896 , mrModifiable( _rModifiable
)
2897 , maNameContainer( new NameContainer(aType
) )
2899 , mbIsModified( true )
2900 , mbInitialised( false )
2902 , mbReadOnly( false )
2903 , mbReadOnlyLink( false )
2904 , mbPreload( false )
2905 , mbPasswordProtected( false )
2906 , mbPasswordVerified( false )
2907 , mbDoc50Password( false )
2908 , mbSharedIndexFile( false )
2909 , mbExtension( false )
2913 SfxLibrary::SfxLibrary( ModifiableHelper
& _rModifiable
, const Type
& aType
,
2914 const Reference
< XSimpleFileAccess3
>& xSFI
,
2915 const OUString
& aLibInfoFileURL
, const OUString
& aStorageURL
, bool ReadOnly
)
2916 : OComponentHelper( m_aMutex
)
2918 , mrModifiable( _rModifiable
)
2919 , maNameContainer( new NameContainer(aType
) )
2921 , mbIsModified( true )
2922 , mbInitialised( false )
2923 , maLibInfoFileURL( aLibInfoFileURL
)
2924 , maStorageURL( aStorageURL
)
2926 , mbReadOnly( false )
2927 , mbReadOnlyLink( ReadOnly
)
2928 , mbPreload( false )
2929 , mbPasswordProtected( false )
2930 , mbPasswordVerified( false )
2931 , mbDoc50Password( false )
2932 , mbSharedIndexFile( false )
2933 , mbExtension( false )
2937 bool SfxLibrary::isLoadedStorable()
2939 return mbLoaded
&& (!mbPasswordProtected
|| mbPasswordVerified
);
2942 void SfxLibrary::implSetModified( bool _bIsModified
)
2944 if ( mbIsModified
== _bIsModified
)
2948 mbIsModified
= _bIsModified
;
2951 mrModifiable
.setModified( true );
2955 // Methods XInterface
2956 Any SAL_CALL
SfxLibrary::queryInterface( const Type
& rType
)
2959 ::cppu::queryInterface(
2961 static_cast< XContainer
* >( this ),
2962 static_cast< XNameContainer
* >( this ),
2963 static_cast< XNameAccess
* >( this ),
2964 static_cast< XElementAccess
* >( this ),
2965 static_cast< XChangesNotifier
* >( this ) );
2966 if( !aRet
.hasValue() )
2968 aRet
= OComponentHelper::queryInterface( rType
);
2973 // Methods XElementAccess
2974 Type
SfxLibrary::getElementType()
2976 return maNameContainer
->getElementType();
2979 sal_Bool
SfxLibrary::hasElements()
2981 bool bRet
= maNameContainer
->hasElements();
2985 // Methods XNameAccess
2986 Any
SfxLibrary::getByName( const OUString
& aName
)
2990 Any aRetAny
= maNameContainer
->getByName( aName
) ;
2994 Sequence
< OUString
> SfxLibrary::getElementNames()
2996 return maNameContainer
->getElementNames();
2999 sal_Bool
SfxLibrary::hasByName( const OUString
& aName
)
3001 bool bRet
= maNameContainer
->hasByName( aName
);
3005 void SfxLibrary::impl_checkReadOnly()
3007 if( mbReadOnly
|| (mbLink
&& mbReadOnlyLink
) )
3009 throw IllegalArgumentException(
3010 "Library is readonly.",
3017 void SfxLibrary::impl_checkLoaded()
3021 throw WrappedTargetException(
3024 Any( LibraryNotLoadedException(
3032 // Methods XNameReplace
3033 void SfxLibrary::replaceByName( const OUString
& aName
, const Any
& aElement
)
3035 impl_checkReadOnly();
3039 !isLibraryElementValid(aElement
), "basic",
3040 "SfxLibrary::replaceByName: replacing element is invalid!");
3042 maNameContainer
->replaceByName( aName
, aElement
);
3043 implSetModified( true );
3047 // Methods XNameContainer
3048 void SfxLibrary::insertByName( const OUString
& aName
, const Any
& aElement
)
3050 impl_checkReadOnly();
3054 !isLibraryElementValid(aElement
), "basic",
3055 "SfxLibrary::insertByName: to-be-inserted element is invalid!");
3057 maNameContainer
->insertByName( aName
, aElement
);
3058 implSetModified( true );
3061 void SfxLibrary::impl_removeWithoutChecks( const OUString
& _rElementName
)
3063 maNameContainer
->removeByName( _rElementName
);
3064 implSetModified( true );
3066 // Remove element file
3067 if( !maStorageURL
.isEmpty() )
3069 INetURLObject
aElementInetObj( maStorageURL
);
3070 aElementInetObj
.insertName( _rElementName
, false,
3071 INetURLObject::LAST_SEGMENT
,
3072 INetURLObject::EncodeMechanism::All
);
3073 aElementInetObj
.setExtension( maLibElementFileExtension
);
3074 OUString aFile
= aElementInetObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
3078 if( mxSFI
->exists( aFile
) )
3080 mxSFI
->kill( aFile
);
3083 catch(const Exception
& )
3085 DBG_UNHANDLED_EXCEPTION("basic");
3090 void SfxLibrary::removeByName( const OUString
& Name
)
3092 impl_checkReadOnly();
3094 impl_removeWithoutChecks( Name
);
3098 Sequence
< Type
> SfxLibrary::getTypes()
3100 static OTypeCollection
ourTypes_NameContainer(
3101 cppu::UnoType
<XNameContainer
>::get(),
3102 cppu::UnoType
<XContainer
>::get(),
3103 cppu::UnoType
<XChangesNotifier
>::get(),
3104 OComponentHelper::getTypes() );
3106 return ourTypes_NameContainer
.getTypes();
3110 Sequence
< sal_Int8
> SfxLibrary::getImplementationId()
3112 return css::uno::Sequence
<sal_Int8
>();
3115 // Methods XContainer
3116 void SAL_CALL
SfxLibrary::addContainerListener( const Reference
< XContainerListener
>& xListener
)
3118 maNameContainer
->setEventSource( static_cast< XInterface
* >( static_cast<OWeakObject
*>(this) ) );
3119 maNameContainer
->addContainerListener( xListener
);
3122 void SAL_CALL
SfxLibrary::removeContainerListener( const Reference
< XContainerListener
>& xListener
)
3124 maNameContainer
->removeContainerListener( xListener
);
3127 // Methods XChangesNotifier
3128 void SAL_CALL
SfxLibrary::addChangesListener( const Reference
< XChangesListener
>& xListener
)
3130 maNameContainer
->setEventSource( static_cast< XInterface
* >( static_cast<OWeakObject
*>(this) ) );
3131 maNameContainer
->addChangesListener( xListener
);
3134 void SAL_CALL
SfxLibrary::removeChangesListener( const Reference
< XChangesListener
>& xListener
)
3136 maNameContainer
->removeChangesListener( xListener
);
3140 // Implementation class ScriptExtensionIterator
3142 #define sBasicLibMediaType "application/vnd.sun.star.basic-library"
3143 #define sDialogLibMediaType "application/vnd.sun.star.dialog-library"
3145 ScriptExtensionIterator::ScriptExtensionIterator()
3146 : m_xContext( comphelper::getProcessComponentContext() )
3147 , m_eState( USER_EXTENSIONS
)
3148 , m_bUserPackagesLoaded( false )
3149 , m_bSharedPackagesLoaded( false )
3150 , m_bBundledPackagesLoaded( false )
3151 , m_iUserPackage( 0 )
3152 , m_iSharedPackage( 0 )
3153 , m_iBundledPackage( 0 )
3154 , m_pScriptSubPackageIterator( nullptr )
3157 OUString
ScriptExtensionIterator::nextBasicOrDialogLibrary( bool& rbPureDialogLib
)
3161 while( aRetLib
.isEmpty() && m_eState
!= END_REACHED
)
3165 case USER_EXTENSIONS
:
3167 Reference
< deployment::XPackage
> xScriptPackage
=
3168 implGetNextUserScriptPackage( rbPureDialogLib
);
3169 if( !xScriptPackage
.is() )
3173 aRetLib
= xScriptPackage
->getURL();
3177 case SHARED_EXTENSIONS
:
3179 Reference
< deployment::XPackage
> xScriptPackage
=
3180 implGetNextSharedScriptPackage( rbPureDialogLib
);
3181 if( !xScriptPackage
.is() )
3185 aRetLib
= xScriptPackage
->getURL();
3188 case BUNDLED_EXTENSIONS
:
3190 Reference
< deployment::XPackage
> xScriptPackage
=
3191 implGetNextBundledScriptPackage( rbPureDialogLib
);
3192 if( !xScriptPackage
.is() )
3196 aRetLib
= xScriptPackage
->getURL();
3202 ("ScriptExtensionIterator::nextBasicOrDialogLibrary():"
3203 " Invalid case END_REACHED"));
3211 ScriptSubPackageIterator::ScriptSubPackageIterator( Reference
< deployment::XPackage
> const & xMainPackage
)
3212 : m_xMainPackage( xMainPackage
)
3213 , m_bIsValid( false )
3214 , m_bIsBundle( false )
3215 , m_nSubPkgCount( 0 )
3216 , m_iNextSubPkg( 0 )
3218 if( !m_xMainPackage
.is() )
3222 // Check if parent package is registered
3223 beans::Optional
< beans::Ambiguous
<sal_Bool
> > option( m_xMainPackage
->isRegistered
3224 ( Reference
<task::XAbortChannel
>(), Reference
<ucb::XCommandEnvironment
>() ) );
3225 bool bRegistered
= false;
3226 if( option
.IsPresent
)
3228 beans::Ambiguous
<sal_Bool
> const & reg
= option
.Value
;
3229 if( !reg
.IsAmbiguous
&& reg
.Value
)
3237 if( m_xMainPackage
->isBundle() )
3240 m_aSubPkgSeq
= m_xMainPackage
->getBundle( Reference
<task::XAbortChannel
>(),
3241 Reference
<ucb::XCommandEnvironment
>() );
3242 m_nSubPkgCount
= m_aSubPkgSeq
.getLength();
3247 Reference
< deployment::XPackage
> ScriptSubPackageIterator::getNextScriptSubPackage( bool& rbPureDialogLib
)
3249 rbPureDialogLib
= false;
3251 Reference
< deployment::XPackage
> xScriptPackage
;
3254 return xScriptPackage
;
3258 const Reference
< deployment::XPackage
>* pSeq
= m_aSubPkgSeq
.getConstArray();
3260 for( iPkg
= m_iNextSubPkg
; iPkg
< m_nSubPkgCount
; ++iPkg
)
3262 const Reference
< deployment::XPackage
> xSubPkg
= pSeq
[ iPkg
];
3263 xScriptPackage
= implDetectScriptPackage( xSubPkg
, rbPureDialogLib
);
3264 if( xScriptPackage
.is() )
3269 m_iNextSubPkg
= iPkg
+ 1;
3273 xScriptPackage
= implDetectScriptPackage( m_xMainPackage
, rbPureDialogLib
);
3274 m_bIsValid
= false; // No more script packages
3277 return xScriptPackage
;
3280 Reference
< deployment::XPackage
> ScriptSubPackageIterator::implDetectScriptPackage ( const Reference
< deployment::XPackage
>& rPackage
,
3281 bool& rbPureDialogLib
)
3283 Reference
< deployment::XPackage
> xScriptPackage
;
3287 const Reference
< deployment::XPackageTypeInfo
> xPackageTypeInfo
= rPackage
->getPackageType();
3288 OUString aMediaType
= xPackageTypeInfo
->getMediaType();
3289 if ( aMediaType
== sBasicLibMediaType
)
3291 xScriptPackage
= rPackage
;
3293 else if ( aMediaType
== sDialogLibMediaType
)
3295 rbPureDialogLib
= true;
3296 xScriptPackage
= rPackage
;
3300 return xScriptPackage
;
3303 Reference
< deployment::XPackage
> ScriptExtensionIterator::implGetNextUserScriptPackage( bool& rbPureDialogLib
)
3305 Reference
< deployment::XPackage
> xScriptPackage
;
3307 if( !m_bUserPackagesLoaded
)
3311 Reference
< XExtensionManager
> xManager
= ExtensionManager::get( m_xContext
);
3312 m_aUserPackagesSeq
= xManager
->getDeployedExtensions("user",
3313 Reference
< task::XAbortChannel
>(),
3314 Reference
< ucb::XCommandEnvironment
>() );
3316 catch(const css::uno::DeploymentException
& )
3318 // Special Office installations may not contain deployment code
3319 m_eState
= END_REACHED
;
3320 return xScriptPackage
;
3323 m_bUserPackagesLoaded
= true;
3326 if( m_iUserPackage
== m_aUserPackagesSeq
.getLength() )
3328 m_eState
= SHARED_EXTENSIONS
; // Later: SHARED_MODULE
3332 if( m_pScriptSubPackageIterator
== nullptr )
3334 const Reference
< deployment::XPackage
>* pUserPackages
= m_aUserPackagesSeq
.getConstArray();
3335 Reference
< deployment::XPackage
> xPackage
= pUserPackages
[ m_iUserPackage
];
3337 !xPackage
.is(), "basic",
3338 ("ScriptExtensionIterator::implGetNextUserScriptPackage():"
3339 " Invalid package"));
3340 m_pScriptSubPackageIterator
= new ScriptSubPackageIterator( xPackage
);
3343 xScriptPackage
= m_pScriptSubPackageIterator
->getNextScriptSubPackage( rbPureDialogLib
);
3344 if( !xScriptPackage
.is() )
3346 delete m_pScriptSubPackageIterator
;
3347 m_pScriptSubPackageIterator
= nullptr;
3352 return xScriptPackage
;
3355 Reference
< deployment::XPackage
> ScriptExtensionIterator::implGetNextSharedScriptPackage( bool& rbPureDialogLib
)
3357 Reference
< deployment::XPackage
> xScriptPackage
;
3359 if( !m_bSharedPackagesLoaded
)
3363 Reference
< XExtensionManager
> xSharedManager
= ExtensionManager::get( m_xContext
);
3364 m_aSharedPackagesSeq
= xSharedManager
->getDeployedExtensions("shared",
3365 Reference
< task::XAbortChannel
>(),
3366 Reference
< ucb::XCommandEnvironment
>() );
3368 catch(const css::uno::DeploymentException
& )
3370 // Special Office installations may not contain deployment code
3371 return xScriptPackage
;
3374 m_bSharedPackagesLoaded
= true;
3377 if( m_iSharedPackage
== m_aSharedPackagesSeq
.getLength() )
3379 m_eState
= BUNDLED_EXTENSIONS
;
3383 if( m_pScriptSubPackageIterator
== nullptr )
3385 const Reference
< deployment::XPackage
>* pSharedPackages
= m_aSharedPackagesSeq
.getConstArray();
3386 Reference
< deployment::XPackage
> xPackage
= pSharedPackages
[ m_iSharedPackage
];
3388 !xPackage
.is(), "basic",
3389 ("ScriptExtensionIterator::implGetNextSharedScriptPackage():"
3390 " Invalid package"));
3391 m_pScriptSubPackageIterator
= new ScriptSubPackageIterator( xPackage
);
3394 xScriptPackage
= m_pScriptSubPackageIterator
->getNextScriptSubPackage( rbPureDialogLib
);
3395 if( !xScriptPackage
.is() )
3397 delete m_pScriptSubPackageIterator
;
3398 m_pScriptSubPackageIterator
= nullptr;
3403 return xScriptPackage
;
3406 Reference
< deployment::XPackage
> ScriptExtensionIterator::implGetNextBundledScriptPackage( bool& rbPureDialogLib
)
3408 Reference
< deployment::XPackage
> xScriptPackage
;
3410 if( !m_bBundledPackagesLoaded
)
3414 Reference
< XExtensionManager
> xManager
= ExtensionManager::get( m_xContext
);
3415 m_aBundledPackagesSeq
= xManager
->getDeployedExtensions("bundled",
3416 Reference
< task::XAbortChannel
>(),
3417 Reference
< ucb::XCommandEnvironment
>() );
3419 catch(const css::uno::DeploymentException
& )
3421 // Special Office installations may not contain deployment code
3422 return xScriptPackage
;
3425 m_bBundledPackagesLoaded
= true;
3428 if( m_iBundledPackage
== m_aBundledPackagesSeq
.getLength() )
3430 m_eState
= END_REACHED
;
3434 if( m_pScriptSubPackageIterator
== nullptr )
3436 const Reference
< deployment::XPackage
>* pBundledPackages
= m_aBundledPackagesSeq
.getConstArray();
3437 Reference
< deployment::XPackage
> xPackage
= pBundledPackages
[ m_iBundledPackage
];
3439 !xPackage
.is(), "basic",
3440 ("ScriptExtensionIterator::implGetNextBundledScriptPackage():"
3441 " Invalid package"));
3442 m_pScriptSubPackageIterator
= new ScriptSubPackageIterator( xPackage
);
3445 xScriptPackage
= m_pScriptSubPackageIterator
->getNextScriptSubPackage( rbPureDialogLib
);
3446 if( !xScriptPackage
.is() )
3448 delete m_pScriptSubPackageIterator
;
3449 m_pScriptSubPackageIterator
= nullptr;
3450 m_iBundledPackage
++;
3454 return xScriptPackage
;
3457 } // namespace basic
3459 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */