LibreOffice Module basic (master) 1
namecont.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <config_extensions.h>
21#include <config_folders.h>
22
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/NoSupportException.hpp>
29#include <com/sun/star/lang/XMultiServiceFactory.hpp>
30#include <com/sun/star/lang/XServiceInfo.hpp>
31#include <com/sun/star/ucb/ContentCreationException.hpp>
32#include <com/sun/star/xml/sax/SAXException.hpp>
33#include <utility>
34#include <vcl/svapp.hxx>
35#include <o3tl/string_view.hxx>
36#include <osl/mutex.hxx>
37#include <vcl/errinf.hxx>
38#include <rtl/ustring.hxx>
39#include <sal/log.hxx>
40#include <sot/storage.hxx>
44
45#include <namecont.hxx>
48#include <tools/urlobj.hxx>
50#include <svtools/sfxecode.hxx>
51#include <svtools/ehdl.hxx>
52#include <basic/basmgr.hxx>
53#include <com/sun/star/xml/sax/Parser.hpp>
54#include <com/sun/star/xml/sax/InputSource.hpp>
55#include <com/sun/star/io/XOutputStream.hpp>
56#include <com/sun/star/xml/sax/Writer.hpp>
57#include <com/sun/star/io/XInputStream.hpp>
58#include <com/sun/star/beans/XPropertySet.hpp>
59#include <com/sun/star/uno/DeploymentException.hpp>
60#include <com/sun/star/lang/DisposedException.hpp>
61#include <com/sun/star/script/LibraryNotLoadedException.hpp>
62#include <com/sun/star/script/vba/VBAScriptEventId.hpp>
63#include <com/sun/star/ucb/SimpleFileAccess.hpp>
64#include <com/sun/star/util/PathSubstitution.hpp>
65#include <com/sun/star/deployment/ExtensionManager.hpp>
71#include <memory>
72#include <string_view>
73
74namespace basic
75{
76
77using namespace com::sun::star::document;
78using namespace com::sun::star::container;
79using namespace com::sun::star::uno;
80using namespace com::sun::star::lang;
81using namespace com::sun::star::io;
82using namespace com::sun::star::ucb;
83using namespace com::sun::star::script;
84using namespace com::sun::star::beans;
85using namespace com::sun::star::xml::sax;
86using namespace com::sun::star::util;
87using namespace com::sun::star::task;
88using namespace com::sun::star::embed;
89using namespace com::sun::star::frame;
90using namespace com::sun::star::deployment;
91using namespace com::sun::star;
92using namespace cppu;
93using namespace osl;
94
96
97// #i34411: Flag for error handling during migration
98static bool GbMigrationSuppressErrors = false;
99
100
101// Implementation class NameContainer
102
103// Methods XElementAccess
105{
106 return mType;
107}
108
110{
111 bool bRet = (mnElementCount > 0);
112 return bRet;
113}
114
115// Methods XNameAccess
116Any NameContainer::getByName( const OUString& aName )
117{
118 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
119 if( aIt == mHashMap.end() )
120 {
121 throw NoSuchElementException();
122 }
123 sal_Int32 iHashResult = (*aIt).second;
124 Any aRetAny = mValues[ iHashResult ];
125 return aRetAny;
126}
127
129{
131}
132
133sal_Bool NameContainer::hasByName( const OUString& aName )
134{
135 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
136 bool bRet = ( aIt != mHashMap.end() );
137 return bRet;
138}
139
140
141// Methods XNameReplace
142void NameContainer::replaceByName( const OUString& aName, const Any& aElement )
143{
144 const Type& aAnyType = aElement.getValueType();
145 if( mType != aAnyType )
146 {
147 throw IllegalArgumentException("types do not match", getXWeak(), 2);
148 }
149 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
150 if( aIt == mHashMap.end() )
151 {
152 throw NoSuchElementException();
153 }
154 sal_Int32 iHashResult = (*aIt).second;
155 Any aOldElement = mValues[ iHashResult ];
156 mValues[ iHashResult ] = aElement;
157
158
159 // Fire event
161 {
162 ContainerEvent aEvent;
163 aEvent.Source = mpxEventSource;
164 aEvent.Accessor <<= aName;
165 aEvent.Element = aElement;
166 aEvent.ReplacedElement = aOldElement;
167 maContainerListeners.notifyEach( &XContainerListener::elementReplaced, aEvent );
168 }
169
170 /* After the container event has been fired (one listener will update the
171 core Basic manager), fire change event. Listeners can rely on that the
172 Basic source code of the core Basic manager is up-to-date. */
173 if( maChangesListeners.getLength() > 0 )
174 {
175 ChangesEvent aEvent;
176 aEvent.Source = mpxEventSource;
177 aEvent.Base <<= aEvent.Source;
178 aEvent.Changes = { { Any(aName), aElement, aOldElement } };
179 maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
180 }
181}
182
183void NameContainer::insertCheck(const OUString& aName, const Any& aElement)
184{
185 NameContainerNameMap::iterator aIt = mHashMap.find(aName);
186 if( aIt != mHashMap.end() )
187 {
188 throw ElementExistException();
189 }
190 insertNoCheck(aName, aElement);
191}
192
193void NameContainer::insertNoCheck(const OUString& aName, const Any& aElement)
194{
195 const Type& aAnyType = aElement.getValueType();
196 if( mType != aAnyType )
197 {
198 throw IllegalArgumentException("types do not match", getXWeak(), 2);
199 }
200
201 sal_Int32 nCount = mNames.size();
202 mNames.push_back( aName );
203 mValues.push_back( aElement );
204
205 mHashMap[ aName ] = nCount;
207
208 // Fire event
210 {
211 ContainerEvent aEvent;
212 aEvent.Source = mpxEventSource;
213 aEvent.Accessor <<= aName;
214 aEvent.Element = aElement;
215 maContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
216 }
217
218 /* After the container event has been fired (one listener will update the
219 core Basic manager), fire change event. Listeners can rely on that the
220 Basic source code of the core Basic manager is up-to-date. */
221 if( maChangesListeners.getLength() > 0 )
222 {
223 ChangesEvent aEvent;
224 aEvent.Source = mpxEventSource;
225 aEvent.Base <<= aEvent.Source;
226 aEvent.Changes = { { Any(aName), aElement, {} } };
227 maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
228 }
229}
230
231// Methods XNameContainer
232void NameContainer::insertByName( const OUString& aName, const Any& aElement )
233{
234 insertCheck(aName, aElement);
235}
236
237void NameContainer::removeByName( const OUString& aName )
238{
239 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
240 if( aIt == mHashMap.end() )
241 {
242 OUString sMessage = "\"" + aName + "\" not found";
243 throw NoSuchElementException(sMessage);
244 }
245
246 sal_Int32 iHashResult = (*aIt).second;
247 Any aOldElement = mValues[ iHashResult ];
248 mHashMap.erase( aIt );
249 sal_Int32 iLast = mNames.size() - 1;
250 if( iLast != iHashResult )
251 {
252 mNames[ iHashResult ] = mNames[ iLast ];
253 mValues[ iHashResult ] = mValues[ iLast ];
254 mHashMap[ mNames[ iHashResult ] ] = iHashResult;
255 }
256 mNames.resize( iLast );
257 mValues.resize( iLast );
259
260 // Fire event
262 {
263 ContainerEvent aEvent;
264 aEvent.Source = mpxEventSource;
265 aEvent.Accessor <<= aName;
266 aEvent.Element = aOldElement;
267 maContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvent );
268 }
269
270 /* After the container event has been fired (one listener will update the
271 core Basic manager), fire change event. Listeners can rely on that the
272 Basic source code of the core Basic manager is up-to-date. */
273 if( maChangesListeners.getLength() > 0 )
274 {
275 ChangesEvent aEvent;
276 aEvent.Source = mpxEventSource;
277 aEvent.Base <<= aEvent.Source;
278 aEvent.Changes = { { Any(aName),
279 {}, // Element remains empty (meaning "replaced with nothing")
280 aOldElement } };
281 maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
282 }
283}
284
285
286// Methods XContainer
288{
289 if( !xListener.is() )
290 {
291 throw RuntimeException("addContainerListener called with null xListener",getXWeak());
292 }
294}
295
297{
298 if( !xListener.is() )
299 {
300 throw RuntimeException("removeContainerListener called with null xListener",getXWeak());
301 }
303}
304
305// Methods XChangesNotifier
307{
308 if( !xListener.is() )
309 {
310 throw RuntimeException("addChangesListener called with null xListener",getXWeak());
311 }
312 maChangesListeners.addInterface( xListener );
313}
314
316{
317 if( !xListener.is() )
318 {
319 throw RuntimeException("removeChangesListener called with null xListener",getXWeak());
320 }
322}
323
324
325// ModifiableHelper
326
327void ModifiableHelper::setModified( bool _bModified )
328{
329 if ( _bModified == mbModified )
330 {
331 return;
332 }
333 mbModified = _bModified;
334
335 if ( m_aModifyListeners.getLength() == 0 )
336 {
337 return;
338 }
339 EventObject aModifyEvent( m_rEventSource );
340 m_aModifyListeners.notifyEach( &XModifyListener::modified, aModifyEvent );
341}
342
343
344// Ctor
347 , maVBAScriptListeners( m_aMutex )
348 , mnRunningVBAScripts( 0 )
349 , mbVBACompat( false )
350 , meVBATextEncoding( RTL_TEXTENCODING_DONTKNOW )
351 , maModifiable( *this, m_aMutex )
352 , maNameContainer( new NameContainer(cppu::UnoType<XNameAccess>::get()) )
353 , mbOldInfoFormat( false )
354 , mbOasis2OOoFormat( false )
355 , mpBasMgr( nullptr )
356 , mbOwnBasMgr( false )
357 , meInitMode(DEFAULT)
358{
360
361 mxSFI = ucb::SimpleFileAccess::create( mxContext );
362
363 mxStringSubstitution = util::PathSubstitution::create( mxContext );
364}
365
367{
368 if( mbOwnBasMgr )
369 {
370 delete mpBasMgr;
371 }
372}
373
375{
377 if ( rBHelper.bInDispose || rBHelper.bDisposed )
378 {
379 throw DisposedException( OUString(), *this );
380 }
381}
382
384{
386}
387
389{
390 try
391 {
392 if ( mpBasMgr )
393 {
394 return mpBasMgr;
395 }
396 Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
398 !xDocument.is(), "basic",
399 ("SfxLibraryContainer::getBasicManager: cannot obtain a BasicManager"
400 " without document!"));
401 if ( xDocument.is() )
402 {
404 }
405 }
406 catch (const css::ucb::ContentCreationException&)
407 {
408 TOOLS_WARN_EXCEPTION( "basic", "SfxLibraryContainer::getBasicManager:" );
409 }
410 return mpBasMgr;
411}
412
413// Methods XStorageBasedLibraryContainer
415{
416 LibraryContainerMethodGuard aGuard( *this );
417 return mxStorage;
418}
419
420void SAL_CALL SfxLibraryContainer::setRootStorage( const Reference< XStorage >& _rxRootStorage )
421{
422 LibraryContainerMethodGuard aGuard( *this );
423 if ( !_rxRootStorage.is() )
424 {
425 throw IllegalArgumentException("no root storage", getXWeak(), 1);
426 }
427 mxStorage = _rxRootStorage;
429}
430
432{
433 LibraryContainerMethodGuard aGuard( *this );
434 if ( !_rxRootStorage.is() )
435 {
436 throw IllegalArgumentException("no root storage", getXWeak(), 1);
437 }
438 try
439 {
440 storeLibraries_Impl( _rxRootStorage, true );
441 }
442 catch( const Exception& )
443 {
444 throw WrappedTargetException( OUString(),
445 *this, ::cppu::getCaughtException() );
446 }
447}
448
449
450// Methods XModifiable
452{
453 LibraryContainerMethodGuard aGuard( *this );
454 if ( maModifiable.isModified() )
455 {
456 return true;
457 }
458 // the library container is not modified, go through the libraries and check whether they are modified
459 Sequence< OUString > aNames = maNameContainer->getElementNames();
460 const OUString* pNames = aNames.getConstArray();
461 sal_Int32 nNameCount = aNames.getLength();
462
463 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
464 {
465 OUString aName = pNames[ i ];
466 try
467 {
468 SfxLibrary* pImplLib = getImplLib( aName );
469 if( pImplLib->isModified() )
470 {
471 if ( aName == "Standard" )
472 {
473 // this is a workaround that has to be implemented because
474 // empty standard library should stay marked as modified
475 // but should not be treated as modified while it is empty
476 if ( pImplLib->hasElements() )
477 return true;
478 }
479 else
480 {
481 return true;
482 }
483 }
484 }
485 catch(const css::container::NoSuchElementException&)
486 {
487 }
488 }
489
490 return false;
491}
492
494{
495 LibraryContainerMethodGuard aGuard( *this );
496 maModifiable.setModified( _bModified );
497}
498
500{
501 LibraryContainerMethodGuard aGuard( *this );
502 maModifiable.addModifyListener( _rxListener );
503}
504
506{
507 LibraryContainerMethodGuard aGuard( *this );
508 maModifiable.removeModifyListener( _rxListener );
509}
510
511// Methods XPersistentLibraryContainer
513{
514 LibraryContainerMethodGuard aGuard( *this );
515 return Any( getRootStorage() );
516}
517
519{
520 LibraryContainerMethodGuard aGuard( *this );
521 return maLibrariesDir;
522}
523
525{
526 LibraryContainerMethodGuard aGuard( *this );
527 try
528 {
530 // we need to store *all* libraries if and only if we are based on a storage:
531 // in this case, storeLibraries_Impl will remove the source storage, after loading
532 // all libraries, so we need to force them to be stored, again
533 }
534 catch( const Exception& )
535 {
536 throw WrappedTargetException( OUString(), *this, ::cppu::getCaughtException() );
537 }
538}
539
540static void checkAndCopyFileImpl( const INetURLObject& rSourceFolderInetObj,
541 const INetURLObject& rTargetFolderInetObj,
542 std::u16string_view rCheckFileName,
543 std::u16string_view rCheckExtension,
545{
546 INetURLObject aTargetFolderInetObj( rTargetFolderInetObj );
547 aTargetFolderInetObj.insertName( rCheckFileName, true, INetURLObject::LAST_SEGMENT,
549 aTargetFolderInetObj.setExtension( rCheckExtension );
550 OUString aTargetFile = aTargetFolderInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
551 if( !xSFI->exists( aTargetFile ) )
552 {
553 INetURLObject aSourceFolderInetObj( rSourceFolderInetObj );
554 aSourceFolderInetObj.insertName( rCheckFileName, true, INetURLObject::LAST_SEGMENT,
556 aSourceFolderInetObj.setExtension( rCheckExtension );
557 OUString aSourceFile = aSourceFolderInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
558 xSFI->copy( aSourceFile, aTargetFile );
559 }
560}
561
562static void createVariableURL( OUString& rStr, std::u16string_view rLibName,
563 std::u16string_view rInfoFileName, bool bUser )
564{
565 if( bUser )
566 {
567 rStr = "$(USER)/basic/";
568 }
569 else
570 {
571 rStr = "$(INST)/" LIBO_SHARE_FOLDER "/basic/";
572 }
573 rStr += OUString::Concat(rLibName) + "/" + rInfoFileName + ".xlb/";
574}
575
576void SfxLibraryContainer::init( const OUString& rInitialDocumentURL, const uno::Reference< embed::XStorage >& rxInitialStorage )
577{
578 // this might be called from within the ctor, and the impl_init might (indirectly) create
579 // a UNO reference to ourself.
580 // Ensure that we're not destroyed while we're in here
581 osl_atomic_increment( &m_refCount );
582 init_Impl( rInitialDocumentURL, rxInitialStorage );
583 osl_atomic_decrement( &m_refCount );
584}
585
586void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL,
587 const uno::Reference< embed::XStorage >& rxInitialStorage )
588{
589 uno::Reference< embed::XStorage > xStorage = rxInitialStorage;
590
591 maInitialDocumentURL = rInitialDocumentURL;
596
598 INetURLObject aInitUrlInetObj( maInitialDocumentURL );
599 OUString aInitFileName = aInitUrlInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
600 if( !aInitFileName.isEmpty() )
601 {
602 // We need a BasicManager to avoid problems
603 StarBASIC* pBas = new StarBASIC();
604 mpBasMgr = new BasicManager( pBas );
605 mbOwnBasMgr = true;
606
607 OUString aExtension = aInitUrlInetObj.getExtension();
608 if( aExtension == "xlc" )
609 {
611 INetURLObject aLibPathInetObj( aInitUrlInetObj );
612 aLibPathInetObj.removeSegment();
614 }
615 else if( aExtension == "xlb" )
616 {
620 implLoadLibraryIndexFile( nullptr, aLibDesc, xDummyStor, aInitFileName );
621 return;
622 }
623 else
624 {
625 // Decide between old and new document
626 bool bOldStorage = SotStorage::IsOLEStorage( aInitFileName );
627 if ( bOldStorage )
628 {
630 importFromOldStorage( aInitFileName );
631 return;
632 }
633 else
634 {
636 try
637 {
639 }
640 catch (const uno::Exception& )
641 {
642 // TODO: error handling
643 }
644 }
645 }
646 }
647 else
648 {
649 // Default paths
651 }
652
654
655 mxStorage = xStorage;
656 bool bStorage = mxStorage.is();
657
658
659 // #110009: Scope to force the StorageRefs to be destructed and
660 // so the streams to be closed before the preload operation
661 {
662
664 OUString aFileName;
665
666 int nPassCount = 1;
667 if( !bStorage && meInitMode == DEFAULT )
668 {
669 nPassCount = 2;
670 }
671 for( int nPass = 0 ; nPass < nPassCount ; nPass++ )
672 {
673 if( bStorage )
674 {
677 "Wrong InitMode for document");
678 try
679 {
681 xLibrariesStor = xStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
682
683 if ( xLibrariesStor.is() )
684 {
685 aFileName = maInfoFileName + "-lc.xml";
686 try
687 {
688 xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
689 }
690 catch(const uno::Exception& )
691 {}
692
693 if( !xStream.is() )
694 {
695 mbOldInfoFormat = true;
696
697 // Check old version
698 aFileName = maOldInfoFileName + ".xml";
699 try
700 {
701 xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
702 }
703 catch(const uno::Exception& )
704 {}
705
706 if( !xStream.is() )
707 {
708 // Check for EA2 document version with wrong extensions
709 aFileName = maOldInfoFileName + ".xli";
710 xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
711 }
712 }
713 }
714
715 if ( xStream.is() )
716 {
717 xInput = xStream->getInputStream();
718 }
719 }
720 catch(const uno::Exception& )
721 {
722 // TODO: error handling?
723 }
724 }
725 else
726 {
727 std::unique_ptr<INetURLObject> pLibInfoInetObj;
729 {
730 aFileName = aInitFileName;
731 }
732 else
733 {
734 if( nPass == 1 )
735 {
736 pLibInfoInetObj.reset(new INetURLObject( o3tl::getToken(maLibraryPath, 0, ';') ));
737 }
738 else
739 {
740 pLibInfoInetObj.reset(new INetURLObject( o3tl::getToken(maLibraryPath, 1, ';') ));
741 }
743 pLibInfoInetObj->setExtension( u"xlc" );
744 aFileName = pLibInfoInetObj->GetMainURL( INetURLObject::DecodeMechanism::NONE );
745 }
746
747 try
748 {
749 xInput = mxSFI->openFileRead( aFileName );
750 }
751 catch(const Exception& )
752 {
753 // Silently tolerate empty or missing files
754 xInput.clear();
755 }
756
757 // Old variant?
758 if( !xInput.is() && nPass == 0 )
759 {
760 INetURLObject aLibInfoInetObj( o3tl::getToken(maLibraryPath, 1, ';') );
762 aLibInfoInetObj.setExtension( u"xli" );
763 aFileName = aLibInfoInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
764
765 try
766 {
767 xInput = mxSFI->openFileRead( aFileName );
768 mbOldInfoFormat = true;
769 }
770 catch(const Exception& )
771 {
772 xInput.clear();
773 }
774 }
775 }
776
777 if( xInput.is() )
778 {
779 InputSource source;
780 source.aInputStream = xInput;
781 source.sSystemId = aFileName;
782
783 // start parsing
784 auto pLibArray = std::make_unique<::xmlscript::LibDescriptorArray> ( );
785
786 Reference< XParser > xParser = xml::sax::Parser::create(mxContext);
787 try
788 {
789 xParser->setDocumentHandler( ::xmlscript::importLibraryContainer( pLibArray.get() ) );
790 xParser->parseStream( source );
791 }
792 catch ( const xml::sax::SAXException& )
793 {
794 TOOLS_WARN_EXCEPTION( "basic", "" );
795 return;
796 }
797 catch ( const io::IOException& )
798 {
799 TOOLS_WARN_EXCEPTION( "basic", "" );
800 return;
801 }
802
803 sal_Int32 nLibCount = pLibArray->mnLibCount;
804 for( sal_Int32 i = 0 ; i < nLibCount ; i++ )
805 {
806 ::xmlscript::LibDescriptor& rLib = pLibArray->mpLibs[i];
807
808 // Check storage URL
809 OUString aStorageURL = rLib.aStorageURL;
810 if( !bStorage && aStorageURL.isEmpty() && nPass == 0 )
811 {
812 OUString aLibraryPath;
814 {
815 aLibraryPath = maLibraryPath;
816 }
817 else
818 {
819 aLibraryPath = maLibraryPath.getToken(1, ';');
820 }
821 INetURLObject aInetObj( aLibraryPath );
822
823 aInetObj.insertName( rLib.aName, true, INetURLObject::LAST_SEGMENT,
825 OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
826 if( mxSFI->isFolder( aLibDirPath ) )
827 {
830 }
831 else if( rLib.bLink )
832 {
833 // Check "share" path
834 INetURLObject aShareInetObj( o3tl::getToken(maLibraryPath, 0, ';') );
835 aShareInetObj.insertName( rLib.aName, true, INetURLObject::LAST_SEGMENT,
837 OUString aShareLibDirPath = aShareInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
838 if( mxSFI->isFolder( aShareLibDirPath ) )
839 {
842 }
843 else
844 {
845 // #i25537: Ignore lib if library folder does not really exist
846 continue;
847 }
848 }
849 }
850
851 OUString aLibName = rLib.aName;
852
853 // If the same library name is used by the shared and the
854 // user lib container index files the user file wins
855 if( nPass == 1 && hasByName( aLibName ) )
856 {
857 continue;
858 }
859 SfxLibrary* pImplLib;
860 if( rLib.bLink )
861 {
863 createLibraryLink( aLibName, rLib.aStorageURL, rLib.bReadOnly );
864 pImplLib = static_cast< SfxLibrary* >( xLib.get() );
865 }
866 else
867 {
869 pImplLib = static_cast< SfxLibrary* >( xLib.get() );
870 pImplLib->mbLoaded = false;
871 pImplLib->mbReadOnly = rLib.bReadOnly;
872 if( !bStorage )
873 {
875 pImplLib->maStorageURL, pImplLib->maUnexpandedStorageURL );
876 }
877 }
878 maModifiable.setModified( false );
879
880 // Read library info files
881 if( !mbOldInfoFormat )
882 {
884 if( !pImplLib->mbInitialised && bStorage )
885 {
886 try
887 {
888 xLibraryStor = xLibrariesStor->openStorageElement( rLib.aName,
890 }
891 catch(const uno::Exception& )
892 {
893 #if OSL_DEBUG_LEVEL > 0
895 "basic",
896 "couldn't open sub storage for library \"" << rLib.aName << "\"");
897 #endif
898 }
899 }
900
901 // Link is already initialised in createLibraryLink()
902 if( !pImplLib->mbInitialised && (!bStorage || xLibraryStor.is()) )
903 {
904 bool bLoaded = implLoadLibraryIndexFile( pImplLib, rLib, xLibraryStor, OUString() );
906 bLoaded && aLibName != rLib.aName, "basic",
907 ("Different library names in library container and"
908 " library info files!"));
909 if( GbMigrationSuppressErrors && !bLoaded )
910 {
911 removeLibrary( aLibName );
912 }
913 }
914 }
915 else if( !bStorage )
916 {
917 // Write new index file immediately because otherwise
918 // the library elements will be lost when storing into
919 // the new info format
921 implStoreLibraryIndexFile( pImplLib, rLib, xTmpStorage );
922 }
923
924 implImportLibDescriptor( pImplLib, rLib );
925
926 if( nPass == 1 )
927 {
928 pImplLib->mbSharedIndexFile = true;
929 pImplLib->mbReadOnly = true;
930 }
931 }
932
933 // Keep flag for documents to force writing the new index files
934 if( !bStorage )
935 {
936 mbOldInfoFormat = false;
937 }
938 }
939 }
940
941 // #110009: END Scope to force the StorageRefs to be destructed
942 }
943
944 if( !bStorage && meInitMode == DEFAULT )
945 {
946 try
947 {
949 }
950 catch(const uno::Exception& )
951 {
952 // TODO: error handling?
953 SAL_WARN("basic", "Cannot access extensions!");
954 }
955 }
956
957 // Preload?
958 {
959 Sequence< OUString > aNames = maNameContainer->getElementNames();
960 const OUString* pNames = aNames.getConstArray();
961 sal_Int32 nNameCount = aNames.getLength();
962 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
963 {
964 OUString aName = pNames[ i ];
965 SfxLibrary* pImplLib = getImplLib( aName );
966 if( pImplLib->mbPreload )
967 {
969 }
970 }
971 }
972
973 if( meInitMode != DEFAULT )
974 return;
975
976 // tdf#121740 speed up loading documents with lots of embedded documents by avoid the UCB work of updating non-existent VBA libraries
977 if (rInitialDocumentURL.isEmpty())
978 return;
979
980 INetURLObject aUserBasicInetObj( o3tl::getToken(maLibraryPath, 1, ';') );
981 OUString aStandardStr("Standard");
982
983 INetURLObject aPrevUserBasicInetObj_1( aUserBasicInetObj );
984 aPrevUserBasicInetObj_1.removeSegment();
985 INetURLObject aPrevUserBasicInetObj_2 = aPrevUserBasicInetObj_1;
986 aPrevUserBasicInetObj_1.Append( u"__basic_80" );
987 aPrevUserBasicInetObj_2.Append( u"__basic_80_2" );
988
989 // #i93163
990 bool bCleanUp = false;
991 try
992 {
993 INetURLObject aPrevUserBasicInetObj = aPrevUserBasicInetObj_1;
994 OUString aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
995 if( mxSFI->isFolder( aPrevFolder ) )
996 {
997 // Check if Standard folder exists and is complete
998 INetURLObject aUserBasicStandardInetObj( aUserBasicInetObj );
999 aUserBasicStandardInetObj.insertName( aStandardStr, true, INetURLObject::LAST_SEGMENT,
1001 INetURLObject aPrevUserBasicStandardInetObj( aPrevUserBasicInetObj );
1002 aPrevUserBasicStandardInetObj.insertName( aStandardStr, true, INetURLObject::LAST_SEGMENT,
1004 OUString aPrevStandardFolder = aPrevUserBasicStandardInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1005 if( mxSFI->isFolder( aPrevStandardFolder ) )
1006 {
1007 OUString aXlbExtension( "xlb" );
1008 OUString aCheckFileName;
1009
1010 // Check if script.xlb exists
1011 aCheckFileName = "script";
1012 checkAndCopyFileImpl( aUserBasicStandardInetObj,
1013 aPrevUserBasicStandardInetObj,
1014 aCheckFileName, aXlbExtension, mxSFI );
1015
1016 // Check if dialog.xlb exists
1017 aCheckFileName = "dialog";
1018 checkAndCopyFileImpl( aUserBasicStandardInetObj,
1019 aPrevUserBasicStandardInetObj,
1020 aCheckFileName, aXlbExtension, mxSFI );
1021
1022 // Check if module1.xba exists
1023 aCheckFileName = "Module1";
1024 checkAndCopyFileImpl( aUserBasicStandardInetObj,
1025 aPrevUserBasicStandardInetObj,
1026 aCheckFileName, u"xba", mxSFI );
1027 }
1028 else
1029 {
1030 OUString aStandardFolder = aUserBasicStandardInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1031 mxSFI->copy( aStandardFolder, aPrevStandardFolder );
1032 }
1033
1034 OUString aPrevCopyToFolder = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1035 mxSFI->copy( aPrevFolder, aPrevCopyToFolder );
1036 }
1037 else
1038 {
1039 aPrevUserBasicInetObj = aPrevUserBasicInetObj_2;
1040 aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1041 }
1042 if( mxSFI->isFolder( aPrevFolder ) )
1043 {
1045
1046 // Rename previous basic folder to make storage URLs correct during initialisation
1047 OUString aFolderUserBasic = aUserBasicInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1048 INetURLObject aUserBasicTmpInetObj( aUserBasicInetObj );
1049 aUserBasicTmpInetObj.removeSegment();
1050 aUserBasicTmpInetObj.Append( u"__basic_tmp" );
1051 OUString aFolderTmp = aUserBasicTmpInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1052
1053 mxSFI->move( aFolderUserBasic, aFolderTmp );
1054 try
1055 {
1056 mxSFI->move( aPrevFolder, aFolderUserBasic );
1057 }
1058 catch(const Exception& )
1059 {
1060 // Move back user/basic folder
1061 try
1062 {
1063 mxSFI->kill( aFolderUserBasic );
1064 }
1065 catch(const Exception& )
1066 {}
1067 mxSFI->move( aFolderTmp, aFolderUserBasic );
1068 throw;
1069 }
1070
1071 INetURLObject aPrevUserBasicLibInfoInetObj( aUserBasicInetObj );
1072 aPrevUserBasicLibInfoInetObj.insertName( maInfoFileName, false, INetURLObject::LAST_SEGMENT,
1074 aPrevUserBasicLibInfoInetObj.setExtension( u"xlc");
1075 OUString aLibInfoFileName = aPrevUserBasicLibInfoInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1076 Sequence<Any> aInitSeq( 1 );
1077 aInitSeq.getArray()[0] <<= aLibInfoFileName;
1079 pPrevCont->initialize( aInitSeq );
1081
1082 // Rename folders back
1083 mxSFI->move( aFolderUserBasic, aPrevFolder );
1084 mxSFI->move( aFolderTmp, aFolderUserBasic );
1085
1086 Sequence< OUString > aNames = pPrevCont->getElementNames();
1087 const OUString* pNames = aNames.getConstArray();
1088 sal_Int32 nNameCount = aNames.getLength();
1089
1090 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1091 {
1092 OUString aLibName = pNames[ i ];
1093 if( hasByName( aLibName ) )
1094 {
1095 if( aLibName == aStandardStr )
1096 {
1097 SfxLibrary* pImplLib = getImplLib( aStandardStr );
1098 OUString aStandardFolder = pImplLib->maStorageURL;
1099 mxSFI->kill( aStandardFolder );
1100 }
1101 else
1102 {
1103 continue;
1104 }
1105 }
1106
1107 SfxLibrary* pImplLib = pPrevCont->getImplLib( aLibName );
1108 if( pImplLib->mbLink )
1109 {
1110 OUString aStorageURL = pImplLib->maUnexpandedStorageURL;
1111 bool bCreateLink = true;
1112 if( aStorageURL.indexOf( "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE" ) != -1 ||
1113 aStorageURL.indexOf( "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE" ) != -1 ||
1114 aStorageURL.indexOf( "vnd.sun.star.expand:$BUNDLED_EXTENSIONS" ) != -1 ||
1115 aStorageURL.indexOf( "$(INST)" ) != -1 )
1116 {
1117 bCreateLink = false;
1118 }
1119 if( bCreateLink )
1120 {
1121 createLibraryLink( aLibName, pImplLib->maStorageURL, pImplLib->mbReadOnly );
1122 }
1123 }
1124 else
1125 {
1126 // Move folder if not already done
1127 INetURLObject aUserBasicLibFolderInetObj( aUserBasicInetObj );
1128 aUserBasicLibFolderInetObj.Append( aLibName );
1129 OUString aLibFolder = aUserBasicLibFolderInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1130
1131 INetURLObject aPrevUserBasicLibFolderInetObj( aPrevUserBasicInetObj );
1132 aPrevUserBasicLibFolderInetObj.Append( aLibName );
1133 OUString aPrevLibFolder = aPrevUserBasicLibFolderInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1134
1135 if( mxSFI->isFolder( aPrevLibFolder ) && !mxSFI->isFolder( aLibFolder ) )
1136 {
1137 mxSFI->move( aPrevLibFolder, aLibFolder );
1138 }
1139
1140 if( aLibName == aStandardStr )
1141 {
1142 maNameContainer->removeByName( aLibName );
1143 }
1144
1145 // Create library
1146 Reference< XNameContainer > xLib = createLibrary( aLibName );
1147 SfxLibrary* pNewLib = static_cast< SfxLibrary* >( xLib.get() );
1148 pNewLib->mbLoaded = false;
1149 pNewLib->implSetModified( false );
1150 checkStorageURL( aLibFolder, pNewLib->maLibInfoFileURL,
1151 pNewLib->maStorageURL, pNewLib->maUnexpandedStorageURL );
1152
1155 implLoadLibraryIndexFile( pNewLib, aLibDesc, xDummyStor, pNewLib->maLibInfoFileURL );
1156 implImportLibDescriptor( pNewLib, aLibDesc );
1157 }
1158 }
1159 mxSFI->kill( aPrevFolder );
1160 }
1161 }
1162 catch(const Exception&)
1163 {
1164 TOOLS_WARN_EXCEPTION("basic", "Upgrade of Basic installation failed somehow" );
1165 bCleanUp = true;
1166 }
1167
1168 // #i93163
1169 if( !bCleanUp )
1170 return;
1171
1172 INetURLObject aPrevUserBasicInetObj_Err( aUserBasicInetObj );
1173 aPrevUserBasicInetObj_Err.removeSegment();
1174 aPrevUserBasicInetObj_Err.Append( u"__basic_80_err" );
1175 OUString aPrevFolder_Err = aPrevUserBasicInetObj_Err.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1176
1177 bool bSaved = false;
1178 try
1179 {
1180 OUString aPrevFolder_1 = aPrevUserBasicInetObj_1.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1181 if( mxSFI->isFolder( aPrevFolder_1 ) )
1182 {
1183 mxSFI->move( aPrevFolder_1, aPrevFolder_Err );
1184 bSaved = true;
1185 }
1186 }
1187 catch(const Exception& )
1188 {}
1189 try
1190 {
1191 OUString aPrevFolder_2 = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1192 if( !bSaved && mxSFI->isFolder( aPrevFolder_2 ) )
1193 {
1194 mxSFI->move( aPrevFolder_2, aPrevFolder_Err );
1195 }
1196 else
1197 {
1198 mxSFI->kill( aPrevFolder_2 );
1199 }
1200 }
1201 catch(const Exception& )
1202 {}
1203}
1204
1206{
1207#if HAVE_FEATURE_EXTENSIONS
1208 ScriptExtensionIterator aScriptIt;
1209
1210 bool bPureDialogLib = false;
1211 for (;;)
1212 {
1213 OUString aLibURL = aScriptIt.nextBasicOrDialogLibrary( bPureDialogLib );
1214 if (aLibURL.isEmpty())
1215 break;
1216 if( bPureDialogLib && maInfoFileName == "script" )
1217 {
1218 continue;
1219 }
1220 // Extract lib name
1221 sal_Int32 nLen = aLibURL.getLength();
1222 sal_Int32 indexLastSlash = aLibURL.lastIndexOf( '/' );
1223 sal_Int32 nReduceCopy = 0;
1224 if( indexLastSlash == nLen - 1 )
1225 {
1226 nReduceCopy = 1;
1227 indexLastSlash = aLibURL.lastIndexOf( '/', nLen - 1 );
1228 }
1229
1230 OUString aLibName = aLibURL.copy( indexLastSlash + 1, nLen - indexLastSlash - nReduceCopy - 1 );
1231
1232 // If a library of the same exists the existing library wins
1233 if( hasByName( aLibName ) )
1234 {
1235 continue;
1236 }
1237 // Add index file to URL
1238 OUString aIndexFileURL = aLibURL;
1239 if( nReduceCopy == 0 )
1240 {
1241 aIndexFileURL += "/";
1242 }
1243 aIndexFileURL += maInfoFileName + ".xlb";
1244
1245 // Create link
1246 const bool bReadOnly = false;
1247 createLibraryLink( aLibName, aIndexFileURL, bReadOnly );
1248 }
1249#else
1250 (void) this;
1251#endif
1252}
1253
1254// Handle maLibInfoFileURL and maStorageURL correctly
1255void SfxLibraryContainer::checkStorageURL( const OUString& aSourceURL,
1256 OUString& aLibInfoFileURL, OUString& aStorageURL,
1257 OUString& aUnexpandedStorageURL )
1258{
1259 OUString aExpandedSourceURL = expand_url( aSourceURL );
1260 if( aExpandedSourceURL != aSourceURL )
1261 {
1262 aUnexpandedStorageURL = aSourceURL;
1263 }
1264 INetURLObject aInetObj( aExpandedSourceURL );
1265 OUString aExtension = aInetObj.getExtension();
1266 if( aExtension == "xlb" )
1267 {
1268 // URL to xlb file
1269 aLibInfoFileURL = aExpandedSourceURL;
1270 aInetObj.removeSegment();
1271 aStorageURL = aInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1272 }
1273 else
1274 {
1275 // URL to library folder
1276 aStorageURL = aExpandedSourceURL;
1278 aInetObj.setExtension( u"xlb" );
1279 aLibInfoFileURL = aInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1280 }
1281}
1282
1283SfxLibrary* SfxLibraryContainer::getImplLib( const OUString& rLibraryName )
1284{
1285 Any aLibAny = maNameContainer->getByName( rLibraryName ) ;
1286 Reference< XNameAccess > xNameAccess;
1287 aLibAny >>= xNameAccess;
1288 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
1289 return pImplLib;
1290}
1291
1292
1293// Storing with password encryption
1294
1295// Empty implementation, avoids unnecessary implementation in dlgcont.cxx
1297 const OUString&,
1300{
1301 return false;
1302}
1303
1305 SfxLibrary* /*pLib*/,
1306 const OUString& /*aName*/,
1307 const css::uno::Reference< css::embed::XStorage >& /*xStorage*/,
1308 const OUString& /*aTargetURL*/,
1309 const Reference< XSimpleFileAccess3 >& /*xToUseSFI*/,
1310 const uno::Reference< task::XInteractionHandler >& )
1311{
1312 return false;
1313}
1314
1316 SfxLibrary* /*pLib*/,
1317 const OUString& /*Name*/,
1318 bool /*bVerifyPasswordOnly*/ )
1319{
1320 return true;
1321}
1322
1323OUString SfxLibraryContainer::createAppLibraryFolder( SfxLibrary* pLib, std::u16string_view aName )
1324{
1325 OUString aLibDirPath = pLib->maStorageURL;
1326 if( aLibDirPath.isEmpty() )
1327 {
1328 INetURLObject aInetObj( o3tl::getToken(maLibraryPath, 1, ';') );
1331 pLib->maStorageURL, pLib->maUnexpandedStorageURL );
1332 aLibDirPath = pLib->maStorageURL;
1333 }
1334
1335 if( !mxSFI->isFolder( aLibDirPath ) )
1336 {
1337 try
1338 {
1339 mxSFI->createFolder( aLibDirPath );
1340 }
1341 catch(const Exception& )
1342 {}
1343 }
1344
1345 return aLibDirPath;
1346}
1347
1348// Storing
1350 std::u16string_view aName,
1351 const uno::Reference< embed::XStorage >& xStorage )
1352{
1355 implStoreLibrary( pLib, aName, xStorage, u"", xDummySFA, xDummyHandler );
1356}
1357
1358// New variant for library export
1359void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
1360 std::u16string_view aName,
1361 const uno::Reference< embed::XStorage >& xStorage,
1362 std::u16string_view aTargetURL,
1363 const Reference< XSimpleFileAccess3 >& rToUseSFI,
1364 const Reference< XInteractionHandler >& xHandler )
1365{
1366 bool bLink = pLib->mbLink;
1367 bool bStorage = xStorage.is() && !bLink;
1368
1369 Sequence< OUString > aElementNames = pLib->getElementNames();
1370 sal_Int32 nNameCount = aElementNames.getLength();
1371 const OUString* pNames = aElementNames.getConstArray();
1372
1373 if( bStorage )
1374 {
1375 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1376 {
1377 OUString aElementName = pNames[ i ];
1378 OUString aStreamName = aElementName + ".xml";
1379
1380 if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
1381 {
1382 SAL_WARN(
1383 "basic",
1384 "invalid library element \"" << aElementName << '"');
1385 continue;
1386 }
1387 try
1388 {
1389 uno::Reference< io::XStream > xElementStream = xStorage->openStreamElement(
1390 aStreamName,
1391 embed::ElementModes::READWRITE );
1392 // throw uno::RuntimeException(); // TODO: method must either return the stream or throw an exception
1393
1394 uno::Reference< beans::XPropertySet > xProps( xElementStream, uno::UNO_QUERY );
1396 !xProps.is(), "basic",
1397 "The StorageStream must implement XPropertySet interface!");
1398 //if ( !xProps.is() ) //TODO
1399
1400 if ( xProps.is() )
1401 {
1402 xProps->setPropertyValue("MediaType", uno::Any( OUString( "text/xml" ) ) );
1403
1404 // #87671 Allow encryption
1405 xProps->setPropertyValue("UseCommonStoragePasswordEncryption", uno::Any( true ) );
1406
1407 Reference< XOutputStream > xOutput = xElementStream->getOutputStream();
1408 Reference< XNameContainer > xLib( pLib );
1409 writeLibraryElement( xLib, aElementName, xOutput );
1410 }
1411 }
1412 catch(const uno::Exception& )
1413 {
1414 SAL_WARN("basic", "Problem during storing of library!");
1415 // TODO: error handling?
1416 }
1417 }
1418 pLib->storeResourcesToStorage( xStorage );
1419 }
1420 else
1421 {
1422 // Export?
1423 bool bExport = !aTargetURL.empty();
1424 try
1425 {
1427 if( rToUseSFI.is() )
1428 {
1429 xSFI = rToUseSFI;
1430 }
1431 OUString aLibDirPath;
1432 if( bExport )
1433 {
1434 INetURLObject aInetObj( aTargetURL );
1435 aInetObj.insertName( aName, true, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All );
1436 aLibDirPath = aInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1437
1438 if( !xSFI->isFolder( aLibDirPath ) )
1439 {
1440 xSFI->createFolder( aLibDirPath );
1441 }
1442 pLib->storeResourcesToURL( aLibDirPath, xHandler );
1443 }
1444 else
1445 {
1446 aLibDirPath = createAppLibraryFolder( pLib, aName );
1447 pLib->storeResources();
1448 }
1449
1450 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1451 {
1452 OUString aElementName = pNames[ i ];
1453
1454 INetURLObject aElementInetObj( aLibDirPath );
1455 aElementInetObj.insertName( aElementName, false,
1458 aElementInetObj.setExtension( maLibElementFileExtension );
1459 OUString aElementPath( aElementInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
1460
1461 if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
1462 {
1463 SAL_WARN(
1464 "basic",
1465 "invalid library element \"" << aElementName << '"');
1466 continue;
1467 }
1468
1469 // TODO: Check modified
1470 try
1471 {
1472 if( xSFI->exists( aElementPath ) )
1473 {
1474 xSFI->kill( aElementPath );
1475 }
1476 Reference< XOutputStream > xOutput = xSFI->openFileWrite( aElementPath );
1477 Reference< XNameContainer > xLib( pLib );
1478 writeLibraryElement( xLib, aElementName, xOutput );
1479 xOutput->closeOutput();
1480 }
1481 catch(const Exception& )
1482 {
1483 if( bExport )
1484 {
1485 throw;
1486 }
1487 SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aElementPath );
1488 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
1489 }
1490 }
1491 }
1492 catch(const Exception& )
1493 {
1494 if( bExport )
1495 {
1496 throw;
1497 }
1498 }
1499 }
1500}
1501
1503 const ::xmlscript::LibDescriptor& rLib,
1504 const uno::Reference< embed::XStorage >& xStorage )
1505{
1507 implStoreLibraryIndexFile( pLib, rLib, xStorage, u"", xDummySFA );
1508}
1509
1510// New variant for library export
1512 const ::xmlscript::LibDescriptor& rLib,
1513 const uno::Reference< embed::XStorage >& xStorage,
1514 std::u16string_view aTargetURL,
1515 const Reference< XSimpleFileAccess3 >& rToUseSFI )
1516{
1517 // Create sax writer
1518 Reference< XWriter > xWriter = xml::sax::Writer::create(mxContext);
1519
1520 bool bLink = pLib->mbLink;
1521 bool bStorage = xStorage.is() && !bLink;
1522
1523 // Write info file
1524 uno::Reference< io::XOutputStream > xOut;
1525 uno::Reference< io::XStream > xInfoStream;
1526 if( bStorage )
1527 {
1528 OUString aStreamName = maInfoFileName + "-lb.xml";
1529
1530 try
1531 {
1532 xInfoStream = xStorage->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
1533 SAL_WARN_IF(!xInfoStream.is(), "basic", "No stream!");
1534 uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
1535 // throw uno::RuntimeException(); // TODO
1536
1537 if ( xProps.is() )
1538 {
1539 xProps->setPropertyValue("MediaType", uno::Any( OUString("text/xml") ) );
1540
1541 // #87671 Allow encryption
1542 xProps->setPropertyValue("UseCommonStoragePasswordEncryption", uno::Any( true ) );
1543
1544 xOut = xInfoStream->getOutputStream();
1545 }
1546 }
1547 catch(const uno::Exception& )
1548 {
1549 SAL_WARN("basic", "Problem during storing of library index file!");
1550 // TODO: error handling?
1551 }
1552 }
1553 else
1554 {
1555 // Export?
1556 bool bExport = !aTargetURL.empty();
1558 if( rToUseSFI.is() )
1559 {
1560 xSFI = rToUseSFI;
1561 }
1562 OUString aLibInfoPath;
1563 if( bExport )
1564 {
1565 INetURLObject aInetObj( aTargetURL );
1566 aInetObj.insertName( rLib.aName, true, INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All );
1567 OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1568 if( !xSFI->isFolder( aLibDirPath ) )
1569 {
1570 xSFI->createFolder( aLibDirPath );
1571 }
1573 aInetObj.setExtension( u"xlb" );
1574 aLibInfoPath = aInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1575 }
1576 else
1577 {
1578 createAppLibraryFolder( pLib, rLib.aName );
1579 aLibInfoPath = pLib->maLibInfoFileURL;
1580 }
1581
1582 try
1583 {
1584 if( xSFI->exists( aLibInfoPath ) )
1585 {
1586 xSFI->kill( aLibInfoPath );
1587 }
1588 xOut = xSFI->openFileWrite( aLibInfoPath );
1589 }
1590 catch(const Exception& )
1591 {
1592 if( bExport )
1593 {
1594 throw;
1595 }
1596 SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
1597 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
1598 }
1599 }
1600 if( !xOut.is() )
1601 {
1602 SAL_WARN("basic", "couldn't open output stream");
1603 return;
1604 }
1605 xWriter->setOutputStream( xOut );
1606 xmlscript::exportLibrary( xWriter, rLib );
1607}
1608
1609
1612 const uno::Reference< embed::XStorage >& xStorage,
1613 const OUString& aIndexFileName )
1614{
1615 Reference< XParser > xParser = xml::sax::Parser::create(mxContext);
1616
1617 bool bStorage = false;
1618 if( pLib )
1619 {
1620 bool bLink = pLib->mbLink;
1621 bStorage = xStorage.is() && !bLink;
1622 }
1623
1624 // Read info file
1626 OUString aLibInfoPath;
1627 if( bStorage )
1628 {
1629 aLibInfoPath = maInfoFileName + "-lb.xml";
1630
1631 try
1632 {
1633 uno::Reference< io::XStream > xInfoStream =
1634 xStorage->openStreamElement( aLibInfoPath, embed::ElementModes::READ );
1635 xInput = xInfoStream->getInputStream();
1636 }
1637 catch(const uno::Exception& )
1638 {}
1639 }
1640 else
1641 {
1642 // Create Input stream
1643 //String aLibInfoPath; // attention: THIS PROBLEM MUST BE REVIEWED BY SCRIPTING OWNER!!!
1644
1645 if( pLib )
1646 {
1648 aLibInfoPath = pLib->maLibInfoFileURL;
1649 }
1650 else
1651 {
1652 aLibInfoPath = aIndexFileName;
1653 }
1654 try
1655 {
1656 xInput = mxSFI->openFileRead( aLibInfoPath );
1657 }
1658 catch(const Exception& )
1659 {
1660 xInput.clear();
1662 {
1663 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
1665 }
1666 }
1667 }
1668 if( !xInput.is() )
1669 {
1670 return false;
1671 }
1672
1673 InputSource source;
1674 source.aInputStream = xInput;
1675 source.sSystemId = aLibInfoPath;
1676
1677 // start parsing
1678 try
1679 {
1680 xParser->setDocumentHandler( ::xmlscript::importLibrary( rLib ) );
1681 xParser->parseStream( source );
1682 }
1683 catch(const Exception& )
1684 {
1685 SAL_WARN("basic", "Parsing error");
1686 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
1688 return false;
1689 }
1690
1691 if( !pLib )
1692 {
1694 pLib = static_cast< SfxLibrary* >( xLib.get() );
1695 pLib->mbLoaded = false;
1696 rLib.aStorageURL = aIndexFileName;
1697 checkStorageURL( rLib.aStorageURL, pLib->maLibInfoFileURL, pLib->maStorageURL,
1698 pLib->maUnexpandedStorageURL );
1699
1701 }
1702
1703 return true;
1704}
1705
1707 ::xmlscript::LibDescriptor const & rLib )
1708{
1709 if( pLib->mbInitialised )
1710 return;
1711
1712 sal_Int32 nElementCount = rLib.aElementNames.getLength();
1713 const OUString* pElementNames = rLib.aElementNames.getConstArray();
1714 Any aDummyElement = createEmptyLibraryElement();
1715 for( sal_Int32 i = 0 ; i < nElementCount ; i++ )
1716 {
1717 pLib->maNameContainer->insertByName( pElementNames[i], aDummyElement );
1718 }
1719 pLib->mbPasswordProtected = rLib.bPasswordProtected;
1720 pLib->mbReadOnly = rLib.bReadOnly;
1721 pLib->mbPreload = rLib.bPreload;
1722 pLib->implSetModified( false );
1723 pLib->mbInitialised = true;
1724}
1725
1726
1727// Methods of new XLibraryStorage interface?
1729 bool bComplete )
1730{
1731 const Sequence< OUString > aNames = maNameContainer->getElementNames();
1732 const sal_Int32 nNameCount = aNames.getLength();
1733 const OUString* pName = aNames.getConstArray();
1734 const OUString* pNamesEnd = aNames.getConstArray() + nNameCount;
1735
1736 // Don't count libs from shared index file
1737 sal_Int32 nLibsToSave = nNameCount;
1738 for( ; pName != pNamesEnd; ++pName )
1739 {
1740 SfxLibrary* pImplLib = getImplLib( *pName );
1741 if( pImplLib->mbSharedIndexFile || pImplLib->mbExtension )
1742 {
1743 nLibsToSave--;
1744 }
1745 }
1746 // Write to storage?
1747 bool bStorage = i_rStorage.is();
1748 uno::Reference< embed::XStorage > xSourceLibrariesStor;
1749 uno::Reference< embed::XStorage > xTargetLibrariesStor;
1750 OUString sTempTargetStorName;
1751 const bool bInplaceStorage = bStorage && ( i_rStorage == mxStorage );
1752
1753 if( nLibsToSave == 0 )
1754 {
1755 if ( bInplaceStorage && mxStorage->hasByName(maLibrariesDir) )
1756 {
1757 mxStorage->removeElement(maLibrariesDir);
1758 }
1759 return;
1760 }
1761
1762 if ( bStorage )
1763 {
1764 // Don't write if only empty standard lib exists
1765 if ( ( nLibsToSave == 1 ) && ( aNames[0] == "Standard" ) )
1766 {
1767 Any aLibAny = maNameContainer->getByName( aNames[0] );
1768 Reference< XNameAccess > xNameAccess;
1769 aLibAny >>= xNameAccess;
1770 if ( ! xNameAccess->hasElements() )
1771 {
1772 if ( bInplaceStorage && mxStorage->hasByName(maLibrariesDir) )
1773 {
1774 mxStorage->removeElement(maLibrariesDir);
1775 }
1776 return;
1777 }
1778 }
1779
1780 // create the empty target storage
1781 try
1782 {
1783 OUString sTargetLibrariesStoreName;
1784 if ( bInplaceStorage )
1785 {
1786 // create a temporary target storage
1787 const OUStringBuffer aTempTargetNameBase = maLibrariesDir + "_temp_";
1788 sal_Int32 index = 0;
1789 do
1790 {
1791 sTargetLibrariesStoreName = aTempTargetNameBase + OUString::number( index++ );
1792 if ( !i_rStorage->hasByName( sTargetLibrariesStoreName ) )
1793 {
1794 break;
1795 }
1796 }
1797 while ( true );
1798 sTempTargetStorName = sTargetLibrariesStoreName;
1799 }
1800 else
1801 {
1802 sTargetLibrariesStoreName = maLibrariesDir;
1803 if ( i_rStorage->hasByName( sTargetLibrariesStoreName ) )
1804 {
1805 i_rStorage->removeElement( sTargetLibrariesStoreName );
1806 }
1807 }
1808
1809 xTargetLibrariesStor.set( i_rStorage->openStorageElement( sTargetLibrariesStoreName, embed::ElementModes::READWRITE ), UNO_SET_THROW );
1810 }
1811 catch( const uno::Exception& )
1812 {
1813 DBG_UNHANDLED_EXCEPTION("basic");
1814 return;
1815 }
1816
1817 // open the source storage which might be used to copy yet-unmodified libraries
1818 try
1819 {
1820 if ( mxStorage->hasByName( maLibrariesDir ) || bInplaceStorage )
1821 {
1822 xSourceLibrariesStor = mxStorage->openStorageElement( maLibrariesDir,
1823 bInplaceStorage ? embed::ElementModes::READWRITE : embed::ElementModes::READ );
1824 }
1825 }
1826 catch( const uno::Exception& )
1827 {
1828 DBG_UNHANDLED_EXCEPTION("basic");
1829 return;
1830 }
1831 }
1832
1833 int iArray = 0;
1834 pName = aNames.getConstArray();
1835 ::xmlscript::LibDescriptor aLibDescriptorForExtensionLibs;
1836 auto pLibArray = std::make_unique< ::xmlscript::LibDescriptorArray > ( nLibsToSave );
1837 for( ; pName != pNamesEnd; ++pName )
1838 {
1839 SfxLibrary* pImplLib = getImplLib( *pName );
1840 if( pImplLib->mbSharedIndexFile )
1841 {
1842 continue;
1843 }
1844 const bool bExtensionLib = pImplLib->mbExtension;
1845 ::xmlscript::LibDescriptor& rLib = bExtensionLib ?
1846 aLibDescriptorForExtensionLibs : pLibArray->mpLibs[iArray];
1847 if( !bExtensionLib )
1848 {
1849 iArray++;
1850 }
1851 rLib.aName = *pName;
1852
1853 rLib.bLink = pImplLib->mbLink;
1854 if( !bStorage || pImplLib->mbLink )
1855 {
1856 rLib.aStorageURL = ( pImplLib->maUnexpandedStorageURL.getLength() ) ?
1857 pImplLib->maUnexpandedStorageURL : pImplLib->maLibInfoFileURL;
1858 }
1859 rLib.bReadOnly = pImplLib->mbReadOnly;
1860 rLib.bPreload = pImplLib->mbPreload;
1861 rLib.bPasswordProtected = pImplLib->mbPasswordProtected;
1862 rLib.aElementNames = pImplLib->getElementNames();
1863
1864 if( pImplLib->implIsModified() || bComplete )
1865 {
1866// Testing pImplLib->implIsModified() is not reliable,
1867// IMHO the value of pImplLib->implIsModified() should
1868// reflect whether the library ( in-memory ) model
1869// is in sync with the library container's own storage. Currently
1870// whenever the library model is written to *any* storage
1871// pImplLib->implSetModified( sal_False ) is called
1872// The way the code works, especially the way that sfx uses
1873// temp storage when saving ( and later sets the root storage of the
1874// library container ) and similar madness in dbaccess means some surgery
1875// is required to make it possible to successfully use this optimisation
1876// It would be possible to do the implSetModified() call below only
1877// conditionally, but that would require an additional boolean to be
1878// passed in via the XStorageBasedDocument::storeLibrariesToStorage()...
1879// fdo#68983: If there's a password and the password is not known, only
1880// copying the storage works!
1881 // Can we simply copy the storage?
1882 bool isCopyStorage = !mbOldInfoFormat && !mbOasis2OOoFormat
1883 && !pImplLib->isLoadedStorable()
1884 && xSourceLibrariesStor.is() /* null for user profile */;
1885 if (isCopyStorage)
1886 {
1887 try
1888 {
1889 (void)xSourceLibrariesStor->isStorageElement(rLib.aName);
1890 }
1891 catch (container::NoSuchElementException const&)
1892 {
1893 isCopyStorage = false;
1894 }
1895 }
1896 if (isCopyStorage)
1897 {
1898 try
1899 {
1900 xSourceLibrariesStor->copyElementTo( rLib.aName, xTargetLibrariesStor, rLib.aName );
1901 }
1902 catch( const uno::Exception& )
1903 {
1904 DBG_UNHANDLED_EXCEPTION("basic");
1905 // TODO: error handling?
1906 }
1907 }
1908 else
1909 {
1911 if( bStorage )
1912 {
1913#if OSL_DEBUG_LEVEL > 0
1914 try
1915 {
1916#endif
1917 xLibraryStor = xTargetLibrariesStor->openStorageElement(
1918 rLib.aName,
1919 embed::ElementModes::READWRITE );
1920#if OSL_DEBUG_LEVEL > 0
1921 }
1922 catch(const uno::Exception& )
1923 {
1925 "basic",
1926 "couldn't create sub storage for library \"" << rLib.aName << "\"");
1927 throw;
1928 }
1929#endif
1930 }
1931
1932 // Maybe lib is not loaded?!
1933 if( bComplete )
1934 {
1935 loadLibrary( rLib.aName );
1936 }
1937 if( pImplLib->mbPasswordProtected )
1938 {
1940 // TODO: Check return value
1941 }
1942 else
1943 {
1944 implStoreLibrary( pImplLib, rLib.aName, xLibraryStor );
1945 }
1946 implStoreLibraryIndexFile( pImplLib, rLib, xLibraryStor );
1947 if( bStorage )
1948 {
1949 try
1950 {
1951 uno::Reference< embed::XTransactedObject > xTransact( xLibraryStor, uno::UNO_QUERY_THROW );
1952 xTransact->commit();
1953 }
1954 catch(const uno::Exception& )
1955 {
1956 DBG_UNHANDLED_EXCEPTION("basic");
1957 // TODO: error handling
1958 throw;
1959 }
1960 }
1961 }
1962 maModifiable.setModified( true );
1963 pImplLib->implSetModified( false );
1964 }
1965
1966 // For container info ReadOnly refers to mbReadOnlyLink
1967 rLib.bReadOnly = pImplLib->mbReadOnlyLink;
1968 }
1969
1970 // if we did an in-place save into a storage (i.e. a save into the storage we were already based on),
1971 // then we need to clean up the temporary storage we used for this
1972 if ( bInplaceStorage && !sTempTargetStorName.isEmpty() )
1973 {
1975 !xSourceLibrariesStor.is(), "basic",
1976 ("SfxLibrariesContainer::storeLibraries_impl: unexpected: we should"
1977 " have a source storage here!"));
1978 try
1979 {
1980 // for this, we first remove everything from the source storage, then copy the complete content
1981 // from the temporary target storage. From then on, what used to be the "source storage" becomes
1982 // the "target storage" for all subsequent operations.
1983
1984 // (We cannot simply remove the storage, denoted by maLibrariesDir, from i_rStorage - there might be
1985 // open references to it.)
1986
1987 if ( xSourceLibrariesStor.is() )
1988 {
1989 // remove
1990 const Sequence< OUString > aRemoveNames( xSourceLibrariesStor->getElementNames() );
1991 for ( auto const & removeName : aRemoveNames )
1992 {
1993 xSourceLibrariesStor->removeElement( removeName );
1994 }
1995
1996 // copy
1997 const Sequence< OUString > aCopyNames( xTargetLibrariesStor->getElementNames() );
1998 for ( auto const & copyName : aCopyNames )
1999 {
2000 xTargetLibrariesStor->copyElementTo( copyName, xSourceLibrariesStor, copyName );
2001 }
2002 }
2003
2004 // close and remove temp target
2005 xTargetLibrariesStor->dispose();
2006 i_rStorage->removeElement( sTempTargetStorName );
2007 xTargetLibrariesStor.clear();
2008 sTempTargetStorName.clear();
2009
2010 // adjust target
2011 xTargetLibrariesStor = xSourceLibrariesStor;
2012 xSourceLibrariesStor.clear();
2013 }
2014 catch( const Exception& )
2015 {
2016 DBG_UNHANDLED_EXCEPTION("basic");
2017 throw;
2018 }
2019 }
2020
2022 {
2023 return;
2024 }
2025 maModifiable.setModified( false );
2026 mbOldInfoFormat = false;
2027
2028 // Write library container info
2029 // Create sax writer
2030 Reference< XWriter > xWriter = xml::sax::Writer::create(mxContext);
2031
2032 // Write info file
2035 if( bStorage )
2036 {
2037 OUString aStreamName = maInfoFileName + "-lc.xml";
2038
2039 try
2040 {
2041 xInfoStream = xTargetLibrariesStor->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
2042 uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY_THROW );
2043 xProps->setPropertyValue("MediaType", uno::Any( OUString( "text/xml" ) ) );
2044
2045 // #87671 Allow encryption
2046 xProps->setPropertyValue("UseCommonStoragePasswordEncryption", uno::Any( true ) );
2047
2048 xOut = xInfoStream->getOutputStream();
2049 }
2050 catch(const uno::Exception& )
2051 {
2053 }
2054 }
2055 else
2056 {
2057 // Create Output stream
2058 INetURLObject aLibInfoInetObj( o3tl::getToken(maLibraryPath, 1, ';') );
2060 aLibInfoInetObj.setExtension( u"xlc" );
2061 OUString aLibInfoPath( aLibInfoInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
2062
2063 try
2064 {
2065 if( mxSFI->exists( aLibInfoPath ) )
2066 {
2067 mxSFI->kill( aLibInfoPath );
2068 }
2069 xOut = mxSFI->openFileWrite( aLibInfoPath );
2070 }
2071 catch(const Exception& )
2072 {
2073 xOut.clear();
2074 SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
2076 }
2077
2078 }
2079 if( !xOut.is() )
2080 {
2081 SAL_WARN("basic", "couldn't open output stream");
2082 return;
2083 }
2084
2085 xWriter->setOutputStream( xOut );
2086
2087 try
2088 {
2089 xmlscript::exportLibraryContainer( xWriter, pLibArray.get() );
2090 if ( bStorage )
2091 {
2092 uno::Reference< embed::XTransactedObject > xTransact( xTargetLibrariesStor, uno::UNO_QUERY_THROW );
2093 xTransact->commit();
2094 }
2095 }
2096 catch(const uno::Exception& )
2097 {
2098 SAL_WARN("basic", "Problem during storing of libraries!");
2100 }
2101}
2102
2103
2104// Methods XElementAccess
2106{
2107 LibraryContainerMethodGuard aGuard( *this );
2108 return maNameContainer->getElementType();
2109}
2110
2112{
2113 LibraryContainerMethodGuard aGuard( *this );
2114 bool bRet = maNameContainer->hasElements();
2115 return bRet;
2116}
2117
2118// Methods XNameAccess
2119Any SfxLibraryContainer::getByName( const OUString& aName )
2120{
2121 LibraryContainerMethodGuard aGuard( *this );
2122 Any aRetAny = maNameContainer->getByName( aName ) ;
2123 return aRetAny;
2124}
2125
2127{
2128 LibraryContainerMethodGuard aGuard( *this );
2129 return maNameContainer->getElementNames();
2130}
2131
2133{
2134 LibraryContainerMethodGuard aGuard( *this );
2135 return maNameContainer->hasByName( aName ) ;
2136}
2137
2138// Methods XLibraryContainer
2140{
2141 LibraryContainerMethodGuard aGuard( *this );
2143 pNewLib->maLibElementFileExtension = maLibElementFileExtension;
2144
2145 createVariableURL( pNewLib->maUnexpandedStorageURL, Name, maInfoFileName, true );
2146 // tdf#151741 - fill various storage URLs for the newly created library
2147 checkStorageURL(pNewLib->maUnexpandedStorageURL, pNewLib->maLibInfoFileURL,
2148 pNewLib->maStorageURL, pNewLib->maUnexpandedStorageURL);
2149
2150 Reference< XNameAccess > xNameAccess( pNewLib );
2151 Any aElement;
2152 aElement <<= xNameAccess;
2153 maNameContainer->insertByName( Name, aElement );
2154 maModifiable.setModified( true );
2155 Reference< XNameContainer > xRet( xNameAccess, UNO_QUERY );
2156 return xRet;
2157}
2158
2160 ( const OUString& Name, const OUString& StorageURL, sal_Bool ReadOnly )
2161{
2162 LibraryContainerMethodGuard aGuard( *this );
2163 // TODO: Check other reasons to force ReadOnly status
2164 //if( !ReadOnly )
2165 //{
2166 //}
2167
2168 OUString aLibInfoFileURL;
2169 OUString aLibDirURL;
2170 OUString aUnexpandedStorageURL;
2171 checkStorageURL( StorageURL, aLibInfoFileURL, aLibDirURL, aUnexpandedStorageURL );
2172
2173
2174 rtl::Reference<SfxLibrary> pNewLib = implCreateLibraryLink( Name, aLibInfoFileURL, aLibDirURL, ReadOnly );
2175 pNewLib->maLibElementFileExtension = maLibElementFileExtension;
2176 pNewLib->maUnexpandedStorageURL = aUnexpandedStorageURL;
2177 pNewLib->maOriginalStorageURL = StorageURL;
2178
2181 implLoadLibraryIndexFile( pNewLib.get(), aLibDesc, xDummyStor, OUString() );
2182 implImportLibDescriptor( pNewLib.get(), aLibDesc );
2183
2184 Reference< XNameAccess > xRet( pNewLib );
2185 Any aElement;
2186 aElement <<= xRet;
2187 maNameContainer->insertByName( Name, aElement );
2188 maModifiable.setModified( true );
2189
2190 if( StorageURL.indexOf( "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE" ) != -1 )
2191 {
2192 pNewLib->mbExtension = true;
2193 }
2194 else if( StorageURL.indexOf( "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE" ) != -1
2195 || StorageURL.indexOf( "vnd.sun.star.expand:$BUNDLED_EXTENSIONS" ) != -1 )
2196 {
2197 pNewLib->mbExtension = true;
2198 pNewLib->mbReadOnly = true;
2199 }
2200
2201 return xRet;
2202}
2203
2204void SAL_CALL SfxLibraryContainer::removeLibrary( const OUString& Name )
2205{
2206 LibraryContainerMethodGuard aGuard( *this );
2207 // Get and hold library before removing
2208 Any aLibAny = maNameContainer->getByName( Name ) ;
2209 Reference< XNameAccess > xNameAccess;
2210 aLibAny >>= xNameAccess;
2211 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2212 if( pImplLib->mbReadOnly && !pImplLib->mbLink )
2213 {
2214 throw IllegalArgumentException("readonly && !link", getXWeak(), 1);
2215 }
2216 // Remove from container
2217 maNameContainer->removeByName( Name );
2218 maModifiable.setModified( true );
2219
2220 // Delete library files, but not for linked libraries
2221 if( pImplLib->mbLink )
2222 return;
2223
2224 if( mxStorage.is() )
2225 {
2226 return;
2227 }
2228 if( xNameAccess->hasElements() )
2229 {
2230 Sequence< OUString > aNames = pImplLib->getElementNames();
2231 sal_Int32 nNameCount = aNames.getLength();
2232 const OUString* pNames = aNames.getConstArray();
2233 for( sal_Int32 i = 0 ; i < nNameCount ; ++i, ++pNames )
2234 {
2236 }
2237 }
2238
2239 // Delete index file
2240 createAppLibraryFolder( pImplLib, Name );
2241 OUString aLibInfoPath = pImplLib->maLibInfoFileURL;
2242 try
2243 {
2244 if( mxSFI->exists( aLibInfoPath ) )
2245 {
2246 mxSFI->kill( aLibInfoPath );
2247 }
2248 }
2249 catch(const Exception& ) {}
2250
2251 // Delete folder if empty
2252 INetURLObject aInetObj( o3tl::getToken(maLibraryPath, 1, ';') );
2255 OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
2256
2257 try
2258 {
2259 if( mxSFI->isFolder( aLibDirPath ) )
2260 {
2261 Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
2262 sal_Int32 nCount = aContentSeq.getLength();
2263 if( !nCount )
2264 {
2265 mxSFI->kill( aLibDirPath );
2266 }
2267 }
2268 }
2269 catch(const Exception& )
2270 {
2271 }
2272}
2273
2274sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLoaded( const OUString& Name )
2275{
2276 LibraryContainerMethodGuard aGuard( *this );
2277 SfxLibrary* pImplLib = getImplLib( Name );
2278 bool bRet = pImplLib->mbLoaded;
2279 return bRet;
2280}
2281
2282
2283void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name )
2284{
2285 LibraryContainerMethodGuard aGuard( *this );
2286 Any aLibAny = maNameContainer->getByName( Name ) ;
2287 Reference< XNameAccess > xNameAccess;
2288 aLibAny >>= xNameAccess;
2289 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2290
2291 bool bLoaded = pImplLib->mbLoaded;
2292 pImplLib->mbLoaded = true;
2293 if( bLoaded || !xNameAccess->hasElements() )
2294 return;
2295
2296 if( pImplLib->mbPasswordProtected )
2297 {
2298 implLoadPasswordLibrary( pImplLib, Name );
2299 return;
2300 }
2301
2302 bool bLink = pImplLib->mbLink;
2303 bool bStorage = mxStorage.is() && !bLink;
2304
2305 uno::Reference< embed::XStorage > xLibrariesStor;
2307 if( bStorage )
2308 {
2309#if OSL_DEBUG_LEVEL > 0
2310 try
2311 {
2312#endif
2313 xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
2315 !xLibrariesStor.is(), "basic",
2316 ("The method must either throw exception or return a"
2317 " storage!"));
2318 if ( !xLibrariesStor.is() )
2319 {
2320 throw uno::RuntimeException("null returned from openStorageElement",getXWeak());
2321 }
2322
2323 xLibraryStor = xLibrariesStor->openStorageElement( Name, embed::ElementModes::READ );
2325 !xLibraryStor.is(), "basic",
2326 ("The method must either throw exception or return a"
2327 " storage!"));
2328 if ( !xLibrariesStor.is() )
2329 {
2330 throw uno::RuntimeException("null returned from openStorageElement",getXWeak());
2331 }
2332#if OSL_DEBUG_LEVEL > 0
2333 }
2334 catch(const uno::Exception& )
2335 {
2337 "basic",
2338 "couldn't open sub storage for library \"" << Name << "\"");
2339 throw;
2340 }
2341#endif
2342 }
2343
2344 Sequence< OUString > aNames = pImplLib->getElementNames();
2345 sal_Int32 nNameCount = aNames.getLength();
2346 const OUString* pNames = aNames.getConstArray();
2347 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
2348 {
2349 OUString aElementName = pNames[ i ];
2350
2351 OUString aFile;
2353
2354 if( bStorage )
2355 {
2356 uno::Reference< io::XStream > xElementStream;
2357
2358 aFile = aElementName + ".xml";
2359
2360 try
2361 {
2362 xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
2363 }
2364 catch(const uno::Exception& )
2365 {}
2366
2367 if( !xElementStream.is() )
2368 {
2369 // Check for EA2 document version with wrong extensions
2370 aFile = aElementName + "." + maLibElementFileExtension;
2371 try
2372 {
2373 xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
2374 }
2375 catch(const uno::Exception& )
2376 {}
2377 }
2378
2379 if ( xElementStream.is() )
2380 {
2381 xInStream = xElementStream->getInputStream();
2382 }
2383 if ( !xInStream.is() )
2384 {
2385 SAL_WARN(
2386 "basic",
2387 "couldn't open library element stream - attempted to"
2388 " open library \"" << Name << '"');
2389 throw RuntimeException("couldn't open library element stream", *this);
2390 }
2391 }
2392 else
2393 {
2394 OUString aLibDirPath = pImplLib->maStorageURL;
2395 INetURLObject aElementInetObj( aLibDirPath );
2396 aElementInetObj.insertName( aElementName, false,
2399 aElementInetObj.setExtension( maLibElementFileExtension );
2400 aFile = aElementInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
2401 }
2402
2403 Reference< XNameContainer > xLib( pImplLib );
2404 Any aAny = importLibraryElement( xLib, aElementName,
2405 aFile, xInStream );
2406 if( pImplLib->hasByName( aElementName ) )
2407 {
2408 if( aAny.hasValue() )
2409 {
2410 pImplLib->maNameContainer->replaceByName( aElementName, aAny );
2411 }
2412 }
2413 else
2414 {
2415 pImplLib->maNameContainer->insertNoCheck(aElementName, aAny);
2416 }
2417 }
2418 pImplLib->implSetModified( false );
2419}
2420
2421// Methods XLibraryContainer2
2422sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLink( const OUString& Name )
2423{
2424 LibraryContainerMethodGuard aGuard( *this );
2425 SfxLibrary* pImplLib = getImplLib( Name );
2426 bool bRet = pImplLib->mbLink;
2427 return bRet;
2428}
2429
2430OUString SAL_CALL SfxLibraryContainer::getLibraryLinkURL( const OUString& Name )
2431{
2432 LibraryContainerMethodGuard aGuard( *this );
2433 SfxLibrary* pImplLib = getImplLib( Name );
2434 bool bLink = pImplLib->mbLink;
2435 if( !bLink )
2436 {
2437 throw IllegalArgumentException("!link", getXWeak(), 1);
2438 }
2439 OUString aRetStr = pImplLib->maLibInfoFileURL;
2440 return aRetStr;
2441}
2442
2443sal_Bool SAL_CALL SfxLibraryContainer::isLibraryReadOnly( const OUString& Name )
2444{
2445 LibraryContainerMethodGuard aGuard( *this );
2446 SfxLibrary* pImplLib = getImplLib( Name );
2447 bool bRet = pImplLib->mbReadOnly || (pImplLib->mbLink && pImplLib->mbReadOnlyLink);
2448 return bRet;
2449}
2450
2451void SAL_CALL SfxLibraryContainer::setLibraryReadOnly( const OUString& Name, sal_Bool bReadOnly )
2452{
2453 LibraryContainerMethodGuard aGuard( *this );
2454 SfxLibrary* pImplLib = getImplLib( Name );
2455 if( pImplLib->mbLink )
2456 {
2457 if( pImplLib->mbReadOnlyLink != bool(bReadOnly) )
2458 {
2459 pImplLib->mbReadOnlyLink = bReadOnly;
2460 pImplLib->implSetModified( true );
2461 maModifiable.setModified( true );
2462 }
2463 }
2464 else
2465 {
2466 if( pImplLib->mbReadOnly != bool(bReadOnly) )
2467 {
2468 pImplLib->mbReadOnly = bReadOnly;
2469 pImplLib->implSetModified( true );
2470 }
2471 }
2472}
2473
2474void SAL_CALL SfxLibraryContainer::renameLibrary( const OUString& Name, const OUString& NewName )
2475{
2476 LibraryContainerMethodGuard aGuard( *this );
2477 if( maNameContainer->hasByName( NewName ) )
2478 {
2479 throw ElementExistException();
2480 }
2481 // Get and hold library before removing
2482 Any aLibAny = maNameContainer->getByName( Name ) ;
2483
2484 // #i24094 Maybe lib is not loaded!
2485 Reference< XNameAccess > xNameAccess;
2486 aLibAny >>= xNameAccess;
2487 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2488 if( pImplLib->mbPasswordProtected && !pImplLib->mbPasswordVerified )
2489 {
2490 return; // Lib with unverified password cannot be renamed
2491 }
2492 loadLibrary( Name );
2493
2494 // Rename library folder, but not for linked libraries
2495 bool bMovedSuccessful = true;
2496
2497 // Rename files
2498 bool bStorage = mxStorage.is();
2499 if( !bStorage && !pImplLib->mbLink )
2500 {
2501 bMovedSuccessful = false;
2502
2503 OUString aLibDirPath = pImplLib->maStorageURL;
2504 // tdf#151741 - fill various storage URLs for the library
2505 // These URLs should not be empty for newly created libraries after
2506 // the change in SfxLibraryContainer::createLibrary.
2507 if (aLibDirPath.isEmpty())
2508 {
2510 pImplLib->maStorageURL, pImplLib->maUnexpandedStorageURL);
2511 }
2512
2513 INetURLObject aDestInetObj( o3tl::getToken(maLibraryPath, 1, ';'));
2514 aDestInetObj.insertName( NewName, true, INetURLObject::LAST_SEGMENT,
2516 OUString aDestDirPath = aDestInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
2517
2518 // Store new URL
2519 OUString aLibInfoFileURL = pImplLib->maLibInfoFileURL;
2520 checkStorageURL( aDestDirPath, pImplLib->maLibInfoFileURL, pImplLib->maStorageURL,
2521 pImplLib->maUnexpandedStorageURL );
2522
2523 try
2524 {
2525 if( mxSFI->isFolder( aLibDirPath ) )
2526 {
2527 if( !mxSFI->isFolder( aDestDirPath ) )
2528 {
2529 mxSFI->createFolder( aDestDirPath );
2530 }
2531 // Move index file
2532 try
2533 {
2534 if( mxSFI->exists( pImplLib->maLibInfoFileURL ) )
2535 {
2536 mxSFI->kill( pImplLib->maLibInfoFileURL );
2537 }
2538 mxSFI->move( aLibInfoFileURL, pImplLib->maLibInfoFileURL );
2539 }
2540 catch(const Exception& )
2541 {
2542 }
2543
2544 Sequence< OUString > aElementNames = xNameAccess->getElementNames();
2545 sal_Int32 nNameCount = aElementNames.getLength();
2546 const OUString* pNames = aElementNames.getConstArray();
2547 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
2548 {
2549 OUString aElementName = pNames[ i ];
2550
2551 INetURLObject aElementInetObj( aLibDirPath );
2552 aElementInetObj.insertName( aElementName, false,
2554 aElementInetObj.setExtension( maLibElementFileExtension );
2555 OUString aElementPath( aElementInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
2556
2557 INetURLObject aElementDestInetObj( aDestDirPath );
2558 aElementDestInetObj.insertName( aElementName, false,
2561 aElementDestInetObj.setExtension( maLibElementFileExtension );
2562 OUString aDestElementPath( aElementDestInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
2563
2564 try
2565 {
2566 if( mxSFI->exists( aDestElementPath ) )
2567 {
2568 mxSFI->kill( aDestElementPath );
2569 }
2570 mxSFI->move( aElementPath, aDestElementPath );
2571 }
2572 catch(const Exception& )
2573 {
2574 }
2575 }
2576 pImplLib->storeResourcesAsURL( aDestDirPath, NewName );
2577
2578 // Delete folder if empty
2579 Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
2580 sal_Int32 nCount = aContentSeq.getLength();
2581 if( !nCount )
2582 {
2583 mxSFI->kill( aLibDirPath );
2584 }
2585
2586 bMovedSuccessful = true;
2587 pImplLib->implSetModified( true );
2588 // Remove old library from container
2589 maNameContainer->removeByName( Name );
2590 maModifiable.setModified( true );
2591 }
2592 }
2593 catch(const Exception& )
2594 {
2595 }
2596 }
2597
2598 if( bStorage && !pImplLib->mbLink )
2599 {
2600 pImplLib->implSetModified( true );
2601 }
2602 if( bMovedSuccessful )
2603 {
2604 maNameContainer->insertByName( NewName, aLibAny ) ;
2605 }
2606}
2607
2608
2609// Methods XInitialization
2610void SAL_CALL SfxLibraryContainer::initialize( const Sequence< Any >& _rArguments )
2611{
2612 LibraryContainerMethodGuard aGuard( *this );
2613 sal_Int32 nArgCount = _rArguments.getLength();
2614 if ( nArgCount != 1 )
2615 throw IllegalArgumentException("too many args", getXWeak(), -1);
2616
2617 OUString sInitialDocumentURL;
2619 if ( _rArguments[0] >>= sInitialDocumentURL )
2620 {
2621 init( sInitialDocumentURL, nullptr );
2622 return;
2623 }
2624
2625 if ( _rArguments[0] >>= xDocument )
2626 {
2627 initializeFromDocument( xDocument );
2628 return;
2629 }
2630 throw IllegalArgumentException("arg1 unknown type", getXWeak(), 1);
2631
2632}
2633
2635{
2636 // check whether this is a valid OfficeDocument, and obtain the document's root storage
2637 Reference< XStorage > xDocStorage;
2638 try
2639 {
2640 Reference< XServiceInfo > xSI( _rxDocument, UNO_QUERY_THROW );
2641 if ( xSI->supportsService("com.sun.star.document.OfficeDocument"))
2642 {
2643 xDocStorage.set( _rxDocument->getDocumentStorage(), UNO_SET_THROW );
2644 }
2645 Reference< XModel > xDocument( _rxDocument, UNO_QUERY_THROW );
2646 Reference< XComponent > xDocComponent( _rxDocument, UNO_QUERY_THROW );
2647
2648 mxOwnerDocument = xDocument;
2649 startComponentListening( xDocComponent );
2650 }
2651 catch( const Exception& ) { }
2652
2653 if ( !xDocStorage.is() )
2654 {
2655 throw IllegalArgumentException("no doc storage", getXWeak(), 1);
2656 }
2657 init( OUString(), xDocStorage );
2658}
2659
2660// OEventListenerAdapter
2661void SfxLibraryContainer::_disposing( const EventObject& _rSource )
2662{
2663#if OSL_DEBUG_LEVEL > 0
2664 Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
2666 xDocument != _rSource.Source || !xDocument.is(), "basic",
2667 "SfxLibraryContainer::_disposing: where does this come from?");
2668#else
2669 (void)_rSource;
2670#endif
2671 dispose();
2672}
2673
2674// OComponentHelper
2676{
2678 EventObject aEvent( xModel );
2681 mxOwnerDocument.clear();
2682}
2683
2684// Methods XLibraryContainerPassword
2686{
2687 return false;
2688}
2689
2691{
2692 throw IllegalArgumentException();
2693}
2694
2695sal_Bool SAL_CALL SfxLibraryContainer::verifyLibraryPassword( const OUString&, const OUString& )
2696{
2697 throw IllegalArgumentException();
2698}
2699
2700void SAL_CALL SfxLibraryContainer::changeLibraryPassword(const OUString&, const OUString&, const OUString& )
2701{
2702 throw IllegalArgumentException();
2703}
2704
2705// Methods XContainer
2707{
2708 LibraryContainerMethodGuard aGuard( *this );
2709 maNameContainer->setEventSource( getXWeak() );
2710 maNameContainer->addContainerListener( xListener );
2711}
2712
2714{
2715 LibraryContainerMethodGuard aGuard( *this );
2716 maNameContainer->removeContainerListener( xListener );
2717}
2718
2719// Methods XLibraryContainerExport
2720void SAL_CALL SfxLibraryContainer::exportLibrary( const OUString& Name, const OUString& URL,
2721 const Reference< XInteractionHandler >& Handler )
2722{
2723 LibraryContainerMethodGuard aGuard( *this );
2724 SfxLibrary* pImplLib = getImplLib( Name );
2725
2727 if( Handler.is() )
2728 {
2729 xToUseSFI = ucb::SimpleFileAccess::create( mxContext );
2730 xToUseSFI->setInteractionHandler( Handler );
2731 }
2732
2733 // Maybe lib is not loaded?!
2734 loadLibrary( Name );
2735
2737 if( pImplLib->mbPasswordProtected )
2738 {
2739 implStorePasswordLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
2740 }
2741 else
2742 {
2743 implStoreLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
2744 }
2746 aLibDesc.aName = Name;
2747 aLibDesc.bLink = false; // Link status gets lost?
2748 aLibDesc.bReadOnly = pImplLib->mbReadOnly;
2749 aLibDesc.bPreload = false; // Preload status gets lost?
2750 aLibDesc.bPasswordProtected = pImplLib->mbPasswordProtected;
2751 aLibDesc.aElementNames = pImplLib->getElementNames();
2752
2753 implStoreLibraryIndexFile( pImplLib, aLibDesc, xDummyStor, URL, xToUseSFI );
2754}
2755
2756OUString SfxLibraryContainer::expand_url( const OUString& url )
2757{
2758 if (url.startsWithIgnoreAsciiCase( "vnd.sun.star.expand:" ))
2759 {
2761 }
2762 else if( mxStringSubstitution.is() )
2763 {
2764 OUString ret( mxStringSubstitution->substituteVariables( url, false ) );
2765 return ret;
2766 }
2767 else
2768 {
2769 return url;
2770 }
2771}
2772
2773//XLibraryContainer3
2774OUString SAL_CALL SfxLibraryContainer::getOriginalLibraryLinkURL( const OUString& Name )
2775{
2776 LibraryContainerMethodGuard aGuard( *this );
2777 SfxLibrary* pImplLib = getImplLib( Name );
2778 bool bLink = pImplLib->mbLink;
2779 if( !bLink )
2780 {
2781 throw IllegalArgumentException("!link", getXWeak(), 1);
2782 }
2783 OUString aRetStr = pImplLib->maOriginalStorageURL;
2784 return aRetStr;
2785}
2786
2787
2788// XVBACompatibility
2790{
2791 return mbVBACompat;
2792}
2793
2795{
2796 /* The member variable mbVBACompat must be set first, the following call
2797 to getBasicManager() may call getVBACompatibilityMode() which returns
2798 this value. */
2799 mbVBACompat = _vbacompatmodeon;
2800 BasicManager* pBasMgr = getBasicManager();
2801 if( !pBasMgr )
2802 return;
2803
2804 // get the standard library
2805 OUString aLibName = pBasMgr->GetName();
2806 if ( aLibName.isEmpty())
2807 {
2808 aLibName = "Standard";
2809 }
2810 if( StarBASIC* pBasic = pBasMgr->GetLib( aLibName ) )
2811 {
2812 pBasic->SetVBAEnabled( _vbacompatmodeon );
2813 }
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.
2820 */
2821 if( mbVBACompat ) try
2822 {
2823 Reference< XModel > xModel( mxOwnerDocument ); // weak-ref -> ref
2825 xFactory->createInstance("ooo.vba.VBAGlobals");
2826 }
2827 catch(const Exception& )
2828 {
2829 }
2830}
2831
2832void SAL_CALL SfxLibraryContainer::setProjectName( const OUString& _projectname )
2833{
2834 msProjectName = _projectname;
2835 BasicManager* pBasMgr = getBasicManager();
2836 // Temporary HACK
2837 // Some parts of the VBA handling ( e.g. in core basic )
2838 // code expect the name of the VBA project to be set as the name of
2839 // the basic manager. Provide fail back here.
2840 if( pBasMgr )
2841 {
2842 pBasMgr->SetName( msProjectName );
2843 }
2844}
2845
2847{
2848 LibraryContainerMethodGuard aGuard( *this );
2849 return mnRunningVBAScripts;
2850}
2851
2853{
2854 maVBAScriptListeners.addInterface( rxListener );
2855}
2856
2858{
2860}
2861
2862void SAL_CALL SfxLibraryContainer::broadcastVBAScriptEvent( sal_Int32 nIdentifier, const OUString& rModuleName )
2863{
2864 // own lock for accessing the number of running scripts
2865 enterMethod();
2866 switch( nIdentifier )
2867 {
2868 case vba::VBAScriptEventId::SCRIPT_STARTED:
2870 break;
2871 case vba::VBAScriptEventId::SCRIPT_STOPPED:
2873 break;
2874 }
2875 leaveMethod();
2876
2877 Reference< XModel > xModel = mxOwnerDocument; // weak-ref -> ref
2878 vba::VBAScriptEvent aEvent( Reference<XInterface>(xModel, UNO_QUERY), nIdentifier, rModuleName );
2879 maVBAScriptListeners.notifyEach( &css::script::vba::XVBAScriptListener::notifyVBAScriptEvent, aEvent );
2880}
2881
2882// Methods XPropertySet
2883css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL SfxLibraryContainer::getPropertySetInfo()
2884{
2886}
2887
2888void SAL_CALL SfxLibraryContainer::setPropertyValue(const OUString& aPropertyName,
2889 const uno::Any& aValue)
2890{
2891 if (aPropertyName != sVBATextEncodingPropName)
2892 throw UnknownPropertyException(aPropertyName, getXWeak());
2893 aValue >>= meVBATextEncoding;
2894}
2895
2896css::uno::Any SAL_CALL SfxLibraryContainer::getPropertyValue(const OUString& aPropertyName)
2897{
2898 if (aPropertyName == sVBATextEncodingPropName)
2900 throw UnknownPropertyException(aPropertyName, getXWeak());
2901}
2902
2904 const OUString& /* aPropertyName */, const Reference<XPropertyChangeListener>& /* xListener */)
2905{
2906 throw NoSupportException();
2907}
2908
2910 const OUString& /* aPropertyName */, const Reference<XPropertyChangeListener>& /* aListener */)
2911{
2912 throw NoSupportException();
2913}
2914
2916 const OUString& /* PropertyName */, const Reference<XVetoableChangeListener>& /* aListener */)
2917{
2918 throw NoSupportException();
2919}
2920
2922 const OUString& /* PropertyName */, const Reference<XVetoableChangeListener>& /* aListener */)
2923{
2924 throw NoSupportException();
2925}
2926
2927// Methods XServiceInfo
2928sal_Bool SAL_CALL SfxLibraryContainer::supportsService( const OUString& _rServiceName )
2929{
2930 return cppu::supportsService(this, _rServiceName);
2931}
2932
2933// Implementation class SfxLibrary
2934
2935// Ctor
2936SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
2938 : mxSFI( xSFI )
2939 , mrModifiable( _rModifiable )
2940 , maNameContainer( new NameContainer(aType) )
2941 , mbLoaded( true )
2942 , mbIsModified( true )
2943 , mbInitialised( false )
2944 , mbLink( false )
2945 , mbReadOnly( false )
2946 , mbReadOnlyLink( false )
2947 , mbPreload( false )
2948 , mbPasswordProtected( false )
2949 , mbPasswordVerified( false )
2950 , mbDoc50Password( false )
2951 , mbSharedIndexFile( false )
2952 , mbExtension( false )
2953{
2954}
2955
2956SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
2958 OUString aLibInfoFileURL, OUString aStorageURL, bool ReadOnly )
2959 : mxSFI( xSFI )
2960 , mrModifiable( _rModifiable )
2961 , maNameContainer( new NameContainer(aType) )
2962 , mbLoaded( false )
2963 , mbIsModified( true )
2964 , mbInitialised( false )
2965 , maLibInfoFileURL(std::move( aLibInfoFileURL ))
2966 , maStorageURL(std::move( aStorageURL ))
2967 , mbLink( true )
2968 , mbReadOnly( false )
2969 , mbReadOnlyLink( ReadOnly )
2970 , mbPreload( false )
2971 , mbPasswordProtected( false )
2972 , mbPasswordVerified( false )
2973 , mbDoc50Password( false )
2974 , mbSharedIndexFile( false )
2975 , mbExtension( false )
2976{
2977}
2978
2980{
2982}
2983
2984void SfxLibrary::implSetModified( bool _bIsModified )
2985{
2986 if ( mbIsModified == _bIsModified )
2987 {
2988 return;
2989 }
2990 mbIsModified = _bIsModified;
2991 if ( mbIsModified )
2992 {
2993 mrModifiable.setModified( true );
2994 }
2995}
2996
2997// Methods XInterface
2998Any SAL_CALL SfxLibrary::queryInterface( const Type& rType )
2999{
3000 Any aRet =
3001 ::cppu::queryInterface(
3002 rType,
3003 static_cast< XContainer * >( this ),
3004 static_cast< XNameContainer * >( this ),
3005 static_cast< XNameAccess * >( this ),
3006 static_cast< XElementAccess * >( this ),
3007 static_cast< XChangesNotifier * >( this ) );
3008 if( !aRet.hasValue() )
3009 {
3010 aRet = WeakComponentImplHelper::queryInterface( rType );
3011 }
3012 return aRet;
3013}
3014
3015// Methods XElementAccess
3017{
3018 return maNameContainer->getElementType();
3019}
3020
3022{
3023 bool bRet = maNameContainer->hasElements();
3024 return bRet;
3025}
3026
3027// Methods XNameAccess
3028Any SfxLibrary::getByName( const OUString& aName )
3029{
3031
3032 Any aRetAny = maNameContainer->getByName( aName ) ;
3033 return aRetAny;
3034}
3035
3037{
3038 return maNameContainer->getElementNames();
3039}
3040
3041sal_Bool SfxLibrary::hasByName( const OUString& aName )
3042{
3043 bool bRet = maNameContainer->hasByName( aName );
3044 return bRet;
3045}
3046
3048{
3049 if( mbReadOnly || (mbLink && mbReadOnlyLink) )
3050 {
3051 throw IllegalArgumentException(
3052 "Library is readonly.",
3053 // TODO: resource
3054 *this, 0
3055 );
3056 }
3057}
3058
3060{
3061 if ( !mbLoaded )
3062 {
3063 throw WrappedTargetException(
3064 OUString(),
3065 *this,
3066 Any( LibraryNotLoadedException(
3067 OUString(),
3068 *this
3069 ) )
3070 );
3071 }
3072}
3073
3074// Methods XNameReplace
3075void SfxLibrary::replaceByName( const OUString& aName, const Any& aElement )
3076{
3079
3081 !isLibraryElementValid(aElement), "basic",
3082 "SfxLibrary::replaceByName: replacing element is invalid!");
3083
3084 maNameContainer->replaceByName( aName, aElement );
3085 implSetModified( true );
3086}
3087
3088
3089// Methods XNameContainer
3090void SfxLibrary::insertByName( const OUString& aName, const Any& aElement )
3091{
3094
3096 !isLibraryElementValid(aElement), "basic",
3097 "SfxLibrary::insertByName: to-be-inserted element is invalid!");
3098
3099 maNameContainer->insertByName( aName, aElement );
3100 implSetModified( true );
3101}
3102
3103void SfxLibrary::impl_removeWithoutChecks( const OUString& _rElementName )
3104{
3105 maNameContainer->removeByName( _rElementName );
3106 implSetModified( true );
3107
3108 // Remove element file
3109 if( maStorageURL.isEmpty() )
3110 return;
3111
3112 INetURLObject aElementInetObj( maStorageURL );
3113 aElementInetObj.insertName( _rElementName, false,
3116 aElementInetObj.setExtension( maLibElementFileExtension );
3117 OUString aFile = aElementInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
3118
3119 try
3120 {
3121 if( mxSFI->exists( aFile ) )
3122 {
3123 mxSFI->kill( aFile );
3124 }
3125 }
3126 catch(const Exception& )
3127 {
3128 DBG_UNHANDLED_EXCEPTION("basic");
3129 }
3130}
3131
3132void SfxLibrary::removeByName( const OUString& Name )
3133{
3137}
3138
3139// XTypeProvider
3141{
3142 static OTypeCollection ourTypes_NameContainer(
3146 WeakComponentImplHelper::getTypes() );
3147
3148 return ourTypes_NameContainer.getTypes();
3149}
3150
3151
3153{
3154 return css::uno::Sequence<sal_Int8>();
3155}
3156
3157// Methods XContainer
3159{
3160 maNameContainer->setEventSource( getXWeak() );
3161 maNameContainer->addContainerListener( xListener );
3162}
3163
3165{
3166 maNameContainer->removeContainerListener( xListener );
3167}
3168
3169// Methods XChangesNotifier
3171{
3172 maNameContainer->setEventSource( getXWeak() );
3173 maNameContainer->addChangesListener( xListener );
3174}
3175
3177{
3178 maNameContainer->removeChangesListener( xListener );
3179}
3180
3181
3182// Implementation class ScriptExtensionIterator
3183
3184constexpr OUStringLiteral sBasicLibMediaType = u"application/vnd.sun.star.basic-library";
3185constexpr OUStringLiteral sDialogLibMediaType = u"application/vnd.sun.star.dialog-library";
3186
3189 , m_eState( USER_EXTENSIONS )
3190 , m_bUserPackagesLoaded( false )
3191 , m_bSharedPackagesLoaded( false )
3192 , m_bBundledPackagesLoaded( false )
3193 , m_iUserPackage( 0 )
3194 , m_iSharedPackage( 0 )
3195 , m_iBundledPackage( 0 )
3196 , m_pScriptSubPackageIterator( nullptr )
3197{}
3198
3200{
3201 OUString aRetLib;
3202
3203 while( aRetLib.isEmpty() && m_eState != END_REACHED )
3204 {
3205 switch( m_eState )
3206 {
3207 case USER_EXTENSIONS:
3208 {
3209 Reference< deployment::XPackage > xScriptPackage =
3210 implGetNextUserScriptPackage( rbPureDialogLib );
3211 if( !xScriptPackage.is() )
3212 {
3213 break;
3214 }
3215 aRetLib = xScriptPackage->getURL();
3216 break;
3217 }
3218
3219 case SHARED_EXTENSIONS:
3220 {
3221 Reference< deployment::XPackage > xScriptPackage =
3222 implGetNextSharedScriptPackage( rbPureDialogLib );
3223 if( !xScriptPackage.is() )
3224 {
3225 break;
3226 }
3227 aRetLib = xScriptPackage->getURL();
3228 break;
3229 }
3230 case BUNDLED_EXTENSIONS:
3231 {
3232 Reference< deployment::XPackage > xScriptPackage =
3233 implGetNextBundledScriptPackage( rbPureDialogLib );
3234 if( !xScriptPackage.is() )
3235 {
3236 break;
3237 }
3238 aRetLib = xScriptPackage->getURL();
3239 break;
3240 }
3241 case END_REACHED:
3242 SAL_WARN(
3243 "basic",
3244 ("ScriptExtensionIterator::nextBasicOrDialogLibrary():"
3245 " Invalid case END_REACHED"));
3246 break;
3247 }
3248 }
3249
3250 return aRetLib;
3251}
3252
3254 : m_xMainPackage( xMainPackage )
3255 , m_bIsValid( false )
3256 , m_bIsBundle( false )
3257 , m_nSubPkgCount( 0 )
3258 , m_iNextSubPkg( 0 )
3259{
3260 if( !m_xMainPackage.is() )
3261 {
3262 return;
3263 }
3264 // Check if parent package is registered
3265 beans::Optional< beans::Ambiguous<sal_Bool> > option( m_xMainPackage->isRegistered
3267 bool bRegistered = false;
3268 if( option.IsPresent )
3269 {
3270 beans::Ambiguous<sal_Bool> const & reg = option.Value;
3271 if( !reg.IsAmbiguous && reg.Value )
3272 {
3273 bRegistered = true;
3274 }
3275 }
3276 if( bRegistered )
3277 {
3278 m_bIsValid = true;
3279 if( m_xMainPackage->isBundle() )
3280 {
3281 m_bIsBundle = true;
3284 m_nSubPkgCount = m_aSubPkgSeq.getLength();
3285 }
3286 }
3287}
3288
3290{
3291 rbPureDialogLib = false;
3292
3293 Reference< deployment::XPackage > xScriptPackage;
3294 if( !m_bIsValid )
3295 {
3296 return xScriptPackage;
3297 }
3298 if( m_bIsBundle )
3299 {
3300 const Reference< deployment::XPackage >* pSeq = m_aSubPkgSeq.getConstArray();
3301 sal_Int32 iPkg;
3302 for( iPkg = m_iNextSubPkg ; iPkg < m_nSubPkgCount ; ++iPkg )
3303 {
3304 const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
3305 xScriptPackage = implDetectScriptPackage( xSubPkg, rbPureDialogLib );
3306 if( xScriptPackage.is() )
3307 {
3308 break;
3309 }
3310 }
3311 m_iNextSubPkg = iPkg + 1;
3312 }
3313 else
3314 {
3315 xScriptPackage = implDetectScriptPackage( m_xMainPackage, rbPureDialogLib );
3316 m_bIsValid = false; // No more script packages
3317 }
3318
3319 return xScriptPackage;
3320}
3321
3323 bool& rbPureDialogLib )
3324{
3325 Reference< deployment::XPackage > xScriptPackage;
3326
3327 if( rPackage.is() )
3328 {
3329 const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = rPackage->getPackageType();
3330 OUString aMediaType = xPackageTypeInfo->getMediaType();
3331 if ( aMediaType == sBasicLibMediaType )
3332 {
3333 xScriptPackage = rPackage;
3334 }
3335 else if ( aMediaType == sDialogLibMediaType )
3336 {
3337 rbPureDialogLib = true;
3338 xScriptPackage = rPackage;
3339 }
3340 }
3341
3342 return xScriptPackage;
3343}
3344
3346{
3347 Reference< deployment::XPackage > xScriptPackage;
3348
3350 {
3351 try
3352 {
3353 Reference< XExtensionManager > xManager = ExtensionManager::get( m_xContext );
3354 m_aUserPackagesSeq = xManager->getDeployedExtensions("user",
3357 }
3358 catch(const css::uno::DeploymentException& )
3359 {
3360 // Special Office installations may not contain deployment code
3362 return xScriptPackage;
3363 }
3364
3365 m_bUserPackagesLoaded = true;
3366 }
3367
3368 if( m_iUserPackage == m_aUserPackagesSeq.getLength() )
3369 {
3370 m_eState = SHARED_EXTENSIONS; // Later: SHARED_MODULE
3371 }
3372 else
3373 {
3374 if( m_pScriptSubPackageIterator == nullptr )
3375 {
3376 const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray();
3377 Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage ];
3379 !xPackage.is(), "basic",
3380 ("ScriptExtensionIterator::implGetNextUserScriptPackage():"
3381 " Invalid package"));
3383 }
3384
3385 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3386 if( !xScriptPackage.is() )
3387 {
3391 }
3392 }
3393
3394 return xScriptPackage;
3395}
3396
3398{
3399 Reference< deployment::XPackage > xScriptPackage;
3400
3402 {
3403 try
3404 {
3405 Reference< XExtensionManager > xSharedManager = ExtensionManager::get( m_xContext );
3406 m_aSharedPackagesSeq = xSharedManager->getDeployedExtensions("shared",
3409 }
3410 catch(const css::uno::DeploymentException& )
3411 {
3412 // Special Office installations may not contain deployment code
3413 return xScriptPackage;
3414 }
3415
3417 }
3418
3419 if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() )
3420 {
3422 }
3423 else
3424 {
3425 if( m_pScriptSubPackageIterator == nullptr )
3426 {
3427 const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray();
3428 Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage ];
3430 !xPackage.is(), "basic",
3431 ("ScriptExtensionIterator::implGetNextSharedScriptPackage():"
3432 " Invalid package"));
3434 }
3435
3436 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3437 if( !xScriptPackage.is() )
3438 {
3442 }
3443 }
3444
3445 return xScriptPackage;
3446}
3447
3449{
3450 Reference< deployment::XPackage > xScriptPackage;
3451
3453 {
3454 try
3455 {
3456 Reference< XExtensionManager > xManager = ExtensionManager::get( m_xContext );
3457 m_aBundledPackagesSeq = xManager->getDeployedExtensions("bundled",
3460 }
3461 catch(const css::uno::DeploymentException& )
3462 {
3463 // Special Office installations may not contain deployment code
3464 return xScriptPackage;
3465 }
3466
3468 }
3469
3470 if( m_iBundledPackage == m_aBundledPackagesSeq.getLength() )
3471 {
3473 }
3474 else
3475 {
3476 if( m_pScriptSubPackageIterator == nullptr )
3477 {
3478 const Reference< deployment::XPackage >* pBundledPackages = m_aBundledPackagesSeq.getConstArray();
3479 Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage ];
3481 !xPackage.is(), "basic",
3482 ("ScriptExtensionIterator::implGetNextBundledScriptPackage():"
3483 " Invalid package"));
3485 }
3486
3487 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3488 if( !xScriptPackage.is() )
3489 {
3493 }
3494 }
3495
3496 return xScriptPackage;
3497}
3498
3499} // namespace basic
3500
3501/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XComponentContext > m_xContext
const char * pName
Reference< XInputStream > xStream
AnyEventRef aEvent
static comphelper::SolarMutex & GetSolarMutex()
StarBASIC * GetLib(sal_uInt16 nLib) const
Definition: basmgr.cxx:1169
void SetName(const OUString &rName)
Definition: basmgr.hxx:134
const OUString & GetName() const
Definition: basmgr.hxx:135
static DialogMask HandleError(ErrCode nId, weld::Window *pParent=nullptr, DialogMask nMask=DialogMask::MAX)
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
OUString getExtension(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
bool removeSegment(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true)
bool insertName(std::u16string_view rTheName, bool bAppendFinalSlash=false, sal_Int32 nIndex=LAST_SEGMENT, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
bool setExtension(std::u16string_view rTheExtension, sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
bool Append(std::u16string_view rTheSegment, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
bool IsOLEStorage() const
const OUString & GetBasicPath() const
static BasicManager * getDocumentBasicManager(const css::uno::Reference< css::frame::XModel > &_rxDocumentModel)
returns the BasicManager belonging to the given document
void setModified(bool _bModified)
Definition: namecont.cxx:327
::comphelper::OInterfaceContainerHelper3< css::util::XModifyListener > m_aModifyListeners
Definition: namecont.hxx:133
void addModifyListener(const css::uno::Reference< css::util::XModifyListener > &_rxListener)
Definition: namecont.hxx:148
bool isModified() const
Definition: namecont.hxx:145
::cppu::OWeakObject & m_rEventSource
Definition: namecont.hxx:134
void removeModifyListener(const css::uno::Reference< css::util::XModifyListener > &_rxListener)
Definition: namecont.hxx:153
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
Definition: namecont.cxx:133
css::uno::XInterface * mpxEventSource
Definition: namecont.hxx:76
void insertCheck(const OUString &aName, const css::uno::Any &aElement)
Definition: namecont.cxx:183
virtual void SAL_CALL replaceByName(const OUString &aName, const css::uno::Any &aElement) override
std::vector< css::uno::Any > mValues
Definition: namecont.hxx:72
virtual void SAL_CALL addContainerListener(const css::uno::Reference< css::container::XContainerListener > &xListener) override
Definition: namecont.cxx:287
css::uno::Type mType
Definition: namecont.hxx:75
sal_Int32 mnElementCount
Definition: namecont.hxx:73
NameContainerNameMap mHashMap
Definition: namecont.hxx:70
::comphelper::OInterfaceContainerHelper3< css::container::XContainerListener > maContainerListeners
Definition: namecont.hxx:78
virtual void SAL_CALL insertByName(const OUString &aName, const css::uno::Any &aElement) override
virtual void SAL_CALL addChangesListener(const css::uno::Reference< css::util::XChangesListener > &xListener) override
Definition: namecont.cxx:306
virtual sal_Bool SAL_CALL hasElements() override
Definition: namecont.cxx:109
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
Definition: namecont.cxx:128
::comphelper::OInterfaceContainerHelper3< css::util::XChangesListener > maChangesListeners
Definition: namecont.hxx:79
virtual void SAL_CALL removeChangesListener(const css::uno::Reference< css::util::XChangesListener > &xListener) override
Definition: namecont.cxx:315
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
Definition: namecont.cxx:116
virtual void SAL_CALL removeByName(const OUString &Name) override
Definition: namecont.cxx:237
virtual void SAL_CALL removeContainerListener(const css::uno::Reference< css::container::XContainerListener > &xListener) override
Definition: namecont.cxx:296
void insertNoCheck(const OUString &aName, const css::uno::Any &aElement)
Definition: namecont.cxx:193
virtual css::uno::Type SAL_CALL getElementType() override
Definition: namecont.cxx:104
std::vector< OUString > mNames
Definition: namecont.hxx:71
css::uno::Reference< css::deployment::XPackage > implGetNextBundledScriptPackage(bool &rbPureDialogLib)
Definition: namecont.cxx:3448
ScriptSubPackageIterator * m_pScriptSubPackageIterator
Definition: namecont.hxx:660
css::uno::Sequence< css::uno::Reference< css::deployment::XPackage > > m_aSharedPackagesSeq
Definition: namecont.hxx:650
OUString nextBasicOrDialogLibrary(bool &rbPureDialogLib)
Definition: namecont.cxx:3199
css::uno::Sequence< css::uno::Reference< css::deployment::XPackage > > m_aBundledPackagesSeq
Definition: namecont.hxx:653
css::uno::Reference< css::uno::XComponentContext > m_xContext
Definition: namecont.hxx:637
enum basic::ScriptExtensionIterator::IteratorState m_eState
css::uno::Reference< css::deployment::XPackage > implGetNextSharedScriptPackage(bool &rbPureDialogLib)
Definition: namecont.cxx:3397
css::uno::Sequence< css::uno::Reference< css::deployment::XPackage > > m_aUserPackagesSeq
Definition: namecont.hxx:647
css::uno::Reference< css::deployment::XPackage > implGetNextUserScriptPackage(bool &rbPureDialogLib)
Definition: namecont.cxx:3345
static css::uno::Reference< css::deployment::XPackage > implDetectScriptPackage(const css::uno::Reference< css::deployment::XPackage > &rPackage, bool &rbPureDialogLib)
Definition: namecont.cxx:3322
css::uno::Reference< css::deployment::XPackage > getNextScriptSubPackage(bool &rbPureDialogLib)
Definition: namecont.cxx:3289
css::uno::Sequence< css::uno::Reference< css::deployment::XPackage > > m_aSubPkgSeq
Definition: namecont.hxx:608
ScriptSubPackageIterator(css::uno::Reference< css::deployment::XPackage > const &xMainPackage)
Definition: namecont.cxx:3253
css::uno::Reference< css::deployment::XPackage > m_xMainPackage
Definition: namecont.hxx:603
virtual void SAL_CALL setVBACompatibilityMode(sal_Bool _vbacompatmodeon) override
Definition: namecont.cxx:2794
virtual sal_Bool SAL_CALL isLibraryPasswordProtected(const OUString &Name) override
Definition: namecont.cxx:2685
virtual void writeLibraryElement(const css::uno::Reference< css::container::XNameContainer > &xLibrary, const OUString &aElementName, const css::uno::Reference< css::io::XOutputStream > &xOutput)=0
virtual css::uno::Any createEmptyLibraryElement()=0
virtual void SAL_CALL removeVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: namecont.cxx:2921
rtl_TextEncoding meVBATextEncoding
Definition: namecont.hxx:186
virtual bool implStorePasswordLibrary(SfxLibrary *pLib, const OUString &aName, const css::uno::Reference< css::embed::XStorage > &xStorage, const css::uno::Reference< css::task::XInteractionHandler > &Handler)
enum basic::SfxLibraryContainer::InitMode meInitMode
bool implLoadLibraryIndexFile(SfxLibrary *pLib, ::xmlscript::LibDescriptor &rLib, const css::uno::Reference< css::embed::XStorage > &xStorage, const OUString &aIndexFileName)
Definition: namecont.cxx:1610
virtual rtl::Reference< SfxLibraryContainer > createInstanceImpl()=0
virtual css::uno::Reference< css::container::XNameContainer > SAL_CALL createLibrary(const OUString &Name) override
Definition: namecont.cxx:2139
virtual sal_Bool SAL_CALL isLibraryLink(const OUString &Name) override
Definition: namecont.cxx:2422
virtual void SAL_CALL removeLibrary(const OUString &Name) override
Definition: namecont.cxx:2204
virtual sal_Bool SAL_CALL verifyLibraryPassword(const OUString &Name, const OUString &Password) override
Definition: namecont.cxx:2695
OUString maLibElementFileExtension
Definition: namecont.hxx:202
static void leaveMethod()
Definition: namecont.cxx:383
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &aArguments) override
Definition: namecont.cxx:2610
void implImportLibDescriptor(SfxLibrary *pLib, ::xmlscript::LibDescriptor const &rLib)
Definition: namecont.cxx:1706
virtual css::uno::Type SAL_CALL getElementType() override
Definition: namecont.cxx:2105
virtual sal_Bool SAL_CALL isModified() override
Definition: namecont.cxx:451
OUString createAppLibraryFolder(SfxLibrary *pLib, std::u16string_view aName)
Definition: namecont.cxx:1323
virtual void SAL_CALL setLibraryReadOnly(const OUString &Name, sal_Bool bReadOnly) override
Definition: namecont.cxx:2451
virtual css::uno::Any SAL_CALL getRootLocation() override
Definition: namecont.cxx:512
virtual sal_Int32 SAL_CALL getRunningVBAScripts() override
Definition: namecont.cxx:2846
virtual bool implLoadPasswordLibrary(SfxLibrary *pLib, const OUString &Name, bool bVerifyPasswordOnly=false)
Definition: namecont.cxx:1315
virtual void SAL_CALL exportLibrary(const OUString &Name, const OUString &URL, const css::uno::Reference< css::task::XInteractionHandler > &Handler) override
Definition: namecont.cxx:2720
virtual void importFromOldStorage(const OUString &aFile)=0
virtual OUString getInfoFileName() const =0
OUString expand_url(const OUString &url)
Definition: namecont.cxx:2756
virtual ~SfxLibraryContainer() override
Definition: namecont.cxx:366
virtual void SAL_CALL setRootStorage(const css::uno::Reference< css::embed::XStorage > &_rootstorage) override
Definition: namecont.cxx:420
css::uno::Reference< css::uno::XComponentContext > mxContext
Definition: namecont.hxx:188
virtual void SAL_CALL addVBAScriptListener(const css::uno::Reference< css::script::vba::XVBAScriptListener > &Listener) override
Definition: namecont.cxx:2852
virtual OUString SAL_CALL getContainerLocationName() override
Definition: namecont.cxx:518
virtual void SAL_CALL changeLibraryPassword(const OUString &Name, const OUString &OldPassword, const OUString &NewPassword) override
Definition: namecont.cxx:2700
virtual css::uno::Any importLibraryElement(const css::uno::Reference< css::container::XNameContainer > &xLibrary, const OUString &aElementName, const OUString &aFile, const css::uno::Reference< css::io::XInputStream > &xElementStream)=0
virtual void SAL_CALL disposing() override
Definition: namecont.cxx:2675
virtual void SAL_CALL addVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: namecont.cxx:2915
virtual void SAL_CALL renameLibrary(const OUString &Name, const OUString &NewName) override
Definition: namecont.cxx:2474
virtual void SAL_CALL removeVBAScriptListener(const css::uno::Reference< css::script::vba::XVBAScriptListener > &Listener) override
Definition: namecont.cxx:2857
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: namecont.cxx:2883
virtual void SAL_CALL removeModifyListener(const css::uno::Reference< css::util::XModifyListener > &aListener) override
Definition: namecont.cxx:505
virtual sal_Bool SAL_CALL hasElements() override
Definition: namecont.cxx:2111
virtual OUString getLibrariesDir() const =0
virtual bool isLibraryElementValid(const css::uno::Any &rElement) const =0
void init_Impl(const OUString &rInitialDocumentURL, const css::uno::Reference< css::embed::XStorage > &_rxInitialStorage)
Definition: namecont.cxx:586
virtual void SAL_CALL removePropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &aListener) override
Definition: namecont.cxx:2909
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: namecont.cxx:2928
virtual void onNewRootStorage()=0
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
Definition: namecont.cxx:2119
void init(const OUString &rInitialDocumentURL, const css::uno::Reference< css::embed::XStorage > &_rxInitialStorage)
Definition: namecont.cxx:576
virtual void SAL_CALL loadLibrary(const OUString &Name) override
Definition: namecont.cxx:2283
void implStoreLibraryIndexFile(SfxLibrary *pLib, const ::xmlscript::LibDescriptor &rLib, const css::uno::Reference< css::embed::XStorage > &xStorage)
static constexpr OUStringLiteral sVBATextEncodingPropName
Definition: namecont.hxx:334
css::uno::Reference< css::ucb::XSimpleFileAccess3 > mxSFI
Definition: namecont.hxx:189
css::uno::Reference< css::embed::XStorage > mxStorage
Definition: namecont.hxx:206
virtual sal_Bool SAL_CALL getVBACompatibilityMode() override
Definition: namecont.cxx:2789
void implStoreLibrary(SfxLibrary *pLib, std::u16string_view rName, const css::uno::Reference< css::embed::XStorage > &rStorage)
virtual void SAL_CALL setProjectName(const OUString &_projectname) override
Definition: namecont.cxx:2832
virtual OUString SAL_CALL getOriginalLibraryLinkURL(const OUString &Name) override
Definition: namecont.cxx:2774
virtual sal_Bool SAL_CALL isLibraryReadOnly(const OUString &Name) override
Definition: namecont.cxx:2443
virtual void SAL_CALL setModified(sal_Bool bModified) override
Definition: namecont.cxx:493
VBAScriptListenerContainer maVBAScriptListeners
Definition: namecont.hxx:182
ModifiableHelper maModifiable
Definition: namecont.hxx:193
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
Definition: namecont.cxx:2132
virtual void SAL_CALL broadcastVBAScriptEvent(sal_Int32 nIdentifier, const OUString &rModuleName) override
Definition: namecont.cxx:2862
virtual rtl::Reference< SfxLibrary > implCreateLibrary(const OUString &aName)=0
virtual sal_Bool SAL_CALL isLibraryPasswordVerified(const OUString &Name) override
Definition: namecont.cxx:2690
virtual void SAL_CALL addPropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: namecont.cxx:2903
void initializeFromDocument(const css::uno::Reference< css::document::XStorageBasedDocument > &_rxDocument)
Definition: namecont.cxx:2634
virtual void SAL_CALL removeContainerListener(const css::uno::Reference< css::container::XContainerListener > &xListener) override
Definition: namecont.cxx:2713
BasicManager * getBasicManager()
Definition: namecont.cxx:388
void storeLibraries_Impl(const css::uno::Reference< css::embed::XStorage > &xStorage, bool bComplete)
Definition: namecont.cxx:1728
void checkStorageURL(const OUString &aSourceURL, OUString &aLibInfoFileURL, OUString &aStorageURL, OUString &aUnexpandedStorageURL)
Definition: namecont.cxx:1255
virtual void SAL_CALL storeLibrariesToStorage(const css::uno::Reference< css::embed::XStorage > &RootStorage) override
Definition: namecont.cxx:431
css::uno::Reference< css::util::XStringSubstitution > mxStringSubstitution
Definition: namecont.hxx:190
virtual OUString getOldInfoFileName() const =0
BasicManager * mpBasMgr
Definition: namecont.hxx:207
virtual void SAL_CALL addContainerListener(const css::uno::Reference< css::container::XContainerListener > &xListener) override
Definition: namecont.cxx:2706
virtual OUString getLibElementFileExtension() const =0
SfxLibrary * getImplLib(const OUString &rLibraryName)
Definition: namecont.cxx:1283
virtual rtl::Reference< SfxLibrary > implCreateLibraryLink(const OUString &aName, const OUString &aLibInfoFileURL, const OUString &StorageURL, bool ReadOnly)=0
virtual void SAL_CALL storeLibraries() override
Definition: namecont.cxx:524
virtual css::uno::Reference< css::container::XNameAccess > SAL_CALL createLibraryLink(const OUString &Name, const OUString &StorageURL, sal_Bool ReadOnly) override
Definition: namecont.cxx:2160
virtual void SAL_CALL addModifyListener(const css::uno::Reference< css::util::XModifyListener > &aListener) override
Definition: namecont.cxx:499
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
Definition: namecont.cxx:2126
virtual void _disposing(const css::lang::EventObject &_rSource) override
Definition: namecont.cxx:2661
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
Definition: namecont.cxx:2888
css::uno::WeakReference< css::frame::XModel > mxOwnerDocument
Definition: namecont.hxx:191
virtual css::uno::Reference< css::embed::XStorage > SAL_CALL getRootStorage() override
Definition: namecont.cxx:414
virtual sal_Bool SAL_CALL isLibraryLoaded(const OUString &Name) override
Definition: namecont.cxx:2274
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
Definition: namecont.cxx:2896
rtl::Reference< NameContainer > maNameContainer
Definition: namecont.hxx:195
virtual OUString SAL_CALL getLibraryLinkURL(const OUString &Name) override
Definition: namecont.cxx:2430
virtual void SAL_CALL replaceByName(const OUString &aName, const css::uno::Any &aElement) override
Definition: namecont.cxx:3075
virtual void SAL_CALL removeByName(const OUString &Name) override
Definition: namecont.cxx:3132
void impl_checkReadOnly()
checks whether the lib is readonly, or a readonly link, throws an IllegalArgumentException if so
Definition: namecont.cxx:3047
virtual sal_Bool SAL_CALL hasElements() override
Definition: namecont.cxx:3021
bool implIsModified() const
Definition: namecont.hxx:520
OUString maLibInfoFileURL
Definition: namecont.hxx:490
virtual void SAL_CALL removeContainerListener(const css::uno::Reference< css::container::XContainerListener > &xListener) override
Definition: namecont.cxx:3164
virtual void SAL_CALL removeChangesListener(const css::uno::Reference< css::util::XChangesListener > &xListener) override
Definition: namecont.cxx:3176
virtual bool isLoadedStorable()
Definition: namecont.cxx:2979
void impl_checkLoaded()
checks whether the library is loaded, throws a LibraryNotLoadedException (wrapped in a WrappedTargetE...
Definition: namecont.cxx:3059
virtual bool isModified()=0
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
Definition: namecont.cxx:2998
rtl::Reference< NameContainer > maNameContainer
Definition: namecont.hxx:481
virtual void SAL_CALL addContainerListener(const css::uno::Reference< css::container::XContainerListener > &xListener) override
Definition: namecont.cxx:3158
virtual css::uno::Type SAL_CALL getElementType() override
Definition: namecont.cxx:3016
OUString maOriginalStorageURL
Definition: namecont.hxx:493
bool mbPasswordProtected
Definition: namecont.hxx:501
virtual void SAL_CALL insertByName(const OUString &aName, const css::uno::Any &aElement) override
Definition: namecont.cxx:3090
OUString maStorageURL
Definition: namecont.hxx:491
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
Definition: namecont.cxx:3028
css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: namecont.cxx:3140
css::uno::Reference< css::ucb::XSimpleFileAccess3 > mxSFI
Definition: namecont.hxx:478
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
Definition: namecont.cxx:3036
SfxLibrary(ModifiableHelper &_rModifiable, const css::uno::Type &aType, const css::uno::Reference< css::ucb::XSimpleFileAccess3 > &xSFI)
OUString maLibElementFileExtension
Definition: namecont.hxx:489
void implSetModified(bool _bIsModified)
Definition: namecont.cxx:2984
void impl_removeWithoutChecks(const OUString &_rElementName)
Definition: namecont.cxx:3103
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
Definition: namecont.cxx:3041
virtual void SAL_CALL addChangesListener(const css::uno::Reference< css::util::XChangesListener > &xListener) override
Definition: namecont.cxx:3170
OUString maUnexpandedStorageURL
Definition: namecont.hxx:492
virtual void storeResourcesAsURL(const OUString &URL, const OUString &NewName)=0
css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
Definition: namecont.cxx:3152
ModifiableHelper & mrModifiable
Definition: namecont.hxx:480
virtual bool isLibraryElementValid(const css::uno::Any &rElement) const =0
void removeElementWithoutChecks(const OUString &_rElementName, LibraryContainerAccess)
Definition: namecont.hxx:589
sal_Int32 addInterface(const css::uno::Reference< ListenerT > &rxIFace)
void disposeAndClear(const css::lang::EventObject &rEvt)
sal_Int32 removeInterface(const css::uno::Reference< ListenerT > &rxIFace)
void notifyEach(void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event)
static css::uno::Reference< css::embed::XStorage > GetStorageFromURL(const OUString &aURL, sal_Int32 nStorageMode, const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >())
sal_uInt32 release(bool bUnlockAll=false)
void acquire(sal_uInt32 nLockCount=1)
css::uno::Sequence< css::uno::Type > SAL_CALL getTypes()
void startComponentListening(const css::uno::Reference< css::lang::XComponent > &_rxComp)
int nCount
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
ULONG m_refCount
float u
#define ERRCODE_IO_GENERAL
Reference< XSingleServiceFactory > xFactory
bool bReadOnly
std::mutex m_aMutex
OUString aName
const char * pLib
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
constexpr OUStringLiteral sDialogLibMediaType
Definition: namecont.cxx:3185
static void checkAndCopyFileImpl(const INetURLObject &rSourceFolderInetObj, const INetURLObject &rTargetFolderInetObj, std::u16string_view rCheckFileName, std::u16string_view rCheckExtension, const Reference< XSimpleFileAccess3 > &xSFI)
Definition: namecont.cxx:540
static void createVariableURL(OUString &rStr, std::u16string_view rLibName, std::u16string_view rInfoFileName, bool bUser)
Definition: namecont.cxx:562
static bool GbMigrationSuppressErrors
Definition: namecont.cxx:98
::cppu::WeakComponentImplHelper< css::lang::XInitialization, css::script::XStorageBasedLibraryContainer, css::script::XLibraryContainerPassword, css::script::XLibraryContainerExport, css::script::XLibraryContainer3, css::container::XContainer, css::script::XLibraryQueryExecutable, css::script::vba::XVBACompatibility, css::lang::XServiceInfo, css::beans::XPropertySet > SfxLibraryContainer_BASE
Definition: namecont.hxx:163
constexpr OUStringLiteral sBasicLibMediaType
Definition: namecont.cxx:3184
@ Exception
COMPHELPER_DLLPUBLIC OUString getExpandedUri(css::uno::Reference< css::uno::XComponentContext > const &context, OUString const &uri)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
Reference< XComponentContext > getProcessComponentContext()
Type
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int i
index
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
void dispose()
void exportLibraryContainer(Reference< xml::sax::XWriter > const &xOut, const LibDescriptorArray *pLibArray)
void exportLibrary(css::uno::Reference< css::xml::sax::XWriter > const &xOut, const LibDescriptor &rLib)
#define ERRCTX_SFX_LOADBASIC
#define ERRCTX_SFX_SAVEDOC
OUString sMessage
css::uno::Sequence< OUString > aElementNames
Reference< XModel > xModel
@ READ
Definition: token.hxx:80
OUString Name
JCOPY_OPTION option
unsigned char sal_Bool
OUString aTargetURL