diff options
author | Andreas Bregas <ab@openoffice.org> | 2009-06-17 13:32:41 +0000 |
---|---|---|
committer | Andreas Bregas <ab@openoffice.org> | 2009-06-17 13:32:41 +0000 |
commit | ee8bb6f09f4ce8a32b827ee2f1da90906ed995d7 (patch) | |
tree | dbe9eba56a185aedcff8afeb6e1d0053c1f31291 | |
parent | defd4f2a6f0ba3029abcc8c2f025fe79aee52a74 (diff) |
#i102261# OLE control event handler support
-rw-r--r-- | extensions/source/propctrlr/eventhandler.cxx | 33 | ||||
-rw-r--r-- | forms/source/inc/InterfaceContainer.hxx | 3 | ||||
-rw-r--r-- | forms/source/misc/InterfaceContainer.cxx | 124 | ||||
-rw-r--r-- | forms/source/misc/makefile.mk | 10 |
4 files changed, 139 insertions, 31 deletions
diff --git a/extensions/source/propctrlr/eventhandler.cxx b/extensions/source/propctrlr/eventhandler.cxx index f8458001e..332912020 100644 --- a/extensions/source/propctrlr/eventhandler.cxx +++ b/extensions/source/propctrlr/eventhandler.cxx @@ -62,6 +62,7 @@ /** === end UNO includes === **/ #include <comphelper/namedvaluecollection.hxx> +#include <comphelper/evtmethodhelper.hxx> #include <comphelper/types.hxx> #include <cppuhelper/implbase1.hxx> #include <rtl/ref.hxx> @@ -165,36 +166,6 @@ namespace pcr namespace { //.................................................................... - Sequence< ::rtl::OUString > lcl_getListenerMethodsForType( const Type& type ) - { - typelib_InterfaceTypeDescription *pType=0; - type.getDescription( (typelib_TypeDescription**)&pType); - - if ( !pType ) - return Sequence< ::rtl::OUString>(); - - Sequence< ::rtl::OUString > aNames( pType->nMembers ); - ::rtl::OUString* pNames = aNames.getArray(); - for ( sal_Int32 i = 0; i < pType->nMembers; ++i, ++pNames) - { - // the decription reference - typelib_TypeDescriptionReference* pMemberDescriptionReference = pType->ppMembers[i]; - // the description for the reference - typelib_TypeDescription* pMemberDescription = NULL; - typelib_typedescriptionreference_getDescription( &pMemberDescription, pMemberDescriptionReference ); - if ( pMemberDescription ) - { - typelib_InterfaceMemberTypeDescription* pRealMemberDescription = - reinterpret_cast<typelib_InterfaceMemberTypeDescription*>(pMemberDescription); - *pNames = pRealMemberDescription->pMemberName; - } - } - - typelib_typedescription_release( (typelib_TypeDescription*)pType ); - return aNames; - } - - //.................................................................... #define DESCRIBE_EVENT( asciinamespace, asciilistener, asciimethod, id_postfix ) \ s_aKnownEvents.insert( EventMap::value_type( \ ::rtl::OUString::createFromAscii( asciimethod ), \ @@ -762,7 +733,7 @@ namespace pcr continue; // loop through all methods - Sequence< ::rtl::OUString > aMethods( lcl_getListenerMethodsForType( *pListeners ) ); + Sequence< ::rtl::OUString > aMethods( comphelper::getEventMethodsForType( *pListeners ) ); const ::rtl::OUString* pMethods = aMethods.getConstArray(); sal_uInt32 methodCount = aMethods.getLength(); diff --git a/forms/source/inc/InterfaceContainer.hxx b/forms/source/inc/InterfaceContainer.hxx index d9c64449e..40c561b53 100644 --- a/forms/source/inc/InterfaceContainer.hxx +++ b/forms/source/inc/InterfaceContainer.hxx @@ -260,6 +260,9 @@ protected: void implCheckIndex( const sal_Int32 _nIndex ) SAL_THROW( ( ::com::sun::star::lang::IndexOutOfBoundsException ) ); private: + // hack for Vba Events + void fakeVbaEventsHack( sal_Int32 _nIndex ); + // the runtime event format has changed from version SO5.2 to OOo enum EventFormat { diff --git a/forms/source/misc/InterfaceContainer.cxx b/forms/source/misc/InterfaceContainer.cxx index b138e5e7e..c0a6089e3 100644 --- a/forms/source/misc/InterfaceContainer.cxx +++ b/forms/source/misc/InterfaceContainer.cxx @@ -60,13 +60,20 @@ #include <rtl/logfile.hxx> //......................................................................... +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/document/XCodeNameQuery.hpp> +#include <ooo/vba/XVBAToOOEventDescGen.hpp> +#include <comphelper/processfactory.hxx> + namespace frm { //......................................................................... +using namespace ::com::sun::star::frame; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::document; using namespace ::com::sun::star::container; using namespace ::com::sun::star::script; using namespace ::com::sun::star::io; @@ -81,6 +88,90 @@ namespace } } +bool +lcl_hasVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents ) +{ + const ScriptEventDescriptor* pDesc = sEvents.getConstArray(); + const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() ); + for ( ; pDesc != pEnd; ++pDesc ) + { + if ( pDesc->ScriptType.equals( rtl::OUString::createFromAscii( "VBAInterop" ) ) ) + return true; + } + return false; +} + +Sequence< ScriptEventDescriptor > +lcl_stripVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents ) +{ + Sequence< ScriptEventDescriptor > sStripped( sEvents.getLength() ); + + const ScriptEventDescriptor* pDesc = sEvents.getConstArray(); + const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() ); + sal_Int32 nCopied = 0; + for ( ; pDesc != pEnd; ++pDesc ) + { + if ( !pDesc->ScriptType.equals( rtl::OUString::createFromAscii( "VBAInterop" ) ) ) + { + sStripped[ nCopied++ ] = *pDesc; + } + } + if ( nCopied ) + sStripped.realloc( nCopied ); + return sStripped; +} + +void +OInterfaceContainer::fakeVbaEventsHack( sal_Int32 _nIndex ) +{ + // we are dealing with form controls + try + { + Reference< XFormComponent > xForm( static_cast< XContainer* >(this), UNO_QUERY_THROW ); + // grand-parent should be the model, no parent ? if not + // we'll ignore, we'll get called back here anyway ) + Reference< XChild > xChild( xForm->getParent(), UNO_QUERY_THROW ); + Reference< XModel > xDocOwner( xChild->getParent(), UNO_QUERY ); + OSL_TRACE(" Is DOC ????? %s", xDocOwner.is() ? "true" : "false" ); + if ( xDocOwner.is() ) + { + bool hasVBABindings = lcl_hasVbaEvents( m_xEventAttacher->getScriptEvents( _nIndex ) ); + if ( hasVBABindings ) + { + OSL_TRACE("Has VBA bindings already, returning "); + return; + } + Reference< XMultiServiceFactory > xFac( comphelper::getProcessServiceFactory(), UNO_QUERY ); + Reference< XMultiServiceFactory > xDocFac( xDocOwner, UNO_QUERY ); + if ( xFac.is() && xDocFac.is() ) + { + try + { + Reference< ooo::vba::XVBAToOOEventDescGen > xDescSupplier( xFac->createInstance( rtl::OUString::createFromAscii( "ooo.vba.VBAToOOEventDesc" ) ), UNO_QUERY_THROW ); + Reference< XInterface > xIf( getByIndex( _nIndex ) , UNO_QUERY_THROW ); + Reference< XCodeNameQuery > xNameQuery( xDocFac->createInstance( rtl::OUString::createFromAscii( "ooo.vba.VBACodeNameProvider" ) ), UNO_QUERY_THROW ); + + rtl::OUString sCodeName; + sCodeName = xNameQuery->getCodeNameForObject( xIf ); + Reference< XPropertySet > xProps( xIf, UNO_QUERY ); + rtl::OUString sServiceName; + xProps->getPropertyValue( rtl::OUString::createFromAscii("DefaultControl" ) ) >>= sServiceName; + + Sequence< ScriptEventDescriptor > vbaEvents = xDescSupplier->getEventDescriptions( xFac->createInstance( sServiceName ), sCodeName ); + // register the vba script events + if ( m_xEventAttacher.is() ) + m_xEventAttacher->registerScriptEvents( _nIndex, vbaEvents ); + } + catch( Exception& e ){ OSL_TRACE("lcl_fakevbaevents - Caught Exception trying to create control eventstuff "); } + } + + } + } + catch( Exception& e ) + { + } + +} //================================================================== //= ElementDescription //================================================================== @@ -743,6 +834,23 @@ void OInterfaceContainer::implInsert(sal_Int32 _nIndex, const Reference< XProper { m_xEventAttacher->insertEntry(_nIndex); m_xEventAttacher->attach( _nIndex, pElementMetaData->xInterface, makeAny( _rxElement ) ); + // insert fake events? + Reference< XEventAttacherManager > xMgr ( pElementMetaData->xInterface, UNO_QUERY ); + if ( xMgr.is() ) + { + OInterfaceContainer* pIfcMgr = dynamic_cast< OInterfaceContainer* >( xMgr.get() ); + sal_Int32 nLen = pIfcMgr->getCount(); + for ( sal_Int32 i = 0; (i < nLen) && pIfcMgr ; ++i ) + { + // add fake events to the control at index i + pIfcMgr->fakeVbaEventsHack( i ); + } + } + else + { + // add fake events to the control at index i + fakeVbaEventsHack( _nIndex ); + } } // notify derived classes @@ -1022,20 +1130,29 @@ void SAL_CALL OInterfaceContainer::removeByName(const ::rtl::OUString& Name) thr //------------------------------------------------------------------------ void SAL_CALL OInterfaceContainer::registerScriptEvent( sal_Int32 nIndex, const ScriptEventDescriptor& aScriptEvent ) throw(IllegalArgumentException, RuntimeException) { + OSL_TRACE("*** registerScriptEvent %d", nIndex); if ( m_xEventAttacher.is() ) + { m_xEventAttacher->registerScriptEvent( nIndex, aScriptEvent ); + fakeVbaEventsHack( nIndex ); // add fake vba events + } } //------------------------------------------------------------------------ void SAL_CALL OInterfaceContainer::registerScriptEvents( sal_Int32 nIndex, const Sequence< ScriptEventDescriptor >& aScriptEvents ) throw(IllegalArgumentException, RuntimeException) { + OSL_TRACE("*** registerScriptEvent(s) %d", nIndex); if ( m_xEventAttacher.is() ) + { m_xEventAttacher->registerScriptEvents( nIndex, aScriptEvents ); + fakeVbaEventsHack( nIndex ); // add fake vba events + } } //------------------------------------------------------------------------ void SAL_CALL OInterfaceContainer::revokeScriptEvent( sal_Int32 nIndex, const ::rtl::OUString& aListenerType, const ::rtl::OUString& aEventMethod, const ::rtl::OUString& aRemoveListenerParam ) throw(IllegalArgumentException, RuntimeException) { + OSL_TRACE("*** revokeScriptEvent %d listenertype %s, eventMethod %s", nIndex, rtl::OUStringToOString( aListenerType, RTL_TEXTENCODING_UTF8 ).getStr(), rtl::OUStringToOString( aEventMethod, RTL_TEXTENCODING_UTF8 ).getStr()); if ( m_xEventAttacher.is() ) m_xEventAttacher->revokeScriptEvent( nIndex, aListenerType, aEventMethod, aRemoveListenerParam ); } @@ -1064,9 +1181,16 @@ void SAL_CALL OInterfaceContainer::removeEntry( sal_Int32 nIndex ) throw(Illegal //------------------------------------------------------------------------ Sequence< ScriptEventDescriptor > SAL_CALL OInterfaceContainer::getScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException) { + OSL_TRACE("getScriptEvents"); Sequence< ScriptEventDescriptor > aReturn; if ( m_xEventAttacher.is() ) + { aReturn = m_xEventAttacher->getScriptEvents( nIndex ); + if ( lcl_hasVbaEvents( aReturn ) ) + { + aReturn = lcl_stripVbaEvents( aReturn ); + } + } return aReturn; } diff --git a/forms/source/misc/makefile.mk b/forms/source/misc/makefile.mk index b03109ba6..9422ba70d 100644 --- a/forms/source/misc/makefile.mk +++ b/forms/source/misc/makefile.mk @@ -45,6 +45,7 @@ ENABLE_EXCEPTIONS=TRUE # --- Types ------------------------------------- INCPRE+=$(SOLARINCDIR)$/offuh +INCPRE*=$(INCCOM)$/$(TARGET) # --- Files ------------------------------------- @@ -62,3 +63,12 @@ SLOFILES= $(SLO)$/limitedformats.obj \ .INCLUDE : target.mk +ALLTAR : \ + $(MISC)$/$(TARGET).don \ + +$(SLOFILES) : $(MISC)$/$(TARGET).don + +$(MISC)$/$(TARGET).don : $(SOLARBINDIR)$/oovbaapi.rdb + +$(CPPUMAKER) -O$(INCCOM)$/$(TARGET) -BUCR $(SOLARBINDIR)$/oovbaapi.rdb -X$(SOLARBINDIR)$/types.rdb && echo > $@ + echo $@ + |