1*dde7d3faSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*dde7d3faSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*dde7d3faSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*dde7d3faSAndrew Rist  * distributed with this work for additional information
6*dde7d3faSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*dde7d3faSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*dde7d3faSAndrew Rist  * "License"); you may not use this file except in compliance
9*dde7d3faSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*dde7d3faSAndrew Rist  *
11*dde7d3faSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*dde7d3faSAndrew Rist  *
13*dde7d3faSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*dde7d3faSAndrew Rist  * software distributed under the License is distributed on an
15*dde7d3faSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*dde7d3faSAndrew Rist  * KIND, either express or implied.  See the License for the
17*dde7d3faSAndrew Rist  * specific language governing permissions and limitations
18*dde7d3faSAndrew Rist  * under the License.
19*dde7d3faSAndrew Rist  *
20*dde7d3faSAndrew Rist  *************************************************************/
21*dde7d3faSAndrew Rist 
22*dde7d3faSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_comphelper.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <deque>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #if defined( OS2 ) || defined( UNX )
30cdf0e10cSrcweir #include <wchar.h>
31cdf0e10cSrcweir #endif
32cdf0e10cSrcweir #include <osl/mutex.hxx>
33cdf0e10cSrcweir #ifndef _VOS_DIAGNOSE_HXX_
34cdf0e10cSrcweir #include <vos/diagnose.hxx>
35cdf0e10cSrcweir #endif
36cdf0e10cSrcweir #include <vos/macros.hxx>
37cdf0e10cSrcweir #include <comphelper/eventattachermgr.hxx>
38cdf0e10cSrcweir #include <com/sun/star/beans/XIntrospection.hpp>
39cdf0e10cSrcweir #include <com/sun/star/io/XObjectInputStream.hpp>
40cdf0e10cSrcweir #include <com/sun/star/io/XPersistObject.hpp>
41cdf0e10cSrcweir #include <com/sun/star/io/XObjectOutputStream.hpp>
42cdf0e10cSrcweir #include <com/sun/star/io/XMarkableStream.hpp>
43cdf0e10cSrcweir #include <com/sun/star/lang/XInitialization.hpp>
44cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
45cdf0e10cSrcweir #include <com/sun/star/reflection/XIdlClass.hpp>
46cdf0e10cSrcweir #include <com/sun/star/reflection/XIdlReflection.hpp>
47cdf0e10cSrcweir #include <com/sun/star/reflection/XIdlMethod.hpp>
48cdf0e10cSrcweir #include <com/sun/star/script/XTypeConverter.hpp>
49cdf0e10cSrcweir #include <com/sun/star/script/XEngineListener.hpp>
50cdf0e10cSrcweir #include <com/sun/star/script/XEventAttacher.hpp>
51cdf0e10cSrcweir #include <com/sun/star/script/XEventAttacherManager.hpp>
52cdf0e10cSrcweir #include <com/sun/star/script/XScriptListener.hpp>
53cdf0e10cSrcweir #include <cppuhelper/weak.hxx>
54cdf0e10cSrcweir #include <cppuhelper/interfacecontainer.hxx>
55cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
56cdf0e10cSrcweir #include <cppuhelper/implbase2.hxx>
57cdf0e10cSrcweir 
58cdf0e10cSrcweir using namespace com::sun::star::uno;
59cdf0e10cSrcweir using namespace com::sun::star::io;
60cdf0e10cSrcweir using namespace com::sun::star::lang;
61cdf0e10cSrcweir using namespace com::sun::star::beans;
62cdf0e10cSrcweir using namespace com::sun::star::script;
63cdf0e10cSrcweir using namespace com::sun::star::reflection;
64cdf0e10cSrcweir using namespace cppu;
65cdf0e10cSrcweir using namespace osl;
66cdf0e10cSrcweir using namespace rtl;
67cdf0e10cSrcweir 
68cdf0e10cSrcweir namespace comphelper
69cdf0e10cSrcweir {
70cdf0e10cSrcweir 
71cdf0e10cSrcweir //-----------------------------------------------------------------------------
72cdf0e10cSrcweir struct AttachedObject_Impl
73cdf0e10cSrcweir {
74cdf0e10cSrcweir     Reference< XInterface >					xTarget;
75cdf0e10cSrcweir     Sequence< Reference< XEventListener > > aAttachedListenerSeq;
76cdf0e10cSrcweir     Any             	         			aHelper;
77cdf0e10cSrcweir 
78cdf0e10cSrcweir     bool    operator<( const AttachedObject_Impl & ) const;
79cdf0e10cSrcweir     bool    operator==( const AttachedObject_Impl & ) const;
80cdf0e10cSrcweir };
81cdf0e10cSrcweir 
82cdf0e10cSrcweir struct AttacherIndex_Impl
83cdf0e10cSrcweir {
84cdf0e10cSrcweir #ifdef DEQUE_OK
85cdf0e10cSrcweir     ::std::deque< ScriptEventDescriptor > aEventList;
86cdf0e10cSrcweir #else
87cdf0e10cSrcweir     Sequence< ScriptEventDescriptor >   aEventList;
88cdf0e10cSrcweir #endif
89cdf0e10cSrcweir     ::std::deque< AttachedObject_Impl > aObjList;
90cdf0e10cSrcweir 
91cdf0e10cSrcweir     bool    operator<( const AttacherIndex_Impl & ) const;
92cdf0e10cSrcweir     bool    operator==( const AttacherIndex_Impl & ) const;
93cdf0e10cSrcweir };
94cdf0e10cSrcweir 
95cdf0e10cSrcweir #if 0
96cdf0e10cSrcweir bool AttachedObject_Impl::operator<( const AttachedObject_Impl & r ) const
97cdf0e10cSrcweir {
98cdf0e10cSrcweir     VOS_ENSHURE( FALSE, "not implemented" );
99cdf0e10cSrcweir     return FALSE;
100cdf0e10cSrcweir     return this < &r;
101cdf0e10cSrcweir }
102cdf0e10cSrcweir 
103cdf0e10cSrcweir bool AttachedObject_Impl::operator==( const AttachedObject_Impl & r ) const
104cdf0e10cSrcweir {
105cdf0e10cSrcweir     VOS_ENSHURE( FALSE, "not implemented" );
106cdf0e10cSrcweir     return this == &r;
107cdf0e10cSrcweir }
108cdf0e10cSrcweir 
109cdf0e10cSrcweir bool AttacherIndex_Impl::operator<( const AttacherIndex_Impl & r ) const
110cdf0e10cSrcweir {
111cdf0e10cSrcweir     VOS_ENSHURE( FALSE, "not implemented" );
112cdf0e10cSrcweir     return this < &r;
113cdf0e10cSrcweir }
114cdf0e10cSrcweir bool AttacherIndex_Impl::operator==( const AttacherIndex_Impl & r ) const
115cdf0e10cSrcweir {
116cdf0e10cSrcweir     VOS_ENSHURE( FALSE, "not implemented" );
117cdf0e10cSrcweir     return this == &r;
118cdf0e10cSrcweir }
119cdf0e10cSrcweir #endif
120cdf0e10cSrcweir 
121cdf0e10cSrcweir //-----------------------------------------------------------------------------
122cdf0e10cSrcweir class ImplEventAttacherManager
123cdf0e10cSrcweir     : public WeakImplHelper2< XEventAttacherManager, XPersistObject >
124cdf0e10cSrcweir {
125cdf0e10cSrcweir     friend class AttacherAllListener_Impl;
126cdf0e10cSrcweir     ::std::deque< AttacherIndex_Impl >  aIndex;
127cdf0e10cSrcweir     Mutex aLock;
128cdf0e10cSrcweir     // Container fuer die ScriptListener
129cdf0e10cSrcweir     OInterfaceContainerHelper   		aScriptListeners;
130cdf0e10cSrcweir     // EventAttacher-Instanz
131cdf0e10cSrcweir     Reference< XEventAttacher >			xAttacher;
132cdf0e10cSrcweir 	Reference< XMultiServiceFactory > 	mxSMgr;
133cdf0e10cSrcweir 	Reference< XIdlReflection > 		mxCoreReflection;
134cdf0e10cSrcweir     Reference< XIntrospection > 		mxIntrospection;
135cdf0e10cSrcweir     Reference< XTypeConverter > 		xConverter;
136cdf0e10cSrcweir     sal_Int16							nVersion;
137cdf0e10cSrcweir public:
138cdf0e10cSrcweir     ImplEventAttacherManager( const Reference< XIntrospection > & rIntrospection,
139cdf0e10cSrcweir 							  const Reference< XMultiServiceFactory > rSMgr );
140cdf0e10cSrcweir     ~ImplEventAttacherManager();
141cdf0e10cSrcweir 
142cdf0e10cSrcweir     // Methoden von XEventAttacherManager
143cdf0e10cSrcweir     virtual void SAL_CALL registerScriptEvent(sal_Int32 Index, const ScriptEventDescriptor& ScriptEvent)
144cdf0e10cSrcweir         throw( IllegalArgumentException, RuntimeException );
145cdf0e10cSrcweir     virtual void SAL_CALL registerScriptEvents(sal_Int32 Index, const Sequence< ScriptEventDescriptor >& ScriptEvents)
146cdf0e10cSrcweir         throw( IllegalArgumentException, RuntimeException );
147cdf0e10cSrcweir     virtual void SAL_CALL revokeScriptEvent(sal_Int32 Index, const OUString& ListenerType, const OUString& EventMethod, const OUString& removeListenerParam)
148cdf0e10cSrcweir         throw( IllegalArgumentException, RuntimeException );
149cdf0e10cSrcweir     virtual void SAL_CALL revokeScriptEvents(sal_Int32 Index)
150cdf0e10cSrcweir         throw( IllegalArgumentException, RuntimeException );
151cdf0e10cSrcweir     virtual void SAL_CALL insertEntry(sal_Int32 Index)
152cdf0e10cSrcweir         throw( IllegalArgumentException, RuntimeException );
153cdf0e10cSrcweir     virtual void SAL_CALL removeEntry(sal_Int32 Index)
154cdf0e10cSrcweir         throw( IllegalArgumentException, RuntimeException );
155cdf0e10cSrcweir     virtual Sequence< ScriptEventDescriptor > SAL_CALL getScriptEvents(sal_Int32 Index)
156cdf0e10cSrcweir         throw( IllegalArgumentException, RuntimeException );
157cdf0e10cSrcweir     virtual void SAL_CALL attach(sal_Int32 Index, const Reference< XInterface >& Object, const Any& Helper)
158cdf0e10cSrcweir         throw( IllegalArgumentException, ServiceNotRegisteredException, RuntimeException );
159cdf0e10cSrcweir     virtual void SAL_CALL detach(sal_Int32 nIndex, const Reference< XInterface >& xObject)
160cdf0e10cSrcweir         throw( IllegalArgumentException, RuntimeException );
161cdf0e10cSrcweir     virtual void SAL_CALL addScriptListener(const Reference< XScriptListener >& aListener)
162cdf0e10cSrcweir         throw( IllegalArgumentException, RuntimeException );
163cdf0e10cSrcweir     virtual void SAL_CALL removeScriptListener(const Reference< XScriptListener >& Listener)
164cdf0e10cSrcweir         throw( IllegalArgumentException, RuntimeException );
165cdf0e10cSrcweir 
166cdf0e10cSrcweir     // Methoden von XPersistObject
167cdf0e10cSrcweir     virtual OUString SAL_CALL getServiceName(void) throw( RuntimeException );
168cdf0e10cSrcweir     virtual void SAL_CALL write(const Reference< XObjectOutputStream >& OutStream) throw( IOException, RuntimeException );
169cdf0e10cSrcweir     virtual void SAL_CALL read(const Reference< XObjectInputStream >& InStream) throw( IOException, RuntimeException );
170cdf0e10cSrcweir 
171cdf0e10cSrcweir private:
172cdf0e10cSrcweir 	Reference< XIdlReflection >	getReflection() throw( Exception );
173cdf0e10cSrcweir 
174cdf0e10cSrcweir 	/** checks if <arg>_nIndex</arg> is a valid index, throws an <type>IllegalArgumentException</type> if not
175cdf0e10cSrcweir 	@param _nIndex
176cdf0e10cSrcweir 		the index to check
177cdf0e10cSrcweir 	@return
178cdf0e10cSrcweir 		the iterator pointing to the position indicated by the index
179cdf0e10cSrcweir 	*/
180cdf0e10cSrcweir 	::std::deque<AttacherIndex_Impl>::iterator implCheckIndex( sal_Int32 _nIndex ) SAL_THROW ( ( IllegalArgumentException ) );
181cdf0e10cSrcweir };
182cdf0e10cSrcweir 
183cdf0e10cSrcweir //========================================================================
184cdf0e10cSrcweir //========================================================================
185cdf0e10cSrcweir //========================================================================
186cdf0e10cSrcweir 
187cdf0e10cSrcweir // Implementation eines EventAttacher-bezogenen AllListeners, der
188cdf0e10cSrcweir // nur einzelne Events an einen allgemeinen AllListener weiterleitet
189cdf0e10cSrcweir class AttacherAllListener_Impl : public WeakImplHelper1< XAllListener >
190cdf0e10cSrcweir {
191cdf0e10cSrcweir     ImplEventAttacherManager*   		mpManager;
192cdf0e10cSrcweir     Reference< XEventAttacherManager >  xManager;
193cdf0e10cSrcweir     OUString        		           	aScriptType;
194cdf0e10cSrcweir     OUString    	        	        aScriptCode;
195cdf0e10cSrcweir     sal_Int16	                	   	nVersion;
196cdf0e10cSrcweir 
197cdf0e10cSrcweir     void convertToEventReturn( Any & rRet, const Type & rRetType )
198cdf0e10cSrcweir         throw( CannotConvertException );
199cdf0e10cSrcweir public:
200cdf0e10cSrcweir     AttacherAllListener_Impl( ImplEventAttacherManager* pManager_, const OUString &rScriptType_,
201cdf0e10cSrcweir                                 const OUString & rScriptCode_ );
202cdf0e10cSrcweir 
203cdf0e10cSrcweir     // Methoden von XAllListener
204cdf0e10cSrcweir     virtual void SAL_CALL firing(const AllEventObject& Event) throw( RuntimeException );
205cdf0e10cSrcweir     virtual Any SAL_CALL approveFiring(const AllEventObject& Event) throw( InvocationTargetException, RuntimeException );
206cdf0e10cSrcweir 
207cdf0e10cSrcweir     // Methoden von XEventListener
208cdf0e10cSrcweir     virtual void SAL_CALL disposing(const EventObject& Source) throw( RuntimeException );
209cdf0e10cSrcweir };
210cdf0e10cSrcweir 
211cdf0e10cSrcweir //========================================================================
212cdf0e10cSrcweir AttacherAllListener_Impl::AttacherAllListener_Impl
213cdf0e10cSrcweir (
214cdf0e10cSrcweir     ImplEventAttacherManager*   pManager_,
215cdf0e10cSrcweir     const OUString &             rScriptType_,
216cdf0e10cSrcweir     const OUString &             rScriptCode_
217cdf0e10cSrcweir )
218cdf0e10cSrcweir     : mpManager( pManager_ )
219cdf0e10cSrcweir     , xManager( pManager_ )
220cdf0e10cSrcweir     , aScriptType( rScriptType_ )
221cdf0e10cSrcweir     , aScriptCode( rScriptCode_ )
222cdf0e10cSrcweir     , nVersion( 2 )
223cdf0e10cSrcweir {
224cdf0e10cSrcweir }
225cdf0e10cSrcweir 
226cdf0e10cSrcweir 
227cdf0e10cSrcweir //========================================================================
228cdf0e10cSrcweir // Methoden von XAllListener
229cdf0e10cSrcweir void SAL_CALL AttacherAllListener_Impl::firing(const AllEventObject& Event)
230cdf0e10cSrcweir     throw( RuntimeException )
231cdf0e10cSrcweir {
232cdf0e10cSrcweir     ScriptEvent aScriptEvent;
233cdf0e10cSrcweir     aScriptEvent.Source         = (OWeakObject *)mpManager; // get correct XInterface
234cdf0e10cSrcweir     aScriptEvent.ListenerType   = Event.ListenerType;
235cdf0e10cSrcweir     aScriptEvent.MethodName     = Event.MethodName;
236cdf0e10cSrcweir     aScriptEvent.Arguments      = Event.Arguments;
237cdf0e10cSrcweir     aScriptEvent.Helper         = Event.Helper;
238cdf0e10cSrcweir     aScriptEvent.ScriptType     = aScriptType;
239cdf0e10cSrcweir     aScriptEvent.ScriptCode     = aScriptCode;
240cdf0e10cSrcweir 
241cdf0e10cSrcweir     // ueber alle Listener iterieren und Events senden
242cdf0e10cSrcweir     OInterfaceIteratorHelper aIt( mpManager->aScriptListeners );
243cdf0e10cSrcweir     while( aIt.hasMoreElements() )
244cdf0e10cSrcweir         ((XScriptListener *)aIt.next())->firing( aScriptEvent );
245cdf0e10cSrcweir }
246cdf0e10cSrcweir 
247cdf0e10cSrcweir //========================================================================
248cdf0e10cSrcweir // Convert to the standard event return
249cdf0e10cSrcweir void AttacherAllListener_Impl::convertToEventReturn( Any & rRet, const Type & rRetType )
250cdf0e10cSrcweir     throw( CannotConvertException )
251cdf0e10cSrcweir {
252cdf0e10cSrcweir     // no return value? Set to the specified values
253cdf0e10cSrcweir     if( rRet.getValueType().getTypeClass() == TypeClass_VOID )
254cdf0e10cSrcweir     {
255cdf0e10cSrcweir         switch( rRetType.getTypeClass()  )
256cdf0e10cSrcweir         {
257cdf0e10cSrcweir             case TypeClass_INTERFACE:
258cdf0e10cSrcweir                 {
259cdf0e10cSrcweir                 rRet <<= Reference< XInterface >();
260cdf0e10cSrcweir                 }
261cdf0e10cSrcweir                 break;
262cdf0e10cSrcweir 
263cdf0e10cSrcweir             case TypeClass_BOOLEAN:
264cdf0e10cSrcweir                 rRet <<= sal_True;
265cdf0e10cSrcweir                 break;
266cdf0e10cSrcweir 
267cdf0e10cSrcweir             case TypeClass_STRING:
268cdf0e10cSrcweir                 rRet <<= OUString();
269cdf0e10cSrcweir                 break;
270cdf0e10cSrcweir 
271cdf0e10cSrcweir             case TypeClass_FLOAT:           rRet <<= float(0);  break;
272cdf0e10cSrcweir             case TypeClass_DOUBLE:          rRet <<= double(0.0);  break;
273cdf0e10cSrcweir             case TypeClass_BYTE:            rRet <<= sal_uInt8(0);      break;
274cdf0e10cSrcweir 			case TypeClass_SHORT:			rRet <<= sal_Int16( 0 );	break;
275cdf0e10cSrcweir 			case TypeClass_LONG:			rRet <<= sal_Int32( 0 );	break;
276cdf0e10cSrcweir 			case TypeClass_UNSIGNED_SHORT:	rRet <<= sal_uInt16( 0 );	break;
277cdf0e10cSrcweir 			case TypeClass_UNSIGNED_LONG:	rRet <<= sal_uInt32( 0 );	break;
278cdf0e10cSrcweir 
279cdf0e10cSrcweir             default:
280cdf0e10cSrcweir                 OSL_ASSERT(false);
281cdf0e10cSrcweir                 break;
282cdf0e10cSrcweir         }
283cdf0e10cSrcweir     }
284cdf0e10cSrcweir     else if( !rRet.getValueType().equals( rRetType ) )
285cdf0e10cSrcweir     {
286cdf0e10cSrcweir         if( mpManager->xConverter.is() )
287cdf0e10cSrcweir             rRet = mpManager->xConverter->convertTo( rRet, rRetType );
288cdf0e10cSrcweir         else
289cdf0e10cSrcweir             throw CannotConvertException();
290cdf0e10cSrcweir     }
291cdf0e10cSrcweir }
292cdf0e10cSrcweir 
293cdf0e10cSrcweir //========================================================================
294cdf0e10cSrcweir // Methoden von XAllListener
295cdf0e10cSrcweir Any SAL_CALL AttacherAllListener_Impl::approveFiring( const AllEventObject& Event )
296cdf0e10cSrcweir     throw( InvocationTargetException, RuntimeException )
297cdf0e10cSrcweir {
298cdf0e10cSrcweir     ScriptEvent aScriptEvent;
299cdf0e10cSrcweir     aScriptEvent.Source         = (OWeakObject *)mpManager; // get correct XInterface
300cdf0e10cSrcweir     aScriptEvent.ListenerType   = Event.ListenerType;
301cdf0e10cSrcweir     aScriptEvent.MethodName     = Event.MethodName;
302cdf0e10cSrcweir     aScriptEvent.Arguments      = Event.Arguments;
303cdf0e10cSrcweir     aScriptEvent.Helper         = Event.Helper;
304cdf0e10cSrcweir     aScriptEvent.ScriptType     = aScriptType;
305cdf0e10cSrcweir     aScriptEvent.ScriptCode     = aScriptCode;
306cdf0e10cSrcweir 
307cdf0e10cSrcweir     Any aRet;
308cdf0e10cSrcweir     // ueber alle Listener iterieren und Events senden
309cdf0e10cSrcweir     OInterfaceIteratorHelper aIt( mpManager->aScriptListeners );
310cdf0e10cSrcweir     while( aIt.hasMoreElements() )
311cdf0e10cSrcweir     {
312cdf0e10cSrcweir         aRet = ((XScriptListener *)aIt.next())->approveFiring( aScriptEvent );
313cdf0e10cSrcweir         try
314cdf0e10cSrcweir         {
315cdf0e10cSrcweir 			Reference< XIdlClass > xListenerType = mpManager->getReflection()->
316cdf0e10cSrcweir 						forName( Event.ListenerType.getTypeName() );
317cdf0e10cSrcweir             Reference< XIdlMethod > xMeth = xListenerType->getMethod( Event.MethodName );
318cdf0e10cSrcweir             if( xMeth.is() )
319cdf0e10cSrcweir             {
320cdf0e10cSrcweir                 Reference< XIdlClass > xRetType = xMeth->getReturnType();
321cdf0e10cSrcweir 				Type aRetType(xRetType->getTypeClass(), xRetType->getName());
322cdf0e10cSrcweir                 convertToEventReturn( aRet, aRetType );
323cdf0e10cSrcweir             }
324cdf0e10cSrcweir 
325cdf0e10cSrcweir             switch( aRet.getValueType().getTypeClass()  )
326cdf0e10cSrcweir             {
327cdf0e10cSrcweir                 case TypeClass_INTERFACE:
328cdf0e10cSrcweir                     {
329cdf0e10cSrcweir                     // Interface not null, return
330cdf0e10cSrcweir                     Reference< XInterface > x;
331cdf0e10cSrcweir 					aRet >>= x;
332cdf0e10cSrcweir                     if( x.is() )
333cdf0e10cSrcweir                         return aRet;
334cdf0e10cSrcweir                     }
335cdf0e10cSrcweir                     break;
336cdf0e10cSrcweir 
337cdf0e10cSrcweir                 case TypeClass_BOOLEAN:
338cdf0e10cSrcweir                     // FALSE -> Return
339cdf0e10cSrcweir                     if( !(*(sal_Bool*)aRet.getValue()) )
340cdf0e10cSrcweir                         return aRet;
341cdf0e10cSrcweir                     break;
342cdf0e10cSrcweir 
343cdf0e10cSrcweir                 case TypeClass_STRING:
344cdf0e10cSrcweir                     // none empty string -> return
345cdf0e10cSrcweir                     if( ((OUString*)aRet.getValue())->getLength() > 0 )
346cdf0e10cSrcweir                         return aRet;
347cdf0e10cSrcweir                     break;
348cdf0e10cSrcweir 
349cdf0e10cSrcweir                     // none zero number -> return
350cdf0e10cSrcweir                 case TypeClass_FLOAT:           if( *((float*)aRet.getValue()) ) 	return aRet; break;
351cdf0e10cSrcweir                 case TypeClass_DOUBLE:          if( *((double*)aRet.getValue()) )  	return aRet; break;
352cdf0e10cSrcweir                 case TypeClass_BYTE:            if( *((sal_uInt8*)aRet.getValue()) )	return aRet; break;
353cdf0e10cSrcweir                 case TypeClass_SHORT:           if( *((sal_Int16*)aRet.getValue()) )	return aRet; break;
354cdf0e10cSrcweir                 case TypeClass_LONG:            if( *((sal_Int32*)aRet.getValue()) )   	return aRet; break;
355cdf0e10cSrcweir                 case TypeClass_UNSIGNED_SHORT:  if( *((sal_uInt16*)aRet.getValue()) )  	return aRet; break;
356cdf0e10cSrcweir                 case TypeClass_UNSIGNED_LONG:   if( *((sal_uInt32*)aRet.getValue()) )  	return aRet; break;
357cdf0e10cSrcweir 
358cdf0e10cSrcweir                 default:
359cdf0e10cSrcweir                     OSL_ASSERT(false);
360cdf0e10cSrcweir                     break;
361cdf0e10cSrcweir             }
362cdf0e10cSrcweir         }
363cdf0e10cSrcweir         catch( CannotConvertException& )
364cdf0e10cSrcweir         {
365cdf0e10cSrcweir             // silent ignore conversions errors from a script call
366cdf0e10cSrcweir 			Reference< XIdlClass > xListenerType = mpManager->getReflection()->
367cdf0e10cSrcweir 						forName( Event.ListenerType.getTypeName() );
368cdf0e10cSrcweir             Reference< XIdlMethod > xMeth = xListenerType->getMethod( Event.MethodName );
369cdf0e10cSrcweir             if( xMeth.is() )
370cdf0e10cSrcweir             {
371cdf0e10cSrcweir                 Reference< XIdlClass > xRetType = xMeth->getReturnType();
372cdf0e10cSrcweir 				Type aRetType(xRetType->getTypeClass(), xRetType->getName());
373cdf0e10cSrcweir                 aRet.clear();
374cdf0e10cSrcweir                 convertToEventReturn( aRet, aRetType );
375cdf0e10cSrcweir             }
376cdf0e10cSrcweir         }
377cdf0e10cSrcweir     }
378cdf0e10cSrcweir     return aRet;
379cdf0e10cSrcweir }
380cdf0e10cSrcweir 
381cdf0e10cSrcweir //========================================================================
382cdf0e10cSrcweir // Methoden von XEventListener
383cdf0e10cSrcweir void SAL_CALL AttacherAllListener_Impl::disposing(const EventObject& )
384cdf0e10cSrcweir     throw( RuntimeException )
385cdf0e10cSrcweir {
386cdf0e10cSrcweir     // It is up to the container to release the object
387cdf0e10cSrcweir }
388cdf0e10cSrcweir 
389cdf0e10cSrcweir 
390cdf0e10cSrcweir //========================================================================
391cdf0e10cSrcweir //========================================================================
392cdf0e10cSrcweir //========================================================================
393cdf0e10cSrcweir 
394cdf0e10cSrcweir // Create-Methode fuer EventAttacherManager
395cdf0e10cSrcweir Reference< XEventAttacherManager > createEventAttacherManager( const Reference< XIntrospection > & rIntrospection,
396cdf0e10cSrcweir 															   const Reference< XMultiServiceFactory > & rSMgr )
397cdf0e10cSrcweir 	throw( Exception )
398cdf0e10cSrcweir {
399cdf0e10cSrcweir     return new ImplEventAttacherManager( rIntrospection, rSMgr );
400cdf0e10cSrcweir }
401cdf0e10cSrcweir 
402cdf0e10cSrcweir // Create-Methode fuer EventAttacherManager
403cdf0e10cSrcweir Reference< XEventAttacherManager > createEventAttacherManager( const Reference< XMultiServiceFactory > & rSMgr )
404cdf0e10cSrcweir 	throw( Exception )
405cdf0e10cSrcweir {
406cdf0e10cSrcweir 	if ( rSMgr.is() )
407cdf0e10cSrcweir 	{
408cdf0e10cSrcweir 		Reference< XInterface > xIFace( rSMgr->createInstance( OUString::createFromAscii("com.sun.star.beans.Introspection") ) );
409cdf0e10cSrcweir 		if ( xIFace.is() )
410cdf0e10cSrcweir 		{
411cdf0e10cSrcweir 		    Reference< XIntrospection > xIntrospection( xIFace, UNO_QUERY);
412cdf0e10cSrcweir 		    return new ImplEventAttacherManager( xIntrospection, rSMgr );
413cdf0e10cSrcweir 		}
414cdf0e10cSrcweir 	}
415cdf0e10cSrcweir 
416cdf0e10cSrcweir 	return Reference< XEventAttacherManager >();
417cdf0e10cSrcweir }
418cdf0e10cSrcweir 
419cdf0e10cSrcweir //-----------------------------------------------------------------------------
420cdf0e10cSrcweir ImplEventAttacherManager::ImplEventAttacherManager( const Reference< XIntrospection > & rIntrospection,
421cdf0e10cSrcweir 													const Reference< XMultiServiceFactory > rSMgr )
422cdf0e10cSrcweir     : aScriptListeners( aLock )
423cdf0e10cSrcweir 	, mxSMgr( rSMgr )
424cdf0e10cSrcweir     , mxIntrospection( rIntrospection )
425cdf0e10cSrcweir {
426cdf0e10cSrcweir 	if ( rSMgr.is() )
427cdf0e10cSrcweir 	{
428cdf0e10cSrcweir     	Reference< XInterface > xIFace( rSMgr->createInstance( OUString::createFromAscii("com.sun.star.script.EventAttacher") ) );
429cdf0e10cSrcweir 		if ( xIFace.is() )
430cdf0e10cSrcweir 		{
431cdf0e10cSrcweir 			xAttacher = Reference< XEventAttacher >::query( xIFace );
432cdf0e10cSrcweir 		}
433cdf0e10cSrcweir     	xIFace = rSMgr->createInstance( OUString::createFromAscii("com.sun.star.script.Converter") );
434cdf0e10cSrcweir 		if ( xIFace.is() )
435cdf0e10cSrcweir 		{
436cdf0e10cSrcweir 			xConverter = Reference< XTypeConverter >::query( xIFace );
437cdf0e10cSrcweir 		}
438cdf0e10cSrcweir 	}
439cdf0e10cSrcweir 
440cdf0e10cSrcweir     Reference< XInitialization > xInit( xAttacher, UNO_QUERY );
441cdf0e10cSrcweir     if( xInit.is() )
442cdf0e10cSrcweir     {
443cdf0e10cSrcweir         Sequence< Any > Arguments( 1 );
444cdf0e10cSrcweir         Arguments[0] <<= rIntrospection;
445cdf0e10cSrcweir         xInit->initialize( Arguments );
446cdf0e10cSrcweir     }
447cdf0e10cSrcweir }
448cdf0e10cSrcweir 
449cdf0e10cSrcweir //-----------------------------------------------------------------------------
450cdf0e10cSrcweir ImplEventAttacherManager::~ImplEventAttacherManager()
451cdf0e10cSrcweir {
452cdf0e10cSrcweir }
453cdf0e10cSrcweir 
454cdf0e10cSrcweir Reference< XIdlReflection > ImplEventAttacherManager::getReflection() throw( Exception )
455cdf0e10cSrcweir {
456cdf0e10cSrcweir 	Guard< Mutex > aGuard( aLock );
457cdf0e10cSrcweir 	// Haben wir den Service schon? Sonst anlegen
458cdf0e10cSrcweir 	if( !mxCoreReflection.is() )
459cdf0e10cSrcweir 	{
460cdf0e10cSrcweir 		Reference< XInterface > xIFace( mxSMgr->createInstance( OUString::createFromAscii("com.sun.star.reflection.CoreReflection") ) );
461cdf0e10cSrcweir 		mxCoreReflection = Reference< XIdlReflection >( xIFace, UNO_QUERY);
462cdf0e10cSrcweir 	}
463cdf0e10cSrcweir 	return mxCoreReflection;
464cdf0e10cSrcweir }
465cdf0e10cSrcweir 
466cdf0e10cSrcweir 
467cdf0e10cSrcweir //-----------------------------------------------------------------------------
468cdf0e10cSrcweir ::std::deque<AttacherIndex_Impl>::iterator ImplEventAttacherManager::implCheckIndex( sal_Int32 _nIndex ) SAL_THROW ( ( IllegalArgumentException ) )
469cdf0e10cSrcweir {
470cdf0e10cSrcweir 	if (_nIndex < 0)
471cdf0e10cSrcweir         throw IllegalArgumentException();
472cdf0e10cSrcweir 
473cdf0e10cSrcweir     ::std::deque<AttacherIndex_Impl>::iterator aIt = aIndex.begin();
474cdf0e10cSrcweir     for ( sal_Int32 i = 0; (i < _nIndex) && (aIt != aIndex.end()); ++i, ++aIt )
475cdf0e10cSrcweir 		;
476cdf0e10cSrcweir 
477cdf0e10cSrcweir     if( aIt == aIndex.end() )
478cdf0e10cSrcweir         throw IllegalArgumentException();
479cdf0e10cSrcweir 
480cdf0e10cSrcweir 	return aIt;
481cdf0e10cSrcweir }
482cdf0e10cSrcweir 
483cdf0e10cSrcweir //-----------------------------------------------------------------------------
484cdf0e10cSrcweir void detachAll_Impl
485cdf0e10cSrcweir (
486cdf0e10cSrcweir     ImplEventAttacherManager * pMgr,
487cdf0e10cSrcweir     sal_Int32 nIdx,
488cdf0e10cSrcweir     ::std::deque< AttachedObject_Impl > & rList
489cdf0e10cSrcweir )
490cdf0e10cSrcweir {
491cdf0e10cSrcweir     ::std::deque< AttachedObject_Impl >::iterator aObjIt =  rList.begin();
492cdf0e10cSrcweir     ::std::deque< AttachedObject_Impl >::iterator aObjEnd = rList.end();
493cdf0e10cSrcweir     while( aObjIt != aObjEnd )
494cdf0e10cSrcweir     {
495cdf0e10cSrcweir         pMgr->detach( nIdx, (*aObjIt).xTarget );
496cdf0e10cSrcweir         aObjIt++;
497cdf0e10cSrcweir     }
498cdf0e10cSrcweir }
499cdf0e10cSrcweir 
500cdf0e10cSrcweir //-----------------------------------------------------------------------------
501cdf0e10cSrcweir void attachAll_Impl
502cdf0e10cSrcweir (
503cdf0e10cSrcweir     ImplEventAttacherManager * pMgr,
504cdf0e10cSrcweir     sal_Int32 nIdx,
505cdf0e10cSrcweir     ::std::deque< AttachedObject_Impl > & rList
506cdf0e10cSrcweir )
507cdf0e10cSrcweir {
508cdf0e10cSrcweir     ::std::deque< AttachedObject_Impl >::iterator aObjIt =  rList.begin();
509cdf0e10cSrcweir     ::std::deque< AttachedObject_Impl >::iterator aObjEnd = rList.end();
510cdf0e10cSrcweir     while( aObjIt != aObjEnd )
511cdf0e10cSrcweir     {
512cdf0e10cSrcweir         pMgr->attach( nIdx, (*aObjIt).xTarget, (*aObjIt).aHelper );
513cdf0e10cSrcweir         aObjIt++;
514cdf0e10cSrcweir     }
515cdf0e10cSrcweir }
516cdf0e10cSrcweir 
517cdf0e10cSrcweir //-----------------------------------------------------------------------------
518cdf0e10cSrcweir //*** Methoden von XEventAttacherManager ***
519cdf0e10cSrcweir void SAL_CALL ImplEventAttacherManager::registerScriptEvent
520cdf0e10cSrcweir (
521cdf0e10cSrcweir     sal_Int32 nIndex,
522cdf0e10cSrcweir     const ScriptEventDescriptor& ScriptEvent
523cdf0e10cSrcweir )
524cdf0e10cSrcweir     throw( IllegalArgumentException, RuntimeException )
525cdf0e10cSrcweir {
526cdf0e10cSrcweir     Guard< Mutex > aGuard( aLock );
527cdf0e10cSrcweir 
528cdf0e10cSrcweir 	// Index pruefen und Array anpassen
529cdf0e10cSrcweir 	::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
530cdf0e10cSrcweir 
531cdf0e10cSrcweir     ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList;
532cdf0e10cSrcweir 
533cdf0e10cSrcweir     ScriptEventDescriptor aEvt = ScriptEvent;
534cdf0e10cSrcweir     const sal_Unicode* pLastDot = aEvt.ListenerType.getStr();
535cdf0e10cSrcweir     pLastDot += rtl_ustr_lastIndexOfChar( pLastDot, '.' );
536cdf0e10cSrcweir     if( pLastDot )
537cdf0e10cSrcweir         aEvt.ListenerType = pLastDot +1;
538cdf0e10cSrcweir #ifdef DEQUE_OK
539cdf0e10cSrcweir     (*aIt).aEventList.push_back( aEvt );
540cdf0e10cSrcweir #else
541cdf0e10cSrcweir     (*aIt).aEventList.realloc( (*aIt).aEventList.getLength() +1 );
542cdf0e10cSrcweir     (*aIt).aEventList.getArray()[(*aIt).aEventList.getLength() -1] = aEvt;
543cdf0e10cSrcweir #endif
544cdf0e10cSrcweir 
545cdf0e10cSrcweir     // register new new Event
546cdf0e10cSrcweir     ::std::deque< AttachedObject_Impl >::iterator aObjIt =  (*aIt).aObjList.begin();
547cdf0e10cSrcweir     ::std::deque< AttachedObject_Impl >::iterator aObjEnd = (*aIt).aObjList.end();
548cdf0e10cSrcweir     while( aObjIt != aObjEnd )
549cdf0e10cSrcweir     {
550cdf0e10cSrcweir         // resize
551cdf0e10cSrcweir         sal_Int32 nPos = (*aObjIt).aAttachedListenerSeq.getLength();
552cdf0e10cSrcweir         (*aObjIt).aAttachedListenerSeq.realloc( nPos + 1 );
553cdf0e10cSrcweir         Reference< XEventListener > * pArray = (*aObjIt).aAttachedListenerSeq.getArray();
554cdf0e10cSrcweir 
555cdf0e10cSrcweir         Reference< XAllListener > xAll =
556cdf0e10cSrcweir             new AttacherAllListener_Impl( this, ScriptEvent.ScriptType, ScriptEvent.ScriptCode );
557cdf0e10cSrcweir         try
558cdf0e10cSrcweir         {
559cdf0e10cSrcweir         pArray[nPos] = xAttacher->attachSingleEventListener( (*aObjIt).xTarget, xAll,
560cdf0e10cSrcweir                         (*aObjIt).aHelper, ScriptEvent.ListenerType,
561cdf0e10cSrcweir                         ScriptEvent.AddListenerParam, ScriptEvent.EventMethod );
562cdf0e10cSrcweir         }
563cdf0e10cSrcweir         catch( Exception& )
564cdf0e10cSrcweir         {
565cdf0e10cSrcweir         }
566cdf0e10cSrcweir 
567cdf0e10cSrcweir         aObjIt++;
568cdf0e10cSrcweir     }
569cdf0e10cSrcweir }
570cdf0e10cSrcweir 
571cdf0e10cSrcweir //-----------------------------------------------------------------------------
572cdf0e10cSrcweir void SAL_CALL ImplEventAttacherManager::registerScriptEvents
573cdf0e10cSrcweir (
574cdf0e10cSrcweir     sal_Int32 nIndex,
575cdf0e10cSrcweir     const Sequence< ScriptEventDescriptor >& ScriptEvents
576cdf0e10cSrcweir )
577cdf0e10cSrcweir     throw( IllegalArgumentException, RuntimeException )
578cdf0e10cSrcweir {
579cdf0e10cSrcweir     Guard< Mutex > aGuard( aLock );
580cdf0e10cSrcweir 
581cdf0e10cSrcweir     // Index pruefen und Array anpassen
582cdf0e10cSrcweir 	::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
583cdf0e10cSrcweir 
584cdf0e10cSrcweir     ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList;
585cdf0e10cSrcweir     detachAll_Impl( this, nIndex, aList );
586cdf0e10cSrcweir 
587cdf0e10cSrcweir     const ScriptEventDescriptor* pArray = ScriptEvents.getConstArray();
588cdf0e10cSrcweir     sal_Int32 nLen = ScriptEvents.getLength();
589cdf0e10cSrcweir     for( sal_Int32 i = 0 ; i < nLen ; i++ )
590cdf0e10cSrcweir         registerScriptEvent( nIndex, pArray[ i ] );
591cdf0e10cSrcweir 
592cdf0e10cSrcweir     attachAll_Impl( this, nIndex, aList );
593cdf0e10cSrcweir }
594cdf0e10cSrcweir 
595cdf0e10cSrcweir //-----------------------------------------------------------------------------
596cdf0e10cSrcweir void SAL_CALL ImplEventAttacherManager::revokeScriptEvent
597cdf0e10cSrcweir (
598cdf0e10cSrcweir     sal_Int32 nIndex,
599cdf0e10cSrcweir     const OUString& ListenerType,
600cdf0e10cSrcweir     const OUString& EventMethod,
601cdf0e10cSrcweir     const OUString& ToRemoveListenerParam
602cdf0e10cSrcweir )
603cdf0e10cSrcweir     throw( IllegalArgumentException, RuntimeException )
604cdf0e10cSrcweir {
605cdf0e10cSrcweir     Guard< Mutex > aGuard( aLock );
606cdf0e10cSrcweir 
607cdf0e10cSrcweir 	::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
608cdf0e10cSrcweir 
609cdf0e10cSrcweir     ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList;
610cdf0e10cSrcweir     detachAll_Impl( this, nIndex, aList );
611cdf0e10cSrcweir 
612cdf0e10cSrcweir     OUString aLstType = ListenerType;
613cdf0e10cSrcweir     const sal_Unicode * pLastDot = aLstType.getStr();
614cdf0e10cSrcweir     pLastDot += rtl_ustr_lastIndexOfChar( pLastDot, '.' );
615cdf0e10cSrcweir     if( pLastDot )
616cdf0e10cSrcweir         aLstType = pLastDot +1;
617cdf0e10cSrcweir 
618cdf0e10cSrcweir #ifdef DEQUE_OK
619cdf0e10cSrcweir     ::std::deque< ScriptEventDescriptor >::iterator aEvtIt =    (*aIt).aEventList.begin();
620cdf0e10cSrcweir     ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd =   (*aIt).aEventList.end();
621cdf0e10cSrcweir     while( aEvtIt != aEvtEnd )
622cdf0e10cSrcweir     {
623cdf0e10cSrcweir         if( aLstType            == (*aEvtIt).ListenerType
624cdf0e10cSrcweir           && EventMethod            == (*aEvtIt).EventMethod
625cdf0e10cSrcweir           && ToRemoveListenerParam  == (*aEvtIt).AddListenerParam )
626cdf0e10cSrcweir         {
627cdf0e10cSrcweir             (*aIt).aEventList.erase( aEvtIt );
628cdf0e10cSrcweir             break;
629cdf0e10cSrcweir         }
630cdf0e10cSrcweir 
631cdf0e10cSrcweir         aEvtIt++;
632cdf0e10cSrcweir     }
633cdf0e10cSrcweir #else
634cdf0e10cSrcweir 	Sequence< ScriptEventDescriptor >& rEventList = (*aIt).aEventList;
635cdf0e10cSrcweir 
636cdf0e10cSrcweir 			ScriptEventDescriptor* pEventList = rEventList.getArray();
637cdf0e10cSrcweir 	const	ScriptEventDescriptor* pEventListEnd = pEventList + rEventList.getLength();
638cdf0e10cSrcweir     for( ; pEventList < pEventListEnd; ++pEventList )
639cdf0e10cSrcweir     {
640cdf0e10cSrcweir         if	(	(aLstType				== pEventList->ListenerType	)
641cdf0e10cSrcweir 			&&	(EventMethod            == pEventList->EventMethod		)
642cdf0e10cSrcweir 			&&	(ToRemoveListenerParam  == pEventList->AddListenerParam)
643cdf0e10cSrcweir 			)
644cdf0e10cSrcweir         {
645cdf0e10cSrcweir 			ScriptEventDescriptor* pMoveTo = pEventList;
646cdf0e10cSrcweir 			const ScriptEventDescriptor* pMoveFrom = pMoveTo + 1;
647cdf0e10cSrcweir 			while (pMoveFrom < pEventListEnd)
648cdf0e10cSrcweir 			{
649cdf0e10cSrcweir 				*pMoveTo++ = *pMoveFrom++;
650cdf0e10cSrcweir 			}
651cdf0e10cSrcweir 			rEventList.realloc( rEventList.getLength() - 1 );
652cdf0e10cSrcweir             break;
653cdf0e10cSrcweir         }
654cdf0e10cSrcweir     }
655cdf0e10cSrcweir #endif
656cdf0e10cSrcweir     attachAll_Impl( this, nIndex, aList );
657cdf0e10cSrcweir }
658cdf0e10cSrcweir 
659cdf0e10cSrcweir //-----------------------------------------------------------------------------
660cdf0e10cSrcweir void SAL_CALL ImplEventAttacherManager::revokeScriptEvents(sal_Int32 nIndex )
661cdf0e10cSrcweir     throw( IllegalArgumentException, RuntimeException )
662cdf0e10cSrcweir {
663cdf0e10cSrcweir     Guard< Mutex > aGuard( aLock );
664cdf0e10cSrcweir 	::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
665cdf0e10cSrcweir 
666cdf0e10cSrcweir     ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList;
667cdf0e10cSrcweir     detachAll_Impl( this, nIndex, aList );
668cdf0e10cSrcweir #ifdef DEQUE_OK
669cdf0e10cSrcweir     (*aIt).aEventList = ::std::deque< ScriptEventDescriptor >();
670cdf0e10cSrcweir #else
671cdf0e10cSrcweir     (*aIt).aEventList.realloc( 0 );
672cdf0e10cSrcweir #endif
673cdf0e10cSrcweir     attachAll_Impl( this, nIndex, aList );
674cdf0e10cSrcweir }
675cdf0e10cSrcweir 
676cdf0e10cSrcweir //-----------------------------------------------------------------------------
677cdf0e10cSrcweir void SAL_CALL ImplEventAttacherManager::insertEntry(sal_Int32 nIndex)
678cdf0e10cSrcweir     throw( IllegalArgumentException, RuntimeException )
679cdf0e10cSrcweir {
680cdf0e10cSrcweir     Guard< Mutex > aGuard( aLock );
681cdf0e10cSrcweir     if( nIndex < 0 )
682cdf0e10cSrcweir         throw IllegalArgumentException();
683cdf0e10cSrcweir 
684cdf0e10cSrcweir //    ::std::deque<AttacherIndex_Impl>::iterator aIt = aIndex.begin();
685cdf0e10cSrcweir //    while( nIndex-- )
686cdf0e10cSrcweir //        aIt++;
687cdf0e10cSrcweir 
688cdf0e10cSrcweir 	if ( static_cast< ::std::deque< AttacherIndex_Impl >::size_type>(nIndex) >= aIndex.size() )
689cdf0e10cSrcweir 		aIndex.resize(nIndex+1);
690cdf0e10cSrcweir 
691cdf0e10cSrcweir     AttacherIndex_Impl aTmp;
692cdf0e10cSrcweir     aIndex.insert( aIndex.begin() + nIndex, aTmp );
693cdf0e10cSrcweir }
694cdf0e10cSrcweir 
695cdf0e10cSrcweir //-----------------------------------------------------------------------------
696cdf0e10cSrcweir void SAL_CALL ImplEventAttacherManager::removeEntry(sal_Int32 nIndex)
697cdf0e10cSrcweir     throw( IllegalArgumentException, RuntimeException )
698cdf0e10cSrcweir {
699cdf0e10cSrcweir     Guard< Mutex > aGuard( aLock );
700cdf0e10cSrcweir 	::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
701cdf0e10cSrcweir 
702cdf0e10cSrcweir     ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList;
703cdf0e10cSrcweir     detachAll_Impl( this, nIndex, aList );
704cdf0e10cSrcweir     aIndex.erase( aIt );
705cdf0e10cSrcweir }
706cdf0e10cSrcweir 
707cdf0e10cSrcweir //-----------------------------------------------------------------------------
708cdf0e10cSrcweir Sequence< ScriptEventDescriptor > SAL_CALL ImplEventAttacherManager::getScriptEvents(sal_Int32 nIndex)
709cdf0e10cSrcweir     throw( IllegalArgumentException, RuntimeException )
710cdf0e10cSrcweir {
711cdf0e10cSrcweir     Guard< Mutex > aGuard( aLock );
712cdf0e10cSrcweir 	::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
713cdf0e10cSrcweir 
714cdf0e10cSrcweir #ifdef DEQUE_OK
715cdf0e10cSrcweir     Sequence< ScriptEventDescriptor > aSeq( (*aIt).aEventList.size() );
716cdf0e10cSrcweir     ScriptEventDescriptor * pArray = aSeq.getArray();
717cdf0e10cSrcweir 
718cdf0e10cSrcweir     ::std::deque< ScriptEventDescriptor >::iterator aEvtIt =    (*aIt).aEventList.begin();
719cdf0e10cSrcweir     ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd =   (*aIt).aEventList.end();
720cdf0e10cSrcweir     sal_Int32 i = 0;
721cdf0e10cSrcweir     while( aEvtIt != aEvtEnd )
722cdf0e10cSrcweir     {
723cdf0e10cSrcweir         pArray[i++] = *aEvtIt;
724cdf0e10cSrcweir         aEvtIt++;
725cdf0e10cSrcweir     }
726cdf0e10cSrcweir     return aSeq;
727cdf0e10cSrcweir #else
728cdf0e10cSrcweir     return (*aIt).aEventList;
729cdf0e10cSrcweir #endif
730cdf0e10cSrcweir }
731cdf0e10cSrcweir 
732cdf0e10cSrcweir //-----------------------------------------------------------------------------
733cdf0e10cSrcweir void SAL_CALL ImplEventAttacherManager::attach(sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any & Helper)
734cdf0e10cSrcweir     throw( IllegalArgumentException, ServiceNotRegisteredException, RuntimeException )
735cdf0e10cSrcweir {
736cdf0e10cSrcweir     Guard< Mutex > aGuard( aLock );
737cdf0e10cSrcweir     if( nIndex < 0 || !xObject.is() )
738cdf0e10cSrcweir         throw IllegalArgumentException();
739cdf0e10cSrcweir 
740cdf0e10cSrcweir     if( static_cast< ::std::deque< AttacherIndex_Impl >::size_type>(nIndex) >= aIndex.size() )
741cdf0e10cSrcweir     {
742cdf0e10cSrcweir         // alte Dateien lesen
743cdf0e10cSrcweir         if( nVersion == 1 )
744cdf0e10cSrcweir         {
745cdf0e10cSrcweir             insertEntry( nIndex );
746cdf0e10cSrcweir             attach( nIndex, xObject, Helper );
747cdf0e10cSrcweir             return;
748cdf0e10cSrcweir         }
749cdf0e10cSrcweir         else
750cdf0e10cSrcweir             throw IllegalArgumentException();
751cdf0e10cSrcweir     }
752cdf0e10cSrcweir 
753cdf0e10cSrcweir 	::std::deque< AttacherIndex_Impl >::iterator aCurrentPosition = aIndex.begin() + nIndex;
754cdf0e10cSrcweir 
755cdf0e10cSrcweir 	AttachedObject_Impl aTmp;
756cdf0e10cSrcweir     aTmp.xTarget = xObject;
757cdf0e10cSrcweir     aTmp.aHelper = Helper;
758cdf0e10cSrcweir     aCurrentPosition->aObjList.push_back( aTmp );
759cdf0e10cSrcweir 
760cdf0e10cSrcweir     //::std::deque< AttachedObject_Impl >::iterator aObjIt = (*aIt).aObjList.back();
761cdf0e10cSrcweir     AttachedObject_Impl & rCurObj = aCurrentPosition->aObjList.back();
762cdf0e10cSrcweir #ifdef DEQUE_OK
763cdf0e10cSrcweir     rCurObj.aAttachedListenerSeq = Sequence< Reference< XEventListener > >( aCurrentPosition->aEventList.size() );
764cdf0e10cSrcweir #else
765cdf0e10cSrcweir     rCurObj.aAttachedListenerSeq = Sequence< Reference< XEventListener > >( aCurrentPosition->aEventList.getLength() );
766cdf0e10cSrcweir #endif
767cdf0e10cSrcweir     Reference< XEventListener > * pArray = rCurObj.aAttachedListenerSeq.getArray();
768cdf0e10cSrcweir 
769cdf0e10cSrcweir #ifdef DEQUE_OK
770cdf0e10cSrcweir     ::std::deque< ScriptEventDescriptor >::iterator aEvtIt =    aCurrentPosition->aEventList.begin();
771cdf0e10cSrcweir     ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd =   aCurrentPosition->aEventList.end();
772cdf0e10cSrcweir     sal_Int32 i = 0;
773cdf0e10cSrcweir     while( aEvtIt != aEvtEnd )
774cdf0e10cSrcweir     {
775cdf0e10cSrcweir         Reference< XAllListener > xAll =
776cdf0e10cSrcweir             new AttacherAllListener_Impl( this, (*aEvtIt).ScriptType, (*aEvtIt).ScriptCode );
777cdf0e10cSrcweir         Reference< XEventListener > xAdapter;
778cdf0e10cSrcweir        	try
779cdf0e10cSrcweir         {
780cdf0e10cSrcweir         xAdapter = xAttacher->attachSingleEventListener( rCurObj.xTarget, xAll,
781cdf0e10cSrcweir                         rCurObj.aHelper, (*aEvtIt).ScriptType,
782cdf0e10cSrcweir                         (*aEvtIt).AddListenerParam, (*aEvtIt).EventMethod );
783cdf0e10cSrcweir         }
784cdf0e10cSrcweir         catch( Exception& )
785cdf0e10cSrcweir         {
786cdf0e10cSrcweir         }
787cdf0e10cSrcweir 
788cdf0e10cSrcweir         pArray[i++] = xAdapter;
789cdf0e10cSrcweir         aEvtIt++;
790cdf0e10cSrcweir     }
791cdf0e10cSrcweir #else
792cdf0e10cSrcweir     sal_Int32 nLen = aCurrentPosition->aEventList.getLength();
793cdf0e10cSrcweir     ScriptEventDescriptor * pEL = aCurrentPosition->aEventList.getArray();
794cdf0e10cSrcweir     for(sal_Int32 i = 0; i < nLen; ++i )
795cdf0e10cSrcweir     {
796cdf0e10cSrcweir         Reference< XAllListener > xAll =
797cdf0e10cSrcweir             new AttacherAllListener_Impl( this, pEL[i].ScriptType, pEL[i].ScriptCode );
798cdf0e10cSrcweir         Reference< XEventListener > xAdapter;
799cdf0e10cSrcweir         try
800cdf0e10cSrcweir         {
801cdf0e10cSrcweir         xAdapter = xAttacher->attachSingleEventListener( rCurObj.xTarget, xAll,
802cdf0e10cSrcweir                         rCurObj.aHelper, pEL[i].ListenerType,
803cdf0e10cSrcweir                         pEL[i].AddListenerParam, pEL[i].EventMethod );
804cdf0e10cSrcweir         }
805cdf0e10cSrcweir         catch( Exception& )
806cdf0e10cSrcweir         {
807cdf0e10cSrcweir         }
808cdf0e10cSrcweir 
809cdf0e10cSrcweir         pArray[i] = xAdapter;
810cdf0e10cSrcweir     }
811cdf0e10cSrcweir #endif
812cdf0e10cSrcweir }
813cdf0e10cSrcweir 
814cdf0e10cSrcweir //-----------------------------------------------------------------------------
815cdf0e10cSrcweir void SAL_CALL ImplEventAttacherManager::detach(sal_Int32 nIndex, const Reference< XInterface >& xObject)
816cdf0e10cSrcweir     throw( IllegalArgumentException, RuntimeException )
817cdf0e10cSrcweir {
818cdf0e10cSrcweir     Guard< Mutex > aGuard( aLock );
819cdf0e10cSrcweir     //return;
820cdf0e10cSrcweir     if( nIndex < 0 || static_cast< ::std::deque< AttacherIndex_Impl >::size_type>(nIndex) >= aIndex.size() || !xObject.is() )
821cdf0e10cSrcweir         throw IllegalArgumentException();
822cdf0e10cSrcweir 
823cdf0e10cSrcweir 	::std::deque< AttacherIndex_Impl >::iterator aCurrentPosition = aIndex.begin() + nIndex;
824cdf0e10cSrcweir     ::std::deque< AttachedObject_Impl >::iterator aObjIt =  aCurrentPosition->aObjList.begin();
825cdf0e10cSrcweir     ::std::deque< AttachedObject_Impl >::iterator aObjEnd = aCurrentPosition->aObjList.end();
826cdf0e10cSrcweir     while( aObjIt != aObjEnd )
827cdf0e10cSrcweir     {
828cdf0e10cSrcweir         if( (*aObjIt).xTarget == xObject )
829cdf0e10cSrcweir         {
830cdf0e10cSrcweir             Reference< XEventListener > * pArray = (*aObjIt).aAttachedListenerSeq.getArray();
831cdf0e10cSrcweir #ifdef DEQUE_OK
832cdf0e10cSrcweir 
833cdf0e10cSrcweir             ::std::deque< ScriptEventDescriptor >::iterator aEvtIt =    aCurrentPosition->aEventList.begin();
834cdf0e10cSrcweir             ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd =   aCurrentPosition->aEventList.end();
835cdf0e10cSrcweir             sal_Int32 i = 0;
836cdf0e10cSrcweir             while( aEvtIt != aEvtEnd )
837cdf0e10cSrcweir             {
838cdf0e10cSrcweir                 if( pArray[i].is() )
839cdf0e10cSrcweir                 {
840cdf0e10cSrcweir                     try
841cdf0e10cSrcweir                     {
842cdf0e10cSrcweir                     xAttacher->removeListener( (*aObjIt).xTarget, (*aEvtIt).ListenerType,
843cdf0e10cSrcweir                                                 (*aEvtIt).AddListenerParam, pArray[i] );
844cdf0e10cSrcweir                     }
845cdf0e10cSrcweir                     catch( Exception& )
846cdf0e10cSrcweir                     {
847cdf0e10cSrcweir                     }
848cdf0e10cSrcweir                 }
849cdf0e10cSrcweir                 i++;
850cdf0e10cSrcweir                 aEvtIt++;
851cdf0e10cSrcweir             }
852cdf0e10cSrcweir #else
853cdf0e10cSrcweir             sal_Int32 nLen = aCurrentPosition->aEventList.getLength();
854cdf0e10cSrcweir             ScriptEventDescriptor * pEL = aCurrentPosition->aEventList.getArray();
855cdf0e10cSrcweir             for( sal_Int32 i = 0; i < nLen; i++ )
856cdf0e10cSrcweir             {
857cdf0e10cSrcweir                 if( pArray[i].is() )
858cdf0e10cSrcweir                 {
859cdf0e10cSrcweir                     try
860cdf0e10cSrcweir                     {
861cdf0e10cSrcweir                     xAttacher->removeListener( (*aObjIt).xTarget, pEL[i].ListenerType,
862cdf0e10cSrcweir                                                 pEL[i].AddListenerParam, pArray[i] );
863cdf0e10cSrcweir                     }
864cdf0e10cSrcweir                     catch( Exception& )
865cdf0e10cSrcweir                     {
866cdf0e10cSrcweir                     }
867cdf0e10cSrcweir                 }
868cdf0e10cSrcweir             }
869cdf0e10cSrcweir #endif
870cdf0e10cSrcweir             aCurrentPosition->aObjList.erase( aObjIt );
871cdf0e10cSrcweir             break;
872cdf0e10cSrcweir         }
873cdf0e10cSrcweir         aObjIt++;
874cdf0e10cSrcweir     }
875cdf0e10cSrcweir }
876cdf0e10cSrcweir 
877cdf0e10cSrcweir void SAL_CALL ImplEventAttacherManager::addScriptListener(const Reference< XScriptListener >& aListener)
878cdf0e10cSrcweir     throw( IllegalArgumentException, RuntimeException )
879cdf0e10cSrcweir {
880cdf0e10cSrcweir     Guard< Mutex > aGuard( aLock );
881cdf0e10cSrcweir     aScriptListeners.addInterface( aListener );
882cdf0e10cSrcweir }
883cdf0e10cSrcweir 
884cdf0e10cSrcweir void SAL_CALL ImplEventAttacherManager::removeScriptListener(const Reference< XScriptListener >& aListener)
885cdf0e10cSrcweir     throw( IllegalArgumentException, RuntimeException )
886cdf0e10cSrcweir {
887cdf0e10cSrcweir     Guard< Mutex > aGuard( aLock );
888cdf0e10cSrcweir     aScriptListeners.removeInterface( aListener );
889cdf0e10cSrcweir }
890cdf0e10cSrcweir 
891cdf0e10cSrcweir 
892cdf0e10cSrcweir // Methoden von XPersistObject
893cdf0e10cSrcweir OUString SAL_CALL ImplEventAttacherManager::getServiceName(void)
894cdf0e10cSrcweir     throw( RuntimeException )
895cdf0e10cSrcweir {
896cdf0e10cSrcweir     return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.script.EventAttacherManager") );
897cdf0e10cSrcweir }
898cdf0e10cSrcweir 
899cdf0e10cSrcweir void SAL_CALL ImplEventAttacherManager::write(const Reference< XObjectOutputStream >& OutStream)
900cdf0e10cSrcweir     throw( IOException, RuntimeException )
901cdf0e10cSrcweir {
902cdf0e10cSrcweir     Guard< Mutex > aGuard( aLock );
903cdf0e10cSrcweir     // Ohne XMarkableStream laeuft nichts
904cdf0e10cSrcweir     Reference< XMarkableStream > xMarkStream( OutStream, UNO_QUERY );
905cdf0e10cSrcweir     if( !xMarkStream.is() )
906cdf0e10cSrcweir         return;
907cdf0e10cSrcweir 
908cdf0e10cSrcweir     // Version schreiben
909cdf0e10cSrcweir     OutStream->writeShort( 2 );
910cdf0e10cSrcweir 
911cdf0e10cSrcweir     // Position fuer Laenge merken
912cdf0e10cSrcweir     sal_Int32 nObjLenMark = xMarkStream->createMark();
913cdf0e10cSrcweir     OutStream->writeLong( 0L );
914cdf0e10cSrcweir 
915cdf0e10cSrcweir     OutStream->writeLong( aIndex.size() );
916cdf0e10cSrcweir 
917cdf0e10cSrcweir     // Sequences schreiben
918cdf0e10cSrcweir     ::std::deque<AttacherIndex_Impl>::iterator aIt = aIndex.begin();
919cdf0e10cSrcweir     ::std::deque<AttacherIndex_Impl>::iterator aEnd = aIndex.end();
920cdf0e10cSrcweir     while( aIt != aEnd )
921cdf0e10cSrcweir     {
922cdf0e10cSrcweir #ifdef DEQUE_OK
923cdf0e10cSrcweir         // Laenge der Sequence und alle Descriptoren schreiben
924cdf0e10cSrcweir         OutStream->writeLong( (*aIt).aEventList.size() );
925cdf0e10cSrcweir         ::std::deque< ScriptEventDescriptor >::iterator aEvtIt =    (*aIt).aEventList.begin();
926cdf0e10cSrcweir         ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd = (*aIt).aEventList.end();
927cdf0e10cSrcweir         while( aEvtIt != aEvtEnd )
928cdf0e10cSrcweir         {
929cdf0e10cSrcweir             const ScriptEventDescriptor& rDesc = (*aEvtIt);
930cdf0e10cSrcweir             OutStream->writeUTF( rDesc.ListenerType );
931cdf0e10cSrcweir             OutStream->writeUTF( rDesc.EventMethod );
932cdf0e10cSrcweir             OutStream->writeUTF( rDesc.AddListenerParam );
933cdf0e10cSrcweir             OutStream->writeUTF( rDesc.ScriptType );
934cdf0e10cSrcweir             OutStream->writeUTF( rDesc.ScriptCode );
935cdf0e10cSrcweir 
936cdf0e10cSrcweir             aEvtIt++;
937cdf0e10cSrcweir         }
938cdf0e10cSrcweir #else
939cdf0e10cSrcweir         sal_Int32 nLen = (*aIt).aEventList.getLength();
940cdf0e10cSrcweir         // Laenge der Sequence und alle Descriptoren schreiben
941cdf0e10cSrcweir         OutStream->writeLong( nLen );
942cdf0e10cSrcweir         ScriptEventDescriptor * pEL = (*aIt).aEventList.getArray();
943cdf0e10cSrcweir         for( sal_Int32 i = 0; i < nLen; i++ )
944cdf0e10cSrcweir         {
945cdf0e10cSrcweir             const ScriptEventDescriptor& rDesc = pEL[i];
946cdf0e10cSrcweir             OutStream->writeUTF( rDesc.ListenerType );
947cdf0e10cSrcweir             OutStream->writeUTF( rDesc.EventMethod );
948cdf0e10cSrcweir             OutStream->writeUTF( rDesc.AddListenerParam );
949cdf0e10cSrcweir             OutStream->writeUTF( rDesc.ScriptType );
950cdf0e10cSrcweir             OutStream->writeUTF( rDesc.ScriptCode );
951cdf0e10cSrcweir         }
952cdf0e10cSrcweir #endif
953cdf0e10cSrcweir         aIt++;
954cdf0e10cSrcweir     }
955cdf0e10cSrcweir 
956cdf0e10cSrcweir     // Die jetzt bekannte Laenge eintragen
957cdf0e10cSrcweir     sal_Int32 nObjLen = xMarkStream->offsetToMark( nObjLenMark ) -4;
958cdf0e10cSrcweir     xMarkStream->jumpToMark( nObjLenMark );
959cdf0e10cSrcweir     OutStream->writeLong( nObjLen );
960cdf0e10cSrcweir     xMarkStream->jumpToFurthest();
961cdf0e10cSrcweir     xMarkStream->deleteMark( nObjLenMark );
962cdf0e10cSrcweir }
963cdf0e10cSrcweir 
964cdf0e10cSrcweir void SAL_CALL ImplEventAttacherManager::read(const Reference< XObjectInputStream >& InStream)
965cdf0e10cSrcweir     throw( IOException, RuntimeException )
966cdf0e10cSrcweir {
967cdf0e10cSrcweir     Guard< Mutex > aGuard( aLock );
968cdf0e10cSrcweir     // Ohne XMarkableStream laeuft nichts
969cdf0e10cSrcweir     Reference< XMarkableStream > xMarkStream( InStream, UNO_QUERY );
970cdf0e10cSrcweir     if( !xMarkStream.is() )
971cdf0e10cSrcweir         return;
972cdf0e10cSrcweir 
973cdf0e10cSrcweir     // Version lesen
974cdf0e10cSrcweir     nVersion = InStream->readShort();
975cdf0e10cSrcweir 
976cdf0e10cSrcweir     // Zunaechst kommen die Daten gemaess Version 1,
977cdf0e10cSrcweir     // muss auch bei hoeheren Versionen beibehalten werden
978cdf0e10cSrcweir     sal_Int32 nLen = InStream->readLong();
979cdf0e10cSrcweir 
980cdf0e10cSrcweir     // Position fuer Vergleichszwecke
981cdf0e10cSrcweir     sal_Int32 nObjLenMark = xMarkStream->createMark();
982cdf0e10cSrcweir 
983cdf0e10cSrcweir     // Anzahl der zu lesenden Sequences
984cdf0e10cSrcweir     sal_Int32 nItemCount = InStream->readLong();
985cdf0e10cSrcweir 
986cdf0e10cSrcweir     for( sal_Int32 i = 0 ; i < nItemCount ; i++ )
987cdf0e10cSrcweir     {
988cdf0e10cSrcweir         insertEntry( i );
989cdf0e10cSrcweir         // Laenge der Sequence lesen
990cdf0e10cSrcweir         sal_Int32 nSeqLen = InStream->readLong();
991cdf0e10cSrcweir 
992cdf0e10cSrcweir         // Sequence anlegen und Descriptoren lesen
993cdf0e10cSrcweir         Sequence< ScriptEventDescriptor > aSEDSeq( nSeqLen );
994cdf0e10cSrcweir         ScriptEventDescriptor* pArray = aSEDSeq.getArray();
995cdf0e10cSrcweir         for( sal_Int32 j = 0 ; j < nSeqLen ; j++ )
996cdf0e10cSrcweir         {
997cdf0e10cSrcweir             ScriptEventDescriptor& rDesc = pArray[ j ];
998cdf0e10cSrcweir             rDesc.ListenerType = InStream->readUTF();
999cdf0e10cSrcweir             rDesc.EventMethod = InStream->readUTF();
1000cdf0e10cSrcweir             rDesc.AddListenerParam = InStream->readUTF();
1001cdf0e10cSrcweir             rDesc.ScriptType = InStream->readUTF();
1002cdf0e10cSrcweir             rDesc.ScriptCode = InStream->readUTF();
1003cdf0e10cSrcweir         }
1004cdf0e10cSrcweir         registerScriptEvents( i, aSEDSeq );
1005cdf0e10cSrcweir     }
1006cdf0e10cSrcweir 
1007cdf0e10cSrcweir     // Haben wir die angegebene Laenge gelesen?
1008cdf0e10cSrcweir     sal_Int32 nRealLen = xMarkStream->offsetToMark( nObjLenMark );
1009cdf0e10cSrcweir     if( nRealLen != nLen )
1010cdf0e10cSrcweir     {
1011cdf0e10cSrcweir         // Nur wenn die StreamVersion > 1 ist und noch Daten folgen, kann das
1012cdf0e10cSrcweir         // Ganze richtig sein. Sonst ist etwas voellig daneben gegangen.
1013cdf0e10cSrcweir         if( nRealLen > nLen || nVersion == 1 )
1014cdf0e10cSrcweir         {
1015cdf0e10cSrcweir             VOS_ENSHURE( sal_False, "ImplEventAttacherManager::read(): Fatal Error, wrong object length" );
1016cdf0e10cSrcweir         }
1017cdf0e10cSrcweir         else
1018cdf0e10cSrcweir         {
1019cdf0e10cSrcweir             // TODO: Pruefen, ob Zwischen-Speicherung der Daten sinnvoll sein koennte
1020cdf0e10cSrcweir 
1021cdf0e10cSrcweir             // Vorerst einfach nur Skippen
1022cdf0e10cSrcweir             sal_Int32 nSkipCount = nLen - nRealLen;
1023cdf0e10cSrcweir             InStream->skipBytes( nSkipCount );
1024cdf0e10cSrcweir         }
1025cdf0e10cSrcweir     }
1026cdf0e10cSrcweir     xMarkStream->jumpToFurthest();
1027cdf0e10cSrcweir     xMarkStream->deleteMark( nObjLenMark );
1028cdf0e10cSrcweir }
1029cdf0e10cSrcweir 
1030cdf0e10cSrcweir } // namesapce comphelper
1031cdf0e10cSrcweir 
1032cdf0e10cSrcweir 
1033