xref: /trunk/main/basic/source/basmgr/basmgr.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_basic.hxx"
26 #include <tools/stream.hxx>
27 #include <sot/storage.hxx>
28 #include <tools/urlobj.hxx>
29 #include <svl/smplhint.hxx>
30 #include <vcl/svapp.hxx>
31 #include <vcl/window.hxx>
32 #include <vcl/wrkwin.hxx>
33 #include <vcl/msgbox.hxx>
34 #include <basic/sbx.hxx>
35 #include <sot/storinfo.hxx>
36 #include <unotools/pathoptions.hxx>
37 #include <tools/debug.hxx>
38 #include <tools/diagnose_ex.h>
39 #include <basic/sbmod.hxx>
40 #include <basic/sbobjmod.hxx>
41 #include <unotools/intlwrapper.hxx>
42 #include <comphelper/processfactory.hxx>
43 
44 #include <basic/sbuno.hxx>
45 #include <basic/basmgr.hxx>
46 #include <sbunoobj.hxx>
47 #include "basrid.hxx"
48 #include "sbintern.hxx"
49 #include <sb.hrc>
50 
51 
52 #define LIB_SEP         0x01
53 #define LIBINFO_SEP     0x02
54 #define LIBINFO_ID      0x1491
55 #define PASSWORD_MARKER 0x31452134
56 
57 
58 // Library API, implemented for XML import/export
59 
60 #include <com/sun/star/container/XNameContainer.hpp>
61 #include <com/sun/star/container/XContainer.hpp>
62 #include <com/sun/star/script/XStarBasicAccess.hpp>
63 #include <com/sun/star/script/XStarBasicModuleInfo.hpp>
64 #include <com/sun/star/script/XStarBasicDialogInfo.hpp>
65 #include <com/sun/star/script/XStarBasicLibraryInfo.hpp>
66 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
67 #include <com/sun/star/script/ModuleInfo.hpp>
68 #include <com/sun/star/script/vba/XVBACompatibility.hpp>
69 #include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
70 
71 #include <cppuhelper/implbase1.hxx>
72 
73 using com::sun::star::uno::Reference;
74 using namespace com::sun::star::container;
75 using namespace com::sun::star::uno;
76 using namespace com::sun::star::lang;
77 using namespace com::sun::star::script;
78 using namespace cppu;
79 
80 typedef WeakImplHelper1< XNameContainer > NameContainerHelper;
81 typedef WeakImplHelper1< XStarBasicModuleInfo > ModuleInfoHelper;
82 typedef WeakImplHelper1< XStarBasicDialogInfo > DialogInfoHelper;
83 typedef WeakImplHelper1< XStarBasicLibraryInfo > LibraryInfoHelper;
84 typedef WeakImplHelper1< XStarBasicAccess > StarBasicAccessHelper;
85 
86 
87 
88 #define CURR_VER        2
89 
90 // Version 1
91 //    sal_uIntPtr   nEndPos
92 //    sal_uInt16    nId
93 //    sal_uInt16    nVer
94 //    sal_Bool      bDoLoad
95 //    String    LibName
96 //    String    AbsStorageName
97 //    String    RelStorageName
98 // Version 2
99 //  + sal_Bool      bReference
100 
101 static const char* szStdLibName = "Standard";
102 static const char szBasicStorage[] = "StarBASIC";
103 static const char* szOldManagerStream = "BasicManager";
104 static const char szManagerStream[] = "BasicManager2";
105 static const char* szImbedded = "LIBIMBEDDED";
106 static const char* szCryptingKey = "CryptedBasic";
107 static const char* szScriptLanguage = "StarBasic";
108 
109 TYPEINIT1( BasicManager, SfxBroadcaster );
110 DBG_NAME( BasicManager );
111 
112 StreamMode eStreamReadMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYALL;
113 StreamMode eStorageReadMode = STREAM_READ | STREAM_SHARE_DENYWRITE;
114 
115 DECLARE_LIST( BasErrorLst, BasicError* )
116 
117 //----------------------------------------------------------------------------
118 // BasicManager impl data
119 struct BasicManagerImpl
120 {
121     LibraryContainerInfo    maContainerInfo;
122 
123     // Save stream data
124     SvMemoryStream*  mpManagerStream;
125     SvMemoryStream** mppLibStreams;
126     sal_Int32        mnLibStreamCount;
127     sal_Bool         mbModifiedByLibraryContainer;
128     sal_Bool         mbError;
129 
BasicManagerImplBasicManagerImpl130     BasicManagerImpl( void )
131         : mpManagerStream( NULL )
132         , mppLibStreams( NULL )
133         , mnLibStreamCount( 0 )
134         , mbModifiedByLibraryContainer( sal_False )
135         , mbError( sal_False )
136     {}
137     ~BasicManagerImpl();
138 };
139 
~BasicManagerImpl()140 BasicManagerImpl::~BasicManagerImpl()
141 {
142     delete mpManagerStream;
143     if( mppLibStreams )
144     {
145         for( sal_Int32 i = 0 ; i < mnLibStreamCount ; i++ )
146             delete mppLibStreams[i];
147         delete[] mppLibStreams;
148     }
149 }
150 
151 //============================================================================
152 // BasMgrContainerListenerImpl
153 //============================================================================
154 
155 typedef ::cppu::WeakImplHelper1< ::com::sun::star::container::XContainerListener > ContainerListenerHelper;
156 
157 class BasMgrContainerListenerImpl: public ContainerListenerHelper
158 {
159     BasicManager* mpMgr;
160     ::rtl::OUString maLibName;      // empty -> no lib, but lib container
161 
162 public:
BasMgrContainerListenerImpl(BasicManager * pMgr,::rtl::OUString aLibName)163     BasMgrContainerListenerImpl( BasicManager* pMgr, ::rtl::OUString aLibName )
164         : mpMgr( pMgr )
165         , maLibName( aLibName ) {}
166 
167     static void insertLibraryImpl( const Reference< XLibraryContainer >& xScriptCont, BasicManager* pMgr,
168         Any aLibAny, ::rtl::OUString aLibName );
169     static void addLibraryModulesImpl( BasicManager* pMgr, Reference< XNameAccess > xLibNameAccess,
170         ::rtl::OUString aLibName );
171 
172 
173     // XEventListener
174     virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source );
175 
176     // XContainerListener
177     virtual void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& Event );
178     virtual void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& Event );
179     virtual void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& Event );
180 };
181 
182 
183 //============================================================================
184 // BasMgrContainerListenerImpl
185 //============================================================================
186 
insertLibraryImpl(const Reference<XLibraryContainer> & xScriptCont,BasicManager * pMgr,Any aLibAny,::rtl::OUString aLibName)187 void BasMgrContainerListenerImpl::insertLibraryImpl( const Reference< XLibraryContainer >& xScriptCont,
188     BasicManager* pMgr, Any aLibAny, ::rtl::OUString aLibName )
189 {
190     Reference< XNameAccess > xLibNameAccess;
191     aLibAny >>= xLibNameAccess;
192 
193     if( !pMgr->GetLib( aLibName ) )
194     {
195         BasicManager* pBasMgr = static_cast< BasicManager* >( pMgr );
196 #ifdef DBG_UTIL
197         StarBASIC* pLib =
198 #endif
199         pBasMgr->CreateLibForLibContainer( aLibName, xScriptCont );
200         DBG_ASSERT( pLib, "XML Import: Basic library could not be created");
201     }
202 
203     Reference< XContainer> xLibContainer( xLibNameAccess, UNO_QUERY );
204     if( xLibContainer.is() )
205     {
206         // Register listener for library
207         Reference< XContainerListener > xLibraryListener
208             = static_cast< XContainerListener* >
209                 ( new BasMgrContainerListenerImpl( pMgr, aLibName ) );
210         xLibContainer->addContainerListener( xLibraryListener );
211     }
212 
213     if( xScriptCont->isLibraryLoaded( aLibName ) )
214     {
215         addLibraryModulesImpl( pMgr, xLibNameAccess, aLibName );
216     }
217 }
218 
219 
addLibraryModulesImpl(BasicManager * pMgr,Reference<XNameAccess> xLibNameAccess,::rtl::OUString aLibName)220 void BasMgrContainerListenerImpl::addLibraryModulesImpl( BasicManager* pMgr,
221     Reference< XNameAccess > xLibNameAccess, ::rtl::OUString aLibName )
222 {
223     Sequence< ::rtl::OUString > aModuleNames = xLibNameAccess->getElementNames();
224     sal_Int32 nModuleCount = aModuleNames.getLength();
225 
226     StarBASIC* pLib = pMgr->GetLib( aLibName );
227     DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::addLibraryModulesImpl: Unknown lib!");
228     if( pLib )
229     {
230         const ::rtl::OUString* pNames = aModuleNames.getConstArray();
231         for( sal_Int32 j = 0 ; j < nModuleCount ; j++ )
232         {
233             ::rtl::OUString aModuleName = pNames[ j ];
234             Any aElement = xLibNameAccess->getByName( aModuleName );
235             ::rtl::OUString aMod;
236             aElement >>= aMod;
237             Reference< vba::XVBAModuleInfo > xVBAModuleInfo( xLibNameAccess, UNO_QUERY );
238             if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aModuleName ) )
239             {
240                 ModuleInfo mInfo = xVBAModuleInfo->getModuleInfo( aModuleName );
241                 OSL_TRACE("#addLibraryModulesImpl - aMod");
242                 pLib->MakeModule32( aModuleName, mInfo, aMod );
243             }
244             else
245         pLib->MakeModule32( aModuleName, aMod );
246         }
247     }
248 
249     pLib->SetModified( sal_False );
250 }
251 
252 
253 
254 // XEventListener
255 //----------------------------------------------------------------------------
256 
disposing(const EventObject & Source)257 void SAL_CALL BasMgrContainerListenerImpl::disposing( const EventObject& Source )
258 {
259     (void)Source;
260 }
261 
262 // XContainerListener
263 //----------------------------------------------------------------------------
264 
elementInserted(const ContainerEvent & Event)265 void SAL_CALL BasMgrContainerListenerImpl::elementInserted( const ContainerEvent& Event )
266 {
267     sal_Bool bLibContainer = maLibName.isEmpty();
268     ::rtl::OUString aName;
269     Event.Accessor >>= aName;
270 
271     mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True;
272 
273     if( bLibContainer )
274     {
275         Reference< XLibraryContainer > xScriptCont( Event.Source, UNO_QUERY );
276         insertLibraryImpl( xScriptCont, mpMgr, Event.Element, aName );
277         StarBASIC* pLib = mpMgr->GetLib( aName );
278         if ( pLib )
279         {
280             Reference< vba::XVBACompatibility > xVBACompat( xScriptCont, UNO_QUERY );
281             if ( xVBACompat.is() )
282                 pLib->SetVBAEnabled( xVBACompat->getVBACompatibilityMode() );
283         }
284     }
285     else
286     {
287 
288         StarBASIC* pLib = mpMgr->GetLib( maLibName );
289         DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::elementInserted: Unknown lib!");
290         if( pLib )
291         {
292             SbModule* pMod = pLib->FindModule( aName );
293             if( !pMod )
294             {
295             ::rtl::OUString aMod;
296             Event.Element >>= aMod;
297                 Reference< vba::XVBAModuleInfo > xVBAModuleInfo( Event.Source, UNO_QUERY );
298                 if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aName ) )
299                 {
300                     ModuleInfo mInfo = xVBAModuleInfo->getModuleInfo( aName );
301                     pLib->MakeModule32( aName, mInfo, aMod );
302                 }
303                 else
304                     pLib->MakeModule32( aName, aMod );
305                 pLib->SetModified( sal_False );
306             }
307         }
308     }
309 }
310 
311 //----------------------------------------------------------------------------
312 
elementReplaced(const ContainerEvent & Event)313 void SAL_CALL BasMgrContainerListenerImpl::elementReplaced( const ContainerEvent& Event )
314 {
315     ::rtl::OUString aName;
316     Event.Accessor >>= aName;
317 
318     mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True;
319 
320     // Replace not possible for library container
321 #ifdef DBG_UTIL
322     sal_Bool bLibContainer = maLibName.isEmpty();
323 #endif
324     DBG_ASSERT( !bLibContainer, "library container fired elementReplaced()");
325 
326     StarBASIC* pLib = mpMgr->GetLib( maLibName );
327     if( pLib )
328     {
329         SbModule* pMod = pLib->FindModule( aName );
330         ::rtl::OUString aMod;
331         Event.Element >>= aMod;
332 
333         if( pMod )
334                 pMod->SetSource32( aMod );
335         else
336                 pLib->MakeModule32( aName, aMod );
337 
338         pLib->SetModified( sal_False );
339     }
340 }
341 
342 //----------------------------------------------------------------------------
343 
elementRemoved(const ContainerEvent & Event)344 void SAL_CALL BasMgrContainerListenerImpl::elementRemoved( const ContainerEvent& Event )
345 {
346     ::rtl::OUString aName;
347     Event.Accessor >>= aName;
348 
349     mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True;
350 
351     sal_Bool bLibContainer = maLibName.isEmpty();
352     if( bLibContainer )
353     {
354         StarBASIC* pLib = mpMgr->GetLib( aName );
355         if( pLib )
356         {
357             sal_uInt16 nLibId = mpMgr->GetLibId( aName );
358             mpMgr->RemoveLib( nLibId, sal_False );
359         }
360     }
361     else
362     {
363         StarBASIC* pLib = mpMgr->GetLib( maLibName );
364         SbModule* pMod = pLib ? pLib->FindModule( aName ) : NULL;
365         if( pMod )
366         {
367             pLib->Remove( pMod );
368             pLib->SetModified( sal_False );
369         }
370     }
371 }
372 
373 
374 //=====================================================================
375 
376 class BasicErrorManager
377 {
378 private:
379     BasErrorLst aErrorList;
380 
381 public:
382                 ~BasicErrorManager();
383 
384     void        Reset();
385     void        InsertError( const BasicError& rError );
386 
HasErrors()387     sal_Bool        HasErrors()         { return (sal_Bool)aErrorList.Count(); }
GetFirstError()388     BasicError* GetFirstError()     { return aErrorList.First(); }
GetNextError()389     BasicError* GetNextError()      { return aErrorList.Next(); }
390 };
391 
392 
~BasicErrorManager()393 BasicErrorManager::~BasicErrorManager()
394 {
395     Reset();
396 }
397 
Reset()398 void BasicErrorManager::Reset()
399 {
400     BasicError* pError = (BasicError*)aErrorList.First();
401     while ( pError )
402     {
403         delete pError;
404         pError = (BasicError*)aErrorList.Next();
405     }
406     aErrorList.Clear();
407 }
408 
InsertError(const BasicError & rError)409 void BasicErrorManager::InsertError( const BasicError& rError )
410 {
411     aErrorList.Insert( new BasicError( rError ), LIST_APPEND );
412 }
413 
414 
BasicError()415 BasicError::BasicError()
416 {
417     nErrorId    = 0;
418     nReason     = 0;
419 }
420 
BasicError(sal_uIntPtr nId,sal_uInt16 nR,const String & rErrStr)421 BasicError::BasicError( sal_uIntPtr nId, sal_uInt16 nR, const String& rErrStr ) :
422     aErrStr( rErrStr )
423 {
424     nErrorId    = nId;
425     nReason     = nR;
426 }
427 
BasicError(const BasicError & rErr)428 BasicError::BasicError( const BasicError& rErr ) :
429     aErrStr( rErr.aErrStr )
430 {
431     nErrorId    = rErr.nErrorId;
432     nReason     = rErr.nReason;
433 }
434 
435 
436 class BasicLibInfo
437 {
438 private:
439     StarBASICRef    xLib;
440     String          aLibName;
441     String          aStorageName;   // String is sufficient, unique at runtime
442     String          aRelStorageName;
443     String          aPassword;
444 
445     sal_Bool            bDoLoad;
446     sal_Bool            bReference;
447     sal_Bool            bPasswordVerified;
448     sal_Bool            bFoundInPath;   // Must not relativated again!
449 
450     // Lib represents library in new UNO library container
451     Reference< XLibraryContainer > mxScriptCont;
452 
453 public:
454     BasicLibInfo();
455     BasicLibInfo( const String& rStorageName );
456 
IsReference() const457     sal_Bool            IsReference() const     { return bReference; }
IsReference()458     sal_Bool&           IsReference()           { return bReference; }
459 
IsExtern() const460     sal_Bool            IsExtern() const        { return ! aStorageName.EqualsAscii(szImbedded); }
461 
SetStorageName(const String & rName)462     void            SetStorageName( const String& rName )   { aStorageName = rName; }
GetStorageName() const463     const String&   GetStorageName() const                  { return aStorageName; }
464 
SetRelStorageName(const String & rN)465     void            SetRelStorageName( const String& rN )   { aRelStorageName = rN; }
GetRelStorageName() const466     const String&   GetRelStorageName() const               { return aRelStorageName; }
467     void            CalcRelStorageName( const String& rMgrStorageName );
468 
GetLib() const469     StarBASICRef    GetLib() const
470     {
471         if( mxScriptCont.is() && mxScriptCont->hasByName( aLibName ) &&
472             !mxScriptCont->isLibraryLoaded( aLibName ) )
473                 return StarBASICRef();
474         return xLib;
475     }
GetLibRef()476     StarBASICRef&   GetLibRef()                         { return xLib; }
SetLib(StarBASIC * pBasic)477     void            SetLib( StarBASIC* pBasic )         { xLib = pBasic; }
478 
GetLibName() const479     const String&   GetLibName() const                  { return aLibName; }
SetLibName(const String & rName)480     void            SetLibName( const String& rName )   { aLibName = rName; }
481 
482     // Only temporary for Load/Save
DoLoad()483     sal_Bool            DoLoad()                            { return bDoLoad; }
484 
HasPassword() const485     sal_Bool            HasPassword() const                 { return aPassword.Len() != 0; }
GetPassword() const486     const String&   GetPassword() const                 { return aPassword; }
SetPassword(const String & rNewPassword)487     void            SetPassword( const String& rNewPassword )
488                                                         { aPassword = rNewPassword; }
IsPasswordVerified() const489     sal_Bool            IsPasswordVerified() const          { return bPasswordVerified; }
SetPasswordVerified()490     void            SetPasswordVerified()               { bPasswordVerified = sal_True; }
491 
IsFoundInPath() const492     sal_Bool            IsFoundInPath() const               { return bFoundInPath; }
SetFoundInPath(sal_Bool bInPath)493     void            SetFoundInPath( sal_Bool bInPath )      { bFoundInPath = bInPath; }
494 
495     void                    Store( SotStorageStream& rSStream, const String& rBasMgrStorageName, sal_Bool bUseOldReloadInfo );
496     static BasicLibInfo*    Create( SotStorageStream& rSStream );
497 
GetLibraryContainer(void)498     Reference< XLibraryContainer > GetLibraryContainer( void )
499         { return mxScriptCont; }
SetLibraryContainer(const Reference<XLibraryContainer> & xScriptCont)500     void SetLibraryContainer( const Reference< XLibraryContainer >& xScriptCont )
501         { mxScriptCont = xScriptCont; }
502 };
503 
504 DECLARE_LIST( BasicLibsBase, BasicLibInfo* )
505 
506 class BasicLibs : public BasicLibsBase
507 {
508 public:
509     String  aBasicLibPath; // TODO: Should be member of manager, but currently not incompatible
510 };
511 
BasicLibInfo()512 BasicLibInfo::BasicLibInfo()
513 {
514     bReference          = sal_False;
515     bPasswordVerified   = sal_False;
516     bDoLoad             = sal_False;
517     bFoundInPath        = sal_False;
518     mxScriptCont        = NULL;
519     aStorageName        = String::CreateFromAscii(szImbedded);
520     aRelStorageName     = String::CreateFromAscii(szImbedded);
521 }
522 
BasicLibInfo(const String & rStorageName)523 BasicLibInfo::BasicLibInfo( const String& rStorageName )
524 {
525     bReference          = sal_True;
526     bPasswordVerified   = sal_False;
527     bDoLoad             = sal_False;
528     mxScriptCont        = NULL;
529     aStorageName        = rStorageName;
530 }
531 
Store(SotStorageStream & rSStream,const String & rBasMgrStorageName,sal_Bool bUseOldReloadInfo)532 void BasicLibInfo::Store( SotStorageStream& rSStream, const String& rBasMgrStorageName, sal_Bool bUseOldReloadInfo )
533 {
534     sal_uIntPtr nStartPos = rSStream.Tell();
535     sal_uInt32 nEndPos = 0;
536 
537     sal_uInt16 nId = LIBINFO_ID;
538     sal_uInt16 nVer = CURR_VER;
539 
540     rSStream << nEndPos;
541     rSStream << nId;
542     rSStream << nVer;
543 
544     String aCurStorageName = INetURLObject(rBasMgrStorageName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
545     DBG_ASSERT(aCurStorageName.Len() != 0, "Bad storage name");
546 
547     // If not set initialize StorageName
548     if ( aStorageName.Len() == 0 )
549         aStorageName = aCurStorageName;
550 
551     // Load again?
552     sal_Bool bDoLoad_ = xLib.Is();
553     if ( bUseOldReloadInfo )
554         bDoLoad_ = DoLoad();
555     rSStream << bDoLoad_;
556 
557     // The name of the lib...
558     rSStream.WriteByteString(GetLibName());
559 
560     // Absolute path...
561     if ( ! GetStorageName().EqualsAscii(szImbedded) )
562     {
563         String aSName = INetURLObject( GetStorageName(), INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
564         DBG_ASSERT(aSName.Len() != 0, "Bad storage name");
565         rSStream.WriteByteString( aSName );
566     }
567     else
568         rSStream.WriteByteString( szImbedded );
569 
570     // Relative path...
571     if ( ( aStorageName == aCurStorageName ) || ( aStorageName.EqualsAscii(szImbedded) ) )
572         rSStream.WriteByteString( szImbedded );
573     else
574     {
575         // Do not determine the relative path if the file was only found in path:
576         // because the relative path would change and after moving the lib the
577         // the file cannot be found.
578         if ( !IsFoundInPath() )
579             CalcRelStorageName( aCurStorageName );
580         rSStream.WriteByteString(aRelStorageName);
581     }
582 
583     // ------------------------------
584     // Version 2
585     // ------------------------------
586 
587     // reference...
588     rSStream << bReference;
589 
590     // ------------------------------
591     // End
592     // ------------------------------
593 
594     nEndPos = rSStream.Tell();
595     rSStream.Seek( nStartPos );
596     rSStream << nEndPos;
597     rSStream.Seek( nEndPos );
598 }
599 
Create(SotStorageStream & rSStream)600 BasicLibInfo* BasicLibInfo::Create( SotStorageStream& rSStream )
601 {
602     BasicLibInfo* pInfo = new BasicLibInfo;
603 
604     sal_uInt32 nEndPos;
605     sal_uInt16 nId;
606     sal_uInt16 nVer;
607 
608     rSStream >> nEndPos;
609     rSStream >> nId;
610     rSStream >> nVer;
611 
612     DBG_ASSERT( nId == LIBINFO_ID, "Keine BasicLibInfo !?" );
613     if( nId == LIBINFO_ID )
614     {
615         // Reload?
616         sal_Bool bDoLoad;
617         rSStream >> bDoLoad;
618         pInfo->bDoLoad = bDoLoad;
619 
620         // The name of the lib...
621         String aName;
622         rSStream.ReadByteString(aName);
623         pInfo->SetLibName( aName );
624 
625         // Absolute path...
626         String aStorageName;
627         rSStream.ReadByteString(aStorageName);
628         pInfo->SetStorageName( aStorageName );
629 
630         // Relative path...
631         String aRelStorageName;
632         rSStream.ReadByteString(aRelStorageName);
633         pInfo->SetRelStorageName( aRelStorageName );
634 
635         if ( nVer >= 2 )
636         {
637             sal_Bool bReferenz;
638             rSStream >> bReferenz;
639             pInfo->IsReference() = bReferenz;
640         }
641 
642         rSStream.Seek( nEndPos );
643     }
644     return pInfo;
645 }
646 
CalcRelStorageName(const String & rMgrStorageName)647 void BasicLibInfo::CalcRelStorageName( const String& rMgrStorageName )
648 {
649     if ( rMgrStorageName.Len() )
650     {
651         INetURLObject aAbsURLObj( rMgrStorageName );
652         aAbsURLObj.removeSegment();
653         String aPath = aAbsURLObj.GetMainURL( INetURLObject::NO_DECODE );
654         UniString aRelURL = INetURLObject::GetRelURL( aPath, GetStorageName() );
655         SetRelStorageName( aRelURL );
656     }
657     else
658         SetRelStorageName( String() );
659 }
BasicManager(SotStorage & rStorage,const String & rBaseURL,StarBASIC * pParentFromStdLib,String * pLibPath,sal_Bool bDocMgr)660 BasicManager::BasicManager( SotStorage& rStorage, const String& rBaseURL, StarBASIC* pParentFromStdLib, String* pLibPath, sal_Bool bDocMgr ) : mbDocMgr( bDocMgr )
661 {
662     DBG_CTOR( BasicManager, 0 );
663 
664     Init();
665 
666     if( pLibPath )
667         pLibs->aBasicLibPath = *pLibPath;
668 
669     String aStorName( rStorage.GetName() );
670     maStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
671 
672     // #91251: Storage name not longer available for documents < 5.0
673     // Should be no real problem, because only relative storage names
674     // (links) can be affected.
675     // DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
676     // DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
677 
678     // If there is no Manager Stream, no further actions are necessary
679     if ( rStorage.IsStream( String(RTL_CONSTASCII_USTRINGPARAM(szManagerStream)) ) )
680     {
681         LoadBasicManager( rStorage, rBaseURL );
682         // StdLib contains Parent:
683         StarBASIC* pStdLib = GetStdLib();
684         DBG_ASSERT( pStdLib, "Standard-Lib not loaded?" );
685         if ( !pStdLib )
686         {
687             // Should never happen, but if it happens we won't crash...
688             pStdLib = new StarBASIC( NULL, mbDocMgr );
689             BasicLibInfo* pStdLibInfo = pLibs->GetObject( 0 );
690             if ( !pStdLibInfo )
691                 pStdLibInfo = CreateLibInfo();
692             pStdLibInfo->SetLib( pStdLib );
693             StarBASICRef xStdLib = pStdLibInfo->GetLib();
694             xStdLib->SetName( String::CreateFromAscii(szStdLibName) );
695             pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
696             xStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
697             xStdLib->SetModified( sal_False );
698         }
699         else
700         {
701             pStdLib->SetParent( pParentFromStdLib );
702             // The other get StdLib as parent:
703             for ( sal_uInt16 nBasic = 1; nBasic < GetLibCount(); nBasic++ )
704             {
705                 StarBASIC* pBasic = GetLib( nBasic );
706                 if ( pBasic )
707                 {
708 //                  pBasic->SetParent( pStdLib );
709                     pStdLib->Insert( pBasic );
710                     pBasic->SetFlag( SBX_EXTSEARCH );
711                 }
712             }
713             // Modified through insert
714             pStdLib->SetModified( sal_False );
715         }
716 
717         // #91626 Save all stream data to save it unmodified if basic isn't modified
718         // in an 6.0+ office. So also the old basic dialogs can be saved.
719         SotStorageStreamRef xManagerStream = rStorage.OpenSotStream
720             ( String(RTL_CONSTASCII_USTRINGPARAM(szManagerStream)), eStreamReadMode );
721         mpImpl->mpManagerStream = new SvMemoryStream();
722         *static_cast<SvStream*>(&xManagerStream) >> *mpImpl->mpManagerStream;
723 
724         SotStorageRef xBasicStorage = rStorage.OpenSotStorage
725                                 ( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)), eStorageReadMode, sal_False );
726         if( xBasicStorage.Is() && !xBasicStorage->GetError() )
727         {
728             sal_uInt16 nLibs = GetLibCount();
729             mpImpl->mppLibStreams = new SvMemoryStream*[ nLibs ];
730             for( sal_uInt16 nL = 0; nL < nLibs; nL++ )
731             {
732                 BasicLibInfo* pInfo = pLibs->GetObject( nL );
733                 DBG_ASSERT( pInfo, "pInfo?!" );
734                 SotStorageStreamRef xBasicStream = xBasicStorage->OpenSotStream( pInfo->GetLibName(), eStreamReadMode );
735                 mpImpl->mppLibStreams[nL] = new SvMemoryStream();
736                 *static_cast<SvStream*>(&xBasicStream) >> *( mpImpl->mppLibStreams[nL] );
737             }
738         }
739         else
740             mpImpl->mbError = sal_True;
741     }
742     else
743     {
744         ImpCreateStdLib( pParentFromStdLib );
745         if ( rStorage.IsStream( String::CreateFromAscii(szOldManagerStream) ) )
746             LoadOldBasicManager( rStorage );
747     }
748 
749     bBasMgrModified = sal_False;
750 }
751 
copyToLibraryContainer(StarBASIC * pBasic,const LibraryContainerInfo & rInfo)752 void copyToLibraryContainer( StarBASIC* pBasic, const LibraryContainerInfo& rInfo )
753 {
754     Reference< XLibraryContainer > xScriptCont( rInfo.mxScriptCont.get() );
755     if ( !xScriptCont.is() )
756         return;
757 
758     String aLibName = pBasic->GetName();
759     if( !xScriptCont->hasByName( aLibName ) )
760         xScriptCont->createLibrary( aLibName );
761 
762     Any aLibAny = xScriptCont->getByName( aLibName );
763     Reference< XNameContainer > xLib;
764     aLibAny >>= xLib;
765     if ( !xLib.is() )
766         return;
767 
768     sal_uInt16 nModCount = pBasic->GetModules()->Count();
769     for ( sal_uInt16 nMod = 0 ; nMod < nModCount ; nMod++ )
770     {
771         SbModule* pModule = (SbModule*)pBasic->GetModules()->Get( nMod );
772         DBG_ASSERT( pModule, "Modul nicht erhalten!" );
773 
774         String aModName = pModule->GetName();
775         if( !xLib->hasByName( aModName ) )
776         {
777             ::rtl::OUString aSource = pModule->GetSource32();
778             Any aSourceAny;
779             aSourceAny <<= aSource;
780             xLib->insertByName( aModName, aSourceAny );
781         }
782     }
783 }
784 
GetDialogLibraryContainer() const785 const Reference< XPersistentLibraryContainer >& BasicManager::GetDialogLibraryContainer() const
786 {
787     return mpImpl->maContainerInfo.mxDialogCont;
788 }
789 
GetScriptLibraryContainer() const790 const Reference< XPersistentLibraryContainer >& BasicManager::GetScriptLibraryContainer() const
791 {
792     return mpImpl->maContainerInfo.mxScriptCont;
793 }
794 
SetLibraryContainerInfo(const LibraryContainerInfo & rInfo)795 void BasicManager::SetLibraryContainerInfo( const LibraryContainerInfo& rInfo )
796 {
797     mpImpl->maContainerInfo = rInfo;
798 
799     Reference< XLibraryContainer > xScriptCont( mpImpl->maContainerInfo.mxScriptCont.get() );
800     StarBASIC* pStdLib = GetStdLib();
801     String aLibName = pStdLib->GetName();
802     if( xScriptCont.is() )
803     {
804         // Register listener for lib container
805         ::rtl::OUString aEmptyLibName;
806         Reference< XContainerListener > xLibContainerListener
807             = static_cast< XContainerListener* >
808                 ( new BasMgrContainerListenerImpl( this, aEmptyLibName ) );
809 
810         Reference< XContainer> xLibContainer( xScriptCont, UNO_QUERY );
811         xLibContainer->addContainerListener( xLibContainerListener );
812 
813         Sequence< ::rtl::OUString > aScriptLibNames = xScriptCont->getElementNames();
814         const ::rtl::OUString* pScriptLibName = aScriptLibNames.getConstArray();
815         sal_Int32 i, nNameCount = aScriptLibNames.getLength();
816 
817         if( nNameCount )
818         {
819             for( i = 0 ; i < nNameCount ; ++i, ++pScriptLibName )
820             {
821                 Any aLibAny = xScriptCont->getByName( *pScriptLibName );
822 
823                 if ( pScriptLibName->equalsAscii( "Standard" ) )
824                     xScriptCont->loadLibrary( *pScriptLibName );
825 
826                 BasMgrContainerListenerImpl::insertLibraryImpl
827                     ( xScriptCont, this, aLibAny, *pScriptLibName );
828             }
829         }
830         else
831         {
832             // No libs? Maybe an 5.2 document already loaded
833             sal_uInt16 nLibs = GetLibCount();
834             for( sal_uInt16 nL = 0; nL < nLibs; nL++ )
835             {
836                 BasicLibInfo* pBasLibInfo = pLibs->GetObject( nL );
837                 StarBASIC* pLib = pBasLibInfo->GetLib();
838                 if( !pLib )
839                 {
840                     sal_Bool bLoaded = ImpLoadLibary( pBasLibInfo, NULL, sal_False );
841                     if( bLoaded )
842                         pLib = pBasLibInfo->GetLib();
843                 }
844                 if( pLib )
845                 {
846                     copyToLibraryContainer( pLib, mpImpl->maContainerInfo );
847                     if( pBasLibInfo->HasPassword() )
848                     {
849                         OldBasicPassword* pOldBasicPassword =
850                             mpImpl->maContainerInfo.mpOldBasicPassword;
851                         if( pOldBasicPassword )
852                         {
853                             pOldBasicPassword->setLibraryPassword
854                                 ( pLib->GetName(), pBasLibInfo->GetPassword() );
855                             pBasLibInfo->SetPasswordVerified();
856                         }
857                     }
858                 }
859             }
860 
861             mpImpl->mbModifiedByLibraryContainer = sal_False;
862         }
863     }
864 
865     SetGlobalUNOConstant( "BasicLibraries", makeAny( mpImpl->maContainerInfo.mxScriptCont ) );
866     SetGlobalUNOConstant( "DialogLibraries", makeAny( mpImpl->maContainerInfo.mxDialogCont ) );
867 }
868 
BasicManager(StarBASIC * pSLib,String * pLibPath,sal_Bool bDocMgr)869 BasicManager::BasicManager( StarBASIC* pSLib, String* pLibPath, sal_Bool bDocMgr ) : mbDocMgr( bDocMgr )
870 {
871     DBG_CTOR( BasicManager, 0 );
872     Init();
873     DBG_ASSERT( pSLib, "BasicManager cannot be created with a NULL-Pointer!" );
874 
875     if( pLibPath )
876         pLibs->aBasicLibPath = *pLibPath;
877 
878     BasicLibInfo* pStdLibInfo = CreateLibInfo();
879     pStdLibInfo->SetLib( pSLib );
880     StarBASICRef xStdLib = pStdLibInfo->GetLib();
881     xStdLib->SetName( String::CreateFromAscii(szStdLibName));
882     pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
883     pSLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
884 
885     // Save is only necessary if basic has changed
886     xStdLib->SetModified( sal_False );
887     bBasMgrModified = sal_False;
888 }
889 
BasicManager()890 BasicManager::BasicManager()
891 {
892     DBG_CTOR( BasicManager, 0 );
893     // This ctor may only be used to adapt relative paths for 'Save As'.
894     // There is no AppBasic so libs must not be loaded...
895     Init();
896 }
897 
ImpMgrNotLoaded(const String & rStorageName)898 void BasicManager::ImpMgrNotLoaded( const String& rStorageName )
899 {
900     // pErrInf is only destroyed if the error is processed by an
901     // ErrorHandler
902     StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, rStorageName, ERRCODE_BUTTON_OK );
903     pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENMGRSTREAM, rStorageName ) );
904 
905     // Create a stdlib otherwise we crash!
906     BasicLibInfo* pStdLibInfo = CreateLibInfo();
907     pStdLibInfo->SetLib( new StarBASIC( NULL, mbDocMgr ) );
908     StarBASICRef xStdLib = pStdLibInfo->GetLib();
909     xStdLib->SetName( String::CreateFromAscii(szStdLibName) );
910     pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
911     xStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
912     xStdLib->SetModified( sal_False );
913 }
914 
915 
ImpCreateStdLib(StarBASIC * pParentFromStdLib)916 void BasicManager::ImpCreateStdLib( StarBASIC* pParentFromStdLib )
917 {
918     BasicLibInfo* pStdLibInfo = CreateLibInfo();
919     StarBASIC* pStdLib = new StarBASIC( pParentFromStdLib, mbDocMgr );
920     pStdLibInfo->SetLib( pStdLib );
921     pStdLib->SetName( String::CreateFromAscii(szStdLibName) );
922     pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
923     pStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
924 }
925 
926 
LoadBasicManager(SotStorage & rStorage,const String & rBaseURL,sal_Bool bLoadLibs)927 void BasicManager::LoadBasicManager( SotStorage& rStorage, const String& rBaseURL, sal_Bool bLoadLibs )
928 {
929     DBG_CHKTHIS( BasicManager, 0 );
930 
931 //  StreamMode eStreamMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE;
932 
933     SotStorageStreamRef xManagerStream = rStorage.OpenSotStream
934         ( String(RTL_CONSTASCII_USTRINGPARAM(szManagerStream)), eStreamReadMode );
935 
936     String aStorName( rStorage.GetName() );
937     // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
938 
939     if ( !xManagerStream.Is() || xManagerStream->GetError() || ( xManagerStream->Seek( STREAM_SEEK_TO_END ) == 0 ) )
940     {
941         ImpMgrNotLoaded( aStorName );
942         return;
943     }
944 
945     maStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
946     // #i13114 removed, DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
947 
948     String aRealStorageName = maStorageName; // for relative paths, can be modified through BaseURL
949 
950     // If loaded from template, only BaseURL is used:
951     //String aBaseURL = INetURLObject::GetBaseURL();
952     if ( rBaseURL.Len() )
953     {
954         INetURLObject aObj( rBaseURL );
955         if ( aObj.GetProtocol() == INET_PROT_FILE )
956             aRealStorageName = aObj.PathToFileName();
957     }
958 
959     xManagerStream->SetBufferSize( 1024 );
960     xManagerStream->Seek( STREAM_SEEK_TO_BEGIN );
961 
962     sal_uInt32 nEndPos;
963     *xManagerStream >> nEndPos;
964 
965     sal_uInt16 nLibs;
966     *xManagerStream >> nLibs;
967     // Plausi!
968     if( nLibs & 0xF000 )
969     {
970         DBG_ASSERT( sal_False, "BasicManager-Stream defect!" );
971         return;
972     }
973     for ( sal_uInt16 nL = 0; nL < nLibs; nL++ )
974     {
975         BasicLibInfo* pInfo = BasicLibInfo::Create( *xManagerStream );
976 
977         // Correct absolute pathname if relative is existing.
978         // Always try relative first if there are two stands on disk
979         if ( pInfo->GetRelStorageName().Len() && ( ! pInfo->GetRelStorageName().EqualsAscii(szImbedded) ) )
980         {
981             INetURLObject aObj( aRealStorageName, INET_PROT_FILE );
982             aObj.removeSegment();
983             bool bWasAbsolute = sal_False;
984             aObj = aObj.smartRel2Abs( pInfo->GetRelStorageName(), bWasAbsolute );
985 
986             //*** TODO: Replace if still necessary
987             /* if ( SfxContentHelper::Exists( aObj.GetMainURL() ) )
988                 pInfo->SetStorageName( aObj.GetMainURL() );
989             else */
990             //*** TODO-End
991             if ( pLibs->aBasicLibPath.Len() )
992             {
993                 // Search lib in path
994                 String aSearchFile = pInfo->GetRelStorageName();
995                 SvtPathOptions aPathCFG;
996                 if( aPathCFG.SearchFile( aSearchFile, SvtPathOptions::PATH_BASIC ) )
997                 {
998                     pInfo->SetStorageName( aSearchFile );
999                     pInfo->SetFoundInPath( sal_True );
1000                 }
1001             }
1002         }
1003 
1004         pLibs->Insert( pInfo, LIST_APPEND );
1005         // Libs from external files should be loaded only when necessary.
1006         // But references are loaded at once, otherwise some big customers get into trouble
1007         if ( bLoadLibs && pInfo->DoLoad() &&
1008             ( ( !pInfo->IsExtern() ) || ( pInfo->IsReference() ) ) )
1009         {
1010             ImpLoadLibary( pInfo, &rStorage );
1011         }
1012     }
1013 
1014     xManagerStream->Seek( nEndPos );
1015     xManagerStream->SetBufferSize( 0 );
1016     xManagerStream.Clear();
1017 }
1018 
LoadOldBasicManager(SotStorage & rStorage)1019 void BasicManager::LoadOldBasicManager( SotStorage& rStorage )
1020 {
1021     DBG_CHKTHIS( BasicManager, 0 );
1022 
1023 //  StreamMode eStreamMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE;
1024 
1025     SotStorageStreamRef xManagerStream = rStorage.OpenSotStream
1026         ( String::CreateFromAscii(szOldManagerStream), eStreamReadMode );
1027 
1028     String aStorName( rStorage.GetName() );
1029     DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
1030 
1031     if ( !xManagerStream.Is() || xManagerStream->GetError() || ( xManagerStream->Seek( STREAM_SEEK_TO_END ) == 0 ) )
1032     {
1033         ImpMgrNotLoaded( aStorName );
1034         return;
1035     }
1036 
1037     xManagerStream->SetBufferSize( 1024 );
1038     xManagerStream->Seek( STREAM_SEEK_TO_BEGIN );
1039     sal_uInt32 nBasicStartOff, nBasicEndOff;
1040     *xManagerStream >> nBasicStartOff;
1041     *xManagerStream >> nBasicEndOff;
1042 
1043     DBG_ASSERT( !xManagerStream->GetError(), "Ungueltiger Manager-Stream!" );
1044 
1045     xManagerStream->Seek( nBasicStartOff );
1046     if( !ImplLoadBasic( *xManagerStream, pLibs->GetObject(0)->GetLibRef() ) )
1047     {
1048 //      String aErrorText( BasicResId( IDS_SBERR_MGROPEN ) );
1049 //      aErrorText.SearchAndReplace( "XX", aStorName );
1050         StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, aStorName, ERRCODE_BUTTON_OK );
1051         pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENMGRSTREAM, aStorName ) );
1052         // und es geht weiter...
1053     }
1054     xManagerStream->Seek( nBasicEndOff+1 ); // +1: 0x00 as separator
1055     String aLibs;
1056     xManagerStream->ReadByteString(aLibs);
1057     xManagerStream->SetBufferSize( 0 );
1058     xManagerStream.Clear(); // Close stream
1059 
1060     if ( aLibs.Len() )
1061     {
1062         String aCurStorageName( aStorName );
1063         INetURLObject aCurStorage( aCurStorageName, INET_PROT_FILE );
1064         sal_uInt16 nLibs = aLibs.GetTokenCount( LIB_SEP );
1065         for ( sal_uInt16 nLib = 0; nLib < nLibs; nLib++ )
1066         {
1067             String aLibInfo( aLibs.GetToken( nLib, LIB_SEP ) );
1068             // TODO: Remove == 2
1069             DBG_ASSERT( ( aLibInfo.GetTokenCount( LIBINFO_SEP ) == 2 ) || ( aLibInfo.GetTokenCount( LIBINFO_SEP ) == 3 ), "Ungueltige Lib-Info!" );
1070             String aLibName( aLibInfo.GetToken( 0, LIBINFO_SEP ) );
1071             String aLibAbsStorageName( aLibInfo.GetToken( 1, LIBINFO_SEP ) );
1072             String aLibRelStorageName( aLibInfo.GetToken( 2, LIBINFO_SEP ) );
1073             INetURLObject aLibAbsStorage( aLibAbsStorageName, INET_PROT_FILE );
1074 
1075             INetURLObject aLibRelStorage( aStorName );
1076             aLibRelStorage.removeSegment();
1077             bool bWasAbsolute = sal_False;
1078             aLibRelStorage = aLibRelStorage.smartRel2Abs( aLibRelStorageName, bWasAbsolute);
1079             DBG_ASSERT(!bWasAbsolute, "RelStorageName was absolute!" );
1080 
1081             SotStorageRef xStorageRef;
1082             if ( ( aLibAbsStorage == aCurStorage ) || ( aLibRelStorageName.EqualsAscii(szImbedded) ) )
1083                 xStorageRef = &rStorage;
1084             else
1085             {
1086                 xStorageRef = new SotStorage( sal_False, aLibAbsStorage.GetMainURL
1087                     ( INetURLObject::NO_DECODE ), eStorageReadMode, sal_True );
1088                 if ( xStorageRef->GetError() != ERRCODE_NONE )
1089                     xStorageRef = new SotStorage( sal_False, aLibRelStorage.
1090                     GetMainURL( INetURLObject::NO_DECODE ), eStorageReadMode, sal_True );
1091             }
1092             if ( xStorageRef.Is() )
1093                 AddLib( *xStorageRef, aLibName, sal_False );
1094             else
1095             {
1096 //              String aErrorText( BasicResId( IDS_SBERR_LIBLOAD ) );
1097 //              aErrorText.SearchAndReplace( "XX", aLibName );
1098                 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, aStorName, ERRCODE_BUTTON_OK );
1099                 pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_STORAGENOTFOUND, aStorName ) );
1100             }
1101         }
1102     }
1103 }
1104 
~BasicManager()1105 BasicManager::~BasicManager()
1106 {
1107     DBG_DTOR( BasicManager, 0 );
1108 
1109     // Notify listener if something needs to be saved
1110     Broadcast( SfxSimpleHint( SFX_HINT_DYING) );
1111 
1112     // Destroy Basic-Infos...
1113     // In reverse order
1114     BasicLibInfo* pInf = pLibs->Last();
1115     while ( pInf )
1116     {
1117         delete pInf;
1118         pInf = pLibs->Prev();
1119     }
1120     pLibs->Clear();
1121     delete pLibs;
1122     delete pErrorMgr;
1123     delete mpImpl;
1124 }
1125 
LegacyDeleteBasicManager(BasicManager * & _rpManager)1126 void BasicManager::LegacyDeleteBasicManager( BasicManager*& _rpManager )
1127 {
1128     delete _rpManager;
1129     _rpManager = NULL;
1130 }
1131 
Init()1132 void BasicManager::Init()
1133 {
1134     DBG_CHKTHIS( BasicManager, 0 );
1135 
1136     bBasMgrModified = sal_False;
1137     pErrorMgr = new BasicErrorManager;
1138     pLibs = new BasicLibs;
1139     mpImpl = new BasicManagerImpl();
1140 }
1141 
CreateLibInfo()1142 BasicLibInfo* BasicManager::CreateLibInfo()
1143 {
1144     DBG_CHKTHIS( BasicManager, 0 );
1145 
1146     BasicLibInfo* pInf = new BasicLibInfo;
1147     pLibs->Insert( pInf, LIST_APPEND );
1148     return pInf;
1149 }
1150 
ImpLoadLibary(BasicLibInfo * pLibInfo,SotStorage * pCurStorage,sal_Bool bInfosOnly) const1151 sal_Bool BasicManager::ImpLoadLibary( BasicLibInfo* pLibInfo, SotStorage* pCurStorage, sal_Bool bInfosOnly ) const
1152 {
1153     DBG_CHKTHIS( BasicManager, 0 );
1154 
1155     DBG_ASSERT( pLibInfo, "LibInfo!?" );
1156 
1157     String aStorageName( pLibInfo->GetStorageName() );
1158     if ( !aStorageName.Len() || ( aStorageName.EqualsAscii(szImbedded) ) )
1159         aStorageName = GetStorageName();
1160 
1161     SotStorageRef xStorage;
1162     // The current must not be opened again...
1163     if ( pCurStorage )
1164     {
1165         String aStorName( pCurStorage->GetName() );
1166         // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
1167 
1168         INetURLObject aCurStorageEntry(aStorName, INET_PROT_FILE);
1169         // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::NO_DECODE ).Len() != 0, "Bad storage name");
1170 
1171         INetURLObject aStorageEntry(aStorageName, INET_PROT_FILE);
1172         // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::NO_DECODE ).Len() != 0, "Bad storage name");
1173 
1174         if ( aCurStorageEntry == aStorageEntry )
1175             xStorage = pCurStorage;
1176     }
1177 
1178     if ( !xStorage.Is() )
1179         xStorage = new SotStorage( sal_False, aStorageName, eStorageReadMode );
1180 
1181     SotStorageRef xBasicStorage = xStorage->OpenSotStorage
1182                             ( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)), eStorageReadMode, sal_False );
1183 
1184     if ( !xBasicStorage.Is() || xBasicStorage->GetError() )
1185     {
1186         StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, xStorage->GetName(), ERRCODE_BUTTON_OK );
1187         pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTORAGE, pLibInfo->GetLibName() ) );
1188     }
1189     else
1190     {
1191         // In the Basic-Storage every lib is in a Stream...
1192         SotStorageStreamRef xBasicStream = xBasicStorage->OpenSotStream( pLibInfo->GetLibName(), eStreamReadMode );
1193         if ( !xBasicStream.Is() || xBasicStream->GetError() )
1194         {
1195             StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD , pLibInfo->GetLibName(), ERRCODE_BUTTON_OK );
1196             pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTREAM, pLibInfo->GetLibName() ) );
1197         }
1198         else
1199         {
1200             sal_Bool bLoaded = sal_False;
1201             if ( xBasicStream->Seek( STREAM_SEEK_TO_END ) != 0 )
1202             {
1203                 if ( !bInfosOnly )
1204                 {
1205                     if ( !pLibInfo->GetLib().Is() )
1206                         pLibInfo->SetLib( new StarBASIC( GetStdLib(), mbDocMgr ) );
1207                     xBasicStream->SetBufferSize( 1024 );
1208                     xBasicStream->Seek( STREAM_SEEK_TO_BEGIN );
1209                     bLoaded = ImplLoadBasic( *xBasicStream, pLibInfo->GetLibRef() );
1210                     xBasicStream->SetBufferSize( 0 );
1211                     StarBASICRef xStdLib = pLibInfo->GetLib();
1212                     xStdLib->SetName( pLibInfo->GetLibName() );
1213                     xStdLib->SetModified( sal_False );
1214                     xStdLib->SetFlag( SBX_DONTSTORE );
1215                 }
1216                 else
1217                 {
1218                     // Skip Basic...
1219                     xBasicStream->Seek( STREAM_SEEK_TO_BEGIN );
1220                     ImplEncryptStream( *xBasicStream );
1221                     SbxBase::Skip( *xBasicStream );
1222                     bLoaded = sal_True;
1223                 }
1224             }
1225             if ( !bLoaded )
1226             {
1227                 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, pLibInfo->GetLibName(), ERRCODE_BUTTON_OK );
1228                 pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_BASICLOADERROR, pLibInfo->GetLibName() ) );
1229             }
1230             else
1231             {
1232                 // Perhaps there are additional information in the stream...
1233                 xBasicStream->SetKey( szCryptingKey );
1234                 xBasicStream->RefreshBuffer();
1235                 sal_uInt32 nPasswordMarker = 0;
1236                 *xBasicStream >> nPasswordMarker;
1237                 if ( ( nPasswordMarker == PASSWORD_MARKER ) && !xBasicStream->IsEof() )
1238                 {
1239                     String aPassword;
1240                     xBasicStream->ReadByteString(aPassword);
1241                     pLibInfo->SetPassword( aPassword );
1242                 }
1243                 xBasicStream->SetKey( ByteString() );
1244                 CheckModules( pLibInfo->GetLib(), pLibInfo->IsReference() );
1245             }
1246             return bLoaded;
1247         }
1248     }
1249     return sal_False;
1250 }
1251 
ImplEncryptStream(SvStream & rStrm) const1252 sal_Bool BasicManager::ImplEncryptStream( SvStream& rStrm ) const
1253 {
1254     sal_uIntPtr nPos = rStrm.Tell();
1255     sal_uInt32 nCreator;
1256     rStrm >> nCreator;
1257     rStrm.Seek( nPos );
1258     sal_Bool bProtected = sal_False;
1259     if ( nCreator != SBXCR_SBX )
1260     {
1261         // Should only be the case for encrypted Streams
1262         bProtected = sal_True;
1263         rStrm.SetKey( szCryptingKey );
1264         rStrm.RefreshBuffer();
1265     }
1266     return bProtected;
1267 }
1268 
1269 // This code is necessary to load the BASIC of Beta 1
1270 // TODO: Which Beta 1?
ImplLoadBasic(SvStream & rStrm,StarBASICRef & rOldBasic) const1271 sal_Bool BasicManager::ImplLoadBasic( SvStream& rStrm, StarBASICRef& rOldBasic ) const
1272 {
1273     sal_Bool bProtected = ImplEncryptStream( rStrm );
1274     SbxBaseRef xNew = SbxBase::Load( rStrm );
1275     sal_Bool bLoaded = sal_False;
1276     if( xNew.Is() )
1277     {
1278         if( xNew->IsA( TYPE(StarBASIC) ) )
1279         {
1280             StarBASIC* pNew = (StarBASIC*)(SbxBase*) xNew;
1281             // Use the Parent of the old BASICs
1282             if( rOldBasic.Is() )
1283             {
1284                 pNew->SetParent( rOldBasic->GetParent() );
1285                 if( pNew->GetParent() )
1286                     pNew->GetParent()->Insert( pNew );
1287                 pNew->SetFlag( SBX_EXTSEARCH );
1288             }
1289             rOldBasic = pNew;
1290 
1291             // Fill new library container (5.2 -> 6.0)
1292             copyToLibraryContainer( pNew, mpImpl->maContainerInfo );
1293 
1294 /*
1295             if( rOldBasic->GetParent() )
1296             {
1297                 rOldBasic->GetParent()->Insert( rOldBasic );
1298                 rOldBasic->SetFlag( SBX_EXTSEARCH );
1299             }
1300 */
1301             pNew->SetModified( sal_False );
1302             bLoaded = sal_True;
1303         }
1304     }
1305     if ( bProtected )
1306         rStrm.SetKey( ByteString() );
1307     return bLoaded;
1308 }
1309 
CheckModules(StarBASIC * pLib,sal_Bool bReference) const1310 void BasicManager::CheckModules( StarBASIC* pLib, sal_Bool bReference ) const
1311 {
1312     if ( !pLib )
1313         return;
1314 
1315     sal_Bool bModified = pLib->IsModified();
1316 
1317     for ( sal_uInt16 nMod = 0; nMod < pLib->GetModules()->Count(); nMod++ )
1318     {
1319         SbModule* pModule = (SbModule*)pLib->GetModules()->Get( nMod );
1320         DBG_ASSERT( pModule, "Modul nicht erhalten!" );
1321         if ( !pModule->IsCompiled() && !StarBASIC::GetErrorCode() )
1322             pLib->Compile( pModule );
1323     }
1324 
1325     // #67477, AB 8.12.99 On demand compile in referenced libs should not
1326     // cause modified
1327     if( !bModified && bReference )
1328     {
1329         DBG_ERROR( "Per Reference eingebundene Basic-Library ist nicht compiliert!" );
1330         pLib->SetModified( sal_False );
1331     }
1332 }
1333 
AddLib(SotStorage & rStorage,const String & rLibName,sal_Bool bReference)1334 StarBASIC* BasicManager::AddLib( SotStorage& rStorage, const String& rLibName, sal_Bool bReference )
1335 {
1336     DBG_CHKTHIS( BasicManager, 0 );
1337 
1338     String aStorName( rStorage.GetName() );
1339     DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
1340 
1341     String aStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
1342     DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
1343 
1344     String aNewLibName( rLibName );
1345     while ( HasLib( aNewLibName ) )
1346         aNewLibName += '_';
1347 
1348     BasicLibInfo* pLibInfo = CreateLibInfo();
1349     // Use original name otherwise ImpLoadLibary fails...
1350     pLibInfo->SetLibName( rLibName );
1351     // Funktioniert so aber nicht, wenn Name doppelt
1352 //  sal_uInt16 nLibId = GetLibId( rLibName );
1353     sal_uInt16 nLibId = (sal_uInt16) pLibs->GetPos( pLibInfo );
1354 
1355     // Set StorageName before load because it is compared with pCurStorage
1356     pLibInfo->SetStorageName( aStorageName );
1357     sal_Bool bLoaded = ImpLoadLibary( pLibInfo, &rStorage );
1358 
1359     if ( bLoaded )
1360     {
1361         if ( aNewLibName != rLibName )
1362             SetLibName( nLibId, aNewLibName );
1363 
1364         if ( bReference )
1365         {
1366             pLibInfo->GetLib()->SetModified( sal_False );   // Don't save in this case
1367             pLibInfo->SetRelStorageName( String() );
1368 //          pLibInfo->CalcRelStorageName( GetStorageName() );
1369             pLibInfo->IsReference() = sal_True;
1370         }
1371         else
1372         {
1373             pLibInfo->GetLib()->SetModified( sal_True ); // Must be saved after Add!
1374             pLibInfo->SetStorageName( String::CreateFromAscii(szImbedded) ); // Save in BasicManager-Storage
1375         }
1376         bBasMgrModified = sal_True;
1377     }
1378     else
1379     {
1380         RemoveLib( nLibId, sal_False );
1381         pLibInfo = 0;
1382     }
1383 
1384     if( pLibInfo )
1385         return &*pLibInfo->GetLib() ;
1386     else
1387         return 0;
1388 }
1389 
IsReference(sal_uInt16 nLib)1390 sal_Bool BasicManager::IsReference( sal_uInt16 nLib )
1391 {
1392     DBG_CHKTHIS( BasicManager, 0 );
1393 
1394     BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
1395     DBG_ASSERT( pLibInfo, "Lib?!" );
1396     if ( pLibInfo )
1397         return pLibInfo->IsReference();
1398 
1399     return sal_False;
1400 }
1401 
RemoveLib(sal_uInt16 nLib)1402 sal_Bool BasicManager::RemoveLib( sal_uInt16 nLib )
1403 {
1404     // Only pyhsical deletion if no reference
1405     return RemoveLib( nLib, !IsReference( nLib ) );
1406 }
1407 
RemoveLib(sal_uInt16 nLib,sal_Bool bDelBasicFromStorage)1408 sal_Bool BasicManager::RemoveLib( sal_uInt16 nLib, sal_Bool bDelBasicFromStorage )
1409 {
1410     DBG_CHKTHIS( BasicManager, 0 );
1411     DBG_ASSERT( nLib, "Standard-Lib cannot be removed!" );
1412 
1413     BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
1414     DBG_ASSERT( pLibInfo, "Lib not found!" );
1415 
1416     if ( !pLibInfo || !nLib )
1417     {
1418 //      String aErrorText( BasicResId( IDS_SBERR_REMOVELIB ) );
1419         StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIB, String(), ERRCODE_BUTTON_OK );
1420         pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_STDLIB, pLibInfo->GetLibName() ) );
1421         return sal_False;
1422     }
1423 
1424     // If one of the streams cannot be opened, this is not an error,
1425     // because BASIC was never written before...
1426     if ( bDelBasicFromStorage && !pLibInfo->IsReference() &&
1427             ( !pLibInfo->IsExtern() || SotStorage::IsStorageFile( pLibInfo->GetStorageName() ) ) )
1428     {
1429         SotStorageRef xStorage;
1430         if ( !pLibInfo->IsExtern() )
1431             xStorage = new SotStorage( sal_False, GetStorageName() );
1432         else
1433             xStorage = new SotStorage( sal_False, pLibInfo->GetStorageName() );
1434 
1435         if ( xStorage->IsStorage( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)) ) )
1436         {
1437             SotStorageRef xBasicStorage = xStorage->OpenSotStorage
1438                             ( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)), STREAM_STD_READWRITE, sal_False );
1439 
1440             if ( !xBasicStorage.Is() || xBasicStorage->GetError() )
1441             {
1442 //              String aErrorText( BasicResId( IDS_SBERR_REMOVELIB ) );
1443                 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIB, String(), ERRCODE_BUTTON_OK );
1444                 pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTORAGE, pLibInfo->GetLibName() ) );
1445             }
1446             else if ( xBasicStorage->IsStream( pLibInfo->GetLibName() ) )
1447             {
1448                 xBasicStorage->Remove( pLibInfo->GetLibName() );
1449                 xBasicStorage->Commit();
1450 
1451                 // If no further stream available,
1452                 // delete the SubStorage.
1453                 SvStorageInfoList aInfoList( 0, 4 );
1454                 xBasicStorage->FillInfoList( &aInfoList );
1455                 if ( !aInfoList.Count() )
1456                 {
1457                     xBasicStorage.Clear();
1458                     xStorage->Remove( String(RTL_CONSTASCII_USTRINGPARAM(szBasicStorage)) );
1459                     xStorage->Commit();
1460                     // If no further Streams or SubStorages available,
1461                     // delete the Storage, too.
1462                     aInfoList.Clear();
1463                     xStorage->FillInfoList( &aInfoList );
1464                     if ( !aInfoList.Count() )
1465                     {
1466                         String aName_( xStorage->GetName() );
1467                         xStorage.Clear();
1468                         //*** TODO: Replace if still necessary
1469                         //SfxContentHelper::Kill( aName );
1470                         //*** TODO-End
1471                     }
1472                 }
1473             }
1474         }
1475     }
1476     bBasMgrModified = sal_True;
1477     if ( pLibInfo->GetLib().Is() )
1478         GetStdLib()->Remove( pLibInfo->GetLib() );
1479     delete pLibs->Remove( pLibInfo );
1480     return sal_True;    // Remove was successful, del unimportant
1481 }
1482 
GetLibCount() const1483 sal_uInt16 BasicManager::GetLibCount() const
1484 {
1485     DBG_CHKTHIS( BasicManager, 0 );
1486     return (sal_uInt16)pLibs->Count();
1487 }
1488 
GetLib(sal_uInt16 nLib) const1489 StarBASIC* BasicManager::GetLib( sal_uInt16 nLib ) const
1490 {
1491     DBG_CHKTHIS( BasicManager, 0 );
1492     BasicLibInfo* pInf = pLibs->GetObject( nLib );
1493     DBG_ASSERT( pInf, "Lib existiert nicht!" );
1494     if ( pInf )
1495         return pInf->GetLib();
1496     return 0;
1497 }
1498 
GetStdLib() const1499 StarBASIC* BasicManager::GetStdLib() const
1500 {
1501     DBG_CHKTHIS( BasicManager, 0 );
1502     StarBASIC* pLib = GetLib( 0 );
1503     return pLib;
1504 }
1505 
GetLib(const String & rName) const1506 StarBASIC* BasicManager::GetLib( const String& rName ) const
1507 {
1508     DBG_CHKTHIS( BasicManager, 0 );
1509 
1510     BasicLibInfo* pInf = pLibs->First();
1511     while ( pInf )
1512     {
1513         if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL )// Check if available...
1514             return pInf->GetLib();
1515 
1516         pInf = pLibs->Next();
1517     }
1518     return 0;
1519 }
1520 
GetLibId(const String & rName) const1521 sal_uInt16 BasicManager::GetLibId( const String& rName ) const
1522 {
1523     DBG_CHKTHIS( BasicManager, 0 );
1524 
1525     BasicLibInfo* pInf = pLibs->First();
1526     while ( pInf )
1527     {
1528         if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL )
1529             return (sal_uInt16)pLibs->GetCurPos();
1530 
1531         pInf = pLibs->Next();
1532     }
1533     return LIB_NOTFOUND;
1534 }
1535 
HasLib(const String & rName) const1536 sal_Bool BasicManager::HasLib( const String& rName ) const
1537 {
1538     DBG_CHKTHIS( BasicManager, 0 );
1539 
1540     BasicLibInfo* pInf = pLibs->First();
1541     while ( pInf )
1542     {
1543         if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL )
1544             return sal_True;
1545 
1546         pInf = pLibs->Next();
1547     }
1548     return sal_False;
1549 }
1550 
SetLibName(sal_uInt16 nLib,const String & rName)1551 sal_Bool BasicManager::SetLibName( sal_uInt16 nLib, const String& rName )
1552 {
1553     DBG_CHKTHIS( BasicManager, 0 );
1554 
1555     BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
1556     DBG_ASSERT( pLibInfo, "Lib?!" );
1557     if ( pLibInfo )
1558     {
1559         pLibInfo->SetLibName( rName );
1560         if ( pLibInfo->GetLib().Is() )
1561         {
1562             StarBASICRef xStdLib = pLibInfo->GetLib();
1563             xStdLib->SetName( rName );
1564             xStdLib->SetModified( sal_True );
1565         }
1566         bBasMgrModified = sal_True;
1567         return sal_True;
1568     }
1569     return sal_False;
1570 }
1571 
GetLibName(sal_uInt16 nLib)1572 String BasicManager::GetLibName( sal_uInt16 nLib )
1573 {
1574     DBG_CHKTHIS( BasicManager, 0 );
1575 
1576     BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
1577     DBG_ASSERT( pLibInfo, "Lib?!" );
1578     if ( pLibInfo )
1579         return pLibInfo->GetLibName();
1580     return String();
1581 }
1582 
LoadLib(sal_uInt16 nLib)1583 sal_Bool BasicManager::LoadLib( sal_uInt16 nLib )
1584 {
1585     DBG_CHKTHIS( BasicManager, 0 );
1586 
1587     sal_Bool bDone = sal_False;
1588     BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
1589     DBG_ASSERT( pLibInfo, "Lib?!" );
1590     if ( pLibInfo )
1591     {
1592         Reference< XLibraryContainer > xLibContainer = pLibInfo->GetLibraryContainer();
1593         if( xLibContainer.is() )
1594         {
1595             String aLibName = pLibInfo->GetLibName();
1596             xLibContainer->loadLibrary( aLibName );
1597             bDone = xLibContainer->isLibraryLoaded( aLibName );
1598         }
1599         else
1600         {
1601             bDone = ImpLoadLibary( pLibInfo, NULL, sal_False );
1602             StarBASIC* pLib = GetLib( nLib );
1603             if ( pLib )
1604             {
1605     //          pLib->SetParent( GetStdLib() );
1606                 GetStdLib()->Insert( pLib );
1607                 pLib->SetFlag( SBX_EXTSEARCH );
1608             }
1609         }
1610     }
1611     else
1612     {
1613 //      String aErrorText( BasicResId( IDS_SBERR_LIBLOAD ) );
1614 //      aErrorText.SearchAndReplace( "XX", "" );
1615         StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, String(), ERRCODE_BUTTON_OK );
1616         pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_LIBNOTFOUND, String::CreateFromInt32(nLib) ) );
1617     }
1618     return bDone;
1619 }
1620 
CreateLib(const String & rLibName)1621 StarBASIC* BasicManager::CreateLib( const String& rLibName )
1622 {
1623     DBG_CHKTHIS( BasicManager, 0 );
1624     if ( GetLib( rLibName ) )
1625         return 0;
1626 
1627     BasicLibInfo* pLibInfo = CreateLibInfo();
1628     StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr );
1629     GetStdLib()->Insert( pNew );
1630     pNew->SetFlag( SBX_EXTSEARCH | SBX_DONTSTORE );
1631     pLibInfo->SetLib( pNew );
1632     pLibInfo->SetLibName( rLibName );
1633     pLibInfo->GetLib()->SetName( rLibName );
1634     return pLibInfo->GetLib();
1635 }
1636 
1637 // For XML import/export:
CreateLib(const String & rLibName,const String & Password,const String & LinkTargetURL)1638 StarBASIC* BasicManager::CreateLib
1639     ( const String& rLibName, const String& Password, const String& LinkTargetURL )
1640 {
1641     // Ask if lib exists because standard lib is always there
1642     StarBASIC* pLib = GetLib( rLibName );
1643     if( !pLib )
1644     {
1645         if( LinkTargetURL.Len() != 0 )
1646         {
1647             SotStorageRef xStorage = new SotStorage( sal_False, LinkTargetURL, STREAM_READ | STREAM_SHARE_DENYWRITE );
1648             if( !xStorage->GetError() )
1649             {
1650                 pLib = AddLib( *xStorage, rLibName, sal_True );
1651 
1652                 //if( !pLibInfo )
1653                     //pLibInfo = FindLibInfo( pLib );
1654                 //pLibInfo->SetStorageName( LinkTargetURL );
1655                 //pLibInfo->GetLib()->SetModified( sal_False ); // Dann nicht speichern
1656                 //pLibInfo->SetRelStorageName( String() );
1657                 //pLibInfo->IsReference() = sal_True;
1658             }
1659             //else
1660                 //Message?
1661 
1662             DBG_ASSERT( pLib, "XML Import: Linked basic library could not be loaded");
1663         }
1664         else
1665         {
1666             pLib = CreateLib( rLibName );
1667             if( Password.Len() != 0 )
1668             {
1669                 BasicLibInfo* pLibInfo = FindLibInfo( pLib );
1670                 pLibInfo ->SetPassword( Password );
1671             }
1672         }
1673         //ExternalSourceURL ?
1674     }
1675     return pLib;
1676 }
1677 
CreateLibForLibContainer(const String & rLibName,const Reference<XLibraryContainer> & xScriptCont)1678 StarBASIC* BasicManager::CreateLibForLibContainer( const String& rLibName,
1679     const Reference< XLibraryContainer >& xScriptCont )
1680 {
1681     DBG_CHKTHIS( BasicManager, 0 );
1682     if ( GetLib( rLibName ) )
1683         return 0;
1684 
1685     BasicLibInfo* pLibInfo = CreateLibInfo();
1686     StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr );
1687     GetStdLib()->Insert( pNew );
1688     pNew->SetFlag( SBX_EXTSEARCH | SBX_DONTSTORE );
1689     pLibInfo->SetLib( pNew );
1690     pLibInfo->SetLibName( rLibName );
1691     pLibInfo->GetLib()->SetName( rLibName );
1692     pLibInfo->SetLibraryContainer( xScriptCont );
1693     return pNew;
1694 }
1695 
1696 
FindLibInfo(StarBASIC * pBasic) const1697 BasicLibInfo* BasicManager::FindLibInfo( StarBASIC* pBasic ) const
1698 {
1699     DBG_CHKTHIS( BasicManager, 0 );
1700 
1701     BasicLibInfo* pInf = ((BasicManager*)this)->pLibs->First();
1702     while ( pInf )
1703     {
1704         if ( pInf->GetLib() == pBasic )
1705             return pInf;
1706 
1707         pInf = ((BasicManager*)this)->pLibs->Next();
1708     }
1709     return 0;
1710 }
1711 
1712 
IsModified() const1713 sal_Bool BasicManager::IsModified() const
1714 {
1715     DBG_CHKTHIS( BasicManager, 0 );
1716 
1717     if ( bBasMgrModified )
1718         return sal_True;
1719     return IsBasicModified();
1720 }
1721 
IsBasicModified() const1722 sal_Bool BasicManager::IsBasicModified() const
1723 {
1724     DBG_CHKTHIS( BasicManager, 0 );
1725 
1726     BasicLibInfo* pInf = pLibs->First();
1727     while ( pInf )
1728     {
1729         if ( pInf->GetLib().Is() && pInf->GetLib()->IsModified() )
1730             return sal_True;
1731 
1732         pInf = pLibs->Next();
1733     }
1734     return sal_False;
1735 }
1736 
SetFlagToAllLibs(short nFlag,sal_Bool bSet) const1737 void BasicManager::SetFlagToAllLibs( short nFlag, sal_Bool bSet ) const
1738 {
1739     sal_uInt16 nLibs = GetLibCount();
1740     for ( sal_uInt16 nL = 0; nL < nLibs; nL++ )
1741     {
1742         BasicLibInfo* pInfo = pLibs->GetObject( nL );
1743         DBG_ASSERT( pInfo, "Info?!" );
1744         StarBASIC* pLib = pInfo->GetLib();
1745         if ( pLib )
1746         {
1747             if ( bSet )
1748                 pLib->SetFlag( nFlag );
1749             else
1750                 pLib->ResetFlag( nFlag );
1751         }
1752     }
1753 }
1754 
HasErrors()1755 sal_Bool BasicManager::HasErrors()
1756 {
1757     DBG_CHKTHIS( BasicManager, 0 );
1758     return pErrorMgr->HasErrors();
1759 }
1760 
ClearErrors()1761 void BasicManager::ClearErrors()
1762 {
1763     DBG_CHKTHIS( BasicManager, 0 );
1764     pErrorMgr->Reset();
1765 }
1766 
GetFirstError()1767 BasicError* BasicManager::GetFirstError()
1768 {
1769     DBG_CHKTHIS( BasicManager, 0 );
1770     return pErrorMgr->GetFirstError();
1771 }
1772 
GetNextError()1773 BasicError* BasicManager::GetNextError()
1774 {
1775     DBG_CHKTHIS( BasicManager, 0 );
1776     return pErrorMgr->GetNextError();
1777 }
GetGlobalUNOConstant(const sal_Char * _pAsciiName,::com::sun::star::uno::Any & aOut)1778 bool BasicManager::GetGlobalUNOConstant( const sal_Char* _pAsciiName, ::com::sun::star::uno::Any& aOut )
1779 {
1780     bool bRes = false;
1781     StarBASIC* pStandardLib = GetStdLib();
1782     OSL_PRECOND( pStandardLib, "BasicManager::GetGlobalUNOConstant: no lib to read from!" );
1783     if ( pStandardLib )
1784         bRes = pStandardLib->GetUNOConstant( _pAsciiName, aOut );
1785     return bRes;
1786 }
1787 
SetGlobalUNOConstant(const sal_Char * _pAsciiName,const Any & _rValue)1788 Any BasicManager::SetGlobalUNOConstant( const sal_Char* _pAsciiName, const Any& _rValue )
1789 {
1790     Any aOldValue;
1791 
1792     StarBASIC* pStandardLib = GetStdLib();
1793     OSL_PRECOND( pStandardLib, "BasicManager::SetGlobalUNOConstant: no lib to insert into!" );
1794     if ( !pStandardLib )
1795         return aOldValue;
1796 
1797     ::rtl::OUString sVarName( ::rtl::OUString::createFromAscii( _pAsciiName ) );
1798 
1799     // obtain the old value
1800     SbxVariable* pVariable = pStandardLib->Find( sVarName, SbxCLASS_OBJECT );
1801     if ( pVariable )
1802         aOldValue = sbxToUnoValue( pVariable );
1803 
1804     SbxObjectRef xUnoObj = GetSbUnoObject( sVarName, _rValue );
1805     xUnoObj->SetFlag( SBX_DONTSTORE );
1806     pStandardLib->Insert( xUnoObj );
1807 
1808     return aOldValue;
1809 }
1810 
LegacyPsswdBinaryLimitExceeded(::com::sun::star::uno::Sequence<rtl::OUString> & _out_rModuleNames)1811 bool BasicManager::LegacyPsswdBinaryLimitExceeded( ::com::sun::star::uno::Sequence< rtl::OUString >& _out_rModuleNames )
1812 {
1813     try
1814     {
1815         Reference< XNameAccess > xScripts( GetScriptLibraryContainer(), UNO_QUERY_THROW );
1816         Reference< XLibraryContainerPassword > xPassword( GetScriptLibraryContainer(), UNO_QUERY_THROW );
1817 
1818         Sequence< ::rtl::OUString > aNames( xScripts->getElementNames() );
1819         const ::rtl::OUString* pNames = aNames.getConstArray();
1820         const ::rtl::OUString* pNamesEnd = aNames.getConstArray() + aNames.getLength();
1821         for ( ; pNames != pNamesEnd; ++pNames )
1822         {
1823             if( /*pLib->mbSharedIndexFile ||*/ !xPassword->isLibraryPasswordProtected( *pNames ) )
1824                 continue;
1825 
1826             StarBASIC* pBasicLib = GetLib( *pNames );
1827             if ( !pBasicLib )
1828                 continue;
1829 
1830             Reference< XNameAccess > xScriptLibrary( xScripts->getByName( *pNames ), UNO_QUERY_THROW );
1831             Sequence< ::rtl::OUString > aElementNames( xScriptLibrary->getElementNames() );
1832             sal_Int32 nLen = aElementNames.getLength();
1833 
1834             Sequence< ::rtl::OUString > aBigModules( nLen );
1835             sal_Int32 nBigModules = 0;
1836 
1837             const ::rtl::OUString* pElementNames = aElementNames.getConstArray();
1838             const ::rtl::OUString* pElementNamesEnd = aElementNames.getConstArray() + aElementNames.getLength();
1839             for ( ; pElementNames != pElementNamesEnd; ++pElementNames )
1840             {
1841                 SbModule* pMod = pBasicLib->FindModule( *pElementNames );
1842                 if ( pMod && pMod->ExceedsLegacyModuleSize() )
1843                     aBigModules[ nBigModules++ ] = *pElementNames;
1844             }
1845 
1846             if ( nBigModules )
1847             {
1848                 aBigModules.realloc( nBigModules );
1849                 _out_rModuleNames = aBigModules;
1850                 return true;
1851             }
1852         }
1853     }
1854     catch( const Exception& )
1855     {
1856         DBG_UNHANDLED_EXCEPTION();
1857     }
1858     return false;
1859 }
1860 
1861 
1862 namespace
1863 {
lcl_queryMacro(BasicManager * i_manager,String const & i_fullyQualifiedName)1864     SbMethod* lcl_queryMacro( BasicManager* i_manager, String const& i_fullyQualifiedName )
1865     {
1866         sal_uInt16 nLast = 0;
1867         String sMacro = i_fullyQualifiedName;
1868         String sLibName = sMacro.GetToken( 0, '.', nLast );
1869         String sModule = sMacro.GetToken( 0, '.', nLast );
1870         sMacro.Erase( 0, nLast );
1871 
1872         IntlWrapper aIntlWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
1873         const CollatorWrapper* pCollator = aIntlWrapper.getCollator();
1874         sal_uInt16 nLibCount = i_manager->GetLibCount();
1875         for ( sal_uInt16 nLib = 0; nLib < nLibCount; ++nLib )
1876         {
1877             if ( COMPARE_EQUAL == pCollator->compareString( i_manager->GetLibName( nLib ), sLibName ) )
1878             {
1879                 StarBASIC* pLib = i_manager->GetLib( nLib );
1880                 if( !pLib )
1881                 {
1882                     i_manager->LoadLib( nLib );
1883                     pLib = i_manager->GetLib( nLib );
1884                 }
1885 
1886                 if( pLib )
1887                 {
1888                     sal_uInt16 nModCount = pLib->GetModules()->Count();
1889                     for( sal_uInt16 nMod = 0; nMod < nModCount; ++nMod )
1890                     {
1891                         SbModule* pMod = (SbModule*)pLib->GetModules()->Get( nMod );
1892                         if ( pMod && COMPARE_EQUAL == pCollator->compareString( pMod->GetName(), sModule ) )
1893                         {
1894                             SbMethod* pMethod = (SbMethod*)pMod->Find( sMacro, SbxCLASS_METHOD );
1895                             if( pMethod )
1896                                 return pMethod;
1897                         }
1898                     }
1899                 }
1900             }
1901         }
1902         return 0;
1903     }
1904 }
1905 
HasMacro(String const & i_fullyQualifiedName) const1906 bool BasicManager::HasMacro( String const& i_fullyQualifiedName ) const
1907 {
1908     return ( NULL != lcl_queryMacro( const_cast< BasicManager* >( this ), i_fullyQualifiedName ) );
1909 }
1910 
ExecuteMacro(String const & i_fullyQualifiedName,SbxArray * i_arguments,SbxValue * i_retValue)1911 ErrCode BasicManager::ExecuteMacro( String const& i_fullyQualifiedName, SbxArray* i_arguments, SbxValue* i_retValue )
1912 {
1913     SbMethod* pMethod = lcl_queryMacro( this, i_fullyQualifiedName );
1914     ErrCode nError = 0;
1915     if ( pMethod )
1916     {
1917         if ( i_arguments )
1918             pMethod->SetParameters( i_arguments );
1919         nError = pMethod->Call( i_retValue );
1920     }
1921     else
1922         nError = ERRCODE_BASIC_PROC_UNDEFINED;
1923     return nError;
1924 }
1925 
ExecuteMacro(String const & i_fullyQualifiedName,String const & i_commaSeparatedArgs,SbxValue * i_retValue)1926 ErrCode BasicManager::ExecuteMacro( String const& i_fullyQualifiedName, String const& i_commaSeparatedArgs, SbxValue* i_retValue )
1927 {
1928     SbMethod* pMethod = lcl_queryMacro( this, i_fullyQualifiedName );
1929     if ( !pMethod )
1930         return ERRCODE_BASIC_PROC_UNDEFINED;
1931 
1932     // arguments must be quoted
1933     String sQuotedArgs;
1934     String sArgs( i_commaSeparatedArgs );
1935     if ( sArgs.Len()<2 || sArgs.GetBuffer()[1] == '\"')
1936         // no args or already quoted args
1937         sQuotedArgs = sArgs;
1938     else
1939     {
1940         // quote parameters
1941         sArgs.Erase( 0, 1 );
1942         sArgs.Erase( sArgs.Len()-1, 1 );
1943 
1944         sQuotedArgs = '(';
1945 
1946         sal_uInt16 nCount = sArgs.GetTokenCount(',');
1947         for ( sal_uInt16 n=0; n<nCount; ++n )
1948         {
1949             sQuotedArgs += '\"';
1950             sQuotedArgs += sArgs.GetToken( n, ',' );
1951             sQuotedArgs += '\"';
1952             if ( n<nCount-1 )
1953                 sQuotedArgs += ',';
1954         }
1955 
1956         sQuotedArgs += ')';
1957     }
1958 
1959     // add quoted arguments and do the call
1960     String sCall( '[' );
1961     sCall += pMethod->GetName();
1962     sCall += sQuotedArgs;
1963     sCall += ']';
1964 
1965     SbxVariable* pRet = pMethod->GetParent()->Execute( sCall );
1966     if ( pRet && ( pRet != pMethod ) )
1967         *i_retValue = *pRet;
1968     return SbxBase::GetError();
1969 }
1970 
1971 //=====================================================================
1972 
1973 class ModuleInfo_Impl : public ModuleInfoHelper
1974 {
1975     ::rtl::OUString maName;
1976     ::rtl::OUString maLanguage;
1977     ::rtl::OUString maSource;
1978 
1979 public:
ModuleInfo_Impl(const::rtl::OUString & aName,const::rtl::OUString & aLanguage,const::rtl::OUString & aSource)1980     ModuleInfo_Impl( const ::rtl::OUString& aName, const ::rtl::OUString& aLanguage, const ::rtl::OUString& aSource )
1981         : maName( aName ), maLanguage( aLanguage), maSource( aSource ) {}
1982 
1983     // Methods XStarBasicModuleInfo
getName()1984     virtual ::rtl::OUString SAL_CALL getName()
1985         { return maName; }
getLanguage()1986     virtual ::rtl::OUString SAL_CALL getLanguage()
1987         { return maLanguage; }
getSource()1988     virtual ::rtl::OUString SAL_CALL getSource()
1989         { return maSource; }
1990 };
1991 
1992 
1993 //=====================================================================
1994 
1995 class DialogInfo_Impl : public DialogInfoHelper
1996 {
1997     ::rtl::OUString maName;
1998     Sequence< sal_Int8 > mData;
1999 
2000 public:
DialogInfo_Impl(const::rtl::OUString & aName,Sequence<sal_Int8> Data)2001     DialogInfo_Impl( const ::rtl::OUString& aName, Sequence< sal_Int8 > Data )
2002         : maName( aName ), mData( Data ) {}
2003 
2004     // Methods XStarBasicDialogInfo
getName()2005     virtual ::rtl::OUString SAL_CALL getName()
2006         { return maName; }
getData()2007     virtual Sequence< sal_Int8 > SAL_CALL getData()
2008         { return mData; }
2009 };
2010 
2011 
2012 //=====================================================================
2013 
2014 class LibraryInfo_Impl : public LibraryInfoHelper
2015 {
2016     ::rtl::OUString maName;
2017     Reference< XNameContainer > mxModuleContainer;
2018     Reference< XNameContainer > mxDialogContainer;
2019     ::rtl::OUString maPassword;
2020     ::rtl::OUString maExternaleSourceURL;
2021     ::rtl::OUString maLinkTargetURL;
2022 
2023 public:
LibraryInfo_Impl(const::rtl::OUString & aName,Reference<XNameContainer> xModuleContainer,Reference<XNameContainer> xDialogContainer,const::rtl::OUString & aPassword,const::rtl::OUString & aExternaleSourceURL,const::rtl::OUString & aLinkTargetURL)2024     LibraryInfo_Impl
2025     (
2026         const ::rtl::OUString& aName,
2027         Reference< XNameContainer > xModuleContainer,
2028         Reference< XNameContainer > xDialogContainer,
2029         const ::rtl::OUString& aPassword,
2030         const ::rtl::OUString& aExternaleSourceURL,
2031         const ::rtl::OUString& aLinkTargetURL
2032     )
2033         : maName( aName )
2034         , mxModuleContainer( xModuleContainer )
2035         , mxDialogContainer( xDialogContainer )
2036         , maPassword( aPassword )
2037         , maExternaleSourceURL( aExternaleSourceURL )
2038         , maLinkTargetURL( aLinkTargetURL )
2039     {}
2040 
2041     // Methods XStarBasicLibraryInfo
getName()2042     virtual ::rtl::OUString SAL_CALL getName()
2043         { return maName; }
getModuleContainer()2044     virtual Reference< XNameContainer > SAL_CALL getModuleContainer()
2045         { return mxModuleContainer; }
getDialogContainer()2046     virtual Reference< XNameContainer > SAL_CALL getDialogContainer()
2047         { return mxDialogContainer; }
getPassword()2048     virtual ::rtl::OUString SAL_CALL getPassword()
2049         { return maPassword; }
getExternalSourceURL()2050     virtual ::rtl::OUString SAL_CALL getExternalSourceURL()
2051         { return maExternaleSourceURL; }
getLinkTargetURL()2052     virtual ::rtl::OUString SAL_CALL getLinkTargetURL()
2053         { return maLinkTargetURL; }
2054 };
2055 
2056 //=====================================================================
2057 
2058 class ModuleContainer_Impl : public NameContainerHelper
2059 {
2060     StarBASIC* mpLib;
2061 
2062 public:
ModuleContainer_Impl(StarBASIC * pLib)2063     ModuleContainer_Impl( StarBASIC* pLib )
2064         :mpLib( pLib ) {}
2065 
2066     // Methods XElementAccess
2067     virtual Type SAL_CALL getElementType();
2068     virtual sal_Bool SAL_CALL hasElements();
2069 
2070     // Methods XNameAccess
2071     virtual Any SAL_CALL getByName( const ::rtl::OUString& aName );
2072     virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames();
2073     virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName );
2074 
2075     // Methods XNameReplace
2076     virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const Any& aElement );
2077 
2078     // Methods XNameContainer
2079     virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const Any& aElement );
2080     virtual void SAL_CALL removeByName( const ::rtl::OUString& Name );
2081 };
2082 
2083 // Methods XElementAccess
getElementType()2084 Type ModuleContainer_Impl::getElementType()
2085 {
2086     Type aModuleType = ::getCppuType( (const Reference< XStarBasicModuleInfo > *)0 );
2087     return aModuleType;
2088 }
2089 
hasElements()2090 sal_Bool ModuleContainer_Impl::hasElements()
2091 {
2092     SbxArray* pMods = mpLib ? mpLib->GetModules() : NULL;
2093     return pMods && pMods->Count() > 0;
2094 }
2095 
2096 // Methods XNameAccess
getByName(const::rtl::OUString & aName)2097 Any ModuleContainer_Impl::getByName( const ::rtl::OUString& aName )
2098 {
2099     SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : NULL;
2100     if( !pMod )
2101         throw NoSuchElementException();
2102     Reference< XStarBasicModuleInfo > xMod = (XStarBasicModuleInfo*)new ModuleInfo_Impl
2103         ( aName, ::rtl::OUString::createFromAscii( szScriptLanguage ), pMod->GetSource32() );
2104     Any aRetAny;
2105     aRetAny <<= xMod;
2106     return aRetAny;
2107 }
2108 
getElementNames()2109 Sequence< ::rtl::OUString > ModuleContainer_Impl::getElementNames()
2110 {
2111     SbxArray* pMods = mpLib ? mpLib->GetModules() : NULL;
2112     sal_uInt16 nMods = pMods ? pMods->Count() : 0;
2113     Sequence< ::rtl::OUString > aRetSeq( nMods );
2114     ::rtl::OUString* pRetSeq = aRetSeq.getArray();
2115     for( sal_uInt16 i = 0 ; i < nMods ; i++ )
2116     {
2117         SbxVariable* pMod = pMods->Get( i );
2118         pRetSeq[i] = ::rtl::OUString( pMod->GetName() );
2119     }
2120     return aRetSeq;
2121 }
2122 
hasByName(const::rtl::OUString & aName)2123 sal_Bool ModuleContainer_Impl::hasByName( const ::rtl::OUString& aName )
2124 {
2125     SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : NULL;
2126     sal_Bool bRet = (pMod != NULL);
2127     return bRet;
2128 }
2129 
2130 
2131 // Methods XNameReplace
replaceByName(const::rtl::OUString & aName,const Any & aElement)2132 void ModuleContainer_Impl::replaceByName( const ::rtl::OUString& aName, const Any& aElement )
2133 {
2134     removeByName( aName );
2135     insertByName( aName, aElement );
2136 }
2137 
2138 
2139 // Methods XNameContainer
insertByName(const::rtl::OUString & aName,const Any & aElement)2140 void ModuleContainer_Impl::insertByName( const ::rtl::OUString& aName, const Any& aElement )
2141 {
2142     Type aModuleType = ::getCppuType( (const Reference< XStarBasicModuleInfo > *)0 );
2143     Type aAnyType = aElement.getValueType();
2144     if( aModuleType != aAnyType )
2145         throw IllegalArgumentException();
2146     Reference< XStarBasicModuleInfo > xMod;
2147     aElement >>= xMod;
2148     mpLib->MakeModule32( aName, xMod->getSource() );
2149 }
2150 
removeByName(const::rtl::OUString & Name)2151 void ModuleContainer_Impl::removeByName( const ::rtl::OUString& Name )
2152 {
2153     SbModule* pMod = mpLib ? mpLib->FindModule( Name ) : NULL;
2154     if( !pMod )
2155         throw NoSuchElementException();
2156     mpLib->Remove( pMod );
2157 }
2158 
2159 
2160 //=====================================================================
2161 
implGetDialogData(SbxObject * pDialog)2162 Sequence< sal_Int8 > implGetDialogData( SbxObject* pDialog )
2163 {
2164     SvMemoryStream aMemStream;
2165     pDialog->Store( aMemStream );
2166     sal_Int32 nLen = aMemStream.Tell();
2167     Sequence< sal_Int8 > aData( nLen );
2168     sal_Int8* pDestData = aData.getArray();
2169     const sal_Int8* pSrcData = (const sal_Int8*)aMemStream.GetData();
2170     rtl_copyMemory( pDestData, pSrcData, nLen );
2171     return aData;
2172 }
2173 
implCreateDialog(Sequence<sal_Int8> aData)2174 SbxObject* implCreateDialog( Sequence< sal_Int8 > aData )
2175 {
2176     sal_Int8* pData = aData.getArray();
2177     SvMemoryStream aMemStream( pData, aData.getLength(), STREAM_READ );
2178     SbxObject* pDialog = (SbxObject*)SbxBase::Load( aMemStream );
2179     return pDialog;
2180 }
2181 
2182 // HACK! Because this value is defined in basctl/inc/vcsbxdef.hxx
2183 // which we can't include here, we have to use the value directly
2184 #define SBXID_DIALOG        101
2185 
2186 
2187 class DialogContainer_Impl : public NameContainerHelper
2188 {
2189     StarBASIC* mpLib;
2190 
2191 public:
DialogContainer_Impl(StarBASIC * pLib)2192     DialogContainer_Impl( StarBASIC* pLib )
2193         :mpLib( pLib ) {}
2194 
2195     // Methods XElementAccess
2196     virtual Type SAL_CALL getElementType();
2197     virtual sal_Bool SAL_CALL hasElements();
2198 
2199     // Methods XNameAccess
2200     virtual Any SAL_CALL getByName( const ::rtl::OUString& aName );
2201     virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames();
2202     virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName );
2203 
2204     // Methods XNameReplace
2205     virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const Any& aElement );
2206 
2207     // Methods XNameContainer
2208     virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const Any& aElement );
2209     virtual void SAL_CALL removeByName( const ::rtl::OUString& Name );
2210 };
2211 
2212 // Methods XElementAccess
getElementType()2213 Type DialogContainer_Impl::getElementType()
2214 {
2215     Type aModuleType = ::getCppuType( (const Reference< XStarBasicDialogInfo > *)0 );
2216     return aModuleType;
2217 }
2218 
hasElements()2219 sal_Bool DialogContainer_Impl::hasElements()
2220 {
2221     sal_Bool bRet = sal_False;
2222 
2223     mpLib->GetAll( SbxCLASS_OBJECT );
2224     sal_Int16 nCount = mpLib->GetObjects()->Count();
2225     for( sal_Int16 nObj = 0; nObj < nCount ; nObj++ )
2226     {
2227         SbxVariable* pVar = mpLib->GetObjects()->Get( nObj );
2228         if ( pVar->ISA( SbxObject ) && ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) )
2229         {
2230             bRet = sal_True;
2231             break;
2232         }
2233     }
2234     return bRet;
2235 }
2236 
2237 // Methods XNameAccess
getByName(const::rtl::OUString & aName)2238 Any DialogContainer_Impl::getByName( const ::rtl::OUString& aName )
2239 {
2240     SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxCLASS_DONTCARE );
2241     if( !( pVar && pVar->ISA( SbxObject ) &&
2242            ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) ) )
2243     {
2244         throw NoSuchElementException();
2245     }
2246 
2247     Reference< XStarBasicDialogInfo > xDialog =
2248         (XStarBasicDialogInfo*)new DialogInfo_Impl
2249             ( aName, implGetDialogData( (SbxObject*)pVar ) );
2250 
2251     Any aRetAny;
2252     aRetAny <<= xDialog;
2253     return aRetAny;
2254 }
2255 
getElementNames()2256 Sequence< ::rtl::OUString > DialogContainer_Impl::getElementNames()
2257 {
2258     mpLib->GetAll( SbxCLASS_OBJECT );
2259     sal_Int16 nCount = mpLib->GetObjects()->Count();
2260     Sequence< ::rtl::OUString > aRetSeq( nCount );
2261     ::rtl::OUString* pRetSeq = aRetSeq.getArray();
2262     sal_Int32 nDialogCounter = 0;
2263 
2264     for( sal_Int16 nObj = 0; nObj < nCount ; nObj++ )
2265     {
2266         SbxVariable* pVar = mpLib->GetObjects()->Get( nObj );
2267         if ( pVar->ISA( SbxObject ) && ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) )
2268         {
2269             pRetSeq[ nDialogCounter ] = ::rtl::OUString( pVar->GetName() );
2270             nDialogCounter++;
2271         }
2272     }
2273     aRetSeq.realloc( nDialogCounter );
2274     return aRetSeq;
2275 }
2276 
hasByName(const::rtl::OUString & aName)2277 sal_Bool DialogContainer_Impl::hasByName( const ::rtl::OUString& aName )
2278 {
2279     sal_Bool bRet = sal_False;
2280     SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxCLASS_DONTCARE );
2281     if( pVar && pVar->ISA( SbxObject ) &&
2282            ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) )
2283     {
2284         bRet = sal_True;
2285     }
2286     return bRet;
2287 }
2288 
2289 
2290 // Methods XNameReplace
replaceByName(const::rtl::OUString & aName,const Any & aElement)2291 void DialogContainer_Impl::replaceByName( const ::rtl::OUString& aName, const Any& aElement )
2292 {
2293     removeByName( aName );
2294     insertByName( aName, aElement );
2295 }
2296 
2297 
2298 // Methods XNameContainer
insertByName(const::rtl::OUString & aName,const Any & aElement)2299 void DialogContainer_Impl::insertByName( const ::rtl::OUString& aName, const Any& aElement )
2300 {
2301     (void)aName;
2302     Type aModuleType = ::getCppuType( (const Reference< XStarBasicDialogInfo > *)0 );
2303     Type aAnyType = aElement.getValueType();
2304     if( aModuleType != aAnyType )
2305         throw IllegalArgumentException();
2306     Reference< XStarBasicDialogInfo > xMod;
2307     aElement >>= xMod;
2308     SbxObjectRef xDialog = implCreateDialog( xMod->getData() );
2309     mpLib->Insert( xDialog );
2310 }
2311 
removeByName(const::rtl::OUString & Name)2312 void DialogContainer_Impl::removeByName( const ::rtl::OUString& Name )
2313 {
2314     (void)Name;
2315     SbxVariable* pVar = mpLib->GetObjects()->Find( Name, SbxCLASS_DONTCARE );
2316     if( !( pVar && pVar->ISA( SbxObject ) &&
2317            ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) ) )
2318     {
2319         throw NoSuchElementException();
2320     }
2321     mpLib->Remove( pVar );
2322 }
2323 
2324 
2325 //=====================================================================
2326 
2327 
2328 class LibraryContainer_Impl : public NameContainerHelper
2329 {
2330     BasicManager* mpMgr;
2331 
2332 public:
LibraryContainer_Impl(BasicManager * pMgr)2333     LibraryContainer_Impl( BasicManager* pMgr )
2334         :mpMgr( pMgr ) {}
2335 
2336     // Methods XElementAccess
2337     virtual Type SAL_CALL getElementType();
2338     virtual sal_Bool SAL_CALL hasElements();
2339 
2340     // Methods XNameAccess
2341     virtual Any SAL_CALL getByName( const ::rtl::OUString& aName );
2342     virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames();
2343     virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName );
2344 
2345     // Methods XNameReplace
2346     virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const Any& aElement );
2347 
2348     // Methods XNameContainer
2349     virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const Any& aElement );
2350     virtual void SAL_CALL removeByName( const ::rtl::OUString& Name );
2351 };
2352 
2353 
2354 // Methods XElementAccess
getElementType()2355 Type LibraryContainer_Impl::getElementType()
2356 {
2357     Type aType = ::getCppuType( (const Reference< XStarBasicLibraryInfo > *)0 );
2358     return aType;
2359 }
2360 
hasElements()2361 sal_Bool LibraryContainer_Impl::hasElements()
2362 {
2363     sal_Int32 nLibs = mpMgr->GetLibCount();
2364     sal_Bool bRet = (nLibs > 0);
2365     return bRet;
2366 }
2367 
2368 // Methods XNameAccess
getByName(const::rtl::OUString & aName)2369 Any LibraryContainer_Impl::getByName( const ::rtl::OUString& aName )
2370 {
2371     Any aRetAny;
2372     if( !mpMgr->HasLib( aName ) )
2373         throw NoSuchElementException();
2374     StarBASIC* pLib = mpMgr->GetLib( aName );
2375 
2376     Reference< XNameContainer > xModuleContainer =
2377         (XNameContainer*)new ModuleContainer_Impl( pLib );
2378 
2379     Reference< XNameContainer > xDialogContainer;
2380         (XNameContainer*)new DialogContainer_Impl( pLib );
2381 
2382     BasicLibInfo* pLibInfo = mpMgr->FindLibInfo( pLib );
2383 
2384     ::rtl::OUString aPassword = pLibInfo->GetPassword();
2385 
2386     // TODO Only provide external info!
2387     ::rtl::OUString aExternaleSourceURL;
2388     ::rtl::OUString aLinkTargetURL;
2389     if( pLibInfo->IsReference() )
2390         aLinkTargetURL = pLibInfo->GetStorageName();
2391     else if( pLibInfo->IsExtern() )
2392         aExternaleSourceURL = pLibInfo->GetStorageName();
2393 
2394     Reference< XStarBasicLibraryInfo > xLibInfo = new LibraryInfo_Impl
2395     (
2396         aName,
2397         xModuleContainer,
2398         xDialogContainer,
2399         aPassword,
2400         aExternaleSourceURL,
2401         aLinkTargetURL
2402     );
2403 
2404     aRetAny <<= xLibInfo;
2405     return aRetAny;
2406 }
2407 
getElementNames()2408 Sequence< ::rtl::OUString > LibraryContainer_Impl::getElementNames()
2409 {
2410     sal_uInt16 nLibs = mpMgr->GetLibCount();
2411     Sequence< ::rtl::OUString > aRetSeq( nLibs );
2412     ::rtl::OUString* pRetSeq = aRetSeq.getArray();
2413     for( sal_uInt16 i = 0 ; i < nLibs ; i++ )
2414     {
2415         pRetSeq[i] = ::rtl::OUString( mpMgr->GetLibName( i ) );
2416     }
2417     return aRetSeq;
2418 }
2419 
hasByName(const::rtl::OUString & aName)2420 sal_Bool LibraryContainer_Impl::hasByName( const ::rtl::OUString& aName )
2421 {
2422     sal_Bool bRet = mpMgr->HasLib( aName );
2423     return bRet;
2424 }
2425 
2426 // Methods XNameReplace
replaceByName(const::rtl::OUString & aName,const Any & aElement)2427 void LibraryContainer_Impl::replaceByName( const ::rtl::OUString& aName, const Any& aElement )
2428 {
2429     removeByName( aName );
2430     insertByName( aName, aElement );
2431 }
2432 
2433 // Methods XNameContainer
insertByName(const::rtl::OUString & aName,const Any & aElement)2434 void LibraryContainer_Impl::insertByName( const ::rtl::OUString& aName, const Any& aElement )
2435 {
2436     (void)aName;
2437     (void)aElement;
2438     // TODO: Insert a complete Library?!
2439 }
2440 
removeByName(const::rtl::OUString & Name)2441 void LibraryContainer_Impl::removeByName( const ::rtl::OUString& Name )
2442 {
2443     StarBASIC* pLib = mpMgr->GetLib( Name );
2444     if( !pLib )
2445         throw NoSuchElementException();
2446     sal_uInt16 nLibId = mpMgr->GetLibId( Name );
2447     mpMgr->RemoveLib( nLibId );
2448 }
2449 
2450 //=====================================================================
2451 
2452 typedef WeakImplHelper1< XStarBasicAccess > StarBasicAccessHelper;
2453 
2454 
2455 class StarBasicAccess_Impl : public StarBasicAccessHelper
2456 {
2457     BasicManager* mpMgr;
2458     Reference< XNameContainer > mxLibContainer;
2459 
2460 public:
StarBasicAccess_Impl(BasicManager * pMgr)2461     StarBasicAccess_Impl( BasicManager* pMgr )
2462         :mpMgr( pMgr ) {}
2463 
2464 public:
2465 
2466     // Methods
2467     virtual Reference< XNameContainer > SAL_CALL getLibraryContainer();
2468     virtual void SAL_CALL createLibrary( const ::rtl::OUString& LibName, const ::rtl::OUString& Password,
2469         const ::rtl::OUString& ExternalSourceURL, const ::rtl::OUString& LinkTargetURL );
2470     virtual void SAL_CALL addModule( const ::rtl::OUString& LibraryName, const ::rtl::OUString& ModuleName,
2471         const ::rtl::OUString& Language, const ::rtl::OUString& Source );
2472     virtual void SAL_CALL addDialog( const ::rtl::OUString& LibraryName, const ::rtl::OUString& DialogName,
2473         const Sequence< sal_Int8 >& Data );
2474 
2475 };
2476 
getLibraryContainer()2477 Reference< XNameContainer > SAL_CALL StarBasicAccess_Impl::getLibraryContainer()
2478 {
2479     if( !mxLibContainer.is() )
2480         mxLibContainer = (XNameContainer*)new LibraryContainer_Impl( mpMgr );
2481     return mxLibContainer;
2482 }
2483 
createLibrary(const::rtl::OUString & LibName,const::rtl::OUString & Password,const::rtl::OUString & ExternalSourceURL,const::rtl::OUString & LinkTargetURL)2484 void SAL_CALL StarBasicAccess_Impl::createLibrary
2485 (
2486     const ::rtl::OUString& LibName,
2487     const ::rtl::OUString& Password,
2488     const ::rtl::OUString& ExternalSourceURL,
2489     const ::rtl::OUString& LinkTargetURL
2490 )
2491 {
2492     (void)ExternalSourceURL;
2493 #ifdef DBG_UTIL
2494     StarBASIC* pLib =
2495 #endif
2496     mpMgr->CreateLib( LibName, Password, LinkTargetURL );
2497     DBG_ASSERT( pLib, "XML Import: Basic library could not be created");
2498 }
2499 
addModule(const::rtl::OUString & LibraryName,const::rtl::OUString & ModuleName,const::rtl::OUString & Language,const::rtl::OUString & Source)2500 void SAL_CALL StarBasicAccess_Impl::addModule
2501 (
2502     const ::rtl::OUString& LibraryName,
2503     const ::rtl::OUString& ModuleName,
2504     const ::rtl::OUString& Language,
2505     const ::rtl::OUString& Source
2506 )
2507 {
2508     (void)Language;
2509     StarBASIC* pLib = mpMgr->GetLib( LibraryName );
2510     DBG_ASSERT( pLib, "XML Import: Lib for module unknown");
2511     if( pLib )
2512         pLib->MakeModule32( ModuleName, Source );
2513 }
2514 
addDialog(const::rtl::OUString & LibraryName,const::rtl::OUString & DialogName,const Sequence<sal_Int8> & Data)2515 void SAL_CALL StarBasicAccess_Impl::addDialog
2516 (
2517     const ::rtl::OUString& LibraryName,
2518     const ::rtl::OUString& DialogName,
2519     const Sequence< sal_Int8 >& Data
2520 )
2521 {
2522     (void)LibraryName;
2523     (void)DialogName;
2524     (void)Data;
2525 }
2526 
2527 // Basic XML Import/Export
getStarBasicAccess(BasicManager * pMgr)2528 Reference< XStarBasicAccess > getStarBasicAccess( BasicManager* pMgr )
2529 {
2530     Reference< XStarBasicAccess > xRet =
2531         new StarBasicAccess_Impl( (BasicManager*)pMgr );
2532     return xRet;
2533 }
2534