1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_comphelper.hxx"
33 #if defined( OS2 ) || defined( UNX )
36 #include <osl/mutex.hxx>
37 #ifndef _VOS_DIAGNOSE_HXX_
38 #include <vos/diagnose.hxx>
40 #include <vos/macros.hxx>
41 #include <comphelper/eventattachermgr.hxx>
42 #include <com/sun/star/beans/XIntrospection.hpp>
43 #include <com/sun/star/io/XObjectInputStream.hpp>
44 #include <com/sun/star/io/XPersistObject.hpp>
45 #include <com/sun/star/io/XObjectOutputStream.hpp>
46 #include <com/sun/star/io/XMarkableStream.hpp>
47 #include <com/sun/star/lang/XInitialization.hpp>
48 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
49 #include <com/sun/star/reflection/XIdlClass.hpp>
50 #include <com/sun/star/reflection/XIdlReflection.hpp>
51 #include <com/sun/star/reflection/XIdlMethod.hpp>
52 #include <com/sun/star/script/XTypeConverter.hpp>
53 #include <com/sun/star/script/XEngineListener.hpp>
54 #include <com/sun/star/script/XEventAttacher.hpp>
55 #include <com/sun/star/script/XEventAttacherManager.hpp>
56 #include <com/sun/star/script/XScriptListener.hpp>
57 #include <cppuhelper/weak.hxx>
58 #include <cppuhelper/interfacecontainer.hxx>
59 #include <cppuhelper/implbase1.hxx>
60 #include <cppuhelper/implbase2.hxx>
62 using namespace com::sun::star::uno
;
63 using namespace com::sun::star::io
;
64 using namespace com::sun::star::lang
;
65 using namespace com::sun::star::beans
;
66 using namespace com::sun::star::script
;
67 using namespace com::sun::star::reflection
;
75 //-----------------------------------------------------------------------------
76 struct AttachedObject_Impl
78 Reference
< XInterface
> xTarget
;
79 Sequence
< Reference
< XEventListener
> > aAttachedListenerSeq
;
82 bool operator<( const AttachedObject_Impl
& ) const;
83 bool operator==( const AttachedObject_Impl
& ) const;
86 struct AttacherIndex_Impl
89 ::std::deque
< ScriptEventDescriptor
> aEventList
;
91 Sequence
< ScriptEventDescriptor
> aEventList
;
93 ::std::deque
< AttachedObject_Impl
> aObjList
;
95 bool operator<( const AttacherIndex_Impl
& ) const;
96 bool operator==( const AttacherIndex_Impl
& ) const;
100 bool AttachedObject_Impl::operator<( const AttachedObject_Impl
& r
) const
102 VOS_ENSHURE( FALSE
, "not implemented" );
107 bool AttachedObject_Impl::operator==( const AttachedObject_Impl
& r
) const
109 VOS_ENSHURE( FALSE
, "not implemented" );
113 bool AttacherIndex_Impl::operator<( const AttacherIndex_Impl
& r
) const
115 VOS_ENSHURE( FALSE
, "not implemented" );
118 bool AttacherIndex_Impl::operator==( const AttacherIndex_Impl
& r
) const
120 VOS_ENSHURE( FALSE
, "not implemented" );
125 //-----------------------------------------------------------------------------
126 class ImplEventAttacherManager
127 : public WeakImplHelper2
< XEventAttacherManager
, XPersistObject
>
129 friend class AttacherAllListener_Impl
;
130 ::std::deque
< AttacherIndex_Impl
> aIndex
;
132 // Container fuer die ScriptListener
133 OInterfaceContainerHelper aScriptListeners
;
134 // EventAttacher-Instanz
135 Reference
< XEventAttacher
> xAttacher
;
136 Reference
< XMultiServiceFactory
> mxSMgr
;
137 Reference
< XIdlReflection
> mxCoreReflection
;
138 Reference
< XIntrospection
> mxIntrospection
;
139 Reference
< XTypeConverter
> xConverter
;
142 ImplEventAttacherManager( const Reference
< XIntrospection
> & rIntrospection
,
143 const Reference
< XMultiServiceFactory
> rSMgr
);
144 ~ImplEventAttacherManager();
146 // Methoden von XEventAttacherManager
147 virtual void SAL_CALL
registerScriptEvent(sal_Int32 Index
, const ScriptEventDescriptor
& ScriptEvent
)
148 throw( IllegalArgumentException
, RuntimeException
);
149 virtual void SAL_CALL
registerScriptEvents(sal_Int32 Index
, const Sequence
< ScriptEventDescriptor
>& ScriptEvents
)
150 throw( IllegalArgumentException
, RuntimeException
);
151 virtual void SAL_CALL
revokeScriptEvent(sal_Int32 Index
, const OUString
& ListenerType
, const OUString
& EventMethod
, const OUString
& removeListenerParam
)
152 throw( IllegalArgumentException
, RuntimeException
);
153 virtual void SAL_CALL
revokeScriptEvents(sal_Int32 Index
)
154 throw( IllegalArgumentException
, RuntimeException
);
155 virtual void SAL_CALL
insertEntry(sal_Int32 Index
)
156 throw( IllegalArgumentException
, RuntimeException
);
157 virtual void SAL_CALL
removeEntry(sal_Int32 Index
)
158 throw( IllegalArgumentException
, RuntimeException
);
159 virtual Sequence
< ScriptEventDescriptor
> SAL_CALL
getScriptEvents(sal_Int32 Index
)
160 throw( IllegalArgumentException
, RuntimeException
);
161 virtual void SAL_CALL
attach(sal_Int32 Index
, const Reference
< XInterface
>& Object
, const Any
& Helper
)
162 throw( IllegalArgumentException
, ServiceNotRegisteredException
, RuntimeException
);
163 virtual void SAL_CALL
detach(sal_Int32 nIndex
, const Reference
< XInterface
>& xObject
)
164 throw( IllegalArgumentException
, RuntimeException
);
165 virtual void SAL_CALL
addScriptListener(const Reference
< XScriptListener
>& aListener
)
166 throw( IllegalArgumentException
, RuntimeException
);
167 virtual void SAL_CALL
removeScriptListener(const Reference
< XScriptListener
>& Listener
)
168 throw( IllegalArgumentException
, RuntimeException
);
170 // Methoden von XPersistObject
171 virtual OUString SAL_CALL
getServiceName(void) throw( RuntimeException
);
172 virtual void SAL_CALL
write(const Reference
< XObjectOutputStream
>& OutStream
) throw( IOException
, RuntimeException
);
173 virtual void SAL_CALL
read(const Reference
< XObjectInputStream
>& InStream
) throw( IOException
, RuntimeException
);
176 Reference
< XIdlReflection
> getReflection() throw( Exception
);
178 /** checks if <arg>_nIndex</arg> is a valid index, throws an <type>IllegalArgumentException</type> if not
182 the iterator pointing to the position indicated by the index
184 ::std::deque
<AttacherIndex_Impl
>::iterator
implCheckIndex( sal_Int32 _nIndex
) SAL_THROW ( ( IllegalArgumentException
) );
187 //========================================================================
188 //========================================================================
189 //========================================================================
191 // Implementation eines EventAttacher-bezogenen AllListeners, der
192 // nur einzelne Events an einen allgemeinen AllListener weiterleitet
193 class AttacherAllListener_Impl
: public WeakImplHelper1
< XAllListener
>
195 ImplEventAttacherManager
* mpManager
;
196 Reference
< XEventAttacherManager
> xManager
;
197 OUString aScriptType
;
198 OUString aScriptCode
;
201 void convertToEventReturn( Any
& rRet
, const Type
& rRetType
)
202 throw( CannotConvertException
);
204 AttacherAllListener_Impl( ImplEventAttacherManager
* pManager_
, const OUString
&rScriptType_
,
205 const OUString
& rScriptCode_
);
207 // Methoden von XAllListener
208 virtual void SAL_CALL
firing(const AllEventObject
& Event
) throw( RuntimeException
);
209 virtual Any SAL_CALL
approveFiring(const AllEventObject
& Event
) throw( InvocationTargetException
, RuntimeException
);
211 // Methoden von XEventListener
212 virtual void SAL_CALL
disposing(const EventObject
& Source
) throw( RuntimeException
);
215 //========================================================================
216 AttacherAllListener_Impl::AttacherAllListener_Impl
218 ImplEventAttacherManager
* pManager_
,
219 const OUString
& rScriptType_
,
220 const OUString
& rScriptCode_
222 : mpManager( pManager_
)
223 , xManager( pManager_
)
224 , aScriptType( rScriptType_
)
225 , aScriptCode( rScriptCode_
)
231 //========================================================================
232 // Methoden von XAllListener
233 void SAL_CALL
AttacherAllListener_Impl::firing(const AllEventObject
& Event
)
234 throw( RuntimeException
)
236 ScriptEvent aScriptEvent
;
237 aScriptEvent
.Source
= (OWeakObject
*)mpManager
; // get correct XInterface
238 aScriptEvent
.ListenerType
= Event
.ListenerType
;
239 aScriptEvent
.MethodName
= Event
.MethodName
;
240 aScriptEvent
.Arguments
= Event
.Arguments
;
241 aScriptEvent
.Helper
= Event
.Helper
;
242 aScriptEvent
.ScriptType
= aScriptType
;
243 aScriptEvent
.ScriptCode
= aScriptCode
;
245 // ueber alle Listener iterieren und Events senden
246 OInterfaceIteratorHelper
aIt( mpManager
->aScriptListeners
);
247 while( aIt
.hasMoreElements() )
248 ((XScriptListener
*)aIt
.next())->firing( aScriptEvent
);
251 //========================================================================
252 // Convert to the standard event return
253 void AttacherAllListener_Impl::convertToEventReturn( Any
& rRet
, const Type
& rRetType
)
254 throw( CannotConvertException
)
256 // no return value? Set to the specified values
257 if( rRet
.getValueType().getTypeClass() == TypeClass_VOID
)
259 switch( rRetType
.getTypeClass() )
261 case TypeClass_INTERFACE
:
263 rRet
<<= Reference
< XInterface
>();
267 case TypeClass_BOOLEAN
:
271 case TypeClass_STRING
:
275 case TypeClass_FLOAT
: rRet
<<= float(0); break;
276 case TypeClass_DOUBLE
: rRet
<<= double(0.0); break;
277 case TypeClass_BYTE
: rRet
<<= sal_uInt8(0); break;
278 case TypeClass_SHORT
: rRet
<<= sal_Int16( 0 ); break;
279 case TypeClass_LONG
: rRet
<<= sal_Int32( 0 ); break;
280 case TypeClass_UNSIGNED_SHORT
: rRet
<<= sal_uInt16( 0 ); break;
281 case TypeClass_UNSIGNED_LONG
: rRet
<<= sal_uInt32( 0 ); break;
288 else if( !rRet
.getValueType().equals( rRetType
) )
290 if( mpManager
->xConverter
.is() )
291 rRet
= mpManager
->xConverter
->convertTo( rRet
, rRetType
);
293 throw CannotConvertException();
297 //========================================================================
298 // Methoden von XAllListener
299 Any SAL_CALL
AttacherAllListener_Impl::approveFiring( const AllEventObject
& Event
)
300 throw( InvocationTargetException
, RuntimeException
)
302 ScriptEvent aScriptEvent
;
303 aScriptEvent
.Source
= (OWeakObject
*)mpManager
; // get correct XInterface
304 aScriptEvent
.ListenerType
= Event
.ListenerType
;
305 aScriptEvent
.MethodName
= Event
.MethodName
;
306 aScriptEvent
.Arguments
= Event
.Arguments
;
307 aScriptEvent
.Helper
= Event
.Helper
;
308 aScriptEvent
.ScriptType
= aScriptType
;
309 aScriptEvent
.ScriptCode
= aScriptCode
;
312 // ueber alle Listener iterieren und Events senden
313 OInterfaceIteratorHelper
aIt( mpManager
->aScriptListeners
);
314 while( aIt
.hasMoreElements() )
316 aRet
= ((XScriptListener
*)aIt
.next())->approveFiring( aScriptEvent
);
319 Reference
< XIdlClass
> xListenerType
= mpManager
->getReflection()->
320 forName( Event
.ListenerType
.getTypeName() );
321 Reference
< XIdlMethod
> xMeth
= xListenerType
->getMethod( Event
.MethodName
);
324 Reference
< XIdlClass
> xRetType
= xMeth
->getReturnType();
325 Type
aRetType(xRetType
->getTypeClass(), xRetType
->getName());
326 convertToEventReturn( aRet
, aRetType
);
329 switch( aRet
.getValueType().getTypeClass() )
331 case TypeClass_INTERFACE
:
333 // Interface not null, return
334 Reference
< XInterface
> x
;
341 case TypeClass_BOOLEAN
:
343 if( !(*(sal_Bool
*)aRet
.getValue()) )
347 case TypeClass_STRING
:
348 // none empty string -> return
349 if( ((OUString
*)aRet
.getValue())->getLength() > 0 )
353 // none zero number -> return
354 case TypeClass_FLOAT
: if( *((float*)aRet
.getValue()) ) return aRet
; break;
355 case TypeClass_DOUBLE
: if( *((double*)aRet
.getValue()) ) return aRet
; break;
356 case TypeClass_BYTE
: if( *((sal_uInt8
*)aRet
.getValue()) ) return aRet
; break;
357 case TypeClass_SHORT
: if( *((sal_Int16
*)aRet
.getValue()) ) return aRet
; break;
358 case TypeClass_LONG
: if( *((sal_Int32
*)aRet
.getValue()) ) return aRet
; break;
359 case TypeClass_UNSIGNED_SHORT
: if( *((sal_uInt16
*)aRet
.getValue()) ) return aRet
; break;
360 case TypeClass_UNSIGNED_LONG
: if( *((sal_uInt32
*)aRet
.getValue()) ) return aRet
; break;
367 catch( CannotConvertException
& )
369 // silent ignore conversions errors from a script call
370 Reference
< XIdlClass
> xListenerType
= mpManager
->getReflection()->
371 forName( Event
.ListenerType
.getTypeName() );
372 Reference
< XIdlMethod
> xMeth
= xListenerType
->getMethod( Event
.MethodName
);
375 Reference
< XIdlClass
> xRetType
= xMeth
->getReturnType();
376 Type
aRetType(xRetType
->getTypeClass(), xRetType
->getName());
378 convertToEventReturn( aRet
, aRetType
);
385 //========================================================================
386 // Methoden von XEventListener
387 void SAL_CALL
AttacherAllListener_Impl::disposing(const EventObject
& )
388 throw( RuntimeException
)
390 // It is up to the container to release the object
394 //========================================================================
395 //========================================================================
396 //========================================================================
398 // Create-Methode fuer EventAttacherManager
399 Reference
< XEventAttacherManager
> createEventAttacherManager( const Reference
< XIntrospection
> & rIntrospection
,
400 const Reference
< XMultiServiceFactory
> & rSMgr
)
403 return new ImplEventAttacherManager( rIntrospection
, rSMgr
);
406 // Create-Methode fuer EventAttacherManager
407 Reference
< XEventAttacherManager
> createEventAttacherManager( const Reference
< XMultiServiceFactory
> & rSMgr
)
412 Reference
< XInterface
> xIFace( rSMgr
->createInstance( OUString::createFromAscii("com.sun.star.beans.Introspection") ) );
415 Reference
< XIntrospection
> xIntrospection( xIFace
, UNO_QUERY
);
416 return new ImplEventAttacherManager( xIntrospection
, rSMgr
);
420 return Reference
< XEventAttacherManager
>();
423 //-----------------------------------------------------------------------------
424 ImplEventAttacherManager::ImplEventAttacherManager( const Reference
< XIntrospection
> & rIntrospection
,
425 const Reference
< XMultiServiceFactory
> rSMgr
)
426 : aScriptListeners( aLock
)
428 , mxIntrospection( rIntrospection
)
432 Reference
< XInterface
> xIFace( rSMgr
->createInstance( OUString::createFromAscii("com.sun.star.script.EventAttacher") ) );
435 xAttacher
= Reference
< XEventAttacher
>::query( xIFace
);
437 xIFace
= rSMgr
->createInstance( OUString::createFromAscii("com.sun.star.script.Converter") );
440 xConverter
= Reference
< XTypeConverter
>::query( xIFace
);
444 Reference
< XInitialization
> xInit( xAttacher
, UNO_QUERY
);
447 Sequence
< Any
> Arguments( 1 );
448 Arguments
[0] <<= rIntrospection
;
449 xInit
->initialize( Arguments
);
453 //-----------------------------------------------------------------------------
454 ImplEventAttacherManager::~ImplEventAttacherManager()
458 Reference
< XIdlReflection
> ImplEventAttacherManager::getReflection() throw( Exception
)
460 Guard
< Mutex
> aGuard( aLock
);
461 // Haben wir den Service schon? Sonst anlegen
462 if( !mxCoreReflection
.is() )
464 Reference
< XInterface
> xIFace( mxSMgr
->createInstance( OUString::createFromAscii("com.sun.star.reflection.CoreReflection") ) );
465 mxCoreReflection
= Reference
< XIdlReflection
>( xIFace
, UNO_QUERY
);
467 return mxCoreReflection
;
471 //-----------------------------------------------------------------------------
472 ::std::deque
<AttacherIndex_Impl
>::iterator
ImplEventAttacherManager::implCheckIndex( sal_Int32 _nIndex
) SAL_THROW ( ( IllegalArgumentException
) )
475 throw IllegalArgumentException();
477 ::std::deque
<AttacherIndex_Impl
>::iterator aIt
= aIndex
.begin();
478 for ( sal_Int32 i
= 0; (i
< _nIndex
) && (aIt
!= aIndex
.end()); ++i
, ++aIt
)
481 if( aIt
== aIndex
.end() )
482 throw IllegalArgumentException();
487 //-----------------------------------------------------------------------------
490 ImplEventAttacherManager
* pMgr
,
492 ::std::deque
< AttachedObject_Impl
> & rList
495 ::std::deque
< AttachedObject_Impl
>::iterator aObjIt
= rList
.begin();
496 ::std::deque
< AttachedObject_Impl
>::iterator aObjEnd
= rList
.end();
497 while( aObjIt
!= aObjEnd
)
499 pMgr
->detach( nIdx
, (*aObjIt
).xTarget
);
504 //-----------------------------------------------------------------------------
507 ImplEventAttacherManager
* pMgr
,
509 ::std::deque
< AttachedObject_Impl
> & rList
512 ::std::deque
< AttachedObject_Impl
>::iterator aObjIt
= rList
.begin();
513 ::std::deque
< AttachedObject_Impl
>::iterator aObjEnd
= rList
.end();
514 while( aObjIt
!= aObjEnd
)
516 pMgr
->attach( nIdx
, (*aObjIt
).xTarget
, (*aObjIt
).aHelper
);
521 //-----------------------------------------------------------------------------
522 //*** Methoden von XEventAttacherManager ***
523 void SAL_CALL
ImplEventAttacherManager::registerScriptEvent
526 const ScriptEventDescriptor
& ScriptEvent
528 throw( IllegalArgumentException
, RuntimeException
)
530 Guard
< Mutex
> aGuard( aLock
);
532 // Index pruefen und Array anpassen
533 ::std::deque
<AttacherIndex_Impl
>::iterator aIt
= implCheckIndex( nIndex
);
535 ::std::deque
< AttachedObject_Impl
> aList
= (*aIt
).aObjList
;
537 ScriptEventDescriptor aEvt
= ScriptEvent
;
538 const sal_Unicode
* pLastDot
= aEvt
.ListenerType
.getStr();
539 pLastDot
+= rtl_ustr_lastIndexOfChar( pLastDot
, '.' );
541 aEvt
.ListenerType
= pLastDot
+1;
543 (*aIt
).aEventList
.push_back( aEvt
);
545 (*aIt
).aEventList
.realloc( (*aIt
).aEventList
.getLength() +1 );
546 (*aIt
).aEventList
.getArray()[(*aIt
).aEventList
.getLength() -1] = aEvt
;
549 // register new new Event
550 ::std::deque
< AttachedObject_Impl
>::iterator aObjIt
= (*aIt
).aObjList
.begin();
551 ::std::deque
< AttachedObject_Impl
>::iterator aObjEnd
= (*aIt
).aObjList
.end();
552 while( aObjIt
!= aObjEnd
)
555 sal_Int32 nPos
= (*aObjIt
).aAttachedListenerSeq
.getLength();
556 (*aObjIt
).aAttachedListenerSeq
.realloc( nPos
+ 1 );
557 Reference
< XEventListener
> * pArray
= (*aObjIt
).aAttachedListenerSeq
.getArray();
559 Reference
< XAllListener
> xAll
=
560 new AttacherAllListener_Impl( this, ScriptEvent
.ScriptType
, ScriptEvent
.ScriptCode
);
563 pArray
[nPos
] = xAttacher
->attachSingleEventListener( (*aObjIt
).xTarget
, xAll
,
564 (*aObjIt
).aHelper
, ScriptEvent
.ListenerType
,
565 ScriptEvent
.AddListenerParam
, ScriptEvent
.EventMethod
);
575 //-----------------------------------------------------------------------------
576 void SAL_CALL
ImplEventAttacherManager::registerScriptEvents
579 const Sequence
< ScriptEventDescriptor
>& ScriptEvents
581 throw( IllegalArgumentException
, RuntimeException
)
583 Guard
< Mutex
> aGuard( aLock
);
585 // Index pruefen und Array anpassen
586 ::std::deque
<AttacherIndex_Impl
>::iterator aIt
= implCheckIndex( nIndex
);
588 ::std::deque
< AttachedObject_Impl
> aList
= (*aIt
).aObjList
;
589 detachAll_Impl( this, nIndex
, aList
);
591 const ScriptEventDescriptor
* pArray
= ScriptEvents
.getConstArray();
592 sal_Int32 nLen
= ScriptEvents
.getLength();
593 for( sal_Int32 i
= 0 ; i
< nLen
; i
++ )
594 registerScriptEvent( nIndex
, pArray
[ i
] );
596 attachAll_Impl( this, nIndex
, aList
);
599 //-----------------------------------------------------------------------------
600 void SAL_CALL
ImplEventAttacherManager::revokeScriptEvent
603 const OUString
& ListenerType
,
604 const OUString
& EventMethod
,
605 const OUString
& ToRemoveListenerParam
607 throw( IllegalArgumentException
, RuntimeException
)
609 Guard
< Mutex
> aGuard( aLock
);
611 ::std::deque
<AttacherIndex_Impl
>::iterator aIt
= implCheckIndex( nIndex
);
613 ::std::deque
< AttachedObject_Impl
> aList
= (*aIt
).aObjList
;
614 detachAll_Impl( this, nIndex
, aList
);
616 OUString aLstType
= ListenerType
;
617 const sal_Unicode
* pLastDot
= aLstType
.getStr();
618 pLastDot
+= rtl_ustr_lastIndexOfChar( pLastDot
, '.' );
620 aLstType
= pLastDot
+1;
623 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtIt
= (*aIt
).aEventList
.begin();
624 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtEnd
= (*aIt
).aEventList
.end();
625 while( aEvtIt
!= aEvtEnd
)
627 if( aLstType
== (*aEvtIt
).ListenerType
628 && EventMethod
== (*aEvtIt
).EventMethod
629 && ToRemoveListenerParam
== (*aEvtIt
).AddListenerParam
)
631 (*aIt
).aEventList
.erase( aEvtIt
);
638 Sequence
< ScriptEventDescriptor
>& rEventList
= (*aIt
).aEventList
;
640 ScriptEventDescriptor
* pEventList
= rEventList
.getArray();
641 const ScriptEventDescriptor
* pEventListEnd
= pEventList
+ rEventList
.getLength();
642 for( ; pEventList
< pEventListEnd
; ++pEventList
)
644 if ( (aLstType
== pEventList
->ListenerType
)
645 && (EventMethod
== pEventList
->EventMethod
)
646 && (ToRemoveListenerParam
== pEventList
->AddListenerParam
)
649 ScriptEventDescriptor
* pMoveTo
= pEventList
;
650 const ScriptEventDescriptor
* pMoveFrom
= pMoveTo
+ 1;
651 while (pMoveFrom
< pEventListEnd
)
653 *pMoveTo
++ = *pMoveFrom
++;
655 rEventList
.realloc( rEventList
.getLength() - 1 );
660 attachAll_Impl( this, nIndex
, aList
);
663 //-----------------------------------------------------------------------------
664 void SAL_CALL
ImplEventAttacherManager::revokeScriptEvents(sal_Int32 nIndex
)
665 throw( IllegalArgumentException
, RuntimeException
)
667 Guard
< Mutex
> aGuard( aLock
);
668 ::std::deque
<AttacherIndex_Impl
>::iterator aIt
= implCheckIndex( nIndex
);
670 ::std::deque
< AttachedObject_Impl
> aList
= (*aIt
).aObjList
;
671 detachAll_Impl( this, nIndex
, aList
);
673 (*aIt
).aEventList
= ::std::deque
< ScriptEventDescriptor
>();
675 (*aIt
).aEventList
.realloc( 0 );
677 attachAll_Impl( this, nIndex
, aList
);
680 //-----------------------------------------------------------------------------
681 void SAL_CALL
ImplEventAttacherManager::insertEntry(sal_Int32 nIndex
)
682 throw( IllegalArgumentException
, RuntimeException
)
684 Guard
< Mutex
> aGuard( aLock
);
686 throw IllegalArgumentException();
688 // ::std::deque<AttacherIndex_Impl>::iterator aIt = aIndex.begin();
692 if ( static_cast< ::std::deque
< AttacherIndex_Impl
>::size_type
>(nIndex
) >= aIndex
.size() )
693 aIndex
.resize(nIndex
+1);
695 AttacherIndex_Impl aTmp
;
696 aIndex
.insert( aIndex
.begin() + nIndex
, aTmp
);
699 //-----------------------------------------------------------------------------
700 void SAL_CALL
ImplEventAttacherManager::removeEntry(sal_Int32 nIndex
)
701 throw( IllegalArgumentException
, RuntimeException
)
703 Guard
< Mutex
> aGuard( aLock
);
704 ::std::deque
<AttacherIndex_Impl
>::iterator aIt
= implCheckIndex( nIndex
);
706 ::std::deque
< AttachedObject_Impl
> aList
= (*aIt
).aObjList
;
707 detachAll_Impl( this, nIndex
, aList
);
711 //-----------------------------------------------------------------------------
712 Sequence
< ScriptEventDescriptor
> SAL_CALL
ImplEventAttacherManager::getScriptEvents(sal_Int32 nIndex
)
713 throw( IllegalArgumentException
, RuntimeException
)
715 Guard
< Mutex
> aGuard( aLock
);
716 ::std::deque
<AttacherIndex_Impl
>::iterator aIt
= implCheckIndex( nIndex
);
719 Sequence
< ScriptEventDescriptor
> aSeq( (*aIt
).aEventList
.size() );
720 ScriptEventDescriptor
* pArray
= aSeq
.getArray();
722 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtIt
= (*aIt
).aEventList
.begin();
723 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtEnd
= (*aIt
).aEventList
.end();
725 while( aEvtIt
!= aEvtEnd
)
727 pArray
[i
++] = *aEvtIt
;
732 return (*aIt
).aEventList
;
736 //-----------------------------------------------------------------------------
737 void SAL_CALL
ImplEventAttacherManager::attach(sal_Int32 nIndex
, const Reference
< XInterface
>& xObject
, const Any
& Helper
)
738 throw( IllegalArgumentException
, ServiceNotRegisteredException
, RuntimeException
)
740 Guard
< Mutex
> aGuard( aLock
);
741 if( nIndex
< 0 || !xObject
.is() )
742 throw IllegalArgumentException();
744 if( static_cast< ::std::deque
< AttacherIndex_Impl
>::size_type
>(nIndex
) >= aIndex
.size() )
746 // alte Dateien lesen
749 insertEntry( nIndex
);
750 attach( nIndex
, xObject
, Helper
);
754 throw IllegalArgumentException();
757 ::std::deque
< AttacherIndex_Impl
>::iterator aCurrentPosition
= aIndex
.begin() + nIndex
;
759 AttachedObject_Impl aTmp
;
760 aTmp
.xTarget
= xObject
;
761 aTmp
.aHelper
= Helper
;
762 aCurrentPosition
->aObjList
.push_back( aTmp
);
764 //::std::deque< AttachedObject_Impl >::iterator aObjIt = (*aIt).aObjList.back();
765 AttachedObject_Impl
& rCurObj
= aCurrentPosition
->aObjList
.back();
767 rCurObj
.aAttachedListenerSeq
= Sequence
< Reference
< XEventListener
> >( aCurrentPosition
->aEventList
.size() );
769 rCurObj
.aAttachedListenerSeq
= Sequence
< Reference
< XEventListener
> >( aCurrentPosition
->aEventList
.getLength() );
771 Reference
< XEventListener
> * pArray
= rCurObj
.aAttachedListenerSeq
.getArray();
774 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtIt
= aCurrentPosition
->aEventList
.begin();
775 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtEnd
= aCurrentPosition
->aEventList
.end();
777 while( aEvtIt
!= aEvtEnd
)
779 Reference
< XAllListener
> xAll
=
780 new AttacherAllListener_Impl( this, (*aEvtIt
).ScriptType
, (*aEvtIt
).ScriptCode
);
781 Reference
< XEventListener
> xAdapter
;
784 xAdapter
= xAttacher
->attachSingleEventListener( rCurObj
.xTarget
, xAll
,
785 rCurObj
.aHelper
, (*aEvtIt
).ScriptType
,
786 (*aEvtIt
).AddListenerParam
, (*aEvtIt
).EventMethod
);
792 pArray
[i
++] = xAdapter
;
796 sal_Int32 nLen
= aCurrentPosition
->aEventList
.getLength();
797 ScriptEventDescriptor
* pEL
= aCurrentPosition
->aEventList
.getArray();
798 for(sal_Int32 i
= 0; i
< nLen
; ++i
)
800 Reference
< XAllListener
> xAll
=
801 new AttacherAllListener_Impl( this, pEL
[i
].ScriptType
, pEL
[i
].ScriptCode
);
802 Reference
< XEventListener
> xAdapter
;
805 xAdapter
= xAttacher
->attachSingleEventListener( rCurObj
.xTarget
, xAll
,
806 rCurObj
.aHelper
, pEL
[i
].ListenerType
,
807 pEL
[i
].AddListenerParam
, pEL
[i
].EventMethod
);
813 pArray
[i
] = xAdapter
;
818 //-----------------------------------------------------------------------------
819 void SAL_CALL
ImplEventAttacherManager::detach(sal_Int32 nIndex
, const Reference
< XInterface
>& xObject
)
820 throw( IllegalArgumentException
, RuntimeException
)
822 Guard
< Mutex
> aGuard( aLock
);
824 if( nIndex
< 0 || static_cast< ::std::deque
< AttacherIndex_Impl
>::size_type
>(nIndex
) >= aIndex
.size() || !xObject
.is() )
825 throw IllegalArgumentException();
827 ::std::deque
< AttacherIndex_Impl
>::iterator aCurrentPosition
= aIndex
.begin() + nIndex
;
828 ::std::deque
< AttachedObject_Impl
>::iterator aObjIt
= aCurrentPosition
->aObjList
.begin();
829 ::std::deque
< AttachedObject_Impl
>::iterator aObjEnd
= aCurrentPosition
->aObjList
.end();
830 while( aObjIt
!= aObjEnd
)
832 if( (*aObjIt
).xTarget
== xObject
)
834 Reference
< XEventListener
> * pArray
= (*aObjIt
).aAttachedListenerSeq
.getArray();
837 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtIt
= aCurrentPosition
->aEventList
.begin();
838 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtEnd
= aCurrentPosition
->aEventList
.end();
840 while( aEvtIt
!= aEvtEnd
)
846 xAttacher
->removeListener( (*aObjIt
).xTarget
, (*aEvtIt
).ListenerType
,
847 (*aEvtIt
).AddListenerParam
, pArray
[i
] );
857 sal_Int32 nLen
= aCurrentPosition
->aEventList
.getLength();
858 ScriptEventDescriptor
* pEL
= aCurrentPosition
->aEventList
.getArray();
859 for( sal_Int32 i
= 0; i
< nLen
; i
++ )
865 xAttacher
->removeListener( (*aObjIt
).xTarget
, pEL
[i
].ListenerType
,
866 pEL
[i
].AddListenerParam
, pArray
[i
] );
874 aCurrentPosition
->aObjList
.erase( aObjIt
);
881 void SAL_CALL
ImplEventAttacherManager::addScriptListener(const Reference
< XScriptListener
>& aListener
)
882 throw( IllegalArgumentException
, RuntimeException
)
884 Guard
< Mutex
> aGuard( aLock
);
885 aScriptListeners
.addInterface( aListener
);
888 void SAL_CALL
ImplEventAttacherManager::removeScriptListener(const Reference
< XScriptListener
>& aListener
)
889 throw( IllegalArgumentException
, RuntimeException
)
891 Guard
< Mutex
> aGuard( aLock
);
892 aScriptListeners
.removeInterface( aListener
);
896 // Methoden von XPersistObject
897 OUString SAL_CALL
ImplEventAttacherManager::getServiceName(void)
898 throw( RuntimeException
)
900 return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.script.EventAttacherManager") );
903 void SAL_CALL
ImplEventAttacherManager::write(const Reference
< XObjectOutputStream
>& OutStream
)
904 throw( IOException
, RuntimeException
)
906 Guard
< Mutex
> aGuard( aLock
);
907 // Ohne XMarkableStream laeuft nichts
908 Reference
< XMarkableStream
> xMarkStream( OutStream
, UNO_QUERY
);
909 if( !xMarkStream
.is() )
913 OutStream
->writeShort( 2 );
915 // Position fuer Laenge merken
916 sal_Int32 nObjLenMark
= xMarkStream
->createMark();
917 OutStream
->writeLong( 0L );
919 OutStream
->writeLong( aIndex
.size() );
921 // Sequences schreiben
922 ::std::deque
<AttacherIndex_Impl
>::iterator aIt
= aIndex
.begin();
923 ::std::deque
<AttacherIndex_Impl
>::iterator aEnd
= aIndex
.end();
927 // Laenge der Sequence und alle Descriptoren schreiben
928 OutStream
->writeLong( (*aIt
).aEventList
.size() );
929 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtIt
= (*aIt
).aEventList
.begin();
930 ::std::deque
< ScriptEventDescriptor
>::iterator aEvtEnd
= (*aIt
).aEventList
.end();
931 while( aEvtIt
!= aEvtEnd
)
933 const ScriptEventDescriptor
& rDesc
= (*aEvtIt
);
934 OutStream
->writeUTF( rDesc
.ListenerType
);
935 OutStream
->writeUTF( rDesc
.EventMethod
);
936 OutStream
->writeUTF( rDesc
.AddListenerParam
);
937 OutStream
->writeUTF( rDesc
.ScriptType
);
938 OutStream
->writeUTF( rDesc
.ScriptCode
);
943 sal_Int32 nLen
= (*aIt
).aEventList
.getLength();
944 // Laenge der Sequence und alle Descriptoren schreiben
945 OutStream
->writeLong( nLen
);
946 ScriptEventDescriptor
* pEL
= (*aIt
).aEventList
.getArray();
947 for( sal_Int32 i
= 0; i
< nLen
; i
++ )
949 const ScriptEventDescriptor
& rDesc
= pEL
[i
];
950 OutStream
->writeUTF( rDesc
.ListenerType
);
951 OutStream
->writeUTF( rDesc
.EventMethod
);
952 OutStream
->writeUTF( rDesc
.AddListenerParam
);
953 OutStream
->writeUTF( rDesc
.ScriptType
);
954 OutStream
->writeUTF( rDesc
.ScriptCode
);
960 // Die jetzt bekannte Laenge eintragen
961 sal_Int32 nObjLen
= xMarkStream
->offsetToMark( nObjLenMark
) -4;
962 xMarkStream
->jumpToMark( nObjLenMark
);
963 OutStream
->writeLong( nObjLen
);
964 xMarkStream
->jumpToFurthest();
965 xMarkStream
->deleteMark( nObjLenMark
);
968 void SAL_CALL
ImplEventAttacherManager::read(const Reference
< XObjectInputStream
>& InStream
)
969 throw( IOException
, RuntimeException
)
971 Guard
< Mutex
> aGuard( aLock
);
972 // Ohne XMarkableStream laeuft nichts
973 Reference
< XMarkableStream
> xMarkStream( InStream
, UNO_QUERY
);
974 if( !xMarkStream
.is() )
978 nVersion
= InStream
->readShort();
980 // Zunaechst kommen die Daten gemaess Version 1,
981 // muss auch bei hoeheren Versionen beibehalten werden
982 sal_Int32 nLen
= InStream
->readLong();
984 // Position fuer Vergleichszwecke
985 sal_Int32 nObjLenMark
= xMarkStream
->createMark();
987 // Anzahl der zu lesenden Sequences
988 sal_Int32 nItemCount
= InStream
->readLong();
990 for( sal_Int32 i
= 0 ; i
< nItemCount
; i
++ )
993 // Laenge der Sequence lesen
994 sal_Int32 nSeqLen
= InStream
->readLong();
996 // Sequence anlegen und Descriptoren lesen
997 Sequence
< ScriptEventDescriptor
> aSEDSeq( nSeqLen
);
998 ScriptEventDescriptor
* pArray
= aSEDSeq
.getArray();
999 for( sal_Int32 j
= 0 ; j
< nSeqLen
; j
++ )
1001 ScriptEventDescriptor
& rDesc
= pArray
[ j
];
1002 rDesc
.ListenerType
= InStream
->readUTF();
1003 rDesc
.EventMethod
= InStream
->readUTF();
1004 rDesc
.AddListenerParam
= InStream
->readUTF();
1005 rDesc
.ScriptType
= InStream
->readUTF();
1006 rDesc
.ScriptCode
= InStream
->readUTF();
1008 registerScriptEvents( i
, aSEDSeq
);
1011 // Haben wir die angegebene Laenge gelesen?
1012 sal_Int32 nRealLen
= xMarkStream
->offsetToMark( nObjLenMark
);
1013 if( nRealLen
!= nLen
)
1015 // Nur wenn die StreamVersion > 1 ist und noch Daten folgen, kann das
1016 // Ganze richtig sein. Sonst ist etwas voellig daneben gegangen.
1017 if( nRealLen
> nLen
|| nVersion
== 1 )
1019 VOS_ENSHURE( sal_False
, "ImplEventAttacherManager::read(): Fatal Error, wrong object length" );
1023 // TODO: Pruefen, ob Zwischen-Speicherung der Daten sinnvoll sein koennte
1025 // Vorerst einfach nur Skippen
1026 sal_Int32 nSkipCount
= nLen
- nRealLen
;
1027 InStream
->skipBytes( nSkipCount
);
1030 xMarkStream
->jumpToFurthest();
1031 xMarkStream
->deleteMark( nObjLenMark
);
1034 } // namesapce comphelper