1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: eventattachermgr.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_comphelper.hxx"
36 #if defined( OS2 ) || defined( UNX )
39 #include <osl/mutex.hxx>
40 #ifndef _VOS_DIAGNOSE_HXX_
41 #include <vos/diagnose.hxx>
43 #include <vos/macros.hxx>
44 #include <comphelper/eventattachermgr.hxx>
45 #include <com/sun/star/beans/XIntrospection.hpp>
46 #include <com/sun/star/io/XObjectInputStream.hpp>
47 #include <com/sun/star/io/XPersistObject.hpp>
48 #include <com/sun/star/io/XObjectOutputStream.hpp>
49 #include <com/sun/star/io/XMarkableStream.hpp>
50 #include <com/sun/star/lang/XInitialization.hpp>
51 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
52 #include <com/sun/star/reflection/XIdlClass.hpp>
53 #include <com/sun/star/reflection/XIdlReflection.hpp>
54 #include <com/sun/star/reflection/XIdlMethod.hpp>
55 #include <com/sun/star/script/XTypeConverter.hpp>
56 #include <com/sun/star/script/XEngineListener.hpp>
57 #include <com/sun/star/script/XEventAttacher.hpp>
58 #include <com/sun/star/script/XEventAttacherManager.hpp>
59 #include <com/sun/star/script/XScriptListener.hpp>
60 #include <cppuhelper/weak.hxx>
61 #include <cppuhelper/interfacecontainer.hxx>
62 #include <cppuhelper/implbase1.hxx>
63 #include <cppuhelper/implbase2.hxx>
65 using namespace com::sun::star::uno
;
66 using namespace com::sun::star::io
;
67 using namespace com::sun::star::lang
;
68 using namespace com::sun::star::beans
;
69 using namespace com::sun::star::script
;
70 using namespace com::sun::star::reflection
;
78 //-----------------------------------------------------------------------------
79 struct AttachedObject_Impl
81 Reference
< XInterface
> xTarget
;
82 Sequence
< Reference
< XEventListener
> > aAttachedListenerSeq
;
85 bool operator<( const AttachedObject_Impl
& ) const;
86 bool operator==( const AttachedObject_Impl
& ) const;
89 struct AttacherIndex_Impl
92 ::std::deque
< ScriptEventDescriptor
> aEventList
;
94 Sequence
< ScriptEventDescriptor
> aEventList
;
96 ::std::deque
< AttachedObject_Impl
> aObjList
;
98 bool operator<( const AttacherIndex_Impl
& ) const;
99 bool operator==( const AttacherIndex_Impl
& ) const;
103 bool AttachedObject_Impl::operator<( const AttachedObject_Impl
& r
) const
105 VOS_ENSHURE( FALSE
, "not implemented" );
110 bool AttachedObject_Impl::operator==( const AttachedObject_Impl
& r
) const
112 VOS_ENSHURE( FALSE
, "not implemented" );
116 bool AttacherIndex_Impl::operator<( const AttacherIndex_Impl
& r
) const
118 VOS_ENSHURE( FALSE
, "not implemented" );
121 bool AttacherIndex_Impl::operator==( const AttacherIndex_Impl
& r
) const
123 VOS_ENSHURE( FALSE
, "not implemented" );
128 //-----------------------------------------------------------------------------
129 class ImplEventAttacherManager
130 : public WeakImplHelper2
< XEventAttacherManager
, XPersistObject
>
132 friend class AttacherAllListener_Impl
;
133 ::std::deque
< AttacherIndex_Impl
> aIndex
;
135 // Container fuer die ScriptListener
136 OInterfaceContainerHelper aScriptListeners
;
137 // EventAttacher-Instanz
138 Reference
< XEventAttacher
> xAttacher
;
139 Reference
< XMultiServiceFactory
> mxSMgr
;
140 Reference
< XIdlReflection
> mxCoreReflection
;
141 Reference
< XIntrospection
> mxIntrospection
;
142 Reference
< XTypeConverter
> xConverter
;
145 ImplEventAttacherManager( const Reference
< XIntrospection
> & rIntrospection
,
146 const Reference
< XMultiServiceFactory
> rSMgr
);
147 ~ImplEventAttacherManager();
149 // Methoden von XEventAttacherManager
150 virtual void SAL_CALL
registerScriptEvent(sal_Int32 Index
, const ScriptEventDescriptor
& ScriptEvent
)
151 throw( IllegalArgumentException
, RuntimeException
);
152 virtual void SAL_CALL
registerScriptEvents(sal_Int32 Index
, const Sequence
< ScriptEventDescriptor
>& ScriptEvents
)
153 throw( IllegalArgumentException
, RuntimeException
);
154 virtual void SAL_CALL
revokeScriptEvent(sal_Int32 Index
, const OUString
& ListenerType
, const OUString
& EventMethod
, const OUString
& removeListenerParam
)
155 throw( IllegalArgumentException
, RuntimeException
);
156 virtual void SAL_CALL
revokeScriptEvents(sal_Int32 Index
)
157 throw( IllegalArgumentException
, RuntimeException
);
158 virtual void SAL_CALL
insertEntry(sal_Int32 Index
)
159 throw( IllegalArgumentException
, RuntimeException
);
160 virtual void SAL_CALL
removeEntry(sal_Int32 Index
)
161 throw( IllegalArgumentException
, RuntimeException
);
162 virtual Sequence
< ScriptEventDescriptor
> SAL_CALL
getScriptEvents(sal_Int32 Index
)
163 throw( IllegalArgumentException
, RuntimeException
);
164 virtual void SAL_CALL
attach(sal_Int32 Index
, const Reference
< XInterface
>& Object
, const Any
& Helper
)
165 throw( IllegalArgumentException
, ServiceNotRegisteredException
, RuntimeException
);
166 virtual void SAL_CALL
detach(sal_Int32 nIndex
, const Reference
< XInterface
>& xObject
)
167 throw( IllegalArgumentException
, RuntimeException
);
168 virtual void SAL_CALL
addScriptListener(const Reference
< XScriptListener
>& aListener
)
169 throw( IllegalArgumentException
, RuntimeException
);
170 virtual void SAL_CALL
removeScriptListener(const Reference
< XScriptListener
>& Listener
)
171 throw( IllegalArgumentException
, RuntimeException
);
173 // Methoden von XPersistObject
174 virtual OUString SAL_CALL
getServiceName(void) throw( RuntimeException
);
175 virtual void SAL_CALL
write(const Reference
< XObjectOutputStream
>& OutStream
) throw( IOException
, RuntimeException
);
176 virtual void SAL_CALL
read(const Reference
< XObjectInputStream
>& InStream
) throw( IOException
, RuntimeException
);
179 Reference
< XIdlReflection
> getReflection() throw( Exception
);
181 /** checks if <arg>_nIndex</arg> is a valid index, throws an <type>IllegalArgumentException</type> if not
185 the iterator pointing to the position indicated by the index
187 ::std::deque
<AttacherIndex_Impl
>::iterator
implCheckIndex( sal_Int32 _nIndex
) SAL_THROW ( ( IllegalArgumentException
) );
190 //========================================================================
191 //========================================================================
192 //========================================================================
194 // Implementation eines EventAttacher-bezogenen AllListeners, der
195 // nur einzelne Events an einen allgemeinen AllListener weiterleitet
196 class AttacherAllListener_Impl
: public WeakImplHelper1
< XAllListener
>
198 ImplEventAttacherManager
* mpManager
;
199 Reference
< XEventAttacherManager
> xManager
;
200 OUString aScriptType
;
201 OUString aScriptCode
;
204 void convertToEventReturn( Any
& rRet
, const Type
& rRetType
)
205 throw( CannotConvertException
);
207 AttacherAllListener_Impl( ImplEventAttacherManager
* pManager_
, const OUString
&rScriptType_
,
208 const OUString
& rScriptCode_
);
210 // Methoden von XAllListener
211 virtual void SAL_CALL
firing(const AllEventObject
& Event
) throw( RuntimeException
);
212 virtual Any SAL_CALL
approveFiring(const AllEventObject
& Event
) throw( InvocationTargetException
, RuntimeException
);
214 // Methoden von XEventListener
215 virtual void SAL_CALL
disposing(const EventObject
& Source
) throw( RuntimeException
);
218 //========================================================================
219 AttacherAllListener_Impl::AttacherAllListener_Impl
221 ImplEventAttacherManager
* pManager_
,
222 const OUString
& rScriptType_
,
223 const OUString
& rScriptCode_
225 : mpManager( pManager_
)
226 , xManager( pManager_
)
227 , aScriptType( rScriptType_
)
228 , aScriptCode( rScriptCode_
)
234 //========================================================================
235 // Methoden von XAllListener
236 void SAL_CALL
AttacherAllListener_Impl::firing(const AllEventObject
& Event
)
237 throw( RuntimeException
)
239 ScriptEvent aScriptEvent
;
240 aScriptEvent
.Source
= (OWeakObject
*)mpManager
; // get correct XInterface
241 aScriptEvent
.ListenerType
= Event
.ListenerType
;
242 aScriptEvent
.MethodName
= Event
.MethodName
;
243 aScriptEvent
.Arguments
= Event
.Arguments
;
244 aScriptEvent
.Helper
= Event
.Helper
;
245 aScriptEvent
.ScriptType
= aScriptType
;
246 aScriptEvent
.ScriptCode
= aScriptCode
;
248 // ueber alle Listener iterieren und Events senden
249 OInterfaceIteratorHelper
aIt( mpManager
->aScriptListeners
);
250 while( aIt
.hasMoreElements() )
251 ((XScriptListener
*)aIt
.next())->firing( aScriptEvent
);
254 //========================================================================
255 // Convert to the standard event return
256 void AttacherAllListener_Impl::convertToEventReturn( Any
& rRet
, const Type
& rRetType
)
257 throw( CannotConvertException
)
259 // no return value? Set to the specified values
260 if( rRet
.getValueType().getTypeClass() == TypeClass_VOID
)
262 switch( rRetType
.getTypeClass() )
264 case TypeClass_INTERFACE
:
266 rRet
<<= Reference
< XInterface
>();
270 case TypeClass_BOOLEAN
:
274 case TypeClass_STRING
:
278 case TypeClass_FLOAT
: rRet
<<= float(0); break;
279 case TypeClass_DOUBLE
: rRet
<<= double(0.0); break;
280 case TypeClass_BYTE
: rRet
<<= sal_uInt8(0); break;
281 case TypeClass_SHORT
: rRet
<<= sal_Int16( 0 ); break;
282 case TypeClass_LONG
: rRet
<<= sal_Int32( 0 ); break;
283 case TypeClass_UNSIGNED_SHORT
: rRet
<<= sal_uInt16( 0 ); break;
284 case TypeClass_UNSIGNED_LONG
: rRet
<<= sal_uInt32( 0 ); break;
291 else if( !rRet
.getValueType().equals( rRetType
) )
293 if( mpManager
->xConverter
.is() )
294 rRet
= mpManager
->xConverter
->convertTo( rRet
, rRetType
);
296 throw CannotConvertException();
300 //========================================================================
301 // Methoden von XAllListener
302 Any SAL_CALL
AttacherAllListener_Impl::approveFiring( const AllEventObject
& Event
)
303 throw( InvocationTargetException
, RuntimeException
)
305 ScriptEvent aScriptEvent
;
306 aScriptEvent
.Source
= (OWeakObject
*)mpManager
; // get correct XInterface
307 aScriptEvent
.ListenerType
= Event
.ListenerType
;
308 aScriptEvent
.MethodName
= Event
.MethodName
;
309 aScriptEvent
.Arguments
= Event
.Arguments
;
310 aScriptEvent
.Helper
= Event
.Helper
;
311 aScriptEvent
.ScriptType
= aScriptType
;
312 aScriptEvent
.ScriptCode
= aScriptCode
;
315 // ueber alle Listener iterieren und Events senden
316 OInterfaceIteratorHelper
aIt( mpManager
->aScriptListeners
);
317 while( aIt
.hasMoreElements() )
319 aRet
= ((XScriptListener
*)aIt
.next())->approveFiring( aScriptEvent
);
322 Reference
< XIdlClass
> xListenerType
= mpManager
->getReflection()->
323 forName( Event
.ListenerType
.getTypeName() );
324 Reference
< XIdlMethod
> xMeth
= xListenerType
->getMethod( Event
.MethodName
);
327 Reference
< XIdlClass
> xRetType
= xMeth
->getReturnType();
328 Type
aRetType(xRetType
->getTypeClass(), xRetType
->getName());
329 convertToEventReturn( aRet
, aRetType
);
332 switch( aRet
.getValueType().getTypeClass() )
334 case TypeClass_INTERFACE
:
336 // Interface not null, return
337 Reference
< XInterface
> x
;
344 case TypeClass_BOOLEAN
:
346 if( !(*(sal_Bool
*)aRet
.getValue()) )
350 case TypeClass_STRING
:
351 // none empty string -> return
352 if( ((OUString
*)aRet
.getValue())->getLength() > 0 )
356 // none zero number -> return
357 case TypeClass_FLOAT
: if( *((float*)aRet
.getValue()) ) return aRet
; break;
358 case TypeClass_DOUBLE
: if( *((double*)aRet
.getValue()) ) return aRet
; break;
359 case TypeClass_BYTE
: if( *((sal_uInt8
*)aRet
.getValue()) ) return aRet
; break;
360 case TypeClass_SHORT
: if( *((sal_Int16
*)aRet
.getValue()) ) return aRet
; break;
361 case TypeClass_LONG
: if( *((sal_Int32
*)aRet
.getValue()) ) return aRet
; break;
362 case TypeClass_UNSIGNED_SHORT
: if( *((sal_uInt16
*)aRet
.getValue()) ) return aRet
; break;
363 case TypeClass_UNSIGNED_LONG
: if( *((sal_uInt32
*)aRet
.getValue()) ) return aRet
; break;
370 catch( CannotConvertException
& )
372 // silent ignore conversions errors from a script call
373 Reference
< XIdlClass
> xListenerType
= mpManager
->getReflection()->
374 forName( Event
.ListenerType
.getTypeName() );
375 Reference
< XIdlMethod
> xMeth
= xListenerType
->getMethod( Event
.MethodName
);
378 Reference
< XIdlClass
> xRetType
= xMeth
->getReturnType();
379 Type
aRetType(xRetType
->getTypeClass(), xRetType
->getName());
381 convertToEventReturn( aRet
, aRetType
);
388 //========================================================================
389 // Methoden von XEventListener
390 void SAL_CALL
AttacherAllListener_Impl::disposing(const EventObject
& )
391 throw( RuntimeException
)
393 // It is up to the container to release the object
397 //========================================================================
398 //========================================================================
399 //========================================================================
401 // Create-Methode fuer EventAttacherManager
402 Reference
< XEventAttacherManager
> createEventAttacherManager( const Reference
< XIntrospection
> & rIntrospection
,
403 const Reference
< XMultiServiceFactory
> & rSMgr
)
406 return new ImplEventAttacherManager( rIntrospection
, rSMgr
);
409 // Create-Methode fuer EventAttacherManager
410 Reference
< XEventAttacherManager
> createEventAttacherManager( const Reference
< XMultiServiceFactory
> & rSMgr
)
415 Reference
< XInterface
> xIFace( rSMgr
->createInstance( OUString::createFromAscii("com.sun.star.beans.Introspection") ) );
418 Reference
< XIntrospection
> xIntrospection( xIFace
, UNO_QUERY
);
419 return new ImplEventAttacherManager( xIntrospection
, rSMgr
);
423 return Reference
< XEventAttacherManager
>();
426 //-----------------------------------------------------------------------------
427 ImplEventAttacherManager::ImplEventAttacherManager( const Reference
< XIntrospection
> & rIntrospection
,
428 const Reference
< XMultiServiceFactory
> rSMgr
)
429 : aScriptListeners( aLock
)
431 , mxIntrospection( rIntrospection
)
435 Reference
< XInterface
> xIFace( rSMgr
->createInstance( OUString::createFromAscii("com.sun.star.script.EventAttacher") ) );
438 xAttacher
= Reference
< XEventAttacher
>::query( xIFace
);
440 xIFace
= rSMgr
->createInstance( OUString::createFromAscii("com.sun.star.script.Converter") );
443 xConverter
= Reference
< XTypeConverter
>::query( xIFace
);
447 Reference
< XInitialization
> xInit( xAttacher
, UNO_QUERY
);
450 Sequence
< Any
> Arguments( 1 );
451 Arguments
[0] <<= rIntrospection
;
452 xInit
->initialize( Arguments
);
456 //-----------------------------------------------------------------------------
457 ImplEventAttacherManager::~ImplEventAttacherManager()
461 Reference
< XIdlReflection
> ImplEventAttacherManager::getReflection() throw( Exception
)
463 Guard
< Mutex
> aGuard( aLock
);
464 // Haben wir den Service schon? Sonst anlegen
465 if( !mxCoreReflection
.is() )
467 Reference
< XInterface
> xIFace( mxSMgr
->createInstance( OUString::createFromAscii("com.sun.star.reflection.CoreReflection") ) );
468 mxCoreReflection
= Reference
< XIdlReflection
>( xIFace
, UNO_QUERY
);
470 return mxCoreReflection
;
474 //-----------------------------------------------------------------------------
475 ::std::deque
<AttacherIndex_Impl
>::iterator
ImplEventAttacherManager::implCheckIndex( sal_Int32 _nIndex
) SAL_THROW ( ( IllegalArgumentException
) )
478 throw IllegalArgumentException();
480 ::std::deque
<AttacherIndex_Impl
>::iterator aIt
= aIndex
.begin();
481 for ( sal_Int32 i
= 0; (i
< _nIndex
) && (aIt
!= aIndex
.end()); ++i
, ++aIt
)
484 if( aIt
== aIndex
.end() )
485 throw IllegalArgumentException();
490 //-----------------------------------------------------------------------------
493 ImplEventAttacherManager
* pMgr
,
495 ::std::deque
< AttachedObject_Impl
> & rList
498 ::std::deque
< AttachedObject_Impl
>::iterator aObjIt
= rList
.begin();
499 ::std::deque
< AttachedObject_Impl
>::iterator aObjEnd
= rList
.end();
500 while( aObjIt
!= aObjEnd
)
502 pMgr
->detach( nIdx
, (*aObjIt
).xTarget
);
507 //-----------------------------------------------------------------------------
510 ImplEventAttacherManager
* pMgr
,
512 ::std::deque
< AttachedObject_Impl
> & rList
515 ::std::deque
< AttachedObject_Impl
>::iterator aObjIt
= rList
.begin();
516 ::std::deque
< AttachedObject_Impl
>::iterator aObjEnd
= rList
.end();
517 while( aObjIt
!= aObjEnd
)
519 pMgr
->attach( nIdx
, (*aObjIt
).xTarget
, (*aObjIt
).aHelper
);
524 //-----------------------------------------------------------------------------
525 //*** Methoden von XEventAttacherManager ***
526 void SAL_CALL
ImplEventAttacherManager::registerScriptEvent
529 const ScriptEventDescriptor
& ScriptEvent
531 throw( IllegalArgumentException
, RuntimeException
)
533 Guard
< Mutex
> aGuard( aLock
);
535 // Index pruefen und Array anpassen
536 ::std::deque
<AttacherIndex_Impl
>::iterator aIt
= implCheckIndex( nIndex
);
538 ::std::deque
< AttachedObject_Impl
> aList
= (*aIt
).aObjList
;
540 ScriptEventDescriptor aEvt
= ScriptEvent
;
541 const sal_Unicode
* pLastDot
= aEvt
.ListenerType
.getStr();
542 pLastDot
+= rtl_ustr_lastIndexOfChar( pLastDot
, '.' );
544 aEvt
.ListenerType
= pLastDot
+1;
546 (*aIt
).aEventList
.push_back( aEvt
);
548 (*aIt
).aEventList
.realloc( (*aIt
).aEventList
.getLength() +1 );
549 (*aIt
).aEventList
.getArray()[(*aIt
).aEventList
.getLength() -1] = aEvt
;
552 // register new new Event
553 ::std::deque
< AttachedObject_Impl
>::iterator aObjIt
= (*aIt
).aObjList
.begin();
554 ::std::deque
< AttachedObject_Impl
>::iterator aObjEnd
= (*aIt
).aObjList
.end();
555 while( aObjIt
!= aObjEnd
)
558 sal_Int32 nPos
= (*aObjIt
).aAttachedListenerSeq
.getLength();
559 (*aObjIt
).aAttachedListenerSeq
.realloc( nPos
+ 1 );
560 Reference
< XEventListener
> * pArray
= (*aObjIt
).aAttachedListenerSeq
.getArray();
562 Reference
< XAllListener
> xAll
=
563 new AttacherAllListener_Impl( this, ScriptEvent
.ScriptType
, ScriptEvent
.ScriptCode
);
566 pArray
[nPos
] = xAttacher
->attachSingleEventListener( (*aObjIt
).xTarget
, xAll
,
567 (*aObjIt
).aHelper
, ScriptEvent
.ListenerType
,
568 ScriptEvent
.AddListenerParam
, ScriptEvent
.EventMethod
);
578 //-----------------------------------------------------------------------------
579 void SAL_CALL
ImplEventAttacherManager::registerScriptEvents
582 const Sequence
< ScriptEventDescriptor
>& ScriptEvents
584 throw( IllegalArgumentException
, RuntimeException
)
586 Guard
< Mutex
> aGuard( aLock
);
588 // Index pruefen und Array anpassen
589 ::std::deque
<AttacherIndex_Impl
>::iterator aIt
= implCheckIndex( nIndex
);
591 ::std::deque
< AttachedObject_Impl
> aList
= (*aIt
).aObjList
;
592 detachAll_Impl( this, nIndex
, aList
);
594 const ScriptEventDescriptor
* pArray
= ScriptEvents
.getConstArray();
595 sal_Int32 nLen
= ScriptEvents
.getLength();
596 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
597 registerScriptEvent( nIndex
, pArray
[ i
] );
599 attachAll_Impl( this, nIndex
, aList
);
602 //-----------------------------------------------------------------------------
603 void SAL_CALL
ImplEventAttacherManager::revokeScriptEvent
606 const OUString
& ListenerType
,
607 const OUString
& EventMethod
,
608 const OUString
& ToRemoveListenerParam
610 throw( IllegalArgumentException
, RuntimeException
)
612 Guard
< Mutex
> aGuard( aLock
);
614 ::std::deque
<AttacherIndex_Impl
>::iterator aIt
= implCheckIndex( nIndex
);
616 ::std::deque
< AttachedObject_Impl
> aList
= (*aIt
).aObjList
;
617 detachAll_Impl( this, nIndex
, aList
);
619 OUString aLstType
= ListenerType
;
620 const sal_Unicode
* pLastDot
= aLstType
.getStr();
621 pLastDot
+= rtl_ustr_lastIndexOfChar( pLastDot
, '.' );
623 aLstType
= pLastDot
+1;
626 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtIt
= (*aIt
).aEventList
.begin();
627 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtEnd
= (*aIt
).aEventList
.end();
628 while( aEvtIt
!= aEvtEnd
)
630 if( aLstType
== (*aEvtIt
).ListenerType
631 && EventMethod
== (*aEvtIt
).EventMethod
632 && ToRemoveListenerParam
== (*aEvtIt
).AddListenerParam
)
634 (*aIt
).aEventList
.erase( aEvtIt
);
641 Sequence
< ScriptEventDescriptor
>& rEventList
= (*aIt
).aEventList
;
643 ScriptEventDescriptor
* pEventList
= rEventList
.getArray();
644 const ScriptEventDescriptor
* pEventListEnd
= pEventList
+ rEventList
.getLength();
645 for( ; pEventList
< pEventListEnd
; ++pEventList
)
647 if ( (aLstType
== pEventList
->ListenerType
)
648 && (EventMethod
== pEventList
->EventMethod
)
649 && (ToRemoveListenerParam
== pEventList
->AddListenerParam
)
652 ScriptEventDescriptor
* pMoveTo
= pEventList
;
653 const ScriptEventDescriptor
* pMoveFrom
= pMoveTo
+ 1;
654 while (pMoveFrom
< pEventListEnd
)
656 *pMoveTo
++ = *pMoveFrom
++;
658 rEventList
.realloc( rEventList
.getLength() - 1 );
663 attachAll_Impl( this, nIndex
, aList
);
666 //-----------------------------------------------------------------------------
667 void SAL_CALL
ImplEventAttacherManager::revokeScriptEvents(sal_Int32 nIndex
)
668 throw( IllegalArgumentException
, RuntimeException
)
670 Guard
< Mutex
> aGuard( aLock
);
671 ::std::deque
<AttacherIndex_Impl
>::iterator aIt
= implCheckIndex( nIndex
);
673 ::std::deque
< AttachedObject_Impl
> aList
= (*aIt
).aObjList
;
674 detachAll_Impl( this, nIndex
, aList
);
676 (*aIt
).aEventList
= ::std::deque
< ScriptEventDescriptor
>();
678 (*aIt
).aEventList
.realloc( 0 );
680 attachAll_Impl( this, nIndex
, aList
);
683 //-----------------------------------------------------------------------------
684 void SAL_CALL
ImplEventAttacherManager::insertEntry(sal_Int32 nIndex
)
685 throw( IllegalArgumentException
, RuntimeException
)
687 Guard
< Mutex
> aGuard( aLock
);
689 throw IllegalArgumentException();
691 // ::std::deque<AttacherIndex_Impl>::iterator aIt = aIndex.begin();
695 if ( static_cast< ::std::deque
< AttacherIndex_Impl
>::size_type
>(nIndex
) >= aIndex
.size() )
696 aIndex
.resize(nIndex
+1);
698 AttacherIndex_Impl aTmp
;
699 aIndex
.insert( aIndex
.begin() + nIndex
, aTmp
);
702 //-----------------------------------------------------------------------------
703 void SAL_CALL
ImplEventAttacherManager::removeEntry(sal_Int32 nIndex
)
704 throw( IllegalArgumentException
, RuntimeException
)
706 Guard
< Mutex
> aGuard( aLock
);
707 ::std::deque
<AttacherIndex_Impl
>::iterator aIt
= implCheckIndex( nIndex
);
709 ::std::deque
< AttachedObject_Impl
> aList
= (*aIt
).aObjList
;
710 detachAll_Impl( this, nIndex
, aList
);
714 //-----------------------------------------------------------------------------
715 Sequence
< ScriptEventDescriptor
> SAL_CALL
ImplEventAttacherManager::getScriptEvents(sal_Int32 nIndex
)
716 throw( IllegalArgumentException
, RuntimeException
)
718 Guard
< Mutex
> aGuard( aLock
);
719 ::std::deque
<AttacherIndex_Impl
>::iterator aIt
= implCheckIndex( nIndex
);
722 Sequence
< ScriptEventDescriptor
> aSeq( (*aIt
).aEventList
.size() );
723 ScriptEventDescriptor
* pArray
= aSeq
.getArray();
725 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtIt
= (*aIt
).aEventList
.begin();
726 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtEnd
= (*aIt
).aEventList
.end();
728 while( aEvtIt
!= aEvtEnd
)
730 pArray
[i
++] = *aEvtIt
;
735 return (*aIt
).aEventList
;
739 //-----------------------------------------------------------------------------
740 void SAL_CALL
ImplEventAttacherManager::attach(sal_Int32 nIndex
, const Reference
< XInterface
>& xObject
, const Any
& Helper
)
741 throw( IllegalArgumentException
, ServiceNotRegisteredException
, RuntimeException
)
743 Guard
< Mutex
> aGuard( aLock
);
744 if( nIndex
< 0 || !xObject
.is() )
745 throw IllegalArgumentException();
747 if( static_cast< ::std::deque
< AttacherIndex_Impl
>::size_type
>(nIndex
) >= aIndex
.size() )
749 // alte Dateien lesen
752 insertEntry( nIndex
);
753 attach( nIndex
, xObject
, Helper
);
757 throw IllegalArgumentException();
760 ::std::deque
< AttacherIndex_Impl
>::iterator aCurrentPosition
= aIndex
.begin() + nIndex
;
762 AttachedObject_Impl aTmp
;
763 aTmp
.xTarget
= xObject
;
764 aTmp
.aHelper
= Helper
;
765 aCurrentPosition
->aObjList
.push_back( aTmp
);
767 //::std::deque< AttachedObject_Impl >::iterator aObjIt = (*aIt).aObjList.back();
768 AttachedObject_Impl
& rCurObj
= aCurrentPosition
->aObjList
.back();
770 rCurObj
.aAttachedListenerSeq
= Sequence
< Reference
< XEventListener
> >( aCurrentPosition
->aEventList
.size() );
772 rCurObj
.aAttachedListenerSeq
= Sequence
< Reference
< XEventListener
> >( aCurrentPosition
->aEventList
.getLength() );
774 Reference
< XEventListener
> * pArray
= rCurObj
.aAttachedListenerSeq
.getArray();
777 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtIt
= aCurrentPosition
->aEventList
.begin();
778 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtEnd
= aCurrentPosition
->aEventList
.end();
780 while( aEvtIt
!= aEvtEnd
)
782 Reference
< XAllListener
> xAll
=
783 new AttacherAllListener_Impl( this, (*aEvtIt
).ScriptType
, (*aEvtIt
).ScriptCode
);
784 Reference
< XEventListener
> xAdapter
;
787 xAdapter
= xAttacher
->attachSingleEventListener( rCurObj
.xTarget
, xAll
,
788 rCurObj
.aHelper
, (*aEvtIt
).ScriptType
,
789 (*aEvtIt
).AddListenerParam
, (*aEvtIt
).EventMethod
);
795 pArray
[i
++] = xAdapter
;
799 sal_Int32 nLen
= aCurrentPosition
->aEventList
.getLength();
800 ScriptEventDescriptor
* pEL
= aCurrentPosition
->aEventList
.getArray();
801 for(sal_Int32 i
= 0; i
< nLen
; ++i
)
803 Reference
< XAllListener
> xAll
=
804 new AttacherAllListener_Impl( this, pEL
[i
].ScriptType
, pEL
[i
].ScriptCode
);
805 Reference
< XEventListener
> xAdapter
;
808 xAdapter
= xAttacher
->attachSingleEventListener( rCurObj
.xTarget
, xAll
,
809 rCurObj
.aHelper
, pEL
[i
].ListenerType
,
810 pEL
[i
].AddListenerParam
, pEL
[i
].EventMethod
);
816 pArray
[i
] = xAdapter
;
821 //-----------------------------------------------------------------------------
822 void SAL_CALL
ImplEventAttacherManager::detach(sal_Int32 nIndex
, const Reference
< XInterface
>& xObject
)
823 throw( IllegalArgumentException
, RuntimeException
)
825 Guard
< Mutex
> aGuard( aLock
);
827 if( nIndex
< 0 || static_cast< ::std::deque
< AttacherIndex_Impl
>::size_type
>(nIndex
) >= aIndex
.size() || !xObject
.is() )
828 throw IllegalArgumentException();
830 ::std::deque
< AttacherIndex_Impl
>::iterator aCurrentPosition
= aIndex
.begin() + nIndex
;
831 ::std::deque
< AttachedObject_Impl
>::iterator aObjIt
= aCurrentPosition
->aObjList
.begin();
832 ::std::deque
< AttachedObject_Impl
>::iterator aObjEnd
= aCurrentPosition
->aObjList
.end();
833 while( aObjIt
!= aObjEnd
)
835 if( (*aObjIt
).xTarget
== xObject
)
837 Reference
< XEventListener
> * pArray
= (*aObjIt
).aAttachedListenerSeq
.getArray();
840 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtIt
= aCurrentPosition
->aEventList
.begin();
841 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtEnd
= aCurrentPosition
->aEventList
.end();
843 while( aEvtIt
!= aEvtEnd
)
849 xAttacher
->removeListener( (*aObjIt
).xTarget
, (*aEvtIt
).ListenerType
,
850 (*aEvtIt
).AddListenerParam
, pArray
[i
] );
860 sal_Int32 nLen
= aCurrentPosition
->aEventList
.getLength();
861 ScriptEventDescriptor
* pEL
= aCurrentPosition
->aEventList
.getArray();
862 for( sal_Int32 i
= 0; i
< nLen
; i
++ )
868 xAttacher
->removeListener( (*aObjIt
).xTarget
, pEL
[i
].ListenerType
,
869 pEL
[i
].AddListenerParam
, pArray
[i
] );
877 aCurrentPosition
->aObjList
.erase( aObjIt
);
884 void SAL_CALL
ImplEventAttacherManager::addScriptListener(const Reference
< XScriptListener
>& aListener
)
885 throw( IllegalArgumentException
, RuntimeException
)
887 Guard
< Mutex
> aGuard( aLock
);
888 aScriptListeners
.addInterface( aListener
);
891 void SAL_CALL
ImplEventAttacherManager::removeScriptListener(const Reference
< XScriptListener
>& aListener
)
892 throw( IllegalArgumentException
, RuntimeException
)
894 Guard
< Mutex
> aGuard( aLock
);
895 aScriptListeners
.removeInterface( aListener
);
899 // Methoden von XPersistObject
900 OUString SAL_CALL
ImplEventAttacherManager::getServiceName(void)
901 throw( RuntimeException
)
903 return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.script.EventAttacherManager") );
906 void SAL_CALL
ImplEventAttacherManager::write(const Reference
< XObjectOutputStream
>& OutStream
)
907 throw( IOException
, RuntimeException
)
909 Guard
< Mutex
> aGuard( aLock
);
910 // Ohne XMarkableStream laeuft nichts
911 Reference
< XMarkableStream
> xMarkStream( OutStream
, UNO_QUERY
);
912 if( !xMarkStream
.is() )
916 OutStream
->writeShort( 2 );
918 // Position fuer Laenge merken
919 sal_Int32 nObjLenMark
= xMarkStream
->createMark();
920 OutStream
->writeLong( 0L );
922 OutStream
->writeLong( aIndex
.size() );
924 // Sequences schreiben
925 ::std::deque
<AttacherIndex_Impl
>::iterator aIt
= aIndex
.begin();
926 ::std::deque
<AttacherIndex_Impl
>::iterator aEnd
= aIndex
.end();
930 // Laenge der Sequence und alle Descriptoren schreiben
931 OutStream
->writeLong( (*aIt
).aEventList
.size() );
932 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtIt
= (*aIt
).aEventList
.begin();
933 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtEnd
= (*aIt
).aEventList
.end();
934 while( aEvtIt
!= aEvtEnd
)
936 const ScriptEventDescriptor
& rDesc
= (*aEvtIt
);
937 OutStream
->writeUTF( rDesc
.ListenerType
);
938 OutStream
->writeUTF( rDesc
.EventMethod
);
939 OutStream
->writeUTF( rDesc
.AddListenerParam
);
940 OutStream
->writeUTF( rDesc
.ScriptType
);
941 OutStream
->writeUTF( rDesc
.ScriptCode
);
946 sal_Int32 nLen
= (*aIt
).aEventList
.getLength();
947 // Laenge der Sequence und alle Descriptoren schreiben
948 OutStream
->writeLong( nLen
);
949 ScriptEventDescriptor
* pEL
= (*aIt
).aEventList
.getArray();
950 for( sal_Int32 i
= 0; i
< nLen
; i
++ )
952 const ScriptEventDescriptor
& rDesc
= pEL
[i
];
953 OutStream
->writeUTF( rDesc
.ListenerType
);
954 OutStream
->writeUTF( rDesc
.EventMethod
);
955 OutStream
->writeUTF( rDesc
.AddListenerParam
);
956 OutStream
->writeUTF( rDesc
.ScriptType
);
957 OutStream
->writeUTF( rDesc
.ScriptCode
);
963 // Die jetzt bekannte Laenge eintragen
964 sal_Int32 nObjLen
= xMarkStream
->offsetToMark( nObjLenMark
) -4;
965 xMarkStream
->jumpToMark( nObjLenMark
);
966 OutStream
->writeLong( nObjLen
);
967 xMarkStream
->jumpToFurthest();
968 xMarkStream
->deleteMark( nObjLenMark
);
971 void SAL_CALL
ImplEventAttacherManager::read(const Reference
< XObjectInputStream
>& InStream
)
972 throw( IOException
, RuntimeException
)
974 Guard
< Mutex
> aGuard( aLock
);
975 // Ohne XMarkableStream laeuft nichts
976 Reference
< XMarkableStream
> xMarkStream( InStream
, UNO_QUERY
);
977 if( !xMarkStream
.is() )
981 nVersion
= InStream
->readShort();
983 // Zunaechst kommen die Daten gemaess Version 1,
984 // muss auch bei hoeheren Versionen beibehalten werden
985 sal_Int32 nLen
= InStream
->readLong();
987 // Position fuer Vergleichszwecke
988 sal_Int32 nObjLenMark
= xMarkStream
->createMark();
990 // Anzahl der zu lesenden Sequences
991 sal_Int32 nItemCount
= InStream
->readLong();
993 for( sal_Int32 i
= 0 ; i
< nItemCount
; i
++ )
996 // Laenge der Sequence lesen
997 sal_Int32 nSeqLen
= InStream
->readLong();
999 // Sequence anlegen und Descriptoren lesen
1000 Sequence
< ScriptEventDescriptor
> aSEDSeq( nSeqLen
);
1001 ScriptEventDescriptor
* pArray
= aSEDSeq
.getArray();
1002 for( sal_Int32 j
= 0 ; j
< nSeqLen
; j
++ )
1004 ScriptEventDescriptor
& rDesc
= pArray
[ j
];
1005 rDesc
.ListenerType
= InStream
->readUTF();
1006 rDesc
.EventMethod
= InStream
->readUTF();
1007 rDesc
.AddListenerParam
= InStream
->readUTF();
1008 rDesc
.ScriptType
= InStream
->readUTF();
1009 rDesc
.ScriptCode
= InStream
->readUTF();
1011 registerScriptEvents( i
, aSEDSeq
);
1014 // Haben wir die angegebene Laenge gelesen?
1015 sal_Int32 nRealLen
= xMarkStream
->offsetToMark( nObjLenMark
);
1016 if( nRealLen
!= nLen
)
1018 // Nur wenn die StreamVersion > 1 ist und noch Daten folgen, kann das
1019 // Ganze richtig sein. Sonst ist etwas voellig daneben gegangen.
1020 if( nRealLen
> nLen
|| nVersion
== 1 )
1022 VOS_ENSHURE( sal_False
, "ImplEventAttacherManager::read(): Fatal Error, wrong object length" );
1026 // TODO: Pruefen, ob Zwischen-Speicherung der Daten sinnvoll sein koennte
1028 // Vorerst einfach nur Skippen
1029 sal_Int32 nSkipCount
= nLen
- nRealLen
;
1030 InStream
->skipBytes( nSkipCount
);
1033 xMarkStream
->jumpToFurthest();
1034 xMarkStream
->deleteMark( nObjLenMark
);
1037 } // namesapce comphelper