xref: /aoo4110/main/basic/source/classes/sb.cxx (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_basic.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include <stdio.h>
28*b1cdbd2cSJim Jagielski 
29*b1cdbd2cSJim Jagielski #include "sb.hxx"
30*b1cdbd2cSJim Jagielski #include <tools/rcid.h>
31*b1cdbd2cSJim Jagielski #include <tools/config.hxx>
32*b1cdbd2cSJim Jagielski #include <tools/stream.hxx>
33*b1cdbd2cSJim Jagielski #ifndef __RSC //autogen
34*b1cdbd2cSJim Jagielski #include <tools/errinf.hxx>
35*b1cdbd2cSJim Jagielski #endif
36*b1cdbd2cSJim Jagielski #include <basic/sbx.hxx>
37*b1cdbd2cSJim Jagielski #include <tools/list.hxx>
38*b1cdbd2cSJim Jagielski #include <tools/shl.hxx>
39*b1cdbd2cSJim Jagielski #include <tools/rc.hxx>
40*b1cdbd2cSJim Jagielski #include <vcl/svapp.hxx>
41*b1cdbd2cSJim Jagielski #include <comphelper/processfactory.hxx>
42*b1cdbd2cSJim Jagielski #include "sbunoobj.hxx"
43*b1cdbd2cSJim Jagielski #include "sbjsmeth.hxx"
44*b1cdbd2cSJim Jagielski #include "sbjsmod.hxx"
45*b1cdbd2cSJim Jagielski #include "sbintern.hxx"
46*b1cdbd2cSJim Jagielski #include "disas.hxx"
47*b1cdbd2cSJim Jagielski #include "runtime.hxx"
48*b1cdbd2cSJim Jagielski #include <basic/sbuno.hxx>
49*b1cdbd2cSJim Jagielski #include <basic/sbobjmod.hxx>
50*b1cdbd2cSJim Jagielski #include "stdobj.hxx"
51*b1cdbd2cSJim Jagielski #include "filefmt.hxx"
52*b1cdbd2cSJim Jagielski #include "sb.hrc"
53*b1cdbd2cSJim Jagielski #include <basrid.hxx>
54*b1cdbd2cSJim Jagielski #include <vos/mutex.hxx>
55*b1cdbd2cSJim Jagielski #include <cppuhelper/implbase1.hxx>
56*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XMultiServiceFactory.hpp>
57*b1cdbd2cSJim Jagielski #include <com/sun/star/util/XCloseBroadcaster.hpp>
58*b1cdbd2cSJim Jagielski #include <com/sun/star/util/XCloseListener.hpp>
59*b1cdbd2cSJim Jagielski #include "errobject.hxx"
60*b1cdbd2cSJim Jagielski #include <map>
61*b1cdbd2cSJim Jagielski #include <hash_map>
62*b1cdbd2cSJim Jagielski 
63*b1cdbd2cSJim Jagielski #include <com/sun/star/script/ModuleType.hpp>
64*b1cdbd2cSJim Jagielski #include <com/sun/star/script/ModuleInfo.hpp>
65*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::script;
66*b1cdbd2cSJim Jagielski 
67*b1cdbd2cSJim Jagielski // #pragma SW_SEGMENT_CLASS( SBASIC, SBASIC_CODE )
68*b1cdbd2cSJim Jagielski 
69*b1cdbd2cSJim Jagielski SV_IMPL_VARARR(SbTextPortions,SbTextPortion)
70*b1cdbd2cSJim Jagielski 
71*b1cdbd2cSJim Jagielski TYPEINIT1(StarBASIC,SbxObject)
72*b1cdbd2cSJim Jagielski 
73*b1cdbd2cSJim Jagielski #define RTLNAME "@SBRTL"
74*b1cdbd2cSJim Jagielski //  i#i68894#
75*b1cdbd2cSJim Jagielski using namespace ::com::sun::star;
76*b1cdbd2cSJim Jagielski using com::sun::star::uno::Reference;
77*b1cdbd2cSJim Jagielski using com::sun::star::uno::Any;
78*b1cdbd2cSJim Jagielski using com::sun::star::uno::UNO_QUERY;
79*b1cdbd2cSJim Jagielski using com::sun::star::lang::XMultiServiceFactory;
80*b1cdbd2cSJim Jagielski 
81*b1cdbd2cSJim Jagielski const static String aThisComponent( RTL_CONSTASCII_USTRINGPARAM("ThisComponent") );
82*b1cdbd2cSJim Jagielski const static String aVBAHook( RTL_CONSTASCII_USTRINGPARAM( "VBAGlobals" ) );
83*b1cdbd2cSJim Jagielski 
84*b1cdbd2cSJim Jagielski // ============================================================================
85*b1cdbd2cSJim Jagielski 
86*b1cdbd2cSJim Jagielski class DocBasicItem : public ::cppu::WeakImplHelper1< util::XCloseListener >
87*b1cdbd2cSJim Jagielski {
88*b1cdbd2cSJim Jagielski public:
89*b1cdbd2cSJim Jagielski     explicit DocBasicItem( StarBASIC& rDocBasic );
90*b1cdbd2cSJim Jagielski     virtual ~DocBasicItem();
91*b1cdbd2cSJim Jagielski 
getClassModules() const92*b1cdbd2cSJim Jagielski     inline const SbxObjectRef& getClassModules() const { return mxClassModules; }
isDocClosed() const93*b1cdbd2cSJim Jagielski     inline bool isDocClosed() const { return mbDocClosed; }
94*b1cdbd2cSJim Jagielski 
95*b1cdbd2cSJim Jagielski 	void clearDependingVarsOnDelete( StarBASIC& rDeletedBasic );
96*b1cdbd2cSJim Jagielski 
97*b1cdbd2cSJim Jagielski     void startListening();
98*b1cdbd2cSJim Jagielski     void stopListening();
99*b1cdbd2cSJim Jagielski 
100*b1cdbd2cSJim Jagielski     virtual void SAL_CALL queryClosing( const lang::EventObject& rSource, sal_Bool bGetsOwnership ) throw (util::CloseVetoException, uno::RuntimeException);
101*b1cdbd2cSJim Jagielski     virtual void SAL_CALL notifyClosing( const lang::EventObject& rSource ) throw (uno::RuntimeException);
102*b1cdbd2cSJim Jagielski     virtual void SAL_CALL disposing( const lang::EventObject& rSource ) throw (uno::RuntimeException);
103*b1cdbd2cSJim Jagielski 
104*b1cdbd2cSJim Jagielski private:
105*b1cdbd2cSJim Jagielski     StarBASIC&      mrDocBasic;
106*b1cdbd2cSJim Jagielski     SbxObjectRef    mxClassModules;
107*b1cdbd2cSJim Jagielski     bool            mbDocClosed;
108*b1cdbd2cSJim Jagielski     bool            mbDisposed;
109*b1cdbd2cSJim Jagielski };
110*b1cdbd2cSJim Jagielski 
111*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
112*b1cdbd2cSJim Jagielski 
DocBasicItem(StarBASIC & rDocBasic)113*b1cdbd2cSJim Jagielski DocBasicItem::DocBasicItem( StarBASIC& rDocBasic ) :
114*b1cdbd2cSJim Jagielski     mrDocBasic( rDocBasic ),
115*b1cdbd2cSJim Jagielski     mxClassModules( new SbxObject( String() ) ),
116*b1cdbd2cSJim Jagielski     mbDocClosed( false ),
117*b1cdbd2cSJim Jagielski     mbDisposed( false )
118*b1cdbd2cSJim Jagielski {
119*b1cdbd2cSJim Jagielski }
120*b1cdbd2cSJim Jagielski 
~DocBasicItem()121*b1cdbd2cSJim Jagielski DocBasicItem::~DocBasicItem()
122*b1cdbd2cSJim Jagielski {
123*b1cdbd2cSJim Jagielski     stopListening();
124*b1cdbd2cSJim Jagielski }
125*b1cdbd2cSJim Jagielski 
clearDependingVarsOnDelete(StarBASIC & rDeletedBasic)126*b1cdbd2cSJim Jagielski void DocBasicItem::clearDependingVarsOnDelete( StarBASIC& rDeletedBasic )
127*b1cdbd2cSJim Jagielski {
128*b1cdbd2cSJim Jagielski     mrDocBasic.implClearDependingVarsOnDelete( &rDeletedBasic );
129*b1cdbd2cSJim Jagielski }
130*b1cdbd2cSJim Jagielski 
startListening()131*b1cdbd2cSJim Jagielski void DocBasicItem::startListening()
132*b1cdbd2cSJim Jagielski {
133*b1cdbd2cSJim Jagielski     Any aThisComp;
134*b1cdbd2cSJim Jagielski     mrDocBasic.GetUNOConstant( "ThisComponent", aThisComp );
135*b1cdbd2cSJim Jagielski     Reference< util::XCloseBroadcaster > xCloseBC( aThisComp, UNO_QUERY );
136*b1cdbd2cSJim Jagielski     mbDisposed = !xCloseBC.is();
137*b1cdbd2cSJim Jagielski     if( xCloseBC.is() )
138*b1cdbd2cSJim Jagielski         try { xCloseBC->addCloseListener( this ); } catch( uno::Exception& ) {}
139*b1cdbd2cSJim Jagielski }
140*b1cdbd2cSJim Jagielski 
stopListening()141*b1cdbd2cSJim Jagielski void DocBasicItem::stopListening()
142*b1cdbd2cSJim Jagielski {
143*b1cdbd2cSJim Jagielski     if( mbDisposed ) return;
144*b1cdbd2cSJim Jagielski     mbDisposed = true;
145*b1cdbd2cSJim Jagielski     Any aThisComp;
146*b1cdbd2cSJim Jagielski     mrDocBasic.GetUNOConstant( "ThisComponent", aThisComp );
147*b1cdbd2cSJim Jagielski     Reference< util::XCloseBroadcaster > xCloseBC( aThisComp, UNO_QUERY );
148*b1cdbd2cSJim Jagielski     if( xCloseBC.is() )
149*b1cdbd2cSJim Jagielski         try { xCloseBC->removeCloseListener( this ); } catch( uno::Exception& ) {}
150*b1cdbd2cSJim Jagielski }
151*b1cdbd2cSJim Jagielski 
queryClosing(const lang::EventObject &,sal_Bool)152*b1cdbd2cSJim Jagielski void SAL_CALL DocBasicItem::queryClosing( const lang::EventObject& /*rSource*/, sal_Bool /*bGetsOwnership*/ ) throw (util::CloseVetoException, uno::RuntimeException)
153*b1cdbd2cSJim Jagielski {
154*b1cdbd2cSJim Jagielski }
155*b1cdbd2cSJim Jagielski 
notifyClosing(const lang::EventObject &)156*b1cdbd2cSJim Jagielski void SAL_CALL DocBasicItem::notifyClosing( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException)
157*b1cdbd2cSJim Jagielski {
158*b1cdbd2cSJim Jagielski     stopListening();
159*b1cdbd2cSJim Jagielski     mbDocClosed = true;
160*b1cdbd2cSJim Jagielski }
161*b1cdbd2cSJim Jagielski 
disposing(const lang::EventObject &)162*b1cdbd2cSJim Jagielski void SAL_CALL DocBasicItem::disposing( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException)
163*b1cdbd2cSJim Jagielski {
164*b1cdbd2cSJim Jagielski     stopListening();
165*b1cdbd2cSJim Jagielski }
166*b1cdbd2cSJim Jagielski 
167*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------------
168*b1cdbd2cSJim Jagielski 
169*b1cdbd2cSJim Jagielski namespace {
170*b1cdbd2cSJim Jagielski 
171*b1cdbd2cSJim Jagielski typedef ::rtl::Reference< DocBasicItem > DocBasicItemRef;
172*b1cdbd2cSJim Jagielski typedef std::map< const StarBASIC*, DocBasicItemRef > DocBasicItemMap;
173*b1cdbd2cSJim Jagielski static DocBasicItemMap GaDocBasicItems;
174*b1cdbd2cSJim Jagielski 
lclFindDocBasicItem(const StarBASIC * pDocBasic)175*b1cdbd2cSJim Jagielski const DocBasicItem* lclFindDocBasicItem( const StarBASIC* pDocBasic )
176*b1cdbd2cSJim Jagielski {
177*b1cdbd2cSJim Jagielski     DocBasicItemMap::iterator it = GaDocBasicItems.find( pDocBasic );
178*b1cdbd2cSJim Jagielski     return (it != GaDocBasicItems.end()) ? it->second.get() : 0;
179*b1cdbd2cSJim Jagielski }
180*b1cdbd2cSJim Jagielski 
lclInsertDocBasicItem(StarBASIC & rDocBasic)181*b1cdbd2cSJim Jagielski void lclInsertDocBasicItem( StarBASIC& rDocBasic )
182*b1cdbd2cSJim Jagielski {
183*b1cdbd2cSJim Jagielski     DocBasicItemRef& rxDocBasicItem = GaDocBasicItems[ &rDocBasic ];
184*b1cdbd2cSJim Jagielski     rxDocBasicItem.set( new DocBasicItem( rDocBasic ) );
185*b1cdbd2cSJim Jagielski     rxDocBasicItem->startListening();
186*b1cdbd2cSJim Jagielski }
187*b1cdbd2cSJim Jagielski 
lclRemoveDocBasicItem(StarBASIC & rDocBasic)188*b1cdbd2cSJim Jagielski void lclRemoveDocBasicItem( StarBASIC& rDocBasic )
189*b1cdbd2cSJim Jagielski {
190*b1cdbd2cSJim Jagielski     DocBasicItemMap::iterator it = GaDocBasicItems.find( &rDocBasic );
191*b1cdbd2cSJim Jagielski     if( it != GaDocBasicItems.end() )
192*b1cdbd2cSJim Jagielski     {
193*b1cdbd2cSJim Jagielski         it->second->stopListening();
194*b1cdbd2cSJim Jagielski         GaDocBasicItems.erase( it );
195*b1cdbd2cSJim Jagielski     }
196*b1cdbd2cSJim Jagielski     DocBasicItemMap::iterator it_end = GaDocBasicItems.end();
197*b1cdbd2cSJim Jagielski     for( it = GaDocBasicItems.begin(); it != it_end; ++it )
198*b1cdbd2cSJim Jagielski         it->second->clearDependingVarsOnDelete( rDocBasic );
199*b1cdbd2cSJim Jagielski }
200*b1cdbd2cSJim Jagielski 
lclGetDocBasicForModule(SbModule * pModule)201*b1cdbd2cSJim Jagielski StarBASIC* lclGetDocBasicForModule( SbModule* pModule )
202*b1cdbd2cSJim Jagielski {
203*b1cdbd2cSJim Jagielski     StarBASIC* pRetBasic = NULL;
204*b1cdbd2cSJim Jagielski     SbxObject* pCurParent = pModule;
205*b1cdbd2cSJim Jagielski     while( pCurParent->GetParent() != NULL )
206*b1cdbd2cSJim Jagielski     {
207*b1cdbd2cSJim Jagielski         pCurParent = pCurParent->GetParent();
208*b1cdbd2cSJim Jagielski         StarBASIC* pDocBasic = PTR_CAST( StarBASIC, pCurParent );
209*b1cdbd2cSJim Jagielski         if( pDocBasic != NULL && pDocBasic->IsDocBasic() )
210*b1cdbd2cSJim Jagielski         {
211*b1cdbd2cSJim Jagielski             pRetBasic = pDocBasic;
212*b1cdbd2cSJim Jagielski             break;
213*b1cdbd2cSJim Jagielski         }
214*b1cdbd2cSJim Jagielski     }
215*b1cdbd2cSJim Jagielski     return pRetBasic;
216*b1cdbd2cSJim Jagielski }
217*b1cdbd2cSJim Jagielski 
218*b1cdbd2cSJim Jagielski } // namespace
219*b1cdbd2cSJim Jagielski 
220*b1cdbd2cSJim Jagielski // ============================================================================
221*b1cdbd2cSJim Jagielski 
getVBAGlobals()222*b1cdbd2cSJim Jagielski SbxObject* StarBASIC::getVBAGlobals( )
223*b1cdbd2cSJim Jagielski {
224*b1cdbd2cSJim Jagielski 	if ( !pVBAGlobals )
225*b1cdbd2cSJim Jagielski 	{
226*b1cdbd2cSJim Jagielski 		Any aThisDoc;
227*b1cdbd2cSJim Jagielski 		if ( GetUNOConstant("ThisComponent", aThisDoc) )
228*b1cdbd2cSJim Jagielski 		{
229*b1cdbd2cSJim Jagielski 			Reference< XMultiServiceFactory > xDocFac( aThisDoc, UNO_QUERY );
230*b1cdbd2cSJim Jagielski                         if ( xDocFac.is() )
231*b1cdbd2cSJim Jagielski 			{
232*b1cdbd2cSJim Jagielski 				try
233*b1cdbd2cSJim Jagielski 				{
234*b1cdbd2cSJim Jagielski 					xDocFac->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals" ) ) );
235*b1cdbd2cSJim Jagielski 				}
236*b1cdbd2cSJim Jagielski 				catch( Exception& )
237*b1cdbd2cSJim Jagielski 				{
238*b1cdbd2cSJim Jagielski 					// Ignore
239*b1cdbd2cSJim Jagielski 				}
240*b1cdbd2cSJim Jagielski 			}
241*b1cdbd2cSJim Jagielski 		}
242*b1cdbd2cSJim Jagielski 		pVBAGlobals = (SbUnoObject*)Find( aVBAHook , SbxCLASS_DONTCARE );
243*b1cdbd2cSJim Jagielski 	}
244*b1cdbd2cSJim Jagielski 	return pVBAGlobals;
245*b1cdbd2cSJim Jagielski }
246*b1cdbd2cSJim Jagielski 
247*b1cdbd2cSJim Jagielski //  i#i68894#
VBAFind(const String & rName,SbxClassType t)248*b1cdbd2cSJim Jagielski SbxVariable* StarBASIC::VBAFind( const String& rName, SbxClassType t )
249*b1cdbd2cSJim Jagielski {
250*b1cdbd2cSJim Jagielski 	if( rName == aThisComponent )
251*b1cdbd2cSJim Jagielski 		return NULL;
252*b1cdbd2cSJim Jagielski 	// rename to init globals
253*b1cdbd2cSJim Jagielski 	if ( getVBAGlobals( ) )
254*b1cdbd2cSJim Jagielski 		return pVBAGlobals->Find( rName, t );
255*b1cdbd2cSJim Jagielski 	return NULL;
256*b1cdbd2cSJim Jagielski 
257*b1cdbd2cSJim Jagielski }
258*b1cdbd2cSJim Jagielski // Create array for conversion SFX <-> VB error code
259*b1cdbd2cSJim Jagielski struct SFX_VB_ErrorItem
260*b1cdbd2cSJim Jagielski {
261*b1cdbd2cSJim Jagielski 	sal_uInt16  nErrorVB;
262*b1cdbd2cSJim Jagielski 	SbError nErrorSFX;
263*b1cdbd2cSJim Jagielski };
264*b1cdbd2cSJim Jagielski 
265*b1cdbd2cSJim Jagielski const SFX_VB_ErrorItem __FAR_DATA SFX_VB_ErrorTab[] =
266*b1cdbd2cSJim Jagielski {
267*b1cdbd2cSJim Jagielski 	{ 1, SbERR_BASIC_EXCEPTION },  // #87844 Map exception to error code 1
268*b1cdbd2cSJim Jagielski 	{ 2, SbERR_SYNTAX },
269*b1cdbd2cSJim Jagielski 	{ 3, SbERR_NO_GOSUB },
270*b1cdbd2cSJim Jagielski 	{ 4, SbERR_REDO_FROM_START },
271*b1cdbd2cSJim Jagielski 	{ 5, SbERR_BAD_ARGUMENT },
272*b1cdbd2cSJim Jagielski 	{ 6, SbERR_MATH_OVERFLOW },
273*b1cdbd2cSJim Jagielski 	{ 7, SbERR_NO_MEMORY },
274*b1cdbd2cSJim Jagielski 	{ 8, SbERR_ALREADY_DIM },
275*b1cdbd2cSJim Jagielski 	{ 9, SbERR_OUT_OF_RANGE },
276*b1cdbd2cSJim Jagielski 	{ 10, SbERR_DUPLICATE_DEF },
277*b1cdbd2cSJim Jagielski 	{ 11, SbERR_ZERODIV },
278*b1cdbd2cSJim Jagielski 	{ 12, SbERR_VAR_UNDEFINED },
279*b1cdbd2cSJim Jagielski 	{ 13, SbERR_CONVERSION },
280*b1cdbd2cSJim Jagielski 	{ 14, SbERR_BAD_PARAMETER },
281*b1cdbd2cSJim Jagielski 	{ 18, SbERR_USER_ABORT },
282*b1cdbd2cSJim Jagielski 	{ 20, SbERR_BAD_RESUME },
283*b1cdbd2cSJim Jagielski 	{ 28, SbERR_STACK_OVERFLOW },
284*b1cdbd2cSJim Jagielski 	{ 35, SbERR_PROC_UNDEFINED },
285*b1cdbd2cSJim Jagielski 	{ 48, SbERR_BAD_DLL_LOAD },
286*b1cdbd2cSJim Jagielski 	{ 49, SbERR_BAD_DLL_CALL },
287*b1cdbd2cSJim Jagielski 	{ 51, SbERR_INTERNAL_ERROR },
288*b1cdbd2cSJim Jagielski 	{ 52, SbERR_BAD_CHANNEL },
289*b1cdbd2cSJim Jagielski 	{ 53, SbERR_FILE_NOT_FOUND },
290*b1cdbd2cSJim Jagielski 	{ 54, SbERR_BAD_FILE_MODE },
291*b1cdbd2cSJim Jagielski 	{ 55, SbERR_FILE_ALREADY_OPEN },
292*b1cdbd2cSJim Jagielski 	{ 57, SbERR_IO_ERROR },
293*b1cdbd2cSJim Jagielski 	{ 58, SbERR_FILE_EXISTS },
294*b1cdbd2cSJim Jagielski 	{ 59, SbERR_BAD_RECORD_LENGTH },
295*b1cdbd2cSJim Jagielski 	{ 61, SbERR_DISK_FULL },
296*b1cdbd2cSJim Jagielski 	{ 62, SbERR_READ_PAST_EOF },
297*b1cdbd2cSJim Jagielski 	{ 63, SbERR_BAD_RECORD_NUMBER },
298*b1cdbd2cSJim Jagielski 	{ 67, SbERR_TOO_MANY_FILES },
299*b1cdbd2cSJim Jagielski 	{ 68, SbERR_NO_DEVICE },
300*b1cdbd2cSJim Jagielski 	{ 70, SbERR_ACCESS_DENIED },
301*b1cdbd2cSJim Jagielski 	{ 71, SbERR_NOT_READY },
302*b1cdbd2cSJim Jagielski 	{ 73, SbERR_NOT_IMPLEMENTED },
303*b1cdbd2cSJim Jagielski 	{ 74, SbERR_DIFFERENT_DRIVE },
304*b1cdbd2cSJim Jagielski 	{ 75, SbERR_ACCESS_ERROR },
305*b1cdbd2cSJim Jagielski 	{ 76, SbERR_PATH_NOT_FOUND },
306*b1cdbd2cSJim Jagielski 	{ 91, SbERR_NO_OBJECT },
307*b1cdbd2cSJim Jagielski 	{ 93, SbERR_BAD_PATTERN },
308*b1cdbd2cSJim Jagielski 	{ 94, SBERR_IS_NULL },
309*b1cdbd2cSJim Jagielski 	{ 250, SbERR_DDE_ERROR },
310*b1cdbd2cSJim Jagielski 	{ 280, SbERR_DDE_WAITINGACK },
311*b1cdbd2cSJim Jagielski 	{ 281, SbERR_DDE_OUTOFCHANNELS },
312*b1cdbd2cSJim Jagielski 	{ 282, SbERR_DDE_NO_RESPONSE },
313*b1cdbd2cSJim Jagielski 	{ 283, SbERR_DDE_MULT_RESPONSES },
314*b1cdbd2cSJim Jagielski 	{ 284, SbERR_DDE_CHANNEL_LOCKED },
315*b1cdbd2cSJim Jagielski 	{ 285, SbERR_DDE_NOTPROCESSED },
316*b1cdbd2cSJim Jagielski 	{ 286, SbERR_DDE_TIMEOUT },
317*b1cdbd2cSJim Jagielski 	{ 287, SbERR_DDE_USER_INTERRUPT },
318*b1cdbd2cSJim Jagielski 	{ 288, SbERR_DDE_BUSY },
319*b1cdbd2cSJim Jagielski 	{ 289, SbERR_DDE_NO_DATA },
320*b1cdbd2cSJim Jagielski 	{ 290, SbERR_DDE_WRONG_DATA_FORMAT },
321*b1cdbd2cSJim Jagielski 	{ 291, SbERR_DDE_PARTNER_QUIT },
322*b1cdbd2cSJim Jagielski 	{ 292, SbERR_DDE_CONV_CLOSED },
323*b1cdbd2cSJim Jagielski 	{ 293, SbERR_DDE_NO_CHANNEL },
324*b1cdbd2cSJim Jagielski 	{ 294, SbERR_DDE_INVALID_LINK },
325*b1cdbd2cSJim Jagielski 	{ 295, SbERR_DDE_QUEUE_OVERFLOW },
326*b1cdbd2cSJim Jagielski 	{ 296, SbERR_DDE_LINK_ALREADY_EST },
327*b1cdbd2cSJim Jagielski 	{ 297, SbERR_DDE_LINK_INV_TOPIC },
328*b1cdbd2cSJim Jagielski 	{ 298, SbERR_DDE_DLL_NOT_FOUND },
329*b1cdbd2cSJim Jagielski 	{ 323, SbERR_CANNOT_LOAD },
330*b1cdbd2cSJim Jagielski 	{ 341, SbERR_BAD_INDEX },
331*b1cdbd2cSJim Jagielski 	{ 366, SbERR_NO_ACTIVE_OBJECT },
332*b1cdbd2cSJim Jagielski 	{ 380, SbERR_BAD_PROP_VALUE },
333*b1cdbd2cSJim Jagielski 	{ 382, SbERR_PROP_READONLY },
334*b1cdbd2cSJim Jagielski 	{ 394, SbERR_PROP_WRITEONLY },
335*b1cdbd2cSJim Jagielski 	{ 420, SbERR_INVALID_OBJECT },
336*b1cdbd2cSJim Jagielski 	{ 423, SbERR_NO_METHOD },
337*b1cdbd2cSJim Jagielski 	{ 424, SbERR_NEEDS_OBJECT },
338*b1cdbd2cSJim Jagielski 	{ 425, SbERR_INVALID_USAGE_OBJECT },
339*b1cdbd2cSJim Jagielski 	{ 430, SbERR_NO_OLE },
340*b1cdbd2cSJim Jagielski 	{ 438, SbERR_BAD_METHOD },
341*b1cdbd2cSJim Jagielski 	{ 440, SbERR_OLE_ERROR },
342*b1cdbd2cSJim Jagielski 	{ 445, SbERR_BAD_ACTION },
343*b1cdbd2cSJim Jagielski 	{ 446, SbERR_NO_NAMED_ARGS },
344*b1cdbd2cSJim Jagielski 	{ 447, SbERR_BAD_LOCALE },
345*b1cdbd2cSJim Jagielski 	{ 448, SbERR_NAMED_NOT_FOUND },
346*b1cdbd2cSJim Jagielski 	{ 449, SbERR_NOT_OPTIONAL },
347*b1cdbd2cSJim Jagielski 	{ 450, SbERR_WRONG_ARGS },
348*b1cdbd2cSJim Jagielski 	{ 451, SbERR_NOT_A_COLL },
349*b1cdbd2cSJim Jagielski 	{ 452, SbERR_BAD_ORDINAL },
350*b1cdbd2cSJim Jagielski 	{ 453, SbERR_DLLPROC_NOT_FOUND },
351*b1cdbd2cSJim Jagielski 	{ 460, SbERR_BAD_CLIPBD_FORMAT },
352*b1cdbd2cSJim Jagielski 	{ 951, SbERR_UNEXPECTED },
353*b1cdbd2cSJim Jagielski 	{ 952, SbERR_EXPECTED },
354*b1cdbd2cSJim Jagielski 	{ 953, SbERR_SYMBOL_EXPECTED },
355*b1cdbd2cSJim Jagielski 	{ 954, SbERR_VAR_EXPECTED },
356*b1cdbd2cSJim Jagielski 	{ 955, SbERR_LABEL_EXPECTED },
357*b1cdbd2cSJim Jagielski 	{ 956, SbERR_LVALUE_EXPECTED },
358*b1cdbd2cSJim Jagielski 	{ 957, SbERR_VAR_DEFINED },
359*b1cdbd2cSJim Jagielski 	{ 958, SbERR_PROC_DEFINED },
360*b1cdbd2cSJim Jagielski 	{ 959, SbERR_LABEL_DEFINED },
361*b1cdbd2cSJim Jagielski 	{ 960, SbERR_UNDEF_VAR },
362*b1cdbd2cSJim Jagielski 	{ 961, SbERR_UNDEF_ARRAY },
363*b1cdbd2cSJim Jagielski 	{ 962, SbERR_UNDEF_PROC },
364*b1cdbd2cSJim Jagielski 	{ 963, SbERR_UNDEF_LABEL },
365*b1cdbd2cSJim Jagielski 	{ 964, SbERR_UNDEF_TYPE },
366*b1cdbd2cSJim Jagielski 	{ 965, SbERR_BAD_EXIT },
367*b1cdbd2cSJim Jagielski 	{ 966, SbERR_BAD_BLOCK },
368*b1cdbd2cSJim Jagielski 	{ 967, SbERR_BAD_BRACKETS },
369*b1cdbd2cSJim Jagielski 	{ 968, SbERR_BAD_DECLARATION },
370*b1cdbd2cSJim Jagielski 	{ 969, SbERR_BAD_PARAMETERS },
371*b1cdbd2cSJim Jagielski 	{ 970, SbERR_BAD_CHAR_IN_NUMBER },
372*b1cdbd2cSJim Jagielski 	{ 971, SbERR_MUST_HAVE_DIMS },
373*b1cdbd2cSJim Jagielski 	{ 972, SbERR_NO_IF },
374*b1cdbd2cSJim Jagielski 	{ 973, SbERR_NOT_IN_SUBR },
375*b1cdbd2cSJim Jagielski 	{ 974, SbERR_NOT_IN_MAIN },
376*b1cdbd2cSJim Jagielski 	{ 975, SbERR_WRONG_DIMS },
377*b1cdbd2cSJim Jagielski 	{ 976, SbERR_BAD_OPTION },
378*b1cdbd2cSJim Jagielski 	{ 977, SbERR_CONSTANT_REDECLARED },
379*b1cdbd2cSJim Jagielski 	{ 978, SbERR_PROG_TOO_LARGE },
380*b1cdbd2cSJim Jagielski 	{ 979, SbERR_NO_STRINGS_ARRAYS },
381*b1cdbd2cSJim Jagielski 	{ 1000, SbERR_PROPERTY_NOT_FOUND },
382*b1cdbd2cSJim Jagielski 	{ 1001, SbERR_METHOD_NOT_FOUND },
383*b1cdbd2cSJim Jagielski 	{ 1002, SbERR_ARG_MISSING },
384*b1cdbd2cSJim Jagielski 	{ 1003, SbERR_BAD_NUMBER_OF_ARGS },
385*b1cdbd2cSJim Jagielski 	{ 1004, SbERR_METHOD_FAILED },
386*b1cdbd2cSJim Jagielski 	{ 1005, SbERR_SETPROP_FAILED },
387*b1cdbd2cSJim Jagielski 	{ 1006, SbERR_GETPROP_FAILED },
388*b1cdbd2cSJim Jagielski 	{ 1007, SbERR_BASIC_COMPAT },
389*b1cdbd2cSJim Jagielski 	{ 0xFFFF, 0xFFFFFFFFL }		// End mark
390*b1cdbd2cSJim Jagielski };
391*b1cdbd2cSJim Jagielski 
392*b1cdbd2cSJim Jagielski // The StarBASIC factory is a hack. When a SbModule is created, its pointer
393*b1cdbd2cSJim Jagielski // is saved and given to the following SbProperties/SbMethods. This restores
394*b1cdbd2cSJim Jagielski // the Modul-relationshop. But it works only when a modul is loaded.
395*b1cdbd2cSJim Jagielski // Can cause troubles with separately loaded properties!
396*b1cdbd2cSJim Jagielski 
Create(sal_uInt16 nSbxId,sal_uInt32 nCreator)397*b1cdbd2cSJim Jagielski SbxBase* SbiFactory::Create( sal_uInt16 nSbxId, sal_uInt32 nCreator )
398*b1cdbd2cSJim Jagielski {
399*b1cdbd2cSJim Jagielski 	if( nCreator ==  SBXCR_SBX )
400*b1cdbd2cSJim Jagielski 	{
401*b1cdbd2cSJim Jagielski 		String aEmpty;
402*b1cdbd2cSJim Jagielski 		switch( nSbxId )
403*b1cdbd2cSJim Jagielski 		{
404*b1cdbd2cSJim Jagielski 			case SBXID_BASIC:
405*b1cdbd2cSJim Jagielski 				return new StarBASIC( NULL );
406*b1cdbd2cSJim Jagielski 			case SBXID_BASICMOD:
407*b1cdbd2cSJim Jagielski 				return new SbModule( aEmpty );
408*b1cdbd2cSJim Jagielski 			case SBXID_BASICPROP:
409*b1cdbd2cSJim Jagielski 				return new SbProperty( aEmpty, SbxVARIANT, NULL );
410*b1cdbd2cSJim Jagielski 			case SBXID_BASICMETHOD:
411*b1cdbd2cSJim Jagielski 				return new SbMethod( aEmpty, SbxVARIANT, NULL );
412*b1cdbd2cSJim Jagielski 			case SBXID_JSCRIPTMOD:
413*b1cdbd2cSJim Jagielski 				return new SbJScriptModule( aEmpty );
414*b1cdbd2cSJim Jagielski 			case SBXID_JSCRIPTMETH:
415*b1cdbd2cSJim Jagielski 				return new SbJScriptMethod( aEmpty, SbxVARIANT, NULL );
416*b1cdbd2cSJim Jagielski 		}
417*b1cdbd2cSJim Jagielski 	}
418*b1cdbd2cSJim Jagielski 	return NULL;
419*b1cdbd2cSJim Jagielski }
420*b1cdbd2cSJim Jagielski 
CreateObject(const String & rClass)421*b1cdbd2cSJim Jagielski SbxObject* SbiFactory::CreateObject( const String& rClass )
422*b1cdbd2cSJim Jagielski {
423*b1cdbd2cSJim Jagielski 	if( rClass.EqualsIgnoreCaseAscii( "StarBASIC" ) )
424*b1cdbd2cSJim Jagielski 		return new StarBASIC( NULL );
425*b1cdbd2cSJim Jagielski 	else
426*b1cdbd2cSJim Jagielski 	if( rClass.EqualsIgnoreCaseAscii( "StarBASICModule" ) )
427*b1cdbd2cSJim Jagielski 	{
428*b1cdbd2cSJim Jagielski 		String aEmpty;
429*b1cdbd2cSJim Jagielski 		return new SbModule( aEmpty );
430*b1cdbd2cSJim Jagielski 	}
431*b1cdbd2cSJim Jagielski 	else
432*b1cdbd2cSJim Jagielski 	if( rClass.EqualsIgnoreCaseAscii( "Collection" ) )
433*b1cdbd2cSJim Jagielski 	{
434*b1cdbd2cSJim Jagielski 		String aCollectionName( RTL_CONSTASCII_USTRINGPARAM("Collection") );
435*b1cdbd2cSJim Jagielski 		return new BasicCollection( aCollectionName );
436*b1cdbd2cSJim Jagielski 	}
437*b1cdbd2cSJim Jagielski 	else
438*b1cdbd2cSJim Jagielski     if( rClass.EqualsIgnoreCaseAscii( "FileSystemObject" ) )
439*b1cdbd2cSJim Jagielski     {
440*b1cdbd2cSJim Jagielski         try
441*b1cdbd2cSJim Jagielski         {
442*b1cdbd2cSJim Jagielski             Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory(), UNO_SET_THROW );
443*b1cdbd2cSJim Jagielski             ::rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.FileSystemObject" ) );
444*b1cdbd2cSJim Jagielski             Reference< XInterface > xInterface( xFactory->createInstance( aServiceName ), UNO_SET_THROW );
445*b1cdbd2cSJim Jagielski             return new SbUnoObject( aServiceName, uno::makeAny( xInterface ) );
446*b1cdbd2cSJim Jagielski         }
447*b1cdbd2cSJim Jagielski         catch( Exception& )
448*b1cdbd2cSJim Jagielski         {}
449*b1cdbd2cSJim Jagielski     }
450*b1cdbd2cSJim Jagielski 
451*b1cdbd2cSJim Jagielski     return NULL;
452*b1cdbd2cSJim Jagielski }
453*b1cdbd2cSJim Jagielski 
454*b1cdbd2cSJim Jagielski 
455*b1cdbd2cSJim Jagielski // Factory class to create OLE objects
456*b1cdbd2cSJim Jagielski class SbOLEFactory : public SbxFactory
457*b1cdbd2cSJim Jagielski {
458*b1cdbd2cSJim Jagielski public:
459*b1cdbd2cSJim Jagielski 	virtual SbxBase* Create( sal_uInt16 nSbxId, sal_uInt32 = SBXCR_SBX );
460*b1cdbd2cSJim Jagielski 	virtual SbxObject* CreateObject( const String& );
461*b1cdbd2cSJim Jagielski };
462*b1cdbd2cSJim Jagielski 
Create(sal_uInt16,sal_uInt32)463*b1cdbd2cSJim Jagielski SbxBase* SbOLEFactory::Create( sal_uInt16, sal_uInt32 )
464*b1cdbd2cSJim Jagielski {
465*b1cdbd2cSJim Jagielski 	// Not supported
466*b1cdbd2cSJim Jagielski 	return NULL;
467*b1cdbd2cSJim Jagielski }
468*b1cdbd2cSJim Jagielski 
469*b1cdbd2cSJim Jagielski SbUnoObject* createOLEObject_Impl( const String& aType );	// sbunoobj.cxx
470*b1cdbd2cSJim Jagielski 
CreateObject(const String & rClassName)471*b1cdbd2cSJim Jagielski SbxObject* SbOLEFactory::CreateObject( const String& rClassName )
472*b1cdbd2cSJim Jagielski {
473*b1cdbd2cSJim Jagielski 	SbxObject* pRet = createOLEObject_Impl( rClassName );
474*b1cdbd2cSJim Jagielski 	return pRet;
475*b1cdbd2cSJim Jagielski }
476*b1cdbd2cSJim Jagielski 
477*b1cdbd2cSJim Jagielski 
478*b1cdbd2cSJim Jagielski //========================================================================
479*b1cdbd2cSJim Jagielski // SbFormFactory, show user forms by: dim as new <user form name>
480*b1cdbd2cSJim Jagielski 
481*b1cdbd2cSJim Jagielski class SbFormFactory : public SbxFactory
482*b1cdbd2cSJim Jagielski {
483*b1cdbd2cSJim Jagielski public:
484*b1cdbd2cSJim Jagielski 	virtual SbxBase* Create( sal_uInt16 nSbxId, sal_uInt32 = SBXCR_SBX );
485*b1cdbd2cSJim Jagielski 	virtual SbxObject* CreateObject( const String& );
486*b1cdbd2cSJim Jagielski };
487*b1cdbd2cSJim Jagielski 
Create(sal_uInt16,sal_uInt32)488*b1cdbd2cSJim Jagielski SbxBase* SbFormFactory::Create( sal_uInt16, sal_uInt32 )
489*b1cdbd2cSJim Jagielski {
490*b1cdbd2cSJim Jagielski 	// Not supported
491*b1cdbd2cSJim Jagielski 	return NULL;
492*b1cdbd2cSJim Jagielski }
493*b1cdbd2cSJim Jagielski 
CreateObject(const String & rClassName)494*b1cdbd2cSJim Jagielski SbxObject* SbFormFactory::CreateObject( const String& rClassName )
495*b1cdbd2cSJim Jagielski {
496*b1cdbd2cSJim Jagielski 	if( SbModule* pMod = pMOD )
497*b1cdbd2cSJim Jagielski 	{
498*b1cdbd2cSJim Jagielski 		if( SbxVariable* pVar = pMod->Find( rClassName, SbxCLASS_OBJECT ) )
499*b1cdbd2cSJim Jagielski 		{
500*b1cdbd2cSJim Jagielski 			if( SbUserFormModule* pFormModule = PTR_CAST( SbUserFormModule, pVar->GetObject() ) )
501*b1cdbd2cSJim Jagielski 			{
502*b1cdbd2cSJim Jagielski 			    bool bInitState = pFormModule->getInitState();
503*b1cdbd2cSJim Jagielski 				if( bInitState )
504*b1cdbd2cSJim Jagielski 				{
505*b1cdbd2cSJim Jagielski 					// Not the first instantiate, reset
506*b1cdbd2cSJim Jagielski 					bool bTriggerTerminateEvent = false;
507*b1cdbd2cSJim Jagielski 					pFormModule->ResetApiObj( bTriggerTerminateEvent );
508*b1cdbd2cSJim Jagielski 					pFormModule->setInitState( false );
509*b1cdbd2cSJim Jagielski 				}
510*b1cdbd2cSJim Jagielski 				else
511*b1cdbd2cSJim Jagielski 				{
512*b1cdbd2cSJim Jagielski 					pFormModule->Load();
513*b1cdbd2cSJim Jagielski 				}
514*b1cdbd2cSJim Jagielski 				return pFormModule->CreateInstance();
515*b1cdbd2cSJim Jagielski 			}
516*b1cdbd2cSJim Jagielski 		}
517*b1cdbd2cSJim Jagielski 	}
518*b1cdbd2cSJim Jagielski 	return 0;
519*b1cdbd2cSJim Jagielski }
520*b1cdbd2cSJim Jagielski 
521*b1cdbd2cSJim Jagielski 
522*b1cdbd2cSJim Jagielski //========================================================================
523*b1cdbd2cSJim Jagielski // SbTypeFactory
524*b1cdbd2cSJim Jagielski 
cloneTypeObjectImpl(const SbxObject & rTypeObj)525*b1cdbd2cSJim Jagielski SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj )
526*b1cdbd2cSJim Jagielski {
527*b1cdbd2cSJim Jagielski 	SbxObject* pRet = new SbxObject( rTypeObj );
528*b1cdbd2cSJim Jagielski 	pRet->PutObject( pRet );
529*b1cdbd2cSJim Jagielski 
530*b1cdbd2cSJim Jagielski 	// Copy the properties, not only the reference to them
531*b1cdbd2cSJim Jagielski 	SbxArray* pProps = pRet->GetProperties();
532*b1cdbd2cSJim Jagielski 	sal_uInt32 nCount = pProps->Count32();
533*b1cdbd2cSJim Jagielski 	for( sal_uInt32 i = 0 ; i < nCount ; i++ )
534*b1cdbd2cSJim Jagielski 	{
535*b1cdbd2cSJim Jagielski 		SbxVariable* pVar = pProps->Get32( i );
536*b1cdbd2cSJim Jagielski 		SbxProperty* pProp = PTR_CAST( SbxProperty, pVar );
537*b1cdbd2cSJim Jagielski 		if( pProp )
538*b1cdbd2cSJim Jagielski 		{
539*b1cdbd2cSJim Jagielski 			SbxProperty* pNewProp = new SbxProperty( *pProp );
540*b1cdbd2cSJim Jagielski 			SbxDataType eVarType = pVar->GetType();
541*b1cdbd2cSJim Jagielski 			if( eVarType & SbxARRAY )
542*b1cdbd2cSJim Jagielski 			{
543*b1cdbd2cSJim Jagielski 				SbxBase* pParObj = pVar->GetObject();
544*b1cdbd2cSJim Jagielski 				SbxDimArray* pSource = PTR_CAST(SbxDimArray,pParObj);
545*b1cdbd2cSJim Jagielski 				SbxDimArray* pDest = new SbxDimArray( pVar->GetType() );
546*b1cdbd2cSJim Jagielski 				sal_Int32 lb = 0;
547*b1cdbd2cSJim Jagielski 				sal_Int32 ub = 0;
548*b1cdbd2cSJim Jagielski 
549*b1cdbd2cSJim Jagielski 				pDest->setHasFixedSize( pSource->hasFixedSize() );
550*b1cdbd2cSJim Jagielski 				if ( pSource->GetDims() && pSource->hasFixedSize() )
551*b1cdbd2cSJim Jagielski 				{
552*b1cdbd2cSJim Jagielski 					for ( sal_Int32 j = 1 ; j <= pSource->GetDims(); ++j )
553*b1cdbd2cSJim Jagielski 					{
554*b1cdbd2cSJim Jagielski 						pSource->GetDim32( (sal_Int32)j, lb, ub );
555*b1cdbd2cSJim Jagielski 						pDest->AddDim32( lb, ub );
556*b1cdbd2cSJim Jagielski 					}
557*b1cdbd2cSJim Jagielski 				}
558*b1cdbd2cSJim Jagielski 				else
559*b1cdbd2cSJim Jagielski 					pDest->unoAddDim( 0, -1 ); // variant array
560*b1cdbd2cSJim Jagielski 
561*b1cdbd2cSJim Jagielski 				sal_uInt16 nSavFlags = pVar->GetFlags();
562*b1cdbd2cSJim Jagielski 				pNewProp->ResetFlag( SBX_FIXED );
563*b1cdbd2cSJim Jagielski 				// need to reset the FIXED flag
564*b1cdbd2cSJim Jagielski 				// when calling PutObject ( because the type will not match Object )
565*b1cdbd2cSJim Jagielski 				pNewProp->PutObject( pDest );
566*b1cdbd2cSJim Jagielski 				pNewProp->SetFlags( nSavFlags );
567*b1cdbd2cSJim Jagielski 			}
568*b1cdbd2cSJim Jagielski 			if( eVarType == SbxOBJECT )
569*b1cdbd2cSJim Jagielski 			{
570*b1cdbd2cSJim Jagielski 				SbxBase* pObjBase = pVar->GetObject();
571*b1cdbd2cSJim Jagielski 				SbxObject* pSrcObj = PTR_CAST(SbxObject,pObjBase);
572*b1cdbd2cSJim Jagielski 				SbxObject* pDestObj = NULL;
573*b1cdbd2cSJim Jagielski 				if( pSrcObj != NULL )
574*b1cdbd2cSJim Jagielski 					pDestObj = cloneTypeObjectImpl( *pSrcObj );
575*b1cdbd2cSJim Jagielski 				pNewProp->PutObject( pDestObj );
576*b1cdbd2cSJim Jagielski 			}
577*b1cdbd2cSJim Jagielski 			pProps->PutDirect( pNewProp, i );
578*b1cdbd2cSJim Jagielski 		}
579*b1cdbd2cSJim Jagielski 	}
580*b1cdbd2cSJim Jagielski 	return pRet;
581*b1cdbd2cSJim Jagielski }
582*b1cdbd2cSJim Jagielski 
583*b1cdbd2cSJim Jagielski // Factory class to create user defined objects (type command)
584*b1cdbd2cSJim Jagielski class SbTypeFactory : public SbxFactory
585*b1cdbd2cSJim Jagielski {
586*b1cdbd2cSJim Jagielski public:
587*b1cdbd2cSJim Jagielski 	virtual SbxBase* Create( sal_uInt16 nSbxId, sal_uInt32 = SBXCR_SBX );
588*b1cdbd2cSJim Jagielski 	virtual SbxObject* CreateObject( const String& );
589*b1cdbd2cSJim Jagielski };
590*b1cdbd2cSJim Jagielski 
Create(sal_uInt16,sal_uInt32)591*b1cdbd2cSJim Jagielski SbxBase* SbTypeFactory::Create( sal_uInt16, sal_uInt32 )
592*b1cdbd2cSJim Jagielski {
593*b1cdbd2cSJim Jagielski 	// Not supported
594*b1cdbd2cSJim Jagielski 	return NULL;
595*b1cdbd2cSJim Jagielski }
596*b1cdbd2cSJim Jagielski 
CreateObject(const String & rClassName)597*b1cdbd2cSJim Jagielski SbxObject* SbTypeFactory::CreateObject( const String& rClassName )
598*b1cdbd2cSJim Jagielski {
599*b1cdbd2cSJim Jagielski 	SbxObject* pRet = NULL;
600*b1cdbd2cSJim Jagielski 	SbModule* pMod = pMOD;
601*b1cdbd2cSJim Jagielski 	if( pMod )
602*b1cdbd2cSJim Jagielski 	{
603*b1cdbd2cSJim Jagielski 		const SbxObject* pObj = pMod->FindType( rClassName );
604*b1cdbd2cSJim Jagielski 		if( pObj )
605*b1cdbd2cSJim Jagielski 			pRet = cloneTypeObjectImpl( *pObj );
606*b1cdbd2cSJim Jagielski 	}
607*b1cdbd2cSJim Jagielski 	return pRet;
608*b1cdbd2cSJim Jagielski }
609*b1cdbd2cSJim Jagielski 
createUserTypeImpl(const String & rClassName)610*b1cdbd2cSJim Jagielski SbxObject* createUserTypeImpl( const String& rClassName )
611*b1cdbd2cSJim Jagielski {
612*b1cdbd2cSJim Jagielski 	SbxObject* pRetObj = pTYPEFAC->CreateObject( rClassName );
613*b1cdbd2cSJim Jagielski 	return pRetObj;
614*b1cdbd2cSJim Jagielski }
615*b1cdbd2cSJim Jagielski 
616*b1cdbd2cSJim Jagielski 
TYPEINIT1(SbClassModuleObject,SbModule)617*b1cdbd2cSJim Jagielski TYPEINIT1(SbClassModuleObject,SbModule)
618*b1cdbd2cSJim Jagielski 
619*b1cdbd2cSJim Jagielski SbClassModuleObject::SbClassModuleObject( SbModule* pClassModule )
620*b1cdbd2cSJim Jagielski 	: SbModule( pClassModule->GetName() )
621*b1cdbd2cSJim Jagielski 	, mpClassModule( pClassModule )
622*b1cdbd2cSJim Jagielski 	, mbInitializeEventDone( false )
623*b1cdbd2cSJim Jagielski {
624*b1cdbd2cSJim Jagielski 	aOUSource = pClassModule->aOUSource;
625*b1cdbd2cSJim Jagielski 	aComment = pClassModule->aComment;
626*b1cdbd2cSJim Jagielski 	pImage = pClassModule->pImage;
627*b1cdbd2cSJim Jagielski 	pBreaks = pClassModule->pBreaks;
628*b1cdbd2cSJim Jagielski 
629*b1cdbd2cSJim Jagielski 	SetClassName( pClassModule->GetName() );
630*b1cdbd2cSJim Jagielski 
631*b1cdbd2cSJim Jagielski 	// Allow search only internally
632*b1cdbd2cSJim Jagielski 	ResetFlag( SBX_GBLSEARCH );
633*b1cdbd2cSJim Jagielski 
634*b1cdbd2cSJim Jagielski 	// Copy the methods from original class module
635*b1cdbd2cSJim Jagielski 	SbxArray* pClassMethods = pClassModule->GetMethods();
636*b1cdbd2cSJim Jagielski 	sal_uInt32 nMethodCount = pClassMethods->Count32();
637*b1cdbd2cSJim Jagielski 	sal_uInt32 i;
638*b1cdbd2cSJim Jagielski 	for( i = 0 ; i < nMethodCount ; i++ )
639*b1cdbd2cSJim Jagielski 	{
640*b1cdbd2cSJim Jagielski 		SbxVariable* pVar = pClassMethods->Get32( i );
641*b1cdbd2cSJim Jagielski 
642*b1cdbd2cSJim Jagielski 		// Exclude SbIfaceMapperMethod to copy them in a second step
643*b1cdbd2cSJim Jagielski 		SbIfaceMapperMethod* pIfaceMethod = PTR_CAST( SbIfaceMapperMethod, pVar );
644*b1cdbd2cSJim Jagielski 		if( !pIfaceMethod )
645*b1cdbd2cSJim Jagielski 		{
646*b1cdbd2cSJim Jagielski 			SbMethod* pMethod = PTR_CAST(SbMethod, pVar );
647*b1cdbd2cSJim Jagielski 			if( pMethod )
648*b1cdbd2cSJim Jagielski 			{
649*b1cdbd2cSJim Jagielski 				sal_uInt16 nFlags_ = pMethod->GetFlags();
650*b1cdbd2cSJim Jagielski 				pMethod->SetFlag( SBX_NO_BROADCAST );
651*b1cdbd2cSJim Jagielski 				SbMethod* pNewMethod = new SbMethod( *pMethod );
652*b1cdbd2cSJim Jagielski 				pNewMethod->ResetFlag( SBX_NO_BROADCAST );
653*b1cdbd2cSJim Jagielski 				pMethod->SetFlags( nFlags_ );
654*b1cdbd2cSJim Jagielski 				pNewMethod->pMod = this;
655*b1cdbd2cSJim Jagielski 				pNewMethod->SetParent( this );
656*b1cdbd2cSJim Jagielski 				pMethods->PutDirect( pNewMethod, i );
657*b1cdbd2cSJim Jagielski 				StartListening( pNewMethod->GetBroadcaster(), sal_True );
658*b1cdbd2cSJim Jagielski 			}
659*b1cdbd2cSJim Jagielski 		}
660*b1cdbd2cSJim Jagielski 	}
661*b1cdbd2cSJim Jagielski 
662*b1cdbd2cSJim Jagielski 	// Copy SbIfaceMapperMethod in a second step to ensure that
663*b1cdbd2cSJim Jagielski 	// the corresponding base methods have already been copied
664*b1cdbd2cSJim Jagielski 	for( i = 0 ; i < nMethodCount ; i++ )
665*b1cdbd2cSJim Jagielski 	{
666*b1cdbd2cSJim Jagielski 		SbxVariable* pVar = pClassMethods->Get32( i );
667*b1cdbd2cSJim Jagielski 
668*b1cdbd2cSJim Jagielski 		SbIfaceMapperMethod* pIfaceMethod = PTR_CAST( SbIfaceMapperMethod, pVar );
669*b1cdbd2cSJim Jagielski 		if( pIfaceMethod )
670*b1cdbd2cSJim Jagielski 		{
671*b1cdbd2cSJim Jagielski 			SbMethod* pImplMethod = pIfaceMethod->getImplMethod();
672*b1cdbd2cSJim Jagielski 			if( !pImplMethod )
673*b1cdbd2cSJim Jagielski 			{
674*b1cdbd2cSJim Jagielski 				DBG_ERROR( "No ImplMethod" );
675*b1cdbd2cSJim Jagielski 				continue;
676*b1cdbd2cSJim Jagielski 			}
677*b1cdbd2cSJim Jagielski 
678*b1cdbd2cSJim Jagielski 			// Search for own copy of ImplMethod
679*b1cdbd2cSJim Jagielski 			String aImplMethodName = pImplMethod->GetName();
680*b1cdbd2cSJim Jagielski 			SbxVariable* p = pMethods->Find( aImplMethodName, SbxCLASS_METHOD );
681*b1cdbd2cSJim Jagielski 			SbMethod* pImplMethodCopy = p ? PTR_CAST(SbMethod,p) : NULL;
682*b1cdbd2cSJim Jagielski 			if( !pImplMethodCopy )
683*b1cdbd2cSJim Jagielski 			{
684*b1cdbd2cSJim Jagielski 				DBG_ERROR( "Found no ImplMethod copy" );
685*b1cdbd2cSJim Jagielski 				continue;
686*b1cdbd2cSJim Jagielski 			}
687*b1cdbd2cSJim Jagielski 			SbIfaceMapperMethod* pNewIfaceMethod =
688*b1cdbd2cSJim Jagielski 				new SbIfaceMapperMethod( pIfaceMethod->GetName(), pImplMethodCopy );
689*b1cdbd2cSJim Jagielski 			pMethods->PutDirect( pNewIfaceMethod, i );
690*b1cdbd2cSJim Jagielski 		}
691*b1cdbd2cSJim Jagielski 	}
692*b1cdbd2cSJim Jagielski 
693*b1cdbd2cSJim Jagielski 	// Copy the properties from original class module
694*b1cdbd2cSJim Jagielski 	SbxArray* pClassProps = pClassModule->GetProperties();
695*b1cdbd2cSJim Jagielski 	sal_uInt32 nPropertyCount = pClassProps->Count32();
696*b1cdbd2cSJim Jagielski 	for( i = 0 ; i < nPropertyCount ; i++ )
697*b1cdbd2cSJim Jagielski 	{
698*b1cdbd2cSJim Jagielski 		SbxVariable* pVar = pClassProps->Get32( i );
699*b1cdbd2cSJim Jagielski 		SbProcedureProperty* pProcedureProp = PTR_CAST( SbProcedureProperty, pVar );
700*b1cdbd2cSJim Jagielski 		if( pProcedureProp )
701*b1cdbd2cSJim Jagielski 		{
702*b1cdbd2cSJim Jagielski 			sal_uInt16 nFlags_ = pProcedureProp->GetFlags();
703*b1cdbd2cSJim Jagielski 			pProcedureProp->SetFlag( SBX_NO_BROADCAST );
704*b1cdbd2cSJim Jagielski 			SbProcedureProperty* pNewProp = new SbProcedureProperty
705*b1cdbd2cSJim Jagielski 				( pProcedureProp->GetName(), pProcedureProp->GetType() );
706*b1cdbd2cSJim Jagielski 				// ( pProcedureProp->GetName(), pProcedureProp->GetType(), this );
707*b1cdbd2cSJim Jagielski 			pNewProp->SetFlags( nFlags_ ); // Copy flags
708*b1cdbd2cSJim Jagielski 			pNewProp->ResetFlag( SBX_NO_BROADCAST ); // except the Broadcast if it was set
709*b1cdbd2cSJim Jagielski 			pProcedureProp->SetFlags( nFlags_ );
710*b1cdbd2cSJim Jagielski 			pProps->PutDirect( pNewProp, i );
711*b1cdbd2cSJim Jagielski 			StartListening( pNewProp->GetBroadcaster(), sal_True );
712*b1cdbd2cSJim Jagielski 		}
713*b1cdbd2cSJim Jagielski 		else
714*b1cdbd2cSJim Jagielski 		{
715*b1cdbd2cSJim Jagielski 			SbxProperty* pProp = PTR_CAST( SbxProperty, pVar );
716*b1cdbd2cSJim Jagielski 			if( pProp )
717*b1cdbd2cSJim Jagielski 			{
718*b1cdbd2cSJim Jagielski 				sal_uInt16 nFlags_ = pProp->GetFlags();
719*b1cdbd2cSJim Jagielski 				pProp->SetFlag( SBX_NO_BROADCAST );
720*b1cdbd2cSJim Jagielski 				SbxProperty* pNewProp = new SbxProperty( *pProp );
721*b1cdbd2cSJim Jagielski 
722*b1cdbd2cSJim Jagielski 				// Special handling for modules instances and collections, they need
723*b1cdbd2cSJim Jagielski 				// to be instantiated, otherwise all refer to the same base object
724*b1cdbd2cSJim Jagielski 				SbxDataType eVarType = pProp->GetType();
725*b1cdbd2cSJim Jagielski 				if( eVarType == SbxOBJECT )
726*b1cdbd2cSJim Jagielski 				{
727*b1cdbd2cSJim Jagielski 					SbxBase* pObjBase = pProp->GetObject();
728*b1cdbd2cSJim Jagielski 					SbxObject* pObj = PTR_CAST(SbxObject,pObjBase);
729*b1cdbd2cSJim Jagielski 					if( pObj != NULL )
730*b1cdbd2cSJim Jagielski 					{
731*b1cdbd2cSJim Jagielski 						String aObjClass = pObj->GetClassName();
732*b1cdbd2cSJim Jagielski 
733*b1cdbd2cSJim Jagielski 						SbClassModuleObject* pClassModuleObj = PTR_CAST(SbClassModuleObject,pObjBase);
734*b1cdbd2cSJim Jagielski 						if( pClassModuleObj != NULL )
735*b1cdbd2cSJim Jagielski 						{
736*b1cdbd2cSJim Jagielski 							SbModule* pLclClassModule = pClassModuleObj->getClassModule();
737*b1cdbd2cSJim Jagielski 							SbClassModuleObject* pNewObj = new SbClassModuleObject( pLclClassModule );
738*b1cdbd2cSJim Jagielski 							pNewObj->SetName( pProp->GetName() );
739*b1cdbd2cSJim Jagielski 							pNewObj->SetParent( pLclClassModule->pParent );
740*b1cdbd2cSJim Jagielski 							pNewProp->PutObject( pNewObj );
741*b1cdbd2cSJim Jagielski 						}
742*b1cdbd2cSJim Jagielski 						else if( aObjClass.EqualsIgnoreCaseAscii( "Collection" ) )
743*b1cdbd2cSJim Jagielski 						{
744*b1cdbd2cSJim Jagielski 							String aCollectionName( RTL_CONSTASCII_USTRINGPARAM("Collection") );
745*b1cdbd2cSJim Jagielski 							BasicCollection* pNewCollection = new BasicCollection( aCollectionName );
746*b1cdbd2cSJim Jagielski 							pNewCollection->SetName( pProp->GetName() );
747*b1cdbd2cSJim Jagielski 							pNewCollection->SetParent( pClassModule->pParent );
748*b1cdbd2cSJim Jagielski 							pNewProp->PutObject( pNewCollection );
749*b1cdbd2cSJim Jagielski 						}
750*b1cdbd2cSJim Jagielski 					}
751*b1cdbd2cSJim Jagielski 				}
752*b1cdbd2cSJim Jagielski 
753*b1cdbd2cSJim Jagielski 				pNewProp->ResetFlag( SBX_NO_BROADCAST );
754*b1cdbd2cSJim Jagielski 				pNewProp->SetParent( this );
755*b1cdbd2cSJim Jagielski 				pProps->PutDirect( pNewProp, i );
756*b1cdbd2cSJim Jagielski 				pProp->SetFlags( nFlags_ );
757*b1cdbd2cSJim Jagielski 			}
758*b1cdbd2cSJim Jagielski 		}
759*b1cdbd2cSJim Jagielski 	}
760*b1cdbd2cSJim Jagielski 	SetModuleType( ModuleType::CLASS );
761*b1cdbd2cSJim Jagielski 	mbVBACompat = pClassModule->mbVBACompat;
762*b1cdbd2cSJim Jagielski }
763*b1cdbd2cSJim Jagielski 
~SbClassModuleObject()764*b1cdbd2cSJim Jagielski SbClassModuleObject::~SbClassModuleObject()
765*b1cdbd2cSJim Jagielski {
766*b1cdbd2cSJim Jagielski     // do not trigger termination event when document is already closed
767*b1cdbd2cSJim Jagielski 	if( StarBASIC::IsRunning() )
768*b1cdbd2cSJim Jagielski         if( StarBASIC* pDocBasic = lclGetDocBasicForModule( this ) )
769*b1cdbd2cSJim Jagielski             if( const DocBasicItem* pDocBasicItem = lclFindDocBasicItem( pDocBasic ) )
770*b1cdbd2cSJim Jagielski                 if( !pDocBasicItem->isDocClosed() )
771*b1cdbd2cSJim Jagielski                     triggerTerminateEvent();
772*b1cdbd2cSJim Jagielski 
773*b1cdbd2cSJim Jagielski 	// Must be deleted by base class dtor because this data
774*b1cdbd2cSJim Jagielski 	// is not owned by the SbClassModuleObject object
775*b1cdbd2cSJim Jagielski 	pImage = NULL;
776*b1cdbd2cSJim Jagielski 	pBreaks = NULL;
777*b1cdbd2cSJim Jagielski }
778*b1cdbd2cSJim Jagielski 
SFX_NOTIFY(SfxBroadcaster & rBC,const TypeId & rBCType,const SfxHint & rHint,const TypeId & rHintType)779*b1cdbd2cSJim Jagielski void SbClassModuleObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
780*b1cdbd2cSJim Jagielski 						   const SfxHint& rHint, const TypeId& rHintType )
781*b1cdbd2cSJim Jagielski {
782*b1cdbd2cSJim Jagielski 	handleProcedureProperties( rBC, rHint );
783*b1cdbd2cSJim Jagielski }
784*b1cdbd2cSJim Jagielski 
Find(const XubString & rName,SbxClassType t)785*b1cdbd2cSJim Jagielski SbxVariable* SbClassModuleObject::Find( const XubString& rName, SbxClassType t )
786*b1cdbd2cSJim Jagielski {
787*b1cdbd2cSJim Jagielski 	SbxVariable* pRes = SbxObject::Find( rName, t );
788*b1cdbd2cSJim Jagielski 	if( pRes )
789*b1cdbd2cSJim Jagielski 	{
790*b1cdbd2cSJim Jagielski 		triggerInitializeEvent();
791*b1cdbd2cSJim Jagielski 
792*b1cdbd2cSJim Jagielski 		SbIfaceMapperMethod* pIfaceMapperMethod = PTR_CAST(SbIfaceMapperMethod,pRes);
793*b1cdbd2cSJim Jagielski 		if( pIfaceMapperMethod )
794*b1cdbd2cSJim Jagielski 		{
795*b1cdbd2cSJim Jagielski 			pRes = pIfaceMapperMethod->getImplMethod();
796*b1cdbd2cSJim Jagielski 			pRes->SetFlag( SBX_EXTFOUND );
797*b1cdbd2cSJim Jagielski 		}
798*b1cdbd2cSJim Jagielski 	}
799*b1cdbd2cSJim Jagielski 	return pRes;
800*b1cdbd2cSJim Jagielski }
801*b1cdbd2cSJim Jagielski 
triggerInitializeEvent(void)802*b1cdbd2cSJim Jagielski void SbClassModuleObject::triggerInitializeEvent( void )
803*b1cdbd2cSJim Jagielski {
804*b1cdbd2cSJim Jagielski 	static String aInitMethodName( RTL_CONSTASCII_USTRINGPARAM("Class_Initialize") );
805*b1cdbd2cSJim Jagielski 
806*b1cdbd2cSJim Jagielski 	if( mbInitializeEventDone )
807*b1cdbd2cSJim Jagielski 		return;
808*b1cdbd2cSJim Jagielski 
809*b1cdbd2cSJim Jagielski 	mbInitializeEventDone = true;
810*b1cdbd2cSJim Jagielski 
811*b1cdbd2cSJim Jagielski 	// Search method
812*b1cdbd2cSJim Jagielski 	SbxVariable* pMeth = SbxObject::Find( aInitMethodName, SbxCLASS_METHOD );
813*b1cdbd2cSJim Jagielski 	if( pMeth )
814*b1cdbd2cSJim Jagielski 	{
815*b1cdbd2cSJim Jagielski 		SbxValues aVals;
816*b1cdbd2cSJim Jagielski 		pMeth->Get( aVals );
817*b1cdbd2cSJim Jagielski 	}
818*b1cdbd2cSJim Jagielski }
819*b1cdbd2cSJim Jagielski 
triggerTerminateEvent(void)820*b1cdbd2cSJim Jagielski void SbClassModuleObject::triggerTerminateEvent( void )
821*b1cdbd2cSJim Jagielski {
822*b1cdbd2cSJim Jagielski 	static String aTermMethodName( RTL_CONSTASCII_USTRINGPARAM("Class_Terminate") );
823*b1cdbd2cSJim Jagielski 
824*b1cdbd2cSJim Jagielski 	if( !mbInitializeEventDone || GetSbData()->bRunInit )
825*b1cdbd2cSJim Jagielski 		return;
826*b1cdbd2cSJim Jagielski 
827*b1cdbd2cSJim Jagielski 	// Search method
828*b1cdbd2cSJim Jagielski 	SbxVariable* pMeth = SbxObject::Find( aTermMethodName, SbxCLASS_METHOD );
829*b1cdbd2cSJim Jagielski 	if( pMeth )
830*b1cdbd2cSJim Jagielski 	{
831*b1cdbd2cSJim Jagielski 		SbxValues aVals;
832*b1cdbd2cSJim Jagielski 		pMeth->Get( aVals );
833*b1cdbd2cSJim Jagielski 	}
834*b1cdbd2cSJim Jagielski }
835*b1cdbd2cSJim Jagielski 
836*b1cdbd2cSJim Jagielski 
SbClassData(void)837*b1cdbd2cSJim Jagielski SbClassData::SbClassData( void )
838*b1cdbd2cSJim Jagielski {
839*b1cdbd2cSJim Jagielski 	mxIfaces = new SbxArray();
840*b1cdbd2cSJim Jagielski }
841*b1cdbd2cSJim Jagielski 
clear(void)842*b1cdbd2cSJim Jagielski void SbClassData::clear( void )
843*b1cdbd2cSJim Jagielski {
844*b1cdbd2cSJim Jagielski 	mxIfaces->Clear();
845*b1cdbd2cSJim Jagielski 	maRequiredTypes.clear();
846*b1cdbd2cSJim Jagielski }
847*b1cdbd2cSJim Jagielski 
SbClassFactory(void)848*b1cdbd2cSJim Jagielski SbClassFactory::SbClassFactory( void )
849*b1cdbd2cSJim Jagielski {
850*b1cdbd2cSJim Jagielski 	String aDummyName;
851*b1cdbd2cSJim Jagielski 	xClassModules = new SbxObject( aDummyName );
852*b1cdbd2cSJim Jagielski }
853*b1cdbd2cSJim Jagielski 
~SbClassFactory()854*b1cdbd2cSJim Jagielski SbClassFactory::~SbClassFactory()
855*b1cdbd2cSJim Jagielski {}
856*b1cdbd2cSJim Jagielski 
AddClassModule(SbModule * pClassModule)857*b1cdbd2cSJim Jagielski void SbClassFactory::AddClassModule( SbModule* pClassModule )
858*b1cdbd2cSJim Jagielski {
859*b1cdbd2cSJim Jagielski 	SbxObjectRef xToUseClassModules = xClassModules;
860*b1cdbd2cSJim Jagielski 
861*b1cdbd2cSJim Jagielski     if( StarBASIC* pDocBasic = lclGetDocBasicForModule( pClassModule ) )
862*b1cdbd2cSJim Jagielski         if( const DocBasicItem* pDocBasicItem = lclFindDocBasicItem( pDocBasic ) )
863*b1cdbd2cSJim Jagielski             xToUseClassModules = pDocBasicItem->getClassModules();
864*b1cdbd2cSJim Jagielski 
865*b1cdbd2cSJim Jagielski 	SbxObject* pParent = pClassModule->GetParent();
866*b1cdbd2cSJim Jagielski 	xToUseClassModules->Insert( pClassModule );
867*b1cdbd2cSJim Jagielski 	pClassModule->SetParent( pParent );
868*b1cdbd2cSJim Jagielski }
869*b1cdbd2cSJim Jagielski 
RemoveClassModule(SbModule * pClassModule)870*b1cdbd2cSJim Jagielski void SbClassFactory::RemoveClassModule( SbModule* pClassModule )
871*b1cdbd2cSJim Jagielski {
872*b1cdbd2cSJim Jagielski 	xClassModules->Remove( pClassModule );
873*b1cdbd2cSJim Jagielski }
874*b1cdbd2cSJim Jagielski 
Create(sal_uInt16,sal_uInt32)875*b1cdbd2cSJim Jagielski SbxBase* SbClassFactory::Create( sal_uInt16, sal_uInt32 )
876*b1cdbd2cSJim Jagielski {
877*b1cdbd2cSJim Jagielski 	// Not supported
878*b1cdbd2cSJim Jagielski 	return NULL;
879*b1cdbd2cSJim Jagielski }
880*b1cdbd2cSJim Jagielski 
CreateObject(const String & rClassName)881*b1cdbd2cSJim Jagielski SbxObject* SbClassFactory::CreateObject( const String& rClassName )
882*b1cdbd2cSJim Jagielski {
883*b1cdbd2cSJim Jagielski 	SbxObjectRef xToUseClassModules = xClassModules;
884*b1cdbd2cSJim Jagielski 
885*b1cdbd2cSJim Jagielski     if( SbModule* pMod = pMOD )
886*b1cdbd2cSJim Jagielski         if( StarBASIC* pDocBasic = lclGetDocBasicForModule( pMod ) )
887*b1cdbd2cSJim Jagielski             if( const DocBasicItem* pDocBasicItem = lclFindDocBasicItem( pDocBasic ) )
888*b1cdbd2cSJim Jagielski                 xToUseClassModules = pDocBasicItem->getClassModules();
889*b1cdbd2cSJim Jagielski 
890*b1cdbd2cSJim Jagielski 	SbxVariable* pVar = xToUseClassModules->Find( rClassName, SbxCLASS_OBJECT );
891*b1cdbd2cSJim Jagielski 	SbxObject* pRet = NULL;
892*b1cdbd2cSJim Jagielski 	if( pVar )
893*b1cdbd2cSJim Jagielski 	{
894*b1cdbd2cSJim Jagielski 		SbModule* pVarMod = (SbModule*)pVar;
895*b1cdbd2cSJim Jagielski 		pRet = new SbClassModuleObject( pVarMod );
896*b1cdbd2cSJim Jagielski 	}
897*b1cdbd2cSJim Jagielski 	return pRet;
898*b1cdbd2cSJim Jagielski }
899*b1cdbd2cSJim Jagielski 
FindClass(const String & rClassName)900*b1cdbd2cSJim Jagielski SbModule* SbClassFactory::FindClass( const String& rClassName )
901*b1cdbd2cSJim Jagielski {
902*b1cdbd2cSJim Jagielski 	SbxVariable* pVar = xClassModules->Find( rClassName, SbxCLASS_DONTCARE );
903*b1cdbd2cSJim Jagielski 	SbModule* pMod = pVar ? (SbModule*)pVar : NULL;
904*b1cdbd2cSJim Jagielski 	return pMod;
905*b1cdbd2cSJim Jagielski }
906*b1cdbd2cSJim Jagielski 
StarBASIC(StarBASIC * p,sal_Bool bIsDocBasic)907*b1cdbd2cSJim Jagielski StarBASIC::StarBASIC( StarBASIC* p, sal_Bool bIsDocBasic  )
908*b1cdbd2cSJim Jagielski 	: SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("StarBASIC") ) ), bDocBasic( bIsDocBasic )
909*b1cdbd2cSJim Jagielski {
910*b1cdbd2cSJim Jagielski 	SetParent( p );
911*b1cdbd2cSJim Jagielski 	pLibInfo = NULL;
912*b1cdbd2cSJim Jagielski 	bNoRtl = bBreak = sal_False;
913*b1cdbd2cSJim Jagielski 	bVBAEnabled = sal_False;
914*b1cdbd2cSJim Jagielski 	pModules = new SbxArray;
915*b1cdbd2cSJim Jagielski 
916*b1cdbd2cSJim Jagielski 	if( !GetSbData()->nInst++ )
917*b1cdbd2cSJim Jagielski 	{
918*b1cdbd2cSJim Jagielski 		pSBFAC = new SbiFactory;
919*b1cdbd2cSJim Jagielski 		AddFactory( pSBFAC );
920*b1cdbd2cSJim Jagielski 		pTYPEFAC = new SbTypeFactory;
921*b1cdbd2cSJim Jagielski 		AddFactory( pTYPEFAC );
922*b1cdbd2cSJim Jagielski 		pCLASSFAC = new SbClassFactory;
923*b1cdbd2cSJim Jagielski 		AddFactory( pCLASSFAC );
924*b1cdbd2cSJim Jagielski 		pOLEFAC = new SbOLEFactory;
925*b1cdbd2cSJim Jagielski 		AddFactory( pOLEFAC );
926*b1cdbd2cSJim Jagielski 		pFORMFAC = new SbFormFactory;
927*b1cdbd2cSJim Jagielski 		AddFactory( pFORMFAC );
928*b1cdbd2cSJim Jagielski 		pUNOFAC = new SbUnoFactory;
929*b1cdbd2cSJim Jagielski 		AddFactory( pUNOFAC );
930*b1cdbd2cSJim Jagielski 	}
931*b1cdbd2cSJim Jagielski 	pRtl = new SbiStdObject( String( RTL_CONSTASCII_USTRINGPARAM(RTLNAME) ), this );
932*b1cdbd2cSJim Jagielski     // Search via StarBasic is always global
933*b1cdbd2cSJim Jagielski 	SetFlag( SBX_GBLSEARCH );
934*b1cdbd2cSJim Jagielski 	pVBAGlobals = NULL;
935*b1cdbd2cSJim Jagielski 	bQuit = sal_False;
936*b1cdbd2cSJim Jagielski 
937*b1cdbd2cSJim Jagielski 	if( bDocBasic )
938*b1cdbd2cSJim Jagielski         lclInsertDocBasicItem( *this );
939*b1cdbd2cSJim Jagielski }
940*b1cdbd2cSJim Jagielski 
941*b1cdbd2cSJim Jagielski // #51727 Override SetModified so that the modified state
942*b1cdbd2cSJim Jagielski // is not given to the parent
SetModified(sal_Bool b)943*b1cdbd2cSJim Jagielski void StarBASIC::SetModified( sal_Bool b )
944*b1cdbd2cSJim Jagielski {
945*b1cdbd2cSJim Jagielski     SbxBase::SetModified( b );
946*b1cdbd2cSJim Jagielski }
947*b1cdbd2cSJim Jagielski 
948*b1cdbd2cSJim Jagielski extern void lcl_closeTraceFile();
949*b1cdbd2cSJim Jagielski 
~StarBASIC()950*b1cdbd2cSJim Jagielski StarBASIC::~StarBASIC()
951*b1cdbd2cSJim Jagielski {
952*b1cdbd2cSJim Jagielski #ifdef DBG_TRACE_BASIC
953*b1cdbd2cSJim Jagielski     lcl_closeTraceFile();
954*b1cdbd2cSJim Jagielski #endif
955*b1cdbd2cSJim Jagielski 
956*b1cdbd2cSJim Jagielski 	// Needs to be first action as it can trigger events
957*b1cdbd2cSJim Jagielski 	disposeComVariablesForBasic( this );
958*b1cdbd2cSJim Jagielski 
959*b1cdbd2cSJim Jagielski 	if( !--GetSbData()->nInst )
960*b1cdbd2cSJim Jagielski 	{
961*b1cdbd2cSJim Jagielski 		RemoveFactory( pSBFAC );
962*b1cdbd2cSJim Jagielski 		delete pSBFAC; pSBFAC = NULL;
963*b1cdbd2cSJim Jagielski 		RemoveFactory( pUNOFAC );
964*b1cdbd2cSJim Jagielski 		delete pUNOFAC; pUNOFAC = NULL;
965*b1cdbd2cSJim Jagielski 		RemoveFactory( pTYPEFAC );
966*b1cdbd2cSJim Jagielski 		delete pTYPEFAC; pTYPEFAC = NULL;
967*b1cdbd2cSJim Jagielski 		RemoveFactory( pCLASSFAC );
968*b1cdbd2cSJim Jagielski 		delete pCLASSFAC; pCLASSFAC = NULL;
969*b1cdbd2cSJim Jagielski 		RemoveFactory( pOLEFAC );
970*b1cdbd2cSJim Jagielski 		delete pOLEFAC; pOLEFAC = NULL;
971*b1cdbd2cSJim Jagielski 		RemoveFactory( pFORMFAC );
972*b1cdbd2cSJim Jagielski 		delete pFORMFAC; pFORMFAC = NULL;
973*b1cdbd2cSJim Jagielski 
974*b1cdbd2cSJim Jagielski #ifdef DBG_UTIL
975*b1cdbd2cSJim Jagielski 	// There is no need to clean SbiData at program end,
976*b1cdbd2cSJim Jagielski 	// but we dislike MLK's at Purify
977*b1cdbd2cSJim Jagielski 	// TODO: Where else???
978*b1cdbd2cSJim Jagielski 	SbiGlobals** pp = (SbiGlobals**) ::GetAppData( SHL_SBC );
979*b1cdbd2cSJim Jagielski 	SbiGlobals* p = *pp;
980*b1cdbd2cSJim Jagielski 	if( p )
981*b1cdbd2cSJim Jagielski 	{
982*b1cdbd2cSJim Jagielski 		delete p;
983*b1cdbd2cSJim Jagielski 		*pp = 0;
984*b1cdbd2cSJim Jagielski 	}
985*b1cdbd2cSJim Jagielski #endif
986*b1cdbd2cSJim Jagielski 	}
987*b1cdbd2cSJim Jagielski 	else if( bDocBasic )
988*b1cdbd2cSJim Jagielski 	{
989*b1cdbd2cSJim Jagielski 	    SbxError eOld = SbxBase::GetError();
990*b1cdbd2cSJim Jagielski 
991*b1cdbd2cSJim Jagielski         lclRemoveDocBasicItem( *this );
992*b1cdbd2cSJim Jagielski 
993*b1cdbd2cSJim Jagielski 		SbxBase::ResetError();
994*b1cdbd2cSJim Jagielski 		if( eOld != SbxERR_OK )
995*b1cdbd2cSJim Jagielski 			SbxBase::SetError( eOld );
996*b1cdbd2cSJim Jagielski 	}
997*b1cdbd2cSJim Jagielski 
998*b1cdbd2cSJim Jagielski     // #100326 Set Parent NULL in registered listeners
999*b1cdbd2cSJim Jagielski     if( xUnoListeners.Is() )
1000*b1cdbd2cSJim Jagielski     {
1001*b1cdbd2cSJim Jagielski         sal_uInt16 uCount = xUnoListeners->Count();
1002*b1cdbd2cSJim Jagielski 	    for( sal_uInt16 i = 0 ; i < uCount ; i++ )
1003*b1cdbd2cSJim Jagielski 	    {
1004*b1cdbd2cSJim Jagielski 		    SbxVariable* pListenerObj = xUnoListeners->Get( i );
1005*b1cdbd2cSJim Jagielski             pListenerObj->SetParent( NULL );
1006*b1cdbd2cSJim Jagielski         }
1007*b1cdbd2cSJim Jagielski         xUnoListeners = NULL;
1008*b1cdbd2cSJim Jagielski     }
1009*b1cdbd2cSJim Jagielski 
1010*b1cdbd2cSJim Jagielski     clearUnoMethodsForBasic( this );
1011*b1cdbd2cSJim Jagielski }
1012*b1cdbd2cSJim Jagielski 
1013*b1cdbd2cSJim Jagielski // Override new() operator, so that everyone can create a new instance
operator new(size_t n)1014*b1cdbd2cSJim Jagielski void* StarBASIC::operator new( size_t n )
1015*b1cdbd2cSJim Jagielski {
1016*b1cdbd2cSJim Jagielski 	if( n < sizeof( StarBASIC ) )
1017*b1cdbd2cSJim Jagielski 	{
1018*b1cdbd2cSJim Jagielski //		DBG_ASSERT( sal_False, "Warnung: inkompatibler BASIC-Stand!" );
1019*b1cdbd2cSJim Jagielski 		n = sizeof( StarBASIC );
1020*b1cdbd2cSJim Jagielski 	}
1021*b1cdbd2cSJim Jagielski 	return ::operator new( n );
1022*b1cdbd2cSJim Jagielski }
1023*b1cdbd2cSJim Jagielski 
operator delete(void * p)1024*b1cdbd2cSJim Jagielski void StarBASIC::operator delete( void* p )
1025*b1cdbd2cSJim Jagielski {
1026*b1cdbd2cSJim Jagielski 	::operator delete( p );
1027*b1cdbd2cSJim Jagielski }
1028*b1cdbd2cSJim Jagielski 
implClearDependingVarsOnDelete(StarBASIC * pDeletedBasic)1029*b1cdbd2cSJim Jagielski void StarBASIC::implClearDependingVarsOnDelete( StarBASIC* pDeletedBasic )
1030*b1cdbd2cSJim Jagielski {
1031*b1cdbd2cSJim Jagielski 	if( this != pDeletedBasic )
1032*b1cdbd2cSJim Jagielski 	{
1033*b1cdbd2cSJim Jagielski 		for( sal_uInt16 i = 0; i < pModules->Count(); i++ )
1034*b1cdbd2cSJim Jagielski 		{
1035*b1cdbd2cSJim Jagielski 			SbModule* p = (SbModule*)pModules->Get( i );
1036*b1cdbd2cSJim Jagielski 			p->ClearVarsDependingOnDeletedBasic( pDeletedBasic );
1037*b1cdbd2cSJim Jagielski 		}
1038*b1cdbd2cSJim Jagielski 	}
1039*b1cdbd2cSJim Jagielski 
1040*b1cdbd2cSJim Jagielski 	for( sal_uInt16 nObj = 0; nObj < pObjs->Count(); nObj++ )
1041*b1cdbd2cSJim Jagielski 	{
1042*b1cdbd2cSJim Jagielski 		SbxVariable* pVar = pObjs->Get( nObj );
1043*b1cdbd2cSJim Jagielski 		StarBASIC* pBasic = PTR_CAST(StarBASIC,pVar);
1044*b1cdbd2cSJim Jagielski 		if( pBasic && pBasic != pDeletedBasic )
1045*b1cdbd2cSJim Jagielski 			pBasic->implClearDependingVarsOnDelete( pDeletedBasic );
1046*b1cdbd2cSJim Jagielski 	}
1047*b1cdbd2cSJim Jagielski }
1048*b1cdbd2cSJim Jagielski 
1049*b1cdbd2cSJim Jagielski 
1050*b1cdbd2cSJim Jagielski /**************************************************************************
1051*b1cdbd2cSJim Jagielski *
1052*b1cdbd2cSJim Jagielski *    Creation/Managment of modules
1053*b1cdbd2cSJim Jagielski *
1054*b1cdbd2cSJim Jagielski **************************************************************************/
1055*b1cdbd2cSJim Jagielski 
MakeModule(const String & rName,const String & rSrc)1056*b1cdbd2cSJim Jagielski SbModule* StarBASIC::MakeModule( const String& rName, const String& rSrc )
1057*b1cdbd2cSJim Jagielski {
1058*b1cdbd2cSJim Jagielski 	return MakeModule32( rName, rSrc );
1059*b1cdbd2cSJim Jagielski }
1060*b1cdbd2cSJim Jagielski 
MakeModule32(const String & rName,const::rtl::OUString & rSrc)1061*b1cdbd2cSJim Jagielski SbModule* StarBASIC::MakeModule32( const String& rName, const ::rtl::OUString& rSrc )
1062*b1cdbd2cSJim Jagielski {
1063*b1cdbd2cSJim Jagielski     ModuleInfo mInfo;
1064*b1cdbd2cSJim Jagielski     mInfo.ModuleType = ModuleType::NORMAL;
1065*b1cdbd2cSJim Jagielski     return MakeModule32(  rName, mInfo, rSrc );
1066*b1cdbd2cSJim Jagielski }
MakeModule32(const String & rName,const ModuleInfo & mInfo,const rtl::OUString & rSrc)1067*b1cdbd2cSJim Jagielski SbModule* StarBASIC::MakeModule32( const String& rName, const ModuleInfo& mInfo, const rtl::OUString& rSrc )
1068*b1cdbd2cSJim Jagielski {
1069*b1cdbd2cSJim Jagielski 
1070*b1cdbd2cSJim Jagielski     OSL_TRACE("create module %s type mInfo %d", rtl::OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr(), mInfo.ModuleType );
1071*b1cdbd2cSJim Jagielski     SbModule* p = NULL;
1072*b1cdbd2cSJim Jagielski     switch ( mInfo.ModuleType )
1073*b1cdbd2cSJim Jagielski     {
1074*b1cdbd2cSJim Jagielski         case ModuleType::DOCUMENT:
1075*b1cdbd2cSJim Jagielski             // In theory we should be able to create Object modules
1076*b1cdbd2cSJim Jagielski             // in ordinary basic ( in vba mode thought these are create
1077*b1cdbd2cSJim Jagielski             // by the application/basic and not by the user )
1078*b1cdbd2cSJim Jagielski             p = new SbObjModule( rName, mInfo, isVBAEnabled() );
1079*b1cdbd2cSJim Jagielski             break;
1080*b1cdbd2cSJim Jagielski         case ModuleType::CLASS:
1081*b1cdbd2cSJim Jagielski             p = new SbModule( rName, isVBAEnabled() );
1082*b1cdbd2cSJim Jagielski 			p->SetModuleType( ModuleType::CLASS );
1083*b1cdbd2cSJim Jagielski 	    break;
1084*b1cdbd2cSJim Jagielski         case ModuleType::FORM:
1085*b1cdbd2cSJim Jagielski             p = new SbUserFormModule( rName, mInfo, isVBAEnabled() );
1086*b1cdbd2cSJim Jagielski 	    break;
1087*b1cdbd2cSJim Jagielski         default:
1088*b1cdbd2cSJim Jagielski             p = new SbModule( rName, isVBAEnabled() );
1089*b1cdbd2cSJim Jagielski 
1090*b1cdbd2cSJim Jagielski     }
1091*b1cdbd2cSJim Jagielski 	p->SetSource32( rSrc );
1092*b1cdbd2cSJim Jagielski 	p->SetParent( this );
1093*b1cdbd2cSJim Jagielski 	pModules->Insert( p, pModules->Count() );
1094*b1cdbd2cSJim Jagielski 	SetModified( sal_True );
1095*b1cdbd2cSJim Jagielski 	return p;
1096*b1cdbd2cSJim Jagielski }
1097*b1cdbd2cSJim Jagielski 
Insert(SbxVariable * pVar)1098*b1cdbd2cSJim Jagielski void StarBASIC::Insert( SbxVariable* pVar )
1099*b1cdbd2cSJim Jagielski {
1100*b1cdbd2cSJim Jagielski 	if( pVar->IsA( TYPE(SbModule) ) )
1101*b1cdbd2cSJim Jagielski 	{
1102*b1cdbd2cSJim Jagielski 		pModules->Insert( pVar, pModules->Count() );
1103*b1cdbd2cSJim Jagielski 		pVar->SetParent( this );
1104*b1cdbd2cSJim Jagielski 		StartListening( pVar->GetBroadcaster(), sal_True );
1105*b1cdbd2cSJim Jagielski 	}
1106*b1cdbd2cSJim Jagielski 	else
1107*b1cdbd2cSJim Jagielski 	{
1108*b1cdbd2cSJim Jagielski 		sal_Bool bWasModified = IsModified();
1109*b1cdbd2cSJim Jagielski 		SbxObject::Insert( pVar );
1110*b1cdbd2cSJim Jagielski 		if( !bWasModified && pVar->IsSet( SBX_DONTSTORE ) )
1111*b1cdbd2cSJim Jagielski 			SetModified( sal_False );
1112*b1cdbd2cSJim Jagielski 	}
1113*b1cdbd2cSJim Jagielski }
1114*b1cdbd2cSJim Jagielski 
Remove(SbxVariable * pVar)1115*b1cdbd2cSJim Jagielski void StarBASIC::Remove( SbxVariable* pVar )
1116*b1cdbd2cSJim Jagielski {
1117*b1cdbd2cSJim Jagielski 	if( pVar->IsA( TYPE(SbModule) ) )
1118*b1cdbd2cSJim Jagielski 	{
1119*b1cdbd2cSJim Jagielski         // #87540 Can be last reference!
1120*b1cdbd2cSJim Jagielski         SbxVariableRef xVar = pVar;
1121*b1cdbd2cSJim Jagielski 		pModules->Remove( pVar );
1122*b1cdbd2cSJim Jagielski 		pVar->SetParent( 0 );
1123*b1cdbd2cSJim Jagielski 		EndListening( pVar->GetBroadcaster() );
1124*b1cdbd2cSJim Jagielski 	}
1125*b1cdbd2cSJim Jagielski 	else
1126*b1cdbd2cSJim Jagielski 		SbxObject::Remove( pVar );
1127*b1cdbd2cSJim Jagielski }
1128*b1cdbd2cSJim Jagielski 
Compile(SbModule * pMod)1129*b1cdbd2cSJim Jagielski sal_Bool StarBASIC::Compile( SbModule* pMod )
1130*b1cdbd2cSJim Jagielski {
1131*b1cdbd2cSJim Jagielski 	return pMod ? pMod->Compile() : sal_False;
1132*b1cdbd2cSJim Jagielski }
1133*b1cdbd2cSJim Jagielski 
Disassemble(SbModule * pMod,String & rText)1134*b1cdbd2cSJim Jagielski sal_Bool StarBASIC::Disassemble( SbModule* pMod, String& rText )
1135*b1cdbd2cSJim Jagielski {
1136*b1cdbd2cSJim Jagielski 	rText.Erase();
1137*b1cdbd2cSJim Jagielski 	if( pMod )
1138*b1cdbd2cSJim Jagielski 		pMod->Disassemble( rText );
1139*b1cdbd2cSJim Jagielski 	return sal_Bool( rText.Len() != 0 );
1140*b1cdbd2cSJim Jagielski }
1141*b1cdbd2cSJim Jagielski 
Clear()1142*b1cdbd2cSJim Jagielski void StarBASIC::Clear()
1143*b1cdbd2cSJim Jagielski {
1144*b1cdbd2cSJim Jagielski 	while( pModules->Count() )
1145*b1cdbd2cSJim Jagielski 		pModules->Remove( pModules->Count() - 1 );
1146*b1cdbd2cSJim Jagielski }
1147*b1cdbd2cSJim Jagielski 
FindModule(const String & rName)1148*b1cdbd2cSJim Jagielski SbModule* StarBASIC::FindModule( const String& rName )
1149*b1cdbd2cSJim Jagielski {
1150*b1cdbd2cSJim Jagielski 	for( sal_uInt16 i = 0; i < pModules->Count(); i++ )
1151*b1cdbd2cSJim Jagielski 	{
1152*b1cdbd2cSJim Jagielski 		SbModule* p = (SbModule*) pModules->Get( i );
1153*b1cdbd2cSJim Jagielski 		if( p->GetName().EqualsIgnoreCaseAscii( rName ) )
1154*b1cdbd2cSJim Jagielski 			return p;
1155*b1cdbd2cSJim Jagielski 	}
1156*b1cdbd2cSJim Jagielski 	return NULL;
1157*b1cdbd2cSJim Jagielski }
1158*b1cdbd2cSJim Jagielski 
1159*b1cdbd2cSJim Jagielski 
1160*b1cdbd2cSJim Jagielski struct ClassModuleRunInitItem
1161*b1cdbd2cSJim Jagielski {
1162*b1cdbd2cSJim Jagielski 	SbModule*		m_pModule;
1163*b1cdbd2cSJim Jagielski 	bool			m_bProcessing;
1164*b1cdbd2cSJim Jagielski 	bool			m_bRunInitDone;
1165*b1cdbd2cSJim Jagielski 	//ModuleVector	m_vModulesDependingOnThisModule;
1166*b1cdbd2cSJim Jagielski 
ClassModuleRunInitItemClassModuleRunInitItem1167*b1cdbd2cSJim Jagielski 	ClassModuleRunInitItem( void )
1168*b1cdbd2cSJim Jagielski 		: m_pModule( NULL )
1169*b1cdbd2cSJim Jagielski 		, m_bProcessing( false )
1170*b1cdbd2cSJim Jagielski 		, m_bRunInitDone( false )
1171*b1cdbd2cSJim Jagielski 	{}
ClassModuleRunInitItemClassModuleRunInitItem1172*b1cdbd2cSJim Jagielski 	ClassModuleRunInitItem( SbModule* pModule )
1173*b1cdbd2cSJim Jagielski 		: m_pModule( pModule )
1174*b1cdbd2cSJim Jagielski 		, m_bProcessing( false )
1175*b1cdbd2cSJim Jagielski 		, m_bRunInitDone( false )
1176*b1cdbd2cSJim Jagielski 	{}
1177*b1cdbd2cSJim Jagielski };
1178*b1cdbd2cSJim Jagielski 
1179*b1cdbd2cSJim Jagielski // Derive from has_map type instead of typedef
1180*b1cdbd2cSJim Jagielski // to allow forward declaration in sbmod.hxx
1181*b1cdbd2cSJim Jagielski class ModuleInitDependencyMap : public
1182*b1cdbd2cSJim Jagielski 	std::hash_map< ::rtl::OUString, ClassModuleRunInitItem,
1183*b1cdbd2cSJim Jagielski 		::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > >
1184*b1cdbd2cSJim Jagielski {};
1185*b1cdbd2cSJim Jagielski 
implProcessModuleRunInit(ModuleInitDependencyMap & rMap,ClassModuleRunInitItem & rItem)1186*b1cdbd2cSJim Jagielski void SbModule::implProcessModuleRunInit( ModuleInitDependencyMap& rMap, ClassModuleRunInitItem& rItem )
1187*b1cdbd2cSJim Jagielski {
1188*b1cdbd2cSJim Jagielski 	rItem.m_bProcessing = true;
1189*b1cdbd2cSJim Jagielski 
1190*b1cdbd2cSJim Jagielski 	//bool bAnyDependencies = true;
1191*b1cdbd2cSJim Jagielski 	SbModule* pModule = rItem.m_pModule;
1192*b1cdbd2cSJim Jagielski 	if( pModule->pClassData != NULL )
1193*b1cdbd2cSJim Jagielski 	{
1194*b1cdbd2cSJim Jagielski 		StringVector& rReqTypes = pModule->pClassData->maRequiredTypes;
1195*b1cdbd2cSJim Jagielski 		if( rReqTypes.size() > 0 )
1196*b1cdbd2cSJim Jagielski 		{
1197*b1cdbd2cSJim Jagielski 			for( StringVector::iterator it = rReqTypes.begin() ; it != rReqTypes.end() ; ++it )
1198*b1cdbd2cSJim Jagielski 			{
1199*b1cdbd2cSJim Jagielski 				String& rStr = *it;
1200*b1cdbd2cSJim Jagielski 
1201*b1cdbd2cSJim Jagielski 				// Is required type a class module?
1202*b1cdbd2cSJim Jagielski 				ModuleInitDependencyMap::iterator itFind = rMap.find( rStr );
1203*b1cdbd2cSJim Jagielski 				if( itFind != rMap.end() )
1204*b1cdbd2cSJim Jagielski 				{
1205*b1cdbd2cSJim Jagielski 					ClassModuleRunInitItem& rParentItem = itFind->second;
1206*b1cdbd2cSJim Jagielski 					if( rParentItem.m_bProcessing )
1207*b1cdbd2cSJim Jagielski 					{
1208*b1cdbd2cSJim Jagielski 						// TODO: raise error?
1209*b1cdbd2cSJim Jagielski 						DBG_ERROR( "Cyclic module dependency detected" );
1210*b1cdbd2cSJim Jagielski 						continue;
1211*b1cdbd2cSJim Jagielski 					}
1212*b1cdbd2cSJim Jagielski 
1213*b1cdbd2cSJim Jagielski 					if( !rParentItem.m_bRunInitDone )
1214*b1cdbd2cSJim Jagielski 						implProcessModuleRunInit( rMap, rParentItem );
1215*b1cdbd2cSJim Jagielski 				}
1216*b1cdbd2cSJim Jagielski 			}
1217*b1cdbd2cSJim Jagielski 		}
1218*b1cdbd2cSJim Jagielski 	}
1219*b1cdbd2cSJim Jagielski 
1220*b1cdbd2cSJim Jagielski 	pModule->RunInit();
1221*b1cdbd2cSJim Jagielski 	rItem.m_bRunInitDone = true;
1222*b1cdbd2cSJim Jagielski 	rItem.m_bProcessing = false;
1223*b1cdbd2cSJim Jagielski }
1224*b1cdbd2cSJim Jagielski 
1225*b1cdbd2cSJim Jagielski // Run Init-Code of all modules (including inserted libraries)
InitAllModules(StarBASIC * pBasicNotToInit)1226*b1cdbd2cSJim Jagielski void StarBASIC::InitAllModules( StarBASIC* pBasicNotToInit )
1227*b1cdbd2cSJim Jagielski {
1228*b1cdbd2cSJim Jagielski 	::vos::OGuard guard( Application::GetSolarMutex() );
1229*b1cdbd2cSJim Jagielski 
1230*b1cdbd2cSJim Jagielski     // Init own modules
1231*b1cdbd2cSJim Jagielski 	for ( sal_uInt16 nMod = 0; nMod < pModules->Count(); nMod++ )
1232*b1cdbd2cSJim Jagielski 	{
1233*b1cdbd2cSJim Jagielski 		SbModule* pModule = (SbModule*)pModules->Get( nMod );
1234*b1cdbd2cSJim Jagielski 		if(	!pModule->IsCompiled() )
1235*b1cdbd2cSJim Jagielski 			pModule->Compile();
1236*b1cdbd2cSJim Jagielski 	}
1237*b1cdbd2cSJim Jagielski 	// compile modules first then RunInit ( otherwise there is
1238*b1cdbd2cSJim Jagielski 	// can be order dependency, e.g. classmodule A has a member
1239*b1cdbd2cSJim Jagielski 	// of of type classmodule B and classmodule B hasn't been compiled yet )
1240*b1cdbd2cSJim Jagielski 
1241*b1cdbd2cSJim Jagielski 	// Consider required types to init in right order. Class modules
1242*b1cdbd2cSJim Jagielski 	// that are required by other modules have to be initialized first.
1243*b1cdbd2cSJim Jagielski 	ModuleInitDependencyMap aMIDMap;
1244*b1cdbd2cSJim Jagielski 	for ( sal_uInt16 nMod = 0; nMod < pModules->Count(); nMod++ )
1245*b1cdbd2cSJim Jagielski 	{
1246*b1cdbd2cSJim Jagielski 		SbModule* pModule = (SbModule*)pModules->Get( nMod );
1247*b1cdbd2cSJim Jagielski 		String aModuleName = pModule->GetName();
1248*b1cdbd2cSJim Jagielski 		if( pModule->isProxyModule() )
1249*b1cdbd2cSJim Jagielski 			aMIDMap[aModuleName] = ClassModuleRunInitItem( pModule );
1250*b1cdbd2cSJim Jagielski 	}
1251*b1cdbd2cSJim Jagielski 
1252*b1cdbd2cSJim Jagielski 	ModuleInitDependencyMap::iterator it;
1253*b1cdbd2cSJim Jagielski 	for( it = aMIDMap.begin() ; it != aMIDMap.end(); ++it )
1254*b1cdbd2cSJim Jagielski 	{
1255*b1cdbd2cSJim Jagielski 		ClassModuleRunInitItem& rItem = it->second;
1256*b1cdbd2cSJim Jagielski 		SbModule::implProcessModuleRunInit( aMIDMap, rItem );
1257*b1cdbd2cSJim Jagielski 	}
1258*b1cdbd2cSJim Jagielski 
1259*b1cdbd2cSJim Jagielski 	// Call RunInit on standard modules
1260*b1cdbd2cSJim Jagielski 	for ( sal_uInt16 nMod = 0; nMod < pModules->Count(); nMod++ )
1261*b1cdbd2cSJim Jagielski 	{
1262*b1cdbd2cSJim Jagielski 		SbModule* pModule = (SbModule*)pModules->Get( nMod );
1263*b1cdbd2cSJim Jagielski 		if( !pModule->isProxyModule() )
1264*b1cdbd2cSJim Jagielski 			pModule->RunInit();
1265*b1cdbd2cSJim Jagielski 	}
1266*b1cdbd2cSJim Jagielski 
1267*b1cdbd2cSJim Jagielski     // Check all objects if they are BASIC,
1268*b1cdbd2cSJim Jagielski     // if yes initialize
1269*b1cdbd2cSJim Jagielski 	for ( sal_uInt16 nObj = 0; nObj < pObjs->Count(); nObj++ )
1270*b1cdbd2cSJim Jagielski 	{
1271*b1cdbd2cSJim Jagielski 		SbxVariable* pVar = pObjs->Get( nObj );
1272*b1cdbd2cSJim Jagielski 		StarBASIC* pBasic = PTR_CAST(StarBASIC,pVar);
1273*b1cdbd2cSJim Jagielski 		if( pBasic && pBasic != pBasicNotToInit )
1274*b1cdbd2cSJim Jagielski 			pBasic->InitAllModules();
1275*b1cdbd2cSJim Jagielski 	}
1276*b1cdbd2cSJim Jagielski }
1277*b1cdbd2cSJim Jagielski 
1278*b1cdbd2cSJim Jagielski // #88329 Put modules back to not initialised state to
1279*b1cdbd2cSJim Jagielski // force reinitialisation at next start
DeInitAllModules(void)1280*b1cdbd2cSJim Jagielski void StarBASIC::DeInitAllModules( void )
1281*b1cdbd2cSJim Jagielski {
1282*b1cdbd2cSJim Jagielski     // Deinit own modules
1283*b1cdbd2cSJim Jagielski 	for ( sal_uInt16 nMod = 0; nMod < pModules->Count(); nMod++ )
1284*b1cdbd2cSJim Jagielski 	{
1285*b1cdbd2cSJim Jagielski 		SbModule* pModule = (SbModule*)pModules->Get( nMod );
1286*b1cdbd2cSJim Jagielski         if( pModule->pImage && !pModule->isProxyModule() && !pModule->ISA(SbObjModule) )
1287*b1cdbd2cSJim Jagielski 		    pModule->pImage->bInit = false;
1288*b1cdbd2cSJim Jagielski 	}
1289*b1cdbd2cSJim Jagielski 
1290*b1cdbd2cSJim Jagielski 	for ( sal_uInt16 nObj = 0; nObj < pObjs->Count(); nObj++ )
1291*b1cdbd2cSJim Jagielski 	{
1292*b1cdbd2cSJim Jagielski 		SbxVariable* pVar = pObjs->Get( nObj );
1293*b1cdbd2cSJim Jagielski 		StarBASIC* pBasic = PTR_CAST(StarBASIC,pVar);
1294*b1cdbd2cSJim Jagielski 		if( pBasic )
1295*b1cdbd2cSJim Jagielski 			pBasic->DeInitAllModules();
1296*b1cdbd2cSJim Jagielski 	}
1297*b1cdbd2cSJim Jagielski }
1298*b1cdbd2cSJim Jagielski 
1299*b1cdbd2cSJim Jagielski // #43011 For TestTool, to delete global vars
ClearGlobalVars(void)1300*b1cdbd2cSJim Jagielski void StarBASIC::ClearGlobalVars( void )
1301*b1cdbd2cSJim Jagielski {
1302*b1cdbd2cSJim Jagielski 	SbxArrayRef xProps( GetProperties() );
1303*b1cdbd2cSJim Jagielski 	sal_uInt16 nPropCount = xProps->Count();
1304*b1cdbd2cSJim Jagielski 	for ( sal_uInt16 nProp = 0 ; nProp < nPropCount ; ++nProp )
1305*b1cdbd2cSJim Jagielski 	{
1306*b1cdbd2cSJim Jagielski 		SbxBase* pVar = xProps->Get( nProp );
1307*b1cdbd2cSJim Jagielski 		pVar->Clear();
1308*b1cdbd2cSJim Jagielski 	}
1309*b1cdbd2cSJim Jagielski 	SetModified( sal_True );
1310*b1cdbd2cSJim Jagielski }
1311*b1cdbd2cSJim Jagielski 
1312*b1cdbd2cSJim Jagielski // This implementation at first searches within the runtime library,
1313*b1cdbd2cSJim Jagielski // then it looks for an element within one module. This moudle can be
1314*b1cdbd2cSJim Jagielski // a public var or an entrypoint. If it is not found and we look for a
1315*b1cdbd2cSJim Jagielski // method and a module with the given name is found the search continues
1316*b1cdbd2cSJim Jagielski // for entrypoint "Main".
1317*b1cdbd2cSJim Jagielski // If this fails again a conventional search over objects is performend.
Find(const String & rName,SbxClassType t)1318*b1cdbd2cSJim Jagielski SbxVariable* StarBASIC::Find( const String& rName, SbxClassType t )
1319*b1cdbd2cSJim Jagielski {
1320*b1cdbd2cSJim Jagielski 	static String aMainStr( RTL_CONSTASCII_USTRINGPARAM("Main") );
1321*b1cdbd2cSJim Jagielski 
1322*b1cdbd2cSJim Jagielski 	SbxVariable* pRes = NULL;
1323*b1cdbd2cSJim Jagielski 	SbModule* pNamed = NULL;
1324*b1cdbd2cSJim Jagielski 	// "Extended" search in Runtime Lib
1325*b1cdbd2cSJim Jagielski 	// but only if SbiRuntime has not set the flag
1326*b1cdbd2cSJim Jagielski 	if( !bNoRtl )
1327*b1cdbd2cSJim Jagielski 	{
1328*b1cdbd2cSJim Jagielski 		if( t == SbxCLASS_DONTCARE || t == SbxCLASS_OBJECT )
1329*b1cdbd2cSJim Jagielski 		{
1330*b1cdbd2cSJim Jagielski 			if( rName.EqualsIgnoreCaseAscii( RTLNAME ) )
1331*b1cdbd2cSJim Jagielski 				pRes = pRtl;
1332*b1cdbd2cSJim Jagielski 		}
1333*b1cdbd2cSJim Jagielski 		if( !pRes )
1334*b1cdbd2cSJim Jagielski 			pRes = ((SbiStdObject*) (SbxObject*) pRtl)->Find( rName, t );
1335*b1cdbd2cSJim Jagielski 		if( pRes )
1336*b1cdbd2cSJim Jagielski 			pRes->SetFlag( SBX_EXTFOUND );
1337*b1cdbd2cSJim Jagielski 	}
1338*b1cdbd2cSJim Jagielski 	// Search module
1339*b1cdbd2cSJim Jagielski 	if( !pRes )
1340*b1cdbd2cSJim Jagielski 	  for( sal_uInt16 i = 0; i < pModules->Count(); i++ )
1341*b1cdbd2cSJim Jagielski 	{
1342*b1cdbd2cSJim Jagielski 		SbModule* p = (SbModule*) pModules->Get( i );
1343*b1cdbd2cSJim Jagielski 		if( p->IsVisible() )
1344*b1cdbd2cSJim Jagielski 		{
1345*b1cdbd2cSJim Jagielski 			// Remember modul fpr Main() call
1346*b1cdbd2cSJim Jagielski 			// or is the name equal?!?
1347*b1cdbd2cSJim Jagielski 			if( p->GetName().EqualsIgnoreCaseAscii( rName ) )
1348*b1cdbd2cSJim Jagielski 			{
1349*b1cdbd2cSJim Jagielski 				if( t == SbxCLASS_OBJECT || t == SbxCLASS_DONTCARE )
1350*b1cdbd2cSJim Jagielski 				{
1351*b1cdbd2cSJim Jagielski 					pRes = p; break;
1352*b1cdbd2cSJim Jagielski 				}
1353*b1cdbd2cSJim Jagielski 				pNamed = p;
1354*b1cdbd2cSJim Jagielski 			}
1355*b1cdbd2cSJim Jagielski 			// Only variables qualified by the Module Name e.g. Sheet1.foo
1356*b1cdbd2cSJim Jagielski 			// should work for Documant && Class type Modules
1357*b1cdbd2cSJim Jagielski 			sal_Int32 nType = p->GetModuleType();
1358*b1cdbd2cSJim Jagielski 			if ( nType == ModuleType::DOCUMENT || nType == ModuleType::FORM )
1359*b1cdbd2cSJim Jagielski 				continue;
1360*b1cdbd2cSJim Jagielski 
1361*b1cdbd2cSJim Jagielski 			// otherwise check if the element is available
1362*b1cdbd2cSJim Jagielski 			// unset GBLSEARCH-Flag (due to Rekursion)
1363*b1cdbd2cSJim Jagielski 			sal_uInt16 nGblFlag = p->GetFlags() & SBX_GBLSEARCH;
1364*b1cdbd2cSJim Jagielski 			p->ResetFlag( SBX_GBLSEARCH );
1365*b1cdbd2cSJim Jagielski 			pRes = p->Find( rName, t );
1366*b1cdbd2cSJim Jagielski 			p->SetFlag( nGblFlag );
1367*b1cdbd2cSJim Jagielski 			if( pRes )
1368*b1cdbd2cSJim Jagielski 				break;
1369*b1cdbd2cSJim Jagielski 		}
1370*b1cdbd2cSJim Jagielski 	}
1371*b1cdbd2cSJim Jagielski 	if( !pRes && pNamed && ( t == SbxCLASS_METHOD || t == SbxCLASS_DONTCARE ) &&
1372*b1cdbd2cSJim Jagielski 		!pNamed->GetName().EqualsIgnoreCaseAscii( aMainStr ) )
1373*b1cdbd2cSJim Jagielski 			pRes = pNamed->Find( aMainStr, SbxCLASS_METHOD );
1374*b1cdbd2cSJim Jagielski 	if( !pRes )
1375*b1cdbd2cSJim Jagielski 		pRes = SbxObject::Find( rName, t );
1376*b1cdbd2cSJim Jagielski 	return pRes;
1377*b1cdbd2cSJim Jagielski }
1378*b1cdbd2cSJim Jagielski 
Call(const String & rName,SbxArray * pParam)1379*b1cdbd2cSJim Jagielski sal_Bool StarBASIC::Call( const String& rName, SbxArray* pParam )
1380*b1cdbd2cSJim Jagielski {
1381*b1cdbd2cSJim Jagielski 	sal_Bool bRes = SbxObject::Call( rName, pParam );
1382*b1cdbd2cSJim Jagielski 	if( !bRes )
1383*b1cdbd2cSJim Jagielski 	{
1384*b1cdbd2cSJim Jagielski 		SbxError eErr = SbxBase::GetError();
1385*b1cdbd2cSJim Jagielski 		SbxBase::ResetError();
1386*b1cdbd2cSJim Jagielski 		if( eErr != SbxERR_OK )
1387*b1cdbd2cSJim Jagielski 			RTError( (SbError)eErr, 0, 0, 0 );
1388*b1cdbd2cSJim Jagielski 	}
1389*b1cdbd2cSJim Jagielski 	return bRes;
1390*b1cdbd2cSJim Jagielski }
1391*b1cdbd2cSJim Jagielski 
1392*b1cdbd2cSJim Jagielski // Find method via name (e.g. query via BASIC IDE)
FindSBXInCurrentScope(const String & rName)1393*b1cdbd2cSJim Jagielski SbxBase* StarBASIC::FindSBXInCurrentScope( const String& rName )
1394*b1cdbd2cSJim Jagielski {
1395*b1cdbd2cSJim Jagielski 	if( !pINST )
1396*b1cdbd2cSJim Jagielski 		return NULL;
1397*b1cdbd2cSJim Jagielski 	if( !pINST->pRun )
1398*b1cdbd2cSJim Jagielski 		return NULL;
1399*b1cdbd2cSJim Jagielski 	return pINST->pRun->FindElementExtern( rName );
1400*b1cdbd2cSJim Jagielski }
1401*b1cdbd2cSJim Jagielski 
1402*b1cdbd2cSJim Jagielski // Preserve old interface
FindVarInCurrentScopy(const String & rName,sal_uInt16 & rStatus)1403*b1cdbd2cSJim Jagielski SbxVariable* StarBASIC::FindVarInCurrentScopy
1404*b1cdbd2cSJim Jagielski ( const String& rName, sal_uInt16& rStatus )
1405*b1cdbd2cSJim Jagielski {
1406*b1cdbd2cSJim Jagielski 	rStatus = 1;              // Presumption: nothing found
1407*b1cdbd2cSJim Jagielski 	SbxVariable* pVar = NULL;
1408*b1cdbd2cSJim Jagielski 	SbxBase* pSbx = FindSBXInCurrentScope( rName );
1409*b1cdbd2cSJim Jagielski 	if( pSbx )
1410*b1cdbd2cSJim Jagielski 	{
1411*b1cdbd2cSJim Jagielski 		if( !pSbx->ISA(SbxMethod) && !pSbx->ISA(SbxObject) )
1412*b1cdbd2cSJim Jagielski 			pVar = PTR_CAST(SbxVariable,pSbx);
1413*b1cdbd2cSJim Jagielski 	}
1414*b1cdbd2cSJim Jagielski 	if( pVar )
1415*b1cdbd2cSJim Jagielski 		rStatus = 0;      // We found something
1416*b1cdbd2cSJim Jagielski 	return pVar;
1417*b1cdbd2cSJim Jagielski }
1418*b1cdbd2cSJim Jagielski 
QuitAndExitApplication()1419*b1cdbd2cSJim Jagielski void StarBASIC::QuitAndExitApplication()
1420*b1cdbd2cSJim Jagielski {
1421*b1cdbd2cSJim Jagielski     Stop();
1422*b1cdbd2cSJim Jagielski     bQuit = sal_True;
1423*b1cdbd2cSJim Jagielski }
1424*b1cdbd2cSJim Jagielski 
Stop()1425*b1cdbd2cSJim Jagielski void StarBASIC::Stop()
1426*b1cdbd2cSJim Jagielski {
1427*b1cdbd2cSJim Jagielski 	SbiInstance* p = pINST;
1428*b1cdbd2cSJim Jagielski 	while( p )
1429*b1cdbd2cSJim Jagielski 	{
1430*b1cdbd2cSJim Jagielski 		p->Stop();
1431*b1cdbd2cSJim Jagielski 		p = p->pNext;
1432*b1cdbd2cSJim Jagielski 	}
1433*b1cdbd2cSJim Jagielski }
1434*b1cdbd2cSJim Jagielski 
IsRunning()1435*b1cdbd2cSJim Jagielski sal_Bool StarBASIC::IsRunning()
1436*b1cdbd2cSJim Jagielski {
1437*b1cdbd2cSJim Jagielski 	return sal_Bool( pINST != NULL );
1438*b1cdbd2cSJim Jagielski }
1439*b1cdbd2cSJim Jagielski 
1440*b1cdbd2cSJim Jagielski /**************************************************************************
1441*b1cdbd2cSJim Jagielski *
1442*b1cdbd2cSJim Jagielski *    Object factories and others
1443*b1cdbd2cSJim Jagielski *
1444*b1cdbd2cSJim Jagielski **************************************************************************/
1445*b1cdbd2cSJim Jagielski 
1446*b1cdbd2cSJim Jagielski // Activation of an object. There is no need to access active objects
1447*b1cdbd2cSJim Jagielski // with name via BASIC. If NULL is given, everything is activated.
ActivateObject(const String * pName,sal_Bool bActivate)1448*b1cdbd2cSJim Jagielski void StarBASIC::ActivateObject( const String* pName, sal_Bool bActivate )
1449*b1cdbd2cSJim Jagielski {
1450*b1cdbd2cSJim Jagielski 	if( pName )
1451*b1cdbd2cSJim Jagielski 	{
1452*b1cdbd2cSJim Jagielski 		SbxObject* p = (SbxObject*) SbxObject::Find( *pName, SbxCLASS_OBJECT );
1453*b1cdbd2cSJim Jagielski 		if( p )
1454*b1cdbd2cSJim Jagielski 		{
1455*b1cdbd2cSJim Jagielski 			if( bActivate )
1456*b1cdbd2cSJim Jagielski 				p->SetFlag( SBX_EXTSEARCH );
1457*b1cdbd2cSJim Jagielski 			else
1458*b1cdbd2cSJim Jagielski 				p->ResetFlag( SBX_EXTSEARCH );
1459*b1cdbd2cSJim Jagielski 		}
1460*b1cdbd2cSJim Jagielski 	}
1461*b1cdbd2cSJim Jagielski 	else
1462*b1cdbd2cSJim Jagielski 	{
1463*b1cdbd2cSJim Jagielski 		for( sal_uInt16 i = 0; i < GetObjects()->Count(); i++ )
1464*b1cdbd2cSJim Jagielski 		{
1465*b1cdbd2cSJim Jagielski 			SbxObject* p = (SbxObject*) GetObjects()->Get( i );
1466*b1cdbd2cSJim Jagielski 			if( bActivate )
1467*b1cdbd2cSJim Jagielski 				p->SetFlag( SBX_EXTSEARCH );
1468*b1cdbd2cSJim Jagielski 			else
1469*b1cdbd2cSJim Jagielski 				p->ResetFlag( SBX_EXTSEARCH );
1470*b1cdbd2cSJim Jagielski 		}
1471*b1cdbd2cSJim Jagielski 	}
1472*b1cdbd2cSJim Jagielski }
1473*b1cdbd2cSJim Jagielski 
1474*b1cdbd2cSJim Jagielski /**************************************************************************
1475*b1cdbd2cSJim Jagielski *
1476*b1cdbd2cSJim Jagielski *    Debugging and error handling
1477*b1cdbd2cSJim Jagielski *
1478*b1cdbd2cSJim Jagielski **************************************************************************/
1479*b1cdbd2cSJim Jagielski 
GetActiveMethod(sal_uInt16 nLevel)1480*b1cdbd2cSJim Jagielski SbMethod* StarBASIC::GetActiveMethod( sal_uInt16 nLevel )
1481*b1cdbd2cSJim Jagielski {
1482*b1cdbd2cSJim Jagielski 	if( pINST )
1483*b1cdbd2cSJim Jagielski 		return pINST->GetCaller( nLevel );
1484*b1cdbd2cSJim Jagielski 	else
1485*b1cdbd2cSJim Jagielski 		return NULL;
1486*b1cdbd2cSJim Jagielski }
1487*b1cdbd2cSJim Jagielski 
GetActiveModule()1488*b1cdbd2cSJim Jagielski SbModule* StarBASIC::GetActiveModule()
1489*b1cdbd2cSJim Jagielski {
1490*b1cdbd2cSJim Jagielski 	if( pINST && !IsCompilerError() )
1491*b1cdbd2cSJim Jagielski 		return pINST->GetActiveModule();
1492*b1cdbd2cSJim Jagielski 	else
1493*b1cdbd2cSJim Jagielski 		return pCMOD;
1494*b1cdbd2cSJim Jagielski }
1495*b1cdbd2cSJim Jagielski 
BreakPoint(sal_uInt16 l,sal_uInt16 c1,sal_uInt16 c2)1496*b1cdbd2cSJim Jagielski sal_uInt16 StarBASIC::BreakPoint( sal_uInt16 l, sal_uInt16 c1, sal_uInt16 c2 )
1497*b1cdbd2cSJim Jagielski {
1498*b1cdbd2cSJim Jagielski 	SetErrorData( 0, l, c1, c2 );
1499*b1cdbd2cSJim Jagielski 	bBreak = sal_True;
1500*b1cdbd2cSJim Jagielski 	if( GetSbData()->aBreakHdl.IsSet() )
1501*b1cdbd2cSJim Jagielski 		return (sal_uInt16) GetSbData()->aBreakHdl.Call( this );
1502*b1cdbd2cSJim Jagielski 	else
1503*b1cdbd2cSJim Jagielski 		return BreakHdl();
1504*b1cdbd2cSJim Jagielski }
1505*b1cdbd2cSJim Jagielski 
StepPoint(sal_uInt16 l,sal_uInt16 c1,sal_uInt16 c2)1506*b1cdbd2cSJim Jagielski sal_uInt16 StarBASIC::StepPoint( sal_uInt16 l, sal_uInt16 c1, sal_uInt16 c2 )
1507*b1cdbd2cSJim Jagielski {
1508*b1cdbd2cSJim Jagielski 	SetErrorData( 0, l, c1, c2 );
1509*b1cdbd2cSJim Jagielski 	bBreak = sal_False;
1510*b1cdbd2cSJim Jagielski 	if( GetSbData()->aBreakHdl.IsSet() )
1511*b1cdbd2cSJim Jagielski 		return (sal_uInt16) GetSbData()->aBreakHdl.Call( this );
1512*b1cdbd2cSJim Jagielski 	else
1513*b1cdbd2cSJim Jagielski 		return BreakHdl();
1514*b1cdbd2cSJim Jagielski }
1515*b1cdbd2cSJim Jagielski 
BreakHdl()1516*b1cdbd2cSJim Jagielski sal_uInt16 __EXPORT StarBASIC::BreakHdl()
1517*b1cdbd2cSJim Jagielski {
1518*b1cdbd2cSJim Jagielski 	return (sal_uInt16) ( aBreakHdl.IsSet()
1519*b1cdbd2cSJim Jagielski 		? aBreakHdl.Call( this ) : SbDEBUG_CONTINUE );
1520*b1cdbd2cSJim Jagielski }
1521*b1cdbd2cSJim Jagielski 
1522*b1cdbd2cSJim Jagielski // Calls for error handler and break handler
GetLine()1523*b1cdbd2cSJim Jagielski sal_uInt16 StarBASIC::GetLine()		{ return GetSbData()->nLine; }
GetCol1()1524*b1cdbd2cSJim Jagielski sal_uInt16 StarBASIC::GetCol1()		{ return GetSbData()->nCol1; }
GetCol2()1525*b1cdbd2cSJim Jagielski sal_uInt16 StarBASIC::GetCol2()		{ return GetSbData()->nCol2; }
1526*b1cdbd2cSJim Jagielski 
1527*b1cdbd2cSJim Jagielski // Specific to error handler
GetErrorCode()1528*b1cdbd2cSJim Jagielski SbError StarBASIC::GetErrorCode()		{ return GetSbData()->nCode; }
GetErrorText()1529*b1cdbd2cSJim Jagielski const String& StarBASIC::GetErrorText()	{ return GetSbData()->aErrMsg; }
IsCompilerError()1530*b1cdbd2cSJim Jagielski sal_Bool StarBASIC::IsCompilerError()		{ return GetSbData()->bCompiler; }
SetGlobalLanguageMode(SbLanguageMode eLanguageMode)1531*b1cdbd2cSJim Jagielski void StarBASIC::SetGlobalLanguageMode( SbLanguageMode eLanguageMode )
1532*b1cdbd2cSJim Jagielski {
1533*b1cdbd2cSJim Jagielski 	GetSbData()->eLanguageMode = eLanguageMode;
1534*b1cdbd2cSJim Jagielski }
GetGlobalLanguageMode()1535*b1cdbd2cSJim Jagielski SbLanguageMode StarBASIC::GetGlobalLanguageMode()
1536*b1cdbd2cSJim Jagielski {
1537*b1cdbd2cSJim Jagielski 	return GetSbData()->eLanguageMode;
1538*b1cdbd2cSJim Jagielski }
1539*b1cdbd2cSJim Jagielski // Local settings
GetLanguageMode()1540*b1cdbd2cSJim Jagielski SbLanguageMode StarBASIC::GetLanguageMode()
1541*b1cdbd2cSJim Jagielski {
1542*b1cdbd2cSJim Jagielski 	// Use global settings?
1543*b1cdbd2cSJim Jagielski 	if( eLanguageMode == SB_LANG_GLOBAL )
1544*b1cdbd2cSJim Jagielski 		return GetSbData()->eLanguageMode;
1545*b1cdbd2cSJim Jagielski 	else
1546*b1cdbd2cSJim Jagielski 		return eLanguageMode;
1547*b1cdbd2cSJim Jagielski }
1548*b1cdbd2cSJim Jagielski 
1549*b1cdbd2cSJim Jagielski // AB: 29.3.96
1550*b1cdbd2cSJim Jagielski // Das Mapping zwischen alten und neuen Fehlercodes erfolgt, indem die Tabelle
1551*b1cdbd2cSJim Jagielski // SFX_VB_ErrorTab[] durchsucht wird. Dies ist zwar nicht besonders performant,
1552*b1cdbd2cSJim Jagielski // verbraucht aber viel weniger Speicher als entsprechende switch-Bloecke.
1553*b1cdbd2cSJim Jagielski // Die Umrechnung von Fehlercodes muss nicht schnell sein, daher auch keine
1554*b1cdbd2cSJim Jagielski // binaere Suche bei VB-Error -> SFX-Error.
1555*b1cdbd2cSJim Jagielski 
1556*b1cdbd2cSJim Jagielski // Neue Fehler-Codes auf alte, Sbx-Kompatible zurueckmappen
GetVBErrorCode(SbError nError)1557*b1cdbd2cSJim Jagielski sal_uInt16 StarBASIC::GetVBErrorCode( SbError nError )
1558*b1cdbd2cSJim Jagielski {
1559*b1cdbd2cSJim Jagielski 	sal_uInt16 nRet = 0;
1560*b1cdbd2cSJim Jagielski 
1561*b1cdbd2cSJim Jagielski 	if( SbiRuntime::isVBAEnabled() )
1562*b1cdbd2cSJim Jagielski 	{
1563*b1cdbd2cSJim Jagielski 		switch( nError )
1564*b1cdbd2cSJim Jagielski 		{
1565*b1cdbd2cSJim Jagielski 			case SbERR_BASIC_ARRAY_FIX:
1566*b1cdbd2cSJim Jagielski 				return 10;
1567*b1cdbd2cSJim Jagielski 			case SbERR_BASIC_STRING_OVERFLOW:
1568*b1cdbd2cSJim Jagielski 				return 14;
1569*b1cdbd2cSJim Jagielski 			case SbERR_BASIC_EXPR_TOO_COMPLEX:
1570*b1cdbd2cSJim Jagielski 				return 16;
1571*b1cdbd2cSJim Jagielski 			case SbERR_BASIC_OPER_NOT_PERFORM:
1572*b1cdbd2cSJim Jagielski 				return 17;
1573*b1cdbd2cSJim Jagielski 			case SbERR_BASIC_TOO_MANY_DLL:
1574*b1cdbd2cSJim Jagielski 				return 47;
1575*b1cdbd2cSJim Jagielski 			case SbERR_BASIC_LOOP_NOT_INIT:
1576*b1cdbd2cSJim Jagielski 				return 92;
1577*b1cdbd2cSJim Jagielski 			default:
1578*b1cdbd2cSJim Jagielski 				nRet = 0;
1579*b1cdbd2cSJim Jagielski 		}
1580*b1cdbd2cSJim Jagielski 	}
1581*b1cdbd2cSJim Jagielski 
1582*b1cdbd2cSJim Jagielski 	// Suchschleife
1583*b1cdbd2cSJim Jagielski 	const SFX_VB_ErrorItem* pErrItem;
1584*b1cdbd2cSJim Jagielski 	sal_uInt16 nIndex = 0;
1585*b1cdbd2cSJim Jagielski 	do
1586*b1cdbd2cSJim Jagielski 	{
1587*b1cdbd2cSJim Jagielski 		pErrItem = SFX_VB_ErrorTab + nIndex;
1588*b1cdbd2cSJim Jagielski 		if( pErrItem->nErrorSFX == nError )
1589*b1cdbd2cSJim Jagielski 		{
1590*b1cdbd2cSJim Jagielski 			nRet = pErrItem->nErrorVB;
1591*b1cdbd2cSJim Jagielski 			break;
1592*b1cdbd2cSJim Jagielski 		}
1593*b1cdbd2cSJim Jagielski 		nIndex++;
1594*b1cdbd2cSJim Jagielski 	}
1595*b1cdbd2cSJim Jagielski 	while( pErrItem->nErrorVB != 0xFFFF );		// bis End-Marke
1596*b1cdbd2cSJim Jagielski 	return nRet;
1597*b1cdbd2cSJim Jagielski }
1598*b1cdbd2cSJim Jagielski 
GetSfxFromVBError(sal_uInt16 nError)1599*b1cdbd2cSJim Jagielski SbError	StarBASIC::GetSfxFromVBError( sal_uInt16 nError )
1600*b1cdbd2cSJim Jagielski {
1601*b1cdbd2cSJim Jagielski 	SbError nRet = 0L;
1602*b1cdbd2cSJim Jagielski 
1603*b1cdbd2cSJim Jagielski 	if( SbiRuntime::isVBAEnabled() )
1604*b1cdbd2cSJim Jagielski 	{
1605*b1cdbd2cSJim Jagielski 		switch( nError )
1606*b1cdbd2cSJim Jagielski 		{
1607*b1cdbd2cSJim Jagielski 			case 1:
1608*b1cdbd2cSJim Jagielski 			case 2:
1609*b1cdbd2cSJim Jagielski 			case 4:
1610*b1cdbd2cSJim Jagielski 			case 8:
1611*b1cdbd2cSJim Jagielski 			case 12:
1612*b1cdbd2cSJim Jagielski 			case 73:
1613*b1cdbd2cSJim Jagielski 				return 0L;
1614*b1cdbd2cSJim Jagielski 			case 10:
1615*b1cdbd2cSJim Jagielski 				return SbERR_BASIC_ARRAY_FIX;
1616*b1cdbd2cSJim Jagielski 			case 14:
1617*b1cdbd2cSJim Jagielski 				return SbERR_BASIC_STRING_OVERFLOW;
1618*b1cdbd2cSJim Jagielski 			case 16:
1619*b1cdbd2cSJim Jagielski 				return SbERR_BASIC_EXPR_TOO_COMPLEX;
1620*b1cdbd2cSJim Jagielski 			case 17:
1621*b1cdbd2cSJim Jagielski 				return SbERR_BASIC_OPER_NOT_PERFORM;
1622*b1cdbd2cSJim Jagielski 			case 47:
1623*b1cdbd2cSJim Jagielski 				return SbERR_BASIC_TOO_MANY_DLL;
1624*b1cdbd2cSJim Jagielski 			case 92:
1625*b1cdbd2cSJim Jagielski 				return SbERR_BASIC_LOOP_NOT_INIT;
1626*b1cdbd2cSJim Jagielski 			default:
1627*b1cdbd2cSJim Jagielski 				nRet = 0L;
1628*b1cdbd2cSJim Jagielski 		}
1629*b1cdbd2cSJim Jagielski 	}
1630*b1cdbd2cSJim Jagielski 	const SFX_VB_ErrorItem* pErrItem;
1631*b1cdbd2cSJim Jagielski 	sal_uInt16 nIndex = 0;
1632*b1cdbd2cSJim Jagielski 	do
1633*b1cdbd2cSJim Jagielski 	{
1634*b1cdbd2cSJim Jagielski 		pErrItem = SFX_VB_ErrorTab + nIndex;
1635*b1cdbd2cSJim Jagielski 		if( pErrItem->nErrorVB == nError )
1636*b1cdbd2cSJim Jagielski 		{
1637*b1cdbd2cSJim Jagielski 			nRet = pErrItem->nErrorSFX;
1638*b1cdbd2cSJim Jagielski 			break;
1639*b1cdbd2cSJim Jagielski 		}
1640*b1cdbd2cSJim Jagielski 		else if( pErrItem->nErrorVB > nError )
1641*b1cdbd2cSJim Jagielski 			break;				// kann nicht mehr gefunden werden
1642*b1cdbd2cSJim Jagielski 
1643*b1cdbd2cSJim Jagielski 		nIndex++;
1644*b1cdbd2cSJim Jagielski 	}
1645*b1cdbd2cSJim Jagielski 	while( pErrItem->nErrorVB != 0xFFFF );		// bis End-Marke
1646*b1cdbd2cSJim Jagielski 	return nRet;
1647*b1cdbd2cSJim Jagielski }
1648*b1cdbd2cSJim Jagielski 
1649*b1cdbd2cSJim Jagielski // Error- / Break-Daten setzen
SetErrorData(SbError nCode,sal_uInt16 nLine,sal_uInt16 nCol1,sal_uInt16 nCol2)1650*b1cdbd2cSJim Jagielski void StarBASIC::SetErrorData
1651*b1cdbd2cSJim Jagielski ( SbError nCode, sal_uInt16 nLine, sal_uInt16 nCol1, sal_uInt16 nCol2 )
1652*b1cdbd2cSJim Jagielski {
1653*b1cdbd2cSJim Jagielski 	SbiGlobals& aGlobals = *GetSbData();
1654*b1cdbd2cSJim Jagielski 	aGlobals.nCode = nCode;
1655*b1cdbd2cSJim Jagielski 	aGlobals.nLine = nLine;
1656*b1cdbd2cSJim Jagielski 	aGlobals.nCol1 = nCol1;
1657*b1cdbd2cSJim Jagielski 	aGlobals.nCol2 = nCol2;
1658*b1cdbd2cSJim Jagielski }
1659*b1cdbd2cSJim Jagielski 
1660*b1cdbd2cSJim Jagielski //----------------------------------------------------------------
1661*b1cdbd2cSJim Jagielski // Hilfsklasse zum Zugriff auf String SubResourcen einer Resource.
1662*b1cdbd2cSJim Jagielski // Quelle: sfx2\source\doc\docfile.cxx (TLX)
1663*b1cdbd2cSJim Jagielski struct BasicStringList_Impl : private Resource
1664*b1cdbd2cSJim Jagielski {
1665*b1cdbd2cSJim Jagielski 	ResId aResId;
1666*b1cdbd2cSJim Jagielski 
BasicStringList_ImplBasicStringList_Impl1667*b1cdbd2cSJim Jagielski 	BasicStringList_Impl( ResId& rErrIdP,  sal_uInt16 nId)
1668*b1cdbd2cSJim Jagielski 		: Resource( rErrIdP ),aResId(nId, *rErrIdP.GetResMgr() ){}
~BasicStringList_ImplBasicStringList_Impl1669*b1cdbd2cSJim Jagielski 	~BasicStringList_Impl() { FreeResource(); }
1670*b1cdbd2cSJim Jagielski 
GetStringBasicStringList_Impl1671*b1cdbd2cSJim Jagielski 	String GetString(){ return String( aResId ); }
IsErrorTextAvailableBasicStringList_Impl1672*b1cdbd2cSJim Jagielski 	sal_Bool IsErrorTextAvailable( void )
1673*b1cdbd2cSJim Jagielski 		{ return IsAvailableRes(aResId.SetRT(RSC_STRING)); }
1674*b1cdbd2cSJim Jagielski };
1675*b1cdbd2cSJim Jagielski //----------------------------------------------------------------
1676*b1cdbd2cSJim Jagielski 
1677*b1cdbd2cSJim Jagielski // #60175 Flag, das bei Basic-Fehlern das Anziehen der SFX-Resourcen verhindert
1678*b1cdbd2cSJim Jagielski static sal_Bool bStaticSuppressSfxResource = sal_False;
1679*b1cdbd2cSJim Jagielski 
StaticSuppressSfxResource(sal_Bool bSuppress)1680*b1cdbd2cSJim Jagielski void StarBASIC::StaticSuppressSfxResource( sal_Bool bSuppress )
1681*b1cdbd2cSJim Jagielski {
1682*b1cdbd2cSJim Jagielski 	bStaticSuppressSfxResource = bSuppress;
1683*b1cdbd2cSJim Jagielski }
1684*b1cdbd2cSJim Jagielski 
1685*b1cdbd2cSJim Jagielski // Hack for #83750, use bStaticSuppressSfxResource as setup flag
runsInSetup(void)1686*b1cdbd2cSJim Jagielski sal_Bool runsInSetup( void )
1687*b1cdbd2cSJim Jagielski {
1688*b1cdbd2cSJim Jagielski 	return bStaticSuppressSfxResource;
1689*b1cdbd2cSJim Jagielski }
1690*b1cdbd2cSJim Jagielski 
1691*b1cdbd2cSJim Jagielski 
MakeErrorText(SbError nId,const String & aMsg)1692*b1cdbd2cSJim Jagielski void StarBASIC::MakeErrorText( SbError nId, const String& aMsg )
1693*b1cdbd2cSJim Jagielski {
1694*b1cdbd2cSJim Jagielski 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1695*b1cdbd2cSJim Jagielski 
1696*b1cdbd2cSJim Jagielski 	if( bStaticSuppressSfxResource )
1697*b1cdbd2cSJim Jagielski 	{
1698*b1cdbd2cSJim Jagielski 		GetSbData()->aErrMsg = String( RTL_CONSTASCII_USTRINGPARAM("No resource: Error message not available") );
1699*b1cdbd2cSJim Jagielski 		return;
1700*b1cdbd2cSJim Jagielski 	}
1701*b1cdbd2cSJim Jagielski 
1702*b1cdbd2cSJim Jagielski 	sal_uInt16 nOldID = GetVBErrorCode( nId );
1703*b1cdbd2cSJim Jagielski 
1704*b1cdbd2cSJim Jagielski 	// Hilfsklasse instanzieren
1705*b1cdbd2cSJim Jagielski 	BasResId aId( RID_BASIC_START );
1706*b1cdbd2cSJim Jagielski 	BasicStringList_Impl aMyStringList( aId, sal_uInt16(nId & ERRCODE_RES_MASK) );
1707*b1cdbd2cSJim Jagielski 
1708*b1cdbd2cSJim Jagielski 	if( aMyStringList.IsErrorTextAvailable() )
1709*b1cdbd2cSJim Jagielski 	{
1710*b1cdbd2cSJim Jagielski 		// Merge Message mit Zusatztext
1711*b1cdbd2cSJim Jagielski 		String aMsg1 = aMyStringList.GetString();
1712*b1cdbd2cSJim Jagielski 		// Argument-Platzhalter durch %s ersetzen
1713*b1cdbd2cSJim Jagielski 		String aSrgStr( RTL_CONSTASCII_USTRINGPARAM("$(ARG1)") );
1714*b1cdbd2cSJim Jagielski 		sal_uInt16 nResult = aMsg1.Search( aSrgStr );
1715*b1cdbd2cSJim Jagielski 
1716*b1cdbd2cSJim Jagielski 		if( nResult != STRING_NOTFOUND )
1717*b1cdbd2cSJim Jagielski 		{
1718*b1cdbd2cSJim Jagielski 			aMsg1.Erase( nResult, aSrgStr.Len() );
1719*b1cdbd2cSJim Jagielski 			aMsg1.Insert( aMsg, nResult );
1720*b1cdbd2cSJim Jagielski 		}
1721*b1cdbd2cSJim Jagielski 		GetSbData()->aErrMsg = aMsg1;
1722*b1cdbd2cSJim Jagielski 	}
1723*b1cdbd2cSJim Jagielski 	else if( nOldID != 0 )
1724*b1cdbd2cSJim Jagielski 	{
1725*b1cdbd2cSJim Jagielski 		String aStdMsg( RTL_CONSTASCII_USTRINGPARAM("Fehler ") );
1726*b1cdbd2cSJim Jagielski 		aStdMsg += String::CreateFromInt32( nOldID);
1727*b1cdbd2cSJim Jagielski 		aStdMsg += String( RTL_CONSTASCII_USTRINGPARAM(": Kein Fehlertext verfuegbar!") );
1728*b1cdbd2cSJim Jagielski 		GetSbData()->aErrMsg = aStdMsg;
1729*b1cdbd2cSJim Jagielski 	}
1730*b1cdbd2cSJim Jagielski 	else
1731*b1cdbd2cSJim Jagielski 		GetSbData()->aErrMsg = String::EmptyString();
1732*b1cdbd2cSJim Jagielski 
1733*b1cdbd2cSJim Jagielski }
1734*b1cdbd2cSJim Jagielski 
CError(SbError code,const String & rMsg,sal_uInt16 l,sal_uInt16 c1,sal_uInt16 c2)1735*b1cdbd2cSJim Jagielski sal_Bool StarBASIC::CError
1736*b1cdbd2cSJim Jagielski 	( SbError code, const String& rMsg, sal_uInt16 l, sal_uInt16 c1, sal_uInt16 c2 )
1737*b1cdbd2cSJim Jagielski {
1738*b1cdbd2cSJim Jagielski 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1739*b1cdbd2cSJim Jagielski 
1740*b1cdbd2cSJim Jagielski 	// Compiler-Fehler waehrend der Laufzeit -> Programm anhalten
1741*b1cdbd2cSJim Jagielski 	if( IsRunning() )
1742*b1cdbd2cSJim Jagielski 	{
1743*b1cdbd2cSJim Jagielski 		// #109018 Check if running Basic is affected
1744*b1cdbd2cSJim Jagielski 		StarBASIC* pStartedBasic = pINST->GetBasic();
1745*b1cdbd2cSJim Jagielski 		if( pStartedBasic != this )
1746*b1cdbd2cSJim Jagielski 			return sal_False;
1747*b1cdbd2cSJim Jagielski 
1748*b1cdbd2cSJim Jagielski 		Stop();
1749*b1cdbd2cSJim Jagielski 	}
1750*b1cdbd2cSJim Jagielski 
1751*b1cdbd2cSJim Jagielski 	// Flag setzen, damit GlobalRunInit den Fehler mitbekommt
1752*b1cdbd2cSJim Jagielski 	GetSbData()->bGlobalInitErr = sal_True;
1753*b1cdbd2cSJim Jagielski 
1754*b1cdbd2cSJim Jagielski 	// Fehlertext basteln
1755*b1cdbd2cSJim Jagielski 	MakeErrorText( code, rMsg );
1756*b1cdbd2cSJim Jagielski 
1757*b1cdbd2cSJim Jagielski 	// Umsetzung des Codes fuer String-Transport in SFX-Error
1758*b1cdbd2cSJim Jagielski 	if( rMsg.Len() )
1759*b1cdbd2cSJim Jagielski 		code = (sal_uIntPtr)*new StringErrorInfo( code, String(rMsg) );
1760*b1cdbd2cSJim Jagielski 
1761*b1cdbd2cSJim Jagielski 	SetErrorData( code, l, c1, c2 );
1762*b1cdbd2cSJim Jagielski 	GetSbData()->bCompiler = sal_True;
1763*b1cdbd2cSJim Jagielski 	sal_Bool bRet;
1764*b1cdbd2cSJim Jagielski 	if( GetSbData()->aErrHdl.IsSet() )
1765*b1cdbd2cSJim Jagielski 		bRet = (sal_Bool) GetSbData()->aErrHdl.Call( this );
1766*b1cdbd2cSJim Jagielski 	else
1767*b1cdbd2cSJim Jagielski 		bRet = ErrorHdl();
1768*b1cdbd2cSJim Jagielski 	GetSbData()->bCompiler = sal_False;		// nur sal_True fuer Error-Handler
1769*b1cdbd2cSJim Jagielski 	return bRet;
1770*b1cdbd2cSJim Jagielski }
1771*b1cdbd2cSJim Jagielski 
RTError(SbError code,sal_uInt16 l,sal_uInt16 c1,sal_uInt16 c2)1772*b1cdbd2cSJim Jagielski sal_Bool StarBASIC::RTError
1773*b1cdbd2cSJim Jagielski 	( SbError code, sal_uInt16 l, sal_uInt16 c1, sal_uInt16 c2 )
1774*b1cdbd2cSJim Jagielski {
1775*b1cdbd2cSJim Jagielski 	return RTError( code, String(), l, c1, c2 );
1776*b1cdbd2cSJim Jagielski }
1777*b1cdbd2cSJim Jagielski 
RTError(SbError code,const String & rMsg,sal_uInt16 l,sal_uInt16 c1,sal_uInt16 c2)1778*b1cdbd2cSJim Jagielski sal_Bool StarBASIC::RTError( SbError code, const String& rMsg, sal_uInt16 l, sal_uInt16 c1, sal_uInt16 c2 )
1779*b1cdbd2cSJim Jagielski {
1780*b1cdbd2cSJim Jagielski 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1781*b1cdbd2cSJim Jagielski 
1782*b1cdbd2cSJim Jagielski 	SbError c = code;
1783*b1cdbd2cSJim Jagielski 	if( (c & ERRCODE_CLASS_MASK) == ERRCODE_CLASS_COMPILER )
1784*b1cdbd2cSJim Jagielski 		c = 0;
1785*b1cdbd2cSJim Jagielski 	MakeErrorText( c, rMsg );
1786*b1cdbd2cSJim Jagielski 
1787*b1cdbd2cSJim Jagielski 	// Umsetzung des Codes fuer String-Transport in SFX-Error
1788*b1cdbd2cSJim Jagielski 	if( rMsg.Len() )
1789*b1cdbd2cSJim Jagielski 	{
1790*b1cdbd2cSJim Jagielski 		// very confusing, even though MakeErrorText sets up the error text
1791*b1cdbd2cSJim Jagielski 		// seems that this is not used ( if rMsg already has content )
1792*b1cdbd2cSJim Jagielski 		// In the case of VBA MakeErrorText also formats the error to be alittle more
1793*b1cdbd2cSJim Jagielski 		// like vba ( adds an error number etc )
1794*b1cdbd2cSJim Jagielski 		if ( SbiRuntime::isVBAEnabled() && ( code == SbERR_BASIC_COMPAT ) )
1795*b1cdbd2cSJim Jagielski 		{
1796*b1cdbd2cSJim Jagielski 			String aTmp = '\'';
1797*b1cdbd2cSJim Jagielski 			aTmp += String::CreateFromInt32( SbxErrObject::getUnoErrObject()->getNumber() );
1798*b1cdbd2cSJim Jagielski 			aTmp += String( RTL_CONSTASCII_USTRINGPARAM("\'\n") );
1799*b1cdbd2cSJim Jagielski 			aTmp +=  GetSbData()->aErrMsg.Len() ? GetSbData()->aErrMsg : rMsg;
1800*b1cdbd2cSJim Jagielski 			code = (sal_uIntPtr)*new StringErrorInfo( code, aTmp );
1801*b1cdbd2cSJim Jagielski 		}
1802*b1cdbd2cSJim Jagielski 		else
1803*b1cdbd2cSJim Jagielski 			code = (sal_uIntPtr)*new StringErrorInfo( code, String(rMsg) );
1804*b1cdbd2cSJim Jagielski 	}
1805*b1cdbd2cSJim Jagielski 
1806*b1cdbd2cSJim Jagielski 	SetErrorData( code, l, c1, c2 );
1807*b1cdbd2cSJim Jagielski 	if( GetSbData()->aErrHdl.IsSet() )
1808*b1cdbd2cSJim Jagielski 		return (sal_Bool) GetSbData()->aErrHdl.Call( this );
1809*b1cdbd2cSJim Jagielski 	else
1810*b1cdbd2cSJim Jagielski 		return ErrorHdl();
1811*b1cdbd2cSJim Jagielski }
1812*b1cdbd2cSJim Jagielski 
Error(SbError n)1813*b1cdbd2cSJim Jagielski void StarBASIC::Error( SbError n )
1814*b1cdbd2cSJim Jagielski {
1815*b1cdbd2cSJim Jagielski 	Error( n, String() );
1816*b1cdbd2cSJim Jagielski }
1817*b1cdbd2cSJim Jagielski 
Error(SbError n,const String & rMsg)1818*b1cdbd2cSJim Jagielski void StarBASIC::Error( SbError n, const String& rMsg )
1819*b1cdbd2cSJim Jagielski {
1820*b1cdbd2cSJim Jagielski 	if( pINST )
1821*b1cdbd2cSJim Jagielski 		pINST->Error( n, rMsg );
1822*b1cdbd2cSJim Jagielski }
1823*b1cdbd2cSJim Jagielski 
FatalError(SbError n)1824*b1cdbd2cSJim Jagielski void StarBASIC::FatalError( SbError n )
1825*b1cdbd2cSJim Jagielski {
1826*b1cdbd2cSJim Jagielski 	if( pINST )
1827*b1cdbd2cSJim Jagielski 		pINST->FatalError( n );
1828*b1cdbd2cSJim Jagielski }
1829*b1cdbd2cSJim Jagielski 
FatalError(SbError _errCode,const String & _details)1830*b1cdbd2cSJim Jagielski void StarBASIC::FatalError( SbError _errCode, const String& _details )
1831*b1cdbd2cSJim Jagielski {
1832*b1cdbd2cSJim Jagielski 	if( pINST )
1833*b1cdbd2cSJim Jagielski 		pINST->FatalError( _errCode, _details );
1834*b1cdbd2cSJim Jagielski }
1835*b1cdbd2cSJim Jagielski 
GetErrBasic()1836*b1cdbd2cSJim Jagielski SbError StarBASIC::GetErrBasic()
1837*b1cdbd2cSJim Jagielski {
1838*b1cdbd2cSJim Jagielski 	if( pINST )
1839*b1cdbd2cSJim Jagielski 		return pINST->GetErr();
1840*b1cdbd2cSJim Jagielski 	else
1841*b1cdbd2cSJim Jagielski 		return 0;
1842*b1cdbd2cSJim Jagielski }
1843*b1cdbd2cSJim Jagielski 
1844*b1cdbd2cSJim Jagielski // #66536 Zusatz-Message fuer RTL-Funktion Error zugreifbar machen
GetErrorMsg()1845*b1cdbd2cSJim Jagielski String StarBASIC::GetErrorMsg()
1846*b1cdbd2cSJim Jagielski {
1847*b1cdbd2cSJim Jagielski 	if( pINST )
1848*b1cdbd2cSJim Jagielski 		return pINST->GetErrorMsg();
1849*b1cdbd2cSJim Jagielski 	else
1850*b1cdbd2cSJim Jagielski 		return String();
1851*b1cdbd2cSJim Jagielski }
1852*b1cdbd2cSJim Jagielski 
GetErl()1853*b1cdbd2cSJim Jagielski sal_uInt16 StarBASIC::GetErl()
1854*b1cdbd2cSJim Jagielski {
1855*b1cdbd2cSJim Jagielski 	if( pINST )
1856*b1cdbd2cSJim Jagielski 		return pINST->GetErl();
1857*b1cdbd2cSJim Jagielski 	else
1858*b1cdbd2cSJim Jagielski 		return 0;
1859*b1cdbd2cSJim Jagielski }
1860*b1cdbd2cSJim Jagielski 
ErrorHdl()1861*b1cdbd2cSJim Jagielski sal_Bool __EXPORT StarBASIC::ErrorHdl()
1862*b1cdbd2cSJim Jagielski {
1863*b1cdbd2cSJim Jagielski 	return (sal_Bool) ( aErrorHdl.IsSet()
1864*b1cdbd2cSJim Jagielski 		? aErrorHdl.Call( this ) : sal_False );
1865*b1cdbd2cSJim Jagielski }
1866*b1cdbd2cSJim Jagielski 
GetGlobalErrorHdl()1867*b1cdbd2cSJim Jagielski Link StarBASIC::GetGlobalErrorHdl()
1868*b1cdbd2cSJim Jagielski {
1869*b1cdbd2cSJim Jagielski 	return GetSbData()->aErrHdl;
1870*b1cdbd2cSJim Jagielski }
1871*b1cdbd2cSJim Jagielski 
SetGlobalErrorHdl(const Link & rLink)1872*b1cdbd2cSJim Jagielski void StarBASIC::SetGlobalErrorHdl( const Link& rLink )
1873*b1cdbd2cSJim Jagielski {
1874*b1cdbd2cSJim Jagielski 	GetSbData()->aErrHdl = rLink;
1875*b1cdbd2cSJim Jagielski }
1876*b1cdbd2cSJim Jagielski 
1877*b1cdbd2cSJim Jagielski 
GetGlobalBreakHdl()1878*b1cdbd2cSJim Jagielski Link StarBASIC::GetGlobalBreakHdl()
1879*b1cdbd2cSJim Jagielski {
1880*b1cdbd2cSJim Jagielski 	return GetSbData()->aBreakHdl;
1881*b1cdbd2cSJim Jagielski }
1882*b1cdbd2cSJim Jagielski 
SetGlobalBreakHdl(const Link & rLink)1883*b1cdbd2cSJim Jagielski void StarBASIC::SetGlobalBreakHdl( const Link& rLink )
1884*b1cdbd2cSJim Jagielski {
1885*b1cdbd2cSJim Jagielski 	GetSbData()->aBreakHdl = rLink;
1886*b1cdbd2cSJim Jagielski }
1887*b1cdbd2cSJim Jagielski 
getUnoListeners(void)1888*b1cdbd2cSJim Jagielski SbxArrayRef StarBASIC::getUnoListeners( void )
1889*b1cdbd2cSJim Jagielski {
1890*b1cdbd2cSJim Jagielski     if( !xUnoListeners.Is() )
1891*b1cdbd2cSJim Jagielski         xUnoListeners = new SbxArray();
1892*b1cdbd2cSJim Jagielski     return xUnoListeners;
1893*b1cdbd2cSJim Jagielski }
1894*b1cdbd2cSJim Jagielski 
1895*b1cdbd2cSJim Jagielski 
1896*b1cdbd2cSJim Jagielski /**************************************************************************
1897*b1cdbd2cSJim Jagielski *
1898*b1cdbd2cSJim Jagielski *	Laden und Speichern
1899*b1cdbd2cSJim Jagielski *
1900*b1cdbd2cSJim Jagielski **************************************************************************/
1901*b1cdbd2cSJim Jagielski 
LoadData(SvStream & r,sal_uInt16 nVer)1902*b1cdbd2cSJim Jagielski sal_Bool StarBASIC::LoadData( SvStream& r, sal_uInt16 nVer )
1903*b1cdbd2cSJim Jagielski {
1904*b1cdbd2cSJim Jagielski 	if( !SbxObject::LoadData( r, nVer ) )
1905*b1cdbd2cSJim Jagielski 		return sal_False;
1906*b1cdbd2cSJim Jagielski 
1907*b1cdbd2cSJim Jagielski     // #95459 Delete dialogs, otherwise endless recursion
1908*b1cdbd2cSJim Jagielski     // in SbxVarable::GetType() if dialogs are accessed
1909*b1cdbd2cSJim Jagielski     sal_uInt16 nObjCount = pObjs->Count();
1910*b1cdbd2cSJim Jagielski     SbxVariable** ppDeleteTab = new SbxVariable*[ nObjCount ];
1911*b1cdbd2cSJim Jagielski 	sal_uInt16 nObj;
1912*b1cdbd2cSJim Jagielski 
1913*b1cdbd2cSJim Jagielski 	for( nObj = 0 ; nObj < nObjCount ; nObj++ )
1914*b1cdbd2cSJim Jagielski 	{
1915*b1cdbd2cSJim Jagielski 		SbxVariable* pVar = pObjs->Get( nObj );
1916*b1cdbd2cSJim Jagielski 		StarBASIC* pBasic = PTR_CAST( StarBASIC, pVar );
1917*b1cdbd2cSJim Jagielski         ppDeleteTab[nObj] = pBasic ? NULL : pVar;
1918*b1cdbd2cSJim Jagielski 	}
1919*b1cdbd2cSJim Jagielski 	for( nObj = 0 ; nObj < nObjCount ; nObj++ )
1920*b1cdbd2cSJim Jagielski 	{
1921*b1cdbd2cSJim Jagielski         SbxVariable* pVar = ppDeleteTab[nObj];
1922*b1cdbd2cSJim Jagielski         if( pVar )
1923*b1cdbd2cSJim Jagielski             pObjs->Remove( pVar );
1924*b1cdbd2cSJim Jagielski     }
1925*b1cdbd2cSJim Jagielski     delete[] ppDeleteTab;
1926*b1cdbd2cSJim Jagielski 
1927*b1cdbd2cSJim Jagielski 	sal_uInt16 nMod;
1928*b1cdbd2cSJim Jagielski 	pModules->Clear();
1929*b1cdbd2cSJim Jagielski 	r >> nMod;
1930*b1cdbd2cSJim Jagielski 	for( sal_uInt16 i = 0; i < nMod; i++ )
1931*b1cdbd2cSJim Jagielski 	{
1932*b1cdbd2cSJim Jagielski 		SbModule* pMod = (SbModule*) SbxBase::Load( r );
1933*b1cdbd2cSJim Jagielski 		if( !pMod )
1934*b1cdbd2cSJim Jagielski 			return sal_False;
1935*b1cdbd2cSJim Jagielski 		else if( pMod->ISA(SbJScriptModule) )
1936*b1cdbd2cSJim Jagielski 		{
1937*b1cdbd2cSJim Jagielski 			// Ref zuweisen, damit pMod deleted wird
1938*b1cdbd2cSJim Jagielski 			SbModuleRef xRef = pMod;
1939*b1cdbd2cSJim Jagielski 		}
1940*b1cdbd2cSJim Jagielski 		else
1941*b1cdbd2cSJim Jagielski 		{
1942*b1cdbd2cSJim Jagielski 			pMod->SetParent( this );
1943*b1cdbd2cSJim Jagielski 			pModules->Put( pMod, i );
1944*b1cdbd2cSJim Jagielski 		}
1945*b1cdbd2cSJim Jagielski 	}
1946*b1cdbd2cSJim Jagielski 	// HACK fuer SFX-Mist!
1947*b1cdbd2cSJim Jagielski 	SbxVariable* p = Find( String( RTL_CONSTASCII_USTRINGPARAM("FALSE") ), SbxCLASS_PROPERTY );
1948*b1cdbd2cSJim Jagielski 	if( p )
1949*b1cdbd2cSJim Jagielski 		Remove( p );
1950*b1cdbd2cSJim Jagielski 	p = Find( String( RTL_CONSTASCII_USTRINGPARAM("TRUE") ), SbxCLASS_PROPERTY );
1951*b1cdbd2cSJim Jagielski 	if( p )
1952*b1cdbd2cSJim Jagielski 		Remove( p );
1953*b1cdbd2cSJim Jagielski 	// Ende des Hacks!
1954*b1cdbd2cSJim Jagielski 	// Suche ueber StarBASIC ist immer global
1955*b1cdbd2cSJim Jagielski 	DBG_ASSERT( IsSet( SBX_GBLSEARCH ), "Basic ohne GBLSEARCH geladen" );
1956*b1cdbd2cSJim Jagielski 	SetFlag( SBX_GBLSEARCH );
1957*b1cdbd2cSJim Jagielski 	return sal_True;
1958*b1cdbd2cSJim Jagielski }
1959*b1cdbd2cSJim Jagielski 
StoreData(SvStream & r) const1960*b1cdbd2cSJim Jagielski sal_Bool StarBASIC::StoreData( SvStream& r ) const
1961*b1cdbd2cSJim Jagielski {
1962*b1cdbd2cSJim Jagielski 	if( !SbxObject::StoreData( r ) )
1963*b1cdbd2cSJim Jagielski 		return sal_False;
1964*b1cdbd2cSJim Jagielski 	r << (sal_uInt16) pModules->Count();
1965*b1cdbd2cSJim Jagielski 	for( sal_uInt16 i = 0; i < pModules->Count(); i++ )
1966*b1cdbd2cSJim Jagielski 	{
1967*b1cdbd2cSJim Jagielski 		SbModule* p = (SbModule*) pModules->Get( i );
1968*b1cdbd2cSJim Jagielski 		if( !p->Store( r ) )
1969*b1cdbd2cSJim Jagielski 			return sal_False;
1970*b1cdbd2cSJim Jagielski 	}
1971*b1cdbd2cSJim Jagielski 	return sal_True;
1972*b1cdbd2cSJim Jagielski }
1973*b1cdbd2cSJim Jagielski 
LoadOldModules(SvStream &)1974*b1cdbd2cSJim Jagielski sal_Bool StarBASIC::LoadOldModules( SvStream& )
1975*b1cdbd2cSJim Jagielski {
1976*b1cdbd2cSJim Jagielski 	return sal_False;
1977*b1cdbd2cSJim Jagielski }
1978*b1cdbd2cSJim Jagielski 
GetUNOConstant(const sal_Char * _pAsciiName,::com::sun::star::uno::Any & aOut)1979*b1cdbd2cSJim Jagielski bool StarBASIC::GetUNOConstant( const sal_Char* _pAsciiName, ::com::sun::star::uno::Any& aOut )
1980*b1cdbd2cSJim Jagielski {
1981*b1cdbd2cSJim Jagielski     bool bRes = false;
1982*b1cdbd2cSJim Jagielski     ::rtl::OUString sVarName( ::rtl::OUString::createFromAscii( _pAsciiName ) );
1983*b1cdbd2cSJim Jagielski     SbUnoObject* pGlobs = dynamic_cast<SbUnoObject*>( Find( sVarName, SbxCLASS_DONTCARE ) );
1984*b1cdbd2cSJim Jagielski     if ( pGlobs )
1985*b1cdbd2cSJim Jagielski     {
1986*b1cdbd2cSJim Jagielski         aOut = pGlobs->getUnoAny();
1987*b1cdbd2cSJim Jagielski         bRes = true;
1988*b1cdbd2cSJim Jagielski     }
1989*b1cdbd2cSJim Jagielski     return bRes;
1990*b1cdbd2cSJim Jagielski }
1991*b1cdbd2cSJim Jagielski 
GetModelFromBasic(SbxObject * pBasic)1992*b1cdbd2cSJim Jagielski Reference< frame::XModel > StarBASIC::GetModelFromBasic( SbxObject* pBasic )
1993*b1cdbd2cSJim Jagielski {
1994*b1cdbd2cSJim Jagielski     OSL_PRECOND( pBasic != NULL, "getModelFromBasic: illegal call!" );
1995*b1cdbd2cSJim Jagielski     if ( !pBasic )
1996*b1cdbd2cSJim Jagielski         return NULL;
1997*b1cdbd2cSJim Jagielski 
1998*b1cdbd2cSJim Jagielski     // look for the ThisComponent variable, first in the parent (which
1999*b1cdbd2cSJim Jagielski     // might be the document's Basic), then in the parent's parent (which might be
2000*b1cdbd2cSJim Jagielski     // the application Basic)
2001*b1cdbd2cSJim Jagielski     const ::rtl::OUString sThisComponent( RTL_CONSTASCII_USTRINGPARAM( "ThisComponent" ) );
2002*b1cdbd2cSJim Jagielski     SbxVariable* pThisComponent = NULL;
2003*b1cdbd2cSJim Jagielski 
2004*b1cdbd2cSJim Jagielski     SbxObject* pLookup = pBasic->GetParent();
2005*b1cdbd2cSJim Jagielski     while ( pLookup && !pThisComponent )
2006*b1cdbd2cSJim Jagielski     {
2007*b1cdbd2cSJim Jagielski         pThisComponent = pLookup->Find( sThisComponent, SbxCLASS_OBJECT );
2008*b1cdbd2cSJim Jagielski         pLookup = pLookup->GetParent();
2009*b1cdbd2cSJim Jagielski     }
2010*b1cdbd2cSJim Jagielski     if ( !pThisComponent )
2011*b1cdbd2cSJim Jagielski     {
2012*b1cdbd2cSJim Jagielski         OSL_TRACE("Failed to get ThisComponent");
2013*b1cdbd2cSJim Jagielski             // the application Basic, at the latest, should have this variable
2014*b1cdbd2cSJim Jagielski         return NULL;
2015*b1cdbd2cSJim Jagielski     }
2016*b1cdbd2cSJim Jagielski 
2017*b1cdbd2cSJim Jagielski     Any aThisComponentAny( sbxToUnoValue( pThisComponent ) );
2018*b1cdbd2cSJim Jagielski     Reference< frame::XModel > xModel( aThisComponentAny, UNO_QUERY );
2019*b1cdbd2cSJim Jagielski     if ( !xModel.is() )
2020*b1cdbd2cSJim Jagielski     {
2021*b1cdbd2cSJim Jagielski         // it's no XModel. Okay, ThisComponent nowadays is allowed to be a controller.
2022*b1cdbd2cSJim Jagielski         Reference< frame::XController > xController( aThisComponentAny, UNO_QUERY );
2023*b1cdbd2cSJim Jagielski         if ( xController.is() )
2024*b1cdbd2cSJim Jagielski             xModel = xController->getModel();
2025*b1cdbd2cSJim Jagielski     }
2026*b1cdbd2cSJim Jagielski 
2027*b1cdbd2cSJim Jagielski     if ( !xModel.is() )
2028*b1cdbd2cSJim Jagielski         return NULL;
2029*b1cdbd2cSJim Jagielski 
2030*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 0
2031*b1cdbd2cSJim Jagielski     OSL_TRACE("Have model ThisComponent points to url %s",
2032*b1cdbd2cSJim Jagielski         ::rtl::OUStringToOString( xModel->getURL(),
2033*b1cdbd2cSJim Jagielski             RTL_TEXTENCODING_ASCII_US ).pData->buffer );
2034*b1cdbd2cSJim Jagielski #endif
2035*b1cdbd2cSJim Jagielski 
2036*b1cdbd2cSJim Jagielski     return xModel;
2037*b1cdbd2cSJim Jagielski }
2038*b1cdbd2cSJim Jagielski 
2039*b1cdbd2cSJim Jagielski 
2040*b1cdbd2cSJim Jagielski //========================================================================
2041*b1cdbd2cSJim Jagielski // #118116 Implementation Collection object
2042*b1cdbd2cSJim Jagielski 
2043*b1cdbd2cSJim Jagielski TYPEINIT1(BasicCollection,SbxObject)
2044*b1cdbd2cSJim Jagielski 
2045*b1cdbd2cSJim Jagielski static const char pCountStr[]	= "Count";
2046*b1cdbd2cSJim Jagielski static const char pAddStr[]		= "Add";
2047*b1cdbd2cSJim Jagielski static const char pItemStr[]	= "Item";
2048*b1cdbd2cSJim Jagielski static const char pRemoveStr[]	= "Remove";
2049*b1cdbd2cSJim Jagielski static sal_uInt16 nCountHash = 0, nAddHash, nItemHash, nRemoveHash;
2050*b1cdbd2cSJim Jagielski 
2051*b1cdbd2cSJim Jagielski SbxInfoRef BasicCollection::xAddInfo = NULL;
2052*b1cdbd2cSJim Jagielski SbxInfoRef BasicCollection::xItemInfo = NULL;
2053*b1cdbd2cSJim Jagielski 
BasicCollection(const XubString & rClass)2054*b1cdbd2cSJim Jagielski BasicCollection::BasicCollection( const XubString& rClass )
2055*b1cdbd2cSJim Jagielski 			 : SbxObject( rClass )
2056*b1cdbd2cSJim Jagielski {
2057*b1cdbd2cSJim Jagielski 	if( !nCountHash )
2058*b1cdbd2cSJim Jagielski 	{
2059*b1cdbd2cSJim Jagielski 		nCountHash  = MakeHashCode( String::CreateFromAscii( pCountStr ) );
2060*b1cdbd2cSJim Jagielski 		nAddHash    = MakeHashCode( String::CreateFromAscii( pAddStr ) );
2061*b1cdbd2cSJim Jagielski 		nItemHash   = MakeHashCode( String::CreateFromAscii( pItemStr ) );
2062*b1cdbd2cSJim Jagielski 		nRemoveHash = MakeHashCode( String::CreateFromAscii( pRemoveStr ) );
2063*b1cdbd2cSJim Jagielski 	}
2064*b1cdbd2cSJim Jagielski 	Initialize();
2065*b1cdbd2cSJim Jagielski 
2066*b1cdbd2cSJim Jagielski }
2067*b1cdbd2cSJim Jagielski 
~BasicCollection()2068*b1cdbd2cSJim Jagielski BasicCollection::~BasicCollection()
2069*b1cdbd2cSJim Jagielski {}
2070*b1cdbd2cSJim Jagielski 
Clear()2071*b1cdbd2cSJim Jagielski void BasicCollection::Clear()
2072*b1cdbd2cSJim Jagielski {
2073*b1cdbd2cSJim Jagielski 	SbxObject::Clear();
2074*b1cdbd2cSJim Jagielski 	Initialize();
2075*b1cdbd2cSJim Jagielski }
2076*b1cdbd2cSJim Jagielski 
Initialize()2077*b1cdbd2cSJim Jagielski void BasicCollection::Initialize()
2078*b1cdbd2cSJim Jagielski {
2079*b1cdbd2cSJim Jagielski 	xItemArray = new SbxArray();
2080*b1cdbd2cSJim Jagielski 	SetType( SbxOBJECT );
2081*b1cdbd2cSJim Jagielski 	SetFlag( SBX_FIXED );
2082*b1cdbd2cSJim Jagielski 	ResetFlag( SBX_WRITE );
2083*b1cdbd2cSJim Jagielski 	SbxVariable* p;
2084*b1cdbd2cSJim Jagielski 	p = Make( String::CreateFromAscii( pCountStr ), SbxCLASS_PROPERTY, SbxINTEGER );
2085*b1cdbd2cSJim Jagielski 	p->ResetFlag( SBX_WRITE );
2086*b1cdbd2cSJim Jagielski 	p->SetFlag( SBX_DONTSTORE );
2087*b1cdbd2cSJim Jagielski 	p = Make( String::CreateFromAscii( pAddStr ), SbxCLASS_METHOD, SbxEMPTY );
2088*b1cdbd2cSJim Jagielski 	p->SetFlag( SBX_DONTSTORE );
2089*b1cdbd2cSJim Jagielski 	p = Make( String::CreateFromAscii( pItemStr ), SbxCLASS_METHOD, SbxVARIANT );
2090*b1cdbd2cSJim Jagielski 	p->SetFlag( SBX_DONTSTORE );
2091*b1cdbd2cSJim Jagielski 	p = Make( String::CreateFromAscii( pRemoveStr ), SbxCLASS_METHOD, SbxEMPTY );
2092*b1cdbd2cSJim Jagielski 	p->SetFlag( SBX_DONTSTORE );
2093*b1cdbd2cSJim Jagielski 	if ( !xAddInfo.Is() )
2094*b1cdbd2cSJim Jagielski 	{
2095*b1cdbd2cSJim Jagielski 		xAddInfo = new SbxInfo;
2096*b1cdbd2cSJim Jagielski 		xAddInfo->AddParam(  String( RTL_CONSTASCII_USTRINGPARAM("Item") ), SbxVARIANT, SBX_READ );
2097*b1cdbd2cSJim Jagielski 		xAddInfo->AddParam(  String( RTL_CONSTASCII_USTRINGPARAM("Key") ), SbxVARIANT, SBX_READ | SBX_OPTIONAL );
2098*b1cdbd2cSJim Jagielski 		xAddInfo->AddParam(  String( RTL_CONSTASCII_USTRINGPARAM("Before") ), SbxVARIANT, SBX_READ | SBX_OPTIONAL );
2099*b1cdbd2cSJim Jagielski 		xAddInfo->AddParam(  String( RTL_CONSTASCII_USTRINGPARAM("After") ), SbxVARIANT, SBX_READ | SBX_OPTIONAL );
2100*b1cdbd2cSJim Jagielski 	}
2101*b1cdbd2cSJim Jagielski 	if ( !xItemInfo.Is() )
2102*b1cdbd2cSJim Jagielski 	{
2103*b1cdbd2cSJim Jagielski 		xItemInfo = new SbxInfo;
2104*b1cdbd2cSJim Jagielski 		xItemInfo->AddParam(  String( RTL_CONSTASCII_USTRINGPARAM("Index") ), SbxVARIANT, SBX_READ | SBX_OPTIONAL);
2105*b1cdbd2cSJim Jagielski 	}
2106*b1cdbd2cSJim Jagielski }
2107*b1cdbd2cSJim Jagielski 
Find(const XubString & rName,SbxClassType t)2108*b1cdbd2cSJim Jagielski SbxVariable* BasicCollection::Find( const XubString& rName, SbxClassType t )
2109*b1cdbd2cSJim Jagielski {
2110*b1cdbd2cSJim Jagielski 	SbxVariable* pFind = SbxObject::Find( rName, t );
2111*b1cdbd2cSJim Jagielski 	return pFind;
2112*b1cdbd2cSJim Jagielski }
2113*b1cdbd2cSJim Jagielski 
SFX_NOTIFY(SfxBroadcaster & rCst,const TypeId & rId1,const SfxHint & rHint,const TypeId & rId2)2114*b1cdbd2cSJim Jagielski void BasicCollection::SFX_NOTIFY( SfxBroadcaster& rCst, const TypeId& rId1,
2115*b1cdbd2cSJim Jagielski 								const SfxHint& rHint, const TypeId& rId2 )
2116*b1cdbd2cSJim Jagielski {
2117*b1cdbd2cSJim Jagielski 	const SbxHint* p = PTR_CAST(SbxHint,&rHint);
2118*b1cdbd2cSJim Jagielski 	if( p )
2119*b1cdbd2cSJim Jagielski 	{
2120*b1cdbd2cSJim Jagielski 		sal_uIntPtr nId = p->GetId();
2121*b1cdbd2cSJim Jagielski 		sal_Bool bRead  = sal_Bool( nId == SBX_HINT_DATAWANTED );
2122*b1cdbd2cSJim Jagielski 		sal_Bool bWrite = sal_Bool( nId == SBX_HINT_DATACHANGED );
2123*b1cdbd2cSJim Jagielski 		sal_Bool bRequestInfo = sal_Bool( nId == SBX_HINT_INFOWANTED );
2124*b1cdbd2cSJim Jagielski 		SbxVariable* pVar = p->GetVar();
2125*b1cdbd2cSJim Jagielski 		SbxArray* pArg = pVar->GetParameters();
2126*b1cdbd2cSJim Jagielski 		XubString aVarName( pVar->GetName() );
2127*b1cdbd2cSJim Jagielski 		if( bRead || bWrite )
2128*b1cdbd2cSJim Jagielski 		{
2129*b1cdbd2cSJim Jagielski 			if( pVar->GetHashCode() == nCountHash
2130*b1cdbd2cSJim Jagielski 				  && aVarName.EqualsIgnoreCaseAscii( pCountStr ) )
2131*b1cdbd2cSJim Jagielski 				pVar->PutLong( xItemArray->Count32() );
2132*b1cdbd2cSJim Jagielski 			else if( pVar->GetHashCode() == nAddHash
2133*b1cdbd2cSJim Jagielski 				  && aVarName.EqualsIgnoreCaseAscii( pAddStr ) )
2134*b1cdbd2cSJim Jagielski 				CollAdd( pArg );
2135*b1cdbd2cSJim Jagielski 			else if( pVar->GetHashCode() == nItemHash
2136*b1cdbd2cSJim Jagielski 				  && aVarName.EqualsIgnoreCaseAscii( pItemStr ) )
2137*b1cdbd2cSJim Jagielski 				CollItem( pArg );
2138*b1cdbd2cSJim Jagielski 			else if( pVar->GetHashCode() == nRemoveHash
2139*b1cdbd2cSJim Jagielski 				  && aVarName.EqualsIgnoreCaseAscii( pRemoveStr ) )
2140*b1cdbd2cSJim Jagielski 				CollRemove( pArg );
2141*b1cdbd2cSJim Jagielski 			else
2142*b1cdbd2cSJim Jagielski 				SbxObject::SFX_NOTIFY( rCst, rId1, rHint, rId2 );
2143*b1cdbd2cSJim Jagielski 			return;
2144*b1cdbd2cSJim Jagielski 		}
2145*b1cdbd2cSJim Jagielski 		else if ( bRequestInfo )
2146*b1cdbd2cSJim Jagielski 		{
2147*b1cdbd2cSJim Jagielski 			if( pVar->GetHashCode() == nAddHash
2148*b1cdbd2cSJim Jagielski 				  && aVarName.EqualsIgnoreCaseAscii( pAddStr ) )
2149*b1cdbd2cSJim Jagielski 				pVar->SetInfo( xAddInfo );
2150*b1cdbd2cSJim Jagielski 			else if( pVar->GetHashCode() == nItemHash
2151*b1cdbd2cSJim Jagielski 				  && aVarName.EqualsIgnoreCaseAscii( pItemStr ) )
2152*b1cdbd2cSJim Jagielski 				pVar->SetInfo( xItemInfo );
2153*b1cdbd2cSJim Jagielski 		}
2154*b1cdbd2cSJim Jagielski 	}
2155*b1cdbd2cSJim Jagielski 	SbxObject::SFX_NOTIFY( rCst, rId1, rHint, rId2 );
2156*b1cdbd2cSJim Jagielski }
2157*b1cdbd2cSJim Jagielski 
implGetIndex(SbxVariable * pIndexVar)2158*b1cdbd2cSJim Jagielski sal_Int32 BasicCollection::implGetIndex( SbxVariable* pIndexVar )
2159*b1cdbd2cSJim Jagielski {
2160*b1cdbd2cSJim Jagielski 	sal_Int32 nIndex = -1;
2161*b1cdbd2cSJim Jagielski 	if( pIndexVar->GetType() == SbxSTRING )
2162*b1cdbd2cSJim Jagielski 		nIndex = implGetIndexForName( pIndexVar->GetString() );
2163*b1cdbd2cSJim Jagielski 	else
2164*b1cdbd2cSJim Jagielski 		nIndex = pIndexVar->GetLong() - 1;
2165*b1cdbd2cSJim Jagielski 	return nIndex;
2166*b1cdbd2cSJim Jagielski }
2167*b1cdbd2cSJim Jagielski 
implGetIndexForName(const String & rName)2168*b1cdbd2cSJim Jagielski sal_Int32 BasicCollection::implGetIndexForName( const String& rName )
2169*b1cdbd2cSJim Jagielski {
2170*b1cdbd2cSJim Jagielski 	sal_Int32 nIndex = -1;
2171*b1cdbd2cSJim Jagielski 	sal_Int32 nCount = xItemArray->Count32();
2172*b1cdbd2cSJim Jagielski 	sal_Int32 nNameHash = MakeHashCode( rName );
2173*b1cdbd2cSJim Jagielski 	for( sal_Int32 i = 0 ; i < nCount ; i++ )
2174*b1cdbd2cSJim Jagielski 	{
2175*b1cdbd2cSJim Jagielski 		SbxVariable* pVar = xItemArray->Get32( i );
2176*b1cdbd2cSJim Jagielski 		if( pVar->GetHashCode() == nNameHash &&
2177*b1cdbd2cSJim Jagielski 			pVar->GetName().EqualsIgnoreCaseAscii( rName ) )
2178*b1cdbd2cSJim Jagielski 		{
2179*b1cdbd2cSJim Jagielski 			nIndex = i;
2180*b1cdbd2cSJim Jagielski 			break;
2181*b1cdbd2cSJim Jagielski 		}
2182*b1cdbd2cSJim Jagielski 	}
2183*b1cdbd2cSJim Jagielski 	return nIndex;
2184*b1cdbd2cSJim Jagielski }
2185*b1cdbd2cSJim Jagielski 
CollAdd(SbxArray * pPar_)2186*b1cdbd2cSJim Jagielski void BasicCollection::CollAdd( SbxArray* pPar_ )
2187*b1cdbd2cSJim Jagielski {
2188*b1cdbd2cSJim Jagielski 	sal_uInt16 nCount = pPar_->Count();
2189*b1cdbd2cSJim Jagielski 	if( nCount < 2 || nCount > 5 )
2190*b1cdbd2cSJim Jagielski 	{
2191*b1cdbd2cSJim Jagielski 		SetError( SbxERR_WRONG_ARGS );
2192*b1cdbd2cSJim Jagielski 		return;
2193*b1cdbd2cSJim Jagielski 	}
2194*b1cdbd2cSJim Jagielski 
2195*b1cdbd2cSJim Jagielski 	SbxVariable* pItem = pPar_->Get(1);
2196*b1cdbd2cSJim Jagielski 	if( pItem )
2197*b1cdbd2cSJim Jagielski 	{
2198*b1cdbd2cSJim Jagielski 		int nNextIndex;
2199*b1cdbd2cSJim Jagielski 		if( nCount < 4 )
2200*b1cdbd2cSJim Jagielski 		{
2201*b1cdbd2cSJim Jagielski 			nNextIndex = xItemArray->Count();
2202*b1cdbd2cSJim Jagielski 		}
2203*b1cdbd2cSJim Jagielski 		else
2204*b1cdbd2cSJim Jagielski 		{
2205*b1cdbd2cSJim Jagielski 			SbxVariable* pBefore = pPar_->Get(3);
2206*b1cdbd2cSJim Jagielski 			if( nCount == 5 )
2207*b1cdbd2cSJim Jagielski 			{
2208*b1cdbd2cSJim Jagielski 				if( !( pBefore->IsErr() || ( pBefore->GetType() == SbxEMPTY ) ) )
2209*b1cdbd2cSJim Jagielski 				{
2210*b1cdbd2cSJim Jagielski 					SetError( SbERR_BAD_ARGUMENT );
2211*b1cdbd2cSJim Jagielski 					return;
2212*b1cdbd2cSJim Jagielski 				}
2213*b1cdbd2cSJim Jagielski 				SbxVariable* pAfter = pPar_->Get(4);
2214*b1cdbd2cSJim Jagielski 				sal_Int32 nAfterIndex = implGetIndex( pAfter );
2215*b1cdbd2cSJim Jagielski 				if( nAfterIndex == -1 )
2216*b1cdbd2cSJim Jagielski 				{
2217*b1cdbd2cSJim Jagielski 					SetError( SbERR_BAD_ARGUMENT );
2218*b1cdbd2cSJim Jagielski 					return;
2219*b1cdbd2cSJim Jagielski 				}
2220*b1cdbd2cSJim Jagielski 				nNextIndex = nAfterIndex + 1;
2221*b1cdbd2cSJim Jagielski 			}
2222*b1cdbd2cSJim Jagielski 			else // if( nCount == 4 )
2223*b1cdbd2cSJim Jagielski 			{
2224*b1cdbd2cSJim Jagielski 				sal_Int32 nBeforeIndex = implGetIndex( pBefore );
2225*b1cdbd2cSJim Jagielski 				if( nBeforeIndex == -1 )
2226*b1cdbd2cSJim Jagielski 				{
2227*b1cdbd2cSJim Jagielski 					SetError( SbERR_BAD_ARGUMENT );
2228*b1cdbd2cSJim Jagielski 					return;
2229*b1cdbd2cSJim Jagielski 				}
2230*b1cdbd2cSJim Jagielski 				nNextIndex = nBeforeIndex;
2231*b1cdbd2cSJim Jagielski 			}
2232*b1cdbd2cSJim Jagielski 		}
2233*b1cdbd2cSJim Jagielski 
2234*b1cdbd2cSJim Jagielski 		SbxVariableRef pNewItem = new SbxVariable( *pItem );
2235*b1cdbd2cSJim Jagielski 		if( nCount >= 3 )
2236*b1cdbd2cSJim Jagielski 		{
2237*b1cdbd2cSJim Jagielski 			SbxVariable* pKey = pPar_->Get(2);
2238*b1cdbd2cSJim Jagielski 			if( !( pKey->IsErr() || ( pKey->GetType() == SbxEMPTY ) ) )
2239*b1cdbd2cSJim Jagielski 			{
2240*b1cdbd2cSJim Jagielski 				if( pKey->GetType() != SbxSTRING )
2241*b1cdbd2cSJim Jagielski 				{
2242*b1cdbd2cSJim Jagielski 					SetError( SbERR_BAD_ARGUMENT );
2243*b1cdbd2cSJim Jagielski 					return;
2244*b1cdbd2cSJim Jagielski 				}
2245*b1cdbd2cSJim Jagielski 				String aKey = pKey->GetString();
2246*b1cdbd2cSJim Jagielski 				if( implGetIndexForName( aKey ) != -1 )
2247*b1cdbd2cSJim Jagielski 				{
2248*b1cdbd2cSJim Jagielski 					SetError( SbERR_BAD_ARGUMENT );
2249*b1cdbd2cSJim Jagielski 					return;
2250*b1cdbd2cSJim Jagielski 				}
2251*b1cdbd2cSJim Jagielski 				pNewItem->SetName( aKey );
2252*b1cdbd2cSJim Jagielski 			}
2253*b1cdbd2cSJim Jagielski 		}
2254*b1cdbd2cSJim Jagielski 		pNewItem->SetFlag( SBX_READWRITE );
2255*b1cdbd2cSJim Jagielski 		xItemArray->Insert32( pNewItem, nNextIndex );
2256*b1cdbd2cSJim Jagielski 	}
2257*b1cdbd2cSJim Jagielski 	else
2258*b1cdbd2cSJim Jagielski 	{
2259*b1cdbd2cSJim Jagielski 		SetError( SbERR_BAD_ARGUMENT );
2260*b1cdbd2cSJim Jagielski 		return;
2261*b1cdbd2cSJim Jagielski 	}
2262*b1cdbd2cSJim Jagielski }
2263*b1cdbd2cSJim Jagielski 
CollItem(SbxArray * pPar_)2264*b1cdbd2cSJim Jagielski void BasicCollection::CollItem( SbxArray* pPar_ )
2265*b1cdbd2cSJim Jagielski {
2266*b1cdbd2cSJim Jagielski 	if( pPar_->Count() != 2 )
2267*b1cdbd2cSJim Jagielski 	{
2268*b1cdbd2cSJim Jagielski 		SetError( SbxERR_WRONG_ARGS );
2269*b1cdbd2cSJim Jagielski 		return;
2270*b1cdbd2cSJim Jagielski 	}
2271*b1cdbd2cSJim Jagielski 	SbxVariable* pRes = NULL;
2272*b1cdbd2cSJim Jagielski 	SbxVariable* p = pPar_->Get( 1 );
2273*b1cdbd2cSJim Jagielski 	sal_Int32 nIndex = implGetIndex( p );
2274*b1cdbd2cSJim Jagielski 	if( nIndex >= 0 && nIndex < (sal_Int32)xItemArray->Count32() )
2275*b1cdbd2cSJim Jagielski 		pRes = xItemArray->Get32( nIndex );
2276*b1cdbd2cSJim Jagielski 	if( !pRes )
2277*b1cdbd2cSJim Jagielski 		SetError( SbERR_BAD_ARGUMENT );
2278*b1cdbd2cSJim Jagielski 	else
2279*b1cdbd2cSJim Jagielski 		*(pPar_->Get(0)) = *pRes;
2280*b1cdbd2cSJim Jagielski }
2281*b1cdbd2cSJim Jagielski 
CollRemove(SbxArray * pPar_)2282*b1cdbd2cSJim Jagielski void BasicCollection::CollRemove( SbxArray* pPar_ )
2283*b1cdbd2cSJim Jagielski {
2284*b1cdbd2cSJim Jagielski 	if( pPar_ == NULL || pPar_->Count() != 2 )
2285*b1cdbd2cSJim Jagielski 	{
2286*b1cdbd2cSJim Jagielski 		SetError( SbxERR_WRONG_ARGS );
2287*b1cdbd2cSJim Jagielski 		return;
2288*b1cdbd2cSJim Jagielski 	}
2289*b1cdbd2cSJim Jagielski 
2290*b1cdbd2cSJim Jagielski 	SbxVariable* p = pPar_->Get( 1 );
2291*b1cdbd2cSJim Jagielski 	sal_Int32 nIndex = implGetIndex( p );
2292*b1cdbd2cSJim Jagielski 	if( nIndex >= 0 && nIndex < (sal_Int32)xItemArray->Count32() )
2293*b1cdbd2cSJim Jagielski 	{
2294*b1cdbd2cSJim Jagielski 		xItemArray->Remove32( nIndex );
2295*b1cdbd2cSJim Jagielski 
2296*b1cdbd2cSJim Jagielski 		// Correct for stack if necessary
2297*b1cdbd2cSJim Jagielski 		SbiInstance* pInst = pINST;
2298*b1cdbd2cSJim Jagielski 		SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
2299*b1cdbd2cSJim Jagielski 		if( pRT )
2300*b1cdbd2cSJim Jagielski 		{
2301*b1cdbd2cSJim Jagielski 			SbiForStack* pStack = pRT->FindForStackItemForCollection( this );
2302*b1cdbd2cSJim Jagielski 			if( pStack != NULL )
2303*b1cdbd2cSJim Jagielski 			{
2304*b1cdbd2cSJim Jagielski 				if( pStack->nCurCollectionIndex >= nIndex )
2305*b1cdbd2cSJim Jagielski 					--pStack->nCurCollectionIndex;
2306*b1cdbd2cSJim Jagielski 			}
2307*b1cdbd2cSJim Jagielski 		}
2308*b1cdbd2cSJim Jagielski 	}
2309*b1cdbd2cSJim Jagielski 	else
2310*b1cdbd2cSJim Jagielski 		SetError( SbERR_BAD_ARGUMENT );
2311*b1cdbd2cSJim Jagielski }
2312*b1cdbd2cSJim Jagielski 
2313