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