Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / basic / source / basmgr / basmgr.cxx
blob46fa3740777abc03a33e1d43a5f5717c036885c2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <vcl/errinf.hxx>
21 #include <tools/stream.hxx>
22 #include <sot/storage.hxx>
23 #include <tools/urlobj.hxx>
24 #include <svl/hint.hxx>
25 #include <basic/sbx.hxx>
26 #include <basic/sbmeth.hxx>
27 #include <sot/storinfo.hxx>
28 #include <unotools/pathoptions.hxx>
29 #include <tools/debug.hxx>
30 #include <tools/diagnose_ex.h>
31 #include <basic/sbmod.hxx>
32 #include <unotools/transliterationwrapper.hxx>
33 #include <sal/log.hxx>
35 #include <basic/sberrors.hxx>
36 #include <basic/sbuno.hxx>
37 #include <basic/basmgr.hxx>
38 #include <global.hxx>
39 #include <com/sun/star/script/XLibraryContainer.hpp>
40 #include <com/sun/star/script/XPersistentLibraryContainer.hpp>
42 #include <memory>
43 #include <vector>
45 #define LIB_SEP 0x01
46 #define LIBINFO_SEP 0x02
47 #define LIBINFO_ID 0x1491
48 #define PASSWORD_MARKER 0x31452134
51 // Library API, implemented for XML import/export
53 #include <com/sun/star/container/XNameContainer.hpp>
54 #include <com/sun/star/container/XContainer.hpp>
55 #include <com/sun/star/script/XStarBasicAccess.hpp>
56 #include <com/sun/star/script/XStarBasicModuleInfo.hpp>
57 #include <com/sun/star/script/XStarBasicDialogInfo.hpp>
58 #include <com/sun/star/script/XStarBasicLibraryInfo.hpp>
59 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
60 #include <com/sun/star/script/ModuleInfo.hpp>
61 #include <com/sun/star/script/vba/XVBACompatibility.hpp>
62 #include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
63 #include <com/sun/star/ucb/ContentCreationException.hpp>
65 #include <cppuhelper/implbase.hxx>
67 using com::sun::star::uno::Reference;
68 using namespace com::sun::star;
69 using namespace com::sun::star::script;
70 using namespace cppu;
72 typedef WeakImplHelper< container::XNameContainer > NameContainerHelper;
73 typedef WeakImplHelper< script::XStarBasicModuleInfo > ModuleInfoHelper;
74 typedef WeakImplHelper< script::XStarBasicAccess > StarBasicAccessHelper;
76 // Version 1
77 // sal_uInt32 nEndPos
78 // sal_uInt16 nId
79 // sal_uInt16 nVer
80 // bool bDoLoad
81 // String LibName
82 // String AbsStorageName
83 // String RelStorageName
84 // Version 2
85 // + bool bReference
87 static const char szStdLibName[] = "Standard";
88 static const char szBasicStorage[] = "StarBASIC";
89 static const char szOldManagerStream[] = "BasicManager";
90 static const char szManagerStream[] = "BasicManager2";
91 static const char szImbedded[] = "LIBIMBEDDED";
92 static const char szCryptingKey[] = "CryptedBasic";
95 const StreamMode eStreamReadMode = StreamMode::READ | StreamMode::NOCREATE | StreamMode::SHARE_DENYALL;
96 const StreamMode eStorageReadMode = StreamMode::READ | StreamMode::SHARE_DENYWRITE;
99 // BasicManager impl data
100 struct BasicManagerImpl
102 LibraryContainerInfo maContainerInfo;
104 std::vector<std::unique_ptr<BasicLibInfo>> aLibs;
105 OUString aBasicLibPath;
107 BasicManagerImpl()
111 // BasMgrContainerListenerImpl
114 typedef ::cppu::WeakImplHelper< container::XContainerListener > ContainerListenerHelper;
116 class BasMgrContainerListenerImpl: public ContainerListenerHelper
118 BasicManager* mpMgr;
119 OUString maLibName; // empty -> no lib, but lib container
121 public:
122 BasMgrContainerListenerImpl( BasicManager* pMgr, const OUString& aLibName )
123 : mpMgr( pMgr )
124 , maLibName( aLibName ) {}
126 static void insertLibraryImpl( const uno::Reference< script::XLibraryContainer >& xScriptCont, BasicManager* pMgr,
127 const uno::Any& aLibAny, const OUString& aLibName );
128 static void addLibraryModulesImpl( BasicManager const * pMgr, const uno::Reference< container::XNameAccess >& xLibNameAccess,
129 const OUString& aLibName );
132 // XEventListener
133 virtual void SAL_CALL disposing( const lang::EventObject& Source ) override;
135 // XContainerListener
136 virtual void SAL_CALL elementInserted( const container::ContainerEvent& Event ) override;
137 virtual void SAL_CALL elementReplaced( const container::ContainerEvent& Event ) override;
138 virtual void SAL_CALL elementRemoved( const container::ContainerEvent& Event ) override;
142 // BasMgrContainerListenerImpl
145 void BasMgrContainerListenerImpl::insertLibraryImpl( const uno::Reference< script::XLibraryContainer >& xScriptCont,
146 BasicManager* pMgr, const uno::Any& aLibAny, const OUString& aLibName )
148 Reference< container::XNameAccess > xLibNameAccess;
149 aLibAny >>= xLibNameAccess;
151 if( !pMgr->GetLib( aLibName ) )
153 StarBASIC* pLib =
154 pMgr->CreateLibForLibContainer( aLibName, xScriptCont );
155 DBG_ASSERT( pLib, "XML Import: Basic library could not be created");
158 uno::Reference< container::XContainer> xLibContainer( xLibNameAccess, uno::UNO_QUERY );
159 if( xLibContainer.is() )
161 // Register listener for library
162 Reference< container::XContainerListener > xLibraryListener
163 = new BasMgrContainerListenerImpl( pMgr, aLibName );
164 xLibContainer->addContainerListener( xLibraryListener );
167 if( xScriptCont->isLibraryLoaded( aLibName ) )
169 addLibraryModulesImpl( pMgr, xLibNameAccess, aLibName );
174 void BasMgrContainerListenerImpl::addLibraryModulesImpl( BasicManager const * pMgr,
175 const uno::Reference< container::XNameAccess >& xLibNameAccess, const OUString& aLibName )
177 uno::Sequence< OUString > aModuleNames = xLibNameAccess->getElementNames();
178 sal_Int32 nModuleCount = aModuleNames.getLength();
180 StarBASIC* pLib = pMgr->GetLib( aLibName );
181 DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::addLibraryModulesImpl: Unknown lib!");
182 if( pLib )
184 const OUString* pNames = aModuleNames.getConstArray();
185 for( sal_Int32 j = 0 ; j < nModuleCount ; j++ )
187 OUString aModuleName = pNames[ j ];
188 uno::Any aElement = xLibNameAccess->getByName( aModuleName );
189 OUString aMod;
190 aElement >>= aMod;
191 uno::Reference< vba::XVBAModuleInfo > xVBAModuleInfo( xLibNameAccess, uno::UNO_QUERY );
192 if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aModuleName ) )
194 ModuleInfo aInfo = xVBAModuleInfo->getModuleInfo( aModuleName );
195 pLib->MakeModule( aModuleName, aInfo, aMod );
197 else
198 pLib->MakeModule( aModuleName, aMod );
201 pLib->SetModified( false );
206 // XEventListener
209 void SAL_CALL BasMgrContainerListenerImpl::disposing( const lang::EventObject& ) {}
211 // XContainerListener
214 void SAL_CALL BasMgrContainerListenerImpl::elementInserted( const container::ContainerEvent& Event )
216 bool bLibContainer = maLibName.isEmpty();
217 OUString aName;
218 Event.Accessor >>= aName;
220 if( bLibContainer )
222 uno::Reference< script::XLibraryContainer > xScriptCont( Event.Source, uno::UNO_QUERY );
223 if (xScriptCont.is())
224 insertLibraryImpl(xScriptCont, mpMgr, Event.Element, aName);
225 StarBASIC* pLib = mpMgr->GetLib( aName );
226 if ( pLib )
228 uno::Reference< vba::XVBACompatibility > xVBACompat( xScriptCont, uno::UNO_QUERY );
229 if ( xVBACompat.is() )
230 pLib->SetVBAEnabled( xVBACompat->getVBACompatibilityMode() );
233 else
236 StarBASIC* pLib = mpMgr->GetLib( maLibName );
237 DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::elementInserted: Unknown lib!");
238 if( pLib )
240 SbModule* pMod = pLib->FindModule( aName );
241 if( !pMod )
243 OUString aMod;
244 Event.Element >>= aMod;
245 uno::Reference< vba::XVBAModuleInfo > xVBAModuleInfo( Event.Source, uno::UNO_QUERY );
246 if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aName ) )
248 ModuleInfo aInfo = xVBAModuleInfo->getModuleInfo( aName );
249 pLib->MakeModule( aName, aInfo, aMod );
251 else
252 pLib->MakeModule( aName, aMod );
253 pLib->SetModified( false );
260 void SAL_CALL BasMgrContainerListenerImpl::elementReplaced( const container::ContainerEvent& Event )
262 OUString aName;
263 Event.Accessor >>= aName;
265 // Replace not possible for library container
266 DBG_ASSERT( !maLibName.isEmpty(), "library container fired elementReplaced()");
268 StarBASIC* pLib = mpMgr->GetLib( maLibName );
269 if( pLib )
271 SbModule* pMod = pLib->FindModule( aName );
272 OUString aMod;
273 Event.Element >>= aMod;
275 if( pMod )
276 pMod->SetSource32( aMod );
277 else
278 pLib->MakeModule( aName, aMod );
280 pLib->SetModified( false );
285 void SAL_CALL BasMgrContainerListenerImpl::elementRemoved( const container::ContainerEvent& Event )
287 OUString aName;
288 Event.Accessor >>= aName;
290 bool bLibContainer = maLibName.isEmpty();
291 if( bLibContainer )
293 StarBASIC* pLib = mpMgr->GetLib( aName );
294 if( pLib )
296 sal_uInt16 nLibId = mpMgr->GetLibId( aName );
297 mpMgr->RemoveLib( nLibId, false );
300 else
302 StarBASIC* pLib = mpMgr->GetLib( maLibName );
303 SbModule* pMod = pLib ? pLib->FindModule( aName ) : nullptr;
304 if( pMod )
306 pLib->Remove( pMod );
307 pLib->SetModified( false );
312 BasicError::BasicError( ErrCode nId, BasicErrorReason nR )
314 nErrorId = nId;
315 nReason = nR;
318 BasicError::BasicError( const BasicError& rErr )
320 nErrorId = rErr.nErrorId;
321 nReason = rErr.nReason;
325 class BasicLibInfo
327 private:
328 StarBASICRef xLib;
329 OUString aLibName;
330 OUString aStorageName; // string is sufficient, unique at runtime
331 OUString aRelStorageName;
332 OUString aPassword;
334 bool bDoLoad;
335 bool bReference;
337 // Lib represents library in new UNO library container
338 uno::Reference< script::XLibraryContainer > mxScriptCont;
340 public:
341 BasicLibInfo();
343 bool IsReference() const { return bReference; }
344 void SetReference(bool b) { bReference = b; }
346 bool IsExtern() const { return aStorageName != szImbedded; }
348 void SetStorageName( const OUString& rName ) { aStorageName = rName; }
349 const OUString& GetStorageName() const { return aStorageName; }
351 void SetRelStorageName( const OUString& rN ) { aRelStorageName = rN; }
352 const OUString& GetRelStorageName() const { return aRelStorageName; }
354 StarBASICRef GetLib() const
356 if( mxScriptCont.is() && mxScriptCont->hasByName( aLibName ) &&
357 !mxScriptCont->isLibraryLoaded( aLibName ) )
358 return StarBASICRef();
359 return xLib;
361 StarBASICRef& GetLibRef() { return xLib; }
362 void SetLib( StarBASIC* pBasic ) { xLib = pBasic; }
364 const OUString& GetLibName() const { return aLibName; }
365 void SetLibName( const OUString& rName ) { aLibName = rName; }
367 // Only temporary for Load/Save
368 bool DoLoad() { return bDoLoad; }
370 bool HasPassword() const { return !aPassword.isEmpty(); }
371 const OUString& GetPassword() const { return aPassword; }
372 void SetPassword( const OUString& rNewPassword )
373 { aPassword = rNewPassword; }
375 static BasicLibInfo* Create( SotStorageStream& rSStream );
377 const uno::Reference< script::XLibraryContainer >& GetLibraryContainer() const
378 { return mxScriptCont; }
379 void SetLibraryContainer( const uno::Reference< script::XLibraryContainer >& xScriptCont )
380 { mxScriptCont = xScriptCont; }
384 BasicLibInfo::BasicLibInfo()
385 : aStorageName(szImbedded)
386 , aRelStorageName(szImbedded)
387 , bDoLoad(false)
388 , bReference(false)
392 BasicLibInfo* BasicLibInfo::Create( SotStorageStream& rSStream )
394 BasicLibInfo* pInfo = new BasicLibInfo;
396 sal_uInt32 nEndPos;
397 sal_uInt16 nId;
398 sal_uInt16 nVer;
400 rSStream.ReadUInt32( nEndPos );
401 rSStream.ReadUInt16( nId );
402 rSStream.ReadUInt16( nVer );
404 DBG_ASSERT( nId == LIBINFO_ID, "No BasicLibInfo?!" );
405 if( nId == LIBINFO_ID )
407 // Reload?
408 bool bDoLoad;
409 rSStream.ReadCharAsBool( bDoLoad );
410 pInfo->bDoLoad = bDoLoad;
412 // The name of the lib...
413 OUString aName = rSStream.ReadUniOrByteString(rSStream.GetStreamCharSet());
414 pInfo->SetLibName( aName );
416 // Absolute path...
417 OUString aStorageName = rSStream.ReadUniOrByteString(rSStream.GetStreamCharSet());
418 pInfo->SetStorageName( aStorageName );
420 // Relative path...
421 OUString aRelStorageName = rSStream.ReadUniOrByteString(rSStream.GetStreamCharSet());
422 pInfo->SetRelStorageName( aRelStorageName );
424 if ( nVer >= 2 )
426 bool bReferenz;
427 rSStream.ReadCharAsBool( bReferenz );
428 pInfo->SetReference(bReferenz);
431 rSStream.Seek( nEndPos );
433 return pInfo;
436 BasicManager::BasicManager( SotStorage& rStorage, const OUString& rBaseURL, StarBASIC* pParentFromStdLib, OUString const * pLibPath, bool bDocMgr ) : mbDocMgr( bDocMgr )
438 Init();
440 if( pLibPath )
442 mpImpl->aBasicLibPath = *pLibPath;
444 OUString aStorName( rStorage.GetName() );
445 maStorageName = INetURLObject(aStorName, INetProtocol::File).GetMainURL( INetURLObject::DecodeMechanism::NONE );
448 // If there is no Manager Stream, no further actions are necessary
449 if ( rStorage.IsStream( szManagerStream ) )
451 LoadBasicManager( rStorage, rBaseURL );
452 // StdLib contains Parent:
453 StarBASIC* pStdLib = GetStdLib();
454 DBG_ASSERT( pStdLib, "Standard-Lib not loaded?" );
455 if ( !pStdLib )
457 // Should never happen, but if it happens we won't crash...
458 pStdLib = new StarBASIC( nullptr, mbDocMgr );
460 if (mpImpl->aLibs.empty())
461 CreateLibInfo();
463 BasicLibInfo& rStdLibInfo = *mpImpl->aLibs.front();
465 rStdLibInfo.SetLib( pStdLib );
466 StarBASICRef xStdLib = rStdLibInfo.GetLib();
467 xStdLib->SetName( szStdLibName );
468 rStdLibInfo.SetLibName( szStdLibName );
469 xStdLib->SetFlag( SbxFlagBits::DontStore | SbxFlagBits::ExtSearch );
470 xStdLib->SetModified( false );
472 else
474 pStdLib->SetParent( pParentFromStdLib );
475 // The other get StdLib as parent:
477 for ( sal_uInt16 nBasic = 1; nBasic < GetLibCount(); nBasic++ )
479 StarBASIC* pBasic = GetLib( nBasic );
480 if ( pBasic )
482 pStdLib->Insert( pBasic );
483 pBasic->SetFlag( SbxFlagBits::ExtSearch );
486 // Modified through insert
487 pStdLib->SetModified( false );
490 else
492 ImpCreateStdLib( pParentFromStdLib );
493 if ( rStorage.IsStream( szOldManagerStream ) )
494 LoadOldBasicManager( rStorage );
498 static void copyToLibraryContainer( StarBASIC* pBasic, const LibraryContainerInfo& rInfo )
500 uno::Reference< script::XLibraryContainer > xScriptCont( rInfo.mxScriptCont.get() );
501 if ( !xScriptCont.is() )
502 return;
504 OUString aLibName = pBasic->GetName();
505 if( !xScriptCont->hasByName( aLibName ) )
506 xScriptCont->createLibrary( aLibName );
508 uno::Any aLibAny = xScriptCont->getByName( aLibName );
509 uno::Reference< container::XNameContainer > xLib;
510 aLibAny >>= xLib;
511 if ( !xLib.is() )
512 return;
514 for ( const auto& pModule: pBasic->GetModules() )
516 OUString aModName = pModule->GetName();
517 if( !xLib->hasByName( aModName ) )
519 OUString aSource = pModule->GetSource32();
520 uno::Any aSourceAny;
521 aSourceAny <<= aSource;
522 xLib->insertByName( aModName, aSourceAny );
527 const uno::Reference< script::XPersistentLibraryContainer >& BasicManager::GetDialogLibraryContainer() const
529 return mpImpl->maContainerInfo.mxDialogCont;
532 const uno::Reference< script::XPersistentLibraryContainer >& BasicManager::GetScriptLibraryContainer() const
534 return mpImpl->maContainerInfo.mxScriptCont;
537 void BasicManager::SetLibraryContainerInfo( const LibraryContainerInfo& rInfo )
539 mpImpl->maContainerInfo = rInfo;
541 uno::Reference< script::XLibraryContainer > xScriptCont( mpImpl->maContainerInfo.mxScriptCont.get() );
542 if( xScriptCont.is() )
544 // Register listener for lib container
545 uno::Reference< container::XContainerListener > xLibContainerListener
546 = new BasMgrContainerListenerImpl( this, "" );
548 uno::Reference< container::XContainer> xLibContainer( xScriptCont, uno::UNO_QUERY );
549 xLibContainer->addContainerListener( xLibContainerListener );
551 const uno::Sequence< OUString > aScriptLibNames = xScriptCont->getElementNames();
553 if( aScriptLibNames.hasElements() )
555 for(const auto& rScriptLibName : aScriptLibNames)
557 uno::Any aLibAny = xScriptCont->getByName( rScriptLibName );
559 if ( rScriptLibName == "Standard" || rScriptLibName == "VBAProject")
560 xScriptCont->loadLibrary( rScriptLibName );
562 BasMgrContainerListenerImpl::insertLibraryImpl
563 ( xScriptCont, this, aLibAny, rScriptLibName );
566 else
568 // No libs? Maybe an 5.2 document already loaded
569 for (auto const& rpBasLibInfo : mpImpl->aLibs)
571 StarBASIC* pLib = rpBasLibInfo->GetLib().get();
572 if( !pLib )
574 bool bLoaded = ImpLoadLibrary( rpBasLibInfo.get(), nullptr );
575 if( bLoaded )
576 pLib = rpBasLibInfo->GetLib().get();
578 if( pLib )
580 copyToLibraryContainer( pLib, mpImpl->maContainerInfo );
581 if (rpBasLibInfo->HasPassword())
583 OldBasicPassword* pOldBasicPassword =
584 mpImpl->maContainerInfo.mpOldBasicPassword;
585 if( pOldBasicPassword )
587 pOldBasicPassword->setLibraryPassword(
588 pLib->GetName(), rpBasLibInfo->GetPassword() );
596 SetGlobalUNOConstant( "BasicLibraries", uno::Any( mpImpl->maContainerInfo.mxScriptCont ) );
597 SetGlobalUNOConstant( "DialogLibraries", uno::Any( mpImpl->maContainerInfo.mxDialogCont ) );
600 BasicManager::BasicManager( StarBASIC* pSLib, OUString const * pLibPath, bool bDocMgr ) : mbDocMgr( bDocMgr )
602 Init();
603 DBG_ASSERT( pSLib, "BasicManager cannot be created with a NULL-Pointer!" );
605 if( pLibPath )
607 mpImpl->aBasicLibPath = *pLibPath;
609 BasicLibInfo* pStdLibInfo = CreateLibInfo();
610 pStdLibInfo->SetLib( pSLib );
611 StarBASICRef xStdLib = pStdLibInfo->GetLib();
612 xStdLib->SetName(szStdLibName);
613 pStdLibInfo->SetLibName(szStdLibName );
614 pSLib->SetFlag( SbxFlagBits::DontStore | SbxFlagBits::ExtSearch );
616 // Save is only necessary if basic has changed
617 xStdLib->SetModified( false );
620 void BasicManager::ImpMgrNotLoaded( const OUString& rStorageName )
622 // pErrInf is only destroyed if the error os processed by an
623 // ErrorHandler
624 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, rStorageName, DialogMask::ButtonsOk );
625 aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENMGRSTREAM);
627 // Create a stdlib otherwise we crash!
628 BasicLibInfo* pStdLibInfo = CreateLibInfo();
629 pStdLibInfo->SetLib( new StarBASIC( nullptr, mbDocMgr ) );
630 StarBASICRef xStdLib = pStdLibInfo->GetLib();
631 xStdLib->SetName( szStdLibName );
632 pStdLibInfo->SetLibName( szStdLibName );
633 xStdLib->SetFlag( SbxFlagBits::DontStore | SbxFlagBits::ExtSearch );
634 xStdLib->SetModified( false );
638 void BasicManager::ImpCreateStdLib( StarBASIC* pParentFromStdLib )
640 BasicLibInfo* pStdLibInfo = CreateLibInfo();
641 StarBASIC* pStdLib = new StarBASIC( pParentFromStdLib, mbDocMgr );
642 pStdLibInfo->SetLib( pStdLib );
643 pStdLib->SetName( szStdLibName );
644 pStdLibInfo->SetLibName( szStdLibName );
645 pStdLib->SetFlag( SbxFlagBits::DontStore | SbxFlagBits::ExtSearch );
648 void BasicManager::LoadBasicManager( SotStorage& rStorage, const OUString& rBaseURL )
650 tools::SvRef<SotStorageStream> xManagerStream = rStorage.OpenSotStream( szManagerStream, eStreamReadMode );
652 OUString aStorName( rStorage.GetName() );
653 // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
655 if ( !xManagerStream.is() || xManagerStream->GetError() || ( xManagerStream->TellEnd() == 0 ) )
657 ImpMgrNotLoaded( aStorName );
658 return;
661 maStorageName = INetURLObject(aStorName, INetProtocol::File).GetMainURL( INetURLObject::DecodeMechanism::NONE );
662 // #i13114 removed, DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
664 OUString aRealStorageName = maStorageName; // for relative paths, can be modified through BaseURL
666 if ( !rBaseURL.isEmpty() )
668 INetURLObject aObj( rBaseURL );
669 if ( aObj.GetProtocol() == INetProtocol::File )
671 aRealStorageName = aObj.PathToFileName();
675 xManagerStream->SetBufferSize( 1024 );
676 xManagerStream->Seek( STREAM_SEEK_TO_BEGIN );
678 sal_uInt32 nEndPos;
679 xManagerStream->ReadUInt32( nEndPos );
681 sal_uInt16 nLibs;
682 xManagerStream->ReadUInt16( nLibs );
683 // Plausibility!
684 if( nLibs & 0xF000 )
686 SAL_WARN( "basic", "BasicManager-Stream defect!" );
687 return;
689 const size_t nMinBasicLibSize(8);
690 const size_t nMaxPossibleLibs = xManagerStream->remainingSize() / nMinBasicLibSize;
691 if (nLibs > nMaxPossibleLibs)
693 SAL_WARN("basic", "Parsing error: " << nMaxPossibleLibs <<
694 " max possible entries, but " << nLibs << " claimed, truncating");
695 nLibs = nMaxPossibleLibs;
697 for (sal_uInt16 nL = 0; nL < nLibs; ++nL)
699 BasicLibInfo* pInfo = BasicLibInfo::Create( *xManagerStream );
701 // Correct absolute pathname if relative is existing.
702 // Always try relative first if there are two stands on disk
703 if ( !pInfo->GetRelStorageName().isEmpty() && pInfo->GetRelStorageName() != szImbedded )
705 INetURLObject aObj( aRealStorageName, INetProtocol::File );
706 aObj.removeSegment();
707 bool bWasAbsolute = false;
708 aObj = aObj.smartRel2Abs( pInfo->GetRelStorageName(), bWasAbsolute );
710 //*** TODO: Replace if still necessary
711 //*** TODO-End
712 if ( ! mpImpl->aBasicLibPath.isEmpty() )
714 // Search lib in path
715 OUString aSearchFile = pInfo->GetRelStorageName();
716 OUString aSearchFileOldFormat(aSearchFile);
717 SvtPathOptions aPathCFG;
718 if( aPathCFG.SearchFile( aSearchFileOldFormat, SvtPathOptions::PATH_BASIC ) )
720 pInfo->SetStorageName( aSearchFile );
725 mpImpl->aLibs.push_back(std::unique_ptr<BasicLibInfo>(pInfo));
726 // Libs from external files should be loaded only when necessary.
727 // But references are loaded at once, otherwise some big customers get into trouble
728 if ( pInfo->DoLoad() &&
729 ( !pInfo->IsExtern() || pInfo->IsReference()))
731 ImpLoadLibrary( pInfo, &rStorage );
735 xManagerStream->Seek( nEndPos );
736 xManagerStream->SetBufferSize( 0 );
737 xManagerStream.clear();
740 void BasicManager::LoadOldBasicManager( SotStorage& rStorage )
742 tools::SvRef<SotStorageStream> xManagerStream = rStorage.OpenSotStream( szOldManagerStream, eStreamReadMode );
744 OUString aStorName( rStorage.GetName() );
745 DBG_ASSERT( aStorName.getLength(), "No Storage Name!" );
747 if ( !xManagerStream.is() || xManagerStream->GetError() || ( xManagerStream->TellEnd() == 0 ) )
749 ImpMgrNotLoaded( aStorName );
750 return;
753 xManagerStream->SetBufferSize( 1024 );
754 xManagerStream->Seek( STREAM_SEEK_TO_BEGIN );
755 sal_uInt32 nBasicStartOff, nBasicEndOff;
756 xManagerStream->ReadUInt32( nBasicStartOff );
757 xManagerStream->ReadUInt32( nBasicEndOff );
759 DBG_ASSERT( !xManagerStream->GetError(), "Invalid Manager-Stream!" );
761 xManagerStream->Seek( nBasicStartOff );
762 if (!ImplLoadBasic( *xManagerStream, mpImpl->aLibs.front()->GetLibRef() ))
764 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, aStorName, DialogMask::ButtonsOk );
765 aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENMGRSTREAM);
766 // and it proceeds ...
768 xManagerStream->Seek( nBasicEndOff+1 ); // +1: 0x00 as separator
769 OUString aLibs = xManagerStream->ReadUniOrByteString(xManagerStream->GetStreamCharSet());
770 xManagerStream->SetBufferSize( 0 );
771 xManagerStream.clear(); // Close stream
773 if ( !aLibs.isEmpty() )
775 INetURLObject aCurStorage( aStorName, INetProtocol::File );
776 sal_Int32 nLibPos {0};
777 do {
778 const OUString aLibInfo(aLibs.getToken(0, LIB_SEP, nLibPos));
779 sal_Int32 nInfoPos {0};
780 const OUString aLibName( aLibInfo.getToken( 0, LIBINFO_SEP, nInfoPos ) );
781 DBG_ASSERT( nInfoPos >= 0, "Invalid Lib-Info!" );
782 const OUString aLibAbsStorageName( aLibInfo.getToken( 0, LIBINFO_SEP, nInfoPos ) );
783 // TODO: fail also here if there are no more tokens?
784 const OUString aLibRelStorageName( aLibInfo.getToken( 0, LIBINFO_SEP, nInfoPos ) );
785 DBG_ASSERT( nInfoPos < 0, "Invalid Lib-Info!" );
786 INetURLObject aLibAbsStorage( aLibAbsStorageName, INetProtocol::File );
788 INetURLObject aLibRelStorage( aStorName );
789 aLibRelStorage.removeSegment();
790 bool bWasAbsolute = false;
791 aLibRelStorage = aLibRelStorage.smartRel2Abs( aLibRelStorageName, bWasAbsolute);
792 DBG_ASSERT(!bWasAbsolute, "RelStorageName was absolute!" );
794 tools::SvRef<SotStorage> xStorageRef;
795 if ( aLibAbsStorage == aCurStorage || aLibRelStorageName == szImbedded )
797 xStorageRef = &rStorage;
799 else
801 xStorageRef = new SotStorage( false, aLibAbsStorage.GetMainURL
802 ( INetURLObject::DecodeMechanism::NONE ), eStorageReadMode );
803 if ( xStorageRef->GetError() != ERRCODE_NONE )
804 xStorageRef = new SotStorage( false, aLibRelStorage.
805 GetMainURL( INetURLObject::DecodeMechanism::NONE ), eStorageReadMode );
807 if ( xStorageRef.is() )
809 AddLib( *xStorageRef, aLibName, false );
811 else
813 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, aStorName, DialogMask::ButtonsOk );
814 aErrors.emplace_back(*pErrInf, BasicErrorReason::STORAGENOTFOUND);
816 } while (nLibPos>=0);
820 BasicManager::~BasicManager()
822 // Notify listener if something needs to be saved
823 Broadcast( SfxHint( SfxHintId::Dying) );
826 bool BasicManager::HasExeCode( const OUString& sLib )
828 StarBASIC* pLib = GetLib(sLib);
829 if ( pLib )
831 for (const auto& pModule: pLib->GetModules())
833 if (pModule->HasExeCode())
834 return true;
837 return false;
840 void BasicManager::Init()
842 mpImpl.reset( new BasicManagerImpl );
845 BasicLibInfo* BasicManager::CreateLibInfo()
847 BasicLibInfo* pInf(new BasicLibInfo);
848 mpImpl->aLibs.push_back(std::unique_ptr<BasicLibInfo>(pInf));
849 return pInf;
852 bool BasicManager::ImpLoadLibrary( BasicLibInfo* pLibInfo, SotStorage* pCurStorage )
854 try {
855 DBG_ASSERT( pLibInfo, "LibInfo!?" );
857 OUString aStorageName( pLibInfo->GetStorageName() );
858 if ( aStorageName.isEmpty() || aStorageName == szImbedded )
860 aStorageName = GetStorageName();
862 tools::SvRef<SotStorage> xStorage;
863 // The current must not be opened again...
864 if ( pCurStorage )
866 OUString aStorName( pCurStorage->GetName() );
867 // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
869 INetURLObject aCurStorageEntry(aStorName, INetProtocol::File);
870 // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::DecodeMechanism::NONE ).Len() != 0, "Bad storage name");
872 INetURLObject aStorageEntry(aStorageName, INetProtocol::File);
873 // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::DecodeMechanism::NONE ).Len() != 0, "Bad storage name");
875 if ( aCurStorageEntry == aStorageEntry )
877 xStorage = pCurStorage;
881 if ( !xStorage.is() )
883 xStorage = new SotStorage( false, aStorageName, eStorageReadMode );
885 tools::SvRef<SotStorage> xBasicStorage = xStorage->OpenSotStorage( szBasicStorage, eStorageReadMode, false );
887 if ( !xBasicStorage.is() || xBasicStorage->GetError() )
889 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, xStorage->GetName(), DialogMask::ButtonsOk );
890 aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENLIBSTORAGE);
892 else
894 // In the Basic-Storage every lib is in a Stream...
895 tools::SvRef<SotStorageStream> xBasicStream = xBasicStorage->OpenSotStream( pLibInfo->GetLibName(), eStreamReadMode );
896 if ( !xBasicStream.is() || xBasicStream->GetError() )
898 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD , pLibInfo->GetLibName(), DialogMask::ButtonsOk );
899 aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENLIBSTREAM);
901 else
903 bool bLoaded = false;
904 if ( xBasicStream->TellEnd() != 0 )
906 if ( !pLibInfo->GetLib().is() )
908 pLibInfo->SetLib( new StarBASIC( GetStdLib(), mbDocMgr ) );
910 xBasicStream->SetBufferSize( 1024 );
911 xBasicStream->Seek( STREAM_SEEK_TO_BEGIN );
912 bLoaded = ImplLoadBasic( *xBasicStream, pLibInfo->GetLibRef() );
913 xBasicStream->SetBufferSize( 0 );
914 StarBASICRef xStdLib = pLibInfo->GetLib();
915 xStdLib->SetName( pLibInfo->GetLibName() );
916 xStdLib->SetModified( false );
917 xStdLib->SetFlag( SbxFlagBits::DontStore );
919 if ( !bLoaded )
921 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, pLibInfo->GetLibName(), DialogMask::ButtonsOk );
922 aErrors.emplace_back(*pErrInf, BasicErrorReason::BASICLOADERROR);
924 else
926 // Perhaps there are additional information in the stream...
927 xBasicStream->SetCryptMaskKey(szCryptingKey);
928 xBasicStream->RefreshBuffer();
929 sal_uInt32 nPasswordMarker = 0;
930 xBasicStream->ReadUInt32( nPasswordMarker );
931 if ( ( nPasswordMarker == PASSWORD_MARKER ) && !xBasicStream->eof() )
933 OUString aPassword = xBasicStream->ReadUniOrByteString(
934 xBasicStream->GetStreamCharSet());
935 pLibInfo->SetPassword( aPassword );
937 xBasicStream->SetCryptMaskKey(OString());
938 CheckModules( pLibInfo->GetLib().get(), pLibInfo->IsReference() );
940 return bLoaded;
944 catch (const css::ucb::ContentCreationException&)
947 return false;
950 bool BasicManager::ImplEncryptStream( SvStream& rStrm )
952 sal_uInt64 const nPos = rStrm.Tell();
953 sal_uInt32 nCreator;
954 rStrm.ReadUInt32( nCreator );
955 rStrm.Seek( nPos );
956 bool bProtected = false;
957 if ( nCreator != SBXCR_SBX )
959 // Should only be the case for encrypted Streams
960 bProtected = true;
961 rStrm.SetCryptMaskKey(szCryptingKey);
962 rStrm.RefreshBuffer();
964 return bProtected;
967 // This code is necessary to load the BASIC of Beta 1
968 // TODO: Which Beta 1?
969 bool BasicManager::ImplLoadBasic( SvStream& rStrm, StarBASICRef& rOldBasic ) const
971 bool bProtected = ImplEncryptStream( rStrm );
972 SbxBaseRef xNew = SbxBase::Load( rStrm );
973 bool bLoaded = false;
974 if( xNew.is() )
976 if( auto pNew = dynamic_cast<StarBASIC*>( xNew.get() ) )
978 // Use the Parent of the old BASICs
979 if( rOldBasic.is() )
981 pNew->SetParent( rOldBasic->GetParent() );
982 if( pNew->GetParent() )
984 pNew->GetParent()->Insert( pNew );
986 pNew->SetFlag( SbxFlagBits::ExtSearch );
988 rOldBasic = pNew;
990 // Fill new library container (5.2 -> 6.0)
991 copyToLibraryContainer( pNew, mpImpl->maContainerInfo );
993 pNew->SetModified( false );
994 bLoaded = true;
997 if ( bProtected )
999 rStrm.SetCryptMaskKey(OString());
1001 return bLoaded;
1004 void BasicManager::CheckModules( StarBASIC* pLib, bool bReference )
1006 if ( !pLib )
1008 return;
1010 bool bModified = pLib->IsModified();
1012 for ( const auto& pModule: pLib->GetModules() )
1014 DBG_ASSERT(pModule, "Module not received!");
1015 if ( !pModule->IsCompiled() && !StarBASIC::GetErrorCode() )
1017 pModule->Compile();
1021 // #67477, AB 8.12.99 On demand compile in referenced libs should not
1022 // cause modified
1023 if( !bModified && bReference )
1025 OSL_FAIL( "Referenced basic library is not compiled!" );
1026 pLib->SetModified( false );
1030 StarBASIC* BasicManager::AddLib( SotStorage& rStorage, const OUString& rLibName, bool bReference )
1032 OUString aStorName( rStorage.GetName() );
1033 DBG_ASSERT( !aStorName.isEmpty(), "No Storage Name!" );
1035 OUString aStorageName = INetURLObject(aStorName, INetProtocol::File).GetMainURL( INetURLObject::DecodeMechanism::NONE );
1036 DBG_ASSERT(!aStorageName.isEmpty(), "Bad storage name");
1038 OUString aNewLibName( rLibName );
1039 while ( HasLib( aNewLibName ) )
1041 aNewLibName += "_";
1043 BasicLibInfo* pLibInfo = CreateLibInfo();
1044 // Use original name otherwise ImpLoadLibrary fails...
1045 pLibInfo->SetLibName( rLibName );
1046 // but doesn't work this way if name exists twice
1047 sal_uInt16 nLibId = static_cast<sal_uInt16>(mpImpl->aLibs.size()) - 1;
1049 // Set StorageName before load because it is compared with pCurStorage
1050 pLibInfo->SetStorageName( aStorageName );
1051 bool bLoaded = ImpLoadLibrary( pLibInfo, &rStorage );
1053 if ( bLoaded )
1055 if ( aNewLibName != rLibName )
1057 pLibInfo->SetLibName(aNewLibName);
1059 if ( bReference )
1061 pLibInfo->GetLib()->SetModified( false ); // Don't save in this case
1062 pLibInfo->SetRelStorageName( OUString() );
1063 pLibInfo->SetReference(true);
1065 else
1067 pLibInfo->GetLib()->SetModified( true ); // Must be saved after Add!
1068 pLibInfo->SetStorageName( szImbedded ); // Save in BasicManager-Storage
1071 else
1073 RemoveLib( nLibId, false );
1074 pLibInfo = nullptr;
1077 return pLibInfo ? &*pLibInfo->GetLib() : nullptr;
1081 bool BasicManager::IsReference( sal_uInt16 nLib )
1083 DBG_ASSERT( nLib < mpImpl->aLibs.size(), "Lib does not exist!" );
1084 if ( nLib < mpImpl->aLibs.size() )
1086 return mpImpl->aLibs[nLib]->IsReference();
1088 return false;
1091 void BasicManager::RemoveLib( sal_uInt16 nLib )
1093 // Only physical deletion if no reference
1094 RemoveLib( nLib, !IsReference( nLib ) );
1097 bool BasicManager::RemoveLib( sal_uInt16 nLib, bool bDelBasicFromStorage )
1099 DBG_ASSERT( nLib, "Standard-Lib cannot be removed!" );
1101 DBG_ASSERT( !nLib || nLib < mpImpl->aLibs.size(), "Lib not found!" );
1103 if( !nLib || nLib < mpImpl->aLibs.size() )
1105 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIB, OUString(), DialogMask::ButtonsOk );
1106 aErrors.emplace_back(*pErrInf, BasicErrorReason::STDLIB);
1107 return false;
1110 auto const itLibInfo = mpImpl->aLibs.begin() + nLib;
1112 // If one of the streams cannot be opened, this is not an error,
1113 // because BASIC was never written before...
1114 if (bDelBasicFromStorage && !(*itLibInfo)->IsReference() &&
1115 (!(*itLibInfo)->IsExtern() || SotStorage::IsStorageFile((*itLibInfo)->GetStorageName())))
1117 tools::SvRef<SotStorage> xStorage;
1120 if (!(*itLibInfo)->IsExtern())
1122 xStorage = new SotStorage(false, GetStorageName());
1124 else
1126 xStorage = new SotStorage(false, (*itLibInfo)->GetStorageName());
1129 catch (const css::ucb::ContentCreationException&)
1131 TOOLS_WARN_EXCEPTION("basic", "BasicManager::RemoveLib:");
1134 if (xStorage.is() && xStorage->IsStorage(szBasicStorage))
1136 tools::SvRef<SotStorage> xBasicStorage = xStorage->OpenSotStorage
1137 ( szBasicStorage, StreamMode::STD_READWRITE, false );
1139 if ( !xBasicStorage.is() || xBasicStorage->GetError() )
1141 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIB, OUString(), DialogMask::ButtonsOk );
1142 aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENLIBSTORAGE);
1144 else if (xBasicStorage->IsStream((*itLibInfo)->GetLibName()))
1146 xBasicStorage->Remove((*itLibInfo)->GetLibName());
1147 xBasicStorage->Commit();
1149 // If no further stream available,
1150 // delete the SubStorage.
1151 SvStorageInfoList aInfoList;
1152 xBasicStorage->FillInfoList( &aInfoList );
1153 if ( aInfoList.empty() )
1155 xBasicStorage.clear();
1156 xStorage->Remove( szBasicStorage );
1157 xStorage->Commit();
1158 // If no further Streams or SubStorages available,
1159 // delete the Storage, too.
1160 aInfoList.clear();
1161 xStorage->FillInfoList( &aInfoList );
1162 if ( aInfoList.empty() )
1164 //OUString aName_( xStorage->GetName() );
1165 xStorage.clear();
1166 //*** TODO: Replace if still necessary
1167 //SfxContentHelper::Kill( aName );
1168 //*** TODO-End
1174 if ((*itLibInfo)->GetLib().is())
1176 GetStdLib()->Remove( (*itLibInfo)->GetLib().get() );
1178 mpImpl->aLibs.erase(itLibInfo);
1179 return true; // Remove was successful, del unimportant
1182 sal_uInt16 BasicManager::GetLibCount() const
1184 return static_cast<sal_uInt16>(mpImpl->aLibs.size());
1187 StarBASIC* BasicManager::GetLib( sal_uInt16 nLib ) const
1189 DBG_ASSERT( nLib < mpImpl->aLibs.size(), "Lib does not exist!" );
1190 if ( nLib < mpImpl->aLibs.size() )
1192 return mpImpl->aLibs[nLib]->GetLib().get();
1194 return nullptr;
1197 StarBASIC* BasicManager::GetStdLib() const
1199 StarBASIC* pLib = GetLib( 0 );
1200 return pLib;
1203 StarBASIC* BasicManager::GetLib( const OUString& rName ) const
1205 for (auto const& rpLib : mpImpl->aLibs)
1207 if (rpLib->GetLibName().equalsIgnoreAsciiCase(rName)) // Check if available...
1209 return rpLib->GetLib().get();
1212 return nullptr;
1215 sal_uInt16 BasicManager::GetLibId( const OUString& rName ) const
1217 for (size_t i = 0; i < mpImpl->aLibs.size(); i++)
1219 if (mpImpl->aLibs[i]->GetLibName().equalsIgnoreAsciiCase( rName ))
1221 return static_cast<sal_uInt16>(i);
1224 return LIB_NOTFOUND;
1227 bool BasicManager::HasLib( const OUString& rName ) const
1229 for (const auto& rpLib : mpImpl->aLibs)
1231 if (rpLib->GetLibName().equalsIgnoreAsciiCase(rName)) // Check if available...
1233 return true;
1236 return false;
1239 OUString BasicManager::GetLibName( sal_uInt16 nLib )
1241 DBG_ASSERT( nLib < mpImpl->aLibs.size(), "Lib?!" );
1242 if ( nLib < mpImpl->aLibs.size() )
1244 return mpImpl->aLibs[nLib]->GetLibName();
1246 return OUString();
1249 bool BasicManager::LoadLib( sal_uInt16 nLib )
1251 bool bDone = false;
1252 DBG_ASSERT( nLib < mpImpl->aLibs.size() , "Lib?!" );
1253 if ( nLib < mpImpl->aLibs.size() )
1255 BasicLibInfo& rLibInfo = *mpImpl->aLibs[nLib];
1256 uno::Reference< script::XLibraryContainer > xLibContainer = rLibInfo.GetLibraryContainer();
1257 if( xLibContainer.is() )
1259 OUString aLibName = rLibInfo.GetLibName();
1260 xLibContainer->loadLibrary( aLibName );
1261 bDone = xLibContainer->isLibraryLoaded( aLibName );
1263 else
1265 bDone = ImpLoadLibrary( &rLibInfo, nullptr );
1266 StarBASIC* pLib = GetLib( nLib );
1267 if ( pLib )
1269 GetStdLib()->Insert( pLib );
1270 pLib->SetFlag( SbxFlagBits::ExtSearch );
1274 else
1276 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, OUString(), DialogMask::ButtonsOk );
1277 aErrors.emplace_back(*pErrInf, BasicErrorReason::LIBNOTFOUND);
1279 return bDone;
1282 StarBASIC* BasicManager::CreateLib( const OUString& rLibName )
1284 if ( GetLib( rLibName ) )
1286 return nullptr;
1288 BasicLibInfo* pLibInfo = CreateLibInfo();
1289 StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr );
1290 GetStdLib()->Insert( pNew );
1291 pNew->SetFlag( SbxFlagBits::ExtSearch | SbxFlagBits::DontStore );
1292 pLibInfo->SetLib( pNew );
1293 pLibInfo->SetLibName( rLibName );
1294 pLibInfo->GetLib()->SetName( rLibName );
1295 return pLibInfo->GetLib().get();
1298 // For XML import/export:
1299 StarBASIC* BasicManager::CreateLib( const OUString& rLibName, const OUString& Password,
1300 const OUString& LinkTargetURL )
1302 // Ask if lib exists because standard lib is always there
1303 StarBASIC* pLib = GetLib( rLibName );
1304 if( !pLib )
1306 if( !LinkTargetURL.isEmpty())
1310 tools::SvRef<SotStorage> xStorage = new SotStorage(false, LinkTargetURL, StreamMode::READ | StreamMode::SHARE_DENYWRITE);
1311 if (!xStorage->GetError())
1313 pLib = AddLib(*xStorage, rLibName, true);
1316 catch (const css::ucb::ContentCreationException&)
1318 TOOLS_WARN_EXCEPTION("basic", "BasicManager::RemoveLib:");
1320 DBG_ASSERT( pLib, "XML Import: Linked basic library could not be loaded");
1322 else
1324 pLib = CreateLib( rLibName );
1325 if( Password.isEmpty())
1327 BasicLibInfo* pLibInfo = FindLibInfo( pLib );
1328 pLibInfo ->SetPassword( Password );
1331 //ExternalSourceURL ?
1333 return pLib;
1336 StarBASIC* BasicManager::CreateLibForLibContainer( const OUString& rLibName,
1337 const uno::Reference< script::XLibraryContainer >& xScriptCont )
1339 if ( GetLib( rLibName ) )
1341 return nullptr;
1343 BasicLibInfo* pLibInfo = CreateLibInfo();
1344 StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr );
1345 GetStdLib()->Insert( pNew );
1346 pNew->SetFlag( SbxFlagBits::ExtSearch | SbxFlagBits::DontStore );
1347 pLibInfo->SetLib( pNew );
1348 pLibInfo->SetLibName( rLibName );
1349 pLibInfo->GetLib()->SetName( rLibName );
1350 pLibInfo->SetLibraryContainer( xScriptCont );
1351 return pNew;
1355 BasicLibInfo* BasicManager::FindLibInfo( StarBASIC const * pBasic )
1357 for (auto const& rpLib : mpImpl->aLibs)
1359 if (rpLib->GetLib().get() == pBasic)
1361 return rpLib.get();
1364 return nullptr;
1368 bool BasicManager::IsBasicModified() const
1370 for (auto const& rpLib : mpImpl->aLibs)
1372 if (rpLib->GetLib().is() && rpLib->GetLib()->IsModified())
1374 return true;
1377 return false;
1381 bool BasicManager::GetGlobalUNOConstant( const OUString& rName, uno::Any& aOut )
1383 bool bRes = false;
1384 StarBASIC* pStandardLib = GetStdLib();
1385 OSL_PRECOND( pStandardLib, "BasicManager::GetGlobalUNOConstant: no lib to read from!" );
1386 if ( pStandardLib )
1387 bRes = pStandardLib->GetUNOConstant( rName, aOut );
1388 return bRes;
1391 uno::Any BasicManager::SetGlobalUNOConstant( const OUString& rName, const uno::Any& _rValue )
1393 uno::Any aOldValue;
1395 StarBASIC* pStandardLib = GetStdLib();
1396 OSL_PRECOND( pStandardLib, "BasicManager::SetGlobalUNOConstant: no lib to insert into!" );
1397 if ( !pStandardLib )
1398 return aOldValue;
1400 // obtain the old value
1401 SbxVariable* pVariable = pStandardLib->Find( rName, SbxClassType::Object );
1402 if ( pVariable )
1403 aOldValue = sbxToUnoValue( pVariable );
1404 SbxObjectRef xUnoObj = GetSbUnoObject( _rValue.getValueType ().getTypeName () , _rValue );
1405 xUnoObj->SetName(rName);
1406 xUnoObj->SetFlag( SbxFlagBits::DontStore );
1407 pStandardLib->Insert( xUnoObj.get() );
1409 return aOldValue;
1412 bool BasicManager::LegacyPsswdBinaryLimitExceeded( std::vector< OUString >& _out_rModuleNames )
1416 uno::Reference< container::XNameAccess > xScripts( GetScriptLibraryContainer(), uno::UNO_QUERY_THROW );
1417 uno::Reference< script::XLibraryContainerPassword > xPassword( GetScriptLibraryContainer(), uno::UNO_QUERY_THROW );
1419 const uno::Sequence< OUString > aNames( xScripts->getElementNames() );
1420 for ( auto const & scriptElementName : aNames )
1422 if( !xPassword->isLibraryPasswordProtected( scriptElementName ) )
1423 continue;
1425 StarBASIC* pBasicLib = GetLib( scriptElementName );
1426 if ( !pBasicLib )
1427 continue;
1429 uno::Reference< container::XNameAccess > xScriptLibrary( xScripts->getByName( scriptElementName ), uno::UNO_QUERY_THROW );
1430 const uno::Sequence< OUString > aElementNames( xScriptLibrary->getElementNames() );
1431 sal_Int32 nLen = aElementNames.getLength();
1433 std::vector< OUString > aBigModules( nLen );
1434 sal_Int32 nBigModules = 0;
1436 for ( auto const & libraryElementName : aElementNames )
1438 SbModule* pMod = pBasicLib->FindModule( libraryElementName );
1439 if ( pMod && pMod->ExceedsLegacyModuleSize() )
1440 aBigModules[ nBigModules++ ] = libraryElementName;
1443 if ( nBigModules )
1445 _out_rModuleNames.swap(aBigModules);
1446 return true;
1450 catch( const uno::Exception& )
1452 DBG_UNHANDLED_EXCEPTION("basic");
1454 return false;
1458 namespace
1460 SbMethod* lcl_queryMacro( BasicManager* i_manager, OUString const& i_fullyQualifiedName )
1462 sal_Int32 nLast = 0;
1463 const OUString sLibName {i_fullyQualifiedName.getToken( 0, '.', nLast )};
1464 const OUString sModule {i_fullyQualifiedName.getToken( 0, '.', nLast )};
1465 OUString sMacro;
1466 if(nLast >= 0)
1468 sMacro = i_fullyQualifiedName.copy(nLast);
1470 else
1472 sMacro = i_fullyQualifiedName;
1475 utl::TransliterationWrapper& rTransliteration = SbGlobal::GetTransliteration();
1476 sal_uInt16 nLibCount = i_manager->GetLibCount();
1477 for ( sal_uInt16 nLib = 0; nLib < nLibCount; ++nLib )
1479 if ( rTransliteration.isEqual( i_manager->GetLibName( nLib ), sLibName ) )
1481 StarBASIC* pLib = i_manager->GetLib( nLib );
1482 if( !pLib )
1484 bool const bLoaded = i_manager->LoadLib( nLib );
1485 if (bLoaded)
1487 pLib = i_manager->GetLib( nLib );
1491 if( pLib )
1493 for ( const auto& pMod: pLib->GetModules() )
1495 if ( rTransliteration.isEqual( pMod->GetName(), sModule ) )
1497 SbMethod* pMethod = static_cast<SbMethod*>(pMod->Find( sMacro, SbxClassType::Method ));
1498 if( pMethod )
1500 return pMethod;
1507 return nullptr;
1511 bool BasicManager::HasMacro( OUString const& i_fullyQualifiedName ) const
1513 return ( lcl_queryMacro( const_cast< BasicManager* >( this ), i_fullyQualifiedName ) != nullptr );
1516 ErrCode BasicManager::ExecuteMacro( OUString const& i_fullyQualifiedName, SbxArray* i_arguments, SbxValue* i_retValue )
1518 SbMethod* pMethod = lcl_queryMacro( this, i_fullyQualifiedName );
1519 ErrCode nError = ERRCODE_NONE;
1520 if ( pMethod )
1522 if ( i_arguments )
1523 pMethod->SetParameters( i_arguments );
1524 nError = pMethod->Call( i_retValue );
1526 else
1527 nError = ERRCODE_BASIC_PROC_UNDEFINED;
1528 return nError;
1531 ErrCode BasicManager::ExecuteMacro( OUString const& i_fullyQualifiedName, OUString const& i_commaSeparatedArgs, SbxValue* i_retValue )
1533 SbMethod* pMethod = lcl_queryMacro( this, i_fullyQualifiedName );
1534 if ( !pMethod )
1536 return ERRCODE_BASIC_PROC_UNDEFINED;
1538 // arguments must be quoted
1539 OUString sQuotedArgs;
1540 OUStringBuffer sArgs( i_commaSeparatedArgs );
1541 if ( sArgs.getLength()<2 || sArgs[1] == '\"')
1543 // no args or already quoted args
1544 sQuotedArgs = sArgs.makeStringAndClear();
1546 else
1548 // quote parameters
1549 sArgs.remove( 0, 1 );
1550 sArgs.remove( sArgs.getLength() - 1, 1 );
1552 OUStringBuffer aBuff;
1553 OUString sArgs2 = sArgs.makeStringAndClear();
1555 aBuff.append("(");
1556 if (!sArgs2.isEmpty())
1559 sal_Int32 nPos {0};
1560 for (;;)
1562 aBuff.append( "\"" );
1563 aBuff.append( sArgs2.getToken(0, ',', nPos) );
1564 aBuff.append( "\"" );
1565 if (nPos<0)
1566 break;
1567 aBuff.append( "," );
1570 aBuff.append( ")" );
1572 sQuotedArgs = aBuff.makeStringAndClear();
1575 // add quoted arguments and do the call
1576 OUString sCall = "["
1577 + pMethod->GetName()
1578 + sQuotedArgs
1579 + "]";
1581 SbxVariable* pRet = pMethod->GetParent()->Execute( sCall );
1582 if ( pRet && ( pRet != pMethod ) )
1584 *i_retValue = *pRet;
1586 return SbxBase::GetError();
1590 class ModuleInfo_Impl : public ModuleInfoHelper
1592 OUString maName;
1593 OUString maLanguage;
1594 OUString maSource;
1596 public:
1597 ModuleInfo_Impl( const OUString& aName, const OUString& aLanguage, const OUString& aSource )
1598 : maName( aName ), maLanguage( aLanguage), maSource( aSource ) {}
1600 // Methods XStarBasicModuleInfo
1601 virtual OUString SAL_CALL getName() override
1602 { return maName; }
1603 virtual OUString SAL_CALL getLanguage() override
1604 { return maLanguage; }
1605 virtual OUString SAL_CALL getSource() override
1606 { return maSource; }
1610 class DialogInfo_Impl : public WeakImplHelper< script::XStarBasicDialogInfo >
1612 OUString maName;
1613 uno::Sequence< sal_Int8 > mData;
1615 public:
1616 DialogInfo_Impl( const OUString& aName, const uno::Sequence< sal_Int8 >& Data )
1617 : maName( aName ), mData( Data ) {}
1619 // Methods XStarBasicDialogInfo
1620 virtual OUString SAL_CALL getName() override
1621 { return maName; }
1622 virtual uno::Sequence< sal_Int8 > SAL_CALL getData() override
1623 { return mData; }
1627 class LibraryInfo_Impl : public WeakImplHelper< script::XStarBasicLibraryInfo >
1629 OUString maName;
1630 uno::Reference< container::XNameContainer > mxModuleContainer;
1631 uno::Reference< container::XNameContainer > mxDialogContainer;
1632 OUString maPassword;
1633 OUString maExternaleSourceURL;
1634 OUString maLinkTargetURL;
1636 public:
1637 LibraryInfo_Impl
1639 const OUString& aName,
1640 uno::Reference< container::XNameContainer > const & xModuleContainer,
1641 uno::Reference< container::XNameContainer > const & xDialogContainer,
1642 const OUString& aPassword,
1643 const OUString& aExternaleSourceURL,
1644 const OUString& aLinkTargetURL
1646 : maName( aName )
1647 , mxModuleContainer( xModuleContainer )
1648 , mxDialogContainer( xDialogContainer )
1649 , maPassword( aPassword )
1650 , maExternaleSourceURL( aExternaleSourceURL )
1651 , maLinkTargetURL( aLinkTargetURL )
1654 // Methods XStarBasicLibraryInfo
1655 virtual OUString SAL_CALL getName() override
1656 { return maName; }
1657 virtual uno::Reference< container::XNameContainer > SAL_CALL getModuleContainer() override
1658 { return mxModuleContainer; }
1659 virtual uno::Reference< container::XNameContainer > SAL_CALL getDialogContainer() override
1660 { return mxDialogContainer; }
1661 virtual OUString SAL_CALL getPassword() override
1662 { return maPassword; }
1663 virtual OUString SAL_CALL getExternalSourceURL() override
1664 { return maExternaleSourceURL; }
1665 virtual OUString SAL_CALL getLinkTargetURL() override
1666 { return maLinkTargetURL; }
1670 class ModuleContainer_Impl : public NameContainerHelper
1672 StarBASIC* mpLib;
1674 public:
1675 explicit ModuleContainer_Impl( StarBASIC* pLib )
1676 :mpLib( pLib ) {}
1678 // Methods XElementAccess
1679 virtual uno::Type SAL_CALL getElementType() override;
1680 virtual sal_Bool SAL_CALL hasElements() override;
1682 // Methods XNameAccess
1683 virtual uno::Any SAL_CALL getByName( const OUString& aName ) override;
1684 virtual uno::Sequence< OUString > SAL_CALL getElementNames() override;
1685 virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override;
1687 // Methods XNameReplace
1688 virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) override;
1690 // Methods XNameContainer
1691 virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) override;
1692 virtual void SAL_CALL removeByName( const OUString& Name ) override;
1695 // Methods XElementAccess
1696 uno::Type ModuleContainer_Impl::getElementType()
1698 uno::Type aModuleType = cppu::UnoType<script::XStarBasicModuleInfo>::get();
1699 return aModuleType;
1702 sal_Bool ModuleContainer_Impl::hasElements()
1704 return mpLib && !mpLib->GetModules().empty();
1707 // Methods XNameAccess
1708 uno::Any ModuleContainer_Impl::getByName( const OUString& aName )
1710 SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : nullptr;
1711 if( !pMod )
1712 throw container::NoSuchElementException();
1713 uno::Reference< script::XStarBasicModuleInfo > xMod = new ModuleInfo_Impl( aName, "StarBasic", pMod->GetSource32() );
1714 uno::Any aRetAny;
1715 aRetAny <<= xMod;
1716 return aRetAny;
1719 uno::Sequence< OUString > ModuleContainer_Impl::getElementNames()
1721 sal_uInt16 nMods = mpLib ? mpLib->GetModules().size() : 0;
1722 uno::Sequence< OUString > aRetSeq( nMods );
1723 OUString* pRetSeq = aRetSeq.getArray();
1724 for( sal_uInt16 i = 0 ; i < nMods ; i++ )
1726 pRetSeq[i] = mpLib->GetModules()[i]->GetName();
1728 return aRetSeq;
1731 sal_Bool ModuleContainer_Impl::hasByName( const OUString& aName )
1733 SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : nullptr;
1734 bool bRet = (pMod != nullptr);
1735 return bRet;
1739 // Methods XNameReplace
1740 void ModuleContainer_Impl::replaceByName( const OUString& aName, const uno::Any& aElement )
1742 removeByName( aName );
1743 insertByName( aName, aElement );
1747 // Methods XNameContainer
1748 void ModuleContainer_Impl::insertByName( const OUString& aName, const uno::Any& aElement )
1750 uno::Type aModuleType = cppu::UnoType<script::XStarBasicModuleInfo>::get();
1751 const uno::Type& aAnyType = aElement.getValueType();
1752 if( aModuleType != aAnyType )
1754 throw lang::IllegalArgumentException();
1756 uno::Reference< script::XStarBasicModuleInfo > xMod;
1757 aElement >>= xMod;
1758 mpLib->MakeModule( aName, xMod->getSource() );
1761 void ModuleContainer_Impl::removeByName( const OUString& Name )
1763 SbModule* pMod = mpLib ? mpLib->FindModule( Name ) : nullptr;
1764 if( !pMod )
1766 throw container::NoSuchElementException();
1768 mpLib->Remove( pMod );
1772 static uno::Sequence< sal_Int8 > implGetDialogData( SbxObject* pDialog )
1774 SvMemoryStream aMemStream;
1775 pDialog->Store( aMemStream );
1776 sal_Int32 nLen = aMemStream.Tell();
1777 if (nLen < 0) { abort(); }
1778 uno::Sequence< sal_Int8 > aData( nLen );
1779 sal_Int8* pDestData = aData.getArray();
1780 const sal_Int8* pSrcData = static_cast<const sal_Int8*>(aMemStream.GetData());
1781 memcpy( pDestData, pSrcData, nLen );
1782 return aData;
1785 static SbxObject* implCreateDialog( const uno::Sequence< sal_Int8 >& aData )
1787 sal_Int8* pData = const_cast< uno::Sequence< sal_Int8 >& >(aData).getArray();
1788 SvMemoryStream aMemStream( pData, aData.getLength(), StreamMode::READ );
1789 SbxBase* pBase = SbxBase::Load( aMemStream );
1790 return dynamic_cast<SbxObject*>(pBase);
1793 // HACK! Because this value is defined in basctl/inc/vcsbxdef.hxx
1794 // which we can't include here, we have to use the value directly
1795 #define SBXID_DIALOG 101
1798 class DialogContainer_Impl : public NameContainerHelper
1800 StarBASIC* mpLib;
1802 public:
1803 explicit DialogContainer_Impl( StarBASIC* pLib )
1804 :mpLib( pLib ) {}
1806 // Methods XElementAccess
1807 virtual uno::Type SAL_CALL getElementType() override;
1808 virtual sal_Bool SAL_CALL hasElements() override;
1810 // Methods XNameAccess
1811 virtual uno::Any SAL_CALL getByName( const OUString& aName ) override;
1812 virtual uno::Sequence< OUString > SAL_CALL getElementNames() override;
1813 virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override;
1815 // Methods XNameReplace
1816 virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) override;
1818 // Methods XNameContainer
1819 virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) override;
1820 virtual void SAL_CALL removeByName( const OUString& Name ) override;
1823 // Methods XElementAccess
1824 uno::Type DialogContainer_Impl::getElementType()
1826 uno::Type aModuleType = cppu::UnoType<script::XStarBasicDialogInfo>::get();
1827 return aModuleType;
1830 sal_Bool DialogContainer_Impl::hasElements()
1832 bool bRet = false;
1834 sal_Int16 nCount = mpLib->GetObjects()->Count();
1835 for( sal_Int16 nObj = 0; nObj < nCount ; nObj++ )
1837 SbxVariable* pVar = mpLib->GetObjects()->Get( nObj );
1838 SbxObject* pObj = dynamic_cast<SbxObject*>(pVar);
1839 if ( pObj && (pObj->GetSbxId() == SBXID_DIALOG ) )
1841 bRet = true;
1842 break;
1845 return bRet;
1848 // Methods XNameAccess
1849 uno::Any DialogContainer_Impl::getByName( const OUString& aName )
1851 SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxClassType::DontCare );
1852 SbxObject* pObj = dynamic_cast<SbxObject*>(pVar);
1853 if( !( pObj && pObj->GetSbxId() == SBXID_DIALOG ) )
1855 throw container::NoSuchElementException();
1858 uno::Reference< script::XStarBasicDialogInfo > xDialog =
1859 new DialogInfo_Impl(aName, implGetDialogData(pObj));
1861 uno::Any aRetAny;
1862 aRetAny <<= xDialog;
1863 return aRetAny;
1866 uno::Sequence< OUString > DialogContainer_Impl::getElementNames()
1868 sal_Int16 nCount = mpLib->GetObjects()->Count();
1869 uno::Sequence< OUString > aRetSeq( nCount );
1870 OUString* pRetSeq = aRetSeq.getArray();
1871 sal_Int32 nDialogCounter = 0;
1873 for( sal_Int16 nObj = 0; nObj < nCount ; nObj++ )
1875 SbxVariable* pVar = mpLib->GetObjects()->Get( nObj );
1876 SbxObject* pObj = dynamic_cast<SbxObject*> (pVar);
1877 if ( pObj && ( pObj->GetSbxId() == SBXID_DIALOG ) )
1879 pRetSeq[ nDialogCounter ] = pVar->GetName();
1880 nDialogCounter++;
1883 aRetSeq.realloc( nDialogCounter );
1884 return aRetSeq;
1887 sal_Bool DialogContainer_Impl::hasByName( const OUString& aName )
1889 bool bRet = false;
1890 SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxClassType::DontCare );
1891 SbxObject* pObj = dynamic_cast<SbxObject*>(pVar);
1892 if( pObj && ( pObj->GetSbxId() == SBXID_DIALOG ) )
1894 bRet = true;
1896 return bRet;
1900 // Methods XNameReplace
1901 void DialogContainer_Impl::replaceByName( const OUString& aName, const uno::Any& aElement )
1903 removeByName( aName );
1904 insertByName( aName, aElement );
1908 // Methods XNameContainer
1909 void DialogContainer_Impl::insertByName( const OUString&, const uno::Any& aElement )
1911 uno::Type aModuleType = cppu::UnoType<script::XStarBasicDialogInfo>::get();
1912 const uno::Type& aAnyType = aElement.getValueType();
1913 if( aModuleType != aAnyType )
1915 throw lang::IllegalArgumentException();
1917 uno::Reference< script::XStarBasicDialogInfo > xMod;
1918 aElement >>= xMod;
1919 SbxObjectRef xDialog = implCreateDialog( xMod->getData() );
1920 mpLib->Insert( xDialog.get() );
1923 void DialogContainer_Impl::removeByName( const OUString& Name )
1925 SbxVariable* pVar = mpLib->GetObjects()->Find( Name, SbxClassType::DontCare );
1926 SbxObject* pObj = dynamic_cast<SbxObject*>(pVar);
1927 if( !( pObj && ( pObj->GetSbxId() == SBXID_DIALOG ) ) )
1929 throw container::NoSuchElementException();
1931 mpLib->Remove( pVar );
1935 class LibraryContainer_Impl : public NameContainerHelper
1937 BasicManager* mpMgr;
1939 public:
1940 explicit LibraryContainer_Impl( BasicManager* pMgr )
1941 :mpMgr( pMgr ) {}
1943 // Methods XElementAccess
1944 virtual uno::Type SAL_CALL getElementType() override;
1945 virtual sal_Bool SAL_CALL hasElements() override;
1947 // Methods XNameAccess
1948 virtual uno::Any SAL_CALL getByName( const OUString& aName ) override;
1949 virtual uno::Sequence< OUString > SAL_CALL getElementNames() override;
1950 virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override;
1952 // Methods XNameReplace
1953 virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) override;
1955 // Methods XNameContainer
1956 virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) override;
1957 virtual void SAL_CALL removeByName( const OUString& Name ) override;
1961 // Methods XElementAccess
1962 uno::Type LibraryContainer_Impl::getElementType()
1964 uno::Type aType = cppu::UnoType<script::XStarBasicLibraryInfo>::get();
1965 return aType;
1968 sal_Bool LibraryContainer_Impl::hasElements()
1970 sal_Int32 nLibs = mpMgr->GetLibCount();
1971 bool bRet = (nLibs > 0);
1972 return bRet;
1975 // Methods XNameAccess
1976 uno::Any LibraryContainer_Impl::getByName( const OUString& aName )
1978 uno::Any aRetAny;
1979 if( !mpMgr->HasLib( aName ) )
1980 throw container::NoSuchElementException();
1981 StarBASIC* pLib = mpMgr->GetLib( aName );
1983 uno::Reference< container::XNameContainer > xModuleContainer =
1984 new ModuleContainer_Impl( pLib );
1986 uno::Reference< container::XNameContainer > xDialogContainer =
1987 new DialogContainer_Impl( pLib );
1989 BasicLibInfo* pLibInfo = mpMgr->FindLibInfo( pLib );
1991 OUString aPassword = pLibInfo->GetPassword();
1993 // TODO Only provide extern info!
1994 OUString aExternaleSourceURL;
1995 OUString aLinkTargetURL;
1996 if( pLibInfo->IsReference() )
1998 aLinkTargetURL = pLibInfo->GetStorageName();
2000 else if( pLibInfo->IsExtern() )
2002 aExternaleSourceURL = pLibInfo->GetStorageName();
2004 uno::Reference< script::XStarBasicLibraryInfo > xLibInfo = new LibraryInfo_Impl
2006 aName,
2007 xModuleContainer,
2008 xDialogContainer,
2009 aPassword,
2010 aExternaleSourceURL,
2011 aLinkTargetURL
2014 aRetAny <<= xLibInfo;
2015 return aRetAny;
2018 uno::Sequence< OUString > LibraryContainer_Impl::getElementNames()
2020 sal_uInt16 nLibs = mpMgr->GetLibCount();
2021 uno::Sequence< OUString > aRetSeq( nLibs );
2022 OUString* pRetSeq = aRetSeq.getArray();
2023 for( sal_uInt16 i = 0 ; i < nLibs ; i++ )
2025 pRetSeq[i] = mpMgr->GetLibName( i );
2027 return aRetSeq;
2030 sal_Bool LibraryContainer_Impl::hasByName( const OUString& aName )
2032 bool bRet = mpMgr->HasLib( aName );
2033 return bRet;
2036 // Methods XNameReplace
2037 void LibraryContainer_Impl::replaceByName( const OUString& aName, const uno::Any& aElement )
2039 removeByName( aName );
2040 insertByName( aName, aElement );
2043 // Methods XNameContainer
2044 void LibraryContainer_Impl::insertByName( const OUString&, const uno::Any& )
2046 // TODO: Insert a complete Library?!
2049 void LibraryContainer_Impl::removeByName( const OUString& Name )
2051 StarBASIC* pLib = mpMgr->GetLib( Name );
2052 if( !pLib )
2054 throw container::NoSuchElementException();
2056 sal_uInt16 nLibId = mpMgr->GetLibId( Name );
2057 mpMgr->RemoveLib( nLibId );
2061 typedef WeakImplHelper< script::XStarBasicAccess > StarBasicAccessHelper;
2064 class StarBasicAccess_Impl : public StarBasicAccessHelper
2066 BasicManager* mpMgr;
2067 uno::Reference< container::XNameContainer > mxLibContainer;
2069 public:
2070 explicit StarBasicAccess_Impl( BasicManager* pMgr )
2071 :mpMgr( pMgr ) {}
2073 public:
2074 // Methods
2075 virtual uno::Reference< container::XNameContainer > SAL_CALL getLibraryContainer() override;
2076 virtual void SAL_CALL createLibrary( const OUString& LibName, const OUString& Password,
2077 const OUString& ExternalSourceURL, const OUString& LinkTargetURL ) override;
2078 virtual void SAL_CALL addModule( const OUString& LibraryName, const OUString& ModuleName,
2079 const OUString& Language, const OUString& Source ) override;
2080 virtual void SAL_CALL addDialog( const OUString& LibraryName, const OUString& DialogName,
2081 const uno::Sequence< sal_Int8 >& Data ) override;
2084 uno::Reference< container::XNameContainer > SAL_CALL StarBasicAccess_Impl::getLibraryContainer()
2086 if( !mxLibContainer.is() )
2087 mxLibContainer = new LibraryContainer_Impl( mpMgr );
2088 return mxLibContainer;
2091 void SAL_CALL StarBasicAccess_Impl::createLibrary
2093 const OUString& LibName,
2094 const OUString& Password,
2095 const OUString&,
2096 const OUString& LinkTargetURL
2099 StarBASIC* pLib = mpMgr->CreateLib( LibName, Password, LinkTargetURL );
2100 DBG_ASSERT( pLib, "XML Import: Basic library could not be created");
2103 void SAL_CALL StarBasicAccess_Impl::addModule
2105 const OUString& LibraryName,
2106 const OUString& ModuleName,
2107 const OUString&,
2108 const OUString& Source
2111 StarBASIC* pLib = mpMgr->GetLib( LibraryName );
2112 DBG_ASSERT( pLib, "XML Import: Lib for module unknown");
2113 if( pLib )
2115 pLib->MakeModule( ModuleName, Source );
2119 void SAL_CALL StarBasicAccess_Impl::addDialog
2121 const OUString&,
2122 const OUString&,
2123 const uno::Sequence< sal_Int8 >&
2127 // Basic XML Import/Export
2128 uno::Reference< script::XStarBasicAccess > getStarBasicAccess( BasicManager* pMgr )
2130 uno::Reference< script::XStarBasicAccess > xRet =
2131 new StarBasicAccess_Impl( pMgr );
2132 return xRet;
2135 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */