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 #include "comphelper/accessiblewrapper.hxx" 31 #include <com/sun/star/reflection/XProxyFactory.hpp> 32 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 33 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 34 35 #include <algorithm> 36 37 using namespace ::comphelper; 38 using namespace ::com::sun::star::accessibility; 39 using namespace ::com::sun::star::uno; 40 using namespace ::com::sun::star::lang; 41 42 //............................................................................. 43 namespace comphelper 44 { 45 //............................................................................. 46 47 //========================================================================= 48 //= OWrappedAccessibleChildrenManager 49 //========================================================================= 50 //-------------------------------------------------------------------- 51 struct RemoveEventListener 52 : public ::std::unary_function< AccessibleMap::value_type, void > 53 { 54 private: 55 Reference< XEventListener > m_xListener; 56 57 public: 58 RemoveEventListener( const Reference< XEventListener >& _rxListener ) 59 :m_xListener( _rxListener ) 60 { 61 } 62 63 void operator()( const AccessibleMap::value_type& _rMapEntry ) const 64 { 65 Reference< XComponent > xComp( _rMapEntry.first, UNO_QUERY ); 66 if ( xComp.is() ) 67 xComp->removeEventListener( m_xListener ); 68 } 69 }; 70 71 //-------------------------------------------------------------------- 72 struct DisposeMappedChild 73 : public ::std::unary_function< AccessibleMap::value_type, void > 74 { 75 void operator()( const AccessibleMap::value_type& _rMapEntry ) const 76 { 77 Reference< XComponent > xContextComponent; 78 if ( _rMapEntry.second.is() ) 79 xContextComponent = xContextComponent.query( _rMapEntry.second->getAccessibleContext() ); 80 if ( xContextComponent.is() ) 81 xContextComponent->dispose(); 82 } 83 }; 84 85 //------------------------------------------------------------------------- 86 OWrappedAccessibleChildrenManager::OWrappedAccessibleChildrenManager( const Reference< XMultiServiceFactory >& _rxORB ) 87 :m_xORB( _rxORB ) 88 ,m_bTransientChildren( sal_True ) 89 { 90 } 91 92 //------------------------------------------------------------------------- 93 OWrappedAccessibleChildrenManager::~OWrappedAccessibleChildrenManager( ) 94 { 95 } 96 97 //------------------------------------------------------------------------- 98 void OWrappedAccessibleChildrenManager::setTransientChildren( sal_Bool _bSet ) 99 { 100 m_bTransientChildren = _bSet; 101 } 102 103 //------------------------------------------------------------------------- 104 void OWrappedAccessibleChildrenManager::setOwningAccessible( const Reference< XAccessible >& _rxAcc ) 105 { 106 OSL_ENSURE( !m_aOwningAccessible.get().is(), "OWrappedAccessibleChildrenManager::setOwningAccessible: to be called only once!" ); 107 m_aOwningAccessible = WeakReference< XAccessible >( _rxAcc ); 108 } 109 110 //------------------------------------------------------------------------- 111 void OWrappedAccessibleChildrenManager::removeFromCache( const Reference< XAccessible >& _rxKey ) 112 { 113 AccessibleMap::iterator aRemovedPos = m_aChildrenMap.find( _rxKey ); 114 if ( m_aChildrenMap.end() != aRemovedPos ) 115 { // it was cached 116 // remove ourself as event listener 117 RemoveEventListener aOperator( this ); 118 aOperator( *aRemovedPos ); 119 // and remove the entry from the map 120 m_aChildrenMap.erase( aRemovedPos ); 121 } 122 } 123 124 //------------------------------------------------------------------------- 125 void OWrappedAccessibleChildrenManager::invalidateAll( ) 126 { 127 // remove as event listener from the map elements 128 ::std::for_each( m_aChildrenMap.begin(), m_aChildrenMap.end(), RemoveEventListener( this ) ); 129 // clear the map 130 AccessibleMap aMap; 131 m_aChildrenMap.swap( aMap ); 132 } 133 134 //------------------------------------------------------------------------- 135 Reference< XAccessible > OWrappedAccessibleChildrenManager::getAccessibleWrapperFor( 136 const Reference< XAccessible >& _rxKey, sal_Bool _bCreate ) 137 { 138 Reference< XAccessible > xValue; 139 140 if( !_rxKey.is() ) 141 { 142 // fprintf( stderr, "It was this path that was crashing stuff\n" ); 143 return xValue; 144 } 145 146 // do we have this child in the cahce? 147 AccessibleMap::const_iterator aPos = m_aChildrenMap.find( _rxKey ); 148 if ( m_aChildrenMap.end() != aPos ) 149 { 150 xValue = aPos->second; 151 } 152 else if ( _bCreate ) 153 { // not found in the cache, and allowed to create 154 // -> new wrapper 155 xValue = new OAccessibleWrapper( m_xORB, _rxKey, (Reference< XAccessible >)m_aOwningAccessible ); 156 157 // see if we do cache children 158 if ( !m_bTransientChildren ) 159 { 160 if (!m_aChildrenMap.insert( 161 AccessibleMap::value_type( _rxKey, xValue ) ).second) 162 { 163 OSL_ENSURE( 164 false, 165 "OWrappedAccessibleChildrenManager::" 166 "getAccessibleWrapperFor: element was already" 167 " inserted!" ); 168 } 169 170 // listen for disposals of inner children - this may happen when the inner context 171 // is the owner for the inner children (it will dispose these children, and of course 172 // not our wrapper for these children) 173 Reference< XComponent > xComp( _rxKey, UNO_QUERY ); 174 if ( xComp.is() ) 175 xComp->addEventListener( this ); 176 } 177 } 178 179 return xValue; 180 } 181 182 //------------------------------------------------------------------------- 183 void OWrappedAccessibleChildrenManager::dispose() 184 { 185 // dispose our children 186 ::std::for_each( m_aChildrenMap.begin(), m_aChildrenMap.end(), RemoveEventListener( this ) ); 187 ::std::for_each( m_aChildrenMap.begin(), m_aChildrenMap.end(), DisposeMappedChild( ) ); 188 // clear our children 189 AccessibleMap aMap; 190 m_aChildrenMap.swap( aMap ); 191 } 192 193 //-------------------------------------------------------------------- 194 void OWrappedAccessibleChildrenManager::implTranslateChildEventValue( const Any& _rInValue, Any& _rOutValue ) 195 { 196 _rOutValue.clear(); 197 Reference< XAccessible > xChild; 198 if ( _rInValue >>= xChild ) 199 _rOutValue <<= getAccessibleWrapperFor( xChild, sal_True ); 200 } 201 202 //------------------------------------------------------------------------- 203 void OWrappedAccessibleChildrenManager::translateAccessibleEvent( const AccessibleEventObject& _rEvent, AccessibleEventObject& _rTranslatedEvent ) 204 { 205 // just in case we can't translate some of the values: 206 _rTranslatedEvent.NewValue = _rEvent.NewValue; 207 _rTranslatedEvent.OldValue = _rEvent.OldValue; 208 209 switch ( _rEvent.EventId ) 210 { 211 case AccessibleEventId::CHILD: 212 case AccessibleEventId::ACTIVE_DESCENDANT_CHANGED: 213 case AccessibleEventId::CONTROLLED_BY_RELATION_CHANGED: 214 case AccessibleEventId::CONTROLLER_FOR_RELATION_CHANGED: 215 case AccessibleEventId::LABEL_FOR_RELATION_CHANGED: 216 case AccessibleEventId::LABELED_BY_RELATION_CHANGED: 217 case AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED: 218 case AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED: 219 // these are events where both the old and the new value contain child references 220 implTranslateChildEventValue( _rEvent.OldValue, _rTranslatedEvent.OldValue ); 221 implTranslateChildEventValue( _rEvent.NewValue, _rTranslatedEvent.NewValue ); 222 break; 223 224 case AccessibleEventId::NAME_CHANGED: 225 case AccessibleEventId::DESCRIPTION_CHANGED: 226 case AccessibleEventId::ACTION_CHANGED: 227 case AccessibleEventId::STATE_CHANGED: 228 case AccessibleEventId::BOUNDRECT_CHANGED: 229 case AccessibleEventId::INVALIDATE_ALL_CHILDREN: 230 case AccessibleEventId::SELECTION_CHANGED: 231 case AccessibleEventId::VISIBLE_DATA_CHANGED: 232 case AccessibleEventId::VALUE_CHANGED: 233 case AccessibleEventId::MEMBER_OF_RELATION_CHANGED: 234 case AccessibleEventId::CARET_CHANGED: 235 case AccessibleEventId::TEXT_CHANGED: 236 case AccessibleEventId::HYPERTEXT_CHANGED: 237 case AccessibleEventId::TABLE_CAPTION_CHANGED: 238 case AccessibleEventId::TABLE_COLUMN_DESCRIPTION_CHANGED: 239 case AccessibleEventId::TABLE_COLUMN_HEADER_CHANGED: 240 case AccessibleEventId::TABLE_MODEL_CHANGED: 241 case AccessibleEventId::TABLE_ROW_DESCRIPTION_CHANGED: 242 case AccessibleEventId::TABLE_ROW_HEADER_CHANGED: 243 case AccessibleEventId::TABLE_SUMMARY_CHANGED: 244 // --> PB 2006-03-21 #130798# EventId TEXT_SELECTION_CHANGED was missed 245 // these Ids are also missed: SUB_WINDOW_OF_RELATION_CHANGED & TEXT_ATTRIBUTE_CHANGED 246 case AccessibleEventId::TEXT_SELECTION_CHANGED: 247 // <-- 248 // nothing to translate 249 break; 250 251 default: 252 OSL_ENSURE( sal_False, "OWrappedAccessibleChildrenManager::translateAccessibleEvent: unknown (or unexpected) event id!" ); 253 break; 254 } 255 } 256 257 //------------------------------------------------------------------------- 258 void OWrappedAccessibleChildrenManager::handleChildNotification( const AccessibleEventObject& _rEvent ) 259 { 260 if ( AccessibleEventId::INVALIDATE_ALL_CHILDREN == _rEvent.EventId ) 261 { // clear our child map 262 invalidateAll( ); 263 } 264 else if ( AccessibleEventId::CHILD == _rEvent.EventId ) 265 { 266 // check if the removed or replaced element is cached 267 Reference< XAccessible > xRemoved; 268 if ( _rEvent.OldValue >>= xRemoved ) 269 removeFromCache( xRemoved ); 270 } 271 } 272 273 //-------------------------------------------------------------------- 274 void SAL_CALL OWrappedAccessibleChildrenManager::disposing( const EventObject& _rSource ) throw (RuntimeException) 275 { 276 // this should come from one of the inner XAccessible's of our children 277 Reference< XAccessible > xSource( _rSource.Source, UNO_QUERY ); 278 AccessibleMap::iterator aDisposedPos = m_aChildrenMap.find( xSource ); 279 #if OSL_DEBUG_LEVEL > 0 280 if ( m_aChildrenMap.end() == aDisposedPos ) 281 { 282 OSL_ENSURE( sal_False, 283 "OWrappedAccessibleChildrenManager::disposing: where did this come from?" ); 284 // helper for dignostics 285 Reference< XAccessible > xOwningAccessible( m_aOwningAccessible ); 286 Reference< XAccessibleContext > xContext; 287 try 288 { 289 if ( xOwningAccessible.is() ) 290 xContext = xOwningAccessible->getAccessibleContext(); 291 if ( xContext.is() ) 292 { 293 ::rtl::OUString sName = xContext->getAccessibleName(); 294 ::rtl::OUString sDescription = xContext->getAccessibleDescription(); 295 // sal_Int32 nPlaceYourBreakpointHere = 0; 296 } 297 } 298 catch( const Exception& /*e*/ ) 299 { 300 // silent this, it's only diagnostics which failed 301 } 302 } 303 #endif 304 if ( m_aChildrenMap.end() != aDisposedPos ) 305 { 306 m_aChildrenMap.erase( aDisposedPos ); 307 } 308 } 309 310 //========================================================================= 311 //= OAccessibleWrapper (implementation) 312 //========================================================================= 313 //------------------------------------------------------------------------- 314 OAccessibleWrapper::OAccessibleWrapper( const Reference< XMultiServiceFactory >& _rxORB, 315 const Reference< XAccessible >& _rxInnerAccessible, const Reference< XAccessible >& _rxParentAccessible ) 316 :OAccessibleWrapper_Base( ) 317 ,OComponentProxyAggregation( _rxORB, Reference< XComponent >( _rxInnerAccessible, UNO_QUERY ) ) 318 ,m_xParentAccessible( _rxParentAccessible ) 319 ,m_xInnerAccessible( _rxInnerAccessible ) 320 { 321 } 322 323 //-------------------------------------------------------------------- 324 OAccessibleWrapper::~OAccessibleWrapper( ) 325 { 326 if ( !m_rBHelper.bDisposed ) 327 { 328 acquire(); // to prevent duplicate dtor calls 329 dispose(); 330 } 331 } 332 333 //-------------------------------------------------------------------- 334 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleWrapper, OComponentProxyAggregation, OAccessibleWrapper_Base ) 335 IMPLEMENT_FORWARD_REFCOUNT( OAccessibleWrapper, OComponentProxyAggregation ) 336 337 //-------------------------------------------------------------------- 338 Any OAccessibleWrapper::queryInterface( const Type& _rType ) throw (RuntimeException) 339 { 340 // #111089# instead of the inner XAccessible the proxy XAccessible must be returned 341 Any aReturn = OAccessibleWrapper_Base::queryInterface( _rType ); 342 if ( !aReturn.hasValue() ) 343 aReturn = OComponentProxyAggregation::queryInterface( _rType ); 344 345 return aReturn; 346 } 347 348 //-------------------------------------------------------------------- 349 Reference< XAccessibleContext > OAccessibleWrapper::getContextNoCreate( ) const 350 { 351 return (Reference< XAccessibleContext >)m_aContext; 352 } 353 354 //-------------------------------------------------------------------- 355 OAccessibleContextWrapper* OAccessibleWrapper::createAccessibleContext( const Reference< XAccessibleContext >& _rxInnerContext ) 356 { 357 return new OAccessibleContextWrapper( getORB(), _rxInnerContext, this, m_xParentAccessible ); 358 } 359 360 //-------------------------------------------------------------------- 361 Reference< XAccessibleContext > SAL_CALL OAccessibleWrapper::getAccessibleContext( ) throw (RuntimeException) 362 { 363 // see if the context is still alive (we cache it) 364 Reference< XAccessibleContext > xContext = (Reference< XAccessibleContext >)m_aContext; 365 if ( !xContext.is() ) 366 { 367 // create a new context 368 Reference< XAccessibleContext > xInnerContext = m_xInnerAccessible->getAccessibleContext( ); 369 if ( xInnerContext.is() ) 370 { 371 xContext = createAccessibleContext( xInnerContext ); 372 // cache it 373 m_aContext = WeakReference< XAccessibleContext >( xContext ); 374 } 375 } 376 377 return xContext; 378 } 379 380 //========================================================================= 381 //= OAccessibleWrapper (implementation) 382 //========================================================================= 383 //------------------------------------------------------------------------- 384 OAccessibleContextWrapperHelper::OAccessibleContextWrapperHelper( 385 const Reference< XMultiServiceFactory >& _rxORB, 386 ::cppu::OBroadcastHelper& _rBHelper, 387 const Reference< XAccessibleContext >& _rxInnerAccessibleContext, 388 const Reference< XAccessible >& _rxOwningAccessible, 389 const Reference< XAccessible >& _rxParentAccessible ) 390 :OComponentProxyAggregationHelper( _rxORB, _rBHelper ) 391 ,m_xInnerContext( _rxInnerAccessibleContext ) 392 ,m_xOwningAccessible( _rxOwningAccessible ) 393 ,m_xParentAccessible( _rxParentAccessible ) 394 ,m_pChildMapper( NULL ) 395 { 396 // initialize the mapper for our children 397 m_pChildMapper = new OWrappedAccessibleChildrenManager( getORB() ); 398 m_pChildMapper->acquire(); 399 400 // determine if we're allowed to cache children 401 Reference< XAccessibleStateSet > xStates( m_xInnerContext->getAccessibleStateSet( ) ); 402 OSL_ENSURE( xStates.is(), "OAccessibleContextWrapperHelper::OAccessibleContextWrapperHelper: no inner state set!" ); 403 m_pChildMapper->setTransientChildren( !xStates.is() || xStates->contains( AccessibleStateType::MANAGES_DESCENDANTS) ); 404 405 m_pChildMapper->setOwningAccessible( m_xOwningAccessible ); 406 } 407 408 //-------------------------------------------------------------------- 409 void OAccessibleContextWrapperHelper::aggregateProxy( oslInterlockedCount& _rRefCount, ::cppu::OWeakObject& _rDelegator ) 410 { 411 Reference< XComponent > xInnerComponent( m_xInnerContext, UNO_QUERY ); 412 OSL_ENSURE( xInnerComponent.is(), "OComponentProxyAggregation::aggregateProxy: accessible is no XComponent!" ); 413 if ( xInnerComponent.is() ) 414 componentAggregateProxyFor( xInnerComponent, _rRefCount, _rDelegator ); 415 416 // add as event listener to the inner context, because we want to multiplex the AccessibleEvents 417 osl_incrementInterlockedCount( &_rRefCount ); 418 { 419 Reference< XAccessibleEventBroadcaster > xBroadcaster( m_xInner, UNO_QUERY ); 420 if ( xBroadcaster.is() ) 421 xBroadcaster->addEventListener( this ); 422 } 423 osl_decrementInterlockedCount( &_rRefCount ); 424 } 425 426 //-------------------------------------------------------------------- 427 OAccessibleContextWrapperHelper::~OAccessibleContextWrapperHelper( ) 428 { 429 OSL_ENSURE( m_rBHelper.bDisposed, "OAccessibleContextWrapperHelper::~OAccessibleContextWrapperHelper: you should ensure (in your dtor) that the object is disposed!" ); 430 431 m_pChildMapper->release(); 432 m_pChildMapper = NULL; 433 } 434 435 //-------------------------------------------------------------------- 436 Any SAL_CALL OAccessibleContextWrapperHelper::queryInterface( const Type& _rType ) throw (RuntimeException) 437 { 438 Any aReturn = OComponentProxyAggregationHelper::queryInterface( _rType ); 439 if ( !aReturn.hasValue() ) 440 aReturn = OAccessibleContextWrapperHelper_Base::queryInterface( _rType ); 441 return aReturn; 442 } 443 444 //-------------------------------------------------------------------- 445 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleContextWrapperHelper, OComponentProxyAggregationHelper, OAccessibleContextWrapperHelper_Base ) 446 447 //-------------------------------------------------------------------- 448 sal_Int32 SAL_CALL OAccessibleContextWrapperHelper::getAccessibleChildCount( ) throw (RuntimeException) 449 { 450 return m_xInnerContext->getAccessibleChildCount(); 451 } 452 453 //-------------------------------------------------------------------- 454 Reference< XAccessible > SAL_CALL OAccessibleContextWrapperHelper::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException) 455 { 456 // get the child of the wrapped component 457 Reference< XAccessible > xInnerChild = m_xInnerContext->getAccessibleChild( i ); 458 return m_pChildMapper->getAccessibleWrapperFor( xInnerChild ); 459 } 460 461 //-------------------------------------------------------------------- 462 Reference< XAccessibleRelationSet > SAL_CALL OAccessibleContextWrapperHelper::getAccessibleRelationSet( ) throw (RuntimeException) 463 { 464 return m_xInnerContext->getAccessibleRelationSet(); 465 // TODO: if this relation set would contain relations to siblings, we would normally need 466 // to wrap them, too .... 467 } 468 469 //-------------------------------------------------------------------- 470 void SAL_CALL OAccessibleContextWrapperHelper::notifyEvent( const AccessibleEventObject& _rEvent ) throw (RuntimeException) 471 { 472 #if OSL_DEBUG_LEVEL > 0 473 if ( AccessibleEventId::STATE_CHANGED == _rEvent.EventId ) 474 { 475 sal_Bool bChildTransienceChanged = sal_False; 476 sal_Int16 nChangeState = 0; 477 if ( _rEvent.OldValue >>= nChangeState ) 478 bChildTransienceChanged = bChildTransienceChanged || AccessibleStateType::MANAGES_DESCENDANTS == nChangeState; 479 if ( _rEvent.NewValue >>= nChangeState ) 480 bChildTransienceChanged = bChildTransienceChanged || AccessibleStateType::MANAGES_DESCENDANTS == nChangeState; 481 OSL_ENSURE( !bChildTransienceChanged, "OAccessibleContextWrapperHelper::notifyEvent: MANAGES_DESCENDANTS is not expected to change during runtime!" ); 482 // if this asserts, then we would need to update our m_bTransientChildren flag here, 483 // as well as (potentially) our child cache 484 } 485 #endif 486 AccessibleEventObject aTranslatedEvent( _rEvent ); 487 488 { 489 ::osl::MutexGuard aGuard( m_rBHelper.rMutex ); 490 491 // translate the event 492 queryInterface( ::getCppuType( static_cast< Reference< XInterface >* >( NULL ) ) ) >>= aTranslatedEvent.Source; 493 m_pChildMapper->translateAccessibleEvent( _rEvent, aTranslatedEvent ); 494 495 // see if any of these notifications affect our child manager 496 m_pChildMapper->handleChildNotification( _rEvent ); 497 498 if ( aTranslatedEvent.NewValue == m_xInner ) 499 aTranslatedEvent.NewValue = makeAny(aTranslatedEvent.Source); 500 if ( aTranslatedEvent.OldValue == m_xInner ) 501 aTranslatedEvent.OldValue = makeAny(aTranslatedEvent.Source); 502 } 503 504 notifyTranslatedEvent( aTranslatedEvent ); 505 } 506 507 //-------------------------------------------------------------------- 508 void SAL_CALL OAccessibleContextWrapperHelper::dispose() throw( RuntimeException ) 509 { 510 ::osl::MutexGuard aGuard( m_rBHelper.rMutex ); 511 512 // stop multiplexing events 513 Reference< XAccessibleEventBroadcaster > xBroadcaster( m_xInner, UNO_QUERY ); 514 OSL_ENSURE( xBroadcaster.is(), "OAccessibleContextWrapperHelper::disposing(): inner context is no broadcaster!" ); 515 if ( xBroadcaster.is() ) 516 xBroadcaster->removeEventListener( this ); 517 518 // dispose the child cache/map 519 m_pChildMapper->dispose(); 520 521 // let the base class dispose the inner component 522 OComponentProxyAggregationHelper::dispose(); 523 } 524 525 //-------------------------------------------------------------------- 526 void SAL_CALL OAccessibleContextWrapperHelper::disposing( const EventObject& _rEvent ) throw (RuntimeException) 527 { 528 // simply disambiguate this 529 OComponentProxyAggregationHelper::disposing( _rEvent ); 530 } 531 532 //==================================================================== 533 //= OAccessibleContextWrapper 534 //==================================================================== 535 //-------------------------------------------------------------------- 536 IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleContextWrapper, OAccessibleContextWrapper_CBase, OAccessibleContextWrapperHelper ) 537 538 //-------------------------------------------------------------------- 539 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleContextWrapper, OAccessibleContextWrapper_CBase, OAccessibleContextWrapperHelper ) 540 541 //-------------------------------------------------------------------- 542 OAccessibleContextWrapper::OAccessibleContextWrapper( const Reference< XMultiServiceFactory >& _rxORB, 543 const Reference< XAccessibleContext >& _rxInnerAccessibleContext, const Reference< XAccessible >& _rxOwningAccessible, 544 const Reference< XAccessible >& _rxParentAccessible ) 545 :OAccessibleContextWrapper_CBase( m_aMutex ) 546 ,OAccessibleContextWrapperHelper( _rxORB, rBHelper, _rxInnerAccessibleContext, _rxOwningAccessible, _rxParentAccessible ) 547 ,m_nNotifierClient( 0 ) 548 { 549 aggregateProxy( m_refCount, *this ); 550 } 551 552 //-------------------------------------------------------------------- 553 OAccessibleContextWrapper::~OAccessibleContextWrapper() 554 { 555 } 556 557 //-------------------------------------------------------------------- 558 sal_Int32 SAL_CALL OAccessibleContextWrapper::getAccessibleChildCount( ) throw (RuntimeException) 559 { 560 return OAccessibleContextWrapperHelper::getAccessibleChildCount(); 561 } 562 563 //-------------------------------------------------------------------- 564 Reference< XAccessible > SAL_CALL OAccessibleContextWrapper::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException) 565 { 566 return OAccessibleContextWrapperHelper::getAccessibleChild( i ); 567 } 568 569 //-------------------------------------------------------------------- 570 Reference< XAccessible > SAL_CALL OAccessibleContextWrapper::getAccessibleParent( ) throw (RuntimeException) 571 { 572 return m_xParentAccessible; 573 } 574 575 //-------------------------------------------------------------------- 576 sal_Int32 SAL_CALL OAccessibleContextWrapper::getAccessibleIndexInParent( ) throw (RuntimeException) 577 { 578 return m_xInnerContext->getAccessibleIndexInParent(); 579 } 580 581 //-------------------------------------------------------------------- 582 sal_Int16 SAL_CALL OAccessibleContextWrapper::getAccessibleRole( ) throw (RuntimeException) 583 { 584 return m_xInnerContext->getAccessibleRole(); 585 } 586 587 //-------------------------------------------------------------------- 588 ::rtl::OUString SAL_CALL OAccessibleContextWrapper::getAccessibleDescription( ) throw (RuntimeException) 589 { 590 return m_xInnerContext->getAccessibleDescription(); 591 } 592 593 //-------------------------------------------------------------------- 594 ::rtl::OUString SAL_CALL OAccessibleContextWrapper::getAccessibleName( ) throw (RuntimeException) 595 { 596 return m_xInnerContext->getAccessibleName(); 597 } 598 599 //-------------------------------------------------------------------- 600 Reference< XAccessibleRelationSet > SAL_CALL OAccessibleContextWrapper::getAccessibleRelationSet( ) throw (RuntimeException) 601 { 602 return OAccessibleContextWrapperHelper::getAccessibleRelationSet(); 603 } 604 605 //-------------------------------------------------------------------- 606 Reference< XAccessibleStateSet > SAL_CALL OAccessibleContextWrapper::getAccessibleStateSet( ) throw (RuntimeException) 607 { 608 return m_xInnerContext->getAccessibleStateSet(); 609 } 610 611 //-------------------------------------------------------------------- 612 Locale SAL_CALL OAccessibleContextWrapper::getLocale( ) throw (IllegalAccessibleComponentStateException, RuntimeException) 613 { 614 return m_xInnerContext->getLocale(); 615 } 616 617 //-------------------------------------------------------------------- 618 void OAccessibleContextWrapper::notifyTranslatedEvent( const AccessibleEventObject& _rEvent ) throw (RuntimeException) 619 { 620 if ( m_nNotifierClient ) 621 AccessibleEventNotifier::addEvent( m_nNotifierClient, _rEvent ); 622 } 623 624 //-------------------------------------------------------------------- 625 void SAL_CALL OAccessibleContextWrapper::addEventListener( const Reference< XAccessibleEventListener >& _rxListener ) throw (RuntimeException) 626 { 627 ::osl::MutexGuard aGuard( m_aMutex ); 628 if ( !m_nNotifierClient ) 629 m_nNotifierClient = AccessibleEventNotifier::registerClient( ); 630 AccessibleEventNotifier::addEventListener( m_nNotifierClient, _rxListener ); 631 } 632 633 //-------------------------------------------------------------------- 634 void SAL_CALL OAccessibleContextWrapper::removeEventListener( const Reference< XAccessibleEventListener >& _rxListener ) throw (RuntimeException) 635 { 636 ::osl::MutexGuard aGuard( m_aMutex ); 637 if ( m_nNotifierClient ) 638 { 639 if ( 0 == AccessibleEventNotifier::removeEventListener( m_nNotifierClient, _rxListener ) ) 640 { 641 AccessibleEventNotifier::TClientId nId( m_nNotifierClient ); 642 m_nNotifierClient = 0; 643 AccessibleEventNotifier::revokeClient( nId ); 644 } 645 } 646 } 647 648 //-------------------------------------------------------------------- 649 void SAL_CALL OAccessibleContextWrapper::disposing() throw (RuntimeException) 650 { 651 AccessibleEventNotifier::TClientId nClientId( 0 ); 652 653 // --- <mutex lock> ----------------------------------------- 654 { 655 ::osl::MutexGuard aGuard( m_aMutex ); 656 657 // prepare notifying our AccessibleListeners 658 if ( m_nNotifierClient ) 659 { 660 nClientId = m_nNotifierClient; 661 m_nNotifierClient = 0; 662 } 663 } 664 // --- </mutex lock> ----------------------------------------- 665 666 // let the base class do 667 OAccessibleContextWrapperHelper::dispose(); 668 669 // notify the disposal 670 if ( nClientId ) 671 AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, *this ); 672 } 673 674 //-------------------------------------------------------------------- 675 void SAL_CALL OAccessibleContextWrapper::dispose() throw( RuntimeException ) 676 { 677 // simply disambiguate 678 OComponentProxyAggregation_CBase::dispose(); 679 } 680 681 //............................................................................. 682 } // namespace accessibility 683 //............................................................................. 684