summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2012-10-06 02:53:44 +0300
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-10-13 03:17:39 +0200
commit4717d36c9110f016868e37d9eff74b1d28af5a9c (patch)
tree7d815c2913c2df3532275d2ed2ffef748ffb2580
parent539ef45689e0d038b6cd83d772597a5be886d8ff (diff)
Fix QTextBoundaryFinder usage cases in QAccessible2
Make the implementation safer and closer to what http://www.linuxfoundation.org/collaborate/workgroups/accessibility/ia2/ia2_implementation_guide#boundaries requires us to do. Change-Id: I00af4697e52a9b6e7f5d7b3f403b29126fa1517b Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com> Reviewed-by: Jan Arve Sæther <jan-arve.saether@digia.com>
-rw-r--r--src/gui/accessible/qaccessible2.cpp288
-rw-r--r--src/gui/accessible/qaccessible2.h8
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.cpp13
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp1
4 files changed, 179 insertions, 131 deletions
diff --git a/src/gui/accessible/qaccessible2.cpp b/src/gui/accessible/qaccessible2.cpp
index e3402ef2e5..7f871f9c5a 100644
--- a/src/gui/accessible/qaccessible2.cpp
+++ b/src/gui/accessible/qaccessible2.cpp
@@ -134,19 +134,184 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QString QAccessibleTextInterface::textBeforeOffset (int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset) const
+ Returns the text item of type \a boundaryType that is close to offset \a offset
+ and sets \a startOffset and \a endOffset values to the start and end positions
+ of that item; returns an empty string if there is no such an item.
+ Sets \a startOffset and \a endOffset values to -1 on error.
*/
+QString QAccessibleTextInterface::textBeforeOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset) const
+{
+ const QString txt = text(0, characterCount());
+
+ if (txt.isEmpty() || offset < 0 || offset > txt.length()) {
+ *startOffset = *endOffset = -1;
+ return QString();
+ }
+ if (offset == 0) {
+ *startOffset = *endOffset = offset;
+ return QString();
+ }
+
+ QTextBoundaryFinder::BoundaryType type;
+ switch (boundaryType) {
+ case QAccessible2::CharBoundary:
+ type = QTextBoundaryFinder::Grapheme;
+ break;
+ case QAccessible2::WordBoundary:
+ type = QTextBoundaryFinder::Word;
+ break;
+ case QAccessible2::SentenceBoundary:
+ type = QTextBoundaryFinder::Sentence;
+ break;
+ default:
+ // in any other case return the whole line
+ *startOffset = 0;
+ *endOffset = txt.length();
+ return txt;
+ }
+
+ // keep behavior in sync with QTextCursor::movePosition()!
+
+ QTextBoundaryFinder boundary(type, txt);
+ boundary.setPosition(offset);
+
+ do {
+ if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
+ break;
+ } while (boundary.toPreviousBoundary() > 0);
+ Q_ASSERT(boundary.position() >= 0);
+ *endOffset = boundary.position();
+
+ while (boundary.toPreviousBoundary() > 0) {
+ if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
+ break;
+ }
+ Q_ASSERT(boundary.position() >= 0);
+ *startOffset = boundary.position();
+
+ return txt.mid(*startOffset, *endOffset - *startOffset);
+}
/*!
- \fn QString QAccessibleTextInterface::textAfterOffset(int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset) const
+ Returns the text item of type \a boundaryType that is right after offset \a offset
+ and sets \a startOffset and \a endOffset values to the start and end positions
+ of that item; returns an empty string if there is no such an item.
+ Sets \a startOffset and \a endOffset values to -1 on error.
*/
+QString QAccessibleTextInterface::textAfterOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset) const
+{
+ const QString txt = text(0, characterCount());
+
+ if (txt.isEmpty() || offset < 0 || offset > txt.length()) {
+ *startOffset = *endOffset = -1;
+ return QString();
+ }
+ if (offset == txt.length()) {
+ *startOffset = *endOffset = offset;
+ return QString();
+ }
+
+ QTextBoundaryFinder::BoundaryType type;
+ switch (boundaryType) {
+ case QAccessible2::CharBoundary:
+ type = QTextBoundaryFinder::Grapheme;
+ break;
+ case QAccessible2::WordBoundary:
+ type = QTextBoundaryFinder::Word;
+ break;
+ case QAccessible2::SentenceBoundary:
+ type = QTextBoundaryFinder::Sentence;
+ break;
+ default:
+ // in any other case return the whole line
+ *startOffset = 0;
+ *endOffset = txt.length();
+ return txt;
+ }
+
+ // keep behavior in sync with QTextCursor::movePosition()!
+
+ QTextBoundaryFinder boundary(type, txt);
+ boundary.setPosition(offset);
+
+ while (boundary.toNextBoundary() < txt.length()) {
+ if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
+ break;
+ }
+ Q_ASSERT(boundary.position() <= txt.length());
+ *startOffset = boundary.position();
+
+ while (boundary.toNextBoundary() < txt.length()) {
+ if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
+ break;
+ }
+ Q_ASSERT(boundary.position() <= txt.length());
+ *endOffset = boundary.position();
+
+ return txt.mid(*startOffset, *endOffset - *startOffset);
+}
/*!
- \fn QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset) const
+ Returns the text item of type \a boundaryType at offset \a offset
+ and sets \a startOffset and \a endOffset values to the start and end positions
+ of that item; returns an empty string if there is no such an item.
+ Sets \a startOffset and \a endOffset values to -1 on error.
*/
+QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset) const
+{
+ const QString txt = text(0, characterCount());
+
+ if (txt.isEmpty() || offset < 0 || offset > txt.length()) {
+ *startOffset = *endOffset = -1;
+ return QString();
+ }
+ if (offset == txt.length()) {
+ *startOffset = *endOffset = offset;
+ return QString();
+ }
+
+ QTextBoundaryFinder::BoundaryType type;
+ switch (boundaryType) {
+ case QAccessible2::CharBoundary:
+ type = QTextBoundaryFinder::Grapheme;
+ break;
+ case QAccessible2::WordBoundary:
+ type = QTextBoundaryFinder::Word;
+ break;
+ case QAccessible2::SentenceBoundary:
+ type = QTextBoundaryFinder::Sentence;
+ break;
+ default:
+ // in any other case return the whole line
+ *startOffset = 0;
+ *endOffset = txt.length();
+ return txt;
+ }
+
+ // keep behavior in sync with QTextCursor::movePosition()!
+
+ QTextBoundaryFinder boundary(type, txt);
+ boundary.setPosition(offset);
+
+ do {
+ if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
+ break;
+ } while (boundary.toPreviousBoundary() > 0);
+ Q_ASSERT(boundary.position() >= 0);
+ *startOffset = boundary.position();
+
+ while (boundary.toNextBoundary() < txt.length()) {
+ if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
+ break;
+ }
+ Q_ASSERT(boundary.position() <= txt.length());
+ *endOffset = boundary.position();
+
+ return txt.mid(*startOffset, *endOffset - *startOffset);
+}
/*!
\fn void QAccessibleTextInterface::removeSelection(int selectionIndex)
@@ -512,117 +677,6 @@ const QString &QAccessibleActionInterface::toggleAction()
return accessibleActionStrings()->toggleAction;
}
-
-/*!
- \internal
-*/
-QString Q_GUI_EXPORT qTextBeforeOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset, const QString& text)
-{
- QTextBoundaryFinder::BoundaryType type;
- switch (boundaryType) {
- case QAccessible2::CharBoundary:
- type = QTextBoundaryFinder::Grapheme;
- break;
- case QAccessible2::WordBoundary:
- type = QTextBoundaryFinder::Word;
- break;
- case QAccessible2::SentenceBoundary:
- type = QTextBoundaryFinder::Sentence;
- break;
- default:
- // in any other case return the whole line
- *startOffset = 0;
- *endOffset = text.length();
- return text;
- }
-
- QTextBoundaryFinder boundary(type, text);
- boundary.setPosition(offset);
-
- if (!boundary.isAtBoundary()) {
- boundary.toPreviousBoundary();
- }
- boundary.toPreviousBoundary();
- *startOffset = boundary.position();
- boundary.toNextBoundary();
- *endOffset = boundary.position();
-
- return text.mid(*startOffset, *endOffset - *startOffset);
-}
-
-/*!
- \internal
-*/
-QString Q_GUI_EXPORT qTextAfterOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset, const QString& text)
-{
- QTextBoundaryFinder::BoundaryType type;
- switch (boundaryType) {
- case QAccessible2::CharBoundary:
- type = QTextBoundaryFinder::Grapheme;
- break;
- case QAccessible2::WordBoundary:
- type = QTextBoundaryFinder::Word;
- break;
- case QAccessible2::SentenceBoundary:
- type = QTextBoundaryFinder::Sentence;
- break;
- default:
- // in any other case return the whole line
- *startOffset = 0;
- *endOffset = text.length();
- return text;
- }
-
- QTextBoundaryFinder boundary(type, text);
- boundary.setPosition(offset);
-
- boundary.toNextBoundary();
- *startOffset = boundary.position();
- boundary.toNextBoundary();
- *endOffset = boundary.position();
-
- return text.mid(*startOffset, *endOffset - *startOffset);
-}
-
-/*!
- \internal
-*/
-QString Q_GUI_EXPORT qTextAtOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset, const QString& text)
-{
- QTextBoundaryFinder::BoundaryType type;
- switch (boundaryType) {
- case QAccessible2::CharBoundary:
- type = QTextBoundaryFinder::Grapheme;
- break;
- case QAccessible2::WordBoundary:
- type = QTextBoundaryFinder::Word;
- break;
- case QAccessible2::SentenceBoundary:
- type = QTextBoundaryFinder::Sentence;
- break;
- default:
- // in any other case return the whole line
- *startOffset = 0;
- *endOffset = text.length();
- return text;
- }
-
- QTextBoundaryFinder boundary(type, text);
- boundary.setPosition(offset);
-
- if (!boundary.isAtBoundary()) {
- boundary.toPreviousBoundary();
- }
- *startOffset = boundary.position();
- boundary.toNextBoundary();
- *endOffset = boundary.position();
-
- return text.mid(*startOffset, *endOffset - *startOffset);
-}
-
QT_END_NAMESPACE
#endif // QT_NO_ACCESSIBILITY
diff --git a/src/gui/accessible/qaccessible2.h b/src/gui/accessible/qaccessible2.h
index ee0215ecf3..c1e7b8b5a2 100644
--- a/src/gui/accessible/qaccessible2.h
+++ b/src/gui/accessible/qaccessible2.h
@@ -83,12 +83,12 @@ public:
// text
virtual QString text(int startOffset, int endOffset) const = 0;
- virtual QString textBeforeOffset (int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset) const = 0;
+ virtual QString textBeforeOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset) const;
virtual QString textAfterOffset(int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset) const = 0;
+ int *startOffset, int *endOffset) const;
virtual QString textAtOffset(int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset) const = 0;
+ int *startOffset, int *endOffset) const;
virtual int characterCount() const = 0;
// character <-> geometry
diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp
index 2015929010..bb90061a7e 100644
--- a/src/plugins/accessible/widgets/simplewidgets.cpp
+++ b/src/plugins/accessible/widgets/simplewidgets.cpp
@@ -72,13 +72,6 @@ extern QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel
QString Q_GUI_EXPORT qt_accStripAmp(const QString &text);
QString Q_GUI_EXPORT qt_accHotKey(const QString &text);
-QString Q_GUI_EXPORT qTextBeforeOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset, const QString& text);
-QString Q_GUI_EXPORT qTextAtOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset, const QString& text);
-QString Q_GUI_EXPORT qTextAfterOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset, const QString& text);
-
/*!
\class QAccessibleButton
\brief The QAccessibleButton class implements the QAccessibleInterface for button type widgets.
@@ -725,7 +718,7 @@ QString QAccessibleLineEdit::textBeforeOffset(int offset, BoundaryType boundaryT
*startOffset = *endOffset = -1;
return QString();
}
- return qTextBeforeOffsetFromString(offset, boundaryType, startOffset, endOffset, lineEdit()->text());
+ return QAccessibleTextInterface::textBeforeOffset(offset, boundaryType, startOffset, endOffset);
}
QString QAccessibleLineEdit::textAfterOffset(int offset, BoundaryType boundaryType,
@@ -735,7 +728,7 @@ QString QAccessibleLineEdit::textAfterOffset(int offset, BoundaryType boundaryTy
*startOffset = *endOffset = -1;
return QString();
}
- return qTextAfterOffsetFromString(offset, boundaryType, startOffset, endOffset, lineEdit()->text());
+ return QAccessibleTextInterface::textAfterOffset(offset, boundaryType, startOffset, endOffset);
}
QString QAccessibleLineEdit::textAtOffset(int offset, BoundaryType boundaryType,
@@ -745,7 +738,7 @@ QString QAccessibleLineEdit::textAtOffset(int offset, BoundaryType boundaryType,
*startOffset = *endOffset = -1;
return QString();
}
- return qTextAtOffsetFromString(offset, boundaryType, startOffset, endOffset, lineEdit()->text());
+ return QAccessibleTextInterface::textAtOffset(offset, boundaryType, startOffset, endOffset);
}
void QAccessibleLineEdit::removeSelection(int selectionIndex)
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
index 1b789b26ae..0166d592a6 100644
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -1885,6 +1885,7 @@ void tst_QAccessibility::lineEditTest()
QCOMPARE(textIface->textAtOffset(8, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" "));
QCOMPARE(textIface->textAtOffset(25, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("advice"));
QCOMPARE(textIface->textAtOffset(92, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("oneself"));
+ QCOMPARE(textIface->textAtOffset(101, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(". --"));
QCOMPARE(textIface->textBeforeOffset(5, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" "));
QCOMPARE(textIface->textAfterOffset(5, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" "));