Coverage Report

Created: 2026-06-07 08:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/accessible/qplatformaccessibility.cpp
Line
Count
Source
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
#include "qplatformaccessibility.h"
4
#include <private/qfactoryloader_p.h>
5
#include "qaccessibleplugin.h"
6
#include "qaccessibleobject.h"
7
#include "qaccessiblebridge.h"
8
#include <QtGui/QGuiApplication>
9
10
#include <QDebug>
11
12
QT_BEGIN_NAMESPACE
13
14
using namespace Qt::StringLiterals;
15
16
#if QT_CONFIG(accessibility)
17
18
/* accessiblebridge plugin discovery stuff */
19
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, bridgeloader,
20
    (QAccessibleBridgeFactoryInterface_iid, "/accessiblebridge"_L1))
21
22
Q_GLOBAL_STATIC(QList<QAccessibleBridge *>, bridges)
23
24
/*!
25
    \class QPlatformAccessibility
26
    \since 5.0
27
    \internal
28
    \preliminary
29
    \ingroup qpa
30
    \ingroup accessibility
31
32
    \brief The QPlatformAccessibility class is the base class for
33
    integrating accessibility backends
34
35
    \sa QAccessible
36
*/
37
QPlatformAccessibility::QPlatformAccessibility()
38
0
{
39
0
}
40
41
QPlatformAccessibility::~QPlatformAccessibility()
42
0
{
43
0
}
44
45
void QPlatformAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
46
0
{
47
0
    initialize();
48
49
0
    if (!bridges() || bridges()->isEmpty())
50
0
        return;
51
52
0
    for (int i = 0; i < bridges()->size(); ++i)
53
0
        bridges()->at(i)->notifyAccessibilityUpdate(event);
54
0
}
55
56
void QPlatformAccessibility::setRootObject(QObject *o)
57
0
{
58
0
    initialize();
59
0
    if (bridges()->isEmpty())
60
0
        return;
61
62
0
    if (!o)
63
0
        return;
64
65
0
    for (int i = 0; i < bridges()->size(); ++i) {
66
0
        QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(o);
67
0
        bridges()->at(i)->setRootObject(iface);
68
0
    }
69
0
}
70
71
void QPlatformAccessibility::initialize()
72
0
{
73
0
    static bool isInit = false;
74
0
    if (isInit)
75
0
        return;
76
0
    isInit = true;      // ### not atomic
77
78
0
    typedef QMultiMap<int, QString> PluginKeyMap;
79
0
    typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator;
80
81
0
    const PluginKeyMap keyMap = bridgeloader()->keyMap();
82
0
    QAccessibleBridgePlugin *factory = nullptr;
83
0
    int i = -1;
84
0
    const PluginKeyMapConstIterator cend = keyMap.constEnd();
85
0
    for (PluginKeyMapConstIterator it = keyMap.constBegin(); it != cend; ++it) {
86
0
        if (it.key() != i) {
87
0
            i = it.key();
88
0
            factory = qobject_cast<QAccessibleBridgePlugin*>(bridgeloader()->instance(i));
89
0
        }
90
0
        if (factory)
91
0
            if (QAccessibleBridge *bridge = factory->create(it.value()))
92
0
                bridges()->append(bridge);
93
0
    }
94
0
}
95
96
void QPlatformAccessibility::cleanup()
97
0
{
98
0
    qDeleteAll(*bridges());
99
0
}
100
101
void qAccessibleNotifyActivationObservers(bool active); // qaccessible.cpp
102
103
void QPlatformAccessibility::setActive(bool active)
104
0
{
105
0
    m_active = active;
106
107
    // Send activeChanged notifications if the new active status differs from
108
    // the notifed one.
109
0
    if ((active && m_activeNotificationState != std::optional<bool>{true}) ||
110
0
        (!active && m_activeNotificationState != std::optional<bool>{false})) {
111
0
        qAccessibleNotifyActivationObservers(active);
112
0
    }
113
114
0
    m_activeNotificationState = active;
115
0
}
116
117
void QPlatformAccessibility::clearActiveNotificationState()
118
0
{
119
0
    m_activeNotificationState = std::nullopt;
120
0
}
121
122
#endif // QT_CONFIG(accessibility)
123
124
QT_END_NAMESPACE