merged tag ooo/OOO330_m14
[LibreOffice.git] / comphelper / source / misc / accessiblewrapper.cxx
blob0ed694856b973c79d80645731bbd7deea3b71399
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
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>
35 #include <algorithm>
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;
42 //.............................................................................
43 namespace comphelper
45 //.............................................................................
47 //=========================================================================
48 //= OWrappedAccessibleChildrenManager
49 //=========================================================================
50 //--------------------------------------------------------------------
51 struct RemoveEventListener
52 : public ::std::unary_function< AccessibleMap::value_type, void >
54 private:
55 Reference< XEventListener > m_xListener;
57 public:
58 RemoveEventListener( const Reference< XEventListener >& _rxListener )
59 :m_xListener( _rxListener )
63 void operator()( const AccessibleMap::value_type& _rMapEntry ) const
65 Reference< XComponent > xComp( _rMapEntry.first, UNO_QUERY );
66 if ( xComp.is() )
67 xComp->removeEventListener( m_xListener );
71 //--------------------------------------------------------------------
72 struct DisposeMappedChild
73 : public ::std::unary_function< AccessibleMap::value_type, void >
75 void operator()( const AccessibleMap::value_type& _rMapEntry ) const
77 Reference< XComponent > xContextComponent;
78 if ( _rMapEntry.second.is() )
79 xContextComponent = xContextComponent.query( _rMapEntry.second->getAccessibleContext() );
80 if ( xContextComponent.is() )
81 xContextComponent->dispose();
85 //-------------------------------------------------------------------------
86 OWrappedAccessibleChildrenManager::OWrappedAccessibleChildrenManager( const Reference< XMultiServiceFactory >& _rxORB )
87 :m_xORB( _rxORB )
88 ,m_bTransientChildren( sal_True )
92 //-------------------------------------------------------------------------
93 OWrappedAccessibleChildrenManager::~OWrappedAccessibleChildrenManager( )
97 //-------------------------------------------------------------------------
98 void OWrappedAccessibleChildrenManager::setTransientChildren( sal_Bool _bSet )
100 m_bTransientChildren = _bSet;
103 //-------------------------------------------------------------------------
104 void OWrappedAccessibleChildrenManager::setOwningAccessible( const Reference< XAccessible >& _rxAcc )
106 OSL_ENSURE( !m_aOwningAccessible.get().is(), "OWrappedAccessibleChildrenManager::setOwningAccessible: to be called only once!" );
107 m_aOwningAccessible = WeakReference< XAccessible >( _rxAcc );
110 //-------------------------------------------------------------------------
111 void OWrappedAccessibleChildrenManager::removeFromCache( const Reference< XAccessible >& _rxKey )
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 );
124 //-------------------------------------------------------------------------
125 void OWrappedAccessibleChildrenManager::invalidateAll( )
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 );
134 //-------------------------------------------------------------------------
135 Reference< XAccessible > OWrappedAccessibleChildrenManager::getAccessibleWrapperFor(
136 const Reference< XAccessible >& _rxKey, sal_Bool _bCreate )
138 Reference< XAccessible > xValue;
140 if( !_rxKey.is() )
142 // fprintf( stderr, "It was this path that was crashing stuff\n" );
143 return xValue;
146 // do we have this child in the cahce?
147 AccessibleMap::const_iterator aPos = m_aChildrenMap.find( _rxKey );
148 if ( m_aChildrenMap.end() != aPos )
150 xValue = aPos->second;
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 );
157 // see if we do cache children
158 if ( !m_bTransientChildren )
160 if (!m_aChildrenMap.insert(
161 AccessibleMap::value_type( _rxKey, xValue ) ).second)
163 OSL_ENSURE(
164 false,
165 "OWrappedAccessibleChildrenManager::"
166 "getAccessibleWrapperFor: element was already"
167 " inserted!" );
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 );
179 return xValue;
182 //-------------------------------------------------------------------------
183 void OWrappedAccessibleChildrenManager::dispose()
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 );
193 //--------------------------------------------------------------------
194 void OWrappedAccessibleChildrenManager::implTranslateChildEventValue( const Any& _rInValue, Any& _rOutValue )
196 _rOutValue.clear();
197 Reference< XAccessible > xChild;
198 if ( _rInValue >>= xChild )
199 _rOutValue <<= getAccessibleWrapperFor( xChild, sal_True );
202 //-------------------------------------------------------------------------
203 void OWrappedAccessibleChildrenManager::translateAccessibleEvent( const AccessibleEventObject& _rEvent, AccessibleEventObject& _rTranslatedEvent )
205 // just in case we can't translate some of the values:
206 _rTranslatedEvent.NewValue = _rEvent.NewValue;
207 _rTranslatedEvent.OldValue = _rEvent.OldValue;
209 switch ( _rEvent.EventId )
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;
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;
251 default:
252 OSL_ENSURE( sal_False, "OWrappedAccessibleChildrenManager::translateAccessibleEvent: unknown (or unexpected) event id!" );
253 break;
257 //-------------------------------------------------------------------------
258 void OWrappedAccessibleChildrenManager::handleChildNotification( const AccessibleEventObject& _rEvent )
260 if ( AccessibleEventId::INVALIDATE_ALL_CHILDREN == _rEvent.EventId )
261 { // clear our child map
262 invalidateAll( );
264 else if ( AccessibleEventId::CHILD == _rEvent.EventId )
266 // check if the removed or replaced element is cached
267 Reference< XAccessible > xRemoved;
268 if ( _rEvent.OldValue >>= xRemoved )
269 removeFromCache( xRemoved );
273 //--------------------------------------------------------------------
274 void SAL_CALL OWrappedAccessibleChildrenManager::disposing( const EventObject& _rSource ) throw (RuntimeException)
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 )
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;
289 if ( xOwningAccessible.is() )
290 xContext = xOwningAccessible->getAccessibleContext();
291 if ( xContext.is() )
293 ::rtl::OUString sName = xContext->getAccessibleName();
294 ::rtl::OUString sDescription = xContext->getAccessibleDescription();
295 // sal_Int32 nPlaceYourBreakpointHere = 0;
298 catch( const Exception& /*e*/ )
300 // silent this, it's only diagnostics which failed
303 #endif
304 if ( m_aChildrenMap.end() != aDisposedPos )
306 m_aChildrenMap.erase( aDisposedPos );
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 )
323 //--------------------------------------------------------------------
324 OAccessibleWrapper::~OAccessibleWrapper( )
326 if ( !m_rBHelper.bDisposed )
328 acquire(); // to prevent duplicate dtor calls
329 dispose();
333 //--------------------------------------------------------------------
334 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleWrapper, OComponentProxyAggregation, OAccessibleWrapper_Base )
335 IMPLEMENT_FORWARD_REFCOUNT( OAccessibleWrapper, OComponentProxyAggregation )
337 //--------------------------------------------------------------------
338 Any OAccessibleWrapper::queryInterface( const Type& _rType ) throw (RuntimeException)
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 );
345 return aReturn;
348 //--------------------------------------------------------------------
349 Reference< XAccessibleContext > OAccessibleWrapper::getContextNoCreate( ) const
351 return (Reference< XAccessibleContext >)m_aContext;
354 //--------------------------------------------------------------------
355 OAccessibleContextWrapper* OAccessibleWrapper::createAccessibleContext( const Reference< XAccessibleContext >& _rxInnerContext )
357 return new OAccessibleContextWrapper( getORB(), _rxInnerContext, this, m_xParentAccessible );
360 //--------------------------------------------------------------------
361 Reference< XAccessibleContext > SAL_CALL OAccessibleWrapper::getAccessibleContext( ) throw (RuntimeException)
363 // see if the context is still alive (we cache it)
364 Reference< XAccessibleContext > xContext = (Reference< XAccessibleContext >)m_aContext;
365 if ( !xContext.is() )
367 // create a new context
368 Reference< XAccessibleContext > xInnerContext = m_xInnerAccessible->getAccessibleContext( );
369 if ( xInnerContext.is() )
371 xContext = createAccessibleContext( xInnerContext );
372 // cache it
373 m_aContext = WeakReference< XAccessibleContext >( xContext );
377 return xContext;
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 )
396 // initialize the mapper for our children
397 m_pChildMapper = new OWrappedAccessibleChildrenManager( getORB() );
398 m_pChildMapper->acquire();
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) );
405 m_pChildMapper->setOwningAccessible( m_xOwningAccessible );
408 //--------------------------------------------------------------------
409 void OAccessibleContextWrapperHelper::aggregateProxy( oslInterlockedCount& _rRefCount, ::cppu::OWeakObject& _rDelegator )
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 );
416 // add as event listener to the inner context, because we want to multiplex the AccessibleEvents
417 osl_incrementInterlockedCount( &_rRefCount );
419 Reference< XAccessibleEventBroadcaster > xBroadcaster( m_xInner, UNO_QUERY );
420 if ( xBroadcaster.is() )
421 xBroadcaster->addEventListener( this );
423 osl_decrementInterlockedCount( &_rRefCount );
426 //--------------------------------------------------------------------
427 OAccessibleContextWrapperHelper::~OAccessibleContextWrapperHelper( )
429 OSL_ENSURE( m_rBHelper.bDisposed, "OAccessibleContextWrapperHelper::~OAccessibleContextWrapperHelper: you should ensure (in your dtor) that the object is disposed!" );
431 m_pChildMapper->release();
432 m_pChildMapper = NULL;
435 //--------------------------------------------------------------------
436 Any SAL_CALL OAccessibleContextWrapperHelper::queryInterface( const Type& _rType ) throw (RuntimeException)
438 Any aReturn = OComponentProxyAggregationHelper::queryInterface( _rType );
439 if ( !aReturn.hasValue() )
440 aReturn = OAccessibleContextWrapperHelper_Base::queryInterface( _rType );
441 return aReturn;
444 //--------------------------------------------------------------------
445 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleContextWrapperHelper, OComponentProxyAggregationHelper, OAccessibleContextWrapperHelper_Base )
447 //--------------------------------------------------------------------
448 sal_Int32 SAL_CALL OAccessibleContextWrapperHelper::getAccessibleChildCount( ) throw (RuntimeException)
450 return m_xInnerContext->getAccessibleChildCount();
453 //--------------------------------------------------------------------
454 Reference< XAccessible > SAL_CALL OAccessibleContextWrapperHelper::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException)
456 // get the child of the wrapped component
457 Reference< XAccessible > xInnerChild = m_xInnerContext->getAccessibleChild( i );
458 return m_pChildMapper->getAccessibleWrapperFor( xInnerChild );
461 //--------------------------------------------------------------------
462 Reference< XAccessibleRelationSet > SAL_CALL OAccessibleContextWrapperHelper::getAccessibleRelationSet( ) throw (RuntimeException)
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 ....
469 //--------------------------------------------------------------------
470 void SAL_CALL OAccessibleContextWrapperHelper::notifyEvent( const AccessibleEventObject& _rEvent ) throw (RuntimeException)
472 #if OSL_DEBUG_LEVEL > 0
473 if ( AccessibleEventId::STATE_CHANGED == _rEvent.EventId )
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
485 #endif
486 AccessibleEventObject aTranslatedEvent( _rEvent );
489 ::osl::MutexGuard aGuard( m_rBHelper.rMutex );
491 // translate the event
492 queryInterface( ::getCppuType( static_cast< Reference< XInterface >* >( NULL ) ) ) >>= aTranslatedEvent.Source;
493 m_pChildMapper->translateAccessibleEvent( _rEvent, aTranslatedEvent );
495 // see if any of these notifications affect our child manager
496 m_pChildMapper->handleChildNotification( _rEvent );
498 if ( aTranslatedEvent.NewValue == m_xInner )
499 aTranslatedEvent.NewValue = makeAny(aTranslatedEvent.Source);
500 if ( aTranslatedEvent.OldValue == m_xInner )
501 aTranslatedEvent.OldValue = makeAny(aTranslatedEvent.Source);
504 notifyTranslatedEvent( aTranslatedEvent );
507 //--------------------------------------------------------------------
508 void SAL_CALL OAccessibleContextWrapperHelper::dispose() throw( RuntimeException )
510 ::osl::MutexGuard aGuard( m_rBHelper.rMutex );
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 );
518 // dispose the child cache/map
519 m_pChildMapper->dispose();
521 // let the base class dispose the inner component
522 OComponentProxyAggregationHelper::dispose();
525 //--------------------------------------------------------------------
526 void SAL_CALL OAccessibleContextWrapperHelper::disposing( const EventObject& _rEvent ) throw (RuntimeException)
528 // simply disambiguate this
529 OComponentProxyAggregationHelper::disposing( _rEvent );
532 //====================================================================
533 //= OAccessibleContextWrapper
534 //====================================================================
535 //--------------------------------------------------------------------
536 IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleContextWrapper, OAccessibleContextWrapper_CBase, OAccessibleContextWrapperHelper )
538 //--------------------------------------------------------------------
539 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleContextWrapper, OAccessibleContextWrapper_CBase, OAccessibleContextWrapperHelper )
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 )
549 aggregateProxy( m_refCount, *this );
552 //--------------------------------------------------------------------
553 OAccessibleContextWrapper::~OAccessibleContextWrapper()
557 //--------------------------------------------------------------------
558 sal_Int32 SAL_CALL OAccessibleContextWrapper::getAccessibleChildCount( ) throw (RuntimeException)
560 return OAccessibleContextWrapperHelper::getAccessibleChildCount();
563 //--------------------------------------------------------------------
564 Reference< XAccessible > SAL_CALL OAccessibleContextWrapper::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException)
566 return OAccessibleContextWrapperHelper::getAccessibleChild( i );
569 //--------------------------------------------------------------------
570 Reference< XAccessible > SAL_CALL OAccessibleContextWrapper::getAccessibleParent( ) throw (RuntimeException)
572 return m_xParentAccessible;
575 //--------------------------------------------------------------------
576 sal_Int32 SAL_CALL OAccessibleContextWrapper::getAccessibleIndexInParent( ) throw (RuntimeException)
578 return m_xInnerContext->getAccessibleIndexInParent();
581 //--------------------------------------------------------------------
582 sal_Int16 SAL_CALL OAccessibleContextWrapper::getAccessibleRole( ) throw (RuntimeException)
584 return m_xInnerContext->getAccessibleRole();
587 //--------------------------------------------------------------------
588 ::rtl::OUString SAL_CALL OAccessibleContextWrapper::getAccessibleDescription( ) throw (RuntimeException)
590 return m_xInnerContext->getAccessibleDescription();
593 //--------------------------------------------------------------------
594 ::rtl::OUString SAL_CALL OAccessibleContextWrapper::getAccessibleName( ) throw (RuntimeException)
596 return m_xInnerContext->getAccessibleName();
599 //--------------------------------------------------------------------
600 Reference< XAccessibleRelationSet > SAL_CALL OAccessibleContextWrapper::getAccessibleRelationSet( ) throw (RuntimeException)
602 return OAccessibleContextWrapperHelper::getAccessibleRelationSet();
605 //--------------------------------------------------------------------
606 Reference< XAccessibleStateSet > SAL_CALL OAccessibleContextWrapper::getAccessibleStateSet( ) throw (RuntimeException)
608 return m_xInnerContext->getAccessibleStateSet();
611 //--------------------------------------------------------------------
612 Locale SAL_CALL OAccessibleContextWrapper::getLocale( ) throw (IllegalAccessibleComponentStateException, RuntimeException)
614 return m_xInnerContext->getLocale();
617 //--------------------------------------------------------------------
618 void OAccessibleContextWrapper::notifyTranslatedEvent( const AccessibleEventObject& _rEvent ) throw (RuntimeException)
620 if ( m_nNotifierClient )
621 AccessibleEventNotifier::addEvent( m_nNotifierClient, _rEvent );
624 //--------------------------------------------------------------------
625 void SAL_CALL OAccessibleContextWrapper::addEventListener( const Reference< XAccessibleEventListener >& _rxListener ) throw (RuntimeException)
627 ::osl::MutexGuard aGuard( m_aMutex );
628 if ( !m_nNotifierClient )
629 m_nNotifierClient = AccessibleEventNotifier::registerClient( );
630 AccessibleEventNotifier::addEventListener( m_nNotifierClient, _rxListener );
633 //--------------------------------------------------------------------
634 void SAL_CALL OAccessibleContextWrapper::removeEventListener( const Reference< XAccessibleEventListener >& _rxListener ) throw (RuntimeException)
636 ::osl::MutexGuard aGuard( m_aMutex );
637 if ( m_nNotifierClient )
639 if ( 0 == AccessibleEventNotifier::removeEventListener( m_nNotifierClient, _rxListener ) )
641 AccessibleEventNotifier::TClientId nId( m_nNotifierClient );
642 m_nNotifierClient = 0;
643 AccessibleEventNotifier::revokeClient( nId );
648 //--------------------------------------------------------------------
649 void SAL_CALL OAccessibleContextWrapper::disposing() throw (RuntimeException)
651 AccessibleEventNotifier::TClientId nClientId( 0 );
653 // --- <mutex lock> -----------------------------------------
655 ::osl::MutexGuard aGuard( m_aMutex );
657 // prepare notifying our AccessibleListeners
658 if ( m_nNotifierClient )
660 nClientId = m_nNotifierClient;
661 m_nNotifierClient = 0;
664 // --- </mutex lock> -----------------------------------------
666 // let the base class do
667 OAccessibleContextWrapperHelper::dispose();
669 // notify the disposal
670 if ( nClientId )
671 AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, *this );
674 //--------------------------------------------------------------------
675 void SAL_CALL OAccessibleContextWrapper::dispose() throw( RuntimeException )
677 // simply disambiguate
678 OComponentProxyAggregation_CBase::dispose();
681 //.............................................................................
682 } // namespace accessibility
683 //.............................................................................