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 <QtWidgets/private/qwidget_p.h>
35#include <qpa/qplatformwindow.h>
39using namespace Qt::StringLiterals;
41QWidgetList _q_ac_childWidgets(
const QWidget *widget);
43static QString buddyString(
const QWidget *widget)
47 QWidget *parent = widget->parentWidget();
50#if QT_CONFIG(shortcut) && QT_CONFIG(label)
51 for (QObject *o : parent->children()) {
52 QLabel *label = qobject_cast<QLabel*>(o);
53 if (label && label->buddy() == widget)
58#if QT_CONFIG(groupbox)
59 QGroupBox *groupbox = qobject_cast<QGroupBox*>(parent);
61 return groupbox->title();
67QString qt_accHotKey(
const QString &text)
70 return QKeySequence::mnemonic(text).toString(QKeySequence::NativeText);
79class QAccessibleWidgetPrivate
82 QAccessibleWidgetPrivate()
83 :role(QAccessible::Client)
86 QAccessible::Role role;
88 QStringList primarySignals;
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
115
116
117
118QAccessibleWidget::QAccessibleWidget(QWidget *w, QAccessible::Role role)
119: QAccessibleObject(w)
122 d =
new QAccessibleWidgetPrivate();
127
128
129
130
131QAccessibleWidget::QAccessibleWidget(QWidget *w, QAccessible::Role role,
const QString &name)
132 : QAccessibleWidget(w, role)
138bool QAccessibleWidget::isValid()
const
140 if (!object() ||
static_cast<QWidget *>(object())->d_func()->data.in_destructor)
142 return QAccessibleObject::isValid();
146QWindow *QAccessibleWidget::window()
const
148 const QWidget *w = widget();
150 QWindow *result = w->windowHandle();
152 if (
const QWidget *nativeParent = w->nativeParentWidget())
153 result = nativeParent->windowHandle();
159
160
161QAccessibleWidget::~QAccessibleWidget()
167
168
169QWidget *QAccessibleWidget::widget()
const
171 return qobject_cast<QWidget*>(object());
175
176
177
178QObject *QAccessibleWidget::parentObject()
const
180 QWidget *w = widget();
181 if (!w || w->isWindow() || !w->parentWidget())
187QRect QAccessibleWidget::rect()
const
189 QWidget *w = widget();
192 QPoint wpos = w->mapToGlobal(QPoint(0, 0));
194 return QRect(wpos.x(), wpos.y(), w->width(), w->height());
198
199
200
201
202
203void QAccessibleWidget::addControllingSignal(
const QString &signal)
205 QByteArray s = QMetaObject::normalizedSignature(signal.toLatin1());
206 if (Q_UNLIKELY(object()->metaObject()->indexOfSignal(s) < 0))
207 qWarning(
"Signal %s unknown in %s", s.constData(), object()->metaObject()->className());
208 d->primarySignals << QLatin1StringView(s);
211static inline bool isAncestor(
const QObject *obj,
const QObject *child)
216 child = child->parent();
222QList<std::pair<QAccessibleInterface *, QAccessible::Relation>>
223QAccessibleWidget::relations(QAccessible::Relation match )
const
225 QList<std::pair<QAccessibleInterface *, QAccessible::Relation>> rels;
226 if (match & QAccessible::Label) {
227 const QAccessible::Relation rel = QAccessible::Label;
228#if QT_CONFIG(shortcut) && QT_CONFIG(label)
229 for (QLabel *label : std::as_const(widget()->d_func()->labels)) {
231 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(label);
232 rels.emplace_back(iface, rel);
235#if QT_CONFIG(groupbox)
236 QGroupBox *groupbox = qobject_cast<QGroupBox *>(widget()->parentWidget());
237 if (groupbox && !groupbox->title().isEmpty()) {
238 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(groupbox);
239 rels.emplace_back(iface, rel);
244 if (match & QAccessible::Controlled) {
245 QObjectList allReceivers;
246 QObject *connectionObject = object();
247 for (
int sig = 0; sig < d->primarySignals.size(); ++sig) {
248 const QObjectList receivers = connectionObject->d_func()->receiverList(d->primarySignals.at(sig).toLatin1());
249 allReceivers += receivers;
252 allReceivers.removeAll(object());
254 for (
int i = 0; i < allReceivers.size(); ++i) {
255 const QAccessible::Relation rel = QAccessible::Controlled;
256 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(allReceivers.at(i));
258 rels.emplace_back(iface, rel);
266QAccessibleInterface *QAccessibleWidget::parent()
const
268 return QAccessible::queryAccessibleInterface(parentObject());
272QAccessibleInterface *QAccessibleWidget::child(
int index)
const
275 QWidgetList childList = _q_ac_childWidgets(widget());
276 if (index >= 0 && index < childList.size())
277 return QAccessible::queryAccessibleInterface(childList.at(index));
282QAccessibleInterface *QAccessibleWidget::focusChild()
const
284 if (widget()->hasFocus())
285 return QAccessible::queryAccessibleInterface(object());
287 QWidget *fw = widget()->focusWidget();
291 if (isAncestor(widget(), fw)) {
292 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(fw);
293 if (!iface || iface ==
this || !iface->focusChild())
295 return iface->focusChild();
301int QAccessibleWidget::childCount()
const
303 QWidgetList cl = _q_ac_childWidgets(widget());
308int QAccessibleWidget::indexOfChild(
const QAccessibleInterface *child)
const
312 QWidgetList cl = _q_ac_childWidgets(widget());
313 return cl.indexOf(qobject_cast<QWidget *>(child->object()));
317QString QAccessibleWidget::text(QAccessible::Text t)
const
322 case QAccessible::Name:
323 if (!d->name.isEmpty()) {
325 }
else if (!widget()->accessibleName().isEmpty()) {
326 str = widget()->accessibleName();
327 }
else if (widget()->isWindow()) {
328 if (QWindow *window = widget()->windowHandle()) {
329 if (QPlatformWindow *platformWindow = window->handle())
330 str = platformWindow->windowTitle();
333 str = qt_accStripAmp(buddyString(widget()));
336 case QAccessible::Description:
337 str = widget()->accessibleDescription();
338#if QT_CONFIG(tooltip)
340 str = widget()->toolTip();
343 case QAccessible::Identifier:
344 str = widget()->accessibleIdentifier();
346 case QAccessible::Help:
347#if QT_CONFIG(whatsthis)
348 str = widget()->whatsThis();
351 case QAccessible::Accelerator:
352 str = qt_accHotKey(buddyString(widget()));
354 case QAccessible::Value:
363QStringList QAccessibleWidget::actionNames()
const
366 if (widget()->isEnabled()) {
367 if (widget()->focusPolicy() != Qt::NoFocus)
368 names << setFocusAction();
369 if (widget()->contextMenuPolicy() == Qt::ActionsContextMenu && widget()->actions().size() > 0)
370 names << showMenuAction();
376void QAccessibleWidget::doAction(
const QString &actionName)
378 if (!widget()->isEnabled())
381 if (actionName == setFocusAction()) {
382 if (widget()->isWindow())
383 widget()->activateWindow();
384 widget()->setFocus();
385 }
else if (actionName == showMenuAction()) {
386 QContextMenuEvent e(QContextMenuEvent::Other,
387 QPoint(), widget()->mapToGlobal(QPoint()),
388 QGuiApplication::keyboardModifiers());
389 QCoreApplication::sendEvent(widget(), &e);
394QStringList QAccessibleWidget::keyBindingsForAction(
const QString & )
const
396 return QStringList();
400QAccessible::Role QAccessibleWidget::role()
const
406QAccessible::State QAccessibleWidget::state()
const
408 QAccessible::State state;
410 QWidget *w = widget();
411 if (w->testAttribute(Qt::WA_WState_Visible) ==
false)
412 state.invisible =
true;
413 if (w->focusPolicy() != Qt::NoFocus)
414 state.focusable =
true;
416 state.focused =
true;
418 state.disabled =
true;
420 if (w->windowFlags() & Qt::WindowSystemMenuHint)
421 state.movable =
true;
422 if (w->minimumSize() != w->maximumSize())
423 state.sizeable =
true;
424 if (w->isActiveWindow())
432QColor QAccessibleWidget::foregroundColor()
const
434 return widget()->palette().color(widget()->foregroundRole());
438QColor QAccessibleWidget::backgroundColor()
const
440 return widget()->palette().color(widget()->backgroundRole());
444void *QAccessibleWidget::interface_cast(QAccessible::InterfaceType t)
446 if (t == QAccessible::ActionInterface)
447 return static_cast<QAccessibleActionInterface*>(
this);
453QAccessibleWidgetV2::QAccessibleWidgetV2(QWidget *object, QAccessible::Role role,
455 : QAccessibleWidget(object, role, name)
460
461
462
463
464QAccessibleWidgetV2::QAccessibleWidgetV2(QWidget *object, QAccessible::Role role)
465 : QAccessibleWidget(object, role)
469QAccessibleWidgetV2::~QAccessibleWidgetV2() =
default;
472void *QAccessibleWidgetV2::interface_cast(QAccessible::InterfaceType t)
474 if (t == QAccessible::AttributesInterface)
475 return static_cast<QAccessibleAttributesInterface *>(
this);
476 return QAccessibleWidget::interface_cast(t);
480QList<QAccessible::Attribute> QAccessibleWidgetV2::attributeKeys()
const
482 return { QAccessible::Attribute::Locale };
486QVariant QAccessibleWidgetV2::attributeValue(QAccessible::Attribute key)
const
488 if (key == QAccessible::Attribute::Locale)
489 return QVariant::fromValue(widget()->locale());