Accessibility text updates for QTextEdit

For Mac this makes QTextEdit work nicely with VoiceOver.

Task-number: QTBUG-37204

Change-Id: I1326d24ca6a932ad667ee395f62881b6ec64e892
Reviewed-by: Jan Arve Sæther <jan-arve.saether@digia.com>
This commit is contained in:
Frederik Gladhorn 2014-04-02 19:49:08 +02:00 committed by The Qt Project
parent 39c5098dbb
commit cc57a2e90f
4 changed files with 72 additions and 0 deletions

View File

@ -438,6 +438,7 @@ void QWidgetTextControlPrivate::setContent(Qt::TextFormat format, const QString
QObject::connect(doc, SIGNAL(contentsChanged()), q, SLOT(_q_updateCurrentCharFormatAndSelection()));
QObject::connect(doc, SIGNAL(cursorPositionChanged(QTextCursor)), q, SLOT(_q_emitCursorPosChanged(QTextCursor)));
QObject::connect(doc, SIGNAL(contentsChange(int,int,int)), q, SLOT(_q_contentsChanged(int,int,int)));
QObject::connect(doc, SIGNAL(documentLayoutChanged()), q, SLOT(_q_documentLayoutChanged()));
// convenience signal forwards
@ -641,6 +642,33 @@ void QWidgetTextControlPrivate::_q_emitCursorPosChanged(const QTextCursor &someC
}
}
void QWidgetTextControlPrivate::_q_contentsChanged(int from, int charsRemoved, int charsAdded)
{
Q_Q(QWidgetTextControl);
#ifndef QT_NO_ACCESSIBILITY
if (QAccessible::isActive()) {
QTextCursor tmp(doc);
tmp.setPosition(from);
tmp.setPosition(from + charsAdded, QTextCursor::KeepAnchor);
QString newText = tmp.selectedText();
// always report the right number of removed chars, but in lack of the real string use spaces
QString oldText = QString(charsRemoved, QLatin1Char(' '));
QAccessibleEvent *ev = 0;
if (charsRemoved == 0) {
ev = new QAccessibleTextInsertEvent(q->parent(), from, newText);
} else if (charsAdded == 0) {
ev = new QAccessibleTextRemoveEvent(q->parent(), from, oldText);
} else {
ev = new QAccessibleTextUpdateEvent(q->parent(), from, oldText, newText);
}
QAccessible::updateAccessibility(ev);
delete ev;
}
#endif
}
void QWidgetTextControlPrivate::_q_documentLayoutChanged()
{
Q_Q(QWidgetTextControl);

View File

@ -262,6 +262,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_copyLink())
Q_PRIVATE_SLOT(d_func(), void _q_updateBlock(const QTextBlock &))
Q_PRIVATE_SLOT(d_func(), void _q_documentLayoutChanged())
Q_PRIVATE_SLOT(d_func(), void _q_contentsChanged(int, int, int))
};

View File

@ -111,6 +111,7 @@ public:
#endif
void _q_emitCursorPosChanged(const QTextCursor &someCursor);
void _q_contentsChanged(int from, int charsRemoved, int charsAdded);
void setBlinkingCursorEnabled(bool enable);

View File

@ -1711,6 +1711,48 @@ void tst_QAccessibility::textEditTest()
QCOMPARE(textIface->textAtOffset(28, QAccessible::CharBoundary, &start, &end), QLatin1String("\n"));
QCOMPARE(start, 28);
QCOMPARE(end, 29);
edit.clear();
QTestAccessibility::clearEvents();
// make sure we get notifications when typing text
QTestEventList keys;
keys.addKeyClick('A');
keys.simulate(&edit);
keys.clear();
QAccessibleTextInsertEvent insertA(&edit, 0, "A");
QVERIFY_EVENT(&insertA);
QAccessibleTextCursorEvent move1(&edit, 1);
QVERIFY_EVENT(&move1);
keys.addKeyClick('c');
keys.simulate(&edit);
keys.clear();
QAccessibleTextInsertEvent insertC(&edit, 1, "c");
QVERIFY_EVENT(&insertC);
QAccessibleTextCursorEvent move2(&edit, 2);
QVERIFY_EVENT(&move2);
keys.addKeyClick(Qt::Key_Backspace);
keys.simulate(&edit);
keys.clear();
// FIXME this should get a proper string instead of space
QAccessibleTextRemoveEvent del(&edit, 1, " ");
QVERIFY_EVENT(&del);
QVERIFY_EVENT(&move1);
// it would be nicer to get a text update event, but the current implementation
// instead does remove and insert which is also fine
edit.setText(QStringLiteral("Accessibility rocks"));
QAccessibleTextRemoveEvent remove(&edit, 0, " ");
QVERIFY_EVENT(&remove);
// FIXME the new text is not there yet
QEXPECT_FAIL("", "Inserting should always contain the new text", Continue);
QAccessibleTextInsertEvent insert(&edit, 0, "Accessibility rocks");
QVERIFY_EVENT(&insert);
}
QTestAccessibility::clearEvents();
}