| 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 | |