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