diff options
Diffstat (limited to 'vbahelper/source')
-rw-r--r-- | vbahelper/source/msforms/vbacontrols.cxx | 31 | ||||
-rw-r--r-- | vbahelper/source/msforms/vbauserform.cxx | 4 | ||||
-rw-r--r-- | vbahelper/source/vbahelper/makefile.mk | 2 | ||||
-rw-r--r-- | vbahelper/source/vbahelper/vbaapplicationbase.cxx | 109 | ||||
-rw-r--r-- | vbahelper/source/vbahelper/vbadocumentbase.cxx | 51 | ||||
-rwxr-xr-x | vbahelper/source/vbahelper/vbaeventshelperbase.cxx | 218 | ||||
-rw-r--r-- | vbahelper/source/vbahelper/vbaglobalbase.cxx | 57 | ||||
-rw-r--r-- | vbahelper/source/vbahelper/vbahelper.cxx | 20 |
8 files changed, 383 insertions, 109 deletions
diff --git a/vbahelper/source/msforms/vbacontrols.cxx b/vbahelper/source/msforms/vbacontrols.cxx index 1284b36be463..8d01687ef905 100644 --- a/vbahelper/source/msforms/vbacontrols.cxx +++ b/vbahelper/source/msforms/vbacontrols.cxx @@ -74,12 +74,20 @@ private: public: ControlArrayWrapper( const uno::Reference< awt::XControl >& xDialog ) { - mxDialog.set( xDialog, uno::UNO_QUERY_THROW ); - uno::Sequence< uno::Reference< awt::XControl > > sXControls = mxDialog->getControls(); + try + { + mxDialog.set( xDialog, uno::UNO_QUERY_THROW ); + uno::Sequence< uno::Reference< awt::XControl > > sXControls = mxDialog->getControls(); - msNames.realloc( sXControls.getLength() ); - for ( sal_Int32 i = 0; i < sXControls.getLength(); ++i ) - SetArrayElementTo( sXControls[ i ], i ); + msNames.realloc( sXControls.getLength() ); + for ( sal_Int32 i = 0; i < sXControls.getLength(); ++i ) + SetArrayElementTo( sXControls[ i ], i ); + } + catch( uno::Exception& ) + { + // accept the case when the dialog already does not exist + // in this case the wrapper should work in dummy mode + } } static rtl::OUString getControlName( const uno::Reference< awt::XControl >& xCtrl ) @@ -186,7 +194,7 @@ ScVbaControls::ScVbaControls( const uno::Reference< XHelperInterface >& xParent, const css::uno::Reference< awt::XControl >& xDialog ) : ControlsImpl_BASE( xParent, xContext, lcl_controlsWrapper( xDialog ) ) { - mxDialog.set( xDialog, uno::UNO_QUERY_THROW ); + mxDialog.set( xDialog, uno::UNO_QUERY ); } uno::Reference< container::XEnumeration > @@ -349,13 +357,16 @@ void SAL_CALL ScVbaControls::Remove( const uno::Any& StringKeyOrIndex ) } catch( uno::RuntimeException& ) { - throw; + // the exceptions are not rethrown, impossibility to find or remove the control is currently not reported + // since in most cases it means just that the controls is already not there, the VBA seems to do it in the same way + + // throw; } catch( uno::Exception& e ) { - throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can not create AXControl!" ) ), - uno::Reference< uno::XInterface >(), - uno::makeAny( e ) ); + // throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can not create AXControl!" ) ), + // uno::Reference< uno::XInterface >(), + // uno::makeAny( e ) ); } } diff --git a/vbahelper/source/msforms/vbauserform.cxx b/vbahelper/source/msforms/vbauserform.cxx index 1ce403fc19c3..2a4cecfc2338 100644 --- a/vbahelper/source/msforms/vbauserform.cxx +++ b/vbahelper/source/msforms/vbauserform.cxx @@ -185,7 +185,9 @@ ScVbaUserForm::hasMethod( const ::rtl::OUString& /*aName*/ ) throw (uno::Runtime uno::Any SAL_CALL ScVbaUserForm::Controls( const uno::Any& index ) throw (uno::RuntimeException) { - uno::Reference< awt::XControl > xDialogControl( m_xDialog, uno::UNO_QUERY_THROW ); + // if the dialog already closed we should do nothing, but the VBA will call methods of the Controls objects + // thus we have to provide a dummy object in this case + uno::Reference< awt::XControl > xDialogControl( m_xDialog, uno::UNO_QUERY ); uno::Reference< XCollection > xControls( new ScVbaControls( this, mxContext, xDialogControl ) ); if ( index.hasValue() ) return uno::makeAny( xControls->Item( index, uno::Any() ) ); diff --git a/vbahelper/source/vbahelper/makefile.mk b/vbahelper/source/vbahelper/makefile.mk index 47ad44b3d0ed..22ed40a3adfa 100644 --- a/vbahelper/source/vbahelper/makefile.mk +++ b/vbahelper/source/vbahelper/makefile.mk @@ -65,6 +65,8 @@ SLOFILES=\ $(SLO)$/vbashaperange.obj \ $(SLO)$/vbatextframe.obj \ $(SLO)$/vbapagesetupbase.obj \ + $(SLO)$/vbaeventshelperbase.obj + # --- Targets ------------------------------------------------------- .INCLUDE : target.mk diff --git a/vbahelper/source/vbahelper/vbaapplicationbase.cxx b/vbahelper/source/vbahelper/vbaapplicationbase.cxx index 6d2c51066ca2..326c150edade 100644 --- a/vbahelper/source/vbahelper/vbaapplicationbase.cxx +++ b/vbahelper/source/vbahelper/vbaapplicationbase.cxx @@ -24,39 +24,37 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #include "vbahelper/vbaapplicationbase.hxx" + #include <com/sun/star/container/XIndexAccess.hpp> -#include <com/sun/star/lang/XMultiServiceFactory.hpp> //Michael E. Bohn -#include <com/sun/star/lang/XMultiComponentFactory.hpp> //Michael E. Bohn -#include <com/sun/star/lang/XComponent.hpp> //Michael E. Bohn -#include <com/sun/star/container/XEnumeration.hpp> //Michael E. Bohn +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/container/XEnumeration.hpp> #include <com/sun/star/frame/XLayoutManager.hpp> #include <com/sun/star/frame/XDesktop.hpp> #include <com/sun/star/container/XEnumerationAccess.hpp> #include <com/sun/star/document/XDocumentInfoSupplier.hpp> #include <com/sun/star/document/XDocumentProperties.hpp> #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> -#include <com/sun/star/document/XEmbeddedScripts.hpp> //Michael E. Bohn -#include <ooo/vba/XVBAAppService.hpp> //Michael E. Bohn +#include <com/sun/star/document/XEmbeddedScripts.hpp> #include <com/sun/star/awt/XWindow2.hpp> - -#include "vbacommandbars.hxx" +#include <hash_map> #include <filter/msfilter/msvbahelper.hxx> #include <tools/datetime.hxx> -// start basic includes #include <basic/sbx.hxx> #include <basic/sbstar.hxx> #include <basic/sbuno.hxx> #include <basic/sbmeth.hxx> #include <basic/sbmod.hxx> -// end basic includes -#include <hash_map> +#include "vbacommandbars.hxx" -using namespace com::sun::star; -using namespace ooo::vba; +using namespace ::com::sun::star; +using namespace ::ooo::vba; #define OFFICEVERSION "11.0" @@ -162,6 +160,9 @@ typedef ::std::hash_map< VbaTimerInfo, VbaTimer*, VbaTimerInfoHash, ::std::equal struct VbaApplicationBase_Impl { VbaTimerHashMap m_aTimerHash; + sal_Bool mbVisible; + + inline VbaApplicationBase_Impl() : mbVisible( sal_True ) {} virtual ~VbaApplicationBase_Impl() { @@ -185,7 +186,6 @@ VbaApplicationBase::VbaApplicationBase( const uno::Reference< uno::XComponentCon VbaApplicationBase::~VbaApplicationBase() { - m_pImpl = 0; delete m_pImpl; } @@ -268,6 +268,16 @@ void SAL_CALL VbaApplicationBase::setInteractive( ::sal_Bool bInteractive ) xWindow->setEnable( bInteractive ); } +sal_Bool SAL_CALL VbaApplicationBase::getVisible() throw (uno::RuntimeException) +{ + return m_pImpl->mbVisible; // dummy implementation +} + +void SAL_CALL VbaApplicationBase::setVisible( sal_Bool bVisible ) throw (uno::RuntimeException) +{ + m_pImpl->mbVisible = bVisible; // dummy implementation +} + uno::Any SAL_CALL VbaApplicationBase::CommandBars( const uno::Any& aIndex ) throw (uno::RuntimeException) { @@ -407,63 +417,50 @@ float SAL_CALL VbaApplicationBase::CentimetersToPoints( float _Centimeters ) thr return ( _Centimeters * rate ); } -// inserted by Michael E. Bohn uno::Any SAL_CALL VbaApplicationBase::getVBE() throw (uno::RuntimeException) { - uno::Any aAny; - uno::Reference< ::lang::XMultiComponentFactory > xServiceManager = mxContext->getServiceManager(); - try - { - uno::Reference < ::uno::XInterface > xInterface = xServiceManager->createInstanceWithContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAAppService" )),mxContext); - uno::Reference < ::ooo::vba::XVBAAppService > xVBAAppService (xInterface, ::uno::UNO_QUERY_THROW ); - if (xVBAAppService.is()){ - uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW ); - return xVBAAppService->getVBE( this, mxContext, xModel); - } - - }catch(uno::Exception* e) - { - } - return aAny; + try // return empty object on error + { + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[ 0 ] <<= uno::Reference< XHelperInterface >( this ); + aArgs[ 1 ] <<= getCurrentDocument(); + uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW ); + uno::Reference< uno::XInterface > xVBE = xServiceManager->createInstanceWithArgumentsAndContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBE" ) ), aArgs, mxContext ); + return uno::Any( xVBE ); + } + catch( uno::Exception& ) + { + } + return uno::Any(); } uno::Any SAL_CALL VbaApplicationBase::getVBProjects() throw (uno::RuntimeException) { - uno::Any aAny; - uno::Reference< ::lang::XMultiComponentFactory > xServiceManager = mxContext->getServiceManager(); - try - { - uno::Reference < ::uno::XInterface > xInterface = xServiceManager->createInstanceWithContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAAppService" )),mxContext); - uno::Reference < ::ooo::vba::XVBAAppService > xVBAAppService (xInterface, ::uno::UNO_QUERY_THROW ); - if (xVBAAppService.is()){ - uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_QUERY_THROW ); - uno::Reference< document::XEmbeddedScripts > xEnbeddedScripts ( xModel, uno::UNO_QUERY_THROW ); - uno::Reference< script::XStorageBasedLibraryContainer > xMacroStorageBasedLibraryContainer = xEnbeddedScripts->getBasicLibraries(); - uno::Reference< script::XStorageBasedLibraryContainer > xDialogStorageBasedLibraryContainer = xEnbeddedScripts->getDialogLibraries(); - uno::Reference< script::XLibraryContainer > xMacroLibraryContainer ( xMacroStorageBasedLibraryContainer, uno::UNO_QUERY_THROW ); - uno::Reference< script::XLibraryContainer > xDialogLibraryContainer( xDialogStorageBasedLibraryContainer, uno::UNO_QUERY_THROW ); - return xVBAAppService->getVBProjects(this, mxContext, xModel, xMacroLibraryContainer, xDialogLibraryContainer); - } - - }catch(uno::Exception* e) - { - } - return aAny; - - - + try // return empty object on error + { + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[ 0 ] <<= uno::Reference< XHelperInterface >( this ); + aArgs[ 1 ] <<= getCurrentDocument(); + uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW ); + uno::Reference< uno::XInterface > xVBProjects = xServiceManager->createInstanceWithArgumentsAndContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBProjects" ) ), aArgs, mxContext ); + return uno::Any( xVBProjects ); + } + catch( uno::Exception& ) + { + } + return uno::Any(); } - - - rtl::OUString& VbaApplicationBase::getServiceImplName() { static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("VbaApplicationBase") ); return sImplName; } + uno::Sequence<rtl::OUString> VbaApplicationBase::getServiceNames() { diff --git a/vbahelper/source/vbahelper/vbadocumentbase.cxx b/vbahelper/source/vbahelper/vbadocumentbase.cxx index f27f2de53c8a..65f7f4bcfbeb 100644 --- a/vbahelper/source/vbahelper/vbadocumentbase.cxx +++ b/vbahelper/source/vbahelper/vbadocumentbase.cxx @@ -24,9 +24,9 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ -#include <vbahelper/vbadocumentbase.hxx> -#include <vbahelper/helperdecl.hxx> -#include <comphelper/unwrapargs.hxx> + +#include "vbahelper/vbadocumentbase.hxx" +#include "vbahelper/helperdecl.hxx" #include <com/sun/star/util/XModifiable.hpp> #include <com/sun/star/util/XProtectable.hpp> @@ -35,8 +35,8 @@ #include <com/sun/star/frame/XFrame.hpp> #include <com/sun/star/document/XEmbeddedScripts.hpp> //Michael E. Bohn #include <com/sun/star/beans/XPropertySet.hpp> -#include <ooo/vba/XVBADocService.hpp> +#include <comphelper/unwrapargs.hxx> #include <tools/urlobj.hxx> #include <osl/file.hxx> @@ -206,40 +206,25 @@ VbaDocumentBase::Activate() throw (uno::RuntimeException) xFrame->activate(); } -// ---- Michael E.Bohn Start----- - uno::Any SAL_CALL VbaDocumentBase::getVBProject() throw (uno::RuntimeException) - { - uno::Any aAny; - uno::Reference< ::lang::XMultiComponentFactory > xServiceManager = mxContext->getServiceManager(); - try - { - uno::Reference < ::uno::XInterface > xInterface = xServiceManager->createInstanceWithContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBADocService" )),mxContext); - uno::Reference < ::ooo::vba::XVBADocService > xVBADocService (xInterface, ::uno::UNO_QUERY_THROW ); - if (xVBADocService.is()){ - uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); - uno::Reference< document::XEmbeddedScripts > xEnbeddedScripts ( xModel, uno::UNO_QUERY_THROW ); - uno::Reference< script::XStorageBasedLibraryContainer > xMacroStorageBasedLibraryContainer = xEnbeddedScripts->getBasicLibraries(); - uno::Reference< script::XStorageBasedLibraryContainer > xDialogStorageBasedLibraryContainer = xEnbeddedScripts->getDialogLibraries(); - uno::Reference< script::XLibraryContainer > xMacroLibraryContainer ( xMacroStorageBasedLibraryContainer, uno::UNO_QUERY_THROW ); - uno::Reference< script::XLibraryContainer > xDialogLibraryContainer( xDialogStorageBasedLibraryContainer, uno::UNO_QUERY_THROW ); - - return xVBADocService->getVBProject( this, mxContext, xModel, xMacroLibraryContainer, xDialogLibraryContainer ); - } - - }catch(uno::Exception* e) - { - } - return aAny; - + try // return empty object on error + { + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[ 0 ] <<= uno::Reference< XHelperInterface >( this ); + aArgs[ 1 ] <<= mxModel; + uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW ); + uno::Reference< uno::XInterface > xVBProjects = xServiceManager->createInstanceWithArgumentsAndContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBProject" ) ), aArgs, mxContext ); + return uno::Any( xVBProjects ); + } + catch( uno::Exception& ) + { + } + return uno::Any(); } - -// ---- Michael E.Bohn End ----- - - rtl::OUString& VbaDocumentBase::getServiceImplName() { diff --git a/vbahelper/source/vbahelper/vbaeventshelperbase.cxx b/vbahelper/source/vbahelper/vbaeventshelperbase.cxx new file mode 100755 index 000000000000..16a8671df601 --- /dev/null +++ b/vbahelper/source/vbahelper/vbaeventshelperbase.cxx @@ -0,0 +1,218 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "vbahelper/vbaeventshelperbase.hxx" +#include <filter/msfilter/msvbahelper.hxx> + +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +// ============================================================================ + +VbaEventsHelperBase::VbaEventsHelperBase( const uno::Sequence< uno::Any >& rArgs, const uno::Reference< uno::XComponentContext >& /*xContext*/ ) : + mpShell( 0 ), + mbDisposed( false ) +{ + try + { + mxModel = getXSomethingFromArgs< frame::XModel >( rArgs, 0, false ); + mpShell = getSfxObjShell( mxModel ); + + // add dispose listener + uno::Reference< lang::XComponent > xComponent( mxModel, uno::UNO_QUERY_THROW ); + xComponent->addEventListener( this ); + } + catch( uno::Exception& ) + { + } +} + +VbaEventsHelperBase::~VbaEventsHelperBase() +{ + stopListening(); +} + +sal_Bool SAL_CALL VbaEventsHelperBase::hasVbaEventHandler( sal_Int32 nEventId, const uno::Sequence< uno::Any >& rArgs ) + throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + // getEventHandlerInfo() throws, if unknown event dentifier has been passed + const EventHandlerInfo& rInfo = getEventHandlerInfo( nEventId ); + // getEventHandlerPath() searches for the macro in the document + return getEventHandlerPath( rInfo, rArgs ).getLength() > 0; +} + +void SAL_CALL VbaEventsHelperBase::processVbaEvent( sal_Int32 nEventId, const uno::Sequence< uno::Any >& rArgs ) + throw (lang::IllegalArgumentException, script::provider::ScriptFrameworkErrorException, util::VetoException, uno::RuntimeException) +{ + /* Derived classes may add new event identifiers to be processed while + processing the original event. All unprocessed events are collected in + a queue. First element in the queue is the next event to be processed. */ + EventQueue aEventQueue; + aEventQueue.push_back( EventQueueEntry( nEventId, rArgs ) ); + + /* bEnabled will track if event processing is enabled. Every event handler + may disable handling of other events. */ + bool bEnabled = true; + + /* bCancel will contain the current Cancel value. It is possible that + multiple events will try to modify the Cancel value. Every event + handler receives the Cancel value of the previous event handler. */ + bool bCancel = false; + + /* bSuccess will change to true if at least one event handler has been + executed successfully. */ + bool bSuccess = false; + + /* Loop as long as there are more events to be processed, and as event + handling is still enabled. Derived classes may add new events to be + processed in the virtual implPrepareEvent() function. */ + while( bEnabled && !aEventQueue.empty() ) + { + /* Check that all class members are available, and that we are not + disposed (this may have happened at any time during execution of + the last event handler). */ + if( mbDisposed || !mxModel.is() || !mpShell ) + throw uno::RuntimeException(); + + // get info for next event + const EventHandlerInfo& rInfo = getEventHandlerInfo( aEventQueue.front().mnEventId ); + uno::Sequence< uno::Any > aEventArgs = aEventQueue.front().maArgs; + aEventQueue.pop_front(); + + // let derived classes decide whether event processing is still enabled + bEnabled = implEventsEnabled(); + // let derived classes prepare the event, they may add new events for next iteration + if( bEnabled && implPrepareEvent( aEventQueue, rInfo, aEventArgs ) ) + { + // search the event handler macro in the document + ::rtl::OUString aMacroPath = getEventHandlerPath( rInfo, aEventArgs ); + bool bEventSuccess = false; + if( aMacroPath.getLength() > 0 ) + { + // build the argument list + uno::Sequence< uno::Any > aVbaArgs = implBuildArgumentList( rInfo, aEventArgs ); + // insert current cancel value + if( rInfo.mnCancelIndex >= 0 ) + { + if( rInfo.mnCancelIndex >= aVbaArgs.getLength() ) + throw lang::IllegalArgumentException(); + aVbaArgs[ rInfo.mnCancelIndex ] <<= bCancel; + } + // execute the event handler + uno::Any aRet, aCaller; + bEventSuccess = executeMacro( mpShell, aMacroPath, aVbaArgs, aRet, aCaller ); + // extract new cancel value + if( rInfo.mnCancelIndex >= 0 ) + { + if( rInfo.mnCancelIndex >= aVbaArgs.getLength() ) + throw lang::IllegalArgumentException(); + // cancel value may be boolean or any integer type, Any(bool) does not extract to sal_Int32 + bool bNewCancel = false; + sal_Int32 nNewCancel = 0; + if( aVbaArgs[ rInfo.mnCancelIndex ] >>= bNewCancel ) + bCancel = bNewCancel; + else if( aVbaArgs[ rInfo.mnCancelIndex ] >>= nNewCancel ) + bCancel = nNewCancel != 0; + } + } + // post processing (also, if event handler does not exist, or on error + implPostProcessEvent( aEventQueue, rInfo, bEventSuccess, bCancel ); + // global success, if at least one event handler succeeded + bSuccess |= bEventSuccess; + } + } + + // if event handlers want to cancel the event, do so regardless of any errors + if( bCancel ) + throw util::VetoException(); + + // if no event handler finished successfully, throw + if( !bSuccess ) + throw script::provider::ScriptFrameworkErrorException(); +} + +void SAL_CALL VbaEventsHelperBase::disposing( const lang::EventObject& /*aSource*/ ) throw (uno::RuntimeException) +{ + OSL_TRACE( "VbaEventsHelperBase::disposing" ); + stopListening(); + mbDisposed = true; +} + +// protected ------------------------------------------------------------------ + +void VbaEventsHelperBase::registerEventHandler( sal_Int32 nEventId, + const sal_Char* pcMacroName, EventHandlerType eType, sal_Int32 nCancelIndex, const uno::Any& rUserData ) +{ + EventHandlerInfo& rInfo = maEvents[ nEventId ]; + rInfo.mnEventId = nEventId; + rInfo.maMacroName = ::rtl::OUString::createFromAscii( pcMacroName ); + rInfo.meType = eType; + rInfo.mnCancelIndex = nCancelIndex; + rInfo.maUserData = rUserData; +} + +// private -------------------------------------------------------------------- + +const VbaEventsHelperBase::EventHandlerInfo& VbaEventsHelperBase::getEventHandlerInfo( + sal_Int32 nEventId ) const throw (lang::IllegalArgumentException) +{ + EventHandlerMap::const_iterator aIt = maEvents.find( nEventId ); + if( aIt == maEvents.end() ) + throw lang::IllegalArgumentException(); + return aIt->second; +} + +::rtl::OUString VbaEventsHelperBase::getEventHandlerPath( const EventHandlerInfo& rInfo, + const uno::Sequence< uno::Any >& rArgs ) const throw (lang::IllegalArgumentException) +{ + ::rtl::OUString aMacroName; + switch( rInfo.meType ) + { + case EVENTHANDLER_GLOBAL: + aMacroName = rInfo.maMacroName; + break; + case EVENTHANDLER_DOCUMENT: + aMacroName = ::rtl::OUStringBuffer( implGetDocumentModuleName( rInfo, rArgs ) ). + append( sal_Unicode( '.' ) ).append( rInfo.maMacroName ).makeStringAndClear(); + break; + } + return resolveVBAMacro( mpShell, aMacroName ).ResolvedMacro(); +} + +void VbaEventsHelperBase::stopListening() +{ + if( !mbDisposed ) try + { + uno::Reference< lang::XComponent > xComponent( mxModel, uno::UNO_QUERY_THROW ); + xComponent->removeEventListener( this ); + } + catch( uno::Exception& ) + { + } +} + +// ============================================================================ diff --git a/vbahelper/source/vbahelper/vbaglobalbase.cxx b/vbahelper/source/vbahelper/vbaglobalbase.cxx index c7c33b93b1a3..e0df37583df5 100644 --- a/vbahelper/source/vbahelper/vbaglobalbase.cxx +++ b/vbahelper/source/vbahelper/vbaglobalbase.cxx @@ -35,22 +35,50 @@ using namespace ooo::vba; rtl::OUString sApplication( RTL_CONSTASCII_USTRINGPARAM("Application") ); +// special key to return the Application +rtl::OUString sAppService( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.Application") ); + VbaGlobalsBase::VbaGlobalsBase( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sDocCtxName ) -: Globals_BASE( xParent, xContext ) +: Globals_BASE( xParent, xContext ), msDocCtxName( sDocCtxName ) { // overwrite context with custom one ( that contains the application ) + // wrap the service manager as we don't want the disposing context to tear down the 'normal' ServiceManager ( or at least thats what the code appears like it wants to do ) + uno::Any aSrvMgr; + if ( xContext.is() && xContext->getServiceManager().is() ) + { + aSrvMgr = uno::makeAny( xContext->getServiceManager()->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.OServiceManagerWrapper") ), xContext ) ); + } + ::cppu::ContextEntry_Init aHandlerContextInfo[] = { ::cppu::ContextEntry_Init( sApplication, uno::Any() ), ::cppu::ContextEntry_Init( sDocCtxName, uno::Any() ), + ::cppu::ContextEntry_Init( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.lang.theServiceManager" ) ), aSrvMgr ) }; - - mxContext = ::cppu::createComponentContext( aHandlerContextInfo, sizeof( aHandlerContextInfo ) / sizeof( aHandlerContextInfo[0] ), xContext ); - + // don't pass a delegate, this seems to introduce yet another cyclic dependency ( and + // some strange behavior + mxContext = ::cppu::createComponentContext( aHandlerContextInfo, sizeof( aHandlerContextInfo ) / sizeof( aHandlerContextInfo[0] ), NULL ); } +VbaGlobalsBase::~VbaGlobalsBase() +{ + try + { + uno::Reference< container::XNameContainer > xNameContainer( mxContext, uno::UNO_QUERY ); + if ( xNameContainer.is() ) + { + // release document reference ( we don't wan't the component context trying to dispose that ) + xNameContainer->removeByName( msDocCtxName ); + // release application reference, as it is holding onto the context + xNameContainer->removeByName( sApplication ); + } + } + catch ( const uno::Exception& ) + { + } +} void VbaGlobalsBase::init( const uno::Sequence< beans::PropertyValue >& aInitArgs ) @@ -74,19 +102,30 @@ uno::Reference< uno::XInterface > SAL_CALL VbaGlobalsBase::createInstance( const ::rtl::OUString& aServiceSpecifier ) throw (uno::Exception, uno::RuntimeException) { uno::Reference< uno::XInterface > xReturn; - - if ( hasServiceName( aServiceSpecifier ) ) + if ( aServiceSpecifier.equals( sAppService ) ) + { + // try to extract the Application from the context + uno::Reference< container::XNameContainer > xNameContainer( mxContext, uno::UNO_QUERY ); + xNameContainer->getByName( sApplication ) >>= xReturn; + } + else if ( hasServiceName( aServiceSpecifier ) ) xReturn = mxContext->getServiceManager()->createInstanceWithContext( aServiceSpecifier, mxContext ); return xReturn; } uno::Reference< uno::XInterface > SAL_CALL -VbaGlobalsBase::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const uno::Sequence< uno::Any >& Arguments ) throw (uno::Exception, uno::RuntimeException) +VbaGlobalsBase::createInstanceWithArguments( const ::rtl::OUString& aServiceSpecifier, const uno::Sequence< uno::Any >& Arguments ) throw (uno::Exception, uno::RuntimeException) { uno::Reference< uno::XInterface > xReturn; - if ( hasServiceName( ServiceSpecifier ) ) - xReturn = mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( ServiceSpecifier, Arguments, mxContext ); + if ( aServiceSpecifier.equals( sAppService ) ) + { + // try to extract the Application from the context + uno::Reference< container::XNameContainer > xNameContainer( mxContext, uno::UNO_QUERY ); + xNameContainer->getByName( sApplication ) >>= xReturn; + } + else if ( hasServiceName( aServiceSpecifier ) ) + xReturn = mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( aServiceSpecifier, Arguments, mxContext ); return xReturn; } diff --git a/vbahelper/source/vbahelper/vbahelper.cxx b/vbahelper/source/vbahelper/vbahelper.cxx index 1953d0772f3c..7cd82dff9536 100644 --- a/vbahelper/source/vbahelper/vbahelper.cxx +++ b/vbahelper/source/vbahelper/vbahelper.cxx @@ -1404,6 +1404,26 @@ void UserFormGeometryHelper::setHeight( double nHeight ) return points; } + uno::Reference< uno::XInterface > getUnoDocModule( const String& aModName, SfxObjectShell* pShell ) + { + uno::Reference< uno::XInterface > xIf; + if ( pShell ) + { + rtl::OUString sProj( RTL_CONSTASCII_USTRINGPARAM("Standard") ); + BasicManager* pBasMgr = pShell->GetBasicManager(); + if ( pBasMgr && pBasMgr->GetName().Len() ) + sProj = pShell->GetBasicManager()->GetName(); + StarBASIC* pBasic = pShell->GetBasicManager()->GetLib( sProj ); + if ( pBasic ) + { + SbModule* pMod = pBasic->FindModule( aModName ); + if ( pMod ) + xIf = pMod->GetUnoModule(); + } + } + return xIf; + } + SfxObjectShell* getSfxObjShell( const uno::Reference< frame::XModel >& xModel ) throw (uno::RuntimeException) { SfxObjectShell* pFoundShell = NULL; |