1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the QtGui module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
45 #include <QtCore/qglobal.h>
46 #include <QtCore/qobject.h>
47 #include <QtCore/qrect.h>
48 #include <QtCore/qset.h>
49 #include <QtCore/qvector.h>
50 #include <QtCore/qvariant.h>
51 #include <QtGui/qcolor.h>
52 #include <QtGui/qevent.h>
61 class QAccessibleInterface;
62 class QAccessibleEvent;
65 // We need to inherit QObject to expose the enums to QML.
66 class Q_GUI_EXPORT QAccessible
72 Q_ENUMS(Role Event State)
78 ForegroundChanged = 0x0003,
81 PopupMenuStart = 0x0006,
82 PopupMenuEnd = 0x0007,
83 ContextHelpStart = 0x000C,
84 ContextHelpEnd = 0x000D,
85 DragDropStart = 0x000E,
89 ScrollingStart = 0x0012,
90 ScrollingEnd = 0x0013,
94 // Values from IAccessible2
95 ActionChanged = 0x0101,
96 ActiveDescendantChanged = 0x0102,
97 AttributeChanged = 0x0103,
98 DocumentContentChanged = 0x0104,
99 DocumentLoadComplete = 0x0105,
100 DocumentLoadStopped = 0x0106,
101 DocumentReload = 0x0107,
102 HyperlinkEndIndexChanged = 0x0108,
103 HyperlinkNumberOfAnchorsChanged = 0x0109,
104 HyperlinkSelectedLinkChanged = 0x010A,
105 HypertextLinkActivated = 0x010B,
106 HypertextLinkSelected = 0x010C,
107 HyperlinkStartIndexChanged = 0x010D,
108 HypertextChanged = 0x010E,
109 HypertextNLinksChanged = 0x010F,
110 ObjectAttributeChanged = 0x0110,
111 PageChanged = 0x0111,
112 SectionChanged = 0x0112,
113 TableCaptionChanged = 0x0113,
114 TableColumnDescriptionChanged = 0x0114,
115 TableColumnHeaderChanged = 0x0115,
116 TableModelChanged = 0x0116,
117 TableRowDescriptionChanged = 0x0117,
118 TableRowHeaderChanged = 0x0118,
119 TableSummaryChanged = 0x0119,
120 TextAttributeChanged = 0x011A,
121 TextCaretMoved = 0x011B,
122 // TextChanged = 0x011C, is deprecated in IA2, use TextUpdated
123 TextColumnChanged = 0x011D,
124 TextInserted = 0x011E,
125 TextRemoved = 0x011F,
126 TextUpdated = 0x0120,
127 TextSelectionChanged = 0x0121,
128 VisibleDataChanged = 0x0122,
130 ObjectCreated = 0x8000,
131 ObjectDestroyed = 0x8001,
134 ObjectReorder = 0x8004,
137 SelectionAdd = 0x8007,
138 SelectionRemove = 0x8008,
139 SelectionWithin = 0x8009,
140 StateChanged = 0x800A,
141 LocationChanged = 0x800B,
142 NameChanged = 0x800C,
143 DescriptionChanged = 0x800D,
144 ValueChanged = 0x800E,
145 ParentChanged = 0x800F,
146 HelpChanged = 0x80A0,
147 DefaultActionChanged = 0x80B0,
148 AcceleratorChanged = 0x80C0,
153 // 64 bit enums seem hard on some platforms (windows...)
154 // which makes using a bit field a sensible alternative
156 // http://msdn.microsoft.com/en-us/library/ms697270.aspx
157 quint64 disabled : 1; // used to be Unavailable
158 quint64 selected : 1;
159 quint64 focusable : 1;
162 quint64 checkable : 1;
164 quint64 checkStateMixed : 1; // used to be Mixed
165 quint64 readOnly : 1;
166 quint64 hotTracked : 1;
167 quint64 defaultButton : 1;
168 quint64 expanded : 1;
169 quint64 collapsed : 1;
171 quint64 expandable : 1;
172 quint64 marqueed : 1;
173 quint64 animated : 1;
174 quint64 invisible : 1;
175 quint64 offscreen : 1;
176 quint64 sizeable : 1;
178 quint64 selfVoicing : 1;
179 quint64 selectable : 1;
181 quint64 traversed : 1;
182 quint64 multiSelectable : 1;
183 quint64 extSelectable : 1;
184 quint64 passwordEdit : 1; // used to be Protected
185 quint64 hasPopup : 1;
188 // IA2 - we chose to not add some IA2 states for now
189 // Below the ones that seem helpful
191 quint64 invalid : 1; // = defunct
192 quint64 editable : 1;
193 quint64 multiLine : 1;
194 quint64 selectableText : 1;
195 quint64 supportsAutoCompletion : 1;
197 // quint64 horizontal : 1;
198 // quint64 vertical : 1;
199 // quint64 invalidEntry : 1;
200 // quint64 managesDescendants : 1;
201 // quint64 singleLine : 1; // we have multi line, this is redundant.
202 // quint64 stale : 1;
203 // quint64 transient : 1;
204 // quint64 pinned : 1;
206 // Apple - see http://mattgemmell.com/2010/12/19/accessibility-for-iphone-and-ipad-apps/
207 // quint64 playsSound : 1;
208 // quint64 summaryElement : 1;
209 // quint64 updatesFrequently : 1;
210 // quint64 adjustable : 1;
211 // more and not included here: http://developer.apple.com/library/mac/#documentation/UserExperience/Reference/Accessibility_RoleAttribute_Ref/Attributes.html
214 // quint64 alertLow : 1;
215 // quint64 alertMedium : 1;
216 // quint64 alertHigh : 1;
219 memset(this, 0, sizeof(State));
229 TitleBar = 0x00000001,
230 MenuBar = 0x00000002,
231 ScrollBar = 0x00000003,
236 AlertMessage = 0x00000008,
239 PopupMenu = 0x0000000B,
240 MenuItem = 0x0000000C,
241 ToolTip = 0x0000000D,
242 Application = 0x0000000E,
243 Document = 0x0000000F,
248 Grouping = 0x00000014,
249 Separator = 0x00000015,
250 ToolBar = 0x00000016,
251 StatusBar = 0x00000017,
253 ColumnHeader = 0x00000019,
254 RowHeader = 0x0000001A,
259 HelpBalloon = 0x0000001F,
260 Assistant = 0x00000020,
262 ListItem = 0x00000022,
264 TreeItem = 0x00000024,
265 PageTab = 0x00000025,
266 PropertyPage = 0x00000026,
267 Indicator = 0x00000027,
268 Graphic = 0x00000028,
269 StaticText = 0x00000029,
270 EditableText = 0x0000002A, // Editable, selectable, etc.
273 PushButton = Button, // deprecated
275 CheckBox = 0x0000002C,
276 RadioButton = 0x0000002D,
277 ComboBox = 0x0000002E,
278 // DropList = 0x0000002F,
279 ProgressBar = 0x00000030,
281 HotkeyField = 0x00000032,
283 SpinBox = 0x00000034,
285 Animation = 0x00000036,
286 Equation = 0x00000037,
287 ButtonDropDown = 0x00000038,
288 ButtonMenu = 0x00000039,
289 ButtonDropGrid = 0x0000003A,
290 Whitespace = 0x0000003B,
291 PageTabList = 0x0000003C,
293 Splitter = 0x0000003E,
294 // Reserved space in case MSAA roles needs to be added
296 // Additional Qt roles where enum value does not map directly to MSAA:
297 LayeredPane = 0x00000080,
298 Terminal = 0x00000081,
299 Desktop = 0x00000082,
300 UserRole = 0x0000ffff
310 UserText = 0x0000ffff
315 Labelled = 0x00000002,
316 Controller = 0x00000004,
317 Controlled = 0x00000008,
318 AllRelations = 0xffffffff
320 Q_DECLARE_FLAGS(Relation, RelationFlag)
325 EditableTextInterface,
333 typedef QAccessibleInterface*(*InterfaceFactory)(const QString &key, QObject*);
334 typedef void(*UpdateHandler)(QAccessibleEvent *event);
335 typedef void(*RootObjectHandler)(QObject*);
337 static void installFactory(InterfaceFactory);
338 static void removeFactory(InterfaceFactory);
339 static UpdateHandler installUpdateHandler(UpdateHandler);
340 static RootObjectHandler installRootObjectHandler(RootObjectHandler);
342 static QAccessibleInterface *queryAccessibleInterface(QObject *);
343 #if QT_DEPRECATED_SINCE(5, 0)
344 QT_DEPRECATED static inline void updateAccessibility(QObject *object, int child, Event reason);
346 static void updateAccessibility(QAccessibleEvent *event);
348 static bool isActive();
349 static void setRootObject(QObject *object);
351 static void cleanup();
354 static UpdateHandler updateHandler;
355 static RootObjectHandler rootObjectHandler;
358 This class is purely a collection of enums and static functions,
359 it is not supposed to be instantiated.
364 Q_GUI_EXPORT bool operator==(const QAccessible::State &first, const QAccessible::State &second);
366 Q_DECLARE_OPERATORS_FOR_FLAGS(QAccessible::Relation)
368 class QAccessible2Interface;
369 class QAccessibleTextInterface;
370 class QAccessibleEditableTextInterface;
371 class QAccessibleValueInterface;
372 class QAccessibleActionInterface;
373 class QAccessibleImageInterface;
374 class QAccessibleTableInterface;
375 class QAccessibleTableCellInterface;
377 class Q_GUI_EXPORT QAccessibleInterface
380 virtual ~QAccessibleInterface() {}
381 // check for valid pointers
382 virtual bool isValid() const = 0;
383 virtual QObject *object() const = 0;
384 virtual QWindow *window() const;
387 virtual QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > relations(QAccessible::Relation match = QAccessible::AllRelations) const;
388 virtual QAccessibleInterface *focusChild() const;
390 virtual QAccessibleInterface *childAt(int x, int y) const = 0;
392 // navigation, hierarchy
393 virtual QAccessibleInterface *parent() const = 0;
394 virtual QAccessibleInterface *child(int index) const = 0;
395 virtual int childCount() const = 0;
396 virtual int indexOfChild(const QAccessibleInterface *) const = 0;
398 // properties and state
399 virtual QString text(QAccessible::Text t) const = 0;
400 virtual void setText(QAccessible::Text t, const QString &text) = 0;
401 virtual QRect rect() const = 0;
402 virtual QAccessible::Role role() const = 0;
403 virtual QAccessible::State state() const = 0;
405 virtual QColor foregroundColor() const;
406 virtual QColor backgroundColor() const;
408 inline QAccessibleTextInterface *textInterface()
409 { return reinterpret_cast<QAccessibleTextInterface *>(interface_cast(QAccessible::TextInterface)); }
411 inline QAccessibleEditableTextInterface *editableTextInterface()
412 { return reinterpret_cast<QAccessibleEditableTextInterface *>(interface_cast(QAccessible::EditableTextInterface)); }
414 inline QAccessibleValueInterface *valueInterface()
415 { return reinterpret_cast<QAccessibleValueInterface *>(interface_cast(QAccessible::ValueInterface)); }
417 inline QAccessibleActionInterface *actionInterface()
418 { return reinterpret_cast<QAccessibleActionInterface *>(interface_cast(QAccessible::ActionInterface)); }
420 inline QAccessibleImageInterface *imageInterface()
421 { return reinterpret_cast<QAccessibleImageInterface *>(interface_cast(QAccessible::ImageInterface)); }
423 inline QAccessibleTableInterface *tableInterface()
424 { return reinterpret_cast<QAccessibleTableInterface *>(interface_cast(QAccessible::TableInterface)); }
426 inline QAccessibleTableCellInterface *tableCellInterface()
427 { return reinterpret_cast<QAccessibleTableCellInterface *>(interface_cast(QAccessible::TableCellInterface)); }
429 virtual void virtual_hook(int id, void *data);
431 virtual void *interface_cast(QAccessible::InterfaceType)
436 class Q_GUI_EXPORT QAccessibleEvent
438 Q_DISABLE_COPY(QAccessibleEvent)
440 inline QAccessibleEvent(QObject *obj, QAccessible::Event typ)
441 : m_type(typ), m_object(obj), m_child(-1)
444 // All events below have a subclass of QAccessibleEvent.
445 // Use the subclass, since it's expected that it's possible to cast to that.
446 Q_ASSERT(m_type != QAccessible::ValueChanged);
447 Q_ASSERT(m_type != QAccessible::StateChanged);
448 Q_ASSERT(m_type != QAccessible::TextCaretMoved);
449 Q_ASSERT(m_type != QAccessible::TextSelectionChanged);
450 Q_ASSERT(m_type != QAccessible::TextInserted);
451 Q_ASSERT(m_type != QAccessible::TextRemoved);
452 Q_ASSERT(m_type != QAccessible::TextUpdated);
453 Q_ASSERT(m_type != QAccessible::TableModelChanged);
456 virtual ~QAccessibleEvent()
459 QAccessible::Event type() const { return m_type; }
460 QObject *object() const { return m_object; }
462 void setChild(int chld) { m_child = chld; }
463 int child() const { return m_child; }
465 QAccessibleInterface *accessibleInterface() const;
468 QAccessible::Event m_type;
473 class Q_GUI_EXPORT QAccessibleStateChangeEvent :public QAccessibleEvent
476 inline QAccessibleStateChangeEvent(QObject *obj, QAccessible::State state)
477 : QAccessibleEvent(obj, QAccessible::InvalidEvent), m_changedStates(state)
479 m_type = QAccessible::StateChanged;
482 QAccessible::State changedStates() const {
483 return m_changedStates;
487 QAccessible::State m_changedStates;
490 // Update the cursor and optionally the selection.
491 class Q_GUI_EXPORT QAccessibleTextCursorEvent : public QAccessibleEvent
494 inline QAccessibleTextCursorEvent(QObject *obj, int cursorPos)
495 : QAccessibleEvent(obj, QAccessible::InvalidEvent)
496 , m_cursorPosition(cursorPos)
498 m_type = QAccessible::TextCaretMoved;
501 void setCursorPosition(int position) { m_cursorPosition = position; }
502 int cursorPosition() const { return m_cursorPosition; }
505 int m_cursorPosition;
508 // Updates the cursor position simultaneously. By default the cursor is set to the end of the selection.
509 class Q_GUI_EXPORT QAccessibleTextSelectionEvent : public QAccessibleTextCursorEvent
512 inline QAccessibleTextSelectionEvent(QObject *obj, int start, int end)
513 : QAccessibleTextCursorEvent(obj, (start == -1) ? 0 : end)
514 , m_selectionStart(start), m_selectionEnd(end)
516 m_type = QAccessible::TextSelectionChanged;
519 void setSelection(int start, int end) {
520 m_selectionStart = start;
521 m_selectionEnd = end;
524 int selectionStart() const { return m_selectionStart; }
525 int selectionEnd() const { return m_selectionEnd; }
528 int m_selectionStart;
532 class Q_GUI_EXPORT QAccessibleTextInsertEvent : public QAccessibleTextCursorEvent
535 inline QAccessibleTextInsertEvent(QObject *obj, int position, const QString &text)
536 : QAccessibleTextCursorEvent(obj, position + text.length())
537 , m_position(position), m_text(text)
539 m_type = QAccessible::TextInserted;
542 QString textInserted() const {
545 int changePosition() const {
554 class Q_GUI_EXPORT QAccessibleTextRemoveEvent : public QAccessibleTextCursorEvent
557 inline QAccessibleTextRemoveEvent(QObject *obj, int position, const QString &text)
558 : QAccessibleTextCursorEvent(obj, position)
559 , m_position(position), m_text(text)
561 m_type = QAccessible::TextRemoved;
564 QString textRemoved() const {
567 int changePosition() const {
576 class Q_GUI_EXPORT QAccessibleTextUpdateEvent : public QAccessibleTextCursorEvent
579 inline QAccessibleTextUpdateEvent(QObject *obj, int position, const QString &oldText, const QString &text)
580 : QAccessibleTextCursorEvent(obj, position + text.length())
581 , m_position(position), m_oldText(oldText), m_text(text)
583 m_type = QAccessible::TextUpdated;
585 QString textRemoved() const {
588 QString textInserted() const {
591 int changePosition() const {
601 class Q_GUI_EXPORT QAccessibleValueChangeEvent : public QAccessibleEvent
604 inline QAccessibleValueChangeEvent(QObject *obj, const QVariant &val)
605 : QAccessibleEvent(obj, QAccessible::InvalidEvent)
608 m_type = QAccessible::ValueChanged;
611 void setValue(const QVariant & val) { m_value= val; }
612 QVariant value() const { return m_value; }
618 class Q_GUI_EXPORT QAccessibleTableModelChangeEvent : public QAccessibleEvent
621 enum ModelChangeType {
630 inline QAccessibleTableModelChangeEvent(QObject *obj, ModelChangeType changeType)
631 : QAccessibleEvent(obj, QAccessible::InvalidEvent)
632 , m_modelChangeType(changeType)
633 , m_firstRow(-1), m_firstColumn(-1), m_lastRow(-1), m_lastColumn(-1)
635 m_type = QAccessible::TableModelChanged;
637 void setModelChangeType(ModelChangeType changeType) { m_modelChangeType = changeType; }
638 ModelChangeType modelChangeType() const { return m_modelChangeType; }
640 void setFirstRow(int row) { m_firstRow = row; }
641 void setFirstColumn(int col) { m_firstColumn = col; }
642 void setLastRow(int row) { m_lastRow = row; }
643 void setLastColumn(int col) { m_lastColumn = col; }
644 int firstRow() const { return m_firstRow; }
645 int firstColumn() const { return m_firstColumn; }
646 int lastRow() const { return m_lastRow; }
647 int lastColumn() const { return m_lastColumn; }
650 ModelChangeType m_modelChangeType;
657 #define QAccessibleInterface_iid "org.qt-project.Qt.QAccessibleInterface"
658 Q_DECLARE_INTERFACE(QAccessibleInterface, QAccessibleInterface_iid)
660 Q_GUI_EXPORT const char *qAccessibleRoleString(QAccessible::Role role);
661 Q_GUI_EXPORT const char *qAccessibleEventString(QAccessible::Event event);
663 #ifndef QT_NO_DEBUG_STREAM
664 Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAccessibleInterface *iface);
665 Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAccessibleEvent &ev);
668 #if QT_DEPRECATED_SINCE(5, 0)
669 inline void QAccessible::updateAccessibility(QObject *object, int child, Event reason)
673 QAccessibleEvent ev(object, reason);
675 updateAccessibility(&ev);
683 #endif // QACCESSIBLE_H