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(QQuickItem *labelledBy READ labelledBy WRITE setLabelledBy NOTIFY labelledByChanged FINAL)
62 Q_PROPERTY(QQuickItem *labelFor READ labelFor WRITE setLabelFor NOTIFY labelForChanged FINAL)
63
64 QML_NAMED_ELEMENT(Accessible)
65 QML_ADDED_IN_VERSION(2, 0)
66 QML_UNCREATABLE("Accessible is only available via attached properties.")
67 QML_ATTACHED(QQuickAccessibleAttached)
68 QML_EXTENDED_NAMESPACE(QAccessible)
69
70public:
71 STATE_PROPERTY(checkable)
72 STATE_PROPERTY(checked)
73 STATE_PROPERTY(editable)
74 STATE_PROPERTY(expandable)
75 STATE_PROPERTY(expanded)
76 STATE_PROPERTY(focusable)
77 STATE_PROPERTY(focused)
78 STATE_PROPERTY(multiLine)
79 STATE_PROPERTY(readOnly)
80 STATE_PROPERTY(selected)
81 STATE_PROPERTY(selectable)
82 STATE_PROPERTY(pressed)
83 STATE_PROPERTY(checkStateMixed)
84 STATE_PROPERTY(defaultButton)
85 STATE_PROPERTY(passwordEdit)
86 STATE_PROPERTY(selectableText)
87 STATE_PROPERTY(searchEdit)
88
89 QQuickAccessibleAttached(QObject *parent);
90 ~QQuickAccessibleAttached();
91
92 QAccessible::Role role() const { return m_role; }
93 void setRole(QAccessible::Role role);
94 QString name() const {
95 if (m_state.passwordEdit)
96 return QString();
97 if (!m_nameExplicitlySet && m_proxying && m_proxying->wasNameExplicitlySet())
98 return m_proxying->name();
99 return m_name;
100 }
101
102 bool wasNameExplicitlySet() const;
103 void setName(const QString &name) {
104 m_nameExplicitlySet = true;
105 if (name != m_name) {
106 m_name = name;
107 Q_EMIT nameChanged();
108 QAccessibleEvent ev(parent(), QAccessible::NameChanged);
109 QAccessible::updateAccessibility(&ev);
110 }
111 }
112 void setNameImplicitly(const QString &name);
113
114 QString description() const {
115 return !m_descriptionExplicitlySet && m_proxying ? m_proxying->description() : m_description;
116 }
117 void setDescription(const QString &description)
118 {
119 if (!m_descriptionExplicitlySet && m_proxying) {
120 disconnect(m_proxying, &QQuickAccessibleAttached::descriptionChanged, this, &QQuickAccessibleAttached::descriptionChanged);
121 }
122 m_descriptionExplicitlySet = true;
123 if (m_description != description) {
124 m_description = description;
125 Q_EMIT descriptionChanged();
126 QAccessibleEvent ev(parent(), QAccessible::DescriptionChanged);
127 QAccessible::updateAccessibility(&ev);
128 }
129 }
130 void setDescriptionImplicitly(const QString &desc);
131
132 QString id() const { return m_id; }
133 void setId(const QString &id)
134 {
135 if (m_id != id) {
136 m_id = id;
137 Q_EMIT idChanged();
138 QAccessibleEvent ev(parent(), QAccessible::IdentifierChanged);
139 QAccessible::updateAccessibility(&ev);
140 }
141 }
142
143 QQuickItem *labelledBy() const
144 {
145 return findRelation(QAccessible::Labelled);
146 }
147
148 void setLabelledBy(QQuickItem *labelledBy)
149 {
150 QQuickItem *p = qobject_cast<QQuickItem *>(parent());
151 if (!labelledBy) {
152 qmlWarning(p) << "labelledBy cannot be null";
153 return;
154 }
155 setLabelledByInternal(labelledBy);
156
157 QQuickAccessibleAttached *label = qobject_cast<QQuickAccessibleAttached *>(
158 qmlAttachedPropertiesObject<QQuickAccessibleAttached>(labelledBy));
159
160 label->setLabelForInternal(p);
161 }
162 void setLabelledByInternal(QQuickItem *labelledBy)
163 {
164 m_relations.append({ labelledBy, QAccessible::Labelled });
165 Q_EMIT labelledByChanged();
166 }
167
168 QQuickItem *labelFor() const
169 {
170 return findRelation(QAccessible::Label);
171 }
172
173 void setLabelFor(QQuickItem *labelFor)
174 {
175 QQuickItem *p = qobject_cast<QQuickItem *>(parent());
176 if (!labelFor) {
177 qmlWarning(p) << "labelFor cannot be null";
178 return;
179 }
180 setLabelForInternal(labelFor);
181
182 QQuickAccessibleAttached *labelled = qobject_cast<QQuickAccessibleAttached *>(
183 qmlAttachedPropertiesObject<QQuickAccessibleAttached>(labelFor));
184 labelled->setLabelledBy(p);
185 }
186
187 void setLabelForInternal(QQuickItem *labelFor)
188 {
189 m_relations.append({ labelFor, QAccessible::Label });
190 Q_EMIT labelForChanged();
191 }
192
193 // Factory function
194 static QQuickAccessibleAttached *qmlAttachedProperties(QObject *obj);
195
196 static QQuickAccessibleAttached *attachedProperties(const QObject *obj)
197 {
198 return qobject_cast<QQuickAccessibleAttached*>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(obj, false));
199 }
200
201 // Property getter
202 static QVariant property(const QObject *object, const char *propertyName)
203 {
204 if (QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object))
205 return attachedObject->property(propertyName);
206 return QVariant();
207 }
208
209 static bool setProperty(QObject *object, const char *propertyName, const QVariant &value)
210 {
211 QObject *obj = qmlAttachedPropertiesObject<QQuickAccessibleAttached>(object, true);
212 if (!obj) {
213 qWarning("cannot set property Accessible.%s of QObject %s", propertyName, object->metaObject()->className());
214 return false;
215 }
216 return obj->setProperty(propertyName, value);
217 }
218
219 static QObject *findAccessible(QObject *object, QAccessible::Role role = QAccessible::NoRole)
220 {
221 while (object) {
222 QQuickAccessibleAttached *att = QQuickAccessibleAttached::attachedProperties(object);
223 if (att && (role == QAccessible::NoRole || att->role() == role)) {
224 break;
225 }
226 if (auto action = object->property("action").value<QObject *>(); action) {
227 QQuickAccessibleAttached *att = QQuickAccessibleAttached::attachedProperties(action);
228 if (att && (role == QAccessible::NoRole || att->role() == role)) {
229 object = action;
230 break;
231 }
232 }
233 object = object->parent();
234 }
235 return object;
236 }
237
238 QAccessible::State state() const { return m_state; }
239 bool ignored() const;
240 bool doAction(const QString &actionName);
241 void availableActions(QStringList *actions) const;
242
243 Q_REVISION(6, 2) Q_INVOKABLE static QString stripHtml(const QString &html);
244 void setProxying(QQuickAccessibleAttached *proxying);
245
246 Q_REVISION(6, 8) Q_INVOKABLE void announce(const QString &message, QAccessible::AnnouncementPoliteness politeness = QAccessible::AnnouncementPoliteness::Polite);
247
248public Q_SLOTS:
249 void valueChanged() {
250 QAccessibleValueChangeEvent ev(parent(), parent()->property("value"));
251 QAccessible::updateAccessibility(&ev);
252 }
253 void cursorPositionChanged() {
254 QAccessibleTextCursorEvent ev(parent(), parent()->property("cursorPosition").toInt());
255 QAccessible::updateAccessibility(&ev);
256 }
257
258 void setIgnored(bool ignored);
259
260Q_SIGNALS:
261 void roleChanged();
262 void nameChanged();
263 void descriptionChanged();
264 void idChanged();
265 void ignoredChanged();
266 void labelledByChanged();
267 void labelForChanged();
268 void pressAction();
269 void toggleAction();
270 void increaseAction();
271 void decreaseAction();
272 void showOnScreenAction();
273 void scrollUpAction();
274 void scrollDownAction();
275 void scrollLeftAction();
276 void scrollRightAction();
277 void previousPageAction();
278 void nextPageAction();
279
280private:
281 QQuickItem *findRelation(QAccessible::Relation relation) const;
282
283 QAccessible::Role m_role;
284 QAccessible::State m_state;
285 QAccessible::State m_stateExplicitlySet;
286 QString m_name;
287 bool m_nameExplicitlySet = false;
288 QString m_description;
289 bool m_descriptionExplicitlySet = false;
290 QQuickAccessibleAttached* m_proxying = nullptr;
291 QString m_id;
292 QList<std::pair<QQuickItem *, QAccessible::Relation>> m_relations;
293
294 static QMetaMethod sigPress;
295 static QMetaMethod sigToggle;
296 static QMetaMethod sigIncrease;
297 static QMetaMethod sigDecrease;
298 static QMetaMethod sigShowOnScreen;
299 static QMetaMethod sigScrollUp;
300 static QMetaMethod sigScrollDown;
301 static QMetaMethod sigScrollLeft;
302 static QMetaMethod sigScrollRight;
303 static QMetaMethod sigPreviousPage;
304 static QMetaMethod sigNextPage;
305
306public:
307 using QObject::property;
308};
309
310
311QT_END_NAMESPACE
312
313#endif // accessibility
314
315#endif