Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickaccessibleattached_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QQUICKACCESSIBLEATTACHED_H
6#define QQUICKACCESSIBLEATTACHED_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtQuick/qquickitem.h>
20
21#include <QtCore/qobject.h>
22#include <QtCore/qstring.h>
23
24#if QT_CONFIG(accessibility)
25
26#include <QtGui/qaccessible.h>
27#include <private/qtquickglobal_p.h>
28#include <QtQml/qqml.h>
29#include <QtQml/qqmlinfo.h>
30
31QT_BEGIN_NAMESPACE
32
33
34#define STATE_PROPERTY(P)
35 Q_PROPERTY(bool P READ P WRITE set_ ## P NOTIFY P ## Changed FINAL)
36 bool P() const { return m_proxying && !m_stateExplicitlySet.P ? m_proxying->P() : m_state.P ; }
37 void set_ ## P(bool arg)
38 {
39 if (m_proxying)
40 m_proxying->set_##P(arg);
41 m_stateExplicitlySet.P = true;
42 if (m_state.P == arg)
43 return;
44 m_state.P = arg;
45 Q_EMIT P ## Changed(arg);
46 QAccessible::State changedState;
47 changedState.P = true;
48 QAccessibleStateChangeEvent ev(parent(), changedState);
49 QAccessible::updateAccessibility(&ev);
50 }
51 Q_SIGNAL void P ## Changed(bool arg);
52
53class Q_QUICK_EXPORT QQuickAccessibleAttached : public QObject
54{
55 Q_OBJECT
56 Q_PROPERTY(QAccessible::Role role READ role WRITE setRole NOTIFY roleChanged FINAL)
57 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged FINAL)
58 Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged FINAL)
59 Q_PROPERTY(QString id READ id WRITE setId NOTIFY idChanged FINAL)
60 Q_PROPERTY(bool ignored READ ignored WRITE setIgnored NOTIFY ignoredChanged FINAL)
61 Q_PROPERTY(int levelAttribute READ levelAttribute WRITE setLevelAttribute NOTIFY levelAttributeChanged FINAL)
62 Q_PROPERTY(QQuickItem *labelledBy READ labelledBy WRITE setLabelledBy NOTIFY labelledByChanged FINAL)
63 Q_PROPERTY(QQuickItem *labelFor READ labelFor WRITE setLabelFor NOTIFY labelForChanged FINAL)
64
65 QML_NAMED_ELEMENT(Accessible)
66 QML_ADDED_IN_VERSION(2, 0)
67 QML_UNCREATABLE("Accessible is only available via attached properties.")
68 QML_ATTACHED(QQuickAccessibleAttached)
69 QML_EXTENDED_NAMESPACE(QAccessible)
70
71public:
72 STATE_PROPERTY(checkable)
73 STATE_PROPERTY(checked)
74 STATE_PROPERTY(editable)
75 STATE_PROPERTY(expandable)
76 STATE_PROPERTY(expanded)
77 STATE_PROPERTY(focusable)
78 STATE_PROPERTY(focused)
79 STATE_PROPERTY(multiLine)
80 STATE_PROPERTY(readOnly)
81 STATE_PROPERTY(selected)
82 STATE_PROPERTY(selectable)
83 STATE_PROPERTY(pressed)
84 STATE_PROPERTY(checkStateMixed)
85 STATE_PROPERTY(defaultButton)
86 STATE_PROPERTY(passwordEdit)
87 STATE_PROPERTY(selectableText)
88 STATE_PROPERTY(searchEdit)
89
90 QQuickAccessibleAttached(QObject *parent);
91 ~QQuickAccessibleAttached();
92
93 QAccessible::Role role() const { return m_role; }
94 void setRole(QAccessible::Role role);
95 QString name() const {
96 if (m_state.passwordEdit)
97 return QString();
98 if (!m_nameExplicitlySet && m_proxying && m_proxying->wasNameExplicitlySet())
99 return m_proxying->name();
100 return m_name;
101 }
102
103 bool wasNameExplicitlySet() const;
104 void setName(const QString &name) {
105 m_nameExplicitlySet = true;
106 if (name != m_name) {
107 m_name = name;
108 Q_EMIT nameChanged();
109 QAccessibleEvent ev(parent(), QAccessible::NameChanged);
110 QAccessible::updateAccessibility(&ev);
111 }
112 }
113 void setNameImplicitly(const QString &name);
114
115 QString description() const {
116 return !m_descriptionExplicitlySet && m_proxying ? m_proxying->description() : m_description;
117 }
118 void setDescription(const QString &description)
119 {
120 if (!m_descriptionExplicitlySet && m_proxying) {
121 disconnect(m_proxying, &QQuickAccessibleAttached::descriptionChanged, this, &QQuickAccessibleAttached::descriptionChanged);
122 }
123 m_descriptionExplicitlySet = true;
124 if (m_description != description) {
125 m_description = description;
126 Q_EMIT descriptionChanged();
127 QAccessibleEvent ev(parent(), QAccessible::DescriptionChanged);
128 QAccessible::updateAccessibility(&ev);
129 }
130 }
131 void setDescriptionImplicitly(const QString &desc);
132
133 QString id() const { return m_id; }
134 void setId(const QString &id)
135 {
136 if (m_id != id) {
137 m_id = id;
138 Q_EMIT idChanged();
139 QAccessibleEvent ev(parent(), QAccessible::IdentifierChanged);
140 QAccessible::updateAccessibility(&ev);
141 }
142 }
143
144 QQuickItem *labelledBy() const
145 {
146 return findRelation(QAccessible::Labelled);
147 }
148
149 void setLabelledBy(QQuickItem *labelledBy)
150 {
151 QQuickItem *p = qobject_cast<QQuickItem *>(parent());
152 if (!labelledBy) {
153 qmlWarning(p) << "labelledBy cannot be null";
154 return;
155 }
156 setLabelledByInternal(labelledBy);
157
158 QQuickAccessibleAttached *label = qobject_cast<QQuickAccessibleAttached *>(
159 qmlAttachedPropertiesObject<QQuickAccessibleAttached>(labelledBy));
160
161 label->setLabelForInternal(p);
162 }
163 void setLabelledByInternal(QQuickItem *labelledBy)
164 {
165 m_relations.append({ labelledBy, QAccessible::Labelled });
166 Q_EMIT labelledByChanged();
167 }
168
169 QQuickItem *labelFor() const
170 {
171 return findRelation(QAccessible::Label);
172 }
173
174 void setLabelFor(QQuickItem *labelFor)
175 {
176 QQuickItem *p = qobject_cast<QQuickItem *>(parent());
177 if (!labelFor) {
178 qmlWarning(p) << "labelFor cannot be null";
179 return;
180 }
181 setLabelForInternal(labelFor);
182
183 QQuickAccessibleAttached *labelled = qobject_cast<QQuickAccessibleAttached *>(
184 qmlAttachedPropertiesObject<QQuickAccessibleAttached>(labelFor));
185 labelled->setLabelledBy(p);
186 }
187
188 void setLabelForInternal(QQuickItem *labelFor)
189 {
190 m_relations.append({ labelFor, QAccessible::Label });
191 Q_EMIT labelForChanged();
192 }
193
194 int levelAttribute() const { return m_levelAttribute; }
195 void setLevelAttribute(int levelAttribute)
196 {
197 if (m_levelAttribute != levelAttribute) {
198 m_levelAttribute = levelAttribute;
199 Q_EMIT levelAttributeChanged();
200 QAccessibleEvent ev(parent(), QAccessible::AttributeChanged);
201 QAccessible::updateAccessibility(&ev);
202 }
203 }
204
205 // Factory function
206 static QQuickAccessibleAttached *qmlAttachedProperties(QObject *obj);
207
208 static QQuickAccessibleAttached *attachedProperties(const QObject *obj)
209 {
210 return qobject_cast<QQuickAccessibleAttached*>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(obj, false));
211 }
212
213 // Property getter
214 static QVariant property(const QObject *object, const char *propertyName)
215 {
216 if (QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object))
217 return attachedObject->property(propertyName);
218 return QVariant();
219 }
220
221 static bool setProperty(QObject *object, const char *propertyName, const QVariant &value)
222 {
223 QObject *obj = qmlAttachedPropertiesObject<QQuickAccessibleAttached>(object, true);
224 if (!obj) {
225 qWarning("cannot set property Accessible.%s of QObject %s", propertyName, object->metaObject()->className());
226 return false;
227 }
228 return obj->setProperty(propertyName, value);
229 }
230
231 static QObject *findAccessible(QObject *object, QAccessible::Role role = QAccessible::NoRole)
232 {
233 while (object) {
234 QQuickAccessibleAttached *att = QQuickAccessibleAttached::attachedProperties(object);
235 if (att && (role == QAccessible::NoRole || att->role() == role)) {
236 break;
237 }
238 if (auto action = object->property("action").value<QObject *>(); action) {
239 QQuickAccessibleAttached *att = QQuickAccessibleAttached::attachedProperties(action);
240 if (att && (role == QAccessible::NoRole || att->role() == role)) {
241 object = action;
242 break;
243 }
244 }
245 object = object->parent();
246 }
247 return object;
248 }
249
250 QAccessible::State state() const { return m_state; }
251 bool ignored() const;
252 bool doAction(const QString &actionName);
253 void availableActions(QStringList *actions) const;
254
255 Q_REVISION(6, 2) Q_INVOKABLE static QString stripHtml(const QString &html);
256 void setProxying(QQuickAccessibleAttached *proxying);
257
258 Q_REVISION(6, 8) Q_INVOKABLE void announce(const QString &message, QAccessible::AnnouncementPoliteness politeness = QAccessible::AnnouncementPoliteness::Polite);
259
260public Q_SLOTS:
261 void valueChanged() {
262 QAccessibleValueChangeEvent ev(parent(), parent()->property("value"));
263 QAccessible::updateAccessibility(&ev);
264 }
265 void cursorPositionChanged() {
266 QAccessibleTextCursorEvent ev(parent(), parent()->property("cursorPosition").toInt());
267 QAccessible::updateAccessibility(&ev);
268 }
269
270 void setIgnored(bool ignored);
271
272Q_SIGNALS:
273 void roleChanged();
274 void nameChanged();
275 void descriptionChanged();
276 void idChanged();
277 void ignoredChanged();
278 void levelAttributeChanged();
279 void labelledByChanged();
280 void labelForChanged();
281 void pressAction();
282 void toggleAction();
283 void increaseAction();
284 void decreaseAction();
285 void showOnScreenAction();
286 void scrollUpAction();
287 void scrollDownAction();
288 void scrollLeftAction();
289 void scrollRightAction();
290 void previousPageAction();
291 void nextPageAction();
292
293private:
294 QQuickItem *findRelation(QAccessible::Relation relation) const;
295
296 QAccessible::Role m_role;
297 QAccessible::State m_state;
298 QAccessible::State m_stateExplicitlySet;
299 QString m_name;
300 bool m_nameExplicitlySet = false;
301 QString m_description;
302 bool m_descriptionExplicitlySet = false;
303 QQuickAccessibleAttached* m_proxying = nullptr;
304 QString m_id;
305 QList<std::pair<QQuickItem *, QAccessible::Relation>> m_relations;
306 int m_levelAttribute = 0;
307
308 static QMetaMethod sigPress;
309 static QMetaMethod sigToggle;
310 static QMetaMethod sigIncrease;
311 static QMetaMethod sigDecrease;
312 static QMetaMethod sigShowOnScreen;
313 static QMetaMethod sigScrollUp;
314 static QMetaMethod sigScrollDown;
315 static QMetaMethod sigScrollLeft;
316 static QMetaMethod sigScrollRight;
317 static QMetaMethod sigPreviousPage;
318 static QMetaMethod sigNextPage;
319
320public:
321 using QObject::property;
322};
323
324
325QT_END_NAMESPACE
326
327#endif // accessibility
328
329#endif