1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 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. 14 * 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). 20 * 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. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_comphelper.hxx" 30 31 #include <deque> 32 33 #if defined( OS2 ) || defined( UNX ) 34 #include <wchar.h> 35 #endif 36 #include <osl/mutex.hxx> 37 #ifndef _VOS_DIAGNOSE_HXX_ 38 #include <vos/diagnose.hxx> 39 #endif 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> 61 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; 68 using namespace cppu; 69 using namespace osl; 70 using namespace rtl; 71 72 namespace comphelper 73 { 74 75 //----------------------------------------------------------------------------- 76 struct AttachedObject_Impl 77 { 78 Reference< XInterface > xTarget; 79 Sequence< Reference< XEventListener > > aAttachedListenerSeq; 80 Any aHelper; 81 82 bool operator<( const AttachedObject_Impl & ) const; 83 bool operator==( const AttachedObject_Impl & ) const; 84 }; 85 86 struct AttacherIndex_Impl 87 { 88 #ifdef DEQUE_OK 89 ::std::deque< ScriptEventDescriptor > aEventList; 90 #else 91 Sequence< ScriptEventDescriptor > aEventList; 92 #endif 93 ::std::deque< AttachedObject_Impl > aObjList; 94 95 bool operator<( const AttacherIndex_Impl & ) const; 96 bool operator==( const AttacherIndex_Impl & ) const; 97 }; 98 99 #if 0 100 bool AttachedObject_Impl::operator<( const AttachedObject_Impl & r ) const 101 { 102 VOS_ENSHURE( FALSE, "not implemented" ); 103 return FALSE; 104 return this < &r; 105 } 106 107 bool AttachedObject_Impl::operator==( const AttachedObject_Impl & r ) const 108 { 109 VOS_ENSHURE( FALSE, "not implemented" ); 110 return this == &r; 111 } 112 113 bool AttacherIndex_Impl::operator<( const AttacherIndex_Impl & r ) const 114 { 115 VOS_ENSHURE( FALSE, "not implemented" ); 116 return this < &r; 117 } 118 bool AttacherIndex_Impl::operator==( const AttacherIndex_Impl & r ) const 119 { 120 VOS_ENSHURE( FALSE, "not implemented" ); 121 return this == &r; 122 } 123 #endif 124 125 //----------------------------------------------------------------------------- 126 class ImplEventAttacherManager 127 : public WeakImplHelper2< XEventAttacherManager, XPersistObject > 128 { 129 friend class AttacherAllListener_Impl; 130 ::std::deque< AttacherIndex_Impl > aIndex; 131 Mutex aLock; 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; 140 sal_Int16 nVersion; 141 public: 142 ImplEventAttacherManager( const Reference< XIntrospection > & rIntrospection, 143 const Reference< XMultiServiceFactory > rSMgr ); 144 ~ImplEventAttacherManager(); 145 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 ); 169 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 ); 174 175 private: 176 Reference< XIdlReflection > getReflection() throw( Exception ); 177 178 /** checks if <arg>_nIndex</arg> is a valid index, throws an <type>IllegalArgumentException</type> if not 179 @param _nIndex 180 the index to check 181 @return 182 the iterator pointing to the position indicated by the index 183 */ 184 ::std::deque<AttacherIndex_Impl>::iterator implCheckIndex( sal_Int32 _nIndex ) SAL_THROW ( ( IllegalArgumentException ) ); 185 }; 186 187 //======================================================================== 188 //======================================================================== 189 //======================================================================== 190 191 // Implementation eines EventAttacher-bezogenen AllListeners, der 192 // nur einzelne Events an einen allgemeinen AllListener weiterleitet 193 class AttacherAllListener_Impl : public WeakImplHelper1< XAllListener > 194 { 195 ImplEventAttacherManager* mpManager; 196 Reference< XEventAttacherManager > xManager; 197 OUString aScriptType; 198 OUString aScriptCode; 199 sal_Int16 nVersion; 200 201 void convertToEventReturn( Any & rRet, const Type & rRetType ) 202 throw( CannotConvertException ); 203 public: 204 AttacherAllListener_Impl( ImplEventAttacherManager* pManager_, const OUString &rScriptType_, 205 const OUString & rScriptCode_ ); 206 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 ); 210 211 // Methoden von XEventListener 212 virtual void SAL_CALL disposing(const EventObject& Source) throw( RuntimeException ); 213 }; 214 215 //======================================================================== 216 AttacherAllListener_Impl::AttacherAllListener_Impl 217 ( 218 ImplEventAttacherManager* pManager_, 219 const OUString & rScriptType_, 220 const OUString & rScriptCode_ 221 ) 222 : mpManager( pManager_ ) 223 , xManager( pManager_ ) 224 , aScriptType( rScriptType_ ) 225 , aScriptCode( rScriptCode_ ) 226 , nVersion( 2 ) 227 { 228 } 229 230 231 //======================================================================== 232 // Methoden von XAllListener 233 void SAL_CALL AttacherAllListener_Impl::firing(const AllEventObject& Event) 234 throw( RuntimeException ) 235 { 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; 244 245 // ueber alle Listener iterieren und Events senden 246 OInterfaceIteratorHelper aIt( mpManager->aScriptListeners ); 247 while( aIt.hasMoreElements() ) 248 ((XScriptListener *)aIt.next())->firing( aScriptEvent ); 249 } 250 251 //======================================================================== 252 // Convert to the standard event return 253 void AttacherAllListener_Impl::convertToEventReturn( Any & rRet, const Type & rRetType ) 254 throw( CannotConvertException ) 255 { 256 // no return value? Set to the specified values 257 if( rRet.getValueType().getTypeClass() == TypeClass_VOID ) 258 { 259 switch( rRetType.getTypeClass() ) 260 { 261 case TypeClass_INTERFACE: 262 { 263 rRet <<= Reference< XInterface >(); 264 } 265 break; 266 267 case TypeClass_BOOLEAN: 268 rRet <<= sal_True; 269 break; 270 271 case TypeClass_STRING: 272 rRet <<= OUString(); 273 break; 274 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; 282 283 default: 284 OSL_ASSERT(false); 285 break; 286 } 287 } 288 else if( !rRet.getValueType().equals( rRetType ) ) 289 { 290 if( mpManager->xConverter.is() ) 291 rRet = mpManager->xConverter->convertTo( rRet, rRetType ); 292 else 293 throw CannotConvertException(); 294 } 295 } 296 297 //======================================================================== 298 // Methoden von XAllListener 299 Any SAL_CALL AttacherAllListener_Impl::approveFiring( const AllEventObject& Event ) 300 throw( InvocationTargetException, RuntimeException ) 301 { 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; 310 311 Any aRet; 312 // ueber alle Listener iterieren und Events senden 313 OInterfaceIteratorHelper aIt( mpManager->aScriptListeners ); 314 while( aIt.hasMoreElements() ) 315 { 316 aRet = ((XScriptListener *)aIt.next())->approveFiring( aScriptEvent ); 317 try 318 { 319 Reference< XIdlClass > xListenerType = mpManager->getReflection()-> 320 forName( Event.ListenerType.getTypeName() ); 321 Reference< XIdlMethod > xMeth = xListenerType->getMethod( Event.MethodName ); 322 if( xMeth.is() ) 323 { 324 Reference< XIdlClass > xRetType = xMeth->getReturnType(); 325 Type aRetType(xRetType->getTypeClass(), xRetType->getName()); 326 convertToEventReturn( aRet, aRetType ); 327 } 328 329 switch( aRet.getValueType().getTypeClass() ) 330 { 331 case TypeClass_INTERFACE: 332 { 333 // Interface not null, return 334 Reference< XInterface > x; 335 aRet >>= x; 336 if( x.is() ) 337 return aRet; 338 } 339 break; 340 341 case TypeClass_BOOLEAN: 342 // FALSE -> Return 343 if( !(*(sal_Bool*)aRet.getValue()) ) 344 return aRet; 345 break; 346 347 case TypeClass_STRING: 348 // none empty string -> return 349 if( ((OUString*)aRet.getValue())->getLength() > 0 ) 350 return aRet; 351 break; 352 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; 361 362 default: 363 OSL_ASSERT(false); 364 break; 365 } 366 } 367 catch( CannotConvertException& ) 368 { 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 ); 373 if( xMeth.is() ) 374 { 375 Reference< XIdlClass > xRetType = xMeth->getReturnType(); 376 Type aRetType(xRetType->getTypeClass(), xRetType->getName()); 377 aRet.clear(); 378 convertToEventReturn( aRet, aRetType ); 379 } 380 } 381 } 382 return aRet; 383 } 384 385 //======================================================================== 386 // Methoden von XEventListener 387 void SAL_CALL AttacherAllListener_Impl::disposing(const EventObject& ) 388 throw( RuntimeException ) 389 { 390 // It is up to the container to release the object 391 } 392 393 394 //======================================================================== 395 //======================================================================== 396 //======================================================================== 397 398 // Create-Methode fuer EventAttacherManager 399 Reference< XEventAttacherManager > createEventAttacherManager( const Reference< XIntrospection > & rIntrospection, 400 const Reference< XMultiServiceFactory > & rSMgr ) 401 throw( Exception ) 402 { 403 return new ImplEventAttacherManager( rIntrospection, rSMgr ); 404 } 405 406 // Create-Methode fuer EventAttacherManager 407 Reference< XEventAttacherManager > createEventAttacherManager( const Reference< XMultiServiceFactory > & rSMgr ) 408 throw( Exception ) 409 { 410 if ( rSMgr.is() ) 411 { 412 Reference< XInterface > xIFace( rSMgr->createInstance( OUString::createFromAscii("com.sun.star.beans.Introspection") ) ); 413 if ( xIFace.is() ) 414 { 415 Reference< XIntrospection > xIntrospection( xIFace, UNO_QUERY); 416 return new ImplEventAttacherManager( xIntrospection, rSMgr ); 417 } 418 } 419 420 return Reference< XEventAttacherManager >(); 421 } 422 423 //----------------------------------------------------------------------------- 424 ImplEventAttacherManager::ImplEventAttacherManager( const Reference< XIntrospection > & rIntrospection, 425 const Reference< XMultiServiceFactory > rSMgr ) 426 : aScriptListeners( aLock ) 427 , mxSMgr( rSMgr ) 428 , mxIntrospection( rIntrospection ) 429 { 430 if ( rSMgr.is() ) 431 { 432 Reference< XInterface > xIFace( rSMgr->createInstance( OUString::createFromAscii("com.sun.star.script.EventAttacher") ) ); 433 if ( xIFace.is() ) 434 { 435 xAttacher = Reference< XEventAttacher >::query( xIFace ); 436 } 437 xIFace = rSMgr->createInstance( OUString::createFromAscii("com.sun.star.script.Converter") ); 438 if ( xIFace.is() ) 439 { 440 xConverter = Reference< XTypeConverter >::query( xIFace ); 441 } 442 } 443 444 Reference< XInitialization > xInit( xAttacher, UNO_QUERY ); 445 if( xInit.is() ) 446 { 447 Sequence< Any > Arguments( 1 ); 448 Arguments[0] <<= rIntrospection; 449 xInit->initialize( Arguments ); 450 } 451 } 452 453 //----------------------------------------------------------------------------- 454 ImplEventAttacherManager::~ImplEventAttacherManager() 455 { 456 } 457 458 Reference< XIdlReflection > ImplEventAttacherManager::getReflection() throw( Exception ) 459 { 460 Guard< Mutex > aGuard( aLock ); 461 // Haben wir den Service schon? Sonst anlegen 462 if( !mxCoreReflection.is() ) 463 { 464 Reference< XInterface > xIFace( mxSMgr->createInstance( OUString::createFromAscii("com.sun.star.reflection.CoreReflection") ) ); 465 mxCoreReflection = Reference< XIdlReflection >( xIFace, UNO_QUERY); 466 } 467 return mxCoreReflection; 468 } 469 470 471 //----------------------------------------------------------------------------- 472 ::std::deque<AttacherIndex_Impl>::iterator ImplEventAttacherManager::implCheckIndex( sal_Int32 _nIndex ) SAL_THROW ( ( IllegalArgumentException ) ) 473 { 474 if (_nIndex < 0) 475 throw IllegalArgumentException(); 476 477 ::std::deque<AttacherIndex_Impl>::iterator aIt = aIndex.begin(); 478 for ( sal_Int32 i = 0; (i < _nIndex) && (aIt != aIndex.end()); ++i, ++aIt ) 479 ; 480 481 if( aIt == aIndex.end() ) 482 throw IllegalArgumentException(); 483 484 return aIt; 485 } 486 487 //----------------------------------------------------------------------------- 488 void detachAll_Impl 489 ( 490 ImplEventAttacherManager * pMgr, 491 sal_Int32 nIdx, 492 ::std::deque< AttachedObject_Impl > & rList 493 ) 494 { 495 ::std::deque< AttachedObject_Impl >::iterator aObjIt = rList.begin(); 496 ::std::deque< AttachedObject_Impl >::iterator aObjEnd = rList.end(); 497 while( aObjIt != aObjEnd ) 498 { 499 pMgr->detach( nIdx, (*aObjIt).xTarget ); 500 aObjIt++; 501 } 502 } 503 504 //----------------------------------------------------------------------------- 505 void attachAll_Impl 506 ( 507 ImplEventAttacherManager * pMgr, 508 sal_Int32 nIdx, 509 ::std::deque< AttachedObject_Impl > & rList 510 ) 511 { 512 ::std::deque< AttachedObject_Impl >::iterator aObjIt = rList.begin(); 513 ::std::deque< AttachedObject_Impl >::iterator aObjEnd = rList.end(); 514 while( aObjIt != aObjEnd ) 515 { 516 pMgr->attach( nIdx, (*aObjIt).xTarget, (*aObjIt).aHelper ); 517 aObjIt++; 518 } 519 } 520 521 //----------------------------------------------------------------------------- 522 //*** Methoden von XEventAttacherManager *** 523 void SAL_CALL ImplEventAttacherManager::registerScriptEvent 524 ( 525 sal_Int32 nIndex, 526 const ScriptEventDescriptor& ScriptEvent 527 ) 528 throw( IllegalArgumentException, RuntimeException ) 529 { 530 Guard< Mutex > aGuard( aLock ); 531 532 // Index pruefen und Array anpassen 533 ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); 534 535 ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList; 536 537 ScriptEventDescriptor aEvt = ScriptEvent; 538 const sal_Unicode* pLastDot = aEvt.ListenerType.getStr(); 539 pLastDot += rtl_ustr_lastIndexOfChar( pLastDot, '.' ); 540 if( pLastDot ) 541 aEvt.ListenerType = pLastDot +1; 542 #ifdef DEQUE_OK 543 (*aIt).aEventList.push_back( aEvt ); 544 #else 545 (*aIt).aEventList.realloc( (*aIt).aEventList.getLength() +1 ); 546 (*aIt).aEventList.getArray()[(*aIt).aEventList.getLength() -1] = aEvt; 547 #endif 548 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 ) 553 { 554 // resize 555 sal_Int32 nPos = (*aObjIt).aAttachedListenerSeq.getLength(); 556 (*aObjIt).aAttachedListenerSeq.realloc( nPos + 1 ); 557 Reference< XEventListener > * pArray = (*aObjIt).aAttachedListenerSeq.getArray(); 558 559 Reference< XAllListener > xAll = 560 new AttacherAllListener_Impl( this, ScriptEvent.ScriptType, ScriptEvent.ScriptCode ); 561 try 562 { 563 pArray[nPos] = xAttacher->attachSingleEventListener( (*aObjIt).xTarget, xAll, 564 (*aObjIt).aHelper, ScriptEvent.ListenerType, 565 ScriptEvent.AddListenerParam, ScriptEvent.EventMethod ); 566 } 567 catch( Exception& ) 568 { 569 } 570 571 aObjIt++; 572 } 573 } 574 575 //----------------------------------------------------------------------------- 576 void SAL_CALL ImplEventAttacherManager::registerScriptEvents 577 ( 578 sal_Int32 nIndex, 579 const Sequence< ScriptEventDescriptor >& ScriptEvents 580 ) 581 throw( IllegalArgumentException, RuntimeException ) 582 { 583 Guard< Mutex > aGuard( aLock ); 584 585 // Index pruefen und Array anpassen 586 ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); 587 588 ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList; 589 detachAll_Impl( this, nIndex, aList ); 590 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 ] ); 595 596 attachAll_Impl( this, nIndex, aList ); 597 } 598 599 //----------------------------------------------------------------------------- 600 void SAL_CALL ImplEventAttacherManager::revokeScriptEvent 601 ( 602 sal_Int32 nIndex, 603 const OUString& ListenerType, 604 const OUString& EventMethod, 605 const OUString& ToRemoveListenerParam 606 ) 607 throw( IllegalArgumentException, RuntimeException ) 608 { 609 Guard< Mutex > aGuard( aLock ); 610 611 ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); 612 613 ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList; 614 detachAll_Impl( this, nIndex, aList ); 615 616 OUString aLstType = ListenerType; 617 const sal_Unicode * pLastDot = aLstType.getStr(); 618 pLastDot += rtl_ustr_lastIndexOfChar( pLastDot, '.' ); 619 if( pLastDot ) 620 aLstType = pLastDot +1; 621 622 #ifdef DEQUE_OK 623 ::std::deque< ScriptEventDescriptor >::iterator aEvtIt = (*aIt).aEventList.begin(); 624 ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd = (*aIt).aEventList.end(); 625 while( aEvtIt != aEvtEnd ) 626 { 627 if( aLstType == (*aEvtIt).ListenerType 628 && EventMethod == (*aEvtIt).EventMethod 629 && ToRemoveListenerParam == (*aEvtIt).AddListenerParam ) 630 { 631 (*aIt).aEventList.erase( aEvtIt ); 632 break; 633 } 634 635 aEvtIt++; 636 } 637 #else 638 Sequence< ScriptEventDescriptor >& rEventList = (*aIt).aEventList; 639 640 ScriptEventDescriptor* pEventList = rEventList.getArray(); 641 const ScriptEventDescriptor* pEventListEnd = pEventList + rEventList.getLength(); 642 for( ; pEventList < pEventListEnd; ++pEventList ) 643 { 644 if ( (aLstType == pEventList->ListenerType ) 645 && (EventMethod == pEventList->EventMethod ) 646 && (ToRemoveListenerParam == pEventList->AddListenerParam) 647 ) 648 { 649 ScriptEventDescriptor* pMoveTo = pEventList; 650 const ScriptEventDescriptor* pMoveFrom = pMoveTo + 1; 651 while (pMoveFrom < pEventListEnd) 652 { 653 *pMoveTo++ = *pMoveFrom++; 654 } 655 rEventList.realloc( rEventList.getLength() - 1 ); 656 break; 657 } 658 } 659 #endif 660 attachAll_Impl( this, nIndex, aList ); 661 } 662 663 //----------------------------------------------------------------------------- 664 void SAL_CALL ImplEventAttacherManager::revokeScriptEvents(sal_Int32 nIndex ) 665 throw( IllegalArgumentException, RuntimeException ) 666 { 667 Guard< Mutex > aGuard( aLock ); 668 ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); 669 670 ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList; 671 detachAll_Impl( this, nIndex, aList ); 672 #ifdef DEQUE_OK 673 (*aIt).aEventList = ::std::deque< ScriptEventDescriptor >(); 674 #else 675 (*aIt).aEventList.realloc( 0 ); 676 #endif 677 attachAll_Impl( this, nIndex, aList ); 678 } 679 680 //----------------------------------------------------------------------------- 681 void SAL_CALL ImplEventAttacherManager::insertEntry(sal_Int32 nIndex) 682 throw( IllegalArgumentException, RuntimeException ) 683 { 684 Guard< Mutex > aGuard( aLock ); 685 if( nIndex < 0 ) 686 throw IllegalArgumentException(); 687 688 // ::std::deque<AttacherIndex_Impl>::iterator aIt = aIndex.begin(); 689 // while( nIndex-- ) 690 // aIt++; 691 692 if ( static_cast< ::std::deque< AttacherIndex_Impl >::size_type>(nIndex) >= aIndex.size() ) 693 aIndex.resize(nIndex+1); 694 695 AttacherIndex_Impl aTmp; 696 aIndex.insert( aIndex.begin() + nIndex, aTmp ); 697 } 698 699 //----------------------------------------------------------------------------- 700 void SAL_CALL ImplEventAttacherManager::removeEntry(sal_Int32 nIndex) 701 throw( IllegalArgumentException, RuntimeException ) 702 { 703 Guard< Mutex > aGuard( aLock ); 704 ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); 705 706 ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList; 707 detachAll_Impl( this, nIndex, aList ); 708 aIndex.erase( aIt ); 709 } 710 711 //----------------------------------------------------------------------------- 712 Sequence< ScriptEventDescriptor > SAL_CALL ImplEventAttacherManager::getScriptEvents(sal_Int32 nIndex) 713 throw( IllegalArgumentException, RuntimeException ) 714 { 715 Guard< Mutex > aGuard( aLock ); 716 ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex ); 717 718 #ifdef DEQUE_OK 719 Sequence< ScriptEventDescriptor > aSeq( (*aIt).aEventList.size() ); 720 ScriptEventDescriptor * pArray = aSeq.getArray(); 721 722 ::std::deque< ScriptEventDescriptor >::iterator aEvtIt = (*aIt).aEventList.begin(); 723 ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd = (*aIt).aEventList.end(); 724 sal_Int32 i = 0; 725 while( aEvtIt != aEvtEnd ) 726 { 727 pArray[i++] = *aEvtIt; 728 aEvtIt++; 729 } 730 return aSeq; 731 #else 732 return (*aIt).aEventList; 733 #endif 734 } 735 736 //----------------------------------------------------------------------------- 737 void SAL_CALL ImplEventAttacherManager::attach(sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any & Helper) 738 throw( IllegalArgumentException, ServiceNotRegisteredException, RuntimeException ) 739 { 740 Guard< Mutex > aGuard( aLock ); 741 if( nIndex < 0 || !xObject.is() ) 742 throw IllegalArgumentException(); 743 744 if( static_cast< ::std::deque< AttacherIndex_Impl >::size_type>(nIndex) >= aIndex.size() ) 745 { 746 // alte Dateien lesen 747 if( nVersion == 1 ) 748 { 749 insertEntry( nIndex ); 750 attach( nIndex, xObject, Helper ); 751 return; 752 } 753 else 754 throw IllegalArgumentException(); 755 } 756 757 ::std::deque< AttacherIndex_Impl >::iterator aCurrentPosition = aIndex.begin() + nIndex; 758 759 AttachedObject_Impl aTmp; 760 aTmp.xTarget = xObject; 761 aTmp.aHelper = Helper; 762 aCurrentPosition->aObjList.push_back( aTmp ); 763 764 //::std::deque< AttachedObject_Impl >::iterator aObjIt = (*aIt).aObjList.back(); 765 AttachedObject_Impl & rCurObj = aCurrentPosition->aObjList.back(); 766 #ifdef DEQUE_OK 767 rCurObj.aAttachedListenerSeq = Sequence< Reference< XEventListener > >( aCurrentPosition->aEventList.size() ); 768 #else 769 rCurObj.aAttachedListenerSeq = Sequence< Reference< XEventListener > >( aCurrentPosition->aEventList.getLength() ); 770 #endif 771 Reference< XEventListener > * pArray = rCurObj.aAttachedListenerSeq.getArray(); 772 773 #ifdef DEQUE_OK 774 ::std::deque< ScriptEventDescriptor >::iterator aEvtIt = aCurrentPosition->aEventList.begin(); 775 ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd = aCurrentPosition->aEventList.end(); 776 sal_Int32 i = 0; 777 while( aEvtIt != aEvtEnd ) 778 { 779 Reference< XAllListener > xAll = 780 new AttacherAllListener_Impl( this, (*aEvtIt).ScriptType, (*aEvtIt).ScriptCode ); 781 Reference< XEventListener > xAdapter; 782 try 783 { 784 xAdapter = xAttacher->attachSingleEventListener( rCurObj.xTarget, xAll, 785 rCurObj.aHelper, (*aEvtIt).ScriptType, 786 (*aEvtIt).AddListenerParam, (*aEvtIt).EventMethod ); 787 } 788 catch( Exception& ) 789 { 790 } 791 792 pArray[i++] = xAdapter; 793 aEvtIt++; 794 } 795 #else 796 sal_Int32 nLen = aCurrentPosition->aEventList.getLength(); 797 ScriptEventDescriptor * pEL = aCurrentPosition->aEventList.getArray(); 798 for(sal_Int32 i = 0; i < nLen; ++i ) 799 { 800 Reference< XAllListener > xAll = 801 new AttacherAllListener_Impl( this, pEL[i].ScriptType, pEL[i].ScriptCode ); 802 Reference< XEventListener > xAdapter; 803 try 804 { 805 xAdapter = xAttacher->attachSingleEventListener( rCurObj.xTarget, xAll, 806 rCurObj.aHelper, pEL[i].ListenerType, 807 pEL[i].AddListenerParam, pEL[i].EventMethod ); 808 } 809 catch( Exception& ) 810 { 811 } 812 813 pArray[i] = xAdapter; 814 } 815 #endif 816 } 817 818 //----------------------------------------------------------------------------- 819 void SAL_CALL ImplEventAttacherManager::detach(sal_Int32 nIndex, const Reference< XInterface >& xObject) 820 throw( IllegalArgumentException, RuntimeException ) 821 { 822 Guard< Mutex > aGuard( aLock ); 823 //return; 824 if( nIndex < 0 || static_cast< ::std::deque< AttacherIndex_Impl >::size_type>(nIndex) >= aIndex.size() || !xObject.is() ) 825 throw IllegalArgumentException(); 826 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 ) 831 { 832 if( (*aObjIt).xTarget == xObject ) 833 { 834 Reference< XEventListener > * pArray = (*aObjIt).aAttachedListenerSeq.getArray(); 835 #ifdef DEQUE_OK 836 837 ::std::deque< ScriptEventDescriptor >::iterator aEvtIt = aCurrentPosition->aEventList.begin(); 838 ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd = aCurrentPosition->aEventList.end(); 839 sal_Int32 i = 0; 840 while( aEvtIt != aEvtEnd ) 841 { 842 if( pArray[i].is() ) 843 { 844 try 845 { 846 xAttacher->removeListener( (*aObjIt).xTarget, (*aEvtIt).ListenerType, 847 (*aEvtIt).AddListenerParam, pArray[i] ); 848 } 849 catch( Exception& ) 850 { 851 } 852 } 853 i++; 854 aEvtIt++; 855 } 856 #else 857 sal_Int32 nLen = aCurrentPosition->aEventList.getLength(); 858 ScriptEventDescriptor * pEL = aCurrentPosition->aEventList.getArray(); 859 for( sal_Int32 i = 0; i < nLen; i++ ) 860 { 861 if( pArray[i].is() ) 862 { 863 try 864 { 865 xAttacher->removeListener( (*aObjIt).xTarget, pEL[i].ListenerType, 866 pEL[i].AddListenerParam, pArray[i] ); 867 } 868 catch( Exception& ) 869 { 870 } 871 } 872 } 873 #endif 874 aCurrentPosition->aObjList.erase( aObjIt ); 875 break; 876 } 877 aObjIt++; 878 } 879 } 880 881 void SAL_CALL ImplEventAttacherManager::addScriptListener(const Reference< XScriptListener >& aListener) 882 throw( IllegalArgumentException, RuntimeException ) 883 { 884 Guard< Mutex > aGuard( aLock ); 885 aScriptListeners.addInterface( aListener ); 886 } 887 888 void SAL_CALL ImplEventAttacherManager::removeScriptListener(const Reference< XScriptListener >& aListener) 889 throw( IllegalArgumentException, RuntimeException ) 890 { 891 Guard< Mutex > aGuard( aLock ); 892 aScriptListeners.removeInterface( aListener ); 893 } 894 895 896 // Methoden von XPersistObject 897 OUString SAL_CALL ImplEventAttacherManager::getServiceName(void) 898 throw( RuntimeException ) 899 { 900 return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.script.EventAttacherManager") ); 901 } 902 903 void SAL_CALL ImplEventAttacherManager::write(const Reference< XObjectOutputStream >& OutStream) 904 throw( IOException, RuntimeException ) 905 { 906 Guard< Mutex > aGuard( aLock ); 907 // Ohne XMarkableStream laeuft nichts 908 Reference< XMarkableStream > xMarkStream( OutStream, UNO_QUERY ); 909 if( !xMarkStream.is() ) 910 return; 911 912 // Version schreiben 913 OutStream->writeShort( 2 ); 914 915 // Position fuer Laenge merken 916 sal_Int32 nObjLenMark = xMarkStream->createMark(); 917 OutStream->writeLong( 0L ); 918 919 OutStream->writeLong( aIndex.size() ); 920 921 // Sequences schreiben 922 ::std::deque<AttacherIndex_Impl>::iterator aIt = aIndex.begin(); 923 ::std::deque<AttacherIndex_Impl>::iterator aEnd = aIndex.end(); 924 while( aIt != aEnd ) 925 { 926 #ifdef DEQUE_OK 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 ) 932 { 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 ); 939 940 aEvtIt++; 941 } 942 #else 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++ ) 948 { 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 ); 955 } 956 #endif 957 aIt++; 958 } 959 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 ); 966 } 967 968 void SAL_CALL ImplEventAttacherManager::read(const Reference< XObjectInputStream >& InStream) 969 throw( IOException, RuntimeException ) 970 { 971 Guard< Mutex > aGuard( aLock ); 972 // Ohne XMarkableStream laeuft nichts 973 Reference< XMarkableStream > xMarkStream( InStream, UNO_QUERY ); 974 if( !xMarkStream.is() ) 975 return; 976 977 // Version lesen 978 nVersion = InStream->readShort(); 979 980 // Zunaechst kommen die Daten gemaess Version 1, 981 // muss auch bei hoeheren Versionen beibehalten werden 982 sal_Int32 nLen = InStream->readLong(); 983 984 // Position fuer Vergleichszwecke 985 sal_Int32 nObjLenMark = xMarkStream->createMark(); 986 987 // Anzahl der zu lesenden Sequences 988 sal_Int32 nItemCount = InStream->readLong(); 989 990 for( sal_Int32 i = 0 ; i < nItemCount ; i++ ) 991 { 992 insertEntry( i ); 993 // Laenge der Sequence lesen 994 sal_Int32 nSeqLen = InStream->readLong(); 995 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++ ) 1000 { 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(); 1007 } 1008 registerScriptEvents( i, aSEDSeq ); 1009 } 1010 1011 // Haben wir die angegebene Laenge gelesen? 1012 sal_Int32 nRealLen = xMarkStream->offsetToMark( nObjLenMark ); 1013 if( nRealLen != nLen ) 1014 { 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 ) 1018 { 1019 VOS_ENSHURE( sal_False, "ImplEventAttacherManager::read(): Fatal Error, wrong object length" ); 1020 } 1021 else 1022 { 1023 // TODO: Pruefen, ob Zwischen-Speicherung der Daten sinnvoll sein koennte 1024 1025 // Vorerst einfach nur Skippen 1026 sal_Int32 nSkipCount = nLen - nRealLen; 1027 InStream->skipBytes( nSkipCount ); 1028 } 1029 } 1030 xMarkStream->jumpToFurthest(); 1031 xMarkStream->deleteMark( nObjLenMark ); 1032 } 1033 1034 } // namesapce comphelper 1035 1036 1037