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