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