From cc57a2e90f18a39ce3c74b6ad0db9a64aa135ddf Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 2 Apr 2014 19:49:08 +0200 Subject: Accessibility text updates for QTextEdit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For Mac this makes QTextEdit work nicely with VoiceOver. Task-number: QTBUG-37204 Change-Id: I1326d24ca6a932ad667ee395f62881b6ec64e892 Reviewed-by: Jan Arve Sæther --- src/widgets/widgets/qwidgettextcontrol.cpp | 28 +++++++++++++++ src/widgets/widgets/qwidgettextcontrol_p.h | 1 + src/widgets/widgets/qwidgettextcontrol_p_p.h | 1 + .../other/qaccessibility/tst_qaccessibility.cpp | 42 ++++++++++++++++++++++ 4 files changed, 72 insertions(+) diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index 3740f3e698..9cc62fd10a 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -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); diff --git a/src/widgets/widgets/qwidgettextcontrol_p.h b/src/widgets/widgets/qwidgettextcontrol_p.h index 0c76355ca1..867b55fe32 100644 --- a/src/widgets/widgets/qwidgettextcontrol_p.h +++ b/src/widgets/widgets/qwidgettextcontrol_p.h @@ -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)) }; diff --git a/src/widgets/widgets/qwidgettextcontrol_p_p.h b/src/widgets/widgets/qwidgettextcontrol_p_p.h index 727821015e..4d578c76f8 100644 --- a/src/widgets/widgets/qwidgettextcontrol_p_p.h +++ b/src/widgets/widgets/qwidgettextcontrol_p_p.h @@ -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); diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 9f0540173a..fcc5581bea 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -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(); } -- cgit v1.2.3