diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-06-23 17:57:34 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-06-26 17:37:08 +0200 |
commit | a58ec950f06c8de366b4b693491eaaafae116041 (patch) | |
tree | c10aaecbc9889faab54dd7d5f338bffacf8d55f0 /src/widgets/accessible | |
parent | 86802ec04d23c8ddc82268e18eb99d5f71450914 (diff) |
Accessibility: improve text attribute ranges
Improve consistency and use QTextDocument functions to find ranges
instead of coming up with our own scheme. This is important since
QCursor's char format depends on block positions.
Change-Id: I94eb137882dc6b5f7b01fa7693b4a536cc48d02a
Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
Diffstat (limited to 'src/widgets/accessible')
-rw-r--r-- | src/widgets/accessible/qaccessiblewidgets.cpp | 63 |
1 files changed, 30 insertions, 33 deletions
diff --git a/src/widgets/accessible/qaccessiblewidgets.cpp b/src/widgets/accessible/qaccessiblewidgets.cpp index d695bdcbc4..f0a8ecf608 100644 --- a/src/widgets/accessible/qaccessiblewidgets.cpp +++ b/src/widgets/accessible/qaccessiblewidgets.cpp @@ -706,51 +706,48 @@ QString QAccessibleTextWidget::attributes(int offset, int *startOffset, int *end http://linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2/textattributes */ - if (offset >= characterCount()) { + // IAccessible2 defines -1 as length and -2 as cursor position + if (offset == -2) + offset = cursorPosition(); + + const int charCount = characterCount(); + + // -1 doesn't make much sense here, but it's better to return something + // screen readers may ask for text attributes at the cursor pos which may be equal to length + if (offset == -1 || offset == charCount) + offset = charCount - 1; + + if (offset < 0 || offset > charCount) { *startOffset = -1; *endOffset = -1; return QString(); } - QMap<QByteArray, QString> attrs; QTextCursor cursor = textCursor(); + cursor.setPosition(offset); + QTextBlock block = cursor.block(); - //cursor.charFormat returns the format of the previous character - cursor.setPosition(offset + 1); - QTextCharFormat charFormat = cursor.charFormat(); + int blockStart = block.position(); + int blockEnd = blockStart + block.length(); - cursor.setPosition(offset); - QTextBlockFormat blockFormat = cursor.blockFormat(); + QTextBlock::iterator iter = block.begin(); + while (!iter.fragment().contains(offset)) + ++iter; - QTextCharFormat charFormatComp; - QTextBlockFormat blockFormatComp; - - *startOffset = offset; - cursor.setPosition(*startOffset); - while (*startOffset > 0) { - charFormatComp = cursor.charFormat(); - cursor.setPosition(*startOffset - 1); - blockFormatComp = cursor.blockFormat(); - if ((charFormat == charFormatComp) && (blockFormat == blockFormatComp)) - (*startOffset)--; - else - break; - } + QTextFragment fragment = iter.fragment(); + int pos = fragment.position(); - int limit = characterCount() + 1; - *endOffset = offset + 1; - cursor.setPosition(*endOffset); - while (*endOffset < limit) { - blockFormatComp = cursor.blockFormat(); - cursor.setPosition(*endOffset + 1); - charFormatComp = cursor.charFormat(); - if ((charFormat == charFormatComp) && (cursor.blockFormat() == blockFormatComp)) - (*endOffset)++; - else - break; - } + // text block and fragment may overlap, use the smallest common range + *startOffset = qMax(pos, blockStart); + Q_ASSERT(*startOffset <= offset); + *endOffset = qMin(pos + fragment.length(), blockEnd); + Q_ASSERT(*endOffset >= offset); + QTextCharFormat charFormat = fragment.charFormat(); + QTextBlockFormat blockFormat = cursor.blockFormat(); + + QMap<QByteArray, QString> attrs; QString family = charFormat.fontFamily(); if (!family.isEmpty()) { family = family.replace('\\',QStringLiteral("\\\\")); |