diff options
author | Mathias Bauer <mba@openoffice.org> | 2010-07-13 14:38:37 +0200 |
---|---|---|
committer | Mathias Bauer <mba@openoffice.org> | 2010-07-13 14:38:37 +0200 |
commit | 8eea0b1b4ba5f07a89fb2bacb39f1c8d9c3039e6 (patch) | |
tree | 874f33673af3b17a40de1980f31ead2c8272a155 /basic | |
parent | f24b1da07ebfbc95e76af93fc9c7133f7d52daa5 (diff) | |
parent | a2e7c2e0d002d75a6b77a629a4e904ab54bf8375 (diff) |
CWS changehid: resync to m84
Diffstat (limited to 'basic')
64 files changed, 3229 insertions, 1205 deletions
diff --git a/basic/inc/basic/sberrors.hxx b/basic/inc/basic/sberrors.hxx index c21b3b0237b8..c34176e0bde7 100644 --- a/basic/inc/basic/sberrors.hxx +++ b/basic/inc/basic/sberrors.hxx @@ -287,6 +287,8 @@ typedef ULONG SbError; #define ERRCODE_BASIC_LOOP_NOT_INIT ((LAST_SBX_ERROR_ID+109UL) | ERRCODE_AREA_SBX | \ ERRCODE_CLASS_COMPILER) // For loop not initialized +#define ERRCODE_BASIC_COMPAT ((LAST_SBX_ERROR_ID+103UL)| ERRCODE_AREA_SBX | ERRCODE_CLASS_RUNTIME) + // Map old codes to new codes #define SbERR_SYNTAX ERRCODE_BASIC_SYNTAX #define SbERR_NO_GOSUB ERRCODE_BASIC_NO_GOSUB @@ -410,6 +412,7 @@ typedef ULONG SbError; #define SbERR_PROG_TOO_LARGE ERRCODE_BASIC_PROG_TOO_LARGE #define SbERR_NO_STRINGS_ARRAYS ERRCODE_BASIC_NO_STRINGS_ARRAYS #define SbERR_BASIC_EXCEPTION ERRCODE_BASIC_EXCEPTION +#define SbERR_BASIC_COMPAT ERRCODE_BASIC_COMPAT #define SbERR_BASIC_ARRAY_FIX ERRCODE_BASIC_ARRAY_FIX #define SbERR_BASIC_STRING_OVERFLOW ERRCODE_BASIC_STRING_OVERFLOW #define SbERR_BASIC_EXPR_TOO_COMPLEX ERRCODE_BASIC_EXPR_TOO_COMPLEX diff --git a/basic/inc/basic/sbmod.hxx b/basic/inc/basic/sbmod.hxx index d73c9780b1bb..cf888adf9dcf 100644 --- a/basic/inc/basic/sbmod.hxx +++ b/basic/inc/basic/sbmod.hxx @@ -31,9 +31,7 @@ #include <basic/sbdef.hxx> #include <basic/sbxobj.hxx> #include <basic/sbxdef.hxx> -#ifndef _RTL_USTRING_HXX #include <rtl/ustring.hxx> -#endif class SbMethod; class SbProperty; @@ -42,6 +40,7 @@ class SbiBreakpoints; class SbiImage; class SbProcedureProperty; class SbIfaceMapperMethod; +class SbClassModuleObject; struct SbClassData; class SbModuleImpl; @@ -63,6 +62,10 @@ protected: SbiImage* pImage; // the Image SbiBreakpoints* pBreaks; // Breakpoints SbClassData* pClassData; + BOOL mbVBACompat; + INT32 mnType; + SbxObjectRef pDocObject; // an impl object ( used by Document Modules ) + bool bIsProxyModule; void StartDefinitions(); SbMethod* GetMethod( const String&, SbxDataType ); @@ -87,7 +90,7 @@ protected: public: SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_BASICMOD,2); TYPEINFO(); - SbModule( const String& ); + SbModule( const String&, BOOL bCompat = FALSE ); virtual void SetParent( SbxObject* ); virtual void Clear(); @@ -123,6 +126,12 @@ public: BOOL LoadBinaryData( SvStream& ); BOOL ExceedsLegacyModuleSize(); void fixUpMethodStart( bool bCvtToLegacy, SbiImage* pImg = NULL ) const; + 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 new file mode 100644 index 000000000000..3d638a475f9a --- /dev/null +++ b/basic/inc/basic/sbobjmod.hxx @@ -0,0 +1,113 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: sbobjmod.hxx,v $ + * + * $Revision: 1.4 $ + * + * last change: $Author: $ $Date: 2007/08/27 16:31:39 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _SB_OBJMOD_HXX +#define _SB_OBJMOD_HXX + +#include <basic/sbmod.hxx> +#include <basic/sbstar.hxx> +#include <com/sun/star/script/ModuleInfo.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/awt/XDialog.hpp> +#include <com/sun/star/frame/XModel.hpp> + +namespace css = ::com::sun::star; + +// Basic-Module for excel object. + +class SbObjModule : public SbModule +{ + SbObjModule( const SbObjModule& ); + SbObjModule(); +public: + TYPEINFO(); + SbObjModule( const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsVbaCompatible ); + virtual SbxVariable* Find( const XubString& rName, SbxClassType t ); + using SbxValue::GetObject; + SbxVariable* GetObject(); + void SetUnoObject( const com::sun::star::uno::Any& aObj )throw ( com::sun::star::uno::RuntimeException ) ; +}; + +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; + String sFormName; + bool mbInit; + SbUserFormModule( const SbUserFormModule& ); + SbUserFormModule(); + +//protected: + virtual void InitObject(); +public: + TYPEINFO(); + SbUserFormModule( const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsVBACompat ); + virtual SbxVariable* Find( const XubString& rName, SbxClassType t ); + void ResetApiObj(); + void Unload(); + void load(); + void triggerMethod( const String& ); + void triggerMethod( const String&, css::uno::Sequence< css::uno::Any >& ); + void triggerActivateEvent(); + 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 + +SV_DECL_IMPL_REF(SbObjModule); + +#endif +#endif + diff --git a/basic/inc/basic/sbstar.hxx b/basic/inc/basic/sbstar.hxx index bdc4aa011cc9..a234dc206ec7 100644 --- a/basic/inc/basic/sbstar.hxx +++ b/basic/inc/basic/sbstar.hxx @@ -37,6 +37,7 @@ #include <basic/sbdef.hxx> #include <basic/sberrors.hxx> +#include <com/sun/star/script/ModuleInfo.hpp> class SbModule; // completed module class SbiInstance; // runtime instance @@ -69,6 +70,7 @@ class StarBASIC : public SbxObject BOOL bNoRtl; // if TRUE: do not search RTL BOOL bBreak; // if TRUE: Break, otherwise Step BOOL bDocBasic; + BOOL bVBAEnabled; BasicLibInfo* pLibInfo; // Info block for basic manager SbLanguageMode eLanguageMode; // LanguageMode of the basic object BOOL bQuit; @@ -117,6 +119,7 @@ public: // Compiler-Interface SbModule* MakeModule( const String& rName, const String& rSrc ); SbModule* MakeModule32( const String& rName, const ::rtl::OUString& rSrc ); + SbModule* MakeModule32( const String& rName, const com::sun::star::script::ModuleInfo& mInfo, const ::rtl::OUString& rSrc ); BOOL Compile( SbModule* ); BOOL Disassemble( SbModule*, String& rText ); static void Stop(); @@ -189,6 +192,8 @@ public: ( const String& rName, USHORT& rStatus ); static SbMethod* GetActiveMethod( USHORT nLevel = 0 ); static SbModule* GetActiveModule(); + void SetVBAEnabled( BOOL bEnabled ); + BOOL isVBAEnabled(); // #60175 TRUE: SFX-Resource is not displayed on basic errors static void StaticSuppressSfxResource( BOOL bSuppress ); diff --git a/basic/inc/basic/sbuno.hxx b/basic/inc/basic/sbuno.hxx index 68e2c6ab8778..d816d424313b 100644 --- a/basic/inc/basic/sbuno.hxx +++ b/basic/inc/basic/sbuno.hxx @@ -41,5 +41,7 @@ void createAllObjectProperties( SbxObject* pObj ); ::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar ); +void unoToSbxValue( SbxVariable* pVar, const ::com::sun::star::uno::Any& aValue ); + #endif 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/inc/pch/precompiled_basic.hxx b/basic/inc/pch/precompiled_basic.hxx index cab46edc0185..e8f9e004ca6a 100644 --- a/basic/inc/pch/precompiled_basic.hxx +++ b/basic/inc/pch/precompiled_basic.hxx @@ -187,7 +187,7 @@ #include "svtools/svmedit.hxx" #include "svl/svstdarr.hxx" #include "svtools/svtdata.hxx" -#include "svl/svtools.hrc" +#include "svtools/svtools.hrc" #include "svtools/svtreebx.hxx" #include "unotools/syslocale.hxx" #include "svtools/taskbar.hxx" diff --git a/basic/prj/build.lst b/basic/prj/build.lst index 994901580c86..c00a3d8412d3 100644..100755 --- a/basic/prj/build.lst +++ b/basic/prj/build.lst @@ -1,11 +1,11 @@ -sb basic : l10n offuh 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 sb basic\source\basmgr nmake - all sb_mgr sb_inc NULL sb basic\source\classes nmake - all sb_class sb_inc NULL sb basic\source\comp nmake - all sb_comp sb_inc NULL -sb basic\source\runtime nmake - all sb_rt sb_inc NULL +sb basic\source\runtime nmake - all sb_rt sb_inc sb_class NULL sb basic\source\sample nmake - all sb_samp sb_inc NULL sb basic\source\sbx nmake - all sb_sbx sb_inc NULL sb basic\source\uno nmake - all sb_uno sb_inc NULL diff --git a/basic/source/basmgr/basmgr.cxx b/basic/source/basmgr/basmgr.cxx index 7646667bc277..b76a2b5e249e 100644 --- a/basic/source/basmgr/basmgr.cxx +++ b/basic/source/basmgr/basmgr.cxx @@ -41,6 +41,7 @@ #include <tools/debug.hxx> #include <tools/diagnose_ex.h> #include <basic/sbmod.hxx> +#include <basic/sbobjmod.hxx> #include <basic/sbuno.hxx> #include <basic/basmgr.hxx> @@ -65,6 +66,9 @@ #include <com/sun/star/script/XStarBasicDialogInfo.hpp> #include <com/sun/star/script/XStarBasicLibraryInfo.hpp> #include <com/sun/star/script/XLibraryContainerPassword.hpp> +#include <com/sun/star/script/ModuleInfo.hpp> +#include <com/sun/star/script/XVBAModuleInfo.hpp> +#include <com/sun/star/script/XVBACompat.hpp> #include <cppuhelper/implbase1.hxx> @@ -236,7 +240,15 @@ void BasMgrContainerListenerImpl::addLibraryModulesImpl( BasicManager* pMgr, Any aElement = xLibNameAccess->getByName( aModuleName ); ::rtl::OUString aMod; aElement >>= aMod; - pLib->MakeModule32( aModuleName, aMod ); + Reference< XVBAModuleInfo > xVBAModuleInfo( xLibNameAccess, UNO_QUERY ); + if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aModuleName ) ) + { + ModuleInfo mInfo = xVBAModuleInfo->getModuleInfo( aModuleName ); + OSL_TRACE("#addLibraryModulesImpl - aMod"); + pLib->MakeModule32( aModuleName, mInfo, aMod ); + } + else + pLib->MakeModule32( aModuleName, aMod ); } } @@ -270,11 +282,16 @@ void SAL_CALL BasMgrContainerListenerImpl::elementInserted( const ContainerEvent { Reference< XLibraryContainer > xScriptCont( Event.Source, UNO_QUERY ); insertLibraryImpl( xScriptCont, mpMgr, Event.Element, aName ); + StarBASIC* pLib = mpMgr->GetLib( aName ); + if ( pLib ) + { + Reference<XVBACompat> xVBACompat( xScriptCont, UNO_QUERY ); + if ( xVBACompat.is() ) + pLib->SetVBAEnabled( xVBACompat->getVBACompatModeOn() ); + } } else { - ::rtl::OUString aMod; - Event.Element >>= aMod; StarBASIC* pLib = mpMgr->GetLib( maLibName ); DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::elementInserted: Unknown lib!"); @@ -283,7 +300,16 @@ void SAL_CALL BasMgrContainerListenerImpl::elementInserted( const ContainerEvent SbModule* pMod = pLib->FindModule( aName ); if( !pMod ) { - pLib->MakeModule32( aName, aMod ); + ::rtl::OUString aMod; + Event.Element >>= aMod; + Reference< XVBAModuleInfo > xVBAModuleInfo( Event.Source, UNO_QUERY ); + if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aName ) ) + { + ModuleInfo mInfo = xVBAModuleInfo->getModuleInfo( aName ); + pLib->MakeModule32( aName, mInfo, aMod ); + } + else + pLib->MakeModule32( aName, aMod ); pLib->SetModified( FALSE ); } } @@ -312,10 +338,11 @@ void SAL_CALL BasMgrContainerListenerImpl::elementReplaced( const ContainerEvent SbModule* pMod = pLib->FindModule( aName ); ::rtl::OUString aMod; Event.Element >>= aMod; + if( pMod ) - pMod->SetSource32( aMod ); + pMod->SetSource32( aMod ); else - pLib->MakeModule32( aName, aMod ); + pLib->MakeModule32( aName, aMod ); pLib->SetModified( FALSE ); } @@ -1762,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/errobject.cxx b/basic/source/classes/errobject.cxx new file mode 100644 index 000000000000..0ec0454e2bb5 --- /dev/null +++ b/basic/source/classes/errobject.cxx @@ -0,0 +1,225 @@ +/************************************************************************* +* +* 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 +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +* +************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_basic.hxx" +#include "errobject.hxx" + +#include <cppuhelper/implbase2.hxx> +#include <com/sun/star/script/XDefaultProperty.hpp> +#include "sbintern.hxx" +#include "runtime.hxx" + +using namespace ::com::sun::star; +using namespace ::ooo; + +typedef ::cppu::WeakImplHelper2< vba::XErrObject, script::XDefaultProperty > ErrObjectImpl_BASE; + +class ErrObject : public ErrObjectImpl_BASE +{ + rtl::OUString m_sHelpFile; + rtl::OUString m_sSource; + rtl::OUString m_sDescription; + sal_Int32 m_nNumber; + sal_Int32 m_nHelpContext; + +public: + ErrObject(); + ~ErrObject(); + // Attributes + virtual ::sal_Int32 SAL_CALL getNumber() throw (uno::RuntimeException); + virtual void SAL_CALL setNumber( ::sal_Int32 _number ) throw (uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getHelpContext() throw (uno::RuntimeException); + virtual void SAL_CALL setHelpContext( ::sal_Int32 _helpcontext ) throw (uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getHelpFile() throw (uno::RuntimeException); + virtual void SAL_CALL setHelpFile( const ::rtl::OUString& _helpfile ) throw (uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getDescription() throw (uno::RuntimeException); + virtual void SAL_CALL setDescription( const ::rtl::OUString& _description ) throw (uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getSource() throw (uno::RuntimeException); + virtual void SAL_CALL setSource( const ::rtl::OUString& _source ) throw (uno::RuntimeException); + + // Methods + virtual void SAL_CALL Clear( ) throw (uno::RuntimeException); + virtual void SAL_CALL Raise( const uno::Any& Number, const uno::Any& Source, const uno::Any& Description, const uno::Any& HelpFile, const uno::Any& HelpContext ) throw (uno::RuntimeException); + // XDefaultProperty + virtual ::rtl::OUString SAL_CALL getDefaultPropertyName( ) throw (uno::RuntimeException); + + // Helper method + void setData( const uno::Any& Number, const uno::Any& Source, const uno::Any& Description, + const uno::Any& HelpFile, const uno::Any& HelpContext ) throw (uno::RuntimeException); +}; + + +ErrObject::~ErrObject() +{ +} + +ErrObject::ErrObject() : m_nNumber(0), m_nHelpContext(0) +{ +} + +sal_Int32 SAL_CALL +ErrObject::getNumber() throw (uno::RuntimeException) +{ + return m_nNumber; +} + +void SAL_CALL +ErrObject::setNumber( ::sal_Int32 _number ) throw (uno::RuntimeException) +{ + pINST->setErrorVB( _number, String() ); + ::rtl::OUString _description = pINST->GetErrorMsg(); + setData( uno::makeAny( _number ), uno::Any(), uno::makeAny( _description ), uno::Any(), uno::Any() ); +} + +::sal_Int32 SAL_CALL +ErrObject::getHelpContext() throw (uno::RuntimeException) +{ + return m_nHelpContext; +} +void SAL_CALL +ErrObject::setHelpContext( ::sal_Int32 _helpcontext ) throw (uno::RuntimeException) +{ + m_nHelpContext = _helpcontext; +} + +::rtl::OUString SAL_CALL +ErrObject::getHelpFile() throw (uno::RuntimeException) +{ + return m_sHelpFile; +} + +void SAL_CALL +ErrObject::setHelpFile( const ::rtl::OUString& _helpfile ) throw (uno::RuntimeException) +{ + m_sHelpFile = _helpfile; +} + +::rtl::OUString SAL_CALL +ErrObject::getDescription() throw (uno::RuntimeException) +{ + return m_sDescription; +} + +void SAL_CALL +ErrObject::setDescription( const ::rtl::OUString& _description ) throw (uno::RuntimeException) +{ + m_sDescription = _description; +} + +::rtl::OUString SAL_CALL +ErrObject::getSource() throw (uno::RuntimeException) +{ + return m_sSource; +} + +void SAL_CALL +ErrObject::setSource( const ::rtl::OUString& _source ) throw (uno::RuntimeException) +{ + m_sSource = _source; +} + +// Methods +void SAL_CALL +ErrObject::Clear( ) throw (uno::RuntimeException) +{ + m_sHelpFile = rtl::OUString(); + m_sSource = m_sHelpFile; + m_sDescription = m_sSource; + m_nNumber = 0; + m_nHelpContext = 0; +} + +void SAL_CALL +ErrObject::Raise( const uno::Any& Number, const uno::Any& Source, const uno::Any& Description, const uno::Any& HelpFile, const uno::Any& HelpContext ) throw (uno::RuntimeException) +{ + setData( Number, Source, Description, HelpFile, HelpContext ); + if ( m_nNumber ) + pINST->ErrorVB( m_nNumber, m_sDescription ); +} + +// XDefaultProperty +::rtl::OUString SAL_CALL +ErrObject::getDefaultPropertyName( ) throw (uno::RuntimeException) +{ + static rtl::OUString sDfltPropName( RTL_CONSTASCII_USTRINGPARAM("Number") ); + return sDfltPropName; +} + +void ErrObject::setData( const uno::Any& Number, const uno::Any& Source, const uno::Any& Description, const uno::Any& HelpFile, const uno::Any& HelpContext ) + throw (uno::RuntimeException) +{ + if ( !Number.hasValue() ) + throw uno::RuntimeException( rtl::OUString::createFromAscii("Missing Required Paramater"), uno::Reference< uno::XInterface >() ); + Number >>= m_nNumber; + Description >>= m_sDescription; + Source >>= m_sSource; + HelpFile >>= m_sHelpFile; + HelpContext >>= m_nHelpContext; +} + +// SbxErrObject +SbxErrObject::SbxErrObject( const String& rName, const Any& rUnoObj ) + : SbUnoObject( rName, rUnoObj ) + , m_pErrObject( NULL ) +{ + OSL_TRACE("SbxErrObject::SbxErrObject ctor"); + rUnoObj >>= m_xErr; + if ( m_xErr.is() ) + { + SetDfltProperty( uno::Reference< script::XDefaultProperty >( m_xErr, uno::UNO_QUERY_THROW )->getDefaultPropertyName() ) ; + m_pErrObject = static_cast< ErrObject* >( m_xErr.get() ); + } +} + +SbxErrObject::~SbxErrObject() +{ + OSL_TRACE("SbxErrObject::~SbxErrObject dtor"); +} + +uno::Reference< vba::XErrObject > +SbxErrObject::getUnoErrObject() +{ + SbxVariable* pVar = getErrObject(); + SbxErrObject* pGlobErr = static_cast< SbxErrObject* >( pVar ); + return pGlobErr->m_xErr; +} + +SbxVariableRef +SbxErrObject::getErrObject() +{ + static SbxVariableRef pGlobErr = new SbxErrObject( String( RTL_CONSTASCII_USTRINGPARAM("Err")), uno::makeAny( uno::Reference< vba::XErrObject >( new ErrObject() ) ) ); + return pGlobErr; +} + +void SbxErrObject::setNumberAndDescription( ::sal_Int32 _number, const ::rtl::OUString& _description ) + throw (uno::RuntimeException) +{ + if( m_pErrObject != NULL ) + m_pErrObject->setData( uno::makeAny( _number ), uno::Any(), uno::makeAny( _description ), uno::Any(), uno::Any() ); +} + diff --git a/basic/source/classes/eventatt.cxx b/basic/source/classes/eventatt.cxx index 5c57af5b6ce8..791e9fe5a8c1 100644 --- a/basic/source/classes/eventatt.cxx +++ b/basic/source/classes/eventatt.cxx @@ -55,13 +55,17 @@ #include <com/sun/star/awt/XDialogProvider.hpp> #include <com/sun/star/frame/XModel.hpp> - +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <basic/basicmanagerrepository.hxx> +#include <basic/basmgr.hxx> //================================================================================================== #include <xmlscript/xmldlg_imexp.hxx> #include <sbunoobj.hxx> #include <basic/sbstar.hxx> #include <basic/sbmeth.hxx> +#include <basic/sbuno.hxx> #include <runtime.hxx> #include <sbintern.hxx> @@ -85,11 +89,6 @@ using namespace ::osl; -//=================================================================== -void unoToSbxValue( SbxVariable* pVar, const Any& aValue ); -Any sbxToUnoValue( SbxVariable* pVar ); - - Reference< frame::XModel > getModelFromBasic( SbxObject* pBasic ) { OSL_PRECOND( pBasic != NULL, "getModelFromBasic: illegal call!" ); @@ -450,6 +449,43 @@ Any implFindDialogLibForDialog( const Any& rDlgAny, SbxObject* pBasic ) return aRetDlgLibAny; } +Any implFindDialogLibForDialogBasic( const Any& aAnyISP, SbxObject* pBasic, StarBASIC*& pFoundBasic ) +{ + Any aDlgLibAny; + // Find dialog library for dialog, direct access is not possible here + StarBASIC* pStartedBasic = (StarBASIC*)pBasic; + SbxObject* pParentBasic = pStartedBasic ? pStartedBasic->GetParent() : NULL; + SbxObject* pParentParentBasic = pParentBasic ? pParentBasic->GetParent() : NULL; + + SbxObject* pSearchBasic1 = NULL; + SbxObject* pSearchBasic2 = NULL; + if( pParentParentBasic ) + { + pSearchBasic1 = pParentBasic; + pSearchBasic2 = pParentParentBasic; + } + else + { + pSearchBasic1 = pStartedBasic; + pSearchBasic2 = pParentBasic; + } + if( pSearchBasic1 ) + { + aDlgLibAny = implFindDialogLibForDialog( aAnyISP, pSearchBasic1 ); + + if ( aDlgLibAny.hasValue() ) + pFoundBasic = (StarBASIC*)pSearchBasic1; + + else if( pSearchBasic2 ) + { + aDlgLibAny = implFindDialogLibForDialog( aAnyISP, pSearchBasic2 ); + if ( aDlgLibAny.hasValue() ) + pFoundBasic = (StarBASIC*)pSearchBasic2; + } + } + return aDlgLibAny; +} + static ::rtl::OUString aDecorationPropName = ::rtl::OUString::createFromAscii( "Decoration" ); static ::rtl::OUString aTitlePropName = @@ -529,39 +565,54 @@ void RTL_Impl_CreateUnoDialog( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite ) {} } - // Find dialog library for dialog, direct access is not possible here - StarBASIC* pStartedBasic = pINST->GetBasic(); - SbxObject* pParentBasic = pStartedBasic ? pStartedBasic->GetParent() : NULL; - SbxObject* pParentParentBasic = pParentBasic ? pParentBasic->GetParent() : NULL; - - SbxObject* pSearchBasic1 = NULL; - SbxObject* pSearchBasic2 = NULL; - if( pParentParentBasic ) + Any aDlgLibAny; + bool bDocDialog = false; + StarBASIC* pFoundBasic = NULL; + OSL_TRACE("About to try get a hold of ThisComponent"); + Reference< frame::XModel > xModel = getModelFromBasic( pINST->GetBasic() ) ; + aDlgLibAny = implFindDialogLibForDialogBasic( aAnyISP, pINST->GetBasic(), pFoundBasic ); + // If we found the dialog then it belongs to the Search basic + if ( !pFoundBasic ) { - pSearchBasic1 = pParentBasic; - pSearchBasic2 = pParentParentBasic; - } - else + Reference< frame::XDesktop > xDesktop( xMSF->createInstance + ( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ) ), + UNO_QUERY ); + Reference< container::XEnumeration > xModels; + if ( xDesktop.is() ) { - pSearchBasic1 = pStartedBasic; - pSearchBasic2 = pParentBasic; - } - - Any aDlgLibAny; - if( pSearchBasic1 ) + Reference< container::XEnumerationAccess > xComponents( xDesktop->getComponents(), UNO_QUERY ); + if ( xComponents.is() ) + xModels.set( xComponents->createEnumeration(), UNO_QUERY ); + if ( xModels.is() ) + { + while ( xModels->hasMoreElements() ) + { + Reference< frame::XModel > xNextModel( xModels->nextElement(), UNO_QUERY ); + if ( xNextModel.is() ) + { + BasicManager* pMgr = basic::BasicManagerRepository::getDocumentBasicManager( xNextModel ); + if ( pMgr ) + aDlgLibAny = implFindDialogLibForDialogBasic( aAnyISP, pMgr->GetLib(0), pFoundBasic ); + if ( aDlgLibAny.hasValue() ) { - aDlgLibAny = implFindDialogLibForDialog( aAnyISP, pSearchBasic1 ); - if( pSearchBasic2 && aDlgLibAny.getValueType().getTypeClass() == TypeClass_VOID ) - aDlgLibAny = implFindDialogLibForDialog( aAnyISP, pSearchBasic2 ); + bDocDialog = true; + xModel = xNextModel; + break; } - - - OSL_TRACE("About to try get a hold of ThisComponent"); - Reference< frame::XModel > xModel = getModelFromBasic( pStartedBasic ) ; - Reference< XScriptListener > xScriptListener = new BasicScriptListener_Impl( pStartedBasic, xModel ); + } + } + } + } + } + if ( pFoundBasic ) + bDocDialog = pFoundBasic->IsDocBasic(); + Reference< XScriptListener > xScriptListener = new BasicScriptListener_Impl( pINST->GetBasic(), xModel ); Sequence< Any > aArgs( 4 ); - aArgs[ 0 ] <<= xModel; + if( bDocDialog ) + aArgs[ 0 ] <<= xModel; + else + aArgs[ 0 ] <<= uno::Reference< uno::XInterface >(); aArgs[ 1 ] <<= xInput; aArgs[ 2 ] = aDlgLibAny; aArgs[ 3 ] <<= xScriptListener; diff --git a/basic/source/classes/makefile.mk b/basic/source/classes/makefile.mk index eb5486f02abf..e00ed4674cc1 100644 --- a/basic/source/classes/makefile.mk +++ b/basic/source/classes/makefile.mk @@ -37,18 +37,28 @@ ENABLE_EXCEPTIONS=TRUE .INCLUDE : settings.mk +ALLTAR .SEQUENTIAL : \ + $(MISC)$/$(TARGET).don \ + $(MISC)$/$(TARGET).slo + +$(MISC)$/$(TARGET).don : $(SOLARBINDIR)$/oovbaapi.rdb + +$(CPPUMAKER) -O$(OUT)$/inc -BUCR $(SOLARBINDIR)$/oovbaapi.rdb -X$(SOLARBINDIR)$/types.rdb && echo > $@ + echo $@ + +$(MISC)$/$(TARGET).slo : $(SLOTARGET) + echo $@ + # --- Allgemein ----------------------------------------------------------- -COMMON_SLOFILES= \ +SLOFILES= \ $(SLO)$/sb.obj \ $(SLO)$/sbxmod.obj \ $(SLO)$/image.obj \ $(SLO)$/sbintern.obj \ $(SLO)$/sbunoobj.obj \ $(SLO)$/propacc.obj \ - $(SLO)$/disas.obj - -SLOFILES= $(COMMON_SLOFILES) \ + $(SLO)$/disas.obj \ + $(SLO)$/errobject.obj \ $(SLO)$/eventatt.obj OBJFILES= \ diff --git a/basic/source/classes/sb.cxx b/basic/source/classes/sb.cxx index 3373442e5eb2..79c5f78601ea 100755 --- a/basic/source/classes/sb.cxx +++ b/basic/source/classes/sb.cxx @@ -49,12 +49,18 @@ #include "disas.hxx" #include "runtime.hxx" #include <basic/sbuno.hxx> +#include <basic/sbobjmod.hxx> #include "stdobj.hxx" #include "filefmt.hxx" #include "sb.hrc" #include <basrid.hxx> #include <vos/mutex.hxx> #include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include "errobject.hxx" + +#include <com/sun/star/script/ModuleType.hpp> +#include <com/sun/star/script/ModuleInfo.hpp> +using namespace ::com::sun::star::script; // #pragma SW_SEGMENT_CLASS( SBASIC, SBASIC_CODE ) @@ -238,6 +244,7 @@ const SFX_VB_ErrorItem __FAR_DATA SFX_VB_ErrorTab[] = { 1004, SbERR_METHOD_FAILED }, { 1005, SbERR_SETPROP_FAILED }, { 1006, SbERR_GETPROP_FAILED }, + { 1007, SbERR_BASIC_COMPAT }, { 0xFFFF, 0xFFFFFFFFL } // End mark }; @@ -314,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 ); @@ -345,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); @@ -372,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; @@ -508,6 +568,7 @@ SbClassModuleObject::SbClassModuleObject( SbModule* pClassModule ) } } } + SetModuleType( ModuleType::CLASS ); } SbClassModuleObject::~SbClassModuleObject() @@ -705,6 +766,7 @@ StarBASIC::StarBASIC( StarBASIC* p, BOOL bIsDocBasic ) SetParent( p ); pLibInfo = NULL; bNoRtl = bBreak = FALSE; + bVBAEnabled = FALSE; pModules = new SbxArray; if( !GetSbData()->nInst++ ) @@ -719,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 @@ -739,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, @@ -805,7 +871,34 @@ SbModule* StarBASIC::MakeModule( const String& rName, const String& rSrc ) SbModule* StarBASIC::MakeModule32( const String& rName, const ::rtl::OUString& rSrc ) { - SbModule* p = new SbModule( rName ); + ModuleInfo mInfo; + mInfo.ModuleType = ModuleType::NORMAL; + return MakeModule32( rName, mInfo, rSrc ); +} +SbModule* StarBASIC::MakeModule32( const String& rName, const ModuleInfo& mInfo, const rtl::OUString& rSrc ) +{ + + OSL_TRACE("create module %s type mInfo %d", rtl::OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr(), mInfo.ModuleType ); + SbModule* p = NULL; + switch ( mInfo.ModuleType ) + { + case ModuleType::DOCUMENT: + // In theory we should be able to create Object modules + // in ordinary basic ( in vba mode thought these are create + // by the application/basic and not by the user ) + p = new SbObjModule( rName, mInfo, isVBAEnabled() ); + break; + case ModuleType::CLASS: + p = new SbModule( rName, isVBAEnabled() ); + p->SetModuleType( ModuleType::CLASS ); + break; + case ModuleType::FORM: + p = new SbUserFormModule( rName, mInfo, isVBAEnabled() ); + break; + default: + p = new SbModule( rName, isVBAEnabled() ); + + } p->SetSource32( rSrc ); p->SetParent( this ); pModules->Insert( p, pModules->Count() ); @@ -981,6 +1074,12 @@ SbxVariable* StarBASIC::Find( const String& rName, SbxClassType t ) } pNamed = p; } + // Only variables qualified by the Module Name e.g. Sheet1.foo + // should work for Documant && Class type Modules + INT32 nType = p->GetModuleType(); + if ( nType == ModuleType::DOCUMENT || nType == ModuleType::FORM ) + continue; + // otherwise check if the element is available // unset GBLSEARCH-Flag (due to Rekursion) USHORT nGblFlag = p->GetFlags() & SBX_GBLSEARCH; @@ -1352,6 +1451,7 @@ void StarBASIC::MakeErrorText( SbError nId, const String& aMsg ) } else GetSbData()->aErrMsg = String::EmptyString(); + } BOOL StarBASIC::CError @@ -1408,7 +1508,22 @@ BOOL StarBASIC::RTError( SbError code, const String& rMsg, USHORT l, USHORT c1, // Umsetzung des Codes fuer String-Transport in SFX-Error if( rMsg.Len() ) - code = (ULONG)*new StringErrorInfo( code, String(rMsg) ); + { + // very confusing, even though MakeErrorText sets up the error text + // seems that this is not used ( if rMsg already has content ) + // In the case of VBA MakeErrorText also formats the error to be alittle more + // like vba ( adds an error number etc ) + if ( SbiRuntime::isVBAEnabled() && ( code == SbERR_BASIC_COMPAT ) ) + { + String aTmp = '\''; + aTmp += String::CreateFromInt32( SbxErrObject::getUnoErrObject()->getNumber() ); + aTmp += String( RTL_CONSTASCII_USTRINGPARAM("\'\n") ); + aTmp += GetSbData()->aErrMsg.Len() ? GetSbData()->aErrMsg : rMsg; + code = (ULONG)*new StringErrorInfo( code, aTmp ); + } + else + code = (ULONG)*new StringErrorInfo( code, String(rMsg) ); + } SetErrorData( code, l, c1, c2 ); if( GetSbData()->aErrHdl.IsSet() ) diff --git a/basic/source/classes/sb.src b/basic/source/classes/sb.src index 926da0359d7e..73cc1c3a0b2c 100644 --- a/basic/source/classes/sb.src +++ b/basic/source/classes/sb.src @@ -588,6 +588,10 @@ Resource RID_BASIC_START { Text [ en-US ] = "For loop not initialized." ; }; + String ERRCODE_BASIC_COMPAT & ERRCODE_RES_MASK + { + Text [ en-US ] = "$(ARG1)" ; + }; }; // Hinweis: IDS_SBERR_TERMINATED = IDS_SBERR_START+2000. String IDS_SBERR_TERMINATED diff --git a/basic/source/classes/sbunoobj.cxx b/basic/source/classes/sbunoobj.cxx index 1c95b4f30de6..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> @@ -567,7 +568,7 @@ SbxDataType unoToSbxType( const Reference< XIdlClass >& xIdlClass ) } return eRetType; } -void unoToSbxValue( SbxVariable* pVar, const Any& aValue ); + static void implSequenceToMultiDimArray( SbxDimArray*& pArray, Sequence< sal_Int32 >& indices, Sequence< sal_Int32 >& sizes, const Any& aValue, sal_Int32& dimension, sal_Bool bIsZeroIndex, Type* pType = NULL ) { Type aType = aValue.getValueType(); @@ -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 092ef458041e..1b49a376c9bd 100644 --- a/basic/source/classes/sbxmod.cxx +++ b/basic/source/classes/sbxmod.cxx @@ -52,7 +52,13 @@ #include <basic/basrdll.hxx> #include <vos/mutex.hxx> +#include <basic/sbobjmod.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/script/ModuleType.hpp> +#include <com/sun/star/script/XVBACompat.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +using namespace com::sun::star; // for the bsearch #ifdef WNT @@ -72,6 +78,13 @@ #include <vcl/svapp.hxx> using namespace ::com::sun::star; +#include <com/sun/star/script/XLibraryContainer.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/awt/XDialogProvider.hpp> +#include <com/sun/star/awt/XTopWindow.hpp> +#include <com/sun/star/awt/XControl.hpp> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/anytostring.hxx> TYPEINIT1(SbModule,SbxObject) TYPEINIT1(SbMethod,SbxMethod) @@ -79,6 +92,8 @@ TYPEINIT1(SbProperty,SbxProperty) TYPEINIT1(SbProcedureProperty,SbxProperty) TYPEINIT1(SbJScriptModule,SbModule) TYPEINIT1(SbJScriptMethod,SbMethod) +TYPEINIT1(SbObjModule,SbModule) +TYPEINIT1(SbUserFormModule,SbObjModule) SV_DECL_VARARR(SbiBreakpoints,USHORT,4,4) SV_IMPL_VARARR(SbiBreakpoints,USHORT) @@ -86,6 +101,26 @@ SV_IMPL_VARARR(SbiBreakpoints,USHORT) SV_IMPL_VARARR(HighlightPortions, HighlightPortion) +bool getDefaultVBAMode( StarBASIC* pb ) +{ + bool bResult = false; + if ( pb && pb->IsDocBasic() ) + { + uno::Any aDoc; + if ( pb->GetUNOConstant( "ThisComponent", aDoc ) ) + { + uno::Reference< beans::XPropertySet > xProp( aDoc, uno::UNO_QUERY ); + if ( xProp.is() ) + { + uno::Reference< script::XVBACompat > xVBAMode( xProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BasicLibraries") ) ), uno::UNO_QUERY ); + if ( xVBAMode.is() ) + bResult = ( xVBAMode->getVBACompatModeOn() == sal_True ); + } + } + } + return bResult; +} + class AsyncQuitHandler { AsyncQuitHandler() {} @@ -148,12 +183,18 @@ bool UnlockControllerHack( StarBASIC* pBasic ) // Ein BASIC-Modul hat EXTSEARCH gesetzt, damit die im Modul enthaltenen // Elemente von anderen Modulen aus gefunden werden koennen. -SbModule::SbModule( const String& rName ) +SbModule::SbModule( const String& rName, BOOL bVBACompat ) : SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("StarBASICModule") ) ), - pImage( NULL ), pBreaks( NULL ), pClassData( NULL ) + pImage( NULL ), pBreaks( NULL ), pClassData( NULL ), mbVBACompat( bVBACompat ), pDocObject( NULL ), bIsProxyModule( false ) { 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() @@ -328,7 +369,10 @@ void SbModule::Clear() 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 && !GetSbData()->bRunInit ) + return NULL; if( !pRes && pImage ) { SbiInstance* pInst = pINST; @@ -413,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 ); + } } } @@ -427,6 +483,8 @@ void SbModule::SetSource( const String& r ) void SbModule::SetSource32( const ::rtl::OUString& r ) { + // Default basic mode to library container mode, but.. allow Option VBASupport 0/1 override + SetVBACompat( getDefaultVBAMode( static_cast< StarBASIC*>( GetParent() ) ) ); aOUSource = r; StartDefinitions(); SbiTokenizer aTok( r ); @@ -457,9 +515,14 @@ void SbModule::SetSource32( const ::rtl::OUString& r ) if( eCurTok == OPTION ) { eCurTok = aTok.Next(); - if( eCurTok == COMPATIBLE - || ( ( eCurTok == VBASUPPORT ) && ( aTok.Next() == NUMBER ) && ( aTok.GetDbl()== 1 ) ) ) + if( eCurTok == COMPATIBLE ) aTok.SetCompatible( true ); + else if ( ( eCurTok == VBASUPPORT ) && ( aTok.Next() == NUMBER ) ) + { + BOOL bIsVBA = ( aTok.GetDbl()== 1 ); + SetVBACompat( bIsVBA ); + aTok.SetCompatible( bIsVBA ); + } } } eLastTok = eCurTok; @@ -600,7 +663,15 @@ void ClearUnoObjectsInRTL_Impl( StarBASIC* pBasic ) if( ((StarBASIC*)p) != pBasic ) ClearUnoObjectsInRTL_Impl_Rek( (StarBASIC*)p ); } +BOOL SbModule::IsVBACompat() const +{ + return mbVBACompat; +} +void SbModule::SetVBACompat( BOOL bCompat ) +{ + mbVBACompat = bCompat; +} // Ausfuehren eines BASIC-Unterprogramms USHORT SbModule::Run( SbMethod* pMeth ) { @@ -695,10 +766,9 @@ USHORT SbModule::Run( SbMethod* pMeth ) if( pRt->pNext ) pRt->pNext->block(); pINST->pRun = pRt; - if ( SbiRuntime ::isVBAEnabled() ) + if ( mbVBACompat ) { pINST->EnableCompatibility( TRUE ); - pRt->SetVBAEnabled( true ); } while( pRt->Step() ) {} if( pRt->pNext ) @@ -1483,6 +1553,418 @@ SbJScriptMethod::~SbJScriptMethod() ///////////////////////////////////////////////////////////////////////// +SbObjModule::SbObjModule( const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsVbaCompatible ) + : SbModule( rName, bIsVbaCompatible ) +{ + SetModuleType( mInfo.ModuleType ); + if ( mInfo.ModuleType == script::ModuleType::FORM ) + { + SetClassName( rtl::OUString::createFromAscii( "Form" ) ); + } + else if ( mInfo.ModuleObject.is() ) + SetUnoObject( uno::makeAny( mInfo.ModuleObject ) ); +} +void +SbObjModule::SetUnoObject( const uno::Any& aObj ) throw ( uno::RuntimeException ) +{ + SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,(SbxVariable*)pDocObject); + if ( pUnoObj && pUnoObj->getUnoAny() == aObj ) // object is equal, nothing to do + return; + pDocObject = new SbUnoObject( GetName(), uno::makeAny( aObj ) ); + + com::sun::star::uno::Reference< com::sun::star::lang::XServiceInfo > xServiceInfo( aObj, com::sun::star::uno::UNO_QUERY_THROW ); + if( xServiceInfo->supportsService( rtl::OUString::createFromAscii( "ooo.vba.excel.Worksheet" ) ) ) + { + SetClassName( rtl::OUString::createFromAscii( "Worksheet" ) ); + } + else if( xServiceInfo->supportsService( rtl::OUString::createFromAscii( "ooo.vba.excel.Workbook" ) ) ) + { + SetClassName( rtl::OUString::createFromAscii( "Workbook" ) ); + } +} + +SbxVariable* +SbObjModule::GetObject() +{ + return pDocObject; +} +SbxVariable* +SbObjModule::Find( const XubString& rName, SbxClassType t ) +{ + //OSL_TRACE("SbObjectModule find for %s", rtl::OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr() ); + SbxVariable* pVar = NULL; + if ( pDocObject) + pVar = pDocObject->Find( rName, t ); + if ( !pVar ) + pVar = SbModule::Find( rName, t ); + return pVar; +} + +typedef ::cppu::WeakImplHelper1< awt::XTopWindowListener > EventListener_BASE; + +class FormObjEventListenerImpl : public EventListener_BASE +{ + SbUserFormModule* mpUserForm; + uno::Reference< lang::XComponent > mxComponent; + bool mbDisposed; + sal_Bool mbOpened; + sal_Bool mbActivated; + sal_Bool mbShowing; + FormObjEventListenerImpl(); // not defined + FormObjEventListenerImpl(const FormObjEventListenerImpl&); // not defined +public: + FormObjEventListenerImpl( SbUserFormModule* pUserForm, const uno::Reference< lang::XComponent >& xComponent ) : mpUserForm( pUserForm ), mxComponent( xComponent) , mbDisposed( false ), mbOpened( sal_False ), mbActivated( sal_False ), mbShowing( sal_False ) + { + if ( mxComponent.is() ) + { + uno::Reference< awt::XTopWindow > xList( mxComponent, uno::UNO_QUERY_THROW );; + OSL_TRACE("*********** Registering the listener"); + xList->addTopWindowListener( this ); + } + } + + ~FormObjEventListenerImpl() + { + removeListener(); + } + sal_Bool isShowing() { return mbShowing; } + void removeListener() + { + try + { + if ( mxComponent.is() && !mbDisposed ) + { + uno::Reference< awt::XTopWindow > xList( mxComponent, uno::UNO_QUERY_THROW );; + OSL_TRACE("*********** Removing the listener"); + xList->removeTopWindowListener( this ); + mxComponent = NULL; + } + } + catch( uno::Exception& ) {} + } + virtual void SAL_CALL windowOpened( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) + { + if ( mpUserForm ) + { + mbOpened = sal_True; + mbShowing = sal_True; + if ( mbActivated ) + { + mbOpened = mbActivated = sal_False; + mpUserForm->triggerActivateEvent(); + } + } + } + + //liuchen 2009-7-21, support Excel VBA Form_QueryClose event + virtual void SAL_CALL windowClosing( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) + { +#if IN_THE_FUTURE + uno::Reference< awt::XDialog > xDialog( e.Source, uno::UNO_QUERY ); + if ( xDialog.is() ) + { + uno::Reference< awt::XControl > xControl( xDialog, uno::UNO_QUERY ); + if ( xControl->getPeer().is() ) + { + uno::Reference< document::XVbaMethodParameter > xVbaMethodParameter( xControl->getPeer(), uno::UNO_QUERY ); + if ( xVbaMethodParameter.is() ) + { + sal_Int8 nCancel = 0; + sal_Int8 nCloseMode = 0; + + Sequence< Any > aParams; + aParams.realloc(2); + aParams[0] <<= nCancel; + aParams[1] <<= nCloseMode; + + mpUserForm->triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_QueryClose") ), + aParams); + xVbaMethodParameter->setVbaMethodParameter( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Cancel")), aParams[0]); + return; + + } + } + } + + mpUserForm->triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_QueryClose") ) ); +#endif + } + //liuchen 2009-7-21 + + virtual void SAL_CALL windowClosed( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) { mbOpened = sal_False; mbShowing = sal_False; } + virtual void SAL_CALL windowMinimized( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) {} + virtual void SAL_CALL windowNormalized( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException){} + virtual void SAL_CALL windowActivated( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) + { + if ( mpUserForm ) + { + mbActivated = sal_True; + if ( mbOpened ) + { + mbOpened = mbActivated = sal_False; + mpUserForm->triggerActivateEvent(); + } + } + } + + virtual void SAL_CALL windowDeactivated( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException) + { + if ( mpUserForm ) + mpUserForm->triggerDeActivateEvent(); + } + + + virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw (uno::RuntimeException) + { + OSL_TRACE("** Userform/Dialog disposing"); + mbDisposed = true; + uno::Any aSource; + aSource <<= Source; + mxComponent = NULL; + if ( mpUserForm ) + mpUserForm->ResetApiObj(); + } +}; + +SbUserFormModule::SbUserFormModule( const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsCompat ) + : SbObjModule( rName, mInfo, bIsCompat ) + , m_mInfo( mInfo ) + , mbInit( false ) +{ + m_xModel.set( mInfo.ModuleObject, uno::UNO_QUERY_THROW ); +} + +void SbUserFormModule::ResetApiObj() +{ + if ( m_xDialog.is() ) // probably someone close the dialog window + { + triggerTerminateEvent(); + } + pDocObject = NULL; + m_xDialog = NULL; +} + +void SbUserFormModule::triggerMethod( const String& aMethodToRun ) +{ + Sequence< Any > aArguments; + triggerMethod( aMethodToRun, aArguments ); +} +void SbUserFormModule::triggerMethod( const String& aMethodToRun, Sequence< Any >& /*aArguments*/) +{ + OSL_TRACE("*** trigger %s ***", rtl::OUStringToOString( aMethodToRun, RTL_TEXTENCODING_UTF8 ).getStr() ); + // Search method + SbxVariable* pMeth = SbObjModule::Find( aMethodToRun, SbxCLASS_METHOD ); + if( pMeth ) + { +#if IN_THE_FUTURE + //liuchen 2009-7-21, support Excel VBA UserForm_QueryClose event with parameters + if ( aArguments.getLength() > 0 ) // Setup parameters + { + SbxArrayRef xArray = new SbxArray; + xArray->Put( pMeth, 0 ); // Method as parameter 0 + + for ( sal_Int32 i = 0; i < aArguments.getLength(); ++i ) + { + SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT ); + unoToSbxValue( static_cast< SbxVariable* >( xSbxVar ), aArguments[i] ); + xArray->Put( xSbxVar, static_cast< USHORT >( i ) + 1 ); + + // Enable passing by ref + if ( xSbxVar->GetType() != SbxVARIANT ) + xSbxVar->SetFlag( SBX_FIXED ); + } + pMeth->SetParameters( xArray ); + + SbxValues aVals; + pMeth->Get( aVals ); + + for ( sal_Int32 i = 0; i < aArguments.getLength(); ++i ) + { + aArguments[i] = sbxToUnoValue( xArray->Get( static_cast< USHORT >(i) + 1) ); + } + pMeth->SetParameters( NULL ); + } + else +//liuchen 2009-7-21 +#endif + { + SbxValues aVals; + pMeth->Get( aVals ); + } + } +} + +void SbUserFormModule::triggerActivateEvent( void ) +{ + OSL_TRACE("**** entering SbUserFormModule::triggerActivate"); + triggerMethod( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("UserForm_activate") ) ); + OSL_TRACE("**** leaving SbUserFormModule::triggerActivate"); +} + +void SbUserFormModule::triggerDeActivateEvent( void ) +{ + OSL_TRACE("**** SbUserFormModule::triggerDeActivate"); + triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_DeActivate") ) ); +} + +void SbUserFormModule::triggerInitializeEvent( void ) + +{ + if ( mbInit ) + return; + OSL_TRACE("**** SbUserFormModule::triggerInitializeEvent"); + static String aInitMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Initialize") ); + triggerMethod( aInitMethodName ); + mbInit = true; +} + +void SbUserFormModule::triggerTerminateEvent( void ) +{ + OSL_TRACE("**** SbUserFormModule::triggerTerminateEvent"); + static String aTermMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Terminate") ); + triggerMethod( aTermMethodName ); + 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() "); + // forces a load + if ( !pDocObject ) + InitObject(); +} + +//liuchen 2009-7-21 change to accmordate VBA's beheavior +void SbUserFormModule::Unload() +{ + OSL_TRACE("** Unload() "); + + sal_Int8 nCancel = 0; + sal_Int8 nCloseMode = 1; + + Sequence< Any > aParams; + aParams.realloc(2); + aParams[0] <<= nCancel; + aParams[1] <<= nCloseMode; + + triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_QueryClose") ), aParams); + + aParams[0] >>= nCancel; + if (nCancel == 1) + { + return; + } + + if ( m_xDialog.is() ) + { + triggerTerminateEvent(); + } + // Search method + SbxVariable* pMeth = SbObjModule::Find( String( RTL_CONSTASCII_USTRINGPARAM( "UnloadObject" ) ), SbxCLASS_METHOD ); + if( pMeth ) + { + OSL_TRACE("Attempting too run the UnloadObjectMethod"); + m_xDialog = NULL; //release ref to the uno object + SbxValues aVals; + FormObjEventListenerImpl* pFormListener = dynamic_cast< FormObjEventListenerImpl* >( m_DialogListener.get() ); + bool bWaitForDispose = true; // assume dialog is showing + if ( pFormListener ) + { + bWaitForDispose = pFormListener->isShowing(); + OSL_TRACE("Showing %d", bWaitForDispose ); + } + pMeth->Get( aVals); + if ( !bWaitForDispose ) + { + // we've either already got a dispose or we'er never going to get one + ResetApiObj(); + } // else wait for dispose + OSL_TRACE("UnloadObject completed ( we hope )"); + } +} +//liuchen + +void SbUserFormModule::InitObject() +{ + try + { + + String aHook( RTL_CONSTASCII_USTRINGPARAM( "VBAGlobals" ) ); + SbUnoObject* pGlobs = (SbUnoObject*)GetParent()->Find( aHook, SbxCLASS_DONTCARE ); + if ( m_xModel.is() && pGlobs ) + { + + uno::Reference< lang::XMultiServiceFactory > xVBAFactory( pGlobs->getUnoAny(), uno::UNO_QUERY_THROW ); + uno::Reference< lang::XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory(); + uno::Sequence< uno::Any > aArgs(1); + aArgs[ 0 ] <<= m_xModel; + rtl::OUString sDialogUrl( RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.script:" ) ); + rtl::OUString sProjectName( RTL_CONSTASCII_USTRINGPARAM("Standard") ); + if ( this->GetParent()->GetName().Len() ) + sProjectName = this->GetParent()->GetName(); + sDialogUrl = sDialogUrl.concat( sProjectName ).concat( rtl::OUString( '.') ).concat( GetName() ).concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("?location=document") ) ); + + uno::Reference< awt::XDialogProvider > xProvider( xFactory->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.DialogProvider")), aArgs ), uno::UNO_QUERY_THROW ); + m_xDialog = xProvider->createDialog( sDialogUrl ); + + // create vba api object + aArgs.realloc( 4 ); + aArgs[ 0 ] = uno::Any(); + aArgs[ 1 ] <<= m_xDialog; + aArgs[ 2 ] <<= m_xModel; + aArgs[ 3 ] <<= rtl::OUString( GetParent()->GetName() ); + pDocObject = new SbUnoObject( GetName(), uno::makeAny( xVBAFactory->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.msforms.UserForm")), aArgs ) ) ); + uno::Reference< lang::XComponent > xComponent( aArgs[ 1 ], uno::UNO_QUERY_THROW ); + // remove old listener if it exists + FormObjEventListenerImpl* pFormListener = dynamic_cast< FormObjEventListenerImpl* >( m_DialogListener.get() ); + if ( pFormListener ) + pFormListener->removeListener(); + m_DialogListener = new FormObjEventListenerImpl( this, xComponent ); + + triggerInitializeEvent(); + } + } + catch( uno::Exception& ) + { + } + +} + +SbxVariable* +SbUserFormModule::Find( const XubString& rName, SbxClassType t ) +{ + if ( !pDocObject && !GetSbData()->bRunInit && pINST ) + InitObject(); + return SbObjModule::Find( rName, t ); +} +///////////////////////////////////////////////////////////////////////// SbProperty::SbProperty( const String& r, SbxDataType t, SbModule* p ) : SbxProperty( r, t ), pMod( p ) diff --git a/basic/source/comp/codegen.cxx b/basic/source/comp/codegen.cxx index c7a63b6d7fbb..46f829b382e8 100644 --- a/basic/source/comp/codegen.cxx +++ b/basic/source/comp/codegen.cxx @@ -32,6 +32,7 @@ #include "sbcomp.hxx" #include "image.hxx" #include <limits> +#include <com/sun/star/script/ModuleType.hpp> // nInc ist die Inkrementgroesse der Puffer @@ -127,12 +128,12 @@ void SbiCodeGen::Save() // OPTION EXPLICIT-Flag uebernehmen if( pParser->bExplicit ) p->SetFlag( SBIMG_EXPLICIT ); - if( pParser->IsVBASupportOn() ) - p->SetFlag( SBIMG_VBASUPPORT ); int nIfaceCount = 0; - if( pParser->bClassModule ) + if( rMod.mnType == com::sun::star::script::ModuleType::CLASS ) { + OSL_TRACE("COdeGen::save() classmodule processing"); + rMod.bIsProxyModule = true; p->SetFlag( SBIMG_CLASSMODULE ); pCLASSFAC->AddClassModule( &rMod ); @@ -155,6 +156,10 @@ void SbiCodeGen::Save() else { pCLASSFAC->RemoveClassModule( &rMod ); + // Only a ClassModule can revert to Normal + if ( rMod.mnType == com::sun::star::script::ModuleType::CLASS ) + rMod.mnType = com::sun::star::script::ModuleType::NORMAL; + rMod.bIsProxyModule = false; } if( pParser->bText ) p->SetFlag( SBIMG_COMPARETEXT ); 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 400e77a94b16..3d7178ae7688 100644 --- a/basic/source/comp/parser.cxx +++ b/basic/source/comp/parser.cxx @@ -29,6 +29,7 @@ #include "precompiled_basic.hxx" #include <basic/sbx.hxx> #include "sbcomp.hxx" +#include <com/sun/star/script/ModuleType.hpp> struct SbiParseStack { // "Stack" fuer Statement-Blocks SbiParseStack* pNext; // Chain @@ -82,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 @@ -140,7 +142,8 @@ SbiParser::SbiParser( StarBASIC* pb, SbModule* pm ) bNewGblDefs = bSingleLineIf = bExplicit = FALSE; - bClassModule = FALSE; + bClassModule = ( pm->GetModuleType() == com::sun::star::script::ModuleType::CLASS ); + OSL_TRACE("Parser - %s, bClassModule %d", rtl::OUStringToOString( pm->GetName(), RTL_TEXTENCODING_UTF8 ).getStr(), bClassModule ); pPool = &aPublics; for( short i = 0; i < 26; i++ ) eDefTypes[ i ] = SbxVARIANT; // Kein expliziter Defaulttyp @@ -153,6 +156,10 @@ SbiParser::SbiParser( StarBASIC* pb, SbModule* pm ) rTypeArray = new SbxArray; // Array fuer Benutzerdefinierte Typen rEnumArray = new SbxArray; // Array for Enum types + bVBASupportOn = pm->IsVBACompat(); + if ( bVBASupportOn ) + EnableCompatibility(); + } @@ -231,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; @@ -361,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 ) @@ -471,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() ) @@ -698,11 +710,37 @@ void SbiParser::Implements() return; } - if( TestSymbol() ) + Peek(); + if( eCurTok != SYMBOL ) { - String aImplementedIface = GetSym(); - aIfaceVector.push_back( aImplementedIface ); + Error( SbERR_SYMBOL_EXPECTED ); + return; } + + String aImplementedIface = aSym; + Next(); + if( Peek() == DOT ) + { + 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() @@ -739,18 +777,23 @@ 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; case CLASSMODULE: bClassModule = TRUE; + aGen.GetModule().SetModuleType( com::sun::star::script::ModuleType::CLASS ); break; case VBASUPPORT: if( Next() == NUMBER ) @@ -760,6 +803,10 @@ void SbiParser::Option() bVBASupportOn = ( nVal == 1 ); if ( bVBASupportOn ) EnableCompatibility(); + // if the module setting is different + // reset it to what the Option tells us + if ( bVBASupportOn != aGen.GetModule().IsVBACompat() ) + aGen.GetModule().SetVBACompat( bVBASupportOn ); 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 d0a613eabebc..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 ); 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/errobject.hxx b/basic/source/inc/errobject.hxx new file mode 100644 index 000000000000..39e6e319caae --- /dev/null +++ b/basic/source/inc/errobject.hxx @@ -0,0 +1,52 @@ +/************************************************************************* +* +* 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 +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +* +************************************************************************/ + +#ifndef ERROBJECT_HXX +#define ERROBJECT_HXX +#include "sbunoobj.hxx" +#include <ooo/vba/XErrObject.hpp> + + +class SbxErrObject : public SbUnoObject +{ + class ErrObject* m_pErrObject; + com::sun::star::uno::Reference< ooo::vba::XErrObject > m_xErr; + + SbxErrObject( const String& aName_, const com::sun::star::uno::Any& aUnoObj_ ); + ~SbxErrObject(); + + class ErrObject* getImplErrObject( void ) + { return m_pErrObject; } + +public: + static SbxVariableRef getErrObject(); + static com::sun::star::uno::Reference< ooo::vba::XErrObject > getUnoErrObject(); + + void setNumberAndDescription( ::sal_Int32 _number, const ::rtl::OUString& _description ) + throw (com::sun::star::uno::RuntimeException); +}; +#endif 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/image.hxx b/basic/source/inc/image.hxx index 7347efe288f3..d674b91faf71 100644 --- a/basic/source/inc/image.hxx +++ b/basic/source/inc/image.hxx @@ -106,6 +106,5 @@ public: #define SBIMG_COMPARETEXT 0x0002 // OPTION COMPARE TEXT ist aktiv #define SBIMG_INITCODE 0x0004 // Init-Code vorhanden #define SBIMG_CLASSMODULE 0x0008 // OPTION ClassModule is active -#define SBIMG_VBASUPPORT 0x0020 // OPTION VBASupport is 1 #endif diff --git a/basic/source/inc/namecont.hxx b/basic/source/inc/namecont.hxx index 1f7e77170d44..ac1199f6c233 100644 --- a/basic/source/inc/namecont.hxx +++ b/basic/source/inc/namecont.hxx @@ -35,6 +35,7 @@ #include <com/sun/star/script/XStorageBasedLibraryContainer.hpp> #include <com/sun/star/script/XLibraryContainerPassword.hpp> #include <com/sun/star/script/XLibraryContainerExport.hpp> +#include <com/sun/star/script/XLibraryContainer3.hpp> #include <com/sun/star/container/XNameContainer.hpp> #include <com/sun/star/container/XContainer.hpp> #include <com/sun/star/ucb/XSimpleFileAccess.hpp> @@ -57,20 +58,23 @@ #include <com/sun/star/deployment/XPackage.hpp> #include <cppuhelper/implbase2.hxx> -#include <cppuhelper/compbase6.hxx> +#include <cppuhelper/compbase8.hxx> #include <cppuhelper/interfacecontainer.hxx> +#include <com/sun/star/script/XVBACompat.hpp> class BasicManager; namespace basic { -typedef ::cppu::WeakComponentImplHelper6< +typedef ::cppu::WeakComponentImplHelper8< ::com::sun::star::lang::XInitialization, ::com::sun::star::script::XStorageBasedLibraryContainer, ::com::sun::star::script::XLibraryContainerPassword, ::com::sun::star::script::XLibraryContainerExport, + ::com::sun::star::script::XLibraryContainer3, ::com::sun::star::container::XContainer, + ::com::sun::star::script::XVBACompat, ::com::sun::star::lang::XServiceInfo > LibraryContainerHelper; typedef ::cppu::WeakImplHelper2< ::com::sun::star::container::XNameContainer, @@ -216,6 +220,7 @@ public: class SfxLibraryContainer :public LibraryContainerHelper ,public ::utl::OEventListenerAdapter { + sal_Bool mbVBACompat; protected: ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxMSF; ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > mxSFI; @@ -280,14 +285,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; @@ -405,6 +413,12 @@ public: virtual ::rtl::OUString SAL_CALL getContainerLocationName() throw (::com::sun::star::uno::RuntimeException); virtual void SAL_CALL storeLibraries( ) throw (::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + //Methods XLibraryContainer3 + virtual ::rtl::OUString SAL_CALL getOriginalLibraryLinkURL( const ::rtl::OUString& Name ) + throw (::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::uno::RuntimeException); + // Methods XLibraryContainer2 (base of XPersistentLibraryContainer) virtual sal_Bool SAL_CALL isLibraryLink( const ::rtl::OUString& Name ) throw (::com::sun::star::container::NoSuchElementException, @@ -493,6 +507,9 @@ public: throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException) = 0; + // Methods XVBACompat + virtual ::sal_Bool SAL_CALL getVBACompatModeOn() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setVBACompatModeOn( ::sal_Bool _vbacompatmodeon ) throw (::com::sun::star::uno::RuntimeException); }; class LibraryContainerMethodGuard @@ -541,6 +558,8 @@ private: ::rtl::OUString maLibInfoFileURL; ::rtl::OUString maStorageURL; ::rtl::OUString maUnexpandedStorageURL; + ::rtl::OUString maOrignialStorageURL; + sal_Bool mbLink; sal_Bool mbReadOnly; sal_Bool mbReadOnlyLink; @@ -689,6 +708,7 @@ enum IteratorState { USER_EXTENSIONS, SHARED_EXTENSIONS, + BUNDLED_EXTENSIONS, END_REACHED }; @@ -708,6 +728,8 @@ protected: implGetNextUserScriptPackage( bool& rbPureDialogLib ); com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetNextSharedScriptPackage( bool& rbPureDialogLib ); + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > + implGetNextBundledScriptPackage( bool& rbPureDialogLib ); com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > m_xContext; @@ -721,8 +743,16 @@ protected: < com::sun::star::deployment::XPackage > > m_aSharedPackagesSeq; bool m_bSharedPackagesLoaded; + com::sun::star::uno::Sequence< com::sun::star::uno::Reference + < com::sun::star::deployment::XPackage > > m_aBundledPackagesSeq; + bool m_bBundledPackagesLoaded; + + int m_iUserPackage; int m_iSharedPackage; + int m_iBundledPackage; + + ScriptSubPackageIterator* m_pScriptSubPackageIterator; 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 4a3f38c51027..6ca69209a752 100644 --- a/basic/source/inc/runtime.hxx +++ b/basic/source/inc/runtime.hxx @@ -219,6 +219,8 @@ public: void Error( SbError ); // trappable Error void Error( SbError, const String& rMsg ); // trappable Error mit Message + void ErrorVB( sal_Int32 nVBNumber, const String& rMsg ); + void setErrorVB( sal_Int32 nVBNumber, const String& rMsg ); void FatalError( SbError ); // non-trappable Error void FatalError( SbError, const String& ); // non-trappable Error void Abort(); // Abbruch mit aktuellem Fehlercode @@ -405,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 ); @@ -414,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 ); @@ -432,8 +434,9 @@ 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 ) { bVBAEnabled = bEnabled; }; + void SetVBAEnabled( bool bEnabled ); USHORT GetImageFlag( USHORT n ) const; USHORT GetBase(); xub_StrLen nLine,nCol1,nCol2; // aktuelle Zeile, Spaltenbereich @@ -441,10 +444,11 @@ public: SbiRuntime( SbModule*, SbMethod*, UINT32 ); ~SbiRuntime(); - void Error( SbError ); // Fehler setzen, falls != 0 + void Error( SbError, bool bVBATranslationAlreadyDone = false ); // Fehler setzen, falls != 0 void Error( SbError, const String& ); // Fehler setzen, falls != 0 void FatalError( SbError ); // Fehlerbehandlung=Standard, Fehler setzen void FatalError( SbError, const String& ); // Fehlerbehandlung=Standard, Fehler setzen + static sal_Int32 translateErrorToVba( SbError nError, String& rMsg ); void DumpPCode(); BOOL Step(); // Einzelschritt (ein Opcode) void Stop() { bRun = FALSE; } 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 19b0698d22a9..d184a2d558e2 100644 --- a/basic/source/inc/scriptcont.hxx +++ b/basic/source/inc/scriptcont.hxx @@ -30,6 +30,8 @@ #include "namecont.hxx" #include <basic/basmgr.hxx> +#include <com/sun/star/script/XVBAModuleInfo.hpp> +#include <comphelper/uno3.hxx> class BasicManager; @@ -51,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 ); @@ -134,13 +139,19 @@ public: }; //============================================================================ +typedef std::hash_map< ::rtl::OUString, ::com::sun::star::script::ModuleInfo, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > ModuleInfoMap; + +typedef ::cppu::ImplHelper1 < ::com::sun::star::script::XVBAModuleInfo + > SfxScriptLibrary_BASE; class SfxScriptLibrary : public SfxLibrary + , public SfxScriptLibrary_BASE { friend class SfxScriptLibraryContainer; sal_Bool mbLoadedSource; sal_Bool mbLoadedBinary; + ModuleInfoMap mModuleInfos; // Provide modify state including resources virtual sal_Bool isModified( void ); @@ -167,6 +178,15 @@ public: const ::rtl::OUString& aLibInfoFileURL, const ::rtl::OUString& aStorageURL, sal_Bool ReadOnly ); + DECLARE_XINTERFACE() + DECLARE_XTYPEPROVIDER() + + // XVBAModuleInfo + virtual ::com::sun::star::script::ModuleInfo SAL_CALL getModuleInfo( const ::rtl::OUString& ModuleName ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasModuleInfo( const ::rtl::OUString& ModuleName ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL insertModuleInfo( const ::rtl::OUString& ModuleName, const ::com::sun::star::script::ModuleInfo& ModuleInfo ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeModuleInfo( const ::rtl::OUString& ModuleName ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + static bool containsValidModule( const ::com::sun::star::uno::Any& _rElement ); protected: 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/methods.cxx b/basic/source/runtime/methods.cxx index 9a21e488d4aa..36fbda5c9097 100644 --- a/basic/source/runtime/methods.cxx +++ b/basic/source/runtime/methods.cxx @@ -61,6 +61,7 @@ #else #include <osl/file.hxx> #endif +#include "errobject.hxx" #ifdef _USE_UNO #include <comphelper/processfactory.hxx> @@ -120,6 +121,8 @@ using namespace com::sun::star::io; #include <io.h> #endif +#include <basic/sbobjmod.hxx> + static void FilterWhiteSpace( String& rStr ) { rStr.EraseAllChars( ' ' ); @@ -205,15 +208,15 @@ String implGetCurDir( void ) } // TODO: -> SbiGlobals -static Reference< XSimpleFileAccess3 > getFileAccess( void ) +static com::sun::star::uno::Reference< XSimpleFileAccess3 > getFileAccess( void ) { - static Reference< XSimpleFileAccess3 > xSFI; + static com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI; if( !xSFI.is() ) { - Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory(); + com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory(); if( xSMgr.is() ) { - xSFI = Reference< XSimpleFileAccess3 >( xSMgr->createInstance + xSFI = com::sun::star::uno::Reference< XSimpleFileAccess3 >( xSMgr->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY ); } } @@ -256,6 +259,7 @@ RTLFUNC(Error) { String aErrorMsg; SbError nErr = 0L; + INT32 nCode = 0; if( rPar.Count() == 1 ) { nErr = StarBASIC::GetErrBasic(); @@ -263,14 +267,34 @@ RTLFUNC(Error) } else { - INT32 nCode = rPar.Get( 1 )->GetLong(); + nCode = rPar.Get( 1 )->GetLong(); if( nCode > 65535L ) StarBASIC::Error( SbERR_CONVERSION ); else nErr = StarBASIC::GetSfxFromVBError( (USHORT)nCode ); } - pBasic->MakeErrorText( nErr, aErrorMsg ); - rPar.Get( 0 )->PutString( pBasic->GetErrorText() ); + + bool bVBA = SbiRuntime::isVBAEnabled(); + String tmpErrMsg; + if( bVBA && aErrorMsg.Len() > 0 ) + { + tmpErrMsg = aErrorMsg; + } + else + { + pBasic->MakeErrorText( nErr, aErrorMsg ); + tmpErrMsg = pBasic->GetErrorText(); + } + // If this rtlfunc 'Error' passed a errcode the same as the active Err Objects's + // current err then return the description for the error message if it is set + // ( complicated isn't it ? ) + if ( bVBA && rPar.Count() > 1 ) + { + com::sun::star::uno::Reference< ooo::vba::XErrObject > xErrObj( SbxErrObject::getUnoErrObject() ); + if ( xErrObj.is() && xErrObj->getNumber() == nCode && xErrObj->getDescription().getLength() ) + tmpErrMsg = xErrObj->getDescription(); + } + rPar.Get( 0 )->PutString( tmpErrMsg ); } } @@ -531,7 +555,7 @@ RTLFUNC(ChDrive) // JSM // Implementation of StepRENAME with UCB void implStepRenameUCB( const String& aSource, const String& aDest ) { - Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); + com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); if( xSFI.is() ) { try @@ -579,7 +603,7 @@ RTLFUNC(FileCopy) // JSM // <-- UCB if( hasUno() ) { - Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); + com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); if( xSFI.is() ) { try @@ -630,7 +654,7 @@ RTLFUNC(Kill) // JSM // <-- UCB if( hasUno() ) { - Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); + com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); if( xSFI.is() ) { String aFullPath = getFullPath( aFileSpec ); @@ -677,7 +701,7 @@ RTLFUNC(MkDir) // JSM // <-- UCB if( hasUno() ) { - Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); + com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); if( xSFI.is() ) { try @@ -778,7 +802,7 @@ RTLFUNC(RmDir) // JSM // <-- UCB if( hasUno() ) { - Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); + com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); if( xSFI.is() ) { try @@ -865,7 +889,7 @@ RTLFUNC(FileLen) // <-- UCB if( hasUno() ) { - Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); + com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); if( xSFI.is() ) { try @@ -1613,7 +1637,7 @@ RTLFUNC(StrComp) ::utl::TransliterationWrapper* pTransliterationWrapper = GetSbData()->pTransliterationWrapper; if( !pTransliterationWrapper ) { - Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory(); + com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory(); pTransliterationWrapper = GetSbData()->pTransliterationWrapper = new ::utl::TransliterationWrapper( xSMgr, ::com::sun::star::i18n::TransliterationModules_IGNORE_CASE | @@ -2608,7 +2632,7 @@ RTLFUNC(Dir) // <-- UCB if( hasUno() ) { - Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); + com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); if( xSFI.is() ) { if ( nParCount >= 2 ) @@ -2971,7 +2995,7 @@ RTLFUNC(GetAttr) // <-- UCB if( hasUno() ) { - Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); + com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); if( xSFI.is() ) { try @@ -3041,7 +3065,7 @@ RTLFUNC(FileDateTime) Date aDate; if( hasUno() ) { - Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); + com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); if( xSFI.is() ) { try @@ -4006,7 +4030,7 @@ RTLFUNC(StrConv) String aNewStr( aOldStr ); if( nType != 0 ) { - Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory(); + com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory(); ::utl::TransliterationWrapper aTransliterationWrapper( xSMgr,nType ); com::sun::star::uno::Sequence<sal_Int32> aOffsets; aTransliterationWrapper.loadModuleIfNeeded( nLanguage ); @@ -4106,12 +4130,20 @@ RTLFUNC(Load) // Diesen Call einfach an das Object weiterreichen SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject(); - if( pObj && pObj->IsA( TYPE( SbxObject ) ) ) + if ( pObj ) { - SbxVariable* pVar = ((SbxObject*)pObj)-> - Find( String( RTL_CONSTASCII_USTRINGPARAM("Load") ), SbxCLASS_METHOD ); - if( pVar ) - pVar->GetInteger(); + if( pObj->IsA( TYPE( SbUserFormModule ) ) ) + { + SbUserFormModule* pFormModule = ( SbUserFormModule* )pObj; + pFormModule->load(); + } + else if( pObj->IsA( TYPE( SbxObject ) ) ) + { + SbxVariable* pVar = ((SbxObject*)pObj)-> + Find( String( RTL_CONSTASCII_USTRINGPARAM("Load") ), SbxCLASS_METHOD ); + if( pVar ) + pVar->GetInteger(); + } } } @@ -4129,12 +4161,20 @@ RTLFUNC(Unload) // Diesen Call einfach an das Object weitereichen SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject(); - if( pObj && pObj->IsA( TYPE( SbxObject ) ) ) + if ( pObj ) { - SbxVariable* pVar = ((SbxObject*)pObj)-> - Find( String( RTL_CONSTASCII_USTRINGPARAM("Unload") ), SbxCLASS_METHOD ); - if( pVar ) - pVar->GetInteger(); + if( pObj->IsA( TYPE( SbUserFormModule ) ) ) + { + SbUserFormModule* pFormModule = ( SbUserFormModule* )pObj; + pFormModule->Unload(); + } + else if( pObj->IsA( TYPE( SbxObject ) ) ) + { + SbxVariable* pVar = ((SbxObject*)pObj)-> + Find( String( RTL_CONSTASCII_USTRINGPARAM("Unload") ), SbxCLASS_METHOD ); + if( pVar ) + pVar->GetInteger(); + } } } @@ -4318,7 +4358,7 @@ RTLFUNC(SetAttr) // JSM // <-- UCB if( hasUno() ) { - Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); + com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); if( xSFI.is() ) { try @@ -4432,7 +4472,7 @@ RTLFUNC(FileExists) // <-- UCB if( hasUno() ) { - Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); + com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); if( xSFI.is() ) { try diff --git a/basic/source/runtime/methods1.cxx b/basic/source/runtime/methods1.cxx index e0501e5c0d94..8c7da2403705 100644 --- a/basic/source/runtime/methods1.cxx +++ b/basic/source/runtime/methods1.cxx @@ -61,6 +61,7 @@ #endif #include <vcl/jobset.hxx> +#include <basic/sbobjmod.hxx> #include "sbintern.hxx" #include "runtime.hxx" @@ -522,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; @@ -621,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() { @@ -2594,14 +2606,16 @@ RTLFUNC(Me) SbModule* pActiveModule = pINST->GetActiveModule(); SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pActiveModule); + SbxVariableRef refVar = rPar.Get(0); if( pClassModuleObject == NULL ) { - StarBASIC::Error( SbERR_INVALID_USAGE_OBJECT ); + SbObjModule* pMod = PTR_CAST(SbObjModule,pActiveModule); + if ( pMod ) + refVar->PutObject( pMod ); + else + StarBASIC::Error( SbERR_INVALID_USAGE_OBJECT ); } else - { - SbxVariableRef refVar = rPar.Get(0); refVar->PutObject( pClassModuleObject ); - } } diff --git a/basic/source/runtime/os2.asm b/basic/source/runtime/os2.asm deleted file mode 100644 index a56f0b74b89e..000000000000 --- a/basic/source/runtime/os2.asm +++ /dev/null @@ -1,103 +0,0 @@ -;************************************************************************* -; -; 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 -; -; This file is part of OpenOffice.org. -; -; OpenOffice.org is free software: you can redistribute it and/or modify -; it under the terms of the GNU Lesser General Public License version 3 -; only, as published by the Free Software Foundation. -; -; OpenOffice.org is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU Lesser General Public License version 3 for more details -; (a copy is included in the LICENSE file that accompanied this code). -; -; You should have received a copy of the GNU Lesser General Public License -; version 3 along with OpenOffice.org. If not, see -; <http://www.openoffice.org/license.html> -; for a copy of the LGPLv3 License. -; -;************************************************************************* - -; Anmerkungen -; Direktaufruf von C- und PASCAL-Routinen, OS/2 -; -; Inhalt: -; type = CallXXX (far *proc, char *stack, short nstack) -; -; Kopie des Basic-Stacks (nstack Bytes) auf den C-Stack -; und Aufruf der Prozedur. - - .386 - .MODEL FLAT - - .CODE - - PUBLIC CallINT - PUBLIC CallLNG - PUBLIC CallSNG - PUBLIC CallDBL - PUBLIC CallSTR - PUBLIC CallFIX - - PUBLIC _CallINT - PUBLIC _CallLNG - PUBLIC _CallSNG - PUBLIC _CallDBL - PUBLIC _CallSTR - PUBLIC _CallFIX - -_CallINT LABEL byte -_CallLNG LABEL byte -_CallSNG LABEL byte -_CallDBL LABEL byte -_CallSTR LABEL byte -_CallFIX LABEL byte - -CallINT LABEL byte -CallLNG LABEL byte -CallSNG LABEL byte -CallDBL LABEL byte -CallSTR LABEL byte -CallFIX PROC - -p EQU [EBP+8] -stk EQU [EBP+12] -n EQU [EBP+16] - - PUSH EBP - MOV EBP,ESP - PUSH ESI - PUSH EDI - MOV DX,DS - MOVZX ECX,word ptr [n] - SUB ESP,ECX - MOV EDI,ESP - MOV AX,SS - MOV ES,AX - MOV ESI,[stk] - SHR ECX,1 - CLD - JCXZ $1 - REP MOVSW ; Stack uebernehmen -$1: MOV DS,DX - CALL LARGE [p] ; 32-bit - MOV ECX,EBP - SUB ECX,8 ; wegen gepushter Register - MOV ESP,ECX - POP EDI - POP ESI - POP EBP -; Bei Borland C++ Calling Convention: -; RET 12 -; CSet System-Calling Convention - RET -CallFIX ENDP - - END diff --git a/basic/source/runtime/props.cxx b/basic/source/runtime/props.cxx index 9b4b35f551e2..cec74444e7a2 100644 --- a/basic/source/runtime/props.cxx +++ b/basic/source/runtime/props.cxx @@ -31,6 +31,7 @@ #include "runtime.hxx" #include "stdobj.hxx" #include "rtlproto.hxx" +#include "errobject.hxx" // Properties und Methoden legen beim Get (bWrite = FALSE) den Returnwert @@ -50,14 +51,21 @@ RTLFUNC(Err) (void)pBasic; (void)bWrite; - if( bWrite ) + if( SbiRuntime::isVBAEnabled() ) { - INT32 nVal = rPar.Get( 0 )->GetLong(); - if( nVal <= 65535L ) - StarBASIC::Error( StarBASIC::GetSfxFromVBError( (USHORT) nVal ) ); + rPar.Get( 0 )->PutObject( SbxErrObject::getErrObject() ); } else - rPar.Get( 0 )->PutLong( StarBASIC::GetVBErrorCode( StarBASIC::GetErrBasic() ) ); + { + if( bWrite ) + { + INT32 nVal = rPar.Get( 0 )->GetLong(); + if( nVal <= 65535L ) + StarBASIC::Error( StarBASIC::GetSfxFromVBError( (USHORT) nVal ) ); + } + else + rPar.Get( 0 )->PutLong( StarBASIC::GetVBErrorCode( StarBASIC::GetErrBasic() ) ); + } } RTLFUNC(False) 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 52aa76e2f2df..c3419adbfdb3 100644..100755 --- a/basic/source/runtime/runtime.cxx +++ b/basic/source/runtime/runtime.cxx @@ -43,13 +43,16 @@ #include <comphelper/processfactory.hxx> #include <com/sun/star/container/XEnumerationAccess.hpp> #include "sbunoobj.hxx" +#include "errobject.hxx" + +using namespace ::com::sun::star; bool SbiRuntime::isVBAEnabled() { bool result = false; SbiInstance* pInst = pINST; if ( pInst && pINST->pRun ) - result = pInst->pRun->GetImageFlag( SBIMG_VBASUPPORT ); + result = pInst->pRun->bVBAEnabled; return result; } @@ -60,6 +63,24 @@ void StarBASIC::StaticEnableReschedule( BOOL bReschedule ) { bStaticGlobalEnableReschedule = bReschedule; } +void StarBASIC::SetVBAEnabled( BOOL bEnabled ) +{ + if ( bDocBasic ) + { + bVBAEnabled = bEnabled; + } +} + +BOOL StarBASIC::isVBAEnabled() +{ + if ( bDocBasic ) + { + if( SbiRuntime::isVBAEnabled() ) + return TRUE; + return bVBAEnabled; + } + return FALSE; +} struct SbiArgvStack { // Argv stack: @@ -134,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 @@ -422,6 +444,35 @@ void SbiInstance::Error( SbError n, const String& rMsg ) } } +void SbiInstance::ErrorVB( sal_Int32 nVBNumber, const String& rMsg ) +{ + if( !bWatchMode ) + { + SbError n = StarBASIC::GetSfxFromVBError( static_cast< USHORT >( nVBNumber ) ); + if ( !n ) + n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors + + aErrorMsg = rMsg; + SbiRuntime::translateErrorToVba( n, aErrorMsg ); + + bool bVBATranslationAlreadyDone = true; + pRun->Error( SbERR_BASIC_COMPAT, bVBATranslationAlreadyDone ); + } +} + +void SbiInstance::setErrorVB( sal_Int32 nVBNumber, const String& rMsg ) +{ + SbError n = StarBASIC::GetSfxFromVBError( static_cast< USHORT >( nVBNumber ) ); + if( !n ) + n = nVBNumber; // force orig number, probably should have a specific table of vb ( localized ) errors + + aErrorMsg = rMsg; + SbiRuntime::translateErrorToVba( n, aErrorMsg ); + + nErr = n; +} + + void SbiInstance::FatalError( SbError n ) { pRun->FatalError( n ); @@ -520,6 +571,7 @@ SbiRuntime::SbiRuntime( SbModule* pm, SbMethod* pe, UINT32 nStart ) nForLvl = 0; nOps = 0; refExprStk = new SbxArray; + SetVBAEnabled( pMod->IsVBACompat() ); #if defined GCC SetParameters( pe ? pe->GetParameters() : (class SbxArray *)NULL ); #else @@ -527,7 +579,6 @@ SbiRuntime::SbiRuntime( SbModule* pm, SbMethod* pe, UINT32 nStart ) #endif pRefSaveList = NULL; pItemStoreList = NULL; - bVBAEnabled = isVBAEnabled(); } SbiRuntime::~SbiRuntime() @@ -546,6 +597,11 @@ SbiRuntime::~SbiRuntime() } } +void SbiRuntime::SetVBAEnabled(bool bEnabled ) +{ + bVBAEnabled = bEnabled; +} + // Aufbau der Parameterliste. Alle ByRef-Parameter werden direkt // uebernommen; von ByVal-Parametern werden Kopien angelegt. Falls // ein bestimmter Datentyp verlangt wird, wird konvertiert. @@ -791,10 +847,24 @@ BOOL SbiRuntime::Step() return bRun; } -void SbiRuntime::Error( SbError n ) +void SbiRuntime::Error( SbError n, bool bVBATranslationAlreadyDone ) { if( n ) + { nError = n; + if( isVBAEnabled() && !bVBATranslationAlreadyDone ) + { + String aMsg = pInst->GetErrorMsg(); + sal_Int32 nVBAErrorNumber = translateErrorToVba( nError, aMsg ); + SbxVariable* pSbxErrObjVar = SbxErrObject::getErrObject(); + SbxErrObject* pGlobErr = static_cast< SbxErrObject* >( pSbxErrObjVar ); + if( pGlobErr != NULL ) + pGlobErr->setNumberAndDescription( nVBAErrorNumber, aMsg ); + + pInst->aErrorMsg = aMsg; + nError = SbERR_BASIC_COMPAT; + } + } } void SbiRuntime::Error( SbError _errCode, const String& _details ) @@ -826,6 +896,32 @@ void SbiRuntime::FatalError( SbError _errCode, const String& _details ) Error( _errCode, _details ); } +sal_Int32 SbiRuntime::translateErrorToVba( SbError nError, String& rMsg ) +{ + // If a message is defined use that ( in preference to + // the defined one for the error ) NB #TODO + // if there is an error defined it more than likely + // is not the one you want ( some are the same though ) + // we really need a new vba compatible error list + if ( !rMsg.Len() ) + { + // TEST, has to be vb here always +#ifdef DBG_UTIL + SbError nTmp = StarBASIC::GetSfxFromVBError( (USHORT)nError ); + DBG_ASSERT( nTmp, "No VB error!" ); +#endif + + StarBASIC::MakeErrorText( nError, rMsg ); + rMsg = StarBASIC::GetErrorText(); + if ( !rMsg.Len() ) // no message for err no, need localized resource here + rMsg = String( RTL_CONSTASCII_USTRINGPARAM("Internal Object Error:") ); + } + // no num? most likely then it *is* really a vba err + USHORT nVBErrorCode = StarBASIC::GetVBErrorCode( nError ); + sal_Int32 nVBAErrorNumber = ( nVBErrorCode == 0 ) ? nError : nVBErrorCode; + return nVBAErrorNumber; +} + ////////////////////////////////////////////////////////////////////////// // // Parameter, Locals, Caller @@ -1136,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 c0b4ffa3cd59..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 }, @@ -230,7 +231,7 @@ static Methods aMethods[] = { { "EOF", SbxBOOL, 1 | _FUNCTION, RTLNAME(EOF),0 }, { "Channel", SbxINTEGER, 0,NULL,0 }, { "Erl", SbxLONG, _ROPROP, RTLNAME( Erl ),0 }, -{ "Err", SbxLONG, _RWPROP, RTLNAME( Err ),0 }, +{ "Err", SbxVARIANT, _RWPROP, RTLNAME( Err ),0 }, { "Error", SbxSTRING, 1 | _FUNCTION, RTLNAME( Error ),0 }, { "code", SbxLONG, 0,NULL,0 }, { "Exp", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Exp),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 33df854a4499..1d9333ff7555 100644 --- a/basic/source/runtime/step0.cxx +++ b/basic/source/runtime/step0.cxx @@ -30,6 +30,7 @@ #include <vcl/msgbox.hxx> #include <tools/fsys.hxx> +#include "errobject.hxx" #include "runtime.hxx" #include "sbintern.hxx" #include "iosys.hxx" @@ -42,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 ); @@ -514,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 @@ -907,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 @@ -1116,6 +1154,7 @@ void SbiRuntime::StepSTDERROR() pInst->nErr = 0L; pInst->nErl = 0; nError = 0L; + SbxErrObject::getUnoErrObject()->Clear(); } void SbiRuntime::StepNOERROR() @@ -1124,6 +1163,7 @@ void SbiRuntime::StepNOERROR() pInst->nErr = 0L; pInst->nErl = 0; nError = 0L; + SbxErrObject::getUnoErrObject()->Clear(); bError = FALSE; } @@ -1132,6 +1172,9 @@ void SbiRuntime::StepNOERROR() void SbiRuntime::StepLEAVE() { bRun = FALSE; + // If VBA and we are leaving an ErrorHandler then clear the error ( it's been processed ) + if ( bInError && pError ) + SbxErrObject::getUnoErrObject()->Clear(); } void SbiRuntime::StepCHANNEL() // TOS = Kanalnummer @@ -1265,6 +1308,9 @@ void SbiRuntime::StepERROR() SbxVariableRef refCode = PopVar(); USHORT n = refCode->GetUShort(); SbError error = StarBASIC::GetSfxFromVBError( n ); - Error( error ); + if ( bVBAEnabled ) + pInst->Error( error ); + else + Error( error ); } diff --git a/basic/source/runtime/step1.cxx b/basic/source/runtime/step1.cxx index 399257cf6ad3..e23ef864218e 100644 --- a/basic/source/runtime/step1.cxx +++ b/basic/source/runtime/step1.cxx @@ -30,11 +30,13 @@ #include <stdlib.h> #include <rtl/math.hxx> +#include <basic/sbuno.hxx> #include "runtime.hxx" #include "sbintern.hxx" #include "iosys.hxx" #include "image.hxx" #include "sbunoobj.hxx" +#include "errobject.hxx" bool checkUnoObjectType( SbUnoObject* refVal, const String& aClass ); @@ -230,8 +232,6 @@ void SbiRuntime::StepRETURN( UINT32 nOp1 ) // FOR-Variable testen (+Endlabel) -void unoToSbxValue( SbxVariable* pVar, const Any& aValue ); - void SbiRuntime::StepTESTFOR( UINT32 nOp1 ) { if( !pForStk ) @@ -360,6 +360,7 @@ void SbiRuntime::StepERRHDL( UINT32 nOp1 ) pInst->nErr = 0; pInst->nErl = 0; nError = 0; + SbxErrObject::getUnoErrObject()->Clear(); } // Resume nach Fehlern (+0=statement, 1=next or Label) @@ -380,6 +381,8 @@ void SbiRuntime::StepRESUME( UINT32 nOp1 ) } else pCode = pErrStmnt; + if ( pError ) // current in error handler ( and got a Resume Next statment ) + SbxErrObject::getUnoErrObject()->Clear(); if( nOp1 > 1 ) StepJUMP( nOp1 ); @@ -450,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 ) @@ -486,6 +489,8 @@ bool SbiRuntime::checkClass_Impl( const SbxVariableRef& refVal, } else { + bOk = true; + SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pObj); if( pClassModuleObject != NULL ) pClassModuleObject->triggerInitializeEvent(); @@ -529,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/win.asm b/basic/source/runtime/win.asm deleted file mode 100644 index dea597a4ce51..000000000000 --- a/basic/source/runtime/win.asm +++ /dev/null @@ -1,80 +0,0 @@ -;************************************************************************* -; -; 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 -; -; This file is part of OpenOffice.org. -; -; OpenOffice.org is free software: you can redistribute it and/or modify -; it under the terms of the GNU Lesser General Public License version 3 -; only, as published by the Free Software Foundation. -; -; OpenOffice.org is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU Lesser General Public License version 3 for more details -; (a copy is included in the LICENSE file that accompanied this code). -; -; You should have received a copy of the GNU Lesser General Public License -; version 3 along with OpenOffice.org. If not, see -; <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 *proc, char *stack, short nstack) -; -; Kopie des Basic-Stacks (nstack Bytes) auf den C-Stack -; und Aufruf der Prozedur. - - .MODEL LARGE,C - - .CODE - - PUBLIC CallINT - PUBLIC CallLNG - PUBLIC CallSNG - PUBLIC CallDBL - PUBLIC CallSTR - PUBLIC CallFIX - -CallINT LABEL byte -CallLNG LABEL byte -CallSNG LABEL byte -CallDBL LABEL byte -CallSTR LABEL byte -CallFIX PROC p:PTR,stk:PTR,n:WORD - - PUSH SI - PUSH DI - MOV DX,DS - SUB SP,[n] - MOV DI,SP - MOV AX,SS - MOV ES,AX - LDS SI,[stk] - MOV CX,[n] - SHR CX,1 - CLD - JCXZ $1 - REP MOVSW ; Stack uebernehmen -$1: MOV DS,DX - CALL [p] ; Aufruf der Prozedur - CLI - MOV SP,BP - SUB SP,4 ; wegen gepushter Register - STI - POP DI - POP SI - RET - -CallFIX ENDP - - END 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/format.src b/basic/source/sbx/format.src index 8ebe6e93c4bb..7e576134fad5 100644 --- a/basic/source/sbx/format.src +++ b/basic/source/sbx/format.src @@ -25,7 +25,7 @@ * ************************************************************************/ -#include "svl/svtools.hrc" +#include "svtools/svtools.hrc" String STR_BASICKEY_FORMAT_ON { diff --git a/basic/source/sbx/sbxscan.cxx b/basic/source/sbx/sbxscan.cxx index 6d5d24fcb951..3d45818e6401 100644 --- a/basic/source/sbx/sbxscan.cxx +++ b/basic/source/sbx/sbxscan.cxx @@ -47,7 +47,7 @@ #include "sbxres.hxx" #include <basic/sbxbase.hxx> #include <basic/sbxform.hxx> -#include <svl/svtools.hrc> +#include <svtools/svtools.hrc> #include "basrid.hxx" #include "runtime.hxx" 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 14c84420dad6..e1ad8b6b4308 100644 --- a/basic/source/uno/namecont.cxx +++ b/basic/source/uno/namecont.cxx @@ -65,7 +65,7 @@ #include <com/sun/star/uno/DeploymentException.hpp> #include <com/sun/star/lang/DisposedException.hpp> #include <com/sun/star/script/LibraryNotLoadedException.hpp> -#include "com/sun/star/deployment/thePackageManagerFactory.hpp" +#include "com/sun/star/deployment/ExtensionManager.hpp" #include <comphelper/storagehelper.hxx> #ifndef _RTL_USTRING_HXX_ #include <comphelper/anytostring.hxx> @@ -73,7 +73,6 @@ #include <cppuhelper/exc_hlp.hxx> #include <basic/sbmod.hxx> - namespace basic { @@ -327,6 +326,7 @@ DBG_NAME( SfxLibraryContainer ) // Ctor SfxLibraryContainer::SfxLibraryContainer( void ) : LibraryContainerHelper( maMutex ) + , mbVBACompat( sal_False ) , maModifiable( *this, maMutex ) , maNameContainer( getCppuType( (Reference< XNameAccess >*) NULL ) ) , mbOldInfoFormat( sal_False ) @@ -1080,6 +1080,7 @@ sal_Bool SfxLibraryContainer::init_Impl( OUString aUserSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE" ); OUString aSharedSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE" ); + OUString aBundledSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$BUNDLED_EXTENSIONS" ); OUString aInstSearchStr = OUString::createFromAscii( "$(INST)" ); Sequence< OUString > aNames = pPrevCont->getElementNames(); @@ -1111,6 +1112,7 @@ sal_Bool SfxLibraryContainer::init_Impl( bool bCreateLink = true; if( aStorageURL.indexOf( aUserSearchStr ) != -1 || aStorageURL.indexOf( aSharedSearchStr ) != -1 || + aStorageURL.indexOf( aBundledSearchStr ) != -1 || aStorageURL.indexOf( aInstSearchStr ) != -1 ) { bCreateLink = false; @@ -1369,8 +1371,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 +1408,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 +1461,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 +1480,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& ) @@ -2167,6 +2171,7 @@ Reference< XNameAccess > SAL_CALL SfxLibraryContainer::createLibraryLink SfxLibrary* pNewLib = implCreateLibraryLink( Name, aLibInfoFileURL, aLibDirURL, ReadOnly ); pNewLib->maLibElementFileExtension = maLibElementFileExtension; pNewLib->maUnexpandedStorageURL = aUnexpandedStorageURL; + pNewLib->maOrignialStorageURL = StorageURL; OUString aInitFileName; uno::Reference< embed::XStorage > xDummyStor; @@ -2182,11 +2187,12 @@ Reference< XNameAccess > SAL_CALL SfxLibraryContainer::createLibraryLink OUString aUserSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE" ); OUString aSharedSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE" ); + OUString aBundledSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$BUNDLED_EXTENSIONS" ); if( StorageURL.indexOf( aUserSearchStr ) != -1 ) { pNewLib->mbExtension = sal_True; } - else if( StorageURL.indexOf( aSharedSearchStr ) != -1 ) + else if( StorageURL.indexOf( aSharedSearchStr ) != -1 || StorageURL.indexOf( aBundledSearchStr ) != -1 ) { pNewLib->mbExtension = sal_True; pNewLib->mbReadOnly = sal_True; @@ -2380,7 +2386,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() ) @@ -2785,6 +2793,43 @@ OUString SfxLibraryContainer::expand_url( const OUString& url ) } } + +//XLibraryContainer3 +OUString SAL_CALL SfxLibraryContainer::getOriginalLibraryLinkURL( const OUString& Name ) + throw (IllegalArgumentException, NoSuchElementException, RuntimeException) +{ + LibraryContainerMethodGuard aGuard( *this ); + SfxLibrary* pImplLib = getImplLib( Name ); + sal_Bool bLink = pImplLib->mbLink; + if( !bLink ) + throw IllegalArgumentException(); + OUString aRetStr = pImplLib->maOrignialStorageURL; + return aRetStr; +} + + +::sal_Bool SAL_CALL SfxLibraryContainer::getVBACompatModeOn() throw (RuntimeException) +{ + return mbVBACompat; +} + +void SAL_CALL SfxLibraryContainer::setVBACompatModeOn( ::sal_Bool _vbacompatmodeon ) throw (RuntimeException) +{ + BasicManager* pBasMgr = getBasicManager(); + if( pBasMgr ) + { + // get the standard library + String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) ); + if ( pBasMgr->GetName().Len() ) + aLibName = pBasMgr->GetName(); + + StarBASIC* pBasic = pBasMgr->GetLib( aLibName ); + if( pBasic ) + pBasic->SetVBAEnabled( _vbacompatmodeon ); + } + mbVBACompat = _vbacompatmodeon; +} + // Methods XServiceInfo ::sal_Bool SAL_CALL SfxLibraryContainer::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException) @@ -3075,8 +3120,10 @@ ScriptExtensionIterator::ScriptExtensionIterator( void ) : m_eState( USER_EXTENSIONS ) , m_bUserPackagesLoaded( false ) , m_bSharedPackagesLoaded( false ) + , m_bBundledPackagesLoaded( false ) , m_iUserPackage( 0 ) , m_iSharedPackage( 0 ) + , m_iBundledPackage( 0 ) , m_pScriptSubPackageIterator( NULL ) { Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory(); @@ -3125,6 +3172,16 @@ rtl::OUString ScriptExtensionIterator::nextBasicOrDialogLibrary( bool& rbPureDia aRetLib = xScriptPackage->getURL(); break; } + case BUNDLED_EXTENSIONS: + { + Reference< deployment::XPackage > xScriptPackage = + implGetNextBundledScriptPackage( rbPureDialogLib ); + if( !xScriptPackage.is() ) + break; + + aRetLib = xScriptPackage->getURL(); + break; + } case END_REACHED: VOS_ENSURE( false, "ScriptExtensionIterator::nextBasicOrDialogLibrary(): Invalid case END_REACHED" ); break; @@ -3295,10 +3352,11 @@ Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextUserScript { try { - Reference< XPackageManager > xUserManager = - thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("user") ); - m_aUserPackagesSeq = xUserManager->getDeployedPackages - ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); + Reference< XExtensionManager > xManager = + ExtensionManager::get( m_xContext ); + m_aUserPackagesSeq = xManager->getDeployedExtensions + (rtl::OUString::createFromAscii("user"), + Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); } catch( com::sun::star::uno::DeploymentException& ) { @@ -3348,10 +3406,11 @@ Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextSharedScri { try { - Reference< XPackageManager > xSharedManager = - thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("shared") ); - m_aSharedPackagesSeq = xSharedManager->getDeployedPackages - ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); + Reference< XExtensionManager > xSharedManager = + ExtensionManager::get( m_xContext ); + m_aSharedPackagesSeq = xSharedManager->getDeployedExtensions + (rtl::OUString::createFromAscii("shared"), + Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); } catch( com::sun::star::uno::DeploymentException& ) { @@ -3364,7 +3423,7 @@ Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextSharedScri if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() ) { - m_eState = END_REACHED; + m_eState = BUNDLED_EXTENSIONS; } else { @@ -3391,4 +3450,57 @@ Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextSharedScri return xScriptPackage; } +Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextBundledScriptPackage + ( bool& rbPureDialogLib ) +{ + Reference< deployment::XPackage > xScriptPackage; + + if( !m_bBundledPackagesLoaded ) + { + try + { + Reference< XExtensionManager > xManager = + ExtensionManager::get( m_xContext ); + m_aBundledPackagesSeq = xManager->getDeployedExtensions + (rtl::OUString::createFromAscii("bundled"), + Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); + } + catch( com::sun::star::uno::DeploymentException& ) + { + // Special Office installations may not contain deployment code + return xScriptPackage; + } + + m_bBundledPackagesLoaded = true; + } + + if( m_iBundledPackage == m_aBundledPackagesSeq.getLength() ) + { + m_eState = END_REACHED; + } + else + { + if( m_pScriptSubPackageIterator == NULL ) + { + const Reference< deployment::XPackage >* pBundledPackages = m_aBundledPackagesSeq.getConstArray(); + Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage ]; + VOS_ENSURE( xPackage.is(), "ScriptExtensionIterator::implGetNextBundledScriptPackage(): Invalid package" ); + m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage ); + } + + if( m_pScriptSubPackageIterator != NULL ) + { + xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib ); + if( !xScriptPackage.is() ) + { + delete m_pScriptSubPackageIterator; + m_pScriptSubPackageIterator = NULL; + m_iBundledPackage++; + } + } + } + + return xScriptPackage; +} + } // namespace basic diff --git a/basic/source/uno/scriptcont.cxx b/basic/source/uno/scriptcont.cxx index 096d497a4c50..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() ) @@ -942,7 +1058,7 @@ sal_Bool SfxScriptLibraryContainer::implLoadPasswordLibrary try { xElementRootStorage = ::comphelper::OStorageHelper::GetStorageFromURL( aElementPath, - embed::ElementModes::READWRITE ); + embed::ElementModes::READ ); } catch( uno::Exception& ) { // TODO: error handling @@ -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() ) @@ -1166,6 +1286,45 @@ bool SAL_CALL SfxScriptLibrary::isLibraryElementValid( ::com::sun::star::uno::An return SfxScriptLibrary::containsValidModule( aElement ); } +IMPLEMENT_FORWARD_XINTERFACE2( SfxScriptLibrary, SfxLibrary, SfxScriptLibrary_BASE ); +IMPLEMENT_FORWARD_XTYPEPROVIDER2( SfxScriptLibrary, SfxLibrary, SfxScriptLibrary_BASE ); + +script::ModuleInfo SAL_CALL +SfxScriptLibrary::getModuleInfo( const ::rtl::OUString& ModuleName ) throw (NoSuchElementException, WrappedTargetException, RuntimeException) +{ + if ( !hasModuleInfo( ModuleName ) ) + throw NoSuchElementException(); + return mModuleInfos[ ModuleName ]; +} + +sal_Bool SAL_CALL +SfxScriptLibrary::hasModuleInfo( const ::rtl::OUString& ModuleName ) throw (RuntimeException) +{ + sal_Bool bRes = sal_False; + ModuleInfoMap::iterator it = mModuleInfos.find( ModuleName ); + + if ( it != mModuleInfos.end() ) + bRes = sal_True; + + return bRes; +} + +void SAL_CALL SfxScriptLibrary::insertModuleInfo( const ::rtl::OUString& ModuleName, const script::ModuleInfo& ModuleInfo ) throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException) +{ + if ( hasModuleInfo( ModuleName ) ) + throw ElementExistException(); + mModuleInfos[ ModuleName ] = ModuleInfo; +} + +void SAL_CALL SfxScriptLibrary::removeModuleInfo( const ::rtl::OUString& ModuleName ) throw (NoSuchElementException, WrappedTargetException, RuntimeException) +{ + // #FIXME add NoSuchElementException to the spec + if ( !hasModuleInfo( ModuleName ) ) + throw NoSuchElementException(); + mModuleInfos.erase( mModuleInfos.find( ModuleName ) ); +} + + //============================================================================ } // namespace basic 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) \ |