1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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
;
38 //= OWrappedAccessibleChildrenManager
41 struct RemoveEventListener
42 : public ::std::unary_function
< AccessibleMap::value_type
, void >
45 Reference
< XEventListener
> m_xListener
;
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
);
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
)
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 ) );
121 m_aChildrenMap
.swap( aMap
);
125 Reference
< XAccessible
> OWrappedAccessibleChildrenManager::getAccessibleWrapperFor(
126 const Reference
< XAccessible
>& _rxKey
, bool _bCreate
)
128 Reference
< XAccessible
> xValue
;
132 // fprintf( stderr, "It was this path that was crashing stuff\n" );
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
;
143 { // not found in the cache, and allowed to create
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
)
154 "OWrappedAccessibleChildrenManager::"
155 "getAccessibleWrapperFor: element was already"
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
);
164 xComp
->addEventListener( this );
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
179 m_aChildrenMap
.swap( aMap
);
183 void OWrappedAccessibleChildrenManager::implTranslateChildEventValue( const Any
& _rInValue
, Any
& _rOutValue
)
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
);
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
:
234 // these Ids are also missed: SUB_WINDOW_OF_RELATION_CHANGED & TEXT_ATTRIBUTE_CHANGED
235 case AccessibleEventId::TEXT_SELECTION_CHANGED
:
236 // nothing to translate
240 OSL_FAIL( "OWrappedAccessibleChildrenManager::translateAccessibleEvent: unknown (or unexpected) event id!" );
246 void OWrappedAccessibleChildrenManager::handleChildNotification( const AccessibleEventObject
& _rEvent
)
248 if ( AccessibleEventId::INVALIDATE_ALL_CHILDREN
== _rEvent
.EventId
)
249 { // clear our child map
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();
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
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
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
);
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
);
361 m_aContext
= WeakReference
< XAccessibleContext
>( 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
);
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
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
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: */