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