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