editeng a11y: Use OAccessibleComponentHelper for paragraph

Let editeng's AccessibleEditableTextPara derive from
OAccessibleComponentHelper to make use of the
logic already implemented there instead of having to
implement all the XAccessibleComponent
and XAccessibleEventBroadcaster methods manually.

The existing AccessibleEditableTextPara::getBounds
implementations provide the necessary logic to implement
OAccessibleComponentHelper::implGetBounds,
so rename those accordingly (and drop the extra mutex
guard, as the base class takes care of that).

Drop all of the other overrides that are no longer
needed as the implementation is now provided by
the base class.

No change in behavior intended or observed in a quick
test with text in Impress slides and Accerciser and Orca
when using the gtk3 and qt6 VCL plugins on Linux.

Change-Id: I5cb47eb9c6738f4bd7807cbeef260151437c0862
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183681
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
This commit is contained in:
Michael Weghorn
2025-04-03 22:31:54 +02:00
parent 5348c79e01
commit 72f62009c9
4 changed files with 19 additions and 205 deletions
@@ -110,13 +110,6 @@ AccessibleEditableTextPara::AccessibleEditableTextPara(
mpEditSource( nullptr ),
maEEOffset( 0, 0 ),
mxParent(std::move( xParent )),
// well, that's strictly (UNO) exception safe, though not
// really robust. We rely on the fact that this member is
// constructed last, and that the constructor body catches
// exceptions, thus no chance for exceptions once the Id is
// fetched. Nevertheless, normally should employ RAII here...
mnNotifierClientId(::comphelper::AccessibleEventNotifier::registerClient()),
// #i27138#
mpParaManager( _pParaManager )
{
@@ -132,21 +125,6 @@ AccessibleEditableTextPara::AccessibleEditableTextPara(
mnStateSet |= AccessibleStateType::SENSITIVE;
}
AccessibleEditableTextPara::~AccessibleEditableTextPara()
{
// sign off from event notifier
if( getNotifierClientId() != -1 )
{
try
{
::comphelper::AccessibleEventNotifier::revokeClient( getNotifierClientId() );
}
catch (const uno::Exception&)
{
}
}
}
OUString AccessibleEditableTextPara::implGetText()
{
return GetTextRange( 0, GetTextLen() );
@@ -275,29 +253,12 @@ void AccessibleEditableTextPara::SetParagraphIndex( sal_Int32 nIndex )
}
void AccessibleEditableTextPara::Dispose()
void SAL_CALL AccessibleEditableTextPara::dispose()
{
int nClientId( getNotifierClientId() );
// #108212# drop all references before notifying dispose
mxParent = nullptr;
mnNotifierClientId = -1;
mpEditSource = nullptr;
// notify listeners
if( nClientId == -1 )
return;
try
{
uno::Reference < XAccessibleContext > xThis = getAccessibleContext();
// #106234# Delegate to EventNotifier
::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, xThis );
}
catch (const uno::Exception&)
{
}
comphelper::OAccessibleComponentHelper::dispose();
}
void AccessibleEditableTextPara::SetEditSource( SvxEditSourceAdapter* pEditSource )
@@ -538,14 +499,7 @@ void AccessibleEditableTextPara::SetEEOffset( const Point& rOffset )
void AccessibleEditableTextPara::FireEvent(const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue)
{
uno::Reference <XAccessibleContext> xThis(this);
AccessibleEventObject aEvent(xThis, nEventId, rNewValue, rOldValue, -1);
// #106234# Delegate to EventNotifier
if( getNotifierClientId() != -1 )
::comphelper::AccessibleEventNotifier::addEvent( getNotifierClientId(),
aEvent );
NotifyAccessibleEvent(nEventId, rOldValue, rNewValue);
}
void AccessibleEditableTextPara::SetState( const sal_Int64 nStateId )
@@ -593,34 +547,6 @@ bool AccessibleEditableTextPara::GetAttributeRun( sal_Int32& nStartIndex, sal_In
nIndex );
}
uno::Any SAL_CALL AccessibleEditableTextPara::queryInterface (const uno::Type & rType)
{
uno::Any aRet;
// must provide XAccessibleText by hand, since it comes publicly inherited by XAccessibleEditableText
if ( rType == cppu::UnoType<XAccessibleText>::get())
{
uno::Reference< XAccessibleText > aAccText = static_cast< XAccessibleEditableText * >(this);
aRet <<= aAccText;
}
else if ( rType == cppu::UnoType<XAccessibleEditableText>::get())
{
uno::Reference< XAccessibleEditableText > aAccEditText = this;
aRet <<= aAccEditText;
}
else if ( rType == cppu::UnoType<XAccessibleHypertext>::get())
{
uno::Reference< XAccessibleHypertext > aAccHyperText = this;
aRet <<= aAccHyperText;
}
else
{
aRet = AccessibleTextParaInterfaceBase::queryInterface(rType);
}
return aRet;
}
// XAccessible
uno::Reference< XAccessibleContext > SAL_CALL AccessibleEditableTextPara::getAccessibleContext()
{
@@ -896,44 +822,7 @@ lang::Locale SAL_CALL AccessibleEditableTextPara::getLocale()
return implGetLocale();
}
void SAL_CALL AccessibleEditableTextPara::addAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
{
if( getNotifierClientId() != -1 )
::comphelper::AccessibleEventNotifier::addEventListener( getNotifierClientId(), xListener );
}
void SAL_CALL AccessibleEditableTextPara::removeAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
{
if( getNotifierClientId() == -1 )
return;
const sal_Int32 nListenerCount = ::comphelper::AccessibleEventNotifier::removeEventListener( getNotifierClientId(), xListener );
if ( !nListenerCount )
{
// no listeners anymore
// -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
// and at least to us not firing any events anymore, in case somebody calls
// NotifyAccessibleEvent, again
::comphelper::AccessibleEventNotifier::TClientId nId( getNotifierClientId() );
mnNotifierClientId = -1;
::comphelper::AccessibleEventNotifier::revokeClient( nId );
}
}
// XAccessibleComponent
sal_Bool SAL_CALL AccessibleEditableTextPara::containsPoint( const awt::Point& aTmpPoint )
{
SolarMutexGuard aGuard;
DBG_ASSERT(GetParagraphIndex() >= 0,
"AccessibleEditableTextPara::contains: index value overflow");
awt::Rectangle aTmpRect = getBounds();
tools::Rectangle aRect( Point(aTmpRect.X, aTmpRect.Y), Size(aTmpRect.Width, aTmpRect.Height) );
Point aPoint( aTmpPoint.X, aTmpPoint.Y );
return aRect.Contains( aPoint );
}
uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleAtPoint( const awt::Point& _aPoint )
{
@@ -968,12 +857,10 @@ uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessible
return uno::Reference< XAccessible >();
}
awt::Rectangle SAL_CALL AccessibleEditableTextPara::getBounds()
awt::Rectangle AccessibleEditableTextPara::implGetBounds()
{
SolarMutexGuard aGuard;
DBG_ASSERT(GetParagraphIndex() >= 0,
"AccessibleEditableTextPara::getBounds: index value overflow");
"AccessibleEditableTextPara::implGetBounds: index value overflow");
SvxTextForwarder& rCacheTF = GetTextForwarder();
tools::Rectangle aRect = rCacheTF.GetParaBounds( GetParagraphIndex() );
@@ -992,53 +879,6 @@ awt::Rectangle SAL_CALL AccessibleEditableTextPara::getBounds()
aScreenRect.GetSize().Height() );
}
awt::Point SAL_CALL AccessibleEditableTextPara::getLocation( )
{
SolarMutexGuard aGuard;
awt::Rectangle aRect = getBounds();
return awt::Point( aRect.X, aRect.Y );
}
awt::Point SAL_CALL AccessibleEditableTextPara::getLocationOnScreen( )
{
SolarMutexGuard aGuard;
// relate us to parent
uno::Reference< XAccessible > xParent = getAccessibleParent();
if( xParent.is() )
{
uno::Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext();
if ( xParentContext.is() )
{
uno::Reference< XAccessibleComponent > xParentContextComponent( xParentContext, uno::UNO_QUERY );
if( xParentContextComponent.is() )
{
awt::Point aRefPoint = xParentContextComponent->getLocationOnScreen();
awt::Point aPoint = getLocation();
aPoint.X += aRefPoint.X;
aPoint.Y += aRefPoint.Y;
return aPoint;
}
}
}
throw uno::RuntimeException(u"Cannot access parent"_ustr,
uno::Reference< uno::XInterface >
( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
}
awt::Size SAL_CALL AccessibleEditableTextPara::getSize( )
{
SolarMutexGuard aGuard;
awt::Rectangle aRect = getBounds();
return awt::Size( aRect.Width, aRect.Height );
}
void SAL_CALL AccessibleEditableTextPara::grabFocus( )
{
// set cursor to this paragraph
@@ -285,7 +285,7 @@ public:
AccessibleParaManager_DisposeChildren() {}
void operator()( ::accessibility::AccessibleEditableTextPara& rPara )
{
rPara.Dispose();
rPara.dispose();
}
};
@@ -377,7 +377,7 @@ void AccessibleParaManager::Release( sal_Int32 nStartPara, sal_Int32 nEndPara )
if (IsReferencable(aChild))
{
aChild->SetEditSource(nullptr);
aChild->Dispose();
aChild->dispose();
}
// clear reference
@@ -329,7 +329,7 @@ void AccessibleStaticTextBase::Dispose()
{
// we're the owner of the paragraph, so destroy it, too
if (mxTextParagraph.is())
mxTextParagraph->Dispose();
mxTextParagraph->dispose();
// drop reference
mxTextParagraph.clear();
+11 -37
View File
@@ -23,21 +23,18 @@
#include <config_options.h>
#include <rtl/ustring.hxx>
#include <tools/gen.hxx>
#include <comphelper/compbase.hxx>
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/accessibility/AccessibleScrollType.hpp>
#include <com/sun/star/accessibility/XAccessible.hpp>
#include <com/sun/star/accessibility/XAccessibleContext.hpp>
#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
#include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
#include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp>
#include <com/sun/star/accessibility/XAccessibleHypertext.hpp>
#include <com/sun/star/accessibility/XAccessibleMultiLineText.hpp>
#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
#include <comphelper/accessibletexthelper.hxx>
#include <cppuhelper/implbase.hxx>
#include <editeng/editdata.hxx>
#include <editeng/editengdllapi.h>
#include <editeng/unoedprx.hxx>
@@ -54,19 +51,15 @@ namespace accessibility
class AccessibleParaManager;
typedef ::comphelper::WeakComponentImplHelper< css::accessibility::XAccessible,
css::accessibility::XAccessibleContext,
css::accessibility::XAccessibleComponent,
css::accessibility::XAccessibleEditableText,
css::accessibility::XAccessibleEventBroadcaster,
css::accessibility::XAccessibleTextAttributes,
css::accessibility::XAccessibleHypertext,
css::accessibility::XAccessibleMultiLineText,
css::lang::XServiceInfo > AccessibleTextParaInterfaceBase;
/** This class implements the actual text paragraphs for the EditEngine/Outliner UAA
*/
class UNLESS_MERGELIBS(EDITENG_DLLPUBLIC) AccessibleEditableTextPara final : public AccessibleTextParaInterfaceBase, private ::comphelper::OCommonAccessibleText
class UNLESS_MERGELIBS(EDITENG_DLLPUBLIC) AccessibleEditableTextPara final
: public cppu::ImplInheritanceHelper<
comphelper::OAccessibleComponentHelper, css::accessibility::XAccessible,
css::accessibility::XAccessibleEditableText,
css::accessibility::XAccessibleTextAttributes, css::accessibility::XAccessibleHypertext,
css::accessibility::XAccessibleMultiLineText, css::lang::XServiceInfo>,
private ::comphelper::OCommonAccessibleText
{
// override OCommonAccessibleText methods
@@ -85,11 +78,6 @@ public:
AccessibleEditableTextPara ( css::uno::Reference< css::accessibility::XAccessible > xParent,
const AccessibleParaManager* _pParaManager = nullptr );
virtual ~AccessibleEditableTextPara () override;
// XInterface
virtual css::uno::Any SAL_CALL queryInterface (const css::uno::Type & rType) override;
// XAccessible
virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override;
@@ -107,17 +95,11 @@ public:
virtual sal_Int64 SAL_CALL getAccessibleStateSet() override;
virtual css::lang::Locale SAL_CALL getLocale() override;
// XAccessibleEventBroadcaster
virtual void SAL_CALL addAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override;
virtual void SAL_CALL removeAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override;
// OAccessibleComponentHelper
virtual css::awt::Rectangle implGetBounds() override;
// XAccessibleComponent
virtual sal_Bool SAL_CALL containsPoint( const css::awt::Point& aPoint ) override;
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override;
virtual css::awt::Rectangle SAL_CALL getBounds( ) override;
virtual css::awt::Point SAL_CALL getLocation( ) override;
virtual css::awt::Point SAL_CALL getLocationOnScreen( ) override;
virtual css::awt::Size SAL_CALL getSize( ) override;
virtual void SAL_CALL grabFocus( ) override;
virtual sal_Int32 SAL_CALL getForeground( ) override;
virtual sal_Int32 SAL_CALL getBackground( ) override;
@@ -228,11 +210,7 @@ public:
*/
void SetEditSource( SvxEditSourceAdapter* pEditSource );
/** Dispose this object
Notifies and deregisters the listeners, drops all references.
*/
void Dispose();
void SAL_CALL dispose() override;
/// Calls all Listener objects to tell them the change. Don't hold locks when calling this!
void FireEvent(const sal_Int16 nEventId, const css::uno::Any& rNewValue = css::uno::Any(), const css::uno::Any& rOldValue = css::uno::Any());
@@ -309,8 +287,6 @@ private:
*/
bool GetAttributeRun( sal_Int32& nStartIndex, sal_Int32& nEndIndex, sal_Int32 nIndex );
int getNotifierClientId() const { return mnNotifierClientId; }
/// Do we have children? This is the case for image bullets
bool HaveChildren();
@@ -374,8 +350,6 @@ private:
/// The shape we're the accessible for (unguarded)
css::uno::Reference< css::accessibility::XAccessible > mxParent;
/// Our listeners (guarded by maMutex)
int mnNotifierClientId;
private:
// Text paragraphs should provide FLOWS_TO and FLOWS_FROM relations (#i27138#)
// the paragraph manager, which created this instance - is NULL, if