summaryrefslogtreecommitdiff
path: root/eventattacher
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@suse.com>2011-08-10 23:00:18 -0400
committerKohei Yoshida <kohei.yoshida@suse.com>2011-08-16 21:22:40 -0400
commit98dc4bb8a1d029ba8b01504b74ed5397e1e7164b (patch)
tree2ca7ef6a45076e9b4b67ceff9dbe814abda5d4e9 /eventattacher
parentacd31343d1a346f045a8145894c7e4451910cbf8 (diff)
Extended UNO's script API to allow adding of multiple listeners at once.
Diffstat (limited to 'eventattacher')
-rw-r--r--eventattacher/source/eventattacher.cxx177
1 files changed, 175 insertions, 2 deletions
diff --git a/eventattacher/source/eventattacher.cxx b/eventattacher/source/eventattacher.cxx
index 95d352fbf04e..7deb8113224c 100644
--- a/eventattacher/source/eventattacher.cxx
+++ b/eventattacher/source/eventattacher.cxx
@@ -33,7 +33,7 @@
#include <com/sun/star/registry/XRegistryKey.hpp>
#include <com/sun/star/beans/XIntrospection.hpp>
#include <com/sun/star/beans/MethodConcept.hpp>
-#include <com/sun/star/script/XEventAttacher.hpp>
+#include <com/sun/star/script/XEventAttacher2.hpp>
#include <com/sun/star/script/XTypeConverter.hpp>
#include <com/sun/star/script/XAllListener.hpp>
#include <com/sun/star/script/XInvocationAdapterFactory.hpp>
@@ -214,7 +214,7 @@ sal_Bool SAL_CALL InvocationToAllListenerMapper::hasProperty(const OUString& Nam
// class EventAttacherImpl
// represents an implementation of the EventAttacher service
//*************************************************************************
-class EventAttacherImpl : public WeakImplHelper3 < XEventAttacher, XInitialization, XServiceInfo >
+class EventAttacherImpl : public WeakImplHelper3 < XEventAttacher2, XInitialization, XServiceInfo >
{
public:
EventAttacherImpl( const Reference< XMultiServiceFactory >& );
@@ -246,10 +246,22 @@ public:
const Reference< XEventListener >& aToRemoveListener)
throw( IllegalArgumentException, IntrospectionException, RuntimeException );
+ // XEventAttacher2
+ virtual Sequence< Reference<XEventListener> > SAL_CALL attachMultipleEventListeners(
+ const Reference<XInterface>& xObject, const Sequence<com::sun::star::script::EventListener>& aListeners )
+ throw( IllegalArgumentException, ServiceNotRegisteredException, CannotCreateAdapterException, IntrospectionException, RuntimeException );
+
// used by FilterAllListener_Impl
Reference< XTypeConverter > getConverter() throw( Exception );
friend class FilterAllListenerImpl;
+
+private:
+ Sequence< Reference<XEventListener> > attachListeners(
+ const Reference<XInterface>& xObject,
+ const Sequence< Reference<XAllListener> >& AllListeners,
+ const Sequence<com::sun::star::script::EventListener>& aListeners );
+
private:
Mutex m_aMutex;
Reference< XMultiServiceFactory > m_xSMgr;
@@ -694,6 +706,152 @@ Reference< XEventListener > EventAttacherImpl::attachListener
return xRet;
}
+Sequence< Reference<XEventListener> > EventAttacherImpl::attachListeners(
+ const Reference<XInterface>& xObject,
+ const Sequence< Reference<XAllListener> >& AllListeners,
+ const Sequence<com::sun::star::script::EventListener>& aListeners )
+{
+ sal_Int32 nCount = aListeners.getLength();
+ if (nCount != AllListeners.getLength())
+ // This is a prerequisite!
+ throw RuntimeException();
+
+ if (!xObject.is())
+ throw IllegalArgumentException();
+
+ Reference< XInvocationAdapterFactory > xInvocationAdapterFactory = getInvocationAdapterService();
+ if( !xInvocationAdapterFactory.is() )
+ throw ServiceNotRegisteredException();
+
+ Reference< XIdlReflection > xReflection = getReflection();
+ if( !xReflection.is() )
+ throw ServiceNotRegisteredException();
+
+ // Sign in, Call the fitting addListener method
+ // First Introspection, as the Methods can be analyzed in the same way
+ // For better perfomance it is implemented here again or make the Impl-Method
+ // of the Introspection configurable for this purpose.
+ Reference< XIntrospection > xIntrospection = getIntrospection();
+ if( !xIntrospection.is() )
+ return Sequence< Reference<XEventListener> >();
+
+ // Inspect Introspection
+ Any aObjAny( &xObject, ::getCppuType(static_cast<const Reference<XInterface>*>(0)) );
+
+ Reference<XIntrospectionAccess> xAccess = xIntrospection->inspect(aObjAny);
+ if (!xAccess.is())
+ return Sequence< Reference<XEventListener> >();
+
+ Sequence< Reference<XEventListener> > aRet(nCount);
+
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ Reference<XEventListener> xRet = NULL;
+
+ const Reference<XAllListener>& AllListener = aListeners[i].AllListener;
+ const Any& Helper = aListeners[i].Helper;
+ const OUString& ListenerType = aListeners[i].ListenerType;
+ const OUString& AddListenerParam = aListeners[i].AddListenerParam;
+
+ // Construct the name of the addListener-Method.
+ OUString aAddListenerName;
+ OUString aListenerName( ListenerType );
+ sal_Int32 nIndex = aListenerName.lastIndexOf( '.' );
+ // set index to the interface name without package name
+ if( nIndex == -1 )
+ // not found
+ nIndex = 0;
+ else
+ nIndex++;
+ if( aListenerName[nIndex] == 'X' )
+ // erase X from the interface name
+ aListenerName = aListenerName.copy( nIndex +1 );
+ aAddListenerName = OUString( RTL_CONSTASCII_USTRINGPARAM( "add" ) ) + aListenerName;
+
+ // Send Methods to the correct addListener-Method
+ Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( MethodConcept::LISTENER );
+ sal_uInt32 j, nLen = aMethodSeq.getLength();
+ const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray();
+
+ for( j = 0 ; j < nLen ; j++ )
+ {
+ const Reference< XIdlMethod >& rxMethod = pMethods[j];
+
+ // Is it the correct method?
+ OUString aMethName = rxMethod->getName();
+
+ if( aAddListenerName == aMethName )
+ {
+ Sequence< Reference< XIdlClass > > params = rxMethod->getParameterTypes();
+ sal_uInt32 nParamCount = params.getLength();
+
+ Reference< XIdlClass > xListenerType;
+ if( nParamCount == 1 )
+ xListenerType = params.getConstArray()[0];
+ else if( nParamCount == 2 )
+ xListenerType = params.getConstArray()[1];
+
+ // Request Adapter for the actual Listener type
+ Reference< XInterface > xAdapter = createAllListenerAdapter
+ ( xInvocationAdapterFactory, xListenerType, AllListener, Helper );
+
+ if( !xAdapter.is() )
+ throw CannotCreateAdapterException();
+ xRet = Reference< XEventListener >( xAdapter, UNO_QUERY );
+
+
+ // Just the Listener as parameter?
+ if( nParamCount == 1 )
+ {
+ Sequence< Any > args( 1 );
+ args.getArray()[0] <<= xAdapter;
+ try
+ {
+ rxMethod->invoke( aObjAny, args );
+ }
+ catch( InvocationTargetException& )
+ {
+ throw IntrospectionException();
+ }
+ }
+ // Else, pass the other parameter now
+ else if( nParamCount == 2 )
+ {
+ Sequence< Any > args( 2 );
+ Any* pAnys = args.getArray();
+
+ // Check the type of the 1st parameter
+ Reference< XIdlClass > xParamClass = params.getConstArray()[0];
+ if( xParamClass->getTypeClass() == TypeClass_STRING )
+ {
+ pAnys[0] <<= AddListenerParam;
+ }
+
+ // 2nd Parameter == Listener? TODO: Test!
+ pAnys[1] <<= xAdapter;
+
+ // TODO: Convert String -> ?
+ // else
+ try
+ {
+ rxMethod->invoke( aObjAny, args );
+ }
+ catch( InvocationTargetException& )
+ {
+ throw IntrospectionException();
+ }
+ }
+ break;
+ // else...
+ // Anything else is not supported
+ }
+ }
+ aRet[nCount] = xRet;
+ }
+
+ return aRet;
+}
+
// XEventAttacher
Reference< XEventListener > EventAttacherImpl::attachSingleEventListener
(
@@ -817,6 +975,21 @@ void EventAttacherImpl::removeListener
}
}
+Sequence< Reference<XEventListener> > EventAttacherImpl::attachMultipleEventListeners(
+ const Reference<XInterface>& xObject, const Sequence<com::sun::star::script::EventListener>& aListeners )
+ throw( IllegalArgumentException, ServiceNotRegisteredException, CannotCreateAdapterException, IntrospectionException, RuntimeException )
+{
+ sal_Int32 nCount = aListeners.getLength();
+ Sequence< Reference<XAllListener> > aFilterListeners(nCount);
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ aFilterListeners[i] = (XAllListener*)
+ new FilterAllListenerImpl(this, aListeners[i].EventMethod, aListeners[i].AllListener);
+ }
+
+ return attachListeners(xObject, aFilterListeners, aListeners);
+}
+
}
extern "C"