Bump version to 4.3-4
[LibreOffice.git] / comphelper / source / misc / accessiblewrapper.cxx
blobe8beaeb1e2835e9338d84b7ebfd2a222ad8e15d2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <comphelper/accessiblewrapper.hxx>
21 #include <com/sun/star/reflection/XProxyFactory.hpp>
22 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
23 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
25 #include <algorithm>
27 using namespace ::comphelper;
28 using namespace ::com::sun::star::accessibility;
29 using namespace ::com::sun::star::uno;
30 using namespace ::com::sun::star::lang;
33 namespace comphelper
38 //= OWrappedAccessibleChildrenManager
41 struct RemoveEventListener
42 : public ::std::unary_function< AccessibleMap::value_type, void >
44 private:
45 Reference< XEventListener > m_xListener;
47 public:
48 RemoveEventListener( const Reference< XEventListener >& _rxListener )
49 :m_xListener( _rxListener )
53 void operator()( const AccessibleMap::value_type& _rMapEntry ) const
55 Reference< XComponent > xComp( _rMapEntry.first, UNO_QUERY );
56 if ( xComp.is() )
57 xComp->removeEventListener( m_xListener );
62 struct DisposeMappedChild
63 : public ::std::unary_function< AccessibleMap::value_type, void >
65 void operator()( const AccessibleMap::value_type& _rMapEntry ) const
67 Reference< XComponent > xContextComponent;
68 if ( _rMapEntry.second.is() )
69 xContextComponent = xContextComponent.query( _rMapEntry.second->getAccessibleContext() );
70 if ( xContextComponent.is() )
71 xContextComponent->dispose();
76 OWrappedAccessibleChildrenManager::OWrappedAccessibleChildrenManager( const Reference< XComponentContext >& _rxContext )
77 :m_xContext( _rxContext )
78 ,m_bTransientChildren( true )
83 OWrappedAccessibleChildrenManager::~OWrappedAccessibleChildrenManager( )
88 void OWrappedAccessibleChildrenManager::setTransientChildren( bool _bSet )
90 m_bTransientChildren = _bSet;
94 void OWrappedAccessibleChildrenManager::setOwningAccessible( const Reference< XAccessible >& _rxAcc )
96 OSL_ENSURE( !m_aOwningAccessible.get().is(), "OWrappedAccessibleChildrenManager::setOwningAccessible: to be called only once!" );
97 m_aOwningAccessible = WeakReference< XAccessible >( _rxAcc );
101 void OWrappedAccessibleChildrenManager::removeFromCache( const Reference< XAccessible >& _rxKey )
103 AccessibleMap::iterator aRemovedPos = m_aChildrenMap.find( _rxKey );
104 if ( m_aChildrenMap.end() != aRemovedPos )
105 { // it was cached
106 // remove ourself as event listener
107 RemoveEventListener aOperator( this );
108 aOperator( *aRemovedPos );
109 // and remove the entry from the map
110 m_aChildrenMap.erase( aRemovedPos );
115 void OWrappedAccessibleChildrenManager::invalidateAll( )
117 // remove as event listener from the map elements
118 ::std::for_each( m_aChildrenMap.begin(), m_aChildrenMap.end(), RemoveEventListener( this ) );
119 // clear the map
120 AccessibleMap aMap;
121 m_aChildrenMap.swap( aMap );
125 Reference< XAccessible > OWrappedAccessibleChildrenManager::getAccessibleWrapperFor(
126 const Reference< XAccessible >& _rxKey, bool _bCreate )
128 Reference< XAccessible > xValue;
130 if( !_rxKey.is() )
132 // fprintf( stderr, "It was this path that was crashing stuff\n" );
133 return xValue;
136 // do we have this child in the cahce?
137 AccessibleMap::const_iterator aPos = m_aChildrenMap.find( _rxKey );
138 if ( m_aChildrenMap.end() != aPos )
140 xValue = aPos->second;
142 else if ( _bCreate )
143 { // not found in the cache, and allowed to create
144 // -> new wrapper
145 xValue = new OAccessibleWrapper( m_xContext, _rxKey, (Reference< XAccessible >)m_aOwningAccessible );
147 // see if we do cache children
148 if ( !m_bTransientChildren )
150 if (!m_aChildrenMap.insert(
151 AccessibleMap::value_type( _rxKey, xValue ) ).second)
153 OSL_FAIL(
154 "OWrappedAccessibleChildrenManager::"
155 "getAccessibleWrapperFor: element was already"
156 " inserted!" );
159 // listen for disposals of inner children - this may happen when the inner context
160 // is the owner for the inner children (it will dispose these children, and of course
161 // not our wrapper for these children)
162 Reference< XComponent > xComp( _rxKey, UNO_QUERY );
163 if ( xComp.is() )
164 xComp->addEventListener( this );
168 return xValue;
172 void OWrappedAccessibleChildrenManager::dispose()
174 // dispose our children
175 ::std::for_each( m_aChildrenMap.begin(), m_aChildrenMap.end(), RemoveEventListener( this ) );
176 ::std::for_each( m_aChildrenMap.begin(), m_aChildrenMap.end(), DisposeMappedChild( ) );
177 // clear our children
178 AccessibleMap aMap;
179 m_aChildrenMap.swap( aMap );
183 void OWrappedAccessibleChildrenManager::implTranslateChildEventValue( const Any& _rInValue, Any& _rOutValue )
185 _rOutValue.clear();
186 Reference< XAccessible > xChild;
187 if ( _rInValue >>= xChild )
188 _rOutValue <<= getAccessibleWrapperFor( xChild, true );
192 void OWrappedAccessibleChildrenManager::translateAccessibleEvent( const AccessibleEventObject& _rEvent, AccessibleEventObject& _rTranslatedEvent )
194 // just in case we can't translate some of the values:
195 _rTranslatedEvent.NewValue = _rEvent.NewValue;
196 _rTranslatedEvent.OldValue = _rEvent.OldValue;
198 switch ( _rEvent.EventId )
200 case AccessibleEventId::CHILD:
201 case AccessibleEventId::ACTIVE_DESCENDANT_CHANGED:
202 case AccessibleEventId::CONTROLLED_BY_RELATION_CHANGED:
203 case AccessibleEventId::CONTROLLER_FOR_RELATION_CHANGED:
204 case AccessibleEventId::LABEL_FOR_RELATION_CHANGED:
205 case AccessibleEventId::LABELED_BY_RELATION_CHANGED:
206 case AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED:
207 case AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED:
208 // these are events where both the old and the new value contain child references
209 implTranslateChildEventValue( _rEvent.OldValue, _rTranslatedEvent.OldValue );
210 implTranslateChildEventValue( _rEvent.NewValue, _rTranslatedEvent.NewValue );
211 break;
213 case AccessibleEventId::NAME_CHANGED:
214 case AccessibleEventId::DESCRIPTION_CHANGED:
215 case AccessibleEventId::ACTION_CHANGED:
216 case AccessibleEventId::STATE_CHANGED:
217 case AccessibleEventId::BOUNDRECT_CHANGED:
218 case AccessibleEventId::INVALIDATE_ALL_CHILDREN:
219 case AccessibleEventId::SELECTION_CHANGED:
220 case AccessibleEventId::VISIBLE_DATA_CHANGED:
221 case AccessibleEventId::VALUE_CHANGED:
222 case AccessibleEventId::MEMBER_OF_RELATION_CHANGED:
223 case AccessibleEventId::CARET_CHANGED:
224 case AccessibleEventId::TEXT_CHANGED:
225 case AccessibleEventId::HYPERTEXT_CHANGED:
226 case AccessibleEventId::TABLE_CAPTION_CHANGED:
227 case AccessibleEventId::TABLE_COLUMN_DESCRIPTION_CHANGED:
228 case AccessibleEventId::TABLE_COLUMN_HEADER_CHANGED:
229 case AccessibleEventId::TABLE_MODEL_CHANGED:
230 case AccessibleEventId::TABLE_ROW_DESCRIPTION_CHANGED:
231 case AccessibleEventId::TABLE_ROW_HEADER_CHANGED:
232 case AccessibleEventId::TABLE_SUMMARY_CHANGED:
233 // #130798#
234 // these Ids are also missed: SUB_WINDOW_OF_RELATION_CHANGED & TEXT_ATTRIBUTE_CHANGED
235 case AccessibleEventId::TEXT_SELECTION_CHANGED:
236 // nothing to translate
237 break;
239 default:
240 OSL_FAIL( "OWrappedAccessibleChildrenManager::translateAccessibleEvent: unknown (or unexpected) event id!" );
241 break;
246 void OWrappedAccessibleChildrenManager::handleChildNotification( const AccessibleEventObject& _rEvent )
248 if ( AccessibleEventId::INVALIDATE_ALL_CHILDREN == _rEvent.EventId )
249 { // clear our child map
250 invalidateAll( );
252 else if ( AccessibleEventId::CHILD == _rEvent.EventId )
254 // check if the removed or replaced element is cached
255 Reference< XAccessible > xRemoved;
256 if ( _rEvent.OldValue >>= xRemoved )
257 removeFromCache( xRemoved );
262 void SAL_CALL OWrappedAccessibleChildrenManager::disposing( const EventObject& _rSource ) throw (RuntimeException, std::exception)
264 // this should come from one of the inner XAccessible's of our children
265 Reference< XAccessible > xSource( _rSource.Source, UNO_QUERY );
266 AccessibleMap::iterator aDisposedPos = m_aChildrenMap.find( xSource );
267 #if OSL_DEBUG_LEVEL > 0
268 if ( m_aChildrenMap.end() == aDisposedPos )
270 OSL_FAIL( "OWrappedAccessibleChildrenManager::disposing: where did this come from?" );
271 // helper for dignostics
272 Reference< XAccessible > xOwningAccessible( m_aOwningAccessible );
273 Reference< XAccessibleContext > xContext;
276 if ( xOwningAccessible.is() )
277 xContext = xOwningAccessible->getAccessibleContext();
278 if ( xContext.is() )
280 //TODO: do something
281 //OUString sName = xContext->getAccessibleName();
282 //OUString sDescription = xContext->getAccessibleDescription();
283 //sal_Int32 nPlaceYourBreakpointHere = 0;
286 catch( const Exception& /*e*/ )
288 // silent this, it's only diagnostics which failed
291 #endif
292 if ( m_aChildrenMap.end() != aDisposedPos )
294 m_aChildrenMap.erase( aDisposedPos );
299 //= OAccessibleWrapper (implementation)
302 OAccessibleWrapper::OAccessibleWrapper( const Reference< XComponentContext >& _rxContext,
303 const Reference< XAccessible >& _rxInnerAccessible, const Reference< XAccessible >& _rxParentAccessible )
304 :OAccessibleWrapper_Base( )
305 ,OComponentProxyAggregation( _rxContext, Reference< XComponent >( _rxInnerAccessible, UNO_QUERY ) )
306 ,m_xParentAccessible( _rxParentAccessible )
307 ,m_xInnerAccessible( _rxInnerAccessible )
312 OAccessibleWrapper::~OAccessibleWrapper( )
314 if ( !m_rBHelper.bDisposed )
316 acquire(); // to prevent duplicate dtor calls
317 dispose();
322 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleWrapper, OComponentProxyAggregation, OAccessibleWrapper_Base )
323 IMPLEMENT_FORWARD_REFCOUNT( OAccessibleWrapper, OComponentProxyAggregation )
326 Any OAccessibleWrapper::queryInterface( const Type& _rType ) throw (RuntimeException, std::exception)
328 // #111089# instead of the inner XAccessible the proxy XAccessible must be returned
329 Any aReturn = OAccessibleWrapper_Base::queryInterface( _rType );
330 if ( !aReturn.hasValue() )
331 aReturn = OComponentProxyAggregation::queryInterface( _rType );
333 return aReturn;
337 Reference< XAccessibleContext > OAccessibleWrapper::getContextNoCreate( ) const
339 return (Reference< XAccessibleContext >)m_aContext;
343 OAccessibleContextWrapper* OAccessibleWrapper::createAccessibleContext( const Reference< XAccessibleContext >& _rxInnerContext )
345 return new OAccessibleContextWrapper( getComponentContext(), _rxInnerContext, this, m_xParentAccessible );
349 Reference< XAccessibleContext > SAL_CALL OAccessibleWrapper::getAccessibleContext( ) throw (RuntimeException, std::exception)
351 // see if the context is still alive (we cache it)
352 Reference< XAccessibleContext > xContext = (Reference< XAccessibleContext >)m_aContext;
353 if ( !xContext.is() )
355 // create a new context
356 Reference< XAccessibleContext > xInnerContext = m_xInnerAccessible->getAccessibleContext( );
357 if ( xInnerContext.is() )
359 xContext = createAccessibleContext( xInnerContext );
360 // cache it
361 m_aContext = WeakReference< XAccessibleContext >( xContext );
365 return xContext;
369 //= OAccessibleWrapper (implementation)
372 OAccessibleContextWrapperHelper::OAccessibleContextWrapperHelper(
373 const Reference< XComponentContext >& _rxContext,
374 ::cppu::OBroadcastHelper& _rBHelper,
375 const Reference< XAccessibleContext >& _rxInnerAccessibleContext,
376 const Reference< XAccessible >& _rxOwningAccessible,
377 const Reference< XAccessible >& _rxParentAccessible )
378 :OComponentProxyAggregationHelper( _rxContext, _rBHelper )
379 ,m_xInnerContext( _rxInnerAccessibleContext )
380 ,m_xOwningAccessible( _rxOwningAccessible )
381 ,m_xParentAccessible( _rxParentAccessible )
382 ,m_pChildMapper( NULL )
384 // initialize the mapper for our children
385 m_pChildMapper = new OWrappedAccessibleChildrenManager( getComponentContext() );
386 m_pChildMapper->acquire();
388 // determine if we're allowed to cache children
389 Reference< XAccessibleStateSet > xStates( m_xInnerContext->getAccessibleStateSet( ) );
390 OSL_ENSURE( xStates.is(), "OAccessibleContextWrapperHelper::OAccessibleContextWrapperHelper: no inner state set!" );
391 m_pChildMapper->setTransientChildren( !xStates.is() || xStates->contains( AccessibleStateType::MANAGES_DESCENDANTS) );
393 m_pChildMapper->setOwningAccessible( m_xOwningAccessible );
397 void OAccessibleContextWrapperHelper::aggregateProxy( oslInterlockedCount& _rRefCount, ::cppu::OWeakObject& _rDelegator )
399 Reference< XComponent > xInnerComponent( m_xInnerContext, UNO_QUERY );
400 OSL_ENSURE( xInnerComponent.is(), "OComponentProxyAggregation::aggregateProxy: accessible is no XComponent!" );
401 if ( xInnerComponent.is() )
402 componentAggregateProxyFor( xInnerComponent, _rRefCount, _rDelegator );
404 // add as event listener to the inner context, because we want to multiplex the AccessibleEvents
405 osl_atomic_increment( &_rRefCount );
407 Reference< XAccessibleEventBroadcaster > xBroadcaster( m_xInner, UNO_QUERY );
408 if ( xBroadcaster.is() )
409 xBroadcaster->addAccessibleEventListener( this );
411 osl_atomic_decrement( &_rRefCount );
415 OAccessibleContextWrapperHelper::~OAccessibleContextWrapperHelper( )
417 OSL_ENSURE( m_rBHelper.bDisposed, "OAccessibleContextWrapperHelper::~OAccessibleContextWrapperHelper: you should ensure (in your dtor) that the object is disposed!" );
419 m_pChildMapper->release();
420 m_pChildMapper = NULL;
424 Any SAL_CALL OAccessibleContextWrapperHelper::queryInterface( const Type& _rType ) throw (RuntimeException, std::exception)
426 Any aReturn = OComponentProxyAggregationHelper::queryInterface( _rType );
427 if ( !aReturn.hasValue() )
428 aReturn = OAccessibleContextWrapperHelper_Base::queryInterface( _rType );
429 return aReturn;
433 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleContextWrapperHelper, OComponentProxyAggregationHelper, OAccessibleContextWrapperHelper_Base )
436 sal_Int32 OAccessibleContextWrapperHelper::baseGetAccessibleChildCount( ) throw (RuntimeException, std::exception)
438 return m_xInnerContext->getAccessibleChildCount();
442 Reference< XAccessible > OAccessibleContextWrapperHelper::baseGetAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException, std::exception)
444 // get the child of the wrapped component
445 Reference< XAccessible > xInnerChild = m_xInnerContext->getAccessibleChild( i );
446 return m_pChildMapper->getAccessibleWrapperFor( xInnerChild );
450 Reference< XAccessibleRelationSet > OAccessibleContextWrapperHelper::baseGetAccessibleRelationSet( ) throw (RuntimeException, std::exception)
452 return m_xInnerContext->getAccessibleRelationSet();
453 // TODO: if this relation set would contain relations to siblings, we would normally need
454 // to wrap them, too ....
458 void SAL_CALL OAccessibleContextWrapperHelper::notifyEvent( const AccessibleEventObject& _rEvent ) throw (RuntimeException, std::exception)
460 #if OSL_DEBUG_LEVEL > 0
461 if ( AccessibleEventId::STATE_CHANGED == _rEvent.EventId )
463 bool bChildTransienceChanged = false;
464 sal_Int16 nChangeState = 0;
465 if ( _rEvent.OldValue >>= nChangeState )
466 bChildTransienceChanged = bChildTransienceChanged || AccessibleStateType::MANAGES_DESCENDANTS == nChangeState;
467 if ( _rEvent.NewValue >>= nChangeState )
468 bChildTransienceChanged = bChildTransienceChanged || AccessibleStateType::MANAGES_DESCENDANTS == nChangeState;
469 OSL_ENSURE( !bChildTransienceChanged, "OAccessibleContextWrapperHelper::notifyEvent: MANAGES_DESCENDANTS is not expected to change during runtime!" );
470 // if this asserts, then we would need to update our m_bTransientChildren flag here,
471 // as well as (potentially) our child cache
473 #endif
474 AccessibleEventObject aTranslatedEvent( _rEvent );
477 ::osl::MutexGuard aGuard( m_rBHelper.rMutex );
479 // translate the event
480 queryInterface( ::getCppuType( static_cast< Reference< XInterface >* >( NULL ) ) ) >>= aTranslatedEvent.Source;
481 m_pChildMapper->translateAccessibleEvent( _rEvent, aTranslatedEvent );
483 // see if any of these notifications affect our child manager
484 m_pChildMapper->handleChildNotification( _rEvent );
486 if ( aTranslatedEvent.NewValue == m_xInner )
487 aTranslatedEvent.NewValue = makeAny(aTranslatedEvent.Source);
488 if ( aTranslatedEvent.OldValue == m_xInner )
489 aTranslatedEvent.OldValue = makeAny(aTranslatedEvent.Source);
492 notifyTranslatedEvent( aTranslatedEvent );
496 void SAL_CALL OAccessibleContextWrapperHelper::dispose() throw( RuntimeException, std::exception )
498 ::osl::MutexGuard aGuard( m_rBHelper.rMutex );
500 // stop multiplexing events
501 Reference< XAccessibleEventBroadcaster > xBroadcaster( m_xInner, UNO_QUERY );
502 OSL_ENSURE( xBroadcaster.is(), "OAccessibleContextWrapperHelper::disposing(): inner context is no broadcaster!" );
503 if ( xBroadcaster.is() )
504 xBroadcaster->removeAccessibleEventListener( this );
506 // dispose the child cache/map
507 m_pChildMapper->dispose();
509 // let the base class dispose the inner component
510 OComponentProxyAggregationHelper::dispose();
514 void SAL_CALL OAccessibleContextWrapperHelper::disposing( const EventObject& _rEvent ) throw (RuntimeException, std::exception)
516 // simply disambiguate this
517 OComponentProxyAggregationHelper::disposing( _rEvent );
521 //= OAccessibleContextWrapper
524 IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleContextWrapper, OAccessibleContextWrapper_CBase, OAccessibleContextWrapperHelper )
527 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleContextWrapper, OAccessibleContextWrapper_CBase, OAccessibleContextWrapperHelper )
530 OAccessibleContextWrapper::OAccessibleContextWrapper( const Reference< XComponentContext >& _rxContext,
531 const Reference< XAccessibleContext >& _rxInnerAccessibleContext, const Reference< XAccessible >& _rxOwningAccessible,
532 const Reference< XAccessible >& _rxParentAccessible )
533 :OAccessibleContextWrapper_CBase( m_aMutex )
534 ,OAccessibleContextWrapperHelper( _rxContext, rBHelper, _rxInnerAccessibleContext, _rxOwningAccessible, _rxParentAccessible )
535 ,m_nNotifierClient( 0 )
537 aggregateProxy( m_refCount, *this );
541 OAccessibleContextWrapper::~OAccessibleContextWrapper()
546 sal_Int32 SAL_CALL OAccessibleContextWrapper::getAccessibleChildCount( ) throw (RuntimeException, std::exception)
548 return baseGetAccessibleChildCount();
552 Reference< XAccessible > SAL_CALL OAccessibleContextWrapper::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException, std::exception)
554 return baseGetAccessibleChild( i );
558 Reference< XAccessible > SAL_CALL OAccessibleContextWrapper::getAccessibleParent( ) throw (RuntimeException, std::exception)
560 return m_xParentAccessible;
564 sal_Int32 SAL_CALL OAccessibleContextWrapper::getAccessibleIndexInParent( ) throw (RuntimeException, std::exception)
566 return m_xInnerContext->getAccessibleIndexInParent();
570 sal_Int16 SAL_CALL OAccessibleContextWrapper::getAccessibleRole( ) throw (RuntimeException, std::exception)
572 return m_xInnerContext->getAccessibleRole();
576 OUString SAL_CALL OAccessibleContextWrapper::getAccessibleDescription( ) throw (RuntimeException, std::exception)
578 return m_xInnerContext->getAccessibleDescription();
582 OUString SAL_CALL OAccessibleContextWrapper::getAccessibleName( ) throw (RuntimeException, std::exception)
584 return m_xInnerContext->getAccessibleName();
588 Reference< XAccessibleRelationSet > SAL_CALL OAccessibleContextWrapper::getAccessibleRelationSet( ) throw (RuntimeException, std::exception)
590 return baseGetAccessibleRelationSet();
594 Reference< XAccessibleStateSet > SAL_CALL OAccessibleContextWrapper::getAccessibleStateSet( ) throw (RuntimeException, std::exception)
596 return m_xInnerContext->getAccessibleStateSet();
600 Locale SAL_CALL OAccessibleContextWrapper::getLocale( ) throw (IllegalAccessibleComponentStateException, RuntimeException, std::exception)
602 return m_xInnerContext->getLocale();
606 void OAccessibleContextWrapper::notifyTranslatedEvent( const AccessibleEventObject& _rEvent ) throw (RuntimeException)
608 if ( m_nNotifierClient )
609 AccessibleEventNotifier::addEvent( m_nNotifierClient, _rEvent );
613 void SAL_CALL OAccessibleContextWrapper::addAccessibleEventListener( const Reference< XAccessibleEventListener >& _rxListener ) throw (RuntimeException, std::exception)
615 ::osl::MutexGuard aGuard( m_aMutex );
616 if ( !m_nNotifierClient )
617 m_nNotifierClient = AccessibleEventNotifier::registerClient( );
618 AccessibleEventNotifier::addEventListener( m_nNotifierClient, _rxListener );
622 void SAL_CALL OAccessibleContextWrapper::removeAccessibleEventListener( const Reference< XAccessibleEventListener >& _rxListener ) throw (RuntimeException, std::exception)
624 ::osl::MutexGuard aGuard( m_aMutex );
625 if ( m_nNotifierClient )
627 if ( 0 == AccessibleEventNotifier::removeEventListener( m_nNotifierClient, _rxListener ) )
629 AccessibleEventNotifier::TClientId nId( m_nNotifierClient );
630 m_nNotifierClient = 0;
631 AccessibleEventNotifier::revokeClient( nId );
637 void SAL_CALL OAccessibleContextWrapper::disposing() throw (RuntimeException)
639 AccessibleEventNotifier::TClientId nClientId( 0 );
641 // --- <mutex lock> -----------------------------------------
643 ::osl::MutexGuard aGuard( m_aMutex );
645 // prepare notifying our AccessibleListeners
646 if ( m_nNotifierClient )
648 nClientId = m_nNotifierClient;
649 m_nNotifierClient = 0;
652 // --- </mutex lock> -----------------------------------------
654 // let the base class do
655 OAccessibleContextWrapperHelper::dispose();
657 // notify the disposal
658 if ( nClientId )
659 AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, *this );
663 void SAL_CALL OAccessibleContextWrapper::dispose() throw( RuntimeException, std::exception )
665 // simply disambiguate
666 WeakComponentImplHelperBase::dispose();
670 } // namespace accessibility
673 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */