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>
This commit is contained in:
parent
d2bf45c6ed
commit
f67499baab
@ -66,6 +66,28 @@ enum TextPatternRangeEndpoint {
|
|||||||
TextPatternRangeEndpoint_End = 1
|
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 {
|
enum CaretPosition {
|
||||||
CaretPosition_Unknown = 0,
|
CaretPosition_Unknown = 0,
|
||||||
CaretPosition_EndOfLine = 1,
|
CaretPosition_EndOfLine = 1,
|
||||||
|
@ -167,6 +167,15 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaTextRangeProvider::GetAttributeValue(TEXTAT
|
|||||||
else
|
else
|
||||||
setVariantI4(CaretPosition_Unknown, pRetVal);
|
setVariantI4(CaretPosition_Unknown, pRetVal);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -517,6 +526,42 @@ HRESULT QWindowsUiaTextRangeProvider::unselect()
|
|||||||
return S_OK;
|
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
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // QT_CONFIG(accessibility)
|
#endif // QT_CONFIG(accessibility)
|
||||||
|
@ -42,6 +42,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
HRESULT unselect();
|
HRESULT unselect();
|
||||||
|
QString valueForIA2Attribute(QAccessibleTextInterface *textInterface, const QString &key);
|
||||||
|
TextDecorationLineStyle uiaLineStyleForIA2LineStyle(const QString &ia2LineStyle);
|
||||||
int m_startOffset;
|
int m_startOffset;
|
||||||
int m_endOffset;
|
int m_endOffset;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user