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