5#ifndef QQUICKACCESSIBLEATTACHED_H
6#define QQUICKACCESSIBLEATTACHED_H
19#include <QtQuick/qquickitem.h>
21#include <QtCore/qobject.h>
22#include <QtCore/qstring.h>
24#if QT_CONFIG(accessibility)
26#include <QtGui/qaccessible.h>
27#include <private/qtquickglobal_p.h>
28#include <QtQml/qqml.h>
33#define STATE_PROPERTY(P)
34 Q_PROPERTY(bool P READ P WRITE set_ ## P NOTIFY P ## Changed FINAL)
35 bool P() const { return m_proxying && !m_stateExplicitlySet.P ? m_proxying->P() : m_state.P ; }
36 void set_ ## P(bool arg)
39 m_proxying->set_##P(arg);
40 m_stateExplicitlySet.P = true;
44 Q_EMIT P ## Changed(arg);
45 QAccessible::State changedState;
46 changedState.P = true;
47 QAccessibleStateChangeEvent ev(parent(), changedState);
48 QAccessible::updateAccessibility(&ev);
50 Q_SIGNAL void P ## Changed(bool arg);
52class Q_QUICK_EXPORT QQuickAccessibleAttached :
public QObject
55 Q_PROPERTY(QAccessible::Role role READ role WRITE setRole NOTIFY roleChanged FINAL)
56 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged FINAL)
57 Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged FINAL)
58 Q_PROPERTY(QString id READ id WRITE setId NOTIFY idChanged FINAL)
59 Q_PROPERTY(
bool ignored READ ignored WRITE setIgnored NOTIFY ignoredChanged FINAL)
60 Q_PROPERTY(QQuickItem *labelledBy READ labelledBy WRITE setLabelledBy NOTIFY labelledByChanged FINAL)
61 Q_PROPERTY(QQuickItem *labelFor READ labelFor WRITE setLabelFor NOTIFY labelForChanged FINAL)
63 QML_NAMED_ELEMENT(Accessible)
64 QML_ADDED_IN_VERSION(2, 0)
65 QML_UNCREATABLE(
"Accessible is only available via attached properties.")
66 QML_ATTACHED(QQuickAccessibleAttached)
67 QML_EXTENDED_NAMESPACE(QAccessible)
70 STATE_PROPERTY(checkable)
71 STATE_PROPERTY(checked)
72 STATE_PROPERTY(editable)
73 STATE_PROPERTY(focusable)
74 STATE_PROPERTY(focused)
75 STATE_PROPERTY(multiLine)
76 STATE_PROPERTY(readOnly)
77 STATE_PROPERTY(selected)
78 STATE_PROPERTY(selectable)
79 STATE_PROPERTY(pressed)
80 STATE_PROPERTY(checkStateMixed)
81 STATE_PROPERTY(defaultButton)
82 STATE_PROPERTY(passwordEdit)
83 STATE_PROPERTY(selectableText)
84 STATE_PROPERTY(searchEdit)
86 QQuickAccessibleAttached(QObject *parent);
87 ~QQuickAccessibleAttached();
89 QAccessible::Role role()
const {
return m_role; }
90 void setRole(QAccessible::Role role);
91 QString name()
const {
92 if (m_state.passwordEdit)
94 if (!m_nameExplicitlySet && m_proxying && m_proxying->wasNameExplicitlySet())
95 return m_proxying->name();
99 bool wasNameExplicitlySet()
const;
100 void setName(
const QString &name) {
101 m_nameExplicitlySet =
true;
102 if (name != m_name) {
104 Q_EMIT nameChanged();
105 QAccessibleEvent ev(parent(), QAccessible::NameChanged);
106 QAccessible::updateAccessibility(&ev);
109 void setNameImplicitly(
const QString &name);
111 QString description()
const {
112 return !m_descriptionExplicitlySet && m_proxying ? m_proxying->description() : m_description;
114 void setDescription(
const QString &description)
116 if (!m_descriptionExplicitlySet && m_proxying) {
117 disconnect(m_proxying, &QQuickAccessibleAttached::descriptionChanged,
this, &QQuickAccessibleAttached::descriptionChanged);
119 m_descriptionExplicitlySet =
true;
120 if (m_description != description) {
121 m_description = description;
122 Q_EMIT descriptionChanged();
123 QAccessibleEvent ev(parent(), QAccessible::DescriptionChanged);
124 QAccessible::updateAccessibility(&ev);
127 void setDescriptionImplicitly(
const QString &desc);
129 QString id()
const {
return m_id; }
130 void setId(
const QString &id)
135 QAccessibleEvent ev(parent(), QAccessible::IdentifierChanged);
136 QAccessible::updateAccessibility(&ev);
140 QQuickItem *labelledBy()
const
142 return findRelation(QAccessible::Labelled);
145 void setLabelledBy(QQuickItem *labelledBy)
147 setLabelledByInternal(labelledBy);
149 QQuickAccessibleAttached *label = qobject_cast<QQuickAccessibleAttached *>(
150 qmlAttachedPropertiesObject<QQuickAccessibleAttached>(labelledBy));
152 label->setLabelForInternal(qobject_cast<QQuickItem *>(parent()));
154 void setLabelledByInternal(QQuickItem *labelledBy)
156 m_relations.append({ labelledBy, QAccessible::Labelled });
157 Q_EMIT labelledByChanged();
160 QQuickItem *labelFor()
const
162 return findRelation(QAccessible::Label);
165 void setLabelFor(QQuickItem *labelFor)
167 setLabelForInternal(labelFor);
169 QQuickAccessibleAttached *labelled = qobject_cast<QQuickAccessibleAttached *>(
170 qmlAttachedPropertiesObject<QQuickAccessibleAttached>(labelFor));
171 labelled->setLabelledBy(qobject_cast<QQuickItem *>(parent()));
174 void setLabelForInternal(QQuickItem *labelFor)
176 m_relations.append({ labelFor, QAccessible::Label });
177 Q_EMIT labelForChanged();
181 static QQuickAccessibleAttached *qmlAttachedProperties(QObject *obj);
183 static QQuickAccessibleAttached *attachedProperties(
const QObject *obj)
185 return qobject_cast<QQuickAccessibleAttached*>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(obj,
false));
189 static QVariant property(
const QObject *object,
const char *propertyName)
191 if (QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object))
192 return attachedObject->property(propertyName);
196 static bool setProperty(QObject *object,
const char *propertyName,
const QVariant &value)
198 QObject *obj = qmlAttachedPropertiesObject<QQuickAccessibleAttached>(object,
true);
200 qWarning(
"cannot set property Accessible.%s of QObject %s", propertyName, object->metaObject()->className());
203 return obj->setProperty(propertyName, value);
206 static QObject *findAccessible(QObject *object, QAccessible::Role role = QAccessible::NoRole)
209 QQuickAccessibleAttached *att = QQuickAccessibleAttached::attachedProperties(object);
210 if (att && (role == QAccessible::NoRole || att->role() == role)) {
213 if (
auto action = object->property(
"action").value<QObject *>(); action) {
214 QQuickAccessibleAttached *att = QQuickAccessibleAttached::attachedProperties(action);
215 if (att && (role == QAccessible::NoRole || att->role() == role)) {
220 object = object->parent();
225 QAccessible::State state()
const {
return m_state; }
226 bool ignored()
const;
227 bool doAction(
const QString &actionName);
228 void availableActions(QStringList *actions)
const;
230 Q_REVISION(6, 2) Q_INVOKABLE
static QString stripHtml(
const QString &html);
231 void setProxying(QQuickAccessibleAttached *proxying);
233 Q_REVISION(6, 8) Q_INVOKABLE
void announce(
const QString &message, QAccessible::AnnouncementPoliteness politeness = QAccessible::AnnouncementPoliteness::Polite);
236 void valueChanged() {
237 QAccessibleValueChangeEvent ev(parent(), parent()->property(
"value"));
238 QAccessible::updateAccessibility(&ev);
240 void cursorPositionChanged() {
241 QAccessibleTextCursorEvent ev(parent(), parent()->property(
"cursorPosition").toInt());
242 QAccessible::updateAccessibility(&ev);
245 void setIgnored(
bool ignored);
250 void descriptionChanged();
252 void ignoredChanged();
253 void labelledByChanged();
254 void labelForChanged();
257 void increaseAction();
258 void decreaseAction();
259 void scrollUpAction();
260 void scrollDownAction();
261 void scrollLeftAction();
262 void scrollRightAction();
263 void previousPageAction();
264 void nextPageAction();
267 QQuickItem *findRelation(QAccessible::Relation relation)
const;
269 QAccessible::Role m_role;
270 QAccessible::State m_state;
271 QAccessible::State m_stateExplicitlySet;
273 bool m_nameExplicitlySet =
false;
274 QString m_description;
275 bool m_descriptionExplicitlySet =
false;
276 QQuickAccessibleAttached* m_proxying =
nullptr;
278 QList<std::pair<QQuickItem *, QAccessible::Relation>> m_relations;
280 static QMetaMethod sigPress;
281 static QMetaMethod sigToggle;
282 static QMetaMethod sigIncrease;
283 static QMetaMethod sigDecrease;
284 static QMetaMethod sigScrollUp;
285 static QMetaMethod sigScrollDown;
286 static QMetaMethod sigScrollLeft;
287 static QMetaMethod sigScrollRight;
288 static QMetaMethod sigPreviousPage;
289 static QMetaMethod sigNextPage;
292 using QObject::property;