summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/widgets/accessible/qaccessiblewidget.cpp3
-rw-r--r--src/widgets/accessible/qaccessiblewidgetfactory.cpp5
-rw-r--r--src/widgets/accessible/rangecontrols.cpp118
-rw-r--r--src/widgets/accessible/rangecontrols.h38
-rw-r--r--src/widgets/accessible/simplewidgets.h1
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp1
-rw-r--r--src/widgets/widgets/qabstractspinbox.h1
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp18
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol_p.h17
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp13
10 files changed, 195 insertions, 20 deletions
diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp
index 48f99f4d35..89fc988329 100644
--- a/src/widgets/accessible/qaccessiblewidget.cpp
+++ b/src/widgets/accessible/qaccessiblewidget.cpp
@@ -70,7 +70,8 @@ static QList<QWidget*> childWidgets(const QWidget *widget)
#if !defined(QT_NO_MENU)
&& !qobject_cast<QMenu*>(w)
#endif
- && w->objectName() != QLatin1String("qt_rubberband"))
+ && w->objectName() != QLatin1String("qt_rubberband")
+ && w->objectName() != QLatin1String("qt_spinbox_lineedit"))
widgets.append(w);
}
return widgets;
diff --git a/src/widgets/accessible/qaccessiblewidgetfactory.cpp b/src/widgets/accessible/qaccessiblewidgetfactory.cpp
index 3d123cc9ab..fb81a4aaeb 100644
--- a/src/widgets/accessible/qaccessiblewidgetfactory.cpp
+++ b/src/widgets/accessible/qaccessiblewidgetfactory.cpp
@@ -66,7 +66,10 @@ QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *obje
if (false) {
#ifndef QT_NO_LINEEDIT
} else if (classname == QLatin1String("QLineEdit")) {
- iface = new QAccessibleLineEdit(widget);
+ if (widget->objectName() == QLatin1String("qt_spinbox_lineedit"))
+ iface = 0;
+ else
+ iface = new QAccessibleLineEdit(widget);
#endif
#ifndef QT_NO_COMBOBOX
} else if (classname == QLatin1String("QComboBox")) {
diff --git a/src/widgets/accessible/rangecontrols.cpp b/src/widgets/accessible/rangecontrols.cpp
index d4dc74ea69..e16b99c25e 100644
--- a/src/widgets/accessible/rangecontrols.cpp
+++ b/src/widgets/accessible/rangecontrols.cpp
@@ -51,20 +51,28 @@
#include <qglobal.h>
#include <QDoubleSpinBox>
#include <QDial>
+#include <QtWidgets/qlineedit.h>
#include <qmath.h>
#include <private/qmath_p.h>
+#include "simplewidgets.h" // let spinbox use line edit's interface
+
QT_BEGIN_NAMESPACE
#ifndef QT_NO_ACCESSIBILITY
#ifndef QT_NO_SPINBOX
QAccessibleAbstractSpinBox::QAccessibleAbstractSpinBox(QWidget *w)
-: QAccessibleWidget(w, QAccessible::SpinBox)
+: QAccessibleWidget(w, QAccessible::SpinBox), lineEdit(Q_NULLPTR)
{
Q_ASSERT(abstractSpinBox());
}
+QAccessibleAbstractSpinBox::~QAccessibleAbstractSpinBox()
+{
+ delete lineEdit;
+}
+
/*!
Returns the underlying QAbstractSpinBox.
*/
@@ -73,6 +81,14 @@ QAbstractSpinBox *QAccessibleAbstractSpinBox::abstractSpinBox() const
return qobject_cast<QAbstractSpinBox*>(object());
}
+QAccessibleInterface *QAccessibleAbstractSpinBox::lineEditIface() const
+{
+ // QAccessibleLineEdit is only used to forward the text functions
+ if (!lineEdit)
+ lineEdit = new QAccessibleLineEdit(abstractSpinBox()->lineEdit());
+ return lineEdit;
+}
+
QString QAccessibleAbstractSpinBox::text(QAccessible::Text t) const
{
if (t == QAccessible::Value)
@@ -84,6 +100,10 @@ void *QAccessibleAbstractSpinBox::interface_cast(QAccessible::InterfaceType t)
{
if (t == QAccessible::ValueInterface)
return static_cast<QAccessibleValueInterface*>(this);
+ if (t == QAccessible::TextInterface)
+ return static_cast<QAccessibleTextInterface*>(this);
+ if (t == QAccessible::EditableTextInterface)
+ return static_cast<QAccessibleEditableTextInterface*>(this);
return QAccessibleWidget::interface_cast(t);
}
@@ -112,6 +132,102 @@ QVariant QAccessibleAbstractSpinBox::minimumStepSize() const
return abstractSpinBox()->property("stepSize");
}
+void QAccessibleAbstractSpinBox::addSelection(int startOffset, int endOffset)
+{
+ lineEditIface()->textInterface()->addSelection(startOffset, endOffset);
+}
+
+QString QAccessibleAbstractSpinBox::attributes(int offset, int *startOffset, int *endOffset) const
+{
+ return lineEditIface()->textInterface()->attributes(offset, startOffset, endOffset);
+}
+
+int QAccessibleAbstractSpinBox::cursorPosition() const
+{
+ return lineEditIface()->textInterface()->cursorPosition();
+}
+
+QRect QAccessibleAbstractSpinBox::characterRect(int offset) const
+{
+ return lineEditIface()->textInterface()->characterRect(offset);
+}
+
+int QAccessibleAbstractSpinBox::selectionCount() const
+{
+ return lineEditIface()->textInterface()->selectionCount();
+}
+
+int QAccessibleAbstractSpinBox::offsetAtPoint(const QPoint &point) const
+{
+ return lineEditIface()->textInterface()->offsetAtPoint(point);
+}
+
+void QAccessibleAbstractSpinBox::selection(int selectionIndex, int *startOffset, int *endOffset) const
+{
+ lineEditIface()->textInterface()->selection(selectionIndex, startOffset, endOffset);
+}
+
+QString QAccessibleAbstractSpinBox::text(int startOffset, int endOffset) const
+{
+ return lineEditIface()->textInterface()->text(startOffset, endOffset);
+}
+
+QString QAccessibleAbstractSpinBox::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const
+{
+ return lineEditIface()->textInterface()->textBeforeOffset(offset, boundaryType, startOffset, endOffset);
+}
+
+QString QAccessibleAbstractSpinBox::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const
+{
+ return lineEditIface()->textInterface()->textAfterOffset(offset, boundaryType, startOffset, endOffset);
+}
+
+QString QAccessibleAbstractSpinBox::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const
+{
+ return lineEditIface()->textInterface()->textAtOffset(offset, boundaryType, startOffset, endOffset);
+}
+
+void QAccessibleAbstractSpinBox::removeSelection(int selectionIndex)
+{
+ lineEditIface()->textInterface()->removeSelection(selectionIndex);
+}
+
+void QAccessibleAbstractSpinBox::setCursorPosition(int position)
+{
+ lineEditIface()->textInterface()->setCursorPosition(position);
+}
+
+void QAccessibleAbstractSpinBox::setSelection(int selectionIndex, int startOffset, int endOffset)
+{
+ lineEditIface()->textInterface()->setSelection(selectionIndex, startOffset, endOffset);
+}
+
+int QAccessibleAbstractSpinBox::characterCount() const
+{
+ return lineEditIface()->textInterface()->characterCount();
+}
+
+void QAccessibleAbstractSpinBox::scrollToSubstring(int startIndex, int endIndex)
+{
+ lineEditIface()->textInterface()->scrollToSubstring(startIndex, endIndex);
+}
+
+void QAccessibleAbstractSpinBox::deleteText(int startOffset, int endOffset)
+{
+ lineEditIface()->editableTextInterface()->deleteText(startOffset, endOffset);
+}
+
+void QAccessibleAbstractSpinBox::insertText(int offset, const QString &text)
+{
+ lineEditIface()->editableTextInterface()->insertText(offset, text);
+}
+
+void QAccessibleAbstractSpinBox::replaceText(int startOffset, int endOffset, const QString &text)
+{
+ lineEditIface()->editableTextInterface()->replaceText(startOffset, endOffset, text);
+}
+
+
/*!
\class QAccessibleSpinBox
\brief The QAccessibleSpinBox class implements the QAccessibleInterface for spinbox widgets.
diff --git a/src/widgets/accessible/rangecontrols.h b/src/widgets/accessible/rangecontrols.h
index 98cef46c5c..158e1cfcc0 100644
--- a/src/widgets/accessible/rangecontrols.h
+++ b/src/widgets/accessible/rangecontrols.h
@@ -55,12 +55,18 @@ class QSlider;
class QSpinBox;
class QDoubleSpinBox;
class QDial;
+class QAccessibleLineEdit;
#ifndef QT_NO_SPINBOX
-class QAccessibleAbstractSpinBox: public QAccessibleWidget, public QAccessibleValueInterface // TODO, public QAccessibleActionInterface
+class QAccessibleAbstractSpinBox:
+ public QAccessibleWidget,
+ public QAccessibleValueInterface,
+ public QAccessibleTextInterface,
+ public QAccessibleEditableTextInterface
{
public:
explicit QAccessibleAbstractSpinBox(QWidget *w);
+ virtual ~QAccessibleAbstractSpinBox();
QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE;
@@ -72,10 +78,37 @@ public:
QVariant minimumValue() const Q_DECL_OVERRIDE;
QVariant minimumStepSize() const Q_DECL_OVERRIDE;
- // FIXME Action interface
+ // QAccessibleTextInterface
+ void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE;
+ QString attributes(int offset, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ int cursorPosition() const Q_DECL_OVERRIDE;
+ QRect characterRect(int offset) const Q_DECL_OVERRIDE;
+ int selectionCount() const Q_DECL_OVERRIDE;
+ int offsetAtPoint(const QPoint &point) const Q_DECL_OVERRIDE;
+ void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE;
+ QString textBeforeOffset (int offset, QAccessible::TextBoundaryType boundaryType,
+ int *endOffset, int *startOffset) const Q_DECL_OVERRIDE;
+ QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ void removeSelection(int selectionIndex) Q_DECL_OVERRIDE;
+ void setCursorPosition(int position) Q_DECL_OVERRIDE;
+ void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE;
+ int characterCount() const Q_DECL_OVERRIDE;
+ void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE;
+
+ // QAccessibleEditableTextInterface
+ void deleteText(int startOffset, int endOffset) Q_DECL_OVERRIDE;
+ void insertText(int offset, const QString &text) Q_DECL_OVERRIDE;
+ void replaceText(int startOffset, int endOffset, const QString &text) Q_DECL_OVERRIDE;
protected:
QAbstractSpinBox *abstractSpinBox() const;
+ QAccessibleInterface *lineEditIface() const;
+private:
+ mutable QAccessibleLineEdit *lineEdit;
};
class QAccessibleSpinBox : public QAccessibleAbstractSpinBox
@@ -94,6 +127,7 @@ public:
QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
+ using QAccessibleAbstractSpinBox::text;
protected:
QDoubleSpinBox *doubleSpinBox() const;
};
diff --git a/src/widgets/accessible/simplewidgets.h b/src/widgets/accessible/simplewidgets.h
index e4ce6150e2..7dce0b3589 100644
--- a/src/widgets/accessible/simplewidgets.h
+++ b/src/widgets/accessible/simplewidgets.h
@@ -174,6 +174,7 @@ public:
void replaceText(int startOffset, int endOffset, const QString &text) Q_DECL_OVERRIDE;
protected:
QLineEdit *lineEdit() const;
+ friend class QAccessibleAbstractSpinBox;
};
#endif // QT_NO_LINEEDIT
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index 43f5d6fd31..4aed153932 100644
--- a/src/widgets/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
@@ -699,6 +699,7 @@ void QAbstractSpinBox::setLineEdit(QLineEdit *lineEdit)
}
d->updateEditFieldGeometry();
d->edit->setContextMenuPolicy(Qt::NoContextMenu);
+ d->edit->d_func()->control->setAccessibleObject(this);
if (isVisible())
d->edit->show();
diff --git a/src/widgets/widgets/qabstractspinbox.h b/src/widgets/widgets/qabstractspinbox.h
index 7989000cc8..5009e4151f 100644
--- a/src/widgets/widgets/qabstractspinbox.h
+++ b/src/widgets/widgets/qabstractspinbox.h
@@ -170,6 +170,7 @@ private:
Q_DECLARE_PRIVATE(QAbstractSpinBox)
Q_DISABLE_COPY(QAbstractSpinBox)
+ friend class QAccessibleAbstractSpinBox;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractSpinBox::StepEnabled)
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index b927004773..2743e4cbbf 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -737,15 +737,15 @@ void QWidgetLineControl::internalSetText(const QString &txt, int pos, bool edite
#ifndef QT_NO_ACCESSIBILITY
if (changed) {
if (oldText.isEmpty()) {
- QAccessibleTextInsertEvent event(parent(), 0, txt);
+ QAccessibleTextInsertEvent event(accessibleObject(), 0, txt);
event.setCursorPosition(m_cursor);
QAccessible::updateAccessibility(&event);
} else if (txt.isEmpty()) {
- QAccessibleTextRemoveEvent event(parent(), 0, oldText);
+ QAccessibleTextRemoveEvent event(accessibleObject(), 0, oldText);
event.setCursorPosition(m_cursor);
QAccessible::updateAccessibility(&event);
} else {
- QAccessibleTextUpdateEvent event(parent(), 0, oldText, txt);
+ QAccessibleTextUpdateEvent event(accessibleObject(), 0, oldText, txt);
event.setCursorPosition(m_cursor);
QAccessible::updateAccessibility(&event);
}
@@ -803,7 +803,7 @@ void QWidgetLineControl::internalInsert(const QString &s)
if (m_maskData) {
QString ms = maskString(m_cursor, s);
#ifndef QT_NO_ACCESSIBILITY
- QAccessibleTextInsertEvent insertEvent(parent(), m_cursor, ms);
+ QAccessibleTextInsertEvent insertEvent(accessibleObject(), m_cursor, ms);
QAccessible::updateAccessibility(&insertEvent);
#endif
for (int i = 0; i < (int) ms.length(); ++i) {
@@ -815,14 +815,14 @@ void QWidgetLineControl::internalInsert(const QString &s)
m_cursor = nextMaskBlank(m_cursor);
m_textDirty = true;
#ifndef QT_NO_ACCESSIBILITY
- QAccessibleTextCursorEvent event(parent(), m_cursor);
+ QAccessibleTextCursorEvent event(accessibleObject(), m_cursor);
QAccessible::updateAccessibility(&event);
#endif
} else {
int remaining = m_maxLength - m_text.length();
if (remaining != 0) {
#ifndef QT_NO_ACCESSIBILITY
- QAccessibleTextInsertEvent insertEvent(parent(), m_cursor, s);
+ QAccessibleTextInsertEvent insertEvent(accessibleObject(), m_cursor, s);
QAccessible::updateAccessibility(&insertEvent);
#endif
m_text.insert(m_cursor, s.left(remaining));
@@ -853,7 +853,7 @@ void QWidgetLineControl::internalDelete(bool wasBackspace)
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(parent(), m_cursor, m_text.at(m_cursor));
+ QAccessibleTextRemoveEvent event(accessibleObject(), m_cursor, m_text.at(m_cursor));
QAccessible::updateAccessibility(&event);
#endif
if (m_maskData) {
@@ -894,7 +894,7 @@ void QWidgetLineControl::removeSelectedText()
addCommand (Command(RemoveSelection, i, m_text.at(i), -1, -1));
}
#ifndef QT_NO_ACCESSIBILITY
- QAccessibleTextRemoveEvent event(parent(), m_selstart, m_text.mid(m_selstart, m_selend - m_selstart));
+ QAccessibleTextRemoveEvent event(accessibleObject(), m_selstart, m_text.mid(m_selstart, m_selend - m_selstart));
QAccessible::updateAccessibility(&event);
#endif
if (m_maskData) {
@@ -1384,7 +1384,7 @@ void QWidgetLineControl::emitCursorPositionChanged()
#ifndef QT_NO_ACCESSIBILITY
// otherwise we send a selection update which includes the cursor
if (!hasSelectedText()) {
- QAccessibleTextCursorEvent event(parent(), m_cursor);
+ QAccessibleTextCursorEvent event(accessibleObject(), m_cursor);
QAccessible::updateAccessibility(&event);
}
#endif
diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h
index ba73e9e25e..153067bd59 100644
--- a/src/widgets/widgets/qwidgetlinecontrol_p.h
+++ b/src/widgets/widgets/qwidgetlinecontrol_p.h
@@ -99,6 +99,7 @@ public:
, m_passwordMaskDelayOverride(-1)
#endif
, m_keyboardScheme(0)
+ , m_accessibleObject(0)
{
init(txt);
}
@@ -108,6 +109,19 @@ public:
delete [] m_maskData;
}
+ void setAccessibleObject(QObject *object)
+ {
+ Q_ASSERT(object);
+ m_accessibleObject = object;
+ }
+
+ QObject *accessibleObject()
+ {
+ if (m_accessibleObject)
+ return m_accessibleObject;
+ return parent();
+ }
+
int nextMaskBlank(int pos)
{
int c = findInMask(pos, true, false);
@@ -532,6 +546,9 @@ private Q_SLOTS:
private:
int m_keyboardScheme;
+
+ // accessibility events are sent for this object
+ QObject *m_accessibleObject;
};
QT_END_NAMESPACE
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
index 88f2120e62..2353d5b5b5 100644
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -1676,13 +1676,10 @@ void tst_QAccessibility::spinBoxTest()
QCOMPARE(accessibleRect, widgetRect);
QCOMPARE(interface->text(QAccessible::Value), QLatin1String("3"));
- // one child, the line edit
+ // make sure that the line edit is not there
const int numChildren = interface->childCount();
- QCOMPARE(numChildren, 1);
- QAccessibleInterface *lineEdit = interface->child(0);
-
- QCOMPARE(lineEdit->role(), QAccessible::EditableText);
- QCOMPARE(lineEdit->text(QAccessible::Value), QLatin1String("3"));
+ QCOMPARE(numChildren, 0);
+ QVERIFY(interface->child(0) == Q_NULLPTR);
QVERIFY(interface->valueInterface());
QCOMPARE(interface->valueInterface()->currentValue().toInt(), 3);
@@ -1696,6 +1693,10 @@ void tst_QAccessibility::spinBoxTest()
QTest::qWait(200);
QAccessibleValueChangeEvent expectedEvent(spinBox, spinBox->value());
QVERIFY(QTestAccessibility::containsEvent(&expectedEvent));
+
+ QAccessibleTextInterface *textIface = interface->textInterface();
+ QVERIFY(textIface);
+
delete spinBox;
QTestAccessibility::clearEvents();
}