Qt 4.8
qaccessible_mac.mm
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 #include "qaccessible.h"
43 
44 #ifndef QT_NO_ACCESSIBILITY
45 #include "qaccessible_mac_p.h"
46 #include "qhash.h"
47 #include "qset.h"
48 #include "qpointer.h"
49 #include "qapplication.h"
50 #include "qmainwindow.h"
51 #include "qtextdocument.h"
52 #include "qdebug.h"
53 #include "qabstractslider.h"
54 #include "qsplitter.h"
55 #include "qtabwidget.h"
56 #include "qlistview.h"
57 #include "qtableview.h"
58 #include "qdockwidget.h"
59 
60 #include <private/qt_mac_p.h>
61 #include <private/qwidget_p.h>
62 #include <CoreFoundation/CoreFoundation.h>
63 
65 
66 /*
67  Set up platform defines. There is a one-to-one correspondence between the
68  Carbon and Cocoa roles and attributes, but the prefix and type changes.
69 */
70 #ifdef QT_MAC_USE_COCOA
71 typedef NSString * const QAXRoleType;
72 #define QAXApplicationRole NSAccessibilityApplicationRole
73 #define QAXButtonRole NSAccessibilityButtonRole
74 #define QAXCancelAction NSAccessibilityCancelAction
75 #define QAXCheckBoxRole NSAccessibilityCheckBoxRole
76 #define QAXChildrenAttribute NSAccessibilityChildrenAttribute
77 #define QAXCloseButtonAttribute NSAccessibilityCloseButtonAttribute
78 #define QAXCloseButtonAttribute NSAccessibilityCloseButtonAttribute
79 #define QAXColumnRole NSAccessibilityColumnRole
80 #define QAXConfirmAction NSAccessibilityConfirmAction
81 #define QAXContentsAttribute NSAccessibilityContentsAttribute
82 #define QAXDecrementAction NSAccessibilityDecrementAction
83 #define QAXDecrementArrowSubrole NSAccessibilityDecrementArrowSubrole
84 #define QAXDecrementPageSubrole NSAccessibilityDecrementPageSubrole
85 #define QAXDescriptionAttribute NSAccessibilityDescriptionAttribute
86 #define QAXEnabledAttribute NSAccessibilityEnabledAttribute
87 #define QAXExpandedAttribute NSAccessibilityExpandedAttribute
88 #define QAXFocusedAttribute NSAccessibilityFocusedAttribute
89 #define QAXFocusedUIElementChangedNotification NSAccessibilityFocusedUIElementChangedNotification
90 #define QAXFocusedWindowChangedNotification NSAccessibilityFocusedWindowChangedNotification
91 #define QAXGroupRole NSAccessibilityGroupRole
92 #define QAXGrowAreaAttribute NSAccessibilityGrowAreaAttribute
93 #define QAXGrowAreaRole NSAccessibilityGrowAreaRole
94 #define QAXHelpAttribute NSAccessibilityHelpAttribute
95 #define QAXHorizontalOrientationValue NSAccessibilityHorizontalOrientationValue
96 #define QAXHorizontalScrollBarAttribute NSAccessibilityHorizontalScrollBarAttribute
97 #define QAXIncrementAction NSAccessibilityIncrementAction
98 #define QAXIncrementArrowSubrole NSAccessibilityIncrementArrowSubrole
99 #define QAXIncrementPageSubrole NSAccessibilityIncrementPageSubrole
100 #define QAXIncrementorRole NSAccessibilityIncrementorRole
101 #define QAXLinkedUIElementsAttribute NSAccessibilityLinkedUIElementsAttribute
102 #define QAXListRole NSAccessibilityListRole
103 #define QAXMainAttribute NSAccessibilityMainAttribute
104 #define QAXMaxValueAttribute NSAccessibilityMaxValueAttribute
105 #define QAXMenuBarRole NSAccessibilityMenuBarRole
106 #define QAXMenuButtonRole NSAccessibilityMenuButtonRole
107 #define QAXMenuClosedNotification NSAccessibilityMenuClosedNotification
108 #define QAXMenuItemRole NSAccessibilityMenuItemRole
109 #define QAXMenuOpenedNotification NSAccessibilityMenuOpenedNotification
110 #define QAXMenuRole NSAccessibilityMenuRole
111 #define QAXMinValueAttribute NSAccessibilityMinValueAttribute
112 #define QAXMinimizeButtonAttribute NSAccessibilityMinimizeButtonAttribute
113 #define QAXMinimizedAttribute NSAccessibilityMinimizedAttribute
114 #define QAXNextContentsAttribute NSAccessibilityNextContentsAttribute
115 #define QAXOrientationAttribute NSAccessibilityOrientationAttribute
116 #define QAXParentAttribute NSAccessibilityParentAttribute
117 #define QAXPickAction NSAccessibilityPickAction
118 #define QAXPopUpButtonRole NSAccessibilityPopUpButtonRole
119 #define QAXPositionAttribute NSAccessibilityPositionAttribute
120 #define QAXPressAction NSAccessibilityPressAction
121 #define QAXPreviousContentsAttribute NSAccessibilityPreviousContentsAttribute
122 #define QAXProgressIndicatorRole NSAccessibilityProgressIndicatorRole
123 #define QAXRadioButtonRole NSAccessibilityRadioButtonRole
124 #define QAXRoleAttribute NSAccessibilityRoleAttribute
125 #define QAXRoleDescriptionAttribute NSAccessibilityRoleDescriptionAttribute
126 #define QAXRowRole NSAccessibilityRowRole
127 #define QAXRowsAttribute NSAccessibilityRowsAttribute
128 #define QAXScrollAreaRole NSAccessibilityScrollAreaRole
129 #define QAXScrollBarRole NSAccessibilityScrollBarRole
130 #define QAXSelectedAttribute NSAccessibilitySelectedAttribute
131 #define QAXSelectedChildrenAttribute NSAccessibilitySelectedChildrenAttribute
132 #define QAXSelectedRowsAttribute NSAccessibilitySelectedRowsAttribute
133 #define QAXSizeAttribute NSAccessibilitySizeAttribute
134 #define QAXSliderRole NSAccessibilitySliderRole
135 #define QAXSplitGroupRole NSAccessibilitySplitGroupRole
136 #define QAXSplitterRole NSAccessibilitySplitterRole
137 #define QAXSplittersAttribute NSAccessibilitySplittersAttribute
138 #define QAXStaticTextRole NSAccessibilityStaticTextRole
139 #define QAXSubroleAttribute NSAccessibilitySubroleAttribute
140 #define QAXSubroleAttribute NSAccessibilitySubroleAttribute
141 #define QAXTabGroupRole NSAccessibilityTabGroupRole
142 #define QAXTableRole NSAccessibilityTableRole
143 #define QAXTabsAttribute NSAccessibilityTabsAttribute
144 #define QAXTextFieldRole NSAccessibilityTextFieldRole
145 #define QAXTitleAttribute NSAccessibilityTitleAttribute
146 #define QAXTitleUIElementAttribute NSAccessibilityTitleUIElementAttribute
147 #define QAXToolbarButtonAttribute NSAccessibilityToolbarButtonAttribute
148 #define QAXToolbarRole NSAccessibilityToolbarRole
149 #define QAXTopLevelUIElementAttribute NSAccessibilityTopLevelUIElementAttribute
150 #define QAXUnknownRole NSAccessibilityUnknownRole
151 #define QAXValueAttribute NSAccessibilityValueAttribute
152 #define QAXValueChangedNotification NSAccessibilityValueChangedNotification
153 #define QAXValueIndicatorRole NSAccessibilityValueIndicatorRole
154 #define QAXVerticalOrientationValue NSAccessibilityVerticalOrientationValue
155 #define QAXVerticalScrollBarAttribute NSAccessibilityVerticalScrollBarAttribute
156 #define QAXVisibleRowsAttribute NSAccessibilityVisibleRowsAttribute
157 #define QAXWindowAttribute NSAccessibilityWindowAttribute
158 #define QAXWindowCreatedNotification NSAccessibilityWindowCreatedNotification
159 #define QAXWindowMovedNotification NSAccessibilityWindowMovedNotification
160 #define QAXWindowRole NSAccessibilityWindowRole
161 #define QAXZoomButtonAttribute NSAccessibilityZoomButtonAttribute
162 #else
163 typedef CFStringRef const QAXRoleType;
164 #define QAXApplicationRole kAXApplicationRole
165 #define QAXButtonRole kAXButtonRole
166 #define QAXCancelAction kAXCancelAction
167 #define QAXCheckBoxRole kAXCheckBoxRole
168 #define QAXChildrenAttribute kAXChildrenAttribute
169 #define QAXCloseButtonAttribute kAXCloseButtonAttribute
170 #define QAXColumnRole kAXColumnRole
171 #define QAXConfirmAction kAXConfirmAction
172 #define QAXContentsAttribute kAXContentsAttribute
173 #define QAXDecrementAction kAXDecrementAction
174 #define QAXDecrementArrowSubrole kAXDecrementArrowSubrole
175 #define QAXDecrementPageSubrole kAXDecrementPageSubrole
176 #define QAXDescriptionAttribute kAXDescriptionAttribute
177 #define QAXEnabledAttribute kAXEnabledAttribute
178 #define QAXExpandedAttribute kAXExpandedAttribute
179 #define QAXFocusedAttribute kAXFocusedAttribute
180 #define QAXFocusedUIElementChangedNotification kAXFocusedUIElementChangedNotification
181 #define QAXFocusedWindowChangedNotification kAXFocusedWindowChangedNotification
182 #define QAXGroupRole kAXGroupRole
183 #define QAXGrowAreaAttribute kAXGrowAreaAttribute
184 #define QAXGrowAreaRole kAXGrowAreaRole
185 #define QAXHelpAttribute kAXHelpAttribute
186 #define QAXHorizontalOrientationValue kAXHorizontalOrientationValue
187 #define QAXHorizontalScrollBarAttribute kAXHorizontalScrollBarAttribute
188 #define QAXIncrementAction kAXIncrementAction
189 #define QAXIncrementArrowSubrole kAXIncrementArrowSubrole
190 #define QAXIncrementPageSubrole kAXIncrementPageSubrole
191 #define QAXIncrementorRole kAXIncrementorRole
192 #define QAXLinkedUIElementsAttribute kAXLinkedUIElementsAttribute
193 #define QAXListRole kAXListRole
194 #define QAXMainAttribute kAXMainAttribute
195 #define QAXMaxValueAttribute kAXMaxValueAttribute
196 #define QAXMenuBarRole kAXMenuBarRole
197 #define QAXMenuButtonRole kAXMenuButtonRole
198 #define QAXMenuClosedNotification kAXMenuClosedNotification
199 #define QAXMenuItemRole kAXMenuItemRole
200 #define QAXMenuOpenedNotification kAXMenuOpenedNotification
201 #define QAXMenuRole kAXMenuRole
202 #define QAXMinValueAttribute kAXMinValueAttribute
203 #define QAXMinimizeButtonAttribute kAXMinimizeButtonAttribute
204 #define QAXMinimizedAttribute kAXMinimizedAttribute
205 #define QAXNextContentsAttribute kAXNextContentsAttribute
206 #define QAXOrientationAttribute kAXOrientationAttribute
207 #define QAXParentAttribute kAXParentAttribute
208 #define QAXPickAction kAXPickAction
209 #define QAXPopUpButtonRole kAXPopUpButtonRole
210 #define QAXPositionAttribute kAXPositionAttribute
211 #define QAXPressAction kAXPressAction
212 #define QAXPreviousContentsAttribute kAXPreviousContentsAttribute
213 #define QAXProgressIndicatorRole kAXProgressIndicatorRole
214 #define QAXRadioButtonRole kAXRadioButtonRole
215 #define QAXRoleAttribute kAXRoleAttribute
216 #define QAXRoleDescriptionAttribute kAXRoleDescriptionAttribute
217 #define QAXRowRole kAXRowRole
218 #define QAXRowsAttribute kAXRowsAttribute
219 #define QAXScrollAreaRole kAXScrollAreaRole
220 #define QAXScrollBarRole kAXScrollBarRole
221 #define QAXSelectedAttribute kAXSelectedAttribute
222 #define QAXSelectedChildrenAttribute kAXSelectedChildrenAttribute
223 #define QAXSelectedRowsAttribute kAXSelectedRowsAttribute
224 #define QAXSizeAttribute kAXSizeAttribute
225 #define QAXSliderRole kAXSliderRole
226 #define QAXSplitGroupRole kAXSplitGroupRole
227 #define QAXSplitterRole kAXSplitterRole
228 #define QAXSplittersAttribute kAXSplittersAttribute
229 #define QAXStaticTextRole kAXStaticTextRole
230 #define QAXSubroleAttribute kAXSubroleAttribute
231 #define QAXTabGroupRole kAXTabGroupRole
232 #define QAXTableRole kAXTableRole
233 #define QAXTabsAttribute kAXTabsAttribute
234 #define QAXTextFieldRole kAXTextFieldRole
235 #define QAXTitleAttribute kAXTitleAttribute
236 #define QAXTitleUIElementAttribute kAXTitleUIElementAttribute
237 #define QAXToolbarButtonAttribute kAXToolbarButtonAttribute
238 #define QAXToolbarRole kAXToolbarRole
239 #define QAXTopLevelUIElementAttribute kAXTopLevelUIElementAttribute
240 #define QAXUnknownRole kAXUnknownRole
241 #define QAXValueAttribute kAXValueAttribute
242 #define QAXValueChangedNotification kAXValueChangedNotification
243 #define QAXValueIndicatorRole kAXValueIndicatorRole
244 #define QAXVerticalOrientationValue kAXVerticalOrientationValue
245 #define QAXVerticalScrollBarAttribute kAXVerticalScrollBarAttribute
246 #define QAXVisibleRowsAttribute kAXVisibleRowsAttribute
247 #define QAXWindowAttribute kAXWindowAttribute
248 #define QAXWindowCreatedNotification kAXWindowCreatedNotification
249 #define QAXWindowMovedNotification kAXWindowMovedNotification
250 #define QAXWindowRole kAXWindowRole
251 #define QAXZoomButtonAttribute kAXZoomButtonAttribute
252 #endif
253 
254 
255 /*****************************************************************************
256  Externals
257  *****************************************************************************/
258 extern bool qt_mac_is_macsheet(const QWidget *w); //qwidget_mac.cpp
259 extern bool qt_mac_is_macdrawer(const QWidget *w); //qwidget_mac.cpp
260 
261 /*****************************************************************************
262  QAccessible Bindings
263  *****************************************************************************/
264 //hardcoded bindings between control info and (known) QWidgets
266  int qt;
268  bool settable;
269 } text_bindings[][10] = {
271  { -1, 0, false }
272  },
273  { { QAccessible::MenuBar, QAXMenuBarRole, false },
274  { -1, 0, false }
275  },
277  { -1, 0, false }
278  },
279  { { QAccessible::Grip, QAXGrowAreaRole, false },
280  { -1, 0, false }
281  },
282  { { QAccessible::Window, QAXWindowRole, false },
283  { -1, 0, false }
284  },
285  { { QAccessible::Dialog, QAXWindowRole, false },
286  { -1, 0, false }
287  },
289  { -1, 0, false }
290  },
291  { { QAccessible::ToolTip, QAXWindowRole, false },
292  { -1, 0, false }
293  },
295  { -1, 0, false }
296  },
297  { { QAccessible::PopupMenu, QAXMenuRole, false },
298  { -1, 0, false }
299  },
301  { -1, 0, false }
302  },
303  { { QAccessible::Pane, QAXGroupRole, false },
304  { -1, 0, false }
305  },
306  { { QAccessible::Grouping, QAXGroupRole, false },
307  { -1, 0, false }
308  },
310  { -1, 0, false }
311  },
312  { { QAccessible::ToolBar, QAXToolbarRole, false },
313  { -1, 0, false }
314  },
316  { -1, 0, false }
317  },
319  { -1, 0, false }
320  },
322  { -1, 0, false }
323  },
325  { -1, 0, false }
326  },
327  { { QAccessible::Slider, QAXSliderRole, false },
328  { -1, 0, false }
329  },
331  { -1, 0, false }
332  },
334  { -1, 0, false }
335  },
337  { -1, 0, false }
338  },
340  { -1, 0, false }
341  },
344  { -1, 0, false }
345  },
346  { { QAccessible::Table, QAXTableRole, false },
347  { -1, 0, false }
348  },
350  { -1, 0, false }
351  },
352  { { QAccessible::Column, QAXColumnRole, false },
353  { -1, 0, false }
354  },
356  { -1, 0, false }
357  },
358  { { QAccessible::Row, QAXRowRole, false },
359  { -1, 0, false }
360  },
361  { { QAccessible::RowHeader, QAXRowRole, false },
362  { -1, 0, false }
363  },
364  { { QAccessible::Cell, QAXTextFieldRole, false },
365  { -1, 0, false }
366  },
368  { -1, 0, false }
369  },
371  { -1, 0, false }
372  },
373  { { QAccessible::Link, QAXTextFieldRole, false },
374  { -1, 0, false }
375  },
377  { -1, 0, false }
378  },
380  { -1, 0, false }
381  },
382  { { QAccessible::List, QAXListRole, false },
383  { -1, 0, false }
384  },
386  { -1, 0, false }
387  },
388  { { QAccessible::Cell, QAXStaticTextRole, false },
389  { -1, 0, false }
390  },
391  { { -1, 0, false } }
392 };
393 
394 class QAInterface;
395 static CFStringRef macRole(const QAInterface &interface);
396 
397 QDebug operator<<(QDebug debug, const QAInterface &interface)
398 {
399  if (interface.isValid() == false)
400  debug << "invalid interface";
401  else
402  debug << interface.object() << "id" << interface.id() << "role" << hex << interface.role();
403  return debug;
404 }
405 
406 // The root of the Qt accessible hiearchy.
407 static QObject *rootObject = 0;
408 
409 
410 bool QAInterface::operator==(const QAInterface &other) const
411 {
412  if (isValid() == false || other.isValid() == false)
413  return (isValid() && other.isValid());
414 
415  // walk up the parent chain, comparing child indexes, until we reach
416  // an interface that has a QObject.
417  QAInterface currentThis = *this;
418  QAInterface currentOther = other;
419 
420  while (currentThis.object() == 0) {
421  if (currentOther.object() != 0)
422  return false;
423 
424  // fail if the child indexes in the two hirearchies don't match.
425  if (currentThis.parent().indexOfChild(currentThis) !=
426  currentOther.parent().indexOfChild(currentOther))
427  return false;
428 
429  currentThis = currentThis.parent();
430  currentOther = currentOther.parent();
431  }
432 
433  return (currentThis.object() == currentOther.object() && currentThis.id() == currentOther.id());
434 }
435 
436 bool QAInterface::operator!=(const QAInterface &other) const
437 {
438  return !operator==(other);
439 }
440 
441 uint qHash(const QAInterface &item)
442 {
443  if (item.isValid())
444  return qHash(item.object()) + qHash(item.id());
445  else
446  return qHash(item.cachedObject()) + qHash(item.id());
447 }
448 
450 {
451  if (!checkValid())
452  return QAInterface();
453 
454  // On a QAccessibleInterface that handles its own children we can short-circut
455  // the navigation if this QAInterface refers to one of the children:
456  if (child != 0) {
457  // The Ancestor interface will always be the same QAccessibleInterface with
458  // a child value of 0.
459  if (relation == QAccessible::Ancestor)
460  return QAInterface(*this, 0);
461 
462  // The child hiearchy is only one level deep, so navigating to a child
463  // of a child is not possible.
464  if (relation == QAccessible::Child) {
465  return QAInterface();
466  }
467  }
468  QAccessibleInterface *child_iface = 0;
469 
470  const int status = base.interface->navigate(relation, entry, &child_iface);
471 
472  if (status == -1)
473  return QAInterface(); // not found;
474 
475  // Check if target is a child of this interface.
476  if (!child_iface) {
477  return QAInterface(*this, status);
478  } else {
479  // Target is child_iface or a child of that (status decides).
480  return QAInterface(child_iface, status);
481  }
482 }
483 
485 :elementRef(0)
486 {}
487 
489 :elementRef(elementRef)
490 {
491  if (elementRef != 0) {
492  CFRetain(elementRef);
493  CFRetain(object());
494  }
495 }
496 
498 :elementRef(element.elementRef)
499 {
500  if (elementRef != 0) {
501  CFRetain(elementRef);
502  CFRetain(object());
503  }
504 }
505 
507 {
508 #ifndef QT_MAC_USE_COCOA
509  if (object == 0) {
510  elementRef = 0; // Create invalid QAElement.
511  } else {
512  elementRef = AXUIElementCreateWithHIObjectAndIdentifier(object, child);
513  CFRetain(object);
514  }
515 #else
516  Q_UNUSED(object);
517  Q_UNUSED(child);
518 #endif
519 }
520 
522 {
523  if (elementRef != 0) {
524  CFRelease(object());
525  CFRelease(elementRef);
526  }
527 }
528 
529 void QAElement::operator=(const QAElement &other)
530 {
531  if (*this == other)
532  return;
533 
534  if (elementRef != 0) {
535  CFRelease(object());
536  CFRelease(elementRef);
537  }
538 
539  elementRef = other.elementRef;
540 
541  if (elementRef != 0) {
542  CFRetain(elementRef);
543  CFRetain(object());
544  }
545 }
546 
547 bool QAElement::operator==(const QAElement &other) const
548 {
549  if (elementRef == 0 || other.elementRef == 0)
550  return (elementRef == other.elementRef);
551 
552  return CFEqual(elementRef, other.elementRef);
553 }
554 
556 {
557  return qHash(element.object()) + qHash(element.id());
558 }
559 
560 #ifndef QT_MAC_USE_COCOA
561 static QInterfaceFactory *createFactory(const QAInterface &interface);
562 #endif
563 Q_GLOBAL_STATIC(QAccessibleHierarchyManager, accessibleHierarchyManager);
564 
565 /*
566  Reomves all accessibility info accosiated with the sender object.
567 */
569 {
570  HIObjectRef hiObject = qobjectHiobjectHash.value(object);
571  delete qobjectElementHash.value(object);
572  qobjectElementHash.remove(object);
573  hiobjectInterfaceHash.remove(hiObject);
574 }
575 
576 /*
577  Removes all stored items.
578 */
580 {
581  qDeleteAll(qobjectElementHash);
582  qobjectElementHash.clear();
583  hiobjectInterfaceHash.clear();
584  qobjectHiobjectHash.clear();
585 }
586 
588 {
589  return accessibleHierarchyManager();
590 }
591 
592 #ifndef QT_MAC_USE_COCOA
593 static bool isItemView(const QAInterface &interface)
594 {
595  QObject *object = interface.object();
596  return (interface.role() == QAccessible::List || interface.role() == QAccessible::Table
597  || (object && qobject_cast<QAbstractItemView *>(interface.object()))
598  || (object && object->objectName() == QLatin1String("qt_scrollarea_viewport")
599  && qobject_cast<QAbstractItemView *>(object->parent())));
600 }
601 #endif
602 
603 static bool isTabWidget(const QAInterface &interface)
604 {
605  if (QObject *object = interface.object())
606  return (object->inherits("QTabWidget") && interface.id() == 0);
607  return false;
608 }
609 
610 static bool isStandaloneTabBar(const QAInterface &interface)
611 {
612  QObject *object = interface.object();
613  if (interface.role() == QAccessible::PageTabList && object)
614  return (qobject_cast<QTabWidget *>(object->parent()) == 0);
615 
616  return false;
617 }
618 
619 static bool isEmbeddedTabBar(const QAInterface &interface)
620 {
621  QObject *object = interface.object();
622  if (interface.role() == QAccessible::PageTabList && object)
623  return (qobject_cast<QTabWidget *>(object->parent()));
624 
625  return false;
626 }
627 
628 /*
629  Decides if a QAInterface is interesting from an accessibility users point of view.
630 */
631 bool isItInteresting(const QAInterface &interface)
632 {
633  // Mac accessibility does not have an attribute that corresponds to the Invisible/Offscreen
634  // state, so we disable the interface here.
635  const QAccessible::State state = interface.state();
636  if (state & QAccessible::Invisible ||
637  state & QAccessible::Offscreen )
638  return false;
639 
640  const QAccessible::Role role = interface.role();
641 
642  if (QObject * const object = interface.object()) {
643  const QString className = QLatin1String(object->metaObject()->className());
644 
645  // VoiceOver focusing on tool tips can be confusing. The contents of the
646  // tool tip is avalible through the description attribute anyway, so
647  // we disable accessibility for tool tips.
648  if (className == QLatin1String("QTipLabel"))
649  return false;
650 
651  // Hide TabBars that has a QTabWidget parent (the tab widget handles the accessibility)
652  if (isEmbeddedTabBar(interface))
653  return false;
654 
655  // Hide docked dockwidgets. ### causes infinitie loop in the apple accessibility code.
656  /* if (QDockWidget *dockWidget = qobject_cast<QDockWidget *>(object)) {
657  if (dockWidget->isFloating() == false)
658  return false;
659  }
660  */
661  }
662 
663  // Client is a generic role returned by plain QWidgets or other
664  // widgets that does not have separate QAccessible interface, such
665  // as the TabWidget. Return false unless macRole gives the interface
666  // a special role.
667  if (role == QAccessible::Client && macRole(interface) == CFStringRef(QAXUnknownRole))
668  return false;
669 
670  // Some roles are not interesting:
671  if (role == QAccessible::Border || // QFrame
672  role == QAccessible::Application || // We use the system-provided application element.
673  role == QAccessible::MenuItem) // The system also provides the menu items.
674  return false;
675 
676  // It is probably better to access the toolbar buttons directly than having
677  // to navigate through the toolbar.
678  if (role == QAccessible::ToolBar)
679  return false;
680 
681  return true;
682 }
683 
685 {
686 #ifndef QT_MAC_USE_COCOA
688 #else
689  Q_UNUSED(object);
690  Q_UNUSED(child);
691  return QAElement();
692 #endif
693 }
694 
695 /*
696  Creates a QAXUIelement that corresponds to the given QAInterface.
697 */
699 {
700 #ifndef QT_MAC_USE_COCOA
701  if (interface.isValid() == false)
702  return QAElement();
704 
705  QObject * qobject = objectInterface.object();
706  HIObjectRef hiobject = objectInterface.hiObject();
707  if (qobject == 0 || hiobject == 0)
708  return QAElement();
709 
710  if (qobjectElementHash.contains(qobject) == false) {
711  registerInterface(qobject, hiobject, createFactory(interface));
712  HIObjectSetAccessibilityIgnored(hiobject, !isItInteresting(interface));
713  }
714 
715  return QAElement(hiobject, interface.id());
716 #else
717  Q_UNUSED(interface);
718  return QAElement();
719 #endif
720 }
721 
722 #ifndef QT_MAC_USE_COCOA
724 #endif
725 
727 {
728 #ifndef QT_MAC_USE_COCOA
729  if (qobjectElementHash.contains(qobject) == false) {
730  qobjectElementHash.insert(qobject, interfaceFactory);
731  qobjectHiobjectHash.insert(qobject, hiobject);
732  connect(qobject, SIGNAL(destroyed(QObject *)), SLOT(objectDestroyed(QObject *)));
733  }
734 
735  if (hiobjectInterfaceHash.contains(hiobject) == false) {
736  hiobjectInterfaceHash.insert(hiobject, interfaceFactory);
738  }
739 #else
740  Q_UNUSED(qobject);
741  Q_UNUSED(hiobject);
742  Q_UNUSED(interfaceFactory);
743 #endif
744 }
745 
747 {
748  QObject * const object = interface.object();
749  if (object == 0)
750  return;
751 
752  QInterfaceFactory *interfaceFactory = qobjectElementHash.value(object);
753 
754  if (interfaceFactory == 0)
755  return;
756 
757  interfaceFactory->registerChildren();
758 }
759 
761 {
762  if (element == 0)
763  return QAInterface();
764 #ifndef QT_MAC_USE_COCOA
765  HIObjectRef hiObject = AXUIElementGetHIObject(element);
766 
767  QInterfaceFactory *factory = hiobjectInterfaceHash.value(hiObject);
768  if (factory == 0) {
769  return QAInterface();
770  }
771 
772  UInt64 id;
773  AXUIElementGetIdentifier(element, &id);
774  return factory->interface(id);
775 #else
776  return QAInterface();
777 #endif
778 }
779 
781 {
782  return lookup(element.element());
783 }
784 
786 {
787  if (interface.isValid() == false)
788  return QAElement();
789 
790  QInterfaceFactory *factory = qobjectElementHash.value(interface.objectInterface().object());
791  if (factory == 0)
792  return QAElement();
793 
794  return factory->element(interface);
795 }
796 
798 {
799  QInterfaceFactory *factory = qobjectElementHash.value(object);
800  if (factory == 0)
801  return QAElement();
802 
803  return factory->element(id);
804 }
805 
806 /*
807  Standard interface mapping, return the stored interface
808  or HIObjectRef, and there is an one-to-one mapping between
809  the identifier and child.
810 */
812 {
813 public:
815  : m_interface(interface), object(interface.hiObject())
816  {
817  CFRetain(object);
818  }
819 
821  {
822  CFRelease(object);
823  }
824 
825 
826  QAInterface interface(UInt64 identifier)
827  {
828  const int child = identifier;
829  return QAInterface(m_interface, child);
830  }
831 
833  {
834  return QAElement(object, id);
835  }
836 
837  QAElement element(const QAInterface &interface)
838  {
839  if (interface.object() == 0)
840  return QAElement();
841  return QAElement(object, interface.id());
842  }
843 
845  {
846  const int childCount = m_interface.childCount();
847  for (int i = 1; i <= childCount; ++i) {
848  accessibleHierarchyManager()->registerInterface(m_interface.navigate(QAccessible::Child, i));
849  }
850  }
851 
852 private:
855 };
856 
857 /*
858  Interface mapping where that creates one HIObject for each interface child.
859 */
861 {
862 public:
864  : m_interface(interface)
865  { }
866 
868  {
869  foreach (HIObjectRef object, objects) {
870  CFRelease(object);
871  }
872  }
873 
874  QAInterface interface(UInt64 identifier)
875  {
876  const int child = identifier;
877  return QAInterface(m_interface, child);
878  }
879 
880  QAElement element(int child)
881  {
882  if (child == 0)
883  return QAElement(m_interface.hiObject(), 0);
884 
885  if (child > objects.count())
886  return QAElement();
887 
888  return QAElement(objects.at(child - 1), child);
889  }
890 
892  {
893 #ifndef QT_MAC_USE_COCOA
894  const int childCount = m_interface.childCount();
895  for (int i = 1; i <= childCount; ++i) {
896  HIObjectRef hiobject;
897  HIObjectCreate(kObjectQtAccessibility, 0, &hiobject);
898  objects.append(hiobject);
899  accessibleHierarchyManager()->registerInterface(m_interface.object(), hiobject, this);
900  HIObjectSetAccessibilityIgnored(hiobject, !isItInteresting(m_interface.navigate(QAccessible::Child, i)));
901  }
902 #endif
903  }
904 
905 private:
908 };
909 
911 {
912 public:
914  : m_interface(interface), object(interface.hiObject())
915  {
916  CFRetain(object);
917  columnCount = 0;
918  if (QTableView * tableView = qobject_cast<QTableView *>(interface.parent().object())) {
919  if (tableView->model())
920  columnCount = tableView->model()->columnCount();
921  if (tableView->verticalHeader())
922  ++columnCount;
923  }
924  }
925 
927  {
928  CFRelease(object);
929  }
930 
931  QAInterface interface(UInt64 identifier)
932  {
933  if (identifier == 0)
934  return m_interface;
935 
936  if (m_interface.role() == QAccessible::List)
937  return m_interface.childAt(identifier);
938 
939  if (m_interface.role() == QAccessible::Table) {
940  const int index = identifier;
941  if (index == 0)
942  return m_interface; // return the item view interface.
943 
944  const int rowIndex = (index - 1) / (columnCount + 1);
945  const int cellIndex = (index - 1) % (columnCount + 1);
946 /*
947  qDebug() << "index" << index;
948  qDebug() << "rowIndex" << rowIndex;
949  qDebug() << "cellIndex" << cellIndex;
950 */
951  const QAInterface rowInterface = m_interface.childAt(rowIndex + 1);
952 
953  if ((cellIndex) == 0) // Is it a row?
954  return rowInterface;
955  else {
956  return rowInterface.childAt(cellIndex);
957  }
958  }
959 
960  return QAInterface();
961  }
962 
964  {
965  if (id != 0) {
966  return QAElement();
967  }
968  return QAElement(object, 0);
969  }
970 
971  QAElement element(const QAInterface &interface)
972  {
973  if (interface.object() && interface.object() == m_interface.object()) {
974  return QAElement(object, 0);
975  } else if (m_interface.role() == QAccessible::List) {
976  if (interface.parent().object() && interface.parent().object() == m_interface.object())
977  return QAElement(object, m_interface.indexOfChild(interface));
978  } else if (m_interface.role() == QAccessible::Table) {
979  QAInterface currentInterface = interface;
980  int index = 0;
981 
982  while (currentInterface.isValid() && currentInterface.object() == 0) {
983  const QAInterface parentInterface = currentInterface.parent();
984 /*
985  qDebug() << "current index" << index;
986  qDebug() << "current interface" << interface;
987 
988  qDebug() << "parent interface" << parentInterface;
989  qDebug() << "grandparent interface" << parentInterface.parent();
990  qDebug() << "childCount" << interface.childCount();
991  qDebug() << "index of child" << parentInterface.indexOfChild(currentInterface);
992 */
993  index += ((parentInterface.indexOfChild(currentInterface) - 1) * (currentInterface.childCount() + 1)) + 1;
994  currentInterface = parentInterface;
995 // qDebug() << "new current interface" << currentInterface;
996  }
997  if (currentInterface.object() == m_interface.object())
998  return QAElement(object, index);
999 
1000 
1001  }
1002  return QAElement();
1003  }
1004 
1006  {
1007  // Item view child interfraces don't have their own qobjects, so there is nothing to register here.
1008  }
1009 
1010 private:
1013  int columnCount; // for table views;
1014 };
1015 
1016 #ifndef QT_MAC_USE_COCOA
1017 static bool managesChildren(const QAInterface &interface)
1018 {
1019  return (interface.childCount() > 0 && interface.childAt(1).id() > 0);
1020 }
1021 
1023 {
1024  if (isItemView(interface)) {
1025  return new QItemViewInterfaceFactory(interface);
1026  } if (managesChildren(interface)) {
1027  return new QMultipleHIObjectFactory(interface);
1028  }
1029 
1030  return new QStandardInterfaceFactory(interface);
1031 }
1032 #endif
1033 
1035 {
1037  foreach (const QAInterface &interface, interfaces)
1038  if (interface.isValid()) {
1039  const QAElement element = accessibleHierarchyManager()->lookup(interface);
1040  if (element.isValid())
1041  elements.append(element);
1042  }
1043  return elements;
1044 }
1045 
1046 // Debug output helpers:
1047 /*
1048 static QString nameForEventKind(UInt32 kind)
1049 {
1050  switch(kind) {
1051  case kEventAccessibleGetChildAtPoint: return QString("GetChildAtPoint"); break;
1052  case kEventAccessibleGetAllAttributeNames: return QString("GetAllAttributeNames"); break;
1053  case kEventAccessibleGetNamedAttribute: return QString("GetNamedAttribute"); break;
1054  case kEventAccessibleSetNamedAttribute: return QString("SetNamedAttribute"); break;
1055  case kEventAccessibleGetAllActionNames: return QString("GetAllActionNames"); break;
1056  case kEventAccessibleGetFocusedChild: return QString("GetFocusedChild"); break;
1057  default:
1058  return QString("Unknown accessibility event type: %1").arg(kind);
1059  break;
1060  };
1061 }
1062 */
1063 #ifndef QT_MAC_USE_COCOA
1064 static bool qt_mac_append_cf_uniq(CFMutableArrayRef array, CFTypeRef value)
1065 {
1066  if (value == 0)
1067  return false;
1068 
1069  CFRange range;
1070  range.location = 0;
1071  range.length = CFArrayGetCount(array);
1072  if(!CFArrayContainsValue(array, range, value)) {
1073  CFArrayAppendValue(array, value);
1074  return true;
1075  }
1076  return false;
1077 }
1078 
1080 {
1081  CFMutableArrayRef array = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
1082  foreach (const QAElement &element, elements) {
1083  if (element.isValid())
1084  CFArrayAppendValue(array, element.element());
1085  }
1086 
1087  const OSStatus err = SetEventParameter(event, kEventParamAccessibleAttributeValue,
1088  typeCFTypeRef, sizeof(array), &array);
1089  CFRelease(array);
1090  return err;
1091 }
1092 #endif //QT_MAC_USE_COCOA
1093 
1094 /*
1095  Gets the AccessibleObject parameter from an event.
1096 */
1097 static inline AXUIElementRef getAccessibleObjectParameter(EventRef event)
1098 {
1099  AXUIElementRef element;
1100  GetEventParameter(event, kEventParamAccessibleObject, typeCFTypeRef, 0,
1101  sizeof(element), 0, &element);
1102  return element;
1103 }
1104 
1105 /*
1106  The application event handler makes sure that all top-level qt windows are registered
1107  before any accessibility events are handeled.
1108 */
1109 #ifndef QT_MAC_USE_COCOA
1111 {
1112  QAInterface rootInterface(QAccessible::queryAccessibleInterface(rootObject ? rootObject : qApp), 0);
1113  accessibleHierarchyManager()->registerChildren(rootInterface);
1114 
1115  return CallNextEventHandler(next_ref, event);
1116 }
1117 
1118 /*
1119  Returns the value for element by combining the QAccessibility::Checked and
1120  QAccessibility::Mixed flags into an int value that the Mac accessibilty
1121  system understands. This works for check boxes, radio buttons, and the like.
1122  The return values are:
1123  0: unchecked
1124  1: checked
1125  2: undecided
1126 */
1128 {
1129  const QAccessible::State state = element.state();
1130  if (state & QAccessible::Mixed)
1131  return 2;
1132  else if(state & QAccessible::Checked)
1133  return 1;
1134  else
1135  return 0;
1136 }
1137 
1138 static QString getValue(const QAInterface &interface)
1139 {
1140  const QAccessible::Role role = interface.role();
1141  if (role == QAccessible::RadioButton || role == QAccessible::CheckBox)
1142  return QString::number(buttonValue(interface));
1143  else
1144  return interface.text(QAccessible::Value);
1145 }
1146 #endif //QT_MAC_USE_COCOA
1147 
1148 /*
1149  Translates a QAccessible::Role into a mac accessibility role.
1150 */
1151 static CFStringRef macRole(const QAInterface &interface)
1152 {
1153  const QAccessible::Role qtRole = interface.role();
1154 
1155 // qDebug() << "role for" << interface.object() << "interface role" << hex << qtRole;
1156 
1157  // Qt accessibility: QAccessible::Splitter contains QAccessible::Grip.
1158  // Mac accessibility: AXSplitGroup contains AXSplitter.
1159  if (qtRole == QAccessible::Grip) {
1160  const QAInterface parent = interface.parent();
1161  if (parent.isValid() && parent.role() == QAccessible::Splitter)
1162  return CFStringRef(QAXSplitterRole);
1163  }
1164 
1165  // Tab widgets and standalone tab bars get the kAXTabGroupRole. Accessibility
1166  // for tab bars emebedded in a tab widget is handled by the tab widget.
1167  if (isTabWidget(interface) || isStandaloneTabBar(interface))
1168  return kAXTabGroupRole;
1169 
1170  if (QObject *object = interface.object()) {
1171  // ### The interface for an abstract scroll area returns the generic "Client"
1172  // role, so we have to to an extra detect on the QObject here.
1173  if (object->inherits("QAbstractScrollArea") && interface.id() == 0)
1175 
1176  if (object->inherits("QDockWidget"))
1177  return CFStringRef(QAXUnknownRole);
1178  }
1179 
1180  int i = 0;
1181  int testRole = text_bindings[i][0].qt;
1182  while (testRole != -1) {
1183  if (testRole == qtRole)
1184  return CFStringRef(text_bindings[i][0].mac);
1185  ++i;
1186  testRole = text_bindings[i][0].qt;
1187  }
1188 
1189 // qDebug() << "got unknown role!" << interface << interface.parent();
1190 
1191  return CFStringRef(QAXUnknownRole);
1192 }
1193 
1194 /*
1195  Translates a QAccessible::Role and an attribute name into a QAccessible::Text, taking into
1196  account execptions listed in text_bindings.
1197 */
1198 #ifndef QT_MAC_USE_COCOA
1200 {
1201  // Search for exception, return it if found.
1202  int testRole = text_bindings[0][0].qt;
1203  int i = 0;
1204  while (testRole != -1) {
1205  if (testRole == role) {
1206  int j = 1;
1207  int qtRole = text_bindings[i][j].qt;
1208  CFStringRef testAttribute = CFStringRef(text_bindings[i][j].mac);
1209  while (qtRole != -1) {
1210  if (CFStringCompare(attribute, testAttribute, 0) == kCFCompareEqualTo) {
1211  return (QAccessible::Text)qtRole;
1212  }
1213  ++j;
1214  testAttribute = CFStringRef(text_bindings[i][j].mac);
1215  qtRole = text_bindings[i][j].qt;
1216  }
1217  break;
1218  }
1219  ++i;
1220  testRole = text_bindings[i][0].qt;
1221  }
1222 
1223  // Return default mappping
1224  if (CFStringCompare(attribute, CFStringRef(QAXTitleAttribute), 0) == kCFCompareEqualTo)
1225  return QAccessible::Name;
1226  else if (CFStringCompare(attribute, CFStringRef(QAXValueAttribute), 0) == kCFCompareEqualTo)
1227  return QAccessible::Value;
1228  else if (CFStringCompare(attribute, CFStringRef(QAXHelpAttribute), 0) == kCFCompareEqualTo)
1229  return QAccessible::Help;
1230  else if (CFStringCompare(attribute, CFStringRef(QAXDescriptionAttribute), 0) == kCFCompareEqualTo)
1231  return QAccessible::Description;
1232  else
1233  return -1;
1234 }
1235 
1236 /*
1237  Returns the subrole string constant for the interface if it has one,
1238  else returns an empty string.
1239 */
1240 static QCFString subrole(const QAInterface &interface)
1241 {
1242  const QAInterface parent = interface.parent();
1243  if (parent.isValid() == false)
1244  return QCFString();
1245 
1246  if (parent.role() == QAccessible::ScrollBar) {
1248  switch(interface.id()) {
1249  case 1: subrole = CFStringRef(QAXDecrementArrowSubrole); break;
1250  case 2: subrole = CFStringRef(QAXDecrementPageSubrole); break;
1251  case 4: subrole = CFStringRef(QAXIncrementPageSubrole); break;
1252  case 5: subrole = CFStringRef(QAXIncrementArrowSubrole); break;
1253  default:
1254  break;
1255  }
1256  return subrole;
1257  }
1258  return QCFString();
1259 }
1260 
1261 // Gets the scroll bar orientation by asking the QAbstractSlider object directly.
1263 {
1264  QObject *const object = scrollBar.object();
1265  if (QAbstractSlider * const sliderObject = qobject_cast<QAbstractSlider * const>(object))
1266  return sliderObject->orientation();
1267 
1268  return Qt::Vertical; // D'oh! The interface wasn't a scroll bar.
1269 }
1270 
1272 {
1273  if (macRole(scrollArea) != CFStringRef(CFStringRef(QAXScrollAreaRole)))
1274  return QAInterface();
1275 
1276  // Child 1 is the contents widget, 2 and 3 are the scroll bar containers wich contains possible scroll bars.
1277  for (int i = 2; i <= 3; ++i) {
1278  QAInterface scrollBarContainer = scrollArea.childAt(i);
1279  for (int i = 1; i <= scrollBarContainer.childCount(); ++i) {
1280  QAInterface scrollBar = scrollBarContainer.childAt(i);
1281  if (scrollBar.isValid() &&
1282  scrollBar.role() == QAccessible::ScrollBar &&
1283  scrollBarOrientation(scrollBar) == orientation)
1284  return scrollBar;
1285  }
1286  }
1287 
1288  return QAInterface();
1289 }
1290 
1291 static bool scrollAreaHasScrollBar(const QAInterface &scrollArea, Qt::Orientation orientation)
1292 {
1293  return scrollAreaGetScrollBarInterface(scrollArea, orientation).isValid();
1294 }
1295 
1296 static QAElement scrollAreaGetScrollBar(const QAInterface &scrollArea, Qt::Orientation orientation)
1297 {
1298  return accessibleHierarchyManager()->lookup(scrollAreaGetScrollBarInterface(scrollArea, orientation));
1299 }
1300 
1302 {
1303  // Child 1 is the contents widget,
1304  return accessibleHierarchyManager()->lookup(scrollArea.navigate(QAccessible::Child, 1));
1305 }
1306 
1308 {
1309  // A kAXTabGroup has a kAXContents attribute, which consists of the
1310  // ui elements for the current tab page. Get the current tab page
1311  // from the QStackedWidget, where the current visible page can
1312  // be found at index 1.
1313  QAInterface stackedWidget = interface.childAt(1);
1314  accessibleHierarchyManager()->registerChildren(stackedWidget);
1315  QAInterface tabPageInterface = stackedWidget.childAt(1);
1316  return accessibleHierarchyManager()->lookup(tabPageInterface);
1317 }
1318 
1320 {
1321  // Get the tabs by searching for children with the "PageTab" role.
1322  // This filters out the left/right navigation buttons.
1323  accessibleHierarchyManager()->registerChildren(interface);
1324  QList<QAElement> tabs;
1325  const int numChildren = interface.childCount();
1326  for (int i = 1; i < numChildren + 1; ++i) {
1327  QAInterface child = interface.navigate(QAccessible::Child, i);
1328  if (child.isValid() && child.role() == QAccessible::PageTab) {
1329  tabs.append(accessibleHierarchyManager()->lookup(child));
1330  }
1331  }
1332  return tabs;
1333 }
1334 
1336 {
1337  // Each QTabWidget has two children, a QStackedWidget and a QTabBar.
1338  // Get the tabs from the QTabBar.
1339  return tabBarGetTabs(interface.childAt(2));
1340 }
1341 
1343 {
1344  // The children for a kAXTabGroup should consist of the tabs and the
1345  // contents of the current open tab page.
1346  QList<QAElement> children = tabWidgetGetTabs(interface);
1347  children += tabWidgetGetContents(interface);
1348  return children;
1349 }
1350 #endif //QT_MAC_USE_COCOA
1351 
1352 /*
1353  Returns the label (buddy) interface for interface, or 0 if it has none.
1354 */
1355 /*
1356 static QAInterface findLabel(const QAInterface &interface)
1357 {
1358  return interface.navigate(QAccessible::Label, 1);
1359 }
1360 */
1361 /*
1362  Returns a list of interfaces this interface labels, or an empty list if it doesn't label any.
1363 */
1364 /*
1365 static QList<QAInterface> findLabelled(const QAInterface &interface)
1366 {
1367  QList<QAInterface> interfaceList;
1368 
1369  int count = 1;
1370  const QAInterface labelled = interface.navigate(QAccessible::Labelled, count);
1371  while (labelled.isValid()) {
1372  interfaceList.append(labelled);
1373  ++count;
1374  }
1375  return interfaceList;
1376 }
1377 */
1378 /*
1379  Tests if the given QAInterface has data for a mac attribute.
1380 */
1381 #ifndef QT_MAC_USE_COCOA
1382 static bool supportsAttribute(CFStringRef attribute, const QAInterface &interface)
1383 {
1384  const int text = textForRoleAndAttribute(interface.role(), attribute);
1385 
1386  // Special case: Static texts don't have a title.
1387  if (interface.role() == QAccessible::StaticText && attribute == CFStringRef(QAXTitleAttribute))
1388  return false;
1389 
1390  // Return true if we the attribute matched a QAccessible::Role and we get text for that role from the interface.
1391  if (text != -1) {
1392  if (text == QAccessible::Value) // Special case for Value, see getValue()
1393  return !getValue(interface).isEmpty();
1394  else
1395  return !interface.text((QAccessible::Text)text).isEmpty();
1396  }
1397 
1398  if (CFStringCompare(attribute, CFStringRef(QAXChildrenAttribute), 0) == kCFCompareEqualTo) {
1399  if (interface.childCount() > 0)
1400  return true;
1401  }
1402 
1403  if (CFStringCompare(attribute, CFStringRef(QAXSubroleAttribute), 0) == kCFCompareEqualTo) {
1404  return (subrole(interface) != QCFString());
1405  }
1406 
1407  return false;
1408 }
1409 
1410 static void appendIfSupported(CFMutableArrayRef array, CFStringRef attribute, const QAInterface &interface)
1411 {
1412  if (supportsAttribute(attribute, interface))
1413  qt_mac_append_cf_uniq(array, attribute);
1414 }
1415 
1416 /*
1417  Returns the names of the attributes the give QAInterface supports.
1418 */
1420 {
1421  // Call system event handler.
1422  OSStatus err = CallNextEventHandler(next_ref, event);
1423  if(err != noErr && err != eventNotHandledErr)
1424  return err;
1425  CFMutableArrayRef attrs = 0;
1426  GetEventParameter(event, kEventParamAccessibleAttributeNames, typeCFMutableArrayRef, 0,
1427  sizeof(attrs), 0, &attrs);
1428 
1429  if (!attrs)
1430  return eventNotHandledErr;
1431 
1432  // Append attribute names that are always supported.
1439 
1440  // Append these names if the QInterafceItem returns any data for them.
1441  appendIfSupported(attrs, CFStringRef(QAXTitleAttribute), interface);
1442  appendIfSupported(attrs, CFStringRef(QAXValueAttribute), interface);
1445  appendIfSupported(attrs, CFStringRef(QAXHelpAttribute), interface);
1449 
1450  // Append attribute names based on the interaface role.
1451  switch (interface.role()) {
1452  case QAccessible::Window:
1460  break;
1462  case QAccessible::CheckBox:
1465  break;
1468  break;
1469  case QAccessible::Splitter:
1471  break;
1472  case QAccessible::Table:
1476  break;
1477  default:
1478  break;
1479  }
1480 
1481  // Append attribute names based on the mac accessibility role.
1482  const QCFString mac_role = macRole(interface);
1483  if (mac_role == CFStringRef(QAXSplitterRole)) {
1487  } else if (mac_role == CFStringRef(QAXScrollAreaRole)) {
1488  if (scrollAreaHasScrollBar(interface, Qt::Horizontal))
1490  if (scrollAreaHasScrollBar(interface, Qt::Vertical))
1493  } else if (mac_role == CFStringRef(QAXTabGroupRole)) {
1495  // Only tab widgets can have the contents attribute, there is no way of getting
1496  // the contents from a QTabBar.
1497  if (isTabWidget(interface))
1499  }
1500 
1501  return noErr;
1502 }
1503 
1505 {
1506  QString str = interface.text(text);
1507  if (str.isEmpty())
1508  return;
1509 
1510  // Remove any html markup from the text string, or VoiceOver will read the html tags.
1511  static QTextDocument document;
1512  document.setHtml(str);
1513  str = document.toPlainText();
1514 
1516  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFStringRef, sizeof(cfstr), &cfstr);
1517 }
1518 
1519 /*
1520  Handles the parent attribute for a interface.
1521  There are basically three cases here:
1522  1. interface is a HIView and has only HIView children.
1523  2. interface is a HIView but has children that is not a HIView
1524  3. interface is not a HIView.
1525 */
1527 {
1528  // Add the children for this interface to the global QAccessibelHierachyManager.
1529  accessibleHierarchyManager()->registerChildren(interface);
1530 
1531  if (isTabWidget(interface)) {
1532  QList<QAElement> children = tabWidgetGetChildren(interface);
1533  const int childCount = children.count();
1534 
1535  CFMutableArrayRef array = 0;
1536  array = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
1537  for (int i = 0; i < childCount; ++i) {
1538  qt_mac_append_cf_uniq(array, children.at(i).element());
1539  }
1540 
1541  OSStatus err;
1542  err = SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFArrayRef, sizeof(array), &array);
1543  if (err != noErr)
1544  qWarning("Qt:Internal error (%s:%d)", __FILE__, __LINE__);
1545 
1546  return noErr;
1547  }
1548 
1549  const QList<QAElement> children = lookup(interface.children());
1550  const int childCount = children.count();
1551 
1552  OSStatus err = eventNotHandledErr;
1553  if (interface.isHIView())
1554  err = CallNextEventHandler(next_ref, event);
1555 
1556  CFMutableArrayRef array = 0;
1557  int arraySize = 0;
1558  if (err == noErr) {
1559  CFTypeRef obj = 0;
1560  err = GetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFTypeRef, NULL , sizeof(obj), NULL, &obj);
1561  if (err == noErr && obj != 0) {
1562  array = (CFMutableArrayRef)obj;
1563  arraySize = CFArrayGetCount(array);
1564  }
1565  }
1566 
1567  if (array) {
1568  CFArrayRemoveAllValues(array);
1569  for (int i = 0; i < childCount; ++i) {
1570  qt_mac_append_cf_uniq(array, children.at(i).element());
1571  }
1572  } else {
1573  array = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
1574  for (int i = 0; i < childCount; ++i) {
1575  qt_mac_append_cf_uniq(array, children.at(i).element());
1576  }
1577 
1578  err = SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFArrayRef, sizeof(array), &array);
1579  if (err != noErr)
1580  qWarning("Qt:Internal error (%s:%d)", __FILE__, __LINE__);
1581  }
1582 
1583  return noErr;
1584 }
1585 
1586 /*
1587 
1588 */
1590 {
1591  OSStatus err = eventNotHandledErr;
1592  if (interface.isHIView()) {
1593  err = CallNextEventHandler(next_ref, event);
1594  }
1595  if (err == noErr)
1596  return err;
1597 
1598  const QAInterface parentInterface = interface.navigate(QAccessible::Ancestor, 1);
1599  const QAElement parentElement = accessibleHierarchyManager()->lookup(parentInterface);
1600 
1601  if (parentElement.isValid() == false)
1602  return eventNotHandledErr;
1603 
1604  AXUIElementRef elementRef = parentElement.element();
1605  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof(elementRef), &elementRef);
1606  return noErr;
1607 }
1608 #endif
1609 
1611 {
1612  static inline bool test(const QAInterface &interface)
1613  {
1614  return (interface.role() == QAccessible::Window);
1615  }
1616 };
1617 
1619 {
1620  static inline bool test(const QAInterface &interface)
1621  {
1622  QWidget * const widget = qobject_cast<QWidget*>(interface.object());
1623  return (interface.role() == QAccessible::Window &&
1624  widget && widget->isWindow() &&
1625  !qt_mac_is_macdrawer(widget) &&
1626  !qt_mac_is_macsheet(widget));
1627  }
1628 };
1629 
1630 /*
1631  Navigates up the iterfaces ancestor hierachy until a QAccessibleInterface that
1632  passes the Test is found. If we reach a interface that is a HIView we stop the
1633  search and call AXUIElementCopyAttributeValue.
1634 */
1635 template <typename TestType>
1637 {
1638  if (interface.isHIView())
1639  return CallNextEventHandler(next_ref, event);
1640 
1641  QAInterface current = interface;
1643  while (current.isValid()) {
1644  if (TestType::test(interface)) {
1645  element = accessibleHierarchyManager()->lookup(current);
1646  break;
1647  }
1648 
1649  // If we reach an InterfaceItem that is a HiView we can hand of the search to
1650  // the system event handler. This is the common case.
1651  if (current.isHIView()) {
1652  CFTypeRef value = 0;
1653  const QAElement currentElement = accessibleHierarchyManager()->lookup(current);
1654  AXError err = AXUIElementCopyAttributeValue(currentElement.element(), attribute, &value);
1655  AXUIElementRef newElement = (AXUIElementRef)value;
1656 
1657  if (err == noErr)
1658  element = QAElement(newElement);
1659 
1660  if (newElement != 0)
1661  CFRelease(newElement);
1662  break;
1663  }
1664 
1665  QAInterface next = current.parent();
1666  if (next.isValid() == false)
1667  break;
1668  if (next == current)
1669  break;
1670  current = next;
1671  }
1672 
1673  if (element.isValid() == false)
1674  return eventNotHandledErr;
1675 
1676 
1677  AXUIElementRef elementRef = element.element();
1678  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFTypeRef,
1679  sizeof(elementRef), &elementRef);
1680  return noErr;
1681 }
1682 
1683 /*
1684  Returns the top-level window for an interface, which is the closest ancestor interface that
1685  has the Window role, but is not a sheet or a drawer.
1686 */
1687 #ifndef QT_MAC_USE_COCOA
1689 {
1690  return navigateAncestors<IsWindowAndNotDrawerOrSheetTest>(next_ref, event, interface, CFStringRef(QAXWindowAttribute));
1691 }
1692 
1693 /*
1694  Returns the top-level window for an interface, which is the closest ancestor interface that
1695  has the Window role. (Can also be a sheet or a drawer)
1696 */
1698 {
1699  return navigateAncestors<IsWindowTest>(next_ref, event, interface, CFStringRef(QAXTopLevelUIElementAttribute));
1700 }
1701 
1702 /*
1703  Returns the tab buttons for an interface.
1704 */
1706 {
1707  Q_UNUSED(next_ref);
1708  if (isTabWidget(interface))
1709  return setAttributeValue(event, tabWidgetGetTabs(interface));
1710  else
1711  return setAttributeValue(event, tabBarGetTabs(interface));
1712 }
1713 
1715 {
1716  QPoint qpoint(interface.rect().topLeft());
1717  HIPoint point;
1718  point.x = qpoint.x();
1719  point.y = qpoint.y();
1720  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeHIPoint, sizeof(point), &point);
1721  return noErr;
1722 }
1723 
1725 {
1726  QSize qSize(interface.rect().size());
1727  HISize size;
1728  size.width = qSize.width();
1729  size.height = qSize.height();
1730  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeHISize, sizeof(size), &size);
1731  return noErr;
1732 }
1733 
1735 {
1736  const QCFString role = subrole(interface);
1737  CFStringRef rolestr = (CFStringRef)role;
1738  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof(rolestr), &rolestr);
1739  return noErr;
1740 }
1741 
1743 {
1744  QObject *const object = interface.object();
1745  Qt::Orientation orientation;
1746  if (interface.role() == QAccessible::ScrollBar) {
1747  orientation = scrollBarOrientation(interface);
1748  } else if (QSplitterHandle * const splitter = qobject_cast<QSplitterHandle * const>(object)) {
1749  // Qt reports the layout orientation, but we want the splitter handle orientation.
1750  orientation = (splitter->orientation() == Qt::Horizontal) ? Qt::Vertical : Qt::Horizontal;
1751  } else {
1752  return CallNextEventHandler(next_ref, event);
1753  }
1754  const CFStringRef orientationString = (orientation == Qt::Vertical)
1756  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFStringRef, sizeof(orientationString), &orientationString);
1757  return noErr;
1758 }
1759 
1760 /*
1761  Figures out the next or previous contents for a splitter.
1762 */
1764 {
1765  if (interface.isValid() == false || interface.role() != QAccessible::Grip)
1766  return eventNotHandledErr;
1767 
1768  const QAInterface parent = interface.parent();
1769  if (parent.isValid() == false)
1770  return CallNextEventHandler(next_ref, event);
1771 
1772  if (parent.role() != QAccessible::Splitter)
1773  return CallNextEventHandler(next_ref, event);
1774 
1775  const QSplitter * const splitter = qobject_cast<const QSplitter * const>(parent.object());
1776  if (splitter == 0)
1777  return CallNextEventHandler(next_ref, event);
1778 
1779  QWidget * const splitterHandle = qobject_cast<QWidget * const>(interface.object());
1780  const int splitterHandleIndex = splitter->indexOf(splitterHandle);
1781  const int widgetIndex = (nextOrPrev == QCFString(CFStringRef(QAXPreviousContentsAttribute))) ? splitterHandleIndex - 1 : splitterHandleIndex;
1782  const QAElement contentsElement = accessibleHierarchyManager()->lookup(splitter->widget(widgetIndex), 0);
1783  return setAttributeValue(event, QList<QAElement>() << contentsElement);
1784 }
1785 
1786 /*
1787  Creates a list of all splitter handles the splitter contains.
1788 */
1790 {
1791  const QSplitter * const splitter = qobject_cast<const QSplitter * const>(interface.object());
1792  if (splitter == 0)
1793  return CallNextEventHandler(next_ref, event);
1794 
1795  accessibleHierarchyManager()->registerChildren(interface);
1796 
1797  QList<QAElement> handles;
1798  const int visibleSplitterCount = splitter->count() -1; // skip first handle, it's always invisible.
1799  for (int i = 0; i < visibleSplitterCount; ++i)
1800  handles.append(accessibleHierarchyManager()->lookup(splitter->handle(i + 1), 0));
1801 
1802  return setAttributeValue(event, handles);
1803 }
1804 
1805 // This handler gets the scroll bars for a scroll area
1807 {
1808  QAElement scrollBar = scrollAreaGetScrollBar(scrollArea, orientation);
1809  if (scrollBar.isValid() == false)
1810  return CallNextEventHandler(next_ref, event);
1811 
1812  AXUIElementRef elementRef = scrollBar.element();
1813  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof(elementRef), &elementRef);
1814  return noErr;
1815 }
1816 
1817 // This handler gets the contents for a scroll area or tab widget.
1819 {
1820  const QCFString mac_role = macRole(interface);
1821 
1822  QAElement contents;
1823 
1824  if (mac_role == kAXTabGroupRole) {
1825  contents = tabWidgetGetContents(interface);
1826  } else {
1827  contents = scrollAreaGetContents(interface);
1828  if (contents.isValid() == false)
1829  return CallNextEventHandler(next_ref, event);
1830  }
1831 
1832  return setAttributeValue(event, QList<QAElement>() << contents);
1833 }
1834 
1836 {
1837  QList<QAElement> rows = lookup(tableView.children());
1838 
1839  // kill the first row which is the horizontal header.
1840  rows.removeAt(0);
1841 
1842  return setAttributeValue(event, rows);
1843 }
1844 
1846 {
1847  QList<QAElement> visibleRows;
1848 
1849  QList<QAInterface> rows = tableView.children();
1850  // kill the first row which is the horizontal header.
1851  rows.removeAt(0);
1852 
1853  foreach (const QAInterface &interface, rows)
1854  if ((interface.state() & QAccessible::Invisible) == false)
1855  visibleRows.append(accessibleHierarchyManager()->lookup(interface));
1856 
1857  return setAttributeValue(event, visibleRows);
1858 }
1859 
1861 {
1862  QList<QAElement> selectedRows;
1863  foreach (const QAInterface &interface, tableView.children())
1864  if ((interface.state() & QAccessible::Selected))
1865  selectedRows.append(accessibleHierarchyManager()->lookup(interface));
1866 
1867  return setAttributeValue(event, selectedRows);
1868 }
1869 
1871 {
1872  CFStringRef var;
1873  GetEventParameter(event, kEventParamAccessibleAttributeName, typeCFStringRef, 0,
1874  sizeof(var), 0, &var);
1875 
1876  if (CFStringCompare(var, CFStringRef(QAXChildrenAttribute), 0) == kCFCompareEqualTo) {
1877  return handleChildrenAttribute(next_ref, event, interface);
1878  } else if(CFStringCompare(var, CFStringRef(QAXTopLevelUIElementAttribute), 0) == kCFCompareEqualTo) {
1879  return handleTopLevelUIElementAttribute(next_ref, event, interface);
1880  } else if(CFStringCompare(var, CFStringRef(QAXWindowAttribute), 0) == kCFCompareEqualTo) {
1881  return handleWindowAttribute(next_ref, event, interface);
1882  } else if(CFStringCompare(var, CFStringRef(QAXParentAttribute), 0) == kCFCompareEqualTo) {
1883  return handleParentAttribute(next_ref, event, interface);
1884  } else if (CFStringCompare(var, CFStringRef(QAXPositionAttribute), 0) == kCFCompareEqualTo) {
1885  return handlePositionAttribute(next_ref, event, interface);
1886  } else if (CFStringCompare(var, CFStringRef(QAXSizeAttribute), 0) == kCFCompareEqualTo) {
1887  return handleSizeAttribute(next_ref, event, interface);
1888  } else if (CFStringCompare(var, CFStringRef(QAXRoleAttribute), 0) == kCFCompareEqualTo) {
1889  CFStringRef role = macRole(interface);
1890 // ###
1891 // QWidget * const widget = qobject_cast<QWidget *>(interface.object());
1892 // if (role == CFStringRef(QAXUnknownRole) && widget && widget->isWindow())
1893 // role = CFStringRef(QAXWindowRole);
1894 
1895  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFStringRef,
1896  sizeof(role), &role);
1897 
1898  } else if (CFStringCompare(var, CFStringRef(QAXEnabledAttribute), 0) == kCFCompareEqualTo) {
1899  Boolean val = !((interface.state() & QAccessible::Unavailable))
1900  && !((interface.state() & QAccessible::Invisible));
1901  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
1902  sizeof(val), &val);
1903  } else if (CFStringCompare(var, CFStringRef(QAXExpandedAttribute), 0) == kCFCompareEqualTo) {
1904  Boolean val = (interface.state() & QAccessible::Expanded);
1905  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
1906  sizeof(val), &val);
1907  } else if (CFStringCompare(var, CFStringRef(QAXSelectedAttribute), 0) == kCFCompareEqualTo) {
1908  Boolean val = (interface.state() & QAccessible::Selection);
1909  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
1910  sizeof(val), &val);
1911  } else if (CFStringCompare(var, CFStringRef(QAXFocusedAttribute), 0) == kCFCompareEqualTo) {
1912  Boolean val = (interface.state() & QAccessible::Focus);
1913  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
1914  sizeof(val), &val);
1915  } else if (CFStringCompare(var, CFStringRef(QAXSelectedChildrenAttribute), 0) == kCFCompareEqualTo) {
1916  const int cc = interface.childCount();
1917  QList<QAElement> selected;
1918  for (int i = 1; i <= cc; ++i) {
1919  const QAInterface child_iface = interface.navigate(QAccessible::Child, i);
1920  if (child_iface.isValid() && child_iface.state() & QAccessible::Selected)
1921  selected.append(accessibleHierarchyManager()->lookup(child_iface));
1922  }
1923 
1924  return setAttributeValue(event, selected);
1925 
1926  } else if (CFStringCompare(var, CFStringRef(QAXCloseButtonAttribute), 0) == kCFCompareEqualTo) {
1927  if(interface.object() && interface.object()->isWidgetType()) {
1928  Boolean val = true; //do we want to add a WState for this?
1929  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
1930  sizeof(val), &val);
1931  }
1932  } else if (CFStringCompare(var, CFStringRef(QAXZoomButtonAttribute), 0) == kCFCompareEqualTo) {
1933  if(interface.object() && interface.object()->isWidgetType()) {
1934  QWidget *widget = (QWidget*)interface.object();
1935  Boolean val = (widget->windowFlags() & Qt::WindowMaximizeButtonHint);
1936  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
1937  sizeof(val), &val);
1938  }
1939  } else if (CFStringCompare(var, CFStringRef(QAXMinimizeButtonAttribute), 0) == kCFCompareEqualTo) {
1940  if(interface.object() && interface.object()->isWidgetType()) {
1941  QWidget *widget = (QWidget*)interface.object();
1942  Boolean val = (widget->windowFlags() & Qt::WindowMinimizeButtonHint);
1943  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
1944  sizeof(val), &val);
1945  }
1946  } else if (CFStringCompare(var, CFStringRef(QAXToolbarButtonAttribute), 0) == kCFCompareEqualTo) {
1947  if(interface.object() && interface.object()->isWidgetType()) {
1948  QWidget *widget = (QWidget*)interface.object();
1949  Boolean val = qobject_cast<QMainWindow *>(widget) != 0;
1950  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
1951  sizeof(val), &val);
1952  }
1953  } else if (CFStringCompare(var, CFStringRef(QAXGrowAreaAttribute), 0) == kCFCompareEqualTo) {
1954  if(interface.object() && interface.object()->isWidgetType()) {
1955  Boolean val = true; //do we want to add a WState for this?
1956  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
1957  sizeof(val), &val);
1958  }
1959  } else if (CFStringCompare(var, CFStringRef(QAXMinimizedAttribute), 0) == kCFCompareEqualTo) {
1960  if (interface.object() && interface.object()->isWidgetType()) {
1961  QWidget *widget = (QWidget*)interface.object();
1962  Boolean val = (widget->windowState() & Qt::WindowMinimized);
1963  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeBoolean,
1964  sizeof(val), &val);
1965  }
1966  } else if (CFStringCompare(var, CFStringRef(QAXSubroleAttribute), 0) == kCFCompareEqualTo) {
1967  return handleSubroleAttribute(next_ref, event, interface);
1968  } else if (CFStringCompare(var, CFStringRef(QAXRoleDescriptionAttribute), 0) == kCFCompareEqualTo) {
1969 #if !defined(QT_MAC_USE_COCOA)
1970  if (HICopyAccessibilityRoleDescription) {
1971  const CFStringRef roleDescription = HICopyAccessibilityRoleDescription(macRole(interface), 0);
1972  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFStringRef,
1973  sizeof(roleDescription), &roleDescription);
1974  } else
1975 #endif
1976  {
1977  // Just use Qt::Description on 10.3
1979  }
1980  } else if (CFStringCompare(var, CFStringRef(QAXTitleAttribute), 0) == kCFCompareEqualTo) {
1981  const QAccessible::Role role = interface.role();
1983  handleStringAttribute(event, text, interface);
1984  } else if (CFStringCompare(var, CFStringRef(QAXValueAttribute), 0) == kCFCompareEqualTo) {
1985  const QAccessible::Role role = interface.role();
1987  if (role == QAccessible::CheckBox || role == QAccessible::RadioButton) {
1988  int value = buttonValue(interface);
1989  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeUInt32, sizeof(value), &value);
1990  } else {
1991  handleStringAttribute(event, text, interface);
1992  }
1993  } else if (CFStringCompare(var, CFStringRef(QAXDescriptionAttribute), 0) == kCFCompareEqualTo) {
1994  const QAccessible::Role role = interface.role();
1996  handleStringAttribute(event, text, interface);
1997  } else if (CFStringCompare(var, CFStringRef(QAXLinkedUIElementsAttribute), 0) == kCFCompareEqualTo) {
1998  return CallNextEventHandler(next_ref, event);
1999  } else if (CFStringCompare(var, CFStringRef(QAXHelpAttribute), 0) == kCFCompareEqualTo) {
2000  const QAccessible::Role role = interface.role();
2002  handleStringAttribute(event, text, interface);
2003  } else if (CFStringCompare(var, kAXTitleUIElementAttribute, 0) == kCFCompareEqualTo) {
2004  return CallNextEventHandler(next_ref, event);
2005  } else if (CFStringCompare(var, CFStringRef(QAXTabsAttribute), 0) == kCFCompareEqualTo) {
2006  return handleTabsAttribute(next_ref, event, interface);
2007  } else if (CFStringCompare(var, CFStringRef(QAXMinValueAttribute), 0) == kCFCompareEqualTo) {
2008  // tabs we first go to the tab bar which is child #2.
2009  QAInterface tabBarInterface = interface.childAt(2);
2010  return handleTabsAttribute(next_ref, event, tabBarInterface);
2011  } else if (CFStringCompare(var, CFStringRef(QAXMinValueAttribute), 0) == kCFCompareEqualTo) {
2012  if (interface.role() == QAccessible::RadioButton || interface.role() == QAccessible::CheckBox) {
2013  uint value = 0;
2014  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeUInt32, sizeof(value), &value);
2015  } else {
2016  return CallNextEventHandler(next_ref, event);
2017  }
2018  } else if (CFStringCompare(var, CFStringRef(QAXMaxValueAttribute), 0) == kCFCompareEqualTo) {
2019  if (interface.role() == QAccessible::RadioButton || interface.role() == QAccessible::CheckBox) {
2020  uint value = 2;
2021  SetEventParameter(event, kEventParamAccessibleAttributeValue, typeUInt32, sizeof(value), &value);
2022  } else {
2023  return CallNextEventHandler(next_ref, event);
2024  }
2025  } else if (CFStringCompare(var, CFStringRef(QAXOrientationAttribute), 0) == kCFCompareEqualTo) {
2026  return handleOrientationAttribute(next_ref, event, interface);
2027  } else if (CFStringCompare(var, CFStringRef(QAXPreviousContentsAttribute), 0) == kCFCompareEqualTo) {
2028  return handleSplitterContentsAttribute(next_ref, event, interface, CFStringRef(QAXPreviousContentsAttribute));
2029  } else if (CFStringCompare(var, CFStringRef(QAXNextContentsAttribute), 0) == kCFCompareEqualTo) {
2030  return handleSplitterContentsAttribute(next_ref, event, interface, CFStringRef(QAXNextContentsAttribute));
2031  } else if (CFStringCompare(var, CFStringRef(QAXSplittersAttribute), 0) == kCFCompareEqualTo) {
2032  return handleSplittersAttribute(next_ref, event, interface);
2033  } else if (CFStringCompare(var, CFStringRef(QAXHorizontalScrollBarAttribute), 0) == kCFCompareEqualTo) {
2034  return handleScrollBarAttribute(next_ref, event, interface, Qt::Horizontal);
2035  } else if (CFStringCompare(var, CFStringRef(QAXVerticalScrollBarAttribute), 0) == kCFCompareEqualTo) {
2036  return handleScrollBarAttribute(next_ref, event, interface, Qt::Vertical);
2037  } else if (CFStringCompare(var, CFStringRef(QAXContentsAttribute), 0) == kCFCompareEqualTo) {
2038  return handleContentsAttribute(next_ref, event, interface);
2039  } else if (CFStringCompare(var, CFStringRef(QAXRowsAttribute), 0) == kCFCompareEqualTo) {
2040  return handleRowsAttribute(next_ref, event, interface);
2041  } else if (CFStringCompare(var, CFStringRef(QAXVisibleRowsAttribute), 0) == kCFCompareEqualTo) {
2042  return handleVisibleRowsAttribute(next_ref, event, interface);
2043  } else if (CFStringCompare(var, CFStringRef(QAXSelectedRowsAttribute), 0) == kCFCompareEqualTo) {
2044  return handleSelectedRowsAttribute(next_ref, event, interface);
2045  } else {
2046  return CallNextEventHandler(next_ref, event);
2047  }
2048  return noErr;
2049 }
2050 
2052 {
2053  CFStringRef var;
2054  GetEventParameter(event, kEventParamAccessibleAttributeName, typeCFStringRef, 0,
2055  sizeof(var), 0, &var);
2056  Boolean settable = false;
2057  if (CFStringCompare(var, CFStringRef(QAXFocusedAttribute), 0) == kCFCompareEqualTo) {
2058  settable = true;
2059  } else {
2060  for (int r = 0; text_bindings[r][0].qt != -1; r++) {
2061  if(interface.role() == (QAccessible::Role)text_bindings[r][0].qt) {
2062  for (int a = 1; text_bindings[r][a].qt != -1; a++) {
2063  if (CFStringCompare(var, CFStringRef(text_bindings[r][a].mac), 0) == kCFCompareEqualTo) {
2064  settable = text_bindings[r][a].settable;
2065  break;
2066  }
2067  }
2068  }
2069  }
2070  }
2071  SetEventParameter(event, kEventParamAccessibleAttributeSettable, typeBoolean,
2072  sizeof(settable), &settable);
2073  return noErr;
2074 }
2075 
2077 {
2078  Q_UNUSED(next_ref);
2079  if (interface.isValid() == false)
2080  return eventNotHandledErr;
2081 
2082  // Add the children for this interface to the global QAccessibelHierachyManager.
2083  accessibleHierarchyManager()->registerChildren(interface);
2084 
2085  Point where;
2086  GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, 0, sizeof(where), 0, &where);
2087  const QAInterface childInterface = interface.childAt(where.h, where.v);
2088 
2089  if (childInterface.isValid() == false || childInterface == interface)
2090  return eventNotHandledErr;
2091 
2092  const QAElement element = accessibleHierarchyManager()->lookup(childInterface);
2093  if (element.isValid() == false)
2094  return eventNotHandledErr;
2095 
2096  AXUIElementRef elementRef = element.element();
2097  CFRetain(elementRef);
2098  SetEventParameter(event, kEventParamAccessibleChild, typeCFTypeRef,
2099  sizeof(elementRef), &elementRef);
2100 
2101  return noErr;
2102 }
2103 
2104 /*
2105  Returns a list of actions the given interface supports.
2106  Currently implemented by getting the interface role and deciding based on that.
2107 */
2109 {
2111  switch (interface.role()) {
2112  default:
2113  // Most things can be pressed.
2114  actions.append(QAccessible::Press);
2115  break;
2116  }
2117 
2118  return actions;
2119 }
2120 
2121 /*
2122  Translates a predefined QAccessible::Action to a Mac action constant.
2123  Returns an empty string if the Qt Action has no mac equivalent.
2124 */
2126 {
2127  switch (action) {
2128  case QAccessible::Press:
2129  return CFStringRef(QAXPressAction);
2130  break;
2131  case QAccessible::Increase:
2133  break;
2134  case QAccessible::Decrease:
2136  break;
2137  case QAccessible::Accept:
2138  return CFStringRef(QAXConfirmAction);
2139  break;
2140  case QAccessible::Select:
2141  return CFStringRef(QAXPickAction);
2142  break;
2143  case QAccessible::Cancel:
2144  return CFStringRef(QAXCancelAction);
2145  break;
2146  default:
2147  return QCFString();
2148  break;
2149  }
2150 }
2151 
2152 /*
2153  Translates between a Mac action constant and a QAccessible::Action.
2154  Returns QAccessible::Default action if there is no Qt predefined equivalent.
2155 */
2157 {
2158  if(CFStringCompare(actionName, CFStringRef(QAXPressAction), 0) == kCFCompareEqualTo) {
2159  return QAccessible::Press;
2160  } else if(CFStringCompare(actionName, CFStringRef(QAXIncrementAction), 0) == kCFCompareEqualTo) {
2161  return QAccessible::Increase;
2162  } else if(CFStringCompare(actionName, CFStringRef(QAXDecrementAction), 0) == kCFCompareEqualTo) {
2163  return QAccessible::Decrease;
2164  } else if(CFStringCompare(actionName, CFStringRef(QAXConfirmAction), 0) == kCFCompareEqualTo) {
2165  return QAccessible::Accept;
2166  } else if(CFStringCompare(actionName, CFStringRef(QAXPickAction), 0) == kCFCompareEqualTo) {
2167  return QAccessible::Select;
2168  } else if(CFStringCompare(actionName, CFStringRef(QAXCancelAction), 0) == kCFCompareEqualTo) {
2169  return QAccessible::Cancel;
2170  } else {
2172  }
2173 }
2174 #endif // QT_MAC_USE_COCOA
2175 
2176 /*
2177  Copies the translated names all supported actions for an interface into the kEventParamAccessibleActionNames
2178  event parameter.
2179 */
2180 #ifndef QT_MAC_USE_COCOA
2182 {
2183  Q_UNUSED(next_ref);
2184 
2185  CFMutableArrayRef actions = 0;
2186  GetEventParameter(event, kEventParamAccessibleActionNames, typeCFMutableArrayRef, 0,
2187  sizeof(actions), 0, &actions);
2188 
2189  // Add supported predefined actions.
2190  const QList<QAccessible::Action> predefinedActions = supportedPredefinedActions(interface);
2191  for (int i = 0; i < predefinedActions.count(); ++i) {
2192  const QCFString action = translateAction(predefinedActions.at(i));
2193  if (action != QCFString())
2194  qt_mac_append_cf_uniq(actions, action);
2195  }
2196 
2197  // Add user actions
2198  const int actionCount = interface.userActionCount();
2199  for (int i = 0; i < actionCount; ++i) {
2200  const QString actionName = interface.actionText(i, QAccessible::Name);
2201  qt_mac_append_cf_uniq(actions, QCFString::toCFStringRef(actionName));
2202  }
2203 
2204  return noErr;
2205 }
2206 #endif
2207 
2208 /*
2209  Handles the perforNamedAction event.
2210 */
2211 #ifndef QT_MAC_USE_COCOA
2213 {
2214  Q_UNUSED(next_ref);
2215 
2216  CFStringRef act;
2217  GetEventParameter(event, kEventParamAccessibleActionName, typeCFStringRef, 0,
2218  sizeof(act), 0, &act);
2219 
2220  const QAccessible::Action action = translateAction(act);
2221 
2222  // Perform built-in action
2223  if (action != QAccessible::DefaultAction) {
2224  interface.doAction(action, QVariantList());
2225  return noErr;
2226  }
2227 
2228  // Search for user-defined actions and perform it if found.
2229  const int actCount = interface.userActionCount();
2230  const QString qAct = QCFString::toQString(act);
2231  for(int i = 0; i < actCount; i++) {
2232  if(interface.actionText(i, QAccessible::Name) == qAct) {
2233  interface.doAction(i, QVariantList());
2234  break;
2235  }
2236  }
2237  return noErr;
2238 }
2239 
2241 {
2242  Q_UNUSED(next_ref);
2243  Q_UNUSED(event);
2244 
2245  CFStringRef var;
2246  GetEventParameter(event, kEventParamAccessibleAttributeName, typeCFStringRef, 0,
2247  sizeof(var), 0, &var);
2248  if(CFStringCompare(var, CFStringRef(QAXFocusedAttribute), 0) == kCFCompareEqualTo) {
2249  CFTypeRef val;
2250  if(GetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFTypeRef, 0,
2251  sizeof(val), 0, &val) == noErr) {
2252  if(CFGetTypeID(val) == CFBooleanGetTypeID() &&
2253  CFEqual(static_cast<CFBooleanRef>(val), kCFBooleanTrue)) {
2254  interface.doAction(QAccessible::SetFocus);
2255  }
2256  }
2257  } else {
2258  bool found = false;
2259  for(int r = 0; text_bindings[r][0].qt != -1; r++) {
2260  if(interface.role() == (QAccessible::Role)text_bindings[r][0].qt) {
2261  for(int a = 1; text_bindings[r][a].qt != -1; a++) {
2262  if(CFStringCompare(var, CFStringRef(text_bindings[r][a].mac), 0) == kCFCompareEqualTo) {
2263  if(!text_bindings[r][a].settable) {
2264  } else {
2265  CFTypeRef val;
2266  if(GetEventParameter(event, kEventParamAccessibleAttributeValue, typeCFTypeRef, 0,
2267  sizeof(val), 0, &val) == noErr) {
2268  if(CFGetTypeID(val) == CFStringGetTypeID())
2269  interface.setText((QAccessible::Text)text_bindings[r][a].qt,
2270  QCFString::toQString(static_cast<CFStringRef>(val)));
2271 
2272  }
2273  }
2274  found = true;
2275  break;
2276  }
2277  }
2278  break;
2279  }
2280  }
2281  }
2282  return noErr;
2283 }
2284 
2285 /*
2286  This is the main accessibility event handler.
2287 */
2289 {
2290  Q_UNUSED(data)
2291 
2292  // Return if this event is not a AccessibleGetNamedAttribute event.
2293  const UInt32 eclass = GetEventClass(event);
2294  if (eclass != kEventClassAccessibility)
2295  return eventNotHandledErr;
2296 
2297  // Get the AXUIElementRef and QAInterface pointer
2298  AXUIElementRef element = 0;
2299  GetEventParameter(event, kEventParamAccessibleObject, typeCFTypeRef, 0, sizeof(element), 0, &element);
2300  QAInterface interface = accessibleHierarchyManager()->lookup(element);
2301  if (interface.isValid() == false)
2302  return eventNotHandledErr;
2303 
2304  const UInt32 ekind = GetEventKind(event);
2305  OSStatus status = noErr;
2306  switch (ekind) {
2307  case kEventAccessibleGetAllAttributeNames:
2308  status = getAllAttributeNames(event, interface, next_ref);
2309  break;
2310  case kEventAccessibleGetNamedAttribute:
2311  status = getNamedAttribute(next_ref, event, interface);
2312  break;
2313  case kEventAccessibleIsNamedAttributeSettable:
2314  status = isNamedAttributeSettable(event, interface);
2315  break;
2316  case kEventAccessibleGetChildAtPoint:
2317  status = getChildAtPoint(next_ref, event, interface);
2318  break;
2319  case kEventAccessibleGetAllActionNames:
2320  status = getAllActionNames(next_ref, event, interface);
2321  break;
2322  case kEventAccessibleGetFocusedChild:
2323  status = CallNextEventHandler(next_ref, event);
2324  break;
2325  case kEventAccessibleSetNamedAttribute:
2326  status = setNamedAttribute(next_ref, event, interface);
2327  break;
2328  case kEventAccessiblePerformNamedAction:
2329  status = performNamedAction(next_ref, event, interface);
2330  break;
2331  default:
2332  status = CallNextEventHandler(next_ref, event);
2333  break;
2334  };
2335  return status;
2336 }
2337 #endif
2338 
2340 {
2341 #ifndef QT_MAC_USE_COCOA
2344 #endif
2345 }
2346 
2347 // Sets thre root object for the application
2349 {
2350  // Call installed root object handler if we have one
2351  if (rootObjectHandler) {
2352  rootObjectHandler(object);
2353  return;
2354  }
2355 
2356  rootObject = object;
2357 }
2358 
2360 {
2361  accessibleHierarchyManager()->reset();
2362 #ifndef QT_MAC_USE_COCOA
2366 #endif
2367 }
2368 
2369 void QAccessible::updateAccessibility(QObject *object, int child, Event reason)
2370 {
2371  // Call installed update handler if we have one.
2372  if (updateHandler) {
2373  updateHandler(object, child, reason);
2374  return;
2375  }
2376 
2377 #ifndef QT_MAC_USE_COCOA
2378  // Return if the mac accessibility is not enabled.
2379  if(!AXAPIEnabled())
2380  return;
2381 
2382  // Work around crash, disable accessiblity for focus frames.
2383  if (qstrcmp(object->metaObject()->className(), "QFocusFrame") == 0)
2384  return;
2385 
2386 // qDebug() << "updateAccessibility" << object << child << hex << reason;
2387 
2388  if (reason == ObjectShow) {
2389  QAInterface interface = QAInterface(QAccessible::queryAccessibleInterface(object), child);
2390  accessibleHierarchyManager()->registerInterface(interface);
2391  }
2392 
2393  const QAElement element = accessibleHierarchyManager()->lookup(object, child);
2394  if (element.isValid() == false)
2395  return;
2396 
2397 
2398  CFStringRef notification = 0;
2399  if(object && object->isWidgetType() && reason == ObjectCreated) {
2400  notification = CFStringRef(QAXWindowCreatedNotification);
2401  } else if(reason == ValueChanged) {
2402  notification = CFStringRef(QAXValueChangedNotification);
2403  } else if(reason == MenuStart) {
2404  notification = CFStringRef(QAXMenuOpenedNotification);
2405  } else if(reason == MenuEnd) {
2406  notification = CFStringRef(QAXMenuClosedNotification);
2407  } else if(reason == LocationChanged) {
2408  notification = CFStringRef(QAXWindowMovedNotification);
2409  } else if(reason == ObjectShow || reason == ObjectHide ) {
2410  // When a widget is deleted we get a ObjectHide before the destroyed(QObject *)
2411  // signal is emitted (which makes sense). However, at this point we are in the
2412  // middle of the QWidget destructor which means that we have to be careful when
2413  // using the widget pointer. Since we can't control what the accessibilty interfaces
2414  // does when navigate() is called below we ignore the hide update in this case.
2415  // (the widget will be deleted soon anyway.)
2417  if (QWidget *widget = qobject_cast<QWidget*>(object)) {
2418  if (qt_widget_private(widget)->data.in_destructor)
2419  return;
2420 
2421  // Check widget parent as well, special case for preventing crash
2422  // when the viewport() of an abstract scroll area is hidden when
2423  // the QWidget destructor hides all its children.
2425  if (parentWidget && qt_widget_private(parentWidget)->data.in_destructor)
2426  return;
2427  }
2428 
2429  // There is no equivalent Mac notification for ObjectShow/Hide, so we call HIObjectSetAccessibilityIgnored
2430  // and isItInteresting which will mark the HIObject accociated with the element as ignored if the
2431  // QAccessible::Invisible state bit is set.
2432  QAInterface interface = accessibleHierarchyManager()->lookup(element);
2433  if (interface.isValid()) {
2434  HIObjectSetAccessibilityIgnored(element.object(), !isItInteresting(interface));
2435  }
2436 
2437  // If the interface manages its own children, also check if we should ignore those.
2438  if (isItemView(interface) == false && managesChildren(interface)) {
2439  for (int i = 1; i <= interface.childCount(); ++i) {
2440  QAInterface childInterface = interface.navigate(QAccessible::Child, i);
2441  if (childInterface.isValid() && childInterface.isHIView() == false) {
2442  const QAElement element = accessibleHierarchyManager()->lookup(childInterface);
2443  if (element.isValid()) {
2444  HIObjectSetAccessibilityIgnored(element.object(), !isItInteresting(childInterface));
2445  }
2446  }
2447  }
2448  }
2449 
2450  } else if(reason == Focus) {
2451  if(object && object->isWidgetType()) {
2452  QWidget *w = static_cast<QWidget*>(object);
2453  if(w->isWindow())
2455  else
2457  }
2458  }
2459 
2460  if (!notification)
2461  return;
2462 
2463  AXNotificationHIObjectNotify(notification, element.object(), element.id());
2464 #endif
2465 }
2466 
2468 
2469 #endif // QT_NO_ACCESSIBILITY
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
static QCFString translateAction(const QAccessible::Action action)
QAElement element(int child)
QSplitterHandle * handle(int index) const
Returns the handle to the left (or above) for the item in the splitter&#39;s layout at the given index...
Definition: qsplitter.cpp:1263
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
#define QAXExpandedAttribute
static EventHandlerUPP objectCreateEventHandlerUPP
int registerInterface(const QDeclarativePrivate::RegisterInterface &interface)
static void appendIfSupported(CFMutableArrayRef array, CFStringRef attribute, const QAInterface &interface)
CFStringRef const QAXRoleType
int indexOfChild(const QAInterface &child) const
const struct __CFString * CFStringRef
#define QAXSplitterRole
static void updateAccessibility(QObject *, int who, Event reason)
Notifies accessibility clients about a change in object&#39;s accessibility information.
QWidget * parentWidget() const
Returns the parent of this widget, or 0 if it does not have any parent widget.
Definition: qwidget.h:1035
#define QAXValueChangedNotification
void doAction(int action, const QVariantList &params=QVariantList()) const
#define QAXTableRole
static bool test(const QAInterface &interface)
static OSStatus handleTabsAttribute(EventHandlerCallRef next_ref, EventRef event, QAInterface &interface)
#define QAXToolbarRole
static void installApplicationEventhandler()
bool operator==(const QAInterface &other) const
static CFStringRef kObjectQtAccessibility
static void handleStringAttribute(EventRef event, QAccessible::Text text, const QAInterface &interface)
virtual void registerChildren()=0
static QList< QAElement > tabWidgetGetChildren(const QAInterface &interface)
static OSStatus handleTopLevelUIElementAttribute(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface)
static OSStatus handleSubroleAttribute(EventHandlerCallRef, EventRef event, const QAInterface &interface)
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
#define QAXSelectedAttribute
EventRef event
QPointer< QWidget > widget
bool qt_mac_is_macsheet(const QWidget *w)
Definition: qwidget_mac.mm:295
static bool isEmbeddedTabBar(const QAInterface &interface)
Qt::WindowStates windowState() const
Returns the current window state.
Definition: qwidget.cpp:3086
#define QAXCheckBoxRole
HIObjectRef object() const
#define QAXGroupRole
#define QAXTitleAttribute
static void installAcessibilityEventHandler(HIObjectRef hiObject)
#define QAXRoleDescriptionAttribute
static EventHandlerUPP accessibilityEventHandlerUPP
#define QAXOrientationAttribute
static QAElement tabWidgetGetContents(const QAInterface &interface)
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition: qwidget.h:945
static OSStatus handleVisibleRowsAttribute(EventHandlerCallRef, EventRef event, QAInterface &tableView)
#define QAXPopUpButtonRole
QList< HIObjectRef > objects
QAInterface navigate(RelationFlag relation, int entry) const
#define QAXWindowCreatedNotification
#define QAXTabGroupRole
QAInterface interface(UInt64 identifier)
Role
This enum defines the role of an accessible object.
Definition: qaccessible.h:188
bool isValid() const
uint qHash(const QAInterface &item)
#define QAXFocusedUIElementChangedNotification
#define SLOT(a)
Definition: qobjectdefs.h:226
static EventHandlerUPP applicationEventHandlerUPP
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
static bool isItemView(const QAInterface &interface)
static CFStringRef toCFStringRef(const QString &str)
Definition: qcore_mac.cpp:69
#define QAXWindowMovedNotification
#define QAXSplittersAttribute
static QString toQString(CFStringRef cfstr)
Definition: qcore_mac.cpp:47
#define QAXScrollBarRole
#define QAXMainAttribute
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
static void registerQtAccessibilityHIObjectSubclass()
#define QAXStaticTextRole
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
QAInterface childAt(int x, int y) const
#define QAXVerticalScrollBarAttribute
long ASN1_INTEGER_get ASN1_INTEGER * a
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
#define QAXHorizontalOrientationValue
static QObject * rootObject
QAInterface interface(UInt64 identifier)
#define QAXFocusedWindowChangedNotification
static OSStatus handleContentsAttribute(EventHandlerCallRef next_ref, EventRef event, QAInterface &interface)
bool isValid() const
The QString class provides a Unicode character string.
Definition: qstring.h:83
static bool test(const QAInterface &interface)
#define QAXContentsAttribute
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
The QSplitterHandle class provides handle functionality of the splitter.
Definition: qsplitter.h:158
#define QAXRoleAttribute
static const uint base
Definition: qurl.cpp:268
#define QAXConfirmAction
static OSStatus handleSizeAttribute(EventHandlerCallRef, EventRef event, const QAInterface &interface)
#define QAXColumnRole
QString toPlainText() const
Returns the plain text contained in the document.
#define QAXMenuBarRole
#define QAXWindowRole
Q_CORE_EXPORT QTextStream & hex(QTextStream &s)
const char * className
Definition: qwizard.cpp:137
#define QAXDecrementAction
static void cleanup()
#define QAXSelectedChildrenAttribute
QWidget * widget(int index) const
Returns the widget at the given index in the splitter&#39;s layout.
Definition: qsplitter.cpp:1276
static OSStatus accessibilityEventHandler(EventHandlerCallRef next_ref, EventRef event, void *data)
static bool isStandaloneTabBar(const QAInterface &interface)
#define QAXProgressIndicatorRole
static OSStatus handleOrientationAttribute(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface)
#define QAXIncrementPageSubrole
static OSStatus getAllActionNames(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface)
#define QAXMenuRole
static OSStatus handleParentAttribute(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface)
static void initialize()
bool isHIView() const
#define QAXRadioButtonRole
#define QAXVerticalOrientationValue
#define SIGNAL(a)
Definition: qobjectdefs.h:227
static OSStatus setNamedAttribute(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface)
int width() const
Returns the width.
Definition: qsize.h:126
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
static OSStatus isNamedAttributeSettable(EventRef event, const QAInterface &interface)
#define QAXTopLevelUIElementAttribute
static OSStatus getChildAtPoint(EventHandlerCallRef next_ref, EventRef event, QAInterface &interface)
bool operator==(const QAElement &other) const
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
int id() const
static QString getValue(const QAInterface &interface)
#define QAXSelectedRowsAttribute
QAInterface parent() const
#define QAXCloseButtonAttribute
#define QAXSliderRole
#define QAXSubroleAttribute
#define QAXTextFieldRole
#define QAXPickAction
int count() const
Returns the number of widgets contained in the splitter&#39;s layout.
Definition: qsplitter.cpp:1289
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
#define qApp
Event
This enum type defines accessible event types.
Definition: qaccessible.h:67
virtual QAElement element(int id)=0
static void removeEventhandler(EventHandlerUPP eventHandler)
static QList< QAElement > tabBarGetTabs(const QAInterface &interface)
RelationFlag
This enum type defines bit flags that can be combined to indicate the relationship between two access...
Definition: qaccessible.h:268
static OSStatus handleRowsAttribute(EventHandlerCallRef, EventRef event, QAInterface &tableView)
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
void setText(Text t, const QString &text) const
static QAccessibleHierarchyManager * instance()
#define QAXMenuButtonRole
#define QAXZoomButtonAttribute
QObject * cachedObject() const
Q_CORE_EXPORT void qWarning(const char *,...)
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
#define QAXValueIndicatorRole
static OSStatus setAttributeValue(EventRef event, const QList< QAElement > &elements)
bool checkValid() const
QRect rect() const
#define QAXChildrenAttribute
#define QAXSplitGroupRole
#define QAXRowRole
#define QAXHorizontalScrollBarAttribute
void setHtml(const QString &html)
Replaces the entire contents of the document with the given HTML-formatted text in the html string...
#define QAXNextContentsAttribute
#define QAXIncrementAction
static OSStatus getAllAttributeNames(EventRef event, const QAInterface &interface, EventHandlerCallRef next_ref)
static int buttonValue(QAInterface element)
#define QAXUnknownRole
#define QAXDecrementPageSubrole
signed long OSStatus
#define QAXLinkedUIElementsAttribute
State state() const
#define QAXGrowAreaRole
#define QAXSizeAttribute
The QTableView class provides a default model/view implementation of a table view.
Definition: qtableview.h:58
int childCount() const
AXUIElementRef element() const
struct OpaqueEventRef * EventRef
#define QAXToolbarButtonAttribute
const void * CFTypeRef
#define QAXButtonRole
static OSStatus performNamedAction(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface)
static QWidget * parentWidget(const QWidget *w)
QAInterface interface(UInt64 identifier)
QString actionText(int action, Text text) const
static AXUIElementRef getAccessibleObjectParameter(EventRef event)
#define QAXPressAction
static int textForRoleAndAttribute(QAccessible::Role role, CFStringRef attribute)
#define QAXFocusedAttribute
Action
This enum describes the possible types of action that can occur.
Definition: qaccessible.h:294
static QAccessibleInterface * queryAccessibleInterface(QObject *)
If a QAccessibleInterface implementation exists for the given object, this function returns a pointer...
QObject * object() const
#define QAXMinimizedAttribute
static QList< QAccessible::Action > supportedPredefinedActions(const QAInterface &interface)
bool operator!=(const QAInterface &other) const
Role role() const
void registerChildren(const QAInterface &interface)
#define QAXPreviousContentsAttribute
#define QAXRowsAttribute
The QAbstractItemView class provides the basic functionality for item view classes.
static bool supportsAttribute(CFStringRef attribute, const QAInterface &interface)
bool isWidgetType() const
Returns true if the object is a widget; otherwise returns false.
Definition: qobject.h:146
#define QAXDecrementArrowSubrole
static QAInterface scrollAreaGetScrollBarInterface(const QAInterface &scrollArea, Qt::Orientation orientation)
static void setRootObject(QObject *)
Sets the root accessible object of this application to object.
int userActionCount() const
#define QAXHelpAttribute
State
Definition: qaudio.h:59
The QAccessibleInterface class defines an interface that exposes information about accessible objects...
Definition: qaccessible.h:370
#define QAXGrowAreaAttribute
#define QAXCancelAction
QMultipleHIObjectFactory(const QAInterface &interface)
static QAElement scrollAreaGetContents(const QAInterface &scrollArea)
void operator=(const QAElement &other)
static QCFString subrole(const QAInterface &interface)
#define QAXIncrementArrowSubrole
OSStatus navigateAncestors(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface, CFStringRef attribute)
int id() const
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
#define QAXVisibleRowsAttribute
QList< QVariant > QVariantList
Definition: qvariant.h:443
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
QAElement element(const QAInterface &interface)
static CFStringRef macRole(const QAInterface &interface)
The QMainWindow class provides a main application window.
Definition: qmainwindow.h:63
const char * className() const
Returns the class name.
Definition: qobjectdefs.h:491
struct OpaqueHIObjectRef * HIObjectRef
if(void) toggleToolbarShown
#define QAXScrollAreaRole
The QAbstractSlider class provides an integer value within a range.
#define QAXMenuOpenedNotification
#define QAXWindowAttribute
static Qt::Orientation scrollBarOrientation(const QAInterface &scrollBar)
static bool scrollAreaHasScrollBar(const QAInterface &scrollArea, Qt::Orientation orientation)
#define QAXMenuItemRole
static OSStatus handlePositionAttribute(EventHandlerCallRef, EventRef event, const QAInterface &interface)
QAInterface lookup(const AXUIElementRef &element)
virtual QAInterface interface(UInt64 identifier)=0
quint16 index
#define QAXParentAttribute
static OSStatus handleChildrenAttribute(EventHandlerCallRef next_ref, EventRef event, QAInterface &interface)
#define QAXPositionAttribute
static const QTextHtmlElement elements[Html_NumElements]
return(isPopup||isToolTip)
static OSStatus handleSplittersAttribute(EventHandlerCallRef next_ref, EventRef event, QAInterface &interface)
static QAElement scrollAreaGetScrollBar(const QAInterface &scrollArea, Qt::Orientation orientation)
The QTextDocument class holds formatted text that can be viewed and edited using a QTextEdit...
static OSStatus applicationEventHandler(EventHandlerCallRef next_ref, EventRef event, void *)
#define QAXValueAttribute
QList< QAElement > lookup(const QList< QAInterface > &interfaces)
QItemViewInterfaceFactory(const QAInterface &interface)
QDebug operator<<(QDebug debug, const QAInterface &interface)
QAElement element(const QAInterface &interface)
#define QAXMaxValueAttribute
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
struct OpaqueEventHandlerCallRef * EventHandlerCallRef
int qstrcmp(const QByteArray &str1, const char *str2)
Definition: qbytearray.cpp:336
QAInterface objectInterface() const
int indexOf(QWidget *w) const
Returns the index in the splitter&#39;s layout of the specified widget.
Definition: qsplitter.cpp:1228
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
Qt::WindowFlags windowFlags() const
Window flags are a combination of a type (e.
Definition: qwidget.h:939
Q_GUI_EXPORT QWidgetPrivate * qt_widget_private(QWidget *widget)
Definition: qwidget.cpp:12920
QList< QAInterface > children() const
Text
This enum specifies string information that an accessible object returns.
Definition: qaccessible.h:259
#define QAXEnabledAttribute
AXUIElementRef elementRef
QStandardInterfaceFactory(const QAInterface &interface)
QString text(Text text) const
Q_GLOBAL_STATIC(QAccessibleHierarchyManager, accessibleHierarchyManager)
Orientation
Definition: qnamespace.h:174
#define QAXMenuClosedNotification
#define QAXDescriptionAttribute
#define QAXTabsAttribute
static OSStatus handleSplitterContentsAttribute(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface, QCFString nextOrPrev)
QAElement registerInterface(QObject *object, int child)
#define QAXIncrementorRole
bool qt_mac_is_macdrawer(const QWidget *w)
Definition: qwidget_mac.mm:306
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
Q_OUTOFLINE_TEMPLATE void qDeleteAll(ForwardIterator begin, ForwardIterator end)
Definition: qalgorithms.h:319
bool operator==(QBool b1, bool b2)
Definition: qglobal.h:2023
static OSStatus handleScrollBarAttribute(EventHandlerCallRef next_ref, EventRef event, QAInterface &scrollArea, Qt::Orientation orientation)
static QInterfaceFactory * createFactory(const QAInterface &interface)
The QSplitter class implements a splitter widget.
Definition: qsplitter.h:62
#define QAXListRole
#define QAXTitleUIElementAttribute
static bool qt_mac_append_cf_uniq(CFMutableArrayRef array, CFTypeRef value)
struct QAccessibleTextBinding text_bindings[][10]
bool isItInteresting(const QAInterface &interface)
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
#define text
Definition: qobjectdefs.h:80
static bool isTabWidget(const QAInterface &interface)
#define QAXMinimizeButtonAttribute
static bool managesChildren(const QAInterface &interface)
#define QAXMinValueAttribute
static OSStatus handleSelectedRowsAttribute(EventHandlerCallRef, EventRef event, QAInterface &tableView)
static OSStatus getNamedAttribute(EventHandlerCallRef next_ref, EventRef event, QAInterface &interface)
static OSStatus handleWindowAttribute(EventHandlerCallRef next_ref, EventRef event, const QAInterface &interface)
#define QAXApplicationRole
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288
static QList< QAElement > tabWidgetGetTabs(const QAInterface &interface)
void removeAt(int i)
Removes the item at index position i.
Definition: qlist.h:480