diff options
author | Noel Power <noel.power@novell.com> | 2010-10-13 10:51:50 +0100 |
---|---|---|
committer | Noel Power <noel.power@novell.com> | 2010-10-13 10:51:50 +0100 |
commit | 6db6a43ddc5a66f41f109b7995fd83adb5d35411 (patch) | |
tree | be01c36438a39fdebd43608355671d2e6d120108 /basic | |
parent | 20658054d8bd6380b4b175b552ccc1480c49d01c (diff) | |
parent | d1a9ad8f4dc25817cea279262286cdfb421fe891 (diff) |
Merge branch 'vba' fix conflics, trailing ws & tab issues
also removed some old headers ( which I need to add new ones for )
Conflicts:
basic/source/classes/sbunoobj.cxx
basic/source/classes/sbxmod.cxx
xmloff/inc/xmlnmspe.hxx
xmloff/inc/xmloff/xmltoken.hxx
xmlscript/inc/xmlscript/xmldlg_imexp.hxx
Diffstat (limited to 'basic')
32 files changed, 1451 insertions, 273 deletions
diff --git a/basic/inc/basic/basmgr.hxx b/basic/inc/basic/basmgr.hxx index 89dca9198b8e..8135d6ede38a 100644 --- a/basic/inc/basic/basmgr.hxx +++ b/basic/inc/basic/basmgr.hxx @@ -236,7 +236,7 @@ public: takes the names of modules whose size exceeds the legacy limit */ bool LegacyPsswdBinaryLimitExceeded( ::com::sun::star::uno::Sequence< rtl::OUString >& _out_rModuleNames ); - + bool HasExeCode( const String& ); private: BOOL IsReference( USHORT nLib ); diff --git a/basic/inc/basic/sbmeth.hxx b/basic/inc/basic/sbmeth.hxx index ebfcd22d19af..63ff4aaf5e0b 100644 --- a/basic/inc/basic/sbmeth.hxx +++ b/basic/inc/basic/sbmeth.hxx @@ -46,6 +46,7 @@ class SbMethod : public SbxMethod friend class SbIfaceMapperMethod; SbMethodImpl* mpSbMethodImpl; // Impl data + SbxVariable* mCaller; // caller SbModule* pMod; USHORT nDebugFlags; USHORT nLine1, nLine2; @@ -72,7 +73,7 @@ public: void GetLineRange( USHORT&, USHORT& ); // Interface to execute a method from the applications - virtual ErrCode Call( SbxValue* pRet = NULL ); + virtual ErrCode Call( SbxValue* pRet = NULL, SbxVariable* pCaller = NULL ); virtual void Broadcast( ULONG nHintId ); }; diff --git a/basic/inc/basic/sbmod.hxx b/basic/inc/basic/sbmod.hxx index abb482f7bfe5..2f6d049e24d8 100644 --- a/basic/inc/basic/sbmod.hxx +++ b/basic/inc/basic/sbmod.hxx @@ -59,6 +59,8 @@ class SbModule : public SbxObject SbModuleImpl* mpSbModuleImpl; // Impl data std::vector< String > mModuleVariableNames; + SbModule(); + SbModule(const SbModule&); protected: com::sun::star::uno::Reference< com::sun::star::script::XInvocation > mxWrapper; @@ -132,6 +134,7 @@ public: BOOL LoadBinaryData( SvStream& ); BOOL ExceedsLegacyModuleSize(); void fixUpMethodStart( bool bCvtToLegacy, SbiImage* pImg = NULL ) const; + bool HasExeCode(); BOOL IsVBACompat() const; void SetVBACompat( BOOL bCompat ); INT32 GetModuleType() { return mnType; } diff --git a/basic/inc/basic/sbuno.hxx b/basic/inc/basic/sbuno.hxx index d816d424313b..cc29e3eb4734 100644 --- a/basic/inc/basic/sbuno.hxx +++ b/basic/inc/basic/sbuno.hxx @@ -38,6 +38,7 @@ SbxObjectRef GetSbUnoObject( const String& aName, const com::sun::star::uno::Any // Force creation of all properties for debugging void createAllObjectProperties( SbxObject* pObj ); +void SetSbUnoObjectDfltPropName( SbxObject* pObj ); ::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar ); diff --git a/basic/source/basmgr/basmgr.cxx b/basic/source/basmgr/basmgr.cxx index 5567edbb4280..c36ee654fd88 100644 --- a/basic/source/basmgr/basmgr.cxx +++ b/basic/source/basmgr/basmgr.cxx @@ -1139,6 +1139,25 @@ void BasicManager::LegacyDeleteBasicManager( BasicManager*& _rpManager ) _rpManager = NULL; } + +bool BasicManager::HasExeCode( const String& sLib ) +{ + StarBASIC* pLib = GetLib(sLib); + if ( pLib ) + { + SbxArray* pMods = pLib->GetModules(); + USHORT nMods = pMods ? pMods->Count() : 0; + for( USHORT i = 0; i < nMods; i++ ) + { + SbModule* p = (SbModule*) pMods->Get( i ); + if ( p ) + if ( p->HasExeCode() ) + return true; + } + } + return false; +} + void BasicManager::Init() { DBG_CHKTHIS( BasicManager, 0 ); diff --git a/basic/source/classes/image.cxx b/basic/source/classes/image.cxx index 2bdfbfd3f287..6a8de8b589d1 100644 --- a/basic/source/classes/image.cxx +++ b/basic/source/classes/image.cxx @@ -431,7 +431,7 @@ void SbiImage::AddString( const String& r ) memcpy( p, pStrings, nStringSize * sizeof( sal_Unicode ) ); delete[] pStrings; pStrings = p; - nStringSize = sal::static_int_cast< UINT16 >(nNewLen); + nStringSize = sal::static_int_cast< UINT32 >(nNewLen); } else bError = TRUE; diff --git a/basic/source/classes/sb.cxx b/basic/source/classes/sb.cxx index a68d203fcee3..fd6f18aa3ba5 100644 --- a/basic/source/classes/sb.cxx +++ b/basic/source/classes/sb.cxx @@ -611,93 +611,7 @@ SbClassModuleObject::~SbClassModuleObject() void SbClassModuleObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType, const SfxHint& rHint, const TypeId& rHintType ) { - bool bDone = false; - - const SbxHint* pHint = PTR_CAST(SbxHint,&rHint); - if( pHint ) - { - SbxVariable* pVar = pHint->GetVar(); - SbProcedureProperty* pProcProperty = PTR_CAST( SbProcedureProperty, pVar ); - if( pProcProperty ) - { - bDone = true; - - if( pHint->GetId() == SBX_HINT_DATAWANTED ) - { - String aProcName; - aProcName.AppendAscii( "Property Get " ); - aProcName += pProcProperty->GetName(); - - SbxVariable* pMeth = Find( aProcName, SbxCLASS_METHOD ); - if( pMeth ) - { - SbxValues aVals; - aVals.eType = SbxVARIANT; - - SbxArray* pArg = pVar->GetParameters(); - USHORT nVarParCount = (pArg != NULL) ? pArg->Count() : 0; - if( nVarParCount > 1 ) - { - SbxArrayRef xMethParameters = new SbxArray; - xMethParameters->Put( pMeth, 0 ); // Method as parameter 0 - for( USHORT i = 1 ; i < nVarParCount ; ++i ) - { - SbxVariable* pPar = pArg->Get( i ); - xMethParameters->Put( pPar, i ); - } - - pMeth->SetParameters( xMethParameters ); - pMeth->Get( aVals ); - pMeth->SetParameters( NULL ); - } - else - { - pMeth->Get( aVals ); - } - - pVar->Put( aVals ); - } - } - else if( pHint->GetId() == SBX_HINT_DATACHANGED ) - { - SbxVariable* pMeth = NULL; - - bool bSet = pProcProperty->isSet(); - if( bSet ) - { - pProcProperty->setSet( false ); - - String aProcName; - aProcName.AppendAscii( "Property Set " ); - aProcName += pProcProperty->GetName(); - pMeth = Find( aProcName, SbxCLASS_METHOD ); - } - if( !pMeth ) // Let - { - String aProcName; - aProcName.AppendAscii( "Property Let " ); - aProcName += pProcProperty->GetName(); - pMeth = Find( aProcName, SbxCLASS_METHOD ); - } - - if( pMeth ) - { - // Setup parameters - SbxArrayRef xArray = new SbxArray; - xArray->Put( pMeth, 0 ); // Method as parameter 0 - xArray->Put( pVar, 1 ); - pMeth->SetParameters( xArray ); - - SbxValues aVals; - pMeth->Get( aVals ); - pMeth->SetParameters( NULL ); - } - } - } - } - - if( !bDone ) - SbModule::SFX_NOTIFY( rBC, rBCType, rHint, rHintType ); + SbModule::SFX_NOTIFY( rBC, rBCType, rHint, rHintType ); } SbxVariable* SbClassModuleObject::Find( const XubString& rName, SbxClassType t ) @@ -1217,7 +1131,6 @@ SbxVariable* StarBASIC::Find( const String& rName, SbxClassType t ) INT32 nType = p->GetModuleType(); if ( nType == ModuleType::DOCUMENT || nType == ModuleType::FORM ) continue; - // otherwise check if the element is available // unset GBLSEARCH-Flag (due to Rekursion) USHORT nGblFlag = p->GetFlags() & SBX_GBLSEARCH; diff --git a/basic/source/classes/sbunoobj.cxx b/basic/source/classes/sbunoobj.cxx index 684edbc11bbe..55953d2e5b47 100644 --- a/basic/source/classes/sbunoobj.cxx +++ b/basic/source/classes/sbunoobj.cxx @@ -58,6 +58,7 @@ #include <com/sun/star/script/XInvocationAdapterFactory.hpp> #include <com/sun/star/script/XTypeConverter.hpp> #include <com/sun/star/script/XDefaultProperty.hpp> +#include <com/sun/star/script/XDefaultMethod.hpp> #include <com/sun/star/container/XNameAccess.hpp> #include <com/sun/star/container/XHierarchicalNameAccess.hpp> #include <com/sun/star/reflection/XIdlArray.hpp> @@ -69,7 +70,7 @@ #include <com/sun/star/bridge/oleautomation/Decimal.hpp> #include <com/sun/star/bridge/oleautomation/Currency.hpp> #include <com/sun/star/bridge/oleautomation/XAutomationObject.hpp> - +#include <com/sun/star/script/XAutomationInvocation.hpp> using com::sun::star::uno::Reference; using namespace com::sun::star::uno; @@ -155,6 +156,21 @@ SbxVariable* getDefaultProp( SbxVariable* pRef ) return pDefaultProp; } +void SetSbUnoObjectDfltPropName( SbxObject* pObj ) +{ + SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,(SbxObject*) pObj); + if ( pUnoObj ) + { + String sDfltPropName; + + if ( SbUnoObject::getDefaultPropName( pUnoObj, sDfltPropName ) ) + { + OSL_TRACE("SetSbUnoObjectDfltPropName setting dflt prop for %s", rtl::OUStringToOString( pObj->GetName(), RTL_TEXTENCODING_UTF8 ).getStr() ); + pUnoObj->SetDfltProperty( sDfltPropName ); + } + } +} + Reference< XComponentContext > getComponentContext_Impl( void ) { static Reference< XComponentContext > xContext; @@ -456,6 +472,32 @@ void implHandleWrappedTargetException( const Any& _rWrappedTargetException ) SbError nError( ERRCODE_BASIC_EXCEPTION ); ::rtl::OUStringBuffer aMessageBuf; + // Add for VBA, to get the correct error code and message. + if ( SbiRuntime::isVBAEnabled() ) + { + if ( aExamine >>= aBasicError ) + { + if ( aBasicError.ErrorCode != 0 ) + { + nError = StarBASIC::GetSfxFromVBError( (USHORT) aBasicError.ErrorCode ); + if ( nError == 0 ) + { + nError = (SbError) aBasicError.ErrorCode; + } + aMessageBuf.append( aBasicError.ErrorMessageArgument ); + aExamine.clear(); + } + } + + IndexOutOfBoundsException aIdxOutBndsExp; + if ( aExamine >>= aIdxOutBndsExp ) + { + nError = SbERR_OUT_OF_RANGE; + aExamine.clear(); + } + } + // End add + // strip any other WrappedTargetException instances, but this time preserve the error messages. WrappedTargetException aWrapped; sal_Int32 nLevel = 0; @@ -1505,6 +1547,101 @@ Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty return aRetVal; } +void processAutomationParams( SbxArray* pParams, Sequence< Any >& args, bool bOLEAutomation, UINT32 nParamCount ) +{ + AutomationNamedArgsSbxArray* pArgNamesArray = NULL; + if( bOLEAutomation ) + pArgNamesArray = PTR_CAST(AutomationNamedArgsSbxArray,pParams); + + args.realloc( nParamCount ); + Any* pAnyArgs = args.getArray(); + bool bBlockConversionToSmallestType = pINST->IsCompatibility(); + UINT32 i = 0; + if( pArgNamesArray ) + { + Sequence< ::rtl::OUString >& rNameSeq = pArgNamesArray->getNames(); + ::rtl::OUString* pNames = rNameSeq.getArray(); + Any aValAny; + for( i = 0 ; i < nParamCount ; i++ ) + { + USHORT iSbx = (USHORT)(i+1); + + aValAny = sbxToUnoValueImpl( pParams->Get( iSbx ), + bBlockConversionToSmallestType ); + + ::rtl::OUString aParamName = pNames[iSbx]; + if( aParamName.getLength() ) + { + oleautomation::NamedArgument aNamedArgument; + aNamedArgument.Name = aParamName; + aNamedArgument.Value = aValAny; + pAnyArgs[i] <<= aNamedArgument; + } + else + { + pAnyArgs[i] = aValAny; + } + } + } + else + { + for( i = 0 ; i < nParamCount ; i++ ) + { + pAnyArgs[i] = sbxToUnoValueImpl( pParams->Get( (USHORT)(i+1) ), + bBlockConversionToSmallestType ); + } + } + +} +enum INVOKETYPE +{ + GetProp = 0, + SetProp, + Func +}; +Any invokeAutomationMethod( const String& Name, Sequence< Any >& args, SbxArray* pParams, UINT32 nParamCount, Reference< XInvocation >& rxInvocation, INVOKETYPE invokeType = Func ) +{ + Sequence< INT16 > OutParamIndex; + Sequence< Any > OutParam; + + Any aRetAny; + switch( invokeType ) + { + case Func: + aRetAny = rxInvocation->invoke( Name, args, OutParamIndex, OutParam ); + break; + case GetProp: + { + Reference< XAutomationInvocation > xAutoInv( rxInvocation, UNO_QUERY ); + aRetAny = xAutoInv->invokeGetProperty( Name, args, OutParamIndex, OutParam ); + break; + } + case SetProp: + { + Reference< XAutomationInvocation > xAutoInv( rxInvocation, UNO_QUERY_THROW ); + aRetAny = xAutoInv->invokePutProperty( Name, args, OutParamIndex, OutParam ); + break; + } + default: + break; // should introduce an error here + + } + const INT16* pIndices = OutParamIndex.getConstArray(); + UINT32 nLen = OutParamIndex.getLength(); + if( nLen ) + { + const Any* pNewValues = OutParam.getConstArray(); + for( UINT32 j = 0 ; j < nLen ; j++ ) + { + INT16 iTarget = pIndices[ j ]; + if( iTarget >= (INT16)nParamCount ) + break; + unoToSbxValue( (SbxVariable*)pParams->Get( (USHORT)(j+1) ), pNewValues[ j ] ); + } + } + return aRetAny; +} + // Debugging help method to readout the imlemented interfaces of an object String Impl_GetInterfaceInfo( const Reference< XInterface >& x, const Reference< XIdlClass >& xClass, USHORT nRekLevel ) { @@ -2011,11 +2148,24 @@ void SbUnoObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType, { try { - // get the value - Any aRetAny = mxInvocation->getValue( pProp->GetName() ); - + UINT32 nParamCount = pParams ? ((UINT32)pParams->Count() - 1) : 0; + sal_Bool bCanBeConsideredAMethod = mxInvocation->hasMethod( pProp->GetName() ); + Any aRetAny; + if ( bCanBeConsideredAMethod && nParamCount ) + { + // Automation properties have methods, so.. we need to invoke this through + // XInvocation + Sequence<Any> args; + processAutomationParams( pParams, args, true, nParamCount ); + aRetAny = invokeAutomationMethod( pProp->GetName(), args, pParams, nParamCount, mxInvocation, GetProp ); + } + else + aRetAny = mxInvocation->getValue( pProp->GetName() ); // take over the value from Uno to Sbx unoToSbxValue( pVar, aRetAny ); + if( pParams && bCanBeConsideredAMethod ) + pVar->SetParameters( NULL ); + } catch( const Exception& ) { @@ -2140,52 +2290,7 @@ void SbUnoObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType, else if( bInvocation && pParams && mxInvocation.is() ) { bool bOLEAutomation = true; - // TODO: bOLEAutomation = xOLEAutomation.is() - - AutomationNamedArgsSbxArray* pArgNamesArray = NULL; - if( bOLEAutomation ) - pArgNamesArray = PTR_CAST(AutomationNamedArgsSbxArray,pParams); - - args.realloc( nParamCount ); - Any* pAnyArgs = args.getArray(); - bool bBlockConversionToSmallestType = pINST->IsCompatibility(); - if( pArgNamesArray ) - { - Sequence< ::rtl::OUString >& rNameSeq = pArgNamesArray->getNames(); - ::rtl::OUString* pNames = rNameSeq.getArray(); - - Any aValAny; - for( i = 0 ; i < nParamCount ; i++ ) - { - USHORT iSbx = (USHORT)(i+1); - - // ATTENTION: Don't forget for Sbx-Parameter the offset! - aValAny = sbxToUnoValueImpl( pParams->Get( iSbx ), - bBlockConversionToSmallestType ); - - ::rtl::OUString aParamName = pNames[iSbx]; - if( aParamName.getLength() ) - { - oleautomation::NamedArgument aNamedArgument; - aNamedArgument.Name = aParamName; - aNamedArgument.Value = aValAny; - pAnyArgs[i] <<= aNamedArgument; - } - else - { - pAnyArgs[i] = aValAny; - } - } - } - else - { - for( i = 0 ; i < nParamCount ; i++ ) - { - // ATTENTION: Don't forget for Sbx-Parameter the offset! - pAnyArgs[i] = sbxToUnoValueImpl( pParams->Get( (USHORT)(i+1) ), - bBlockConversionToSmallestType ); - } - } + processAutomationParams( pParams, args, bOLEAutomation, nParamCount ); } // call the method @@ -2220,26 +2325,8 @@ void SbUnoObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType, } else if( bInvocation && mxInvocation.is() ) { - Sequence< INT16 > OutParamIndex; - Sequence< Any > OutParam; - Any aRetAny = mxInvocation->invoke( pMeth->GetName(), args, OutParamIndex, OutParam ); - - // take over the value from Uno to Sbx + Any aRetAny = invokeAutomationMethod( pMeth->GetName(), args, pParams, nParamCount, mxInvocation ); unoToSbxValue( pVar, aRetAny ); - - const INT16* pIndices = OutParamIndex.getConstArray(); - UINT32 nLen = OutParamIndex.getLength(); - if( nLen ) - { - const Any* pNewValues = OutParam.getConstArray(); - for( UINT32 j = 0 ; j < nLen ; j++ ) - { - INT16 iTarget = pIndices[ j ]; - if( iTarget >= (INT16)nParamCount ) - break; - unoToSbxValue( (SbxVariable*)pParams->Get( (USHORT)(j+1) ), pNewValues[ j ] ); - } - } } // remove parameter here, because this was not done anymore in unoToSbxValue() @@ -3177,11 +3264,16 @@ getTypeDescriptorEnumeration( const ::rtl::OUString& sSearchRoot, typedef std::hash_map< ::rtl::OUString, Any, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > VBAConstantsHash; -SbxVariable* getVBAConstant( const String& rName ) +VBAConstantHelper& +VBAConstantHelper::instance() +{ + static VBAConstantHelper aHelper; + return aHelper; +} + +void +VBAConstantHelper::init() { - SbxVariable* pConst = NULL; - static VBAConstantsHash aConstCache; - static bool isInited = false; if ( !isInited ) { Sequence< TypeClass > types(1); @@ -3189,39 +3281,77 @@ SbxVariable* getVBAConstant( const String& rName ) Reference< XTypeDescriptionEnumeration > xEnum = getTypeDescriptorEnumeration( defaultNameSpace, types, TypeDescriptionSearchDepth_INFINITE ); if ( !xEnum.is() ) - return NULL; + return; //NULL; while ( xEnum->hasMoreElements() ) { Reference< XConstantsTypeDescription > xConstants( xEnum->nextElement(), UNO_QUERY ); if ( xConstants.is() ) { + // store constant group name + ::rtl::OUString sFullName = xConstants->getName(); + sal_Int32 indexLastDot = sFullName.lastIndexOf('.'); + ::rtl::OUString sLeafName( sFullName ); + if ( indexLastDot > -1 ) + sLeafName = sFullName.copy( indexLastDot + 1); + aConstCache.push_back( sLeafName ); // assume constant group names are unique Sequence< Reference< XConstantTypeDescription > > aConsts = xConstants->getConstants(); Reference< XConstantTypeDescription >* pSrc = aConsts.getArray(); sal_Int32 nLen = aConsts.getLength(); for ( sal_Int32 index =0; index<nLen; ++pSrc, ++index ) { + // store constant member name Reference< XConstantTypeDescription >& rXConst = *pSrc; - ::rtl::OUString sFullName = rXConst->getName(); - sal_Int32 indexLastDot = sFullName.lastIndexOf('.'); - ::rtl::OUString sLeafName; + sFullName = rXConst->getName(); + indexLastDot = sFullName.lastIndexOf('.'); + sLeafName = sFullName; if ( indexLastDot > -1 ) sLeafName = sFullName.copy( indexLastDot + 1); - aConstCache[ sLeafName.toAsciiLowerCase() ] = rXConst->getConstantValue(); + aConstHash[ sLeafName.toAsciiLowerCase() ] = rXConst->getConstantValue(); } } } isInited = true; } +} + +bool +VBAConstantHelper::isVBAConstantType( const String& rName ) +{ + init(); + bool bConstant = false; ::rtl::OUString sKey( rName ); - VBAConstantsHash::const_iterator it = aConstCache.find( sKey.toAsciiLowerCase() ); - if ( it != aConstCache.end() ) + VBAConstantsVector::const_iterator it = aConstCache.begin(); + + for( ; it != aConstCache.end(); it++ ) + { + if( sKey.equalsIgnoreAsciiCase( *it ) ) + { + bConstant = true; + break; + } + } + return bConstant; +} + +SbxVariable* +VBAConstantHelper::getVBAConstant( const String& rName ) +{ + SbxVariable* pConst = NULL; + init(); + + ::rtl::OUString sKey( rName ); + + VBAConstantsHash::const_iterator it = aConstHash.find( sKey.toAsciiLowerCase() ); + + if ( it != aConstHash.end() ) { pConst = new SbxVariable( SbxVARIANT ); pConst->SetName( rName ); unoToSbxValue( pConst, it->second ); } + return pConst; } diff --git a/basic/source/classes/sbxmod.cxx b/basic/source/classes/sbxmod.cxx index bfcb22b62d0a..18981ac0c1d7 100644 --- a/basic/source/classes/sbxmod.cxx +++ b/basic/source/classes/sbxmod.cxx @@ -56,6 +56,7 @@ #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/script/ModuleType.hpp> #include <com/sun/star/script/vba/XVBACompatibility.hpp> +#include <com/sun/star/document/XVbaMethodParameter.hpp> #include <com/sun/star/beans/XPropertySet.hpp> using namespace com::sun::star; @@ -498,7 +499,6 @@ IMPL_LINK( AsyncQuitHandler, OnAsyncQuit, void*, /*pNull*/ ) return 0L; } -#if 0 bool UnlockControllerHack( StarBASIC* pBasic ) { bool bRes = false; @@ -524,7 +524,7 @@ bool UnlockControllerHack( StarBASIC* pBasic ) } return bRes; } -#endif + ///////////////////////////////////////////////////////////////////////////// // A Basic module has set EXTSEARCH, so that the elements, that the modul contains, @@ -793,6 +793,82 @@ void SbModule::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType, SbxVariable* pVar = pHint->GetVar(); SbProperty* pProp = PTR_CAST(SbProperty,pVar); SbMethod* pMeth = PTR_CAST(SbMethod,pVar); + SbProcedureProperty* pProcProperty = PTR_CAST( SbProcedureProperty, pVar ); + if( pProcProperty ) + { + + if( pHint->GetId() == SBX_HINT_DATAWANTED ) + { + String aProcName; + aProcName.AppendAscii( "Property Get " ); + aProcName += pProcProperty->GetName(); + + SbxVariable* pMethVar = Find( aProcName, SbxCLASS_METHOD ); + if( pMethVar ) + { + SbxValues aVals; + aVals.eType = SbxVARIANT; + + SbxArray* pArg = pVar->GetParameters(); + USHORT nVarParCount = (pArg != NULL) ? pArg->Count() : 0; + if( nVarParCount > 1 ) + { + SbxArrayRef xMethParameters = new SbxArray; + xMethParameters->Put( pMethVar, 0 ); // Method as parameter 0 + for( USHORT i = 1 ; i < nVarParCount ; ++i ) + { + SbxVariable* pPar = pArg->Get( i ); + xMethParameters->Put( pPar, i ); + } + + pMethVar->SetParameters( xMethParameters ); + pMethVar->Get( aVals ); + pMethVar->SetParameters( NULL ); + } + else + { + pMethVar->Get( aVals ); + } + + pVar->Put( aVals ); + } + } + else if( pHint->GetId() == SBX_HINT_DATACHANGED ) + { + SbxVariable* pMethVar = NULL; + + bool bSet = pProcProperty->isSet(); + if( bSet ) + { + pProcProperty->setSet( false ); + + String aProcName; + aProcName.AppendAscii( "Property Set " ); + aProcName += pProcProperty->GetName(); + pMethVar = Find( aProcName, SbxCLASS_METHOD ); + } + if( !pMethVar ) // Let + { + String aProcName; + aProcName.AppendAscii( "Property Let " ); + aProcName += pProcProperty->GetName(); + pMethVar = Find( aProcName, SbxCLASS_METHOD ); + } + + if( pMethVar ) + { + // Setup parameters + SbxArrayRef xArray = new SbxArray; + xArray->Put( pMethVar, 0 ); // Method as parameter 0 + xArray->Put( pVar, 1 ); + pMethVar->SetParameters( xArray ); + + SbxValues aVals; + pMethVar->Get( aVals ); + pMethVar->SetParameters( NULL ); + } + } + } if( pProp ) { if( pProp->GetModule() != this ) @@ -847,6 +923,7 @@ void SbModule::SetSource32( const ::rtl::OUString& r ) aOUSource = r; StartDefinitions(); SbiTokenizer aTok( r ); + aTok.SetCompatible( IsVBACompat() ); while( !aTok.IsEof() ) { SbiToken eEndTok = NIL; @@ -1034,12 +1111,14 @@ void SbModule::SetVBACompat( BOOL bCompat ) // Run a Basic-subprogram USHORT SbModule::Run( SbMethod* pMeth ) { + OSL_TRACE("About to run %s, vba compatmode is %d", rtl::OUStringToOString( pMeth->GetName(), RTL_TEXTENCODING_UTF8 ).getStr(), mbVBACompat ); static USHORT nMaxCallLevel = 0; static String aMSOMacroRuntimeLibName = String::CreateFromAscii( "Launcher" ); static String aMSOMacroRuntimeAppSymbol = String::CreateFromAscii( "Application" ); USHORT nRes = 0; BOOL bDelInst = BOOL( pINST == NULL ); + bool bQuit = false; StarBASICRef xBasic; if( bDelInst ) { @@ -1172,6 +1251,15 @@ USHORT SbModule::Run( SbMethod* pMeth ) delete pRt; pMOD = pOldMod; + if ( pINST->nCallLvl == 0 && IsVBACompat() ) + { + // VBA always ensure screenupdating is enabled after completing + StarBASIC* pBasic = PTR_CAST(StarBASIC,GetParent()); + if ( pBasic && pBasic->IsDocBasic() ) + { + UnlockControllerHack( pBasic ); + } + } if( bDelInst ) { // #57841 Clear Uno-Objects, which were helt in RTL functions, @@ -1199,10 +1287,8 @@ USHORT SbModule::Run( SbMethod* pMeth ) // VBA always ensure screenupdating is enabled after completing StarBASIC* pBasic = PTR_CAST(StarBASIC,GetParent()); -#if 0 if ( pBasic && pBasic->IsDocBasic() && !pINST ) UnlockControllerHack( pBasic ); -#endif if( bDelInst ) { // #57841 Clear Uno-Objects, which were helt in RTL functions, @@ -1213,6 +1299,8 @@ USHORT SbModule::Run( SbMethod* pMeth ) pINST = NULL; } if ( pBasic && pBasic->IsDocBasic() && pBasic->IsQuitApplication() && !pINST ) + bQuit = true; + if ( bQuit ) { Application::PostUserEvent( LINK( &AsyncQuitHandler::instance(), AsyncQuitHandler, OnAsyncQuit ), NULL ); } @@ -1663,6 +1751,48 @@ BOOL SbModule::ExceedsLegacyModuleSize() return false; } +class ErrorHdlResetter +{ + Link mErrHandler; + bool mbError; + public: + ErrorHdlResetter() : mbError( false ) + { + // save error handler + mErrHandler = StarBASIC::GetGlobalErrorHdl(); + // set new error handler + StarBASIC::SetGlobalErrorHdl( LINK( this, ErrorHdlResetter, BasicErrorHdl ) ); + } + ~ErrorHdlResetter() + { + // restore error handler + StarBASIC::SetGlobalErrorHdl(mErrHandler); + } + DECL_LINK( BasicErrorHdl, StarBASIC * ); + bool HasError() { return mbError; } +}; +IMPL_LINK( ErrorHdlResetter, BasicErrorHdl, StarBASIC *, /*pBasic*/) +{ + mbError = true; + return 0; +} + +bool SbModule::HasExeCode() +{ + + ErrorHdlResetter aGblErrHdl; + // And empty Image always has the Global Chain set up + static const unsigned char pEmptyImage[] = { 0x45, 0x0 , 0x0, 0x0, 0x0 }; + // lets be stricter for the moment than VBA + + bool bRes = false; + if ( !IsCompiled() ) + Compile(); + if ( pImage && !( pImage->GetCodeSize() == 5 && ( memcmp( pImage->GetCode(), pEmptyImage, pImage->GetCodeSize() ) == 0 ) ) + || aGblErrHdl.HasError() ) + bRes = true; + return bRes; +} // Store only image, no source BOOL SbModule::StoreBinaryData( SvStream& rStrm ) @@ -1712,7 +1842,6 @@ BOOL SbModule::LoadBinaryData( SvStream& rStrm ) return bRet; } - BOOL SbModule::LoadCompleted() { SbxArray* p = GetMethods(); @@ -1780,6 +1909,7 @@ SbMethod::SbMethod( const String& r, SbxDataType t, SbModule* p ) nLine1 = nLine2 = 0; refStatics = new SbxArray; + mCaller = 0; // From: 1996-07.02: HACK due to 'Referenz could not be saved' SetFlag( SBX_NO_MODIFY ); } @@ -1794,6 +1924,7 @@ SbMethod::SbMethod( const SbMethod& r ) nLine1 = r.nLine1; nLine2 = r.nLine2; refStatics = r.refStatics; + mCaller = r.mCaller; SetFlag( SBX_NO_MODIFY ); } @@ -1862,9 +1993,14 @@ SbxInfo* SbMethod::GetInfo() // Interface to execute a method of the applications // #34191# With special RefCounting, damit so that the Basic was not fired of by CloseDocument() // The return value will be delivered as string. -ErrCode SbMethod::Call( SbxValue* pRet ) +ErrCode SbMethod::Call( SbxValue* pRet, SbxVariable* pCaller ) { - // Increment the RefCount of the module + if ( pCaller ) + { + OSL_TRACE("SbMethod::Call Have been passed a caller 0x%x", pCaller ); + mCaller = pCaller; + } + // RefCount vom Modul hochzaehlen SbModule* pMod_ = (SbModule*)GetParent(); pMod_->AddRef(); @@ -1891,7 +2027,7 @@ ErrCode SbMethod::Call( SbxValue* pRet ) // Release objects pMod_->ReleaseRef(); pBasic->ReleaseRef(); - + mCaller = 0; return nErr; } @@ -2074,9 +2210,8 @@ public: } //liuchen 2009-7-21, support Excel VBA Form_QueryClose event - virtual void SAL_CALL windowClosing( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) + virtual void SAL_CALL windowClosing( const lang::EventObject& e ) throw (uno::RuntimeException) { -#if IN_THE_FUTURE uno::Reference< awt::XDialog > xDialog( e.Source, uno::UNO_QUERY ); if ( xDialog.is() ) { @@ -2104,7 +2239,6 @@ public: } mpUserForm->triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_QueryClose") ) ); -#endif } //liuchen 2009-7-21 @@ -2201,14 +2335,13 @@ void SbUserFormModule::triggerMethod( const String& aMethodToRun ) Sequence< Any > aArguments; triggerMethod( aMethodToRun, aArguments ); } -void SbUserFormModule::triggerMethod( const String& aMethodToRun, Sequence< Any >& /*aArguments*/) +void SbUserFormModule::triggerMethod( const String& aMethodToRun, Sequence< Any >& aArguments) { OSL_TRACE("*** trigger %s ***", rtl::OUStringToOString( aMethodToRun, RTL_TEXTENCODING_UTF8 ).getStr() ); // Search method SbxVariable* pMeth = SbObjModule::Find( aMethodToRun, SbxCLASS_METHOD ); if( pMeth ) { -#if IN_THE_FUTURE //liuchen 2009-7-21, support Excel VBA UserForm_QueryClose event with parameters if ( aArguments.getLength() > 0 ) // Setup parameters { @@ -2238,7 +2371,6 @@ void SbUserFormModule::triggerMethod( const String& aMethodToRun, Sequence< Any } else //liuchen 2009-7-21 -#endif { SbxValues aVals; pMeth->Get( aVals ); @@ -2340,7 +2472,10 @@ void SbUserFormModule::Unload() triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_QueryClose") ), aParams); aParams[0] >>= nCancel; - if (nCancel == 1) + // basic boolean ( and what the user might use ) can be ambiguous ( e.g. basic true = -1 ) + // test agains 0 ( false ) and assume anything else is true + // ( Note: ) this used to work ( something changes somewhere ) + if (nCancel != 0) { return; } @@ -2401,7 +2536,7 @@ void SbUserFormModule::InitObject() aArgs[ 0 ] = uno::Any(); aArgs[ 1 ] <<= m_xDialog; aArgs[ 2 ] <<= m_xModel; - aArgs[ 3 ] <<= rtl::OUString( GetParent()->GetName() ); + aArgs[ 3 ] <<= sProjectName; pDocObject = new SbUnoObject( GetName(), uno::makeAny( xVBAFactory->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.msforms.UserForm")), aArgs ) ) ); uno::Reference< lang::XComponent > xComponent( aArgs[ 1 ], uno::UNO_QUERY_THROW ); // remove old listener if it exists diff --git a/basic/source/comp/codegen.cxx b/basic/source/comp/codegen.cxx index 93fb18baf86e..8bec885c8846 100644 --- a/basic/source/comp/codegen.cxx +++ b/basic/source/comp/codegen.cxx @@ -163,8 +163,6 @@ void SbiCodeGen::Save() rMod.bIsProxyModule = false; } - if( pParser->bText ) - p->SetFlag( SBIMG_COMPARETEXT ); // GlobalCode-Flag if( pParser->HasGlobalCode() ) p->SetFlag( SBIMG_INITCODE ); @@ -244,6 +242,8 @@ void SbiCodeGen::Save() if( nPass == 1 ) aPropName = aPropName.Copy( aIfaceName.Len() + 1 ); SbProcedureProperty* pProcedureProperty = NULL; + OSL_TRACE("*** getProcedureProperty for thing %s", + rtl::OUStringToOString( aPropName,RTL_TEXTENCODING_UTF8 ).getStr() ); pProcedureProperty = rMod.GetProcedureProperty( aPropName, ePropType ); } if( nPass == 1 ) diff --git a/basic/source/comp/dim.cxx b/basic/source/comp/dim.cxx index 59d77e3f3757..6e746b4d7fbe 100644 --- a/basic/source/comp/dim.cxx +++ b/basic/source/comp/dim.cxx @@ -29,6 +29,8 @@ #include "precompiled_basic.hxx" #include <basic/sbx.hxx> #include "sbcomp.hxx" +#include "sbunoobj.hxx" + SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj ); @@ -153,7 +155,7 @@ void SbiParser::TypeDecl( SbiSymDef& rDef, BOOL bAsNewAlreadyParsed ) } } } - else if( rEnumArray->Find( aCompleteName, SbxCLASS_OBJECT ) ) + else if( rEnumArray->Find( aCompleteName, SbxCLASS_OBJECT ) || ( IsVBASupportOn() && VBAConstantHelper::instance().isVBAConstantType( aCompleteName ) ) ) { eType = SbxLONG; break; @@ -426,7 +428,10 @@ void SbiParser::DefVar( SbiOpcode eOp, BOOL bStatic ) aExpr.Gen(); SbiOpcode eOp_ = pDef->IsNew() ? _CREATE : _TCREATE; aGen.Gen( eOp_, pDef->GetId(), pDef->GetTypeId() ); - aGen.Gen( _SET ); + if ( bVBASupportOn ) + aGen.Gen( _VBASET ); + else + aGen.Gen( _SET ); } } else @@ -1043,6 +1048,24 @@ void SbiParser::DefDeclare( BOOL bPrivate ) } } +void SbiParser::Attribute() +{ + // TODO: Need to implement the method as an attributed object. + while( Next() != EQ ) + { + String aSym( GetSym() ); + if( Next() != DOT) + break; + } + + if( eCurTok != EQ ) + Error( SbERR_SYNTAX ); + else + SbiExpression aValue( this ); + + // Don't generate any code - just discard it. +} + // Aufruf einer SUB oder FUNCTION void SbiParser::Call() diff --git a/basic/source/comp/exprtree.cxx b/basic/source/comp/exprtree.cxx index 7a4ea5965558..04d8236d7669 100644 --- a/basic/source/comp/exprtree.cxx +++ b/basic/source/comp/exprtree.cxx @@ -373,8 +373,12 @@ SbiExprNode* SbiExpression::Term( const KeywordSymbolInfo* pKeywordSymbolInfo ) // Typ SbxOBJECT sein if( pDef->GetType() != SbxOBJECT && pDef->GetType() != SbxVARIANT ) { - pParser->Error( SbERR_BAD_DECLARATION, aSym ); - bError = TRUE; + // defer error until runtime if in vba mode + if ( !pParser->IsVBASupportOn() ) + { + pParser->Error( SbERR_BAD_DECLARATION, aSym ); + bError = TRUE; + } } if( !bError ) pNd->aVar.pNext = ObjTerm( *pDef ); @@ -580,7 +584,11 @@ SbiExprNode* SbiExpression::Unary() eTok = NEG; case NOT: pParser->Next(); - pNd = new SbiExprNode( pParser, Unary(), eTok, NULL ); + // process something like "Do While Not "foo"="" " + if( pParser->IsVBASupportOn() ) + pNd = new SbiExprNode( pParser, Like(), eTok, NULL ); + else + pNd = new SbiExprNode( pParser, Unary(), eTok, NULL ); break; case PLUS: pParser->Next(); @@ -736,7 +744,7 @@ SbiExprNode* SbiExpression::Like() pNd = new SbiExprNode( pParser, pNd, eTok, Comp() ), nCount++; } // Mehrere Operatoren hintereinander gehen nicht - if( nCount > 1 ) + if( nCount > 1 && !pParser->IsVBASupportOn() ) { pParser->Error( SbERR_SYNTAX ); bError = TRUE; diff --git a/basic/source/comp/parser.cxx b/basic/source/comp/parser.cxx index 3d7178ae7688..433bf28663e3 100644 --- a/basic/source/comp/parser.cxx +++ b/basic/source/comp/parser.cxx @@ -49,6 +49,7 @@ struct SbiStatement { #define N FALSE static SbiStatement StmntTable [] = { +{ ATTRIBUTE, &SbiParser::Attribute, Y, Y, }, // ATTRIBUTE { CALL, &SbiParser::Call, N, Y, }, // CALL { CLOSE, &SbiParser::Close, N, Y, }, // CLOSE { _CONST_, &SbiParser::Dim, Y, Y, }, // CONST @@ -387,6 +388,18 @@ BOOL SbiParser::Parse() Next(); return TRUE; } + // In vba it's possible to do Error.foobar ( even if it results in + // a runtime error + if ( eCurTok == _ERROR_ && IsVBASupportOn() ) // we probably need to define a subset of keywords where this madness applies e.g. if ( IsVBASupportOn() && SymbolCanBeRedined( eCurTok ) ) + { + SbiTokenizer tokens( *(SbiTokenizer*)this ); + tokens.Next(); + if ( tokens.Peek() == DOT ) + { + eCurTok = SYMBOL; + ePush = eCurTok; + } + } // Kommt ein Symbol, ist es entweder eine Variable( LET ) // oder eine SUB-Prozedur( CALL ohne Klammern ) // DOT fuer Zuweisungen im WITH-Block: .A=5 @@ -795,7 +808,7 @@ void SbiParser::Option() bClassModule = TRUE; aGen.GetModule().SetModuleType( com::sun::star::script::ModuleType::CLASS ); break; - case VBASUPPORT: + case VBASUPPORT: // Option VBASupport used to override the module mode ( in fact this must reset the mode if( Next() == NUMBER ) { if ( nVal == 1 || nVal == 0 ) diff --git a/basic/source/comp/token.cxx b/basic/source/comp/token.cxx index 8cb3126f03f1..76eab0dc1ec5 100644 --- a/basic/source/comp/token.cxx +++ b/basic/source/comp/token.cxx @@ -58,6 +58,7 @@ static TokenTable aTokTable_Basic [] = { // Token-Tabelle: { ANY, "Any" }, { APPEND, "Append" }, { AS, "As" }, + { ATTRIBUTE,"Attribute" }, { BASE, "Base" }, { BINARY, "Binary" }, { TBOOLEAN, "Boolean" }, diff --git a/basic/source/inc/dlgcont.hxx b/basic/source/inc/dlgcont.hxx index 737d1274718f..ac6a1cb7d949 100644 --- a/basic/source/inc/dlgcont.hxx +++ b/basic/source/inc/dlgcont.hxx @@ -94,7 +94,9 @@ public: throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException); - + // XLibraryQueryExecutable + virtual sal_Bool SAL_CALL HasExecutableCode(const rtl::OUString&) + throw (::com::sun::star::uno::RuntimeException); // Service static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static(); static ::rtl::OUString getImplementationName_static(); diff --git a/basic/source/inc/namecont.hxx b/basic/source/inc/namecont.hxx index 7fd6eb06f607..a2903caf6536 100644 --- a/basic/source/inc/namecont.hxx +++ b/basic/source/inc/namecont.hxx @@ -35,6 +35,7 @@ #include <com/sun/star/script/XStorageBasedLibraryContainer.hpp> #include <com/sun/star/script/XLibraryContainerPassword.hpp> #include <com/sun/star/script/XLibraryContainerExport.hpp> +#include <com/sun/star/script/XLibraryQueryExecutable.hpp> #include <com/sun/star/script/XLibraryContainer3.hpp> #include <com/sun/star/container/XNameContainer.hpp> #include <com/sun/star/container/XContainer.hpp> @@ -59,6 +60,7 @@ #include <cppuhelper/implbase2.hxx> #include <cppuhelper/compbase8.hxx> +#include <cppuhelper/compbase9.hxx> #include <cppuhelper/interfacecontainer.hxx> #include <com/sun/star/script/vba/XVBACompatibility.hpp> @@ -67,13 +69,14 @@ class BasicManager; namespace basic { -typedef ::cppu::WeakComponentImplHelper8< +typedef ::cppu::WeakComponentImplHelper9< ::com::sun::star::lang::XInitialization, ::com::sun::star::script::XStorageBasedLibraryContainer, ::com::sun::star::script::XLibraryContainerPassword, ::com::sun::star::script::XLibraryContainerExport, ::com::sun::star::script::XLibraryContainer3, ::com::sun::star::container::XContainer, + ::com::sun::star::script::XLibraryQueryExecutable, ::com::sun::star::script::vba::XVBACompatibility, ::com::sun::star::lang::XServiceInfo > LibraryContainerHelper; diff --git a/basic/source/inc/parser.hxx b/basic/source/inc/parser.hxx index 733a65db7f61..1e99f9421b82 100644 --- a/basic/source/inc/parser.hxx +++ b/basic/source/inc/parser.hxx @@ -107,6 +107,7 @@ public: void BadSyntax(); // Falsches SbiToken void NoIf(); // ELSE/ELSE IF ohne IF void Assign(); // LET + void Attribute(); // Attribute void Call(); // CALL void Close(); // CLOSE void Declare(); // DECLARE diff --git a/basic/source/inc/runtime.hxx b/basic/source/inc/runtime.hxx index cd75be1a1ec2..d564d35081e2 100644 --- a/basic/source/inc/runtime.hxx +++ b/basic/source/inc/runtime.hxx @@ -196,7 +196,6 @@ class SbiInstance BOOL bCompatibility; // Flag: TRUE = VBA runtime compatibility mode ComponentVector_t ComponentVector; - public: SbiRuntime* pRun; // Call-Stack SbiInstance* pNext; // Instanzen-Chain @@ -285,7 +284,9 @@ class SbiRuntime SbxArrayRef refExprStk; // expression stack SbxArrayRef refCaseStk; // CASE expression stack SbxArrayRef refRedimpArray; // Array saved to use for REDIM PRESERVE + SbxVariableRef refRedim; // Array saved to use for REDIM SbxVariableRef xDummyVar; // Ersatz fuer nicht gefundene Variablen + SbxVariable* mpExtCaller; // Caller ( external - e.g. button name, shape, range object etc. - only in vba mode ) SbiArgvStack* pArgvStk; // ARGV-Stack SbiGosubStack* pGosubStk; // GOSUB stack SbiForStack* pForStk; // FOR/NEXT-Stack @@ -455,6 +456,7 @@ public: SbMethod* GetCaller(); SbxArray* GetLocals(); SbxArray* GetParams(); + SbxVariable* GetExternalCaller(){ return mpExtCaller; } SbxBase* FindElementExtern( const String& rName ); static bool isVBAEnabled(); diff --git a/basic/source/inc/sbunoobj.hxx b/basic/source/inc/sbunoobj.hxx index 5a5981379fb7..d66c003214ed 100644 --- a/basic/source/inc/sbunoobj.hxx +++ b/basic/source/inc/sbunoobj.hxx @@ -41,6 +41,7 @@ #include <com/sun/star/reflection/XServiceTypeDescription2.hpp> #include <com/sun/star/reflection/XSingletonTypeDescription.hpp> #include <rtl/ustring.hxx> +#include <hash_map> class SbUnoObject: public SbxObject { @@ -319,6 +320,26 @@ public: virtual void Clear(); }; +typedef std::hash_map< ::rtl::OUString, ::com::sun::star::uno::Any, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > VBAConstantsHash; + +typedef std::vector< rtl::OUString > VBAConstantsVector; + +class VBAConstantHelper +{ +private: + + VBAConstantsVector aConstCache; + VBAConstantsHash aConstHash; + bool isInited; + VBAConstantHelper():isInited( false ) {} + VBAConstantHelper(const VBAConstantHelper&); + void init(); +public: + static VBAConstantHelper& instance(); + SbxVariable* getVBAConstant( const String& rName ); + bool isVBAConstantType( const String& rName ); +}; + #endif diff --git a/basic/source/inc/scriptcont.hxx b/basic/source/inc/scriptcont.hxx index 091fbc24cdbe..2310a3d633ec 100644 --- a/basic/source/inc/scriptcont.hxx +++ b/basic/source/inc/scriptcont.hxx @@ -122,7 +122,9 @@ public: throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException); - + // XLibraryQueryExecutable + virtual sal_Bool SAL_CALL HasExecutableCode(const rtl::OUString&) + throw (::com::sun::star::uno::RuntimeException); // Methods XServiceInfo virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException); diff --git a/basic/source/inc/token.hxx b/basic/source/inc/token.hxx index ec07dcbd8518..531bafae04bc 100644 --- a/basic/source/inc/token.hxx +++ b/basic/source/inc/token.hxx @@ -70,7 +70,7 @@ enum SbiToken { IF, _IN_, INPUT, LET, LINE, LINEINPUT, LOCAL, LOOP, LPRINT, LSET, NAME, NEW, NEXT, - ON, OPEN, OPTION, IMPLEMENTS, + ON, OPEN, OPTION, ATTRIBUTE, IMPLEMENTS, PRINT, PRIVATE, PROPERTY, PUBLIC, REDIM, REM, RESUME, RETURN, RSET, SELECT, SET, SHARED, STATIC, STEP, STOP, SUB, diff --git a/basic/source/runtime/methods.cxx b/basic/source/runtime/methods.cxx index 6ea1f1f20ba1..11edeab8d6f9 100644 --- a/basic/source/runtime/methods.cxx +++ b/basic/source/runtime/methods.cxx @@ -46,6 +46,7 @@ #include <unotools/ucbstreamhelper.hxx> #include <tools/wldcrd.hxx> #include <i18npool/lang.h> +#include <rtl/string.hxx> #include "runtime.hxx" #include "sbunoobj.hxx" @@ -71,13 +72,16 @@ #include <com/sun/star/io/XOutputStream.hpp> #include <com/sun/star/io/XStream.hpp> #include <com/sun/star/io/XSeekable.hpp> - +#include <com/sun/star/script/XErrorQuery.hpp> +#include <ooo/vba/XHelperInterface.hpp> +#include <com/sun/star/bridge/oleautomation/XAutomationObject.hpp> using namespace comphelper; using namespace osl; using namespace com::sun::star::uno; using namespace com::sun::star::lang; using namespace com::sun::star::ucb; using namespace com::sun::star::io; +using namespace com::sun::star::script; #endif /* _USE_UNO */ @@ -99,6 +103,8 @@ using namespace com::sun::star::io; #include <stdlib.h> #include <ctype.h> +SbxVariable* getDefaultProp( SbxVariable* pRef ); + #if defined (WIN) || defined (WNT) || defined (OS2) #include <direct.h> // _getdcwd get current work directory, _chdrive #endif @@ -117,6 +123,9 @@ using namespace com::sun::star::io; #include <io.h> #endif + +#include <basic/sbobjmod.hxx> + #include <basic/sbobjmod.hxx> static void FilterWhiteSpace( String& rStr ) @@ -702,6 +711,36 @@ RTLFUNC(MkDir) // JSM { try { + if ( SbiRuntime::isVBAEnabled() ) + { + // If aPath is the folder name, not a path, then create the folder under current directory. + INetURLObject aTryPathURL( aPath ); + ::rtl::OUString sPathURL = aTryPathURL.GetMainURL( INetURLObject::NO_DECODE ); + if ( !sPathURL.getLength() ) + { + File::getFileURLFromSystemPath( aPath, sPathURL ); + } + INetURLObject aPathURL( sPathURL ); + if ( !aPathURL.GetPath().getLength() ) + { + ::rtl::OUString sCurDirURL; + SbxArrayRef pPar = new SbxArray; + SbxVariableRef pVar = new SbxVariable(); + pPar->Put( pVar, 0 ); + SbRtl_CurDir( pBasic, *pPar, FALSE ); + String aCurPath = pPar->Get(0)->GetString(); + + File::getFileURLFromSystemPath( aCurPath, sCurDirURL ); + INetURLObject aDirURL( sCurDirURL ); + aDirURL.Append( aPath ); + ::rtl::OUString aTmpPath = aDirURL.GetMainURL( INetURLObject::NO_DECODE ); + if ( aTmpPath.getLength() > 0 ) + { + aPath = aTmpPath; + } + } + } + xSFI->createFolder( getFullPath( aPath ) ); } catch( Exception & ) @@ -936,6 +975,26 @@ RTLFUNC(Hex) } } +RTLFUNC(FuncCaller) +{ + (void)pBasic; + (void)bWrite; + if ( SbiRuntime::isVBAEnabled() && pINST && pINST->pRun ) + { + if ( pINST->pRun->GetExternalCaller() ) + *rPar.Get(0) = *pINST->pRun->GetExternalCaller(); + else + { + SbxVariableRef pVar = new SbxVariable(SbxVARIANT); + *rPar.Get(0) = *pVar; + } + } + else + { + StarBASIC::Error( SbERR_NOT_IMPLEMENTED ); + } + +} // InStr( [start],string,string,[compare] ) RTLFUNC(InStr) @@ -2407,7 +2466,18 @@ RTLFUNC(IsEmpty) if ( rPar.Count() < 2 ) StarBASIC::Error( SbERR_BAD_ARGUMENT ); else - rPar.Get( 0 )->PutBool( rPar.Get(1)->IsEmpty() ); + { + SbxVariable* pVar = NULL; + if( SbiRuntime::isVBAEnabled() ) + pVar = getDefaultProp( rPar.Get(1) ); + if ( pVar ) + { + pVar->Broadcast( SBX_HINT_DATAWANTED ); + rPar.Get( 0 )->PutBool( pVar->IsEmpty() ); + } + else + rPar.Get( 0 )->PutBool( rPar.Get(1)->IsEmpty() ); + } } RTLFUNC(IsError) @@ -2418,7 +2488,22 @@ RTLFUNC(IsError) if ( rPar.Count() < 2 ) StarBASIC::Error( SbERR_BAD_ARGUMENT ); else - rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() ); + { + SbxVariable* pVar =rPar.Get( 1 ); + SbUnoObject* pObj = PTR_CAST(SbUnoObject,pVar ); + if ( !pObj ) + { + if ( SbxBase* pBaseObj = pVar->GetObject() ) + pObj = PTR_CAST(SbUnoObject, pBaseObj ); + } + Reference< XErrorQuery > xError; + if ( pObj ) + xError.set( pObj->getUnoAny(), UNO_QUERY ); + if ( xError.is() ) + rPar.Get( 0 )->PutBool( xError->hasError() ); + else + rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() ); + } } RTLFUNC(IsNull) @@ -3538,6 +3623,13 @@ RTLFUNC(Shell) NAMESPACE_VOS(OArgumentList) aArgList( pArgumentList, nParamCount ); bSucc = pApp->execute( eOptions, aArgList ) == NAMESPACE_VOS(OProcess)::E_None; } + long nResult = 0; + NAMESPACE_VOS(OProcess)::TProcessInfo aInfo; + // We should return the identifier of the executing process when is running VBA, because method Shell(...) returns it in Excel. + if ( bSucc && SbiRuntime::isVBAEnabled() && pApp->getInfo( NAMESPACE_VOS(OProcess)::TData_Identifier, &aInfo ) == NAMESPACE_VOS(OProcess)::E_None ) + { + nResult = aInfo.Ident; + } /* if( nParamCount == 0 ) @@ -3552,7 +3644,7 @@ RTLFUNC(Shell) if( !bSucc ) StarBASIC::Error( SbERR_FILE_NOT_FOUND ); else - rPar.Get(0)->PutLong( 0 ); + rPar.Get(0)->PutLong( nResult ); } } @@ -3623,6 +3715,65 @@ String getBasicTypeName( SbxDataType eType ) return aRetStr; } +String getObjectTypeName( SbxVariable* pVar ) +{ + rtl::OUString sRet( RTL_CONSTASCII_USTRINGPARAM("Object") ); + if ( pVar ) + { + SbxBase* pObj = pVar->GetObject(); + if( !pObj ) + sRet = String( RTL_CONSTASCII_USTRINGPARAM("Nothing") ); + else + { + SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pVar ); + if ( !pUnoObj ) + { + if ( SbxBase* pBaseObj = pVar->GetObject() ) + pUnoObj = PTR_CAST(SbUnoObject, pBaseObj ); + } + if ( pUnoObj ) + { + Any aObj = pUnoObj->getUnoAny(); + // For upstreaming unless we start to build oovbaapi by default + // we need to get detect the vba-ness of the object in some + // other way + // note: Automation objects do not support XServiceInfo + Reference< XServiceInfo > xServInfo( aObj, UNO_QUERY ); + if ( xServInfo.is() ) + { + // is this a VBA object ? + Reference< ooo::vba::XHelperInterface > xVBA( aObj, UNO_QUERY ); + Sequence< rtl::OUString > sServices = xServInfo->getSupportedServiceNames(); + if ( sServices.getLength() ) + sRet = sServices[ 0 ]; + } + else + { + Reference< com::sun::star::bridge::oleautomation::XAutomationObject > xAutoMation( aObj, UNO_QUERY ); + if ( xAutoMation.is() ) + { + Reference< XInvocation > xInv( aObj, UNO_QUERY ); + if ( xInv.is() ) + { + try + { + xInv->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("$GetTypeName") ) ) >>= sRet; + } + catch( Exception& ) + { + } + } + } + } + sal_Int32 nDot = sRet.lastIndexOf( '.' ); + if ( nDot != -1 && nDot < sRet.getLength() ) + sRet = sRet.copy( nDot + 1 ); + } + } + } + return sRet; +} + RTLFUNC(TypeName) { (void)pBasic; @@ -3634,7 +3785,12 @@ RTLFUNC(TypeName) { SbxDataType eType = rPar.Get(1)->GetType(); BOOL bIsArray = ( ( eType & SbxARRAY ) != 0 ); - String aRetStr = getBasicTypeName( eType ); + + String aRetStr; + if ( SbiRuntime::isVBAEnabled() && eType == SbxOBJECT ) + aRetStr = getObjectTypeName( rPar.Get(1) ); + else + aRetStr = getBasicTypeName( eType ); if( bIsArray ) aRetStr.AppendAscii( "()" ); rPar.Get(0)->PutString( aRetStr ); diff --git a/basic/source/runtime/methods1.cxx b/basic/source/runtime/methods1.cxx index ebffbee9f23c..a557de13a1d2 100644 --- a/basic/source/runtime/methods1.cxx +++ b/basic/source/runtime/methods1.cxx @@ -76,11 +76,15 @@ #include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/i18n/XCalendar.hpp> +#include <com/sun/star/sheet/XFunctionAccess.hpp> using namespace comphelper; +using namespace com::sun::star::sheet; using namespace com::sun::star::uno; using namespace com::sun::star::i18n; +void unoToSbxValue( SbxVariable* pVar, const Any& aValue ); +Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, com::sun::star::beans::Property* pUnoProperty = NULL ); static Reference< XCalendar > getLocaleCalendar( void ) { @@ -526,6 +530,10 @@ RTLFUNC(DoEvents) (void)pBasic; (void)bWrite; (void)rPar; +// don't undstand what upstream are up to +// we already process application events etc. in between +// basic runtime pcode ( on a timed basis ) +#if 0 // Dummy implementation as the following code leads // to performance problems for unknown reasons //Timer aTimer; @@ -533,6 +541,9 @@ RTLFUNC(DoEvents) //aTimer.Start(); //while ( aTimer.IsActive() ) // Application::Reschedule(); +#endif + // always return 0 + rPar.Get(0)->PutInteger( 0 ); } RTLFUNC(GetGUIVersion) @@ -2516,6 +2527,546 @@ RTLFUNC(Round) rPar.Get(0)->PutDouble( dRes ); } +void CallFunctionAccessFunction( const Sequence< Any >& aArgs, const rtl::OUString& sFuncName, SbxVariable* pRet ) +{ + static Reference< XFunctionAccess > xFunc; + Any aRes; + try + { + if ( !xFunc.is() ) + { + Reference< XMultiServiceFactory > xFactory( getProcessServiceFactory() ); + if( xFactory.is() ) + { + xFunc.set( xFactory->createInstance(::rtl::OUString::createFromAscii( "com.sun.star.sheet.FunctionAccess")), UNO_QUERY_THROW); + } + } + Any aRet = xFunc->callFunction( sFuncName, aArgs ); + + unoToSbxValue( pRet, aRet ); + + } + catch( Exception& ) + { + StarBASIC::Error( SbERR_BAD_ARGUMENT ); + } +} + +RTLFUNC(SYD) +{ + (void)pBasic; + (void)bWrite; + + ULONG nArgCount = rPar.Count()-1; + + if ( nArgCount < 4 ) + { + StarBASIC::Error( SbERR_BAD_ARGUMENT ); + return; + } + + // retrieve non-optional params + + Sequence< Any > aParams( 4 ); + aParams[ 0 ] <<= makeAny( rPar.Get(1)->GetDouble() ); + aParams[ 1 ] <<= makeAny( rPar.Get(2)->GetDouble() ); + aParams[ 2 ] <<= makeAny( rPar.Get(3)->GetDouble() ); + aParams[ 3 ] <<= makeAny( rPar.Get(4)->GetDouble() ); + + CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SYD") ), rPar.Get( 0 ) ); +} + +RTLFUNC(SLN) +{ + (void)pBasic; + (void)bWrite; + + ULONG nArgCount = rPar.Count()-1; + + if ( nArgCount < 3 ) + { + StarBASIC::Error( SbERR_BAD_ARGUMENT ); + return; + } + + // retrieve non-optional params + + Sequence< Any > aParams( 3 ); + aParams[ 0 ] <<= makeAny( rPar.Get(1)->GetDouble() ); + aParams[ 1 ] <<= makeAny( rPar.Get(2)->GetDouble() ); + aParams[ 2 ] <<= makeAny( rPar.Get(3)->GetDouble() ); + + CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SLN") ), rPar.Get( 0 ) ); +} + +RTLFUNC(Pmt) +{ + (void)pBasic; + (void)bWrite; + + ULONG nArgCount = rPar.Count()-1; + + if ( nArgCount < 3 || nArgCount > 5 ) + { + StarBASIC::Error( SbERR_BAD_ARGUMENT ); + return; + } + // retrieve non-optional params + + double rate = rPar.Get(1)->GetDouble(); + double nper = rPar.Get(2)->GetDouble(); + double pmt = rPar.Get(3)->GetDouble(); + + // set default values for Optional args + double fv = 0; + double type = 0; + + // fv + if ( nArgCount >= 4 ) + { + if( rPar.Get(4)->GetType() != SbxEMPTY ) + fv = rPar.Get(4)->GetDouble(); + } + // type + if ( nArgCount >= 5 ) + { + if( rPar.Get(5)->GetType() != SbxEMPTY ) + type = rPar.Get(5)->GetDouble(); + } + + Sequence< Any > aParams( 5 ); + aParams[ 0 ] <<= rate; + aParams[ 1 ] <<= nper; + aParams[ 2 ] <<= pmt; + aParams[ 3 ] <<= fv; + aParams[ 4 ] <<= type; + + CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Pmt") ), rPar.Get( 0 ) ); +} + +RTLFUNC(PPmt) +{ + (void)pBasic; + (void)bWrite; + + ULONG nArgCount = rPar.Count()-1; + + if ( nArgCount < 4 || nArgCount > 6 ) + { + StarBASIC::Error( SbERR_BAD_ARGUMENT ); + return; + } + // retrieve non-optional params + + double rate = rPar.Get(1)->GetDouble(); + double per = rPar.Get(2)->GetDouble(); + double nper = rPar.Get(3)->GetDouble(); + double pv = rPar.Get(4)->GetDouble(); + + // set default values for Optional args + double fv = 0; + double type = 0; + + // fv + if ( nArgCount >= 5 ) + { + if( rPar.Get(5)->GetType() != SbxEMPTY ) + fv = rPar.Get(5)->GetDouble(); + } + // type + if ( nArgCount >= 6 ) + { + if( rPar.Get(6)->GetType() != SbxEMPTY ) + type = rPar.Get(6)->GetDouble(); + } + + Sequence< Any > aParams( 6 ); + aParams[ 0 ] <<= rate; + aParams[ 1 ] <<= per; + aParams[ 2 ] <<= nper; + aParams[ 3 ] <<= pv; + aParams[ 4 ] <<= fv; + aParams[ 5 ] <<= type; + + CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PPmt") ), rPar.Get( 0 ) ); +} + +RTLFUNC(PV) +{ + (void)pBasic; + (void)bWrite; + + ULONG nArgCount = rPar.Count()-1; + + if ( nArgCount < 3 || nArgCount > 5 ) + { + StarBASIC::Error( SbERR_BAD_ARGUMENT ); + return; + } + // retrieve non-optional params + + double rate = rPar.Get(1)->GetDouble(); + double nper = rPar.Get(2)->GetDouble(); + double pmt = rPar.Get(3)->GetDouble(); + + // set default values for Optional args + double fv = 0; + double type = 0; + + // fv + if ( nArgCount >= 4 ) + { + if( rPar.Get(4)->GetType() != SbxEMPTY ) + fv = rPar.Get(4)->GetDouble(); + } + // type + if ( nArgCount >= 5 ) + { + if( rPar.Get(5)->GetType() != SbxEMPTY ) + type = rPar.Get(5)->GetDouble(); + } + + Sequence< Any > aParams( 5 ); + aParams[ 0 ] <<= rate; + aParams[ 1 ] <<= nper; + aParams[ 2 ] <<= pmt; + aParams[ 3 ] <<= fv; + aParams[ 4 ] <<= type; + + CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PV") ), rPar.Get( 0 ) ); +} + +RTLFUNC(NPV) +{ + (void)pBasic; + (void)bWrite; + + ULONG nArgCount = rPar.Count()-1; + + if ( nArgCount < 1 || nArgCount > 2 ) + { + StarBASIC::Error( SbERR_BAD_ARGUMENT ); + return; + } + + Sequence< Any > aParams( 2 ); + aParams[ 0 ] <<= makeAny( rPar.Get(1)->GetDouble() ); + Any aValues = sbxToUnoValue( rPar.Get(2), + getCppuType( (Sequence<double>*)0 ) ); + + // convert for calc functions + Sequence< Sequence< double > > sValues(1); + aValues >>= sValues[ 0 ]; + aValues <<= sValues; + + aParams[ 1 ] <<= aValues; + + CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NPV") ), rPar.Get( 0 ) ); +} + +RTLFUNC(NPer) +{ + (void)pBasic; + (void)bWrite; + + ULONG nArgCount = rPar.Count()-1; + + if ( nArgCount < 3 || nArgCount > 5 ) + { + StarBASIC::Error( SbERR_BAD_ARGUMENT ); + return; + } + // retrieve non-optional params + + double rate = rPar.Get(1)->GetDouble(); + double pmt = rPar.Get(2)->GetDouble(); + double pv = rPar.Get(3)->GetDouble(); + + // set default values for Optional args + double fv = 0; + double type = 0; + + // fv + if ( nArgCount >= 4 ) + { + if( rPar.Get(4)->GetType() != SbxEMPTY ) + fv = rPar.Get(4)->GetDouble(); + } + // type + if ( nArgCount >= 5 ) + { + if( rPar.Get(5)->GetType() != SbxEMPTY ) + type = rPar.Get(5)->GetDouble(); + } + + Sequence< Any > aParams( 5 ); + aParams[ 0 ] <<= rate; + aParams[ 1 ] <<= pmt; + aParams[ 2 ] <<= pv; + aParams[ 3 ] <<= fv; + aParams[ 4 ] <<= type; + + CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NPer") ), rPar.Get( 0 ) ); +} + +RTLFUNC(MIRR) +{ + (void)pBasic; + (void)bWrite; + + ULONG nArgCount = rPar.Count()-1; + + if ( nArgCount < 3 ) + { + StarBASIC::Error( SbERR_BAD_ARGUMENT ); + return; + } + + // retrieve non-optional params + + Sequence< Any > aParams( 3 ); + Any aValues = sbxToUnoValue( rPar.Get(1), + getCppuType( (Sequence<double>*)0 ) ); + + // convert for calc functions + Sequence< Sequence< double > > sValues(1); + aValues >>= sValues[ 0 ]; + aValues <<= sValues; + + aParams[ 0 ] <<= aValues; + aParams[ 1 ] <<= makeAny( rPar.Get(2)->GetDouble() ); + aParams[ 2 ] <<= makeAny( rPar.Get(3)->GetDouble() ); + + CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("MIRR") ), rPar.Get( 0 ) ); +} + +RTLFUNC(IRR) +{ + (void)pBasic; + (void)bWrite; + + ULONG nArgCount = rPar.Count()-1; + + if ( nArgCount < 1 || nArgCount > 2 ) + { + StarBASIC::Error( SbERR_BAD_ARGUMENT ); + return; + } + // retrieve non-optional params + Any aValues = sbxToUnoValue( rPar.Get(1), + getCppuType( (Sequence<double>*)0 ) ); + + // convert for calc functions + Sequence< Sequence< double > > sValues(1); + aValues >>= sValues[ 0 ]; + aValues <<= sValues; + + // set default values for Optional args + double guess = 0.1; + // guess + if ( nArgCount >= 2 ) + { + if( rPar.Get(2)->GetType() != SbxEMPTY ) + guess = rPar.Get(2)->GetDouble(); + } + + Sequence< Any > aParams( 2 ); + aParams[ 0 ] <<= aValues; + aParams[ 1 ] <<= guess; + + CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("IRR") ), rPar.Get( 0 ) ); +} + +RTLFUNC(IPmt) +{ + (void)pBasic; + (void)bWrite; + + ULONG nArgCount = rPar.Count()-1; + + if ( nArgCount < 4 || nArgCount > 6 ) + { + StarBASIC::Error( SbERR_BAD_ARGUMENT ); + return; + } + // retrieve non-optional params + + double rate = rPar.Get(1)->GetDouble(); + double per = rPar.Get(2)->GetInteger(); + double nper = rPar.Get(3)->GetDouble(); + double pv = rPar.Get(4)->GetDouble(); + + // set default values for Optional args + double fv = 0; + double type = 0; + + // fv + if ( nArgCount >= 5 ) + { + if( rPar.Get(5)->GetType() != SbxEMPTY ) + fv = rPar.Get(5)->GetDouble(); + } + // type + if ( nArgCount >= 6 ) + { + if( rPar.Get(6)->GetType() != SbxEMPTY ) + type = rPar.Get(6)->GetDouble(); + } + + Sequence< Any > aParams( 6 ); + aParams[ 0 ] <<= rate; + aParams[ 1 ] <<= per; + aParams[ 2 ] <<= nper; + aParams[ 3 ] <<= pv; + aParams[ 4 ] <<= fv; + aParams[ 5 ] <<= type; + + CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("IPmt") ), rPar.Get( 0 ) ); +} + +RTLFUNC(FV) +{ + (void)pBasic; + (void)bWrite; + + ULONG nArgCount = rPar.Count()-1; + + if ( nArgCount < 3 || nArgCount > 5 ) + { + StarBASIC::Error( SbERR_BAD_ARGUMENT ); + return; + } + // retrieve non-optional params + + double rate = rPar.Get(1)->GetDouble(); + double nper = rPar.Get(2)->GetDouble(); + double pmt = rPar.Get(3)->GetDouble(); + + // set default values for Optional args + double pv = 0; + double type = 0; + + // pv + if ( nArgCount >= 4 ) + { + if( rPar.Get(4)->GetType() != SbxEMPTY ) + pv = rPar.Get(4)->GetDouble(); + } + // type + if ( nArgCount >= 5 ) + { + if( rPar.Get(5)->GetType() != SbxEMPTY ) + type = rPar.Get(5)->GetDouble(); + } + + Sequence< Any > aParams( 5 ); + aParams[ 0 ] <<= rate; + aParams[ 1 ] <<= nper; + aParams[ 2 ] <<= pmt; + aParams[ 3 ] <<= pv; + aParams[ 4 ] <<= type; + + CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FV") ), rPar.Get( 0 ) ); +} + +RTLFUNC(DDB) +{ + (void)pBasic; + (void)bWrite; + + ULONG nArgCount = rPar.Count()-1; + + if ( nArgCount < 4 || nArgCount > 5 ) + { + StarBASIC::Error( SbERR_BAD_ARGUMENT ); + return; + } + // retrieve non-optional params + + double cost = rPar.Get(1)->GetDouble(); + double salvage = rPar.Get(2)->GetDouble(); + double life = rPar.Get(3)->GetDouble(); + double period = rPar.Get(4)->GetDouble(); + + // set default values for Optional args + double factor = 2; + + // factor + if ( nArgCount >= 5 ) + { + if( rPar.Get(5)->GetType() != SbxEMPTY ) + factor = rPar.Get(5)->GetDouble(); + } + + Sequence< Any > aParams( 5 ); + aParams[ 0 ] <<= cost; + aParams[ 1 ] <<= salvage; + aParams[ 2 ] <<= life; + aParams[ 3 ] <<= period; + aParams[ 4 ] <<= factor; + + CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DDB") ), rPar.Get( 0 ) ); +} + +RTLFUNC(Rate) +{ + (void)pBasic; + (void)bWrite; + + ULONG nArgCount = rPar.Count()-1; + + if ( nArgCount < 3 || nArgCount > 6 ) + { + StarBASIC::Error( SbERR_BAD_ARGUMENT ); + return; + } + // retrieve non-optional params + + double nper = 0; + double pmt = 0; + double pv = 0; + + nper = rPar.Get(1)->GetDouble(); + pmt = rPar.Get(2)->GetDouble(); + pv = rPar.Get(3)->GetDouble(); + + // set default values for Optional args + double fv = 0; + double type = 0; + double guess = 0.1; + + // fv + if ( nArgCount >= 4 ) + { + if( rPar.Get(4)->GetType() != SbxEMPTY ) + fv = rPar.Get(4)->GetDouble(); + } + + // type + if ( nArgCount >= 5 ) + { + if( rPar.Get(5)->GetType() != SbxEMPTY ) + type = rPar.Get(5)->GetDouble(); + } + + // guess + if ( nArgCount >= 6 ) + { + if( rPar.Get(6)->GetType() != SbxEMPTY ) + type = rPar.Get(6)->GetDouble(); + } + + Sequence< Any > aParams( 6 ); + aParams[ 0 ] <<= nper; + aParams[ 1 ] <<= pmt; + aParams[ 2 ] <<= pv; + aParams[ 3 ] <<= fv; + aParams[ 4 ] <<= type; + aParams[ 5 ] <<= guess; + + CallFunctionAccessFunction( aParams, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Rate") ), rPar.Get( 0 ) ); +} + RTLFUNC(StrReverse) { (void)pBasic; diff --git a/basic/source/runtime/rtlproto.hxx b/basic/source/runtime/rtlproto.hxx index 5437654f69a0..bfcb8633e90b 100644 --- a/basic/source/runtime/rtlproto.hxx +++ b/basic/source/runtime/rtlproto.hxx @@ -165,29 +165,41 @@ extern RTLFUNC(Kill); // JSM extern RTLFUNC(MkDir); // JSM extern RTLFUNC(RmDir); // JSM extern RTLFUNC(SendKeys); // JSM +extern RTLFUNC(DDB); extern RTLFUNC(DimArray); extern RTLFUNC(Dir); extern RTLFUNC(DoEvents); extern RTLFUNC(Exp); extern RTLFUNC(FileLen); extern RTLFUNC(Fix); +extern RTLFUNC(FV); extern RTLFUNC(Hex); extern RTLFUNC(Input); extern RTLFUNC(InStr); extern RTLFUNC(InStrRev); extern RTLFUNC(Int); +extern RTLFUNC(IPmt); +extern RTLFUNC(IRR); extern RTLFUNC(Join); extern RTLFUNC(LCase); extern RTLFUNC(Left); extern RTLFUNC(Log); extern RTLFUNC(LTrim); extern RTLFUNC(Mid); +extern RTLFUNC(MIRR); +extern RTLFUNC(NPer); +extern RTLFUNC(NPV); extern RTLFUNC(Oct); +extern RTLFUNC(Pmt); +extern RTLFUNC(PPmt); +extern RTLFUNC(PV); +extern RTLFUNC(Rate); extern RTLFUNC(Replace); extern RTLFUNC(Right); extern RTLFUNC(RTrim); extern RTLFUNC(RTL); extern RTLFUNC(Sgn); +extern RTLFUNC(SLN); extern RTLFUNC(Space); extern RTLFUNC(Split); extern RTLFUNC(Sqr); @@ -195,6 +207,7 @@ extern RTLFUNC(Str); extern RTLFUNC(StrComp); extern RTLFUNC(String); extern RTLFUNC(StrReverse); +extern RTLFUNC(SYD); extern RTLFUNC(Tan); extern RTLFUNC(UCase); extern RTLFUNC(Val); @@ -297,6 +310,7 @@ extern RTLFUNC(Switch); extern RTLFUNC(Wait); //i#64882# add new WaitUntil extern RTLFUNC(WaitUntil); +extern RTLFUNC(FuncCaller); extern RTLFUNC(GetGUIVersion); extern RTLFUNC(Choose); diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx index 1bb6fb82e113..c30f64af2fe3 100644 --- a/basic/source/runtime/runtime.cxx +++ b/basic/source/runtime/runtime.cxx @@ -46,6 +46,8 @@ #include "errobject.hxx" #include "sbtrace.hxx" +SbxVariable* getDefaultProp( SbxVariable* pRef ); + using namespace ::com::sun::star; bool SbiRuntime::isVBAEnabled() @@ -544,7 +546,7 @@ SbxArray* SbiInstance::GetLocals( SbMethod* pMeth ) SbiRuntime::SbiRuntime( SbModule* pm, SbMethod* pe, UINT32 nStart ) : rBasic( *(StarBASIC*)pm->pParent ), pInst( pINST ), - pMod( pm ), pMeth( pe ), pImg( pMod->pImage ), m_nLastTime(0) + pMod( pm ), pMeth( pe ), pImg( pMod->pImage ), mpExtCaller(0), m_nLastTime(0) { nFlags = pe ? pe->GetDebugFlags() : 0; pIosys = pInst->pIosys; @@ -601,6 +603,13 @@ SbiRuntime::~SbiRuntime() void SbiRuntime::SetVBAEnabled(bool bEnabled ) { bVBAEnabled = bEnabled; + if ( bVBAEnabled ) + { + if ( pMeth ) + mpExtCaller = pMeth->mCaller; + } + else + mpExtCaller = 0; } // Aufbau der Parameterliste. Alle ByRef-Parameter werden direkt @@ -1029,7 +1038,25 @@ SbxVariable* SbiRuntime::GetTOS( short n ) void SbiRuntime::TOSMakeTemp() { SbxVariable* p = refExprStk->Get( nExprLvl - 1 ); - if( p->GetRefCount() != 1 ) + if ( p->GetType() == SbxEMPTY ) + p->Broadcast( SBX_HINT_DATAWANTED ); + + SbxVariable* pDflt = NULL; + if ( bVBAEnabled && ( p->GetType() == SbxOBJECT || p->GetType() == SbxVARIANT ) && ( pDflt = getDefaultProp( p ) ) ) + { + pDflt->Broadcast( SBX_HINT_DATAWANTED ); + // replacing new p on stack causes object pointed by + // pDft->pParent to be deleted, when p2->Compute() is + // called below pParent is accessed ( but its deleted ) + // so set it to NULL now + pDflt->SetParent( NULL ); + p = new SbxVariable( *pDflt ); + p->SetFlag( SBX_READWRITE ); + refExprStk->Put( p, nExprLvl - 1 ); +// return; + } + + else if( p->GetRefCount() != 1 ) { SbxVariable* pNew = new SbxVariable( *p ); pNew->SetFlag( SBX_READWRITE ); @@ -1038,7 +1065,6 @@ void SbiRuntime::TOSMakeTemp() } // Der GOSUB-Stack nimmt Returnadressen fuer GOSUBs auf - void SbiRuntime::PushGosub( const BYTE* pc ) { if( ++nGosubLvl > MAXRECURSION ) diff --git a/basic/source/runtime/stdobj.cxx b/basic/source/runtime/stdobj.cxx index 4455901bfeba..1e127486b432 100644 --- a/basic/source/runtime/stdobj.cxx +++ b/basic/source/runtime/stdobj.cxx @@ -33,7 +33,7 @@ #include <basic/sbstdobj.hxx> #include "rtlproto.hxx" #include "sbintern.hxx" - +#include <hash_map> // Das nArgs-Feld eines Tabelleneintrags ist wie folgt verschluesselt: // Zur Zeit wird davon ausgegangen, dass Properties keine Parameter // benoetigen! @@ -69,6 +69,45 @@ struct Methods { USHORT nHash; // Hashcode }; +struct StringHashCode +{ + size_t operator()( const String& rStr ) const + { + return rtl_ustr_hashCode_WithLength( rStr.GetBuffer(), rStr.Len() ); + } +}; + +class VBABlacklist +{ +friend class VBABlackListQuery; + std::hash_map< String, bool, StringHashCode > mBlackList; + VBABlacklist() + { + const char* list[] = { "Red" }; + sal_Int32 nSize = sizeof( list ) / sizeof( list[ 0 ] ); + for ( sal_Int32 index = 0; index < nSize; ++index ) + { + mBlackList[ String::CreateFromAscii( list[ index ] ).ToLowerAscii() ] = true; + } + } +public: + bool isBlackListed( const String& sName ) + { + String sNameLower( sName ); + sNameLower.ToLowerAscii(); + return ( mBlackList.find( sNameLower ) != mBlackList.end() ); + } +}; + +class VBABlackListQuery +{ +public: + static bool isBlackListed( const String& sName ) + { + static VBABlacklist blackList; + return blackList.isBlackListed( sName ); + } +}; static Methods aMethods[] = { { "AboutStarBasic", SbxNULL, 1 | _FUNCTION, RTLNAME(AboutStarBasic),0 }, @@ -171,7 +210,12 @@ static Methods aMethods[] = { { "expression", SbxVARIANT, 0,NULL,0 }, { "CVErr", SbxVARIANT, 1 | _FUNCTION, RTLNAME(CVErr),0 }, { "expression", SbxVARIANT, 0,NULL,0 }, - +{ "DDB", SbxDOUBLE, 5 | _FUNCTION | _COMPTMASK, RTLNAME(DDB),0 }, + { "Cost", SbxDOUBLE, 0, NULL,0 }, + { "Salvage", SbxDOUBLE, 0, NULL,0 }, + { "Life", SbxDOUBLE, 0, NULL,0 }, + { "Period", SbxDOUBLE, 0, NULL,0 }, + { "Factor", SbxVARIANT, _OPT, NULL,0 }, { "Date", SbxDATE, _LFUNCTION,RTLNAME(Date),0 }, { "DateAdd", SbxDATE, 3 | _FUNCTION, RTLNAME(DateAdd),0 }, { "Interval", SbxSTRING, 0,NULL,0 }, @@ -216,7 +260,7 @@ static Methods aMethods[] = { { "Dir", SbxSTRING, 2 | _FUNCTION, RTLNAME(Dir),0 }, { "FileSpec", SbxSTRING, _OPT, NULL,0 }, { "attrmask", SbxINTEGER, _OPT, NULL,0 }, -{ "DoEvents", SbxEMPTY, _FUNCTION, RTLNAME(DoEvents),0 }, +{ "DoEvents", SbxINTEGER, _FUNCTION, RTLNAME(DoEvents),0 }, { "DumpAllObjects", SbxEMPTY, 2 | _SUB, RTLNAME(DumpAllObjects),0 }, { "FileSpec", SbxSTRING, 0,NULL,0 }, { "DumpAll", SbxINTEGER, _OPT, NULL,0 }, @@ -271,6 +315,12 @@ static Methods aMethods[] = { { "FreeLibrary", SbxNULL, 1 | _FUNCTION, RTLNAME(FreeLibrary),0 }, { "Modulename", SbxSTRING, 0,NULL,0 }, +{ "FV", SbxDOUBLE, 5 | _FUNCTION | _COMPTMASK, RTLNAME(FV),0 }, + { "Rate", SbxDOUBLE, 0, NULL,0 }, + { "NPer", SbxDOUBLE, 0, NULL,0 }, + { "Pmt", SbxDOUBLE, 0, NULL,0 }, + { "PV", SbxVARIANT, _OPT, NULL,0 }, + { "Due", SbxVARIANT, _OPT, NULL,0 }, { "Get", SbxNULL, 3 | _FUNCTION, RTLNAME(Get),0 }, { "filenumber", SbxINTEGER, 0,NULL,0 }, { "recordnumber", SbxLONG, 0,NULL,0 }, @@ -331,6 +381,16 @@ static Methods aMethods[] = { { "Compare", SbxINTEGER, _OPT, NULL,0 }, { "Int", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Int),0 }, { "number", SbxDOUBLE, 0,NULL,0 }, +{ "IPmt", SbxDOUBLE, 6 | _FUNCTION | _COMPTMASK, RTLNAME(IPmt),0 }, + { "Rate", SbxDOUBLE, 0, NULL,0 }, + { "Per", SbxDOUBLE, 0, NULL,0 }, + { "NPer", SbxDOUBLE, 0, NULL,0 }, + { "PV", SbxDOUBLE, 0, NULL,0 }, + { "FV", SbxVARIANT, _OPT, NULL,0 }, + { "Due", SbxVARIANT, _OPT, NULL,0 }, +{ "IRR", SbxDOUBLE, 2 | _FUNCTION | _COMPTMASK, RTLNAME(IRR),0 }, + { "ValueArray", SbxARRAY, 0, NULL,0 }, + { "Guess", SbxVARIANT, _OPT, NULL,0 }, { "IsArray", SbxBOOL, 1 | _FUNCTION, RTLNAME(IsArray),0 }, { "Variant", SbxVARIANT, 0,NULL,0 }, { "IsDate", SbxBOOL, 1 | _FUNCTION, RTLNAME(IsDate),0 }, @@ -401,6 +461,10 @@ static Methods aMethods[] = { { "Length", SbxLONG, _OPT, NULL,0 }, { "Minute", SbxINTEGER, 1 | _FUNCTION, RTLNAME(Minute),0 }, { "Date", SbxDATE, 0,NULL,0 }, +{ "MIRR", SbxDOUBLE, 2 | _FUNCTION | _COMPTMASK, RTLNAME(MIRR),0 }, + { "ValueArray", SbxARRAY, 0, NULL,0 }, + { "FinanceRate", SbxDOUBLE, 0, NULL,0 }, + { "ReinvestRate", SbxDOUBLE, 0, NULL,0 }, { "MkDir", SbxNULL, 1 | _FUNCTION, RTLNAME(MkDir),0 }, { "pathname", SbxSTRING, 0,NULL,0 }, { "Month", SbxINTEGER, 1 | _FUNCTION, RTLNAME(Month),0 }, @@ -417,6 +481,15 @@ static Methods aMethods[] = { { "Nothing", SbxOBJECT, _CPROP, RTLNAME(Nothing),0 }, { "Now", SbxDATE, _FUNCTION, RTLNAME(Now),0 }, +{ "NPer", SbxDOUBLE, 5 | _FUNCTION | _COMPTMASK, RTLNAME(NPer),0 }, + { "Rate", SbxDOUBLE, 0, NULL,0 }, + { "Pmt", SbxDOUBLE, 0, NULL,0 }, + { "PV", SbxDOUBLE, 0, NULL,0 }, + { "FV", SbxVARIANT, _OPT, NULL,0 }, + { "Due", SbxVARIANT, _OPT, NULL,0 }, +{ "NPV", SbxDOUBLE, 2 | _FUNCTION | _COMPTMASK, RTLNAME(NPV),0 }, + { "Rate", SbxDOUBLE, 0, NULL,0 }, + { "ValueArray", SbxARRAY, 0, NULL,0 }, { "Null", SbxNULL, _CPROP, RTLNAME(Null),0 }, { "Oct", SbxSTRING, 1 | _FUNCTION, RTLNAME(Oct),0 }, @@ -428,16 +501,46 @@ static Methods aMethods[] = { { "stop", SbxLONG, 0,NULL,0 }, { "interval", SbxLONG, 0,NULL,0 }, { "Pi", SbxDOUBLE, _CPROP, RTLNAME(PI),0 }, + +{ "Pmt", SbxDOUBLE, 5 | _FUNCTION | _COMPTMASK, RTLNAME(Pmt),0 }, + { "Rate", SbxDOUBLE, 0, NULL,0 }, + { "NPer", SbxDOUBLE, 0, NULL,0 }, + { "PV", SbxDOUBLE, 0, NULL,0 }, + { "FV", SbxVARIANT, _OPT, NULL,0 }, + { "Due", SbxVARIANT, _OPT, NULL,0 }, + +{ "PPmt", SbxDOUBLE, 6 | _FUNCTION | _COMPTMASK, RTLNAME(PPmt),0 }, + { "Rate", SbxDOUBLE, 0, NULL,0 }, + { "Per", SbxDOUBLE, 0, NULL,0 }, + { "NPer", SbxDOUBLE, 0, NULL,0 }, + { "PV", SbxDOUBLE, 0, NULL,0 }, + { "FV", SbxVARIANT, _OPT, NULL,0 }, + { "Due", SbxVARIANT, _OPT, NULL,0 }, + { "Put", SbxNULL, 3 | _FUNCTION, RTLNAME(Put),0 }, { "filenumber", SbxINTEGER, 0,NULL,0 }, { "recordnumber", SbxLONG, 0,NULL,0 }, { "variablename", SbxVARIANT, 0,NULL,0 }, +{ "PV", SbxDOUBLE, 5 | _FUNCTION | _COMPTMASK, RTLNAME(PV),0 }, + { "Rate", SbxDOUBLE, 0, NULL,0 }, + { "NPer", SbxDOUBLE, 0, NULL,0 }, + { "Pmt", SbxDOUBLE, 0, NULL,0 }, + { "FV", SbxVARIANT, _OPT, NULL,0 }, + { "Due", SbxVARIANT, _OPT, NULL,0 }, + { "QBColor", SbxLONG, 1 | _FUNCTION, RTLNAME(QBColor),0 }, { "number", SbxINTEGER, 0,NULL,0 }, { "Randomize", SbxNULL, 1 | _FUNCTION, RTLNAME(Randomize),0 }, { "Number", SbxDOUBLE, _OPT, NULL,0 }, +{ "Rate", SbxDOUBLE, 6 | _FUNCTION | _COMPTMASK, RTLNAME(Rate),0 }, + { "NPer", SbxDOUBLE, 0, NULL,0 }, + { "Pmt", SbxDOUBLE, 0, NULL,0 }, + { "PV", SbxDOUBLE, 0, NULL,0 }, + { "FV", SbxVARIANT, _OPT, NULL,0 }, + { "Due", SbxVARIANT, _OPT, NULL,0 }, + { "Guess", SbxVARIANT, _OPT, NULL,0 }, { "Red", SbxINTEGER, 1 | _FUNCTION, RTLNAME(Red),0 }, { "RGB-Value", SbxLONG, 0,NULL,0 }, { "Reset", SbxNULL, 0 | _FUNCTION, RTLNAME(Reset),0 }, @@ -491,6 +594,15 @@ static Methods aMethods[] = { { "WindowStyle", SbxINTEGER, _OPT, NULL,0 }, { "Sin", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Sin),0 }, { "number", SbxDOUBLE, 0,NULL,0 }, +{ "SLN", SbxDOUBLE, 2 | _FUNCTION | _COMPTMASK, RTLNAME(SLN),0 }, + { "Cost", SbxDOUBLE, 0,NULL,0 }, + { "Double", SbxDOUBLE, 0,NULL,0 }, + { "Life", SbxDOUBLE, 0,NULL,0 }, +{ "SYD", SbxDOUBLE, 2 | _FUNCTION | _COMPTMASK, RTLNAME(SYD),0 }, + { "Cost", SbxDOUBLE, 0,NULL,0 }, + { "Salvage", SbxDOUBLE, 0,NULL,0 }, + { "Life", SbxDOUBLE, 0,NULL,0 }, + { "Period", SbxDOUBLE, 0,NULL,0 }, { "Space", SbxSTRING, 1 | _FUNCTION, RTLNAME(Space),0 }, { "string", SbxLONG, 0,NULL,0 }, { "Spc", SbxSTRING, 1 | _FUNCTION, RTLNAME(Spc),0 }, @@ -605,6 +717,7 @@ static Methods aMethods[] = { { "Wait", SbxNULL, 1 | _FUNCTION, RTLNAME(Wait),0 }, { "Milliseconds", SbxLONG, 0,NULL,0 }, +{ "FuncCaller", SbxVARIANT, _FUNCTION, RTLNAME(FuncCaller),0 }, //#i64882# { "WaitUntil", SbxNULL, 1 | _FUNCTION, RTLNAME(WaitUntil),0 }, { "Date", SbxDOUBLE, 0,NULL,0 }, @@ -683,13 +796,15 @@ SbxVariable* SbiStdObject::Find( const String& rName, SbxClassType t ) && ( p->nHash == nHash_ ) && ( rName.EqualsIgnoreCaseAscii( p->pName ) ) ) { + SbiInstance* pInst = pINST; bFound = TRUE; if( p->nArgs & _COMPTMASK ) { - SbiInstance* pInst = pINST; if( !pInst || !pInst->IsCompatibility() ) bFound = FALSE; } + if ( pInst && pInst->IsCompatibility() && VBABlackListQuery::isBlackListed( rName ) ) + bFound = FALSE; break; } nIndex += ( p->nArgs & _ARGSMASK ) + 1; diff --git a/basic/source/runtime/step0.cxx b/basic/source/runtime/step0.cxx index 06a8bb19af00..e184d8928f3f 100644 --- a/basic/source/runtime/step0.cxx +++ b/basic/source/runtime/step0.cxx @@ -48,6 +48,11 @@ Reference< XInterface > createComListener( const Any& aControlAny, const ::rtl:: #include <algorithm> +// for a patch forward declaring these methods below makes sense +// but, #FIXME lets really just move the methods to the top +void lcl_clearImpl( SbxVariableRef& refVar, SbxDataType& eType ); +void lcl_eraseImpl( SbxVariableRef& refVar, bool bVBAEnabled ); + SbxVariable* getDefaultProp( SbxVariable* pRef ); void SbiRuntime::StepNOP() @@ -59,34 +64,6 @@ void SbiRuntime::StepArith( SbxOperator eOp ) TOSMakeTemp(); SbxVariable* p2 = GetTOS(); - - // This could & should be moved to the MakeTempTOS() method in runtime.cxx - // In the code which this is cut'npaste from there is a check for a ref - // count != 1 based on which the copy of the SbxVariable is done. - // see orig code in MakeTempTOS ( and I'm not sure what the significance, - // of that is ) - // here we alway seem to have a refcount of 1. Also it seems that - // MakeTempTOS is called for other operation, so I hold off for now - // until I have a better idea - if ( bVBAEnabled - && ( p2->GetType() == SbxOBJECT || p2->GetType() == SbxVARIANT ) - ) - { - SbxVariable* pDflt = getDefaultProp( p2 ); - if ( pDflt ) - { - pDflt->Broadcast( SBX_HINT_DATAWANTED ); - // replacing new p2 on stack causes object pointed by - // pDft->pParent to be deleted, when p2->Compute() is - // called below pParent is accessed ( but its deleted ) - // so set it to NULL now - pDflt->SetParent( NULL ); - p2 = new SbxVariable( *pDflt ); - p2->SetFlag( SBX_READWRITE ); - refExprStk->Put( p2, nExprLvl - 1 ); - } - } - p2->ResetFlag( SBX_FIXED ); p2->Compute( eOp, *p1 ); @@ -109,19 +86,24 @@ void SbiRuntime::StepCompare( SbxOperator eOp ) // values ( and type ) set as appropriate SbxDataType p1Type = p1->GetType(); SbxDataType p2Type = p2->GetType(); + if ( p1Type == SbxEMPTY ) + { + p1->Broadcast( SBX_HINT_DATAWANTED ); + p1Type = p1->GetType(); + } + if ( p2Type == SbxEMPTY ) + { + p2->Broadcast( SBX_HINT_DATAWANTED ); + p2Type = p2->GetType(); + } if ( p1Type == p2Type ) { - if ( p1Type == SbxEMPTY ) - { - p1->Broadcast( SBX_HINT_DATAWANTED ); - p2->Broadcast( SBX_HINT_DATAWANTED ); - } // if both sides are an object and have default props // then we need to use the default props // we don't need to worry if only one side ( lhs, rhs ) is an // object ( object side will get coerced to correct type in // Compare ) - else if ( p1Type == SbxOBJECT ) + if ( p1Type == SbxOBJECT ) { SbxVariable* pDflt = getDefaultProp( p1 ); if ( pDflt ) @@ -141,8 +123,21 @@ void SbiRuntime::StepCompare( SbxOperator eOp ) #ifndef WIN static SbxVariable* pTRUE = NULL; static SbxVariable* pFALSE = NULL; - - if( p2->Compare( eOp, *p1 ) ) + static SbxVariable* pNULL = NULL; + // why do this on non-windows ? + // why do this at all ? + // I dumbly follow the pattern :-/ + if ( bVBAEnabled && ( p1->IsNull() || p2->IsNull() ) ) + { + if( !pNULL ) + { + pNULL = new SbxVariable; + pNULL->PutNull(); + pNULL->AddRef(); + } + PushVar( pNULL ); + } + else if( p2->Compare( eOp, *p1 ) ) { if( !pTRUE ) { @@ -163,9 +158,14 @@ void SbiRuntime::StepCompare( SbxOperator eOp ) PushVar( pFALSE ); } #else - BOOL bRes = p2->Compare( eOp, *p1 ); SbxVariable* pRes = new SbxVariable; - pRes->PutBool( bRes ); + if ( bVBAEnabled && ( p1->IsNull() || p2->IsNull() ) ) + pRes->PutNull(); + else + { + BOOL bRes = p2->Compare( eOp, *p1 ); + pRes->PutBool( bRes ); + } PushVar( pRes ); #endif } @@ -679,6 +679,17 @@ void SbiRuntime::StepDIM() // #56204 DIM-Funktionalitaet in Hilfsmethode auslagern (step0.cxx) void SbiRuntime::DimImpl( SbxVariableRef refVar ) { + // If refDim then this DIM statement is terminating a ReDIM and + // previous StepERASE_CLEAR for an array, the following actions have + // been delayed from ( StepERASE_CLEAR ) 'till here + if ( refRedim ) + { + if ( !refRedimpArray ) // only erase the array not ReDim Preserve + lcl_eraseImpl( refVar, bVBAEnabled ); + SbxDataType eType = refVar->GetType(); + lcl_clearImpl( refVar, eType ); + refRedim = NULL; + } SbxArray* pDims = refVar->GetParameters(); // Muss eine gerade Anzahl Argumente haben // Man denke daran, dass Arg[0] nicht zaehlt! @@ -844,6 +855,7 @@ void SbiRuntime::StepREDIMP() void SbiRuntime::StepREDIMP_ERASE() { SbxVariableRef refVar = PopVar(); + refRedim = refVar; SbxDataType eType = refVar->GetType(); if( eType & SbxARRAY ) { @@ -854,12 +866,6 @@ void SbiRuntime::StepREDIMP_ERASE() refRedimpArray = pDimArray; } - // As in ERASE - USHORT nSavFlags = refVar->GetFlags(); - refVar->ResetFlag( SBX_FIXED ); - refVar->SetType( SbxDataType(eType & 0x0FFF) ); - refVar->SetFlags( nSavFlags ); - refVar->Clear(); } else if( refVar->IsFixed() ) @@ -932,10 +938,7 @@ void SbiRuntime::StepERASE() void SbiRuntime::StepERASE_CLEAR() { - SbxVariableRef refVar = PopVar(); - lcl_eraseImpl( refVar, bVBAEnabled ); - SbxDataType eType = refVar->GetType(); - lcl_clearImpl( refVar, eType ); + refRedim = PopVar(); } void SbiRuntime::StepARRAYACCESS() diff --git a/basic/source/runtime/step1.cxx b/basic/source/runtime/step1.cxx index e23ef864218e..ec440a33f16c 100644 --- a/basic/source/runtime/step1.cxx +++ b/basic/source/runtime/step1.cxx @@ -93,6 +93,15 @@ void SbiRuntime::StepARGN( UINT32 nOp1 ) { String aAlias( pImg->GetString( static_cast<short>( nOp1 ) ) ); SbxVariableRef pVal = PopVar(); + if( bVBAEnabled && ( pVal->ISA(SbxMethod) || pVal->ISA(SbUnoProperty) || pVal->ISA(SbProcedureProperty) ) ) + { + // named variables ( that are Any especially properties ) can be empty at this point and need a broadcast + if ( pVal->GetType() == SbxEMPTY ) + pVal->Broadcast( SBX_HINT_DATAWANTED ); + // Methoden und Properties evaluieren! + SbxVariable* pRes = new SbxVariable( *pVal ); + pVal = pRes; + } refArgv->Put( pVal, nArgc ); refArgv->PutAlias( aAlias, nArgc++ ); } @@ -182,7 +191,9 @@ void SbiRuntime::StepJUMPT( UINT32 nOp1 ) void SbiRuntime::StepJUMPF( UINT32 nOp1 ) { SbxVariableRef p = PopVar(); - if( !p->GetBool() ) + // In a test e.g. If Null then + // will evaluate Null will act as if False + if( ( bVBAEnabled && p->IsNull() ) || !p->GetBool() ) StepJUMP( nOp1 ); } diff --git a/basic/source/runtime/step2.cxx b/basic/source/runtime/step2.cxx index 072f33d55347..7f0ec8ceabf2 100644 --- a/basic/source/runtime/step2.cxx +++ b/basic/source/runtime/step2.cxx @@ -139,7 +139,7 @@ SbxVariable* SbiRuntime::FindElement if ( pElem ) bSetName = false; // don't overwrite uno name else - pElem = getVBAConstant( aName ); + pElem = VBAConstantHelper::instance().getVBAConstant( aName ); } // #72382 VORSICHT! Liefert jetzt wegen unbekannten // Modulen IMMER ein Ergebnis! @@ -455,7 +455,7 @@ SbxVariable* SbiRuntime::CheckArray( SbxVariable* pElem ) { // Falls wir ein Array haben, wollen wir bitte das Array-Element! SbxArray* pPar; - if( pElem->GetType() & SbxARRAY ) + if( ( pElem->GetType() & SbxARRAY ) && (SbxVariable*)refRedim != pElem ) { SbxBase* pElemObj = pElem->GetObject(); SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj); @@ -487,7 +487,7 @@ SbxVariable* SbiRuntime::CheckArray( SbxVariable* pElem ) pPar->Put( NULL, 0 ); } // Index-Access bei UnoObjekten beruecksichtigen - else if( pElem->GetType() == SbxOBJECT && !pElem->ISA(SbxMethod) ) + else if( pElem->GetType() == SbxOBJECT && !pElem->ISA(SbxMethod) && ( !bVBAEnabled || ( bVBAEnabled && !pElem->ISA(SbxProperty) ) ) ) { pPar = pElem->GetParameters(); if ( pPar ) @@ -731,6 +731,8 @@ void SbiRuntime::StepPARAM( UINT32 nOp1, UINT32 nOp2 ) SaveRef( q ); *q = *p; p = q; + if ( i ) + refParams->Put( p, i ); } SetupArgs( p, nOp1 ); PushVar( CheckArray( p ) ); diff --git a/basic/source/sbx/sbxvalue.cxx b/basic/source/sbx/sbxvalue.cxx index d8f047059ef0..047d6c07a8ab 100644 --- a/basic/source/sbx/sbxvalue.cxx +++ b/basic/source/sbx/sbxvalue.cxx @@ -1146,8 +1146,8 @@ BOOL SbxValue::Compute( SbxOperator eOp, const SbxValue& rOp ) { SbxValues aL, aR; bool bDecimal = false; - if( bVBAInterop && ( ( eThisType == SbxSTRING && eOpType != SbxSTRING ) || - ( eThisType != SbxSTRING && eOpType == SbxSTRING ) ) && + if( bVBAInterop && ( ( eThisType == SbxSTRING && eOpType != SbxSTRING && eOpType != SbxEMPTY ) || + ( eThisType != SbxSTRING && eThisType != SbxEMPTY && eOpType == SbxSTRING ) ) && ( eOp == SbxMUL || eOp == SbxDIV || eOp == SbxPLUS || eOp == SbxMINUS ) ) { goto Lbl_OpIsDouble; @@ -1194,6 +1194,8 @@ BOOL SbxValue::Compute( SbxOperator eOp, const SbxValue& rOp ) aL.eType = aR.eType = GetType(); // else if( GetType() == SbxDouble || GetType() == SbxSingle ) // aL.eType = aR.eType = SbxLONG64; + else if ( bVBAInterop && eOpType == SbxBOOL ) + aL.eType = aR.eType = SbxBOOL; else aL.eType = aR.eType = SbxLONG; } @@ -1280,7 +1282,12 @@ BOOL SbxValue::Compute( SbxOperator eOp, const SbxValue& rOp ) break; case SbxNOT: if( aL.eType != SbxLONG && aL.eType != SbxULONG ) - aL.nLong64 = ~aL.nLong64; + { + if ( aL.eType != SbxBOOL ) + aL.nLong64 = ~aL.nLong64; + else + aL.nLong = ~aL.nLong; + } else aL.nLong = ~aL.nLong; break; diff --git a/basic/source/uno/dlgcont.cxx b/basic/source/uno/dlgcont.cxx index 004b61fbf198..ed8db5c9e1e8 100644 --- a/basic/source/uno/dlgcont.cxx +++ b/basic/source/uno/dlgcont.cxx @@ -322,7 +322,7 @@ Any SAL_CALL SfxDialogLibraryContainer::importLibraryElement try { // start parsing - xParser->setDocumentHandler( ::xmlscript::importDialogModel( xDialogModel, xContext ) ); + xParser->setDocumentHandler( ::xmlscript::importDialogModel( xDialogModel, xContext, mxOwnerDocument ) ); xParser->parseStream( source ); } catch( Exception& ) @@ -336,7 +336,7 @@ Any SAL_CALL SfxDialogLibraryContainer::importLibraryElement // Create InputStream, TODO: Implement own InputStreamProvider // to avoid creating the DialogModel here! - Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext ); + Reference< XInputStreamProvider > xISP = ::xmlscript::exportDialogModel( xDialogModel, xContext, mxOwnerDocument ); aRetAny <<= xISP; return aRetAny; } @@ -484,7 +484,11 @@ void SfxDialogLibraryContainer::onNewRootStorage() } } - +sal_Bool SAL_CALL +SfxDialogLibraryContainer:: HasExecutableCode( const ::rtl::OUString& Library ) throw (uno::RuntimeException) +{ + return sal_False; // dialog library has no executable code +} //============================================================================ // Service diff --git a/basic/source/uno/scriptcont.cxx b/basic/source/uno/scriptcont.cxx index 3d81d4108bc4..8e11f6b6f0b5 100644 --- a/basic/source/uno/scriptcont.cxx +++ b/basic/source/uno/scriptcont.cxx @@ -64,7 +64,8 @@ #include <xmlscript/xmlmod_imexp.hxx> #include <cppuhelper/factory.hxx> #include <com/sun/star/util/VetoException.hpp> - +#include <com/sun/star/script/XLibraryQueryExecutable.hpp> +#include <cppuhelper/implbase1.hxx> namespace basic { @@ -135,7 +136,6 @@ sal_Bool SfxScriptLibraryContainer::hasLibraryPassword( const String& rLibraryNa return pImplLib->mbPasswordProtected; } - // Ctor for service SfxScriptLibraryContainer::SfxScriptLibraryContainer( void ) :maScriptLanguage( RTL_CONSTASCII_USTRINGPARAM( "StarBasic" ) ) @@ -1163,6 +1163,17 @@ void SfxScriptLibraryContainer::onNewRootStorage() { } +sal_Bool SAL_CALL +SfxScriptLibraryContainer:: HasExecutableCode( const ::rtl::OUString& Library ) throw (uno::RuntimeException) +{ + BasicManager* pBasicMgr = getBasicManager(); + OSL_ENSURE( pBasicMgr, "we need a basicmanager, really we do" ); + if ( pBasicMgr ) + return pBasicMgr->HasExeCode( Library ); // need to change this to take name + // default to it has code if we can't decide + return sal_True; +} + //============================================================================ // Service void createRegistryInfo_SfxScriptLibraryContainer() |