7#include <QtGui/private/qaccessiblehelper_p.h>
8#include <QtGui/qtextdocument.h>
10#include "QtQuick/private/qquickitem_p.h"
11#include "QtQuick/private/qquicktext_p.h"
12#include <private/qquicktext_p_p.h>
14#include "QtQuick/private/qquicktextinput_p.h"
15#include "QtQuick/private/qquickaccessibleattached_p.h"
16#include "QtQuick/qquicktextdocument.h"
17#include "QtQuick/qquickrendercontrol.h"
20#if QT_CONFIG(accessibility)
22class QAccessibleHyperlink :
public QAccessibleInterface,
public QAccessibleHyperlinkInterface {
24 QAccessibleHyperlink(QQuickItem *parentTextItem,
int linkIndex);
27 bool isValid()
const override;
28 QObject *object()
const override;
29 QWindow *window()
const override;
32 QAccessibleInterface *parent()
const override;
33 QAccessibleInterface *child(
int index)
const override;
34 int childCount()
const override;
35 int indexOfChild(
const QAccessibleInterface *iface)
const override;
36 QAccessibleInterface *childAt(
int x,
int y)
const override;
39 QString text(QAccessible::Text)
const override;
40 void setText(QAccessible::Text,
const QString &text) override;
41 QRect rect()
const override;
42 QAccessible::Role role()
const override;
43 QAccessible::State state()
const override;
45 void *interface_cast(QAccessible::InterfaceType t) override;
48 QString anchor()
const override
50 const QList<QQuickTextPrivate::LinkDesc> links = QQuickTextPrivate::get(textItem())->getLinks();
51 if (linkIndex < links.size())
52 return links.at(linkIndex).m_anchor;
56 QString anchorTarget()
const override
58 const QList<QQuickTextPrivate::LinkDesc> links = QQuickTextPrivate::get(textItem())->getLinks();
59 if (linkIndex < links.size())
60 return links.at(linkIndex).m_anchorTarget;
64 int startIndex()
const override
66 const QList<QQuickTextPrivate::LinkDesc> links = QQuickTextPrivate::get(textItem())->getLinks();
67 if (linkIndex < links.size())
68 return links.at(linkIndex).m_startIndex;
72 int endIndex()
const override
74 const QList<QQuickTextPrivate::LinkDesc> links = QQuickTextPrivate::get(textItem())->getLinks();
75 if (linkIndex < links.size())
76 return links.at(linkIndex).m_endIndex;
81 QQuickText *textItem()
const {
return qobject_cast<QQuickText*>(parentTextItem); }
82 QQuickItem *parentTextItem;
85 friend class QAccessibleQuickItem;
89QAccessibleHyperlink::QAccessibleHyperlink(QQuickItem *parentTextItem,
int linkIndex)
90 : parentTextItem(parentTextItem),
96bool QAccessibleHyperlink::isValid()
const
102QObject *QAccessibleHyperlink::object()
const
108QWindow *QAccessibleHyperlink::window()
const
110 return textItem()->window();
115QRect QAccessibleHyperlink::rect()
const
117 const QList<QQuickTextPrivate::LinkDesc> links = QQuickTextPrivate::get(textItem())->getLinks();
118 if (linkIndex < links.size()) {
119 const QPoint tl = itemScreenRect(textItem()).topLeft();
120 return links.at(linkIndex).rect.translated(tl);
126QAccessibleInterface *QAccessibleHyperlink::childAt(
int,
int)
const
132QAccessibleInterface *QAccessibleHyperlink::parent()
const
134 return QAccessible::queryAccessibleInterface(textItem());
138QAccessibleInterface *QAccessibleHyperlink::child(
int)
const
144int QAccessibleHyperlink::childCount()
const
150int QAccessibleHyperlink::indexOfChild(
const QAccessibleInterface *)
const
156QAccessible::State QAccessibleHyperlink::state()
const
158 QAccessible::State s;
161 s.selectableText =
true;
167QAccessible::Role QAccessibleHyperlink::role()
const
169 return QAccessible::Link;
173QString QAccessibleHyperlink::text(QAccessible::Text t)
const
183 if (t == QAccessible::Name)
185 if (t == QAccessible::Value)
186 return anchorTarget();
191void QAccessibleHyperlink::setText(QAccessible::Text,
const QString &)
197void *QAccessibleHyperlink::interface_cast(QAccessible::InterfaceType t)
199 if (t == QAccessible::HyperlinkInterface)
200 return static_cast<QAccessibleHyperlinkInterface*>(
this);
206
207
208
209
210QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item)
211 : QAccessibleObject(item), m_doc(textDocument())
215bool QAccessibleQuickItem::isValid()
const
217 return item() && !QQuickItemPrivate::get(item())->inDestructor;
221QWindow *QAccessibleQuickItem::window()
const
223 QQuickWindow *window = item()->window();
228 if (window && !window->handle()) {
229 if (QQuickRenderControl *renderControl = QQuickWindowPrivate::get(window)->renderControl) {
230 if (QWindow *renderWindow = renderControl->renderWindow(
nullptr))
238int QAccessibleQuickItem::childCount()
const
242 if (QQuickText *textItem = qobject_cast<QQuickText*>(item())) {
243 cc = QQuickTextPrivate::get(textItem)->getLinks().size();
245 cc += childItems().size();
249QRect QAccessibleQuickItem::rect()
const
251 const QRect r = itemScreenRect(item());
255QRect QAccessibleQuickItem::viewRect()
const
258 if (!item()->window()) {
262 QQuickWindow *window = item()->window();
263 QPoint screenPos = window->mapToGlobal(QPoint(0,0));
264 return QRect(screenPos, window->size());
268bool QAccessibleQuickItem::clipsChildren()
const
270 return static_cast<QQuickItem *>(item())->clip();
273QAccessibleInterface *QAccessibleQuickItem::childAt(
int x,
int y)
const
275 if (item()->clip()) {
276 if (!rect().contains(x, y))
281 if (QQuickText *textItem = qobject_cast<QQuickText*>(item())) {
282 const auto hyperLinkChildCount = QQuickTextPrivate::get(textItem)->getLinks().size();
283 for (
auto i = 0; i < hyperLinkChildCount; i++) {
284 QAccessibleInterface *iface = child(i);
285 if (iface->rect().contains(x,y)) {
292 const QList<QQuickItem*> kids = accessibleUnignoredChildren(item(),
true);
293 for (
int i = kids.size() - 1; i >= 0; --i) {
294 QAccessibleInterface *childIface = QAccessible::queryAccessibleInterface(kids.at(i));
295 if (QAccessibleInterface *childChild = childIface->childAt(x, y))
297 if (childIface && !childIface->state().invisible) {
298 if (childIface->rect().contains(x, y))
306QAccessibleInterface *QAccessibleQuickItem::parent()
const
308 QQuickItem *parent = item()->parentItem();
309 QQuickWindow *itemWindow = item()->window();
310 QQuickItem *ci = itemWindow ? itemWindow->contentItem() :
nullptr;
311 while (parent && !QQuickItemPrivate::get(parent)->isAccessible && parent != ci)
312 parent = parent->parentItem();
316 if (
auto *iface = itemWindow->accessibleRoot())
319 return QAccessible::queryAccessibleInterface(window());
321 while (parent && !parent->d_func()->isAccessible)
322 parent = parent->parentItem();
323 return QAccessible::queryAccessibleInterface(parent);
329QAccessibleInterface *QAccessibleQuickItem::child(
int index)
const
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
356 if (QQuickText *textItem = qobject_cast<QQuickText*>(item())) {
357 const int hyperLinkChildCount = QQuickTextPrivate::get(textItem)->getLinks().size();
358 if (index < hyperLinkChildCount) {
359 auto it = m_childToId.constFind(index);
360 if (it != m_childToId.constEnd())
361 return QAccessible::accessibleInterface(it.value());
363 QAccessibleHyperlink *iface =
new QAccessibleHyperlink(item(), index);
364 QAccessible::Id id = QAccessible::registerAccessibleInterface(iface);
365 m_childToId.insert(index, id);
368 index -= hyperLinkChildCount;
371 QList<QQuickItem *> children = childItems();
372 if (index < children.size()) {
373 QQuickItem *child = children.at(index);
374 return QAccessible::queryAccessibleInterface(child);
379int QAccessibleQuickItem::indexOfChild(
const QAccessibleInterface *iface)
const
381 int hyperLinkChildCount = 0;
382 if (QQuickText *textItem = qobject_cast<QQuickText*>(item())) {
383 hyperLinkChildCount = QQuickTextPrivate::get(textItem)->getLinks().size();
384 if (QAccessibleHyperlinkInterface *hyperLinkIface =
const_cast<QAccessibleInterface *>(iface)->hyperlinkInterface()) {
387 QAccessibleHyperlink *hyperLink =
static_cast<QAccessibleHyperlink*>(hyperLinkIface);
388 if (hyperLink->textItem() ==
static_cast<QQuickText*>(item())) {
389 return hyperLink->linkIndex;
393 QList<QQuickItem*> kids = childItems();
394 int idx = kids.indexOf(
static_cast<QQuickItem*>(iface->object()));
396 idx += hyperLinkChildCount;
400static void unignoredChildren(QQuickItem *item, QList<QQuickItem *> *items,
bool paintOrder)
402 const QList<QQuickItem*> childItems = paintOrder ? QQuickItemPrivate::get(item)->paintOrderChildItems()
403 : item->childItems();
404 for (QQuickItem *child : childItems) {
405 if (QQuickItemPrivate::get(child)->isAccessible) {
406 items->append(child);
408 unignoredChildren(child, items, paintOrder);
413QList<QQuickItem *> accessibleUnignoredChildren(QQuickItem *item,
bool paintOrder)
415 QList<QQuickItem *> items;
416 unignoredChildren(item, &items, paintOrder);
420QList<QQuickItem *> QAccessibleQuickItem::childItems()
const
422 return accessibleUnignoredChildren(item());
425static bool isTextRole(QAccessible::Role role)
427 return role == QAccessible::EditableText || role == QAccessible::StaticText;
430QAccessible::State QAccessibleQuickItem::state()
const
432 QQuickAccessibleAttached *attached = QQuickAccessibleAttached::attachedProperties(item());
434 return QAccessible::State();
436 QAccessible::State state = attached->state();
438 QRect viewRect_ = viewRect();
439 QRect itemRect = rect();
441 if (viewRect_.isNull() || itemRect.isNull() || !window() || !window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
442 state.invisible =
true;
443 if (!viewRect_.intersects(itemRect))
444 state.offscreen =
true;
445 if ((role() == QAccessible::CheckBox
446 || role() == QAccessible::RadioButton
447 || role() == QAccessible::Switch)
448 && object()->property(
"checked").toBool())
449 state.checked =
true;
450 if (item()->activeFocusOnTab() || isTextRole(role()))
451 state.focusable =
true;
452 if (item()->hasActiveFocus())
453 state.focused =
true;
454 if (role() == QAccessible::EditableText)
455 if (
auto ti = qobject_cast<QQuickTextInput *>(item()))
456 state.passwordEdit = ti->echoMode() != QQuickTextInput::Normal;
457 if (!item()->isEnabled()) {
458 state.focusable =
false;
459 state.disabled =
true;
461 if (item()->property(
"readOnly").toBool() || role() == QAccessible::ProgressBar)
462 state.readOnly =
true;
466QList<std::pair<QAccessibleInterface *, QAccessible::Relation>>
467QAccessibleQuickItem::relations(QAccessible::Relation match)
const
469 QList<std::pair<QAccessibleInterface *, QAccessible::Relation>> rels =
470 QAccessibleObject::relations(match);
471 if (QQuickAccessibleAttached *attached = QQuickAccessibleAttached::attachedProperties(item())) {
472 if (match & QAccessible::Labelled) {
473 if (
auto *labelFor = attached->labelFor()) {
474 rels.append({QAccessible::queryAccessibleInterface(labelFor),
475 QAccessible::Labelled});
479 if (match & QAccessible::Label) {
480 if (
auto *labelledBy = attached->labelledBy()) {
481 rels.append({QAccessible::queryAccessibleInterface(labelledBy),
482 QAccessible::Label});
489QAccessible::Role QAccessibleQuickItem::role()
const
495 QAccessible::Role role = QAccessible::NoRole;
497 role = QQuickItemPrivate::get(item())->effectiveAccessibleRole();
498 if (role == QAccessible::NoRole) {
499 if (qobject_cast<QQuickText*>(
const_cast<QQuickItem *>(item())))
500 role = QAccessible::StaticText;
501 else if (qobject_cast<QQuickTextInput*>(
const_cast<QQuickItem *>(item())))
502 role = QAccessible::EditableText;
504 role = QAccessible::Client;
510bool QAccessibleQuickItem::isAccessible()
const
512 return item()->d_func()->isAccessible;
515QStringList QAccessibleQuickItem::actionNames()
const
519 case QAccessible::Link:
520 case QAccessible::PushButton:
521 case QAccessible::MenuItem:
522 actions << QAccessibleActionInterface::pressAction();
524 case QAccessible::RadioButton:
525 case QAccessible::CheckBox:
526 case QAccessible::Switch:
527 actions << QAccessibleActionInterface::toggleAction()
528 << QAccessibleActionInterface::pressAction();
530 case QAccessible::Slider:
531 case QAccessible::SpinBox:
532 case QAccessible::ScrollBar:
533 actions << QAccessibleActionInterface::increaseAction()
534 << QAccessibleActionInterface::decreaseAction();
539 if (state().focusable)
540 actions.append(QAccessibleActionInterface::setFocusAction());
543 if (QQuickAccessibleAttached *attached = QQuickAccessibleAttached::attachedProperties(item()))
544 attached->availableActions(&actions);
548void QAccessibleQuickItem::doAction(
const QString &actionName)
550 bool accepted =
false;
551 if (actionName == QAccessibleActionInterface::setFocusAction()) {
552 item()->forceActiveFocus();
555 if (QQuickAccessibleAttached *attached = QQuickAccessibleAttached::attachedProperties(item()))
556 accepted = attached->doAction(actionName);
562 const QByteArray functionName =
"accessible" + actionName.toLatin1() +
"Action";
563 if (object()->metaObject()->indexOfMethod(QByteArray(functionName +
"()")) != -1) {
564 QMetaObject::invokeMethod(object(), functionName);
574 case QAccessible::RadioButton:
575 case QAccessible::CheckBox:
576 case QAccessible::Switch: {
577 QVariant checked = object()->property(
"checked");
578 if (checked.isValid()) {
579 if (actionName == QAccessibleActionInterface::toggleAction() ||
580 actionName == QAccessibleActionInterface::pressAction()) {
582 object()->setProperty(
"checked", QVariant(!checked.toBool()));
587 case QAccessible::Slider:
588 case QAccessible::SpinBox:
589 case QAccessible::Dial:
590 case QAccessible::ScrollBar: {
591 if (actionName != QAccessibleActionInterface::increaseAction() &&
592 actionName != QAccessibleActionInterface::decreaseAction())
598 if (QAccessibleValueInterface *valueIface = valueInterface()) {
599 QVariant valueV = valueIface->currentValue();
600 qreal newValue = valueV.toReal();
602 QVariant stepSizeV = object()->property(
"stepSize");
603 qreal stepSize = stepSizeV.isValid() ? stepSizeV.toReal() : qreal(1.0);
604 if (actionName == QAccessibleActionInterface::increaseAction()) {
605 newValue += stepSize;
607 newValue -= stepSize;
610 QVariant minimumValueV = valueIface->minimumValue();
611 if (minimumValueV.isValid()) {
612 newValue = qMax(newValue, minimumValueV.toReal());
614 QVariant maximumValueV = valueIface->maximumValue();
615 if (maximumValueV.isValid()) {
616 newValue = qMin(newValue, maximumValueV.toReal());
619 valueIface->setCurrentValue(QVariant(newValue));
628QStringList QAccessibleQuickItem::keyBindingsForAction(
const QString &actionName)
const
630 Q_UNUSED(actionName);
631 return QStringList();
634QString QAccessibleQuickItem::text(QAccessible::Text textType)
const
638 case QAccessible::Name: {
639 QVariant accessibleName = QQuickAccessibleAttached::property(object(),
"name");
640 if (!accessibleName.isNull())
641 return accessibleName.toString();
643 case QAccessible::Description: {
644 QVariant accessibleDecription = QQuickAccessibleAttached::property(object(),
"description");
645 if (!accessibleDecription.isNull())
646 return accessibleDecription.toString();
648 case QAccessible::Identifier: {
649 QVariant accessibleIdentifier = QQuickAccessibleAttached::property(object(),
"id");
650 if (!accessibleIdentifier.isNull())
651 return accessibleIdentifier.toString();
652 auto quickItem = item();
653 if (quickItem->isComponentComplete()) {
654 QQmlContext *context = qmlContext(quickItem);
656 const auto objectId = context->nameForObject(quickItem);
657 if (!objectId.isEmpty())
662#ifdef Q_ACCESSIBLE_QUICK_ITEM_ENABLE_DEBUG_DESCRIPTION
663 case QAccessible::DebugDescription: {
665 debugString = QString::fromLatin1(object()->metaObject()->className()) + QLatin1Char(
' ');
666 debugString += isAccessible() ? QLatin1String(
"enabled") : QLatin1String(
"disabled");
670 case QAccessible::Value:
671 case QAccessible::Help:
672 case QAccessible::Accelerator:
678 if (role() == QAccessible::EditableText) {
679 if (textType == QAccessible::Value) {
680 if (
auto textInput = qobject_cast<QQuickTextInput *>(item()))
681 return textInput->displayText();
682 if (QTextDocument *doc = textDocument()) {
683 return doc->toPlainText();
685 QVariant text = object()->property(
"text");
686 return text.toString();
693void QAccessibleQuickItem::setText(QAccessible::Text textType,
const QString &text)
695 if (role() != QAccessible::EditableText)
697 if (textType != QAccessible::Value)
700 if (QTextDocument *doc = textDocument()) {
701 doc->setPlainText(text);
704 auto textPropertyName =
"text";
705 if (object()->metaObject()->indexOfProperty(textPropertyName) >= 0)
706 object()->setProperty(textPropertyName, text);
709void *QAccessibleQuickItem::interface_cast(QAccessible::InterfaceType t)
711 const QAccessible::Role r = role();
713 case QAccessible::ActionInterface:
714 return static_cast<QAccessibleActionInterface*>(
this);
715 case QAccessible::AttributesInterface:
716 return static_cast<QAccessibleAttributesInterface *>(
this);
717 case QAccessible::ValueInterface:
718 if (r == QAccessible::Slider
719 || r == QAccessible::SpinBox
720 || r == QAccessible::Dial
721 || r == QAccessible::ScrollBar
722 || r == QAccessible::ProgressBar) {
723 return static_cast<QAccessibleValueInterface*>(
this);
726 case QAccessible::TextInterface:
727 if (r == QAccessible::EditableText
728 || r == QAccessible::StaticText
729 || r == QAccessible::Heading) {
730 return static_cast<QAccessibleTextInterface*>(
this);
737 return QAccessibleObject::interface_cast(t);
740QVariant QAccessibleQuickItem::currentValue()
const
742 return item()->property(
"value");
745void QAccessibleQuickItem::setCurrentValue(
const QVariant &value)
747 item()->setProperty(
"value", value);
750QVariant QAccessibleQuickItem::maximumValue()
const
752 const auto minimumValue = item()->property(
"minimumValue");
753 const auto maximumValue = item()->property(
"maximumValue");
754 const auto from = item()->property(
"from");
755 const auto to = item()->property(
"to");
757 if (minimumValue.isValid() && maximumValue.isValid())
760 if (from.isValid() && to.isValid())
766QVariant QAccessibleQuickItem::minimumValue()
const
768 const auto minimumValue = item()->property(
"minimumValue");
769 const auto maximumValue = item()->property(
"maximumValue");
770 const auto from = item()->property(
"from");
771 const auto to = item()->property(
"to");
773 if (minimumValue.isValid() && maximumValue.isValid())
776 if (from.isValid() && to.isValid())
782QVariant QAccessibleQuickItem::minimumStepSize()
const
784 return item()->property(
"stepSize");
788
789
790
791QRect itemScreenRect(QQuickItem *item)
795 if (!item->window() ||!item->isVisible() || qFuzzyIsNull(item->opacity())) {
799 QSizeF itemSize(item->width(), item->height());
802 if (itemSize.isEmpty()) {
803 itemSize = QSize(item->implicitWidth(), item->implicitHeight());
804 if (itemSize.isEmpty() && item->parentItem())
806 itemSize = QSize(item->parentItem()->width(), item->parentItem()->height());
809 QRectF sceneRect = item->mapRectToScene(QRectF(QPointF(0, 0), itemSize));
810 QPoint screenPos = item->window()->mapToGlobal(sceneRect.topLeft().toPoint());
811 QSize screenSize = sceneRect.size().toSize();
812 return QRect(screenPos, screenSize);
815QTextDocument *QAccessibleQuickItem::textDocument()
const
817 QVariant docVariant = item()->property(
"textDocument");
818 if (docVariant.canConvert<QQuickTextDocument*>()) {
819 QQuickTextDocument *qqdoc = docVariant.value<QQuickTextDocument*>();
820 return qqdoc->textDocument();
825int QAccessibleQuickItem::characterCount()
const
828 QTextCursor cursor = QTextCursor(m_doc);
829 cursor.movePosition(QTextCursor::End);
830 return cursor.position();
833 if (role() == QAccessible::EditableText)
834 return text(QAccessible::Value).size();
836 return text(QAccessible::Name).size();
839int QAccessibleQuickItem::cursorPosition()
const
841 QVariant pos = item()->property(
"cursorPosition");
845void QAccessibleQuickItem::setCursorPosition(
int position)
847 item()->setProperty(
"cursorPosition", position);
850QString QAccessibleQuickItem::text(
int startOffset,
int endOffset)
const
853 QTextCursor cursor = QTextCursor(m_doc);
854 cursor.setPosition(startOffset);
855 cursor.setPosition(endOffset, QTextCursor::KeepAnchor);
856 return cursor.selectedText();
859 if (role() == QAccessible::EditableText)
860 return text(QAccessible::Value).mid(startOffset, endOffset - startOffset);
862 return text(QAccessible::Name).mid(startOffset, endOffset - startOffset);
865QString QAccessibleQuickItem::textBeforeOffset(
int offset, QAccessible::TextBoundaryType boundaryType,
866 int *startOffset,
int *endOffset)
const
868 Q_ASSERT(startOffset);
872 return qt_accTextBeforeOffsetHelper(*
this, QTextCursor(m_doc), offset, boundaryType, startOffset, endOffset);
874 return QAccessibleTextInterface::textBeforeOffset(offset, boundaryType, startOffset, endOffset);
878QString QAccessibleQuickItem::textAfterOffset(
int offset, QAccessible::TextBoundaryType boundaryType,
879 int *startOffset,
int *endOffset)
const
881 Q_ASSERT(startOffset);
885 return qt_accTextAfterOffsetHelper(*
this, QTextCursor(m_doc), offset, boundaryType, startOffset, endOffset);
887 return QAccessibleTextInterface::textAfterOffset(offset, boundaryType, startOffset, endOffset);
891QString QAccessibleQuickItem::textAtOffset(
int offset, QAccessible::TextBoundaryType boundaryType,
892 int *startOffset,
int *endOffset)
const
894 Q_ASSERT(startOffset);
898 return qt_accTextAtOffsetHelper(*
this, QTextCursor(m_doc), offset, boundaryType, startOffset, endOffset);
900 return QAccessibleTextInterface::textAtOffset(offset, boundaryType, startOffset, endOffset);
904void QAccessibleQuickItem::selection(
int selectionIndex,
int *startOffset,
int *endOffset)
const
906 if (selectionIndex == 0) {
907 *startOffset = item()->property(
"selectionStart").toInt();
908 *endOffset = item()->property(
"selectionEnd").toInt();
915int QAccessibleQuickItem::selectionCount()
const
917 if (item()->property(
"selectionStart").toInt() != item()->property(
"selectionEnd").toInt())
922void QAccessibleQuickItem::addSelection(
int startOffset,
int endOffset)
924 setSelection(0, startOffset, endOffset);
926void QAccessibleQuickItem::removeSelection(
int )
930void QAccessibleQuickItem::setSelection(
int ,
int ,
int )
935QList<QAccessible::Attribute> QAccessibleQuickItem::attributeKeys()
const
937 if (attributeValue(QAccessible::Attribute::Locale).isValid())
938 return { QAccessible::Attribute::Locale };
943QVariant QAccessibleQuickItem::attributeValue(QAccessible::Attribute key)
const
945 if (key == QAccessible::Attribute::Locale) {
946 QAccessibleInterface *windowIface = QAccessible::queryAccessibleInterface(window());
947 if (!windowIface || !windowIface->attributesInterface())
950 return windowIface->attributesInterface()->attributeValue(QAccessible::Attribute::Locale);