From 477c43260eea8461dff1e0e8acb4b61a1600518a Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 30 Jan 2012 18:52:46 +0100 Subject: Accessibility: add text update events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iece9d100b3f5a379d7d8e29dea67a10d0c918c06 Reviewed-by: Jan-Arve Sæther --- src/gui/accessible/qaccessible.cpp | 14 +- src/gui/accessible/qaccessible.h | 147 ++++++++++++++++++++- src/testlib/qtestaccessible.h | 74 ++++++++++- src/widgets/widgets/qabstractslider.cpp | 2 +- src/widgets/widgets/qabstractspinbox.cpp | 4 +- src/widgets/widgets/qlineedit_p.cpp | 5 +- src/widgets/widgets/qprogressbar.cpp | 2 +- src/widgets/widgets/qwidgetlinecontrol.cpp | 42 +++++- .../other/qaccessibility/tst_qaccessibility.cpp | 93 +++++++++++-- 9 files changed, 347 insertions(+), 36 deletions(-) diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 59794a5a06..561aa83142 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -268,16 +268,16 @@ QT_BEGIN_NAMESPACE row's header, has been changed. \value TableRowHeaderChanged A table row header has been changed. \value TableSummaryChanged The summary of a table has been changed. - \value TextAttributeChanged - \value TextCaretMoved The caret has moved in an editable widget. + \omitvalue TextAttributeChanged + \omitvalue TextCaretMoved The caret has moved in an editable widget. The caret represents the cursor position in an editable widget with the input focus. \value TextColumnChanged A text column has been changed. - \value TextInserted Text has been inserted into an editable widget. - \value TextRemoved Text has been removed from an editable widget. - \value TextSelectionChanged The selected text has changed in an editable widget. - \value TextUpdated The text has been update in an editable widget. - \value ValueChanged The QAccessible::Value of an object has changed. + \omitvalue TextInserted Text has been inserted into an editable widget. + \omitvalue TextRemoved Text has been removed from an editable widget. + \omitvalue TextSelectionChanged The selected text has changed in an editable widget. + \omitvalue TextUpdated The text has been update in an editable widget. + \omitvalue ValueChanged The QAccessible::Value of an object has changed. \value VisibleDataChanged The values for this enum are defined to be the same as those defined in the diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index 4d79fe78ee..a5ec8071b8 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -145,7 +145,9 @@ public: ParentChanged = 0x800F, HelpChanged = 0x80A0, DefaultActionChanged = 0x80B0, - AcceleratorChanged = 0x80C0 + AcceleratorChanged = 0x80C0, + + InvalidEvent }; // 64 bit enums seem hard on some platforms (windows...) @@ -436,6 +438,15 @@ public: : m_type(typ), m_object(obj), m_child(chld) { Q_ASSERT(obj); + // All events below have a subclass of QAccessibleEvent. + // Use the subclass, since it's expected that it's possible to cast to that. + Q_ASSERT(m_type != QAccessible::ValueChanged); + Q_ASSERT(m_type != QAccessible::StateChanged); + Q_ASSERT(m_type != QAccessible::TextCaretMoved); + Q_ASSERT(m_type != QAccessible::TextSelectionChanged); + Q_ASSERT(m_type != QAccessible::TextInserted); + Q_ASSERT(m_type != QAccessible::TextRemoved); + Q_ASSERT(m_type != QAccessible::TextUpdated); } virtual ~QAccessibleEvent() @@ -448,7 +459,6 @@ public: QAccessibleInterface *accessibleInterface() const; protected: - QAccessible::Event m_type; QObject *m_object; int m_child; @@ -458,8 +468,10 @@ class Q_GUI_EXPORT QAccessibleStateChangeEvent :public QAccessibleEvent { public: inline QAccessibleStateChangeEvent(QAccessible::State state, QObject *obj, int chld = -1) - : QAccessibleEvent(QAccessible::StateChanged, obj, chld), m_changedStates(state) - {} + : QAccessibleEvent(QAccessible::InvalidEvent, obj, chld), m_changedStates(state) + { + m_type = QAccessible::StateChanged; + } QAccessible::State changedStates() const { return m_changedStates; @@ -469,6 +481,133 @@ protected: QAccessible::State m_changedStates; }; +// Update the cursor and optionally the selection. +class Q_GUI_EXPORT QAccessibleTextCursorEvent : public QAccessibleEvent +{ +public: + inline QAccessibleTextCursorEvent(int cursorPos, QObject *obj, int chld = -1) + : QAccessibleEvent(QAccessible::InvalidEvent, obj, chld) + , m_cursorPosition(cursorPos) + { + m_type = QAccessible::TextCaretMoved; + } + + void setCursorPosition(int position) { m_cursorPosition = position; } + int cursorPosition() const { return m_cursorPosition; } + +protected: + int m_cursorPosition; +}; + +// Updates the cursor position simultaneously. By default the cursor is set to the end of the selection. +class Q_GUI_EXPORT QAccessibleTextSelectionEvent : public QAccessibleTextCursorEvent +{ +public: + inline QAccessibleTextSelectionEvent(int start, int end, QObject *obj, int chld = -1) + : QAccessibleTextCursorEvent((start == -1) ? 0 : end, obj, chld) + , m_selectionStart(start), m_selectionEnd(end) + { + m_type = QAccessible::TextSelectionChanged; + } + + void setSelection(int start, int end) { + m_selectionStart = start; + m_selectionEnd = end; + } + + int selectionStart() const { return m_selectionStart; } + int selectionEnd() const { return m_selectionEnd; } + +protected: + int m_selectionStart; + int m_selectionEnd; +}; + +class Q_GUI_EXPORT QAccessibleTextInsertEvent : public QAccessibleTextCursorEvent +{ +public: + inline QAccessibleTextInsertEvent(int position, const QString &text, QObject *obj, int chld = -1) + : QAccessibleTextCursorEvent(position + text.length(), obj, chld) + , m_position(position), m_text(text) + { + m_type = QAccessible::TextInserted; + } + + QString textInserted() const { + return m_text; + } + int changePosition() const { + return m_position; + } + +protected: + int m_position; + QString m_text; +}; + +class Q_GUI_EXPORT QAccessibleTextRemoveEvent : public QAccessibleTextCursorEvent +{ +public: + inline QAccessibleTextRemoveEvent(int position, const QString &text, QObject *obj, int chld = -1) + : QAccessibleTextCursorEvent(position, obj, chld) + , m_position(position), m_text(text) + { + m_type = QAccessible::TextRemoved; + } + + QString textRemoved() const { + return m_text; + } + int changePosition() const { + return m_position; + } + +protected: + int m_position; + QString m_text; +}; + +class Q_GUI_EXPORT QAccessibleTextUpdateEvent : public QAccessibleTextCursorEvent +{ +public: + inline QAccessibleTextUpdateEvent(int position, const QString &oldText, const QString &text, QObject *obj, int chld = -1) + : QAccessibleTextCursorEvent(position + text.length(), obj, chld) + , m_position(position), m_oldText(oldText), m_text(text) + { + m_type = QAccessible::TextUpdated; + } + QString textRemoved() const { + return m_oldText; + } + QString textInserted() const { + return m_text; + } + int changePosition() const { + return m_position; + } + +protected: + int m_position; + QString m_oldText; + QString m_text; +}; + +class Q_GUI_EXPORT QAccessibleValueChangeEvent : public QAccessibleEvent +{ +public: + inline QAccessibleValueChangeEvent(const QVariant &val, QObject *obj, int chld = -1) + : QAccessibleEvent(QAccessible::InvalidEvent, obj, chld) + , m_value(val) + { + m_type = QAccessible::ValueChanged; + } + + void setValue(const QVariant & val) { m_value= val; } + QVariant value() const { return m_value; } + +protected: + QVariant m_value; +}; #define QAccessibleInterface_iid "org.qt-project.Qt.QAccessibleInterface" Q_DECLARE_INTERFACE(QAccessibleInterface, QAccessibleInterface_iid) diff --git a/src/testlib/qtestaccessible.h b/src/testlib/qtestaccessible.h index 6d8d6125c1..fa2718b1b7 100644 --- a/src/testlib/qtestaccessible.h +++ b/src/testlib/qtestaccessible.h @@ -68,14 +68,51 @@ typedef QList EventList; bool operator==(const QAccessibleEvent &l, const QAccessibleEvent &r) { - if (l.type() != r.type() || - l.object() != r.object() || - l.child() != r.child()) + if (l.type() != r.type()) { +// qDebug() << "QAccessibleEvent with wrong type: " << qAccessibleEventString(l.type()) << " and " << qAccessibleEventString(r.type()); return false; + } + if (l.object() != r.object() || + l.child() != r.child()) { +// qDebug() << "QAccessibleEvent for wrong object: " << l.object() << " and " << r.object() << " child: " << l.child() << " and " << r.child(); + return false; + } if (l.type() == QAccessible::StateChanged) { return static_cast(&l)->changedStates() == static_cast(&r)->changedStates(); + } else if (l.type() == QAccessible::TextCaretMoved) { + return static_cast(&l)->cursorPosition() + == static_cast(&r)->cursorPosition(); + } else if (l.type() == QAccessible::TextSelectionChanged) { + const QAccessibleTextSelectionEvent *le = static_cast(&l); + const QAccessibleTextSelectionEvent *re = static_cast(&r); + return le->cursorPosition() == re->cursorPosition() && + le->selectionStart() == re->selectionStart() && + le->selectionEnd() == re->selectionEnd(); + } else if (l.type() == QAccessible::TextInserted) { + const QAccessibleTextInsertEvent *le = static_cast(&l); + const QAccessibleTextInsertEvent *re = static_cast(&r); + return le->cursorPosition() == re->cursorPosition() && + le->changePosition() == re->changePosition() && + le->textInserted() == re->textInserted(); + } else if (l.type() == QAccessible::TextRemoved) { + const QAccessibleTextRemoveEvent *le = static_cast(&l); + const QAccessibleTextRemoveEvent *re = static_cast(&r); + return le->cursorPosition() == re->cursorPosition() && + le->changePosition() == re->changePosition() && + le->textRemoved() == re->textRemoved(); + } else if (l.type() == QAccessible::TextUpdated) { + const QAccessibleTextUpdateEvent *le = static_cast(&l); + const QAccessibleTextUpdateEvent *re = static_cast(&r); + return le->cursorPosition() == re->cursorPosition() && + le->changePosition() == re->changePosition() && + le->textInserted() == re->textInserted() && + le->textRemoved() == re->textRemoved(); + } else if (l.type() == QAccessible::ValueChanged) { + const QAccessibleValueChangeEvent *le = static_cast(&l); + const QAccessibleValueChangeEvent *re = static_cast(&r); + return le->value() == re->value(); } return true; } @@ -108,7 +145,7 @@ public: return res; } static bool containsEvent(QAccessibleEvent *event) { - Q_FOREACH (QAccessibleEvent *ev, eventList()) { + Q_FOREACH (const QAccessibleEvent *ev, eventList()) { if (*ev == *event) return true; } @@ -146,9 +183,34 @@ private: } static QAccessibleEvent *copyEvent(QAccessibleEvent *event) { - if (event->type() == QAccessible::StateChanged) - return new QAccessibleStateChangeEvent(static_cast(event)->changedStates(), + if (event->type() == QAccessible::StateChanged) { + return new QAccessibleStateChangeEvent(static_cast(event)->changedStates(), event->object(), event->child()); + } else if (event->type() == QAccessible::TextCaretMoved) { + return new QAccessibleTextCursorEvent(static_cast(event)->cursorPosition(), event->object(), event->child()); + } else if (event->type() == QAccessible::TextSelectionChanged) { + const QAccessibleTextSelectionEvent *original = static_cast(event); + QAccessibleTextSelectionEvent *ev = new QAccessibleTextSelectionEvent(original->selectionStart(), original->selectionEnd(), event->object(), event->child()); + ev->setCursorPosition(original->cursorPosition()); + return ev; + } else if (event->type() == QAccessible::TextInserted) { + const QAccessibleTextInsertEvent *original = static_cast(event); + QAccessibleTextInsertEvent *ev = new QAccessibleTextInsertEvent(original->changePosition(), original->textInserted(), event->object(), event->child()); + ev->setCursorPosition(original->cursorPosition()); + return ev; + } else if (event->type() == QAccessible::TextRemoved) { + const QAccessibleTextRemoveEvent *original = static_cast(event); + QAccessibleTextRemoveEvent *ev = new QAccessibleTextRemoveEvent(original->changePosition(), original->textRemoved(), event->object(), event->child()); + ev->setCursorPosition(original->cursorPosition()); + return ev; + } else if (event->type() == QAccessible::TextUpdated) { + const QAccessibleTextUpdateEvent *original = static_cast(event); + QAccessibleTextUpdateEvent *ev = new QAccessibleTextUpdateEvent(original->changePosition(), original->textRemoved(), original->textInserted(), event->object(), event->child()); + ev->setCursorPosition(original->cursorPosition()); + return ev; + } else if (event->type() == QAccessible::ValueChanged) { + return new QAccessibleValueChangeEvent(static_cast(event)->value(), event->object(), event->child()); + } return new QAccessibleEvent(event->type(), event->object(), event->child()); } diff --git a/src/widgets/widgets/qabstractslider.cpp b/src/widgets/widgets/qabstractslider.cpp index 2d3f79e43d..083b9303f4 100644 --- a/src/widgets/widgets/qabstractslider.cpp +++ b/src/widgets/widgets/qabstractslider.cpp @@ -538,7 +538,7 @@ void QAbstractSlider::setValue(int value) emit sliderMoved((d->position = value)); } #ifndef QT_NO_ACCESSIBILITY - QAccessibleEvent event(QAccessible::ValueChanged, this); + QAccessibleValueChangeEvent event(d->value, this); QAccessible::updateAccessibility(&event); #endif sliderChange(SliderValueChange); diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index 7b55b0fa8c..384fff7f7b 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -976,7 +976,7 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event) } } #ifndef QT_NO_ACCESSIBILITY - QAccessibleEvent event(QAccessible::ValueChanged, this); + QAccessibleValueChangeEvent event(d->value, this); QAccessible::updateAccessibility(&event); #endif return; @@ -1596,7 +1596,7 @@ void QAbstractSpinBoxPrivate::updateState(bool up, bool fromKeyboard /* = false buttonState = (up ? Up : Down) | (fromKeyboard ? Keyboard : Mouse); q->stepBy(up ? 1 : -1); #ifndef QT_NO_ACCESSIBILITY - QAccessibleEvent event(QAccessible::ValueChanged, q); + QAccessibleValueChangeEvent event(value, q); QAccessible::updateAccessibility(&event); #endif } diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index 37e956c27f..36e394450b 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -144,8 +144,9 @@ void QLineEditPrivate::_q_selectionChanged() emit q->selectionChanged(); #ifndef QT_NO_ACCESSIBILITY - QAccessibleEvent event(QAccessible::TextSelectionChanged, q); - QAccessible::updateAccessibility(&event); + QAccessibleTextSelectionEvent ev(control->selectionStart(), control->selectionEnd(), q); + ev.setCursorPosition(control->cursorPosition()); + QAccessible::updateAccessibility(&ev); #endif } diff --git a/src/widgets/widgets/qprogressbar.cpp b/src/widgets/widgets/qprogressbar.cpp index 0439caeb88..22b35d05a5 100644 --- a/src/widgets/widgets/qprogressbar.cpp +++ b/src/widgets/widgets/qprogressbar.cpp @@ -314,7 +314,7 @@ void QProgressBar::setValue(int value) d->value = value; emit valueChanged(value); #ifndef QT_NO_ACCESSIBILITY - QAccessibleEvent event(QAccessible::ValueChanged, this); + QAccessibleValueChangeEvent event(value, this); QAccessible::updateAccessibility(&event); #endif if (d->repaintRequired()) diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp index 7c659ebb64..8806999355 100644 --- a/src/widgets/widgets/qwidgetlinecontrol.cpp +++ b/src/widgets/widgets/qwidgetlinecontrol.cpp @@ -768,8 +768,19 @@ void QWidgetLineControl::internalSetText(const QString &txt, int pos, bool edite #ifndef QT_NO_ACCESSIBILITY if (changed) { - QAccessibleEvent event(QAccessible::TextUpdated, parent()); - QAccessible::updateAccessibility(&event); + if (oldText.isEmpty()) { + QAccessibleTextInsertEvent event(0, txt, parent()); + event.setCursorPosition(m_cursor); + QAccessible::updateAccessibility(&event); + } else if (txt.isEmpty()) { + QAccessibleTextRemoveEvent event(0, oldText, parent()); + event.setCursorPosition(m_cursor); + QAccessible::updateAccessibility(&event); + } else { + QAccessibleTextUpdateEvent event(0, oldText, txt, parent()); + event.setCursorPosition(m_cursor); + QAccessible::updateAccessibility(&event); + } } #endif } @@ -816,6 +827,10 @@ void QWidgetLineControl::internalInsert(const QString &s) addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend)); if (m_maskData) { QString ms = maskString(m_cursor, s); +#ifndef QT_NO_ACCESSIBILITY + QAccessibleTextInsertEvent insertEvent(m_cursor, ms, parent()); + QAccessible::updateAccessibility(&insertEvent); +#endif for (int i = 0; i < (int) ms.length(); ++i) { addCommand (Command(DeleteSelection, m_cursor + i, m_text.at(m_cursor + i), -1, -1)); addCommand(Command(Insert, m_cursor + i, ms.at(i), -1, -1)); @@ -824,9 +839,17 @@ void QWidgetLineControl::internalInsert(const QString &s) m_cursor += ms.length(); m_cursor = nextMaskBlank(m_cursor); m_textDirty = true; +#ifndef QT_NO_ACCESSIBILITY + QAccessibleTextCursorEvent event(m_cursor, parent()); + QAccessible::updateAccessibility(&event); +#endif } else { int remaining = m_maxLength - m_text.length(); if (remaining != 0) { +#ifndef QT_NO_ACCESSIBILITY + QAccessibleTextInsertEvent insertEvent(m_cursor, s, parent()); + QAccessible::updateAccessibility(&insertEvent); +#endif m_text.insert(m_cursor, s.left(remaining)); for (int i = 0; i < (int) s.left(remaining).length(); ++i) addCommand(Command(Insert, m_cursor++, s.at(i), -1, -1)); @@ -854,6 +877,10 @@ void QWidgetLineControl::internalDelete(bool wasBackspace) addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend)); addCommand(Command((CommandType)((m_maskData ? 2 : 0) + (wasBackspace ? Remove : Delete)), m_cursor, m_text.at(m_cursor), -1, -1)); +#ifndef QT_NO_ACCESSIBILITY + QAccessibleTextRemoveEvent event(m_cursor, m_text.at(m_cursor), parent()); + QAccessible::updateAccessibility(&event); +#endif if (m_maskData) { m_text.replace(m_cursor, 1, clearString(m_cursor, 1)); addCommand(Command(Insert, m_cursor, m_text.at(m_cursor), -1, -1)); @@ -891,6 +918,10 @@ void QWidgetLineControl::removeSelectedText() for (i = m_selend-1; i >= m_selstart; --i) addCommand (Command(RemoveSelection, i, m_text.at(i), -1, -1)); } +#ifndef QT_NO_ACCESSIBILITY + QAccessibleTextRemoveEvent event(m_selstart, m_text.mid(m_selstart, m_selend - m_selstart), parent()); + QAccessible::updateAccessibility(&event); +#endif if (m_maskData) { m_text.replace(m_selstart, m_selend - m_selstart, clearString(m_selstart, m_selend - m_selstart)); for (int i = 0; i < m_selend - m_selstart; ++i) @@ -1369,8 +1400,11 @@ void QWidgetLineControl::emitCursorPositionChanged() m_lastCursorPos = m_cursor; cursorPositionChanged(oldLast, m_cursor); #ifndef QT_NO_ACCESSIBILITY - QAccessibleEvent event(QAccessible::TextCaretMoved, parent()); - QAccessible::updateAccessibility(&event); + // otherwise we send a selection update which includes the cursor + if (!hasSelectedText()) { + QAccessibleTextCursorEvent event(m_cursor, parent()); + QAccessible::updateAccessibility(&event); + } #endif } } diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index a72dac1b81..fbbf45ad58 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -1475,7 +1475,7 @@ void tst_QAccessibility::spinBoxTest() QTestAccessibility::clearEvents(); QTest::keyPress(spinBox, Qt::Key_Up); QTest::qWait(200); - QAccessibleEvent expectedEvent(QAccessible::ValueChanged, spinBox); + QAccessibleValueChangeEvent expectedEvent(spinBox->value(), spinBox); QVERIFY(QTestAccessibility::containsEvent(&expectedEvent)); delete spinBox; QTestAccessibility::clearEvents(); @@ -1695,8 +1695,10 @@ void tst_QAccessibility::mdiSubWindowTest() void tst_QAccessibility::lineEditTest() { + QWidget *toplevel = new QWidget; + { QLineEdit *le = new QLineEdit; - QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(le); + QAIPtr iface(QAccessible::queryAccessibleInterface(le)); QVERIFY(iface); le->show(); @@ -1727,7 +1729,6 @@ void tst_QAccessibility::lineEditTest() QVERIFY(!(iface->state().passwordEdit)); QCOMPARE(iface->text(QAccessible::Value), secret); - QWidget *toplevel = new QWidget; le->setParent(toplevel); toplevel->show(); QApplication::processEvents(); @@ -1754,20 +1755,23 @@ void tst_QAccessibility::lineEditTest() iface->setText(QAccessible::Value, QLatin1String("This text is not a number")); QCOMPARE(le->text(), QLatin1String("500")); - delete iface; delete le; delete le2; - QTestAccessibility::clearEvents(); + } - // IA2 + { + // Text interface to get the current text QString cite = "I always pass on good advice. It is the only thing to do with it. It is never of any use to oneself. --Oscar Wilde"; QLineEdit *le3 = new QLineEdit(cite, toplevel); - iface = QAccessible::queryAccessibleInterface(le3); + le3->show(); + QAIPtr iface(QAccessible::queryAccessibleInterface(le3)); QAccessibleTextInterface* textIface = iface->textInterface(); le3->deselect(); + QTestAccessibility::clearEvents(); le3->setCursorPosition(3); QCOMPARE(textIface->cursorPosition(), 3); - QAccessibleEvent caretEvent(QAccessible::TextCaretMoved, le3); + + QAccessibleTextCursorEvent caretEvent(3, le3); QTRY_VERIFY(QTestAccessibility::containsEvent(&caretEvent)); QCOMPARE(textIface->selectionCount(), 0); QTestAccessibility::clearEvents(); @@ -1813,7 +1817,78 @@ void tst_QAccessibility::lineEditTest() QCOMPARE(textIface->textAtOffset(5, QAccessible2::LineBoundary,&start,&end), cite); QCOMPARE(textIface->textAtOffset(5, QAccessible2::NoBoundary,&start,&end), cite); - delete iface; + QTestAccessibility::clearEvents(); + } + + { + // Test events: cursor movement, selection, text changes + QString text = "Hello, world"; + QLineEdit *lineEdit = new QLineEdit(text, toplevel); + lineEdit->show(); + QTestAccessibility::clearEvents(); + // cursor + lineEdit->setCursorPosition(5); + QAccessibleTextCursorEvent cursorEvent(5, lineEdit); + QVERIFY_EVENT(&cursorEvent); + lineEdit->setCursorPosition(0); + cursorEvent.setCursorPosition(0); + QVERIFY_EVENT(&cursorEvent); + + // selection + lineEdit->setSelection(2, 4); + + QAccessibleTextSelectionEvent sel(2, 2+4, lineEdit); + QVERIFY_EVENT(&sel); + + lineEdit->selectAll(); + sel.setSelection(0, lineEdit->text().length()); + sel.setCursorPosition(lineEdit->text().length()); + QVERIFY_EVENT(&sel); + + lineEdit->setSelection(10, -4); + QCOMPARE(lineEdit->cursorPosition(), 6); + QAccessibleTextSelectionEvent sel2(6, 10, lineEdit); + sel2.setCursorPosition(6); + QVERIFY_EVENT(&sel2); + + lineEdit->deselect(); + QAccessibleTextSelectionEvent sel3(-1, -1, lineEdit); + sel3.setCursorPosition(6); + QVERIFY_EVENT(&sel3); + + // editing + lineEdit->clear(); + // FIXME: improve redundant updates + QAccessibleTextRemoveEvent remove(0, text, lineEdit); + QVERIFY_EVENT(&remove); + + QAccessibleTextSelectionEvent noSel(-1, -1, lineEdit); + QVERIFY_EVENT(&noSel); + QAccessibleTextCursorEvent cursor(0, lineEdit); + QVERIFY_EVENT(&cursor); + + lineEdit->setText("foo"); + qDebug() << QTestAccessibility::events(); + cursorEvent.setCursorPosition(3); + QVERIFY_EVENT(&cursorEvent); + + QAccessibleTextInsertEvent e(0, "foo", lineEdit); + QVERIFY(QTestAccessibility::containsEvent(&e)); + + lineEdit->setText("bar"); + QAccessibleTextUpdateEvent update(0, "foo", "bar", lineEdit); + QVERIFY(QTestAccessibility::containsEvent(&update)); + +// QTestEventList keys; +// keys.addKeyClick('D'); +// keys.addKeyClick('E'); +// keys.addKeyClick(Qt::Key_Left); +// keys.addKeyClick(Qt::Key_Left); +// keys.addKeyClick('C'); +// keys.addKeyClick('O'); +// keys.simulate(lineEdit); +// FIXME: Test key press events... + } delete toplevel; QTestAccessibility::clearEvents(); } -- cgit v1.2.3