632 lines
23 KiB
C++
632 lines
23 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <comphelper/accessiblewrapper.hxx>
|
|
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
|
|
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
|
|
|
|
using namespace ::comphelper;
|
|
using namespace ::com::sun::star::accessibility;
|
|
using namespace ::com::sun::star::uno;
|
|
using namespace ::com::sun::star::lang;
|
|
|
|
|
|
namespace comphelper
|
|
{
|
|
OWrappedAccessibleChildrenManager::OWrappedAccessibleChildrenManager( const Reference< XComponentContext >& _rxContext )
|
|
:m_xContext( _rxContext )
|
|
,m_bTransientChildren( true )
|
|
{
|
|
}
|
|
|
|
|
|
OWrappedAccessibleChildrenManager::~OWrappedAccessibleChildrenManager( )
|
|
{
|
|
}
|
|
|
|
|
|
void OWrappedAccessibleChildrenManager::setTransientChildren( bool _bSet )
|
|
{
|
|
m_bTransientChildren = _bSet;
|
|
}
|
|
|
|
|
|
void OWrappedAccessibleChildrenManager::setOwningAccessible( const Reference< XAccessible >& _rxAcc )
|
|
{
|
|
OSL_ENSURE( !m_aOwningAccessible.get().is(), "OWrappedAccessibleChildrenManager::setOwningAccessible: to be called only once!" );
|
|
m_aOwningAccessible = WeakReference< XAccessible >( _rxAcc );
|
|
}
|
|
|
|
|
|
void OWrappedAccessibleChildrenManager::removeFromCache( const Reference< XAccessible >& _rxKey )
|
|
{
|
|
AccessibleMap::iterator aRemovedPos = m_aChildrenMap.find( _rxKey );
|
|
if ( m_aChildrenMap.end() != aRemovedPos )
|
|
{ // it was cached
|
|
// remove ourself as event listener
|
|
Reference< XComponent > xComp( aRemovedPos->first, UNO_QUERY );
|
|
if( xComp.is() )
|
|
xComp->removeEventListener( this );
|
|
// and remove the entry from the map
|
|
m_aChildrenMap.erase( aRemovedPos );
|
|
}
|
|
}
|
|
|
|
|
|
void OWrappedAccessibleChildrenManager::invalidateAll( )
|
|
{
|
|
// remove as event listener from the map elements
|
|
for( const auto& rChild : m_aChildrenMap )
|
|
{
|
|
Reference< XComponent > xComp( rChild.first, UNO_QUERY );
|
|
if( xComp.is() )
|
|
xComp->removeEventListener( this );
|
|
}
|
|
// clear the map
|
|
m_aChildrenMap.clear();
|
|
}
|
|
|
|
|
|
Reference< XAccessible > OWrappedAccessibleChildrenManager::getAccessibleWrapperFor(
|
|
const Reference< XAccessible >& _rxKey )
|
|
{
|
|
rtl::Reference< OAccessibleWrapper > xValue;
|
|
|
|
if( !_rxKey.is() )
|
|
{
|
|
// fprintf( stderr, "It was this path that was crashing stuff\n" );
|
|
return xValue;
|
|
}
|
|
|
|
// do we have this child in the cache?
|
|
AccessibleMap::const_iterator aPos = m_aChildrenMap.find( _rxKey );
|
|
if ( m_aChildrenMap.end() != aPos )
|
|
{
|
|
xValue = aPos->second;
|
|
}
|
|
else
|
|
{ // not found in the cache, and allowed to create
|
|
// -> new wrapper
|
|
xValue = new OAccessibleWrapper( m_xContext, _rxKey, m_aOwningAccessible );
|
|
|
|
// see if we do cache children
|
|
if ( !m_bTransientChildren )
|
|
{
|
|
if (!m_aChildrenMap.emplace( _rxKey, xValue ).second)
|
|
{
|
|
OSL_FAIL(
|
|
"OWrappedAccessibleChildrenManager::"
|
|
"getAccessibleWrapperFor: element was already"
|
|
" inserted!" );
|
|
}
|
|
|
|
// listen for disposals of inner children - this may happen when the inner context
|
|
// is the owner for the inner children (it will dispose these children, and of course
|
|
// not our wrapper for these children)
|
|
Reference< XComponent > xComp( _rxKey, UNO_QUERY );
|
|
if ( xComp.is() )
|
|
xComp->addEventListener( this );
|
|
}
|
|
}
|
|
|
|
return xValue;
|
|
}
|
|
|
|
|
|
void OWrappedAccessibleChildrenManager::dispose()
|
|
{
|
|
// dispose our children
|
|
for( const auto& rChild : m_aChildrenMap )
|
|
{
|
|
Reference< XComponent > xComp( rChild.first, UNO_QUERY );
|
|
if( xComp.is() )
|
|
xComp->removeEventListener( this );
|
|
|
|
Reference< XComponent > xContextComponent;
|
|
if( rChild.second.is() )
|
|
xContextComponent.set( rChild.second->getContextNoCreate(),
|
|
::css::uno::UNO_QUERY );
|
|
if( xContextComponent.is() )
|
|
xContextComponent->dispose();
|
|
}
|
|
|
|
// clear our children
|
|
m_aChildrenMap.clear();
|
|
}
|
|
|
|
|
|
void OWrappedAccessibleChildrenManager::implTranslateChildEventValue( const Any& _rInValue, Any& _rOutValue )
|
|
{
|
|
_rOutValue.clear();
|
|
Reference< XAccessible > xChild;
|
|
if ( _rInValue >>= xChild )
|
|
_rOutValue <<= getAccessibleWrapperFor( xChild );
|
|
}
|
|
|
|
|
|
void OWrappedAccessibleChildrenManager::translateAccessibleEvent( const AccessibleEventObject& _rEvent, AccessibleEventObject& _rTranslatedEvent )
|
|
{
|
|
// just in case we can't translate some of the values:
|
|
_rTranslatedEvent.NewValue = _rEvent.NewValue;
|
|
_rTranslatedEvent.OldValue = _rEvent.OldValue;
|
|
|
|
switch ( _rEvent.EventId )
|
|
{
|
|
case AccessibleEventId::CHILD:
|
|
case AccessibleEventId::ACTIVE_DESCENDANT_CHANGED:
|
|
case AccessibleEventId::CONTROLLED_BY_RELATION_CHANGED:
|
|
case AccessibleEventId::CONTROLLER_FOR_RELATION_CHANGED:
|
|
case AccessibleEventId::LABEL_FOR_RELATION_CHANGED:
|
|
case AccessibleEventId::LABELED_BY_RELATION_CHANGED:
|
|
case AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED:
|
|
case AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED:
|
|
// these are events where both the old and the new value contain child references
|
|
implTranslateChildEventValue( _rEvent.OldValue, _rTranslatedEvent.OldValue );
|
|
implTranslateChildEventValue( _rEvent.NewValue, _rTranslatedEvent.NewValue );
|
|
break;
|
|
|
|
case AccessibleEventId::NAME_CHANGED:
|
|
case AccessibleEventId::DESCRIPTION_CHANGED:
|
|
case AccessibleEventId::ACTION_CHANGED:
|
|
case AccessibleEventId::STATE_CHANGED:
|
|
case AccessibleEventId::BOUNDRECT_CHANGED:
|
|
case AccessibleEventId::INVALIDATE_ALL_CHILDREN:
|
|
case AccessibleEventId::SELECTION_CHANGED:
|
|
case AccessibleEventId::VISIBLE_DATA_CHANGED:
|
|
case AccessibleEventId::VALUE_CHANGED:
|
|
case AccessibleEventId::MEMBER_OF_RELATION_CHANGED:
|
|
case AccessibleEventId::CARET_CHANGED:
|
|
case AccessibleEventId::TEXT_CHANGED:
|
|
case AccessibleEventId::HYPERTEXT_CHANGED:
|
|
case AccessibleEventId::TABLE_CAPTION_CHANGED:
|
|
case AccessibleEventId::TABLE_COLUMN_DESCRIPTION_CHANGED:
|
|
case AccessibleEventId::TABLE_COLUMN_HEADER_CHANGED:
|
|
case AccessibleEventId::TABLE_MODEL_CHANGED:
|
|
case AccessibleEventId::TABLE_ROW_DESCRIPTION_CHANGED:
|
|
case AccessibleEventId::TABLE_ROW_HEADER_CHANGED:
|
|
case AccessibleEventId::TABLE_SUMMARY_CHANGED:
|
|
// these Ids are also missed: SUB_WINDOW_OF_RELATION_CHANGED & TEXT_ATTRIBUTE_CHANGED
|
|
case AccessibleEventId::TEXT_SELECTION_CHANGED:
|
|
// nothing to translate
|
|
break;
|
|
|
|
default:
|
|
OSL_FAIL( "OWrappedAccessibleChildrenManager::translateAccessibleEvent: unknown (or unexpected) event id!" );
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void OWrappedAccessibleChildrenManager::handleChildNotification( const AccessibleEventObject& _rEvent )
|
|
{
|
|
if ( AccessibleEventId::INVALIDATE_ALL_CHILDREN == _rEvent.EventId )
|
|
{ // clear our child map
|
|
invalidateAll( );
|
|
}
|
|
else if ( AccessibleEventId::CHILD == _rEvent.EventId )
|
|
{
|
|
// check if the removed or replaced element is cached
|
|
Reference< XAccessible > xRemoved;
|
|
if ( _rEvent.OldValue >>= xRemoved )
|
|
removeFromCache( xRemoved );
|
|
}
|
|
}
|
|
|
|
|
|
void SAL_CALL OWrappedAccessibleChildrenManager::disposing( const EventObject& _rSource )
|
|
{
|
|
// this should come from one of the inner XAccessible's of our children
|
|
Reference< XAccessible > xSource( _rSource.Source, UNO_QUERY );
|
|
AccessibleMap::iterator aDisposedPos = m_aChildrenMap.find( xSource );
|
|
#if OSL_DEBUG_LEVEL > 0
|
|
if ( m_aChildrenMap.end() == aDisposedPos )
|
|
{
|
|
OSL_FAIL( "OWrappedAccessibleChildrenManager::disposing: where did this come from?" );
|
|
// helper for diagnostics
|
|
Reference< XAccessible > xOwningAccessible( m_aOwningAccessible );
|
|
Reference< XAccessibleContext > xContext;
|
|
try
|
|
{
|
|
if ( xOwningAccessible.is() )
|
|
xContext = xOwningAccessible->getAccessibleContext();
|
|
if ( xContext.is() )
|
|
{
|
|
//TODO: do something
|
|
//OUString sName = xContext->getAccessibleName();
|
|
//OUString sDescription = xContext->getAccessibleDescription();
|
|
//sal_Int32 nPlaceYourBreakpointHere = 0;
|
|
}
|
|
}
|
|
catch( const Exception& /*e*/ )
|
|
{
|
|
// silent this, it's only diagnostics which failed
|
|
}
|
|
}
|
|
#endif
|
|
if ( m_aChildrenMap.end() != aDisposedPos )
|
|
{
|
|
m_aChildrenMap.erase( aDisposedPos );
|
|
}
|
|
}
|
|
|
|
OAccessibleWrapper::OAccessibleWrapper( const Reference< XComponentContext >& _rxContext,
|
|
const Reference< XAccessible >& _rxInnerAccessible, const Reference< XAccessible >& _rxParentAccessible )
|
|
:OAccessibleWrapper_Base( )
|
|
,OComponentProxyAggregation( _rxContext, Reference< XComponent >( _rxInnerAccessible, UNO_QUERY ) )
|
|
,m_xParentAccessible( _rxParentAccessible )
|
|
,m_xInnerAccessible( _rxInnerAccessible )
|
|
{
|
|
}
|
|
|
|
|
|
OAccessibleWrapper::~OAccessibleWrapper( )
|
|
{
|
|
if ( !m_rBHelper.bDisposed )
|
|
{
|
|
acquire(); // to prevent duplicate dtor calls
|
|
dispose();
|
|
}
|
|
}
|
|
|
|
|
|
IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleWrapper, OComponentProxyAggregation, OAccessibleWrapper_Base )
|
|
IMPLEMENT_FORWARD_REFCOUNT( OAccessibleWrapper, OComponentProxyAggregation )
|
|
|
|
|
|
Any OAccessibleWrapper::queryInterface( const Type& _rType )
|
|
{
|
|
// #111089# instead of the inner XAccessible the proxy XAccessible must be returned
|
|
Any aReturn = OAccessibleWrapper_Base::queryInterface( _rType );
|
|
if ( !aReturn.hasValue() )
|
|
aReturn = OComponentProxyAggregation::queryInterface( _rType );
|
|
|
|
return aReturn;
|
|
}
|
|
|
|
|
|
Reference< XAccessibleContext > OAccessibleWrapper::getContextNoCreate( ) const
|
|
{
|
|
return m_aContext;
|
|
}
|
|
|
|
|
|
rtl::Reference<OAccessibleContextWrapper> OAccessibleWrapper::createAccessibleContext( const Reference< XAccessibleContext >& _rxInnerContext )
|
|
{
|
|
return new OAccessibleContextWrapper( getComponentContext(), _rxInnerContext, this, m_xParentAccessible );
|
|
}
|
|
|
|
|
|
Reference< XAccessibleContext > SAL_CALL OAccessibleWrapper::getAccessibleContext( )
|
|
{
|
|
// see if the context is still alive (we cache it)
|
|
Reference< XAccessibleContext > xContext = m_aContext;
|
|
if ( !xContext.is() )
|
|
{
|
|
// create a new context
|
|
Reference< XAccessibleContext > xInnerContext = m_xInnerAccessible->getAccessibleContext( );
|
|
if ( xInnerContext.is() )
|
|
{
|
|
xContext = createAccessibleContext( xInnerContext );
|
|
// cache it
|
|
m_aContext = WeakReference< XAccessibleContext >( xContext );
|
|
}
|
|
}
|
|
|
|
return xContext;
|
|
}
|
|
|
|
OAccessibleContextWrapperHelper::OAccessibleContextWrapperHelper(
|
|
const Reference< XComponentContext >& _rxContext,
|
|
::cppu::OBroadcastHelper& _rBHelper,
|
|
const Reference< XAccessibleContext >& _rxInnerAccessibleContext,
|
|
const Reference< XAccessible >& _rxOwningAccessible,
|
|
const Reference< XAccessible >& _rxParentAccessible )
|
|
:OComponentProxyAggregationHelper( _rxContext, _rBHelper )
|
|
,m_xInnerContext( _rxInnerAccessibleContext )
|
|
,m_xOwningAccessible( _rxOwningAccessible )
|
|
,m_xParentAccessible( _rxParentAccessible )
|
|
// initialize the mapper for our children
|
|
,m_xChildMapper( new OWrappedAccessibleChildrenManager( getComponentContext() ) )
|
|
{
|
|
// determine if we're allowed to cache children
|
|
sal_Int64 aStates = m_xInnerContext->getAccessibleStateSet( );
|
|
m_xChildMapper->setTransientChildren( aStates & AccessibleStateType::MANAGES_DESCENDANTS );
|
|
|
|
m_xChildMapper->setOwningAccessible( m_xOwningAccessible );
|
|
}
|
|
|
|
|
|
void OAccessibleContextWrapperHelper::aggregateProxy( oslInterlockedCount& _rRefCount, ::cppu::OWeakObject& _rDelegator )
|
|
{
|
|
Reference< XComponent > xInnerComponent( m_xInnerContext, UNO_QUERY );
|
|
OSL_ENSURE( xInnerComponent.is(), "OComponentProxyAggregation::aggregateProxy: accessible is no XComponent!" );
|
|
if ( xInnerComponent.is() )
|
|
componentAggregateProxyFor( xInnerComponent, _rRefCount, _rDelegator );
|
|
|
|
// add as event listener to the inner context, because we want to multiplex the AccessibleEvents
|
|
osl_atomic_increment( &_rRefCount );
|
|
{
|
|
Reference< XAccessibleEventBroadcaster > xBroadcaster( m_xInner, UNO_QUERY );
|
|
if ( xBroadcaster.is() )
|
|
xBroadcaster->addAccessibleEventListener( this );
|
|
}
|
|
osl_atomic_decrement( &_rRefCount );
|
|
}
|
|
|
|
|
|
OAccessibleContextWrapperHelper::~OAccessibleContextWrapperHelper( )
|
|
{
|
|
OSL_ENSURE( m_rBHelper.bDisposed, "OAccessibleContextWrapperHelper::~OAccessibleContextWrapperHelper: you should ensure (in your dtor) that the object is disposed!" );
|
|
}
|
|
|
|
|
|
Any SAL_CALL OAccessibleContextWrapperHelper::queryInterface( const Type& _rType )
|
|
{
|
|
Any aReturn = OComponentProxyAggregationHelper::queryInterface( _rType );
|
|
if ( !aReturn.hasValue() )
|
|
aReturn = OAccessibleContextWrapperHelper_Base::queryInterface( _rType );
|
|
return aReturn;
|
|
}
|
|
|
|
|
|
IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleContextWrapperHelper, OComponentProxyAggregationHelper, OAccessibleContextWrapperHelper_Base )
|
|
|
|
|
|
sal_Int64 OAccessibleContextWrapperHelper::baseGetAccessibleChildCount( )
|
|
{
|
|
return m_xInnerContext->getAccessibleChildCount();
|
|
}
|
|
|
|
|
|
Reference< XAccessible > OAccessibleContextWrapperHelper::baseGetAccessibleChild( sal_Int64 i )
|
|
{
|
|
// get the child of the wrapped component
|
|
Reference< XAccessible > xInnerChild = m_xInnerContext->getAccessibleChild( i );
|
|
return m_xChildMapper->getAccessibleWrapperFor( xInnerChild );
|
|
}
|
|
|
|
|
|
Reference< XAccessibleRelationSet > OAccessibleContextWrapperHelper::baseGetAccessibleRelationSet( )
|
|
{
|
|
return m_xInnerContext->getAccessibleRelationSet();
|
|
// TODO: if this relation set would contain relations to siblings, we would normally need
|
|
// to wrap them, too...
|
|
}
|
|
|
|
|
|
void SAL_CALL OAccessibleContextWrapperHelper::notifyEvent( const AccessibleEventObject& _rEvent )
|
|
{
|
|
#if OSL_DEBUG_LEVEL > 0
|
|
if ( AccessibleEventId::STATE_CHANGED == _rEvent.EventId )
|
|
{
|
|
bool bChildTransienceChanged = false;
|
|
sal_Int64 nChangeState = 0;
|
|
if ( _rEvent.OldValue >>= nChangeState )
|
|
bChildTransienceChanged = bChildTransienceChanged || AccessibleStateType::MANAGES_DESCENDANTS == nChangeState;
|
|
if ( _rEvent.NewValue >>= nChangeState )
|
|
bChildTransienceChanged = bChildTransienceChanged || AccessibleStateType::MANAGES_DESCENDANTS == nChangeState;
|
|
OSL_ENSURE( !bChildTransienceChanged, "OAccessibleContextWrapperHelper::notifyEvent: MANAGES_DESCENDANTS is not expected to change during runtime!" );
|
|
// if this asserts, then we would need to update our m_bTransientChildren flag here,
|
|
// as well as (potentially) our child cache
|
|
}
|
|
#endif
|
|
AccessibleEventObject aTranslatedEvent( _rEvent );
|
|
|
|
{
|
|
::osl::MutexGuard aGuard( m_rBHelper.rMutex );
|
|
|
|
// translate the event
|
|
queryInterface( cppu::UnoType<XInterface>::get() ) >>= aTranslatedEvent.Source;
|
|
m_xChildMapper->translateAccessibleEvent( _rEvent, aTranslatedEvent );
|
|
|
|
// see if any of these notifications affect our child manager
|
|
m_xChildMapper->handleChildNotification( _rEvent );
|
|
|
|
if ( aTranslatedEvent.NewValue == m_xInner )
|
|
aTranslatedEvent.NewValue <<= aTranslatedEvent.Source;
|
|
if ( aTranslatedEvent.OldValue == m_xInner )
|
|
aTranslatedEvent.OldValue <<= aTranslatedEvent.Source;
|
|
}
|
|
|
|
notifyTranslatedEvent( aTranslatedEvent );
|
|
}
|
|
|
|
|
|
void SAL_CALL OAccessibleContextWrapperHelper::dispose()
|
|
{
|
|
::osl::MutexGuard aGuard( m_rBHelper.rMutex );
|
|
|
|
// stop multiplexing events
|
|
Reference< XAccessibleEventBroadcaster > xBroadcaster( m_xInner, UNO_QUERY );
|
|
OSL_ENSURE( xBroadcaster.is(), "OAccessibleContextWrapperHelper::disposing(): inner context is no broadcaster!" );
|
|
if ( xBroadcaster.is() )
|
|
xBroadcaster->removeAccessibleEventListener( this );
|
|
|
|
// dispose the child cache/map
|
|
m_xChildMapper->dispose();
|
|
|
|
// let the base class dispose the inner component
|
|
OComponentProxyAggregationHelper::dispose();
|
|
}
|
|
|
|
|
|
void SAL_CALL OAccessibleContextWrapperHelper::disposing( const EventObject& _rEvent )
|
|
{
|
|
// simply disambiguate this
|
|
OComponentProxyAggregationHelper::disposing( _rEvent );
|
|
}
|
|
|
|
IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleContextWrapper, OAccessibleContextWrapper_CBase, OAccessibleContextWrapperHelper )
|
|
|
|
|
|
IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleContextWrapper, OAccessibleContextWrapper_CBase, OAccessibleContextWrapperHelper )
|
|
|
|
|
|
OAccessibleContextWrapper::OAccessibleContextWrapper( const Reference< XComponentContext >& _rxContext,
|
|
const Reference< XAccessibleContext >& _rxInnerAccessibleContext, const Reference< XAccessible >& _rxOwningAccessible,
|
|
const Reference< XAccessible >& _rxParentAccessible )
|
|
:OAccessibleContextWrapper_CBase( m_aMutex )
|
|
,OAccessibleContextWrapperHelper( _rxContext, rBHelper, _rxInnerAccessibleContext, _rxOwningAccessible, _rxParentAccessible )
|
|
,m_nNotifierClient( 0 )
|
|
{
|
|
aggregateProxy( m_refCount, *this );
|
|
}
|
|
|
|
|
|
OAccessibleContextWrapper::~OAccessibleContextWrapper()
|
|
{
|
|
}
|
|
|
|
|
|
sal_Int64 SAL_CALL OAccessibleContextWrapper::getAccessibleChildCount( )
|
|
{
|
|
return baseGetAccessibleChildCount();
|
|
}
|
|
|
|
|
|
Reference< XAccessible > SAL_CALL OAccessibleContextWrapper::getAccessibleChild( sal_Int64 i )
|
|
{
|
|
return baseGetAccessibleChild( i );
|
|
}
|
|
|
|
|
|
Reference< XAccessible > SAL_CALL OAccessibleContextWrapper::getAccessibleParent( )
|
|
{
|
|
return m_xParentAccessible;
|
|
}
|
|
|
|
|
|
sal_Int64 SAL_CALL OAccessibleContextWrapper::getAccessibleIndexInParent( )
|
|
{
|
|
return m_xInnerContext->getAccessibleIndexInParent();
|
|
}
|
|
|
|
|
|
sal_Int16 SAL_CALL OAccessibleContextWrapper::getAccessibleRole( )
|
|
{
|
|
return m_xInnerContext->getAccessibleRole();
|
|
}
|
|
|
|
|
|
OUString SAL_CALL OAccessibleContextWrapper::getAccessibleDescription( )
|
|
{
|
|
return m_xInnerContext->getAccessibleDescription();
|
|
}
|
|
|
|
|
|
OUString SAL_CALL OAccessibleContextWrapper::getAccessibleName( )
|
|
{
|
|
return m_xInnerContext->getAccessibleName();
|
|
}
|
|
|
|
|
|
Reference< XAccessibleRelationSet > SAL_CALL OAccessibleContextWrapper::getAccessibleRelationSet( )
|
|
{
|
|
return baseGetAccessibleRelationSet();
|
|
}
|
|
|
|
|
|
sal_Int64 SAL_CALL OAccessibleContextWrapper::getAccessibleStateSet( )
|
|
{
|
|
return m_xInnerContext->getAccessibleStateSet();
|
|
}
|
|
|
|
|
|
Locale SAL_CALL OAccessibleContextWrapper::getLocale( )
|
|
{
|
|
return m_xInnerContext->getLocale();
|
|
}
|
|
|
|
|
|
void OAccessibleContextWrapper::notifyTranslatedEvent( const AccessibleEventObject& _rEvent )
|
|
{
|
|
if ( m_nNotifierClient )
|
|
AccessibleEventNotifier::addEvent( m_nNotifierClient, _rEvent );
|
|
}
|
|
|
|
|
|
void SAL_CALL OAccessibleContextWrapper::addAccessibleEventListener( const Reference< XAccessibleEventListener >& _rxListener )
|
|
{
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
|
if ( !m_nNotifierClient )
|
|
m_nNotifierClient = AccessibleEventNotifier::registerClient( );
|
|
AccessibleEventNotifier::addEventListener( m_nNotifierClient, _rxListener );
|
|
}
|
|
|
|
|
|
void SAL_CALL OAccessibleContextWrapper::removeAccessibleEventListener( const Reference< XAccessibleEventListener >& _rxListener )
|
|
{
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
|
if ( m_nNotifierClient )
|
|
{
|
|
if ( 0 == AccessibleEventNotifier::removeEventListener( m_nNotifierClient, _rxListener ) )
|
|
{
|
|
AccessibleEventNotifier::TClientId nId( m_nNotifierClient );
|
|
m_nNotifierClient = 0;
|
|
AccessibleEventNotifier::revokeClient( nId );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void OAccessibleContextWrapper::implDisposing(const css::lang::EventObject* pEvent)
|
|
{
|
|
AccessibleEventNotifier::TClientId nClientId( 0 );
|
|
|
|
// --- <mutex lock> -----------------------------------------
|
|
{
|
|
::osl::MutexGuard aGuard( m_aMutex );
|
|
|
|
// prepare notifying our AccessibleListeners
|
|
if ( m_nNotifierClient )
|
|
{
|
|
nClientId = m_nNotifierClient;
|
|
m_nNotifierClient = 0;
|
|
}
|
|
}
|
|
// --- </mutex lock> -----------------------------------------
|
|
|
|
// let the base class do
|
|
if (pEvent)
|
|
OAccessibleContextWrapperHelper::disposing(*pEvent);
|
|
else
|
|
OAccessibleContextWrapperHelper::dispose();
|
|
|
|
// notify the disposal
|
|
if ( nClientId )
|
|
AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, *this );
|
|
}
|
|
|
|
void SAL_CALL OAccessibleContextWrapper::disposing()
|
|
{
|
|
implDisposing(nullptr);
|
|
}
|
|
|
|
void SAL_CALL OAccessibleContextWrapper::disposing(const css::lang::EventObject& rEvent)
|
|
{
|
|
assert(rEvent.Source == Reference<XInterface>(m_xInnerContext, UNO_QUERY)
|
|
&& "OAccessibleContextWrapper::disposing called with event source that's not the "
|
|
"wrapped a11y context");
|
|
|
|
implDisposing(&rEvent);
|
|
}
|
|
} // namespace accessibility
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|