summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gui/accessible/qaccessible.cpp14
-rw-r--r--src/gui/accessible/qaccessible.h147
-rw-r--r--src/testlib/qtestaccessible.h74
-rw-r--r--src/widgets/widgets/qabstractslider.cpp2
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp4
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp5
-rw-r--r--src/widgets/widgets/qprogressbar.cpp2
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp42
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
}
}