diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/accessible/qaccessible.cpp | 14 | ||||
-rw-r--r-- | src/gui/accessible/qaccessible.h | 147 | ||||
-rw-r--r-- | src/testlib/qtestaccessible.h | 74 | ||||
-rw-r--r-- | src/widgets/widgets/qabstractslider.cpp | 2 | ||||
-rw-r--r-- | src/widgets/widgets/qabstractspinbox.cpp | 4 | ||||
-rw-r--r-- | src/widgets/widgets/qlineedit_p.cpp | 5 | ||||
-rw-r--r-- | src/widgets/widgets/qprogressbar.cpp | 2 | ||||
-rw-r--r-- | src/widgets/widgets/qwidgetlinecontrol.cpp | 42 |
8 files changed, 263 insertions, 27 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<QAccessibleEvent*> 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<const QAccessibleStateChangeEvent*>(&l)->changedStates() == static_cast<const QAccessibleStateChangeEvent*>(&r)->changedStates(); + } else if (l.type() == QAccessible::TextCaretMoved) { + return static_cast<const QAccessibleTextCursorEvent*>(&l)->cursorPosition() + == static_cast<const QAccessibleTextCursorEvent*>(&r)->cursorPosition(); + } else if (l.type() == QAccessible::TextSelectionChanged) { + const QAccessibleTextSelectionEvent *le = static_cast<const QAccessibleTextSelectionEvent*>(&l); + const QAccessibleTextSelectionEvent *re = static_cast<const QAccessibleTextSelectionEvent*>(&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<const QAccessibleTextInsertEvent*>(&l); + const QAccessibleTextInsertEvent *re = static_cast<const QAccessibleTextInsertEvent*>(&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<const QAccessibleTextRemoveEvent*>(&l); + const QAccessibleTextRemoveEvent *re = static_cast<const QAccessibleTextRemoveEvent*>(&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<const QAccessibleTextUpdateEvent*>(&l); + const QAccessibleTextUpdateEvent *re = static_cast<const QAccessibleTextUpdateEvent*>(&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<const QAccessibleValueChangeEvent*>(&l); + const QAccessibleValueChangeEvent *re = static_cast<const QAccessibleValueChangeEvent*>(&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<const QAccessibleStateChangeEvent*>(event)->changedStates(), + if (event->type() == QAccessible::StateChanged) { + return new QAccessibleStateChangeEvent(static_cast<QAccessibleStateChangeEvent*>(event)->changedStates(), event->object(), event->child()); + } else if (event->type() == QAccessible::TextCaretMoved) { + return new QAccessibleTextCursorEvent(static_cast<QAccessibleTextCursorEvent*>(event)->cursorPosition(), event->object(), event->child()); + } else if (event->type() == QAccessible::TextSelectionChanged) { + const QAccessibleTextSelectionEvent *original = static_cast<QAccessibleTextSelectionEvent*>(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<QAccessibleTextInsertEvent*>(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<QAccessibleTextRemoveEvent*>(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<QAccessibleTextUpdateEvent*>(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<QAccessibleValueChangeEvent*>(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 } } |