summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Weghorn <m.weghorn@posteo.de>2023-10-13 19:00:01 +0200
committerMichael Weghorn <m.weghorn@posteo.de>2023-11-15 12:06:27 +0100
commitf67499baab77e287a54d5c2abf0e8e6088ef5930 (patch)
tree1611133b12e1d7c1f4b97e72b98deca18c7a695f
parentd2bf45c6ed3264babc12061e635ab620a1322d2f (diff)
a11y uia: Report UIA_StrikethroughStyleAttributeId
Implement support for getting the strikethrough style (UIA attribute UIA_StrikethroughStyleAttributeId [1]) by checking for the corresponding IAccessible2 text attribute "text-line-through-type" [2] and mapping the value accordingly if set. Only report those attributes from the QAccessibleTextInterface::attributes return value, if they apply for the whole range of the QWindowsUiaTextRangeProvider. With this in place, the NVDA screen reader on Windows announces "strikethrough" as expected when asked to report the formatting information (e.g. via NVDA+f shortcut) for the QTBUG-118106 example. [1] https://learn.microsoft.com/en-us/windows/win32/winauto/uiauto-textattribute-ids [2] https://wiki.linuxfoundation.org/accessibility/iaccessible2/textattributes Task-number: QTBUG-118106 Change-Id: I2fa060bd3bf493227bba766385f34d224497784c Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
-rw-r--r--src/gui/accessible/windows/apisupport/uiatypes_p.h22
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp45
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h2
3 files changed, 69 insertions, 0 deletions
diff --git a/src/gui/accessible/windows/apisupport/uiatypes_p.h b/src/gui/accessible/windows/apisupport/uiatypes_p.h
index ebee2f34ad..1dfae43cbe 100644
--- a/src/gui/accessible/windows/apisupport/uiatypes_p.h
+++ b/src/gui/accessible/windows/apisupport/uiatypes_p.h
@@ -66,6 +66,28 @@ enum TextPatternRangeEndpoint {
TextPatternRangeEndpoint_End = 1
};
+enum TextDecorationLineStyle {
+ TextDecorationLineStyle_None = 0,
+ TextDecorationLineStyle_Single = 1,
+ TextDecorationLineStyle_WordsOnly = 2,
+ TextDecorationLineStyle_Double = 3,
+ TextDecorationLineStyle_Dot = 4,
+ TextDecorationLineStyle_Dash = 5,
+ TextDecorationLineStyle_DashDot = 6,
+ TextDecorationLineStyle_DashDotDot = 7,
+ TextDecorationLineStyle_Wavy = 8,
+ TextDecorationLineStyle_ThickSingle = 9,
+ TextDecorationLineStyle_DoubleWavy = 11,
+ TextDecorationLineStyle_ThickWavy = 12,
+ TextDecorationLineStyle_LongDash = 13,
+ TextDecorationLineStyle_ThickDash = 14,
+ TextDecorationLineStyle_ThickDashDot = 15,
+ TextDecorationLineStyle_ThickDashDotDot = 16,
+ TextDecorationLineStyle_ThickDot = 17,
+ TextDecorationLineStyle_ThickLongDash = 18,
+ TextDecorationLineStyle_Other = -1
+};
+
enum CaretPosition {
CaretPosition_Unknown = 0,
CaretPosition_EndOfLine = 1,
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp
index 4d02036196..9e46ffd5eb 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp
@@ -167,6 +167,15 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaTextRangeProvider::GetAttributeValue(TEXTAT
else
setVariantI4(CaretPosition_Unknown, pRetVal);
break;
+ case UIA_StrikethroughStyleAttributeId:
+ {
+ const QString value = valueForIA2Attribute(textInterface, QStringLiteral("text-line-through-type"));
+ if (value.isEmpty())
+ break;
+ const TextDecorationLineStyle uiaLineStyle = uiaLineStyleForIA2LineStyle(value);
+ setVariantI4(uiaLineStyle, pRetVal);
+ break;
+ }
default:
break;
}
@@ -517,6 +526,42 @@ HRESULT QWindowsUiaTextRangeProvider::unselect()
return S_OK;
}
+// helper method to retrieve the value of the given IAccessible2 text attribute,
+// or an empty string if not set
+QString QWindowsUiaTextRangeProvider::valueForIA2Attribute(QAccessibleTextInterface *textInterface,
+ const QString &key)
+{
+ Q_ASSERT(textInterface);
+
+ int startOffset;
+ int endOffset;
+ const QString attributes = textInterface->attributes(m_startOffset, &startOffset, &endOffset);
+ // don't report if attributes don't apply for the whole range
+ if (startOffset > m_startOffset || endOffset < m_endOffset)
+ return {};
+
+ for (auto attr : QStringTokenizer{attributes, u';'})
+ {
+ const QList<QStringView> items = attr.split(u':', Qt::SkipEmptyParts, Qt::CaseSensitive);
+ if (items.count() == 2 && items[0] == key)
+ return items[1].toString();
+ }
+
+ return {};
+}
+
+TextDecorationLineStyle QWindowsUiaTextRangeProvider::uiaLineStyleForIA2LineStyle(const QString &ia2LineStyle)
+{
+ if (ia2LineStyle == QStringLiteral("none"))
+ return TextDecorationLineStyle_None;
+ if (ia2LineStyle == QStringLiteral("single"))
+ return TextDecorationLineStyle_Single;
+ if (ia2LineStyle == QStringLiteral("double"))
+ return TextDecorationLineStyle_Double;
+
+ return TextDecorationLineStyle_Other;
+}
+
QT_END_NAMESPACE
#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h
index f7d28a34d2..d9a9c67ee0 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h
@@ -42,6 +42,8 @@ public:
private:
HRESULT unselect();
+ QString valueForIA2Attribute(QAccessibleTextInterface *textInterface, const QString &key);
+ TextDecorationLineStyle uiaLineStyleForIA2LineStyle(const QString &ia2LineStyle);
int m_startOffset;
int m_endOffset;
};