5#include <QtCore/qdebug.h>
6#include <QtCore/qloggingcategory.h>
8#if QT_CONFIG(accessibility)
12Q_STATIC_LOGGING_CATEGORY(lcAccessibilityCache,
"qt.accessibility.cache");
15
16
17
18
20static QAccessibleCache *accessibleCache =
nullptr;
22static void cleanupAccessibleCache()
24 delete accessibleCache;
25 accessibleCache =
nullptr;
28QAccessibleObjectDestroyedEvent::~QAccessibleObjectDestroyedEvent()
32QAccessibleCache::~QAccessibleCache()
34 for (QAccessible::Id id: idToInterface.keys())
38QAccessibleCache *QAccessibleCache::instance()
40 if (!accessibleCache) {
41 accessibleCache =
new QAccessibleCache;
42 qAddPostRoutine(cleanupAccessibleCache);
44 return accessibleCache;
48
49
50
51
52QAccessible::Id QAccessibleCache::acquireId()
const
54 static const QAccessible::Id FirstId = QAccessible::Id(INT_MAX) + 1;
55 static QAccessible::Id nextId = FirstId;
57 while (idToInterface.contains(nextId)) {
60 if (nextId == UINT_MAX - 1)
69QAccessibleInterface *QAccessibleCache::interfaceForId(QAccessible::Id id)
const
71 return idToInterface.value(id);
74QAccessible::Id QAccessibleCache::idForInterface(QAccessibleInterface *iface)
const
76 return interfaceToId.value(iface);
79QAccessible::Id QAccessibleCache::idForObject(QObject *obj)
const
82 const QMetaObject *mo = obj->metaObject();
83 for (
auto pair : objectToId.values(obj)) {
84 if (pair.second == mo) {
93
94
95
96
97bool QAccessibleCache::containsObject(QObject *obj)
const
100 const QMetaObject *mo = obj->metaObject();
101 for (
auto pair : objectToId.values(obj)) {
102 if (pair.second == mo) {
110QAccessible::Id QAccessibleCache::insert(QObject *object, QAccessibleInterface *iface)
const
116 Q_ASSERT(!containsObject(object));
117 Q_ASSERT_X(!interfaceToId.contains(iface),
"",
"Accessible interface inserted into cache twice!");
119 QAccessible::Id id = acquireId();
120 QObject *obj = iface->object();
121 Q_ASSERT(object == obj);
123 objectToId.insert(obj, std::pair(id, obj->metaObject()));
124 connect(obj, &QObject::destroyed,
this, &QAccessibleCache::objectDestroyed);
126 idToInterface.insert(id, iface);
127 interfaceToId.insert(iface, id);
128 qCDebug(lcAccessibilityCache) <<
"insert - id:" << id <<
" iface:" << iface;
132void QAccessibleCache::objectDestroyed(QObject* obj)
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 for (
auto pair : objectToId.values(obj)) {
160 QAccessible::Id id = pair.first;
161 Q_ASSERT_X(idToInterface.contains(id),
"",
"QObject with accessible interface deleted, where interface not in cache!");
162 deleteInterface(id, obj);
166void QAccessibleCache::sendObjectDestroyedEvent(QObject *obj)
168 for (
auto pair : objectToId.values(obj)) {
169 QAccessible::Id id = pair.first;
170 Q_ASSERT_X(idToInterface.contains(id),
"",
"QObject with accessible interface deleted, where interface not in cache!");
172 QAccessibleObjectDestroyedEvent event(id);
173 QAccessible::updateAccessibility(&event);
177void QAccessibleCache::deleteInterface(QAccessible::Id id, QObject *obj)
179 QAccessibleInterface *iface = idToInterface.take(id);
180 qCDebug(lcAccessibilityCache) <<
"delete - id:" << id <<
" iface:" << iface;
183 interfaceToId.take(iface);
185 obj = iface->object();
187 objectToId.remove(obj);
191 removeAccessibleElement(id);
197#include "moc_qaccessiblecache_p.cpp"