diff options
author | Konstantin Ritt <ritt.ks@gmail.com> | 2012-10-06 02:53:44 +0300 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-10-13 03:17:39 +0200 |
commit | 4717d36c9110f016868e37d9eff74b1d28af5a9c (patch) | |
tree | 7d815c2913c2df3532275d2ed2ffef748ffb2580 | |
parent | 539ef45689e0d038b6cd83d772597a5be886d8ff (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.cpp | 288 | ||||
-rw-r--r-- | src/gui/accessible/qaccessible2.h | 8 | ||||
-rw-r--r-- | src/plugins/accessible/widgets/simplewidgets.cpp | 13 | ||||
-rw-r--r-- | tests/auto/other/qaccessibility/tst_qaccessibility.cpp | 1 |
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(" ")); |