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