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