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 /src/controls | |
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>
Diffstat (limited to 'src/controls')
28 files changed, 317 insertions, 9 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 |