7#if QT_CONFIG(accessibility)
9#include "qapplication.h"
10#if QT_CONFIG(groupbox)
19#if QT_CONFIG(whatsthis)
20#include "qwhatsthis.h"
25#if QT_CONFIG(rubberband)
32#include <QtGui/private/qaccessiblehelper_p.h>
33#include <QtGui/private/qwindow_p.h>
34#include <QtWidgets/private/qwidget_p.h>
36#include <qpa/qplatformwindow.h>
40using namespace Qt::StringLiterals;
42QWidgetList _q_ac_childWidgets(
const QWidget *widget);
44static QString buddyString(
const QWidget *widget)
48 QWidget *parent = widget->parentWidget();
51#if QT_CONFIG(shortcut) && QT_CONFIG(label)
52 for (QObject *o : parent->children()) {
53 QLabel *label = qobject_cast<QLabel*>(o);
54 if (label && label->buddy() == widget)
59#if QT_CONFIG(groupbox)
60 QGroupBox *groupbox = qobject_cast<QGroupBox*>(parent);
62 return groupbox->title();
68QString qt_accHotKey(
const QString &text)
71 return QKeySequence::mnemonic(text).toString(QKeySequence::NativeText);
80class QAccessibleWidgetPrivate
83 QAccessibleWidgetPrivate()
84 :role(QAccessible::Client)
87 QAccessible::Role role;
89 QStringList primarySignals;
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
116
117
118
119QAccessibleWidget::QAccessibleWidget(QWidget *w, QAccessible::Role role)
120: QAccessibleObject(w)
123 d =
new QAccessibleWidgetPrivate();
128
129
130
131
132QAccessibleWidget::QAccessibleWidget(QWidget *w, QAccessible::Role role,
const QString &name)
133 : QAccessibleWidget(w, role)
139bool QAccessibleWidget::isValid()
const
141 if (!object() ||
static_cast<QWidget *>(object())->d_func()->data.in_destructor)
143 return QAccessibleObject::isValid();
147QWindow *QAccessibleWidget::window()
const
149 const QWidget *w = widget();
151 QWindow *result = w->windowHandle();
153 if (
const QWidget *nativeParent = w->nativeParentWidget())
154 result = nativeParent->windowHandle();
160
161
162QAccessibleWidget::~QAccessibleWidget()
168
169
170QWidget *QAccessibleWidget::widget()
const
172 return qobject_cast<QWidget*>(object());
176
177
178
179
180QObject *QAccessibleWidget::parentObject()
const
182 QWidget *w = widget();
186 if (!w->isWindow()) {
187 if (QWidget *parent = w->parentWidget())
191 if (QWindow *window = w->windowHandle()) {
193 if (QObject *a11yParent = QWindowPrivate::get(window)->accessibleParent)
201QRect QAccessibleWidget::rect()
const
203 QWidget *w = widget();
206 QPoint wpos = w->mapToGlobal(QPoint(0, 0));
208 return QRect(wpos.x(), wpos.y(), w->width(), w->height());
212
213
214
215
216
217void QAccessibleWidget::addControllingSignal(
const QString &signal)
219 QByteArray s = QMetaObject::normalizedSignature(signal.toLatin1());
220 if (Q_UNLIKELY(object()->metaObject()->indexOfSignal(s) < 0))
221 qWarning(
"Signal %s unknown in %s", s.constData(), object()->metaObject()->className());
222 d->primarySignals << QLatin1StringView(s);
225static inline bool isAncestor(
const QObject *obj,
const QObject *child)
230 child = child->parent();
236QList<std::pair<QAccessibleInterface *, QAccessible::Relation>>
237QAccessibleWidget::relations(QAccessible::Relation match )
const
239 QList<std::pair<QAccessibleInterface *, QAccessible::Relation>> rels;
240 if (match & QAccessible::Label) {
241 const QAccessible::Relation rel = QAccessible::Label;
242#if QT_CONFIG(shortcut) && QT_CONFIG(label)
243 for (QLabel *label : std::as_const(widget()->d_func()->labels)) {
245 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(label);
246 rels.emplace_back(iface, rel);
249#if QT_CONFIG(groupbox)
250 QGroupBox *groupbox = qobject_cast<QGroupBox *>(widget()->parentWidget());
251 if (groupbox && !groupbox->title().isEmpty()) {
252 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(groupbox);
253 rels.emplace_back(iface, rel);
258 if (match & QAccessible::Controlled) {
259 QObjectList allReceivers;
260 QObject *connectionObject = object();
261 for (
int sig = 0; sig < d->primarySignals.size(); ++sig) {
262 const QObjectList receivers = connectionObject->d_func()->receiverList(d->primarySignals.at(sig).toLatin1());
263 allReceivers += receivers;
266 allReceivers.removeAll(object());
268 for (
int i = 0; i < allReceivers.size(); ++i) {
269 const QAccessible::Relation rel = QAccessible::Controlled;
270 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(allReceivers.at(i));
272 rels.emplace_back(iface, rel);
280QAccessibleInterface *QAccessibleWidget::parent()
const
282 return QAccessible::queryAccessibleInterface(parentObject());
286QAccessibleInterface *QAccessibleWidget::child(
int index)
const
289 QWidgetList childList = _q_ac_childWidgets(widget());
290 if (index >= 0 && index < childList.size())
291 return QAccessible::queryAccessibleInterface(childList.at(index));
296QAccessibleInterface *QAccessibleWidget::focusChild()
const
298 if (widget()->hasFocus())
299 return QAccessible::queryAccessibleInterface(object());
301 QWidget *fw = widget()->focusWidget();
305 if (isAncestor(widget(), fw)) {
306 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(fw);
307 if (!iface || iface ==
this || !iface->focusChild())
309 return iface->focusChild();
315int QAccessibleWidget::childCount()
const
317 QWidgetList cl = _q_ac_childWidgets(widget());
322int QAccessibleWidget::indexOfChild(
const QAccessibleInterface *child)
const
326 QWidgetList cl = _q_ac_childWidgets(widget());
327 return cl.indexOf(qobject_cast<QWidget *>(child->object()));
331QString QAccessibleWidget::text(QAccessible::Text t)
const
336 case QAccessible::Name:
337 if (!d->name.isEmpty()) {
339 }
else if (!widget()->accessibleName().isEmpty()) {
340 str = widget()->accessibleName();
341 }
else if (widget()->isWindow()) {
342 if (QWindow *window = widget()->windowHandle()) {
343 if (QPlatformWindow *platformWindow = window->handle())
344 str = platformWindow->windowTitle();
347 str = qt_accStripAmp(buddyString(widget()));
350 case QAccessible::Description:
351 str = widget()->accessibleDescription();
352#if QT_CONFIG(tooltip)
354 str = widget()->toolTip();
357 case QAccessible::Identifier:
358 str = widget()->accessibleIdentifier();
360 case QAccessible::Help:
361#if QT_CONFIG(whatsthis)
362 str = widget()->whatsThis();
365 case QAccessible::Accelerator:
366 str = qt_accHotKey(buddyString(widget()));
368 case QAccessible::Value:
377QStringList QAccessibleWidget::actionNames()
const
380 if (widget()->isEnabled()) {
381 if (widget()->focusPolicy() != Qt::NoFocus)
382 names << setFocusAction();
383 if (widget()->contextMenuPolicy() == Qt::ActionsContextMenu && widget()->actions().size() > 0)
384 names << showMenuAction();
390void QAccessibleWidget::doAction(
const QString &actionName)
392 if (!widget()->isEnabled())
395 if (actionName == setFocusAction()) {
396 if (widget()->isWindow())
397 widget()->activateWindow();
398 widget()->setFocus();
399 }
else if (actionName == showMenuAction()) {
400 QContextMenuEvent e(QContextMenuEvent::Other,
401 QPoint(), widget()->mapToGlobal(QPoint()),
402 QGuiApplication::keyboardModifiers());
403 QCoreApplication::sendEvent(widget(), &e);
408QStringList QAccessibleWidget::keyBindingsForAction(
const QString & )
const
410 return QStringList();
414QAccessible::Role QAccessibleWidget::role()
const
420QAccessible::State QAccessibleWidget::state()
const
422 QAccessible::State state;
424 QWidget *w = widget();
425 if (w->testAttribute(Qt::WA_WState_Visible) ==
false)
426 state.invisible =
true;
427 if (w->focusPolicy() != Qt::NoFocus)
428 state.focusable =
true;
430 state.focused =
true;
432 state.disabled =
true;
434 if (w->windowFlags() & Qt::WindowSystemMenuHint)
435 state.movable =
true;
436 if (w->minimumSize() != w->maximumSize())
437 state.sizeable =
true;
438 if (w->isActiveWindow())
446QColor QAccessibleWidget::foregroundColor()
const
448 return widget()->palette().color(widget()->foregroundRole());
452QColor QAccessibleWidget::backgroundColor()
const
454 return widget()->palette().color(widget()->backgroundRole());
458void *QAccessibleWidget::interface_cast(QAccessible::InterfaceType t)
460 if (t == QAccessible::ActionInterface)
461 return static_cast<QAccessibleActionInterface*>(
this);
467QAccessibleWidgetV2::QAccessibleWidgetV2(QWidget *object, QAccessible::Role role,
469 : QAccessibleWidget(object, role, name)
474
475
476
477
478QAccessibleWidgetV2::QAccessibleWidgetV2(QWidget *object, QAccessible::Role role)
479 : QAccessibleWidget(object, role)
483QAccessibleWidgetV2::~QAccessibleWidgetV2() =
default;
486void *QAccessibleWidgetV2::interface_cast(QAccessible::InterfaceType t)
488 if (t == QAccessible::AttributesInterface)
489 return static_cast<QAccessibleAttributesInterface *>(
this);
490 return QAccessibleWidget::interface_cast(t);
494QList<QAccessible::Attribute> QAccessibleWidgetV2::attributeKeys()
const
496 return { QAccessible::Attribute::Locale };
500QVariant QAccessibleWidgetV2::attributeValue(QAccessible::Attribute key)
const
502 if (key == QAccessible::Attribute::Locale)
503 return QVariant::fromValue(widget()->locale());