1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
24 #include <tools/rcid.h>
25 #include <tools/stream.hxx>
26 #include <tools/errinf.hxx>
27 #include <basic/sbx.hxx>
28 #include <tools/rc.hxx>
29 #include <vcl/svapp.hxx>
30 #include <comphelper/processfactory.hxx>
32 #include "sbunoobj.hxx"
33 #include "sbjsmeth.hxx"
34 #include "sbjsmod.hxx"
35 #include "sbintern.hxx"
36 #include "runtime.hxx"
37 #include <basic/sbuno.hxx>
38 #include <basic/sbobjmod.hxx>
40 #include "filefmt.hxx"
43 #include <osl/mutex.hxx>
44 #include <cppuhelper/implbase1.hxx>
45 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
46 #include <com/sun/star/util/XCloseBroadcaster.hpp>
47 #include <com/sun/star/util/XCloseListener.hpp>
48 #include "errobject.hxx"
49 #include <boost/unordered_map.hpp>
51 #include <com/sun/star/script/ModuleType.hpp>
52 #include <com/sun/star/script/ModuleInfo.hpp>
53 using namespace ::com::sun::star::script
;
55 TYPEINIT1(StarBASIC
,SbxObject
)
57 #define RTLNAME "@SBRTL"
59 using namespace ::com::sun::star
;
60 using namespace ::com::sun::star::uno
;
61 using com::sun::star::uno::Reference
;
62 using com::sun::star::uno::Any
;
63 using com::sun::star::uno::UNO_QUERY
;
64 using com::sun::star::lang::XMultiServiceFactory
;
66 // ============================================================================
68 class DocBasicItem
: public ::cppu::WeakImplHelper1
< util::XCloseListener
>
71 explicit DocBasicItem( StarBASIC
& rDocBasic
);
72 virtual ~DocBasicItem();
74 inline const SbxObjectRef
& getClassModules() const { return mxClassModules
; }
75 inline bool isDocClosed() const { return mbDocClosed
; }
77 void clearDependingVarsOnDelete( StarBASIC
& rDeletedBasic
);
79 void startListening();
82 virtual void SAL_CALL
queryClosing( const lang::EventObject
& rSource
, sal_Bool bGetsOwnership
) throw (util::CloseVetoException
, uno::RuntimeException
);
83 virtual void SAL_CALL
notifyClosing( const lang::EventObject
& rSource
) throw (uno::RuntimeException
);
84 virtual void SAL_CALL
disposing( const lang::EventObject
& rSource
) throw (uno::RuntimeException
);
87 StarBASIC
& mrDocBasic
;
88 SbxObjectRef mxClassModules
;
93 // ----------------------------------------------------------------------------
95 DocBasicItem::DocBasicItem( StarBASIC
& rDocBasic
) :
96 mrDocBasic( rDocBasic
),
97 mxClassModules( new SbxObject( OUString() ) ),
103 DocBasicItem::~DocBasicItem()
108 void DocBasicItem::clearDependingVarsOnDelete( StarBASIC
& rDeletedBasic
)
110 mrDocBasic
.implClearDependingVarsOnDelete( &rDeletedBasic
);
113 void DocBasicItem::startListening()
116 mrDocBasic
.GetUNOConstant( "ThisComponent", aThisComp
);
117 Reference
< util::XCloseBroadcaster
> xCloseBC( aThisComp
, UNO_QUERY
);
118 mbDisposed
= !xCloseBC
.is();
121 try { xCloseBC
->addCloseListener( this ); } catch(const uno::Exception
& ) {}
125 void DocBasicItem::stopListening()
127 if( mbDisposed
) return;
130 mrDocBasic
.GetUNOConstant( "ThisComponent", aThisComp
);
131 Reference
< util::XCloseBroadcaster
> xCloseBC( aThisComp
, UNO_QUERY
);
134 try { xCloseBC
->removeCloseListener( this ); } catch(const uno::Exception
& ) {}
138 void SAL_CALL
DocBasicItem::queryClosing( const lang::EventObject
& /*rSource*/, sal_Bool
/*bGetsOwnership*/ ) throw (util::CloseVetoException
, uno::RuntimeException
)
142 void SAL_CALL
DocBasicItem::notifyClosing( const lang::EventObject
& /*rEvent*/ ) throw (uno::RuntimeException
)
148 void SAL_CALL
DocBasicItem::disposing( const lang::EventObject
& /*rEvent*/ ) throw (uno::RuntimeException
)
153 // ----------------------------------------------------------------------------
157 typedef ::rtl::Reference
< DocBasicItem
> DocBasicItemRef
;
158 typedef boost::unordered_map
< const StarBASIC
*, DocBasicItemRef
> DocBasicItemMap
;
160 class GaDocBasicItems
: public rtl::Static
<DocBasicItemMap
,GaDocBasicItems
> {};
162 const DocBasicItem
* lclFindDocBasicItem( const StarBASIC
* pDocBasic
)
164 DocBasicItemMap::iterator it
= GaDocBasicItems::get().find( pDocBasic
);
165 DocBasicItemMap::iterator end
= GaDocBasicItems::get().end();
166 return (it
!= end
) ? it
->second
.get() : 0;
169 void lclInsertDocBasicItem( StarBASIC
& rDocBasic
)
171 DocBasicItemRef
& rxDocBasicItem
= GaDocBasicItems::get()[ &rDocBasic
];
172 rxDocBasicItem
.set( new DocBasicItem( rDocBasic
) );
173 rxDocBasicItem
->startListening();
176 void lclRemoveDocBasicItem( StarBASIC
& rDocBasic
)
178 DocBasicItemMap::iterator it
= GaDocBasicItems::get().find( &rDocBasic
);
179 if( it
!= GaDocBasicItems::get().end() )
181 it
->second
->stopListening();
182 GaDocBasicItems::get().erase( it
);
184 DocBasicItemMap::iterator it_end
= GaDocBasicItems::get().end();
185 for( it
= GaDocBasicItems::get().begin(); it
!= it_end
; ++it
)
187 it
->second
->clearDependingVarsOnDelete( rDocBasic
);
191 StarBASIC
* lclGetDocBasicForModule( SbModule
* pModule
)
193 StarBASIC
* pRetBasic
= NULL
;
194 SbxObject
* pCurParent
= pModule
;
195 while( pCurParent
->GetParent() != NULL
)
197 pCurParent
= pCurParent
->GetParent();
198 StarBASIC
* pDocBasic
= PTR_CAST( StarBASIC
, pCurParent
);
199 if( pDocBasic
!= NULL
&& pDocBasic
->IsDocBasic() )
201 pRetBasic
= pDocBasic
;
210 // ============================================================================
212 SbxObject
* StarBASIC::getVBAGlobals( )
217 if ( GetUNOConstant("ThisComponent", aThisDoc
) )
219 Reference
< XMultiServiceFactory
> xDocFac( aThisDoc
, UNO_QUERY
);
224 xDocFac
->createInstance( OUString( "ooo.vba.VBAGlobals" ) );
226 catch(const Exception
& )
232 const OUString
aVBAHook("VBAGlobals");
233 pVBAGlobals
= (SbUnoObject
*)Find( aVBAHook
, SbxCLASS_DONTCARE
);
239 SbxVariable
* StarBASIC::VBAFind( const OUString
& rName
, SbxClassType t
)
241 if( rName
== "ThisComponent" )
245 // rename to init globals
246 if ( getVBAGlobals( ) )
248 return pVBAGlobals
->Find( rName
, t
);
253 // Create array for conversion SFX <-> VB error code
254 struct SFX_VB_ErrorItem
260 const SFX_VB_ErrorItem SFX_VB_ErrorTab
[] =
262 { 1, SbERR_BASIC_EXCEPTION
}, // #87844 Map exception to error code 1
264 { 3, SbERR_NO_GOSUB
},
265 { 4, SbERR_REDO_FROM_START
},
266 { 5, SbERR_BAD_ARGUMENT
},
267 { 6, SbERR_MATH_OVERFLOW
},
268 { 7, SbERR_NO_MEMORY
},
269 { 8, SbERR_ALREADY_DIM
},
270 { 9, SbERR_OUT_OF_RANGE
},
271 { 10, SbERR_DUPLICATE_DEF
},
272 { 11, SbERR_ZERODIV
},
273 { 12, SbERR_VAR_UNDEFINED
},
274 { 13, SbERR_CONVERSION
},
275 { 14, SbERR_BAD_PARAMETER
},
276 { 18, SbERR_USER_ABORT
},
277 { 20, SbERR_BAD_RESUME
},
278 { 28, SbERR_STACK_OVERFLOW
},
279 { 35, SbERR_PROC_UNDEFINED
},
280 { 48, SbERR_BAD_DLL_LOAD
},
281 { 49, SbERR_BAD_DLL_CALL
},
282 { 51, SbERR_INTERNAL_ERROR
},
283 { 52, SbERR_BAD_CHANNEL
},
284 { 53, SbERR_FILE_NOT_FOUND
},
285 { 54, SbERR_BAD_FILE_MODE
},
286 { 55, SbERR_FILE_ALREADY_OPEN
},
287 { 57, SbERR_IO_ERROR
},
288 { 58, SbERR_FILE_EXISTS
},
289 { 59, SbERR_BAD_RECORD_LENGTH
},
290 { 61, SbERR_DISK_FULL
},
291 { 62, SbERR_READ_PAST_EOF
},
292 { 63, SbERR_BAD_RECORD_NUMBER
},
293 { 67, SbERR_TOO_MANY_FILES
},
294 { 68, SbERR_NO_DEVICE
},
295 { 70, SbERR_ACCESS_DENIED
},
296 { 71, SbERR_NOT_READY
},
297 { 73, SbERR_NOT_IMPLEMENTED
},
298 { 74, SbERR_DIFFERENT_DRIVE
},
299 { 75, SbERR_ACCESS_ERROR
},
300 { 76, SbERR_PATH_NOT_FOUND
},
301 { 91, SbERR_NO_OBJECT
},
302 { 93, SbERR_BAD_PATTERN
},
303 { 94, SBERR_IS_NULL
},
304 { 250, SbERR_DDE_ERROR
},
305 { 280, SbERR_DDE_WAITINGACK
},
306 { 281, SbERR_DDE_OUTOFCHANNELS
},
307 { 282, SbERR_DDE_NO_RESPONSE
},
308 { 283, SbERR_DDE_MULT_RESPONSES
},
309 { 284, SbERR_DDE_CHANNEL_LOCKED
},
310 { 285, SbERR_DDE_NOTPROCESSED
},
311 { 286, SbERR_DDE_TIMEOUT
},
312 { 287, SbERR_DDE_USER_INTERRUPT
},
313 { 288, SbERR_DDE_BUSY
},
314 { 289, SbERR_DDE_NO_DATA
},
315 { 290, SbERR_DDE_WRONG_DATA_FORMAT
},
316 { 291, SbERR_DDE_PARTNER_QUIT
},
317 { 292, SbERR_DDE_CONV_CLOSED
},
318 { 293, SbERR_DDE_NO_CHANNEL
},
319 { 294, SbERR_DDE_INVALID_LINK
},
320 { 295, SbERR_DDE_QUEUE_OVERFLOW
},
321 { 296, SbERR_DDE_LINK_ALREADY_EST
},
322 { 297, SbERR_DDE_LINK_INV_TOPIC
},
323 { 298, SbERR_DDE_DLL_NOT_FOUND
},
324 { 323, SbERR_CANNOT_LOAD
},
325 { 341, SbERR_BAD_INDEX
},
326 { 366, SbERR_NO_ACTIVE_OBJECT
},
327 { 380, SbERR_BAD_PROP_VALUE
},
328 { 382, SbERR_PROP_READONLY
},
329 { 394, SbERR_PROP_WRITEONLY
},
330 { 420, SbERR_INVALID_OBJECT
},
331 { 423, SbERR_NO_METHOD
},
332 { 424, SbERR_NEEDS_OBJECT
},
333 { 425, SbERR_INVALID_USAGE_OBJECT
},
334 { 430, SbERR_NO_OLE
},
335 { 438, SbERR_BAD_METHOD
},
336 { 440, SbERR_OLE_ERROR
},
337 { 445, SbERR_BAD_ACTION
},
338 { 446, SbERR_NO_NAMED_ARGS
},
339 { 447, SbERR_BAD_LOCALE
},
340 { 448, SbERR_NAMED_NOT_FOUND
},
341 { 449, SbERR_NOT_OPTIONAL
},
342 { 450, SbERR_WRONG_ARGS
},
343 { 451, SbERR_NOT_A_COLL
},
344 { 452, SbERR_BAD_ORDINAL
},
345 { 453, SbERR_DLLPROC_NOT_FOUND
},
346 { 460, SbERR_BAD_CLIPBD_FORMAT
},
347 { 951, SbERR_UNEXPECTED
},
348 { 952, SbERR_EXPECTED
},
349 { 953, SbERR_SYMBOL_EXPECTED
},
350 { 954, SbERR_VAR_EXPECTED
},
351 { 955, SbERR_LABEL_EXPECTED
},
352 { 956, SbERR_LVALUE_EXPECTED
},
353 { 957, SbERR_VAR_DEFINED
},
354 { 958, SbERR_PROC_DEFINED
},
355 { 959, SbERR_LABEL_DEFINED
},
356 { 960, SbERR_UNDEF_VAR
},
357 { 961, SbERR_UNDEF_ARRAY
},
358 { 962, SbERR_UNDEF_PROC
},
359 { 963, SbERR_UNDEF_LABEL
},
360 { 964, SbERR_UNDEF_TYPE
},
361 { 965, SbERR_BAD_EXIT
},
362 { 966, SbERR_BAD_BLOCK
},
363 { 967, SbERR_BAD_BRACKETS
},
364 { 968, SbERR_BAD_DECLARATION
},
365 { 969, SbERR_BAD_PARAMETERS
},
366 { 970, SbERR_BAD_CHAR_IN_NUMBER
},
367 { 971, SbERR_MUST_HAVE_DIMS
},
368 { 972, SbERR_NO_IF
},
369 { 973, SbERR_NOT_IN_SUBR
},
370 { 974, SbERR_NOT_IN_MAIN
},
371 { 975, SbERR_WRONG_DIMS
},
372 { 976, SbERR_BAD_OPTION
},
373 { 977, SbERR_CONSTANT_REDECLARED
},
374 { 978, SbERR_PROG_TOO_LARGE
},
375 { 979, SbERR_NO_STRINGS_ARRAYS
},
376 { 1000, SbERR_PROPERTY_NOT_FOUND
},
377 { 1001, SbERR_METHOD_NOT_FOUND
},
378 { 1002, SbERR_ARG_MISSING
},
379 { 1003, SbERR_BAD_NUMBER_OF_ARGS
},
380 { 1004, SbERR_METHOD_FAILED
},
381 { 1005, SbERR_SETPROP_FAILED
},
382 { 1006, SbERR_GETPROP_FAILED
},
383 { 1007, SbERR_BASIC_COMPAT
},
384 { 0xFFFF, 0xFFFFFFFFL
} // End mark
387 // The StarBASIC factory is a hack. When a SbModule is created, its pointer
388 // is saved and given to the following SbProperties/SbMethods. This restores
389 // the Modul-relationshop. But it works only when a modul is loaded.
390 // Can cause troubles with separately loaded properties!
392 SbxBase
* SbiFactory::Create( sal_uInt16 nSbxId
, sal_uInt32 nCreator
)
394 if( nCreator
== SBXCR_SBX
)
400 return new StarBASIC( NULL
);
402 return new SbModule( aEmpty
);
403 case SBXID_BASICPROP
:
404 return new SbProperty( aEmpty
, SbxVARIANT
, NULL
);
405 case SBXID_BASICMETHOD
:
406 return new SbMethod( aEmpty
, SbxVARIANT
, NULL
);
407 case SBXID_JSCRIPTMOD
:
408 return new SbJScriptModule( aEmpty
);
409 case SBXID_JSCRIPTMETH
:
410 return new SbJScriptMethod( aEmpty
, SbxVARIANT
, NULL
);
416 SbxObject
* SbiFactory::CreateObject( const OUString
& rClass
)
418 if( rClass
.equalsIgnoreAsciiCase( "StarBASIC" ) )
420 return new StarBASIC( NULL
);
422 else if( rClass
.equalsIgnoreAsciiCase( "StarBASICModule" ) )
424 return new SbModule( OUString() );
426 else if( rClass
.equalsIgnoreAsciiCase( "Collection" ) )
428 return new BasicCollection( OUString("Collection"));
430 else if( rClass
.equalsIgnoreAsciiCase( "FileSystemObject" ) )
434 Reference
< XMultiServiceFactory
> xFactory( comphelper::getProcessServiceFactory(), UNO_SET_THROW
);
435 OUString
aServiceName("ooo.vba.FileSystemObject");
436 Reference
< XInterface
> xInterface( xFactory
->createInstance( aServiceName
), UNO_SET_THROW
);
437 return new SbUnoObject( aServiceName
, uno::makeAny( xInterface
) );
439 catch(const Exception
& )
447 // Factory class to create OLE objects
448 class SbOLEFactory
: public SbxFactory
451 virtual SbxBase
* Create( sal_uInt16 nSbxId
, sal_uInt32
= SBXCR_SBX
);
452 virtual SbxObject
* CreateObject( const OUString
& );
455 SbxBase
* SbOLEFactory::Create( sal_uInt16
, sal_uInt32
)
461 SbUnoObject
* createOLEObject_Impl( const OUString
& aType
); // sbunoobj.cxx
463 SbxObject
* SbOLEFactory::CreateObject( const OUString
& rClassName
)
465 SbxObject
* pRet
= createOLEObject_Impl( rClassName
);
470 //========================================================================
471 // SbFormFactory, show user forms by: dim as new <user form name>
473 class SbFormFactory
: public SbxFactory
476 virtual SbxBase
* Create( sal_uInt16 nSbxId
, sal_uInt32
= SBXCR_SBX
);
477 virtual SbxObject
* CreateObject( const OUString
& );
480 SbxBase
* SbFormFactory::Create( sal_uInt16
, sal_uInt32
)
486 SbxObject
* SbFormFactory::CreateObject( const OUString
& rClassName
)
488 if( SbModule
* pMod
= GetSbData()->pMod
)
490 if( SbxVariable
* pVar
= pMod
->Find( rClassName
, SbxCLASS_OBJECT
) )
492 if( SbUserFormModule
* pFormModule
= PTR_CAST( SbUserFormModule
, pVar
->GetObject() ) )
494 bool bInitState
= pFormModule
->getInitState();
497 // Not the first instantiate, reset
498 bool bTriggerTerminateEvent
= false;
499 pFormModule
->ResetApiObj( bTriggerTerminateEvent
);
500 pFormModule
->setInitState( false );
506 return pFormModule
->CreateInstance();
514 //========================================================================
517 SbxObject
* cloneTypeObjectImpl( const SbxObject
& rTypeObj
)
519 SbxObject
* pRet
= new SbxObject( rTypeObj
);
520 pRet
->PutObject( pRet
);
522 // Copy the properties, not only the reference to them
523 SbxArray
* pProps
= pRet
->GetProperties();
524 sal_uInt32 nCount
= pProps
->Count32();
525 for( sal_uInt32 i
= 0 ; i
< nCount
; i
++ )
527 SbxVariable
* pVar
= pProps
->Get32( i
);
528 SbxProperty
* pProp
= PTR_CAST( SbxProperty
, pVar
);
531 SbxProperty
* pNewProp
= new SbxProperty( *pProp
);
532 SbxDataType eVarType
= pVar
->GetType();
533 if( eVarType
& SbxARRAY
)
535 SbxBase
* pParObj
= pVar
->GetObject();
536 SbxDimArray
* pSource
= PTR_CAST(SbxDimArray
,pParObj
);
537 SbxDimArray
* pDest
= new SbxDimArray( pVar
->GetType() );
539 pDest
->setHasFixedSize( pSource
->hasFixedSize() );
540 if ( pSource
->GetDims() && pSource
->hasFixedSize() )
544 for ( sal_Int32 j
= 1 ; j
<= pSource
->GetDims(); ++j
)
546 pSource
->GetDim32( (sal_Int32
)j
, lb
, ub
);
547 pDest
->AddDim32( lb
, ub
);
552 pDest
->unoAddDim( 0, -1 ); // variant array
554 sal_uInt16 nSavFlags
= pVar
->GetFlags();
555 pNewProp
->ResetFlag( SBX_FIXED
);
556 // need to reset the FIXED flag
557 // when calling PutObject ( because the type will not match Object )
558 pNewProp
->PutObject( pDest
);
559 pNewProp
->SetFlags( nSavFlags
);
561 if( eVarType
== SbxOBJECT
)
563 SbxBase
* pObjBase
= pVar
->GetObject();
564 SbxObject
* pSrcObj
= PTR_CAST(SbxObject
,pObjBase
);
565 SbxObject
* pDestObj
= NULL
;
566 if( pSrcObj
!= NULL
)
567 pDestObj
= cloneTypeObjectImpl( *pSrcObj
);
568 pNewProp
->PutObject( pDestObj
);
570 pProps
->PutDirect( pNewProp
, i
);
576 // Factory class to create user defined objects (type command)
577 class SbTypeFactory
: public SbxFactory
580 virtual SbxBase
* Create( sal_uInt16 nSbxId
, sal_uInt32
= SBXCR_SBX
);
581 virtual SbxObject
* CreateObject( const OUString
& );
584 SbxBase
* SbTypeFactory::Create( sal_uInt16
, sal_uInt32
)
590 SbxObject
* SbTypeFactory::CreateObject( const OUString
& rClassName
)
592 SbxObject
* pRet
= NULL
;
593 SbModule
* pMod
= GetSbData()->pMod
;
596 const SbxObject
* pObj
= pMod
->FindType( rClassName
);
599 pRet
= cloneTypeObjectImpl( *pObj
);
605 SbxObject
* createUserTypeImpl( const OUString
& rClassName
)
607 SbxObject
* pRetObj
= GetSbData()->pTypeFac
->CreateObject( rClassName
);
612 TYPEINIT1(SbClassModuleObject
,SbModule
)
614 SbClassModuleObject::SbClassModuleObject( SbModule
* pClassModule
)
615 : SbModule( pClassModule
->GetName() )
616 , mpClassModule( pClassModule
)
617 , mbInitializeEventDone( false )
619 aOUSource
= pClassModule
->aOUSource
;
620 aComment
= pClassModule
->aComment
;
621 pImage
= pClassModule
->pImage
;
622 pBreaks
= pClassModule
->pBreaks
;
624 SetClassName( pClassModule
->GetName() );
626 // Allow search only internally
627 ResetFlag( SBX_GBLSEARCH
);
629 // Copy the methods from original class module
630 SbxArray
* pClassMethods
= pClassModule
->GetMethods();
631 sal_uInt32 nMethodCount
= pClassMethods
->Count32();
633 for( i
= 0 ; i
< nMethodCount
; i
++ )
635 SbxVariable
* pVar
= pClassMethods
->Get32( i
);
637 // Exclude SbIfaceMapperMethod to copy them in a second step
638 SbIfaceMapperMethod
* pIfaceMethod
= PTR_CAST( SbIfaceMapperMethod
, pVar
);
641 SbMethod
* pMethod
= PTR_CAST(SbMethod
, pVar
);
644 sal_uInt16 nFlags_
= pMethod
->GetFlags();
645 pMethod
->SetFlag( SBX_NO_BROADCAST
);
646 SbMethod
* pNewMethod
= new SbMethod( *pMethod
);
647 pNewMethod
->ResetFlag( SBX_NO_BROADCAST
);
648 pMethod
->SetFlags( nFlags_
);
649 pNewMethod
->pMod
= this;
650 pNewMethod
->SetParent( this );
651 pMethods
->PutDirect( pNewMethod
, i
);
652 StartListening( pNewMethod
->GetBroadcaster(), sal_True
);
657 // Copy SbIfaceMapperMethod in a second step to ensure that
658 // the corresponding base methods have already been copied
659 for( i
= 0 ; i
< nMethodCount
; i
++ )
661 SbxVariable
* pVar
= pClassMethods
->Get32( i
);
663 SbIfaceMapperMethod
* pIfaceMethod
= PTR_CAST( SbIfaceMapperMethod
, pVar
);
666 SbMethod
* pImplMethod
= pIfaceMethod
->getImplMethod();
669 OSL_FAIL( "No ImplMethod" );
673 // Search for own copy of ImplMethod
674 SbxVariable
* p
= pMethods
->Find( pImplMethod
->GetName(), SbxCLASS_METHOD
);
675 SbMethod
* pImplMethodCopy
= p
? PTR_CAST(SbMethod
,p
) : NULL
;
676 if( !pImplMethodCopy
)
678 OSL_FAIL( "Found no ImplMethod copy" );
681 SbIfaceMapperMethod
* pNewIfaceMethod
=
682 new SbIfaceMapperMethod( pIfaceMethod
->GetName(), pImplMethodCopy
);
683 pMethods
->PutDirect( pNewIfaceMethod
, i
);
687 // Copy the properties from original class module
688 SbxArray
* pClassProps
= pClassModule
->GetProperties();
689 sal_uInt32 nPropertyCount
= pClassProps
->Count32();
690 for( i
= 0 ; i
< nPropertyCount
; i
++ )
692 SbxVariable
* pVar
= pClassProps
->Get32( i
);
693 SbProcedureProperty
* pProcedureProp
= PTR_CAST( SbProcedureProperty
, pVar
);
696 sal_uInt16 nFlags_
= pProcedureProp
->GetFlags();
697 pProcedureProp
->SetFlag( SBX_NO_BROADCAST
);
698 SbProcedureProperty
* pNewProp
= new SbProcedureProperty
699 ( pProcedureProp
->GetName(), pProcedureProp
->GetType() );
700 pNewProp
->SetFlags( nFlags_
); // Copy flags
701 pNewProp
->ResetFlag( SBX_NO_BROADCAST
); // except the Broadcast if it was set
702 pProcedureProp
->SetFlags( nFlags_
);
703 pProps
->PutDirect( pNewProp
, i
);
704 StartListening( pNewProp
->GetBroadcaster(), sal_True
);
708 SbxProperty
* pProp
= PTR_CAST( SbxProperty
, pVar
);
711 sal_uInt16 nFlags_
= pProp
->GetFlags();
712 pProp
->SetFlag( SBX_NO_BROADCAST
);
713 SbxProperty
* pNewProp
= new SbxProperty( *pProp
);
715 // Special handling for modules instances and collections, they need
716 // to be instantiated, otherwise all refer to the same base object
717 SbxDataType eVarType
= pProp
->GetType();
718 if( eVarType
== SbxOBJECT
)
720 SbxBase
* pObjBase
= pProp
->GetObject();
721 SbxObject
* pObj
= PTR_CAST(SbxObject
,pObjBase
);
724 OUString aObjClass
= pObj
->GetClassName();
726 SbClassModuleObject
* pClassModuleObj
= PTR_CAST(SbClassModuleObject
,pObjBase
);
727 if( pClassModuleObj
!= NULL
)
729 SbModule
* pLclClassModule
= pClassModuleObj
->getClassModule();
730 SbClassModuleObject
* pNewObj
= new SbClassModuleObject( pLclClassModule
);
731 pNewObj
->SetName( pProp
->GetName() );
732 pNewObj
->SetParent( pLclClassModule
->pParent
);
733 pNewProp
->PutObject( pNewObj
);
735 else if( aObjClass
.equalsIgnoreAsciiCase( "Collection" ) )
737 OUString
aCollectionName("Collection");
738 BasicCollection
* pNewCollection
= new BasicCollection( aCollectionName
);
739 pNewCollection
->SetName( pProp
->GetName() );
740 pNewCollection
->SetParent( pClassModule
->pParent
);
741 pNewProp
->PutObject( pNewCollection
);
746 pNewProp
->ResetFlag( SBX_NO_BROADCAST
);
747 pNewProp
->SetParent( this );
748 pProps
->PutDirect( pNewProp
, i
);
749 pProp
->SetFlags( nFlags_
);
753 SetModuleType( ModuleType::CLASS
);
754 mbVBACompat
= pClassModule
->mbVBACompat
;
757 SbClassModuleObject::~SbClassModuleObject()
759 // do not trigger termination event when document is already closed
760 if( StarBASIC::IsRunning() )
761 if( StarBASIC
* pDocBasic
= lclGetDocBasicForModule( this ) )
762 if( const DocBasicItem
* pDocBasicItem
= lclFindDocBasicItem( pDocBasic
) )
763 if( !pDocBasicItem
->isDocClosed() )
764 triggerTerminateEvent();
766 // Must be deleted by base class dtor because this data
767 // is not owned by the SbClassModuleObject object
772 void SbClassModuleObject::SFX_NOTIFY( SfxBroadcaster
& rBC
, const TypeId
& rBCType
,
773 const SfxHint
& rHint
, const TypeId
& rHintType
)
775 handleProcedureProperties( rBC
, rHint
);
778 SbxVariable
* SbClassModuleObject::Find( const OUString
& rName
, SbxClassType t
)
780 SbxVariable
* pRes
= SbxObject::Find( rName
, t
);
783 triggerInitializeEvent();
785 SbIfaceMapperMethod
* pIfaceMapperMethod
= PTR_CAST(SbIfaceMapperMethod
,pRes
);
786 if( pIfaceMapperMethod
)
788 pRes
= pIfaceMapperMethod
->getImplMethod();
789 pRes
->SetFlag( SBX_EXTFOUND
);
795 void SbClassModuleObject::triggerInitializeEvent( void )
797 if( mbInitializeEventDone
)
802 mbInitializeEventDone
= true;
805 SbxVariable
* pMeth
= SbxObject::Find(OUString("Class_Initialize"), SbxCLASS_METHOD
);
813 void SbClassModuleObject::triggerTerminateEvent( void )
815 if( !mbInitializeEventDone
|| GetSbData()->bRunInit
)
820 SbxVariable
* pMeth
= SbxObject::Find(OUString("Class_Terminate"), SbxCLASS_METHOD
);
829 SbClassData::SbClassData( void )
831 mxIfaces
= new SbxArray();
834 void SbClassData::clear( void )
837 maRequiredTypes
.clear();
840 SbClassFactory::SbClassFactory( void )
843 xClassModules
= new SbxObject( aDummyName
);
846 SbClassFactory::~SbClassFactory()
849 void SbClassFactory::AddClassModule( SbModule
* pClassModule
)
851 SbxObjectRef xToUseClassModules
= xClassModules
;
853 if( StarBASIC
* pDocBasic
= lclGetDocBasicForModule( pClassModule
) )
854 if( const DocBasicItem
* pDocBasicItem
= lclFindDocBasicItem( pDocBasic
) )
855 xToUseClassModules
= pDocBasicItem
->getClassModules();
857 SbxObject
* pParent
= pClassModule
->GetParent();
858 xToUseClassModules
->Insert( pClassModule
);
859 pClassModule
->SetParent( pParent
);
862 void SbClassFactory::RemoveClassModule( SbModule
* pClassModule
)
864 xClassModules
->Remove( pClassModule
);
867 SbxBase
* SbClassFactory::Create( sal_uInt16
, sal_uInt32
)
873 SbxObject
* SbClassFactory::CreateObject( const OUString
& rClassName
)
875 SbxObjectRef xToUseClassModules
= xClassModules
;
877 if( SbModule
* pMod
= GetSbData()->pMod
)
879 if( StarBASIC
* pDocBasic
= lclGetDocBasicForModule( pMod
) )
881 if( const DocBasicItem
* pDocBasicItem
= lclFindDocBasicItem( pDocBasic
) )
883 xToUseClassModules
= pDocBasicItem
->getClassModules();
887 SbxVariable
* pVar
= xToUseClassModules
->Find( rClassName
, SbxCLASS_OBJECT
);
888 SbxObject
* pRet
= NULL
;
891 SbModule
* pVarMod
= (SbModule
*)pVar
;
892 pRet
= new SbClassModuleObject( pVarMod
);
897 SbModule
* SbClassFactory::FindClass( const OUString
& rClassName
)
899 SbxVariable
* pVar
= xClassModules
->Find( rClassName
, SbxCLASS_DONTCARE
);
900 SbModule
* pMod
= pVar
? (SbModule
*)pVar
: NULL
;
904 StarBASIC::StarBASIC( StarBASIC
* p
, bool bIsDocBasic
)
905 : SbxObject( OUString("StarBASIC") ), bDocBasic( bIsDocBasic
)
909 bNoRtl
= bBreak
= false;
911 pModules
= new SbxArray
;
913 if( !GetSbData()->nInst
++ )
915 GetSbData()->pSbFac
= new SbiFactory
;
916 AddFactory( GetSbData()->pSbFac
);
917 GetSbData()->pTypeFac
= new SbTypeFactory
;
918 AddFactory( GetSbData()->pTypeFac
);
919 GetSbData()->pClassFac
= new SbClassFactory
;
920 AddFactory( GetSbData()->pClassFac
);
921 GetSbData()->pOLEFac
= new SbOLEFactory
;
922 AddFactory( GetSbData()->pOLEFac
);
923 GetSbData()->pFormFac
= new SbFormFactory
;
924 AddFactory( GetSbData()->pFormFac
);
925 GetSbData()->pUnoFac
= new SbUnoFactory
;
926 AddFactory( GetSbData()->pUnoFac
);
928 pRtl
= new SbiStdObject(OUString(RTLNAME
), this );
929 // Search via StarBasic is always global
930 SetFlag( SBX_GBLSEARCH
);
936 lclInsertDocBasicItem( *this );
940 // #51727 Override SetModified so that the modified state
941 // is not given to the parent
942 void StarBASIC::SetModified( sal_Bool b
)
944 SbxBase::SetModified( b
);
947 StarBASIC::~StarBASIC()
949 // Needs to be first action as it can trigger events
950 disposeComVariablesForBasic( this );
952 if( !--GetSbData()->nInst
)
954 RemoveFactory( GetSbData()->pSbFac
);
955 delete GetSbData()->pSbFac
; GetSbData()->pSbFac
= NULL
;
956 RemoveFactory( GetSbData()->pUnoFac
);
957 delete GetSbData()->pUnoFac
; GetSbData()->pUnoFac
= NULL
;
958 RemoveFactory( GetSbData()->pTypeFac
);
959 delete GetSbData()->pTypeFac
; GetSbData()->pTypeFac
= NULL
;
960 RemoveFactory( GetSbData()->pClassFac
);
961 delete GetSbData()->pClassFac
; GetSbData()->pClassFac
= NULL
;
962 RemoveFactory( GetSbData()->pOLEFac
);
963 delete GetSbData()->pOLEFac
; GetSbData()->pOLEFac
= NULL
;
964 RemoveFactory( GetSbData()->pFormFac
);
965 delete GetSbData()->pFormFac
; GetSbData()->pFormFac
= NULL
;
967 if( SbiGlobals::pGlobals
)
969 delete SbiGlobals::pGlobals
;
970 SbiGlobals::pGlobals
= 0;
975 SbxError eOld
= SbxBase::GetError();
977 lclRemoveDocBasicItem( *this );
979 SbxBase::ResetError();
980 if( eOld
!= SbxERR_OK
)
982 SbxBase::SetError( eOld
);
986 // #100326 Set Parent NULL in registered listeners
987 if( xUnoListeners
.Is() )
989 sal_uInt16 uCount
= xUnoListeners
->Count();
990 for( sal_uInt16 i
= 0 ; i
< uCount
; i
++ )
992 SbxVariable
* pListenerObj
= xUnoListeners
->Get( i
);
993 pListenerObj
->SetParent( NULL
);
995 xUnoListeners
= NULL
;
998 clearUnoMethodsForBasic( this );
1001 // Override new() operator, so that everyone can create a new instance
1002 void* StarBASIC::operator new( size_t n
)
1004 if( n
< sizeof( StarBASIC
) )
1006 n
= sizeof( StarBASIC
);
1008 return ::operator new( n
);
1011 void StarBASIC::operator delete( void* p
)
1013 ::operator delete( p
);
1016 void StarBASIC::implClearDependingVarsOnDelete( StarBASIC
* pDeletedBasic
)
1018 if( this != pDeletedBasic
)
1020 for( sal_uInt16 i
= 0; i
< pModules
->Count(); i
++ )
1022 SbModule
* p
= (SbModule
*)pModules
->Get( i
);
1023 p
->ClearVarsDependingOnDeletedBasic( pDeletedBasic
);
1027 for( sal_uInt16 nObj
= 0; nObj
< pObjs
->Count(); nObj
++ )
1029 SbxVariable
* pVar
= pObjs
->Get( nObj
);
1030 StarBASIC
* pBasic
= PTR_CAST(StarBASIC
,pVar
);
1031 if( pBasic
&& pBasic
!= pDeletedBasic
)
1033 pBasic
->implClearDependingVarsOnDelete( pDeletedBasic
);
1039 /**************************************************************************
1041 * Creation/Managment of modules
1043 **************************************************************************/
1045 SbModule
* StarBASIC::MakeModule( const OUString
& rName
, const OUString
& rSrc
)
1047 return MakeModule32( rName
, rSrc
);
1050 SbModule
* StarBASIC::MakeModule32( const OUString
& rName
, const OUString
& rSrc
)
1053 mInfo
.ModuleType
= ModuleType::NORMAL
;
1054 return MakeModule32( rName
, mInfo
, rSrc
);
1056 SbModule
* StarBASIC::MakeModule32( const OUString
& rName
, const ModuleInfo
& mInfo
, const OUString
& rSrc
)
1059 OSL_TRACE("create module %s type mInfo %d", OUStringToOString( rName
, RTL_TEXTENCODING_UTF8
).getStr(), mInfo
.ModuleType
);
1061 switch ( mInfo
.ModuleType
)
1063 case ModuleType::DOCUMENT
:
1064 // In theory we should be able to create Object modules
1065 // in ordinary basic ( in vba mode thought these are create
1066 // by the application/basic and not by the user )
1067 p
= new SbObjModule( rName
, mInfo
, isVBAEnabled() );
1069 case ModuleType::CLASS
:
1070 p
= new SbModule( rName
, isVBAEnabled() );
1071 p
->SetModuleType( ModuleType::CLASS
);
1073 case ModuleType::FORM
:
1074 p
= new SbUserFormModule( rName
, mInfo
, isVBAEnabled() );
1077 p
= new SbModule( rName
, isVBAEnabled() );
1080 p
->SetSource32( rSrc
);
1081 p
->SetParent( this );
1082 pModules
->Insert( p
, pModules
->Count() );
1083 SetModified( sal_True
);
1087 void StarBASIC::Insert( SbxVariable
* pVar
)
1089 if( pVar
->IsA( TYPE(SbModule
) ) )
1091 pModules
->Insert( pVar
, pModules
->Count() );
1092 pVar
->SetParent( this );
1093 StartListening( pVar
->GetBroadcaster(), sal_True
);
1097 sal_Bool bWasModified
= IsModified();
1098 SbxObject::Insert( pVar
);
1099 if( !bWasModified
&& pVar
->IsSet( SBX_DONTSTORE
) )
1101 SetModified( sal_False
);
1106 void StarBASIC::Remove( SbxVariable
* pVar
)
1108 if( pVar
->IsA( TYPE(SbModule
) ) )
1110 // #87540 Can be last reference!
1111 SbxVariableRef xVar
= pVar
;
1112 pModules
->Remove( pVar
);
1113 pVar
->SetParent( 0 );
1114 EndListening( pVar
->GetBroadcaster() );
1118 SbxObject::Remove( pVar
);
1122 sal_Bool
StarBASIC::Compile( SbModule
* pMod
)
1124 return pMod
? pMod
->Compile() : sal_False
;
1127 void StarBASIC::Clear()
1129 while( pModules
->Count() )
1131 pModules
->Remove( pModules
->Count() - 1 );
1135 SbModule
* StarBASIC::FindModule( const OUString
& rName
)
1137 for( sal_uInt16 i
= 0; i
< pModules
->Count(); i
++ )
1139 SbModule
* p
= (SbModule
*) pModules
->Get( i
);
1140 if( p
->GetName().equalsIgnoreAsciiCase( rName
) )
1149 struct ClassModuleRunInitItem
1151 SbModule
* m_pModule
;
1153 bool m_bRunInitDone
;
1155 ClassModuleRunInitItem( void )
1157 , m_bProcessing( false )
1158 , m_bRunInitDone( false )
1160 ClassModuleRunInitItem( SbModule
* pModule
)
1161 : m_pModule( pModule
)
1162 , m_bProcessing( false )
1163 , m_bRunInitDone( false )
1167 // Derive from unordered_map type instead of typedef
1168 // to allow forward declaration in sbmod.hxx
1169 class ModuleInitDependencyMap
: public
1170 boost::unordered_map
< OUString
, ClassModuleRunInitItem
,
1171 OUStringHash
, ::std::equal_to
< OUString
> >
1174 void SbModule::implProcessModuleRunInit( ModuleInitDependencyMap
& rMap
, ClassModuleRunInitItem
& rItem
)
1176 rItem
.m_bProcessing
= true;
1178 SbModule
* pModule
= rItem
.m_pModule
;
1179 if( pModule
->pClassData
!= NULL
)
1181 StringVector
& rReqTypes
= pModule
->pClassData
->maRequiredTypes
;
1182 if( rReqTypes
.size() > 0 )
1184 for( StringVector::iterator it
= rReqTypes
.begin() ; it
!= rReqTypes
.end() ; ++it
)
1186 OUString
& rStr
= *it
;
1188 // Is required type a class module?
1189 ModuleInitDependencyMap::iterator itFind
= rMap
.find( rStr
);
1190 if( itFind
!= rMap
.end() )
1192 ClassModuleRunInitItem
& rParentItem
= itFind
->second
;
1193 if( rParentItem
.m_bProcessing
)
1195 // TODO: raise error?
1196 OSL_FAIL( "Cyclic module dependency detected" );
1200 if( !rParentItem
.m_bRunInitDone
)
1202 implProcessModuleRunInit( rMap
, rParentItem
);
1210 rItem
.m_bRunInitDone
= true;
1211 rItem
.m_bProcessing
= false;
1214 // Run Init-Code of all modules (including inserted libraries)
1215 void StarBASIC::InitAllModules( StarBASIC
* pBasicNotToInit
)
1217 SolarMutexGuard guard
;
1220 for ( sal_uInt16 nMod
= 0; nMod
< pModules
->Count(); nMod
++ )
1222 SbModule
* pModule
= (SbModule
*)pModules
->Get( nMod
);
1223 if( !pModule
->IsCompiled() )
1228 // compile modules first then RunInit ( otherwise there is
1229 // can be order dependency, e.g. classmodule A has a member
1230 // of of type classmodule B and classmodule B hasn't been compiled yet )
1232 // Consider required types to init in right order. Class modules
1233 // that are required by other modules have to be initialized first.
1234 ModuleInitDependencyMap aMIDMap
;
1235 for ( sal_uInt16 nMod
= 0; nMod
< pModules
->Count(); nMod
++ )
1237 SbModule
* pModule
= (SbModule
*)pModules
->Get( nMod
);
1238 OUString aModuleName
= pModule
->GetName();
1239 if( pModule
->isProxyModule() )
1241 aMIDMap
[aModuleName
] = ClassModuleRunInitItem( pModule
);
1245 ModuleInitDependencyMap::iterator it
;
1246 for( it
= aMIDMap
.begin() ; it
!= aMIDMap
.end(); ++it
)
1248 ClassModuleRunInitItem
& rItem
= it
->second
;
1249 SbModule::implProcessModuleRunInit( aMIDMap
, rItem
);
1252 // Call RunInit on standard modules
1253 for ( sal_uInt16 nMod
= 0; nMod
< pModules
->Count(); nMod
++ )
1255 SbModule
* pModule
= (SbModule
*)pModules
->Get( nMod
);
1256 if( !pModule
->isProxyModule() )
1262 // Check all objects if they are BASIC,
1263 // if yes initialize
1264 for ( sal_uInt16 nObj
= 0; nObj
< pObjs
->Count(); nObj
++ )
1266 SbxVariable
* pVar
= pObjs
->Get( nObj
);
1267 StarBASIC
* pBasic
= PTR_CAST(StarBASIC
,pVar
);
1268 if( pBasic
&& pBasic
!= pBasicNotToInit
)
1270 pBasic
->InitAllModules();
1275 // #88329 Put modules back to not initialised state to
1276 // force reinitialisation at next start
1277 void StarBASIC::DeInitAllModules( void )
1279 // Deinit own modules
1280 for ( sal_uInt16 nMod
= 0; nMod
< pModules
->Count(); nMod
++ )
1282 SbModule
* pModule
= (SbModule
*)pModules
->Get( nMod
);
1283 if( pModule
->pImage
&& !pModule
->isProxyModule() && !pModule
->ISA(SbObjModule
) )
1285 pModule
->pImage
->bInit
= false;
1289 for ( sal_uInt16 nObj
= 0; nObj
< pObjs
->Count(); nObj
++ )
1291 SbxVariable
* pVar
= pObjs
->Get( nObj
);
1292 StarBASIC
* pBasic
= PTR_CAST(StarBASIC
,pVar
);
1295 pBasic
->DeInitAllModules();
1300 // This implementation at first searches within the runtime library,
1301 // then it looks for an element within one module. This moudle can be
1302 // a public var or an entrypoint. If it is not found and we look for a
1303 // method and a module with the given name is found the search continues
1304 // for entrypoint "Main".
1305 // If this fails again a conventional search over objects is performend.
1306 SbxVariable
* StarBASIC::Find( const OUString
& rName
, SbxClassType t
)
1308 SbxVariable
* pRes
= NULL
;
1309 SbModule
* pNamed
= NULL
;
1310 // "Extended" search in Runtime Lib
1311 // but only if SbiRuntime has not set the flag
1314 if( t
== SbxCLASS_DONTCARE
|| t
== SbxCLASS_OBJECT
)
1316 if( rName
.equalsIgnoreAsciiCase( RTLNAME
) )
1323 pRes
= ((SbiStdObject
*) (SbxObject
*) pRtl
)->Find( rName
, t
);
1327 pRes
->SetFlag( SBX_EXTFOUND
);
1333 for( sal_uInt16 i
= 0; i
< pModules
->Count(); i
++ )
1335 SbModule
* p
= (SbModule
*) pModules
->Get( i
);
1336 if( p
->IsVisible() )
1338 // Remember modul fpr Main() call
1339 // or is the name equal?!?
1340 if( p
->GetName().equalsIgnoreAsciiCase( rName
) )
1342 if( t
== SbxCLASS_OBJECT
|| t
== SbxCLASS_DONTCARE
)
1348 // Only variables qualified by the Module Name e.g. Sheet1.foo
1349 // should work for Documant && Class type Modules
1350 sal_Int32 nType
= p
->GetModuleType();
1351 if ( nType
== ModuleType::DOCUMENT
|| nType
== ModuleType::FORM
)
1355 // otherwise check if the element is available
1356 // unset GBLSEARCH-Flag (due to Rekursion)
1357 sal_uInt16 nGblFlag
= p
->GetFlags() & SBX_GBLSEARCH
;
1358 p
->ResetFlag( SBX_GBLSEARCH
);
1359 pRes
= p
->Find( rName
, t
);
1360 p
->SetFlag( nGblFlag
);
1368 OUString
aMainStr("Main");
1369 if( !pRes
&& pNamed
&& ( t
== SbxCLASS_METHOD
|| t
== SbxCLASS_DONTCARE
) &&
1370 !pNamed
->GetName().equalsIgnoreAsciiCase( aMainStr
) )
1372 pRes
= pNamed
->Find( aMainStr
, SbxCLASS_METHOD
);
1376 pRes
= SbxObject::Find( rName
, t
);
1381 sal_Bool
StarBASIC::Call( const OUString
& rName
, SbxArray
* pParam
)
1383 sal_Bool bRes
= SbxObject::Call( rName
, pParam
);
1386 SbxError eErr
= SbxBase::GetError();
1387 SbxBase::ResetError();
1388 if( eErr
!= SbxERR_OK
)
1390 RTError( (SbError
)eErr
, 0, 0, 0 );
1396 // Find method via name (e.g. query via BASIC IDE)
1397 SbxBase
* StarBASIC::FindSBXInCurrentScope( const OUString
& rName
)
1399 if( !GetSbData()->pInst
)
1403 if( !GetSbData()->pInst
->pRun
)
1407 return GetSbData()->pInst
->pRun
->FindElementExtern( rName
);
1410 void StarBASIC::QuitAndExitApplication()
1416 void StarBASIC::Stop()
1418 SbiInstance
* p
= GetSbData()->pInst
;
1426 bool StarBASIC::IsRunning()
1428 return GetSbData()->pInst
!= NULL
;
1431 /**************************************************************************
1433 * Debugging and error handling
1435 **************************************************************************/
1437 SbMethod
* StarBASIC::GetActiveMethod( sal_uInt16 nLevel
)
1439 if( GetSbData()->pInst
)
1441 return GetSbData()->pInst
->GetCaller( nLevel
);
1449 SbModule
* StarBASIC::GetActiveModule()
1451 if( GetSbData()->pInst
&& !IsCompilerError() )
1453 return GetSbData()->pInst
->GetActiveModule();
1457 return GetSbData()->pCompMod
;
1461 sal_uInt16
StarBASIC::BreakPoint( sal_Int32 l
, sal_Int32 c1
, sal_Int32 c2
)
1463 SetErrorData( 0, l
, c1
, c2
);
1465 if( GetSbData()->aBreakHdl
.IsSet() )
1467 return (sal_uInt16
) GetSbData()->aBreakHdl
.Call( this );
1475 sal_uInt16
StarBASIC::StepPoint( sal_Int32 l
, sal_Int32 c1
, sal_Int32 c2
)
1477 SetErrorData( 0, l
, c1
, c2
);
1479 if( GetSbData()->aBreakHdl
.IsSet() )
1481 return (sal_uInt16
) GetSbData()->aBreakHdl
.Call( this );
1489 sal_uInt16
StarBASIC::BreakHdl()
1491 return (sal_uInt16
) ( aBreakHdl
.IsSet() ? aBreakHdl
.Call( this ) : SbDEBUG_CONTINUE
);
1494 // Calls for error handler and break handler
1495 sal_uInt16
StarBASIC::GetLine() { return GetSbData()->nLine
; }
1496 sal_uInt16
StarBASIC::GetCol1() { return GetSbData()->nCol1
; }
1497 sal_uInt16
StarBASIC::GetCol2() { return GetSbData()->nCol2
; }
1499 // Specific to error handler
1500 SbError
StarBASIC::GetErrorCode() { return GetSbData()->nCode
; }
1501 const OUString
& StarBASIC::GetErrorText() { return GetSbData()->aErrMsg
; }
1502 bool StarBASIC::IsCompilerError() { return GetSbData()->bCompiler
; }
1505 // The mapping between the old and the new error codes take place by searching
1506 // through the table SFX_VB_ErrorTab[]. This is indeed not with good performance,
1507 // but it consumes much less memory than corresponding switch blocs.
1508 // Because the conversion of error codes has not to be fast. there is no
1509 // binary search by VB Error -> Error SFX.
1511 // Map back new error codes to old, Sbx-compatible
1512 sal_uInt16
StarBASIC::GetVBErrorCode( SbError nError
)
1514 sal_uInt16 nRet
= 0;
1516 if( SbiRuntime::isVBAEnabled() )
1520 case SbERR_BASIC_ARRAY_FIX
:
1522 case SbERR_BASIC_STRING_OVERFLOW
:
1524 case SbERR_BASIC_EXPR_TOO_COMPLEX
:
1526 case SbERR_BASIC_OPER_NOT_PERFORM
:
1528 case SbERR_BASIC_TOO_MANY_DLL
:
1530 case SbERR_BASIC_LOOP_NOT_INIT
:
1538 const SFX_VB_ErrorItem
* pErrItem
;
1539 sal_uInt16 nIndex
= 0;
1542 pErrItem
= SFX_VB_ErrorTab
+ nIndex
;
1543 if( pErrItem
->nErrorSFX
== nError
)
1545 nRet
= pErrItem
->nErrorVB
;
1550 while( pErrItem
->nErrorVB
!= 0xFFFF ); // up to end mark
1554 SbError
StarBASIC::GetSfxFromVBError( sal_uInt16 nError
)
1558 if( SbiRuntime::isVBAEnabled() )
1570 return SbERR_BASIC_ARRAY_FIX
;
1572 return SbERR_BASIC_STRING_OVERFLOW
;
1574 return SbERR_BASIC_EXPR_TOO_COMPLEX
;
1576 return SbERR_BASIC_OPER_NOT_PERFORM
;
1578 return SbERR_BASIC_TOO_MANY_DLL
;
1580 return SbERR_BASIC_LOOP_NOT_INIT
;
1585 const SFX_VB_ErrorItem
* pErrItem
;
1586 sal_uInt16 nIndex
= 0;
1589 pErrItem
= SFX_VB_ErrorTab
+ nIndex
;
1590 if( pErrItem
->nErrorVB
== nError
)
1592 nRet
= pErrItem
->nErrorSFX
;
1595 else if( pErrItem
->nErrorVB
> nError
)
1597 break; // couldn't found anymore
1601 while( pErrItem
->nErrorVB
!= 0xFFFF ); // up to end mark
1605 // set Error- / Break-data
1606 void StarBASIC::SetErrorData( SbError nCode
, sal_uInt16 nLine
,
1607 sal_uInt16 nCol1
, sal_uInt16 nCol2
)
1609 SbiGlobals
& aGlobals
= *GetSbData();
1610 aGlobals
.nCode
= nCode
;
1611 aGlobals
.nLine
= nLine
;
1612 aGlobals
.nCol1
= nCol1
;
1613 aGlobals
.nCol2
= nCol2
;
1616 //----------------------------------------------------------------
1617 // help class for access to string SubResource of a Resource.
1618 // Source: sfx2\source\doc\docfile.cxx (TLX)
1619 struct BasicStringList_Impl
: private Resource
1623 BasicStringList_Impl( ResId
& rErrIdP
, sal_uInt16 nId
)
1624 : Resource( rErrIdP
),aResId(nId
, *rErrIdP
.GetResMgr() ){}
1625 ~BasicStringList_Impl() { FreeResource(); }
1627 OUString
GetString(){ return aResId
.toString(); }
1628 sal_Bool
IsErrorTextAvailable( void )
1629 { return IsAvailableRes(aResId
.SetRT(RSC_STRING
)); }
1631 //----------------------------------------------------------------
1633 void StarBASIC::MakeErrorText( SbError nId
, const OUString
& aMsg
)
1635 SolarMutexGuard aSolarGuard
;
1636 sal_uInt16 nOldID
= GetVBErrorCode( nId
);
1638 // intantiate the help class
1639 BasResId
aId( RID_BASIC_START
);
1640 BasicStringList_Impl
aMyStringList( aId
, sal_uInt16(nId
& ERRCODE_RES_MASK
) );
1642 if( aMyStringList
.IsErrorTextAvailable() )
1644 // merge message with additional text
1645 OUStringBuffer
aMsg1(aMyStringList
.GetString());
1646 // replace argument placeholder with %s
1647 OUString
aSrgStr( "$(ARG1)" );
1648 sal_Int32 nResult
= aMyStringList
.GetString().indexOf( aSrgStr
);
1652 aMsg1
.remove(nResult
, aSrgStr
.getLength());
1653 aMsg1
.insert(nResult
, aMsg
);
1655 GetSbData()->aErrMsg
= aMsg1
.makeStringAndClear();
1657 else if( nOldID
!= 0 )
1659 OUString aStdMsg
= "Fehler " + OUString::number(nOldID
) +
1660 ": Kein Fehlertext verfuegbar!";
1661 GetSbData()->aErrMsg
= aStdMsg
;
1665 GetSbData()->aErrMsg
= "";
1669 sal_Bool
StarBASIC::CError( SbError code
, const OUString
& rMsg
,
1670 sal_Int32 l
, sal_Int32 c1
, sal_Int32 c2
)
1672 SolarMutexGuard aSolarGuard
;
1674 // compiler error during runtime -> stop programm
1677 // #109018 Check if running Basic is affected
1678 StarBASIC
* pStartedBasic
= GetSbData()->pInst
->GetBasic();
1679 if( pStartedBasic
!= this )
1686 // set flag, so that GlobalRunInit notice the error
1687 GetSbData()->bGlobalInitErr
= true;
1689 // tinker the error message
1690 MakeErrorText( code
, rMsg
);
1692 // Implementation of the code for the string transport to SFX-Error
1693 if( !rMsg
.isEmpty() )
1695 code
= (sal_uIntPtr
)*new StringErrorInfo( code
, rMsg
);
1697 SetErrorData( code
, l
, c1
, c2
);
1698 GetSbData()->bCompiler
= true;
1700 if( GetSbData()->aErrHdl
.IsSet() )
1702 bRet
= (sal_Bool
) GetSbData()->aErrHdl
.Call( this );
1708 GetSbData()->bCompiler
= false; // only true for error handler
1712 sal_Bool
StarBASIC::RTError( SbError code
, sal_Int32 l
, sal_Int32 c1
, sal_Int32 c2
)
1714 return RTError( code
, OUString(), l
, c1
, c2
);
1717 sal_Bool
StarBASIC::RTError( SbError code
, const OUString
& rMsg
, sal_Int32 l
, sal_Int32 c1
, sal_Int32 c2
)
1719 SolarMutexGuard aSolarGuard
;
1722 if( (c
& ERRCODE_CLASS_MASK
) == ERRCODE_CLASS_COMPILER
)
1726 MakeErrorText( c
, rMsg
);
1728 // Implementation of the code for the string transport to SFX-Error
1729 if( !rMsg
.isEmpty() )
1731 // very confusing, even though MakeErrorText sets up the error text
1732 // seems that this is not used ( if rMsg already has content )
1733 // In the case of VBA MakeErrorText also formats the error to be alittle more
1734 // like vba ( adds an error number etc )
1735 if ( SbiRuntime::isVBAEnabled() && ( code
== SbERR_BASIC_COMPAT
) )
1737 OUString aTmp
= "\'" + OUString::valueOf(SbxErrObject::getUnoErrObject()->getNumber()) +
1738 "\'\n" + OUString(!GetSbData()->aErrMsg
.isEmpty() ? GetSbData()->aErrMsg
: rMsg
);
1739 code
= (sal_uIntPtr
)*new StringErrorInfo( code
, aTmp
);
1743 code
= (sal_uIntPtr
)*new StringErrorInfo( code
, rMsg
);
1747 SetErrorData( code
, l
, c1
, c2
);
1748 if( GetSbData()->aErrHdl
.IsSet() )
1750 return (sal_Bool
) GetSbData()->aErrHdl
.Call( this );
1758 void StarBASIC::Error( SbError n
)
1760 Error( n
, OUString() );
1763 void StarBASIC::Error( SbError n
, const OUString
& rMsg
)
1765 if( GetSbData()->pInst
)
1767 GetSbData()->pInst
->Error( n
, rMsg
);
1771 void StarBASIC::FatalError( SbError n
)
1773 if( GetSbData()->pInst
)
1775 GetSbData()->pInst
->FatalError( n
);
1779 void StarBASIC::FatalError( SbError _errCode
, const OUString
& _details
)
1781 if( GetSbData()->pInst
)
1783 GetSbData()->pInst
->FatalError( _errCode
, _details
);
1787 SbError
StarBASIC::GetErrBasic()
1789 if( GetSbData()->pInst
)
1791 return GetSbData()->pInst
->GetErr();
1799 // make the additional message for the RTL function error accessible
1800 OUString
StarBASIC::GetErrorMsg()
1802 if( GetSbData()->pInst
)
1804 return GetSbData()->pInst
->GetErrorMsg();
1812 sal_Int32
StarBASIC::GetErl()
1814 if( GetSbData()->pInst
)
1816 return GetSbData()->pInst
->GetErl();
1824 sal_Bool
StarBASIC::ErrorHdl()
1826 return (sal_Bool
) ( aErrorHdl
.IsSet()
1827 ? aErrorHdl
.Call( this ) : sal_False
);
1830 Link
StarBASIC::GetGlobalErrorHdl()
1832 return GetSbData()->aErrHdl
;
1835 void StarBASIC::SetGlobalErrorHdl( const Link
& rLink
)
1837 GetSbData()->aErrHdl
= rLink
;
1840 void StarBASIC::SetGlobalBreakHdl( const Link
& rLink
)
1842 GetSbData()->aBreakHdl
= rLink
;
1845 SbxArrayRef
StarBASIC::getUnoListeners( void )
1847 if( !xUnoListeners
.Is() )
1849 xUnoListeners
= new SbxArray();
1851 return xUnoListeners
;
1855 /**************************************************************************
1859 **************************************************************************/
1861 sal_Bool
StarBASIC::LoadData( SvStream
& r
, sal_uInt16 nVer
)
1863 if( !SbxObject::LoadData( r
, nVer
) )
1867 // #95459 Delete dialogs, otherwise endless recursion
1868 // in SbxVarable::GetType() if dialogs are accessed
1869 sal_uInt16 nObjCount
= pObjs
->Count();
1870 SbxVariable
** ppDeleteTab
= new SbxVariable
*[ nObjCount
];
1873 for( nObj
= 0 ; nObj
< nObjCount
; nObj
++ )
1875 SbxVariable
* pVar
= pObjs
->Get( nObj
);
1876 StarBASIC
* pBasic
= PTR_CAST( StarBASIC
, pVar
);
1877 ppDeleteTab
[nObj
] = pBasic
? NULL
: pVar
;
1879 for( nObj
= 0 ; nObj
< nObjCount
; nObj
++ )
1881 SbxVariable
* pVar
= ppDeleteTab
[nObj
];
1884 pObjs
->Remove( pVar
);
1887 delete[] ppDeleteTab
;
1892 for( sal_uInt16 i
= 0; i
< nMod
; i
++ )
1894 SbModule
* pMod
= (SbModule
*) SbxBase::Load( r
);
1899 else if( pMod
->ISA(SbJScriptModule
) )
1901 // assign Ref, so that pMod will be deleted
1902 SbModuleRef xRef
= pMod
;
1906 pMod
->SetParent( this );
1907 pModules
->Put( pMod
, i
);
1910 // HACK for SFX-Bullshit!
1911 SbxVariable
* p
= Find( OUString("FALSE"), SbxCLASS_PROPERTY
);
1916 p
= Find( OUString("TRUE"), SbxCLASS_PROPERTY
);
1921 // End of the hacks!
1922 // Search via StarBASIC is at all times global
1923 DBG_ASSERT( IsSet( SBX_GBLSEARCH
), "Basic loaded without GBLSEARCH" );
1924 SetFlag( SBX_GBLSEARCH
);
1928 sal_Bool
StarBASIC::StoreData( SvStream
& r
) const
1930 if( !SbxObject::StoreData( r
) )
1934 r
<< (sal_uInt16
) pModules
->Count();
1935 for( sal_uInt16 i
= 0; i
< pModules
->Count(); i
++ )
1937 SbModule
* p
= (SbModule
*) pModules
->Get( i
);
1938 if( !p
->Store( r
) )
1946 bool StarBASIC::GetUNOConstant( const sal_Char
* _pAsciiName
, ::com::sun::star::uno::Any
& aOut
)
1949 OUString
sVarName( OUString::createFromAscii( _pAsciiName
) );
1950 SbUnoObject
* pGlobs
= dynamic_cast<SbUnoObject
*>( Find( sVarName
, SbxCLASS_DONTCARE
) );
1953 aOut
= pGlobs
->getUnoAny();
1959 Reference
< frame::XModel
> StarBASIC::GetModelFromBasic( SbxObject
* pBasic
)
1961 OSL_PRECOND( pBasic
!= NULL
, "getModelFromBasic: illegal call!" );
1966 // look for the ThisComponent variable, first in the parent (which
1967 // might be the document's Basic), then in the parent's parent (which might be
1968 // the application Basic)
1969 const OUString
sThisComponent( "ThisComponent");
1970 SbxVariable
* pThisComponent
= NULL
;
1972 SbxObject
* pLookup
= pBasic
->GetParent();
1973 while ( pLookup
&& !pThisComponent
)
1975 pThisComponent
= pLookup
->Find( sThisComponent
, SbxCLASS_OBJECT
);
1976 pLookup
= pLookup
->GetParent();
1978 if ( !pThisComponent
)
1980 OSL_TRACE("Failed to get ThisComponent");
1981 // the application Basic, at the latest, should have this variable
1985 Any
aThisComponentAny( sbxToUnoValue( pThisComponent
) );
1986 Reference
< frame::XModel
> xModel( aThisComponentAny
, UNO_QUERY
);
1989 // it's no XModel. Okay, ThisComponent nowadays is allowed to be a controller.
1990 Reference
< frame::XController
> xController( aThisComponentAny
, UNO_QUERY
);
1991 if ( xController
.is() )
1993 xModel
= xController
->getModel();
2000 #if OSL_DEBUG_LEVEL > 0
2001 OSL_TRACE("Have model ThisComponent points to url %s",
2002 OUStringToOString( xModel
->getURL(),
2003 RTL_TEXTENCODING_ASCII_US
).pData
->buffer
);
2010 //========================================================================
2011 // #118116 Implementation Collection object
2013 TYPEINIT1(BasicCollection
,SbxObject
)
2015 static const char pCountStr
[] = "Count";
2016 static const char pAddStr
[] = "Add";
2017 static const char pItemStr
[] = "Item";
2018 static const char pRemoveStr
[] = "Remove";
2019 static sal_uInt16 nCountHash
= 0, nAddHash
, nItemHash
, nRemoveHash
;
2021 SbxInfoRef
BasicCollection::xAddInfo
= NULL
;
2022 SbxInfoRef
BasicCollection::xItemInfo
= NULL
;
2024 BasicCollection::BasicCollection( const OUString
& rClass
)
2025 : SbxObject( rClass
)
2029 nCountHash
= MakeHashCode( OUString::createFromAscii( pCountStr
) );
2030 nAddHash
= MakeHashCode( OUString::createFromAscii( pAddStr
) );
2031 nItemHash
= MakeHashCode( OUString::createFromAscii( pItemStr
) );
2032 nRemoveHash
= MakeHashCode( OUString::createFromAscii( pRemoveStr
) );
2038 BasicCollection::~BasicCollection()
2041 void BasicCollection::Clear()
2047 void BasicCollection::Initialize()
2049 xItemArray
= new SbxArray();
2050 SetType( SbxOBJECT
);
2051 SetFlag( SBX_FIXED
);
2052 ResetFlag( SBX_WRITE
);
2054 p
= Make( OUString::createFromAscii( pCountStr
), SbxCLASS_PROPERTY
, SbxINTEGER
);
2055 p
->ResetFlag( SBX_WRITE
);
2056 p
->SetFlag( SBX_DONTSTORE
);
2057 p
= Make( OUString::createFromAscii( pAddStr
), SbxCLASS_METHOD
, SbxEMPTY
);
2058 p
->SetFlag( SBX_DONTSTORE
);
2059 p
= Make( OUString::createFromAscii( pItemStr
), SbxCLASS_METHOD
, SbxVARIANT
);
2060 p
->SetFlag( SBX_DONTSTORE
);
2061 p
= Make( OUString::createFromAscii( pRemoveStr
), SbxCLASS_METHOD
, SbxEMPTY
);
2062 p
->SetFlag( SBX_DONTSTORE
);
2063 if ( !xAddInfo
.Is() )
2065 xAddInfo
= new SbxInfo
;
2066 xAddInfo
->AddParam( OUString( "Item" ), SbxVARIANT
, SBX_READ
);
2067 xAddInfo
->AddParam( OUString( "Key" ), SbxVARIANT
, SBX_READ
| SBX_OPTIONAL
);
2068 xAddInfo
->AddParam( OUString( "Before" ), SbxVARIANT
, SBX_READ
| SBX_OPTIONAL
);
2069 xAddInfo
->AddParam( OUString( "After" ), SbxVARIANT
, SBX_READ
| SBX_OPTIONAL
);
2071 if ( !xItemInfo
.Is() )
2073 xItemInfo
= new SbxInfo
;
2074 xItemInfo
->AddParam( OUString( "Index" ), SbxVARIANT
, SBX_READ
| SBX_OPTIONAL
);
2078 SbxVariable
* BasicCollection::Find( const OUString
& rName
, SbxClassType t
)
2080 SbxVariable
* pFind
= SbxObject::Find( rName
, t
);
2084 void BasicCollection::SFX_NOTIFY( SfxBroadcaster
& rCst
, const TypeId
& rId1
,
2085 const SfxHint
& rHint
, const TypeId
& rId2
)
2087 const SbxHint
* p
= PTR_CAST(SbxHint
,&rHint
);
2090 sal_uIntPtr nId
= p
->GetId();
2091 sal_Bool bRead
= sal_Bool( nId
== SBX_HINT_DATAWANTED
);
2092 sal_Bool bWrite
= sal_Bool( nId
== SBX_HINT_DATACHANGED
);
2093 sal_Bool bRequestInfo
= sal_Bool( nId
== SBX_HINT_INFOWANTED
);
2094 SbxVariable
* pVar
= p
->GetVar();
2095 SbxArray
* pArg
= pVar
->GetParameters();
2096 OUString
aVarName( pVar
->GetName() );
2097 if( bRead
|| bWrite
)
2099 if( pVar
->GetHashCode() == nCountHash
2100 && aVarName
.equalsIgnoreAsciiCaseAscii( pCountStr
) )
2102 pVar
->PutLong( xItemArray
->Count32() );
2104 else if( pVar
->GetHashCode() == nAddHash
2105 && aVarName
.equalsIgnoreAsciiCaseAscii( pAddStr
) )
2109 else if( pVar
->GetHashCode() == nItemHash
2110 && aVarName
.equalsIgnoreAsciiCaseAscii( pItemStr
) )
2114 else if( pVar
->GetHashCode() == nRemoveHash
2115 && aVarName
.equalsIgnoreAsciiCaseAscii( pRemoveStr
) )
2121 SbxObject::SFX_NOTIFY( rCst
, rId1
, rHint
, rId2
);
2125 else if ( bRequestInfo
)
2127 if( pVar
->GetHashCode() == nAddHash
2128 && aVarName
.equalsIgnoreAsciiCaseAscii( pAddStr
) )
2130 pVar
->SetInfo( xAddInfo
);
2132 else if( pVar
->GetHashCode() == nItemHash
2133 && aVarName
.equalsIgnoreAsciiCaseAscii( pItemStr
) )
2135 pVar
->SetInfo( xItemInfo
);
2139 SbxObject::SFX_NOTIFY( rCst
, rId1
, rHint
, rId2
);
2142 sal_Int32
BasicCollection::implGetIndex( SbxVariable
* pIndexVar
)
2144 sal_Int32 nIndex
= -1;
2145 if( pIndexVar
->GetType() == SbxSTRING
)
2147 nIndex
= implGetIndexForName( pIndexVar
->GetOUString() );
2151 nIndex
= pIndexVar
->GetLong() - 1;
2156 sal_Int32
BasicCollection::implGetIndexForName( const OUString
& rName
)
2158 sal_Int32 nIndex
= -1;
2159 sal_Int32 nCount
= xItemArray
->Count32();
2160 sal_Int32 nNameHash
= MakeHashCode( rName
);
2161 for( sal_Int32 i
= 0 ; i
< nCount
; i
++ )
2163 SbxVariable
* pVar
= xItemArray
->Get32( i
);
2164 if( pVar
->GetHashCode() == nNameHash
&&
2165 pVar
->GetName().equalsIgnoreAsciiCase( rName
) )
2174 void BasicCollection::CollAdd( SbxArray
* pPar_
)
2176 sal_uInt16 nCount
= pPar_
->Count();
2177 if( nCount
< 2 || nCount
> 5 )
2179 SetError( SbxERR_WRONG_ARGS
);
2183 SbxVariable
* pItem
= pPar_
->Get(1);
2189 nNextIndex
= xItemArray
->Count();
2193 SbxVariable
* pBefore
= pPar_
->Get(3);
2196 if( !( pBefore
->IsErr() || ( pBefore
->GetType() == SbxEMPTY
) ) )
2198 SetError( SbERR_BAD_ARGUMENT
);
2201 SbxVariable
* pAfter
= pPar_
->Get(4);
2202 sal_Int32 nAfterIndex
= implGetIndex( pAfter
);
2203 if( nAfterIndex
== -1 )
2205 SetError( SbERR_BAD_ARGUMENT
);
2208 nNextIndex
= nAfterIndex
+ 1;
2210 else // if( nCount == 4 )
2212 sal_Int32 nBeforeIndex
= implGetIndex( pBefore
);
2213 if( nBeforeIndex
== -1 )
2215 SetError( SbERR_BAD_ARGUMENT
);
2218 nNextIndex
= nBeforeIndex
;
2222 SbxVariableRef pNewItem
= new SbxVariable( *pItem
);
2225 SbxVariable
* pKey
= pPar_
->Get(2);
2226 if( !( pKey
->IsErr() || ( pKey
->GetType() == SbxEMPTY
) ) )
2228 if( pKey
->GetType() != SbxSTRING
)
2230 SetError( SbERR_BAD_ARGUMENT
);
2233 OUString aKey
= pKey
->GetOUString();
2234 if( implGetIndexForName( aKey
) != -1 )
2236 SetError( SbERR_BAD_ARGUMENT
);
2239 pNewItem
->SetName( aKey
);
2242 pNewItem
->SetFlag( SBX_READWRITE
);
2243 xItemArray
->Insert32( pNewItem
, nNextIndex
);
2247 SetError( SbERR_BAD_ARGUMENT
);
2252 void BasicCollection::CollItem( SbxArray
* pPar_
)
2254 if( pPar_
->Count() != 2 )
2256 SetError( SbxERR_WRONG_ARGS
);
2259 SbxVariable
* pRes
= NULL
;
2260 SbxVariable
* p
= pPar_
->Get( 1 );
2261 sal_Int32 nIndex
= implGetIndex( p
);
2262 if( nIndex
>= 0 && nIndex
< (sal_Int32
)xItemArray
->Count32() )
2264 pRes
= xItemArray
->Get32( nIndex
);
2268 SetError( SbERR_BAD_ARGUMENT
);
2272 *(pPar_
->Get(0)) = *pRes
;
2276 void BasicCollection::CollRemove( SbxArray
* pPar_
)
2278 if( pPar_
== NULL
|| pPar_
->Count() != 2 )
2280 SetError( SbxERR_WRONG_ARGS
);
2284 SbxVariable
* p
= pPar_
->Get( 1 );
2285 sal_Int32 nIndex
= implGetIndex( p
);
2286 if( nIndex
>= 0 && nIndex
< (sal_Int32
)xItemArray
->Count32() )
2288 xItemArray
->Remove32( nIndex
);
2290 // Correct for stack if necessary
2291 SbiInstance
* pInst
= GetSbData()->pInst
;
2292 SbiRuntime
* pRT
= pInst
? pInst
->pRun
: NULL
;
2295 SbiForStack
* pStack
= pRT
->FindForStackItemForCollection( this );
2296 if( pStack
!= NULL
)
2298 if( pStack
->nCurCollectionIndex
>= nIndex
)
2300 --pStack
->nCurCollectionIndex
;
2307 SetError( SbERR_BAD_ARGUMENT
);
2311 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */