diff options
-rw-r--r-- | src/widgets/accessible/qaccessiblewidget.cpp | 3 | ||||
-rw-r--r-- | src/widgets/accessible/qaccessiblewidgetfactory.cpp | 5 | ||||
-rw-r--r-- | src/widgets/accessible/rangecontrols.cpp | 118 | ||||
-rw-r--r-- | src/widgets/accessible/rangecontrols.h | 38 | ||||
-rw-r--r-- | src/widgets/accessible/simplewidgets.h | 1 | ||||
-rw-r--r-- | src/widgets/widgets/qabstractspinbox.cpp | 1 | ||||
-rw-r--r-- | src/widgets/widgets/qabstractspinbox.h | 1 | ||||
-rw-r--r-- | src/widgets/widgets/qwidgetlinecontrol.cpp | 18 | ||||
-rw-r--r-- | src/widgets/widgets/qwidgetlinecontrol_p.h | 17 | ||||
-rw-r--r-- | tests/auto/other/qaccessibility/tst_qaccessibility.cpp | 13 |
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(); } |