diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2015-09-02 16:40:32 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2015-09-14 18:51:51 +0000 |
commit | 9ecf1fd9507101607996e8df50093098edab5d64 (patch) | |
tree | 179df2c6dbb647b6cad44967148c7cd63e68ec6d | |
parent | 8957158ce42ffe1823b7ae1304a48bfdca40ec86 (diff) |
Controls: move Accessible from QML to C++
Controls 2.0 could be built with QT_NO_ACCESSIBILITY defined.
Added a few helper functions for accessible in QQuickControl.
Don't set text as Accessible.name for TextArea and TextField.
Change-Id: I40383bbcec2f8c742f709bdec0209623f80da449
Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
70 files changed, 747 insertions, 77 deletions
diff --git a/src/controls/qquickabstractbutton.cpp b/src/controls/qquickabstractbutton.cpp index 4211e5a5..964b97c4 100644 --- a/src/controls/qquickabstractbutton.cpp +++ b/src/controls/qquickabstractbutton.cpp @@ -83,6 +83,7 @@ QQuickAbstractButton::QQuickAbstractButton(QQuickItem *parent) : { setActiveFocusOnTab(true); setAcceptedMouseButtons(Qt::LeftButton); + setAccessibleRole(0x0000002B); //QAccessible::Button } QQuickAbstractButton::QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQuickItem *parent) : @@ -90,6 +91,7 @@ QQuickAbstractButton::QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQui { setActiveFocusOnTab(true); setAcceptedMouseButtons(Qt::LeftButton); + setAccessibleRole(0x0000002B); //QAccessible::Button } /*! @@ -113,6 +115,7 @@ void QQuickAbstractButton::setText(const QString &text) Q_D(QQuickAbstractButton); if (d->text != text) { d->text = text; + setAccessibleName(text); emit textChanged(); } } @@ -133,6 +136,7 @@ void QQuickAbstractButton::setPressed(bool isPressed) Q_D(QQuickAbstractButton); if (d->pressed != isPressed) { d->pressed = isPressed; + setAccessibleProperty("pressed", isPressed); emit pressedChanged(); } } diff --git a/src/controls/qquickbusyindicator.cpp b/src/controls/qquickbusyindicator.cpp index cc15f432..836fd78f 100644 --- a/src/controls/qquickbusyindicator.cpp +++ b/src/controls/qquickbusyindicator.cpp @@ -79,6 +79,7 @@ public: QQuickBusyIndicator::QQuickBusyIndicator(QQuickItem *parent) : QQuickControl(*(new QQuickBusyIndicatorPrivate), parent) { + setAccessibleRole(0x00000027); //QAccessible::Indicator } /*! diff --git a/src/controls/qquickcheckable.cpp b/src/controls/qquickcheckable.cpp index faf26c92..0130308e 100644 --- a/src/controls/qquickcheckable.cpp +++ b/src/controls/qquickcheckable.cpp @@ -79,6 +79,7 @@ void QQuickCheckable::setChecked(bool checked) Q_D(QQuickCheckable); if (d->checked != checked) { d->checked = checked; + setAccessibleProperty("checked", checked); emit checkedChanged(); } } @@ -148,4 +149,10 @@ void QQuickCheckable::mouseReleaseEvent(QMouseEvent *event) setChecked(d->exclusive || !d->checked); } +void QQuickCheckable::classBegin() +{ + QQuickAbstractButton::classBegin(); + setAccessibleProperty("checkable", true); +} + QT_END_NAMESPACE diff --git a/src/controls/qquickcheckable_p.h b/src/controls/qquickcheckable_p.h index 74f53946..3790e2cf 100644 --- a/src/controls/qquickcheckable_p.h +++ b/src/controls/qquickcheckable_p.h @@ -85,6 +85,8 @@ protected: void keyReleaseEvent(QKeyEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void classBegin() Q_DECL_OVERRIDE; + private: Q_DISABLE_COPY(QQuickCheckable) Q_DECLARE_PRIVATE(QQuickCheckable) diff --git a/src/controls/qquickcheckbox.cpp b/src/controls/qquickcheckbox.cpp index 7e877f45..3d9b0704 100644 --- a/src/controls/qquickcheckbox.cpp +++ b/src/controls/qquickcheckbox.cpp @@ -83,6 +83,7 @@ QT_BEGIN_NAMESPACE QQuickCheckBox::QQuickCheckBox(QQuickItem *parent) : QQuickCheckable(parent) { + setAccessibleRole(0x0000002C); //QAccessible::CheckBox } QT_END_NAMESPACE diff --git a/src/controls/qquickcontrol.cpp b/src/controls/qquickcontrol.cpp index 0e9dc997..d441fc85 100644 --- a/src/controls/qquickcontrol.cpp +++ b/src/controls/qquickcontrol.cpp @@ -45,6 +45,10 @@ #include "qquicktextfield_p.h" #include "qquicktextfield_p_p.h" +#ifndef QT_NO_ACCESSIBILITY +#include <QtQuick/private/qquickaccessibleattached_p.h> +#endif + QT_BEGIN_NAMESPACE /*! @@ -60,7 +64,8 @@ QT_BEGIN_NAMESPACE QQuickControlPrivate::QQuickControlPrivate() : hasTopPadding(false), hasLeftPadding(false), hasRightPadding(false), hasBottomPadding(false), padding(0), topPadding(0), leftPadding(0), rightPadding(0), bottomPadding(0), spacing(0), - layoutDirection(Qt::LeftToRight), background(Q_NULLPTR), contentItem(Q_NULLPTR) + layoutDirection(Qt::LeftToRight), background(Q_NULLPTR), contentItem(Q_NULLPTR), + accessibleAttached(Q_NULLPTR), accessibleRole(0) // QAccessible::NoRole { } @@ -226,6 +231,70 @@ void QQuickControlPrivate::updateFontRecur(QQuickItem *i, const QFont &f) } } +int QQuickControl::accessibleRole() const +{ +#ifndef QT_NO_ACCESSIBILITY + Q_D(const QQuickControl); + if (d->accessibleAttached) + return d->accessibleAttached->role(); +#endif + return 0; // QAccessible::NoRole +} + +void QQuickControl::setAccessibleRole(int role) +{ + Q_D(QQuickControl); + d->accessibleRole = role; +#ifndef QT_NO_ACCESSIBILITY + if (d->accessibleAttached) + d->accessibleAttached->setRole((QAccessible::Role)role); +#endif +} + +QString QQuickControl::accessibleName() const +{ +#ifndef QT_NO_ACCESSIBILITY + Q_D(const QQuickControl); + if (d->accessibleAttached) + return d->accessibleAttached->name(); +#endif + return QString(); +} + +void QQuickControl::setAccessibleName(const QString &name) +{ +#ifndef QT_NO_ACCESSIBILITY + Q_D(QQuickControl); + if (d->accessibleAttached) + d->accessibleAttached->setName(name); +#else + Q_UNUSED(name) +#endif +} + +QVariant QQuickControl::accessibleProperty(const char *propertyName) +{ +#ifndef QT_NO_ACCESSIBILITY + Q_D(QQuickControl); + if (d->accessibleAttached) + return QQuickAccessibleAttached::property(this, propertyName); +#endif + Q_UNUSED(propertyName) + return QVariant(); +} + +bool QQuickControl::setAccessibleProperty(const char *propertyName, const QVariant &value) +{ +#ifndef QT_NO_ACCESSIBILITY + Q_D(QQuickControl); + if (d->accessibleAttached) + return QQuickAccessibleAttached::setProperty(this, propertyName, value); +#endif + Q_UNUSED(propertyName) + Q_UNUSED(value) + return false; +} + QQuickControl::QQuickControl(QQuickItem *parent) : QQuickItem(*(new QQuickControlPrivate), parent) { @@ -596,6 +665,19 @@ void QQuickControl::setContentItem(QQuickItem *item) } } +void QQuickControl::classBegin() +{ + QQuickItem::classBegin(); +#ifndef QT_NO_ACCESSIBILITY + Q_D(QQuickControl); + d->accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(this, true)); + if (d->accessibleAttached) + d->accessibleAttached->setRole((QAccessible::Role)(d->accessibleRole)); + else + qWarning() << "QQuickControl: QQuickAccessibleAttached object creation failed!"; +#endif +} + void QQuickControl::mousePressEvent(QMouseEvent *event) { event->accept(); diff --git a/src/controls/qquickcontrol_p.h b/src/controls/qquickcontrol_p.h index 9b2ede50..ff0b92db 100644 --- a/src/controls/qquickcontrol_p.h +++ b/src/controls/qquickcontrol_p.h @@ -149,6 +149,17 @@ protected: virtual void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding); virtual void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem); + void classBegin() Q_DECL_OVERRIDE; + + int accessibleRole() const; // int for QAccessible::Role + void setAccessibleRole(int role); // int for QAccessible::Role + + QString accessibleName() const; + void setAccessibleName(const QString &name); + + QVariant accessibleProperty(const char *propertyName); + bool setAccessibleProperty(const char *propertyName, const QVariant &value); + private: Q_DISABLE_COPY(QQuickControl) Q_DECLARE_PRIVATE(QQuickControl) diff --git a/src/controls/qquickcontrol_p_p.h b/src/controls/qquickcontrol_p_p.h index 2861c067..6104b2a2 100644 --- a/src/controls/qquickcontrol_p_p.h +++ b/src/controls/qquickcontrol_p_p.h @@ -52,6 +52,8 @@ QT_BEGIN_NAMESPACE +class QQuickAccessibleAttached; + class Q_QUICKCONTROLS_EXPORT QQuickControlPrivate : public QQuickItemPrivate { Q_DECLARE_PUBLIC(QQuickControl) @@ -93,6 +95,8 @@ public: Qt::LayoutDirection layoutDirection; QQuickItem *background; QQuickItem *contentItem; + QQuickAccessibleAttached *accessibleAttached; + int accessibleRole; }; Q_DECLARE_TYPEINFO(QQuickControlPrivate, Q_COMPLEX_TYPE); diff --git a/src/controls/qquicklabel.cpp b/src/controls/qquicklabel.cpp index f70179c1..2175fc33 100644 --- a/src/controls/qquicklabel.cpp +++ b/src/controls/qquicklabel.cpp @@ -43,11 +43,18 @@ #include <QtQuick/private/qquicktext_p.h> #include <QtQuick/private/qquickclipnode_p.h> +#ifndef QT_NO_ACCESSIBILITY +#include <QtQuick/private/qquickaccessibleattached_p.h> +#endif + QT_BEGIN_NAMESPACE QQuickLabel::QQuickLabel(QQuickItem *parent) : QQuickText(*(new QQuickLabelPrivate), parent) { + Q_D(const QQuickLabel); + QObjectPrivate::connect(this, &QQuickText::textChanged, + d, &QQuickLabelPrivate::_q_textChanged); } QQuickLabel::~QQuickLabel() @@ -70,6 +77,16 @@ void QQuickLabelPrivate::resolveFont() setFont_helper(resolvedFont); } +void QQuickLabelPrivate::_q_textChanged(const QString &text) +{ +#ifndef QT_NO_ACCESSIBILITY + if (accessibleAttached) + accessibleAttached->setName(text); +#else + Q_UNUSED(text) +#endif +} + QFont QQuickLabel::font() const { Q_D(const QQuickLabel); @@ -95,6 +112,19 @@ void QQuickLabel::setFont(const QFont &font) emit fontChanged(); } +void QQuickLabel::classBegin() +{ + QQuickText::classBegin(); +#ifndef QT_NO_ACCESSIBILITY + Q_D(QQuickLabel); + d->accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(this, true)); + if (d->accessibleAttached) + d->accessibleAttached->setRole((QAccessible::Role)0x00000029); // Accessible.StaticText + else + qWarning() << "QQuickLabel: QQuickAccessibleAttached object creation failed!"; +#endif +} + QQuickItem *QQuickLabel::background() const { Q_D(const QQuickLabel); diff --git a/src/controls/qquicklabel_p.h b/src/controls/qquicklabel_p.h index 77b2d7f6..71430b32 100644 --- a/src/controls/qquicklabel_p.h +++ b/src/controls/qquicklabel_p.h @@ -78,6 +78,8 @@ Q_SIGNALS: protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; + void classBegin() Q_DECL_OVERRIDE; + private: Q_DISABLE_COPY(QQuickLabel) Q_DECLARE_PRIVATE(QQuickLabel) diff --git a/src/controls/qquicklabel_p_p.h b/src/controls/qquicklabel_p_p.h index d57662a5..43f03382 100644 --- a/src/controls/qquicklabel_p_p.h +++ b/src/controls/qquicklabel_p_p.h @@ -52,12 +52,14 @@ QT_BEGIN_NAMESPACE +class QQuickAccessibleAttached; + class QQuickLabelPrivate : public QQuickTextPrivate { Q_DECLARE_PUBLIC(QQuickLabel) public: - QQuickLabelPrivate() : background(Q_NULLPTR) { } + QQuickLabelPrivate() : background(Q_NULLPTR), accessibleAttached(Q_NULLPTR) { } static QQuickLabelPrivate *get(QQuickLabel *item) { return static_cast<QQuickLabelPrivate *>(QObjectPrivate::get(item)); } @@ -72,7 +74,10 @@ public: } void resolveFont(); + void _q_textChanged(const QString &text); + QQuickItem *background; + QQuickAccessibleAttached *accessibleAttached; }; Q_DECLARE_TYPEINFO(QQuickLabelPrivate, Q_COMPLEX_TYPE); diff --git a/src/controls/qquickpageindicator.cpp b/src/controls/qquickpageindicator.cpp index 0f8af4f7..37a52fe0 100644 --- a/src/controls/qquickpageindicator.cpp +++ b/src/controls/qquickpageindicator.cpp @@ -79,6 +79,7 @@ public: QQuickPageIndicator::QQuickPageIndicator(QQuickItem *parent) : QQuickControl(*(new QQuickPageIndicatorPrivate), parent) { + setAccessibleRole(0x00000027); //QAccessible::Indicator } /*! diff --git a/src/controls/qquickprogressbar.cpp b/src/controls/qquickprogressbar.cpp index f189d937..9607bcff 100644 --- a/src/controls/qquickprogressbar.cpp +++ b/src/controls/qquickprogressbar.cpp @@ -80,6 +80,7 @@ public: QQuickProgressBar::QQuickProgressBar(QQuickItem *parent) : QQuickControl(*(new QQuickProgressBarPrivate), parent) { + setAccessibleRole(0x00000030); //QAccessible::ProgressBar } /*! diff --git a/src/controls/qquickradiobutton.cpp b/src/controls/qquickradiobutton.cpp index fb767012..6681c69c 100644 --- a/src/controls/qquickradiobutton.cpp +++ b/src/controls/qquickradiobutton.cpp @@ -87,6 +87,7 @@ QQuickRadioButton::QQuickRadioButton(QQuickItem *parent) : QQuickCheckable(parent) { setExclusive(true); + setAccessibleRole(0x0000002D); //QAccessible::RadioButton } QT_END_NAMESPACE diff --git a/src/controls/qquickscrollbar.cpp b/src/controls/qquickscrollbar.cpp index aaa0e007..085900ba 100644 --- a/src/controls/qquickscrollbar.cpp +++ b/src/controls/qquickscrollbar.cpp @@ -105,6 +105,7 @@ QQuickScrollBar::QQuickScrollBar(QQuickItem *parent) : { setKeepMouseGrab(true); setAcceptedMouseButtons(Qt::LeftButton); + setAccessibleRole(0x00000003); //QAccessible::ScrollBar } QQuickScrollBarAttached *QQuickScrollBar::qmlAttachedProperties(QObject *object) @@ -198,6 +199,7 @@ void QQuickScrollBar::setPressed(bool pressed) Q_D(QQuickScrollBar); if (d->pressed != pressed) { d->pressed = pressed; + setAccessibleProperty("pressed", pressed); setActive(d->pressed || d->moving); emit pressedChanged(); } diff --git a/src/controls/qquickscrollindicator.cpp b/src/controls/qquickscrollindicator.cpp index a44db0cb..b935b0e8 100644 --- a/src/controls/qquickscrollindicator.cpp +++ b/src/controls/qquickscrollindicator.cpp @@ -93,6 +93,7 @@ public: QQuickScrollIndicator::QQuickScrollIndicator(QQuickItem *parent) : QQuickControl(*(new QQuickScrollIndicatorPrivate), parent) { + setAccessibleRole(0x00000027); //QAccessible::Indicator } QQuickScrollIndicatorAttached *QQuickScrollIndicator::qmlAttachedProperties(QObject *object) diff --git a/src/controls/qquickslider.cpp b/src/controls/qquickslider.cpp index a17da03d..581f85da 100644 --- a/src/controls/qquickslider.cpp +++ b/src/controls/qquickslider.cpp @@ -158,6 +158,7 @@ QQuickSlider::QQuickSlider(QQuickItem *parent) : { setActiveFocusOnTab(true); setAcceptedMouseButtons(Qt::LeftButton); + setAccessibleRole(0x00000033); //QAccessible::Slider } /*! @@ -348,6 +349,7 @@ void QQuickSlider::setPressed(bool pressed) Q_D(QQuickSlider); if (d->pressed != pressed) { d->pressed = pressed; + setAccessibleProperty("pressed", pressed); emit pressedChanged(); } } diff --git a/src/controls/qquickswitch.cpp b/src/controls/qquickswitch.cpp index 9eec7c16..b4619318 100644 --- a/src/controls/qquickswitch.cpp +++ b/src/controls/qquickswitch.cpp @@ -103,6 +103,7 @@ QQuickSwitch::QQuickSwitch(QQuickItem *parent) : { setFiltersChildMouseEvents(true); QObjectPrivate::connect(this, &QQuickCheckable::checkedChanged, d_func(), &QQuickSwitchPrivate::updatePosition); + setAccessibleRole(0x0000002B); //QAccessible::Button } /*! diff --git a/src/controls/qquicktabbar.cpp b/src/controls/qquicktabbar.cpp index ff28f620..38de7f49 100644 --- a/src/controls/qquicktabbar.cpp +++ b/src/controls/qquicktabbar.cpp @@ -177,6 +177,7 @@ QQuickTabBar::QQuickTabBar(QQuickItem *parent) : Q_D(QQuickTabBar); setFlag(ItemIsFocusScope); setActiveFocusOnTab(true); + setAccessibleRole(0x0000003C); //QAccessible::PageTabList d->group = new QQuickExclusiveGroup(this); connect(d->group, &QQuickExclusiveGroup::currentChanged, this, &QQuickTabBar::currentItemChanged); diff --git a/src/controls/qquicktabbutton.cpp b/src/controls/qquicktabbutton.cpp index dacffc24..ce88c7ab 100644 --- a/src/controls/qquicktabbutton.cpp +++ b/src/controls/qquicktabbutton.cpp @@ -65,6 +65,7 @@ QQuickTabButton::QQuickTabButton(QQuickItem *parent) : QQuickCheckable(parent) { setExclusive(true); + setAccessibleRole(0x00000025); //QAccessible::PageTab } QT_END_NAMESPACE diff --git a/src/controls/qquicktextarea.cpp b/src/controls/qquicktextarea.cpp index b9e4e4f8..5427358b 100644 --- a/src/controls/qquicktextarea.cpp +++ b/src/controls/qquicktextarea.cpp @@ -44,6 +44,10 @@ #include <QtQuick/private/qquicktext_p.h> #include <QtQuick/private/qquickclipnode_p.h> +#ifndef QT_NO_ACCESSIBILITY +#include <QtQuick/private/qquickaccessibleattached_p.h> +#endif + QT_BEGIN_NAMESPACE /*! @@ -85,8 +89,11 @@ void QQuickTextAreaPrivate::resizeBackground() QQuickTextArea::QQuickTextArea(QQuickItem *parent) : QQuickTextEdit(*(new QQuickTextAreaPrivate), parent) { + Q_D(QQuickTextArea); setActiveFocusOnTab(true); - d_func()->pressAndHoldHelper.control = this; + d->pressAndHoldHelper.control = this; + QObjectPrivate::connect(this, &QQuickTextEdit::readOnlyChanged, + d, &QQuickTextAreaPrivate::_q_readOnlyChanged); } QQuickTextArea::~QQuickTextArea() @@ -109,6 +116,27 @@ void QQuickTextAreaPrivate::resolveFont() setFont_helper(resolvedFont); } +void QQuickTextAreaPrivate::_q_readOnlyChanged(bool isReadOnly) +{ +#ifndef QT_NO_ACCESSIBILITY + Q_Q(QQuickTextArea); + if (accessibleAttached) + QQuickAccessibleAttached::setProperty(q, "readOnly", isReadOnly); +#else + Q_UNUSED(isReadOnly) +#endif +} + +void QQuickTextAreaPrivate::_q_placeholderTextChanged(const QString &text) +{ +#ifndef QT_NO_ACCESSIBILITY + if (accessibleAttached) + accessibleAttached->setDescription(text); +#else + Q_UNUSED(text) +#endif +} + QFont QQuickTextArea::font() const { Q_D(const QQuickTextArea); @@ -185,10 +213,22 @@ void QQuickTextArea::setPlaceholder(QQuickText *placeholder) { Q_D(QQuickTextArea); if (d->placeholder != placeholder) { - delete d->placeholder; + if (d->placeholder) { + QObjectPrivate::disconnect(d->placeholder, &QQuickText::textChanged, + d, &QQuickTextAreaPrivate::_q_placeholderTextChanged); + delete d->placeholder; + } d->placeholder = placeholder; - if (placeholder && !placeholder->parentItem()) + if (placeholder && !placeholder->parentItem()) { placeholder->setParentItem(this); + QObjectPrivate::connect(d->placeholder, &QQuickText::textChanged, + d, &QQuickTextAreaPrivate::_q_placeholderTextChanged); + } else { +#ifndef QT_NO_ACCESSIBILITY + if (d->accessibleAttached) + d->accessibleAttached->setDescription(QLatin1Literal("")); +#endif + } emit placeholderChanged(); } } @@ -249,4 +289,19 @@ void QQuickTextArea::timerEvent(QTimerEvent *event) } } +void QQuickTextArea::classBegin() +{ + QQuickTextEdit::classBegin(); +#ifndef QT_NO_ACCESSIBILITY + Q_D(QQuickTextArea); + d->accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(this, true)); + if (d->accessibleAttached) { + d->accessibleAttached->setRole((QAccessible::Role)(0x0000002A)); // Accessible.EditableText + QQuickAccessibleAttached::setProperty(this, "multiLine", true); + } else { + qWarning() << "QQuickTextArea: QQuickAccessibleAttached object creation failed!"; + } +#endif +} + QT_END_NAMESPACE diff --git a/src/controls/qquicktextarea_p.h b/src/controls/qquicktextarea_p.h index 239fa559..6e5561b6 100644 --- a/src/controls/qquicktextarea_p.h +++ b/src/controls/qquicktextarea_p.h @@ -91,6 +91,8 @@ protected: void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE; + void classBegin() Q_DECL_OVERRIDE; + private: Q_DISABLE_COPY(QQuickTextArea) Q_DECLARE_PRIVATE(QQuickTextArea) diff --git a/src/controls/qquicktextarea_p_p.h b/src/controls/qquicktextarea_p_p.h index 83194ef1..2d93c13e 100644 --- a/src/controls/qquicktextarea_p_p.h +++ b/src/controls/qquicktextarea_p_p.h @@ -51,14 +51,18 @@ #include <QtQuick/private/qquicktextedit_p_p.h> #include <QtQuickControls/private/qquickpressandholdhelper_p.h> +#include "qquicktextarea_p.h" + QT_BEGIN_NAMESPACE +class QQuickAccessibleAttached; + class QQuickTextAreaPrivate : public QQuickTextEditPrivate { Q_DECLARE_PUBLIC(QQuickTextArea) public: - QQuickTextAreaPrivate() : background(Q_NULLPTR), placeholder(Q_NULLPTR) { } + QQuickTextAreaPrivate() : background(Q_NULLPTR), placeholder(Q_NULLPTR), accessibleAttached(Q_NULLPTR) { } static QQuickTextAreaPrivate *get(QQuickTextArea *item) { return static_cast<QQuickTextAreaPrivate *>(QObjectPrivate::get(item)); } @@ -73,9 +77,13 @@ public: } void resolveFont(); + void _q_readOnlyChanged(bool isReadOnly); + void _q_placeholderTextChanged(const QString &text); + QQuickItem *background; QQuickText *placeholder; QQuickPressAndHoldHelper pressAndHoldHelper; + QQuickAccessibleAttached *accessibleAttached; }; Q_DECLARE_TYPEINFO(QQuickTextAreaPrivate, Q_COMPLEX_TYPE); diff --git a/src/controls/qquicktextfield.cpp b/src/controls/qquicktextfield.cpp index 01b26cf7..cf8f24a2 100644 --- a/src/controls/qquicktextfield.cpp +++ b/src/controls/qquicktextfield.cpp @@ -42,8 +42,13 @@ #include <QtCore/qbasictimer.h> #include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qquicktext_p.h> +#include <QtQuick/private/qquicktextinput_p.h> #include <QtQuick/private/qquickclipnode_p.h> +#ifndef QT_NO_ACCESSIBILITY +#include <QtQuick/private/qquickaccessibleattached_p.h> +#endif + QT_BEGIN_NAMESPACE /*! @@ -102,8 +107,13 @@ void QQuickTextFieldPrivate::resizeBackground() QQuickTextField::QQuickTextField(QQuickItem *parent) : QQuickTextInput(*(new QQuickTextFieldPrivate), parent) { - d_func()->pressAndHoldHelper.control = this; + Q_D(QQuickTextField); + d->pressAndHoldHelper.control = this; setActiveFocusOnTab(true); + QObjectPrivate::connect(this, &QQuickTextInput::readOnlyChanged, + d, &QQuickTextFieldPrivate::_q_readOnlyChanged); + QObjectPrivate::connect(this, &QQuickTextInput::echoModeChanged, + d, &QQuickTextFieldPrivate::_q_echoModeChanged); } QQuickTextField::~QQuickTextField() @@ -126,6 +136,39 @@ void QQuickTextFieldPrivate::resolveFont() setFont_helper(resolvedFont); } +void QQuickTextFieldPrivate::_q_readOnlyChanged(bool isReadOnly) +{ +#ifndef QT_NO_ACCESSIBILITY + Q_Q(QQuickTextField); + if (accessibleAttached) + QQuickAccessibleAttached::setProperty(q, "readOnly", isReadOnly); +#else + Q_UNUSED(isReadOnly) +#endif +} + +void QQuickTextFieldPrivate::_q_placeholderTextChanged(const QString &text) +{ +#ifndef QT_NO_ACCESSIBILITY + if (accessibleAttached) + accessibleAttached->setDescription(text); +#else + Q_UNUSED(text) +#endif +} + +void QQuickTextFieldPrivate::_q_echoModeChanged(QQuickTextField::EchoMode echoMode) +{ +#ifndef QT_NO_ACCESSIBILITY + Q_Q(QQuickTextField); + if (accessibleAttached) + QQuickAccessibleAttached::setProperty(q, "passwordEdit", + (echoMode == QQuickTextField::Password || echoMode == QQuickTextField::PasswordEchoOnEdit) ? true : false); +#else + Q_UNUSED(echoMode) +#endif +} + QFont QQuickTextField::font() const { Q_D(const QQuickTextField); @@ -202,10 +245,22 @@ void QQuickTextField::setPlaceholder(QQuickText *placeholder) { Q_D(QQuickTextField); if (d->placeholder != placeholder) { - delete d->placeholder; + if (d->placeholder) { + QObjectPrivate::disconnect(d->placeholder, &QQuickText::textChanged, + d, &QQuickTextFieldPrivate::_q_placeholderTextChanged); + delete d->placeholder; + } d->placeholder = placeholder; - if (placeholder && !placeholder->parentItem()) + if (placeholder && !placeholder->parentItem()) { placeholder->setParentItem(this); + QObjectPrivate::connect(d->placeholder, &QQuickText::textChanged, + d, &QQuickTextFieldPrivate::_q_placeholderTextChanged); + } else { +#ifndef QT_NO_ACCESSIBILITY + if (d->accessibleAttached) + d->accessibleAttached->setDescription(QLatin1Literal("")); +#endif + } emit placeholderChanged(); } } @@ -266,4 +321,19 @@ void QQuickTextField::timerEvent(QTimerEvent *event) } } +void QQuickTextField::classBegin() +{ + QQuickTextInput::classBegin(); +#ifndef QT_NO_ACCESSIBILITY + Q_D(QQuickTextField); + d->accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(this, true)); + if (d->accessibleAttached) { + d->accessibleAttached->setRole((QAccessible::Role)(0x0000002A)); // Accessible.EditableText + QQuickAccessibleAttached::setProperty(this, "multiLine", true); + } else { + qWarning() << "QQuickTextField: QQuickAccessibleAttached object creation failed!"; + } +#endif +} + QT_END_NAMESPACE diff --git a/src/controls/qquicktextfield_p.h b/src/controls/qquicktextfield_p.h index 6f22cdd5..937113f2 100644 --- a/src/controls/qquicktextfield_p.h +++ b/src/controls/qquicktextfield_p.h @@ -91,6 +91,8 @@ protected: void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE; + void classBegin() Q_DECL_OVERRIDE; + private: Q_DISABLE_COPY(QQuickTextField) Q_DECLARE_PRIVATE(QQuickTextField) diff --git a/src/controls/qquicktextfield_p_p.h b/src/controls/qquicktextfield_p_p.h index ceefb91e..89dc0572 100644 --- a/src/controls/qquicktextfield_p_p.h +++ b/src/controls/qquicktextfield_p_p.h @@ -51,8 +51,12 @@ #include <QtQuick/private/qquicktextinput_p_p.h> #include <QtQuickControls/private/qquickpressandholdhelper_p.h> +#include "qquicktextfield_p.h" + QT_BEGIN_NAMESPACE +class QQuickAccessibleAttached; + class QQuickTextFieldPrivate : public QQuickTextInputPrivate { Q_DECLARE_PUBLIC(QQuickTextField) @@ -76,9 +80,14 @@ public: } void resolveFont(); + void _q_readOnlyChanged(bool isReadOnly); + void _q_placeholderTextChanged(const QString &text); + void _q_echoModeChanged(QQuickTextField::EchoMode echoMode); + QQuickItem *background; QQuickText *placeholder; QQuickPressAndHoldHelper pressAndHoldHelper; + QQuickAccessibleAttached *accessibleAttached; }; Q_DECLARE_TYPEINFO(QQuickTextFieldPrivate, Q_COMPLEX_TYPE); diff --git a/src/controls/qquicktogglebutton.cpp b/src/controls/qquicktogglebutton.cpp index a399691e..96edbefd 100644 --- a/src/controls/qquicktogglebutton.cpp +++ b/src/controls/qquicktogglebutton.cpp @@ -78,6 +78,7 @@ QT_BEGIN_NAMESPACE QQuickToggleButton::QQuickToggleButton(QQuickItem *parent) : QQuickSwitch(parent) { + setAccessibleRole(0x0000002B); //QAccessible::Button } QT_END_NAMESPACE diff --git a/src/controls/qquicktoolbar.cpp b/src/controls/qquicktoolbar.cpp index 297114c5..f9141b25 100644 --- a/src/controls/qquicktoolbar.cpp +++ b/src/controls/qquicktoolbar.cpp @@ -92,6 +92,7 @@ QT_BEGIN_NAMESPACE QQuickToolBar::QQuickToolBar(QQuickItem *parent) : QQuickFrame(parent) { + setAccessibleRole(0x00000016); //QAccessible::ToolBar } QT_END_NAMESPACE diff --git a/src/imports/controls/BusyIndicator.qml b/src/imports/controls/BusyIndicator.qml index dde7699f..e8a4babd 100644 --- a/src/imports/controls/BusyIndicator.qml +++ b/src/imports/controls/BusyIndicator.qml @@ -44,8 +44,6 @@ T.BusyIndicator { implicitWidth: indicator.implicitWidth + leftPadding + rightPadding implicitHeight: indicator.implicitHeight + topPadding + bottomPadding - Accessible.role: Accessible.Indicator - padding: 6 //! [indicator] diff --git a/src/imports/controls/Button.qml b/src/imports/controls/Button.qml index f6e50f99..19934824 100644 --- a/src/imports/controls/Button.qml +++ b/src/imports/controls/Button.qml @@ -46,10 +46,6 @@ T.Button { implicitHeight: Math.max(background ? background.implicitHeight : 0, label ? label.implicitHeight + topPadding + bottomPadding : 0) - Accessible.name: text - Accessible.pressed: pressed - Accessible.role: Accessible.Button - padding: 6 leftPadding: 8 rightPadding: 8 diff --git a/src/imports/controls/CheckBox.qml b/src/imports/controls/CheckBox.qml index e5915b8f..df53fd09 100644 --- a/src/imports/controls/CheckBox.qml +++ b/src/imports/controls/CheckBox.qml @@ -49,11 +49,6 @@ T.CheckBox { Math.max(label ? label.implicitHeight : 0, indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) - Accessible.name: text - Accessible.checked: checked - Accessible.pressed: pressed - Accessible.role: Accessible.CheckBox - padding: 6 spacing: 6 diff --git a/src/imports/controls/Label.qml b/src/imports/controls/Label.qml index 9c2477b0..ce67db71 100644 --- a/src/imports/controls/Label.qml +++ b/src/imports/controls/Label.qml @@ -41,9 +41,6 @@ import QtQuick.Templates 2.0 as T T.Label { id: control - Accessible.name: text - Accessible.role: Accessible.StaticText - color: Theme.textColor linkColor: Theme.focusColor // TODO } diff --git a/src/imports/controls/PageIndicator.qml b/src/imports/controls/PageIndicator.qml index 4891951b..55e9a40e 100644 --- a/src/imports/controls/PageIndicator.qml +++ b/src/imports/controls/PageIndicator.qml @@ -41,8 +41,6 @@ import QtQuick.Templates 2.0 as T T.PageIndicator { id: control - Accessible.role: Accessible.Indicator - implicitWidth: Math.max(background ? background.implicitWidth : 0, contentItem.implicitWidth + leftPadding + rightPadding) implicitHeight: Math.max(background ? background.implicitHeight : 0, diff --git a/src/imports/controls/ProgressBar.qml b/src/imports/controls/ProgressBar.qml index fbb469be..3a040573 100644 --- a/src/imports/controls/ProgressBar.qml +++ b/src/imports/controls/ProgressBar.qml @@ -46,8 +46,6 @@ T.ProgressBar { implicitHeight: Math.max(background ? background.implicitHeight : 0, indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding - Accessible.role: Accessible.ProgressBar - padding: 6 //! [indicator] diff --git a/src/imports/controls/RadioButton.qml b/src/imports/controls/RadioButton.qml index 16bf4f89..5c94382f 100644 --- a/src/imports/controls/RadioButton.qml +++ b/src/imports/controls/RadioButton.qml @@ -49,11 +49,6 @@ T.RadioButton { Math.max(label ? label.implicitHeight : 0, indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) - Accessible.name: text - Accessible.checked: checked - Accessible.pressed: pressed - Accessible.role: Accessible.RadioButton - padding: 6 spacing: 6 diff --git a/src/imports/controls/ScrollBar.qml b/src/imports/controls/ScrollBar.qml index a0821ac0..c3ae743d 100644 --- a/src/imports/controls/ScrollBar.qml +++ b/src/imports/controls/ScrollBar.qml @@ -46,9 +46,6 @@ T.ScrollBar { implicitHeight: Math.max(background ? background.implicitHeight : 0, handle.implicitHeight + topPadding + bottomPadding) - Accessible.pressed: pressed - Accessible.role: Accessible.ScrollBar - padding: 2 //! [handle] diff --git a/src/imports/controls/ScrollIndicator.qml b/src/imports/controls/ScrollIndicator.qml index fb6f9277..b02f6c1f 100644 --- a/src/imports/controls/ScrollIndicator.qml +++ b/src/imports/controls/ScrollIndicator.qml @@ -46,8 +46,6 @@ T.ScrollIndicator { implicitHeight: Math.max(background ? background.implicitHeight : 0, indicator.implicitHeight + topPadding + bottomPadding) - Accessible.role: Accessible.Indicator - padding: 2 //! [indicator] diff --git a/src/imports/controls/Slider.qml b/src/imports/controls/Slider.qml index 1074b6dd..309c07cd 100644 --- a/src/imports/controls/Slider.qml +++ b/src/imports/controls/Slider.qml @@ -48,9 +48,6 @@ T.Slider { Math.max(track ? track.implicitHeight : 0, handle ? handle.implicitHeight : 0) + topPadding + bottomPadding) - Accessible.pressed: pressed - Accessible.role: Accessible.Slider - padding: 6 //! [handle] diff --git a/src/imports/controls/Switch.qml b/src/imports/controls/Switch.qml index 6ddf840f..0eafc2b2 100644 --- a/src/imports/controls/Switch.qml +++ b/src/imports/controls/Switch.qml @@ -49,12 +49,6 @@ T.Switch { Math.max(label ? label.implicitHeight : 0, indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) - Accessible.name: text - Accessible.checkable: true - Accessible.checked: checked - Accessible.pressed: pressed - Accessible.role: Accessible.Button // TODO: Switch? - padding: 6 spacing: 6 diff --git a/src/imports/controls/TabBar.qml b/src/imports/controls/TabBar.qml index 89ab3166..173cad37 100644 --- a/src/imports/controls/TabBar.qml +++ b/src/imports/controls/TabBar.qml @@ -46,8 +46,6 @@ T.TabBar { implicitHeight: Math.max(background ? background.implicitHeight : 0, contentItem.implicitHeight + topPadding + bottomPadding) - Accessible.role: Accessible.PageTabList - spacing: 1 //! [contentItem] diff --git a/src/imports/controls/TabButton.qml b/src/imports/controls/TabButton.qml index c5ca6f72..b1a88b00 100644 --- a/src/imports/controls/TabButton.qml +++ b/src/imports/controls/TabButton.qml @@ -46,11 +46,6 @@ T.TabButton { implicitHeight: Math.max(background ? background.implicitHeight : 0, label ? label.implicitHeight + topPadding + bottomPadding : 0) - Accessible.name: text - Accessible.pressed: pressed - Accessible.selected: checked - Accessible.role: Accessible.PageTab - padding: 6 //! [label] diff --git a/src/imports/controls/TextArea.qml b/src/imports/controls/TextArea.qml index 52b7ade4..0ce489ff 100644 --- a/src/imports/controls/TextArea.qml +++ b/src/imports/controls/TextArea.qml @@ -41,12 +41,6 @@ import QtQuick.Templates 2.0 as T T.TextArea { id: control - Accessible.name: text - Accessible.multiLine: true - Accessible.role: Accessible.EditableText - Accessible.readOnly: readOnly - Accessible.description: placeholder ? placeholder.text : "" - color: enabled ? Theme.textColor : Theme.disabledColor selectionColor: Theme.selectionColor selectedTextColor: Theme.selectedTextColor diff --git a/src/imports/controls/TextField.qml b/src/imports/controls/TextField.qml index ca477107..98baebbc 100644 --- a/src/imports/controls/TextField.qml +++ b/src/imports/controls/TextField.qml @@ -41,12 +41,6 @@ import QtQuick.Templates 2.0 as T T.TextField { id: control - Accessible.name: text - Accessible.role: Accessible.EditableText - Accessible.readOnly: readOnly - Accessible.description: placeholder ? placeholder.text : "" - Accessible.passwordEdit: echoMode === TextInput.Password || echoMode === TextInput.PasswordEchoOnEdit - padding: 6 color: enabled ? Theme.textColor : Theme.disabledColor diff --git a/src/imports/controls/ToggleButton.qml b/src/imports/controls/ToggleButton.qml index 8a732f02..e533b154 100644 --- a/src/imports/controls/ToggleButton.qml +++ b/src/imports/controls/ToggleButton.qml @@ -49,12 +49,6 @@ T.ToggleButton { Math.max(label ? label.implicitHeight : 0, indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) - Accessible.name: text - Accessible.checkable: true - Accessible.checked: checked - Accessible.pressed: pressed - Accessible.role: Accessible.Button - padding: 6 spacing: 6 diff --git a/src/imports/controls/ToolBar.qml b/src/imports/controls/ToolBar.qml index 2c0fb5f0..db3d65c1 100644 --- a/src/imports/controls/ToolBar.qml +++ b/src/imports/controls/ToolBar.qml @@ -47,8 +47,6 @@ T.ToolBar { contentWidth: contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0 contentHeight: contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0 - Accessible.role: Accessible.ToolBar - //! [contentItem] contentItem: Item { } //! [contentItem] diff --git a/src/imports/controls/ToolButton.qml b/src/imports/controls/ToolButton.qml index 4eac37fd..f68653b3 100644 --- a/src/imports/controls/ToolButton.qml +++ b/src/imports/controls/ToolButton.qml @@ -46,10 +46,6 @@ T.ToolButton { implicitHeight: Math.max(background ? background.implicitHeight : 0, label ? label.implicitHeight + topPadding + bottomPadding : 0) - Accessible.name: text - Accessible.pressed: pressed - Accessible.role: Accessible.Button - padding: 6 //! [label] diff --git a/tests/auto/accessibility/accessibility.pro b/tests/auto/accessibility/accessibility.pro new file mode 100644 index 00000000..c57eba11 --- /dev/null +++ b/tests/auto/accessibility/accessibility.pro @@ -0,0 +1,15 @@ +CONFIG += testcase +TARGET = tst_accessibility +SOURCES += tst_accessibility.cpp + +osx:CONFIG -= app_bundle + +QT += core-private gui-private qml-private quick-private testlib + +include (../shared/util.pri) + +TESTDATA = data/* + +OTHER_FILES += \ + data/* + diff --git a/tests/auto/accessibility/data/busyindicator.qml b/tests/auto/accessibility/data/busyindicator.qml new file mode 100644 index 00000000..4bde9634 --- /dev/null +++ b/tests/auto/accessibility/data/busyindicator.qml @@ -0,0 +1,12 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + BusyIndicator { + id: busyindicator + objectName: "busyindicator" + } +} diff --git a/tests/auto/accessibility/data/button.qml b/tests/auto/accessibility/data/button.qml new file mode 100644 index 00000000..75925185 --- /dev/null +++ b/tests/auto/accessibility/data/button.qml @@ -0,0 +1,13 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + Button { + id: button + objectName: "button" + text: "Button" + } +} diff --git a/tests/auto/accessibility/data/checkbox.qml b/tests/auto/accessibility/data/checkbox.qml new file mode 100644 index 00000000..9700663d --- /dev/null +++ b/tests/auto/accessibility/data/checkbox.qml @@ -0,0 +1,13 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + CheckBox { + id: checkbox + objectName: "checkbox" + text: "CheckBox" + } +} diff --git a/tests/auto/accessibility/data/control.qml b/tests/auto/accessibility/data/control.qml new file mode 100644 index 00000000..ceaba509 --- /dev/null +++ b/tests/auto/accessibility/data/control.qml @@ -0,0 +1,12 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + Control { + id: control + objectName: "control" + } +} diff --git a/tests/auto/accessibility/data/label.qml b/tests/auto/accessibility/data/label.qml new file mode 100644 index 00000000..409898d4 --- /dev/null +++ b/tests/auto/accessibility/data/label.qml @@ -0,0 +1,13 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + Label { + id: label + objectName: "label" + text: "Label" + } +} diff --git a/tests/auto/accessibility/data/pageindicator.qml b/tests/auto/accessibility/data/pageindicator.qml new file mode 100644 index 00000000..b42d3f9e --- /dev/null +++ b/tests/auto/accessibility/data/pageindicator.qml @@ -0,0 +1,12 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + PageIndicator { + id: pageindicator + objectName: "pageindicator" + } +} diff --git a/tests/auto/accessibility/data/progressbar.qml b/tests/auto/accessibility/data/progressbar.qml new file mode 100644 index 00000000..283db003 --- /dev/null +++ b/tests/auto/accessibility/data/progressbar.qml @@ -0,0 +1,15 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + ProgressBar { + id: progressbar + objectName: "progressbar" + from: 0 + to: 100 + value: 50 + } +} diff --git a/tests/auto/accessibility/data/radiobutton.qml b/tests/auto/accessibility/data/radiobutton.qml new file mode 100644 index 00000000..1883fff8 --- /dev/null +++ b/tests/auto/accessibility/data/radiobutton.qml @@ -0,0 +1,13 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + RadioButton { + id: radiobutton + objectName: "radiobutton" + text: "RadioButton" + } +} diff --git a/tests/auto/accessibility/data/scrollbar.qml b/tests/auto/accessibility/data/scrollbar.qml new file mode 100644 index 00000000..2e360422 --- /dev/null +++ b/tests/auto/accessibility/data/scrollbar.qml @@ -0,0 +1,12 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + ScrollBar { + id: scrollbar + objectName: "scrollbar" + } +} diff --git a/tests/auto/accessibility/data/scrollindicator.qml b/tests/auto/accessibility/data/scrollindicator.qml new file mode 100644 index 00000000..e933dece --- /dev/null +++ b/tests/auto/accessibility/data/scrollindicator.qml @@ -0,0 +1,12 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + ScrollIndicator { + id: scrollindicator + objectName: "scrollindicator" + } +} diff --git a/tests/auto/accessibility/data/slider.qml b/tests/auto/accessibility/data/slider.qml new file mode 100644 index 00000000..060bb66c --- /dev/null +++ b/tests/auto/accessibility/data/slider.qml @@ -0,0 +1,17 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + Slider { + id: slider + objectName: "slider" + from: 0 + to: 100 + value: 50 + stepSize: 1 + orientation: "Horizontal" + } +} diff --git a/tests/auto/accessibility/data/switch.qml b/tests/auto/accessibility/data/switch.qml new file mode 100644 index 00000000..9913e3f1 --- /dev/null +++ b/tests/auto/accessibility/data/switch.qml @@ -0,0 +1,13 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + Switch { + //id: switch + objectName: "switch" + text: "Switch" + } +} diff --git a/tests/auto/accessibility/data/tabbar.qml b/tests/auto/accessibility/data/tabbar.qml new file mode 100644 index 00000000..127c4e81 --- /dev/null +++ b/tests/auto/accessibility/data/tabbar.qml @@ -0,0 +1,12 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + TabBar { + id: tabbar + objectName: "tabbar" + } +} diff --git a/tests/auto/accessibility/data/tabbutton.qml b/tests/auto/accessibility/data/tabbutton.qml new file mode 100644 index 00000000..cfb04ca2 --- /dev/null +++ b/tests/auto/accessibility/data/tabbutton.qml @@ -0,0 +1,17 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + TabBar { + id: tabbar + objectName: "TabBar" + TabButton { + id: tabbutton + objectName: "tabbutton" + text: "TabButton" + } + } +} diff --git a/tests/auto/accessibility/data/textarea-2.qml b/tests/auto/accessibility/data/textarea-2.qml new file mode 100644 index 00000000..381c08bd --- /dev/null +++ b/tests/auto/accessibility/data/textarea-2.qml @@ -0,0 +1,13 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + TextArea { + id: textarea + objectName: "textarea" + text: "TextArea" + } +} diff --git a/tests/auto/accessibility/data/textarea.qml b/tests/auto/accessibility/data/textarea.qml new file mode 100644 index 00000000..9ae51ca8 --- /dev/null +++ b/tests/auto/accessibility/data/textarea.qml @@ -0,0 +1,14 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + TextArea { + id: textarea + objectName: "textarea" + text: "TextArea" + Accessible.name: text + } +} diff --git a/tests/auto/accessibility/data/textfield-2.qml b/tests/auto/accessibility/data/textfield-2.qml new file mode 100644 index 00000000..5db46d82 --- /dev/null +++ b/tests/auto/accessibility/data/textfield-2.qml @@ -0,0 +1,13 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + TextField { + id: textfield + objectName: "textfield" + text: "TextField" + } +} diff --git a/tests/auto/accessibility/data/textfield.qml b/tests/auto/accessibility/data/textfield.qml new file mode 100644 index 00000000..c3ea9b08 --- /dev/null +++ b/tests/auto/accessibility/data/textfield.qml @@ -0,0 +1,14 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + TextField { + id: textfield + objectName: "textfield" + text: "TextField" + Accessible.name: text + } +} diff --git a/tests/auto/accessibility/data/togglebutton.qml b/tests/auto/accessibility/data/togglebutton.qml new file mode 100644 index 00000000..8f75c364 --- /dev/null +++ b/tests/auto/accessibility/data/togglebutton.qml @@ -0,0 +1,13 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + ToggleButton { + id: togglebutton + objectName: "togglebutton" + text: "ToggleButton" + } +} diff --git a/tests/auto/accessibility/data/toolbar.qml b/tests/auto/accessibility/data/toolbar.qml new file mode 100644 index 00000000..c0503aef --- /dev/null +++ b/tests/auto/accessibility/data/toolbar.qml @@ -0,0 +1,12 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + ToolBar { + id: toolbar + objectName: "toolbar" + } +} diff --git a/tests/auto/accessibility/data/toolbutton.qml b/tests/auto/accessibility/data/toolbutton.qml new file mode 100644 index 00000000..63aacddc --- /dev/null +++ b/tests/auto/accessibility/data/toolbutton.qml @@ -0,0 +1,13 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +Window { + visible: true + + ToolButton { + id: toolbutton + objectName: "toolbutton" + text: "ToolButton" + } +} diff --git a/tests/auto/accessibility/tst_accessibility.cpp b/tests/auto/accessibility/tst_accessibility.cpp new file mode 100644 index 00000000..31700044 --- /dev/null +++ b/tests/auto/accessibility/tst_accessibility.cpp @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> +#include <QtTest/QSignalSpy> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlcontext.h> +#include <QtQuick/qquickview.h> +#include <QtQuick/private/qquickitem_p.h> +#include "../shared/util.h" +#include "../shared/visualtestutil.h" + +#ifndef QT_NO_ACCESSIBILITY +#include <QtQuick/private/qquickaccessibleattached_p.h> +#endif + +using namespace QQuickVisualTestUtil; + +class tst_accessibility : public QQmlDataTest +{ + Q_OBJECT +public: + +private slots: + void a11y_data(); + void a11y(); + +private: + QQmlEngine engine; +}; + +void tst_accessibility::a11y_data() +{ + QTest::addColumn<QString>("name"); + QTest::addColumn<int>("role"); + QTest::addColumn<QString>("text"); + + QTest::newRow("BusyIndicator") << "busyindicator" << 0x00000027 << ""; //QAccessible::Indicator + QTest::newRow("Button") << "button" << 0x0000002B << "Button"; //QAccessible::Button + QTest::newRow("CheckBox") << "checkbox" << 0x0000002C << "CheckBox"; //QAccessible::CheckBox + // Frame + // GroupBox + QTest::newRow("Label") << "label" << 0x00000029 << "Label"; //QAccessible::StaticText + QTest::newRow("PageIndicator") << "pageindicator" << 0x00000027 << ""; //QAccessible::Indicator + QTest::newRow("ProgressBar") << "progressbar" << 0x00000030 << ""; //QAccessible::ProgressBar + QTest::newRow("RadioButton") << "radiobutton" << 0x0000002D << "RadioButton"; //QAccessible::RadioButton + QTest::newRow("ScrollBar") << "scrollbar" << 0x00000003 << ""; //QAccessible::ScrollBar + QTest::newRow("ScrollIndicator") << "scrollindicator" << 0x00000027 << ""; //QAccessible::Indicator + QTest::newRow("Slider") << "slider" << 0x00000033 << ""; //QAccessible::Slider + // StackView + QTest::newRow("Switch") << "switch" << 0x0000002B << "Switch"; //QAccessible::Button + QTest::newRow("TabBar") << "tabbar" << 0x0000003C << ""; //QAccessible::PageTabList + QTest::newRow("TabButton") << "tabbutton" << 0x00000025 << "TabButton"; //QAccessible::PageTab + QTest::newRow("TextArea") << "textarea" << 0x0000002A << "TextArea"; //QAccessible::Accessible.EditableText + QTest::newRow("TextField") << "textfield" << 0x0000002A << "TextField"; //QAccessible::Accessible.EditableText + QTest::newRow("ToggleButton") << "togglebutton" << 0x0000002B << "ToggleButton"; //QAccessible::Button + QTest::newRow("ToolBar") << "toolbar" << 0x00000016 << ""; //QAccessible::ToolBar + QTest::newRow("ToolButton") << "toolbutton" << 0x0000002B << "ToolButton"; //QAccessible::Button +} + +void tst_accessibility::a11y() +{ + QFETCH(QString, name); + QFETCH(int, role); + QFETCH(QString, text); + + QQmlComponent component(&engine); + QString fn = name; +#ifdef QT_NO_ACCESSIBILITY + if (name == QLatin1Literal("textarea") || name == QLatin1Literal("textfield")) + fn += QLatin1Literal("-2"); +#endif + component.loadUrl(testFileUrl(fn + ".qml")); + QObject* created = component.create(); + QVERIFY(created); + QScopedPointer<QObject> cleanup(created); + QVERIFY(!cleanup.isNull()); + + QQuickWindow* window = qobject_cast<QQuickWindow*>(created); + QVERIFY(window); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickItem *item = findItem<QQuickItem>(window->contentItem(), name); + QVERIFY(item); + +#ifndef QT_NO_ACCESSIBILITY + QQuickAccessibleAttached *acc = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(item, false)); + QVERIFY(acc); + QCOMPARE(acc->role(), (QAccessible::Role)role); + QCOMPARE(acc->name(), text); +#else + Q_UNUSED(role) + Q_UNUSED(text) + QObject *acc = qmlAttachedPropertiesObject<QObject>(item, false); + QVERIFY(!acc); +#endif +} + +QTEST_MAIN(tst_accessibility) + +#include "tst_accessibility.moc" diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index d9a7e631..6bb49ad1 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -1,5 +1,6 @@ TEMPLATE = subdirs SUBDIRS += \ + accessibility \ applicationwindow \ controls \ extras \ |