~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/gui/accessible/qaccessible_mac_p.h

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2008-08-01 11:30:30 UTC
  • mto: (15.1.1 lenny) (1.3.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 55.
  • Revision ID: james.westby@ubuntu.com-20080801113030-c33y1z0l21t6cj5r
Tags: upstream-4.4.1
ImportĀ upstreamĀ versionĀ 4.4.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
 
4
**
 
5
** This file is part of the QtGui module of the Qt Toolkit.
 
6
**
 
7
** This file may be used under the terms of the GNU General Public
 
8
** License versions 2.0 or 3.0 as published by the Free Software
 
9
** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
 
10
** included in the packaging of this file.  Alternatively you may (at
 
11
** your option) use any later version of the GNU General Public
 
12
** License if such license has been publicly approved by Trolltech ASA
 
13
** (or its successors, if any) and the KDE Free Qt Foundation. In
 
14
** addition, as a special exception, Trolltech gives you certain
 
15
** additional rights. These rights are described in the Trolltech GPL
 
16
** Exception version 1.2, which can be found at
 
17
** http://www.trolltech.com/products/qt/gplexception/ and in the file
 
18
** GPL_EXCEPTION.txt in this package.
 
19
**
 
20
** Please review the following information to ensure GNU General
 
21
** Public Licensing requirements will be met:
 
22
** http://trolltech.com/products/qt/licenses/licensing/opensource/. If
 
23
** you are unsure which license is appropriate for your use, please
 
24
** review the following information:
 
25
** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
 
26
** or contact the sales department at sales@trolltech.com.
 
27
**
 
28
** In addition, as a special exception, Trolltech, as the sole
 
29
** copyright holder for Qt Designer, grants users of the Qt/Eclipse
 
30
** Integration plug-in the right for the Qt/Eclipse Integration to
 
31
** link to functionality provided by Qt Designer and its related
 
32
** libraries.
 
33
**
 
34
** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
 
35
** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
 
36
** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly
 
37
** granted herein.
 
38
**
 
39
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
40
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
41
**
 
42
****************************************************************************/
 
43
 
 
44
#ifndef QACCESSIBLE_MAC_P_H
 
45
#define QACCESSIBLE_MAC_P_H
 
46
 
 
47
//
 
48
//  W A R N I N G
 
49
//  -------------
 
50
//
 
51
// This file is not part of the Qt API.  It exists purely as an
 
52
// implementation detail.  This header file may change from version to
 
53
// version without notice, or even be removed.
 
54
//
 
55
// We mean it.
 
56
//
 
57
//
 
58
 
 
59
#include <qglobal.h>
 
60
#include <private/qt_mac_p.h>
 
61
#include <qaccessible.h>
 
62
#include <qwidget.h>
 
63
#include <qdebug.h>
 
64
 
 
65
//#define Q_ACCESSIBLE_MAC_DEBUG
 
66
 
 
67
QT_BEGIN_NAMESPACE
 
68
 
 
69
/*
 
70
    QAccessibleInterfaceWrapper wraps QAccessibleInterface and adds
 
71
    a ref count. QAccessibleInterfaceWrapper is a "by-value" class.
 
72
*/
 
73
class Q_AUTOTEST_EXPORT QAccessibleInterfaceWrapper
 
74
{
 
75
public:
 
76
    QAccessibleInterfaceWrapper()
 
77
    : interface(0), childrenIsRegistered(new bool(false)), refCount(new int(1)) { }
 
78
 
 
79
    QAccessibleInterfaceWrapper(QAccessibleInterface *interface)
 
80
    :interface(interface), childrenIsRegistered(new bool(false)), refCount(new int(1))  { }
 
81
 
 
82
    ~QAccessibleInterfaceWrapper()
 
83
    {
 
84
        if (--(*refCount) == 0) {
 
85
            delete interface;
 
86
            delete refCount;
 
87
            delete childrenIsRegistered;
 
88
        }
 
89
    }
 
90
 
 
91
    QAccessibleInterfaceWrapper(const QAccessibleInterfaceWrapper &other)
 
92
    :interface(other.interface), childrenIsRegistered(other.childrenIsRegistered), refCount(other.refCount)
 
93
    {
 
94
        ++(*refCount);
 
95
    }
 
96
 
 
97
    void operator=(const QAccessibleInterfaceWrapper &other)
 
98
    {
 
99
        if (other.interface == interface)
 
100
            return;
 
101
 
 
102
        if (--(*refCount) == 0) {
 
103
            delete interface;
 
104
            delete refCount;
 
105
            delete childrenIsRegistered;
 
106
        }
 
107
 
 
108
        interface = other.interface;
 
109
        childrenIsRegistered = other.childrenIsRegistered;
 
110
        refCount = other.refCount;
 
111
        ++(*refCount);
 
112
    }
 
113
 
 
114
    QAccessibleInterface *interface;
 
115
    bool *childrenIsRegistered;
 
116
private:
 
117
    int *refCount;
 
118
};
 
119
 
 
120
/*
 
121
    QAInterface represents one accessiblity item. It hides the fact that
 
122
    one QAccessibleInterface may represent more than one item, and it also
 
123
    automates the memory management for QAccessibleInterfaces using the
 
124
    QAccessibleInterfaceWrapper wrapper class.
 
125
 
 
126
    It has the same API as QAccessibleInterface, minus the child parameter
 
127
    in the funcitons.
 
128
*/
 
129
class Q_AUTOTEST_EXPORT QAInterface : public QAccessible
 
130
{
 
131
public:
 
132
    QAInterface()
 
133
    : base(QAccessibleInterfaceWrapper())
 
134
    { }
 
135
 
 
136
    QAInterface(QAccessibleInterface *interface, int child = 0)
 
137
    {
 
138
        if (interface == 0 || child > interface->childCount()) {
 
139
           base = QAccessibleInterfaceWrapper(); 
 
140
        } else {
 
141
            base = QAccessibleInterfaceWrapper(interface);
 
142
            m_cachedObject = interface->object();
 
143
            this->child = child;
 
144
        }
 
145
    }
 
146
 
 
147
    QAInterface(QAccessibleInterfaceWrapper wrapper, int child = 0)
 
148
    :base(wrapper), m_cachedObject(wrapper.interface->object()), child(child)
 
149
    { }
 
150
 
 
151
    QAInterface(const QAInterface &other, int child)
 
152
    {
 
153
        if (other.isValid() == false || child > other.childCount()) {
 
154
           base = QAccessibleInterfaceWrapper();
 
155
        } else {
 
156
            base = other.base;
 
157
            m_cachedObject = other.m_cachedObject;
 
158
            this->child = child;
 
159
        }
 
160
    }
 
161
 
 
162
    bool operator==(const QAInterface &other) const;
 
163
    bool operator!=(const QAInterface &other) const;
 
164
 
 
165
    inline QString actionText (int action, Text text) const
 
166
    { return base.interface->actionText(action, text, child); }
 
167
 
 
168
    QAInterface childAt(int x, int y) const
 
169
    {
 
170
        if (!checkValid())
 
171
            return QAInterface();
 
172
 
 
173
        const int foundChild = base.interface->childAt(x, y);
 
174
 
 
175
        if (foundChild == -1)
 
176
            return QAInterface();
 
177
 
 
178
        if (child == 0)
 
179
            return navigate(QAccessible::Child, foundChild);
 
180
 
 
181
        if (foundChild == child)
 
182
            return *this;
 
183
        return QAInterface();
 
184
    }
 
185
 
 
186
    int indexOfChild(const QAInterface &child) const
 
187
    {
 
188
        if (!checkValid())
 
189
            return -1;
 
190
 
 
191
        if (*this != child.parent())
 
192
            return -1;
 
193
 
 
194
        if (object() == child.object())
 
195
            return child.id();
 
196
 
 
197
        return base.interface->indexOfChild(child.base.interface);
 
198
    }
 
199
 
 
200
    inline int childCount() const
 
201
    {
 
202
        if (!checkValid())
 
203
            return 0;
 
204
 
 
205
        if (child != 0)
 
206
            return 0;
 
207
        return base.interface->childCount();
 
208
    }
 
209
 
 
210
    QList<QAInterface> children() const
 
211
    {
 
212
        if (!checkValid())
 
213
            return QList<QAInterface>();
 
214
 
 
215
        QList<QAInterface> children;
 
216
        for (int i = 1; i <= childCount(); ++i) {
 
217
            children.append(navigate(QAccessible::Child, i));
 
218
        }
 
219
        return children;
 
220
    }
 
221
 
 
222
    QAInterface childAt(int index) const
 
223
    {
 
224
        return navigate(QAccessible::Child, index);
 
225
    }
 
226
 
 
227
    inline void doAction(int action, const QVariantList &params = QVariantList()) const
 
228
    {
 
229
        if (!checkValid())
 
230
            return;
 
231
 
 
232
        base.interface->doAction(action, child, params);
 
233
    }
 
234
 
 
235
    QAInterface navigate(RelationFlag relation, int entry) const;
 
236
 
 
237
    inline QObject * object() const
 
238
    {
 
239
        if (!checkValid())
 
240
            return 0;
 
241
 
 
242
        return base.interface->object();
 
243
    }
 
244
 
 
245
    QAInterface objectInterface() const
 
246
    {
 
247
        if (!checkValid())
 
248
            return QAInterface();
 
249
 
 
250
        QObject *obj = object();
 
251
        QAInterface current = *this;
 
252
        while (obj == 0)
 
253
        {
 
254
            QAInterface parent = current.parent();
 
255
            if (parent.isValid() == false)
 
256
                break;
 
257
            obj = parent.object();
 
258
            current = parent;
 
259
        }
 
260
        return current;
 
261
    }
 
262
 
 
263
    inline HIObjectRef hiObject() const
 
264
    {
 
265
        if (!checkValid())
 
266
            return 0;
 
267
        QWidget * const widget = qobject_cast<QWidget * const>(object());
 
268
        if (widget)
 
269
            return (HIObjectRef)widget->winId();
 
270
        else
 
271
            return 0;
 
272
    }
 
273
 
 
274
    inline QObject * cachedObject() const
 
275
    {
 
276
        if (!checkValid())
 
277
            return 0;
 
278
        return m_cachedObject;
 
279
    }
 
280
 
 
281
    inline QRect rect() const
 
282
    {
 
283
        if (!checkValid())
 
284
            return QRect();
 
285
        return base.interface->rect(child);
 
286
    }
 
287
 
 
288
    inline Role role() const
 
289
    {
 
290
        if (!checkValid())
 
291
            return QAccessible::NoRole;
 
292
        return base.interface->role(child);
 
293
    }
 
294
 
 
295
    inline void setText(Text t, const QString &text) const
 
296
    {
 
297
        if (!checkValid())
 
298
            return;
 
299
        base.interface->setText(t, child, text);
 
300
    }
 
301
 
 
302
    inline State state() const
 
303
    {
 
304
        if (!checkValid())
 
305
            return 0;
 
306
        return base.interface->state(child);
 
307
    }
 
308
 
 
309
    inline QString text (Text text) const
 
310
    {
 
311
        if (!checkValid())
 
312
            return QString();
 
313
        return base.interface->text(text, child);
 
314
    }
 
315
 
 
316
    inline QString value() const
 
317
    { return text(QAccessible::Value); }
 
318
 
 
319
    inline QString name() const
 
320
    { return text(QAccessible::Name); }
 
321
 
 
322
    inline int userActionCount() const
 
323
    {
 
324
        if (!checkValid())
 
325
            return 0;
 
326
        return base.interface->userActionCount(child);
 
327
    }
 
328
 
 
329
    inline QString className() const
 
330
    {
 
331
        if (!checkValid())
 
332
            return QString();
 
333
        return QLatin1String(base.interface->object()->metaObject()->className());
 
334
    }
 
335
 
 
336
    inline bool isHIView() const
 
337
    { return (child == 0 && object() != 0); }
 
338
 
 
339
    inline int id() const
 
340
    { return child; }
 
341
 
 
342
    inline bool isValid() const
 
343
    {
 
344
        return (base.interface != 0 && base.interface->isValid());
 
345
    }
 
346
 
 
347
    QAInterface parent() const
 
348
    { return navigate(QAccessible::Ancestor, 1); }
 
349
 
 
350
    QAccessibleInterfaceWrapper interfaceWrapper() const
 
351
    { return base; }
 
352
 
 
353
protected:
 
354
    bool checkValid() const
 
355
    {
 
356
        const bool valid = isValid();
 
357
#ifdef Q_ACCESSIBLE_MAC_DEBUG
 
358
        if (!valid)
 
359
            qFatal("QAccessible_mac: tried to use invalid interface.");
 
360
#endif
 
361
        return valid;
 
362
    }
 
363
 
 
364
    QAccessibleInterfaceWrapper base;
 
365
    QObject *m_cachedObject;
 
366
    int child;
 
367
};
 
368
 
 
369
Q_AUTOTEST_EXPORT QDebug operator<<(QDebug debug, const QAInterface &interface);
 
370
 
 
371
/*
 
372
    QAElement is a thin wrapper around an AXUIElementRef that automates
 
373
    the ref-counting.
 
374
*/
 
375
class Q_AUTOTEST_EXPORT QAElement
 
376
{
 
377
public:
 
378
    QAElement();
 
379
    explicit QAElement(AXUIElementRef elementRef);
 
380
    QAElement(const QAElement &element);
 
381
    QAElement(HIObjectRef, int child);
 
382
    ~QAElement();
 
383
 
 
384
    inline HIObjectRef object() const
 
385
    {
 
386
        return AXUIElementGetHIObject(elementRef);
 
387
    }
 
388
 
 
389
    inline int id() const
 
390
    {
 
391
        UInt64 id;
 
392
        AXUIElementGetIdentifier(elementRef, &id);
 
393
        return id;
 
394
    }
 
395
 
 
396
    inline AXUIElementRef element() const
 
397
    {
 
398
        return elementRef;
 
399
    }
 
400
 
 
401
    inline bool isValid() const
 
402
    {
 
403
        return (elementRef != 0);
 
404
    }
 
405
 
 
406
    void operator=(const QAElement &other);
 
407
    bool operator==(const QAElement &other) const;
 
408
private:
 
409
    AXUIElementRef elementRef;
 
410
};
 
411
 
 
412
 
 
413
class QInterfaceFactory
 
414
{
 
415
public:
 
416
    virtual QAInterface interface(UInt64 identifier) = 0;
 
417
    virtual QAElement element(int id) = 0;
 
418
    virtual QAElement element(const QAInterface &interface)
 
419
    {
 
420
        return element(interface.id());
 
421
    }
 
422
    virtual void registerChildren() = 0;
 
423
    virtual ~QInterfaceFactory() {}
 
424
};
 
425
 
 
426
/*
 
427
    QAccessibleHierarchyManager bridges the Mac and Qt accessibility hierarchies.
 
428
    There is a one-to-one relationship between QAElements on the Mac side
 
429
    and QAInterfaces on the Qt side, and this class provies lookup funcitons
 
430
    that translates between these to items.
 
431
 
 
432
    The identity of a QAInterface is determined by its QAccessibleInterface and
 
433
    child identifier, and the identity of a QAElement is determined by its
 
434
    HIObjectRef and identifier.
 
435
 
 
436
    QAccessibleHierarchyManager receives QObject::destroyed() signals and deletes
 
437
    the accessibility objects for destroyed objects.
 
438
*/
 
439
class Q_AUTOTEST_EXPORT QAccessibleHierarchyManager : public QObject
 
440
{
 
441
Q_OBJECT
 
442
public:
 
443
    ~QAccessibleHierarchyManager() { reset(); }
 
444
    static QAccessibleHierarchyManager *instance();
 
445
    void reset();
 
446
 
 
447
    QAElement registerInterface(QObject *object, int child);
 
448
    QAElement registerInterface(const QAInterface &interface);
 
449
    void registerInterface(QObject *object, HIObjectRef hiobject, QInterfaceFactory *interfaceFactory);
 
450
 
 
451
    void registerChildren(const QAInterface &interface);
 
452
 
 
453
    QAInterface lookup(const AXUIElementRef &element);
 
454
    QAInterface lookup(const QAElement &element);
 
455
    QAElement lookup(const QAInterface &interface);
 
456
    QAElement lookup(QObject * const object, int id);
 
457
private slots:
 
458
    void objectDestroyed(QObject *);
 
459
private:
 
460
    typedef QHash<QObject *, QInterfaceFactory *> QObjectElementHash;
 
461
    typedef QHash<HIObjectRef, QInterfaceFactory *> HIObjectInterfaceHash;
 
462
    typedef QHash<QObject *, HIObjectRef> QObjectHIObjectHash;
 
463
 
 
464
    QObjectElementHash qobjectElementHash;
 
465
    HIObjectInterfaceHash hiobjectInterfaceHash;
 
466
    QObjectHIObjectHash qobjectHiobjectHash;
 
467
};
 
468
 
 
469
Q_AUTOTEST_EXPORT bool isItInteresting(const QAInterface &interface);
 
470
 
 
471
QT_END_NAMESPACE
 
472
 
 
473
#endif