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