1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
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 The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/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 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #include <QtGui/qtguiglobal.h> |
41 | |
42 | #ifndef QT_NO_ACCESSIBILITY |
43 | #ifndef QACCESSIBLE_H |
44 | #define QACCESSIBLE_H |
45 | |
46 | #include <QtCore/qcoreapplication.h> |
47 | #include <QtCore/qdebug.h> |
48 | #include <QtCore/qglobal.h> |
49 | #include <QtCore/qobject.h> |
50 | #include <QtCore/qrect.h> |
51 | #include <QtCore/qset.h> |
52 | #include <QtCore/qvector.h> |
53 | #include <QtCore/qvariant.h> |
54 | #include <QtGui/qcolor.h> |
55 | #include <QtGui/qevent.h> |
56 | |
57 | #include <stdlib.h> |
58 | |
59 | QT_BEGIN_NAMESPACE |
60 | |
61 | class QAccessibleInterface; |
62 | class QAccessibleEvent; |
63 | class QWindow; |
64 | class QTextCursor; |
65 | |
66 | class Q_GUI_EXPORT QAccessible |
67 | { |
68 | Q_GADGET |
69 | public: |
70 | |
71 | enum Event { |
72 | SoundPlayed = 0x0001, |
73 | Alert = 0x0002, |
74 | ForegroundChanged = 0x0003, |
75 | = 0x0004, |
76 | = 0x0005, |
77 | = 0x0006, |
78 | = 0x0007, |
79 | ContextHelpStart = 0x000C, |
80 | ContextHelpEnd = 0x000D, |
81 | DragDropStart = 0x000E, |
82 | DragDropEnd = 0x000F, |
83 | DialogStart = 0x0010, |
84 | DialogEnd = 0x0011, |
85 | ScrollingStart = 0x0012, |
86 | ScrollingEnd = 0x0013, |
87 | |
88 | MenuCommand = 0x0018, |
89 | |
90 | // Values from IAccessible2 |
91 | ActionChanged = 0x0101, |
92 | ActiveDescendantChanged = 0x0102, |
93 | AttributeChanged = 0x0103, |
94 | DocumentContentChanged = 0x0104, |
95 | DocumentLoadComplete = 0x0105, |
96 | DocumentLoadStopped = 0x0106, |
97 | DocumentReload = 0x0107, |
98 | HyperlinkEndIndexChanged = 0x0108, |
99 | HyperlinkNumberOfAnchorsChanged = 0x0109, |
100 | HyperlinkSelectedLinkChanged = 0x010A, |
101 | HypertextLinkActivated = 0x010B, |
102 | HypertextLinkSelected = 0x010C, |
103 | HyperlinkStartIndexChanged = 0x010D, |
104 | HypertextChanged = 0x010E, |
105 | HypertextNLinksChanged = 0x010F, |
106 | ObjectAttributeChanged = 0x0110, |
107 | PageChanged = 0x0111, |
108 | SectionChanged = 0x0112, |
109 | TableCaptionChanged = 0x0113, |
110 | TableColumnDescriptionChanged = 0x0114, |
111 | TableColumnHeaderChanged = 0x0115, |
112 | TableModelChanged = 0x0116, |
113 | TableRowDescriptionChanged = 0x0117, |
114 | = 0x0118, |
115 | TableSummaryChanged = 0x0119, |
116 | TextAttributeChanged = 0x011A, |
117 | TextCaretMoved = 0x011B, |
118 | // TextChanged = 0x011C, is deprecated in IA2, use TextUpdated |
119 | TextColumnChanged = 0x011D, |
120 | TextInserted = 0x011E, |
121 | TextRemoved = 0x011F, |
122 | TextUpdated = 0x0120, |
123 | TextSelectionChanged = 0x0121, |
124 | VisibleDataChanged = 0x0122, |
125 | |
126 | ObjectCreated = 0x8000, |
127 | ObjectDestroyed = 0x8001, |
128 | ObjectShow = 0x8002, |
129 | ObjectHide = 0x8003, |
130 | ObjectReorder = 0x8004, |
131 | Focus = 0x8005, |
132 | Selection = 0x8006, |
133 | SelectionAdd = 0x8007, |
134 | SelectionRemove = 0x8008, |
135 | SelectionWithin = 0x8009, |
136 | StateChanged = 0x800A, |
137 | LocationChanged = 0x800B, |
138 | NameChanged = 0x800C, |
139 | DescriptionChanged = 0x800D, |
140 | ValueChanged = 0x800E, |
141 | ParentChanged = 0x800F, |
142 | HelpChanged = 0x80A0, |
143 | DefaultActionChanged = 0x80B0, |
144 | AcceleratorChanged = 0x80C0, |
145 | |
146 | InvalidEvent |
147 | }; |
148 | Q_ENUM(Event) |
149 | |
150 | // 64 bit enums seem hard on some platforms (windows...) |
151 | // which makes using a bit field a sensible alternative |
152 | struct State { |
153 | // http://msdn.microsoft.com/en-us/library/ms697270.aspx |
154 | quint64 disabled : 1; // used to be Unavailable |
155 | quint64 selected : 1; |
156 | quint64 focusable : 1; |
157 | quint64 focused : 1; |
158 | quint64 pressed : 1; |
159 | quint64 checkable : 1; |
160 | quint64 checked : 1; |
161 | quint64 checkStateMixed : 1; // used to be Mixed |
162 | quint64 readOnly : 1; |
163 | quint64 hotTracked : 1; |
164 | quint64 defaultButton : 1; |
165 | quint64 expanded : 1; |
166 | quint64 collapsed : 1; |
167 | quint64 busy : 1; |
168 | quint64 expandable : 1; |
169 | quint64 marqueed : 1; |
170 | quint64 animated : 1; |
171 | quint64 invisible : 1; |
172 | quint64 offscreen : 1; |
173 | quint64 sizeable : 1; |
174 | quint64 movable : 1; |
175 | quint64 selfVoicing : 1; |
176 | quint64 selectable : 1; |
177 | quint64 linked : 1; |
178 | quint64 traversed : 1; |
179 | quint64 multiSelectable : 1; |
180 | quint64 extSelectable : 1; |
181 | quint64 passwordEdit : 1; // used to be Protected |
182 | quint64 : 1; |
183 | quint64 modal : 1; |
184 | |
185 | // IA2 - we chose to not add some IA2 states for now |
186 | // Below the ones that seem helpful |
187 | quint64 active : 1; |
188 | quint64 invalid : 1; // = defunct |
189 | quint64 editable : 1; |
190 | quint64 multiLine : 1; |
191 | quint64 selectableText : 1; |
192 | quint64 supportsAutoCompletion : 1; |
193 | |
194 | quint64 searchEdit : 1; |
195 | |
196 | // quint64 horizontal : 1; |
197 | // quint64 vertical : 1; |
198 | // quint64 invalidEntry : 1; |
199 | // quint64 managesDescendants : 1; |
200 | // quint64 singleLine : 1; // we have multi line, this is redundant. |
201 | // quint64 stale : 1; |
202 | // quint64 transient : 1; |
203 | // quint64 pinned : 1; |
204 | |
205 | // Apple - see http://mattgemmell.com/2010/12/19/accessibility-for-iphone-and-ipad-apps/ |
206 | // quint64 playsSound : 1; |
207 | // quint64 summaryElement : 1; |
208 | // quint64 updatesFrequently : 1; |
209 | // quint64 adjustable : 1; |
210 | // more and not included here: http://developer.apple.com/library/mac/#documentation/UserExperience/Reference/Accessibility_RoleAttribute_Ref/Attributes.html |
211 | |
212 | // MSAA |
213 | // quint64 alertLow : 1; |
214 | // quint64 alertMedium : 1; |
215 | // quint64 alertHigh : 1; |
216 | |
217 | State() { |
218 | memset(s: this, c: 0, n: sizeof(State)); |
219 | } |
220 | }; |
221 | |
222 | |
223 | |
224 | |
225 | |
226 | enum Role { |
227 | NoRole = 0x00000000, |
228 | TitleBar = 0x00000001, |
229 | = 0x00000002, |
230 | ScrollBar = 0x00000003, |
231 | Grip = 0x00000004, |
232 | Sound = 0x00000005, |
233 | Cursor = 0x00000006, |
234 | Caret = 0x00000007, |
235 | AlertMessage = 0x00000008, |
236 | Window = 0x00000009, |
237 | Client = 0x0000000A, |
238 | = 0x0000000B, |
239 | = 0x0000000C, |
240 | ToolTip = 0x0000000D, |
241 | Application = 0x0000000E, |
242 | Document = 0x0000000F, |
243 | Pane = 0x00000010, |
244 | Chart = 0x00000011, |
245 | Dialog = 0x00000012, |
246 | Border = 0x00000013, |
247 | Grouping = 0x00000014, |
248 | Separator = 0x00000015, |
249 | ToolBar = 0x00000016, |
250 | StatusBar = 0x00000017, |
251 | Table = 0x00000018, |
252 | ColumnHeader = 0x00000019, |
253 | = 0x0000001A, |
254 | Column = 0x0000001B, |
255 | Row = 0x0000001C, |
256 | Cell = 0x0000001D, |
257 | Link = 0x0000001E, |
258 | HelpBalloon = 0x0000001F, |
259 | Assistant = 0x00000020, |
260 | List = 0x00000021, |
261 | ListItem = 0x00000022, |
262 | Tree = 0x00000023, |
263 | TreeItem = 0x00000024, |
264 | PageTab = 0x00000025, |
265 | PropertyPage = 0x00000026, |
266 | Indicator = 0x00000027, |
267 | Graphic = 0x00000028, |
268 | StaticText = 0x00000029, |
269 | EditableText = 0x0000002A, // Editable, selectable, etc. |
270 | Button = 0x0000002B, |
271 | #ifndef Q_QDOC |
272 | PushButton = Button, // deprecated |
273 | #endif |
274 | CheckBox = 0x0000002C, |
275 | RadioButton = 0x0000002D, |
276 | ComboBox = 0x0000002E, |
277 | // DropList = 0x0000002F, |
278 | ProgressBar = 0x00000030, |
279 | Dial = 0x00000031, |
280 | HotkeyField = 0x00000032, |
281 | Slider = 0x00000033, |
282 | SpinBox = 0x00000034, |
283 | Canvas = 0x00000035, // MSAA: ROLE_SYSTEM_DIAGRAM - The object represents a graphical image that is used to diagram data. |
284 | Animation = 0x00000036, |
285 | Equation = 0x00000037, |
286 | ButtonDropDown = 0x00000038, // The object represents a button that expands a grid. |
287 | = 0x00000039, |
288 | ButtonDropGrid = 0x0000003A, |
289 | Whitespace = 0x0000003B, // The object represents blank space between other objects. |
290 | PageTabList = 0x0000003C, |
291 | Clock = 0x0000003D, |
292 | Splitter = 0x0000003E, |
293 | // Reserved space in case MSAA roles needs to be added |
294 | |
295 | // Additional Qt roles where enum value does not map directly to MSAA: |
296 | LayeredPane = 0x00000080, |
297 | Terminal = 0x00000081, |
298 | Desktop = 0x00000082, |
299 | Paragraph = 0x00000083, |
300 | WebDocument = 0x00000084, |
301 | Section = 0x00000085, |
302 | Notification = 0x00000086, |
303 | |
304 | // IAccessible2 roles |
305 | // IA2_ROLE_CANVAS = 0x401, // An object that can be drawn into and to manage events from the objects drawn into it |
306 | // IA2_ROLE_CAPTION = 0x402, |
307 | // IA2_ROLE_CHECK_MENU_ITEM = 0x403, |
308 | ColorChooser = 0x404, |
309 | // IA2_ROLE_DATE_EDITOR = 0x405, |
310 | // IA2_ROLE_DESKTOP_ICON = 0x406, |
311 | // IA2_ROLE_DESKTOP_PANE = 0x407, |
312 | // IA2_ROLE_DIRECTORY_PANE = 0x408, |
313 | // IA2_ROLE_EDITBAR = 0x409, |
314 | // IA2_ROLE_EMBEDDED_OBJECT = 0x40A, |
315 | // IA2_ROLE_ENDNOTE = 0x40B, |
316 | // IA2_ROLE_FILE_CHOOSER = 0x40C, |
317 | // IA2_ROLE_FONT_CHOOSER = 0x40D, |
318 | = 0x40E, |
319 | // IA2_ROLE_FOOTNOTE = 0x40F, |
320 | Form = 0x410, |
321 | // some platforms (windows and at-spi) use Frame for regular windows |
322 | // because window was taken for tool/dock windows by MSAA |
323 | // Frame = 0x411, |
324 | // IA2_ROLE_GLASS_PANE = 0x412, |
325 | // IA2_ROLE_HEADER = 0x413, |
326 | Heading = 0x414, |
327 | // IA2_ROLE_ICON = 0x415, |
328 | // IA2_ROLE_IMAGE_MAP = 0x416, |
329 | // IA2_ROLE_INPUT_METHOD_WINDOW = 0x417, |
330 | // IA2_ROLE_INTERNAL_FRAME = 0x418, |
331 | // IA2_ROLE_LABEL = 0x419, |
332 | // IA2_ROLE_LAYERED_PANE = 0x41A, |
333 | Note = 0x41B, |
334 | // IA2_ROLE_OPTION_PANE = 0x41C, |
335 | // IA2_ROLE_PAGE = 0x41D, |
336 | // IA2_ROLE_PARAGRAPH = 0x42E, |
337 | // IA2_ROLE_RADIO_MENU_ITEM = 0x41F, |
338 | // IA2_ROLE_REDUNDANT_OBJECT = 0x420, |
339 | // IA2_ROLE_ROOT_PANE = 0x421, |
340 | // IA2_ROLE_RULER = 0x422, |
341 | // IA2_ROLE_SCROLL_PANE = 0x423, |
342 | // IA2_ROLE_SECTION = 0x424, |
343 | // IA2_ROLE_SHAPE = 0x425, |
344 | // IA2_ROLE_SPLIT_PANE = 0x426, |
345 | // IA2_ROLE_TEAR_OFF_MENU = 0x427, |
346 | // IA2_ROLE_TERMINAL = 0x428, |
347 | // IA2_ROLE_TEXT_FRAME = 0x429, |
348 | // IA2_ROLE_TOGGLE_BUTTON = 0x42A, |
349 | // IA2_ROLE_VIEW_PORT = 0x42B, |
350 | ComplementaryContent = 0x42C, |
351 | |
352 | UserRole = 0x0000ffff |
353 | }; |
354 | Q_ENUM(Role) |
355 | |
356 | enum Text { |
357 | Name = 0, |
358 | Description, |
359 | Value, |
360 | Help, |
361 | Accelerator, |
362 | DebugDescription, |
363 | UserText = 0x0000ffff |
364 | }; |
365 | |
366 | enum RelationFlag { |
367 | Label = 0x00000001, |
368 | Labelled = 0x00000002, |
369 | Controller = 0x00000004, |
370 | Controlled = 0x00000008, |
371 | AllRelations = 0xffffffff |
372 | }; |
373 | Q_DECLARE_FLAGS(Relation, RelationFlag) |
374 | |
375 | enum InterfaceType |
376 | { |
377 | TextInterface, |
378 | EditableTextInterface, |
379 | ValueInterface, |
380 | ActionInterface, |
381 | ImageInterface, |
382 | TableInterface, |
383 | TableCellInterface |
384 | }; |
385 | |
386 | enum TextBoundaryType { |
387 | CharBoundary, |
388 | WordBoundary, |
389 | SentenceBoundary, |
390 | ParagraphBoundary, |
391 | LineBoundary, |
392 | NoBoundary |
393 | }; |
394 | |
395 | typedef QAccessibleInterface*(*InterfaceFactory)(const QString &key, QObject*); |
396 | typedef void(*UpdateHandler)(QAccessibleEvent *event); |
397 | typedef void(*RootObjectHandler)(QObject*); |
398 | |
399 | typedef unsigned Id; |
400 | |
401 | static void installFactory(InterfaceFactory); |
402 | static void removeFactory(InterfaceFactory); |
403 | static UpdateHandler installUpdateHandler(UpdateHandler); |
404 | static RootObjectHandler installRootObjectHandler(RootObjectHandler); |
405 | |
406 | class Q_GUI_EXPORT ActivationObserver |
407 | { |
408 | public: |
409 | virtual ~ActivationObserver(); |
410 | virtual void accessibilityActiveChanged(bool active) = 0; |
411 | }; |
412 | static void installActivationObserver(ActivationObserver *); |
413 | static void removeActivationObserver(ActivationObserver *); |
414 | |
415 | static QAccessibleInterface *queryAccessibleInterface(QObject *); |
416 | static Id uniqueId(QAccessibleInterface *iface); |
417 | static QAccessibleInterface *accessibleInterface(Id uniqueId); |
418 | static Id registerAccessibleInterface(QAccessibleInterface *iface); |
419 | static void deleteAccessibleInterface(Id uniqueId); |
420 | |
421 | |
422 | #if QT_DEPRECATED_SINCE(5, 0) |
423 | QT_DEPRECATED static inline void updateAccessibility(QObject *object, int child, Event reason); |
424 | #endif |
425 | static void updateAccessibility(QAccessibleEvent *event); |
426 | |
427 | static bool isActive(); |
428 | static void setActive(bool active); |
429 | static void setRootObject(QObject *object); |
430 | |
431 | static void cleanup(); |
432 | |
433 | static QPair< int, int > qAccessibleTextBoundaryHelper(const QTextCursor &cursor, TextBoundaryType boundaryType); |
434 | |
435 | private: |
436 | static UpdateHandler updateHandler; |
437 | static RootObjectHandler rootObjectHandler; |
438 | |
439 | QAccessible() {} |
440 | |
441 | friend class QAccessibleCache; |
442 | }; |
443 | |
444 | Q_GUI_EXPORT bool operator==(const QAccessible::State &first, const QAccessible::State &second); |
445 | |
446 | Q_DECLARE_OPERATORS_FOR_FLAGS(QAccessible::Relation) |
447 | |
448 | class QAccessible2Interface; |
449 | class QAccessibleTextInterface; |
450 | class QAccessibleEditableTextInterface; |
451 | class QAccessibleValueInterface; |
452 | class QAccessibleActionInterface; |
453 | class QAccessibleImageInterface; |
454 | class QAccessibleTableInterface; |
455 | class QAccessibleTableCellInterface; |
456 | class QAccessibleTableModelChangeEvent; |
457 | |
458 | class Q_GUI_EXPORT QAccessibleInterface |
459 | { |
460 | protected: |
461 | virtual ~QAccessibleInterface(); |
462 | |
463 | public: |
464 | // check for valid pointers |
465 | virtual bool isValid() const = 0; |
466 | virtual QObject *object() const = 0; |
467 | virtual QWindow *window() const; |
468 | |
469 | // relations |
470 | virtual QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > relations(QAccessible::Relation match = QAccessible::AllRelations) const; |
471 | virtual QAccessibleInterface *focusChild() const; |
472 | |
473 | virtual QAccessibleInterface *childAt(int x, int y) const = 0; |
474 | |
475 | // navigation, hierarchy |
476 | virtual QAccessibleInterface *parent() const = 0; |
477 | virtual QAccessibleInterface *child(int index) const = 0; |
478 | virtual int childCount() const = 0; |
479 | virtual int indexOfChild(const QAccessibleInterface *) const = 0; |
480 | |
481 | // properties and state |
482 | virtual QString text(QAccessible::Text t) const = 0; |
483 | virtual void setText(QAccessible::Text t, const QString &text) = 0; |
484 | virtual QRect rect() const = 0; |
485 | virtual QAccessible::Role role() const = 0; |
486 | virtual QAccessible::State state() const = 0; |
487 | |
488 | virtual QColor foregroundColor() const; |
489 | virtual QColor backgroundColor() const; |
490 | |
491 | inline QAccessibleTextInterface *textInterface() |
492 | { return reinterpret_cast<QAccessibleTextInterface *>(interface_cast(QAccessible::TextInterface)); } |
493 | |
494 | inline QAccessibleEditableTextInterface *editableTextInterface() |
495 | { return reinterpret_cast<QAccessibleEditableTextInterface *>(interface_cast(QAccessible::EditableTextInterface)); } |
496 | |
497 | inline QAccessibleValueInterface *valueInterface() |
498 | { return reinterpret_cast<QAccessibleValueInterface *>(interface_cast(QAccessible::ValueInterface)); } |
499 | |
500 | inline QAccessibleActionInterface *actionInterface() |
501 | { return reinterpret_cast<QAccessibleActionInterface *>(interface_cast(QAccessible::ActionInterface)); } |
502 | |
503 | inline QAccessibleImageInterface *imageInterface() |
504 | { return reinterpret_cast<QAccessibleImageInterface *>(interface_cast(QAccessible::ImageInterface)); } |
505 | |
506 | inline QAccessibleTableInterface *tableInterface() |
507 | { return reinterpret_cast<QAccessibleTableInterface *>(interface_cast(QAccessible::TableInterface)); } |
508 | |
509 | inline QAccessibleTableCellInterface *tableCellInterface() |
510 | { return reinterpret_cast<QAccessibleTableCellInterface *>(interface_cast(QAccessible::TableCellInterface)); } |
511 | |
512 | virtual void virtual_hook(int id, void *data); |
513 | |
514 | virtual void *interface_cast(QAccessible::InterfaceType) |
515 | { return nullptr; } |
516 | |
517 | protected: |
518 | friend class QAccessibleCache; |
519 | }; |
520 | |
521 | class Q_GUI_EXPORT QAccessibleTextInterface |
522 | { |
523 | public: |
524 | virtual ~QAccessibleTextInterface(); |
525 | // selection |
526 | virtual void selection(int selectionIndex, int *startOffset, int *endOffset) const = 0; |
527 | virtual int selectionCount() const = 0; |
528 | virtual void addSelection(int startOffset, int endOffset) = 0; |
529 | virtual void removeSelection(int selectionIndex) = 0; |
530 | virtual void setSelection(int selectionIndex, int startOffset, int endOffset) = 0; |
531 | |
532 | // cursor |
533 | virtual int cursorPosition() const = 0; |
534 | virtual void setCursorPosition(int position) = 0; |
535 | |
536 | // text |
537 | virtual QString text(int startOffset, int endOffset) const = 0; |
538 | virtual QString textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, |
539 | int *startOffset, int *endOffset) const; |
540 | virtual QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, |
541 | int *startOffset, int *endOffset) const; |
542 | virtual QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, |
543 | int *startOffset, int *endOffset) const; |
544 | virtual int characterCount() const = 0; |
545 | |
546 | // character <-> geometry |
547 | virtual QRect characterRect(int offset) const = 0; |
548 | virtual int offsetAtPoint(const QPoint &point) const = 0; |
549 | |
550 | virtual void scrollToSubstring(int startIndex, int endIndex) = 0; |
551 | virtual QString attributes(int offset, int *startOffset, int *endOffset) const = 0; |
552 | }; |
553 | |
554 | class Q_GUI_EXPORT QAccessibleEditableTextInterface |
555 | { |
556 | public: |
557 | virtual ~QAccessibleEditableTextInterface(); |
558 | |
559 | virtual void deleteText(int startOffset, int endOffset) = 0; |
560 | virtual void insertText(int offset, const QString &text) = 0; |
561 | virtual void replaceText(int startOffset, int endOffset, const QString &text) = 0; |
562 | }; |
563 | |
564 | class Q_GUI_EXPORT QAccessibleValueInterface |
565 | { |
566 | public: |
567 | virtual ~QAccessibleValueInterface(); |
568 | |
569 | virtual QVariant currentValue() const = 0; |
570 | virtual void setCurrentValue(const QVariant &value) = 0; |
571 | virtual QVariant maximumValue() const = 0; |
572 | virtual QVariant minimumValue() const = 0; |
573 | virtual QVariant minimumStepSize() const = 0; |
574 | }; |
575 | |
576 | class Q_GUI_EXPORT QAccessibleTableCellInterface |
577 | { |
578 | public: |
579 | virtual ~QAccessibleTableCellInterface(); |
580 | |
581 | virtual bool isSelected() const = 0; |
582 | |
583 | virtual QList<QAccessibleInterface*> columnHeaderCells() const = 0; |
584 | virtual QList<QAccessibleInterface*> () const = 0; |
585 | virtual int columnIndex() const = 0; |
586 | virtual int rowIndex() const = 0; |
587 | virtual int columnExtent() const = 0; |
588 | virtual int rowExtent() const = 0; |
589 | |
590 | virtual QAccessibleInterface* table() const = 0; |
591 | }; |
592 | |
593 | class Q_GUI_EXPORT QAccessibleTableInterface |
594 | { |
595 | public: |
596 | virtual ~QAccessibleTableInterface(); |
597 | |
598 | virtual QAccessibleInterface *caption() const = 0; |
599 | virtual QAccessibleInterface *summary() const = 0; |
600 | |
601 | virtual QAccessibleInterface *cellAt (int row, int column) const = 0; |
602 | virtual int selectedCellCount() const = 0; |
603 | virtual QList<QAccessibleInterface*> selectedCells() const = 0; |
604 | |
605 | virtual QString columnDescription(int column) const = 0; |
606 | virtual QString rowDescription(int row) const = 0; |
607 | virtual int selectedColumnCount() const = 0; |
608 | virtual int selectedRowCount() const = 0; |
609 | virtual int columnCount() const = 0; |
610 | virtual int rowCount() const = 0; |
611 | virtual QList<int> selectedColumns() const = 0; |
612 | virtual QList<int> selectedRows() const = 0; |
613 | virtual bool isColumnSelected(int column) const = 0; |
614 | virtual bool isRowSelected(int row) const = 0; |
615 | virtual bool selectRow(int row) = 0; |
616 | virtual bool selectColumn(int column) = 0; |
617 | virtual bool unselectRow(int row) = 0; |
618 | virtual bool unselectColumn(int column) = 0; |
619 | |
620 | virtual void modelChange(QAccessibleTableModelChangeEvent *event) = 0; |
621 | |
622 | protected: |
623 | friend class QAbstractItemView; |
624 | friend class QAbstractItemViewPrivate; |
625 | }; |
626 | |
627 | class Q_GUI_EXPORT QAccessibleActionInterface |
628 | { |
629 | Q_DECLARE_TR_FUNCTIONS(QAccessibleActionInterface) |
630 | public: |
631 | virtual ~QAccessibleActionInterface(); |
632 | |
633 | virtual QStringList actionNames() const = 0; |
634 | virtual QString localizedActionName(const QString &name) const; |
635 | virtual QString localizedActionDescription(const QString &name) const; |
636 | virtual void doAction(const QString &actionName) = 0; |
637 | virtual QStringList keyBindingsForAction(const QString &actionName) const = 0; |
638 | |
639 | static const QString &pressAction(); |
640 | static const QString &increaseAction(); |
641 | static const QString &decreaseAction(); |
642 | static const QString &(); |
643 | static const QString &setFocusAction(); |
644 | static const QString &toggleAction(); |
645 | static QString scrollLeftAction(); |
646 | static QString scrollRightAction(); |
647 | static QString scrollUpAction(); |
648 | static QString scrollDownAction(); |
649 | static QString nextPageAction(); |
650 | static QString previousPageAction(); |
651 | }; |
652 | |
653 | class Q_GUI_EXPORT QAccessibleImageInterface |
654 | { |
655 | public: |
656 | virtual ~QAccessibleImageInterface(); |
657 | |
658 | virtual QString imageDescription() const = 0; |
659 | virtual QSize imageSize() const = 0; |
660 | virtual QPoint imagePosition() const = 0; |
661 | }; |
662 | |
663 | |
664 | class Q_GUI_EXPORT QAccessibleEvent |
665 | { |
666 | Q_DISABLE_COPY(QAccessibleEvent) |
667 | public: |
668 | |
669 | inline QAccessibleEvent(QObject *obj, QAccessible::Event typ) |
670 | : m_type(typ), m_object(obj), m_child(-1) |
671 | { |
672 | Q_ASSERT(obj); |
673 | // All events below have a subclass of QAccessibleEvent. |
674 | // Use the subclass, since it's expected that it's possible to cast to that. |
675 | Q_ASSERT(m_type != QAccessible::ValueChanged); |
676 | Q_ASSERT(m_type != QAccessible::StateChanged); |
677 | Q_ASSERT(m_type != QAccessible::TextCaretMoved); |
678 | Q_ASSERT(m_type != QAccessible::TextSelectionChanged); |
679 | Q_ASSERT(m_type != QAccessible::TextInserted); |
680 | Q_ASSERT(m_type != QAccessible::TextRemoved); |
681 | Q_ASSERT(m_type != QAccessible::TextUpdated); |
682 | Q_ASSERT(m_type != QAccessible::TableModelChanged); |
683 | } |
684 | |
685 | inline QAccessibleEvent(QAccessibleInterface *iface, QAccessible::Event typ) |
686 | : m_type(typ), m_object(nullptr) |
687 | { |
688 | Q_ASSERT(iface); |
689 | Q_ASSERT(m_type != QAccessible::ValueChanged); |
690 | Q_ASSERT(m_type != QAccessible::StateChanged); |
691 | Q_ASSERT(m_type != QAccessible::TextCaretMoved); |
692 | Q_ASSERT(m_type != QAccessible::TextSelectionChanged); |
693 | Q_ASSERT(m_type != QAccessible::TextInserted); |
694 | Q_ASSERT(m_type != QAccessible::TextRemoved); |
695 | Q_ASSERT(m_type != QAccessible::TextUpdated); |
696 | Q_ASSERT(m_type != QAccessible::TableModelChanged); |
697 | m_uniqueId = QAccessible::uniqueId(iface); |
698 | } |
699 | |
700 | virtual ~QAccessibleEvent(); |
701 | |
702 | QAccessible::Event type() const { return m_type; } |
703 | QObject *object() const { return m_object; } |
704 | QAccessible::Id uniqueId() const; |
705 | |
706 | void setChild(int chld) { m_child = chld; } |
707 | int child() const { return m_child; } |
708 | |
709 | virtual QAccessibleInterface *accessibleInterface() const; |
710 | |
711 | protected: |
712 | QAccessible::Event m_type; |
713 | QObject *m_object; |
714 | union { |
715 | int m_child; |
716 | QAccessible::Id m_uniqueId; |
717 | }; |
718 | |
719 | }; |
720 | |
721 | class Q_GUI_EXPORT QAccessibleStateChangeEvent :public QAccessibleEvent |
722 | { |
723 | public: |
724 | inline QAccessibleStateChangeEvent(QObject *obj, QAccessible::State state) |
725 | : QAccessibleEvent(obj, QAccessible::InvalidEvent), m_changedStates(state) |
726 | { |
727 | m_type = QAccessible::StateChanged; |
728 | } |
729 | inline QAccessibleStateChangeEvent(QAccessibleInterface *iface, QAccessible::State state) |
730 | : QAccessibleEvent(iface, QAccessible::InvalidEvent), m_changedStates(state) |
731 | { |
732 | m_type = QAccessible::StateChanged; |
733 | } |
734 | ~QAccessibleStateChangeEvent(); |
735 | |
736 | QAccessible::State changedStates() const { |
737 | return m_changedStates; |
738 | } |
739 | |
740 | protected: |
741 | QAccessible::State m_changedStates; |
742 | }; |
743 | |
744 | // Update the cursor and optionally the selection. |
745 | class Q_GUI_EXPORT QAccessibleTextCursorEvent : public QAccessibleEvent |
746 | { |
747 | public: |
748 | inline QAccessibleTextCursorEvent(QObject *obj, int cursorPos) |
749 | : QAccessibleEvent(obj, QAccessible::InvalidEvent) |
750 | , m_cursorPosition(cursorPos) |
751 | { |
752 | m_type = QAccessible::TextCaretMoved; |
753 | } |
754 | inline QAccessibleTextCursorEvent(QAccessibleInterface *iface, int cursorPos) |
755 | : QAccessibleEvent(iface, QAccessible::InvalidEvent) |
756 | , m_cursorPosition(cursorPos) |
757 | { |
758 | m_type = QAccessible::TextCaretMoved; |
759 | } |
760 | |
761 | ~QAccessibleTextCursorEvent(); |
762 | |
763 | void setCursorPosition(int position) { m_cursorPosition = position; } |
764 | int cursorPosition() const { return m_cursorPosition; } |
765 | |
766 | protected: |
767 | int m_cursorPosition; |
768 | }; |
769 | |
770 | // Updates the cursor position simultaneously. By default the cursor is set to the end of the selection. |
771 | class Q_GUI_EXPORT QAccessibleTextSelectionEvent : public QAccessibleTextCursorEvent |
772 | { |
773 | public: |
774 | inline QAccessibleTextSelectionEvent(QObject *obj, int start, int end) |
775 | : QAccessibleTextCursorEvent(obj, (start == -1) ? 0 : end) |
776 | , m_selectionStart(start), m_selectionEnd(end) |
777 | { |
778 | m_type = QAccessible::TextSelectionChanged; |
779 | } |
780 | inline QAccessibleTextSelectionEvent(QAccessibleInterface *iface, int start, int end) |
781 | : QAccessibleTextCursorEvent(iface, (start == -1) ? 0 : end) |
782 | , m_selectionStart(start), m_selectionEnd(end) |
783 | { |
784 | m_type = QAccessible::TextSelectionChanged; |
785 | } |
786 | |
787 | ~QAccessibleTextSelectionEvent(); |
788 | |
789 | void setSelection(int start, int end) { |
790 | m_selectionStart = start; |
791 | m_selectionEnd = end; |
792 | } |
793 | |
794 | int selectionStart() const { return m_selectionStart; } |
795 | int selectionEnd() const { return m_selectionEnd; } |
796 | |
797 | protected: |
798 | int m_selectionStart; |
799 | int m_selectionEnd; |
800 | }; |
801 | |
802 | class Q_GUI_EXPORT QAccessibleTextInsertEvent : public QAccessibleTextCursorEvent |
803 | { |
804 | public: |
805 | inline QAccessibleTextInsertEvent(QObject *obj, int position, const QString &text) |
806 | : QAccessibleTextCursorEvent(obj, position + text.length()) |
807 | , m_position(position), m_text(text) |
808 | { |
809 | m_type = QAccessible::TextInserted; |
810 | } |
811 | inline QAccessibleTextInsertEvent(QAccessibleInterface *iface, int position, const QString &text) |
812 | : QAccessibleTextCursorEvent(iface, position + text.length()) |
813 | , m_position(position), m_text(text) |
814 | { |
815 | m_type = QAccessible::TextInserted; |
816 | } |
817 | |
818 | ~QAccessibleTextInsertEvent(); |
819 | |
820 | QString textInserted() const { |
821 | return m_text; |
822 | } |
823 | int changePosition() const { |
824 | return m_position; |
825 | } |
826 | |
827 | protected: |
828 | int m_position; |
829 | QString m_text; |
830 | }; |
831 | |
832 | class Q_GUI_EXPORT QAccessibleTextRemoveEvent : public QAccessibleTextCursorEvent |
833 | { |
834 | public: |
835 | inline QAccessibleTextRemoveEvent(QObject *obj, int position, const QString &text) |
836 | : QAccessibleTextCursorEvent(obj, position) |
837 | , m_position(position), m_text(text) |
838 | { |
839 | m_type = QAccessible::TextRemoved; |
840 | } |
841 | inline QAccessibleTextRemoveEvent(QAccessibleInterface *iface, int position, const QString &text) |
842 | : QAccessibleTextCursorEvent(iface, position) |
843 | , m_position(position), m_text(text) |
844 | { |
845 | m_type = QAccessible::TextRemoved; |
846 | } |
847 | |
848 | ~QAccessibleTextRemoveEvent(); |
849 | |
850 | QString textRemoved() const { |
851 | return m_text; |
852 | } |
853 | int changePosition() const { |
854 | return m_position; |
855 | } |
856 | |
857 | protected: |
858 | int m_position; |
859 | QString m_text; |
860 | }; |
861 | |
862 | class Q_GUI_EXPORT QAccessibleTextUpdateEvent : public QAccessibleTextCursorEvent |
863 | { |
864 | public: |
865 | inline QAccessibleTextUpdateEvent(QObject *obj, int position, const QString &oldText, const QString &text) |
866 | : QAccessibleTextCursorEvent(obj, position + text.length()) |
867 | , m_position(position), m_oldText(oldText), m_text(text) |
868 | { |
869 | m_type = QAccessible::TextUpdated; |
870 | } |
871 | inline QAccessibleTextUpdateEvent(QAccessibleInterface *iface, int position, const QString &oldText, const QString &text) |
872 | : QAccessibleTextCursorEvent(iface, position + text.length()) |
873 | , m_position(position), m_oldText(oldText), m_text(text) |
874 | { |
875 | m_type = QAccessible::TextUpdated; |
876 | } |
877 | |
878 | ~QAccessibleTextUpdateEvent(); |
879 | |
880 | QString textRemoved() const { |
881 | return m_oldText; |
882 | } |
883 | QString textInserted() const { |
884 | return m_text; |
885 | } |
886 | int changePosition() const { |
887 | return m_position; |
888 | } |
889 | |
890 | protected: |
891 | int m_position; |
892 | QString m_oldText; |
893 | QString m_text; |
894 | }; |
895 | |
896 | class Q_GUI_EXPORT QAccessibleValueChangeEvent : public QAccessibleEvent |
897 | { |
898 | public: |
899 | inline QAccessibleValueChangeEvent(QObject *obj, const QVariant &val) |
900 | : QAccessibleEvent(obj, QAccessible::InvalidEvent) |
901 | , m_value(val) |
902 | { |
903 | m_type = QAccessible::ValueChanged; |
904 | } |
905 | inline QAccessibleValueChangeEvent(QAccessibleInterface *iface, const QVariant &val) |
906 | : QAccessibleEvent(iface, QAccessible::InvalidEvent) |
907 | , m_value(val) |
908 | { |
909 | m_type = QAccessible::ValueChanged; |
910 | } |
911 | |
912 | ~QAccessibleValueChangeEvent(); |
913 | |
914 | void setValue(const QVariant & val) { m_value= val; } |
915 | QVariant value() const { return m_value; } |
916 | |
917 | protected: |
918 | QVariant m_value; |
919 | }; |
920 | |
921 | class Q_GUI_EXPORT QAccessibleTableModelChangeEvent : public QAccessibleEvent |
922 | { |
923 | public: |
924 | enum ModelChangeType { |
925 | ModelReset, |
926 | DataChanged, |
927 | RowsInserted, |
928 | ColumnsInserted, |
929 | RowsRemoved, |
930 | ColumnsRemoved |
931 | }; |
932 | |
933 | inline QAccessibleTableModelChangeEvent(QObject *obj, ModelChangeType changeType) |
934 | : QAccessibleEvent(obj, QAccessible::InvalidEvent) |
935 | , m_modelChangeType(changeType) |
936 | , m_firstRow(-1), m_firstColumn(-1), m_lastRow(-1), m_lastColumn(-1) |
937 | { |
938 | m_type = QAccessible::TableModelChanged; |
939 | } |
940 | inline QAccessibleTableModelChangeEvent(QAccessibleInterface *iface, ModelChangeType changeType) |
941 | : QAccessibleEvent(iface, QAccessible::InvalidEvent) |
942 | , m_modelChangeType(changeType) |
943 | , m_firstRow(-1), m_firstColumn(-1), m_lastRow(-1), m_lastColumn(-1) |
944 | { |
945 | m_type = QAccessible::TableModelChanged; |
946 | } |
947 | |
948 | ~QAccessibleTableModelChangeEvent(); |
949 | |
950 | void setModelChangeType(ModelChangeType changeType) { m_modelChangeType = changeType; } |
951 | ModelChangeType modelChangeType() const { return m_modelChangeType; } |
952 | |
953 | void setFirstRow(int row) { m_firstRow = row; } |
954 | void setFirstColumn(int col) { m_firstColumn = col; } |
955 | void setLastRow(int row) { m_lastRow = row; } |
956 | void setLastColumn(int col) { m_lastColumn = col; } |
957 | int firstRow() const { return m_firstRow; } |
958 | int firstColumn() const { return m_firstColumn; } |
959 | int lastRow() const { return m_lastRow; } |
960 | int lastColumn() const { return m_lastColumn; } |
961 | |
962 | protected: |
963 | ModelChangeType m_modelChangeType; |
964 | int m_firstRow; |
965 | int m_firstColumn; |
966 | int m_lastRow; |
967 | int m_lastColumn; |
968 | }; |
969 | |
970 | #ifndef Q_CLANG_QDOC |
971 | #define QAccessibleInterface_iid "org.qt-project.Qt.QAccessibleInterface" |
972 | Q_DECLARE_INTERFACE(QAccessibleInterface, QAccessibleInterface_iid) |
973 | #endif |
974 | |
975 | Q_GUI_EXPORT const char *qAccessibleRoleString(QAccessible::Role role); |
976 | Q_GUI_EXPORT const char *qAccessibleEventString(QAccessible::Event event); |
977 | Q_GUI_EXPORT QString qAccessibleLocalizedActionDescription(const QString &actionName); |
978 | |
979 | #ifndef QT_NO_DEBUG_STREAM |
980 | Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAccessibleInterface *iface); |
981 | Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAccessibleEvent &ev); |
982 | #endif |
983 | |
984 | #if QT_DEPRECATED_SINCE(5, 0) |
985 | inline void QAccessible::updateAccessibility(QObject *object, int child, Event reason) |
986 | { |
987 | Q_ASSERT(object); |
988 | |
989 | QAccessibleEvent ev(object, reason); |
990 | ev.setChild(child); |
991 | updateAccessibility(&ev); |
992 | } |
993 | #endif |
994 | |
995 | QT_END_NAMESPACE |
996 | |
997 | #endif // QACCESSIBLE_H |
998 | #endif //!QT_NO_ACCESSIBILITY |
999 | |