diff options
author | Michael Weghorn <m.weghorn@posteo.de> | 2023-10-17 14:36:58 +0200 |
---|---|---|
committer | Michael Weghorn <m.weghorn@posteo.de> | 2023-10-18 12:48:57 +0200 |
commit | ec2e02cfa41510c3d30b118cbf7595c84a046d03 (patch) | |
tree | 2a9d5b2dfd568232ca56784636bcb15fc6785bcc | |
parent | 15a6e23c4fc160c50a316da3d18980a02fc10ce8 (diff) |
tdf#157696 a11y: Report spelling error via IA2 "invalid:spelling" attr
Let `AccessibleTextAttributeHelper::GetIAccessible2TextAttributes`
also report spelling errors as a text attribute, since the
"invalid:" text attribute with a value of "spelling" is specified
for that in the IAccessible2 tex attributes specification [1].
In order to adapt the start/end index for the attribute run,
iterate over all of the text markups that can be retrieved from
the `XAccessibleTextMarkup` interface instead of just deterining
whether the offset itself lies within a range of misspelled text
via `XAccessibleTextMarkup::getTextMarkupAtIndex`.
(This is strongly inspired by how the gtk3 a11y implementation
does it, s. `handle_text_markup_as_run_attribute` in
vcl/unx/gtk3/a11y/atktext.cxx.)
When using the qt6 VCL plugin on Linux, the attribute shows up as
expected in Accerciser and the Orca screen reader announces
"misspelled" when moving the cursor in front of a misspelled
word using the Arrow_Right key.
Announcement by NVDA works once winaccessibility and NVDA
have been switched over to use IAccessible2 text attributes
instead of custom LibreOffice ones.
[1] https://wiki.linuxfoundation.org/accessibility/iaccessible2/textattributes
Change-Id: I54e5bcbb4bef4c73068243f91a3ee69c10326460
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158089
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
-rw-r--r-- | vcl/source/accessibility/AccessibleTextAttributeHelper.cxx | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/vcl/source/accessibility/AccessibleTextAttributeHelper.cxx b/vcl/source/accessibility/AccessibleTextAttributeHelper.cxx index 5862b96a86c6..f69b7483d9e5 100644 --- a/vcl/source/accessibility/AccessibleTextAttributeHelper.cxx +++ b/vcl/source/accessibility/AccessibleTextAttributeHelper.cxx @@ -20,10 +20,12 @@ #include <vcl/accessibility/AccessibleTextAttributeHelper.hxx> #include <com/sun/star/accessibility/AccessibleTextType.hpp> +#include <com/sun/star/accessibility/XAccessibleTextMarkup.hpp> #include <com/sun/star/awt/FontSlant.hpp> #include <com/sun/star/awt/FontStrikeout.hpp> #include <com/sun/star/awt/FontUnderline.hpp> #include <com/sun/star/awt/FontWeight.hpp> +#include <com/sun/star/text/TextMarkupType.hpp> #include <o3tl/any.hxx> #include <tools/color.hxx> @@ -303,13 +305,53 @@ OUString AccessibleTextAttributeHelper::GetIAccessible2TextAttributes( const css::uno::Sequence<css::beans::PropertyValue> attribs = xText->getCharacterAttributes(nOffset, css::uno::Sequence<OUString>()); - const OUString sAttributes = ConvertUnoToIAccessible2TextAttributes(attribs); + OUString sAttributes = ConvertUnoToIAccessible2TextAttributes(attribs); css::accessibility::TextSegment aAttributeRun = xText->getTextAtIndex(nOffset, css::accessibility::AccessibleTextType::ATTRIBUTE_RUN); rStartOffset = aAttributeRun.SegmentStart; rEndOffset = aAttributeRun.SegmentEnd; + // report spelling error as "invalid:spelling;" IA2 text attribute and + // adapt start/end index as necessary + css::uno::Reference<css::accessibility::XAccessibleTextMarkup> xTextMarkup(xText, + css::uno::UNO_QUERY); + if (xTextMarkup.is()) + { + bool bInvalidSpelling = false; + const sal_Int32 nMarkupCount( + xTextMarkup->getTextMarkupCount(css::text::TextMarkupType::SPELLCHECK)); + for (sal_Int32 nMarkupIndex = 0; nMarkupIndex < nMarkupCount; ++nMarkupIndex) + { + const css::accessibility::TextSegment aTextSegment + = xTextMarkup->getTextMarkup(nMarkupIndex, css::text::TextMarkupType::SPELLCHECK); + const sal_Int32 nStartOffsetTextMarkup = aTextSegment.SegmentStart; + const sal_Int32 nEndOffsetTextMarkup = aTextSegment.SegmentEnd; + if (nStartOffsetTextMarkup <= nOffset) + { + if (nOffset < nEndOffsetTextMarkup) + { + // offset is inside invalid spelling + rStartOffset = ::std::max(rStartOffset, nStartOffsetTextMarkup); + rEndOffset = ::std::min(rEndOffset, nEndOffsetTextMarkup); + bInvalidSpelling = true; + break; + } + else + { + rStartOffset = ::std::max(rStartOffset, nEndOffsetTextMarkup); + } + } + else + { + rEndOffset = ::std::min(rEndOffset, nStartOffsetTextMarkup); + } + } + + if (bInvalidSpelling) + sAttributes += u"invalid:spelling;"_ustr; + } + return sAttributes; } |