diff options
Diffstat (limited to 'src/gui/accessible')
| -rw-r--r-- | src/gui/accessible/linux/atspiadaptor.cpp | 15 | ||||
| -rw-r--r-- | src/gui/accessible/qaccessible.cpp | 78 | ||||
| -rw-r--r-- | src/gui/accessible/qaccessible_base.h | 3 | ||||
| -rw-r--r-- | src/gui/accessible/qaccessiblehelper.cpp | 77 | ||||
| -rw-r--r-- | src/gui/accessible/qaccessiblehelper_p.h | 18 |
5 files changed, 150 insertions, 41 deletions
diff --git a/src/gui/accessible/linux/atspiadaptor.cpp b/src/gui/accessible/linux/atspiadaptor.cpp index e91539d6ee3..dad0ac2b74a 100644 --- a/src/gui/accessible/linux/atspiadaptor.cpp +++ b/src/gui/accessible/linux/atspiadaptor.cpp @@ -1688,6 +1688,17 @@ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QS sendReply(connection, message, QVariant::fromValue(QDBusVariant(interface->text(QAccessible::Help)))); } else if (function == "GetState"_L1) { quint64 spiState = spiStatesFromQState(interface->state()); + if (QAccessibleAttributesInterface *attributesIface = interface->attributesInterface()) { + const QVariant orientationVariant = + attributesIface->attributeValue(QAccessible::Attribute::Orientation); + if (orientationVariant.isValid()) { + Q_ASSERT(orientationVariant.canConvert<Qt::Orientation>()); + const Qt::Orientation orientation = orientationVariant.value<Qt::Orientation>(); + setSpiStateBit(&spiState, + orientation == Qt::Horizontal ? ATSPI_STATE_HORIZONTAL + : ATSPI_STATE_VERTICAL); + } + } if (interface->tableInterface()) { // For tables, setting manages_descendants should // indicate to the client that it cannot cache these @@ -1877,7 +1888,7 @@ void AtSpiAdaptor::addMatchingDescendants(QList<QAccessibleInterface *> &matches const QSpiMatchRuleMatcher &matcher, bool invert, int count, bool traverse) { - if (!accessible || matches.size() >= count) + if (!accessible || (count != 0 && matches.size() >= count)) return; const int childCount = accessible->childCount(); @@ -1889,7 +1900,7 @@ void AtSpiAdaptor::addMatchingDescendants(QList<QAccessibleInterface *> &matches if (traverse) addMatchingDescendants(matches, child, matcher, invert, count, traverse); - if (matches.size() >= count) + if (count != 0 && matches.size() >= count) return; } } diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index eeb06c535b8..30ebe90da0b 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -458,6 +458,9 @@ Q_STATIC_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core"); differs from the application's default locale, e.g. for documents or paragraphs within a document that use a language that differs from the application's user interface language. + \value [since 6.11] Orientation value type: \a Qt::Orientation + Orientation of the element. This attribute conceptually matches + the "aria-orientation" property in ARIA. \sa QAccessibleAttributesInterface */ @@ -968,9 +971,21 @@ void QAccessible::updateAccessibility(QAccessibleEvent *event) pfAccessibility->notifyAccessibilityUpdate(event); } +static std::pair<int, int> qAccessibleTextBoundaryHelperHelper(QTextCursor &cursor, + QTextCursor::MoveOperation start, + QTextCursor::MoveOperation end) +{ + std::pair<int, int> result; + cursor.movePosition(start, QTextCursor::MoveAnchor); + result.first = cursor.position(); + cursor.movePosition(end, QTextCursor::KeepAnchor); + result.second = cursor.position(); + return result; +} + /*! \internal - \brief getBoundaries is a helper function to find the accessible text boundaries for QTextCursor based documents. + \brief qAccessibleTextBoundaryHelper is a helper function to find the accessible text boundaries for QTextCursor based documents. \param documentCursor a valid cursor bound to the document (not null). It needs to ba at the position to look for the boundary \param boundaryType the type of boundary to find \return the boundaries as pair @@ -979,32 +994,20 @@ std::pair< int, int > QAccessible::qAccessibleTextBoundaryHelper(const QTextCurs { Q_ASSERT(!offsetCursor.isNull()); - QTextCursor endCursor = offsetCursor; - endCursor.movePosition(QTextCursor::End); - int characterCount = endCursor.position(); - - std::pair<int, int> result; QTextCursor cursor = offsetCursor; switch (boundaryType) { case CharBoundary: - result.first = cursor.position(); - cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); - result.second = cursor.position(); - break; + return qAccessibleTextBoundaryHelperHelper(cursor, QTextCursor::NoMove, + QTextCursor::NextCharacter); case WordBoundary: - cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor); - result.first = cursor.position(); - cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); - result.second = cursor.position(); - break; + return qAccessibleTextBoundaryHelperHelper(cursor, QTextCursor::StartOfWord, + QTextCursor::EndOfWord); case SentenceBoundary: { // QCursor does not provide functionality to move to next sentence. // We therefore find the current block, then go through the block using // QTextBoundaryFinder and find the sentence the \offset represents - cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); - result.first = cursor.position(); - cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); - result.second = cursor.position(); + std::pair<int, int> result = qAccessibleTextBoundaryHelperHelper( + cursor, QTextCursor::StartOfBlock, QTextCursor::EndOfBlock); QString blockText = cursor.selectedText(); const int offsetWithinBlockText = offsetCursor.position() - result.first; QTextBoundaryFinder sentenceFinder(QTextBoundaryFinder::Sentence, blockText); @@ -1018,25 +1021,19 @@ std::pair< int, int > QAccessible::qAccessibleTextBoundaryHelper(const QTextCurs result.second = result.first + nextBoundary; if (prevBoundary != -1) result.first += prevBoundary; - break; } + return result; + } case LineBoundary: - cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor); - result.first = cursor.position(); - cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); - result.second = cursor.position(); - break; + return qAccessibleTextBoundaryHelperHelper(cursor, QTextCursor::StartOfLine, + QTextCursor::EndOfLine); case ParagraphBoundary: - cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); - result.first = cursor.position(); - cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); - result.second = cursor.position(); - break; + return qAccessibleTextBoundaryHelperHelper(cursor, QTextCursor::StartOfBlock, + QTextCursor::EndOfBlock); case NoBoundary: - result.first = 0; - result.second = characterCount; - break; + return qAccessibleTextBoundaryHelperHelper(cursor, QTextCursor::Start, QTextCursor::End); } - return result; + + Q_UNREACHABLE_RETURN({}); } /*! @@ -2274,13 +2271,16 @@ QString QAccessibleTextInterface::textBeforeOffset(int offset, QAccessible::Text break; } while (boundary.toPreviousBoundary() > 0); Q_ASSERT(boundary.position() >= 0); - *endOffset = boundary.position(); + const int endPos = boundary.position(); while (boundary.toPreviousBoundary() > 0) { if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem))) break; } - Q_ASSERT(boundary.position() >= 0); + if (boundary.position() < 0) + return QString(); + + *endOffset = endPos; *startOffset = boundary.position(); return txt.mid(*startOffset, *endOffset - *startOffset); @@ -2437,13 +2437,17 @@ QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoun break; } while (boundary.toPreviousBoundary() > 0); Q_ASSERT(boundary.position() >= 0); - *startOffset = boundary.position(); + const int startPos = boundary.position(); while (boundary.toNextBoundary() < txt.size()) { if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem))) break; + if (boundary.position() == -1) + return QString(); } + Q_ASSERT(boundary.position() <= txt.size()); + *startOffset = startPos; *endOffset = boundary.position(); return txt.mid(*startOffset, *endOffset - *startOffset); diff --git a/src/gui/accessible/qaccessible_base.h b/src/gui/accessible/qaccessible_base.h index 31b97880ffc..3881c6346a0 100644 --- a/src/gui/accessible/qaccessible_base.h +++ b/src/gui/accessible/qaccessible_base.h @@ -156,8 +156,6 @@ public: quint64 searchEdit : 1; - // quint64 horizontal : 1; - // quint64 vertical : 1; // quint64 invalidEntry : 1; // quint64 managesDescendants : 1; // quint64 singleLine : 1; // we have multi line, this is redundant. @@ -380,6 +378,7 @@ public: Custom, Level, Locale, + Orientation, }; Q_ENUM(Attribute) diff --git a/src/gui/accessible/qaccessiblehelper.cpp b/src/gui/accessible/qaccessiblehelper.cpp index 2ae8ebbac08..9ea72b1f6c9 100644 --- a/src/gui/accessible/qaccessiblehelper.cpp +++ b/src/gui/accessible/qaccessiblehelper.cpp @@ -3,6 +3,8 @@ #include "qaccessiblehelper_p.h" +#include <QtGui/qtextcursor.h> + QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; @@ -48,4 +50,79 @@ QString qt_accStripAmp(const QString &text) return newText.replace("&&"_L1, "&"_L1); } +QString qt_accTextBeforeOffsetHelper(const QAccessibleTextInterface &textInterface, + const QTextCursor &textCursor, int offset, + QAccessible::TextBoundaryType boundaryType, int *startOffset, + int *endOffset) +{ + Q_ASSERT(startOffset); + Q_ASSERT(endOffset); + *startOffset = *endOffset = -1; + + QTextCursor cursor = textCursor; + cursor.setPosition(offset); + std::pair<int, int> boundaries = + QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); + if (boundaries.second > offset) { + cursor.setPosition(boundaries.first); + while (boundaries.second > offset) { + if (!cursor.movePosition(QTextCursor::PreviousCharacter)) + return QString(); + boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); + } + } + + *startOffset = boundaries.first; + *endOffset = boundaries.second; + + return textInterface.text(boundaries.first, boundaries.second); +} + +QString qt_accTextAfterOffsetHelper(const QAccessibleTextInterface &textInterface, + const QTextCursor &textCursor, int offset, + QAccessible::TextBoundaryType boundaryType, int *startOffset, + int *endOffset) +{ + Q_ASSERT(startOffset); + Q_ASSERT(endOffset); + *startOffset = *endOffset = -1; + + QTextCursor cursor = textCursor; + cursor.setPosition(offset); + std::pair<int, int> boundaries = + QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); + if (boundaries.first <= offset) { + cursor.setPosition(boundaries.second); + while (boundaries.first <= offset) { + if (!cursor.movePosition(QTextCursor::NextCharacter)) + return QString(); + boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); + } + } + + *startOffset = boundaries.first; + *endOffset = boundaries.second; + + return textInterface.text(boundaries.first, boundaries.second); +} + +QString qt_accTextAtOffsetHelper(const QAccessibleTextInterface &textInterface, + const QTextCursor &textCursor, int offset, + QAccessible::TextBoundaryType boundaryType, int *startOffset, + int *endOffset) +{ + Q_ASSERT(startOffset); + Q_ASSERT(endOffset); + + QTextCursor cursor = textCursor; + cursor.setPosition(offset); + std::pair<int, int> boundaries = + QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); + + *startOffset = boundaries.first; + *endOffset = boundaries.second; + + return textInterface.text(boundaries.first, boundaries.second); +} + QT_END_NAMESPACE diff --git a/src/gui/accessible/qaccessiblehelper_p.h b/src/gui/accessible/qaccessiblehelper_p.h index 38cc493fdea..03cccbbe539 100644 --- a/src/gui/accessible/qaccessiblehelper_p.h +++ b/src/gui/accessible/qaccessiblehelper_p.h @@ -16,12 +16,30 @@ // #include <QtCore/QString> +#include <QtGui/qaccessible.h> #include <QtGui/qtguiglobal.h> +class QTextCursor; + QT_BEGIN_NAMESPACE Q_GUI_EXPORT QString qt_accStripAmp(const QString &text); +Q_GUI_EXPORT QString qt_accTextBeforeOffsetHelper(const QAccessibleTextInterface &textInterface, + const QTextCursor &textCursor, int offset, + QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset); + +Q_GUI_EXPORT QString qt_accTextAfterOffsetHelper(const QAccessibleTextInterface &textInterface, + const QTextCursor &textCursor, int offset, + QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset); + +Q_GUI_EXPORT QString qt_accTextAtOffsetHelper(const QAccessibleTextInterface &textInterface, + const QTextCursor &textCursor, int offset, + QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset); + QT_END_NAMESPACE #endif // QACCESSIBLEHELPER_P_H |
