diff options
author | Mathias Bauer <mba@openoffice.org> | 2009-12-12 19:59:48 +0100 |
---|---|---|
committer | Mathias Bauer <mba@openoffice.org> | 2009-12-12 19:59:48 +0100 |
commit | ac2b789d27c6b11c8e89dd6c4cc13a1a42dcda55 (patch) | |
tree | 555bb2c73dd6951f0c98b910b56e5e5e7fa6976b /vbahelper | |
parent | f5d7ad8d499636045087296f1338e0ab7f6ce11e (diff) |
for split build filter must depend on vbahelper, not the other way around
Diffstat (limited to 'vbahelper')
-rw-r--r-- | vbahelper/inc/vbahelper/msvbahelper.hxx | 58 | ||||
-rw-r--r-- | vbahelper/prj/build.lst | 2 | ||||
-rw-r--r-- | vbahelper/source/vbahelper/makefile.mk | 1 | ||||
-rw-r--r-- | vbahelper/source/vbahelper/msvbahelper.cxx | 384 | ||||
-rw-r--r-- | vbahelper/source/vbahelper/vbaapplicationbase.cxx | 2 | ||||
-rw-r--r-- | vbahelper/source/vbahelper/vbacommandbarcontrol.cxx | 2 | ||||
-rw-r--r-- | vbahelper/util/makefile.mk | 3 |
7 files changed, 447 insertions, 5 deletions
diff --git a/vbahelper/inc/vbahelper/msvbahelper.hxx b/vbahelper/inc/vbahelper/msvbahelper.hxx new file mode 100644 index 000000000000..ebefdbb3e4b5 --- /dev/null +++ b/vbahelper/inc/vbahelper/msvbahelper.hxx @@ -0,0 +1,58 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: + * $Revision: + * + * 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 _MSVBAHELPER_HXX +#define _MSVBAHELPER_HXX + +#include <sfx2/objsh.hxx> +#include <vbahelper/vbadllapi.h> + +namespace ooo { namespace vba +{ + class VBAHELPER_DLLPUBLIC VBAMacroResolvedInfo + { + SfxObjectShell* mpDocContext; + bool mbFound; + String msResolvedMacro; + public: + VBAMacroResolvedInfo() : mpDocContext(NULL), mbFound( false ){} + void SetResolved( bool bRes ) { mbFound = bRes; } + bool IsResolved() { return mbFound; } + void SetMacroDocContext(SfxObjectShell* pShell ) { mpDocContext = pShell; } + SfxObjectShell* MacroDocContext() { return mpDocContext; } + String ResolvedMacro() { return msResolvedMacro; } + void SetResolvedMacro(const String& sMacro ) { msResolvedMacro = sMacro; } + }; + + VBAHELPER_DLLPUBLIC String makeMacroURL( const String& sMacroName ); + VBAHELPER_DLLPUBLIC VBAMacroResolvedInfo resolveVBAMacro( SfxObjectShell* pShell, const rtl::OUString& sMod, bool bSearchGlobalTemplates = false ); + VBAHELPER_DLLPUBLIC sal_Bool executeMacro( SfxObjectShell* pShell, const String& sMacroName, com::sun::star::uno::Sequence< com::sun::star::uno::Any >& aArgs, com::sun::star::uno::Any& aRet, const com::sun::star::uno::Any& aCaller ); +} } + +#endif diff --git a/vbahelper/prj/build.lst b/vbahelper/prj/build.lst index 07cc9ac50173..0db5274b7ad3 100644 --- a/vbahelper/prj/build.lst +++ b/vbahelper/prj/build.lst @@ -1,4 +1,4 @@ -vba vbahelper : filter oovbaapi basic sfx2 svx cppuhelper vcl comphelper svtools tools sal NULL +vba vbahelper : oovbaapi basic sfx2 svx cppuhelper vcl comphelper svtools tools sal NULL vba vbahelper usr1 - all vba_mkout NULL #vba vbahelper\inc nmake - all vba_inc NULL vba vbahelper\source\vbahelper nmake - all vba_vbahelper NULL diff --git a/vbahelper/source/vbahelper/makefile.mk b/vbahelper/source/vbahelper/makefile.mk index a8a4167948f4..487ce5d56d79 100644 --- a/vbahelper/source/vbahelper/makefile.mk +++ b/vbahelper/source/vbahelper/makefile.mk @@ -40,6 +40,7 @@ VISIBILITY_HIDDEN=TRUE .INCLUDE : settings.mk SLOFILES=\ + $(SLO)$/msvbahelper.obj \ $(SLO)$/vbahelper.obj \ $(SLO)$/vbapropvalue.obj \ $(SLO)$/vbacommandbars.obj \ diff --git a/vbahelper/source/vbahelper/msvbahelper.cxx b/vbahelper/source/vbahelper/msvbahelper.cxx new file mode 100644 index 000000000000..005de1b2471b --- /dev/null +++ b/vbahelper/source/vbahelper/msvbahelper.cxx @@ -0,0 +1,384 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: + * $Revision: + * + * 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. + * + ************************************************************************/ + +#define VBAHELPER_DLLIMPLEMENTATION +#include <vbahelper/msvbahelper.hxx> +#include <basic/sbx.hxx> +#include <basic/sbstar.hxx> +#include <basic/basmgr.hxx> +#include <basic/sbmod.hxx> +#include <basic/sbmeth.hxx> +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include <com/sun/star/document/XDocumentProperties.hpp> +#include <com/sun/star/document/XDocumentInfoSupplier.hpp> +#include <tools/urlobj.hxx> +#include <osl/file.hxx> + +using namespace ::com::sun::star; + +const static rtl::OUString sUrlPart0 = rtl::OUString::createFromAscii( "vnd.sun.star.script:"); +const static rtl::OUString sUrlPart1 = rtl::OUString::createFromAscii( "?language=Basic&location=document"); + +namespace ooo { namespace vba { + +String makeMacroURL( const String& sMacroName ) +{ + return sUrlPart0.concat( sMacroName ).concat( sUrlPart1 ) ; +} + +SfxObjectShell* findShellForUrl( const rtl::OUString& sMacroURLOrPath ) +{ + SfxObjectShell* pFoundShell=NULL; + SfxObjectShell* pShell = SfxObjectShell::GetFirst(); + INetURLObject aObj; + aObj.SetURL( sMacroURLOrPath ); + bool bIsURL = aObj.GetProtocol() != INET_PROT_NOT_VALID; + rtl::OUString aURL; + if ( bIsURL ) + aURL = sMacroURLOrPath; + else + { + osl::FileBase::getFileURLFromSystemPath( sMacroURLOrPath, aURL ); + aObj.SetURL( aURL ); + } + OSL_TRACE("Trying to find shell for url %s", rtl::OUStringToOString( aURL, RTL_TEXTENCODING_UTF8 ).getStr() ); + while ( pShell ) + { + + uno::Reference< frame::XModel > xModel = pShell->GetModel(); + // are we searching for a template? if so we have to cater for the + // fact that in openoffice a document opened from a template is always + // a new document :/ + if ( xModel.is() ) + { + OSL_TRACE("shell 0x%x has model with url %s and we look for %s", pShell + , rtl::OUStringToOString( xModel->getURL(), RTL_TEXTENCODING_UTF8 ).getStr() + , rtl::OUStringToOString( aURL, RTL_TEXTENCODING_UTF8 ).getStr() + ); + if ( sMacroURLOrPath.endsWithIgnoreAsciiCaseAsciiL( ".dot", 4 ) ) + { + uno::Reference< document::XDocumentInfoSupplier > xDocInfoSupp( xModel, uno::UNO_QUERY ); + if( xDocInfoSupp.is() ) + { + uno::Reference< document::XDocumentPropertiesSupplier > xDocPropSupp( xDocInfoSupp->getDocumentInfo(), uno::UNO_QUERY_THROW ); + uno::Reference< document::XDocumentProperties > xDocProps( xDocPropSupp->getDocumentProperties(), uno::UNO_QUERY_THROW ); + rtl::OUString sCurrName = xDocProps->getTemplateName(); + if( sMacroURLOrPath.lastIndexOf( sCurrName ) >= 0 ) + { + pFoundShell = pShell; + break; + } + } + } + else + { + if ( aURL.equals( xModel->getURL() ) ) + { + pFoundShell = pShell; + break; + } + } + } + pShell = SfxObjectShell::GetNext( *pShell ); + } + return pFoundShell; +} + +// sMod can be empty ( but we really need the library to search in ) +// if sMod is empty and a macro is found then sMod is updated +bool hasMacro( SfxObjectShell* pShell, const String& sLibrary, String& sMod, const String& sMacro ) +{ + bool bFound = false; + if ( sLibrary.Len() && sMacro.Len() ) + { + OSL_TRACE("** Searching for %s.%s in library %s" + ,rtl::OUStringToOString( sMod, RTL_TEXTENCODING_UTF8 ).getStr() + ,rtl::OUStringToOString( sMacro, RTL_TEXTENCODING_UTF8 ).getStr() + ,rtl::OUStringToOString( sLibrary, RTL_TEXTENCODING_UTF8 ).getStr() ); + BasicManager* pBasicMgr = pShell-> GetBasicManager(); + if ( pBasicMgr ) + { + StarBASIC* pBasic = pBasicMgr->GetLib( sLibrary ); + if ( !pBasic ) + { + USHORT nId = pBasicMgr->GetLibId( sLibrary ); + pBasicMgr->LoadLib( nId ); + pBasic = pBasicMgr->GetLib( sLibrary ); + } + if ( pBasic ) + { + if ( sMod.Len() ) // we wish to find the macro is a specific module + { + SbModule* pModule = pBasic->FindModule( sMod ); + if ( pModule ) + { + SbxArray* pMethods = pModule->GetMethods(); + if ( pMethods ) + { + SbMethod* pMethod = static_cast< SbMethod* >( pMethods->Find( sMacro, SbxCLASS_METHOD ) ); + if ( pMethod ) + bFound = true; + } + } + } + else if( SbMethod* pMethod = dynamic_cast< SbMethod* >( pBasic->Find( sMacro, SbxCLASS_METHOD ) ) ) + { + if( SbModule* pModule = pMethod->GetModule() ) + { + sMod = pModule->GetName(); + bFound = true; + } + } + } + } + } + return bFound; +} +void parseMacro( const rtl::OUString& sMacro, String& sContainer, String& sModule, String& sProcedure ) +{ + sal_Int32 nMacroDot = sMacro.lastIndexOf( '.' ); + + if ( nMacroDot != -1 ) + { + sProcedure = sMacro.copy( nMacroDot + 1 ); + + sal_Int32 nContainerDot = sMacro.lastIndexOf( '.', nMacroDot - 1 ); + if ( nContainerDot != -1 ) + { + sModule = sMacro.copy( nContainerDot + 1, nMacroDot - nContainerDot - 1 ); + sContainer = sMacro.copy( 0, nContainerDot ); + } + else + sModule = sMacro.copy( 0, nMacroDot ); + } + else + sProcedure = sMacro; +} + +VBAMacroResolvedInfo resolveVBAMacro( SfxObjectShell* pShell, const rtl::OUString& MacroName, bool bSearchGlobalTemplates ) +{ + VBAMacroResolvedInfo aRes; + if ( !pShell ) + return aRes; + aRes.SetMacroDocContext( pShell ); + // parse the macro name + sal_Int32 nDocSepIndex = MacroName.indexOfAsciiL( "!", 1 ); + String sMacroUrl = MacroName; + + String sContainer; + String sModule; + String sProcedure; + + if( nDocSepIndex > 0 ) + { + // macro specified by document name + // find document shell for document name and call ourselves + // recursively + + // assume for now that the document name is *this* document + String sDocUrlOrPath = MacroName.copy( 0, nDocSepIndex ); + sMacroUrl = MacroName.copy( nDocSepIndex + 1 ); + OSL_TRACE("doc search, current shell is 0x%x", pShell ); + SfxObjectShell* pFoundShell = findShellForUrl( sDocUrlOrPath ); + OSL_TRACE("doc search, after find, found shell is 0x%x", pFoundShell ); + aRes = resolveVBAMacro( pFoundShell, sMacroUrl ); + } + else + { + // macro is contained in 'this' document ( or code imported from a template + // where that template is a global template or perhaps the template this + // document is created from ) + + // macro format = Container.Module.Procedure + parseMacro( MacroName, sContainer, sModule, sProcedure ); + uno::Reference< lang::XMultiServiceFactory> xSF( pShell->GetModel(), uno::UNO_QUERY); + uno::Reference< container::XNameContainer > xPrjNameCache; + if ( xSF.is() ) + xPrjNameCache.set( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAProjectNameProvider" ) ) ), uno::UNO_QUERY ); + + std::vector< rtl::OUString > sSearchList; + + if ( sContainer.Len() > 0 ) + { + // get the Project associated with the Container + if ( xPrjNameCache.is() ) + { + if ( xPrjNameCache->hasByName( sContainer ) ) + { + rtl::OUString sProject; + xPrjNameCache->getByName( sContainer ) >>= sProject; + sContainer = sProject; + } + } + sSearchList.push_back( sContainer ); // First Lib to search + } + else + { + // Ok, if we have no Container specified then we need to search them in order, this document, template this document created from, global templates, + // get the name of Project/Library for 'this' document + rtl::OUString sThisProject; + BasicManager* pBasicMgr = pShell-> GetBasicManager(); + if ( pBasicMgr ) + { + if ( pBasicMgr->GetName().Len() ) + sThisProject = pBasicMgr->GetName(); + else // cater for the case where VBA is not enabled + sThisProject = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Standard") ); + } + sSearchList.push_back( sThisProject ); // First Lib to search + if ( xPrjNameCache.is() ) + { + // is this document created from a template? + uno::Reference< document::XDocumentInfoSupplier > xDocInfoSupp( pShell->GetModel(), uno::UNO_QUERY_THROW ); + uno::Reference< document::XDocumentPropertiesSupplier > xDocPropSupp( xDocInfoSupp->getDocumentInfo(), uno::UNO_QUERY_THROW ); + uno::Reference< document::XDocumentProperties > xDocProps( xDocPropSupp->getDocumentProperties(), uno::UNO_QUERY_THROW ); + + rtl::OUString sCreatedFrom = xDocProps->getTemplateURL(); + if ( sCreatedFrom.getLength() ) + { + INetURLObject aObj; + aObj.SetURL( sCreatedFrom ); + bool bIsURL = aObj.GetProtocol() != INET_PROT_NOT_VALID; + rtl::OUString aURL; + if ( bIsURL ) + aURL = sCreatedFrom; + else + { + osl::FileBase::getFileURLFromSystemPath( sCreatedFrom, aURL ); + aObj.SetURL( aURL ); + } + sCreatedFrom = aObj.GetLastName(); + } + + sal_Int32 nIndex = sCreatedFrom.lastIndexOf( '.' ); + if ( nIndex != -1 ) + sCreatedFrom = sCreatedFrom.copy( 0, nIndex ); + + rtl::OUString sPrj; + if ( sCreatedFrom.getLength() && xPrjNameCache->hasByName( sCreatedFrom ) ) + { + xPrjNameCache->getByName( sCreatedFrom ) >>= sPrj; + // Make sure we don't double up with this project + if ( !sPrj.equals( sThisProject ) ) + sSearchList.push_back( sPrj ); + } + + // get list of global template Names + uno::Sequence< rtl::OUString > sTemplateNames = xPrjNameCache->getElementNames(); + sal_Int32 nLen = sTemplateNames.getLength(); + for ( sal_Int32 index = 0; ( bSearchGlobalTemplates && index < nLen ); ++index ) + { + + if ( !sCreatedFrom.equals( sTemplateNames[ index ] ) ) + { + if ( xPrjNameCache->hasByName( sTemplateNames[ index ] ) ) + { + xPrjNameCache->getByName( sTemplateNames[ index ] ) >>= sPrj; + // Make sure we don't double up with this project + if ( !sPrj.equals( sThisProject ) ) + sSearchList.push_back( sPrj ); + } + } + + } + } + } + std::vector< rtl::OUString >::iterator it_end = sSearchList.end(); + for ( std::vector< rtl::OUString >::iterator it = sSearchList.begin(); it != it_end; ++it ) + { + bool bRes = hasMacro( pShell, *it, sModule, sProcedure ); + if ( bRes ) + { + aRes.SetResolved( true ); + aRes.SetMacroDocContext( pShell ); + sContainer = *it; + break; + } + } + } + aRes.SetResolvedMacro( sProcedure.Insert( '.', 0 ).Insert( sModule, 0).Insert( '.', 0 ).Insert( sContainer, 0 ) ); + + return aRes; +} + +// Treat the args as possible inouts ( convertion at bottom of method ) +sal_Bool executeMacro( SfxObjectShell* pShell, const String& sMacroName, uno::Sequence< uno::Any >& aArgs, uno::Any& /*aRet*/, const uno::Any& aCaller ) +{ + sal_Bool bRes = sal_False; + if ( !pShell ) + return bRes; + rtl::OUString sUrl = makeMacroURL( sMacroName ); + + uno::Sequence< sal_Int16 > aOutArgsIndex; + uno::Sequence< uno::Any > aOutArgs; + + try + { + uno::Reference< script::provider::XScriptProvider > xScriptProvider; + uno::Reference< script::provider::XScriptProviderSupplier > xSPS( pShell->GetModel(), uno::UNO_QUERY_THROW ); + + xScriptProvider.set( xSPS->getScriptProvider(), uno::UNO_QUERY_THROW ); + + uno::Reference< script::provider::XScript > xScript( xScriptProvider->getScript( sUrl ), uno::UNO_QUERY_THROW ); + + if ( aCaller.hasValue() ) + { + uno::Reference< beans::XPropertySet > xProps( xScript, uno::UNO_QUERY ); + if ( xProps.is() ) + { + uno::Sequence< uno::Any > aCallerHack(1); + aCallerHack[ 0 ] = aCaller; + xProps->setPropertyValue( rtl::OUString::createFromAscii( "Caller" ), uno::makeAny( aCallerHack ) ); + } + } + + + xScript->invoke( aArgs, aOutArgsIndex, aOutArgs ); + + sal_Int32 nLen = aOutArgs.getLength(); + // convert any out params to seem like they were inouts + if ( nLen ) + { + for ( sal_Int32 index=0; index < nLen; ++index ) + { + sal_Int32 nOutIndex = aOutArgsIndex[ index ]; + aArgs[ nOutIndex ] = aOutArgs[ index ]; + } + } + + bRes = sal_True; + } + catch ( uno::Exception& e ) + { + bRes = sal_False; + } + return bRes; +} +} } // vba // ooo diff --git a/vbahelper/source/vbahelper/vbaapplicationbase.cxx b/vbahelper/source/vbahelper/vbaapplicationbase.cxx index 1f898565c303..d9cf4f029472 100644 --- a/vbahelper/source/vbahelper/vbaapplicationbase.cxx +++ b/vbahelper/source/vbahelper/vbaapplicationbase.cxx @@ -42,7 +42,7 @@ #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> #include "vbacommandbars.hxx" -#include <filter/msfilter/msvbahelper.hxx> +#include <vbahelper/msvbahelper.hxx> // start basic includes #include <basic/sbx.hxx> diff --git a/vbahelper/source/vbahelper/vbacommandbarcontrol.cxx b/vbahelper/source/vbahelper/vbacommandbarcontrol.cxx index 999eb8b99ece..84239e74d4c1 100644 --- a/vbahelper/source/vbahelper/vbacommandbarcontrol.cxx +++ b/vbahelper/source/vbahelper/vbacommandbarcontrol.cxx @@ -35,7 +35,7 @@ #include "vbacommandbarcontrol.hxx" #include "vbacommandbarcontrols.hxx" #include <vbahelper/vbahelper.hxx> -#include <filter/msfilter/msvbahelper.hxx> +#include <vbahelper/msvbahelper.hxx> using namespace com::sun::star; using namespace ooo::vba; diff --git a/vbahelper/util/makefile.mk b/vbahelper/util/makefile.mk index 39bfac956288..e16e7fe1102d 100644 --- a/vbahelper/util/makefile.mk +++ b/vbahelper/util/makefile.mk @@ -60,8 +60,7 @@ SHL1STDLIBS= \ $(SVLLIB) \ $(VCLLIB) \ $(SVTOOLLIB) \ - $(TKLIB) \ - $(MSFILTERLIB) + $(TKLIB) SHL1DEPN= SHL1IMPLIB= i$(TARGET_HELPER) |