diff options
95 files changed, 3279 insertions, 1118 deletions
diff --git a/basic/inc/basic/sbmod.hxx b/basic/inc/basic/sbmod.hxx index 63ffef6cdd61..cf888adf9dcf 100644 --- a/basic/inc/basic/sbmod.hxx +++ b/basic/inc/basic/sbmod.hxx @@ -40,6 +40,7 @@ class SbiBreakpoints; class SbiImage; class SbProcedureProperty; class SbIfaceMapperMethod; +class SbClassModuleObject; struct SbClassData; class SbModuleImpl; @@ -125,11 +126,12 @@ public: BOOL LoadBinaryData( SvStream& ); BOOL ExceedsLegacyModuleSize(); void fixUpMethodStart( bool bCvtToLegacy, SbiImage* pImg = NULL ) const; - BOOL IsVBACompat(); - void SetVBACompat( BOOL bCompat ); - INT32 GetModuleType() { return mnType; } - void SetModuleType( INT32 nType ) { mnType = nType; } + BOOL IsVBACompat() const; + void SetVBACompat( BOOL bCompat ); + INT32 GetModuleType() { return mnType; } + void SetModuleType( INT32 nType ) { mnType = nType; } bool GetIsProxyModule() { return bIsProxyModule; } + bool createCOMWrapperForIface( ::com::sun::star::uno::Any& o_rRetAny, SbClassModuleObject* pProxyClassModuleObject ); }; #ifndef __SB_SBMODULEREF_HXX diff --git a/basic/inc/basic/sbobjmod.hxx b/basic/inc/basic/sbobjmod.hxx index ad804dcfab38..3d638a475f9a 100644 --- a/basic/inc/basic/sbobjmod.hxx +++ b/basic/inc/basic/sbobjmod.hxx @@ -62,6 +62,7 @@ public: class SbUserFormModule : public SbObjModule { + com::sun::star::script::ModuleInfo m_mInfo; css::uno::Reference<css::lang::XEventListener> m_DialogListener; css::uno::Reference<css::awt::XDialog> m_xDialog; css::uno::Reference<css::frame::XModel> m_xModel; @@ -70,7 +71,7 @@ class SbUserFormModule : public SbObjModule SbUserFormModule( const SbUserFormModule& ); SbUserFormModule(); -protected: +//protected: virtual void InitObject(); public: TYPEINFO(); @@ -85,8 +86,23 @@ public: void triggerDeActivateEvent(); void triggerInitializeEvent(); void triggerTerminateEvent(); + + class SbUserFormModuleInstance* CreateInstance(); }; +class SbUserFormModuleInstance : public SbUserFormModule +{ + SbUserFormModule* m_pParentModule; + +public: + SbUserFormModuleInstance( SbUserFormModule* pParentModule, const String& rName, + const com::sun::star::script::ModuleInfo& mInfo, bool bIsVBACompat ); + + virtual BOOL IsClass( const String& ) const; + virtual SbxVariable* Find( const XubString& rName, SbxClassType t ); +}; + + #ifndef __SB_SBOBJMODULEREF_HXX #define __SB_SBOBJMODULEREF_HXX diff --git a/basic/inc/basic/sbx.hxx b/basic/inc/basic/sbx.hxx index 1254716c84e6..2eb194708739 100644 --- a/basic/inc/basic/sbx.hxx +++ b/basic/inc/basic/sbx.hxx @@ -171,8 +171,8 @@ class SbxArray : public SbxBase { // #100883 Method to set method directly to parameter array friend class SbMethod; - friend class SbTypeFactory; friend class SbClassModuleObject; + friend SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj ); void PutDirect( SbxVariable* pVar, UINT32 nIdx ); SbxArrayImpl* mpSbxArrayImpl; // Impl data diff --git a/basic/inc/basic/sbxdef.hxx b/basic/inc/basic/sbxdef.hxx index 8206fa2b1667..89322be776f9 100644 --- a/basic/inc/basic/sbxdef.hxx +++ b/basic/inc/basic/sbxdef.hxx @@ -105,6 +105,9 @@ enum SbxDataType { SbxUSERn = 2047 // last user defined data type }; +const UINT32 SBX_TYPE_WITH_EVENTS_FLAG = 0x10000; +const UINT32 SBX_FIXED_LEN_STRING_FLAG = 0x10000; // same value as above as no conflict possible + #endif #ifndef _SBX_OPERATOR @@ -313,6 +316,7 @@ enum SbxError { // Ergebnis einer Rechenoperation/Konversion #define SBX_NO_BROADCAST 0x2000 // No broadcast on Get/Put #define SBX_REFERENCE 0x4000 // Parameter is Reference (DLL-call) #define SBX_NO_MODIFY 0x8000 // SetModified is suppressed +#define SBX_WITH_EVENTS 0x0080 // Same value as unused SBX_HIDDEN // Broadcaster-IDs: #define SBX_HINT_DYING SFX_HINT_DYING diff --git a/basic/inc/basic/sbxvar.hxx b/basic/inc/basic/sbxvar.hxx index 715d8c46f0f3..4d9d19b52a59 100644 --- a/basic/inc/basic/sbxvar.hxx +++ b/basic/inc/basic/sbxvar.hxx @@ -230,8 +230,6 @@ class SbxValueImpl; class SbxValue : public SbxBase { - friend class SbiDllMgr; // BASIC-Runtime must access aData - SbxValueImpl* mpSbxValueImplImpl; // Impl data // #55226 Transport additional infos @@ -289,6 +287,8 @@ public: const SbxValues& GetValues_Impl() const { return aData; } virtual BOOL Put( const SbxValues& ); + inline SbxValues * data() { return &aData; } + SbxINT64 GetCurrency() const; SbxINT64 GetLong64() const; SbxUINT64 GetULong64() const; @@ -447,6 +447,9 @@ class SbxVariable : public SbxValue String maName; // Name, if available SbxArrayRef mpPar; // Parameter-Array, if set USHORT nHash; // Hash-ID for search + + SbxVariableImpl* getImpl( void ); + protected: SbxInfoRef pInfo; // Probably called information sal_uIntPtr nUserData; // User data for Call() @@ -492,6 +495,10 @@ public: inline SbxObject* GetParent() { return pParent; } virtual void SetParent( SbxObject* ); + const String& GetDeclareClassName( void ); + void SetDeclareClassName( const String& ); + void SetComListener( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xComListener ); + static USHORT MakeHashCode( const String& rName ); }; diff --git a/basic/prj/build.lst b/basic/prj/build.lst index 2cd1d3dc0466..a41428a1ca20 100755 --- a/basic/prj/build.lst +++ b/basic/prj/build.lst @@ -1,4 +1,4 @@ -sb basic : l10n offuh oovbaapi svtools xmlscript framework NULL +sb basic : l10n offuh oovbaapi svtools xmlscript framework salhelper NULL sb basic usr1 - all sb_mkout NULL sb basic\inc nmake - all sb_inc NULL sb basic\source\app nmake - all sb_app sb_class sb_inc NULL diff --git a/basic/source/basmgr/basmgr.cxx b/basic/source/basmgr/basmgr.cxx index c242165df825..b76a2b5e249e 100644 --- a/basic/source/basmgr/basmgr.cxx +++ b/basic/source/basmgr/basmgr.cxx @@ -1789,7 +1789,7 @@ bool BasicManager::GetGlobalUNOConstant( const sal_Char* _pAsciiName, ::com::sun { bool bRes = false; StarBASIC* pStandardLib = GetStdLib(); - OSL_PRECOND( pStandardLib, "BasicManager::SetGlobalUNOConstant: no lib to insert into!" ); + OSL_PRECOND( pStandardLib, "BasicManager::GetGlobalUNOConstant: no lib to read from!" ); if ( pStandardLib ) bRes = pStandardLib->GetUNOConstant( _pAsciiName, aOut ); return bRes; diff --git a/basic/source/classes/disas.cxx b/basic/source/classes/disas.cxx index 36e88b6353e8..7317005d74fe 100644 --- a/basic/source/classes/disas.cxx +++ b/basic/source/classes/disas.cxx @@ -89,7 +89,8 @@ static const char* pOp1[] = { "INITFOREACH", "VBASET", "ERASE_CLEAR", - "ARRAYACCESS" + "ARRAYACCESS", + "BYVAL" }; static const char* pOp2[] = { diff --git a/basic/source/classes/sb.cxx b/basic/source/classes/sb.cxx index 4f2f90d5da1f..79c5f78601ea 100755 --- a/basic/source/classes/sb.cxx +++ b/basic/source/classes/sb.cxx @@ -321,23 +321,52 @@ SbxObject* SbOLEFactory::CreateObject( const String& rClassName ) } -// Factory class to create user defined objects (type command) -class SbTypeFactory : public SbxFactory -{ - SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj ); +//======================================================================== +// SbFormFactory, show user forms by: dim as new <user form name> +class SbFormFactory : public SbxFactory +{ public: virtual SbxBase* Create( UINT16 nSbxId, UINT32 = SBXCR_SBX ); virtual SbxObject* CreateObject( const String& ); }; -SbxBase* SbTypeFactory::Create( UINT16, UINT32 ) +SbxBase* SbFormFactory::Create( UINT16, UINT32 ) { // Not supported return NULL; } -SbxObject* SbTypeFactory::cloneTypeObjectImpl( const SbxObject& rTypeObj ) +SbxObject* SbFormFactory::CreateObject( const String& rClassName ) +{ + static String aLoadMethodName( RTL_CONSTASCII_USTRINGPARAM("load") ); + + SbxObject* pRet = NULL; + SbModule* pMod = pMOD; + if( pMod ) + { + SbxVariable* pVar = pMod->Find( rClassName, SbxCLASS_OBJECT ); + if( pVar ) + { + SbxBase* pObj = pVar->GetObject(); + SbUserFormModule* pFormModule = PTR_CAST( SbUserFormModule, pObj ); + + if( pFormModule != NULL ) + { + pFormModule->load(); + SbUserFormModuleInstance* pFormInstance = pFormModule->CreateInstance(); + pRet = pFormInstance; + } + } + } + return pRet; +} + + +//======================================================================== +// SbTypeFactory + +SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj ) { SbxObject* pRet = new SbxObject( rTypeObj ); pRet->PutObject( pRet ); @@ -352,7 +381,8 @@ SbxObject* SbTypeFactory::cloneTypeObjectImpl( const SbxObject& rTypeObj ) if( pProp ) { SbxProperty* pNewProp = new SbxProperty( *pProp ); - if( pVar->GetType() & SbxARRAY ) + SbxDataType eVarType = pVar->GetType(); + if( eVarType & SbxARRAY ) { SbxBase* pParObj = pVar->GetObject(); SbxDimArray* pSource = PTR_CAST(SbxDimArray,pParObj); @@ -379,12 +409,35 @@ SbxObject* SbTypeFactory::cloneTypeObjectImpl( const SbxObject& rTypeObj ) pNewProp->PutObject( pDest ); pNewProp->SetFlags( nSavFlags ); } + if( eVarType == SbxOBJECT ) + { + SbxBase* pObjBase = pVar->GetObject(); + SbxObject* pSrcObj = PTR_CAST(SbxObject,pObjBase); + SbxObject* pDestObj = NULL; + if( pSrcObj != NULL ) + pDestObj = cloneTypeObjectImpl( *pSrcObj ); + pNewProp->PutObject( pDestObj ); + } pProps->PutDirect( pNewProp, i ); } } return pRet; } +// Factory class to create user defined objects (type command) +class SbTypeFactory : public SbxFactory +{ +public: + virtual SbxBase* Create( UINT16 nSbxId, UINT32 = SBXCR_SBX ); + virtual SbxObject* CreateObject( const String& ); +}; + +SbxBase* SbTypeFactory::Create( UINT16, UINT32 ) +{ + // Not supported + return NULL; +} + SbxObject* SbTypeFactory::CreateObject( const String& rClassName ) { SbxObject* pRet = NULL; @@ -728,6 +781,8 @@ StarBASIC::StarBASIC( StarBASIC* p, BOOL bIsDocBasic ) AddFactory( pCLASSFAC ); pOLEFAC = new SbOLEFactory; AddFactory( pOLEFAC ); + pFORMFAC = new SbFormFactory; + AddFactory( pFORMFAC ); } pRtl = new SbiStdObject( String( RTL_CONSTASCII_USTRINGPARAM(RTLNAME) ), this ); // Search via StarBasic is always global @@ -748,15 +803,17 @@ StarBASIC::~StarBASIC() if( !--GetSbData()->nInst ) { RemoveFactory( pSBFAC ); - pSBFAC = NULL; + delete pSBFAC; pSBFAC = NULL; RemoveFactory( pUNOFAC ); - pUNOFAC = NULL; + delete pUNOFAC; pUNOFAC = NULL; RemoveFactory( pTYPEFAC ); - pTYPEFAC = NULL; + delete pTYPEFAC; pTYPEFAC = NULL; RemoveFactory( pCLASSFAC ); - pCLASSFAC = NULL; + delete pCLASSFAC; pCLASSFAC = NULL; RemoveFactory( pOLEFAC ); - pOLEFAC = NULL; + delete pOLEFAC; pOLEFAC = NULL; + RemoveFactory( pFORMFAC ); + delete pFORMFAC; pFORMFAC = NULL; #ifdef DBG_UTIL // There is no need to clean SbiData at program end, diff --git a/basic/source/classes/sbunoobj.cxx b/basic/source/classes/sbunoobj.cxx index 849fd839bfd1..e51a0c09270b 100644 --- a/basic/source/classes/sbunoobj.cxx +++ b/basic/source/classes/sbunoobj.cxx @@ -49,6 +49,7 @@ #include <com/sun/star/uno/XComponentContext.hpp> #include <com/sun/star/uno/DeploymentException.hpp> #include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/beans/PropertyAttribute.hpp> @@ -1074,8 +1075,19 @@ Any sbxToUnoValueImpl( SbxVariable* pVar, bool bBlockConversionToSmallestType = if( eBaseType == SbxOBJECT ) { SbxBaseRef xObj = (SbxBase*)pVar->GetObject(); - if( xObj.Is() && xObj->ISA(SbUnoAnyObject) ) - return ((SbUnoAnyObject*)(SbxBase*)xObj)->getValue(); + if( xObj.Is() ) + { + if( xObj->ISA(SbUnoAnyObject) ) + return ((SbUnoAnyObject*)(SbxBase*)xObj)->getValue(); + if( xObj->ISA(SbClassModuleObject) ) + { + Any aRetAny; + SbClassModuleObject* pClassModuleObj = (SbClassModuleObject*)(SbxBase*)xObj; + SbModule* pClassModule = pClassModuleObj->getClassModule(); + if( pClassModule->createCOMWrapperForIface( aRetAny, pClassModuleObj ) ) + return aRetAny; + } + } } Type aType = getUnoTypeForSbxValue( pVar ); @@ -1581,12 +1593,18 @@ String getBasicObjectTypeName( SbxObject* pObj ) bool checkUnoObjectType( SbUnoObject* pUnoObj, const String& aClass ) { - bool result = false; Any aToInspectObj = pUnoObj->getUnoAny(); TypeClass eType = aToInspectObj.getValueType().getTypeClass(); if( eType != TypeClass_INTERFACE ) return false; const Reference< XInterface > x = *(Reference< XInterface >*)aToInspectObj.getValue(); + + // Return true for XInvocation based objects as interface type names don't count then + Reference< XInvocation > xInvocation( x, UNO_QUERY ); + if( xInvocation.is() ) + return true; + + bool result = false; Reference< XTypeProvider > xTypeProvider( x, UNO_QUERY ); if( xTypeProvider.is() ) { @@ -4135,3 +4153,267 @@ void RTL_Impl_CreateUnoValue( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite ) refVar->PutObject( xUnoAnyObject ); } +//========================================================================== + +typedef WeakImplHelper1< XInvocation > ModuleInvocationProxyHelper; + +class ModuleInvocationProxy : public ModuleInvocationProxyHelper +{ + ::rtl::OUString m_aPrefix; + SbxObjectRef m_xScopeObj; + bool m_bProxyIsClassModuleObject; + +public: + ModuleInvocationProxy( const ::rtl::OUString& aPrefix, SbxObjectRef xScopeObj ); + ~ModuleInvocationProxy() + {} + + // XInvocation + virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection() throw(); + virtual void SAL_CALL setValue( const ::rtl::OUString& rProperty, const Any& rValue ) + throw( UnknownPropertyException ); + virtual Any SAL_CALL getValue( const ::rtl::OUString& rProperty ) + throw( UnknownPropertyException ); + virtual sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& rName ) throw(); + virtual sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& rProp ) throw(); + + virtual Any SAL_CALL invoke( const ::rtl::OUString& rFunction, + const Sequence< Any >& rParams, + Sequence< sal_Int16 >& rOutParamIndex, + Sequence< Any >& rOutParam ) + throw( CannotConvertException, InvocationTargetException ); +}; + +ModuleInvocationProxy::ModuleInvocationProxy( const ::rtl::OUString& aPrefix, SbxObjectRef xScopeObj ) + : m_aPrefix( aPrefix + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_") ) ) + , m_xScopeObj( xScopeObj ) +{ + m_bProxyIsClassModuleObject = xScopeObj.Is() ? xScopeObj->ISA(SbClassModuleObject) : false; +} + +Reference< XIntrospectionAccess > SAL_CALL ModuleInvocationProxy::getIntrospection() throw() +{ + return Reference< XIntrospectionAccess >(); +} + +void SAL_CALL ModuleInvocationProxy::setValue( const ::rtl::OUString& rProperty, const Any& rValue ) throw( UnknownPropertyException ) +{ + if( !m_bProxyIsClassModuleObject ) + throw UnknownPropertyException(); + + NAMESPACE_VOS(OGuard) guard( Application::GetSolarMutex() ); + + ::rtl::OUString aPropertyFunctionName( RTL_CONSTASCII_USTRINGPARAM( "Property Set ") ); + aPropertyFunctionName += m_aPrefix; + aPropertyFunctionName += rProperty; + + SbxVariable* p = m_xScopeObj->Find( aPropertyFunctionName, SbxCLASS_METHOD ); + SbMethod* pMeth = p != NULL ? PTR_CAST(SbMethod,p) : NULL; + if( pMeth == NULL ) + { + // TODO: Check vba behavior concernig missing function + //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName ); + throw UnknownPropertyException(); + } + + // Setup parameter + SbxArrayRef xArray = new SbxArray; + SbxVariableRef xVar = new SbxVariable( SbxVARIANT ); + unoToSbxValue( (SbxVariable*)xVar, rValue ); + xArray->Put( xVar, 1 ); + + // Call property method + SbxVariableRef xValue = new SbxVariable; + pMeth->SetParameters( xArray ); + pMeth->Call( xValue ); + //aRet = sbxToUnoValue( xValue ); + pMeth->SetParameters( NULL ); + + // TODO: OutParameter? + + // throw InvocationTargetException(); + + //return aRet; + +} + +Any SAL_CALL ModuleInvocationProxy::getValue( const ::rtl::OUString& rProperty ) throw( UnknownPropertyException ) +{ + if( !m_bProxyIsClassModuleObject ) + throw UnknownPropertyException(); + + NAMESPACE_VOS(OGuard) guard( Application::GetSolarMutex() ); + + ::rtl::OUString aPropertyFunctionName( RTL_CONSTASCII_USTRINGPARAM( "Property Get ") ); + aPropertyFunctionName += m_aPrefix; + aPropertyFunctionName += rProperty; + + SbxVariable* p = m_xScopeObj->Find( aPropertyFunctionName, SbxCLASS_METHOD ); + SbMethod* pMeth = p != NULL ? PTR_CAST(SbMethod,p) : NULL; + if( pMeth == NULL ) + { + // TODO: Check vba behavior concernig missing function + //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName ); + throw UnknownPropertyException(); + } + + // Call method + SbxVariableRef xValue = new SbxVariable; + pMeth->Call( xValue ); + Any aRet = sbxToUnoValue( xValue ); + return aRet; +} + +sal_Bool SAL_CALL ModuleInvocationProxy::hasMethod( const ::rtl::OUString& ) throw() +{ + return sal_False; +} + +sal_Bool SAL_CALL ModuleInvocationProxy::hasProperty( const ::rtl::OUString& ) throw() +{ + return sal_False; +} + +Any SAL_CALL ModuleInvocationProxy::invoke( const ::rtl::OUString& rFunction, + const Sequence< Any >& rParams, + Sequence< sal_Int16 >&, + Sequence< Any >& ) + throw( CannotConvertException, InvocationTargetException ) +{ + NAMESPACE_VOS(OGuard) guard( Application::GetSolarMutex() ); + + Any aRet; + if( !m_xScopeObj.Is() ) + return aRet; + + ::rtl::OUString aFunctionName = m_aPrefix; + aFunctionName += rFunction; + + SbxVariable* p = m_xScopeObj->Find( aFunctionName, SbxCLASS_METHOD ); + SbMethod* pMeth = p != NULL ? PTR_CAST(SbMethod,p) : NULL; + if( pMeth == NULL ) + { + // TODO: Check vba behavior concernig missing function + //StarBASIC::Error( SbERR_NO_METHOD, aFunctionName ); + return aRet; + } + + // Setup parameters + SbxArrayRef xArray; + sal_Int32 nParamCount = rParams.getLength(); + if( nParamCount ) + { + xArray = new SbxArray; + const Any *pArgs = rParams.getConstArray(); + for( sal_Int32 i = 0 ; i < nParamCount ; i++ ) + { + SbxVariableRef xVar = new SbxVariable( SbxVARIANT ); + unoToSbxValue( (SbxVariable*)xVar, pArgs[i] ); + xArray->Put( xVar, sal::static_int_cast< USHORT >(i+1) ); + } + } + + // Call method + SbxVariableRef xValue = new SbxVariable; + if( xArray.Is() ) + pMeth->SetParameters( xArray ); + pMeth->Call( xValue ); + aRet = sbxToUnoValue( xValue ); + pMeth->SetParameters( NULL ); + + // TODO: OutParameter? + + return aRet; +} + +Reference< XInterface > createComListener( const Any& aControlAny, const ::rtl::OUString& aVBAType, + const ::rtl::OUString& aPrefix, SbxObjectRef xScopeObj ) +{ + Reference< XInterface > xRet; + + Reference< XComponentContext > xContext = getComponentContext_Impl(); + Reference< XMultiComponentFactory > xServiceMgr( xContext->getServiceManager() ); + + Reference< XInvocation > xProxy = new ModuleInvocationProxy( aPrefix, xScopeObj ); + + Sequence<Any> args( 3 ); + args[0] <<= aControlAny; + args[1] <<= aVBAType; + args[2] <<= xProxy; + + try + { + xRet = xServiceMgr->createInstanceWithArgumentsAndContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.custom.UnoComListener")), + args, xContext ); + } + catch( const Exception& ) + { + implHandleAnyException( ::cppu::getCaughtException() ); + } + + return xRet; +} + +// Handle module implements mechanism for OLE types +bool SbModule::createCOMWrapperForIface( Any& o_rRetAny, SbClassModuleObject* pProxyClassModuleObject ) +{ + // For now: Take first interface that allows to instantiate COM wrapper + // TODO: Check if support for multiple interfaces is needed + + Reference< XComponentContext > xContext = getComponentContext_Impl(); + Reference< XMultiComponentFactory > xServiceMgr( xContext->getServiceManager() ); + Reference< XSingleServiceFactory > xComImplementsFactory + ( + xServiceMgr->createInstanceWithContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.custom.ComImplementsFactory")), xContext ), + UNO_QUERY + ); + if( !xComImplementsFactory.is() ) + return false; + + bool bSuccess = false; + + SbxArray* pModIfaces = pClassData->mxIfaces; + USHORT nCount = pModIfaces->Count(); + for( USHORT i = 0 ; i < nCount ; ++i ) + { + SbxVariable* pVar = pModIfaces->Get( i ); + ::rtl::OUString aIfaceName = pVar->GetName(); + + if( aIfaceName.getLength() != 0 ) + { + ::rtl::OUString aPureIfaceName = aIfaceName; + sal_Int32 indexLastDot = aIfaceName.lastIndexOf('.'); + if ( indexLastDot > -1 ) + aPureIfaceName = aIfaceName.copy( indexLastDot + 1 ); + + Reference< XInvocation > xProxy = new ModuleInvocationProxy( aPureIfaceName, pProxyClassModuleObject ); + + Sequence<Any> args( 2 ); + args[0] <<= aIfaceName; + args[1] <<= xProxy; + + Reference< XInterface > xRet; + bSuccess = false; + try + { + xRet = xComImplementsFactory->createInstanceWithArguments( args ); + bSuccess = true; + } + catch( const Exception& ) + { + implHandleAnyException( ::cppu::getCaughtException() ); + } + + if( bSuccess ) + { + o_rRetAny <<= xRet; + break; + } + } + } + + return bSuccess; +} + diff --git a/basic/source/classes/sbxmod.cxx b/basic/source/classes/sbxmod.cxx index 83c0ae9e65f4..6a00e5b6649b 100644 --- a/basic/source/classes/sbxmod.cxx +++ b/basic/source/classes/sbxmod.cxx @@ -190,6 +190,11 @@ SbModule::SbModule( const String& rName, BOOL bVBACompat ) SetName( rName ); SetFlag( SBX_EXTSEARCH | SBX_GBLSEARCH ); SetModuleType( script::ModuleType::NORMAL ); + + // #i92642: Set name property to intitial name + SbxVariable* pNameProp = pProps->Find( String( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_PROPERTY ); + if( pNameProp != NULL ) + pNameProp->PutString( GetName() ); } SbModule::~SbModule() @@ -366,7 +371,7 @@ SbxVariable* SbModule::Find( const XubString& rName, SbxClassType t ) { // make sure a search in an uninstatiated class module will fail SbxVariable* pRes = SbxObject::Find( rName, t ); - if ( bIsProxyModule ) + if ( bIsProxyModule && !GetSbData()->bRunInit ) return NULL; if( !pRes && pImage ) { @@ -452,7 +457,19 @@ void SbModule::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType, } } else - SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType ); + { + // #i92642: Special handling for name property to avoid + // side effects when using name as variable implicitely + bool bForwardToSbxObject = true; + + ULONG nId = pHint->GetId(); + if( (nId == SBX_HINT_DATAWANTED || nId == SBX_HINT_DATACHANGED) && + pVar->GetName().EqualsIgnoreCaseAscii( "name" ) ) + bForwardToSbxObject = false; + + if( bForwardToSbxObject ) + SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType ); + } } } @@ -646,7 +663,7 @@ void ClearUnoObjectsInRTL_Impl( StarBASIC* pBasic ) if( ((StarBASIC*)p) != pBasic ) ClearUnoObjectsInRTL_Impl_Rek( (StarBASIC*)p ); } -BOOL SbModule::IsVBACompat() +BOOL SbModule::IsVBACompat() const { return mbVBACompat; } @@ -1710,18 +1727,20 @@ public: }; SbUserFormModule::SbUserFormModule( const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsCompat ) - :SbObjModule( rName, mInfo, bIsCompat ), mbInit( false ) + : SbObjModule( rName, mInfo, bIsCompat ) + , m_mInfo( mInfo ) + , mbInit( false ) { - m_xModel.set( mInfo.ModuleObject, uno::UNO_QUERY_THROW ); + m_xModel.set( mInfo.ModuleObject, uno::UNO_QUERY_THROW ); } void SbUserFormModule::ResetApiObj() { - if ( m_xDialog.is() ) // probably someone close the dialog window + if ( m_xDialog.is() ) // probably someone close the dialog window { - triggerTerminateEvent(); - } - pDocObject = NULL; + triggerTerminateEvent(); + } + pDocObject = NULL; m_xDialog = NULL; } @@ -1807,6 +1826,33 @@ void SbUserFormModule::triggerTerminateEvent( void ) mbInit=false; } +SbUserFormModuleInstance* SbUserFormModule::CreateInstance() +{ + SbUserFormModuleInstance* pInstance = new SbUserFormModuleInstance( this, GetName(), m_mInfo, IsVBACompat() ); + return pInstance; +} + +SbUserFormModuleInstance::SbUserFormModuleInstance( SbUserFormModule* pParentModule, + const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsVBACompat ) + : SbUserFormModule( rName, mInfo, bIsVBACompat ) + , m_pParentModule( pParentModule ) +{ +} + +BOOL SbUserFormModuleInstance::IsClass( const XubString& rName ) const +{ + BOOL bParentNameMatches = m_pParentModule->GetName().EqualsIgnoreCaseAscii( rName ); + BOOL bRet = bParentNameMatches || SbxObject::IsClass( rName ); + return bRet; +} + +SbxVariable* SbUserFormModuleInstance::Find( const XubString& rName, SbxClassType t ) +{ + SbxVariable* pVar = m_pParentModule->Find( rName, t ); + return pVar; +} + + void SbUserFormModule::load() { OSL_TRACE("** load() "); diff --git a/basic/source/comp/dim.cxx b/basic/source/comp/dim.cxx index fb4071bcc2a2..bff3d22dd9b0 100644 --- a/basic/source/comp/dim.cxx +++ b/basic/source/comp/dim.cxx @@ -1,4 +1,4 @@ - /************************************************************************* +/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -30,6 +30,8 @@ #include <basic/sbx.hxx> #include "sbcomp.hxx" +SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj ); + // Deklaration einer Variablen // Bei Fehlern wird bis zum Komma oder Newline geparst. // Returnwert: eine neue Instanz, die eingefuegt und dann geloescht wird. @@ -37,6 +39,12 @@ SbiSymDef* SbiParser::VarDecl( SbiDimList** ppDim, BOOL bStatic, BOOL bConst ) { + bool bWithEvents = false; + if( Peek() == WITHEVENTS ) + { + Next(); + bWithEvents = true; + } if( !TestSymbol() ) return NULL; SbxDataType t = eScanType; SbiSymDef* pDef = bConst ? new SbiConstDef( aSym ) : new SbiSymDef( aSym ); @@ -47,6 +55,8 @@ SbiSymDef* SbiParser::VarDecl( SbiDimList** ppDim, BOOL bStatic, BOOL bConst ) pDef->SetType( t ); if( bStatic ) pDef->SetStatic(); + if( bWithEvents ) + pDef->SetWithEvents(); TypeDecl( *pDef ); if( !ppDim && pDim ) { @@ -107,8 +117,10 @@ void SbiParser::TypeDecl( SbiSymDef& rDef, BOOL bAsNewAlreadyParsed ) Next(); SbiConstExpression aSize( this ); nSize = aSize.GetShortValue(); - if( nSize < 0 ) + if( nSize < 0 || (bVBASupportOn && nSize <= 0) ) Error( SbERR_OUT_OF_RANGE ); + else + rDef.SetFixedStringLength( nSize ); } } break; @@ -209,7 +221,7 @@ void SbiParser::DefVar( SbiOpcode eOp, BOOL bStatic ) // #110004 It can also be a sub/function if( !bConst && (eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY || - eCurTok == STATIC || eCurTok == ENUM || eCurTok == DECLARE) ) + eCurTok == STATIC || eCurTok == ENUM || eCurTok == DECLARE || eCurTok == TYPE) ) { // Next token is read here, because !bConst bool bPrivate = ( eFirstTok == PRIVATE ); @@ -244,6 +256,13 @@ void SbiParser::DefVar( SbiOpcode eOp, BOOL bStatic ) DefDeclare( bPrivate ); return; } + // #i109049 + else if( eCurTok == TYPE ) + { + Next(); + DefType( bPrivate ); + return; + } } #ifdef SHARED @@ -349,9 +368,15 @@ void SbiParser::DefVar( SbiOpcode eOp, BOOL bStatic ) break; default: eOp2 = _LOCAL; } - aGen.Gen( - eOp2, pDef->GetId(), - sal::static_int_cast< UINT16 >( pDef->GetType() ) ); + UINT32 nOpnd2 = sal::static_int_cast< UINT16 >( pDef->GetType() ); + if( pDef->IsWithEvents() ) + nOpnd2 |= SBX_TYPE_WITH_EVENTS_FLAG; + + short nFixedStringLength = pDef->GetFixedStringLength(); + if( nFixedStringLength >= 0 ) + nOpnd2 |= (SBX_FIXED_LEN_STRING_FLAG + (UINT32(nFixedStringLength) << 17)); // len = all bits above 0x10000 + + aGen.Gen( eOp2, pDef->GetId(), nOpnd2 ); } // Initialisierung fuer selbstdefinierte Datentypen @@ -473,7 +498,7 @@ void SbiParser::DefVar( SbiOpcode eOp, BOOL bStatic ) // d.h. pPool muss immer am Schleifen-Ende zurueckgesetzt werden. // auch bei break pPool = pOldPool; - continue; // MyBreak überspingen + continue; // MyBreak berspingen MyBreak: pPool = pOldPool; break; @@ -506,18 +531,7 @@ void SbiParser::Erase() { while( !bAbort ) { - if( !TestSymbol() ) return; - String aName( aSym ); - SbxDataType eType = eScanType; - SbiSymDef* pDef = pPool->Find( aName ); - if( !pDef ) - { - if( bExplicit ) - Error( SbERR_UNDEF_VAR, aName ); - pDef = pPool->AddSym( aName ); - pDef->SetType( eType ); - } - SbiExpression aExpr( this, *pDef ); + SbiExpression aExpr( this, SbLVALUE ); aExpr.Gen(); aGen.Gen( _ERASE ); if( !TestComma() ) break; @@ -576,12 +590,14 @@ void SbiParser::DefType( BOOL bPrivate ) } if( pElem ) { - SbxArray *pTypeMembers = pType -> GetProperties(); - if (pTypeMembers -> Find (pElem->GetName(),SbxCLASS_DONTCARE)) + SbxArray *pTypeMembers = pType->GetProperties(); + String aElemName = pElem->GetName(); + if( pTypeMembers->Find( aElemName, SbxCLASS_DONTCARE) ) Error (SbERR_VAR_DEFINED); else { - SbxProperty *pTypeElem = new SbxProperty (pElem->GetName(),pElem->GetType()); + SbxDataType eElemType = pElem->GetType(); + SbxProperty *pTypeElem = new SbxProperty( aElemName, eElemType ); if( pDim ) { SbxDimArray* pArray = new SbxDimArray( pElem->GetType() ); @@ -618,6 +634,21 @@ void SbiParser::DefType( BOOL bPrivate ) pTypeElem->PutObject( pArray ); pTypeElem->SetFlags( nSavFlags ); } + // Nested user type? + if( eElemType == SbxOBJECT ) + { + USHORT nElemTypeId = pElem->GetTypeId(); + if( nElemTypeId != 0 ) + { + String aTypeName( aGblStrings.Find( nElemTypeId ) ); + SbxObject* pTypeObj = static_cast< SbxObject* >( rTypeArray->Find( aTypeName, SbxCLASS_OBJECT ) ); + if( pTypeObj != NULL ) + { + SbxObject* pCloneObj = cloneTypeObjectImpl( *pTypeObj ); + pTypeElem->PutObject( pCloneObj ); + } + } + } delete pDim; pTypeMembers->Insert( pTypeElem, pTypeMembers->Count() ); } diff --git a/basic/source/comp/exprgen.cxx b/basic/source/comp/exprgen.cxx index 89520832ff67..60869307aecf 100644 --- a/basic/source/comp/exprgen.cxx +++ b/basic/source/comp/exprgen.cxx @@ -148,6 +148,10 @@ void SbiExprNode::Gen( RecursiveMode eRecMode ) pLeft->Gen(); pGen->Gen( _TESTCLASS, nTypeStrId ); } + else if( IsNew() ) + { + pGen->Gen( _CREATE, 0, nTypeStrId ); + } else { pLeft->Gen(); @@ -285,6 +289,8 @@ void SbiExpression::Gen( RecursiveMode eRecMode ) // AB: 17.12.1995, Spezialbehandlung fuer WITH // Wenn pExpr == .-Ausdruck in With, zunaechst Gen fuer Basis-Objekt pExpr->Gen( eRecMode ); + if( bByVal ) + pParser->aGen.Gen( _BYVAL ); if( bBased ) { USHORT uBase = pParser->nBase; diff --git a/basic/source/comp/exprnode.cxx b/basic/source/comp/exprnode.cxx index a77cf32abbaa..d47c86f86ea8 100644 --- a/basic/source/comp/exprnode.cxx +++ b/basic/source/comp/exprnode.cxx @@ -100,6 +100,15 @@ SbiExprNode::SbiExprNode( SbiParser* p, SbiExprNode* l, USHORT nId ) nTypeStrId = nId; } +// new <type> +SbiExprNode::SbiExprNode( SbiParser* p, USHORT nId ) +{ + BaseInit( p ); + + eType = SbxOBJECT; + eNodeType = SbxNEW; + nTypeStrId = nId; +} // AB: 17.12.95, Hilfsfunktion fuer Ctor fuer einheitliche Initialisierung void SbiExprNode::BaseInit( SbiParser* p ) @@ -253,7 +262,8 @@ void SbiExprNode::CollectBits() void SbiExprNode::FoldConstants() { if( IsOperand() || eTok == LIKE ) return; - pLeft->FoldConstants(); + if( pLeft ) + pLeft->FoldConstants(); if( pRight ) { pRight->FoldConstants(); @@ -431,7 +441,7 @@ void SbiExprNode::FoldConstants() } } } - else if( pLeft->IsNumber() ) + else if( pLeft && pLeft->IsNumber() ) { nVal = pLeft->nVal; delete pLeft; diff --git a/basic/source/comp/exprtree.cxx b/basic/source/comp/exprtree.cxx index 2f5c0b967a2e..0cf0d9870378 100644 --- a/basic/source/comp/exprtree.cxx +++ b/basic/source/comp/exprtree.cxx @@ -38,7 +38,8 @@ |* ***************************************************************************/ -SbiExpression::SbiExpression( SbiParser* p, SbiExprType t, SbiExprMode eMode ) +SbiExpression::SbiExpression( SbiParser* p, SbiExprType t, + SbiExprMode eMode, const KeywordSymbolInfo* pKeywordSymbolInfo ) { pParser = p; bError = bByVal = bBased = bBracket = FALSE; @@ -46,7 +47,7 @@ SbiExpression::SbiExpression( SbiParser* p, SbiExprType t, SbiExprMode eMode ) eCurExpr = t; m_eMode = eMode; pNext = NULL; - pExpr = (t != SbSTDEXPR ) ? Term() : Boolean(); + pExpr = (t != SbSTDEXPR ) ? Term( pKeywordSymbolInfo ) : Boolean(); if( t != SbSYMBOL ) pExpr->Optimize(); if( t == SbLVALUE && !pExpr->IsLvalue() ) @@ -114,7 +115,7 @@ static BOOL DoParametersFollow( SbiParser* p, SbiExprType eCurExpr, SbiToken eTo if( !p->WhiteSpace() || eCurExpr != SbSYMBOL ) return FALSE; if ( eTok == NUMBER || eTok == MINUS || eTok == FIXSTRING - || eTok == SYMBOL || eTok == COMMA || eTok == DOT || eTok == NOT ) + || eTok == SYMBOL || eTok == COMMA || eTok == DOT || eTok == NOT || eTok == BYVAL ) { return TRUE; } @@ -177,7 +178,7 @@ static SbiSymDef* AddSym // Zur Zeit sind sogar Keywords zugelassen (wg. gleichnamiger Dflt-Properties) -SbiExprNode* SbiExpression::Term( void ) +SbiExprNode* SbiExpression::Term( const KeywordSymbolInfo* pKeywordSymbolInfo ) { if( pParser->Peek() == DOT ) { @@ -204,11 +205,11 @@ SbiExprNode* SbiExpression::Term( void ) return pNd; } - SbiToken eTok = pParser->Next(); + SbiToken eTok = (pKeywordSymbolInfo == NULL) ? pParser->Next() : pKeywordSymbolInfo->m_eTok; // Anfang des Parsings merken pParser->LockColumn(); - String aSym( pParser->GetSym() ); - SbxDataType eType = pParser->GetType(); + String aSym( (pKeywordSymbolInfo == NULL) ? pParser->GetSym() : pKeywordSymbolInfo->m_aKeywordSymbol ); + SbxDataType eType = (pKeywordSymbolInfo == NULL) ? pParser->GetType() : pKeywordSymbolInfo->m_eSbxDataType; SbiParameters* pPar = NULL; SbiExprListVector* pvMoreParLcl = NULL; // Folgen Parameter? @@ -280,6 +281,12 @@ SbiExprNode* SbiExpression::Term( void ) // AB 31.3.1996: In Parser-Methode ausgelagert // (wird auch in SbiParser::DefVar() in DIM.CXX benoetigt) pDef = pParser->CheckRTLForSym( aSym, eType ); + + // #i109184: Check if symbol is or later will be defined inside module + SbModule& rMod = pParser->aGen.GetModule(); + SbxArray* pModMethods = rMod.GetMethods(); + if( pModMethods->Find( aSym, SbxCLASS_DONTCARE ) ) + pDef = NULL; } if( !pDef ) { @@ -417,13 +424,27 @@ SbiExprNode* SbiExpression::ObjTerm( SbiSymDef& rObj ) String aSym( pParser->GetSym() ); SbxDataType eType = pParser->GetType(); SbiParameters* pPar = NULL; + SbiExprListVector* pvMoreParLcl = NULL; eTok = pParser->Peek(); // Parameter? if( DoParametersFollow( pParser, eCurExpr, eTok ) ) { - pPar = new SbiParameters( pParser ); + bool bStandaloneExpression = false; + pPar = new SbiParameters( pParser, bStandaloneExpression ); bError |= !pPar->IsValid(); eTok = pParser->Peek(); + + // i109624 check for additional sets of parameters + while( eTok == LPAREN ) + { + if( pvMoreParLcl == NULL ) + pvMoreParLcl = new SbiExprListVector(); + SbiParameters* pAddPar = new SbiParameters( pParser ); + pvMoreParLcl->push_back( pAddPar ); + bError |= !pPar->IsValid(); + eTok = pParser->Peek(); + } + } BOOL bObj = BOOL( ( eTok == DOT || eTok == EXCLAM ) && !pParser->WhiteSpace() ); if( bObj ) @@ -450,6 +471,7 @@ SbiExprNode* SbiExpression::ObjTerm( SbiSymDef& rObj ) SbiExprNode* pNd = new SbiExprNode( pParser, *pDef, eType ); pNd->aVar.pPar = pPar; + pNd->aVar.pvMorePar = pvMoreParLcl; if( bObj ) { // Falls wir etwas mit Punkt einscannen, muss der @@ -483,7 +505,7 @@ SbiExprNode* SbiExpression::ObjTerm( SbiSymDef& rObj ) // Funktionen // geklammerte Ausdruecke -SbiExprNode* SbiExpression::Operand() +SbiExprNode* SbiExpression::Operand( bool bUsedForTypeOf ) { SbiExprNode *pRes; SbiToken eTok; @@ -494,7 +516,7 @@ SbiExprNode* SbiExpression::Operand() case SYMBOL: pRes = Term(); // process something like "IF Not r Is Nothing Then .." - if( pParser->IsVBASupportOn() && pParser->Peek() == IS ) + if( !bUsedForTypeOf && pParser->IsVBASupportOn() && pParser->Peek() == IS ) { eTok = pParser->Next(); pRes = new SbiExprNode( pParser, pRes, eTok, Like() ); @@ -576,7 +598,8 @@ SbiExprNode* SbiExpression::Unary() case TYPEOF: { pParser->Next(); - SbiExprNode* pObjNode = Operand(); + bool bUsedForTypeOf = true; + SbiExprNode* pObjNode = Operand( bUsedForTypeOf ); pParser->TestToken( IS ); String aDummy; SbiSymDef* pTypeDef = new SbiSymDef( aDummy ); @@ -584,6 +607,15 @@ SbiExprNode* SbiExpression::Unary() pNd = new SbiExprNode( pParser, pObjNode, pTypeDef->GetTypeId() ); break; } + case NEW: + { + pParser->Next(); + String aStr; + SbiSymDef* pTypeDef = new SbiSymDef( aStr ); + pParser->TypeDecl( *pTypeDef, TRUE ); + pNd = new SbiExprNode( pParser, pTypeDef->GetTypeId() ); + break; + } default: pNd = Operand(); } @@ -938,6 +970,14 @@ SbiParameters::SbiParameters( SbiParser* p, BOOL bStandaloneExpression, BOOL bPa // Benannte Argumente: entweder .name= oder name:= else { + bool bByVal = false; + if( eTok == BYVAL ) + { + bByVal = true; + pParser->Next(); + eTok = pParser->Peek(); + } + if( bAssumeExprLParenMode ) { pExpr = new SbiExpression( pParser, SbSTDEXPR, EXPRMODE_LPAREN_PENDING ); @@ -961,12 +1001,22 @@ SbiParameters::SbiParameters( SbiParser* p, BOOL bStandaloneExpression, BOOL bPa { bBracket = TRUE; delete pExpr; + if( bByVal ) + pParser->Error( SbERR_LVALUE_EXPECTED ); return; } } else pExpr = new SbiExpression( pParser ); + if( bByVal ) + { + if( !pExpr->IsLvalue() ) + pParser->Error( SbERR_LVALUE_EXPECTED ); + else + pExpr->SetByVal(); + } + //pExpr = bConst ? new SbiConstExpression( pParser ) // : new SbiExpression( pParser ); if( !bAssumeArrayMode ) diff --git a/basic/source/comp/io.cxx b/basic/source/comp/io.cxx index 1ed551994c92..b211ea0b7b08 100644 --- a/basic/source/comp/io.cxx +++ b/basic/source/comp/io.cxx @@ -115,6 +115,30 @@ void SbiParser::Write() aGen.Gen( _CHAN0 ); } + +// #i92642 Handle LINE keyword outside ::Next() +void SbiParser::Line() +{ + // #i92642: Special handling to allow name as symbol + if( Peek() == INPUT ) + { + Next(); + LineInput(); + } + else + { + aGen.Statement(); + + KeywordSymbolInfo aInfo; + aInfo.m_aKeywordSymbol = String( RTL_CONSTASCII_USTRINGPARAM( "line" ) ); + aInfo.m_eSbxDataType = GetType(); + aInfo.m_eTok = SYMBOL; + + Symbol( &aInfo ); + } +} + + // LINE INPUT [prompt], var$ void SbiParser::LineInput() @@ -288,6 +312,19 @@ void SbiParser::Open() void SbiParser::Name() { + // #i92642: Special handling to allow name as symbol + if( Peek() == EQ ) + { + aGen.Statement(); + + KeywordSymbolInfo aInfo; + aInfo.m_aKeywordSymbol = String( RTL_CONSTASCII_USTRINGPARAM( "name" ) ); + aInfo.m_eSbxDataType = GetType(); + aInfo.m_eTok = SYMBOL; + + Symbol( &aInfo ); + return; + } SbiExpression aExpr1( this ); TestToken( AS ); SbiExpression aExpr2( this ); diff --git a/basic/source/comp/parser.cxx b/basic/source/comp/parser.cxx index 8770dc8539f0..3d7178ae7688 100644 --- a/basic/source/comp/parser.cxx +++ b/basic/source/comp/parser.cxx @@ -83,6 +83,7 @@ static SbiStatement StmntTable [] = { { IMPLEMENTS, &SbiParser::Implements, Y, N, }, // IMPLEMENTS { INPUT, &SbiParser::Input, N, Y, }, // INPUT { LET, &SbiParser::Assign, N, Y, }, // LET +{ LINE, &SbiParser::Line, N, Y, }, // LINE, -> LINE INPUT (#i92642) { LINEINPUT,&SbiParser::LineInput, N, Y, }, // LINE INPUT { LOOP, &SbiParser::BadBlock, N, Y, }, // LOOP { LSET, &SbiParser::LSet, N, Y, }, // LSET @@ -237,7 +238,9 @@ void SbiParser::Exit() SbiToken eTok = Next(); for( SbiParseStack* p = pStack; p; p = p->pNext ) { - if( eTok == p->eExitTok ) + SbiToken eExitTok = p->eExitTok; + if( eTok == eExitTok || + (eTok == PROPERTY && (eExitTok == GET || eExitTok == LET) ) ) // #i109051 { p->nChain = aGen.Gen( _JUMP, p->nChain ); return; @@ -367,7 +370,10 @@ BOOL SbiParser::Parse() } // Ende des Parsings? - if( eCurTok == eEndTok ) + if( eCurTok == eEndTok || + ( bVBASupportOn && // #i109075 + (eCurTok == ENDFUNC || eCurTok == ENDPROPERTY || eCurTok == ENDSUB) && + (eEndTok == ENDFUNC || eEndTok == ENDPROPERTY || eEndTok == ENDSUB) ) ) { Next(); if( eCurTok != NIL ) @@ -477,10 +483,10 @@ SbiExprNode* SbiParser::GetWithVar() // Zuweisung oder Subroutine Call -void SbiParser::Symbol() +void SbiParser::Symbol( const KeywordSymbolInfo* pKeywordSymbolInfo ) { SbiExprMode eMode = bVBASupportOn ? EXPRMODE_STANDALONE : EXPRMODE_STANDARD; - SbiExpression aVar( this, SbSYMBOL, eMode ); + SbiExpression aVar( this, SbSYMBOL, eMode, pKeywordSymbolInfo ); bool bEQ = ( Peek() == EQ ); if( !bEQ && bVBASupportOn && aVar.IsBracket() ) @@ -704,11 +710,37 @@ void SbiParser::Implements() return; } - if( TestSymbol() ) + Peek(); + if( eCurTok != SYMBOL ) + { + Error( SbERR_SYMBOL_EXPECTED ); + return; + } + + String aImplementedIface = aSym; + Next(); + if( Peek() == DOT ) { - String aImplementedIface = GetSym(); - aIfaceVector.push_back( aImplementedIface ); + String aDotStr( '.' ); + while( Peek() == DOT ) + { + aImplementedIface += aDotStr; + Next(); + SbiToken ePeekTok = Peek(); + if( ePeekTok == SYMBOL || IsKwd( ePeekTok ) ) + { + Next(); + aImplementedIface += aSym; + } + else + { + Next(); + Error( SbERR_SYMBOL_EXPECTED ); + break; + } + } } + aIfaceVector.push_back( aImplementedIface ); } void SbiParser::EnableCompatibility() @@ -745,12 +777,16 @@ void SbiParser::Option() break; } case COMPARE: - switch( Next() ) - { - case TEXT: bText = TRUE; return; - case BINARY: bText = FALSE; return; - default:; - } // Fall thru! + { + SbiToken eTok = Next(); + if( eTok == BINARY ) + bText = FALSE; + else if( eTok == SYMBOL && GetSym().EqualsIgnoreCaseAscii("text") ) + bText = TRUE; + else + Error( SbERR_EXPECTED, "Text/Binary" ); + break; + } case COMPATIBLE: EnableCompatibility(); break; diff --git a/basic/source/comp/symtbl.cxx b/basic/source/comp/symtbl.cxx index 24f0f890eebb..d6b3dbb878fc 100644 --- a/basic/source/comp/symtbl.cxx +++ b/basic/source/comp/symtbl.cxx @@ -300,12 +300,14 @@ SbiSymDef::SbiSymDef( const String& rName ) : aName( rName ) bStatic = bOpt = bParamArray = + bWithEvents = bByVal = bChained = bGlobal = FALSE; pIn = pPool = NULL; nDefaultId = 0; + nFixedStringLength = -1; } SbiSymDef::~SbiSymDef() diff --git a/basic/source/comp/token.cxx b/basic/source/comp/token.cxx index 9fdfef0490b1..8cb3126f03f1 100644 --- a/basic/source/comp/token.cxx +++ b/basic/source/comp/token.cxx @@ -185,6 +185,7 @@ static TokenTable aTokTable_Basic [] = { // Token-Tabelle: { WEND, "Wend" }, { WHILE, "While" }, { WITH, "With" }, + { WITHEVENTS, "WithEvents" }, { WRITE, "Write" }, // auch WRITE # { XOR, "Xor" }, { NIL, "" } @@ -353,6 +354,29 @@ TokenTable aTokTable_Java [] = { // Token-Tabelle: }; */ +// #i109076 +TokenLabelInfo::TokenLabelInfo( void ) +{ + m_pTokenCanBeLabelTab = new bool[VBASUPPORT+1]; + for( int i = 0 ; i <= VBASUPPORT ; ++i ) + m_pTokenCanBeLabelTab[i] = false; + + // Token accepted as label by VBA + SbiToken eLabelToken[] = { ACCESS, ALIAS, APPEND, BASE, BINARY, CLASSMODULE, + COMPARE, COMPATIBLE, DEFERR, _ERROR_, EXPLICIT, LIB, LINE, LPRINT, NAME, + TOBJECT, OUTPUT, PROPERTY, RANDOM, READ, STEP, STOP, TEXT, VBASUPPORT, NIL }; + SbiToken* pTok = eLabelToken; + SbiToken eTok; + for( pTok = eLabelToken ; (eTok = *pTok) != NIL ; ++pTok ) + m_pTokenCanBeLabelTab[eTok] = true; +} + +TokenLabelInfo::~TokenLabelInfo() +{ + delete[] m_pTokenCanBeLabelTab; +} + + // Der Konstruktor ermittelt die Laenge der Token-Tabelle. SbiTokenizer::SbiTokenizer( const ::rtl::OUString& rSrc, StarBASIC* pb ) @@ -371,7 +395,8 @@ SbiTokenizer::SbiTokenizer( const ::rtl::OUString& rSrc, StarBASIC* pb ) } SbiTokenizer::~SbiTokenizer() -{} +{ +} // Wiederablage (Pushback) eines Tokens. (Bis zu 2 Tokens) @@ -513,7 +538,8 @@ SbiToken SbiTokenizer::Next() tp = &pTokTable[ lb + delta ]; StringCompare res = aSym.CompareIgnoreCaseToAscii( tp->s ); // Gefunden? - if( res == COMPARE_EQUAL ) goto special; + if( res == COMPARE_EQUAL ) + goto special; // Groesser? Dann untere Haelfte if( res == COMPARE_LESS ) { @@ -534,24 +560,14 @@ SbiToken SbiTokenizer::Next() return eCurTok = SYMBOL; } special: - // LINE INPUT - if( tp->t == LINE ) - { - short nC1 = nCol1; - String aOldSym = aSym; - eCurTok = Peek(); - if( eCurTok == INPUT ) - { - Next(); - nCol1 = nC1; - return eCurTok = LINEINPUT; - } - else - { - aSym = aOldSym; - return eCurTok = LINE; - } - } + // #i92642 + if( eCurTok != NIL && eCurTok != REM && eCurTok != EOLN && (tp->t == NAME || tp->t == LINE) ) + return eCurTok = SYMBOL; + else if( tp->t == TEXT ) + return eCurTok = SYMBOL; + + // #i92642: Special LINE token handling -> SbiParser::Line() + // END IF, CASE, SUB, DEF, FUNCTION, TYPE, CLASS, WITH if( tp->t == END ) { @@ -639,7 +655,7 @@ special: BOOL SbiTokenizer::MayBeLabel( BOOL bNeedsColon ) { - if( eCurTok == SYMBOL ) + if( eCurTok == SYMBOL || m_aTokenLabelInfo.canTokenBeLabel( eCurTok ) ) return bNeedsColon ? DoesColonFollow() : TRUE; else return BOOL( eCurTok == NUMBER diff --git a/basic/source/inc/codegen.hxx b/basic/source/inc/codegen.hxx index 3d90d16bdcbe..a3fe02227cfd 100644 --- a/basic/source/inc/codegen.hxx +++ b/basic/source/inc/codegen.hxx @@ -44,6 +44,7 @@ class SbiCodeGen { // Code-Erzeugung: public: SbiCodeGen( SbModule&, SbiParser*, short ); SbiParser* GetParser() { return pParser; } + SbModule& GetModule() { return rMod; } UINT32 Gen( SbiOpcode ); UINT32 Gen( SbiOpcode, UINT32 ); UINT32 Gen( SbiOpcode, UINT32, UINT32 ); @@ -53,7 +54,6 @@ public: void GenStmnt(); // evtl. Statement-Opcode erzeugen UINT32 GetPC(); UINT32 GetOffset() { return GetPC() + 1; } - SbModule& GetModule() { return rMod; } void Save(); // #29955 for-Schleifen-Ebene pflegen diff --git a/basic/source/inc/dlgcont.hxx b/basic/source/inc/dlgcont.hxx index b0b3334b5031..2c927a8286f4 100644 --- a/basic/source/inc/dlgcont.hxx +++ b/basic/source/inc/dlgcont.hxx @@ -54,14 +54,17 @@ class SfxDialogLibraryContainer : public SfxLibraryContainer virtual bool SAL_CALL isLibraryElementValid( ::com::sun::star::uno::Any aElement ) const; virtual void SAL_CALL writeLibraryElement ( - ::com::sun::star::uno::Any aElement, + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer>& xLibrary, const ::rtl::OUString& aElementName, - ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xOutput + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutput ) throw(::com::sun::star::uno::Exception); virtual ::com::sun::star::uno::Any SAL_CALL importLibraryElement - ( const ::rtl::OUString& aFile, + ( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer>& xLibrary, + const ::rtl::OUString& aElementName, + const ::rtl::OUString& aFile, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xElementStream ); virtual void SAL_CALL importFromOldStorage( const ::rtl::OUString& aFile ); diff --git a/basic/source/inc/expr.hxx b/basic/source/inc/expr.hxx index 8ccbcebe4309..9b8f51d09dea 100644 --- a/basic/source/inc/expr.hxx +++ b/basic/source/inc/expr.hxx @@ -52,6 +52,13 @@ struct SbVar { // Variablen-Element: SbiExprListVector* pvMorePar; // Array of arrays foo(pPar)(avMorePar[0])(avMorePar[1])... }; +struct KeywordSymbolInfo +{ + String m_aKeywordSymbol; + SbxDataType m_eSbxDataType; + SbiToken m_eTok; +}; + enum SbiExprType { // Expression-Typen: SbSTDEXPR, // normaler Ausdruck SbLVALUE, // beliebiger lValue @@ -76,6 +83,7 @@ enum SbiNodeType { SbxVARVAL, // aVar = Wert SbxTYPEOF, // TypeOf ObjExpr Is Type SbxNODE, // Node + SbxNEW, // new <type> expression SbxDUMMY }; @@ -107,9 +115,11 @@ class SbiExprNode { // Operatoren (und Operanden) void FoldConstants(); // Constant Folding durchfuehren void CollectBits(); // Umwandeln von Zahlen in Strings BOOL IsOperand() // TRUE, wenn Operand - { return BOOL( eNodeType != SbxNODE && eNodeType != SbxTYPEOF ); } + { return BOOL( eNodeType != SbxNODE && eNodeType != SbxTYPEOF && eNodeType != SbxNEW ); } BOOL IsTypeOf() { return BOOL( eNodeType == SbxTYPEOF ); } + BOOL IsNew() + { return BOOL( eNodeType == SbxNEW ); } BOOL IsNumber(); // TRUE bei Zahlen BOOL IsString(); // TRUE bei Strings BOOL IsLvalue(); // TRUE, falls als Lvalue verwendbar @@ -122,6 +132,7 @@ public: SbiExprNode( SbiParser*, const SbiSymDef&, SbxDataType, SbiExprList* = NULL ); SbiExprNode( SbiParser*, SbiExprNode*, SbiToken, SbiExprNode* ); SbiExprNode( SbiParser*, SbiExprNode*, USHORT ); // #120061 TypeOf + SbiExprNode( SbiParser*, USHORT ); // new <type> virtual ~SbiExprNode(); BOOL IsValid() { return BOOL( !bError ); } @@ -166,9 +177,9 @@ protected: BOOL bByVal; // TRUE: ByVal-Parameter BOOL bBracket; // TRUE: Parameter list with brackets USHORT nParenLevel; - SbiExprNode* Term(); + SbiExprNode* Term( const KeywordSymbolInfo* pKeywordSymbolInfo = NULL ); SbiExprNode* ObjTerm( SbiSymDef& ); - SbiExprNode* Operand(); + SbiExprNode* Operand( bool bUsedForTypeOf = false ); SbiExprNode* Unary(); SbiExprNode* Exp(); SbiExprNode* MulDiv(); @@ -180,7 +191,8 @@ protected: SbiExprNode* Comp(); SbiExprNode* Boolean(); public: - SbiExpression( SbiParser*, SbiExprType = SbSTDEXPR, SbiExprMode eMode = EXPRMODE_STANDARD ); // Parsender Ctor + SbiExpression( SbiParser*, SbiExprType = SbSTDEXPR, + SbiExprMode eMode = EXPRMODE_STANDARD, const KeywordSymbolInfo* pKeywordSymbolInfo = NULL ); // Parsender Ctor SbiExpression( SbiParser*, const String& ); SbiExpression( SbiParser*, double, SbxDataType = SbxDOUBLE ); SbiExpression( SbiParser*, const SbiSymDef&, SbiExprList* = NULL ); diff --git a/basic/source/inc/namecont.hxx b/basic/source/inc/namecont.hxx index 1f4084db1d0d..4df1c48557d2 100644 --- a/basic/source/inc/namecont.hxx +++ b/basic/source/inc/namecont.hxx @@ -284,14 +284,17 @@ protected: virtual bool SAL_CALL isLibraryElementValid( ::com::sun::star::uno::Any aElement ) const = 0; virtual void SAL_CALL writeLibraryElement ( - ::com::sun::star::uno::Any aElement, + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer>& xLibrary, const ::rtl::OUString& aElementName, - ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xOutput + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutput ) throw(::com::sun::star::uno::Exception) = 0; virtual ::com::sun::star::uno::Any SAL_CALL importLibraryElement - ( const ::rtl::OUString& aFile, + ( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer>& xLibrary, + const ::rtl::OUString& aElementName, + const ::rtl::OUString& aFile, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xElementStream ) = 0; virtual void SAL_CALL importFromOldStorage( const ::rtl::OUString& aFile ) = 0; diff --git a/basic/source/inc/opcodes.hxx b/basic/source/inc/opcodes.hxx index 9d909c03c436..ff7eff027f83 100644 --- a/basic/source/inc/opcodes.hxx +++ b/basic/source/inc/opcodes.hxx @@ -93,6 +93,7 @@ enum SbiOpcode { _VBASET, // VBA-like Set _ERASE_CLEAR, // Erase array and clear variable _ARRAYACCESS, // Assign parameters to TOS and get value, used for array of arrays + _BYVAL, // byref -> byval for lvalue parameter passed in call SbOP0_END, // Alle Opcodes mit einem Operanden diff --git a/basic/source/inc/parser.hxx b/basic/source/inc/parser.hxx index 3dc8525377a2..1161c4ed259d 100644 --- a/basic/source/inc/parser.hxx +++ b/basic/source/inc/parser.hxx @@ -99,7 +99,7 @@ public: BOOL TestComma(); // Komma oder EOLN? void TestEoln(); // EOLN? - void Symbol(); // Let oder Call + void Symbol( const KeywordSymbolInfo* pKeywordSymbolInfo = NULL ); // Let oder Call void ErrorStmnt(); // ERROR n void NotImp(); // nicht implementiert void BadBlock(); // LOOP/WEND/NEXT @@ -119,6 +119,7 @@ public: void If(); // IF void Implements(); // IMPLEMENTS void Input(); // INPUT, INPUT # + void Line(); // LINE -> LINE INPUT [#] (#i92642) void LineInput(); // LINE INPUT, LINE INPUT # void LSet(); // LSET void Name(); // NAME .. AS .. diff --git a/basic/source/inc/runtime.hxx b/basic/source/inc/runtime.hxx index c9a41110ad46..6ca69209a752 100644 --- a/basic/source/inc/runtime.hxx +++ b/basic/source/inc/runtime.hxx @@ -407,7 +407,7 @@ class SbiRuntime void StepPRINTF(), StepWRITE(), StepRENAME(), StepPROMPT(); void StepRESTART(), StepEMPTY(), StepLEAVE(); void StepLSET(), StepRSET(), StepREDIMP_ERASE(), StepERASE_CLEAR(); - void StepARRAYACCESS(); + void StepARRAYACCESS(), StepBYVAL(); // Alle Opcodes mit einem Operanden void StepLOADNC( UINT32 ), StepLOADSC( UINT32 ), StepLOADI( UINT32 ); void StepARGN( UINT32 ), StepBASED( UINT32 ), StepPAD( UINT32 ); @@ -416,7 +416,7 @@ class SbiRuntime void StepGOSUB( UINT32 ), StepRETURN( UINT32 ); void StepTESTFOR( UINT32 ), StepCASETO( UINT32 ), StepERRHDL( UINT32 ); void StepRESUME( UINT32 ), StepSETCLASS( UINT32 ), StepVBASETCLASS( UINT32 ), StepTESTCLASS( UINT32 ), StepLIB( UINT32 ); - bool checkClass_Impl( const SbxVariableRef& refVal, const String& aClass, bool bRaiseErrors ); + bool checkClass_Impl( const SbxVariableRef& refVal, const String& aClass, bool bRaiseErrors, bool bDefault = true ); void StepCLOSE( UINT32 ), StepPRCHAR( UINT32 ), StepARGTYP( UINT32 ); // Alle Opcodes mit zwei Operanden void StepRTL( UINT32, UINT32 ), StepPUBLIC( UINT32, UINT32 ), StepPUBLIC_P( UINT32, UINT32 ); @@ -434,6 +434,7 @@ class SbiRuntime void StepDCREATE_REDIMP(UINT32,UINT32), StepDCREATE_IMPL(UINT32,UINT32); void StepFIND_CM( UINT32, UINT32 ); void StepFIND_STATIC( UINT32, UINT32 ); + void implCreateFixedString( SbxVariable* pStrVar, UINT32 nOp2 ); public: void SetVBAEnabled( bool bEnabled ); USHORT GetImageFlag( USHORT n ) const; diff --git a/basic/source/inc/sbintern.hxx b/basic/source/inc/sbintern.hxx index 5896db78ea40..59cfe21d25a8 100644 --- a/basic/source/inc/sbintern.hxx +++ b/basic/source/inc/sbintern.hxx @@ -39,6 +39,7 @@ namespace utl class SbUnoFactory; class SbTypeFactory; class SbOLEFactory; +class SbFormFactory; class SbiInstance; class SbModule; @@ -101,6 +102,7 @@ struct SbiGlobals SbTypeFactory* pTypeFac; // Factory for user defined types SbClassFactory* pClassFac; // Factory for user defined classes (based on class modules) SbOLEFactory* pOLEFac; // Factory for OLE types + SbFormFactory* pFormFac; // Factory for user forms SbModule* pMod; // aktuell aktives Modul SbModule* pCompMod; // aktuell compiliertes Modul short nInst; // Anzahl BASICs @@ -136,6 +138,7 @@ SbiGlobals* GetSbData(); #define pTYPEFAC GetSbData()->pTypeFac #define pCLASSFAC GetSbData()->pClassFac #define pOLEFAC GetSbData()->pOLEFac +#define pFORMFAC GetSbData()->pFormFac #endif diff --git a/basic/source/inc/scriptcont.hxx b/basic/source/inc/scriptcont.hxx index 31025c48c4a4..d184a2d558e2 100644 --- a/basic/source/inc/scriptcont.hxx +++ b/basic/source/inc/scriptcont.hxx @@ -53,14 +53,17 @@ class SfxScriptLibraryContainer : public SfxLibraryContainer, public OldBasicPas virtual bool SAL_CALL isLibraryElementValid( ::com::sun::star::uno::Any aElement ) const; virtual void SAL_CALL writeLibraryElement ( - ::com::sun::star::uno::Any aElement, + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer>& xLibrary, const ::rtl::OUString& aElementName, - ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xOutput + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutput ) throw(::com::sun::star::uno::Exception); virtual ::com::sun::star::uno::Any SAL_CALL importLibraryElement - ( const ::rtl::OUString& aFile, + ( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer>& xLibrary, + const ::rtl::OUString& aElementName, + const ::rtl::OUString& aFile, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xElementStream ); virtual void SAL_CALL importFromOldStorage( const ::rtl::OUString& aFile ); diff --git a/basic/source/inc/symtbl.hxx b/basic/source/inc/symtbl.hxx index 03202edba910..9bd8cfd49754 100644 --- a/basic/source/inc/symtbl.hxx +++ b/basic/source/inc/symtbl.hxx @@ -132,7 +132,9 @@ protected: BOOL bAs : 1; // TRUE: Datentyp per AS XXX definiert BOOL bGlobal : 1; // TRUE: Global-Variable BOOL bParamArray : 1; // TRUE: ParamArray parameter + BOOL bWithEvents : 1; // TRUE: Declared WithEvents USHORT nDefaultId; // Symbol number of default value + short nFixedStringLength; // String length in: Dim foo As String*Length public: SbiSymDef( const String& ); virtual ~SbiSymDef(); @@ -156,6 +158,7 @@ public: BOOL IsDefined() const{ return bChained; } void SetOptional() { bOpt = TRUE; } void SetParamArray() { bParamArray = TRUE; } + void SetWithEvents() { bWithEvents = TRUE; } void SetByVal() { bByVal = TRUE; } void SetStatic( BOOL bAsStatic = TRUE ) { bStatic = bAsStatic; } void SetNew() { bNew = TRUE; } @@ -165,11 +168,14 @@ public: USHORT GetDefaultId( void ) { return nDefaultId; } BOOL IsOptional() const{ return bOpt; } BOOL IsParamArray() const{ return bParamArray; } + BOOL IsWithEvents() const{ return bWithEvents; } BOOL IsByVal() const { return bByVal; } BOOL IsStatic() const { return bStatic; } BOOL IsNew() const { return bNew; } BOOL IsDefinedAs() const { return bAs; } BOOL IsGlobal() const { return bGlobal; } + short GetFixedStringLength( void ) const { return nFixedStringLength; } + void SetFixedStringLength( short n ) { nFixedStringLength = n; } SbiSymPool& GetPool(); UINT32 Define(); // Symbol in Code definieren diff --git a/basic/source/inc/token.hxx b/basic/source/inc/token.hxx index 3dc1113b57d1..930f68910b78 100644 --- a/basic/source/inc/token.hxx +++ b/basic/source/inc/token.hxx @@ -95,7 +95,7 @@ enum SbiToken { NUMBER=FIRSTEXTRA, FIXSTRING, SYMBOL, _CDECL_, BYVAL, BYREF, OUTPUT, RANDOM, APPEND, BINARY, ACCESS, LOCK, READ, PRESERVE, BASE, ANY, LIB, _OPTIONAL_, - EXPLICIT, COMPATIBLE, CLASSMODULE, PARAMARRAY, + EXPLICIT, COMPATIBLE, CLASSMODULE, PARAMARRAY, WITHEVENTS, // Ab hier kommen JavaScript-Tokens (gleiches enum, damit gleicher Typ) FIRSTJAVA, @@ -120,7 +120,25 @@ enum SbiToken { #undef SbiTokenSHAREDTMPUNDEF #endif +// #i109076 +class TokenLabelInfo +{ + bool* m_pTokenCanBeLabelTab; + +public: + TokenLabelInfo( void ); + TokenLabelInfo( const TokenLabelInfo& rInfo ) + : m_pTokenCanBeLabelTab( NULL ) + { (void)rInfo; } + ~TokenLabelInfo(); + + bool canTokenBeLabel( SbiToken eTok ) + { return m_pTokenCanBeLabelTab[eTok]; } +}; + class SbiTokenizer : public SbiScanner { + TokenLabelInfo m_aTokenLabelInfo; + protected: SbiToken eCurTok; // aktuelles Token SbiToken ePush; // Pushback-Token diff --git a/basic/source/runtime/dllmgr.cxx b/basic/source/runtime/dllmgr.cxx index 22014763bb29..bc08a8cb64bc 100644 --- a/basic/source/runtime/dllmgr.cxx +++ b/basic/source/runtime/dllmgr.cxx @@ -25,647 +25,714 @@ * ************************************************************************/ -// MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_basic.hxx" +#include "sal/config.h" -#include <stdlib.h> -#ifdef OS2 -#define INCL_DOSMODULEMGR -#include <svpm.h> -#endif - -#if defined( WIN ) || defined( WNT ) -#ifndef _SVWIN_H -#undef WB_LEFT -#undef WB_RIGHT -#include <tools/svwin.h> -#endif -#endif -#include <tools/debug.hxx> -#include <tools/string.hxx> -#include <tools/errcode.hxx> -#include <basic/sbxvar.hxx> -#include <basic/sbx.hxx> - -#if defined(WIN) -typedef HINSTANCE SbiDllHandle; -typedef FARPROC SbiDllProc; -#elif defined(WNT) -typedef HMODULE SbiDllHandle; -typedef int(*SbiDllProc)(); -#elif defined(OS2) -typedef HMODULE SbiDllHandle; -typedef PFN SbiDllProc; -#else -typedef void* SbiDllHandle; -typedef void* SbiDllProc; -#endif +#include <algorithm> +#include <cstddef> +#include <list> +#include <map> +#include <vector> -#define _DLLMGR_CXX -#include "dllmgr.hxx" -#include <basic/sberrors.hxx> +#include "basic/sbx.hxx" +#include "basic/sbxvar.hxx" +#include "osl/thread.h" +#include "rtl/ref.hxx" +#include "rtl/string.hxx" +#include "rtl/ustring.hxx" +#include "salhelper/simplereferenceobject.hxx" +#include "tools/svwin.h" -#ifndef WINAPI -#ifdef WNT -#define WINAPI __far __pascal -#endif -#endif +#undef max -extern "C" { -#if defined(INTEL) && (defined(WIN) || defined(WNT)) +#include "dllmgr.hxx" -extern INT16 WINAPI CallINT( SbiDllProc, char *stack, short nstack); -extern INT32 WINAPI CallLNG( SbiDllProc, char *stack, short nstack); -#ifndef WNT -extern float WINAPI CallSNG( SbiDllProc, char *stack, short nstack); -#endif -extern double WINAPI CallDBL( SbiDllProc, char *stack, short nstack); -extern char* WINAPI CallSTR( SbiDllProc, char *stack, short nstack); -// extern CallFIX( SbiDllProc, char *stack, short nstack); +/* Open issues: -#else + Only 32-bit Windows for now. -INT16 CallINT( SbiDllProc, char *, short ) { return 0; } -INT32 CallLNG( SbiDllProc, char *, short ) { return 0; } -float CallSNG( SbiDllProc, char *, short ) { return 0; } -double CallDBL( SbiDllProc, char *, short) { return 0; } -char* CallSTR( SbiDllProc, char *, short ) { return 0; } -#endif -} + Missing support for functions returning structs (see TODO in call()). -SV_IMPL_OP_PTRARR_SORT(ImplDllArr,ByteStringPtr) + Missing support for additional data types (64 bit integers, Any, ...; would + trigger OSL_ASSERT(false) in various switches). -/* mit Optimierung An stuerzt unter Win95 folgendes Makro ab: -declare Sub MessageBeep Lib "user32" (ByVal long) -sub main - MessageBeep( 1 ) -end sub + It is assumed that the variables passed into SbiDllMgr::Call to represent + the arguments and return value have types that exactly match the Declare + statement; it would be better if this code had access to the function + signature from the Declare statement, so that it could convert the passed + variables accordingly. */ -#if defined (WNT) && defined (MSC) -//#pragma optimize ("", off) -#endif -// -// *********************************************************************** -// +#if defined WNT // only 32-bit Windows, actually -class ImplSbiProc : public ByteString -{ - SbiDllProc pProc; - ImplSbiProc(); - ImplSbiProc( const ImplSbiProc& ); - -public: - ImplSbiProc( const ByteString& rName, SbiDllProc pFunc ) - : ByteString( rName ) { pProc = pFunc; } - SbiDllProc GetProc() const { return pProc; } -}; +extern "C" { -// -// *********************************************************************** -// +int __stdcall DllMgr_call32(FARPROC, void const * stack, std::size_t size); +double __stdcall DllMgr_callFp(FARPROC, void const * stack, std::size_t size); -class ImplSbiDll : public ByteString -{ - ImplDllArr aProcArr; - SbiDllHandle hDLL; +} - ImplSbiDll( const ImplSbiDll& ); -public: - ImplSbiDll( const ByteString& rName, SbiDllHandle hHandle ) - : ByteString( rName ) { hDLL = hHandle; } - ~ImplSbiDll(); - SbiDllHandle GetHandle() const { return hDLL; } - SbiDllProc GetProc( const ByteString& rName ) const; - void InsertProc( const ByteString& rName, SbiDllProc pProc ); -}; +namespace { -ImplSbiDll::~ImplSbiDll() -{ - USHORT nCount = aProcArr.Count(); - for( USHORT nCur = 0; nCur < nCount; nCur++ ) - { - ImplSbiProc* pProc = (ImplSbiProc*)aProcArr.GetObject( nCur ); - delete pProc; - } +char * address(std::vector< char > & blob) { + return blob.empty() ? 0 : &blob[0]; } -SbiDllProc ImplSbiDll::GetProc( const ByteString& rName ) const -{ - USHORT nPos; - BOOL bRet = aProcArr.Seek_Entry( (ByteStringPtr)&rName, &nPos ); - if( bRet ) - { - ImplSbiProc* pImplProc = (ImplSbiProc*)aProcArr.GetObject(nPos); - return pImplProc->GetProc(); - } - return (SbiDllProc)0; +SbError convert(rtl::OUString const & source, rtl::OString * target) { + return + source.convertToString( + target, osl_getThreadTextEncoding(), + (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | + RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)) + ? ERRCODE_NONE : ERRCODE_BASIC_BAD_ARGUMENT; + //TODO: more specific errcode? } -void ImplSbiDll::InsertProc( const ByteString& rName, SbiDllProc pProc ) -{ - DBG_ASSERT(aProcArr.Seek_Entry((ByteStringPtr)&rName,0)==0,"InsertProc: Already in table"); - ImplSbiProc* pImplProc = new ImplSbiProc( rName, pProc ); - aProcArr.Insert( (ByteStringPtr)pImplProc ); +SbError convert(char const * source, sal_Int32 length, rtl::OUString * target) { + return + rtl_convertStringToUString( + &target->pData, source, length, osl_getThreadTextEncoding(), + (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR | + RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR | + RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)) + ? ERRCODE_NONE : ERRCODE_BASIC_BAD_ARGUMENT; + //TODO: more specific errcode? } +struct UnmarshalData { + UnmarshalData(SbxVariable * theVariable, void * theBuffer): + variable(theVariable), buffer(theBuffer) {} -// -// *********************************************************************** -// + SbxVariable * variable; + void * buffer; +}; -SbiDllMgr::SbiDllMgr( const SbiDllMgr& ) -{ -} +struct StringData: public UnmarshalData { + StringData(SbxVariable * theVariable, void * theBuffer, bool theSpecial): + UnmarshalData(theVariable, theBuffer), special(theSpecial) {} -SbiDllMgr::SbiDllMgr() -{ -} + bool special; +}; -SbiDllMgr::~SbiDllMgr() -{ - USHORT nCount = aDllArr.Count(); - for( USHORT nCur = 0; nCur < nCount; nCur++ ) - { - ImplSbiDll* pDll = (ImplSbiDll*)aDllArr.GetObject( nCur ); - FreeDllHandle( pDll->GetHandle() ); - delete pDll; +class MarshalData: private boost::noncopyable { +public: + std::vector< char > * newBlob() { + blobs_.push_front(std::vector< char >()); + return &blobs_.front(); } -} -void SbiDllMgr::FreeDll( const ByteString& rDllName ) -{ - USHORT nPos; - BOOL bRet = aDllArr.Seek_Entry( (ByteStringPtr)&rDllName, &nPos ); - if( bRet ) - { - ImplSbiDll* pDll = (ImplSbiDll*)aDllArr.GetObject(nPos); - FreeDllHandle( pDll->GetHandle() ); - delete pDll; - aDllArr.Remove( nPos, 1 ); - } -} + std::vector< UnmarshalData > unmarshal; + std::vector< StringData > unmarshalStrings; -ImplSbiDll* SbiDllMgr::GetDll( const ByteString& rDllName ) -{ - USHORT nPos; - ImplSbiDll* pDll = 0; - BOOL bRet = aDllArr.Seek_Entry( (ByteStringPtr)&rDllName, &nPos ); - if( bRet ) - pDll = (ImplSbiDll*)aDllArr.GetObject(nPos); - else - { - SbiDllHandle hDll = CreateDllHandle( rDllName ); - if( hDll ) - { - pDll = new ImplSbiDll( rDllName, hDll ); - aDllArr.Insert( (ByteStringPtr)pDll ); - } - } - return pDll; +private: + std::list< std::vector< char > > blobs_; +}; + +std::size_t align(std::size_t address, std::size_t alignment) { + // alignment = 2^k for some k >= 0 + return (address + (alignment - 1)) & ~(alignment - 1); } -SbiDllProc SbiDllMgr::GetProc( ImplSbiDll* pDll, const ByteString& rProcName ) +char * align( + std::vector< char > & blob, std::size_t alignment, std::size_t offset, + std::size_t add) { - DBG_ASSERT(pDll,"GetProc: No dll-ptr"); - SbiDllProc pProc; - pProc = pDll->GetProc( rProcName ); - if( !pProc ) - { - pProc = GetProcAddr( pDll->GetHandle(), rProcName ); - if( pProc ) - pDll->InsertProc( rProcName, pProc ); - } - return pProc; + std::vector< char >::size_type n = blob.size(); + n = align(n - offset, alignment) + offset; //TODO: overflow in align() + blob.resize(n + add); //TODO: overflow + return address(blob) + n; } - -SbError SbiDllMgr::Call( const char* pProcName, const char* pDllName, - SbxArray* pArgs, SbxVariable& rResult, BOOL bCDecl ) +template< typename T > void add( + std::vector< char > & blob, T const & data, std::size_t alignment, + std::size_t offset) { - DBG_ASSERT(pProcName&&pDllName,"Call: Bad parms"); - SbError nSbErr = 0; - ByteString aDllName( pDllName ); - CheckDllName( aDllName ); - ImplSbiDll* pDll = GetDll( aDllName ); - if( pDll ) - { - SbiDllProc pProc = GetProc( pDll, pProcName ); - if( pProc ) - { - if( bCDecl ) - nSbErr = CallProcC( pProc, pArgs, rResult ); - else - nSbErr = CallProc( pProc, pArgs, rResult ); + *reinterpret_cast< T * >(align(blob, alignment, offset, sizeof (T))) = data; +} + +std::size_t alignment(SbxVariable * variable) { + OSL_ASSERT(variable != 0); + if ((variable->GetType() & SbxARRAY) == 0) { + switch (variable->GetType()) { + case SbxINTEGER: + return 2; + case SbxLONG: + case SbxSINGLE: + case SbxSTRING: + return 4; + case SbxDOUBLE: + return 8; + case SbxOBJECT: + { + std::size_t n = 1; + SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())-> + GetProperties(); + for (USHORT i = 0; i < props->Count(); ++i) { + n = std::max(n, alignment(props->Get(i))); + } + return n; + } + case SbxBOOL: + case SbxBYTE: + return 1; + default: + OSL_ASSERT(false); + return 1; + } + } else { + SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject()); + int dims = arr->GetDims(); + std::vector< INT32 > low(dims); + for (int i = 0; i < dims; ++i) { + INT32 up; + arr->GetDim32(i + 1, low[i], up); } - else - nSbErr = SbERR_PROC_UNDEFINED; + return alignment(arr->Get32(&low[0])); } - else - nSbErr = SbERR_BAD_DLL_LOAD; - return nSbErr; } -// *********************************************************************** -// ******************* abhaengige Implementationen *********************** -// *********************************************************************** +SbError marshal( + bool outer, SbxVariable * variable, bool special, + std::vector< char > & blob, std::size_t offset, MarshalData & data); -void SbiDllMgr::CheckDllName( ByteString& rDllName ) +SbError marshalString( + SbxVariable * variable, bool special, MarshalData & data, void ** buffer) { -#if defined(WIN) || defined(WNT) || defined(OS2) - if( rDllName.Search('.') == STRING_NOTFOUND ) - rDllName += ".DLL"; -#else - (void)rDllName; -#endif + OSL_ASSERT(variable != 0 && buffer != 0); + rtl::OString str; + SbError e = convert(variable->GetString(), &str); + if (e != ERRCODE_NONE) { + return e; + } + std::vector< char > * blob = data.newBlob(); + blob->insert(blob->begin(), str.getStr(), str.getStr() + str.getLength()); + *buffer = address(*blob); + data.unmarshalStrings.push_back(StringData(variable, *buffer, special)); + return ERRCODE_NONE; } - -SbiDllHandle SbiDllMgr::CreateDllHandle( const ByteString& rDllName ) +SbError marshalStruct( + SbxVariable * variable, std::vector< char > & blob, std::size_t offset, + MarshalData & data) { - (void)rDllName; - -#if defined(UNX) - SbiDllHandle hLib=0; -#else - SbiDllHandle hLib; -#endif - -#if defined(WIN) - hLib = LoadLibrary( (const char*)rDllName ); - if( (ULONG)hLib < 32 ) - hLib = 0; - -#elif defined(WNT) - hLib = LoadLibrary( rDllName.GetBuffer() ); - if( !(ULONG)hLib ) - { -#ifdef DBG_UTIL - ULONG nLastErr; - nLastErr = GetLastError(); -#endif - hLib = 0; + OSL_ASSERT(variable != 0); + SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())-> + GetProperties(); + for (USHORT i = 0; i < props->Count(); ++i) { + SbError e = marshal(false, props->Get(i), false, blob, offset, data); + if (e != ERRCODE_NONE) { + return e; + } } - -#elif defined(OS2) - char cErr[ 100 ]; - if( DosLoadModule( (PSZ) cErr, 100, (const char*)rDllName.GetBuffer(), &hLib ) ) - hLib = 0; -#endif - return hLib; + return ERRCODE_NONE; } -void SbiDllMgr::FreeDllHandle( SbiDllHandle hLib ) +SbError marshalArray( + SbxVariable * variable, std::vector< char > & blob, std::size_t offset, + MarshalData & data) { -#if defined(WIN) || defined(WNT) - if( hLib ) - FreeLibrary ((HINSTANCE) hLib); -#elif defined(OS2) - if( hLib ) - DosFreeModule( (HMODULE) hLib ); -#else - (void)hLib; -#endif + OSL_ASSERT(variable != 0); + SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject()); + int dims = arr->GetDims(); + std::vector< INT32 > low(dims); + std::vector< INT32 > up(dims); + for (int i = 0; i < dims; ++i) { + arr->GetDim32(i + 1, low[i], up[i]); + } + for (std::vector< INT32 > idx = low;;) { + SbError e = marshal( + false, arr->Get32(&idx[0]), false, blob, offset, data); + if (e != ERRCODE_NONE) { + return e; + } + int i = dims - 1; + while (idx[i] == up[i]) { + idx[i] = low[i]; + if (i == 0) { + return ERRCODE_NONE; + } + --i; + } + ++idx[i]; + } } -SbiDllProc SbiDllMgr::GetProcAddr(SbiDllHandle hLib, const ByteString& rProcName) +// 8-aligned structs are only 4-aligned on stack, so alignment of members in +// such structs must take that into account via "offset" +SbError marshal( + bool outer, SbxVariable * variable, bool special, + std::vector< char > & blob, std::size_t offset, MarshalData & data) { - char buf1 [128] = ""; - char buf2 [128] = ""; - - SbiDllProc pProc = 0; - int nOrd = 0; - - // Ordinal? - if( rProcName.GetBuffer()[0] == '@' ) - nOrd = atoi( rProcName.GetBuffer()+1 ); - - // Moegliche Parameter weg: - DBG_ASSERT( sizeof(buf1) > rProcName.Len(), - "SbiDllMgr::GetProcAddr: buffer to small!" ); - strncpy( buf1, rProcName.GetBuffer(), sizeof(buf1)-1 ); - char *p = strchr( buf1, '#' ); - if( p ) - *p = 0; - - DBG_ASSERT( sizeof(buf2) > strlen(buf1) + 1, - "SbiDllMgr::GetProcAddr: buffer to small!" ); - strncpy( buf2, "_", sizeof(buf2)-1 ); - strncat( buf2, buf1, sizeof(buf2)-1-strlen(buf2) ); - -#if defined(WIN) || defined(WNT) - if( nOrd > 0 ) - pProc = (SbiDllProc)GetProcAddress( hLib, (char*)(long) nOrd ); - else - { - // 2. mit Parametern: - pProc = (SbiDllProc)GetProcAddress ( hLib, rProcName.GetBuffer() ); - // 3. nur der Name: - if (!pProc) - pProc = (SbiDllProc)GetProcAddress( hLib, buf1 ); - // 4. der Name mit Underline vorweg: - if( !pProc ) - pProc = (SbiDllProc)GetProcAddress( hLib, buf2 ); + OSL_ASSERT(variable != 0); + if ((variable->GetFlags() & SBX_REFERENCE) == 0) { + if ((variable->GetType() & SbxARRAY) == 0) { + switch (variable->GetType()) { + case SbxINTEGER: + add(blob, variable->GetInteger(), outer ? 4 : 2, offset); + break; + case SbxLONG: + add(blob, variable->GetLong(), 4, offset); + break; + case SbxSINGLE: + add(blob, variable->GetSingle(), 4, offset); + break; + case SbxDOUBLE: + add(blob, variable->GetDouble(), outer ? 4 : 8, offset); + break; + case SbxSTRING: + { + void * p; + SbError e = marshalString(variable, special, data, &p); + if (e != ERRCODE_NONE) { + return e; + } + add(blob, p, 4, offset); + break; + } + case SbxOBJECT: + { + align(blob, outer ? 4 : alignment(variable), offset, 0); + SbError e = marshalStruct(variable, blob, offset, data); + if (e != ERRCODE_NONE) { + return e; + } + break; + } + case SbxBOOL: + add(blob, variable->GetBool(), outer ? 4 : 1, offset); + break; + case SbxBYTE: + add(blob, variable->GetByte(), outer ? 4 : 1, offset); + break; + default: + OSL_ASSERT(false); + break; + } + } else { + SbError e = marshalArray(variable, blob, offset, data); + if (e != ERRCODE_NONE) { + return e; + } + } + } else { + if ((variable->GetType() & SbxARRAY) == 0) { + switch (variable->GetType()) { + case SbxINTEGER: + case SbxLONG: + case SbxSINGLE: + case SbxDOUBLE: + case SbxBOOL: + case SbxBYTE: + add(blob, variable->data(), 4, offset); + break; + case SbxSTRING: + { + std::vector< char > * blob2 = data.newBlob(); + void * p; + SbError e = marshalString(variable, special, data, &p); + if (e != ERRCODE_NONE) { + return e; + } + add(*blob2, p, 4, 0); + add(blob, address(*blob2), 4, offset); + break; + } + case SbxOBJECT: + { + std::vector< char > * blob2 = data.newBlob(); + SbError e = marshalStruct(variable, *blob2, 0, data); + if (e != ERRCODE_NONE) { + return e; + } + void * p = address(*blob2); + if (outer) { + data.unmarshal.push_back(UnmarshalData(variable, p)); + } + add(blob, p, 4, offset); + break; + } + default: + OSL_ASSERT(false); + break; + } + } else { + std::vector< char > * blob2 = data.newBlob(); + SbError e = marshalArray(variable, *blob2, 0, data); + if (e != ERRCODE_NONE) { + return e; + } + void * p = address(*blob2); + if (outer) { + data.unmarshal.push_back(UnmarshalData(variable, p)); + } + add(blob, p, 4, offset); + } } + return ERRCODE_NONE; +} -#elif defined(OS2) - PSZ pp; - APIRET rc; - // 1. Ordinal oder mit Parametern: - rc = DosQueryProcAddr( hLib, nOrd, pp = (char*)rProcName.GetBuffer(), &pProc ); - // 2. nur der Name: - if( rc ) - rc = DosQueryProcAddr( hLib, 0, pp = (PSZ)buf1, &pProc ); - // 3. der Name mit Underline vorweg: - if( rc ) - rc = DosQueryProcAddr( hLib, 0, pp = (PSZ)buf2, &pProc ); - if( rc ) - pProc = NULL; - else - { - // 16-bit oder 32-bit? - ULONG nInfo = 0; - if( DosQueryProcType( hLib, nOrd, pp, &nInfo ) ) - nInfo = 0;; - } -#else - (void)hLib; -#endif - return pProc; +template< typename T > T read(void const ** pointer) { + T const * p = static_cast< T const * >(*pointer); + *pointer = static_cast< void const * >(p + 1); + return *p; } -SbError SbiDllMgr::CallProc( SbiDllProc pProc, SbxArray* pArgs, - SbxVariable& rResult ) -{ -// ByteString aStr("Calling DLL at "); -// aStr += (ULONG)pProc; -// InfoBox( 0, aStr ).Execute(); - INT16 nInt16; int nInt; INT32 nInt32; double nDouble; - char* pStr; - - USHORT nSize; - char* pStack = (char*)CreateStack( pArgs, nSize ); - switch( rResult.GetType() ) - { +void const * unmarshal(SbxVariable * variable, void const * data) { + OSL_ASSERT(variable != 0); + if ((variable->GetType() & SbxARRAY) == 0) { + switch (variable->GetType()) { case SbxINTEGER: - nInt16 = CallINT(pProc, pStack, (short)nSize ); - rResult.PutInteger( nInt16 ); - break; - - case SbxUINT: - case SbxUSHORT: - nInt16 = (INT16)CallINT(pProc, pStack, (short)nSize ); - rResult.PutUShort( (USHORT)nInt16 ); - break; - - case SbxERROR: - nInt16 = (INT16)CallINT(pProc, pStack, (short)nSize ); - rResult.PutErr( (USHORT)nInt16 ); - break; - - case SbxINT: - nInt = CallINT(pProc, pStack, (short)nSize ); - rResult.PutInt( nInt ); + variable->PutInteger(read< sal_Int16 >(&data)); break; - case SbxLONG: - nInt32 = CallLNG(pProc, pStack, (short)nSize ); - rResult.PutLong( nInt32 ); + variable->PutLong(read< sal_Int32 >(&data)); break; - - case SbxULONG: - nInt32 = CallINT(pProc, pStack, (short)nSize ); - rResult.PutULong( (ULONG)nInt32 ); - break; - -#ifndef WNT case SbxSINGLE: - { - float nSingle = CallSNG(pProc, pStack, (short)nSize ); - rResult.PutSingle( nSingle ); + variable->PutSingle(read< float >(&data)); break; - } -#endif - case SbxDOUBLE: -#ifdef WNT - case SbxSINGLE: -#endif - nDouble = CallDBL(pProc, pStack, (short)nSize ); - rResult.PutDouble( nDouble ); + variable->PutDouble(read< double >(&data)); break; - - case SbxDATE: - nDouble = CallDBL(pProc, pStack, (short)nSize ); - rResult.PutDate( nDouble ); + case SbxSTRING: + read< char * >(&data); // handled by unmarshalString break; - - case SbxCHAR: - case SbxBYTE: + case SbxOBJECT: + { + data = reinterpret_cast< void const * >( + align( + reinterpret_cast< sal_uIntPtr >(data), + alignment(variable))); + SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())-> + GetProperties(); + for (USHORT i = 0; i < props->Count(); ++i) { + data = unmarshal(props->Get(i), data); + } + break; + } case SbxBOOL: - nInt16 = CallINT(pProc, pStack, (short)nSize ); - rResult.PutByte( (BYTE)nInt16 ); - break; - - case SbxSTRING: - case SbxLPSTR: - pStr = CallSTR(pProc, pStack, (short)nSize ); - rResult.PutString( String::CreateFromAscii( pStr ) ); + variable->PutBool(read< sal_Bool >(&data)); break; - - case SbxNULL: - case SbxEMPTY: - nInt16 = CallINT(pProc, pStack, (short)nSize ); - // Rueckgabe nur zulaessig, wenn variant! - if( !rResult.IsFixed() ) - rResult.PutInteger( nInt16 ); + case SbxBYTE: + variable->PutByte(read< sal_uInt8 >(&data)); break; - - case SbxCURRENCY: - case SbxOBJECT: - case SbxDATAOBJECT: default: - CallINT(pProc, pStack, (short)nSize ); + OSL_ASSERT(false); break; - } - delete [] pStack; - - if( pArgs ) - { - // die Laengen aller uebergebenen Strings anpassen - USHORT nCount = pArgs->Count(); - for( USHORT nCur = 1; nCur < nCount; nCur++ ) - { - SbxVariable* pVar = pArgs->Get( nCur ); - BOOL bIsString = ( pVar->GetType() == SbxSTRING ) || - ( pVar->GetType() == SbxLPSTR ); - - if( pVar->GetFlags() & SBX_REFERENCE ) - { - pVar->ResetFlag( SBX_REFERENCE ); // Sbx moechte es so - if( bIsString ) - { - ByteString aByteStr( (char*)pVar->GetUserData() ); - String aStr( aByteStr, gsl_getSystemTextEncoding() ); - pVar->PutString( aStr ); + } + } else { + SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject()); + int dims = arr->GetDims(); + std::vector< INT32 > low(dims); + std::vector< INT32 > up(dims); + for (int i = 0; i < dims; ++i) { + arr->GetDim32(i + 1, low[i], up[i]); + } + for (std::vector< INT32 > idx = low;;) { + data = unmarshal(arr->Get32(&idx[0]), data); + int i = dims - 1; + while (idx[i] == up[i]) { + idx[i] = low[i]; + if (i == 0) { + goto done; } + --i; } - if( bIsString ) - { - delete (char*)(pVar->GetUserData()); - pVar->SetUserData( 0 ); - } + ++idx[i]; } + done:; } - return 0; + return data; } -SbError SbiDllMgr::CallProcC( SbiDllProc pProc, SbxArray* pArgs, - SbxVariable& rResult ) -{ - (void)pProc; - (void)pArgs; - (void)rResult; - - DBG_ERROR("C calling convention not supported"); - return SbERR_BAD_ARGUMENT; +SbError unmarshalString(StringData const & data, SbxVariable & result) { + rtl::OUString str; + if (data.buffer != 0) { + char const * p = static_cast< char const * >(data.buffer); + sal_Int32 len; + if (data.special) { + len = static_cast< sal_Int32 >(result.GetULong()); + if (len < 0) { // i.e., DWORD result >= 2^31 + return ERRCODE_BASIC_BAD_ARGUMENT; + //TODO: more specific errcode? + } + } else { + len = rtl_str_getLength(p); + } + SbError e = convert(p, len, &str); + if (e != ERRCODE_NONE) { + return e; + } + } + data.variable->PutString(String(str)); + return ERRCODE_NONE; } -void* SbiDllMgr::CreateStack( SbxArray* pArgs, USHORT& rSize ) +struct ProcData { + rtl::OString name; + FARPROC proc; +}; + +SbError call( + rtl::OUString const & dll, ProcData const & proc, SbxArray * arguments, + SbxVariable & result) { - if( !pArgs ) + std::vector< char > stack; + MarshalData data; + // For DWORD GetLogicalDriveStringsA(DWORD nBufferLength, LPSTR lpBuffer) + // from kernel32, upon return, filled lpBuffer length is result DWORD, which + // requires special handling in unmarshalString; other functions might + // require similar treatment, too: + bool special = + dll.equalsIgnoreAsciiCaseAsciiL( + RTL_CONSTASCII_STRINGPARAM("KERNEL32.DLL")) && + (proc.name == + rtl::OString(RTL_CONSTASCII_STRINGPARAM("GetLogicalDriveStringsA"))); + for (USHORT i = 1; i < (arguments == 0 ? 0 : arguments->Count()); ++i) { + SbError e = marshal( + true, arguments->Get(i), special && i == 2, stack, stack.size(), + data); + if (e != ERRCODE_NONE) { + return e; + } + align(stack, 4, 0, 0); + } + switch (result.GetType()) { + case SbxEMPTY: + DllMgr_call32(proc.proc, address(stack), stack.size()); + break; + case SbxINTEGER: + result.PutInteger( + static_cast< sal_Int16 >( + DllMgr_call32(proc.proc, address(stack), stack.size()))); + break; + case SbxLONG: + result.PutLong( + static_cast< sal_Int32 >( + DllMgr_call32(proc.proc, address(stack), stack.size()))); + break; + case SbxSINGLE: + result.PutSingle( + static_cast< float >( + DllMgr_callFp(proc.proc, address(stack), stack.size()))); + break; + case SbxDOUBLE: + result.PutDouble( + DllMgr_callFp(proc.proc, address(stack), stack.size())); + break; + case SbxSTRING: + { + char const * s1 = reinterpret_cast< char const * >( + DllMgr_call32(proc.proc, address(stack), stack.size())); + rtl::OUString s2; + SbError e = convert(s1, rtl_str_getLength(s1), &s2); + if (e != ERRCODE_NONE) { + return e; + } + result.PutString(String(s2)); + break; + } + case SbxOBJECT: + //TODO + DllMgr_call32(proc.proc, address(stack), stack.size()); + break; + case SbxBOOL: + result.PutBool( + static_cast< sal_Bool >( + DllMgr_call32(proc.proc, address(stack), stack.size()))); + break; + case SbxBYTE: + result.PutByte( + static_cast< sal_uInt8 >( + DllMgr_call32(proc.proc, address(stack), stack.size()))); + break; + default: + OSL_ASSERT(false); + break; + } + for (USHORT i = 1; i < (arguments == 0 ? 0 : arguments->Count()); ++i) { + arguments->Get(i)->ResetFlag(SBX_REFERENCE); + //TODO: skipped for errors?!? + } + for (std::vector< UnmarshalData >::iterator i(data.unmarshal.begin()); + i != data.unmarshal.end(); ++i) { - rSize = 0; - return 0; + unmarshal(i->variable, i->buffer); } - char* pStack = new char[ 2048 ]; - char* pTop = pStack; - USHORT nCount = pArgs->Count(); - // erstes Element ueberspringen -#ifndef WIN - for( USHORT nCur = 1; nCur < nCount; nCur++ ) -#else - // unter 16-Bit Windows anders rum (OS/2 ?????) - for( USHORT nCur = nCount-1; nCur >= 1; nCur-- ) -#endif + for (std::vector< StringData >::iterator i(data.unmarshalStrings.begin()); + i != data.unmarshalStrings.end(); ++i) { - SbxVariable* pVar = pArgs->Get( nCur ); - // AB 22.1.1996, Referenz - if( pVar->GetFlags() & SBX_REFERENCE ) // Es ist eine Referenz - { - switch( pVar->GetType() ) - { - case SbxINTEGER: - case SbxUINT: - case SbxINT: - case SbxUSHORT: - case SbxLONG: - case SbxULONG: - case SbxSINGLE: - case SbxDOUBLE: - case SbxCHAR: - case SbxBYTE: - case SbxBOOL: - *((void**)pTop) = (void*)&(pVar->aData); - pTop += sizeof( void* ); - break; - - case SbxSTRING: - case SbxLPSTR: - { - USHORT nLen = 256; - ByteString rStr( pVar->GetString(), gsl_getSystemTextEncoding() ); - if( rStr.Len() > 255 ) - nLen = rStr.Len() + 1; - - char* pStr = new char[ nLen ]; - strcpy( pStr, rStr.GetBuffer() ); // #100211# - checked - // ist nicht so sauber, aber wir sparen ein Pointerarray - DBG_ASSERT(sizeof(UINT32)>=sizeof(char*),"Gleich krachts im Basic"); - pVar->SetUserData( (sal_uIntPtr)pStr ); - *((const char**)pTop) = pStr; - pTop += sizeof( char* ); - } - break; + SbError e = unmarshalString(*i, result); + if (e != ERRCODE_NONE) { + return e; + } + } + return ERRCODE_NONE; +} - case SbxNULL: - case SbxEMPTY: - case SbxERROR: - case SbxDATE: - case SbxCURRENCY: - case SbxOBJECT: - case SbxDATAOBJECT: - default: - break; +SbError getProcData(HMODULE handle, rtl::OUString const & name, ProcData * proc) +{ + OSL_ASSERT(proc != 0); + if (name.getLength() != 0 && name[0] == '@') { //TODO: "@" vs. "#"??? + sal_Int32 n = name.copy(1).toInt32(); //TODO: handle bad input + if (n <= 0 || n > 0xFFFF) { + return ERRCODE_BASIC_BAD_ARGUMENT; //TODO: more specific errcode? + } + FARPROC p = GetProcAddress(handle, reinterpret_cast< LPCSTR >(n)); + if (p != 0) { + proc->name = rtl::OString(RTL_CONSTASCII_STRINGPARAM("#")) + + rtl::OString::valueOf(n); + proc->proc = p; + return ERRCODE_NONE; + } + } else { + rtl::OString name8; + SbError e = convert(name, &name8); + if (e != ERRCODE_NONE) { + return e; + } + FARPROC p = GetProcAddress(handle, name8.getStr()); + if (p != 0) { + proc->name = name8; + proc->proc = p; + return ERRCODE_NONE; + } + sal_Int32 i = name8.indexOf('#'); + if (i != -1) { + name8 = name8.copy(0, i); + p = GetProcAddress(handle, name8.getStr()); + if (p != 0) { + proc->name = name8; + proc->proc = p; + return ERRCODE_NONE; } } - else - { - // ByVal - switch( pVar->GetType() ) - { - case SbxINTEGER: - case SbxUINT: - case SbxINT: - case SbxUSHORT: - *((INT16*)pTop) = pVar->GetInteger(); - pTop += sizeof( INT16 ); - break; + rtl::OString real( + rtl::OString(RTL_CONSTASCII_STRINGPARAM("_")) + name8); + p = GetProcAddress(handle, real.getStr()); + if (p != 0) { + proc->name = real; + proc->proc = p; + return ERRCODE_NONE; + } + real = name8 + rtl::OString(RTL_CONSTASCII_STRINGPARAM("A")); + p = GetProcAddress(handle, real.getStr()); + if (p != 0) { + proc->name = real; + proc->proc = p; + return ERRCODE_NONE; + } + } + return ERRCODE_BASIC_PROC_UNDEFINED; +} - case SbxLONG: - case SbxULONG: - *((INT32*)pTop) = pVar->GetLong(); - pTop += sizeof( INT32 ); - break; +struct Dll: public salhelper::SimpleReferenceObject { +private: + typedef std::map< rtl::OUString, ProcData > Procs; - case SbxSINGLE: - *((float*)pTop) = pVar->GetSingle(); - pTop += sizeof( float ); - break; + virtual ~Dll(); - case SbxDOUBLE: - *((double*)pTop) = pVar->GetDouble(); - pTop += sizeof( double ); - break; +public: + Dll(): handle(0) {} - case SbxSTRING: - case SbxLPSTR: - { - char* pStr = new char[ pVar->GetString().Len() + 1 ]; - ByteString aByteStr( pVar->GetString(), gsl_getSystemTextEncoding() ); - strcpy( pStr, aByteStr.GetBuffer() ); // #100211# - checked - // ist nicht so sauber, aber wir sparen ein Pointerarray - DBG_ASSERT(sizeof(UINT32)>=sizeof(char*),"Gleich krachts im Basic"); - pVar->SetUserData( (sal_uIntPtr)pStr ); - *((const char**)pTop) = pStr; - pTop += sizeof( char* ); - } - break; + SbError getProc(rtl::OUString const & name, ProcData * proc); - case SbxCHAR: - case SbxBYTE: - case SbxBOOL: - *((BYTE*)pTop) = pVar->GetByte(); - pTop += sizeof( BYTE ); - break; + HMODULE handle; + Procs procs; +}; - case SbxNULL: - case SbxEMPTY: - case SbxERROR: - case SbxDATE: - case SbxCURRENCY: - case SbxOBJECT: - case SbxDATAOBJECT: - default: - break; - } +Dll::~Dll() { + if (handle != 0 && !FreeLibrary(handle)) { + OSL_TRACE("FreeLibrary(%p) failed with %u", handle, GetLastError()); + } +} + +SbError Dll::getProc(rtl::OUString const & name, ProcData * proc) { + Procs::iterator i(procs.find(name)); + if (i != procs.end()) { + *proc = i->second; + return ERRCODE_NONE; + } + SbError e = getProcData(handle, name, proc); + if (e == ERRCODE_NONE) { + procs.insert(Procs::value_type(name, *proc)); + } + return e; +} + +rtl::OUString fullDllName(rtl::OUString const & name) { + rtl::OUString full(name); + if (full.indexOf('.') == -1) { + full += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".DLL")); + } + return full; +} + +} + +struct SbiDllMgr::Impl: private boost::noncopyable { +private: + typedef std::map< rtl::OUString, rtl::Reference< Dll > > Dlls; + +public: + Dll * getDll(rtl::OUString const & name); + + Dlls dlls; +}; + +Dll * SbiDllMgr::Impl::getDll(rtl::OUString const & name) { + Dlls::iterator i(dlls.find(name)); + if (i == dlls.end()) { + i = dlls.insert(Dlls::value_type(name, new Dll)).first; + HMODULE h = LoadLibraryW(name); + if (h == 0) { + dlls.erase(i); + return 0; } + i->second->handle = h; } - rSize = (USHORT)((ULONG)pTop - (ULONG)pStack); - return pStack; + return i->second.get(); } +SbError SbiDllMgr::Call( + rtl::OUString const & function, rtl::OUString const & library, + SbxArray * arguments, SbxVariable & result, bool cdeclConvention) +{ + if (cdeclConvention) { + return ERRCODE_BASIC_NOT_IMPLEMENTED; + } + rtl::OUString dllName(fullDllName(library)); + Dll * dll = impl_->getDll(dllName); + if (dll == 0) { + return ERRCODE_BASIC_BAD_DLL_LOAD; + } + ProcData proc; + SbError e = dll->getProc(function, &proc); + if (e != ERRCODE_NONE) { + return e; + } + return call(dllName, proc, arguments, result); +} + +void SbiDllMgr::FreeDll(rtl::OUString const & library) { + impl_->dlls.erase(library); +} +#else + +struct SbiDllMgr::Impl {}; + +SbError SbiDllMgr::Call( + rtl::OUString const &, rtl::OUString const &, SbxArray *, SbxVariable &, + bool) +{ + return ERRCODE_BASIC_NOT_IMPLEMENTED; +} + +void SbiDllMgr::FreeDll(rtl::OUString const &) {} + +#endif +SbiDllMgr::SbiDllMgr(): impl_(new Impl) {} +SbiDllMgr::~SbiDllMgr() {} diff --git a/basic/source/runtime/dllmgr.hxx b/basic/source/runtime/dllmgr.hxx index 2c71a2843c37..fdff8c2849be 100644 --- a/basic/source/runtime/dllmgr.hxx +++ b/basic/source/runtime/dllmgr.hxx @@ -25,71 +25,36 @@ * ************************************************************************/ -#ifndef _DLLMGR_HXX -#define _DLLMGR_HXX +#ifndef INCLUDED_BASIC_SOURCE_RUNTIME_DLLMGR_HXX +#define INCLUDED_BASIC_SOURCE_RUNTIME_DLLMGR_HXX -#define _SVSTDARR_BYTESTRINGSSORT -#include <svl/svarray.hxx> -#ifndef _SVSTDARR_HXX //autogen -#include <svl/svstdarr.hxx> -#endif +#include "sal/config.h" -// !!! nur zum debuggen fuer infoboxes !!! -//#ifndef _SV_HXX -//#include <sv.hxx> -//#endif +#include <memory> -//#ifndef _TOOLS_HXX -//#include <tools.hxx> -//#endif -#define _SVSTDARR_STRINGS -//#ifndef _SVSTDARR_HXX -//#include <svstdarr.hxx> -//#endif -#ifndef _SBERRORS_HXX -#include <basic/sberrors.hxx> -#endif +#include "basic/sberrors.hxx" +#include "boost/noncopyable.hpp" +namespace rtl { class OUString; } class SbxArray; class SbxVariable; -class ImplSbiDll; -class ImplSbiProc; - -SV_DECL_PTRARR_SORT(ImplDllArr,ByteStringPtr,5,5) - -class SbiDllMgr -{ - ImplDllArr aDllArr; - - SbiDllMgr( const SbiDllMgr& ); +class SbiDllMgr: private boost::noncopyable { +public: + SbiDllMgr(); -#ifdef _DLLMGR_CXX - ImplSbiDll* GetDll( const ByteString& rDllName ); - SbiDllProc GetProc( ImplSbiDll*, const ByteString& rProcName ); + ~SbiDllMgr(); - SbiDllHandle CreateDllHandle( const ByteString& rDllName ); - void FreeDllHandle( SbiDllHandle ); - SbiDllProc GetProcAddr( SbiDllHandle, const ByteString& pProcName ); - SbError CallProc( SbiDllProc pProc, SbxArray* pArgs, - SbxVariable& rResult ); - SbError CallProcC( SbiDllProc pProc, SbxArray* pArgs, - SbxVariable& rResult ); - void* CreateStack( SbxArray* pArgs, USHORT& rSize ); - void CheckDllName( ByteString& rName ); -#endif + SbError Call( + rtl::OUString const & function, rtl::OUString const & library, + SbxArray * arguments, SbxVariable & result, bool cdeclConvention); -public: - SbiDllMgr(); - ~SbiDllMgr(); + void FreeDll(rtl::OUString const & library); - SbError Call( const char* pFunc, const char* pDll, - SbxArray* pArgs, SbxVariable& rResult, - BOOL bCDecl ); +private: + struct Impl; - void FreeDll( const ByteString& rDllName ); + std::auto_ptr< Impl > impl_; }; - - #endif diff --git a/basic/source/runtime/makefile.mk b/basic/source/runtime/makefile.mk index 9bd197975ee6..f2ed11196b28 100644 --- a/basic/source/runtime/makefile.mk +++ b/basic/source/runtime/makefile.mk @@ -30,6 +30,8 @@ PRJ=..$/.. PRJNAME=basic TARGET=runtime +ENABLE_EXCEPTIONS = TRUE + # --- Settings ----------------------------------------------------------- .INCLUDE : settings.mk @@ -53,29 +55,12 @@ SLOFILES= \ $(SLO)$/ddectrl.obj \ $(SLO)$/dllmgr.obj -.IF "$(GUI)$(CPU)" == "WINI" -SLOFILES+= $(SLO)$/win.obj -.ENDIF - .IF "$(GUI)$(COM)$(CPU)" == "WNTMSCI" SLOFILES+= $(SLO)$/wnt.obj -.ENDIF - -.IF "$(GUI)$(COM)$(CPU)" == "WNTGCCI" +.ELIF "$(GUI)$(COM)$(CPU)" == "WNTGCCI" SLOFILES+= $(SLO)$/wnt-mingw.obj .ENDIF -.IF "$(GUI)$(CPU)" == "OS2I" -#FIXME SLOFILES+= $(SLO)$/os2.obj -.ENDIF - -EXCEPTIONSFILES=$(SLO)$/step0.obj \ - $(SLO)$/step2.obj \ - $(SLO)$/methods.obj \ - $(SLO)$/methods1.obj \ - $(SLO)$/iosys.obj \ - $(SLO)$/runtime.obj - # --- Targets ------------------------------------------------------------- .INCLUDE : target.mk diff --git a/basic/source/runtime/methods1.cxx b/basic/source/runtime/methods1.cxx index b25c213a493d..8c7da2403705 100644 --- a/basic/source/runtime/methods1.cxx +++ b/basic/source/runtime/methods1.cxx @@ -523,6 +523,18 @@ RTLFUNC(WaitUntil) Wait_Impl( true, rPar ); } +RTLFUNC(DoEvents) +{ + (void)pBasic; + (void)bWrite; + (void)rPar; + Timer aTimer; + aTimer.SetTimeout( 1 ); + aTimer.Start(); + while ( aTimer.IsActive() ) + Application::Yield(); +} + RTLFUNC(GetGUIVersion) { (void)pBasic; @@ -622,8 +634,7 @@ RTLFUNC(FreeLibrary) if ( rPar.Count() != 2 ) StarBASIC::Error( SbERR_BAD_ARGUMENT ); - ByteString aByteDLLName( rPar.Get(1)->GetString(), gsl_getSystemTextEncoding() ); - pINST->GetDllMgr()->FreeDll( aByteDLLName ); + pINST->GetDllMgr()->FreeDll( rPar.Get(1)->GetString() ); } bool IsBaseIndexOne() { diff --git a/basic/source/runtime/rtlproto.hxx b/basic/source/runtime/rtlproto.hxx index 6c90c408cd93..1a1ae4f32283 100644 --- a/basic/source/runtime/rtlproto.hxx +++ b/basic/source/runtime/rtlproto.hxx @@ -166,6 +166,7 @@ extern RTLFUNC(RmDir); // JSM extern RTLFUNC(SendKeys); // JSM extern RTLFUNC(DimArray); extern RTLFUNC(Dir); +extern RTLFUNC(DoEvents); extern RTLFUNC(Exp); extern RTLFUNC(FileLen); extern RTLFUNC(Fix); diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx index 29e49b0ffde8..1ace790f8aee 100755 --- a/basic/source/runtime/runtime.cxx +++ b/basic/source/runtime/runtime.cxx @@ -155,6 +155,7 @@ SbiRuntime::pStep0 SbiRuntime::aStep0[] = { // Alle Opcodes ohne Operanden &SbiRuntime::StepVBASET,// vba-like set statement &SbiRuntime::StepERASE_CLEAR,// vba-like set statement &SbiRuntime::StepARRAYACCESS,// access TOS as array + &SbiRuntime::StepBYVAL, // access TOS as array }; SbiRuntime::pStep1 SbiRuntime::aStep1[] = { // Alle Opcodes mit einem Operanden @@ -1231,9 +1232,7 @@ void SbiRuntime::DllCall SbxVariable* pRes = new SbxVariable( eResType ); SbiDllMgr* pDllMgr = pInst->GetDllMgr(); - ByteString aByteFuncName( aFuncName, gsl_getSystemTextEncoding() ); - ByteString aByteDLLName( aDLLName, gsl_getSystemTextEncoding() ); - SbError nErr = pDllMgr->Call( aByteFuncName.GetBuffer(), aByteDLLName.GetBuffer(), pArgs, *pRes, bCDecl ); + SbError nErr = pDllMgr->Call( aFuncName, aDLLName, pArgs, *pRes, bCDecl ); if( nErr ) Error( nErr ); PushVar( pRes ); diff --git a/basic/source/runtime/stdobj.cxx b/basic/source/runtime/stdobj.cxx index 13bc8810144a..60d2e9cf448d 100644 --- a/basic/source/runtime/stdobj.cxx +++ b/basic/source/runtime/stdobj.cxx @@ -216,6 +216,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 }, { "DumpAllObjects", SbxEMPTY, 2 | _SUB, RTLNAME(DumpAllObjects),0 }, { "FileSpec", SbxSTRING, 0,NULL,0 }, { "DumpAll", SbxINTEGER, _OPT, NULL,0 }, @@ -361,6 +362,8 @@ static Methods aMethods[] = { { "Count", SbxLONG, 0,NULL,0 }, { "Len", SbxLONG, 1 | _FUNCTION, RTLNAME(Len),0 }, { "StringOrVariant", SbxVARIANT, 0,NULL,0 }, +{ "LenB", SbxLONG, 1 | _FUNCTION, RTLNAME(Len),0 }, + { "StringOrVariant", SbxVARIANT, 0,NULL,0 }, { "Load", SbxNULL, 1 | _FUNCTION, RTLNAME(Load),0 }, { "object", SbxOBJECT, 0,NULL,0 }, { "LoadPicture", SbxOBJECT, 1 | _FUNCTION, RTLNAME(LoadPicture),0 }, @@ -628,6 +631,10 @@ SbiStdObject::SbiStdObject( const String& r, StarBASIC* pb ) : SbxObject( r ) p += ( p->nArgs & _ARGSMASK ) + 1; } + // #i92642: Remove default properties + Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_DONTCARE ); + Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Parent") ), SbxCLASS_DONTCARE ); + SetParent( pb ); pStdFactory = new SbStdFactory; diff --git a/basic/source/runtime/step0.cxx b/basic/source/runtime/step0.cxx index 39af5ea4adc3..1d9333ff7555 100644 --- a/basic/source/runtime/step0.cxx +++ b/basic/source/runtime/step0.cxx @@ -43,6 +43,9 @@ #include <vcl/svapp.hxx> #include <unotools/textsearch.hxx> +Reference< XInterface > createComListener( const Any& aControlAny, const ::rtl::OUString& aVBAType, + const ::rtl::OUString& aPrefix, SbxObjectRef xScopeObj ); + #include <algorithm> SbxVariable* getDefaultProp( SbxVariable* pRef ); @@ -515,8 +518,29 @@ void SbiRuntime::StepSET_Impl( SbxVariableRef& refVal, SbxVariableRef& refVar, b } } + // Handle withevents + BOOL bWithEvents = refVar->IsSet( SBX_WITH_EVENTS ); + Reference< XInterface > xComListener; + if( bWithEvents ) + { + SbxBase* pObj = refVal->GetObject(); + SbUnoObject* pUnoObj = (pObj != NULL) ? PTR_CAST(SbUnoObject,pObj) : NULL; + if( pUnoObj != NULL ) + { + Any aControlAny = pUnoObj->getUnoAny(); + String aDeclareClassName = refVar->GetDeclareClassName(); + ::rtl::OUString aVBAType = aDeclareClassName; + ::rtl::OUString aPrefix = refVar->GetName(); + SbxObjectRef xScopeObj = refVar->GetParent(); + xComListener = createComListener( aControlAny, aVBAType, aPrefix, xScopeObj ); + } + } + *refVar = *refVal; + if( bWithEvents ) + refVar->SetComListener( xComListener ); // Hold reference + // lhs is a property who's value is currently (Empty e.g. no broadcast yet) // in this case if there is a default prop involved the value of the // default property may infact be void so the type will also be SbxEMPTY @@ -908,6 +932,19 @@ void SbiRuntime::StepARRAYACCESS() PushVar( CheckArray( refVar ) ); } +void SbiRuntime::StepBYVAL() +{ + // Copy variable on stack to break call by reference + SbxVariableRef pVar = PopVar(); + SbxDataType t = pVar->GetType(); + + SbxVariable* pCopyVar = new SbxVariable( t ); + pCopyVar->SetFlag( SBX_READWRITE ); + *pCopyVar = *pVar; + + PushVar( pCopyVar ); +} + // Einrichten eines Argvs // nOp1 bleibt so -> 1. Element ist Returnwert diff --git a/basic/source/runtime/step1.cxx b/basic/source/runtime/step1.cxx index c6f090048bf2..e23ef864218e 100644 --- a/basic/source/runtime/step1.cxx +++ b/basic/source/runtime/step1.cxx @@ -453,9 +453,9 @@ bool SbiRuntime::implIsClass( SbxObject* pObj, const String& aClass ) } bool SbiRuntime::checkClass_Impl( const SbxVariableRef& refVal, - const String& aClass, bool bRaiseErrors ) + const String& aClass, bool bRaiseErrors, bool bDefault ) { - bool bOk = true; + bool bOk = bDefault; SbxDataType t = refVal->GetType(); if( t == SbxOBJECT ) @@ -489,6 +489,8 @@ bool SbiRuntime::checkClass_Impl( const SbxVariableRef& refVal, } else { + bOk = true; + SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pObj); if( pClassModuleObject != NULL ) pClassModuleObject->triggerInitializeEvent(); @@ -532,7 +534,8 @@ void SbiRuntime::StepTESTCLASS( UINT32 nOp1 ) { SbxVariableRef xObjVal = PopVar(); String aClass( pImg->GetString( static_cast<short>( nOp1 ) ) ); - bool bOk = checkClass_Impl( xObjVal, aClass, false ); + bool bDefault = !bVBAEnabled; + bool bOk = checkClass_Impl( xObjVal, aClass, false, bDefault ); SbxVariable* pRet = new SbxVariable; pRet->PutBool( bOk ); diff --git a/basic/source/runtime/step2.cxx b/basic/source/runtime/step2.cxx index 3a260ad203a3..72ea67dd8db4 100644 --- a/basic/source/runtime/step2.cxx +++ b/basic/source/runtime/step2.cxx @@ -1068,9 +1068,17 @@ void SbiRuntime::StepTCREATE( UINT32 nOp1, UINT32 nOp2 ) pCopyObj->SetName( aName ); SbxVariable* pNew = new SbxVariable; pNew->PutObject( pCopyObj ); + pNew->SetDeclareClassName( aClass ); PushVar( pNew ); } +void SbiRuntime::implCreateFixedString( SbxVariable* pStrVar, UINT32 nOp2 ) +{ + USHORT nCount = static_cast<USHORT>( nOp2 >> 17 ); // len = all bits above 0x10000 + String aStr; + aStr.Fill( nCount, 0 ); + pStrVar->PutString( aStr ); +} // Einrichten einer lokalen Variablen (+StringID+Typ) @@ -1081,9 +1089,15 @@ void SbiRuntime::StepLOCAL( UINT32 nOp1, UINT32 nOp2 ) String aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); if( refLocals->Find( aName, SbxCLASS_DONTCARE ) == NULL ) { - SbxDataType t = (SbxDataType) nOp2; + SbxDataType t = (SbxDataType)(nOp2 & 0xffff); SbxVariable* p = new SbxVariable( t ); p->SetName( aName ); + bool bWithEvents = ((t & 0xff) == SbxOBJECT && (nOp2 & SBX_TYPE_WITH_EVENTS_FLAG) != 0); + if( bWithEvents ) + p->SetFlag( SBX_WITH_EVENTS ); + bool bFixedString = ((t & 0xff) == SbxSTRING && (nOp2 & SBX_FIXED_LEN_STRING_FLAG) != 0); + if( bFixedString ) + implCreateFixedString( p, nOp2 ); refLocals->Put( p, refLocals->Count() ); } } @@ -1093,7 +1107,7 @@ void SbiRuntime::StepLOCAL( UINT32 nOp1, UINT32 nOp2 ) void SbiRuntime::StepPUBLIC_Impl( UINT32 nOp1, UINT32 nOp2, bool bUsedForClassModule ) { String aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); - SbxDataType t = (SbxDataType) nOp2; + SbxDataType t = (SbxDataType)(SbxDataType)(nOp2 & 0xffff);; BOOL bFlag = pMod->IsSet( SBX_NO_MODIFY ); pMod->SetFlag( SBX_NO_MODIFY ); SbxVariableRef p = pMod->Find( aName, SbxCLASS_PROPERTY ); @@ -1109,6 +1123,13 @@ void SbiRuntime::StepPUBLIC_Impl( UINT32 nOp1, UINT32 nOp2, bool bUsedForClassMo pProp->SetFlag( SBX_DONTSTORE ); // AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden' pProp->SetFlag( SBX_NO_MODIFY); + + bool bWithEvents = ((t & 0xff) == SbxOBJECT && (nOp2 & SBX_TYPE_WITH_EVENTS_FLAG) != 0); + if( bWithEvents ) + pProp->SetFlag( SBX_WITH_EVENTS ); + bool bFixedString = ((t & 0xff) == SbxSTRING && (nOp2 & SBX_FIXED_LEN_STRING_FLAG) != 0); + if( bFixedString ) + implCreateFixedString( p, nOp2 ); } } @@ -1122,7 +1143,10 @@ void SbiRuntime::StepPUBLIC_P( UINT32 nOp1, UINT32 nOp2 ) // Creates module variable that isn't reinitialised when // between invocations ( for VBASupport & document basic only ) if( pMod->pImage->bFirstInit ) - StepPUBLIC( nOp1, nOp2 ); + { + bool bUsedForClassModule = pImg->GetFlag( SBIMG_CLASSMODULE ); + StepPUBLIC_Impl( nOp1, nOp2, bUsedForClassModule ); + } } // Einrichten einer globalen Variablen (+StringID+Typ) @@ -1133,7 +1157,7 @@ void SbiRuntime::StepGLOBAL( UINT32 nOp1, UINT32 nOp2 ) StepPUBLIC_Impl( nOp1, nOp2, true ); String aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); - SbxDataType t = (SbxDataType) nOp2; + SbxDataType t = (SbxDataType)(SbxDataType)(nOp2 & 0xffff);; BOOL bFlag = rBasic.IsSet( SBX_NO_MODIFY ); rBasic.SetFlag( SBX_NO_MODIFY ); SbxVariableRef p = rBasic.Find( aName, SbxCLASS_PROPERTY ); diff --git a/basic/source/runtime/wnt-mingw.s b/basic/source/runtime/wnt-mingw.s index 1168804102d0..7868ddd386f0 100644 --- a/basic/source/runtime/wnt-mingw.s +++ b/basic/source/runtime/wnt-mingw.s @@ -1,7 +1,7 @@ #************************************************************************* # # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# +# # Copyright 2000, 2010 Oracle and/or its affiliates. # # OpenOffice.org - a multi-platform office productivity suite @@ -23,71 +23,31 @@ # <http://www.openoffice.org/license.html> # for a copy of the LGPLv3 License. # -#************************************************************************* - -# Anmerkungen -# Direktaufruf von C- und PASCAL-Routinen, Windows und OS/2 -# -# Inhalt: -# type = CallXXX (far *pProc, char *pStack, short nStack) -# -# Kopie des Basic-Stacks (nStack Bytes) auf den C-Stack -# und Aufruf der Prozedur. - - .intel_syntax - #.386 - -#_TEXT SEGMENT DWORD PUBLIC 'CODE' USE32 - - #ASSUME CS:_TEXT - -.globl _CallINT -.globl _CallLNG -.globl _CallDBL -.globl _CallSTR -.globl _CallFIX - -_CallINT: -_CallLNG: -_CallDBL: -_CallSTR: - -_CallFIX: PUSH EBP - MOV EBP,ESP - PUSH ESI - PUSH EDI - - PUSH ECX - PUSH EDX - - MOV DX,DS - MOVZX EAX,WORD PTR [EBP+16] # EAX == nStack - SUB ESP,EAX # Stack um nStack Bytes vergroessern - MOV EDI,ESP - MOV AX,SS - MOV ES,AX # ES:EDI = Startadresse des fuer - # Parameter reservierten Stackbereichs - MOV ESI,[EBP+12] # DS:ESI == pStack - - MOVZX ECX,WORD PTR [EBP+16] # ECX == nStack - SHR ECX,1 - CLD - JCXZ $1 - REP MOVSW # Stack uebernehmen -$1: MOV DS,DX - CALL DWORD PTR [EBP+8] # Aufruf der Prozedur - # CLI # unter NT nicht erlaubt (privileged instruction) - MOV ESP,EBP - SUB ESP,16 # wegen gepushter Register - # (ESI, EDI) - # STI - POP EDX - POP ECX - POP EDI - POP ESI - POP EBP - RET 12 - -#_TEXT ENDS - - #END +#***********************************************************************/ + +.intel_syntax + +.globl _DllMgr_call32 +.globl _DllMgr_callFp + +_DllMgr_call32: +_DllMgr_callFp: + push ebp + mov ebp, esp + push esi + push edi + mov ecx, [ebp+16] + jecxz $1 + sub esp, ecx + mov edi, esp + mov esi, [ebp+12] + shr ecx, 2 + rep movsd +$1: call DWORD PTR [ebp+8] + ; for extra safety, do not trust esp after call (in case the Basic Declare + ; signature is wrong): + mov edi, [ebp-8] + mov esi, [ebp-4] + mov esp, ebp + pop ebp + ret 12 diff --git a/basic/source/runtime/wnt.asm b/basic/source/runtime/wnt.asm index 3824daae964b..2a8710e34243 100644 --- a/basic/source/runtime/wnt.asm +++ b/basic/source/runtime/wnt.asm @@ -1,7 +1,7 @@ ;************************************************************************* ; ; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -; +; ; Copyright 2000, 2010 Oracle and/or its affiliates. ; ; OpenOffice.org - a multi-platform office productivity suite @@ -23,70 +23,34 @@ ; <http://www.openoffice.org/license.html> ; for a copy of the LGPLv3 License. ; -;************************************************************************* - -; Anmerkungen -; Direktaufruf von C- und PASCAL-Routinen, Windows und OS/2 -; -; Inhalt: -; type = CallXXX (far *pProc, char *pStack, short nStack) -; -; Kopie des Basic-Stacks (nStack Bytes) auf den C-Stack -; und Aufruf der Prozedur. - - .386 - -_TEXT SEGMENT DWORD PUBLIC 'CODE' USE32 - - ASSUME CS:_TEXT - - PUBLIC _CallINT@12 - PUBLIC _CallLNG@12 - PUBLIC _CallDBL@12 - PUBLIC _CallSTR@12 - PUBLIC _CallFIX@12 - -_CallINT@12 LABEL byte -_CallLNG@12 LABEL byte -_CallDBL@12 LABEL byte -_CallSTR@12 LABEL byte - -_CallFIX@12: PUSH EBP - MOV EBP,ESP - PUSH ESI - PUSH EDI - - PUSH ECX - PUSH EDX - - MOV DX,DS - MOVZX EAX,WORD PTR [EBP+16] ; EAX == nStack - SUB ESP,EAX ; Stack um nStack Bytes vergroessern - MOV EDI,ESP - MOV AX,SS - MOV ES,AX ; ES:EDI = Startadresse des fuer - ; Parameter reservierten Stackbereichs - MOV ESI,[EBP+12] ; DS:ESI == pStack - - MOVZX ECX,WORD PTR [EBP+16] ; ECX == nStack - SHR ECX,1 - CLD - JCXZ $1 - REP MOVSW ; Stack uebernehmen -$1: MOV DS,DX - CALL DWORD PTR [EBP+8] ; Aufruf der Prozedur - ; CLI ; unter NT nicht erlaubt (privileged instruction) - MOV ESP,EBP - SUB ESP,16 ; wegen gepushter Register - ; (ESI, EDI) - ; STI - POP EDX - POP ECX - POP EDI - POP ESI - POP EBP - RET 12 - -_TEXT ENDS - - END +;***********************************************************************/ + +.386 + +PUBLIC _DllMgr_call32@12 +PUBLIC _DllMgr_callFp@12 + +_TEXT SEGMENT +_DllMgr_call32@12: +_DllMgr_callFp@12: + push ebp + mov ebp, esp + push esi + push edi + mov ecx, [ebp+16] + jecxz $1 + sub esp, ecx + mov edi, esp + mov esi, [ebp+12] + shr ecx, 2 + rep movsd +$1: call DWORD PTR [ebp+8] + ; for extra safety, do not trust esp after call (in case the Basic Declare + ; signature is wrong): + mov edi, [ebp-8] + mov esi, [ebp-4] + mov esp, ebp + pop ebp + ret 12 +_TEXT ENDS +END diff --git a/basic/source/sbx/sbxvar.cxx b/basic/source/sbx/sbxvar.cxx index 9a83fb7ba578..20060f1f7493 100644 --- a/basic/source/sbx/sbxvar.cxx +++ b/basic/source/sbx/sbxvar.cxx @@ -39,6 +39,9 @@ #include <math.h> #include <ctype.h> +#include "com/sun/star/uno/XInterface.hpp" +using namespace com::sun::star::uno; + ///////////////////////////// SbxVariable ////////////////////////////// TYPEINIT1(SbxVariable,SbxValue) @@ -49,10 +52,28 @@ extern UINT32 nVarCreator; // in SBXBASE.CXX, fuer LoadData() static ULONG nVar = 0; #endif +///////////////////////////// SbxVariableImpl //////////////////////////// + +class SbxVariableImpl +{ + friend class SbxVariable; + String m_aDeclareClassName; + Reference< XInterface > m_xComListener; + + SbxVariableImpl( void ) + {} + SbxVariableImpl( const SbxVariableImpl& r ) + : m_aDeclareClassName( r.m_aDeclareClassName ) + , m_xComListener( r.m_xComListener ) + {} +}; + + ///////////////////////////// Konstruktoren ////////////////////////////// SbxVariable::SbxVariable() : SbxValue() { + mpSbxVariableImpl = NULL; pCst = NULL; pParent = NULL; nUserData = 0; @@ -66,6 +87,9 @@ SbxVariable::SbxVariable() : SbxValue() SbxVariable::SbxVariable( const SbxVariable& r ) : SvRefBase( r ), SbxValue( r ), mpPar( r.mpPar ), pInfo( r.pInfo ) { + mpSbxVariableImpl = NULL; + if( r.mpSbxVariableImpl != NULL ) + mpSbxVariableImpl = new SbxVariableImpl( *r.mpSbxVariableImpl ); pCst = NULL; if( r.CanRead() ) { @@ -91,6 +115,7 @@ SbxVariable::SbxVariable( const SbxVariable& r ) SbxVariable::SbxVariable( SbxDataType t, void* p ) : SbxValue( t, p ) { + mpSbxVariableImpl = NULL; pCst = NULL; pParent = NULL; nUserData = 0; @@ -111,6 +136,7 @@ SbxVariable::~SbxVariable() maName.AssignAscii( aCellsStr, sizeof( aCellsStr )-1 ); GetSbxData_Impl()->aVars.Remove( this ); #endif + delete mpSbxVariableImpl; delete pCst; } @@ -287,6 +313,11 @@ USHORT SbxVariable::MakeHashCode( const XubString& rName ) SbxVariable& SbxVariable::operator=( const SbxVariable& r ) { SbxValue::operator=( r ); + delete mpSbxVariableImpl; + if( r.mpSbxVariableImpl != NULL ) + mpSbxVariableImpl = new SbxVariableImpl( *r.mpSbxVariableImpl ); + else + mpSbxVariableImpl = NULL; return *this; } @@ -346,6 +377,32 @@ void SbxVariable::SetParent( SbxObject* p ) pParent = p; } +SbxVariableImpl* SbxVariable::getImpl( void ) +{ + if( mpSbxVariableImpl == NULL ) + mpSbxVariableImpl = new SbxVariableImpl(); + return mpSbxVariableImpl; +} + +const String& SbxVariable::GetDeclareClassName( void ) +{ + SbxVariableImpl* pImpl = getImpl(); + return pImpl->m_aDeclareClassName; +} + +void SbxVariable::SetDeclareClassName( const String& rDeclareClassName ) +{ + SbxVariableImpl* pImpl = getImpl(); + pImpl->m_aDeclareClassName = rDeclareClassName; +} + +void SbxVariable::SetComListener( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xComListener ) +{ + SbxVariableImpl* pImpl = getImpl(); + pImpl->m_xComListener = xComListener; +} + + ////////////////////////////// Laden/Speichern ///////////////////////////// BOOL SbxVariable::LoadData( SvStream& rStrm, USHORT nVer ) diff --git a/basic/source/uno/dlgcont.cxx b/basic/source/uno/dlgcont.cxx index 051b4fa9f077..004b61fbf198 100644 --- a/basic/source/uno/dlgcont.cxx +++ b/basic/source/uno/dlgcont.cxx @@ -187,12 +187,13 @@ bool writeOasis2OOoLibraryElement( void SAL_CALL SfxDialogLibraryContainer::writeLibraryElement ( - Any aElement, - const OUString& /*aElementName*/, - Reference< XOutputStream > xOutput + const Reference < XNameContainer >& xLib, + const OUString& aElementName, + const Reference< XOutputStream >& xOutput ) throw(Exception) { + Any aElement = xLib->getByName( aElementName ); Reference< XInputStreamProvider > xISP; aElement >>= xISP; if( !xISP.is() ) @@ -256,7 +257,9 @@ void SfxDialogLibraryContainer::storeLibrariesToStorage( const uno::Reference< e Any SAL_CALL SfxDialogLibraryContainer::importLibraryElement - ( const OUString& aFile, const uno::Reference< io::XInputStream >& xElementStream ) + ( const Reference < XNameContainer >& /*xLib*/, + const OUString& /*aElementName */, const OUString& aFile, + const uno::Reference< io::XInputStream >& xElementStream ) { Any aRetAny; diff --git a/basic/source/uno/namecont.cxx b/basic/source/uno/namecont.cxx index 90e7cb4cb4d5..f692277fc5ba 100644 --- a/basic/source/uno/namecont.cxx +++ b/basic/source/uno/namecont.cxx @@ -1369,8 +1369,8 @@ void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib, OUString aStreamName = aElementName; aStreamName += String( RTL_CONSTASCII_USTRINGPARAM(".xml") ); - Any aElement = pLib->getByName( aElementName ); - if( !isLibraryElementValid( aElement ) ) + /*Any aElement = pLib->getByName( aElementName );*/ + if( !isLibraryElementValid( pLib->getByName( aElementName ) ) ) { #if OSL_DEBUG_LEVEL > 0 ::rtl::OStringBuffer aMessage; @@ -1406,7 +1406,8 @@ void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib, xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) ); Reference< XOutputStream > xOutput = xElementStream->getOutputStream(); - writeLibraryElement( aElement, aElementName, xOutput ); + Reference< XNameContainer > xLib( pLib ); + writeLibraryElement( xLib, aElementName, xOutput ); // writeLibraryElement closes the stream // xOutput->closeOutput(); } @@ -1458,8 +1459,8 @@ void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib, aElementInetObj.setExtension( maLibElementFileExtension ); String aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) ); - Any aElement = pLib->getByName( aElementName ); - if( !isLibraryElementValid( aElement ) ) + /*Any aElement = pLib->getByName( aElementName );*/ + if( !isLibraryElementValid( pLib->getByName( aElementName ) ) ) { #if OSL_DEBUG_LEVEL > 0 ::rtl::OStringBuffer aMessage; @@ -1477,7 +1478,8 @@ void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib, if( xSFI->exists( aElementPath ) ) xSFI->kill( aElementPath ); Reference< XOutputStream > xOutput = xSFI->openFileWrite( aElementPath ); - writeLibraryElement( aElement, aElementName, xOutput ); + Reference< XNameContainer > xLib( pLib ); + writeLibraryElement( xLib, aElementName, xOutput ); xOutput->closeOutput(); } catch( Exception& ) @@ -2380,7 +2382,9 @@ void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name ) aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ); } - Any aAny = importLibraryElement( aFile, xInStream ); + Reference< XNameContainer > xLib( pImplLib ); + Any aAny = importLibraryElement( xLib, aElementName, + aFile, xInStream ); if( pImplLib->hasByName( aElementName ) ) { if( aAny.hasValue() ) diff --git a/basic/source/uno/scriptcont.cxx b/basic/source/uno/scriptcont.cxx index 4185b6f9579c..5622adc19af1 100644 --- a/basic/source/uno/scriptcont.cxx +++ b/basic/source/uno/scriptcont.cxx @@ -41,6 +41,7 @@ #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/embed/XTransactedObject.hpp> #include <com/sun/star/task/ErrorCodeIOException.hpp> +#include <com/sun/star/script/ModuleType.hpp> #include <comphelper/processfactory.hxx> #ifndef _COMPHELPER_STORAGEHELPER_HXX_ #include <comphelper/storagehelper.hxx> @@ -60,6 +61,7 @@ #include <svtools/ehdl.hxx> #include <basic/basmgr.hxx> #include <basic/sbmod.hxx> +#include <basic/basicmanagerrepository.hxx> #include "modsizeexceeded.hxx" #include <xmlscript/xmlmod_imexp.hxx> #include <cppuhelper/factory.hxx> @@ -184,9 +186,9 @@ bool SAL_CALL SfxScriptLibraryContainer::isLibraryElementValid( Any aElement ) c void SAL_CALL SfxScriptLibraryContainer::writeLibraryElement ( - Any aElement, + const Reference < XNameContainer >& xLib, const OUString& aElementName, - Reference< XOutputStream > xOutput + const Reference< XOutputStream >& xOutput ) throw(Exception) { @@ -211,13 +213,42 @@ void SAL_CALL SfxScriptLibraryContainer::writeLibraryElement xmlscript::ModuleDescriptor aMod; aMod.aName = aElementName; aMod.aLanguage = maScriptLanguage; + Any aElement = xLib->getByName( aElementName ); aElement >>= aMod.aCode; + + Reference < script::XVBAModuleInfo > xModInfo( xLib, UNO_QUERY ); + + if( xModInfo.is() && xModInfo->hasModuleInfo( aElementName ) ) + { + script::ModuleInfo aModInfo = xModInfo->getModuleInfo( aElementName ); + switch( aModInfo.ModuleType ) + { + case ModuleType::NORMAL: + aMod.aModuleType = OUString( RTL_CONSTASCII_USTRINGPARAM("normal") ); + break; + case ModuleType::CLASS: + aMod.aModuleType = OUString( RTL_CONSTASCII_USTRINGPARAM("class") ); + break; + case ModuleType::FORM: + aMod.aModuleType = OUString( RTL_CONSTASCII_USTRINGPARAM("form") ); + break; + case ModuleType::DOCUMENT: + aMod.aModuleType = OUString( RTL_CONSTASCII_USTRINGPARAM("document") ); + break; + case ModuleType::UNKNOWN: + // nothing + break; + } + } + xmlscript::exportScriptModule( xHandler, aMod ); } Any SAL_CALL SfxScriptLibraryContainer::importLibraryElement - ( const OUString& aFile, const uno::Reference< io::XInputStream >& xInStream ) + ( const Reference < XNameContainer >& xLib, + const OUString& aElementName, const OUString& aFile, + const uno::Reference< io::XInputStream >& xInStream ) { Any aRetAny; @@ -279,6 +310,86 @@ Any SAL_CALL SfxScriptLibraryContainer::importLibraryElement // TODO: Check language // aMod.aLanguage // aMod.aName ignored + if( aMod.aModuleType.getLength() > 0 ) + { + if( !getVBACompatModeOn() ) + { + setVBACompatModeOn( sal_True ); + + Any aGlobs; + Sequence< Any > aArgs(1); + Reference<frame::XModel > xModel( mxOwnerDocument ); + aArgs[ 0 ] <<= xModel; + + BasicManager* pBasicMgr = getBasicManager(); + if( pBasicMgr ) + { + aGlobs <<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.Globals" ) ), aArgs ); + pBasicMgr->SetGlobalUNOConstant( "VBAGlobals", aGlobs ); + } + pBasicMgr = BasicManagerRepository::getApplicationBasicManager( sal_False ); + if( pBasicMgr ) + pBasicMgr->SetGlobalUNOConstant( "ThisExcelDoc", aArgs[0] ); + } + + script::ModuleInfo aModInfo; + aModInfo.ModuleType = ModuleType::UNKNOWN; + if( aMod.aModuleType.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("normal") )) + { + aModInfo.ModuleType = ModuleType::NORMAL; + } + else if( aMod.aModuleType.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("class") )) + { + aModInfo.ModuleType = ModuleType::CLASS; + } + else if( aMod.aModuleType.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("form") )) + { + aModInfo.ModuleType = ModuleType::FORM; + aModInfo.ModuleObject = mxOwnerDocument; + } + else if( aMod.aModuleType.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("document") )) + { + aModInfo.ModuleType = ModuleType::DOCUMENT; + Reference<frame::XModel > xModel( mxOwnerDocument ); + Reference< XMultiServiceFactory> xSF( xModel, UNO_QUERY); + Reference< container::XNameAccess > xVBACodeNameAccess; + if( xSF.is() ) + { + try + { + xVBACodeNameAccess.set( xSF->createInstance( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "ooo.vba.VBAObjectModuleObjectProvider"))), + UNO_QUERY ); + } + catch(uno::Exception&) {} + } + if( xVBACodeNameAccess.is() ) + { + try + { + aModInfo.ModuleObject.set( xVBACodeNameAccess->getByName( aElementName), uno::UNO_QUERY ); + } + catch(uno::Exception&) + { + OSL_TRACE("Failed to get documument object for %s", rtl::OUStringToOString( aElementName, RTL_TEXTENCODING_UTF8 ).getStr() ); + } + } + } + + Reference< script::XVBAModuleInfo > xVBAModuleInfo( xLib, + UNO_QUERY ); + if( xVBAModuleInfo.is() ) + { + if( xVBAModuleInfo->hasModuleInfo( aElementName ) ) + xVBAModuleInfo->removeModuleInfo( aElementName ); + xVBAModuleInfo->insertModuleInfo( aElementName, aModInfo ); + } + } return aRetAny; } @@ -574,8 +685,8 @@ sal_Bool SfxScriptLibraryContainer::implStorePasswordLibrary( SfxLibrary* pLib, if( pLib->mbPasswordVerified || pLib->mbDoc50Password ) { - Any aElement = pLib->getByName( aElementName ); - if( !isLibraryElementValid( aElement ) ) + /*Any aElement = pLib->getByName( aElementName );*/ + if( !isLibraryElementValid( pLib->getByName( aElementName ) ) ) { #if OSL_DEBUG_LEVEL > 0 ::rtl::OStringBuffer aMessage; @@ -606,7 +717,8 @@ sal_Bool SfxScriptLibraryContainer::implStorePasswordLibrary( SfxLibrary* pLib, setStreamKey( xSourceStream, pLib->maPassword ); Reference< XOutputStream > xOutput = xSourceStream->getOutputStream(); - writeLibraryElement( aElement, aElementName, xOutput ); + Reference< XNameContainer > xLib( pLib ); + writeLibraryElement( xLib, aElementName, xOutput ); // writeLibraryElement should have the stream already closed // xOutput->closeOutput(); } @@ -659,8 +771,8 @@ sal_Bool SfxScriptLibraryContainer::implStorePasswordLibrary( SfxLibrary* pLib, aElementInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("pba") ) ); String aElementPath = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ); - Any aElement = pLib->getByName( aElementName ); - if( !isLibraryElementValid( aElement ) ) + /*Any aElement = pLib->getByName( aElementName );*/ + if( !isLibraryElementValid( pLib->getByName( aElementName ) ) ) { #if OSL_DEBUG_LEVEL > 0 ::rtl::OStringBuffer aMessage; @@ -741,7 +853,8 @@ sal_Bool SfxScriptLibraryContainer::implStorePasswordLibrary( SfxLibrary* pLib, xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) ); Reference< XOutputStream > xOut = xSourceStream->getOutputStream(); - writeLibraryElement( aElement, aElementName, xOut ); + Reference< XNameContainer > xLib( pLib ); + writeLibraryElement( xLib, aElementName, xOut ); // i50568: sax writer already closes stream // xOut->closeOutput(); @@ -903,7 +1016,10 @@ sal_Bool SfxScriptLibraryContainer::implLoadPasswordLibrary if ( !xInStream.is() ) throw io::IOException(); // read access denied, seems to be impossible - Any aAny = importLibraryElement( aSourceStreamName, xInStream ); + Reference< XNameContainer > xLib( pLib ); + Any aAny = importLibraryElement( xLib, + aElementName, aSourceStreamName, + xInStream ); if( pLib->hasByName( aElementName ) ) { if( aAny.hasValue() ) @@ -1006,7 +1122,11 @@ sal_Bool SfxScriptLibraryContainer::implLoadPasswordLibrary if ( !xInStream.is() ) throw io::IOException(); // read access denied, seems to be impossible - Any aAny = importLibraryElement( aSourceStreamName, xInStream ); + Reference< XNameContainer > xLib( pLib ); + Any aAny = importLibraryElement( xLib, + aElementName, + aSourceStreamName, + xInStream ); if( pLib->hasByName( aElementName ) ) { if( aAny.hasValue() ) diff --git a/basic/util/makefile.mk b/basic/util/makefile.mk index 645c9b6a3ce8..629586f0441c 100644 --- a/basic/util/makefile.mk +++ b/basic/util/makefile.mk @@ -59,6 +59,7 @@ SHL1STDLIBS= \ $(VCLLIB) \ $(VOSLIB) \ $(SALLIB) \ + $(SALHELPERLIB) \ $(COMPHELPERLIB) \ $(UNOTOOLSLIB) \ $(SOTLIB) \ diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx index 4cc5306fec9f..d4e43363676f 100644 --- a/formula/source/core/api/FormulaCompiler.cxx +++ b/formula/source/core/api/FormulaCompiler.cxx @@ -493,7 +493,7 @@ void FormulaCompiler::OpCodeMap::putOpCode( const String & rStr, const OpCode eO DBG_ASSERT( 0 < eOp && USHORT(eOp) < mnSymbols, "OpCodeMap::putOpCode: OpCode out of range"); if (0 < eOp && USHORT(eOp) < mnSymbols) { - DBG_ASSERT( (mpTable[eOp].Len() == 0) || (mpTable[eOp] == rStr), + DBG_ASSERT( (mpTable[eOp].Len() == 0) || (mpTable[eOp] == rStr) || (eOp == ocCurrency), ByteString( "OpCodeMap::putOpCode: reusing OpCode "). Append( ByteString::CreateFromInt32( sal_Int32( eOp))).Append( " ("). Append( ByteString( rStr, RTL_TEXTENCODING_ASCII_US)).Append( ')').GetBuffer()); diff --git a/oovbaapi/ooo/vba/XApplicationBase.idl b/oovbaapi/ooo/vba/XApplicationBase.idl index b42e456bd7eb..7f59ddb75247 100644 --- a/oovbaapi/ooo/vba/XApplicationBase.idl +++ b/oovbaapi/ooo/vba/XApplicationBase.idl @@ -38,19 +38,27 @@ module ooo { module vba { //============================================================================= + + interface XApplicationBase { interface ::ooo::vba::XHelperInterface; [attribute] boolean ScreenUpdating; [attribute] boolean DisplayStatusBar; + [attribute] boolean Interactive; [attribute, readonly] string Version; + //mbn + [attribute, readonly] any VBE; + [attribute, readonly] any VBProjects; void Quit(); any CommandBars( [in] any aIndex ); void Run([in] string MacroName, [in] /*Optional*/ any varg1, [in] /*Optional*/ any varg2, [in] /*Optional*/ any varg3, [in] /*Optional*/ any varg4, [in] /*Optional*/ any varg5, [in] /*Optional*/ any varg6, [in] /*Optional*/ any varg7, [in] /*Optional*/ any varg8, [in] /*Optional*/ any varg9, [in] /*Optional*/ any varg10, [in] /*Optional*/ any varg11, [in] /*Optional*/ any varg12, [in] /*Optional*/ any varg13, [in] /*Optional*/ any varg14, [in] /*Optional*/ any varg15, [in] /*Optional*/ any varg16, [in] /*Optional*/ any varg17, [in] /*Optional*/ any varg18, [in] /*Optional*/ any varg19, [in] /*Optional*/ any varg20, [in] /*Optional*/ any varg21, [in] /*Optional*/ any varg22, [in] /*Optional*/ any varg23, [in] /*Optional*/ any varg24, [in] /*Optional*/ any varg25, [in] /*Optional*/ any varg26, [in] /*Optional*/ any varg27, [in] /*Optional*/ any varg28, [in] /*Optional*/ any varg29, [in] /*Optional*/ any varg30); + void OnTime( [in] any aEarliestTime, [in] string aFunction, [in] any aLatestTime, [in] any aSchedule ); float CentimetersToPoints([in] float Centimeters ); + void Undo(); }; }; }; diff --git a/oovbaapi/ooo/vba/XCollection.idl b/oovbaapi/ooo/vba/XCollection.idl index 60971034bb5d..63982aab36d6 100644 --- a/oovbaapi/ooo/vba/XCollection.idl +++ b/oovbaapi/ooo/vba/XCollection.idl @@ -52,6 +52,7 @@ interface XCollection interface ::com::sun::star::container::XEnumerationAccess; [attribute, readonly] long Count; + any Item( [in] any Index1, [in] any Index2 ); }; diff --git a/oovbaapi/ooo/vba/XCommandBarControl.idl b/oovbaapi/ooo/vba/XCommandBarControl.idl index 2f89959cdaa0..7f20a6bf2c3f 100644 --- a/oovbaapi/ooo/vba/XCommandBarControl.idl +++ b/oovbaapi/ooo/vba/XCommandBarControl.idl @@ -48,6 +48,7 @@ interface XCommandBarControl [attribute] boolean Visible; [attribute, readonly] long Type; [attribute] boolean Enabled; + [attribute] boolean BeginGroup; void Delete() raises ( com::sun::star::script::BasicErrorException ); any Controls( [in] any Index ) raises ( com::sun::star::script::BasicErrorException ); diff --git a/oovbaapi/ooo/vba/XDocumentBase.idl b/oovbaapi/ooo/vba/XDocumentBase.idl index 12cb931987d6..a4ee8b4366c6 100644 --- a/oovbaapi/ooo/vba/XDocumentBase.idl +++ b/oovbaapi/ooo/vba/XDocumentBase.idl @@ -38,6 +38,8 @@ module ooo { module vba { //============================================================================= + + interface XDocumentBase { interface ::ooo::vba::XHelperInterface; @@ -46,6 +48,7 @@ interface XDocumentBase [attribute, readonly] string Path; [attribute, readonly] string FullName; [attribute] boolean Saved; + [attribute, readonly] any VBProject; // Michael E. Bohn void Close([in] any SaveChanges, [in] any FileName, [in] any RouteWorkBook); void Save(); diff --git a/oovbaapi/ooo/vba/excel/XApplication.idl b/oovbaapi/ooo/vba/excel/XApplication.idl index e4c063d161cf..39693a37511c 100644 --- a/oovbaapi/ooo/vba/excel/XApplication.idl +++ b/oovbaapi/ooo/vba/excel/XApplication.idl @@ -27,17 +27,10 @@ #ifndef __ooo_vba_excel_XApplication_idl__ #define __ooo_vba_excel_XApplication_idl__ -#ifndef __com_sun_star_uno_XInterface_idl__ -#include <com/sun/star/uno/XInterface.idl> -#endif - -#ifndef __ooo_vba_XHelperInterface_idl__ +#include <com/sun/star/beans/XExactName.idl> +#include <com/sun/star/script/XInvocation.idl> #include <ooo/vba/XHelperInterface.idl> -#endif - -#ifndef __ooo_vba_XAssistant_idl__ #include <ooo/vba/XAssistant.idl> -#endif module ooo { module vba { module excel { @@ -49,8 +42,11 @@ interface XWorksheetFunction; interface XWindow; interface XWorksheet; -interface XApplication : com::sun::star::uno::XInterface +interface XApplication { + // Application serves as WorksheetFunction object with little differences + interface ::com::sun::star::beans::XExactName; + interface ::com::sun::star::script::XInvocation; // interface ::ooo::vba::XHelperInterface; @@ -86,8 +82,7 @@ interface XApplication : com::sun::star::uno::XInterface any Range( [in] any Cell1, [in] any Cell2 ); any Names( [in] any Index ); void GoTo( [in] any Reference, [in] any Scroll ); - // #FIXME #TODO up to 30 args needed - double CountA( [in] any arg1 ); + void wait( [in] double time ); void Calculate() raises(com::sun::star::script::BasicErrorException); XRange Intersect([in] XRange Arg1, [in] XRange Arg2, [in] /*Optional*/ any Arg3, [in] /*Optional*/ any Arg4, [in] /*Optional*/ any Arg5, [in] /*Optional*/ any Arg6, [in] /*Optional*/ any Arg7, [in] /*Optional*/ any Arg8, [in] /*Optional*/ any Arg9, [in] /*Optional*/ any Arg10, [in] /*Optional*/ any Arg11, [in] /*Optional*/ any Arg12, [in] /*Optional*/ any Arg13, [in] /*Optional*/ any Arg14, [in] /*Optional*/ any Arg15, [in] /*Optional*/ any Arg16, [in] /*Optional*/ any Arg17, [in] /*Optional*/ any Arg18, [in] /*Optional*/ any Arg19, [in] /*Optional*/ any Arg20, [in] /*Optional*/ any Arg21, [in] /*Optional*/ any Arg22, [in] /*Optional*/ any Arg23, [in] /*Optional*/ any Arg24, [in] /*Optional*/ any Arg25, [in] /*Optional*/ any Arg26, [in] /*Optional*/ any Arg27, [in] /*Optional*/ any Arg28, [in] /*Optional*/ any Arg29, [in] /*Optional*/ any Arg30) diff --git a/oovbaapi/ooo/vba/excel/XComment.idl b/oovbaapi/ooo/vba/excel/XComment.idl index 9f333cfd9542..8b811f31cc41 100644 --- a/oovbaapi/ooo/vba/excel/XComment.idl +++ b/oovbaapi/ooo/vba/excel/XComment.idl @@ -27,15 +27,8 @@ #ifndef __ooo_vba_excel_XComment_idl__ #define __ooo_vba_excel_XComment_idl__ -#ifndef __com_sun_star_uno_XInterface_idl__ -#include <com/sun/star/uno/XInterface.idl> -#endif -#ifndef __com_sun_star_lang_IllegalArgumentException_idl__ -#include <com/sun/star/lang/IllegalArgumentException.idl> -#endif -#ifndef __ooo_vba_XHelperInterface_idl__ -#include <ooo/vba/XHelperInterface.idl> -#endif +#include <ooo/vba/msforms/XShape.idl> + //============================================================================= module ooo { module vba { module excel { @@ -48,7 +41,7 @@ interface XComment interface ::ooo::vba::XHelperInterface; [attribute] string Author; -// [attribute, readonly] Shape Shape; + [attribute, readonly] ooo::vba::msforms::XShape Shape; [attribute] boolean Visible; void Delete(); diff --git a/oovbaapi/ooo/vba/excel/XHyperlink.idl b/oovbaapi/ooo/vba/excel/XHyperlink.idl index 32fd985a4a37..1f6f9d23bfa6 100644 --- a/oovbaapi/ooo/vba/excel/XHyperlink.idl +++ b/oovbaapi/ooo/vba/excel/XHyperlink.idl @@ -27,31 +27,38 @@ #ifndef __ooo_vba_excel_XHyperlink_idl__ #define __ooo_vba_excel_XHyperlink_idl__ -#ifndef __com_sun_star_uno_XInterface_idl__ -#include <com/sun/star/uno/XInterface.idl> -#endif - -#ifndef __ooo_vba_XHelperInterface_idl__ #include <ooo/vba/XHelperInterface.idl> -#endif //============================================================================= +module ooo { module vba { module msforms { + interface XShape; +}; }; }; + module ooo { module vba { module excel { -//============================================================================= interface XRange; + +//============================================================================= + interface XHyperlink { interface ::ooo::vba::XHelperInterface; - [attribute] string Address; [attribute] string Name; + [attribute] string Address; + [attribute] string SubAddress; + [attribute] string ScreenTip; [attribute] string TextToDisplay; - - XRange Range(); + [attribute, readonly] long Type; + [attribute, readonly] XRange Range; + [attribute, readonly] ooo::vba::msforms::XShape Shape; }; +//============================================================================= + }; }; }; +//============================================================================= + #endif diff --git a/oovbaapi/ooo/vba/excel/XPane.idl b/oovbaapi/ooo/vba/excel/XPane.idl index acc5520bb9ea..ac9ec2e3ca08 100644 --- a/oovbaapi/ooo/vba/excel/XPane.idl +++ b/oovbaapi/ooo/vba/excel/XPane.idl @@ -27,9 +27,7 @@ #ifndef __com_sun_star_helper_XPane_idl__ #define __com_sun_star_helper_XPane_idl__ -#ifndef __com_sun_star_uno_XInterface_idl__ #include <com/sun/star/uno/XInterface.idl> -#endif //============================================================================ @@ -37,10 +35,13 @@ module ooo { module vba { module excel { //============================================================================ -interface XPane: com::sun::star::uno::XInterface +interface XRange; + +interface XPane : com::sun::star::uno::XInterface { [attribute] long ScrollColumn; [attribute] long ScrollRow; + [attribute, readonly] XRange VisibleRange; void SmallScroll([in] /*Optional*/ any Down, [in] /*Optional*/ any Up, [in] /*Optional*/ any ToRight, [in] /*Optional*/ any ToLeft); void LargeScroll([in] /*Optional*/ any Down, [in] /*Optional*/ any Up, [in] /*Optional*/ any ToRight, [in] /*Optional*/ any ToLeft); diff --git a/oovbaapi/ooo/vba/excel/XRange.idl b/oovbaapi/ooo/vba/excel/XRange.idl index 5eb1913fc40a..3820911f2c96 100644 --- a/oovbaapi/ooo/vba/excel/XRange.idl +++ b/oovbaapi/ooo/vba/excel/XRange.idl @@ -98,6 +98,7 @@ interface XRange [attribute, readonly ] any Left; [attribute] any PageBreak; [attribute, readonly] XValidation Validation; + [attribute, readonly] any PrefixCharacter; [attribute] any Style; [attribute] any AddIndent; [attribute] any ShowDetail; @@ -164,7 +165,7 @@ interface XRange void RemoveSubtotal() raises ( com::sun::star::script::BasicErrorException ); void Subtotal( [in] long GroupBy, [in] long Function, [in] /*Optional*/ sequence<long> TotalList, [in] /*Optional*/ any Replace, [in] /*Optional*/ any PageBreaks, [in] any SummaryBelowData ) raises ( com::sun::star::script::BasicErrorException ); XRange MergeArea( ) raises ( com::sun::star::script::BasicErrorException ); - + any Hyperlinks( [in] any aIndex ); }; //============================================================================= diff --git a/oovbaapi/ooo/vba/excel/XWindow.idl b/oovbaapi/ooo/vba/excel/XWindow.idl index 0ac2271a32d6..dde7818ebda7 100644 --- a/oovbaapi/ooo/vba/excel/XWindow.idl +++ b/oovbaapi/ooo/vba/excel/XWindow.idl @@ -27,22 +27,18 @@ #ifndef __ooo_vba_excel_XWindow_idl__ #define __ooo_vba_excel_XWindow_idl__ -#ifndef __com_sun_star_uno_XInterface_idl__ -#include <com/sun/star/uno/XInterface.idl> -#endif - -#ifndef __ooo_vba_XHelperInterface_idl__ #include <ooo/vba/XHelperInterface.idl> -#endif //============================================================================= module ooo { module vba { module excel { //============================================================================= + interface XRange; interface XWorksheet; interface XPane; + interface XWindow : com::sun::star::uno::XInterface { [attribute] any Caption; @@ -61,6 +57,7 @@ interface XWindow : com::sun::star::uno::XInterface [attribute] any ScrollColumn; [attribute] any ScrollRow; [attribute] any View; + [attribute, readonly] XRange VisibleRange; [attribute] any WindowState; [attribute] any Zoom; any SelectedSheets( [in] any aIndex ); @@ -71,6 +68,7 @@ interface XWindow : com::sun::star::uno::XInterface void Close([in] any SaveChanges, [in] any FileName, [in] any RouteWorkBook); XRange ActiveCell() raises(com::sun::star::script::BasicErrorException); any Selection() raises(com::sun::star::script::BasicErrorException); + XRange RangeSelection() raises(com::sun::star::script::BasicErrorException); long PointsToScreenPixelsX([in] long Points) raises(com::sun::star::script::BasicErrorException); long PointsToScreenPixelsY([in] long Points) raises(com::sun::star::script::BasicErrorException); void PrintOut([in] /*optional short*/ any From, diff --git a/oovbaapi/ooo/vba/excel/XWorksheet.idl b/oovbaapi/ooo/vba/excel/XWorksheet.idl index 3620c899de83..271cd81d4d0e 100644 --- a/oovbaapi/ooo/vba/excel/XWorksheet.idl +++ b/oovbaapi/ooo/vba/excel/XWorksheet.idl @@ -83,6 +83,8 @@ interface XWorksheet void Protect([in] any Password,[in] any DrawingObjects ,[in] any Contents,[in] any Scenarios,[in] any UserInterfaceOnly); void Unprotect([in] any Password ); void CheckSpelling([in] any CustomDictionary,[in] any IgnoreUppercase, [in] any AlwaysSuggest,[in] any SpellingLang ); + void ShowDataForm(); + XRange Range([in] any Cell1, [in] any Cell2 ); any ChartObjects([in] any Index); any PivotTables([in] any Index); @@ -92,23 +94,32 @@ interface XWorksheet any HPageBreaks([in] any Index); any VPageBreaks([in] any Index); any OLEObjects([in] any Index); - void ShowDataForm(); any Shapes([in] any Index); + /* The following form control related symbols do not refer to ActiveX form + controls embedded in the sheet, but to the old-style drawing controls + of Excel. This is an Excel-only feature. */ + any Buttons( [in] any aIndex ); + any CheckBoxes( [in] any aIndex ); + any DropDowns( [in] any aIndex ); + any GroupBoxes( [in] any aIndex ); + any Labels( [in] any aIndex ); + any ListBoxes( [in] any aIndex ); + any OptionButtons( [in] any aIndex ); + any ScrollBars( [in] any aIndex ); + any Spinners( [in] any aIndex ); // FIXME: should prolly inherit from Range somehow... XRange Cells([in] any RowIndex, [in] any ColumnIndex); XRange Rows([in] any aIndex); XRange Columns([in] any aIndex); + any Hyperlinks( [in] any aIndex ); any Evaluate( [in] string Name); - void setEnableCalculation([in] boolean EnableCalculation) raises(com::sun::star::script::BasicErrorException); boolean getEnableCalculation() raises(com::sun::star::script::BasicErrorException); void PrintOut( [in] any From, [in] any To, [in] any Copies, [in] any Preview, [in] any ActivePrinter, [in] any PrintToFile, [in] any Collate, [in] any PrToFileName, [in] any IgnorePrintAreas ); - - }; //============================================================================= @@ -116,5 +127,3 @@ interface XWorksheet }; }; }; #endif - - diff --git a/oovbaapi/ooo/vba/excel/makefile.mk b/oovbaapi/ooo/vba/excel/makefile.mk index 01e26d4cb19b..12dcf025e489 100644 --- a/oovbaapi/ooo/vba/excel/makefile.mk +++ b/oovbaapi/ooo/vba/excel/makefile.mk @@ -39,6 +39,8 @@ PACKAGE=ooo$/vba$/Excel IDLFILES= XGlobals.idl\ Globals.idl\ + SheetObject.idl\ + SheetObjects.idl\ XApplication.idl\ XComment.idl\ XComments.idl\ @@ -92,6 +94,7 @@ IDLFILES= XGlobals.idl\ Window.idl \ XHyperlink.idl \ Hyperlink.idl \ + XHyperlinks.idl \ XPageSetup.idl \ XPageBreak.idl \ XHPageBreak.idl \ diff --git a/oovbaapi/ooo/vba/makefile.mk b/oovbaapi/ooo/vba/makefile.mk index 7fc70303d942..75f6465bf4c0 100644 --- a/oovbaapi/ooo/vba/makefile.mk +++ b/oovbaapi/ooo/vba/makefile.mk @@ -1,4 +1,4 @@ -#************************************************************************* + #************************************************************************* # # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # @@ -62,7 +62,8 @@ IDLFILES=\ XDialogsBase.idl\ XDialogBase.idl\ XPageSetupBase.idl \ - + XVBAAppService.idl\ + XVBADocService.idl\ # ------------------------------------------------------------------ .ENDIF .INCLUDE : target.mk diff --git a/oovbaapi/ooo/vba/msforms/XControl.idl b/oovbaapi/ooo/vba/msforms/XControl.idl index 867fd564c9af..97ca9d152716 100644 --- a/oovbaapi/ooo/vba/msforms/XControl.idl +++ b/oovbaapi/ooo/vba/msforms/XControl.idl @@ -45,13 +45,16 @@ interface XControl { interface ::ooo::vba::XHelperInterface; void SetFocus(); + void Move( [in] double Left, [in] double Top, [in] any Width, [in] any Height ); + [attribute, readonly ] com::sun::star::uno::XInterface Object; [attribute] string ControlSource; [attribute] string RowSource; [attribute] boolean Enabled; [attribute] boolean Visible; //Size. there are some defferent between Mso and OOo. - //Mso use double but OOo use long. OOo 1 = 1/100mm but Mso use pt + //Mso use double but OOo use long. OOo 1 = 1/100mm but Mso use pt. + //in Dialogs Mso uses pixels [attribute] double Height; [attribute] double Width; //Postion @@ -59,6 +62,7 @@ interface XControl [attribute] double Top; [attribute] string Name; [attribute] string ControlTipText; + [attribute] string Tag; }; //============================================================================= diff --git a/oovbaapi/ooo/vba/msforms/XControls.idl b/oovbaapi/ooo/vba/msforms/XControls.idl index 00d8f16f9dd9..11325303d56c 100644 --- a/oovbaapi/ooo/vba/msforms/XControls.idl +++ b/oovbaapi/ooo/vba/msforms/XControls.idl @@ -41,6 +41,13 @@ interface XControls { interface ooo::vba::XCollection; void Move( [in] double cx, [in] double cy ); + + // the following two methods should be actually part of XCollection, but at least Add conflicts with + // methods in the derived from XCollection interfaces + // thus the methods are declared in the top-level interface + any Add( [in] any Object, [in] any StringKey, [in] any Before, [in] any After ); + void Remove( [in] any StringKeyOrIndex ); + }; }; }; }; diff --git a/oovbaapi/prj/d.lst b/oovbaapi/prj/d.lst index 1acd2acd5b4b..ac5924e2d684 100644 --- a/oovbaapi/prj/d.lst +++ b/oovbaapi/prj/d.lst @@ -1 +1,15 @@ +mkdir: %COMMON_DEST%\idl%_EXT%\ooo + +mkdir: %COMMON_DEST%\idl%_EXT%\ooo\vba +mkdir: %COMMON_DEST%\idl%_EXT%\ooo\vba\constants +mkdir: %COMMON_DEST%\idl%_EXT%\ooo\vba\excel +mkdir: %COMMON_DEST%\idl%_EXT%\ooo\vba\msforms +mkdir: %COMMON_DEST%\idl%_EXT%\ooo\vba\word + ..\%__SRC%\ucr\oovbaapi.db %_DEST%\bin%_EXT%\oovbaapi.rdb + +..\ooo\vba\*.idl %COMMON_DEST%\idl%_EXT%\ooo\vba\ +..\ooo\vba\constants\*.idl %COMMON_DEST%\idl%_EXT%\ooo\vba\constants +..\ooo\vba\excel\*.idl %COMMON_DEST%\idl%_EXT%\ooo\vba\excel +..\ooo\vba\msforms\*.idl %COMMON_DEST%\idl%_EXT%\ooo\vba\msforms +..\ooo\vba\word\*.idl %COMMON_DEST%\idl%_EXT%\ooo\vba\word diff --git a/vbahelper/inc/vbahelper/vbaapplicationbase.hxx b/vbahelper/inc/vbahelper/vbaapplicationbase.hxx index e72015413192..e2a5a3bff5da 100644 --- a/vbahelper/inc/vbahelper/vbaapplicationbase.hxx +++ b/vbahelper/inc/vbahelper/vbaapplicationbase.hxx @@ -34,8 +34,12 @@ typedef InheritedHelperInterfaceImpl1< ov::XApplicationBase > ApplicationBase_BASE; +struct VbaApplicationBase_Impl; + class VBAHELPER_DLLPUBLIC VbaApplicationBase : public ApplicationBase_BASE { + VbaApplicationBase_Impl* m_pImpl; + protected: VbaApplicationBase( const css::uno::Reference< css::uno::XComponentContext >& xContext ); virtual ~VbaApplicationBase(); @@ -49,11 +53,18 @@ public: virtual void SAL_CALL setScreenUpdating(sal_Bool bUpdate) throw (css::uno::RuntimeException); virtual sal_Bool SAL_CALL getDisplayStatusBar() throw (css::uno::RuntimeException); virtual void SAL_CALL setDisplayStatusBar(sal_Bool bDisplayStatusBar) throw (css::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL getInteractive() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setInteractive( ::sal_Bool bInteractive ) throw (::com::sun::star::uno::RuntimeException); virtual css::uno::Any SAL_CALL CommandBars( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); virtual ::rtl::OUString SAL_CALL getVersion() throw (css::uno::RuntimeException); virtual void SAL_CALL Run( const ::rtl::OUString& MacroName, const css::uno::Any& varg1, const css::uno::Any& varg2, const css::uno::Any& varg3, const css::uno::Any& varg4, const css::uno::Any& varg5, const css::uno::Any& varg6, const css::uno::Any& varg7, const css::uno::Any& varg8, const css::uno::Any& varg9, const css::uno::Any& varg10, const css::uno::Any& varg11, const css::uno::Any& varg12, const css::uno::Any& varg13, const css::uno::Any& varg14, const css::uno::Any& varg15, const css::uno::Any& varg16, const css::uno::Any& varg17, const css::uno::Any& varg18, const css::uno::Any& varg19, const css::uno::Any& varg20, const css::uno::Any& varg21, const css::uno::Any& varg22, const css::uno::Any& varg23, const css::uno::Any& varg24, const css::uno::Any& varg25, const css::uno::Any& varg26, const css::uno::Any& varg27, const css::uno::Any& varg28, const css::uno::Any& varg29, const css::uno::Any& varg30 ) throw (css::uno::RuntimeException); + virtual void SAL_CALL OnTime( const ::com::sun::star::uno::Any& aEarliestTime, const ::rtl::OUString& aFunction, const ::com::sun::star::uno::Any& aLatestTime, const ::com::sun::star::uno::Any& aSchedule ) throw (::com::sun::star::uno::RuntimeException); virtual float SAL_CALL CentimetersToPoints( float _Centimeters ) throw (css::uno::RuntimeException); + virtual void SAL_CALL Undo( ) throw (::com::sun::star::uno::RuntimeException); virtual void SAL_CALL Quit( ) throw (::com::sun::star::uno::RuntimeException); + virtual css::uno::Any SAL_CALL getVBE() throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL SAL_CALL getVBProjects() throw (css::uno::RuntimeException); + // XHelperInterface virtual rtl::OUString& getServiceImplName(); virtual css::uno::Sequence<rtl::OUString> getServiceNames(); diff --git a/vbahelper/inc/vbahelper/vbacollectionimpl.hxx b/vbahelper/inc/vbahelper/vbacollectionimpl.hxx index 6d596c31ba53..36102116c7b3 100644 --- a/vbahelper/inc/vbahelper/vbacollectionimpl.hxx +++ b/vbahelper/inc/vbahelper/vbacollectionimpl.hxx @@ -24,6 +24,7 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #ifndef OOVBAAPI_VBA_COLLECTION_IMPL_HXX #define OOVBAAPI_VBA_COLLECTION_IMPL_HXX @@ -44,8 +45,91 @@ #include <vector> +// ============================================================================ + typedef ::cppu::WeakImplHelper1< css::container::XEnumeration > EnumerationHelper_BASE; +// ============================================================================ + +/** A wrapper that holds a com.sun.star.container.XIndexAccess and provides a + com.sun.star.container.XEnumeration. + + Can be used to provide an enumeration from an index container that contains + completely constructed/initialized VBA implementation objects. CANNOT be + used to provide an enumeration from an index container with other objects + (e.g. UNO objects) where construction of the VBA objects is needed first. + */ +class VBAHELPER_DLLPUBLIC SimpleIndexAccessToEnumeration : public EnumerationHelper_BASE +{ +public: + explicit SimpleIndexAccessToEnumeration( + const css::uno::Reference< css::container::XIndexAccess >& rxIndexAccess ) throw (css::uno::RuntimeException) : + mxIndexAccess( rxIndexAccess ), mnIndex( 0 ) {} + + virtual sal_Bool SAL_CALL hasMoreElements() throw (css::uno::RuntimeException) + { + return mnIndex < mxIndexAccess->getCount(); + } + + virtual css::uno::Any SAL_CALL nextElement() throw (css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException) + { + if( !hasMoreElements() ) + throw css::container::NoSuchElementException(); + return mxIndexAccess->getByIndex( mnIndex++ ); + } + +private: + css::uno::Reference< css::container::XIndexAccess > mxIndexAccess; + sal_Int32 mnIndex; +}; + +// ============================================================================ + +/** A wrapper that holds a com.sun.star.container.XEnumeration or a + com.sun.star.container.XIndexAccess and provides an enumeration of VBA objects. + + The method nextElement() needs to be implemented by the derived class. This + class can be used to convert an enumeration or an index container + containing UNO objects to an enumeration providing the related VBA objects. + */ +class VBAHELPER_DLLPUBLIC SimpleEnumerationBase : public EnumerationHelper_BASE +{ +public: + explicit SimpleEnumerationBase( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::container::XEnumeration >& rxEnumeration ) throw (css::uno::RuntimeException) : + mxParent( rxParent ), mxContext( rxContext ), mxEnumeration( rxEnumeration ) {} + + explicit SimpleEnumerationBase( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::container::XIndexAccess >& rxIndexAccess ) throw (css::uno::RuntimeException) : + mxParent( rxParent ), mxContext( rxContext ), mxEnumeration( new SimpleIndexAccessToEnumeration( rxIndexAccess ) ) {} + + virtual sal_Bool SAL_CALL hasMoreElements() throw (css::uno::RuntimeException) + { + return mxEnumeration->hasMoreElements(); + } + + virtual css::uno::Any SAL_CALL nextElement() throw (css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException) + { + return createCollectionObject( mxEnumeration->nextElement() ); + } + + /** Derived classes implement creation of a VBA implementation object from + the passed container element. */ + virtual css::uno::Any createCollectionObject( const css::uno::Any& rSource ) = 0; + +protected: + css::uno::Reference< ov::XHelperInterface > mxParent; + css::uno::Reference< css::uno::XComponentContext > mxContext; + css::uno::Reference< css::container::XEnumeration > mxEnumeration; +}; + +// ============================================================================ + +// deprecated, use SimpleEnumerationBase instead! class VBAHELPER_DLLPUBLIC EnumerationHelperImpl : public EnumerationHelper_BASE { protected: @@ -181,6 +265,14 @@ protected: // need to adjust for vba index ( for which first element is 1 ) return createCollectionObject( m_xIndexAccess->getByIndex( nIndex - 1 ) ); } + + virtual void UpdateCollectionIndex( const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess ) + { + css::uno::Reference< css::container::XNameAccess > xNameAccess( xIndexAccess, css::uno::UNO_QUERY_THROW ); + m_xIndexAccess = xIndexAccess; + m_xNameAccess = xNameAccess; + } + public: ScVbaCollectionBase( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess ) : BaseColBase( xParent, xContext ), m_xIndexAccess( xIndexAccess ){ m_xNameAccess.set(m_xIndexAccess, css::uno::UNO_QUERY); } //XCollection diff --git a/vbahelper/inc/vbahelper/vbadocumentbase.hxx b/vbahelper/inc/vbahelper/vbadocumentbase.hxx index 36648ff6849b..7131e1963b26 100644 --- a/vbahelper/inc/vbahelper/vbadocumentbase.hxx +++ b/vbahelper/inc/vbahelper/vbadocumentbase.hxx @@ -53,6 +53,9 @@ public: virtual sal_Bool SAL_CALL getSaved() throw (css::uno::RuntimeException); virtual void SAL_CALL setSaved( sal_Bool bSave ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL getVBProject() throw (css::uno::RuntimeException); // Michhael E. Bohn + + // Methods virtual void SAL_CALL Close( const css::uno::Any &bSaveChanges, const css::uno::Any &aFileName, diff --git a/vbahelper/inc/vbahelper/vbafontbase.hxx b/vbahelper/inc/vbahelper/vbafontbase.hxx index b820804f1fe2..d1272c9dcf48 100644 --- a/vbahelper/inc/vbahelper/vbafontbase.hxx +++ b/vbahelper/inc/vbahelper/vbafontbase.hxx @@ -63,8 +63,15 @@ class VBAHELPER_DLLPUBLIC VbaFontBase : public VbaFontBase_BASE protected: css::uno::Reference< css::beans::XPropertySet > mxFont; css::uno::Reference< css::container::XIndexAccess > mxPalette; + bool mbFormControl; + public: - VbaFontBase( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xPalette, css::uno::Reference< css::beans::XPropertySet > xPropertySet ) throw ( css::uno::RuntimeException ); + VbaFontBase( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::container::XIndexAccess >& xPalette, + const css::uno::Reference< css::beans::XPropertySet >& xPropertySet, + bool bFormControl = false ) throw ( css::uno::RuntimeException ); virtual ~VbaFontBase();// {} // Attributes diff --git a/vbahelper/inc/vbahelper/vbahelper.hxx b/vbahelper/inc/vbahelper/vbahelper.hxx index 166ad76475d8..33613bb76091 100644 --- a/vbahelper/inc/vbahelper/vbahelper.hxx +++ b/vbahelper/inc/vbahelper/vbahelper.hxx @@ -35,6 +35,7 @@ #include <com/sun/star/lang/IllegalArgumentException.hpp> #include <com/sun/star/awt/XControl.hpp> #include <com/sun/star/awt/XDevice.hpp> +#include <com/sun/star/awt/XUnitConversion.hpp> #include <basic/basmgr.hxx> #include <basic/sberrors.hxx> #include <cppuhelper/implbase1.hxx> @@ -74,8 +75,8 @@ namespace ooo VBAHELPER_DLLPUBLIC css::uno::Reference< css::beans::XIntrospectionAccess > getIntrospectionAccess( const css::uno::Any& aObject ) throw (css::uno::RuntimeException); VBAHELPER_DLLPUBLIC css::uno::Reference< css::script::XTypeConverter > getTypeConverter( const css::uno::Reference< css::uno::XComponentContext >& xContext ) throw (css::uno::RuntimeException); - VBAHELPER_DLLPUBLIC void dispatchRequests (css::uno::Reference< css::frame::XModel>& xModel,rtl::OUString & aUrl) ; - VBAHELPER_DLLPUBLIC void dispatchRequests (css::uno::Reference< css::frame::XModel>& xModel,rtl::OUString & aUrl, css::uno::Sequence< css::beans::PropertyValue >& sProps ) ; + VBAHELPER_DLLPUBLIC void dispatchRequests( const css::uno::Reference< css::frame::XModel>& xModel, const rtl::OUString& aUrl ); + VBAHELPER_DLLPUBLIC void dispatchRequests( const css::uno::Reference< css::frame::XModel>& xModel, const rtl::OUString& aUrl, const css::uno::Sequence< css::beans::PropertyValue >& sProps ); VBAHELPER_DLLPUBLIC void dispatchExecute(SfxViewShell* pView, USHORT nSlot, SfxCallMode nCall = SFX_CALLMODE_SYNCHRON ); VBAHELPER_DLLPUBLIC sal_Int32 OORGBToXLRGB( sal_Int32 ); VBAHELPER_DLLPUBLIC sal_Int32 XLRGBToOORGB( sal_Int32 ); @@ -92,7 +93,9 @@ namespace ooo VBAHELPER_DLLPUBLIC rtl::OUString VBAToRegexp(const rtl::OUString &rIn, bool bForLike = false); // needs to be in an uno service ( already this code is duplicated in basic ) VBAHELPER_DLLPUBLIC double getPixelTo100thMillimeterConversionFactor( css::uno::Reference< css::awt::XDevice >& xDevice, sal_Bool bVertical); VBAHELPER_DLLPUBLIC double PointsToPixels( css::uno::Reference< css::awt::XDevice >& xDevice, double fPoints, sal_Bool bVertical); - VBAHELPER_DLLPUBLIC double PixelsToPoints( css::uno::Reference< css::awt::XDevice >& xDevice, double fPoints, sal_Bool bVertical); + VBAHELPER_DLLPUBLIC double PixelsToPoints( css::uno::Reference< css::awt::XDevice >& xDevice, double fPixels, sal_Bool bVertical); + VBAHELPER_DLLPUBLIC sal_Int32 PointsToHmm( double fPoints ); + VBAHELPER_DLLPUBLIC double HmmToPoints( sal_Int32 nHmm ); VBAHELPER_DLLPUBLIC sal_Int32 getPointerStyle( const css::uno::Reference< css::frame::XModel >& ); VBAHELPER_DLLPUBLIC void setCursorHelper( const css::uno::Reference< css::frame::XModel >& xModel, const Pointer& rPointer, sal_Bool bOverWrite ); VBAHELPER_DLLPUBLIC void setDefaultPropByIntrospection( const css::uno::Any& aObj, const css::uno::Any& aValue ) throw ( css::uno::RuntimeException ); @@ -103,8 +106,6 @@ class VBAHELPER_DLLPUBLIC Millimeter { //Factor to translate between points and hundredths of millimeters: private: - static const double factor; - double m_nMillimeter; public: @@ -178,12 +179,19 @@ public: virtual double getWidth(); virtual void setWidth( double nWidth); }; + #define VBA_LEFT "PositionX" #define VBA_TOP "PositionY" +#define VBA_HEIGHT "Height" +#define VBA_WIDTH "Width" class VBAHELPER_DLLPUBLIC UserFormGeometryHelper : public AbstractGeometryAttributes { - + css::uno::Reference< css::awt::XUnitConversion > mxControlUnits; css::uno::Reference< css::beans::XPropertySet > mxModel; + + sal_Int32 ConvertLogicToPixel( sal_Int32 nValue, sal_Bool bIsPoint, sal_Bool bIsX, sal_Int16 nSourceUnit ); + sal_Int32 ConvertPixelToLogic( sal_Int32 nValue, sal_Bool bIsPoint, sal_Bool bIsX, sal_Int16 nTargetUnit ); + public: UserFormGeometryHelper( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::awt::XControl >& xControl ); virtual double getLeft(); diff --git a/vbahelper/inc/vbahelper/vbahelperinterface.hxx b/vbahelper/inc/vbahelper/vbahelperinterface.hxx index 5695ab36b4fa..21339631e1ed 100644 --- a/vbahelper/inc/vbahelper/vbahelperinterface.hxx +++ b/vbahelper/inc/vbahelper/vbahelperinterface.hxx @@ -115,4 +115,57 @@ public: InheritedHelperInterfaceImpl1< Ifc1 > ( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext ) : Base( xParent, xContext ) {} }; + +// ============================================================================ + +/** Helper macro to implement the method 'getServiceImplName()' of the + 'ooo.vba.XHelperInterface' interface. Will return the class name as service + implementation name. + */ +#define VBAHELPER_IMPL_GETSERVICEIMPLNAME( classname ) \ +::rtl::OUString& classname::getServiceImplName() \ +{ \ + static ::rtl::OUString saImplName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( #classname ) ); \ + return saImplName; \ +} + +// ---------------------------------------------------------------------------- + +/** Helper macro to implement the method 'getServiceNames()' for a single + service name. + */ +#define VBAHELPER_IMPL_GETSERVICENAMES( classname, servicename ) \ +css::uno::Sequence< ::rtl::OUString > classname::getServiceNames() \ +{ \ + static css::uno::Sequence< ::rtl::OUString > saServiceNames; \ + if( saServiceNames.getLength() == 0 ) \ + { \ + saServiceNames.realloc( 1 ); \ + saServiceNames[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( servicename ) ); \ + } \ + return saServiceNames; \ +} + +// ---------------------------------------------------------------------------- + +/** Helper macro to declare the methods 'getServiceImplName()' and + 'getServiceNames()' of the 'ooo.vba.XHelperInterface' interface in a class + declaration. + */ +#define VBAHELPER_DECL_XHELPERINTERFACE \ + virtual ::rtl::OUString& getServiceImplName(); \ + virtual css::uno::Sequence< ::rtl::OUString > getServiceNames(); + +// ---------------------------------------------------------------------------- + +/** Helper macro to implement the methods 'getServiceImplName()' and + 'getServiceNames()' of the 'ooo.vba.XHelperInterface' interface. Will + return the class name as service implementation name. + */ +#define VBAHELPER_IMPL_XHELPERINTERFACE( classname, servicename ) \ +VBAHELPER_IMPL_GETSERVICEIMPLNAME( classname ) \ +VBAHELPER_IMPL_GETSERVICENAMES( classname, servicename ) + +// ============================================================================ + #endif diff --git a/vbahelper/source/msforms/makefile.mk b/vbahelper/source/msforms/makefile.mk index 7c61e4302b7f..5fce64649dcb 100644 --- a/vbahelper/source/msforms/makefile.mk +++ b/vbahelper/source/msforms/makefile.mk @@ -58,6 +58,7 @@ SLOFILES=\ $(SLO)$/vbamultipage.obj \ $(SLO)$/vbalistcontrolhelper.obj \ $(SLO)$/vbaspinbutton.obj \ + $(SLO)$/vbasystemaxcontrol.obj \ $(SLO)$/vbaimage.obj \ $(SLO)$/vbapages.obj \ $(SLO)$/vbauserform.obj \ diff --git a/vbahelper/source/msforms/vbacontrol.cxx b/vbahelper/source/msforms/vbacontrol.cxx index 2ff12b145824..4222e3d299d0 100644 --- a/vbahelper/source/msforms/vbacontrol.cxx +++ b/vbahelper/source/msforms/vbacontrol.cxx @@ -57,6 +57,7 @@ #include "vbaprogressbar.hxx" #include "vbamultipage.hxx" #include "vbaspinbutton.hxx" +#include "vbasystemaxcontrol.hxx" #include "vbaimage.hxx" #include <vbahelper/helperdecl.hxx> @@ -254,6 +255,22 @@ void SAL_CALL ScVbaControl::SetFocus() throw (uno::RuntimeException) xWin->setFocus(); } +void SAL_CALL ScVbaControl::Move( double Left, double Top, const uno::Any& Width, const uno::Any& Height ) + throw ( uno::RuntimeException ) +{ + double nWidth; + double nHeight; + + setLeft( Left ); + setTop( Top ); + + if ( Width >>= nWidth ) + setWidth( nWidth ); + + if ( Height >>= nHeight ) + setHeight( nHeight ); +} + rtl::OUString SAL_CALL ScVbaControl::getControlSource() throw (uno::RuntimeException) { @@ -368,6 +385,20 @@ ScVbaControl::setControlTipText( const rtl::OUString& rsToolTip ) throw (css::un m_xProps->setPropertyValue (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HelpText" ) ), uno::makeAny( rsToolTip ) ); } + +::rtl::OUString SAL_CALL ScVbaControl::getTag() + throw (css::uno::RuntimeException) +{ + return m_aControlTag; +} + +void SAL_CALL ScVbaControl::setTag( const ::rtl::OUString& aTag ) + throw (css::uno::RuntimeException) +{ + m_aControlTag = aTag; +} + + //ScVbaControlFactory ScVbaControlFactory::ScVbaControlFactory( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< uno::XInterface >& xControl, const uno::Reference< frame::XModel >& xModel ): m_xContext( xContext ), m_xControl( xControl ), m_xModel( xModel ) @@ -383,7 +414,6 @@ ScVbaControl* ScVbaControlFactory::createControl( const uno::Reference< uno::XIn if ( !xControl.is() ) throw uno::RuntimeException(); // really we should be more informative return createControl( xControl, xParent ); - } ScVbaControl* ScVbaControlFactory::createControl(const uno::Reference< drawing::XControlShape >& xControlShape, const uno::Reference< uno::XInterface >& /*xParent*/ ) throw (uno::RuntimeException) @@ -456,6 +486,8 @@ ScVbaControl* ScVbaControlFactory::createControl( const uno::Reference< awt::XCo pControl = new ScVbaMultiPage( xVbaParent, m_xContext, xControl, m_xModel, new UserFormGeometryHelper( m_xContext, xControl ), xParent ); else if ( xServiceInfo->supportsService( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlSpinButtonModel") ) ) ) pControl = new ScVbaSpinButton( xVbaParent, m_xContext, xControl, m_xModel, new UserFormGeometryHelper( m_xContext, xControl ) ); + else if ( xServiceInfo->supportsService( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.custom.awt.UnoControlSystemAXContainerModel") ) ) ) + pControl = new VbaSystemAXControl( xVbaParent, m_xContext, xControl, m_xModel, new UserFormGeometryHelper( m_xContext, xControl ) ); else throw uno::RuntimeException( rtl::OUString::createFromAscii("Unsupported control " ), uno::Reference< uno::XInterface >() ); return pControl; diff --git a/vbahelper/source/msforms/vbacontrol.hxx b/vbahelper/source/msforms/vbacontrol.hxx index 1a8ed063548b..992fbd94a8c5 100644 --- a/vbahelper/source/msforms/vbacontrol.hxx +++ b/vbahelper/source/msforms/vbacontrol.hxx @@ -48,6 +48,10 @@ class ScVbaControl : public ControlImpl_BASE private: com::sun::star::uno::Reference< com::sun::star::lang::XEventListener > m_xEventListener; protected: + // awt control has nothing similar to Tag property of Mso controls, + // whether it is necessary is another question + ::rtl::OUString m_aControlTag; + std::auto_ptr< ov::AbstractGeometryAttributes > mpGeometryHelper; css::uno::Reference< css::beans::XPropertySet > m_xProps; css::uno::Reference< css::uno::XInterface > m_xControl; @@ -75,6 +79,7 @@ public: virtual double SAL_CALL getTop() throw (css::uno::RuntimeException); virtual void SAL_CALL setTop( double _top ) throw (css::uno::RuntimeException); virtual void SAL_CALL SetFocus( ) throw (css::uno::RuntimeException); + virtual void SAL_CALL Move( double Left, double Top, const ::com::sun::star::uno::Any& Width, const ::com::sun::star::uno::Any& Height ) throw (::com::sun::star::uno::RuntimeException); virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getObject() throw (css::uno::RuntimeException); virtual rtl::OUString SAL_CALL getControlSource() throw (css::uno::RuntimeException); @@ -85,6 +90,8 @@ public: virtual void SAL_CALL setName( const rtl::OUString& _name ) throw (css::uno::RuntimeException); virtual rtl::OUString SAL_CALL getControlTipText() throw (css::uno::RuntimeException); virtual void SAL_CALL setControlTipText( const rtl::OUString& ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getTag() throw (css::uno::RuntimeException); + virtual void SAL_CALL setTag( const ::rtl::OUString& aTag ) throw (css::uno::RuntimeException); //remove resouce because ooo.vba.excel.XControl is a wrapper of com.sun.star.drawing.XControlShape virtual void removeResouce() throw( css::uno::RuntimeException ); //XHelperInterface diff --git a/vbahelper/source/msforms/vbacontrols.cxx b/vbahelper/source/msforms/vbacontrols.cxx index 48ef83d60aa6..1284b36be463 100644 --- a/vbahelper/source/msforms/vbacontrols.cxx +++ b/vbahelper/source/msforms/vbacontrols.cxx @@ -25,9 +25,14 @@ * ************************************************************************/ +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/XControlContainer.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/script/XInvocation.hpp> +#include <com/sun/star/lang/WrappedTargetException.hpp> + #include "vbacontrols.hxx" #include <cppuhelper/implbase2.hxx> -#include <com/sun/star/awt/XControlContainer.hpp> #include <ooo/vba//XControlProvider.hpp> #include <hash_map> @@ -48,16 +53,25 @@ class ControlArrayWrapper : public ArrayWrapImpl ControlVec mControls; ControlIndexMap mIndices; - rtl::OUString getControlName( const uno::Reference< awt::XControl >& xCtrl ) +private: + void SetArrayElementTo( const uno::Reference< awt::XControl >& xCtrl, sal_Int32 nIndex = -1 ) { - uno::Reference< beans::XPropertySet > xProp( xCtrl->getModel(), uno::UNO_QUERY ); - rtl::OUString sName; - xProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" ) ) ) >>= sName; - return sName; + // initialize the element with specified index to the control + if ( xCtrl.is() ) + { + if ( nIndex == -1 ) + nIndex = msNames.getLength(); + + if ( nIndex >= msNames.getLength() ) + msNames.realloc( nIndex ); + + msNames[ nIndex ] = getControlName( xCtrl ); + mControls.push_back( xCtrl ); + mIndices[ msNames[ nIndex ] ] = nIndex; + } } public: - ControlArrayWrapper( const uno::Reference< awt::XControl >& xDialog ) { mxDialog.set( xDialog, uno::UNO_QUERY_THROW ); @@ -65,14 +79,21 @@ public: msNames.realloc( sXControls.getLength() ); for ( sal_Int32 i = 0; i < sXControls.getLength(); ++i ) - { - uno::Reference< awt::XControl > xCtrl = sXControls[ i ]; - msNames[ i ] = getControlName( xCtrl ); - mControls.push_back( xCtrl ); - mIndices[ msNames[ i ] ] = i; - } + SetArrayElementTo( sXControls[ i ], i ); + } + + static rtl::OUString getControlName( const uno::Reference< awt::XControl >& xCtrl ) + { + if ( !xCtrl.is() ) + throw uno::RuntimeException(); + + uno::Reference< beans::XPropertySet > xProp( xCtrl->getModel(), uno::UNO_QUERY_THROW ); + rtl::OUString sName; + xProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" ) ) ) >>= sName; + return sName; } + // XElementAccess virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException) { @@ -204,6 +225,141 @@ ScVbaControls::Move( double cx, double cy ) throw (uno::RuntimeException) } } +uno::Any SAL_CALL ScVbaControls::Add( const uno::Any& Object, const uno::Any& StringKey, const uno::Any& /*Before*/, const uno::Any& /*After*/ ) + throw (uno::RuntimeException) +{ + uno::Any aResult; + ::rtl::OUString aComServiceName; + + try + { + if ( !mxDialog.is() ) + throw uno::RuntimeException(); + + uno::Reference< awt::XControl > xNewControl; + uno::Reference< lang::XMultiServiceFactory > xModelFactory( mxDialog->getModel(), uno::UNO_QUERY_THROW ); + + uno::Reference< container::XNameContainer > xDialogContainer( xModelFactory, uno::UNO_QUERY_THROW ); + + Object >>= aComServiceName; + + // TODO: Support Before and After? + ::rtl::OUString aNewName; + StringKey >>= aNewName; + if ( !aNewName.getLength() ) + { + aNewName = aComServiceName; + if ( !aNewName.getLength() ) + aNewName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Control" ) ); + + sal_Int32 nInd = 0; + while( xDialogContainer->hasByName( aNewName ) && nInd < SAL_MAX_INT32 ) + { + aNewName = aComServiceName; + aNewName += ::rtl::OUString::valueOf( nInd ); + } + } + + if ( aComServiceName.getLength() ) + { + uno::Reference< awt::XControlModel > xNewModel( xModelFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.custom.awt.UnoControlSystemAXContainerModel" ) ) ), uno::UNO_QUERY_THROW ); + + + xDialogContainer->insertByName( aNewName, uno::makeAny( xNewModel ) ); + uno::Reference< awt::XControlContainer > xControlContainer( mxDialog, uno::UNO_QUERY_THROW ); + xNewControl = xControlContainer->getControl( aNewName ); + + try + { + uno::Reference< script::XInvocation > xControlInvoke( xNewControl, uno::UNO_QUERY_THROW ); + + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[0] <<= aComServiceName; + uno::Sequence< sal_Int16 > aOutIDDummy; + uno::Sequence< uno::Any > aOutDummy; + xControlInvoke->invoke( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SOAddAXControl" ) ), aArgs, aOutIDDummy, aOutDummy ); + } + catch( uno::Exception& ) + { + xDialogContainer->removeByName( aNewName ); + throw; + } + } + + if ( xNewControl.is() ) + { + UpdateCollectionIndex( lcl_controlsWrapper( mxDialog ) ); + aResult <<= xNewControl; + aResult = createCollectionObject( aResult ); + } + else + throw uno::RuntimeException(); + } + catch( uno::RuntimeException& ) + { + throw; + } + catch( uno::Exception& e ) + { + throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can not create AXControl!" ) ), + uno::Reference< uno::XInterface >(), + uno::makeAny( e ) ); + } + + return aResult; +} + +void SAL_CALL ScVbaControls::Remove( const uno::Any& StringKeyOrIndex ) + throw (uno::RuntimeException) +{ + ::rtl::OUString aControlName; + sal_Int32 nIndex = -1; + + try + { + if ( !mxDialog.is() ) + throw uno::RuntimeException(); + + uno::Reference< lang::XMultiServiceFactory > xModelFactory( mxDialog->getModel(), uno::UNO_QUERY_THROW ); + uno::Reference< container::XNameContainer > xDialogContainer( xModelFactory, uno::UNO_QUERY_THROW ); + + if ( !( ( StringKeyOrIndex >>= aControlName ) && aControlName.getLength() ) + && !( ( StringKeyOrIndex >>= nIndex ) && nIndex >= 0 && nIndex < m_xIndexAccess->getCount() ) ) + throw uno::RuntimeException(); + + uno::Reference< awt::XControl > xControl; + if ( aControlName.getLength() ) + { + uno::Reference< awt::XControlContainer > xControlContainer( mxDialog, uno::UNO_QUERY_THROW ); + xControl = xControlContainer->getControl( aControlName ); + } + else + { + m_xIndexAccess->getByIndex( nIndex ) >>= xControl; + } + + if ( !xControl.is() ) + throw uno::RuntimeException(); + + if ( !aControlName.getLength() ) + aControlName = ControlArrayWrapper::getControlName( xControl ); + + xDialogContainer->removeByName( aControlName ); + xControl->dispose(); + } + catch( uno::RuntimeException& ) + { + throw; + } + catch( uno::Exception& e ) + { + throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can not create AXControl!" ) ), + uno::Reference< uno::XInterface >(), + uno::makeAny( e ) ); + } +} + + uno::Type ScVbaControls::getElementType() throw (uno::RuntimeException) { diff --git a/vbahelper/source/msforms/vbacontrols.hxx b/vbahelper/source/msforms/vbacontrols.hxx index 804133dbddfa..a72506609531 100644 --- a/vbahelper/source/msforms/vbacontrols.hxx +++ b/vbahelper/source/msforms/vbacontrols.hxx @@ -39,14 +39,19 @@ typedef CollTestImplHelper< ov::msforms::XControls > ControlsImpl_BASE; class ScVbaControls : public ControlsImpl_BASE { css::uno::Reference< css::awt::XControl > mxDialog; + protected: virtual rtl::OUString& getServiceImplName(); virtual css::uno::Sequence<rtl::OUString> getServiceNames(); + public: ScVbaControls( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::awt::XControl >& xDialog ); // XControls - virtual void SAL_CALL Move( double cx, double cy ) throw (css::uno::RuntimeException); + virtual void SAL_CALL Move( double cx, double cy ) throw (css::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL Add( const ::com::sun::star::uno::Any& Object, const ::com::sun::star::uno::Any& StringKey, const ::com::sun::star::uno::Any& Before, const ::com::sun::star::uno::Any& After ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL Remove( const ::com::sun::star::uno::Any& StringKeyOrIndex ) throw (::com::sun::star::uno::RuntimeException); + // XEnumerationAccess virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException); virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException); diff --git a/vbahelper/source/vbahelper/makefile.mk b/vbahelper/source/vbahelper/makefile.mk index b11b4ffa0a4f..47ad44b3d0ed 100644 --- a/vbahelper/source/vbahelper/makefile.mk +++ b/vbahelper/source/vbahelper/makefile.mk @@ -65,7 +65,6 @@ SLOFILES=\ $(SLO)$/vbashaperange.obj \ $(SLO)$/vbatextframe.obj \ $(SLO)$/vbapagesetupbase.obj \ - # --- Targets ------------------------------------------------------- .INCLUDE : target.mk diff --git a/vbahelper/source/vbahelper/vbaapplicationbase.cxx b/vbahelper/source/vbahelper/vbaapplicationbase.cxx index 54b635d2f08d..6d2c51066ca2 100644 --- a/vbahelper/source/vbahelper/vbaapplicationbase.cxx +++ b/vbahelper/source/vbahelper/vbaapplicationbase.cxx @@ -26,15 +26,24 @@ ************************************************************************/ #include "vbahelper/vbaapplicationbase.hxx" #include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> //Michael E. Bohn +#include <com/sun/star/lang/XMultiComponentFactory.hpp> //Michael E. Bohn +#include <com/sun/star/lang/XComponent.hpp> //Michael E. Bohn +#include <com/sun/star/container/XEnumeration.hpp> //Michael E. Bohn #include <com/sun/star/frame/XLayoutManager.hpp> #include <com/sun/star/frame/XDesktop.hpp> #include <com/sun/star/container/XEnumerationAccess.hpp> #include <com/sun/star/document/XDocumentInfoSupplier.hpp> #include <com/sun/star/document/XDocumentProperties.hpp> #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include <com/sun/star/document/XEmbeddedScripts.hpp> //Michael E. Bohn +#include <ooo/vba/XVBAAppService.hpp> //Michael E. Bohn +#include <com/sun/star/awt/XWindow2.hpp> + #include "vbacommandbars.hxx" #include <filter/msfilter/msvbahelper.hxx> +#include <tools/datetime.hxx> // start basic includes #include <basic/sbx.hxx> @@ -43,18 +52,141 @@ #include <basic/sbmeth.hxx> #include <basic/sbmod.hxx> // end basic includes + +#include <hash_map> + using namespace com::sun::star; using namespace ooo::vba; #define OFFICEVERSION "11.0" +// ====VbaTimerInfo================================== +typedef ::std::pair< ::rtl::OUString, ::std::pair< double, double > > VbaTimerInfo; + +// ====VbaTimer================================== +class VbaTimer +{ + Timer m_aTimer; + VbaTimerInfo m_aTimerInfo; + ::rtl::Reference< VbaApplicationBase > m_xBase; + + // the following declarations are here to prevent the usage of them + VbaTimer( const VbaTimer& ); + VbaTimer& operator=( const VbaTimer& ); + +public: + VbaTimer() + {} + + virtual ~VbaTimer() + { + m_aTimer.Stop(); + } + + static double GetNow() + { + Date aDateNow; + Time aTimeNow; + Date aRefDate( 1,1,1900 ); + long nDiffDays = (long)(aDateNow - aRefDate); + nDiffDays += 2; // Anpassung VisualBasic: 1.Jan.1900 == 2 + + long nDiffSeconds = aTimeNow.GetHour() * 3600 + aTimeNow.GetMin() * 60 + aTimeNow.GetSec(); + return (double)nDiffDays + ((double)nDiffSeconds)/(double)(24*3600); + } + + static sal_Int32 GetTimerMiliseconds( double nFrom, double nTo ) + { + double nResult = nTo - nFrom; + if ( nResult > 0 ) + nResult *= 24*3600*1000; + else + nResult = 50; + + return (sal_Int32) nResult; + } + + void Start( const ::rtl::Reference< VbaApplicationBase > xBase, const ::rtl::OUString& aFunction, double nFrom, double nTo ) + { + if ( !xBase.is() || !aFunction.getLength() ) + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected arguments!" ) ), uno::Reference< uno::XInterface >() ); + + m_xBase = xBase; + m_aTimerInfo = VbaTimerInfo( aFunction, ::std::pair< double, double >( nFrom, nTo ) ); + m_aTimer.SetTimeoutHdl( LINK( this, VbaTimer, MacroCallHdl ) ); + m_aTimer.SetTimeout( GetTimerMiliseconds( GetNow(), nFrom ) ); + m_aTimer.Start(); + } + + DECL_LINK( MacroCallHdl, void* ); +}; + +IMPL_LINK( VbaTimer, MacroCallHdl, void*, EMPTYARG ) +{ + if ( m_aTimerInfo.second.second == 0 || GetNow() < m_aTimerInfo.second.second ) + { + uno::Any aDummyArg; + try + { + m_xBase->Run( m_aTimerInfo.first, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg ); + } + catch( uno::Exception& ) + {} + } + + // mast be the last call in the method since it deletes the timer + try + { + m_xBase->OnTime( uno::makeAny( m_aTimerInfo.second.first ), m_aTimerInfo.first, uno::makeAny( m_aTimerInfo.second.second ), uno::makeAny( sal_False ) ); + } catch( uno::Exception& ) + {} + + return 0; +} + +// ====VbaTimerInfoHash================================== +struct VbaTimerInfoHash +{ + size_t operator()( const VbaTimerInfo& rTimerInfo ) const + { + return (size_t)rTimerInfo.first.hashCode() + + (size_t)rtl_str_hashCode_WithLength( (char*)&rTimerInfo.second.first, sizeof( double ) ) + + (size_t)rtl_str_hashCode_WithLength( (char*)&rTimerInfo.second.second, sizeof( double ) ); + } +}; + +// ====VbaTimerHashMap================================== +typedef ::std::hash_map< VbaTimerInfo, VbaTimer*, VbaTimerInfoHash, ::std::equal_to< VbaTimerInfo > > VbaTimerHashMap; + +// ====VbaApplicationBase_Impl================================== +struct VbaApplicationBase_Impl +{ + VbaTimerHashMap m_aTimerHash; + + virtual ~VbaApplicationBase_Impl() + { + // remove the remaining timers + for ( VbaTimerHashMap::iterator aIter = m_aTimerHash.begin(); + aIter != m_aTimerHash.end(); + aIter++ ) + { + delete aIter->second; + aIter->second = NULL; + } + } +}; + +// ====VbaApplicationBase================================== VbaApplicationBase::VbaApplicationBase( const uno::Reference< uno::XComponentContext >& xContext ) : ApplicationBase_BASE( uno::Reference< XHelperInterface >(), xContext ) + , m_pImpl( new VbaApplicationBase_Impl ) { } VbaApplicationBase::~VbaApplicationBase() { + m_pImpl = 0; + delete m_pImpl; } sal_Bool SAL_CALL @@ -116,6 +248,26 @@ VbaApplicationBase::setDisplayStatusBar(sal_Bool bDisplayStatusBar) throw (uno:: return; } +::sal_Bool SAL_CALL VbaApplicationBase::getInteractive() + throw (uno::RuntimeException) +{ + uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW ); + uno::Reference< frame::XFrame > xFrame( xModel->getCurrentController()->getFrame(), uno::UNO_QUERY_THROW ); + uno::Reference< awt::XWindow2 > xWindow( xFrame->getContainerWindow(), uno::UNO_QUERY_THROW ); + + return xWindow->isEnabled(); +} + +void SAL_CALL VbaApplicationBase::setInteractive( ::sal_Bool bInteractive ) + throw (uno::RuntimeException) +{ + uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW ); + uno::Reference< frame::XFrame > xFrame( xModel->getCurrentController()->getFrame(), uno::UNO_QUERY_THROW ); + uno::Reference< awt::XWindow > xWindow( xFrame->getContainerWindow(), uno::UNO_SET_THROW ); + + xWindow->setEnable( bInteractive ); +} + uno::Any SAL_CALL VbaApplicationBase::CommandBars( const uno::Any& aIndex ) throw (uno::RuntimeException) { @@ -133,7 +285,54 @@ VbaApplicationBase::getVersion() throw (uno::RuntimeException) void SAL_CALL VbaApplicationBase::Run( const ::rtl::OUString& MacroName, const uno::Any& varg1, const uno::Any& varg2, const uno::Any& varg3, const uno::Any& varg4, const uno::Any& varg5, const uno::Any& varg6, const uno::Any& varg7, const uno::Any& varg8, const uno::Any& varg9, const uno::Any& varg10, const uno::Any& varg11, const uno::Any& varg12, const uno::Any& varg13, const uno::Any& varg14, const uno::Any& varg15, const uno::Any& varg16, const uno::Any& varg17, const uno::Any& varg18, const uno::Any& varg19, const uno::Any& varg20, const uno::Any& varg21, const uno::Any& varg22, const uno::Any& varg23, const uno::Any& varg24, const uno::Any& varg25, const uno::Any& varg26, const uno::Any& varg27, const uno::Any& varg28, const uno::Any& varg29, const uno::Any& varg30 ) throw (uno::RuntimeException) { - VBAMacroResolvedInfo aMacroInfo = resolveVBAMacro( getSfxObjShell( getCurrentDocument() ), MacroName ); + ::rtl::OUString sSeparator = ::rtl::OUString::createFromAscii("/"); + ::rtl::OUString sMacroSeparator = ::rtl::OUString::createFromAscii("!"); + ::rtl::OUString sMacro_only_Name; + sal_Int32 Position_MacroSeparator = MacroName.indexOf(sMacroSeparator); + + uno::Reference< frame::XModel > aMacroDocumentModel; + if (-1 != Position_MacroSeparator) + { + uno::Reference< container::XEnumerationAccess > xComponentEnumAccess; + uno::Reference< lang::XMultiComponentFactory > xServiceManager = mxContext->getServiceManager(); + try + { + uno::Reference< frame::XDesktop > xDesktop (xServiceManager->createInstanceWithContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" )),mxContext ), uno::UNO_QUERY_THROW ); + xComponentEnumAccess = xDesktop->getComponents(); + } + catch(uno::Exception&) + { + } + + //rem look for the name of the document in the cmpoonents collection + uno::Reference < container::XEnumeration > xEnum = xComponentEnumAccess->createEnumeration(); + + // iterate through the collection by name + while (xEnum->hasMoreElements()) + { + // get the next element as a UNO Any + uno::Any aComponentHelper = xEnum->nextElement(); + uno::Reference <frame::XModel> xDocModel( aComponentHelper, uno::UNO_QUERY_THROW ); + + // get the name of the sheet from its XNamed interface + ::rtl::OUString aName = xDocModel->getURL(); + + + if (aName.match(MacroName.copy(0,Position_MacroSeparator-1),aName.lastIndexOf(sSeparator)+1)) + { + aMacroDocumentModel = xDocModel; + sMacro_only_Name = MacroName.copy(Position_MacroSeparator+1); + } + } + } + else + { + aMacroDocumentModel = getCurrentDocument(); + sMacro_only_Name = MacroName.copy(0); + } + + + VBAMacroResolvedInfo aMacroInfo = resolveVBAMacro( getSfxObjShell( aMacroDocumentModel ), sMacro_only_Name ); if( aMacroInfo.IsResolved() ) { // handle the arguments @@ -168,6 +367,39 @@ void SAL_CALL VbaApplicationBase::Run( const ::rtl::OUString& MacroName, const u } } +void SAL_CALL VbaApplicationBase::OnTime( const uno::Any& aEarliestTime, const ::rtl::OUString& aFunction, const uno::Any& aLatestTime, const uno::Any& aSchedule ) + throw ( uno::RuntimeException ) +{ + if ( !aFunction.getLength() ) + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected function name!" ) ), uno::Reference< uno::XInterface >() ); + + double nEarliestTime = 0; + double nLatestTime = 0; + if ( !( aEarliestTime >>= nEarliestTime ) + || ( aLatestTime.hasValue() && !( aLatestTime >>= nLatestTime ) ) ) + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Only double is supported as time for now!" ) ), uno::Reference< uno::XInterface >() ); + + sal_Bool bSetTimer = sal_True; + aSchedule >>= bSetTimer; + + VbaTimerInfo aTimerIndex( aFunction, ::std::pair< double, double >( nEarliestTime, nLatestTime ) ); + + VbaTimerHashMap::iterator aIter = m_pImpl->m_aTimerHash.find( aTimerIndex ); + if ( aIter != m_pImpl->m_aTimerHash.end() ) + { + delete aIter->second; + aIter->second = NULL; + m_pImpl->m_aTimerHash.erase( aIter ); + } + + if ( bSetTimer ) + { + VbaTimer* pTimer = new VbaTimer; + m_pImpl->m_aTimerHash[ aTimerIndex ] = pTimer; + pTimer->Start( this, aFunction, nEarliestTime, nLatestTime ); + } +} + float SAL_CALL VbaApplicationBase::CentimetersToPoints( float _Centimeters ) throw (uno::RuntimeException) { // i cm = 28.35 points @@ -175,6 +407,57 @@ float SAL_CALL VbaApplicationBase::CentimetersToPoints( float _Centimeters ) thr return ( _Centimeters * rate ); } +// inserted by Michael E. Bohn +uno::Any SAL_CALL VbaApplicationBase::getVBE() throw (uno::RuntimeException) +{ + uno::Any aAny; + uno::Reference< ::lang::XMultiComponentFactory > xServiceManager = mxContext->getServiceManager(); + try + { + uno::Reference < ::uno::XInterface > xInterface = xServiceManager->createInstanceWithContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAAppService" )),mxContext); + uno::Reference < ::ooo::vba::XVBAAppService > xVBAAppService (xInterface, ::uno::UNO_QUERY_THROW ); + if (xVBAAppService.is()){ + uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW ); + return xVBAAppService->getVBE( this, mxContext, xModel); + } + + }catch(uno::Exception* e) + { + } + return aAny; +} + +uno::Any SAL_CALL +VbaApplicationBase::getVBProjects() throw (uno::RuntimeException) +{ + uno::Any aAny; + uno::Reference< ::lang::XMultiComponentFactory > xServiceManager = mxContext->getServiceManager(); + try + { + uno::Reference < ::uno::XInterface > xInterface = xServiceManager->createInstanceWithContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAAppService" )),mxContext); + uno::Reference < ::ooo::vba::XVBAAppService > xVBAAppService (xInterface, ::uno::UNO_QUERY_THROW ); + if (xVBAAppService.is()){ + uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW ); + uno::Reference< document::XEmbeddedScripts > xEnbeddedScripts ( xModel, uno::UNO_QUERY_THROW ); + uno::Reference< script::XStorageBasedLibraryContainer > xMacroStorageBasedLibraryContainer = xEnbeddedScripts->getBasicLibraries(); + uno::Reference< script::XStorageBasedLibraryContainer > xDialogStorageBasedLibraryContainer = xEnbeddedScripts->getDialogLibraries(); + uno::Reference< script::XLibraryContainer > xMacroLibraryContainer ( xMacroStorageBasedLibraryContainer, uno::UNO_QUERY_THROW ); + uno::Reference< script::XLibraryContainer > xDialogLibraryContainer( xDialogStorageBasedLibraryContainer, uno::UNO_QUERY_THROW ); + return xVBAAppService->getVBProjects(this, mxContext, xModel, xMacroLibraryContainer, xDialogLibraryContainer); + } + + }catch(uno::Exception* e) + { + } + return aAny; + + + +} + + + + rtl::OUString& VbaApplicationBase::getServiceImplName() { @@ -193,6 +476,13 @@ VbaApplicationBase::getServiceNames() return aServiceNames; } +void SAL_CALL VbaApplicationBase::Undo() + throw (uno::RuntimeException) +{ + uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW ); + dispatchRequests( xModel, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:Undo" ) ) ); +} + void VbaApplicationBase::Quit() throw (uno::RuntimeException) { // need to stop basic @@ -208,3 +498,4 @@ void VbaApplicationBase::Quit() throw (uno::RuntimeException) } } } + diff --git a/vbahelper/source/vbahelper/vbacommandbar.cxx b/vbahelper/source/vbahelper/vbacommandbar.cxx index 1e2911ad4f52..1e8d21d53583 100644 --- a/vbahelper/source/vbahelper/vbacommandbar.cxx +++ b/vbahelper/source/vbahelper/vbacommandbar.cxx @@ -202,3 +202,85 @@ ScVbaCommandBar::getServiceNames() } return aServiceNames; } + + +VbaDummyCommandBar::VbaDummyCommandBar( + const uno::Reference< ov::XHelperInterface > xParent, + const uno::Reference< uno::XComponentContext > xContext, + const ::rtl::OUString& rName, sal_Int32 nType ) throw( uno::RuntimeException ) : + CommandBar_BASE( xParent, xContext ), + maName( rName ), + mnType( nType ) +{ +} + +::rtl::OUString SAL_CALL VbaDummyCommandBar::getName() throw ( uno::RuntimeException ) +{ + return maName; +} + +void SAL_CALL VbaDummyCommandBar::setName( const ::rtl::OUString& _name ) throw (uno::RuntimeException) +{ + maName = _name; +} + +::sal_Bool SAL_CALL VbaDummyCommandBar::getVisible() throw (uno::RuntimeException) +{ + return sal_True; +} + +void SAL_CALL VbaDummyCommandBar::setVisible( ::sal_Bool /*_visible*/ ) throw (uno::RuntimeException) +{ +} + +::sal_Bool SAL_CALL VbaDummyCommandBar::getEnabled() throw (uno::RuntimeException) +{ + // emulated with Visible + return getVisible(); +} + +void SAL_CALL VbaDummyCommandBar::setEnabled( sal_Bool _enabled ) throw (uno::RuntimeException) +{ + // emulated with Visible + setVisible( _enabled ); +} + +void SAL_CALL VbaDummyCommandBar::Delete( ) throw (script::BasicErrorException, uno::RuntimeException) +{ + // no-op +} + +uno::Any SAL_CALL VbaDummyCommandBar::Controls( const uno::Any& aIndex ) throw (script::BasicErrorException, uno::RuntimeException) +{ + uno::Reference< XCommandBarControls > xCommandBarControls( new VbaDummyCommandBarControls( this, mxContext ) ); + if( aIndex.hasValue() ) + return xCommandBarControls->Item( aIndex, uno::Any() ); + return uno::Any( xCommandBarControls ); +} + +sal_Int32 SAL_CALL VbaDummyCommandBar::Type() throw (script::BasicErrorException, uno::RuntimeException) +{ + return mnType; +} + +uno::Any SAL_CALL VbaDummyCommandBar::FindControl( const uno::Any& /*aType*/, const uno::Any& /*aId*/, const uno::Any& /*aTag*/, const uno::Any& /*aVisible*/, const uno::Any& /*aRecursive*/ ) throw (script::BasicErrorException, uno::RuntimeException) +{ + return uno::Any( uno::Reference< XCommandBarControl >() ); +} + +rtl::OUString& VbaDummyCommandBar::getServiceImplName() +{ + static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("VbaDummyCommandBar") ); + return sImplName; +} + +uno::Sequence< rtl::OUString > VbaDummyCommandBar::getServiceNames() +{ + static uno::Sequence< rtl::OUString > aServiceNames; + if ( aServiceNames.getLength() == 0 ) + { + aServiceNames.realloc( 1 ); + aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.CommandBar" ) ); + } + return aServiceNames; +} diff --git a/vbahelper/source/vbahelper/vbacommandbar.hxx b/vbahelper/source/vbahelper/vbacommandbar.hxx index 4f488fab6cd2..bcb5a11e9691 100644 --- a/vbahelper/source/vbahelper/vbacommandbar.hxx +++ b/vbahelper/source/vbahelper/vbacommandbar.hxx @@ -72,4 +72,38 @@ public: virtual rtl::OUString& getServiceImplName(); virtual css::uno::Sequence<rtl::OUString> getServiceNames(); }; + +/** Dummy command bar implementation. Does nothing but provide its name. */ +class VbaDummyCommandBar : public CommandBar_BASE +{ +public: + VbaDummyCommandBar( + const css::uno::Reference< ov::XHelperInterface > xParent, + const css::uno::Reference< css::uno::XComponentContext > xContext, + const ::rtl::OUString& rName, + sal_Int32 nType ) throw( css::uno::RuntimeException ); + + // Attributes + virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException); + virtual void SAL_CALL setName( const ::rtl::OUString& _name ) throw (css::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL getVisible() throw (css::uno::RuntimeException); + virtual void SAL_CALL setVisible( ::sal_Bool _visible ) throw (css::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL getEnabled() throw (css::uno::RuntimeException); + virtual void SAL_CALL setEnabled( ::sal_Bool _enabled ) throw (css::uno::RuntimeException); + + // Methods + virtual void SAL_CALL Delete( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Controls( const css::uno::Any& aIndex ) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL Type( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL FindControl( const css::uno::Any& aType, const css::uno::Any& aId, const css::uno::Any& aTag, const css::uno::Any& aVisible, const css::uno::Any& aRecursive ) throw (css::script::BasicErrorException, css::uno::RuntimeException); + + // XHelperInterface + virtual rtl::OUString& getServiceImplName(); + virtual css::uno::Sequence<rtl::OUString> getServiceNames(); + +private: + ::rtl::OUString maName; + sal_Int32 mnType; +}; + #endif//SC_VBA_COMMANDBAR_HXX diff --git a/vbahelper/source/vbahelper/vbacommandbarcontrol.cxx b/vbahelper/source/vbahelper/vbacommandbarcontrol.cxx index a4bb3adc7dbf..3f9c7ddeae89 100644 --- a/vbahelper/source/vbahelper/vbacommandbarcontrol.cxx +++ b/vbahelper/source/vbahelper/vbacommandbarcontrol.cxx @@ -141,6 +141,22 @@ ScVbaCommandBarControl::setEnabled( sal_Bool _enabled ) throw (uno::RuntimeExcep } } +::sal_Bool SAL_CALL +ScVbaCommandBarControl::getBeginGroup() throw (css::uno::RuntimeException) +{ + // TODO: need to check if the item before this item is of type 'separator' + return sal_False; +} + +void SAL_CALL +ScVbaCommandBarControl::setBeginGroup( ::sal_Bool _begin ) throw (css::uno::RuntimeException) +{ + if( getBeginGroup() != _begin ) + { + // TODO: need to insert or remove an item of type 'separator' before this item + } +} + void SAL_CALL ScVbaCommandBarControl::Delete( ) throw (script::BasicErrorException, uno::RuntimeException) { diff --git a/vbahelper/source/vbahelper/vbacommandbarcontrol.hxx b/vbahelper/source/vbahelper/vbacommandbarcontrol.hxx index 6411430bacb1..a165f8e1cccd 100644 --- a/vbahelper/source/vbahelper/vbacommandbarcontrol.hxx +++ b/vbahelper/source/vbahelper/vbacommandbarcontrol.hxx @@ -67,6 +67,8 @@ public: virtual void SAL_CALL setVisible( ::sal_Bool _visible ) throw (css::uno::RuntimeException); virtual ::sal_Bool SAL_CALL getEnabled() throw (css::uno::RuntimeException); virtual void SAL_CALL setEnabled( ::sal_Bool _enabled ) throw (css::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL getBeginGroup() throw (css::uno::RuntimeException); + virtual void SAL_CALL setBeginGroup( ::sal_Bool _begin ) throw (css::uno::RuntimeException); virtual sal_Int32 SAL_CALL getType() throw (css::uno::RuntimeException) { return ov::office::MsoControlType::msoControlButton; diff --git a/vbahelper/source/vbahelper/vbacommandbarcontrols.cxx b/vbahelper/source/vbahelper/vbacommandbarcontrols.cxx index 21e2dfb4b368..634b4a0e9395 100644 --- a/vbahelper/source/vbahelper/vbacommandbarcontrols.cxx +++ b/vbahelper/source/vbahelper/vbacommandbarcontrols.cxx @@ -34,10 +34,10 @@ typedef ::cppu::WeakImplHelper1< container::XEnumeration > CommandBarControlEnum class CommandBarControlEnumeration : public CommandBarControlEnumeration_BASE { //uno::Reference< uno::XComponentContext > m_xContext; - ScVbaCommandBarControls* m_pCommandBarControls; + CommandBarControls_BASE* m_pCommandBarControls; sal_Int32 m_nCurrentPosition; public: - CommandBarControlEnumeration( ScVbaCommandBarControls* pCommandBarControls ) : m_pCommandBarControls( pCommandBarControls ), m_nCurrentPosition( 0 ) {} + CommandBarControlEnumeration( CommandBarControls_BASE* pCommandBarControls ) : m_pCommandBarControls( pCommandBarControls ), m_nCurrentPosition( 0 ) {} virtual sal_Bool SAL_CALL hasMoreElements() throw ( uno::RuntimeException ) { if( m_nCurrentPosition < m_pCommandBarControls->getCount() ) @@ -140,7 +140,7 @@ ScVbaCommandBarControls::Item( const uno::Any& aIndex, const uno::Any& /*aIndex* { rtl::OUString sName; aIndex >>= sName; - nPosition = VbaCommandBarHelper::findControlByName( m_xIndexAccess, sName ); + nPosition = VbaCommandBarHelper::findControlByName( m_xIndexAccess, sName, m_bIsMenu ); } else { @@ -246,3 +246,75 @@ ScVbaCommandBarControls::getServiceNames() return aServiceNames; } +// ============================================================================ + +class VbaDummyIndexAccess : public ::cppu::WeakImplHelper1< container::XIndexAccess > +{ +public: + inline VbaDummyIndexAccess() {} + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException) + { return 0; } + virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 /*Index*/ ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) + { throw lang::IndexOutOfBoundsException(); } + // XElementAccess + virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException) + { return XCommandBarControl::static_type( 0 ); } + virtual ::sal_Bool SAL_CALL hasElements( ) throw (::com::sun::star::uno::RuntimeException) + { return false; } +}; + +// ---------------------------------------------------------------------------- + +VbaDummyCommandBarControls::VbaDummyCommandBarControls( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext ) throw (uno::RuntimeException) : + CommandBarControls_BASE( xParent, xContext, new VbaDummyIndexAccess ) +{ +} + +// XEnumerationAccess +uno::Type SAL_CALL VbaDummyCommandBarControls::getElementType() throw ( uno::RuntimeException ) +{ + return XCommandBarControl::static_type( 0 ); +} + +uno::Reference< container::XEnumeration > VbaDummyCommandBarControls::createEnumeration() throw ( uno::RuntimeException ) +{ + return uno::Reference< container::XEnumeration >( new CommandBarControlEnumeration( this ) ); +} + +uno::Any VbaDummyCommandBarControls::createCollectionObject( const uno::Any& /*aSource*/ ) +{ + return uno::Any( uno::Reference< XCommandBarControl >() ); +} + +// Methods +uno::Any SAL_CALL VbaDummyCommandBarControls::Item( const uno::Any& /*aIndex*/, const uno::Any& /*aIndex*/ ) throw (uno::RuntimeException) +{ + return uno::Any( uno::Reference< XCommandBarControl >() ); +} + +uno::Reference< XCommandBarControl > SAL_CALL VbaDummyCommandBarControls::Add( + const uno::Any& /*Type*/, const uno::Any& /*Id*/, const uno::Any& /*Parameter*/, const uno::Any& /*Before*/, const uno::Any& /*Temporary*/ ) throw (script::BasicErrorException, uno::RuntimeException) +{ + return uno::Reference< XCommandBarControl >(); +} + +// XHelperInterface +rtl::OUString& VbaDummyCommandBarControls::getServiceImplName() +{ + static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("VbaDummyCommandBarControls") ); + return sImplName; +} + +uno::Sequence<rtl::OUString> VbaDummyCommandBarControls::getServiceNames() +{ + static uno::Sequence< rtl::OUString > aServiceNames; + if ( aServiceNames.getLength() == 0 ) + { + aServiceNames.realloc( 1 ); + aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.CommandBarControls" ) ); + } + return aServiceNames; +} diff --git a/vbahelper/source/vbahelper/vbacommandbarcontrols.hxx b/vbahelper/source/vbahelper/vbacommandbarcontrols.hxx index 534ba5a10966..0b35773660d1 100644 --- a/vbahelper/source/vbahelper/vbacommandbarcontrols.hxx +++ b/vbahelper/source/vbahelper/vbacommandbarcontrols.hxx @@ -64,4 +64,24 @@ public: virtual css::uno::Sequence<rtl::OUString> getServiceNames(); }; +class VbaDummyCommandBarControls : public CommandBarControls_BASE +{ +public: + VbaDummyCommandBarControls( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext ) throw( css::uno::RuntimeException ); + + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException); + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException); + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ); + + // Methods + virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index, const css::uno::Any& /*Index2*/ ) throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::XCommandBarControl > SAL_CALL Add( const css::uno::Any& Type, const css::uno::Any& Id, const css::uno::Any& Parameter, const css::uno::Any& Before, const css::uno::Any& Temporary ) throw (css::script::BasicErrorException, css::uno::RuntimeException); + // XHelperInterface + virtual rtl::OUString& getServiceImplName(); + virtual css::uno::Sequence<rtl::OUString> getServiceNames(); +}; + #endif//SC_VBA_COMMANDBARCONTROLS_HXX diff --git a/vbahelper/source/vbahelper/vbacommandbarhelper.cxx b/vbahelper/source/vbahelper/vbacommandbarhelper.cxx index 06b997186169..385b220d201c 100644 --- a/vbahelper/source/vbahelper/vbacommandbarhelper.cxx +++ b/vbahelper/source/vbahelper/vbacommandbarhelper.cxx @@ -30,11 +30,10 @@ #include <com/sun/star/ui/XModuleUIConfigurationManager.hpp> #include <com/sun/star/ui/XUIConfigurationPersistence.hpp> #include <com/sun/star/ui/XUIElement.hpp> -#ifndef _COM_SUN_STAR_UI_UIElementType_HPP_ #include <com/sun/star/ui/UIElementType.hpp> -#endif #include <comphelper/processfactory.hxx> #include <vbahelper/vbahelper.hxx> +#include <rtl/ustrbuf.hxx> #include <time.h> #include <map> @@ -233,7 +232,7 @@ rtl::OUString VbaCommandBarHelper::findToolbarByName( const css::uno::Reference< } // if found, return the position of the control. if not found, return -1 -sal_Int32 VbaCommandBarHelper::findControlByName( const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess, const rtl::OUString& sName ) throw (css::uno::RuntimeException) +sal_Int32 VbaCommandBarHelper::findControlByName( const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess, const rtl::OUString& sName, bool bMenu ) throw (css::uno::RuntimeException) { sal_Int32 nCount = xIndexAccess->getCount(); css::uno::Sequence< css::beans::PropertyValue > aProps; @@ -242,17 +241,21 @@ sal_Int32 VbaCommandBarHelper::findControlByName( const css::uno::Reference< css rtl::OUString sLabel; xIndexAccess->getByIndex( i ) >>= aProps; getPropertyValue( aProps, rtl::OUString::createFromAscii(ITEM_DESCRIPTOR_LABEL) ) >>= sLabel; - // handle the hotkey character '~' - rtl::OUString sNewLabel; + // handle the hotkey marker '~' (remove in toolbars (?), replace by '&' in menus) + ::rtl::OUStringBuffer aBuffer; sal_Int32 index = sLabel.indexOf( sal_Unicode('~') ); if( index < 0 ) - sNewLabel = sLabel; - else if( index == 0 ) - sNewLabel = sLabel.copy( index + 1); - else if( index == sNewLabel.getLength() - 1 ) - sNewLabel = sLabel.copy(0, index ); + { + aBuffer = sLabel; + } else - sNewLabel = sLabel.copy( 0, index ) + sLabel.copy( index + 1 ); + { + aBuffer.append( sLabel.copy( 0, index ) ); + if( bMenu ) + aBuffer.append( sal_Unicode( '&' ) ); + aBuffer.append( sLabel.copy( index + 1 ) ); + } + rtl::OUString sNewLabel = aBuffer.makeStringAndClear(); OSL_TRACE("VbaCommandBarHelper::findControlByName, control name: %s", rtl::OUStringToOString( sNewLabel, RTL_TEXTENCODING_UTF8 ).getStr() ); if( sName.equalsIgnoreAsciiCase( sNewLabel ) ) return i; diff --git a/vbahelper/source/vbahelper/vbacommandbarhelper.hxx b/vbahelper/source/vbahelper/vbacommandbarhelper.hxx index 1c18af07b3df..1fa41d7141b3 100644 --- a/vbahelper/source/vbahelper/vbacommandbarhelper.hxx +++ b/vbahelper/source/vbahelper/vbacommandbarhelper.hxx @@ -95,8 +95,8 @@ public: const rtl::OUString getModuleId(){ return maModuleId; } rtl::OUString findToolbarByName( const css::uno::Reference< css::container::XNameAccess >& xNameAccess, const rtl::OUString& sName ) throw (css::uno::RuntimeException); - static sal_Int32 findControlByName( const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess, const rtl::OUString& sName ) throw (css::uno::RuntimeException); + static sal_Int32 findControlByName( const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess, const rtl::OUString& sName, bool bMenu = false ) throw (css::uno::RuntimeException); static rtl::OUString generateCustomURL(); }; -#endif//VBA_COMMANDBARHELPER_HXX +#endif //VBA_COMMANDBARHELPER_HXX diff --git a/vbahelper/source/vbahelper/vbacommandbars.cxx b/vbahelper/source/vbahelper/vbacommandbars.cxx index 3e7bdc6d53e8..9d6cd9e2eea7 100644 --- a/vbahelper/source/vbahelper/vbacommandbars.cxx +++ b/vbahelper/source/vbahelper/vbacommandbars.cxx @@ -31,6 +31,7 @@ #include <com/sun/star/ui/XUIConfigurationStorage.hpp> #include <com/sun/star/ui/XModuleUIConfigurationManager.hpp> #include <com/sun/star/ui/XUIConfigurationPersistence.hpp> +#include <ooo/vba/office/MsoBarType.hpp> #include "vbacommandbars.hxx" #include "vbacommandbar.hxx" @@ -45,13 +46,13 @@ class CommandBarEnumeration : public CommandBarEnumeration_BASE { uno::Reference< XHelperInterface > m_xParent; uno::Reference< uno::XComponentContext > m_xContext; - VbaCommandBarHelperRef pCBarHelper; + VbaCommandBarHelperRef m_pCBarHelper; uno::Sequence< rtl::OUString > m_sNames; sal_Int32 m_nCurrentPosition; public: - CommandBarEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, VbaCommandBarHelperRef pHelper) throw ( uno::RuntimeException ) : m_xParent( xParent ), m_xContext( xContext ), pCBarHelper( pHelper ) , m_nCurrentPosition( 0 ) + CommandBarEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, VbaCommandBarHelperRef pHelper) throw ( uno::RuntimeException ) : m_xParent( xParent ), m_xContext( xContext ), m_pCBarHelper( pHelper ) , m_nCurrentPosition( 0 ) { - uno::Reference< container::XNameAccess > xNameAccess = pCBarHelper->getPersistentWindowState(); + uno::Reference< container::XNameAccess > xNameAccess = m_pCBarHelper->getPersistentWindowState(); m_sNames = xNameAccess->getElementNames(); } virtual sal_Bool SAL_CALL hasMoreElements() throw ( uno::RuntimeException ) @@ -68,8 +69,8 @@ public: rtl::OUString sResourceUrl( m_sNames[ m_nCurrentPosition++ ] ); if( sResourceUrl.indexOf( rtl::OUString::createFromAscii("private:resource/toolbar/") ) != -1 ) { - uno::Reference< container::XIndexAccess > xCBarSetting = pCBarHelper->getSettings( sResourceUrl ); - uno::Reference< XCommandBar > xCommandBar( new ScVbaCommandBar( m_xParent, m_xContext, pCBarHelper, xCBarSetting, sResourceUrl, sal_False, sal_False ) ); + uno::Reference< container::XIndexAccess > xCBarSetting = m_pCBarHelper->getSettings( sResourceUrl ); + uno::Reference< XCommandBar > xCommandBar( new ScVbaCommandBar( m_xParent, m_xContext, m_pCBarHelper, xCBarSetting, sResourceUrl, sal_False, sal_False ) ); } else return nextElement(); @@ -82,8 +83,8 @@ public: ScVbaCommandBars::ScVbaCommandBars( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) : CommandBars_BASE( xParent, xContext, xIndexAccess ) { - pCBarHelper.reset( new VbaCommandBarHelper( mxContext, xModel ) ); - m_xNameAccess = pCBarHelper->getPersistentWindowState(); + m_pCBarHelper.reset( new VbaCommandBarHelper( mxContext, xModel ) ); + m_xNameAccess = m_pCBarHelper->getPersistentWindowState(); } ScVbaCommandBars::~ScVbaCommandBars() @@ -100,7 +101,7 @@ ScVbaCommandBars::getElementType() throw ( uno::RuntimeException ) uno::Reference< container::XEnumeration > ScVbaCommandBars::createEnumeration() throw ( uno::RuntimeException ) { - return uno::Reference< container::XEnumeration >( new CommandBarEnumeration( this, mxContext, pCBarHelper ) ); + return uno::Reference< container::XEnumeration >( new CommandBarEnumeration( this, mxContext, m_pCBarHelper ) ); } uno::Any @@ -111,28 +112,53 @@ ScVbaCommandBars::createCollectionObject( const uno::Any& aSource ) uno::Reference< container::XIndexAccess > xBarSettings; rtl::OUString sBarName; sal_Bool bMenu = sal_False; + uno::Any aRet; + if( aSource >>= sBarName ) { - if( sBarName.equalsIgnoreAsciiCase( rtl::OUString::createFromAscii("Worksheet Menu Bar") ) - || sBarName.equalsIgnoreAsciiCase( rtl::OUString::createFromAscii("Menu Bar") ) ) + // some built-in command bars + if( m_pCBarHelper->getModuleId().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.sheet.SpreadsheetDocument") ) ) { - // menu bar - sResourceUrl = rtl::OUString::createFromAscii( ITEM_MENUBAR_URL ); - bMenu = sal_True; + if( sBarName.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM("Worksheet Menu Bar") ) ) + { + // spreadsheet menu bar + sResourceUrl = rtl::OUString::createFromAscii( ITEM_MENUBAR_URL ); + bMenu = sal_True; + } + else if( sBarName.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM("Cell") ) ) + { + // EVIL HACK (tm): spreadsheet cell context menu as dummy object without functionality + aRet <<= uno::Reference< XCommandBar >( new VbaDummyCommandBar( this, mxContext, sBarName, office::MsoBarType::msoBarTypePopup ) ); + } } - else + else if( m_pCBarHelper->getModuleId().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.text.TextDocument") ) ) + { + if( sBarName.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM("Menu Bar") ) ) + { + // text processor menu bar + sResourceUrl = rtl::OUString::createFromAscii( ITEM_MENUBAR_URL ); + bMenu = sal_True; + } + } + + // nothing found - try to resolve from name + if( !aRet.hasValue() && (sResourceUrl.getLength() == 0) ) { - sResourceUrl = pCBarHelper->findToolbarByName( m_xNameAccess, sBarName ); + sResourceUrl = m_pCBarHelper->findToolbarByName( m_xNameAccess, sBarName ); bMenu = sal_False; } } if( sResourceUrl.getLength() ) - xBarSettings = pCBarHelper->getSettings( sResourceUrl ); - else + { + xBarSettings = m_pCBarHelper->getSettings( sResourceUrl ); + aRet <<= uno::Reference< XCommandBar >( new ScVbaCommandBar( this, mxContext, m_pCBarHelper, xBarSettings, sResourceUrl, bMenu, sal_False ) ); + } + + if( !aRet.hasValue() ) throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Toolbar do not exist") ), uno::Reference< uno::XInterface >() ); - return uno::Any( uno::Reference< XCommandBar >( new ScVbaCommandBar( this, mxContext, pCBarHelper, xBarSettings, sResourceUrl, bMenu, sal_False ) ) ); + return aRet; } // XCommandBars @@ -149,7 +175,7 @@ ScVbaCommandBars::Add( const css::uno::Any& Name, const css::uno::Any& /*Positio rtl::OUString sResourceUrl; if( sName.getLength() ) { - sResourceUrl = pCBarHelper->findToolbarByName( m_xNameAccess, sName ); + sResourceUrl = m_pCBarHelper->findToolbarByName( m_xNameAccess, sName ); if( sResourceUrl.getLength() ) throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Toolbar exists") ), uno::Reference< uno::XInterface >() ); } @@ -163,8 +189,8 @@ ScVbaCommandBars::Add( const css::uno::Any& Name, const css::uno::Any& /*Positio Temporary >>= bTemporary; sResourceUrl = VbaCommandBarHelper::generateCustomURL(); - uno::Reference< container::XIndexAccess > xBarSettings( pCBarHelper->getSettings( sResourceUrl ), uno::UNO_QUERY_THROW ); - uno::Reference< XCommandBar > xCBar( new ScVbaCommandBar( this, mxContext, pCBarHelper, xBarSettings, sResourceUrl, sal_False, bTemporary ) ); + uno::Reference< container::XIndexAccess > xBarSettings( m_pCBarHelper->getSettings( sResourceUrl ), uno::UNO_QUERY_THROW ); + uno::Reference< XCommandBar > xCBar( new ScVbaCommandBar( this, mxContext, m_pCBarHelper, xBarSettings, sResourceUrl, sal_False, bTemporary ) ); xCBar->setName( sName ); return xCBar; } @@ -199,9 +225,9 @@ ScVbaCommandBars::Item( const uno::Any& aIndex, const uno::Any& /*aIndex2*/ ) th if( nIndex == 1 ) { uno::Any aSource; - if( pCBarHelper->getModuleId().equalsAscii( "com.sun.star.sheet.SpreadsheetDocument" ) ) + if( m_pCBarHelper->getModuleId().equalsAscii( "com.sun.star.sheet.SpreadsheetDocument" ) ) aSource <<= rtl::OUString::createFromAscii( "Worksheet Menu Bar" ); - else if( pCBarHelper->getModuleId().equalsAscii("com.sun.star.text.TextDocument") ) + else if( m_pCBarHelper->getModuleId().equalsAscii("com.sun.star.text.TextDocument") ) aSource <<= rtl::OUString::createFromAscii( "Menu Bar" ); if( aSource.hasValue() ) return createCollectionObject( aSource ); diff --git a/vbahelper/source/vbahelper/vbacommandbars.hxx b/vbahelper/source/vbahelper/vbacommandbars.hxx index 698d718f7cdf..92ed1438d269 100644 --- a/vbahelper/source/vbahelper/vbacommandbars.hxx +++ b/vbahelper/source/vbahelper/vbacommandbars.hxx @@ -40,7 +40,7 @@ typedef CollTestImplHelper< ov::XCommandBars > CommandBars_BASE; class ScVbaCommandBars : public CommandBars_BASE { private: - VbaCommandBarHelperRef pCBarHelper; + VbaCommandBarHelperRef m_pCBarHelper; public: ScVbaCommandBars( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess, const css::uno::Reference< css::frame::XModel >& xModel ) throw (css::uno::RuntimeException); diff --git a/vbahelper/source/vbahelper/vbadocumentbase.cxx b/vbahelper/source/vbahelper/vbadocumentbase.cxx index fb2af0687d11..f27f2de53c8a 100644 --- a/vbahelper/source/vbahelper/vbadocumentbase.cxx +++ b/vbahelper/source/vbahelper/vbadocumentbase.cxx @@ -33,7 +33,9 @@ #include <com/sun/star/util/XCloseable.hpp> #include <com/sun/star/frame/XStorable.hpp> #include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/document/XEmbeddedScripts.hpp> //Michael E. Bohn #include <com/sun/star/beans/XPropertySet.hpp> +#include <ooo/vba/XVBADocService.hpp> #include <tools/urlobj.hxx> #include <osl/file.hxx> @@ -179,14 +181,14 @@ void VbaDocumentBase::setSaved( sal_Bool bSave ) throw (uno::RuntimeException) { uno::Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY_THROW ); - xModifiable->setModified( bSave ); + xModifiable->setModified( !bSave ); } sal_Bool VbaDocumentBase::getSaved() throw (uno::RuntimeException) { uno::Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY_THROW ); - return xModifiable->isModified(); + return !xModifiable->isModified(); } void @@ -204,6 +206,40 @@ VbaDocumentBase::Activate() throw (uno::RuntimeException) xFrame->activate(); } +// ---- Michael E.Bohn Start----- + +uno::Any SAL_CALL +VbaDocumentBase::getVBProject() throw (uno::RuntimeException) + +{ + uno::Any aAny; + uno::Reference< ::lang::XMultiComponentFactory > xServiceManager = mxContext->getServiceManager(); + try + { + uno::Reference < ::uno::XInterface > xInterface = xServiceManager->createInstanceWithContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBADocService" )),mxContext); + uno::Reference < ::ooo::vba::XVBADocService > xVBADocService (xInterface, ::uno::UNO_QUERY_THROW ); + if (xVBADocService.is()){ + uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); + uno::Reference< document::XEmbeddedScripts > xEnbeddedScripts ( xModel, uno::UNO_QUERY_THROW ); + uno::Reference< script::XStorageBasedLibraryContainer > xMacroStorageBasedLibraryContainer = xEnbeddedScripts->getBasicLibraries(); + uno::Reference< script::XStorageBasedLibraryContainer > xDialogStorageBasedLibraryContainer = xEnbeddedScripts->getDialogLibraries(); + uno::Reference< script::XLibraryContainer > xMacroLibraryContainer ( xMacroStorageBasedLibraryContainer, uno::UNO_QUERY_THROW ); + uno::Reference< script::XLibraryContainer > xDialogLibraryContainer( xDialogStorageBasedLibraryContainer, uno::UNO_QUERY_THROW ); + + return xVBADocService->getVBProject( this, mxContext, xModel, xMacroLibraryContainer, xDialogLibraryContainer ); + } + + }catch(uno::Exception* e) + { + } + return aAny; + +} + + +// ---- Michael E.Bohn End ----- + + rtl::OUString& VbaDocumentBase::getServiceImplName() { diff --git a/vbahelper/source/vbahelper/vbafontbase.cxx b/vbahelper/source/vbahelper/vbafontbase.cxx index 76e5de7761e1..3e84f55ef11a 100644 --- a/vbahelper/source/vbahelper/vbafontbase.cxx +++ b/vbahelper/source/vbahelper/vbafontbase.cxx @@ -35,7 +35,20 @@ using namespace ::ooo::vba; using namespace ::com::sun::star; -VbaFontBase::VbaFontBase( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< css::container::XIndexAccess >& xPalette, uno::Reference< beans::XPropertySet > xPropertySet ) throw ( uno::RuntimeException ) : VbaFontBase_BASE( xParent, xContext ), mxFont( xPropertySet, css::uno::UNO_QUERY_THROW ), mxPalette( xPalette ) +// form controls use other property name as the remaining OOo API +#define VBAFONTBASE_PROPNAME( ascii_normal, ascii_control ) \ + mbFormControl ? rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ascii_control ) ) : rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ascii_normal ) ) + +VbaFontBase::VbaFontBase( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< css::container::XIndexAccess >& xPalette, + const uno::Reference< beans::XPropertySet >& xPropertySet, + bool bFormControl ) throw ( uno::RuntimeException ) : + VbaFontBase_BASE( xParent, xContext ), + mxFont( xPropertySet, uno::UNO_SET_THROW ), + mxPalette( xPalette, uno::UNO_SET_THROW ), + mbFormControl( bFormControl ) { } @@ -43,19 +56,22 @@ VbaFontBase::~VbaFontBase() { } - void SAL_CALL VbaFontBase::setSuperscript( const uno::Any& aValue ) throw ( uno::RuntimeException ) { + // not supported in form controls + if( mbFormControl ) + return; + sal_Bool bValue = sal_False; aValue >>= bValue; sal_Int16 nValue = NORMAL; sal_Int8 nValue2 = NORMALHEIGHT; - if( bValue ) + if( bValue ) { nValue = SUPERSCRIPT; - nValue2 = SUPERSCRIPTHEIGHT; + nValue2 = SUPERSCRIPTHEIGHT; } mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapement" ) ), ( uno::Any )nValue ); mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapementHeight" ) ), ( uno::Any )nValue2 ); @@ -64,23 +80,29 @@ VbaFontBase::setSuperscript( const uno::Any& aValue ) throw ( uno::RuntimeExcept uno::Any SAL_CALL VbaFontBase::getSuperscript() throw ( uno::RuntimeException ) { - short nValue = 0; - mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapement" ) ) ) >>= nValue; + short nValue = NORMAL; + // not supported in form controls + if( !mbFormControl ) + mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapement" ) ) ) >>= nValue; return uno::makeAny( ( nValue == SUPERSCRIPT ) ); } void SAL_CALL VbaFontBase::setSubscript( const uno::Any& aValue ) throw ( uno::RuntimeException ) { + // not supported in form controls + if( mbFormControl ) + return; + sal_Bool bValue = sal_False; aValue >>= bValue; sal_Int16 nValue = NORMAL; sal_Int8 nValue2 = NORMALHEIGHT; - if( bValue ) + if( bValue ) { nValue= SUBSCRIPT; - nValue2 = SUBSCRIPTHEIGHT; + nValue2 = SUBSCRIPTHEIGHT; } mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapementHeight" ) ), ( uno::Any )nValue2 ); @@ -92,20 +114,30 @@ uno::Any SAL_CALL VbaFontBase::getSubscript() throw ( uno::RuntimeException ) { short nValue = NORMAL; - mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapement" ) ) ) >>= nValue; + // not supported in form controls + if( !mbFormControl ) + mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharEscapement" ) ) ) >>= nValue; return uno::makeAny( ( nValue == SUBSCRIPT ) ); } void SAL_CALL VbaFontBase::setSize( const uno::Any& aValue ) throw( uno::RuntimeException ) { - mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharHeight" ) ), aValue ); + // form controls need a sal_Int16 containing points, other APIs need a float + uno::Any aVal( aValue ); + if( mbFormControl ) + { + float fVal; + aVal >>= fVal; + aVal <<= static_cast< sal_Int16 >( fVal ); + } + mxFont->setPropertyValue( VBAFONTBASE_PROPNAME( "CharHeight", "FontHeight" ), aVal ); } uno::Any SAL_CALL VbaFontBase::getSize() throw ( uno::RuntimeException ) { - return mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharHeight" ) ) ); + return mxFont->getPropertyValue( VBAFONTBASE_PROPNAME( "CharHeight", "FontHeight" ) ); } void SAL_CALL @@ -152,7 +184,7 @@ VbaFontBase::setBold( const uno::Any& aValue ) throw( uno::RuntimeException ) double fBoldValue = awt::FontWeight::NORMAL; if( bValue ) fBoldValue = awt::FontWeight::BOLD; - mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharWeight" ) ), ( uno::Any )fBoldValue ); + mxFont->setPropertyValue( VBAFONTBASE_PROPNAME( "CharWeight", "FontWeight" ), uno::Any( fBoldValue ) ); } @@ -160,7 +192,7 @@ uno::Any SAL_CALL VbaFontBase::getBold() throw ( uno::RuntimeException ) { double fValue = 0.0; - mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharWeight" ) ) ) >>= fValue; + mxFont->getPropertyValue( VBAFONTBASE_PROPNAME( "CharWeight", "FontWeight" ) ) >>= fValue; return uno::makeAny( fValue == awt::FontWeight::BOLD ); } @@ -172,27 +204,28 @@ VbaFontBase::setStrikethrough( const uno::Any& aValue ) throw ( uno::RuntimeExce short nValue = awt::FontStrikeout::NONE; if( bValue ) nValue = awt::FontStrikeout::SINGLE; - mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharStrikeout" ) ), ( uno::Any )nValue ); + mxFont->setPropertyValue( VBAFONTBASE_PROPNAME( "CharStrikeout", "FontStrikeout" ), uno::Any( nValue ) ); } uno::Any SAL_CALL VbaFontBase::getStrikethrough() throw ( uno::RuntimeException ) { short nValue = 0; - mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharStrikeout" ) ) ) >>= nValue; + mxFont->getPropertyValue( VBAFONTBASE_PROPNAME( "CharStrikeout", "FontStrikeout" ) ) >>= nValue; return uno::Any( nValue == awt::FontStrikeout::SINGLE ); } void SAL_CALL VbaFontBase::setShadow( const uno::Any& aValue ) throw ( uno::RuntimeException ) { - mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharShadowed" ) ), aValue ); + if( !mbFormControl ) + mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharShadowed" ) ), aValue ); } uno::Any SAL_CALL VbaFontBase::getShadow() throw (uno::RuntimeException) { - return mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharShadowed" ) ) ); + return mbFormControl ? uno::Any( false ) : mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharShadowed" ) ) ); } void SAL_CALL @@ -203,15 +236,14 @@ VbaFontBase::setItalic( const uno::Any& aValue ) throw ( uno::RuntimeException ) short nValue = awt::FontSlant_NONE; if( bValue ) nValue = awt::FontSlant_ITALIC; - mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharPosture" ) ), ( uno::Any )nValue ); + mxFont->setPropertyValue( VBAFONTBASE_PROPNAME( "CharPosture", "FontSlant" ), uno::Any( nValue ) ); } uno::Any SAL_CALL VbaFontBase::getItalic() throw ( uno::RuntimeException ) { - awt::FontSlant aFS; - mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharPosture" ) ) ) >>= aFS; + mxFont->getPropertyValue( VBAFONTBASE_PROPNAME( "CharPosture", "FontSlant" ) ) >>= aFS; return uno::makeAny( aFS == awt::FontSlant_ITALIC ); } @@ -220,26 +252,27 @@ VbaFontBase::setName( const uno::Any& aValue ) throw ( uno::RuntimeException ) { rtl::OUString sString; aValue >>= sString; - mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharFontName" ) ), aValue); + mxFont->setPropertyValue( VBAFONTBASE_PROPNAME( "CharFontName", "FontName" ), aValue ); } uno::Any SAL_CALL VbaFontBase::getName() throw ( uno::RuntimeException ) { - return mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharFontName" ) ) ); + return mxFont->getPropertyValue( VBAFONTBASE_PROPNAME( "CharFontName", "FontName" ) ); } + uno::Any VbaFontBase::getColor() throw (uno::RuntimeException) { uno::Any aAny; - aAny = OORGBToXLRGB( mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharColor" ) ) ) ); + aAny = OORGBToXLRGB( mxFont->getPropertyValue( VBAFONTBASE_PROPNAME( "CharColor", "TextColor" ) ) ); return aAny; } void VbaFontBase::setColor( const uno::Any& _color ) throw (uno::RuntimeException) { - mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharColor" ) ) , XLRGBToOORGB(_color)); + mxFont->setPropertyValue( VBAFONTBASE_PROPNAME( "CharColor", "TextColor" ), XLRGBToOORGB(_color) ); } void SAL_CALL @@ -273,7 +306,7 @@ VbaFontBase::setUnderline( const uno::Any& /*aValue*/ ) throw ( uno::RuntimeExce throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Unknown value for Underline")), uno::Reference< uno::XInterface >() ); } - mxFont->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharUnderline" ) ), ( uno::Any )nValue ); + mxFont->setPropertyValue( VBAFONTBASE_PROPNAME( "CharUnderline", "FontUnderline" ), uno::Any( nValue ) ); */ } @@ -282,7 +315,7 @@ uno::Any SAL_CALL VbaFontBase::getUnderline() throw ( uno::RuntimeException ) { sal_Int32 nValue = awt::FontUnderline::NONE; - mxFont->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharUnderline" ) ) ) >>= nValue; + mxFont->getPropertyValue( VBAFONTBASE_PROPNAME( "CharUnderline", "FontUnderline" ) ) >>= nValue; /* switch ( nValue ) { diff --git a/vbahelper/source/vbahelper/vbahelper.cxx b/vbahelper/source/vbahelper/vbahelper.cxx index a9e72318536d..1953d0772f3c 100644 --- a/vbahelper/source/vbahelper/vbahelper.cxx +++ b/vbahelper/source/vbahelper/vbahelper.cxx @@ -31,11 +31,15 @@ #include <com/sun/star/frame/XFrame.hpp> #include <com/sun/star/frame/XDesktop.hpp> #include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/frame/XModel2.hpp> #include <com/sun/star/script/XDefaultProperty.hpp> #include <com/sun/star/uno/XComponentContext.hpp> #include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/XIntrospection.hpp> +#include <com/sun/star/util/MeasureUnit.hpp> + #include <ooo/vba/msforms/XShape.hpp> #include <comphelper/processfactory.hxx> @@ -63,8 +67,6 @@ #include <osl/file.hxx> #include <toolkit/awt/vclxwindow.hxx> #include <toolkit/helper/vclunohelper.hxx> -#include <com/sun/star/frame/XModel2.hpp> -#include <com/sun/star/lang/XUnoTunnel.hpp> #include <vcl/window.hxx> #include <vcl/syswin.hxx> #include <tools/diagnose_ex.h> @@ -82,12 +84,6 @@ using namespace ::com::sun::star; using namespace ::ooo::vba; -#define NAME_HEIGHT "Height" -#define NAME_WIDTH "Width" - -#define POINTTO100THMILLIMETERFACTOR 35.27778 - - void unoToSbxValue( SbxVariable* pVar, const uno::Any& aValue ); uno::Any sbxToUnoValue( SbxVariable* pVar ); @@ -98,6 +94,8 @@ namespace ooo namespace vba { +namespace { const double factor = 2540.0 / 72.0; } + css::uno::Reference< css::uno::XInterface > createVBAUnoAPIService( SfxObjectShell* pShell, const sal_Char* _pAsciiName ) throw (css::uno::RuntimeException) { OSL_PRECOND( pShell, "createVBAUnoAPIService: no shell!" ); @@ -271,7 +269,6 @@ getCurrentViewFrame() }; #endif -const double Millimeter::factor = 35.27778; uno::Reference< beans::XIntrospectionAccess > getIntrospectionAccess( const uno::Any& aObject ) throw (uno::RuntimeException) @@ -314,10 +311,9 @@ void dispatchExecute(SfxViewShell* pViewShell, USHORT nSlot, SfxCallMode nCall) } void -dispatchRequests (uno::Reference< frame::XModel>& xModel,rtl::OUString & aUrl, uno::Sequence< beans::PropertyValue >& sProps ) +dispatchRequests( const uno::Reference< frame::XModel>& xModel, const rtl::OUString& aUrl, const uno::Sequence< beans::PropertyValue >& sProps ) { - - util::URL url ; + util::URL url; url.Complete = aUrl; rtl::OUString emptyString = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "" )); uno::Reference<frame::XController> xController = xModel->getCurrentController(); @@ -328,25 +324,22 @@ dispatchRequests (uno::Reference< frame::XModel>& xModel,rtl::OUString & aUrl, u uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW ); uno::Reference<uno::XComponentContext > xContext( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), uno::UNO_QUERY_THROW ); if ( !xContext.is() ) - { - return ; - } + return; - uno::Reference<lang::XMultiComponentFactory > xServiceManager( - xContext->getServiceManager() ); + uno::Reference<lang::XMultiComponentFactory > xServiceManager = xContext->getServiceManager(); if ( !xServiceManager.is() ) - { - return ; - } - uno::Reference<util::XURLTransformer> xParser( xServiceManager->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ) ) - ,xContext), uno::UNO_QUERY_THROW ); + return; + + uno::Reference<util::XURLTransformer> xParser( xServiceManager->createInstanceWithContext( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ) ), xContext), + uno::UNO_QUERY_THROW ); if (!xParser.is()) return; xParser->parseStrict (url); } catch ( uno::Exception & /*e*/ ) { - return ; + return; } uno::Reference<frame::XDispatch> xDispatcher = xDispatchProvider->queryDispatch(url,emptyString,0); @@ -360,7 +353,7 @@ dispatchRequests (uno::Reference< frame::XModel>& xModel,rtl::OUString & aUrl, u dispatchProps.realloc( nProps + 1 ); // need to reaccquire pDest after realloc pDest = dispatchProps.getArray(); - beans::PropertyValue* pSrc = sProps.getArray(); + const beans::PropertyValue* pSrc = sProps.getConstArray(); for ( sal_Int32 index=0; index<nProps; ++index, ++pSrc, ++pDest ) *pDest = *pSrc; } @@ -373,16 +366,13 @@ dispatchRequests (uno::Reference< frame::XModel>& xModel,rtl::OUString & aUrl, u } void -dispatchRequests (uno::Reference< frame::XModel>& xModel,rtl::OUString & aUrl) +dispatchRequests( const uno::Reference< frame::XModel>& xModel, const rtl::OUString& aUrl ) { uno::Sequence<beans::PropertyValue> dispatchProps; dispatchRequests( xModel, aUrl, dispatchProps ); } - - - - uno::Reference< frame::XModel > +uno::Reference< frame::XModel > getCurrentDoc( const rtl::OUString& sKey ) throw (uno::RuntimeException) { uno::Reference< frame::XModel > xModel; @@ -840,12 +830,22 @@ double getPixelTo100thMillimeterConversionFactor( css::uno::Reference< css::awt: double PointsToPixels( css::uno::Reference< css::awt::XDevice >& xDevice, double fPoints, sal_Bool bVertical) { double fConvertFactor = getPixelTo100thMillimeterConversionFactor( xDevice, bVertical ); - return fPoints * POINTTO100THMILLIMETERFACTOR * fConvertFactor; + return PointsToHmm( fPoints ) * fConvertFactor; } double PixelsToPoints( css::uno::Reference< css::awt::XDevice >& xDevice, double fPixels, sal_Bool bVertical) { double fConvertFactor = getPixelTo100thMillimeterConversionFactor( xDevice, bVertical ); - return (fPixels/fConvertFactor)/POINTTO100THMILLIMETERFACTOR; + return HmmToPoints( fPixels/fConvertFactor ); +} + +sal_Int32 PointsToHmm( double fPoints ) +{ + return static_cast<sal_Int32>( fPoints * factor + 0.5 ); +} + +double HmmToPoints( sal_Int32 nHmm ) +{ + return nHmm / factor; } ConcreteXShapeGeometryAttributes::ConcreteXShapeGeometryAttributes( const css::uno::Reference< css::uno::XComponentContext >& /*xContext*/, const css::uno::Reference< css::drawing::XShape >& xShape ) @@ -962,53 +962,284 @@ sal_Bool setPropertyValue( uno::Sequence< beans::PropertyValue >& aProp, const r return sal_False; } -#define VBA_LEFT "PositionX" -#define VBA_TOP "PositionY" +// ====UserFormGeomentryHelper==== +//--------------------------------------------- UserFormGeometryHelper::UserFormGeometryHelper( const uno::Reference< uno::XComponentContext >& /*xContext*/, const uno::Reference< awt::XControl >& xControl ) { + if ( !xControl.is() ) + throw uno::RuntimeException(); + + mxControlUnits.set( xControl->getPeer(), uno::UNO_QUERY_THROW ); mxModel.set( xControl->getModel(), uno::UNO_QUERY_THROW ); } - double UserFormGeometryHelper::getLeft() + +//--------------------------------------------- +sal_Int32 UserFormGeometryHelper::ConvertPixelToLogic( sal_Int32 nValue, sal_Bool bIsPoint, sal_Bool bIsX, sal_Int16 nTargetUnit ) +{ + sal_Int32 nResult = 0; + if ( bIsPoint ) + { + // conversion for a point + awt::Point aPixelPoint( 0, 0 ); + ( bIsX ? aPixelPoint.X : aPixelPoint.Y ) = nValue; + awt::Point aTargetPoint( 0, 0 ); + aTargetPoint = mxControlUnits->convertPointToLogic( aPixelPoint, nTargetUnit ); + + nResult = bIsX ? aTargetPoint.X : aTargetPoint.Y; + } + else + { + // conversion for a size + awt::Size aPixelSize( 0, 0 ); + ( bIsX ? aPixelSize.Width : aPixelSize.Height ) = nValue; + awt::Size aTargetSize( 0, 0 ); + aTargetSize = mxControlUnits->convertSizeToLogic( aPixelSize, nTargetUnit ); + + nResult = bIsX ? aTargetSize.Width : aTargetSize.Height; + } + + return nResult; +} + +//--------------------------------------------- +sal_Int32 UserFormGeometryHelper::ConvertLogicToPixel( sal_Int32 nValue, sal_Bool bIsPoint, sal_Bool bIsX, sal_Int16 nSourceUnit ) +{ + sal_Int32 nResult = 0; + if ( bIsPoint ) + { + // conversion for a point + awt::Point aSourcePoint( 0, 0 ); + ( bIsX ? aSourcePoint.X : aSourcePoint.Y ) = nValue; + + awt::Point aPixelPoint( 0, 0 ); + aPixelPoint = mxControlUnits->convertPointToPixel( aSourcePoint, nSourceUnit ); + + nResult = bIsX ? aPixelPoint.X : aPixelPoint.Y; + } + else + { + // conversion for a size + awt::Size aSourceSize( 0, 0 ); + ( bIsX ? aSourceSize.Width : aSourceSize.Height ) = nValue; + + awt::Size aPixelSize( 0, 0 ); + aPixelSize = mxControlUnits->convertSizeToPixel( aSourceSize, nSourceUnit ); + + nResult = bIsX ? aPixelSize.Width : aPixelSize.Height; + } + + return nResult; +} +//--------------------------------------------- +double UserFormGeometryHelper::getLeft() +{ + double nResult = 0; + + try + { + sal_Int32 nLeft = 0; + mxModel->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VBA_LEFT ) ) ) >>= nLeft; + nResult = ConvertLogicToPixel( nLeft, + sal_True, // Point + sal_True, // X + util::MeasureUnit::APPFONT ); + } + catch ( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& e ) + { + throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can not get position X!" ) ), + uno::Reference< uno::XInterface >(), + uno::makeAny( e ) ); + } + + return nResult; +} + +//--------------------------------------------- +void UserFormGeometryHelper::setLeft( double nLeft ) +{ + try + { + mxModel->setPropertyValue( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VBA_LEFT ) ), + uno::makeAny( ConvertPixelToLogic( nLeft, + sal_True, // Point + sal_True, // X + util::MeasureUnit::APPFONT ) ) ); + } + catch ( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& e ) + { + throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can not set position X!" ) ), + uno::Reference< uno::XInterface >(), + uno::makeAny( e ) ); + } +} + +//--------------------------------------------- +double UserFormGeometryHelper::getTop() +{ + double nResult = 0; + + try { - sal_Int32 nLeft = 0; - mxModel->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VBA_LEFT ) ) ) >>= nLeft; - return Millimeter::getInPoints( nLeft ); + sal_Int32 nTop = 0; + mxModel->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VBA_TOP ) ) ) >>= nTop; + nResult = ConvertLogicToPixel( nTop, + sal_True, // Point + sal_False, // Y + util::MeasureUnit::APPFONT ); } - void UserFormGeometryHelper::setLeft( double nLeft ) + catch ( uno::RuntimeException& ) { - mxModel->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VBA_LEFT ) ), uno::makeAny( Millimeter::getInHundredthsOfOneMillimeter( nLeft ) ) ); + throw; } - double UserFormGeometryHelper::getTop() + catch ( uno::Exception& e ) { - sal_Int32 nTop = 0; - mxModel->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VBA_TOP ) ) ) >>= nTop; - return Millimeter::getInPoints( nTop ); + throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can not get position Y!" ) ), + uno::Reference< uno::XInterface >(), + uno::makeAny( e ) ); } - void UserFormGeometryHelper::setTop( double nTop ) + + return nResult; +} + +//--------------------------------------------- +void UserFormGeometryHelper::setTop( double nTop ) +{ + try + { + mxModel->setPropertyValue( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VBA_TOP ) ), + uno::makeAny( ConvertPixelToLogic( nTop, + sal_True, // Point + sal_False, // Y + util::MeasureUnit::APPFONT ) ) ); + } + catch ( uno::RuntimeException& ) { - mxModel->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VBA_TOP ) ), uno::makeAny( Millimeter::getInHundredthsOfOneMillimeter( nTop ) ) ); + throw; } - double UserFormGeometryHelper::getHeight() + catch ( uno::Exception& e ) { - sal_Int32 nHeight = 0; - mxModel->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( NAME_HEIGHT ) ) ) >>= nHeight; - return Millimeter::getInPoints( nHeight ); + throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can not set position X!" ) ), + uno::Reference< uno::XInterface >(), + uno::makeAny( e ) ); } - void UserFormGeometryHelper::setHeight( double nHeight ) +} + +//--------------------------------------------- +double UserFormGeometryHelper::getWidth() +{ + double nResult = 0; + + try { - mxModel->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( NAME_HEIGHT ) ), uno::makeAny( Millimeter::getInHundredthsOfOneMillimeter( nHeight ) ) ); + sal_Int32 nWidth = 0; + mxModel->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VBA_WIDTH ) ) ) >>= nWidth; + nResult = ConvertLogicToPixel( nWidth, + sal_False, // Size + sal_True, // X + util::MeasureUnit::APPFONT ); } - double UserFormGeometryHelper::getWidth() + catch ( uno::RuntimeException& ) { - sal_Int32 nWidth = 0; - mxModel->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( NAME_WIDTH ) ) ) >>= nWidth; - return Millimeter::getInPoints( nWidth ); + throw; } - void UserFormGeometryHelper::setWidth( double nWidth) + catch ( uno::Exception& e ) { - mxModel->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( NAME_WIDTH ) ), uno::makeAny( Millimeter::getInHundredthsOfOneMillimeter( nWidth ) ) ); + throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can not get width!" ) ), + uno::Reference< uno::XInterface >(), + uno::makeAny( e ) ); } + return nResult; +} + +//--------------------------------------------- +void UserFormGeometryHelper::setWidth( double nWidth) +{ + try + { + mxModel->setPropertyValue( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VBA_WIDTH ) ), + uno::makeAny( ConvertPixelToLogic( nWidth, + sal_False, // Size + sal_True, // X + util::MeasureUnit::APPFONT ) ) ); + } + catch ( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& e ) + { + throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can not set width!" ) ), + uno::Reference< uno::XInterface >(), + uno::makeAny( e ) ); + } +} + +//--------------------------------------------- +double UserFormGeometryHelper::getHeight() +{ + double nResult = 0; + + try + { + sal_Int32 nHeight = 0; + mxModel->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VBA_HEIGHT ) ) ) >>= nHeight; + nResult = ConvertLogicToPixel( nHeight, + sal_False, // Size + sal_False, // Y + util::MeasureUnit::APPFONT ); + } + catch ( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& e ) + { + throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can not get height!" ) ), + uno::Reference< uno::XInterface >(), + uno::makeAny( e ) ); + } + + return nResult; +} + +//--------------------------------------------- +void UserFormGeometryHelper::setHeight( double nHeight ) +{ + try + { + mxModel->setPropertyValue( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VBA_HEIGHT ) ), + uno::makeAny( ConvertPixelToLogic( nHeight, + sal_False, // Size + sal_False, // Y + util::MeasureUnit::APPFONT ) ) ); + } + catch ( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& e ) + { + throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can not set height!" ) ), + uno::Reference< uno::XInterface >(), + uno::makeAny( e ) ); + } +} + +// ============ + double ConcreteXShapeGeometryAttributes::getLeft() { return m_pShapeHelper->getLeft(); @@ -1140,8 +1371,7 @@ UserFormGeometryHelper::UserFormGeometryHelper( const uno::Reference< uno::XComp void Millimeter::set(double mm) { m_nMillimeter = mm; } void Millimeter::setInPoints(double points) { - m_nMillimeter = points * 0.352777778; - // 25.4mm / 72 + m_nMillimeter = points * factor / 100.0; } void Millimeter::setInHundredthsOfOneMillimeter(double hmm) @@ -1159,7 +1389,7 @@ UserFormGeometryHelper::UserFormGeometryHelper( const uno::Reference< uno::XComp } double Millimeter::getInPoints() { - return m_nMillimeter * 2.834645669; // 72 / 25.4mm + return m_nMillimeter / factor * 100.0; } sal_Int32 Millimeter::getInHundredthsOfOneMillimeter(double points) diff --git a/xmloff/inc/xmloff/XMLEventExport.hxx b/xmloff/inc/xmloff/XMLEventExport.hxx index 4a8a8b8d45b5..b0ec63b45b35 100644 --- a/xmloff/inc/xmloff/XMLEventExport.hxx +++ b/xmloff/inc/xmloff/XMLEventExport.hxx @@ -73,6 +73,8 @@ class XMLOFF_DLLPUBLIC XMLEventExport HandlerMap aHandlerMap; NameMap aNameTranslationMap; + bool bExtNamespace; + public: XMLEventExport(SvXMLExport& rExport, const XMLEventNameTranslation* pTranslationTable = NULL); @@ -104,6 +106,12 @@ public: ::com::sun::star::container::XNameAccess> & xAccess, sal_Bool bUseWhitespace = sal_True); + /// export the events, but write <officeooo:events> element + /// (for new file format additions) + void ExportExt( ::com::sun::star::uno::Reference< + ::com::sun::star::container::XNameAccess> & xAccess, + sal_Bool bUseWhitespace = sal_True); + /// export a single event (writes <office:events> element) void ExportSingleEvent( ::com::sun::star::uno::Sequence< diff --git a/xmloff/source/script/XMLEventExport.cxx b/xmloff/source/script/XMLEventExport.cxx index e7c716a39372..f126fd566e94 100644 --- a/xmloff/source/script/XMLEventExport.cxx +++ b/xmloff/source/script/XMLEventExport.cxx @@ -62,7 +62,8 @@ using ::xmloff::token::XML_EVENT_LISTENERS; XMLEventExport::XMLEventExport(SvXMLExport& rExp, const XMLEventNameTranslation* pTranslationTable) : sEventType(RTL_CONSTASCII_USTRINGPARAM("EventType")), - rExport(rExp) + rExport(rExp), + bExtNamespace(false) { AddTranslationTable(pTranslationTable); } @@ -175,6 +176,16 @@ void XMLEventExport::Export( Reference<XNameAccess> & rAccess, } } +void XMLEventExport::ExportExt( Reference<XNameAccess> & rAccess, + sal_Bool bWhitespace ) +{ + // set bExtNamespace flag to use XML_NAMESPACE_OFFICE_EXT namespace + // for events element (not for child elements) + bExtNamespace = true; + Export(rAccess, bWhitespace); + bExtNamespace = false; // reset for future Export calls +} + /// export a singular event and wirte <office:events> container void XMLEventExport::ExportSingleEvent( Sequence<PropertyValue>& rEventValues, @@ -270,13 +281,17 @@ void XMLEventExport::StartElement(sal_Bool bWhitespace) { rExport.IgnorableWhitespace(); } - rExport.StartElement( XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, + sal_uInt16 nNamespace = bExtNamespace ? XML_NAMESPACE_OFFICE_EXT + : XML_NAMESPACE_OFFICE; + rExport.StartElement( nNamespace, XML_EVENT_LISTENERS, bWhitespace); } void XMLEventExport::EndElement(sal_Bool bWhitespace) { - rExport.EndElement(XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, bWhitespace); + sal_uInt16 nNamespace = bExtNamespace ? XML_NAMESPACE_OFFICE_EXT + : XML_NAMESPACE_OFFICE; + rExport.EndElement(nNamespace, XML_EVENT_LISTENERS, bWhitespace); if (bWhitespace) { rExport.IgnorableWhitespace(); @@ -343,6 +358,10 @@ const XMLEventNameTranslation aStandardEventTable[] = { "OnFieldMerge", XML_NAMESPACE_OFFICE, "field-merge" }, { "OnFieldMergeFinished", XML_NAMESPACE_OFFICE, "field-merge-finished" }, { "OnLayoutFinished", XML_NAMESPACE_OFFICE, "layout-finished" }, + { "OnDoubleClick", XML_NAMESPACE_OFFICE, "dblclick" }, + { "OnRightClick", XML_NAMESPACE_OFFICE, "contextmenu" }, + { "OnChange", XML_NAMESPACE_OFFICE, "content-changed" }, + { "OnCalculate", XML_NAMESPACE_OFFICE, "calculated" }, { NULL, 0, 0 } }; diff --git a/xmlscript/inc/xmlscript/xmlmod_imexp.hxx b/xmlscript/inc/xmlscript/xmlmod_imexp.hxx index c7c1d6d1acdc..a2873542d10c 100644 --- a/xmlscript/inc/xmlscript/xmlmod_imexp.hxx +++ b/xmlscript/inc/xmlscript/xmlmod_imexp.hxx @@ -45,6 +45,7 @@ struct ModuleDescriptor ::rtl::OUString aName; ::rtl::OUString aLanguage; ::rtl::OUString aCode; + ::rtl::OUString aModuleType; // VBA }; void diff --git a/xmlscript/source/xmlmod_imexp/xmlmod_export.cxx b/xmlscript/source/xmlmod_imexp/xmlmod_export.cxx index ba23ad031f91..781d2d779dda 100644 --- a/xmlscript/source/xmlmod_imexp/xmlmod_export.cxx +++ b/xmlscript/source/xmlmod_imexp/xmlmod_export.cxx @@ -65,6 +65,9 @@ SAL_CALL exportScriptModule( rMod.aName ); pModElement->addAttribute( OUString( RTL_CONSTASCII_USTRINGPARAM(XMLNS_SCRIPT_PREFIX ":language") ), rMod.aLanguage ); + if( rMod.aModuleType.getLength()>0 ) + pModElement->addAttribute( OUString( RTL_CONSTASCII_USTRINGPARAM(XMLNS_SCRIPT_PREFIX ":moduleType") ), + rMod.aModuleType ); xOut->ignorableWhitespace( OUString() ); xOut->startElement( aModuleName, xAttributes ); diff --git a/xmlscript/source/xmlmod_imexp/xmlmod_import.cxx b/xmlscript/source/xmlmod_imexp/xmlmod_import.cxx index b995817c1eb9..7f38f915aa62 100644 --- a/xmlscript/source/xmlmod_imexp/xmlmod_import.cxx +++ b/xmlscript/source/xmlmod_imexp/xmlmod_import.cxx @@ -188,11 +188,14 @@ Reference< xml::input::XElement > ModuleImport::startRootElement( else if (rLocalName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("module") )) { mrModuleDesc.aName = xAttributes->getValueByUidName( - XMLNS_LIBRARY_UID, + XMLNS_SCRIPT_UID, OUString( RTL_CONSTASCII_USTRINGPARAM("name") ) ); mrModuleDesc.aLanguage = xAttributes->getValueByUidName( - XMLNS_XLINK_UID, + XMLNS_SCRIPT_UID, OUString( RTL_CONSTASCII_USTRINGPARAM("language") ) ); + mrModuleDesc.aModuleType = xAttributes->getValueByUidName( + XMLNS_SCRIPT_UID, + OUString( RTL_CONSTASCII_USTRINGPARAM("moduleType") ) ); return new ModuleElement( rLocalName, xAttributes, 0, this ); } |