Qt 4.8
qaccessible_mac_p.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QACCESSIBLE_MAC_P_H
43 #define QACCESSIBLE_MAC_P_H
44 
45 //
46 // W A R N I N G
47 // -------------
48 //
49 // This file is not part of the Qt API. It exists purely as an
50 // implementation detail. This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55 //
56 
57 #include <qglobal.h>
58 #include <private/qt_mac_p.h>
59 #include <qaccessible.h>
60 #include <qwidget.h>
61 #include <qdebug.h>
62 
63 //#define Q_ACCESSIBLE_MAC_DEBUG
64 
66 
67 /*
68  QAccessibleInterfaceWrapper wraps QAccessibleInterface and adds
69  a ref count. QAccessibleInterfaceWrapper is a "by-value" class.
70 */
72 {
73 public:
75  : interface(0), childrenIsRegistered(new bool(false)), refCount(new int(1)) { }
76 
78  :interface(interface), childrenIsRegistered(new bool(false)), refCount(new int(1)) { }
79 
81  {
82  if (--(*refCount) == 0) {
83  delete interface;
84  delete refCount;
85  delete childrenIsRegistered;
86  }
87  }
88 
90  :interface(other.interface), childrenIsRegistered(other.childrenIsRegistered), refCount(other.refCount)
91  {
92  ++(*refCount);
93  }
94 
96  {
97  if (other.interface == interface)
98  return;
99 
100  if (--(*refCount) == 0) {
101  delete interface;
102  delete refCount;
103  delete childrenIsRegistered;
104  }
105 
106  interface = other.interface;
107  childrenIsRegistered = other.childrenIsRegistered;
108  refCount = other.refCount;
109  ++(*refCount);
110  }
111 
114 private:
115  int *refCount;
116 };
117 
118 /*
119  QAInterface represents one accessiblity item. It hides the fact that
120  one QAccessibleInterface may represent more than one item, and it also
121  automates the memory management for QAccessibleInterfaces using the
122  QAccessibleInterfaceWrapper wrapper class.
123 
124  It has the same API as QAccessibleInterface, minus the child parameter
125  in the functions.
126 */
128 {
129 public:
132  { }
133 
134  QAInterface(QAccessibleInterface *interface, int child = 0)
135  {
136  if (interface == 0 || child > interface->childCount()) {
138  } else {
139  base = QAccessibleInterfaceWrapper(interface);
140  m_cachedObject = interface->object();
141  this->child = child;
142  }
143  }
144 
145  QAInterface(QAccessibleInterfaceWrapper wrapper, int child = 0)
146  :base(wrapper), m_cachedObject(wrapper.interface->object()), child(child)
147  { }
148 
149  QAInterface(const QAInterface &other, int child)
150  {
151  if (other.isValid() == false || child > other.childCount()) {
153  } else {
154  base = other.base;
155  m_cachedObject = other.m_cachedObject;
156  this->child = child;
157  }
158  }
159 
160  bool operator==(const QAInterface &other) const;
161  bool operator!=(const QAInterface &other) const;
162 
163  inline QString actionText (int action, Text text) const
164  { return base.interface->actionText(action, text, child); }
165 
166  QAInterface childAt(int x, int y) const
167  {
168  if (!checkValid())
169  return QAInterface();
170 
171  const int foundChild = base.interface->childAt(x, y);
172 
173  if (foundChild == -1)
174  return QAInterface();
175 
176  if (child == 0)
177  return navigate(QAccessible::Child, foundChild);
178 
179  if (foundChild == child)
180  return *this;
181  return QAInterface();
182  }
183 
184  int indexOfChild(const QAInterface &child) const
185  {
186  if (!checkValid())
187  return -1;
188 
189  if (*this != child.parent())
190  return -1;
191 
192  if (object() == child.object())
193  return child.id();
194 
195  return base.interface->indexOfChild(child.base.interface);
196  }
197 
198  inline int childCount() const
199  {
200  if (!checkValid())
201  return 0;
202 
203  if (child != 0)
204  return 0;
205  return base.interface->childCount();
206  }
207 
209  {
210  if (!checkValid())
211  return QList<QAInterface>();
212 
213  QList<QAInterface> children;
214  for (int i = 1; i <= childCount(); ++i) {
215  children.append(navigate(QAccessible::Child, i));
216  }
217  return children;
218  }
219 
221  {
222  return navigate(QAccessible::Child, index);
223  }
224 
225  inline void doAction(int action, const QVariantList &params = QVariantList()) const
226  {
227  if (!checkValid())
228  return;
229 
230  base.interface->doAction(action, child, params);
231  }
232 
233  QAInterface navigate(RelationFlag relation, int entry) const;
234 
235  inline QObject * object() const
236  {
237  if (!checkValid())
238  return 0;
239 
240  return base.interface->object();
241  }
242 
244  {
245  if (!checkValid())
246  return QAInterface();
247 
248  QObject *obj = object();
249  QAInterface current = *this;
250  while (obj == 0)
251  {
252  QAInterface parent = current.parent();
253  if (parent.isValid() == false)
254  break;
255  obj = parent.object();
256  current = parent;
257  }
258  return current;
259  }
260 
261  inline HIObjectRef hiObject() const
262  {
263  if (!checkValid())
264  return 0;
265  QWidget * const widget = qobject_cast<QWidget * const>(object());
266  if (widget)
267  return (HIObjectRef)widget->winId();
268  else
269  return 0;
270  }
271 
272  inline QObject * cachedObject() const
273  {
274  if (!checkValid())
275  return 0;
276  return m_cachedObject;
277  }
278 
279  inline QRect rect() const
280  {
281  if (!checkValid())
282  return QRect();
283  return base.interface->rect(child);
284  }
285 
286  inline Role role() const
287  {
288  if (!checkValid())
289  return QAccessible::NoRole;
290  return base.interface->role(child);
291  }
292 
293  inline void setText(Text t, const QString &text) const
294  {
295  if (!checkValid())
296  return;
297  base.interface->setText(t, child, text);
298  }
299 
300  inline State state() const
301  {
302  if (!checkValid())
303  return 0;
304  return base.interface->state(child);
305  }
306 
307  inline QString text (Text text) const
308  {
309  if (!checkValid())
310  return QString();
311  return base.interface->text(text, child);
312  }
313 
314  inline QString value() const
315  { return text(QAccessible::Value); }
316 
317  inline QString name() const
318  { return text(QAccessible::Name); }
319 
320  inline int userActionCount() const
321  {
322  if (!checkValid())
323  return 0;
324  return base.interface->userActionCount(child);
325  }
326 
327  inline QString className() const
328  {
329  if (!checkValid())
330  return QString();
331  return QLatin1String(base.interface->object()->metaObject()->className());
332  }
333 
334  inline bool isHIView() const
335  { return (child == 0 && object() != 0); }
336 
337  inline int id() const
338  { return child; }
339 
340  inline bool isValid() const
341  {
342  return (base.interface != 0 && base.interface->isValid());
343  }
344 
346  { return navigate(QAccessible::Ancestor, 1); }
347 
349  { return base; }
350 
351 protected:
352  bool checkValid() const
353  {
354  const bool valid = isValid();
355 #ifdef Q_ACCESSIBLE_MAC_DEBUG
356  if (!valid)
357  qFatal("QAccessible_mac: tried to use invalid interface.");
358 #endif
359  return valid;
360  }
361 
364  int child;
365 };
366 
367 Q_AUTOTEST_EXPORT QDebug operator<<(QDebug debug, const QAInterface &interface);
368 
369 /*
370  QAElement is a thin wrapper around an AXUIElementRef that automates
371  the ref-counting.
372 */
374 {
375 public:
376  QAElement();
377  explicit QAElement(AXUIElementRef elementRef);
378  QAElement(const QAElement &element);
379  QAElement(HIObjectRef, int child);
380  ~QAElement();
381 
382  inline HIObjectRef object() const
383  {
384 #ifndef Q_WS_MAC64
385  return AXUIElementGetHIObject(elementRef);
386 #else
387  return 0;
388 #endif
389  }
390 
391  inline int id() const
392  {
393  UInt64 theId;
394 #ifndef QT_MAC_USE_COCOA
395  AXUIElementGetIdentifier(elementRef, &theId);
396 #else
397  theId = 0;
398 #endif
399  return theId;
400  }
401 
402  inline AXUIElementRef element() const
403  {
404  return elementRef;
405  }
406 
407  inline bool isValid() const
408  {
409  return (elementRef != 0);
410  }
411 
412  void operator=(const QAElement &other);
413  bool operator==(const QAElement &other) const;
414 private:
415  AXUIElementRef elementRef;
416 };
417 
418 
420 {
421 public:
422  virtual QAInterface interface(UInt64 identifier) = 0;
423  virtual QAElement element(int id) = 0;
424  virtual QAElement element(const QAInterface &interface)
425  {
426  return element(interface.id());
427  }
428  virtual void registerChildren() = 0;
429  virtual ~QInterfaceFactory() {}
430 };
431 
432 /*
433  QAccessibleHierarchyManager bridges the Mac and Qt accessibility hierarchies.
434  There is a one-to-one relationship between QAElements on the Mac side
435  and QAInterfaces on the Qt side, and this class provides lookup functions
436  that translates between these to items.
437 
438  The identity of a QAInterface is determined by its QAccessibleInterface and
439  child identifier, and the identity of a QAElement is determined by its
440  HIObjectRef and identifier.
441 
442  QAccessibleHierarchyManager receives QObject::destroyed() signals and deletes
443  the accessibility objects for destroyed objects.
444 */
446 {
447 Q_OBJECT
448 public:
450  static QAccessibleHierarchyManager *instance();
451  void reset();
452 
453  QAElement registerInterface(QObject *object, int child);
454  QAElement registerInterface(const QAInterface &interface);
455  void registerInterface(QObject *object, HIObjectRef hiobject, QInterfaceFactory *interfaceFactory);
456 
457  void registerChildren(const QAInterface &interface);
458 
459  QAInterface lookup(const AXUIElementRef &element);
460  QAInterface lookup(const QAElement &element);
461  QAElement lookup(const QAInterface &interface);
462  QAElement lookup(QObject * const object, int id);
463 private slots:
464  void objectDestroyed(QObject *);
465 private:
469 
470  QObjectElementHash qobjectElementHash;
471  HIObjectInterfaceHash hiobjectInterfaceHash;
472  QObjectHIObjectHash qobjectHiobjectHash;
473 };
474 
475 Q_AUTOTEST_EXPORT bool isItInteresting(const QAInterface &interface);
476 
478 
479 #endif
HIObjectRef hiObject() const
T qobject_cast(QObject *object)
Definition: qobject.h:375
The QDebug class provides an output stream for debugging information.
Definition: qdebug.h:62
int registerInterface(const QDeclarativePrivate::RegisterInterface &interface)
int indexOfChild(const QAInterface &child) const
void doAction(int action, const QVariantList &params=QVariantList()) const
QObjectElementHash qobjectElementHash
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QPointer< QWidget > widget
HIObjectRef object() const
Role
This enum defines the role of an accessible object.
Definition: qaccessible.h:188
Q_CORE_EXPORT QTextStream & reset(QTextStream &s)
bool isValid() const
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
virtual int childCount() const =0
Returns the number of children that belong to this object.
QAccessibleInterfaceWrapper(const QAccessibleInterfaceWrapper &other)
QAInterface childAt(int index) const
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
QAccessibleInterface * interface
QAInterface childAt(int x, int y) const
HIObjectInterfaceHash hiobjectInterfaceHash
bool operator!=(QBool b1, bool b2)
Definition: qglobal.h:2026
bool isValid() const
The QString class provides a Unicode character string.
Definition: qstring.h:83
virtual QObject * object() const =0
Returns a pointer to the QObject this interface implementation provides information for...
QHash< QObject *, HIObjectRef > QObjectHIObjectHash
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
static const uint base
Definition: qurl.cpp:268
QAInterface(QAccessibleInterfaceWrapper wrapper, int child=0)
QAInterface(const QAInterface &other, int child)
bool isHIView() const
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
QHash< QObject *, QInterfaceFactory * > QObjectElementHash
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
int id() const
QAInterface parent() const
RelationFlag
This enum type defines bit flags that can be combined to indicate the relationship between two access...
Definition: qaccessible.h:268
void setText(Text t, const QString &text) const
QObject * cachedObject() const
bool checkValid() const
QString name() const
QRect rect() const
QString value() const
QAInterface(QAccessibleInterface *interface, int child=0)
The State element defines configurations of objects and properties.
virtual ~QInterfaceFactory()
State state() const
int childCount() const
#define Q_OBJECT
Definition: qobjectdefs.h:157
AXUIElementRef element() const
QString actionText(int action, Text text) const
QHash< HIObjectRef, QInterfaceFactory * > HIObjectInterfaceHash
QObject * object() const
Role role() const
Q_CORE_EXPORT void qFatal(const char *,...)
Q_AUTOTEST_EXPORT bool isItInteresting(const QAInterface &interface)
virtual QAElement element(const QAInterface &interface)
int userActionCount() const
The QAccessibleInterface class defines an interface that exposes information about accessible objects...
Definition: qaccessible.h:370
int id() const
QList< QVariant > QVariantList
Definition: qvariant.h:443
struct OpaqueHIObjectRef * HIObjectRef
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
#define Q_AUTOTEST_EXPORT
Definition: qglobal.h:1510
quint16 index
QList< QAElement > lookup(const QList< QAInterface > &interfaces)
QAccessibleInterfaceWrapper(QAccessibleInterface *interface)
WId winId() const
Returns the window system identifier of the widget.
Definition: qwidget.cpp:2557
QAccessibleInterfaceWrapper interfaceWrapper() const
QAInterface objectInterface() const
QList< QAInterface > children() const
QObject * m_cachedObject
#define slots
Definition: qobjectdefs.h:68
AXUIElementRef elementRef
QString text(Text text) const
bool operator==(QBool b1, bool b2)
Definition: qglobal.h:2023
QString className() const
void operator=(const QAccessibleInterfaceWrapper &other)
QAccessibleInterfaceWrapper base
#define text
Definition: qobjectdefs.h:80
The QAccessible class provides enums and static functions relating to accessibility.
Definition: qaccessible.h:64
QObjectHIObjectHash qobjectHiobjectHash
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
The Text item allows you to add formatted text to a scene.
Q_AUTOTEST_EXPORT QDebug operator<<(QDebug debug, const QAInterface &interface)