1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
40 ****************************************************************************/
42 #include "qaccessible2.h"
43 #include <QtGui/QGuiApplication>
44 #include "qclipboard.h"
45 #include "qtextboundaryfinder.h"
47 #ifndef QT_NO_ACCESSIBILITY
52 \namespace QAccessible2
53 \ingroup accessibility
56 \brief The QAccessible2 namespace defines constants relating to
57 IAccessible2-based interfaces
59 \l{IAccessible2 Specification}
63 \class QAccessibleTextInterface
67 \ingroup accessibility
69 \brief The QAccessibleTextInterface class implements support for text handling.
71 This interface corresponds to the IAccessibleText interface.
72 It should be implemented for widgets that display more text than a plain label.
73 Labels should be represented by only \l QAccessibleInterface
74 and return their text as name (\l QAccessibleInterface::text() with \l QAccessible::Name as type).
75 The QAccessibleTextInterface is typically for text that a screen reader
76 might want to read line by line, and for widgets that support text selection and input.
77 This interface is, for example, implemented for QLineEdit.
79 Editable text objects should also implement \l QAccessibleEditableTextInterface.
80 \l{IAccessible2 Specification}
84 \fn QAccessibleTextInterface::~QAccessibleTextInterface()
89 \fn void QAccessibleTextInterface::addSelection(int startOffset, int endOffset)
90 Select the text from \a startOffset to \a endOffset.
91 The \a startOffset is the first character that will be selected.
92 The \a endOffset is the first character that will not be selected.
94 When the object supports multiple selections (e.g. in a word processor),
95 this adds a new selection, otherwise it replaces the previous selection.
97 The selection will be \a endOffset - \a startOffset characters long.
101 \fn QString QAccessibleTextInterface::attributes(int offset, int *startOffset, int *endOffset) const
105 \fn int QAccessibleTextInterface::cursorPosition() const
107 Returns the current cursor position.
111 \fn QRect QAccessibleTextInterface::characterRect(int offset) const
115 \fn int QAccessibleTextInterface::selectionCount() const
117 Returns the number of selections in this text.
121 \fn int QAccessibleTextInterface::offsetAtPoint(const QPoint &point) const
125 \fn void QAccessibleTextInterface::selection(int selectionIndex, int *startOffset, int *endOffset) const
129 \fn QString QAccessibleTextInterface::text(int startOffset, int endOffset) const
131 Returns the text from \a startOffset to \a endOffset.
132 The \a startOffset is the first character that will be returned.
133 The \a endOffset is the first character that will not be returned.
137 Returns the text item of type \a boundaryType that is close to offset \a offset
138 and sets \a startOffset and \a endOffset values to the start and end positions
139 of that item; returns an empty string if there is no such an item.
140 Sets \a startOffset and \a endOffset values to -1 on error.
142 QString QAccessibleTextInterface::textBeforeOffset(int offset, QAccessible2::BoundaryType boundaryType,
143 int *startOffset, int *endOffset) const
145 const QString txt = text(0, characterCount());
147 if (txt.isEmpty() || offset < 0 || offset > txt.length()) {
148 *startOffset = *endOffset = -1;
152 *startOffset = *endOffset = offset;
156 QTextBoundaryFinder::BoundaryType type;
157 switch (boundaryType) {
158 case QAccessible2::CharBoundary:
159 type = QTextBoundaryFinder::Grapheme;
161 case QAccessible2::WordBoundary:
162 type = QTextBoundaryFinder::Word;
164 case QAccessible2::SentenceBoundary:
165 type = QTextBoundaryFinder::Sentence;
168 // in any other case return the whole line
170 *endOffset = txt.length();
174 // keep behavior in sync with QTextCursor::movePosition()!
176 QTextBoundaryFinder boundary(type, txt);
177 boundary.setPosition(offset);
180 if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
182 } while (boundary.toPreviousBoundary() > 0);
183 Q_ASSERT(boundary.position() >= 0);
184 *endOffset = boundary.position();
186 while (boundary.toPreviousBoundary() > 0) {
187 if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
190 Q_ASSERT(boundary.position() >= 0);
191 *startOffset = boundary.position();
193 return txt.mid(*startOffset, *endOffset - *startOffset);
197 Returns the text item of type \a boundaryType that is right after offset \a offset
198 and sets \a startOffset and \a endOffset values to the start and end positions
199 of that item; returns an empty string if there is no such an item.
200 Sets \a startOffset and \a endOffset values to -1 on error.
202 QString QAccessibleTextInterface::textAfterOffset(int offset, QAccessible2::BoundaryType boundaryType,
203 int *startOffset, int *endOffset) const
205 const QString txt = text(0, characterCount());
207 if (txt.isEmpty() || offset < 0 || offset > txt.length()) {
208 *startOffset = *endOffset = -1;
211 if (offset == txt.length()) {
212 *startOffset = *endOffset = offset;
216 QTextBoundaryFinder::BoundaryType type;
217 switch (boundaryType) {
218 case QAccessible2::CharBoundary:
219 type = QTextBoundaryFinder::Grapheme;
221 case QAccessible2::WordBoundary:
222 type = QTextBoundaryFinder::Word;
224 case QAccessible2::SentenceBoundary:
225 type = QTextBoundaryFinder::Sentence;
228 // in any other case return the whole line
230 *endOffset = txt.length();
234 // keep behavior in sync with QTextCursor::movePosition()!
236 QTextBoundaryFinder boundary(type, txt);
237 boundary.setPosition(offset);
239 while (boundary.toNextBoundary() < txt.length()) {
240 if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
243 Q_ASSERT(boundary.position() <= txt.length());
244 *startOffset = boundary.position();
246 while (boundary.toNextBoundary() < txt.length()) {
247 if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
250 Q_ASSERT(boundary.position() <= txt.length());
251 *endOffset = boundary.position();
253 return txt.mid(*startOffset, *endOffset - *startOffset);
257 Returns the text item of type \a boundaryType at offset \a offset
258 and sets \a startOffset and \a endOffset values to the start and end positions
259 of that item; returns an empty string if there is no such an item.
260 Sets \a startOffset and \a endOffset values to -1 on error.
262 QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible2::BoundaryType boundaryType,
263 int *startOffset, int *endOffset) const
265 const QString txt = text(0, characterCount());
267 if (txt.isEmpty() || offset < 0 || offset > txt.length()) {
268 *startOffset = *endOffset = -1;
271 if (offset == txt.length()) {
272 *startOffset = *endOffset = offset;
276 QTextBoundaryFinder::BoundaryType type;
277 switch (boundaryType) {
278 case QAccessible2::CharBoundary:
279 type = QTextBoundaryFinder::Grapheme;
281 case QAccessible2::WordBoundary:
282 type = QTextBoundaryFinder::Word;
284 case QAccessible2::SentenceBoundary:
285 type = QTextBoundaryFinder::Sentence;
288 // in any other case return the whole line
290 *endOffset = txt.length();
294 // keep behavior in sync with QTextCursor::movePosition()!
296 QTextBoundaryFinder boundary(type, txt);
297 boundary.setPosition(offset);
300 if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
302 } while (boundary.toPreviousBoundary() > 0);
303 Q_ASSERT(boundary.position() >= 0);
304 *startOffset = boundary.position();
306 while (boundary.toNextBoundary() < txt.length()) {
307 if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
310 Q_ASSERT(boundary.position() <= txt.length());
311 *endOffset = boundary.position();
313 return txt.mid(*startOffset, *endOffset - *startOffset);
317 \fn void QAccessibleTextInterface::removeSelection(int selectionIndex)
319 Clears the selection with \a index selectionIndex.
323 \fn void QAccessibleTextInterface::setCursorPosition(int position)
325 Moves the cursor to \a position.
329 \fn void QAccessibleTextInterface::setSelection(int selectionIndex, int startOffset, int endOffset)
331 Set the selection \a selectionIndex to the range from \a startOffset to \a endOffset.
333 \sa addSelection(), removeSelection()
337 \fn int QAccessibleTextInterface::characterCount() const
339 Returns the length of the text (total size including spaces).
343 \fn void QAccessibleTextInterface::scrollToSubstring(int startIndex, int endIndex)
345 Ensures that the text between \a startIndex and \a endIndex is visible.
349 \class QAccessibleEditableTextInterface
350 \ingroup accessibility
354 \brief The QAccessibleEditableTextInterface class implements support for objects with editable text.
356 When implementing this interface you will almost certainly also want to implement \l QAccessibleTextInterface.
358 \sa QAccessibleInterface
360 \l{IAccessible2 Specification}
364 \fn QAccessibleEditableTextInterface::~QAccessibleEditableTextInterface()
370 \fn void QAccessibleEditableTextInterface::deleteText(int startOffset, int endOffset)
372 Deletes the text from \a startOffset to \a endOffset.
376 \fn void QAccessibleEditableTextInterface::insertText(int offset, const QString &text)
378 Inserts \a text at position \a offset.
382 \fn void QAccessibleEditableTextInterface::replaceText(int startOffset, int endOffset, const QString &text)
384 Removes the text from \a startOffset to \a endOffset and instead inserts \a text.
388 \class QAccessibleValueInterface
390 \ingroup accessibility
393 \brief The QAccessibleValueInterface class implements support for objects that manipulate a value.
395 This interface should be implemented by accessible objects that represent a value.
396 Examples are spinner, slider, dial and scroll bar.
398 Instead of forcing the user to deal with the individual parts of the widgets, this interface
399 gives an easier approach to the kind of widget it represents.
401 Usually this interface is implemented by classes that also implement \l QAccessibleInterface.
403 \l{IAccessible2 Specification}
407 \fn QAccessibleValueInterface::~QAccessibleValueInterface()
412 \fn QVariant QAccessibleValueInterface::currentValue() const
414 Returns the current value of the widget. This is usually a double or int.
415 \sa setCurrentValue()
419 \fn void QAccessibleValueInterface::setCurrentValue(const QVariant &value)
421 Sets the \a value. If the desired \a value is out of the range of permissible values,
422 this call will be ignored.
424 \sa currentValue(), minimumValue(), maximumValue()
428 \fn QVariant QAccessibleValueInterface::maximumValue() const
430 Returns the maximum value this object accepts.
431 \sa minimumValue(), currentValue()
435 \fn QVariant QAccessibleValueInterface::minimumValue() const
437 Returns the minimum value this object accepts.
438 \sa maximumValue(), currentValue()
442 \fn QVariant QAccessibleValueInterface::minimumStepSize() const
444 Returns the minimum step size for the accessible.
445 This is the smalles increment that makes sense when changing the value.
446 When programatically changing the value it should always be a multiple
447 of the minimum step size.
449 Some tools use this value even when the setCurrentValue does not
450 perform any action. Progress bars for example are read-only but
451 should return their range divided by 100.
455 \class QAccessibleImageInterface
457 \ingroup accessibility
461 \brief The QAccessibleImageInterface class implements support for
462 the IAccessibleImage interface.
464 \l{IAccessible2 Specification}
468 \class QAccessibleTableCellInterface
470 \ingroup accessibility
473 \brief The QAccessibleTableCellInterface class implements support for
474 the IAccessibleTable2 Cell interface.
476 \l{IAccessible2 Specification}
480 \class QAccessibleTableInterface
481 \ingroup accessibility
484 \brief The QAccessibleTableInterface class implements support for
485 the IAccessibleTable2 interface.
487 \l{IAccessible2 Specification}
492 \class QAccessibleActionInterface
493 \ingroup accessibility
496 \brief The QAccessibleActionInterface class implements support for
497 invocable actions in the interface.
499 Accessible objects should implement the action interface if they support user interaction.
500 Usually this interface is implemented by classes that also implement \l QAccessibleInterface.
502 The supported actions should use the predefined actions offered in this class unless they do not
503 fit a predefined action. In that case a custom action can be added.
505 When subclassing QAccessibleActionInterface you need to provide a list of actionNames which
506 is the primary means to discover the available actions. Action names are never localized.
507 In order to present actions to the user there are two functions that need to return localized versions
508 of the name and give a description of the action. For the predefined action names use
509 \l QAccessibleActionInterface::localizedActionName() and \l QAccessibleActionInterface::localizedActionDescription()
510 to return their localized counterparts.
512 In general you should use one of the predefined action names, unless describing an action that does not fit these:
514 \header \li Action name \li Description
515 \row \li \l toggleAction() \li toggles the item (checkbox, radio button, switch, ...)
516 \row \li \l decreaseAction() \li decrease the value of the accessible (e.g. spinbox)
517 \row \li \l increaseAction() \li increase the value of the accessible (e.g. spinbox)
518 \row \li \l pressAction() \li press or click or activate the accessible (should correspont to clicking the object with the mouse)
519 \row \li \l setFocusAction() \li set the focus to this accessible
520 \row \li \l showMenuAction() \li show a context menu, corresponds to right-clicks
523 In order to invoke the action, \l doAction() is called with an action name.
525 Most widgets will simply implement \l pressAction(). This is what happens when the widget is activated by
526 being clicked, space pressed or similar.
528 \l{IAccessible2 Specification}
532 \fn QStringList QAccessibleActionInterface::actionNames() const
534 Returns the list of actions supported by this accessible object.
535 The actions returned should be in preferred order,
536 i.e. the action that the user most likely wants to trigger should be returned first,
537 while the least likely action should be returned last.
539 The list does only contain actions that can be invoked.
540 It won't return disabled actions, or actions associated with disabled UI controls.
542 The list can be empty.
544 Note that this list is not localized. For a localized representation re-implement \l localizedActionName()
545 and \l localizedActionDescription()
547 \sa doAction(), localizedActionName(), localizedActionDescription()
551 \fn QString QAccessibleActionInterface::localizedActionName(const QString &actionName) const
553 Returns a localized action name of \a actionName.
555 For custom actions this function has to be re-implemented.
556 When using one of the default names, you can call this function in QAccessibleActionInterface
557 to get the localized string.
559 \sa actionNames(), localizedActionDescription()
563 \fn QString QAccessibleActionInterface::localizedActionDescription(const QString &actionName) const
565 Returns a localized action description of the action \a actionName.
567 When using one of the default names, you can call this function in QAccessibleActionInterface
568 to get the localized string.
570 \sa actionNames(), localizedActionName()
574 \fn void QAccessibleActionInterface::doAction(const QString &actionName)
576 Invokes the action specified by \a actionName.
577 Note that \a actionName is the non-localized name as returned by \l actionNames()
578 This function is usually implemented by calling the same functions
579 that other user interaction, such as clicking the object, would trigger.
585 \fn QStringList QAccessibleActionInterface::keyBindingsForAction(const QString &actionName) const
587 Returns a list of the keyboard shortcuts available for invoking the action named \a actionName.
589 This is important to let users learn alternative ways of using the application by emphasizing the keyboard.
595 struct QAccessibleActionStrings
597 QAccessibleActionStrings() :
598 pressAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "Press"))),
599 increaseAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "Increase"))),
600 decreaseAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "Decrease"))),
601 showMenuAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "ShowMenu"))),
602 setFocusAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "SetFocus"))),
603 toggleAction(QStringLiteral(QT_TRANSLATE_NOOP("QAccessibleActionInterface", "Toggle"))) {}
605 const QString pressAction;
606 const QString increaseAction;
607 const QString decreaseAction;
608 const QString showMenuAction;
609 const QString setFocusAction;
610 const QString toggleAction;
613 Q_GLOBAL_STATIC(QAccessibleActionStrings, accessibleActionStrings)
615 QString QAccessibleActionInterface::localizedActionName(const QString &actionName) const
617 return QAccessibleActionInterface::tr(qPrintable(actionName));
620 QString QAccessibleActionInterface::localizedActionDescription(const QString &actionName) const
622 const QAccessibleActionStrings *strings = accessibleActionStrings();
623 if (actionName == strings->pressAction)
624 return tr("Triggers the action");
625 else if (actionName == strings->increaseAction)
626 return tr("Increase the value");
627 else if (actionName == strings->decreaseAction)
628 return tr("Decrease the value");
629 else if (actionName == strings->showMenuAction)
630 return tr("Shows the menu");
631 else if (actionName == strings->setFocusAction)
632 return tr("Sets the focus");
633 else if (actionName == strings->toggleAction)
634 return tr("Toggles the state");
640 Returns the name of the press default action.
641 \sa actionNames(), localizedActionName()
643 const QString &QAccessibleActionInterface::pressAction()
645 return accessibleActionStrings()->pressAction;
649 Returns the name of the increase default action.
650 \sa actionNames(), localizedActionName()
652 const QString &QAccessibleActionInterface::increaseAction()
654 return accessibleActionStrings()->increaseAction;
658 Returns the name of the decrease default action.
659 \sa actionNames(), localizedActionName()
661 const QString &QAccessibleActionInterface::decreaseAction()
663 return accessibleActionStrings()->decreaseAction;
667 Returns the name of the show menu default action.
668 \sa actionNames(), localizedActionName()
670 const QString &QAccessibleActionInterface::showMenuAction()
672 return accessibleActionStrings()->showMenuAction;
676 Returns the name of the set focus default action.
677 \sa actionNames(), localizedActionName()
679 const QString &QAccessibleActionInterface::setFocusAction()
681 return accessibleActionStrings()->setFocusAction;
685 Returns the name of the toggle default action.
686 \sa actionNames(), localizedActionName()
688 const QString &QAccessibleActionInterface::toggleAction()
690 return accessibleActionStrings()->toggleAction;
695 #endif // QT_NO_ACCESSIBILITY