Accessibility: add text update events
[profile/ivi/qtbase.git] / src / gui / accessible / qaccessible.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QACCESSIBLE_H
43 #define QACCESSIBLE_H
44
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>
53
54 QT_BEGIN_HEADER
55
56 QT_BEGIN_NAMESPACE
57
58
59 #ifndef QT_NO_ACCESSIBILITY
60
61 class QAccessibleInterface;
62 class QAccessibleEvent;
63 class QWindow;
64
65 // We need to inherit QObject to expose the enums to QML.
66 class Q_GUI_EXPORT QAccessible
67 #ifndef qdoc
68         :public QObject
69 #endif
70 {
71     Q_OBJECT
72     Q_ENUMS(Role Event State)
73 public:
74
75     enum Event {
76         SoundPlayed          = 0x0001,
77         Alert                = 0x0002,
78         ForegroundChanged    = 0x0003,
79         MenuStart            = 0x0004,
80         MenuEnd              = 0x0005,
81         PopupMenuStart       = 0x0006,
82         PopupMenuEnd         = 0x0007,
83         ContextHelpStart     = 0x000C,
84         ContextHelpEnd       = 0x000D,
85         DragDropStart        = 0x000E,
86         DragDropEnd          = 0x000F,
87         DialogStart          = 0x0010,
88         DialogEnd            = 0x0011,
89         ScrollingStart       = 0x0012,
90         ScrollingEnd         = 0x0013,
91
92         MenuCommand          = 0x0018,
93
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,
129
130         ObjectCreated        = 0x8000,
131         ObjectDestroyed      = 0x8001,
132         ObjectShow           = 0x8002,
133         ObjectHide           = 0x8003,
134         ObjectReorder        = 0x8004,
135         Focus                = 0x8005,
136         Selection            = 0x8006,
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,
149
150         InvalidEvent
151     };
152
153     // 64 bit enums seem hard on some platforms (windows...)
154     // which makes using a bit field a sensible alternative
155     struct State {
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;
160         quint64 focused : 1;
161         quint64 pressed : 1;
162         quint64 checkable : 1;
163         quint64 checked : 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;
170         quint64 busy : 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;
177         quint64 movable : 1;
178         quint64 selfVoicing : 1;
179         quint64 selectable : 1;
180         quint64 linked : 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;
186         quint64 modal : 1;
187
188         // IA2 - we chose to not add some IA2 states for now
189         // Below the ones that seem helpful
190         quint64 active : 1;
191         quint64 invalid : 1; // = defunct
192         quint64 editable : 1;
193         quint64 multiLine : 1;
194         quint64 selectableText : 1;
195         quint64 supportsAutoCompletion : 1;
196
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;
205
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
212
213         // MSAA
214         // quint64 alertLow : 1;
215         // quint64 alertMedium : 1;
216         // quint64 alertHigh : 1;
217
218         State() {
219             qMemSet(this, 0, sizeof(State));
220         }
221     };
222
223
224
225
226
227     enum Role {
228         NoRole         = 0x00000000,
229         TitleBar       = 0x00000001,
230         MenuBar        = 0x00000002,
231         ScrollBar      = 0x00000003,
232         Grip           = 0x00000004,
233         Sound          = 0x00000005,
234         Cursor         = 0x00000006,
235         Caret          = 0x00000007,
236         AlertMessage   = 0x00000008,
237         Window         = 0x00000009,
238         Client         = 0x0000000A,
239         PopupMenu      = 0x0000000B,
240         MenuItem       = 0x0000000C,
241         ToolTip        = 0x0000000D,
242         Application    = 0x0000000E,
243         Document       = 0x0000000F,
244         Pane           = 0x00000010,
245         Chart          = 0x00000011,
246         Dialog         = 0x00000012,
247         Border         = 0x00000013,
248         Grouping       = 0x00000014,
249         Separator      = 0x00000015,
250         ToolBar        = 0x00000016,
251         StatusBar      = 0x00000017,
252         Table          = 0x00000018,
253         ColumnHeader   = 0x00000019,
254         RowHeader      = 0x0000001A,
255         Column         = 0x0000001B,
256         Row            = 0x0000001C,
257         Cell           = 0x0000001D,
258         Link           = 0x0000001E,
259         HelpBalloon    = 0x0000001F,
260         Assistant      = 0x00000020,
261         List           = 0x00000021,
262         ListItem       = 0x00000022,
263         Tree           = 0x00000023,
264         TreeItem       = 0x00000024,
265         PageTab        = 0x00000025,
266         PropertyPage   = 0x00000026,
267         Indicator      = 0x00000027,
268         Graphic        = 0x00000028,
269         StaticText     = 0x00000029,
270         EditableText   = 0x0000002A,  // Editable, selectable, etc.
271         Button         = 0x0000002B,
272 #ifndef qdoc
273         PushButton     = Button, // deprecated
274 #endif
275         CheckBox       = 0x0000002C,
276         RadioButton    = 0x0000002D,
277         ComboBox       = 0x0000002E,
278         // DropList       = 0x0000002F,
279         ProgressBar    = 0x00000030,
280         Dial           = 0x00000031,
281         HotkeyField    = 0x00000032,
282         Slider         = 0x00000033,
283         SpinBox        = 0x00000034,
284         Canvas         = 0x00000035,
285         Animation      = 0x00000036,
286         Equation       = 0x00000037,
287         ButtonDropDown = 0x00000038,
288         ButtonMenu     = 0x00000039,
289         ButtonDropGrid = 0x0000003A,
290         Whitespace     = 0x0000003B,
291         PageTabList    = 0x0000003C,
292         Clock          = 0x0000003D,
293         Splitter       = 0x0000003E,
294         // Additional Qt roles where enum value does not map directly to MSAA:
295         LayeredPane    = 0x0000003F,
296         Terminal       = 0x00000040,
297         Desktop        = 0x00000041,
298         UserRole       = 0x0000ffff
299     };
300
301     enum Text {
302         Name         = 0,
303         Description,
304         Value,
305         Help,
306         Accelerator,
307         DebugDescription,
308         UserText     = 0x0000ffff
309     };
310
311     enum RelationFlag {
312         Label         = 0x00000001,
313         Labelled      = 0x00000002,
314         Controller    = 0x00000004,
315         Controlled    = 0x00000008,
316         AllRelations  = 0xffffffff
317     };
318     Q_DECLARE_FLAGS(Relation, RelationFlag)
319
320     enum InterfaceType
321     {
322         TextInterface,
323         EditableTextInterface,
324         ValueInterface,
325         ActionInterface,
326         ImageInterface,
327         TableInterface,
328         TableCellInterface
329     };
330
331     typedef QAccessibleInterface*(*InterfaceFactory)(const QString &key, QObject*);
332     typedef void(*UpdateHandler)(QAccessibleEvent *event);
333     typedef void(*RootObjectHandler)(QObject*);
334
335     static void installFactory(InterfaceFactory);
336     static void removeFactory(InterfaceFactory);
337     static UpdateHandler installUpdateHandler(UpdateHandler);
338     static RootObjectHandler installRootObjectHandler(RootObjectHandler);
339
340     static QAccessibleInterface *queryAccessibleInterface(QObject *);
341
342     QT_DEPRECATED static void updateAccessibility(QObject *object, int child, Event reason);
343     static void updateAccessibility(QAccessibleEvent *event);
344
345     static bool isActive();
346     static void setRootObject(QObject *object);
347
348     static void cleanup();
349
350 private:
351     static UpdateHandler updateHandler;
352     static RootObjectHandler rootObjectHandler;
353
354     /*! @internal
355       This class is purely a collection of enums and static functions,
356       it is not supposed to be instantiated.
357     */
358     QAccessible() {}
359 };
360
361 Q_GUI_EXPORT bool operator==(const QAccessible::State &first, const QAccessible::State &second);
362
363 Q_DECLARE_OPERATORS_FOR_FLAGS(QAccessible::Relation)
364
365 class QAccessible2Interface;
366 class QAccessibleTextInterface;
367 class QAccessibleEditableTextInterface;
368 class QAccessibleValueInterface;
369 class QAccessibleActionInterface;
370 class QAccessibleImageInterface;
371 class QAccessibleTableInterface;
372 class QAccessibleTableCellInterface;
373
374 class Q_GUI_EXPORT QAccessibleInterface
375 {
376 public:
377     virtual ~QAccessibleInterface() {}
378     // check for valid pointers
379     virtual bool isValid() const = 0;
380     virtual QObject *object() const = 0;
381     virtual QWindow *window() const;
382
383     // relations
384     virtual QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > relations(QAccessible::Relation match = QAccessible::AllRelations) const;
385     virtual QAccessibleInterface *focusChild() const;
386
387     virtual QAccessibleInterface *childAt(int x, int y) const = 0;
388
389     // navigation, hierarchy
390     virtual QAccessibleInterface *parent() const = 0;
391     virtual QAccessibleInterface *child(int index) const = 0;
392     virtual int childCount() const = 0;
393     virtual int indexOfChild(const QAccessibleInterface *) const = 0;
394
395     // properties and state
396     virtual QString text(QAccessible::Text t) const = 0;
397     virtual void setText(QAccessible::Text t, const QString &text) = 0;
398     virtual QRect rect() const = 0;
399     virtual QAccessible::Role role() const = 0;
400     virtual QAccessible::State state() const = 0;
401
402     virtual QColor foregroundColor() const;
403     virtual QColor backgroundColor() const;
404
405     inline QAccessibleTextInterface *textInterface()
406     { return reinterpret_cast<QAccessibleTextInterface *>(interface_cast(QAccessible::TextInterface)); }
407
408     inline QAccessibleEditableTextInterface *editableTextInterface()
409     { return reinterpret_cast<QAccessibleEditableTextInterface *>(interface_cast(QAccessible::EditableTextInterface)); }
410
411     inline QAccessibleValueInterface *valueInterface()
412     { return reinterpret_cast<QAccessibleValueInterface *>(interface_cast(QAccessible::ValueInterface)); }
413
414     inline QAccessibleActionInterface *actionInterface()
415     { return reinterpret_cast<QAccessibleActionInterface *>(interface_cast(QAccessible::ActionInterface)); }
416
417     inline QAccessibleImageInterface *imageInterface()
418     { return reinterpret_cast<QAccessibleImageInterface *>(interface_cast(QAccessible::ImageInterface)); }
419
420     inline QAccessibleTableInterface *tableInterface()
421     { return reinterpret_cast<QAccessibleTableInterface *>(interface_cast(QAccessible::TableInterface)); }
422
423     inline QAccessibleTableCellInterface *tableCellInterface()
424     { return reinterpret_cast<QAccessibleTableCellInterface *>(interface_cast(QAccessible::TableCellInterface)); }
425
426     virtual void virtual_hook(int id, void *data);
427
428     virtual void *interface_cast(QAccessible::InterfaceType)
429     { return 0; }
430 private:
431 };
432
433 class Q_GUI_EXPORT QAccessibleEvent
434 {
435     Q_DISABLE_COPY(QAccessibleEvent)
436 public:
437     inline QAccessibleEvent(QAccessible::Event typ, QObject *obj, int chld = -1)
438         : m_type(typ), m_object(obj), m_child(chld)
439     {
440         Q_ASSERT(obj);
441         // All events below have a subclass of QAccessibleEvent.
442         // Use the subclass, since it's expected that it's possible to cast to that.
443         Q_ASSERT(m_type != QAccessible::ValueChanged);
444         Q_ASSERT(m_type != QAccessible::StateChanged);
445         Q_ASSERT(m_type != QAccessible::TextCaretMoved);
446         Q_ASSERT(m_type != QAccessible::TextSelectionChanged);
447         Q_ASSERT(m_type != QAccessible::TextInserted);
448         Q_ASSERT(m_type != QAccessible::TextRemoved);
449         Q_ASSERT(m_type != QAccessible::TextUpdated);
450     }
451
452     virtual ~QAccessibleEvent()
453     {}
454
455     QAccessible::Event type() const { return m_type; }
456     QObject *object() const { return m_object; }
457     int child() const { return m_child; }
458
459     QAccessibleInterface *accessibleInterface() const;
460
461 protected:
462     QAccessible::Event m_type;
463     QObject *m_object;
464     int m_child;
465 };
466
467 class Q_GUI_EXPORT QAccessibleStateChangeEvent :public QAccessibleEvent
468 {
469 public:
470     inline QAccessibleStateChangeEvent(QAccessible::State state, QObject *obj, int chld = -1)
471         : QAccessibleEvent(QAccessible::InvalidEvent, obj, chld), m_changedStates(state)
472     {
473         m_type = QAccessible::StateChanged;
474     }
475
476     QAccessible::State changedStates() const {
477         return m_changedStates;
478     }
479
480 protected:
481     QAccessible::State m_changedStates;
482 };
483
484 // Update the cursor and optionally the selection.
485 class Q_GUI_EXPORT QAccessibleTextCursorEvent : public QAccessibleEvent
486 {
487 public:
488     inline QAccessibleTextCursorEvent(int cursorPos, QObject *obj, int chld = -1)
489         : QAccessibleEvent(QAccessible::InvalidEvent, obj, chld)
490       , m_cursorPosition(cursorPos)
491     {
492         m_type = QAccessible::TextCaretMoved;
493     }
494
495     void setCursorPosition(int position) { m_cursorPosition = position; }
496     int cursorPosition() const { return m_cursorPosition; }
497
498 protected:
499     int m_cursorPosition;
500 };
501
502 // Updates the cursor position simultaneously. By default the cursor is set to the end of the selection.
503 class Q_GUI_EXPORT QAccessibleTextSelectionEvent : public QAccessibleTextCursorEvent
504 {
505 public:
506     inline QAccessibleTextSelectionEvent(int start, int end, QObject *obj, int chld = -1)
507         : QAccessibleTextCursorEvent((start == -1) ? 0 : end, obj, chld)
508         , m_selectionStart(start), m_selectionEnd(end)
509     {
510         m_type = QAccessible::TextSelectionChanged;
511     }
512
513     void setSelection(int start, int end) {
514         m_selectionStart = start;
515         m_selectionEnd = end;
516     }
517
518     int selectionStart() const { return m_selectionStart; }
519     int selectionEnd() const { return m_selectionEnd; }
520
521 protected:
522         int m_selectionStart;
523         int m_selectionEnd;
524 };
525
526 class Q_GUI_EXPORT QAccessibleTextInsertEvent : public QAccessibleTextCursorEvent
527 {
528 public:
529     inline QAccessibleTextInsertEvent(int position, const QString &text, QObject *obj, int chld = -1)
530         : QAccessibleTextCursorEvent(position + text.length(), obj, chld)
531         , m_position(position), m_text(text)
532     {
533         m_type = QAccessible::TextInserted;
534     }
535
536     QString textInserted() const {
537         return m_text;
538     }
539     int changePosition() const {
540         return m_position;
541     }
542
543 protected:
544     int m_position;
545     QString m_text;
546 };
547
548 class Q_GUI_EXPORT QAccessibleTextRemoveEvent : public QAccessibleTextCursorEvent
549 {
550 public:
551     inline QAccessibleTextRemoveEvent(int position, const QString &text, QObject *obj, int chld = -1)
552         : QAccessibleTextCursorEvent(position, obj, chld)
553         , m_position(position), m_text(text)
554     {
555         m_type = QAccessible::TextRemoved;
556     }
557
558     QString textRemoved() const {
559         return m_text;
560     }
561     int changePosition() const {
562         return m_position;
563     }
564
565 protected:
566     int m_position;
567     QString m_text;
568 };
569
570 class Q_GUI_EXPORT QAccessibleTextUpdateEvent : public QAccessibleTextCursorEvent
571 {
572 public:
573     inline QAccessibleTextUpdateEvent(int position, const QString &oldText, const QString &text, QObject *obj, int chld = -1)
574         : QAccessibleTextCursorEvent(position + text.length(), obj, chld)
575         , m_position(position), m_oldText(oldText), m_text(text)
576     {
577         m_type = QAccessible::TextUpdated;
578     }
579     QString textRemoved() const {
580         return m_oldText;
581     }
582     QString textInserted() const {
583         return m_text;
584     }
585     int changePosition() const {
586         return m_position;
587     }
588
589 protected:
590     int m_position;
591     QString m_oldText;
592     QString m_text;
593 };
594
595 class Q_GUI_EXPORT QAccessibleValueChangeEvent : public QAccessibleEvent
596 {
597 public:
598     inline QAccessibleValueChangeEvent(const QVariant &val, QObject *obj, int chld = -1)
599         : QAccessibleEvent(QAccessible::InvalidEvent, obj, chld)
600       , m_value(val)
601     {
602         m_type = QAccessible::ValueChanged;
603     }
604
605     void setValue(const QVariant & val) { m_value= val; }
606     QVariant value() const { return m_value; }
607
608 protected:
609     QVariant m_value;
610 };
611
612 #define QAccessibleInterface_iid "org.qt-project.Qt.QAccessibleInterface"
613 Q_DECLARE_INTERFACE(QAccessibleInterface, QAccessibleInterface_iid)
614
615 Q_GUI_EXPORT const char *qAccessibleRoleString(QAccessible::Role role);
616 Q_GUI_EXPORT const char *qAccessibleEventString(QAccessible::Event event);
617
618 #ifndef QT_NO_DEBUG_STREAM
619 Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAccessibleInterface *iface);
620 #endif
621
622 #endif // QT_NO_ACCESSIBILITY
623
624 QT_END_NAMESPACE
625
626 QT_END_HEADER
627
628 #endif // QACCESSIBLE_H