summaryrefslogtreecommitdiffstats
path: root/src/widgets/accessible
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2014-06-23 17:57:34 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-06-26 17:37:08 +0200
commita58ec950f06c8de366b4b693491eaaafae116041 (patch)
treec10aaecbc9889faab54dd7d5f338bffacf8d55f0 /src/widgets/accessible
parent86802ec04d23c8ddc82268e18eb99d5f71450914 (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.cpp63
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("\\\\"));