Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include <list>
22 :
23 : #include <vcl/svapp.hxx>
24 : #include <tools/stream.hxx>
25 : #include <svl/brdcst.hxx>
26 : #include <tools/shl.hxx>
27 : #include <basic/sbx.hxx>
28 : #include "sbdiagnose.hxx"
29 : #include "sb.hxx"
30 : #include <sbjsmeth.hxx>
31 : #include "sbjsmod.hxx"
32 : #include "sbintern.hxx"
33 : #include "image.hxx"
34 : #include "opcodes.hxx"
35 : #include "runtime.hxx"
36 : #include "token.hxx"
37 : #include "sbunoobj.hxx"
38 :
39 : #include <svtools/syntaxhighlight.hxx>
40 :
41 : #include <basic/basrdll.hxx>
42 : #include <osl/mutex.hxx>
43 : #include <basic/sbobjmod.hxx>
44 : #include <basic/vbahelper.hxx>
45 : #include <cppuhelper/implbase3.hxx>
46 : #include <unotools/eventcfg.hxx>
47 : #include <com/sun/star/lang/XServiceInfo.hpp>
48 : #include <com/sun/star/script/ModuleType.hpp>
49 : #include <com/sun/star/script/vba/XVBACompatibility.hpp>
50 : #include <com/sun/star/script/vba/VBAScriptEventId.hpp>
51 : #include <com/sun/star/beans/XPropertySet.hpp>
52 : #include <com/sun/star/document/XEventBroadcaster.hpp>
53 : #include <com/sun/star/document/XEventListener.hpp>
54 :
55 : using namespace com::sun::star;
56 :
57 : // for the bsearch
58 : #ifdef WNT
59 : #define CDECL _cdecl
60 : #endif
61 : #if defined(UNX)
62 : #define CDECL
63 : #endif
64 : #ifdef UNX
65 : #include <sys/resource.h>
66 : #endif
67 :
68 : #include <stdio.h>
69 : #include <com/sun/star/frame/XDesktop.hpp>
70 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
71 : #include <comphelper/processfactory.hxx>
72 : #include <map>
73 : #include <com/sun/star/reflection/ProxyFactory.hpp>
74 : #include <cppuhelper/implbase1.hxx>
75 : #include <com/sun/star/uno/XAggregation.hpp>
76 : #include <com/sun/star/script/XInvocation.hpp>
77 :
78 : using namespace ::com::sun::star;
79 : using namespace com::sun::star::lang;
80 : using namespace com::sun::star::reflection;
81 : using namespace com::sun::star::beans;
82 : using namespace com::sun::star::script;
83 :
84 :
85 : #include <com/sun/star/script/XLibraryContainer.hpp>
86 : #include <com/sun/star/awt/XDialogProvider.hpp>
87 : #include <com/sun/star/awt/XTopWindow.hpp>
88 : #include <com/sun/star/awt/XWindow.hpp>
89 : #include <com/sun/star/awt/XControl.hpp>
90 : #include <comphelper/anytostring.hxx>
91 : #include <ooo/vba/VbQueryClose.hpp>
92 :
93 : typedef ::cppu::WeakImplHelper1< XInvocation > DocObjectWrapper_BASE;
94 : typedef ::std::map< sal_Int16, Any, ::std::less< sal_Int16 > > OutParamMap;
95 : ::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar );
96 : void unoToSbxValue( SbxVariable* pVar, const ::com::sun::star::uno::Any& aValue );
97 :
98 : class DocObjectWrapper : public DocObjectWrapper_BASE
99 : {
100 : Reference< XAggregation > m_xAggProxy;
101 : Reference< XInvocation > m_xAggInv;
102 : Reference< XTypeProvider > m_xAggregateTypeProv;
103 : Sequence< Type > m_Types;
104 : SbModule* m_pMod;
105 : SbMethodRef getMethod( const OUString& aName ) throw (RuntimeException);
106 : SbPropertyRef getProperty( const OUString& aName ) throw (RuntimeException);
107 : OUString mName; // for debugging
108 :
109 : public:
110 : DocObjectWrapper( SbModule* pMod );
111 : virtual ~DocObjectWrapper();
112 :
113 : virtual void SAL_CALL acquire() throw();
114 : virtual void SAL_CALL release() throw();
115 :
116 22 : virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (RuntimeException)
117 : {
118 22 : if( !m_xAggregateTypeProv.is() )
119 0 : throw RuntimeException();
120 22 : return m_xAggregateTypeProv->getImplementationId();
121 : }
122 :
123 : virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection( ) throw (RuntimeException);
124 :
125 : virtual Any SAL_CALL invoke( const OUString& aFunctionName, const Sequence< Any >& aParams, Sequence< ::sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) throw (IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException);
126 : virtual void SAL_CALL setValue( const OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException);
127 : virtual Any SAL_CALL getValue( const OUString& aPropertyName ) throw (UnknownPropertyException, RuntimeException);
128 : virtual ::sal_Bool SAL_CALL hasMethod( const OUString& aName ) throw (RuntimeException);
129 : virtual ::sal_Bool SAL_CALL hasProperty( const OUString& aName ) throw (RuntimeException);
130 : virtual Any SAL_CALL queryInterface( const Type& aType ) throw ( RuntimeException );
131 :
132 : virtual Sequence< Type > SAL_CALL getTypes() throw ( RuntimeException );
133 : };
134 :
135 8 : DocObjectWrapper::DocObjectWrapper( SbModule* pVar ) : m_pMod( pVar ), mName( pVar->GetName() )
136 : {
137 8 : SbObjModule* pMod = PTR_CAST(SbObjModule,pVar);
138 8 : if ( pMod )
139 : {
140 8 : if ( pMod->GetModuleType() == ModuleType::DOCUMENT )
141 : {
142 : // Use proxy factory service to create aggregatable proxy.
143 8 : SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pMod->GetObject() );
144 8 : Reference< XInterface > xIf;
145 8 : if ( pUnoObj )
146 : {
147 8 : Any aObj = pUnoObj->getUnoAny();
148 8 : aObj >>= xIf;
149 8 : if ( xIf.is() )
150 : {
151 8 : m_xAggregateTypeProv.set( xIf, UNO_QUERY );
152 8 : m_xAggInv.set( xIf, UNO_QUERY );
153 8 : }
154 : }
155 8 : if ( xIf.is() )
156 : {
157 : try
158 : {
159 8 : Reference< XProxyFactory > xProxyFac = ProxyFactory::create( comphelper::getProcessComponentContext() );
160 8 : m_xAggProxy = xProxyFac->createProxy( xIf );
161 : }
162 0 : catch(const Exception& )
163 : {
164 : OSL_FAIL( "DocObjectWrapper::DocObjectWrapper: Caught exception!" );
165 : }
166 : }
167 :
168 8 : if ( m_xAggProxy.is() )
169 : {
170 8 : osl_atomic_increment( &m_refCount );
171 :
172 : /* i35609 - Fix crash on Solaris. The setDelegator call needs
173 : to be in its own block to ensure that all temporary Reference
174 : instances that are acquired during the call are released
175 : before m_refCount is decremented again */
176 : {
177 8 : m_xAggProxy->setDelegator( static_cast< cppu::OWeakObject * >( this ) );
178 : }
179 :
180 8 : osl_atomic_decrement( &m_refCount );
181 8 : }
182 : }
183 : }
184 8 : }
185 :
186 : void SAL_CALL
187 6462 : DocObjectWrapper::acquire() throw ()
188 : {
189 6462 : osl_atomic_increment( &m_refCount );
190 : OSL_TRACE("DocObjectWrapper::acquire(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount );
191 6462 : }
192 : void SAL_CALL
193 6462 : DocObjectWrapper::release() throw ()
194 : {
195 6462 : if ( osl_atomic_decrement( &m_refCount ) == 0 )
196 : {
197 : OSL_TRACE("DocObjectWrapper::release(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount );
198 8 : delete this;
199 : }
200 : else
201 : {
202 : OSL_TRACE("DocObjectWrapper::release(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount );
203 : }
204 6462 : }
205 :
206 16 : DocObjectWrapper::~DocObjectWrapper()
207 : {
208 16 : }
209 :
210 22 : Sequence< Type > SAL_CALL DocObjectWrapper::getTypes()
211 : throw ( RuntimeException )
212 : {
213 22 : if ( m_Types.getLength() == 0 )
214 : {
215 2 : Sequence< Type > sTypes;
216 2 : if ( m_xAggregateTypeProv.is() )
217 : {
218 2 : sTypes = m_xAggregateTypeProv->getTypes();
219 : }
220 2 : m_Types.realloc( sTypes.getLength() + 1 );
221 2 : Type* pPtr = m_Types.getArray();
222 10 : for ( int i=0; i<m_Types.getLength(); ++i, ++pPtr )
223 : {
224 8 : if ( i == 0 )
225 : {
226 2 : *pPtr = XInvocation::static_type( NULL );
227 : }
228 : else
229 : {
230 6 : *pPtr = sTypes[ i - 1 ];
231 : }
232 2 : }
233 : }
234 22 : return m_Types;
235 : }
236 :
237 : Reference< XIntrospectionAccess > SAL_CALL
238 0 : DocObjectWrapper::getIntrospection( ) throw (RuntimeException)
239 : {
240 0 : return NULL;
241 : }
242 :
243 : Any SAL_CALL
244 0 : DocObjectWrapper::invoke( const OUString& aFunctionName, const Sequence< Any >& aParams, Sequence< ::sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) throw (IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException)
245 : {
246 0 : if ( m_xAggInv.is() && m_xAggInv->hasMethod( aFunctionName ) )
247 0 : return m_xAggInv->invoke( aFunctionName, aParams, aOutParamIndex, aOutParam );
248 0 : SbMethodRef pMethod = getMethod( aFunctionName );
249 0 : if ( !pMethod )
250 0 : throw RuntimeException();
251 : // check number of parameters
252 0 : sal_Int32 nParamsCount = aParams.getLength();
253 0 : SbxInfo* pInfo = pMethod->GetInfo();
254 0 : if ( pInfo )
255 : {
256 0 : sal_Int32 nSbxOptional = 0;
257 0 : sal_uInt16 n = 1;
258 0 : for ( const SbxParamInfo* pParamInfo = pInfo->GetParam( n ); pParamInfo; pParamInfo = pInfo->GetParam( ++n ) )
259 : {
260 0 : if ( ( pParamInfo->nFlags & SBX_OPTIONAL ) != 0 )
261 0 : ++nSbxOptional;
262 : else
263 0 : nSbxOptional = 0;
264 : }
265 0 : sal_Int32 nSbxCount = n - 1;
266 0 : if ( nParamsCount < nSbxCount - nSbxOptional )
267 : {
268 0 : throw RuntimeException( OUString( "wrong number of parameters!" ), Reference< XInterface >() );
269 : }
270 : }
271 : // set parameters
272 0 : SbxArrayRef xSbxParams;
273 0 : if ( nParamsCount > 0 )
274 : {
275 0 : xSbxParams = new SbxArray;
276 0 : const Any* pParams = aParams.getConstArray();
277 0 : for ( sal_Int32 i = 0; i < nParamsCount; ++i )
278 : {
279 0 : SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT );
280 0 : unoToSbxValue( static_cast< SbxVariable* >( xSbxVar ), pParams[i] );
281 0 : xSbxParams->Put( xSbxVar, static_cast< sal_uInt16 >( i ) + 1 );
282 :
283 : // Enable passing by ref
284 0 : if ( xSbxVar->GetType() != SbxVARIANT )
285 0 : xSbxVar->SetFlag( SBX_FIXED );
286 0 : }
287 : }
288 0 : if ( xSbxParams.Is() )
289 0 : pMethod->SetParameters( xSbxParams );
290 :
291 : // call method
292 0 : SbxVariableRef xReturn = new SbxVariable;
293 :
294 0 : pMethod->Call( xReturn );
295 0 : Any aReturn;
296 : // get output parameters
297 0 : if ( xSbxParams.Is() )
298 : {
299 0 : SbxInfo* pInfo_ = pMethod->GetInfo();
300 0 : if ( pInfo_ )
301 : {
302 0 : OutParamMap aOutParamMap;
303 0 : for ( sal_uInt16 n = 1, nCount = xSbxParams->Count(); n < nCount; ++n )
304 : {
305 0 : const SbxParamInfo* pParamInfo = pInfo_->GetParam( n );
306 0 : if ( pParamInfo && ( pParamInfo->eType & SbxBYREF ) != 0 )
307 : {
308 0 : SbxVariable* pVar = xSbxParams->Get( n );
309 0 : if ( pVar )
310 : {
311 0 : SbxVariableRef xVar = pVar;
312 0 : aOutParamMap.insert( OutParamMap::value_type( n - 1, sbxToUnoValue( xVar ) ) );
313 : }
314 : }
315 : }
316 0 : sal_Int32 nOutParamCount = aOutParamMap.size();
317 0 : aOutParamIndex.realloc( nOutParamCount );
318 0 : aOutParam.realloc( nOutParamCount );
319 0 : sal_Int16* pOutParamIndex = aOutParamIndex.getArray();
320 0 : Any* pOutParam = aOutParam.getArray();
321 0 : for ( OutParamMap::iterator aIt = aOutParamMap.begin(); aIt != aOutParamMap.end(); ++aIt, ++pOutParamIndex, ++pOutParam )
322 : {
323 0 : *pOutParamIndex = aIt->first;
324 0 : *pOutParam = aIt->second;
325 0 : }
326 : }
327 : }
328 :
329 : // get return value
330 0 : aReturn = sbxToUnoValue( xReturn );
331 :
332 0 : pMethod->SetParameters( NULL );
333 :
334 0 : return aReturn;
335 : }
336 :
337 : void SAL_CALL
338 0 : DocObjectWrapper::setValue( const OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException)
339 : {
340 0 : if ( m_xAggInv.is() && m_xAggInv->hasProperty( aPropertyName ) )
341 0 : return m_xAggInv->setValue( aPropertyName, aValue );
342 :
343 0 : SbPropertyRef pProperty = getProperty( aPropertyName );
344 0 : if ( !pProperty.Is() )
345 0 : throw UnknownPropertyException();
346 0 : unoToSbxValue( (SbxVariable*) pProperty, aValue );
347 : }
348 :
349 : Any SAL_CALL
350 0 : DocObjectWrapper::getValue( const OUString& aPropertyName ) throw (UnknownPropertyException, RuntimeException)
351 : {
352 0 : if ( m_xAggInv.is() && m_xAggInv->hasProperty( aPropertyName ) )
353 0 : return m_xAggInv->getValue( aPropertyName );
354 :
355 0 : SbPropertyRef pProperty = getProperty( aPropertyName );
356 0 : if ( !pProperty.Is() )
357 0 : throw UnknownPropertyException();
358 :
359 0 : SbxVariable* pProp = ( SbxVariable* ) pProperty;
360 0 : if ( pProp->GetType() == SbxEMPTY )
361 0 : pProperty->Broadcast( SBX_HINT_DATAWANTED );
362 :
363 0 : Any aRet = sbxToUnoValue( pProp );
364 0 : return aRet;
365 : }
366 :
367 : ::sal_Bool SAL_CALL
368 0 : DocObjectWrapper::hasMethod( const OUString& aName ) throw (RuntimeException)
369 : {
370 0 : if ( m_xAggInv.is() && m_xAggInv->hasMethod( aName ) )
371 0 : return sal_True;
372 0 : return getMethod( aName ).Is();
373 : }
374 :
375 : ::sal_Bool SAL_CALL
376 0 : DocObjectWrapper::hasProperty( const OUString& aName ) throw (RuntimeException)
377 : {
378 0 : sal_Bool bRes = sal_False;
379 0 : if ( m_xAggInv.is() && m_xAggInv->hasProperty( aName ) )
380 0 : bRes = sal_True;
381 0 : else bRes = getProperty( aName ).Is();
382 0 : return bRes;
383 : }
384 :
385 1748 : Any SAL_CALL DocObjectWrapper::queryInterface( const Type& aType )
386 : throw ( RuntimeException )
387 : {
388 1748 : Any aRet = DocObjectWrapper_BASE::queryInterface( aType );
389 1748 : if ( aRet.hasValue() )
390 1012 : return aRet;
391 736 : else if ( m_xAggProxy.is() )
392 736 : aRet = m_xAggProxy->queryAggregation( aType );
393 736 : return aRet;
394 : }
395 :
396 0 : SbMethodRef DocObjectWrapper::getMethod( const OUString& aName ) throw (RuntimeException)
397 : {
398 0 : SbMethodRef pMethod = NULL;
399 0 : if ( m_pMod )
400 : {
401 0 : sal_uInt16 nSaveFlgs = m_pMod->GetFlags();
402 : // Limit search to this module
403 0 : m_pMod->ResetFlag( SBX_GBLSEARCH );
404 0 : pMethod = (SbMethod*) m_pMod->SbModule::Find( aName, SbxCLASS_METHOD );
405 0 : m_pMod->SetFlags( nSaveFlgs );
406 : }
407 :
408 0 : return pMethod;
409 : }
410 :
411 0 : SbPropertyRef DocObjectWrapper::getProperty( const OUString& aName ) throw (RuntimeException)
412 : {
413 0 : SbPropertyRef pProperty = NULL;
414 0 : if ( m_pMod )
415 : {
416 0 : sal_uInt16 nSaveFlgs = m_pMod->GetFlags();
417 : // Limit search to this module.
418 0 : m_pMod->ResetFlag( SBX_GBLSEARCH );
419 0 : pProperty = (SbProperty*)m_pMod->SbModule::Find( aName, SbxCLASS_PROPERTY );
420 0 : m_pMod->SetFlag( nSaveFlgs );
421 : }
422 :
423 0 : return pProperty;
424 : }
425 :
426 2604 : TYPEINIT1(SbModule,SbxObject)
427 3148 : TYPEINIT1(SbMethod,SbxMethod)
428 4350 : TYPEINIT1(SbProperty,SbxProperty)
429 916 : TYPEINIT1(SbProcedureProperty,SbxProperty)
430 0 : TYPEINIT1(SbJScriptModule,SbModule)
431 0 : TYPEINIT1(SbJScriptMethod,SbMethod)
432 284 : TYPEINIT1(SbObjModule,SbModule)
433 0 : TYPEINIT1(SbUserFormModule,SbObjModule)
434 :
435 124 : uno::Reference< frame::XModel > getDocumentModel( StarBASIC* pb )
436 : {
437 124 : uno::Reference< frame::XModel > xModel;
438 124 : if( pb && pb->IsDocBasic() )
439 : {
440 4 : uno::Any aDoc;
441 4 : if( pb->GetUNOConstant( "ThisComponent", aDoc ) )
442 4 : xModel.set( aDoc, uno::UNO_QUERY );
443 : }
444 124 : return xModel;
445 : }
446 :
447 74 : uno::Reference< vba::XVBACompatibility > getVBACompatibility( const uno::Reference< frame::XModel >& rxModel )
448 : {
449 74 : uno::Reference< vba::XVBACompatibility > xVBACompat;
450 : try
451 : {
452 74 : uno::Reference< beans::XPropertySet > xModelProps( rxModel, uno::UNO_QUERY_THROW );
453 4 : xVBACompat.set( xModelProps->getPropertyValue( OUString( "BasicLibraries" ) ), uno::UNO_QUERY );
454 : }
455 70 : catch(const uno::Exception& )
456 : {
457 : }
458 74 : return xVBACompat;
459 : }
460 :
461 70 : bool getDefaultVBAMode( StarBASIC* pb )
462 : {
463 70 : uno::Reference< vba::XVBACompatibility > xVBACompat = getVBACompatibility( getDocumentModel( pb ) );
464 70 : return xVBACompat.is() && xVBACompat->getVBACompatibilityMode();
465 : }
466 :
467 : class AsyncQuitHandler
468 : {
469 0 : AsyncQuitHandler() {}
470 : AsyncQuitHandler( const AsyncQuitHandler&);
471 : public:
472 0 : static AsyncQuitHandler& instance()
473 : {
474 0 : static AsyncQuitHandler dInst;
475 0 : return dInst;
476 : }
477 :
478 0 : void QuitApplication()
479 : {
480 0 : uno::Reference< lang::XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
481 0 : if ( xFactory.is() )
482 : {
483 0 : uno::Reference< frame::XDesktop > xDeskTop( xFactory->createInstance( OUString( "com.sun.star.frame.Desktop" ) ), uno::UNO_QUERY );
484 0 : if ( xDeskTop.is() )
485 0 : xDeskTop->terminate();
486 0 : }
487 0 : }
488 : DECL_LINK( OnAsyncQuit, void* );
489 : };
490 :
491 0 : IMPL_LINK( AsyncQuitHandler, OnAsyncQuit, void*, /*pNull*/ )
492 : {
493 0 : QuitApplication();
494 0 : return 0L;
495 : }
496 :
497 : // A Basic module has set EXTSEARCH, so that the elements, that the modul contains,
498 : // could be found from other module.
499 :
500 70 : SbModule::SbModule( const OUString& rName, sal_Bool bVBACompat )
501 : : SbxObject( OUString("StarBASICModule") ),
502 70 : pImage( NULL ), pBreaks( NULL ), pClassData( NULL ), mbVBACompat( bVBACompat ), pDocObject( NULL ), bIsProxyModule( false )
503 : {
504 70 : SetName( rName );
505 70 : SetFlag( SBX_EXTSEARCH | SBX_GBLSEARCH );
506 70 : SetModuleType( script::ModuleType::NORMAL );
507 :
508 : // #i92642: Set name property to intitial name
509 70 : SbxVariable* pNameProp = pProps->Find( OUString("Name"), SbxCLASS_PROPERTY );
510 70 : if( pNameProp != NULL )
511 : {
512 70 : pNameProp->PutString( GetName() );
513 : }
514 70 : }
515 :
516 196 : SbModule::~SbModule()
517 : {
518 : OSL_TRACE("Module named %s is destructing", rtl::OUStringToOString( GetName(), RTL_TEXTENCODING_UTF8 ).getStr() );
519 70 : delete pImage;
520 70 : delete pBreaks;
521 70 : delete pClassData;
522 70 : mxWrapper = NULL;
523 168 : }
524 :
525 : uno::Reference< script::XInvocation >
526 180 : SbModule::GetUnoModule()
527 : {
528 180 : if ( !mxWrapper.is() )
529 8 : mxWrapper = new DocObjectWrapper( this );
530 :
531 : OSL_TRACE("Module named %s returning wrapper mxWrapper (0x%x)", rtl::OUStringToOString( GetName(), RTL_TEXTENCODING_UTF8 ).getStr(), mxWrapper.get() );
532 180 : return mxWrapper;
533 : }
534 :
535 214 : sal_Bool SbModule::IsCompiled() const
536 : {
537 214 : return sal_Bool( pImage != 0 );
538 : }
539 :
540 12 : const SbxObject* SbModule::FindType( OUString aTypeName ) const
541 : {
542 12 : return pImage ? pImage->FindType( aTypeName ) : NULL;
543 : }
544 :
545 :
546 : // From the code generator: deletion of images and the oposite of validation for entries
547 :
548 108 : void SbModule::StartDefinitions()
549 : {
550 108 : delete pImage; pImage = NULL;
551 108 : if( pClassData )
552 0 : pClassData->clear();
553 :
554 : // methods and properties persist, but they are invalid;
555 : // at least are the information under certain conditions clogged
556 : sal_uInt16 i;
557 142 : for( i = 0; i < pMethods->Count(); i++ )
558 : {
559 34 : SbMethod* p = PTR_CAST(SbMethod,pMethods->Get( i ) );
560 34 : if( p )
561 34 : p->bInvalid = sal_True;
562 : }
563 432 : for( i = 0; i < pProps->Count(); )
564 : {
565 216 : SbProperty* p = PTR_CAST(SbProperty,pProps->Get( i ) );
566 216 : if( p )
567 0 : pProps->Remove( i );
568 : else
569 216 : i++;
570 : }
571 108 : }
572 :
573 : // request/create method
574 :
575 94 : SbMethod* SbModule::GetMethod( const OUString& rName, SbxDataType t )
576 : {
577 94 : SbxVariable* p = pMethods->Find( rName, SbxCLASS_METHOD );
578 94 : SbMethod* pMeth = p ? PTR_CAST(SbMethod,p) : NULL;
579 94 : if( p && !pMeth )
580 : {
581 0 : pMethods->Remove( p );
582 : }
583 94 : if( !pMeth )
584 : {
585 60 : pMeth = new SbMethod( rName, t, this );
586 60 : pMeth->SetParent( this );
587 60 : pMeth->SetFlags( SBX_READ );
588 60 : pMethods->Put( pMeth, pMethods->Count() );
589 60 : StartListening( pMeth->GetBroadcaster(), sal_True );
590 : }
591 : // The method is per default valid, because it could be
592 : // created from the compiler (code generator) as well.
593 94 : pMeth->bInvalid = sal_False;
594 94 : pMeth->ResetFlag( SBX_FIXED );
595 94 : pMeth->SetFlag( SBX_WRITE );
596 94 : pMeth->SetType( t );
597 94 : pMeth->ResetFlag( SBX_WRITE );
598 94 : if( t != SbxVARIANT )
599 : {
600 62 : pMeth->SetFlag( SBX_FIXED );
601 : }
602 94 : return pMeth;
603 : }
604 :
605 : // request/create property
606 :
607 8 : SbProperty* SbModule::GetProperty( const OUString& rName, SbxDataType t )
608 : {
609 8 : SbxVariable* p = pProps->Find( rName, SbxCLASS_PROPERTY );
610 8 : SbProperty* pProp = p ? PTR_CAST(SbProperty,p) : NULL;
611 8 : if( p && !pProp )
612 : {
613 0 : pProps->Remove( p );
614 : }
615 8 : if( !pProp )
616 : {
617 8 : pProp = new SbProperty( rName, t, this );
618 8 : pProp->SetFlag( SBX_READWRITE );
619 8 : pProp->SetParent( this );
620 8 : pProps->Put( pProp, pProps->Count() );
621 8 : StartListening( pProp->GetBroadcaster(), sal_True );
622 : }
623 8 : return pProp;
624 : }
625 :
626 0 : SbProcedureProperty* SbModule::GetProcedureProperty( const OUString& rName, SbxDataType t )
627 : {
628 0 : SbxVariable* p = pProps->Find( rName, SbxCLASS_PROPERTY );
629 0 : SbProcedureProperty* pProp = p ? PTR_CAST(SbProcedureProperty,p) : NULL;
630 0 : if( p && !pProp )
631 : {
632 0 : pProps->Remove( p );
633 : }
634 0 : if( !pProp )
635 : {
636 0 : pProp = new SbProcedureProperty( rName, t );
637 0 : pProp->SetFlag( SBX_READWRITE );
638 0 : pProp->SetParent( this );
639 0 : pProps->Put( pProp, pProps->Count() );
640 0 : StartListening( pProp->GetBroadcaster(), sal_True );
641 : }
642 0 : return pProp;
643 : }
644 :
645 0 : SbIfaceMapperMethod* SbModule::GetIfaceMapperMethod( const OUString& rName, SbMethod* pImplMeth )
646 : {
647 0 : SbxVariable* p = pMethods->Find( rName, SbxCLASS_METHOD );
648 0 : SbIfaceMapperMethod* pMapperMethod = p ? PTR_CAST(SbIfaceMapperMethod,p) : NULL;
649 0 : if( p && !pMapperMethod )
650 : {
651 0 : pMethods->Remove( p );
652 : }
653 0 : if( !pMapperMethod )
654 : {
655 0 : pMapperMethod = new SbIfaceMapperMethod( rName, pImplMeth );
656 0 : pMapperMethod->SetParent( this );
657 0 : pMapperMethod->SetFlags( SBX_READ );
658 0 : pMethods->Put( pMapperMethod, pMethods->Count() );
659 : }
660 0 : pMapperMethod->bInvalid = sal_False;
661 0 : return pMapperMethod;
662 : }
663 :
664 0 : SbIfaceMapperMethod::~SbIfaceMapperMethod()
665 : {
666 0 : }
667 :
668 0 : TYPEINIT1(SbIfaceMapperMethod,SbMethod)
669 :
670 :
671 : // From the code generator: remove invalid entries
672 :
673 108 : void SbModule::EndDefinitions( sal_Bool bNewState )
674 : {
675 310 : for( sal_uInt16 i = 0; i < pMethods->Count(); )
676 : {
677 94 : SbMethod* p = PTR_CAST(SbMethod,pMethods->Get( i ) );
678 94 : if( p )
679 : {
680 94 : if( p->bInvalid )
681 0 : pMethods->Remove( p );
682 : else
683 : {
684 94 : p->bInvalid = bNewState;
685 94 : i++;
686 : }
687 : }
688 : else
689 0 : i++;
690 : }
691 108 : SetModified( sal_True );
692 108 : }
693 :
694 0 : void SbModule::Clear()
695 : {
696 0 : delete pImage; pImage = NULL;
697 0 : if( pClassData )
698 0 : pClassData->clear();
699 0 : SbxObject::Clear();
700 0 : }
701 :
702 :
703 546 : SbxVariable* SbModule::Find( const OUString& rName, SbxClassType t )
704 : {
705 : // make sure a search in an uninstatiated class module will fail
706 546 : SbxVariable* pRes = SbxObject::Find( rName, t );
707 546 : if ( bIsProxyModule && !GetSbData()->bRunInit )
708 : {
709 0 : return NULL;
710 : }
711 546 : if( !pRes && pImage )
712 : {
713 176 : SbiInstance* pInst = GetSbData()->pInst;
714 176 : if( pInst && pInst->IsCompatibility() )
715 : {
716 : // Put enum types as objects into module,
717 : // allows MyEnum.First notation
718 76 : SbxArrayRef xArray = pImage->GetEnums();
719 76 : if( xArray.Is() )
720 : {
721 0 : SbxVariable* pEnumVar = xArray->Find( rName, SbxCLASS_DONTCARE );
722 0 : SbxObject* pEnumObject = PTR_CAST( SbxObject, pEnumVar );
723 0 : if( pEnumObject )
724 : {
725 0 : bool bPrivate = pEnumObject->IsSet( SBX_PRIVATE );
726 0 : OUString aEnumName = pEnumObject->GetName();
727 :
728 0 : pRes = new SbxVariable( SbxOBJECT );
729 0 : pRes->SetName( aEnumName );
730 0 : pRes->SetParent( this );
731 0 : pRes->SetFlag( SBX_READ );
732 0 : if( bPrivate )
733 : {
734 0 : pRes->SetFlag( SBX_PRIVATE );
735 : }
736 0 : pRes->PutObject( pEnumObject );
737 : }
738 76 : }
739 : }
740 : }
741 546 : return pRes;
742 : }
743 :
744 38 : const OUString& SbModule::GetSource32() const
745 : {
746 38 : return aOUSource;
747 : }
748 :
749 0 : const OUString& SbModule::GetSource() const
750 : {
751 0 : static OUString aRetStr;
752 0 : aRetStr = aOUSource;
753 0 : return aRetStr;
754 : }
755 :
756 : // Parent and BASIC are one!
757 :
758 70 : void SbModule::SetParent( SbxObject* p )
759 : {
760 70 : pParent = p;
761 70 : }
762 :
763 420 : void SbModule::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
764 : const SfxHint& rHint, const TypeId& rHintType )
765 : {
766 420 : const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
767 420 : if( pHint )
768 : {
769 420 : SbxVariable* pVar = pHint->GetVar();
770 420 : SbProperty* pProp = PTR_CAST(SbProperty,pVar);
771 420 : SbMethod* pMeth = PTR_CAST(SbMethod,pVar);
772 420 : SbProcedureProperty* pProcProperty = PTR_CAST( SbProcedureProperty, pVar );
773 420 : if( pProcProperty )
774 : {
775 :
776 0 : if( pHint->GetId() == SBX_HINT_DATAWANTED )
777 : {
778 0 : OUString aProcName("Property Get ");
779 0 : aProcName += pProcProperty->GetName();
780 :
781 0 : SbxVariable* pMethVar = Find( aProcName, SbxCLASS_METHOD );
782 0 : if( pMethVar )
783 : {
784 0 : SbxValues aVals;
785 0 : aVals.eType = SbxVARIANT;
786 :
787 0 : SbxArray* pArg = pVar->GetParameters();
788 0 : sal_uInt16 nVarParCount = (pArg != NULL) ? pArg->Count() : 0;
789 0 : if( nVarParCount > 1 )
790 : {
791 0 : SbxArrayRef xMethParameters = new SbxArray;
792 0 : xMethParameters->Put( pMethVar, 0 ); // Method as parameter 0
793 0 : for( sal_uInt16 i = 1 ; i < nVarParCount ; ++i )
794 : {
795 0 : SbxVariable* pPar = pArg->Get( i );
796 0 : xMethParameters->Put( pPar, i );
797 : }
798 :
799 0 : pMethVar->SetParameters( xMethParameters );
800 0 : pMethVar->Get( aVals );
801 0 : pMethVar->SetParameters( NULL );
802 : }
803 : else
804 : {
805 0 : pMethVar->Get( aVals );
806 : }
807 :
808 0 : pVar->Put( aVals );
809 0 : }
810 : }
811 0 : else if( pHint->GetId() == SBX_HINT_DATACHANGED )
812 : {
813 0 : SbxVariable* pMethVar = NULL;
814 :
815 0 : bool bSet = pProcProperty->isSet();
816 0 : if( bSet )
817 : {
818 0 : pProcProperty->setSet( false );
819 :
820 0 : OUString aProcName("Property Set ");
821 0 : aProcName += pProcProperty->GetName();
822 0 : pMethVar = Find( aProcName, SbxCLASS_METHOD );
823 : }
824 0 : if( !pMethVar ) // Let
825 : {
826 0 : OUString aProcName("Property Let " );
827 0 : aProcName += pProcProperty->GetName();
828 0 : pMethVar = Find( aProcName, SbxCLASS_METHOD );
829 : }
830 :
831 0 : if( pMethVar )
832 : {
833 : // Setup parameters
834 0 : SbxArrayRef xArray = new SbxArray;
835 0 : xArray->Put( pMethVar, 0 ); // Method as parameter 0
836 0 : xArray->Put( pVar, 1 );
837 0 : pMethVar->SetParameters( xArray );
838 :
839 0 : SbxValues aVals;
840 0 : pMethVar->Get( aVals );
841 0 : pMethVar->SetParameters( NULL );
842 : }
843 : }
844 : }
845 420 : if( pProp )
846 : {
847 216 : if( pProp->GetModule() != this )
848 0 : SetError( SbxERR_BAD_ACTION );
849 : }
850 204 : else if( pMeth )
851 : {
852 134 : if( pHint->GetId() == SBX_HINT_DATAWANTED )
853 : {
854 134 : if( pMeth->bInvalid && !Compile() )
855 : {
856 : // auto compile has not worked!
857 0 : StarBASIC::Error( SbERR_BAD_PROP_VALUE );
858 : }
859 : else
860 : {
861 : // Call of a subprogram
862 134 : SbModule* pOld = GetSbData()->pMod;
863 134 : GetSbData()->pMod = this;
864 134 : Run( (SbMethod*) pVar );
865 134 : GetSbData()->pMod = pOld;
866 : }
867 : }
868 : }
869 : else
870 : {
871 : // #i92642: Special handling for name property to avoid
872 : // side effects when using name as variable implicitely
873 70 : bool bForwardToSbxObject = true;
874 :
875 70 : sal_uIntPtr nId = pHint->GetId();
876 140 : if( (nId == SBX_HINT_DATAWANTED || nId == SBX_HINT_DATACHANGED) &&
877 70 : pVar->GetName().equalsIgnoreAsciiCase( "name" ) )
878 : {
879 70 : bForwardToSbxObject = false;
880 : }
881 70 : if( bForwardToSbxObject )
882 : {
883 0 : SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
884 : }
885 : }
886 : }
887 420 : }
888 :
889 : // The setting of the source makes the image invalid
890 : // and scans the method definitions newly in
891 :
892 0 : void SbModule::SetSource( const OUString& r )
893 : {
894 0 : SetSource32( r );
895 0 : }
896 :
897 70 : void SbModule::SetSource32( const OUString& r )
898 : {
899 : // Default basic mode to library container mode, but.. allow Option VBASupport 0/1 override
900 70 : SetVBACompat( getDefaultVBAMode( static_cast< StarBASIC*>( GetParent() ) ) );
901 70 : aOUSource = r;
902 70 : StartDefinitions();
903 70 : SbiTokenizer aTok( r );
904 70 : aTok.SetCompatible( IsVBACompat() );
905 270 : while( !aTok.IsEof() )
906 : {
907 130 : SbiToken eEndTok = NIL;
908 :
909 : // Searching for SUB or FUNCTION
910 130 : SbiToken eLastTok = NIL;
911 760 : while( !aTok.IsEof() )
912 : {
913 : // #32385: not by declare
914 560 : SbiToken eCurTok = aTok.Next();
915 560 : if( eLastTok != DECLARE )
916 : {
917 560 : if( eCurTok == SUB )
918 : {
919 34 : eEndTok = ENDSUB; break;
920 : }
921 526 : if( eCurTok == FUNCTION )
922 : {
923 26 : eEndTok = ENDFUNC; break;
924 : }
925 500 : if( eCurTok == PROPERTY )
926 : {
927 0 : eEndTok = ENDPROPERTY; break;
928 : }
929 500 : if( eCurTok == OPTION )
930 : {
931 56 : eCurTok = aTok.Next();
932 56 : if( eCurTok == COMPATIBLE )
933 : {
934 0 : aTok.SetCompatible( true );
935 : }
936 56 : else if ( ( eCurTok == VBASUPPORT ) && ( aTok.Next() == NUMBER ) )
937 : {
938 50 : sal_Bool bIsVBA = ( aTok.GetDbl()== 1 );
939 50 : SetVBACompat( bIsVBA );
940 50 : aTok.SetCompatible( bIsVBA );
941 : }
942 : }
943 : }
944 500 : eLastTok = eCurTok;
945 : }
946 : // Definition of the method
947 130 : SbMethod* pMeth = NULL;
948 130 : if( eEndTok != NIL )
949 : {
950 60 : sal_uInt16 nLine1 = aTok.GetLine();
951 60 : if( aTok.Next() == SYMBOL )
952 : {
953 60 : OUString aName_( aTok.GetSym() );
954 60 : SbxDataType t = aTok.GetType();
955 60 : if( t == SbxVARIANT && eEndTok == ENDSUB )
956 : {
957 34 : t = SbxVOID;
958 : }
959 60 : pMeth = GetMethod( aName_, t );
960 60 : pMeth->nLine1 = pMeth->nLine2 = nLine1;
961 : // The method is for a start VALID
962 60 : pMeth->bInvalid = sal_False;
963 : }
964 : else
965 : {
966 0 : eEndTok = NIL;
967 : }
968 : }
969 : // Skip up to END SUB/END FUNCTION
970 130 : if( eEndTok != NIL )
971 : {
972 6672 : while( !aTok.IsEof() )
973 : {
974 6612 : if( aTok.Next() == eEndTok )
975 : {
976 60 : pMeth->nLine2 = aTok.GetLine();
977 60 : break;
978 : }
979 : }
980 60 : if( aTok.IsEof() )
981 : {
982 0 : pMeth->nLine2 = aTok.GetLine();
983 : }
984 : }
985 : }
986 70 : EndDefinitions( sal_True );
987 70 : }
988 :
989 0 : SbMethod* SbModule::GetFunctionForLine( sal_uInt16 nLine )
990 : {
991 0 : for( sal_uInt16 i = 0; i < pMethods->Count(); i++ )
992 : {
993 0 : SbMethod* p = (SbMethod*) pMethods->Get( i );
994 0 : if( p->GetSbxId() == SBXID_BASICMETHOD )
995 : {
996 0 : if( nLine >= p->nLine1 && nLine <= p->nLine2 )
997 0 : return p;
998 : }
999 : }
1000 0 : return NULL;
1001 : }
1002 :
1003 : // Broadcast of a hint to all Basics
1004 :
1005 96 : static void _SendHint( SbxObject* pObj, sal_uIntPtr nId, SbMethod* p )
1006 : {
1007 : // Self a BASIC?
1008 96 : if( pObj->IsA( TYPE(StarBASIC) ) && pObj->IsBroadcaster() )
1009 0 : pObj->GetBroadcaster().Broadcast( SbxHint( nId, p ) );
1010 : // Then ask for the subobjects
1011 96 : SbxArray* pObjs = pObj->GetObjects();
1012 152 : for( sal_uInt16 i = 0; i < pObjs->Count(); i++ )
1013 : {
1014 56 : SbxVariable* pVar = pObjs->Get( i );
1015 56 : if( pVar->IsA( TYPE(SbxObject) ) )
1016 56 : _SendHint( PTR_CAST(SbxObject,pVar), nId, p );
1017 : }
1018 96 : }
1019 :
1020 40 : static void SendHint( SbxObject* pObj, sal_uIntPtr nId, SbMethod* p )
1021 : {
1022 100 : while( pObj->GetParent() )
1023 20 : pObj = pObj->GetParent();
1024 40 : _SendHint( pObj, nId, p );
1025 40 : }
1026 :
1027 : // #57841 Clear Uno-Objects, which were helt in RTL functions,
1028 : // at the end of the program, so that nothing were helt.
1029 26 : void ClearUnoObjectsInRTL_Impl_Rek( StarBASIC* pBasic )
1030 : {
1031 : // delete the return value of CreateUnoService
1032 26 : static OUString aName("CreateUnoService");
1033 26 : SbxVariable* pVar = pBasic->GetRtl()->Find( aName, SbxCLASS_METHOD );
1034 26 : if( pVar )
1035 : {
1036 26 : pVar->SbxValue::Clear();
1037 : }
1038 : // delete the return value of CreateUnoDialog
1039 26 : static OUString aName2("CreateUnoDialog");
1040 26 : pVar = pBasic->GetRtl()->Find( aName2, SbxCLASS_METHOD );
1041 26 : if( pVar )
1042 : {
1043 26 : pVar->SbxValue::Clear();
1044 : }
1045 : // delete the return value of CDec
1046 26 : static OUString aName3("CDec");
1047 26 : pVar = pBasic->GetRtl()->Find( aName3, SbxCLASS_METHOD );
1048 26 : if( pVar )
1049 : {
1050 26 : pVar->SbxValue::Clear();
1051 : }
1052 : // delete return value of CreateObject
1053 26 : static OUString aName4("CreateObject");
1054 26 : pVar = pBasic->GetRtl()->Find( aName4, SbxCLASS_METHOD );
1055 26 : if( pVar )
1056 : {
1057 26 : pVar->SbxValue::Clear();
1058 : }
1059 : // Go over all Sub-Basics
1060 26 : SbxArray* pObjs = pBasic->GetObjects();
1061 26 : sal_uInt16 nCount = pObjs->Count();
1062 60 : for( sal_uInt16 i = 0 ; i < nCount ; i++ )
1063 : {
1064 34 : SbxVariable* pObjVar = pObjs->Get( i );
1065 34 : StarBASIC* pSubBasic = PTR_CAST( StarBASIC, pObjVar );
1066 34 : if( pSubBasic )
1067 : {
1068 0 : ClearUnoObjectsInRTL_Impl_Rek( pSubBasic );
1069 : }
1070 : }
1071 26 : }
1072 :
1073 20 : void ClearUnoObjectsInRTL_Impl( StarBASIC* pBasic )
1074 : {
1075 : // #67781 Delete return values of the Uno-methods
1076 20 : clearUnoMethods();
1077 20 : clearUnoServiceCtors();
1078 :
1079 20 : ClearUnoObjectsInRTL_Impl_Rek( pBasic );
1080 :
1081 : // Search for the topmost Basic
1082 20 : SbxObject* p = pBasic;
1083 50 : while( p->GetParent() )
1084 10 : p = p->GetParent();
1085 20 : if( ((StarBASIC*)p) != pBasic )
1086 6 : ClearUnoObjectsInRTL_Impl_Rek( (StarBASIC*)p );
1087 20 : }
1088 :
1089 264 : bool SbModule::IsVBACompat() const
1090 : {
1091 264 : return mbVBACompat;
1092 : }
1093 :
1094 120 : void SbModule::SetVBACompat( bool bCompat )
1095 : {
1096 120 : if( mbVBACompat != bCompat )
1097 : {
1098 50 : mbVBACompat = bCompat;
1099 : // initialize VBA document API
1100 50 : if( mbVBACompat ) try
1101 : {
1102 50 : StarBASIC* pBasic = static_cast< StarBASIC* >( GetParent() );
1103 100 : uno::Reference< lang::XMultiServiceFactory > xFactory( getDocumentModel( pBasic ), uno::UNO_QUERY_THROW );
1104 0 : xFactory->createInstance( OUString("ooo.vba.VBAGlobals") );
1105 : }
1106 50 : catch( Exception& )
1107 : {
1108 : }
1109 : }
1110 120 : }
1111 :
1112 : // Run a Basic-subprogram
1113 134 : sal_uInt16 SbModule::Run( SbMethod* pMeth )
1114 : {
1115 : OSL_TRACE("About to run %s, vba compatmode is %d", rtl::OUStringToOString( pMeth->GetName(), RTL_TEXTENCODING_UTF8 ).getStr(), mbVBACompat );
1116 : static sal_uInt16 nMaxCallLevel = 0;
1117 :
1118 134 : sal_uInt16 nRes = 0;
1119 134 : bool bDelInst = ( GetSbData()->pInst == NULL );
1120 134 : bool bQuit = false;
1121 134 : StarBASICRef xBasic;
1122 134 : uno::Reference< frame::XModel > xModel;
1123 134 : uno::Reference< script::vba::XVBACompatibility > xVBACompat;
1124 134 : if( bDelInst )
1125 : {
1126 : // #32779: Hold Basic during the execution
1127 20 : xBasic = (StarBASIC*) GetParent();
1128 :
1129 20 : GetSbData()->pInst = new SbiInstance( (StarBASIC*) GetParent() );
1130 :
1131 : /* If a VBA script in a document is started, get the VBA compatibility
1132 : interface from the document Basic library container, and notify all
1133 : VBA script listeners about the started script. */
1134 20 : if( mbVBACompat )
1135 : {
1136 4 : StarBASIC* pBasic = static_cast< StarBASIC* >( GetParent() );
1137 4 : if( pBasic && pBasic->IsDocBasic() ) try
1138 : {
1139 4 : xModel.set( getDocumentModel( pBasic ), uno::UNO_SET_THROW );
1140 4 : xVBACompat.set( getVBACompatibility( xModel ), uno::UNO_SET_THROW );
1141 4 : xVBACompat->broadcastVBAScriptEvent( script::vba::VBAScriptEventId::SCRIPT_STARTED, GetName() );
1142 : }
1143 0 : catch(const uno::Exception& )
1144 : {
1145 : }
1146 : }
1147 :
1148 : // Launcher problem
1149 : // i80726 The Find below will genarate an error in Testtool so we reset it unless there was one before already
1150 20 : sal_Bool bWasError = SbxBase::GetError() != 0;
1151 20 : SbxVariable* pMSOMacroRuntimeLibVar = Find( OUString("Launcher"), SbxCLASS_OBJECT );
1152 20 : if ( !bWasError && (SbxBase::GetError() == SbxERR_PROC_UNDEFINED) )
1153 0 : SbxBase::ResetError();
1154 20 : if( pMSOMacroRuntimeLibVar )
1155 : {
1156 0 : StarBASIC* pMSOMacroRuntimeLib = PTR_CAST(StarBASIC,pMSOMacroRuntimeLibVar);
1157 0 : if( pMSOMacroRuntimeLib )
1158 : {
1159 0 : sal_uInt16 nGblFlag = pMSOMacroRuntimeLib->GetFlags() & SBX_GBLSEARCH;
1160 0 : pMSOMacroRuntimeLib->ResetFlag( SBX_GBLSEARCH );
1161 0 : SbxVariable* pAppSymbol = pMSOMacroRuntimeLib->Find( OUString("Application"), SbxCLASS_METHOD );
1162 0 : pMSOMacroRuntimeLib->SetFlag( nGblFlag );
1163 0 : if( pAppSymbol )
1164 : {
1165 0 : pMSOMacroRuntimeLib->SetFlag( SBX_EXTSEARCH ); // Could have been disabled before
1166 0 : GetSbData()->pMSOMacroRuntimLib = pMSOMacroRuntimeLib;
1167 : }
1168 : }
1169 : }
1170 :
1171 20 : if( nMaxCallLevel == 0 )
1172 : {
1173 : #ifdef UNX
1174 : struct rlimit rl;
1175 8 : getrlimit ( RLIMIT_STACK, &rl );
1176 : #endif
1177 : #if defined LINUX
1178 : // Empiric value, 900 = needed bytes/Basic call level
1179 : // for Linux including 10% safety margin
1180 8 : nMaxCallLevel = rl.rlim_cur / 900;
1181 : #elif defined SOLARIS
1182 : // Empiric value, 1650 = needed bytes/Basic call level
1183 : // for Solaris including 10% safety margin
1184 : nMaxCallLevel = rl.rlim_cur / 1650;
1185 : #elif defined WIN32
1186 : nMaxCallLevel = 5800;
1187 : #else
1188 : nMaxCallLevel = MAXRECURSION;
1189 : #endif
1190 : }
1191 : }
1192 :
1193 : // Recursion to deep?
1194 134 : if( ++GetSbData()->pInst->nCallLvl <= nMaxCallLevel )
1195 : {
1196 : // Define a globale variable in all Mods
1197 134 : GlobalRunInit( /* bBasicStart = */ bDelInst );
1198 :
1199 : // Appeared a compiler error? Then we don't launch
1200 134 : if( !GetSbData()->bGlobalInitErr )
1201 : {
1202 134 : if( bDelInst )
1203 : {
1204 20 : SendHint( GetParent(), SBX_HINT_BASICSTART, pMeth );
1205 :
1206 : // 1996-10-16: #31460 New concept for StepInto/Over/Out
1207 : // For an explanation see runtime.cxx at SbiInstance::CalcBreakCallLevel()
1208 : // Identify the BreakCallLevel
1209 20 : GetSbData()->pInst->CalcBreakCallLevel( pMeth->GetDebugFlags() );
1210 : }
1211 :
1212 134 : SbModule* pOldMod = GetSbData()->pMod;
1213 134 : GetSbData()->pMod = this;
1214 134 : SbiRuntime* pRt = new SbiRuntime( this, pMeth, pMeth->nStart );
1215 :
1216 134 : pRt->pNext = GetSbData()->pInst->pRun;
1217 134 : if( pRt->pNext )
1218 114 : pRt->pNext->block();
1219 134 : GetSbData()->pInst->pRun = pRt;
1220 134 : if ( mbVBACompat )
1221 : {
1222 118 : GetSbData()->pInst->EnableCompatibility( sal_True );
1223 : }
1224 134 : while( pRt->Step() ) {}
1225 134 : if( pRt->pNext )
1226 114 : pRt->pNext->unblock();
1227 :
1228 : // #63710 It can happen by an another thread handling at events,
1229 : // that the show call returns to an dialog (by closing the
1230 : // dialog per UI), before a by an event triggered further call returned,
1231 : // which stands in Basic more top in the stack and that had been run on
1232 : // a Basic-Breakpoint. Then would the instance below destroyed. And if the Basic,
1233 : // that stand still in the call, further runs, there is a GPF.
1234 : // Thus here had to be wait until the other call comes back.
1235 134 : if( bDelInst )
1236 : {
1237 : // Compare here with 1 instead of 0, because before nCallLvl--
1238 40 : while( GetSbData()->pInst->nCallLvl != 1 )
1239 0 : GetpApp()->Yield();
1240 : }
1241 :
1242 134 : nRes = sal_True;
1243 134 : GetSbData()->pInst->pRun = pRt->pNext;
1244 134 : GetSbData()->pInst->nCallLvl--; // Call-Level down again
1245 :
1246 : // Exist an higher-ranking runtime instance?
1247 : // Then take over SbDEBUG_BREAK, if set
1248 134 : SbiRuntime* pRtNext = pRt->pNext;
1249 134 : if( pRtNext && (pRt->GetDebugFlags() & SbDEBUG_BREAK) )
1250 0 : pRtNext->SetDebugFlags( SbDEBUG_BREAK );
1251 :
1252 134 : delete pRt;
1253 134 : GetSbData()->pMod = pOldMod;
1254 134 : if( bDelInst )
1255 : {
1256 : // #57841 Clear Uno-Objects, which were helt in RTL functions,
1257 : // at the end of the program, so that nothing were helt.
1258 20 : ClearUnoObjectsInRTL_Impl( xBasic );
1259 :
1260 20 : clearNativeObjectWrapperVector();
1261 :
1262 : DBG_ASSERT(GetSbData()->pInst->nCallLvl==0,"BASIC-Call-Level > 0");
1263 20 : delete GetSbData()->pInst, GetSbData()->pInst = NULL, bDelInst = false;
1264 :
1265 : // #i30690
1266 20 : SolarMutexGuard aSolarGuard;
1267 20 : SendHint( GetParent(), SBX_HINT_BASICSTOP, pMeth );
1268 :
1269 20 : GlobalRunDeInit();
1270 :
1271 : #ifdef DBG_UTIL
1272 : ResetCapturedAssertions();
1273 : #endif
1274 :
1275 20 : if( xVBACompat.is() )
1276 : {
1277 : // notify all VBA script listeners about the stopped script
1278 : try
1279 : {
1280 4 : xVBACompat->broadcastVBAScriptEvent( script::vba::VBAScriptEventId::SCRIPT_STOPPED, GetName() );
1281 : }
1282 0 : catch(const uno::Exception& )
1283 : {
1284 : }
1285 : // VBA always ensures screenupdating is enabled after completing
1286 4 : ::basic::vba::lockControllersOfAllDocuments( xModel, sal_False );
1287 4 : ::basic::vba::enableContainerWindowsOfAllDocuments( xModel, sal_True );
1288 20 : }
1289 :
1290 : #ifdef DBG_TRACE_BASIC
1291 : dbg_DeInitTrace();
1292 : #endif
1293 : }
1294 : }
1295 : else
1296 0 : GetSbData()->pInst->nCallLvl--; // Call-Level down again
1297 : }
1298 : else
1299 : {
1300 0 : GetSbData()->pInst->nCallLvl--; // Call-Level down again
1301 0 : StarBASIC::FatalError( SbERR_STACK_OVERFLOW );
1302 : }
1303 :
1304 134 : StarBASIC* pBasic = PTR_CAST(StarBASIC,GetParent());
1305 134 : if( bDelInst )
1306 : {
1307 : // #57841 Clear Uno-Objects, which were helt in RTL functions,
1308 : // the end of the program, so that nothing were helt.
1309 0 : ClearUnoObjectsInRTL_Impl( xBasic );
1310 :
1311 0 : delete GetSbData()->pInst;
1312 0 : GetSbData()->pInst = NULL;
1313 : }
1314 134 : if ( pBasic && pBasic->IsDocBasic() && pBasic->IsQuitApplication() && !GetSbData()->pInst )
1315 0 : bQuit = true;
1316 134 : if ( bQuit )
1317 : {
1318 0 : Application::PostUserEvent( LINK( &AsyncQuitHandler::instance(), AsyncQuitHandler, OnAsyncQuit ), NULL );
1319 : }
1320 :
1321 134 : return nRes;
1322 : }
1323 :
1324 : // Execute of the init method of a module after the loading
1325 : // or the compilation
1326 :
1327 36 : void SbModule::RunInit()
1328 : {
1329 108 : if( pImage
1330 36 : && !pImage->bInit
1331 36 : && pImage->GetFlag( SBIMG_INITCODE ) )
1332 : {
1333 : // Set flag, so that RunInit get activ (Testtool)
1334 2 : GetSbData()->bRunInit = true;
1335 :
1336 2 : SbModule* pOldMod = GetSbData()->pMod;
1337 2 : GetSbData()->pMod = this;
1338 : // The init code starts always here
1339 2 : SbiRuntime* pRt = new SbiRuntime( this, NULL, 0 );
1340 :
1341 2 : pRt->pNext = GetSbData()->pInst->pRun;
1342 2 : GetSbData()->pInst->pRun = pRt;
1343 2 : while( pRt->Step() ) {}
1344 :
1345 2 : GetSbData()->pInst->pRun = pRt->pNext;
1346 2 : delete pRt;
1347 2 : GetSbData()->pMod = pOldMod;
1348 2 : pImage->bInit = true;
1349 2 : pImage->bFirstInit = false;
1350 :
1351 : // RunInit is not activ anymore
1352 2 : GetSbData()->bRunInit = false;
1353 : }
1354 36 : }
1355 :
1356 : // Delete with private/dim declared variables
1357 :
1358 0 : void SbModule::AddVarName( const OUString& aName )
1359 : {
1360 : // see if the name is added allready
1361 0 : std::vector< OUString >::iterator it_end = mModuleVariableNames.end();
1362 0 : for ( std::vector< OUString >::iterator it = mModuleVariableNames.begin(); it != it_end; ++it )
1363 : {
1364 0 : if ( aName == *it )
1365 0 : return;
1366 : }
1367 0 : mModuleVariableNames.push_back( aName );
1368 : }
1369 :
1370 38 : void SbModule::RemoveVars()
1371 : {
1372 38 : std::vector< OUString >::iterator it_end = mModuleVariableNames.end();
1373 38 : for ( std::vector< OUString >::iterator it = mModuleVariableNames.begin(); it != it_end; ++it )
1374 : {
1375 : // We don't want a Find being called in a derived class ( e.g.
1376 : // SbUserform because it could trigger say an initialise event
1377 : // which would cause basic to be re-run in the middle of the init ( and remember RemoveVars is called from compile and we don't want code to run as part of the compile )
1378 0 : SbxVariableRef p = SbModule::Find( *it, SbxCLASS_PROPERTY );
1379 0 : if( p.Is() )
1380 0 : Remove (p);
1381 0 : }
1382 38 : }
1383 :
1384 0 : void SbModule::ClearPrivateVars()
1385 : {
1386 0 : for( sal_uInt16 i = 0 ; i < pProps->Count() ; i++ )
1387 : {
1388 0 : SbProperty* p = PTR_CAST(SbProperty,pProps->Get( i ) );
1389 0 : if( p )
1390 : {
1391 : // Delete not the arrays, only their content
1392 0 : if( p->GetType() & SbxARRAY )
1393 : {
1394 0 : SbxArray* pArray = PTR_CAST(SbxArray,p->GetObject());
1395 0 : if( pArray )
1396 : {
1397 0 : for( sal_uInt16 j = 0 ; j < pArray->Count() ; j++ )
1398 : {
1399 0 : SbxVariable* pj = PTR_CAST(SbxVariable,pArray->Get( j ));
1400 0 : pj->SbxValue::Clear();
1401 : }
1402 : }
1403 : }
1404 : else
1405 : {
1406 0 : p->SbxValue::Clear();
1407 : }
1408 : }
1409 : }
1410 0 : }
1411 :
1412 8 : void SbModule::implClearIfVarDependsOnDeletedBasic( SbxVariable* pVar, StarBASIC* pDeletedBasic )
1413 : {
1414 8 : if( pVar->SbxValue::GetType() != SbxOBJECT || pVar->ISA( SbProcedureProperty ) )
1415 16 : return;
1416 :
1417 0 : SbxObject* pObj = PTR_CAST(SbxObject,pVar->GetObject());
1418 0 : if( pObj != NULL )
1419 : {
1420 0 : SbxObject* p = pObj;
1421 :
1422 0 : SbModule* pMod = PTR_CAST( SbModule, p );
1423 0 : if( pMod != NULL )
1424 0 : pMod->ClearVarsDependingOnDeletedBasic( pDeletedBasic );
1425 :
1426 0 : while( (p = p->GetParent()) != NULL )
1427 : {
1428 0 : StarBASIC* pBasic = PTR_CAST( StarBASIC, p );
1429 0 : if( pBasic != NULL && pBasic == pDeletedBasic )
1430 : {
1431 0 : pVar->SbxValue::Clear();
1432 0 : break;
1433 : }
1434 : }
1435 : }
1436 : }
1437 :
1438 50 : void SbModule::ClearVarsDependingOnDeletedBasic( StarBASIC* pDeletedBasic )
1439 : {
1440 : (void)pDeletedBasic;
1441 :
1442 158 : for( sal_uInt16 i = 0 ; i < pProps->Count() ; i++ )
1443 : {
1444 108 : SbProperty* p = PTR_CAST(SbProperty,pProps->Get( i ) );
1445 108 : if( p )
1446 : {
1447 8 : if( p->GetType() & SbxARRAY )
1448 : {
1449 0 : SbxArray* pArray = PTR_CAST(SbxArray,p->GetObject());
1450 0 : if( pArray )
1451 : {
1452 0 : for( sal_uInt16 j = 0 ; j < pArray->Count() ; j++ )
1453 : {
1454 0 : SbxVariable* pVar = PTR_CAST(SbxVariable,pArray->Get( j ));
1455 0 : implClearIfVarDependsOnDeletedBasic( pVar, pDeletedBasic );
1456 : }
1457 : }
1458 : }
1459 : else
1460 : {
1461 8 : implClearIfVarDependsOnDeletedBasic( p, pDeletedBasic );
1462 : }
1463 : }
1464 : }
1465 50 : }
1466 :
1467 44 : void StarBASIC::ClearAllModuleVars( void )
1468 : {
1469 : // Initialise the own module
1470 98 : for ( sal_uInt16 nMod = 0; nMod < pModules->Count(); nMod++ )
1471 : {
1472 54 : SbModule* pModule = (SbModule*)pModules->Get( nMod );
1473 : // Initialise only, if the startcode was already executed
1474 54 : if( pModule->pImage && pModule->pImage->bInit && !pModule->isProxyModule() && !pModule->ISA(SbObjModule) )
1475 0 : pModule->ClearPrivateVars();
1476 : }
1477 :
1478 44 : }
1479 :
1480 : // Execution of the init-code of all module
1481 134 : void SbModule::GlobalRunInit( bool bBasicStart )
1482 : {
1483 : // If no Basic-Start, only initialise, if the module is not initialised
1484 134 : if( !bBasicStart )
1485 114 : if( !(pImage && !pImage->bInit) )
1486 248 : return;
1487 :
1488 : // Initialise GlobalInitErr-Flag for Compiler-Error
1489 : // With the help of this flags could be located in SbModule::Run() after the call of
1490 : // GlobalRunInit, if at the intialising of the module
1491 : // an error occurred. Then it will not be launched.
1492 20 : GetSbData()->bGlobalInitErr = false;
1493 :
1494 : // Parent of the module is a Basic
1495 20 : StarBASIC *pBasic = PTR_CAST(StarBASIC,GetParent());
1496 20 : if( pBasic )
1497 : {
1498 20 : pBasic->InitAllModules();
1499 :
1500 20 : SbxObject* pParent_ = pBasic->GetParent();
1501 20 : if( pParent_ )
1502 : {
1503 6 : StarBASIC * pParentBasic = PTR_CAST(StarBASIC,pParent_);
1504 6 : if( pParentBasic )
1505 : {
1506 6 : pParentBasic->InitAllModules( pBasic );
1507 :
1508 : // #109018 Parent can also have a parent (library in doc)
1509 6 : SbxObject* pParentParent = pParentBasic->GetParent();
1510 6 : if( pParentParent )
1511 : {
1512 4 : StarBASIC * pParentParentBasic = PTR_CAST(StarBASIC,pParentParent);
1513 4 : if( pParentParentBasic )
1514 4 : pParentParentBasic->InitAllModules( pParentBasic );
1515 : }
1516 : }
1517 : }
1518 : }
1519 : }
1520 :
1521 20 : void SbModule::GlobalRunDeInit( void )
1522 : {
1523 20 : StarBASIC *pBasic = PTR_CAST(StarBASIC,GetParent());
1524 20 : if( pBasic )
1525 : {
1526 20 : pBasic->DeInitAllModules();
1527 :
1528 20 : SbxObject* pParent_ = pBasic->GetParent();
1529 20 : if( pParent_ )
1530 6 : pBasic = PTR_CAST(StarBASIC,pParent_);
1531 20 : if( pBasic )
1532 20 : pBasic->DeInitAllModules();
1533 : }
1534 20 : }
1535 :
1536 : // Search for the next STMNT-Command in the code. This was used from the STMNT-
1537 : // Opcode to set the endcolumn.
1538 :
1539 950 : const sal_uInt8* SbModule::FindNextStmnt( const sal_uInt8* p, sal_uInt16& nLine, sal_uInt16& nCol ) const
1540 : {
1541 950 : return FindNextStmnt( p, nLine, nCol, sal_False );
1542 : }
1543 :
1544 950 : const sal_uInt8* SbModule::FindNextStmnt( const sal_uInt8* p, sal_uInt16& nLine, sal_uInt16& nCol,
1545 : sal_Bool bFollowJumps, const SbiImage* pImg ) const
1546 : {
1547 950 : sal_uInt32 nPC = (sal_uInt32) ( p - (const sal_uInt8*) pImage->GetCode() );
1548 6080 : while( nPC < pImage->GetCodeSize() )
1549 : {
1550 5104 : SbiOpcode eOp = (SbiOpcode ) ( *p++ );
1551 5104 : nPC++;
1552 5104 : if( bFollowJumps && eOp == _JUMP && pImg )
1553 : {
1554 : DBG_ASSERT( pImg, "FindNextStmnt: pImg==NULL with FollowJumps option" );
1555 0 : sal_uInt32 nOp1 = *p++; nOp1 |= *p++ << 8;
1556 0 : nOp1 |= *p++ << 16; nOp1 |= *p++ << 24;
1557 0 : p = (const sal_uInt8*) pImg->GetCode() + nOp1;
1558 : }
1559 5104 : else if( eOp >= SbOP1_START && eOp <= SbOP1_END )
1560 728 : p += 4, nPC += 4;
1561 4376 : else if( eOp == _STMNT )
1562 : {
1563 : sal_uInt32 nl, nc;
1564 924 : nl = *p++; nl |= *p++ << 8;
1565 924 : nl |= *p++ << 16 ; nl |= *p++ << 24;
1566 924 : nc = *p++; nc |= *p++ << 8;
1567 924 : nc |= *p++ << 16 ; nc |= *p++ << 24;
1568 924 : nLine = (sal_uInt16)nl; nCol = (sal_uInt16)nc;
1569 924 : return p;
1570 : }
1571 3452 : else if( eOp >= SbOP2_START && eOp <= SbOP2_END )
1572 1700 : p += 8, nPC += 8;
1573 1752 : else if( !( eOp >= SbOP0_START && eOp <= SbOP0_END ) )
1574 : {
1575 0 : StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
1576 0 : break;
1577 : }
1578 : }
1579 26 : return NULL;
1580 : }
1581 :
1582 : // Test, if a line contains STMNT-Opcodes
1583 :
1584 0 : sal_Bool SbModule::IsBreakable( sal_uInt16 nLine ) const
1585 : {
1586 0 : if( !pImage )
1587 0 : return sal_False;
1588 0 : const sal_uInt8* p = (const sal_uInt8* ) pImage->GetCode();
1589 : sal_uInt16 nl, nc;
1590 0 : while( ( p = FindNextStmnt( p, nl, nc ) ) != NULL )
1591 0 : if( nl == nLine )
1592 0 : return sal_True;
1593 0 : return sal_False;
1594 : }
1595 :
1596 0 : size_t SbModule::GetBPCount() const
1597 : {
1598 0 : return pBreaks ? pBreaks->size() : 0;
1599 : }
1600 :
1601 0 : sal_uInt16 SbModule::GetBP( size_t n ) const
1602 : {
1603 0 : if( pBreaks && n < pBreaks->size() )
1604 0 : return pBreaks->operator[]( n );
1605 : else
1606 0 : return 0;
1607 : }
1608 :
1609 0 : sal_Bool SbModule::IsBP( sal_uInt16 nLine ) const
1610 : {
1611 0 : if( pBreaks )
1612 : {
1613 0 : for( size_t i = 0; i < pBreaks->size(); i++ )
1614 : {
1615 0 : sal_uInt16 b = pBreaks->operator[]( i );
1616 0 : if( b == nLine )
1617 0 : return sal_True;
1618 0 : if( b < nLine )
1619 0 : break;
1620 : }
1621 : }
1622 0 : return sal_False;
1623 : }
1624 :
1625 0 : sal_Bool SbModule::SetBP( sal_uInt16 nLine )
1626 : {
1627 0 : if( !IsBreakable( nLine ) )
1628 0 : return sal_False;
1629 0 : if( !pBreaks )
1630 0 : pBreaks = new SbiBreakpoints;
1631 : size_t i;
1632 0 : for( i = 0; i < pBreaks->size(); i++ )
1633 : {
1634 0 : sal_uInt16 b = pBreaks->operator[]( i );
1635 0 : if( b == nLine )
1636 0 : return sal_True;
1637 0 : if( b < nLine )
1638 0 : break;
1639 : }
1640 0 : pBreaks->insert( pBreaks->begin() + i, nLine );
1641 :
1642 : // #38568: Set during runtime as well here SbDEBUG_BREAK
1643 0 : if( GetSbData()->pInst && GetSbData()->pInst->pRun )
1644 0 : GetSbData()->pInst->pRun->SetDebugFlags( SbDEBUG_BREAK );
1645 :
1646 0 : return IsBreakable( nLine );
1647 : }
1648 :
1649 0 : sal_Bool SbModule::ClearBP( sal_uInt16 nLine )
1650 : {
1651 0 : sal_Bool bRes = sal_False;
1652 0 : if( pBreaks )
1653 : {
1654 0 : for( size_t i = 0; i < pBreaks->size(); i++ )
1655 : {
1656 0 : sal_uInt16 b = pBreaks->operator[]( i );
1657 0 : if( b == nLine )
1658 : {
1659 0 : pBreaks->erase( pBreaks->begin() + i );
1660 0 : bRes = sal_True;
1661 0 : break;
1662 : }
1663 0 : if( b < nLine )
1664 0 : break;
1665 : }
1666 0 : if( pBreaks->empty() )
1667 0 : delete pBreaks, pBreaks = NULL;
1668 : }
1669 0 : return bRes;
1670 : }
1671 :
1672 0 : void SbModule::ClearAllBP()
1673 : {
1674 0 : delete pBreaks;
1675 0 : pBreaks = NULL;
1676 0 : }
1677 :
1678 : void
1679 0 : SbModule::fixUpMethodStart( bool bCvtToLegacy, SbiImage* pImg ) const
1680 : {
1681 0 : if ( !pImg )
1682 0 : pImg = pImage;
1683 0 : for( sal_uInt32 i = 0; i < pMethods->Count(); i++ )
1684 : {
1685 0 : SbMethod* pMeth = PTR_CAST(SbMethod,pMethods->Get( (sal_uInt16)i ) );
1686 0 : if( pMeth )
1687 : {
1688 : //fixup method start positions
1689 0 : if ( bCvtToLegacy )
1690 0 : pMeth->nStart = pImg->CalcLegacyOffset( pMeth->nStart );
1691 : else
1692 0 : pMeth->nStart = pImg->CalcNewOffset( (sal_uInt16)pMeth->nStart );
1693 : }
1694 : }
1695 :
1696 0 : }
1697 :
1698 0 : sal_Bool SbModule::LoadData( SvStream& rStrm, sal_uInt16 nVer )
1699 : {
1700 0 : Clear();
1701 0 : if( !SbxObject::LoadData( rStrm, 1 ) )
1702 0 : return sal_False;
1703 : // As a precaution...
1704 0 : SetFlag( SBX_EXTSEARCH | SBX_GBLSEARCH );
1705 : sal_uInt8 bImage;
1706 0 : rStrm >> bImage;
1707 0 : if( bImage )
1708 : {
1709 0 : SbiImage* p = new SbiImage;
1710 0 : sal_uInt32 nImgVer = 0;
1711 :
1712 0 : if( !p->Load( rStrm, nImgVer ) )
1713 : {
1714 0 : delete p;
1715 0 : return sal_False;
1716 : }
1717 : // If the image is in old format, we fix up the method start offsets
1718 0 : if ( nImgVer < B_EXT_IMG_VERSION )
1719 : {
1720 0 : fixUpMethodStart( false, p );
1721 0 : p->ReleaseLegacyBuffer();
1722 : }
1723 0 : aComment = p->aComment;
1724 0 : SetName( p->aName );
1725 0 : if( p->GetCodeSize() )
1726 : {
1727 0 : aOUSource = p->aOUSource;
1728 : // Old version: image away
1729 0 : if( nVer == 1 )
1730 : {
1731 0 : SetSource32( p->aOUSource );
1732 0 : delete p;
1733 : }
1734 : else
1735 0 : pImage = p;
1736 : }
1737 : else
1738 : {
1739 0 : SetSource32( p->aOUSource );
1740 0 : delete p;
1741 : }
1742 : }
1743 0 : return sal_True;
1744 : }
1745 :
1746 0 : sal_Bool SbModule::StoreData( SvStream& rStrm ) const
1747 : {
1748 0 : bool bFixup = ( pImage && !pImage->ExceedsLegacyLimits() );
1749 0 : if ( bFixup )
1750 0 : fixUpMethodStart( true );
1751 0 : sal_Bool bRet = SbxObject::StoreData( rStrm );
1752 0 : if ( !bRet )
1753 0 : return sal_False;
1754 :
1755 0 : if( pImage )
1756 : {
1757 0 : pImage->aOUSource = aOUSource;
1758 0 : pImage->aComment = aComment;
1759 0 : pImage->aName = GetName();
1760 0 : rStrm << (sal_uInt8) 1;
1761 : // # PCode is saved only for legacy formats only
1762 : // It should be noted that it probably isn't necessary
1763 : // It would be better not to store the image ( more flexible with
1764 : // formats )
1765 0 : bool bRes = pImage->Save( rStrm, B_LEGACYVERSION );
1766 0 : if ( bFixup )
1767 0 : fixUpMethodStart( false ); // restore method starts
1768 0 : return bRes;
1769 :
1770 : }
1771 : else
1772 : {
1773 0 : SbiImage aImg;
1774 0 : aImg.aOUSource = aOUSource;
1775 0 : aImg.aComment = aComment;
1776 0 : aImg.aName = GetName();
1777 0 : rStrm << (sal_uInt8) 1;
1778 0 : return aImg.Save( rStrm );
1779 : }
1780 : }
1781 :
1782 0 : sal_Bool SbModule::ExceedsLegacyModuleSize()
1783 : {
1784 0 : if ( !IsCompiled() )
1785 0 : Compile();
1786 0 : if ( pImage && pImage->ExceedsLegacyLimits() )
1787 0 : return true;
1788 0 : return false;
1789 : }
1790 :
1791 : class ErrorHdlResetter
1792 : {
1793 : Link mErrHandler;
1794 : bool mbError;
1795 : public:
1796 0 : ErrorHdlResetter() : mbError( false )
1797 : {
1798 : // save error handler
1799 0 : mErrHandler = StarBASIC::GetGlobalErrorHdl();
1800 : // set new error handler
1801 0 : StarBASIC::SetGlobalErrorHdl( LINK( this, ErrorHdlResetter, BasicErrorHdl ) );
1802 0 : }
1803 0 : ~ErrorHdlResetter()
1804 : {
1805 : // restore error handler
1806 0 : StarBASIC::SetGlobalErrorHdl(mErrHandler);
1807 0 : }
1808 : DECL_LINK( BasicErrorHdl, StarBASIC * );
1809 0 : bool HasError() { return mbError; }
1810 : };
1811 0 : IMPL_LINK( ErrorHdlResetter, BasicErrorHdl, StarBASIC *, /*pBasic*/)
1812 : {
1813 0 : mbError = true;
1814 0 : return 0;
1815 : }
1816 :
1817 0 : bool SbModule::HasExeCode()
1818 : {
1819 : // And empty Image always has the Global Chain set up
1820 : static const unsigned char pEmptyImage[] = { 0x45, 0x0 , 0x0, 0x0, 0x0 };
1821 : // lets be stricter for the moment than VBA
1822 :
1823 0 : if (!IsCompiled())
1824 : {
1825 0 : ErrorHdlResetter aGblErrHdl;
1826 0 : Compile();
1827 0 : if (aGblErrHdl.HasError()) //assume unsafe on compile error
1828 0 : return true;
1829 : }
1830 :
1831 0 : bool bRes = false;
1832 0 : if (pImage && !(pImage->GetCodeSize() == 5 && (memcmp(pImage->GetCode(), pEmptyImage, pImage->GetCodeSize()) == 0 )))
1833 0 : bRes = true;
1834 :
1835 0 : return bRes;
1836 : }
1837 :
1838 : // Store only image, no source
1839 0 : sal_Bool SbModule::StoreBinaryData( SvStream& rStrm )
1840 : {
1841 0 : return StoreBinaryData( rStrm, 0 );
1842 : }
1843 :
1844 0 : sal_Bool SbModule::StoreBinaryData( SvStream& rStrm, sal_uInt16 nVer )
1845 : {
1846 0 : sal_Bool bRet = Compile();
1847 0 : if( bRet )
1848 : {
1849 0 : bool bFixup = ( !nVer && !pImage->ExceedsLegacyLimits() );// save in old image format, fix up method starts
1850 :
1851 0 : if ( bFixup ) // save in old image format, fix up method starts
1852 0 : fixUpMethodStart( true );
1853 0 : bRet = SbxObject::StoreData( rStrm );
1854 0 : if( bRet )
1855 : {
1856 0 : pImage->aOUSource = OUString();
1857 0 : pImage->aComment = aComment;
1858 0 : pImage->aName = GetName();
1859 :
1860 0 : rStrm << (sal_uInt8) 1;
1861 0 : if ( nVer )
1862 0 : bRet = pImage->Save( rStrm, B_EXT_IMG_VERSION );
1863 : else
1864 0 : bRet = pImage->Save( rStrm, B_LEGACYVERSION );
1865 0 : if ( bFixup )
1866 0 : fixUpMethodStart( false ); // restore method starts
1867 :
1868 0 : pImage->aOUSource = aOUSource;
1869 : }
1870 : }
1871 0 : return bRet;
1872 : }
1873 :
1874 : // Called for >= OO 1.0 passwd protected libraries only
1875 :
1876 0 : sal_Bool SbModule::LoadBinaryData( SvStream& rStrm )
1877 : {
1878 0 : OUString aKeepSource = aOUSource;
1879 0 : bool bRet = LoadData( rStrm, 2 );
1880 0 : LoadCompleted();
1881 0 : aOUSource = aKeepSource;
1882 0 : return bRet;
1883 : }
1884 :
1885 0 : sal_Bool SbModule::LoadCompleted()
1886 : {
1887 0 : SbxArray* p = GetMethods();
1888 : sal_uInt16 i;
1889 0 : for( i = 0; i < p->Count(); i++ )
1890 : {
1891 0 : SbMethod* q = PTR_CAST(SbMethod,p->Get( i ) );
1892 0 : if( q )
1893 0 : q->pMod = this;
1894 : }
1895 0 : p = GetProperties();
1896 0 : for( i = 0; i < p->Count(); i++ )
1897 : {
1898 0 : SbProperty* q = PTR_CAST(SbProperty,p->Get( i ) );
1899 0 : if( q )
1900 0 : q->pMod = this;
1901 : }
1902 0 : return sal_True;
1903 : }
1904 :
1905 0 : void SbModule::handleProcedureProperties( SfxBroadcaster& rBC, const SfxHint& rHint )
1906 : {
1907 0 : bool bDone = false;
1908 :
1909 0 : const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
1910 0 : if( pHint )
1911 : {
1912 0 : SbxVariable* pVar = pHint->GetVar();
1913 0 : SbProcedureProperty* pProcProperty = PTR_CAST( SbProcedureProperty, pVar );
1914 0 : if( pProcProperty )
1915 : {
1916 0 : bDone = true;
1917 :
1918 0 : if( pHint->GetId() == SBX_HINT_DATAWANTED )
1919 : {
1920 0 : OUString aProcName("Property Get ");
1921 0 : aProcName += pProcProperty->GetName();
1922 :
1923 0 : SbxVariable* pMeth = Find( aProcName, SbxCLASS_METHOD );
1924 0 : if( pMeth )
1925 : {
1926 0 : SbxValues aVals;
1927 0 : aVals.eType = SbxVARIANT;
1928 :
1929 0 : SbxArray* pArg = pVar->GetParameters();
1930 0 : sal_uInt16 nVarParCount = (pArg != NULL) ? pArg->Count() : 0;
1931 0 : if( nVarParCount > 1 )
1932 : {
1933 0 : SbxArrayRef xMethParameters = new SbxArray;
1934 0 : xMethParameters->Put( pMeth, 0 ); // Method as parameter 0
1935 0 : for( sal_uInt16 i = 1 ; i < nVarParCount ; ++i )
1936 : {
1937 0 : SbxVariable* pPar = pArg->Get( i );
1938 0 : xMethParameters->Put( pPar, i );
1939 : }
1940 :
1941 0 : pMeth->SetParameters( xMethParameters );
1942 0 : pMeth->Get( aVals );
1943 0 : pMeth->SetParameters( NULL );
1944 : }
1945 : else
1946 : {
1947 0 : pMeth->Get( aVals );
1948 : }
1949 :
1950 0 : pVar->Put( aVals );
1951 0 : }
1952 : }
1953 0 : else if( pHint->GetId() == SBX_HINT_DATACHANGED )
1954 : {
1955 0 : SbxVariable* pMeth = NULL;
1956 :
1957 0 : bool bSet = pProcProperty->isSet();
1958 0 : if( bSet )
1959 : {
1960 0 : pProcProperty->setSet( false );
1961 :
1962 0 : OUString aProcName("Property Set " );
1963 0 : aProcName += pProcProperty->GetName();
1964 0 : pMeth = Find( aProcName, SbxCLASS_METHOD );
1965 : }
1966 0 : if( !pMeth ) // Let
1967 : {
1968 0 : OUString aProcName("Property Set " );
1969 0 : aProcName += pProcProperty->GetName();
1970 0 : pMeth = Find( aProcName, SbxCLASS_METHOD );
1971 : }
1972 :
1973 0 : if( pMeth )
1974 : {
1975 : // Setup parameters
1976 0 : SbxArrayRef xArray = new SbxArray;
1977 0 : xArray->Put( pMeth, 0 ); // Method as parameter 0
1978 0 : xArray->Put( pVar, 1 );
1979 0 : pMeth->SetParameters( xArray );
1980 :
1981 0 : SbxValues aVals;
1982 0 : pMeth->Get( aVals );
1983 0 : pMeth->SetParameters( NULL );
1984 : }
1985 : }
1986 : }
1987 : }
1988 :
1989 0 : if( !bDone )
1990 0 : SbModule::Notify( rBC, rHint );
1991 0 : }
1992 :
1993 :
1994 : // Implementation SbJScriptModule (Basic module for JavaScript source code)
1995 0 : SbJScriptModule::SbJScriptModule( const OUString& rName )
1996 0 : :SbModule( rName )
1997 : {
1998 0 : }
1999 :
2000 0 : sal_Bool SbJScriptModule::LoadData( SvStream& rStrm, sal_uInt16 nVer )
2001 : {
2002 : (void)nVer;
2003 :
2004 0 : Clear();
2005 0 : if( !SbxObject::LoadData( rStrm, 1 ) )
2006 0 : return sal_False;
2007 :
2008 : // Get the source string
2009 0 : aOUSource = rStrm.ReadUniOrByteString( osl_getThreadTextEncoding() );
2010 0 : return sal_True;
2011 : }
2012 :
2013 0 : sal_Bool SbJScriptModule::StoreData( SvStream& rStrm ) const
2014 : {
2015 0 : if( !SbxObject::StoreData( rStrm ) )
2016 0 : return sal_False;
2017 :
2018 : // Write the source string
2019 0 : OUString aTmp = aOUSource;
2020 0 : rStrm.WriteUniOrByteString( aTmp, osl_getThreadTextEncoding() );
2021 0 : return sal_True;
2022 : }
2023 :
2024 :
2025 : /////////////////////////////////////////////////////////////////////////
2026 :
2027 60 : SbMethod::SbMethod( const OUString& r, SbxDataType t, SbModule* p )
2028 60 : : SbxMethod( r, t ), pMod( p )
2029 : {
2030 60 : bInvalid = sal_True;
2031 : nStart =
2032 : nDebugFlags =
2033 : nLine1 =
2034 60 : nLine2 = 0;
2035 60 : refStatics = new SbxArray;
2036 60 : mCaller = 0;
2037 : // HACK due to 'Referenz could not be saved'
2038 60 : SetFlag( SBX_NO_MODIFY );
2039 60 : }
2040 :
2041 134 : SbMethod::SbMethod( const SbMethod& r )
2042 134 : : SvRefBase( r ), SbxMethod( r )
2043 : {
2044 134 : pMod = r.pMod;
2045 134 : bInvalid = r.bInvalid;
2046 134 : nStart = r.nStart;
2047 134 : nDebugFlags = r.nDebugFlags;
2048 134 : nLine1 = r.nLine1;
2049 134 : nLine2 = r.nLine2;
2050 134 : refStatics = r.refStatics;
2051 134 : mCaller = r.mCaller;
2052 134 : SetFlag( SBX_NO_MODIFY );
2053 134 : }
2054 :
2055 582 : SbMethod::~SbMethod()
2056 : {
2057 582 : }
2058 :
2059 34 : void SbMethod::ClearStatics()
2060 : {
2061 34 : refStatics = new SbxArray;
2062 :
2063 34 : }
2064 0 : SbxArray* SbMethod::GetStatics()
2065 : {
2066 0 : return refStatics;
2067 : }
2068 :
2069 0 : sal_Bool SbMethod::LoadData( SvStream& rStrm, sal_uInt16 nVer )
2070 : {
2071 0 : if( !SbxMethod::LoadData( rStrm, 1 ) )
2072 0 : return sal_False;
2073 : sal_Int16 n;
2074 0 : rStrm >> n;
2075 0 : sal_Int16 nTempStart = (sal_Int16)nStart;
2076 0 : if( nVer == 2 )
2077 0 : rStrm >> nLine1 >> nLine2 >> nTempStart >> bInvalid;
2078 : // HACK ue to 'Referenz could not be saved'
2079 0 : SetFlag( SBX_NO_MODIFY );
2080 0 : nStart = nTempStart;
2081 0 : return sal_True;
2082 : }
2083 :
2084 0 : sal_Bool SbMethod::StoreData( SvStream& rStrm ) const
2085 : {
2086 0 : if( !SbxMethod::StoreData( rStrm ) )
2087 0 : return sal_False;
2088 0 : rStrm << (sal_Int16) nDebugFlags
2089 0 : << (sal_Int16) nLine1
2090 0 : << (sal_Int16) nLine2
2091 0 : << (sal_Int16) nStart
2092 0 : << (sal_uInt8) bInvalid;
2093 0 : return sal_True;
2094 : }
2095 :
2096 0 : void SbMethod::GetLineRange( sal_uInt16& l1, sal_uInt16& l2 )
2097 : {
2098 0 : l1 = nLine1; l2 = nLine2;
2099 0 : }
2100 :
2101 : // Could later be deleted
2102 :
2103 174 : SbxInfo* SbMethod::GetInfo()
2104 : {
2105 174 : return pInfo;
2106 : }
2107 :
2108 : // Interface to execute a method of the applications
2109 : // With special RefCounting, so that the Basic was not fired of by CloseDocument()
2110 : // The return value will be delivered as string.
2111 6 : ErrCode SbMethod::Call( SbxValue* pRet, SbxVariable* pCaller )
2112 : {
2113 6 : if ( pCaller )
2114 : {
2115 : OSL_TRACE("SbMethod::Call Have been passed a caller 0x%x", pCaller );
2116 0 : mCaller = pCaller;
2117 : }
2118 : // RefCount vom Modul hochzaehlen
2119 6 : SbModule* pMod_ = (SbModule*)GetParent();
2120 6 : pMod_->AddRef();
2121 :
2122 : // Increment the RefCount of the Basic
2123 6 : StarBASIC* pBasic = (StarBASIC*)pMod_->GetParent();
2124 6 : pBasic->AddRef();
2125 :
2126 : // Establish the values to get the return value
2127 6 : SbxValues aVals;
2128 6 : aVals.eType = SbxVARIANT;
2129 :
2130 : // #104083: Compile BEFORE get
2131 6 : if( bInvalid && !pMod_->Compile() )
2132 0 : StarBASIC::Error( SbERR_BAD_PROP_VALUE );
2133 :
2134 6 : Get( aVals );
2135 6 : if ( pRet )
2136 6 : pRet->Put( aVals );
2137 :
2138 : // Was there an error
2139 6 : ErrCode nErr = SbxBase::GetError();
2140 6 : SbxBase::ResetError();
2141 :
2142 : // Release objects
2143 6 : pMod_->ReleaseRef();
2144 6 : pBasic->ReleaseRef();
2145 6 : mCaller = 0;
2146 6 : return nErr;
2147 : }
2148 :
2149 :
2150 : // #100883 Own Broadcast for SbMethod
2151 534 : void SbMethod::Broadcast( sal_uIntPtr nHintId )
2152 : {
2153 534 : if( pCst && !IsSet( SBX_NO_BROADCAST ) )
2154 : {
2155 : // Because the method could be called from outside, test here once again
2156 : // the authorisation
2157 134 : if( nHintId & SBX_HINT_DATAWANTED )
2158 134 : if( !CanRead() )
2159 : return;
2160 134 : if( nHintId & SBX_HINT_DATACHANGED )
2161 0 : if( !CanWrite() )
2162 : return;
2163 :
2164 134 : if( pMod && !pMod->IsCompiled() )
2165 0 : pMod->Compile();
2166 :
2167 : // Block broadcasts while creating new method
2168 134 : SfxBroadcaster* pSave = pCst;
2169 134 : pCst = NULL;
2170 134 : SbMethod* pThisCopy = new SbMethod( *this );
2171 134 : SbMethodRef xHolder = pThisCopy;
2172 134 : if( mpPar.Is() )
2173 : {
2174 : // Enrigister this as element 0, but don't reset the parent!
2175 112 : if( GetType() != SbxVOID )
2176 112 : mpPar->PutDirect( pThisCopy, 0 );
2177 112 : SetParameters( NULL );
2178 : }
2179 :
2180 134 : pCst = pSave;
2181 134 : pSave->Broadcast( SbxHint( nHintId, pThisCopy ) );
2182 :
2183 134 : sal_uInt16 nSaveFlags = GetFlags();
2184 134 : SetFlag( SBX_READWRITE );
2185 134 : pCst = NULL;
2186 134 : Put( pThisCopy->GetValues_Impl() );
2187 134 : pCst = pSave;
2188 134 : SetFlags( nSaveFlags );
2189 : }
2190 : }
2191 :
2192 :
2193 : // Implementation of SbJScriptMethod (method class as a wrapper for JavaScript-functions)
2194 :
2195 0 : SbJScriptMethod::SbJScriptMethod( const OUString& r, SbxDataType t, SbModule* p )
2196 0 : : SbMethod( r, t, p )
2197 : {
2198 0 : }
2199 :
2200 0 : SbJScriptMethod::~SbJScriptMethod()
2201 0 : {}
2202 :
2203 :
2204 42 : SbObjModule::SbObjModule( const OUString& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsVbaCompatible )
2205 42 : : SbModule( rName, bIsVbaCompatible )
2206 : {
2207 42 : SetModuleType( mInfo.ModuleType );
2208 42 : if ( mInfo.ModuleType == script::ModuleType::FORM )
2209 : {
2210 0 : SetClassName( OUString("Form" ) );
2211 : }
2212 42 : else if ( mInfo.ModuleObject.is() )
2213 : {
2214 16 : SetUnoObject( uno::makeAny( mInfo.ModuleObject ) );
2215 : }
2216 42 : }
2217 :
2218 126 : SbObjModule::~SbObjModule()
2219 : {
2220 126 : }
2221 :
2222 : void
2223 16 : SbObjModule::SetUnoObject( const uno::Any& aObj ) throw ( uno::RuntimeException )
2224 : {
2225 16 : SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,(SbxVariable*)pDocObject);
2226 16 : if ( pUnoObj && pUnoObj->getUnoAny() == aObj ) // object is equal, nothing to do
2227 16 : return;
2228 16 : pDocObject = new SbUnoObject( GetName(), uno::makeAny( aObj ) );
2229 :
2230 16 : com::sun::star::uno::Reference< com::sun::star::lang::XServiceInfo > xServiceInfo( aObj, com::sun::star::uno::UNO_QUERY_THROW );
2231 16 : if( xServiceInfo->supportsService( OUString("ooo.vba.excel.Worksheet" ) ) )
2232 : {
2233 12 : SetClassName( OUString("Worksheet" ) );
2234 : }
2235 4 : else if( xServiceInfo->supportsService( OUString("ooo.vba.excel.Workbook" ) ) )
2236 : {
2237 4 : SetClassName( OUString("Workbook" ) );
2238 16 : }
2239 : }
2240 :
2241 : SbxVariable*
2242 24 : SbObjModule::GetObject()
2243 : {
2244 24 : return pDocObject;
2245 : }
2246 : SbxVariable*
2247 0 : SbObjModule::Find( const OUString& rName, SbxClassType t )
2248 : {
2249 0 : SbxVariable* pVar = NULL;
2250 0 : if ( pDocObject)
2251 0 : pVar = pDocObject->Find( rName, t );
2252 0 : if ( !pVar )
2253 0 : pVar = SbModule::Find( rName, t );
2254 0 : return pVar;
2255 : }
2256 :
2257 0 : void SbObjModule::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
2258 : const SfxHint& rHint, const TypeId& rHintType )
2259 : {
2260 0 : SbModule::handleProcedureProperties( rBC, rHint );
2261 0 : }
2262 :
2263 :
2264 : typedef ::cppu::WeakImplHelper3<
2265 : awt::XTopWindowListener,
2266 : awt::XWindowListener,
2267 : document::XEventListener > FormObjEventListener_BASE;
2268 :
2269 : class FormObjEventListenerImpl : public FormObjEventListener_BASE
2270 : {
2271 : SbUserFormModule* mpUserForm;
2272 : uno::Reference< lang::XComponent > mxComponent;
2273 : uno::Reference< frame::XModel > mxModel;
2274 : bool mbDisposed;
2275 : sal_Bool mbOpened;
2276 : sal_Bool mbActivated;
2277 : sal_Bool mbShowing;
2278 :
2279 : FormObjEventListenerImpl(const FormObjEventListenerImpl&); // not defined
2280 : FormObjEventListenerImpl& operator=(const FormObjEventListenerImpl&); // not defined
2281 :
2282 : public:
2283 0 : FormObjEventListenerImpl( SbUserFormModule* pUserForm, const uno::Reference< lang::XComponent >& xComponent, const uno::Reference< frame::XModel >& xModel ) :
2284 : mpUserForm( pUserForm ), mxComponent( xComponent), mxModel( xModel ),
2285 0 : mbDisposed( false ), mbOpened( sal_False ), mbActivated( sal_False ), mbShowing( sal_False )
2286 : {
2287 0 : if ( mxComponent.is() )
2288 : {
2289 : OSL_TRACE("*********** Registering the listeners");
2290 : try
2291 : {
2292 0 : uno::Reference< awt::XTopWindow >( mxComponent, uno::UNO_QUERY_THROW )->addTopWindowListener( this );
2293 : }
2294 0 : catch(const uno::Exception& ) {}
2295 : try
2296 : {
2297 0 : uno::Reference< awt::XWindow >( mxComponent, uno::UNO_QUERY_THROW )->addWindowListener( this );
2298 : }
2299 0 : catch(const uno::Exception& ) {}
2300 : }
2301 :
2302 0 : if ( mxModel.is() )
2303 : {
2304 : try
2305 : {
2306 0 : uno::Reference< document::XEventBroadcaster >( mxModel, uno::UNO_QUERY_THROW )->addEventListener( this );
2307 : }
2308 0 : catch(const uno::Exception& ) {}
2309 : }
2310 0 : }
2311 :
2312 0 : virtual ~FormObjEventListenerImpl()
2313 0 : {
2314 0 : removeListener();
2315 0 : }
2316 :
2317 0 : sal_Bool isShowing() const { return mbShowing; }
2318 :
2319 0 : void removeListener()
2320 : {
2321 0 : if ( mxComponent.is() && !mbDisposed )
2322 : {
2323 : OSL_TRACE("*********** Removing the listeners");
2324 : try
2325 : {
2326 0 : uno::Reference< awt::XTopWindow >( mxComponent, uno::UNO_QUERY_THROW )->removeTopWindowListener( this );
2327 : }
2328 0 : catch(const uno::Exception& ) {}
2329 : try
2330 : {
2331 0 : uno::Reference< awt::XWindow >( mxComponent, uno::UNO_QUERY_THROW )->removeWindowListener( this );
2332 : }
2333 0 : catch(const uno::Exception& ) {}
2334 : }
2335 0 : mxComponent.clear();
2336 :
2337 0 : if ( mxModel.is() && !mbDisposed )
2338 : {
2339 : try
2340 : {
2341 0 : uno::Reference< document::XEventBroadcaster >( mxModel, uno::UNO_QUERY_THROW )->removeEventListener( this );
2342 : }
2343 0 : catch(const uno::Exception& ) {}
2344 : }
2345 0 : mxModel.clear();
2346 0 : }
2347 :
2348 0 : virtual void SAL_CALL windowOpened( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2349 : {
2350 0 : if ( mpUserForm )
2351 : {
2352 0 : mbOpened = sal_True;
2353 0 : mbShowing = sal_True;
2354 0 : if ( mbActivated )
2355 : {
2356 0 : mbOpened = mbActivated = sal_False;
2357 0 : mpUserForm->triggerActivateEvent();
2358 : }
2359 : }
2360 0 : }
2361 :
2362 :
2363 0 : virtual void SAL_CALL windowClosing( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2364 : {
2365 : #ifdef IN_THE_FUTURE
2366 : uno::Reference< awt::XDialog > xDialog( e.Source, uno::UNO_QUERY );
2367 : if ( xDialog.is() )
2368 : {
2369 : uno::Reference< awt::XControl > xControl( xDialog, uno::UNO_QUERY );
2370 : if ( xControl->getPeer().is() )
2371 : {
2372 : uno::Reference< document::XVbaMethodParameter > xVbaMethodParameter( xControl->getPeer(), uno::UNO_QUERY );
2373 : if ( xVbaMethodParameter.is() )
2374 : {
2375 : sal_Int8 nCancel = 0;
2376 : sal_Int8 nCloseMode = ::ooo::vba::VbQueryClose::vbFormControlMenu;
2377 :
2378 : Sequence< Any > aParams;
2379 : aParams.realloc(2);
2380 : aParams[0] <<= nCancel;
2381 : aParams[1] <<= nCloseMode;
2382 :
2383 : mpUserForm->triggerMethod( OUString("Userform_QueryClose" ), aParams);
2384 : return;
2385 :
2386 : }
2387 : }
2388 : }
2389 :
2390 : mpUserForm->triggerMethod( OUString("Userform_QueryClose" ) );
2391 : #endif
2392 0 : }
2393 :
2394 :
2395 0 : virtual void SAL_CALL windowClosed( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2396 : {
2397 0 : mbOpened = sal_False;
2398 0 : mbShowing = sal_False;
2399 0 : }
2400 :
2401 0 : virtual void SAL_CALL windowMinimized( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2402 : {
2403 0 : }
2404 :
2405 0 : virtual void SAL_CALL windowNormalized( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2406 : {
2407 0 : }
2408 :
2409 0 : virtual void SAL_CALL windowActivated( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2410 : {
2411 0 : if ( mpUserForm )
2412 : {
2413 0 : mbActivated = sal_True;
2414 0 : if ( mbOpened )
2415 : {
2416 0 : mbOpened = mbActivated = sal_False;
2417 0 : mpUserForm->triggerActivateEvent();
2418 : }
2419 : }
2420 0 : }
2421 :
2422 0 : virtual void SAL_CALL windowDeactivated( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2423 : {
2424 0 : if ( mpUserForm )
2425 0 : mpUserForm->triggerDeactivateEvent();
2426 0 : }
2427 :
2428 0 : virtual void SAL_CALL windowResized( const awt::WindowEvent& /*e*/ ) throw (uno::RuntimeException)
2429 : {
2430 0 : if ( mpUserForm )
2431 : {
2432 0 : mpUserForm->triggerResizeEvent();
2433 0 : mpUserForm->triggerLayoutEvent();
2434 : }
2435 0 : }
2436 :
2437 0 : virtual void SAL_CALL windowMoved( const awt::WindowEvent& /*e*/ ) throw (uno::RuntimeException)
2438 : {
2439 0 : if ( mpUserForm )
2440 0 : mpUserForm->triggerLayoutEvent();
2441 0 : }
2442 :
2443 0 : virtual void SAL_CALL windowShown( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2444 : {
2445 0 : }
2446 :
2447 0 : virtual void SAL_CALL windowHidden( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
2448 : {
2449 0 : }
2450 :
2451 0 : virtual void SAL_CALL notifyEvent( const document::EventObject& rEvent ) throw (uno::RuntimeException)
2452 : {
2453 : // early dosposing on document event "OnUnload", to be sure Basic still exists when calling VBA "UserForm_Terminate"
2454 0 : if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_CLOSEDOC ) )
2455 : {
2456 0 : removeListener();
2457 0 : mbDisposed = true;
2458 0 : if ( mpUserForm )
2459 0 : mpUserForm->ResetApiObj(); // will trigger "UserForm_Terminate"
2460 : }
2461 0 : }
2462 :
2463 0 : virtual void SAL_CALL disposing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException)
2464 : {
2465 : OSL_TRACE("** Userform/Dialog disposing");
2466 0 : removeListener();
2467 0 : mbDisposed = true;
2468 0 : if ( mpUserForm )
2469 0 : mpUserForm->ResetApiObj( false ); // pass false (too late to trigger VBA events here)
2470 0 : }
2471 : };
2472 :
2473 0 : SbUserFormModule::SbUserFormModule( const OUString& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsCompat )
2474 : : SbObjModule( rName, mInfo, bIsCompat )
2475 : , m_mInfo( mInfo )
2476 0 : , mbInit( false )
2477 : {
2478 0 : m_xModel.set( mInfo.ModuleObject, uno::UNO_QUERY_THROW );
2479 0 : }
2480 :
2481 0 : SbUserFormModule::~SbUserFormModule()
2482 : {
2483 0 : }
2484 :
2485 0 : void SbUserFormModule::ResetApiObj( bool bTriggerTerminateEvent )
2486 : {
2487 : OSL_TRACE(" SbUserFormModule::ResetApiObj( %s )", bTriggerTerminateEvent ? "true" : "false" );
2488 0 : if ( bTriggerTerminateEvent && m_xDialog.is() ) // probably someone close the dialog window
2489 : {
2490 0 : triggerTerminateEvent();
2491 : }
2492 0 : pDocObject = NULL;
2493 0 : m_xDialog = NULL;
2494 0 : }
2495 :
2496 0 : void SbUserFormModule::triggerMethod( const OUString& aMethodToRun )
2497 : {
2498 0 : Sequence< Any > aArguments;
2499 0 : triggerMethod( aMethodToRun, aArguments );
2500 0 : }
2501 :
2502 0 : void SbUserFormModule::triggerMethod( const OUString& aMethodToRun, Sequence< Any >& aArguments )
2503 : {
2504 : OSL_TRACE("*** trigger %s ***", rtl::OUStringToOString( aMethodToRun, RTL_TEXTENCODING_UTF8 ).getStr() );
2505 : // Search method
2506 0 : SbxVariable* pMeth = SbObjModule::Find( aMethodToRun, SbxCLASS_METHOD );
2507 0 : if( pMeth )
2508 : {
2509 0 : if ( aArguments.getLength() > 0 ) // Setup parameters
2510 : {
2511 0 : SbxArrayRef xArray = new SbxArray;
2512 0 : xArray->Put( pMeth, 0 ); // Method as parameter 0
2513 :
2514 0 : for ( sal_Int32 i = 0; i < aArguments.getLength(); ++i )
2515 : {
2516 0 : SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT );
2517 0 : unoToSbxValue( static_cast< SbxVariable* >( xSbxVar ), aArguments[i] );
2518 0 : xArray->Put( xSbxVar, static_cast< sal_uInt16 >( i ) + 1 );
2519 :
2520 : // Enable passing by ref
2521 0 : if ( xSbxVar->GetType() != SbxVARIANT )
2522 0 : xSbxVar->SetFlag( SBX_FIXED );
2523 0 : }
2524 0 : pMeth->SetParameters( xArray );
2525 :
2526 0 : SbxValues aVals;
2527 0 : pMeth->Get( aVals );
2528 :
2529 0 : for ( sal_Int32 i = 0; i < aArguments.getLength(); ++i )
2530 : {
2531 0 : aArguments[i] = sbxToUnoValue( xArray->Get( static_cast< sal_uInt16 >(i) + 1) );
2532 : }
2533 0 : pMeth->SetParameters( NULL );
2534 : }
2535 : else
2536 : {
2537 0 : SbxValues aVals;
2538 0 : pMeth->Get( aVals );
2539 : }
2540 : }
2541 0 : }
2542 :
2543 0 : void SbUserFormModule::triggerActivateEvent( void )
2544 : {
2545 : OSL_TRACE("**** entering SbUserFormModule::triggerActivate");
2546 0 : triggerMethod( OUString( "UserForm_Activate" ) );
2547 : OSL_TRACE("**** leaving SbUserFormModule::triggerActivate");
2548 0 : }
2549 :
2550 0 : void SbUserFormModule::triggerDeactivateEvent( void )
2551 : {
2552 : OSL_TRACE("**** SbUserFormModule::triggerDeactivate");
2553 0 : triggerMethod( OUString("Userform_Deactivate" ) );
2554 0 : }
2555 :
2556 0 : void SbUserFormModule::triggerInitializeEvent( void )
2557 : {
2558 0 : if ( mbInit )
2559 0 : return;
2560 : OSL_TRACE("**** SbUserFormModule::triggerInitializeEvent");
2561 0 : static OUString aInitMethodName( "Userform_Initialize");
2562 0 : triggerMethod( aInitMethodName );
2563 0 : mbInit = true;
2564 : }
2565 :
2566 0 : void SbUserFormModule::triggerTerminateEvent( void )
2567 : {
2568 : OSL_TRACE("**** SbUserFormModule::triggerTerminateEvent");
2569 0 : static OUString aTermMethodName( "Userform_Terminate" );
2570 0 : triggerMethod( aTermMethodName );
2571 0 : mbInit=false;
2572 0 : }
2573 :
2574 0 : void SbUserFormModule::triggerLayoutEvent( void )
2575 : {
2576 0 : static OUString aMethodName( "Userform_Layout" );
2577 0 : triggerMethod( aMethodName );
2578 0 : }
2579 :
2580 0 : void SbUserFormModule::triggerResizeEvent( void )
2581 : {
2582 0 : static OUString aMethodName("Userform_Resize");
2583 0 : triggerMethod( aMethodName );
2584 0 : }
2585 :
2586 0 : SbUserFormModuleInstance* SbUserFormModule::CreateInstance()
2587 : {
2588 0 : SbUserFormModuleInstance* pInstance = new SbUserFormModuleInstance( this, GetName(), m_mInfo, IsVBACompat() );
2589 0 : return pInstance;
2590 : }
2591 :
2592 0 : SbUserFormModuleInstance::SbUserFormModuleInstance( SbUserFormModule* pParentModule,
2593 : const OUString& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsVBACompat )
2594 : : SbUserFormModule( rName, mInfo, bIsVBACompat )
2595 0 : , m_pParentModule( pParentModule )
2596 : {
2597 0 : }
2598 :
2599 0 : sal_Bool SbUserFormModuleInstance::IsClass( const OUString& rName ) const
2600 : {
2601 0 : sal_Bool bParentNameMatches = m_pParentModule->GetName().equalsIgnoreAsciiCase( rName );
2602 0 : sal_Bool bRet = bParentNameMatches || SbxObject::IsClass( rName );
2603 0 : return bRet;
2604 : }
2605 :
2606 0 : SbxVariable* SbUserFormModuleInstance::Find( const OUString& rName, SbxClassType t )
2607 : {
2608 0 : SbxVariable* pVar = m_pParentModule->Find( rName, t );
2609 0 : return pVar;
2610 : }
2611 :
2612 :
2613 0 : void SbUserFormModule::Load()
2614 : {
2615 : OSL_TRACE("** load() ");
2616 : // forces a load
2617 0 : if ( !pDocObject )
2618 0 : InitObject();
2619 0 : }
2620 :
2621 :
2622 0 : void SbUserFormModule::Unload()
2623 : {
2624 : OSL_TRACE("** Unload() ");
2625 :
2626 0 : sal_Int8 nCancel = 0;
2627 0 : sal_Int8 nCloseMode = ::ooo::vba::VbQueryClose::vbFormCode;
2628 :
2629 0 : Sequence< Any > aParams;
2630 0 : aParams.realloc(2);
2631 0 : aParams[0] <<= nCancel;
2632 0 : aParams[1] <<= nCloseMode;
2633 :
2634 0 : triggerMethod( OUString("Userform_QueryClose" ), aParams);
2635 :
2636 0 : aParams[0] >>= nCancel;
2637 : // basic boolean ( and what the user might use ) can be ambiguous ( e.g. basic true = -1 )
2638 : // test agains 0 ( false ) and assume anything else is true
2639 : // ( Note: ) this used to work ( something changes somewhere )
2640 0 : if (nCancel != 0)
2641 : {
2642 0 : return;
2643 : }
2644 :
2645 0 : if ( m_xDialog.is() )
2646 : {
2647 0 : triggerTerminateEvent();
2648 : }
2649 : // Search method
2650 0 : SbxVariable* pMeth = SbObjModule::Find( OUString("UnloadObject"), SbxCLASS_METHOD );
2651 0 : if( pMeth )
2652 : {
2653 : OSL_TRACE("Attempting too run the UnloadObjectMethod");
2654 0 : m_xDialog.clear(); //release ref to the uno object
2655 0 : SbxValues aVals;
2656 0 : bool bWaitForDispose = true; // assume dialog is showing
2657 0 : if ( m_DialogListener.get() )
2658 : {
2659 0 : bWaitForDispose = m_DialogListener->isShowing();
2660 : OSL_TRACE("Showing %d", bWaitForDispose );
2661 : }
2662 0 : pMeth->Get( aVals);
2663 0 : if ( !bWaitForDispose )
2664 : {
2665 : // we've either already got a dispose or we'er never going to get one
2666 0 : ResetApiObj();
2667 : } // else wait for dispose
2668 : OSL_TRACE("UnloadObject completed ( we hope )");
2669 0 : }
2670 : }
2671 :
2672 :
2673 : void registerComponentToBeDisposedForBasic( Reference< XComponent > xComponent, StarBASIC* pBasic );
2674 :
2675 0 : void SbUserFormModule::InitObject()
2676 : {
2677 : try
2678 : {
2679 0 : OUString aHook("VBAGlobals");
2680 0 : SbUnoObject* pGlobs = (SbUnoObject*)GetParent()->Find( aHook, SbxCLASS_DONTCARE );
2681 0 : if ( m_xModel.is() && pGlobs )
2682 : {
2683 : // broadcast INITIALIZE_USERFORM script event before the dialog is created
2684 0 : Reference< script::vba::XVBACompatibility > xVBACompat( getVBACompatibility( m_xModel ), uno::UNO_SET_THROW );
2685 0 : xVBACompat->broadcastVBAScriptEvent( script::vba::VBAScriptEventId::INITIALIZE_USERFORM, GetName() );
2686 :
2687 0 : uno::Reference< lang::XMultiServiceFactory > xVBAFactory( pGlobs->getUnoAny(), uno::UNO_QUERY_THROW );
2688 0 : uno::Reference< lang::XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
2689 0 : uno::Sequence< uno::Any > aArgs(1);
2690 0 : aArgs[ 0 ] <<= m_xModel;
2691 0 : OUString sDialogUrl( "vnd.sun.star.script:" );
2692 0 : OUString sProjectName( "Standard" );
2693 :
2694 : try
2695 : {
2696 0 : Reference< beans::XPropertySet > xProps( m_xModel, UNO_QUERY_THROW );
2697 0 : uno::Reference< script::vba::XVBACompatibility > xVBAMode( xProps->getPropertyValue( OUString( "BasicLibraries" ) ), uno::UNO_QUERY_THROW );
2698 0 : sProjectName = xVBAMode->getProjectName();
2699 : }
2700 0 : catch(const Exception& ) {}
2701 :
2702 0 : sDialogUrl = sDialogUrl + sProjectName + "." + GetName() + "?location=document";
2703 :
2704 0 : uno::Reference< awt::XDialogProvider > xProvider( xFactory->createInstanceWithArguments( OUString( "com.sun.star.awt.DialogProvider"), aArgs ), uno::UNO_QUERY_THROW );
2705 0 : m_xDialog = xProvider->createDialog( sDialogUrl );
2706 :
2707 : // create vba api object
2708 0 : aArgs.realloc( 4 );
2709 0 : aArgs[ 0 ] = uno::Any();
2710 0 : aArgs[ 1 ] <<= m_xDialog;
2711 0 : aArgs[ 2 ] <<= m_xModel;
2712 0 : aArgs[ 3 ] <<= rtl::OUString( GetParent()->GetName() );
2713 0 : pDocObject = new SbUnoObject( GetName(), uno::makeAny( xVBAFactory->createInstanceWithArguments( rtl::OUString( "ooo.vba.msforms.UserForm"), aArgs ) ) );
2714 :
2715 0 : uno::Reference< lang::XComponent > xComponent( m_xDialog, uno::UNO_QUERY_THROW );
2716 :
2717 : // the dialog must be disposed at the end!
2718 0 : StarBASIC* pParentBasic = NULL;
2719 0 : SbxObject* pCurObject = this;
2720 0 : do
2721 : {
2722 0 : SbxObject* pObjParent = pCurObject->GetParent();
2723 0 : pParentBasic = PTR_CAST( StarBASIC, pObjParent );
2724 0 : pCurObject = pObjParent;
2725 : }
2726 : while( pParentBasic == NULL && pCurObject != NULL );
2727 :
2728 : OSL_ASSERT( pParentBasic != NULL );
2729 0 : registerComponentToBeDisposedForBasic( xComponent, pParentBasic );
2730 :
2731 : // if old listener object exists, remove it from dialog and document model
2732 0 : if( m_DialogListener.is() )
2733 0 : m_DialogListener->removeListener();
2734 0 : m_DialogListener.set( new FormObjEventListenerImpl( this, xComponent, m_xModel ) );
2735 :
2736 0 : triggerInitializeEvent();
2737 0 : }
2738 : }
2739 0 : catch(const uno::Exception& )
2740 : {
2741 : }
2742 :
2743 0 : }
2744 :
2745 : SbxVariable*
2746 0 : SbUserFormModule::Find( const rtl::OUString& rName, SbxClassType t )
2747 : {
2748 0 : if ( !pDocObject && !GetSbData()->bRunInit && GetSbData()->pInst )
2749 0 : InitObject();
2750 0 : return SbObjModule::Find( rName, t );
2751 : }
2752 :
2753 8 : SbProperty::SbProperty( const OUString& r, SbxDataType t, SbModule* p )
2754 8 : : SbxProperty( r, t ), pMod( p )
2755 : {
2756 8 : bInvalid = sal_False;
2757 8 : }
2758 :
2759 24 : SbProperty::~SbProperty()
2760 24 : {}
2761 :
2762 :
2763 0 : SbProcedureProperty::~SbProcedureProperty()
2764 0 : {}
2765 :
2766 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|