From 5aa14793c422dc77f3b464c27091dcd1b2ed1c72 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Tue, 11 Oct 2011 16:20:47 +0200 Subject: [PATCH] Add default actions to QAccessibleWidget. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: I9f251aad663fd0b8db2ef068c6581241d91c090d Reviewed-by: Jan-Arve Sæther --- src/gui/accessible/qaccessible2.cpp | 31 +++------ src/gui/accessible/qaccessible2.h | 2 + src/plugins/accessible/widgets/complexwidgets.h | 2 +- src/plugins/accessible/widgets/simplewidgets.cpp | 24 ++++--- src/plugins/accessible/widgets/simplewidgets.h | 2 +- src/widgets/accessible/qaccessiblewidget.cpp | 27 ++++++++ src/widgets/accessible/qaccessiblewidget.h | 8 ++- .../qaccessibility/tst_qaccessibility.cpp | 81 ++++++++++++++++------ 8 files changed, 119 insertions(+), 58 deletions(-) diff --git a/src/gui/accessible/qaccessible2.cpp b/src/gui/accessible/qaccessible2.cpp index b33d975..b3ad00c 100644 --- a/src/gui/accessible/qaccessible2.cpp +++ b/src/gui/accessible/qaccessible2.cpp @@ -198,32 +198,17 @@ QT_BEGIN_NAMESPACE \sa actionNames() */ -const QString QAccessibleActionInterface::PressAction = QStringLiteral("Press"); -const QString QAccessibleActionInterface::IncreaseAction = QStringLiteral("Increase"); -const QString QAccessibleActionInterface::DecreaseAction = QStringLiteral("Decrease"); -const QString QAccessibleActionInterface::ShowMenuAction = QStringLiteral("ShowMenu"); -const QString QAccessibleActionInterface::SetFocusAction = QStringLiteral("SetFocus"); -const QString QAccessibleActionInterface::CheckAction = QStringLiteral("Check"); -const QString QAccessibleActionInterface::UncheckAction = QStringLiteral("Uncheck"); +const QString QAccessibleActionInterface::PressAction = QStringLiteral(QT_TR_NOOP("Press")); +const QString QAccessibleActionInterface::IncreaseAction = QStringLiteral(QT_TR_NOOP("Increase")); +const QString QAccessibleActionInterface::DecreaseAction = QStringLiteral(QT_TR_NOOP("Decrease")); +const QString QAccessibleActionInterface::ShowMenuAction = QStringLiteral(QT_TR_NOOP("ShowMenu")); +const QString QAccessibleActionInterface::SetFocusAction = QStringLiteral(QT_TR_NOOP("SetFocus")); +const QString QAccessibleActionInterface::CheckAction = QStringLiteral(QT_TR_NOOP("Check")); +const QString QAccessibleActionInterface::UncheckAction = QStringLiteral(QT_TR_NOOP("Uncheck")); QString QAccessibleActionInterface::localizedActionName(const QString &actionName) const { - if (actionName == PressAction) - return QCoreApplication::translate("QAccessibleActionInterface", "Press"); - else if (actionName == IncreaseAction) - return QCoreApplication::translate("QAccessibleActionInterface", "Increase"); - else if (actionName == DecreaseAction) - return QCoreApplication::translate("QAccessibleActionInterface", "Decrease"); - else if (actionName == ShowMenuAction) - return QCoreApplication::translate("QAccessibleActionInterface", "ShowMenu"); - else if (actionName == SetFocusAction) - return QCoreApplication::translate("QAccessibleActionInterface", "SetFocus"); - else if (actionName == CheckAction) - return QCoreApplication::translate("QAccessibleActionInterface", "Check"); - else if (actionName == UncheckAction) - return QCoreApplication::translate("QAccessibleActionInterface", "Uncheck"); - - return QString(); + return QAccessibleActionInterface::tr(qPrintable(actionName)); } QString QAccessibleActionInterface::localizedActionDescription(const QString &actionName) const diff --git a/src/gui/accessible/qaccessible2.h b/src/gui/accessible/qaccessible2.h index 65e63b4..d3777d6 100644 --- a/src/gui/accessible/qaccessible2.h +++ b/src/gui/accessible/qaccessible2.h @@ -43,6 +43,7 @@ #define QACCESSIBLE2_H #include +#include QT_BEGIN_HEADER @@ -328,6 +329,7 @@ friend class QAbstractItemViewPrivate; class Q_GUI_EXPORT QAccessibleActionInterface: public QAccessible2Interface { + Q_DECLARE_TR_FUNCTIONS(QAccessibleActionInterface) public: inline QAccessible2Interface *qAccessibleActionCastHelper() { return this; } diff --git a/src/plugins/accessible/widgets/complexwidgets.h b/src/plugins/accessible/widgets/complexwidgets.h index 980eee2..13fe9be 100644 --- a/src/plugins/accessible/widgets/complexwidgets.h +++ b/src/plugins/accessible/widgets/complexwidgets.h @@ -250,7 +250,7 @@ protected: #endif // QT_NO_TABBAR #ifndef QT_NO_COMBOBOX -class QAccessibleComboBox : public QAccessibleWidget, public QAccessibleActionInterface +class QAccessibleComboBox : public QAccessibleWidget { Q_ACCESSIBLE_OBJECT public: diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp index 4771d93..d2c5256 100644 --- a/src/plugins/accessible/widgets/simplewidgets.cpp +++ b/src/plugins/accessible/widgets/simplewidgets.cpp @@ -187,6 +187,7 @@ QStringList QAccessibleButton::actionNames() const break; } } + names << QAccessibleWidget::actionNames(); return names; } @@ -203,12 +204,13 @@ void QAccessibleButton::doAction(const QString &actionName) else #endif button()->animateClick(); - } - - if (actionName == CheckAction) + } else if (actionName == CheckAction) { button()->setChecked(true); - if (actionName == UncheckAction) + } else if (actionName == UncheckAction) { button()->setChecked(false); + } else { + QAccessibleWidget::doAction(actionName); + } } QStringList QAccessibleButton::keyBindingsForAction(const QString &actionName) const @@ -456,10 +458,10 @@ QAccessible::Relation QAccessibleDisplay::relationTo(int child, const QAccessibl #endif #ifndef QT_NO_GROUPBOX } else { - QGroupBox *groupbox = qobject_cast(object()); - if (groupbox && !groupbox->title().isEmpty()) - if (groupbox->children().contains(o)) - relation |= Label; + QGroupBox *groupbox = qobject_cast(object()); + if (groupbox && !groupbox->title().isEmpty()) + if (groupbox->children().contains(o)) + relation |= Label; #endif } return relation; @@ -478,9 +480,9 @@ int QAccessibleDisplay::navigate(RelationFlag rel, int entry, QAccessibleInterfa #endif #ifndef QT_NO_GROUPBOX } else { - QGroupBox *groupbox = qobject_cast(object()); - if (groupbox && !groupbox->title().isEmpty()) - rel = Child; + QGroupBox *groupbox = qobject_cast(object()); + if (groupbox && !groupbox->title().isEmpty()) + rel = Child; #endif } *target = QAccessible::queryAccessibleInterface(targetObject); diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h index 252d994..8642f8d 100644 --- a/src/plugins/accessible/widgets/simplewidgets.h +++ b/src/plugins/accessible/widgets/simplewidgets.h @@ -55,7 +55,7 @@ class QLineEdit; class QToolButton; class QProgressBar; -class QAccessibleButton : public QAccessibleWidget, public QAccessibleActionInterface +class QAccessibleButton : public QAccessibleWidget { Q_ACCESSIBLE_OBJECT Q_DECLARE_TR_FUNCTIONS(QAccessibleButton) diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index 9e11ab8..b4613a6 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -819,6 +819,33 @@ QString QAccessibleWidget::text(Text t, int child) const return str; } +QStringList QAccessibleWidget::actionNames() const +{ + QStringList names; + if (widget()->isEnabled()) { + if (widget()->focusPolicy() != Qt::NoFocus) + names << SetFocusAction; + } + return names; +} + +void QAccessibleWidget::doAction(const QString &actionName) +{ + if (!widget()->isEnabled()) + return; + + if (actionName == SetFocusAction) { + if (widget()->isWindow()) + widget()->activateWindow(); + widget()->setFocus(); + } +} + +QStringList QAccessibleWidget::keyBindingsForAction(const QString &actionName) const +{ + return QStringList(); +} + /*! \reimp */ QAccessible::Role QAccessibleWidget::role(int child) const { diff --git a/src/widgets/accessible/qaccessiblewidget.h b/src/widgets/accessible/qaccessiblewidget.h index 9a6dae6..e3b5a86 100644 --- a/src/widgets/accessible/qaccessiblewidget.h +++ b/src/widgets/accessible/qaccessiblewidget.h @@ -54,8 +54,9 @@ QT_MODULE(Gui) class QAccessibleWidgetPrivate; -class Q_WIDGETS_EXPORT QAccessibleWidget : public QAccessibleObject +class Q_WIDGETS_EXPORT QAccessibleWidget : public QAccessibleObject, public QAccessibleActionInterface { + Q_ACCESSIBLE_OBJECT public: explicit QAccessibleWidget(QWidget *o, Role r = Client, const QString& name = QString()); @@ -80,6 +81,11 @@ public: QVariant invokeMethod(Method method, int child, const QVariantList ¶ms); + // QAccessibleActionInterface + QStringList actionNames() const; + void doAction(const QString &actionName); + QStringList keyBindingsForAction(const QString &actionName) const; + protected: ~QAccessibleWidget(); QWidget *widget() const; diff --git a/tests/auto/integrationtests/qaccessibility/tst_qaccessibility.cpp b/tests/auto/integrationtests/qaccessibility/tst_qaccessibility.cpp index fdd120e..a87ffb0 100644 --- a/tests/auto/integrationtests/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/integrationtests/qaccessibility/tst_qaccessibility.cpp @@ -266,6 +266,11 @@ private slots: void accessibleName(); void labelTest(); void accelerators(); + +protected slots: + void onClicked(); +private: + int click_count; }; const double Q_PI = 3.14159265358979323846; @@ -360,12 +365,18 @@ public: tst_QAccessibility::tst_QAccessibility() { + click_count = 0; } tst_QAccessibility::~tst_QAccessibility() { } +void tst_QAccessibility::onClicked() +{ + click_count++; +} + void tst_QAccessibility::initTestCase() { QTestAccessibility::initialize(); @@ -935,26 +946,53 @@ void tst_QAccessibility::hideShowTest() void tst_QAccessibility::actionTest() { + { QCOMPARE(QAccessibleActionInterface::PressAction, QString("Press")); QWidget *widget = new QWidget; + widget->setFocusPolicy(Qt::NoFocus); widget->show(); - QAccessibleInterface *test = QAccessible::queryAccessibleInterface(widget); - QVERIFY(test); - QVERIFY(test->isValid()); - -// QCOMPARE(test->actionText(1, QAccessible::Name, 0), QString()); -// QCOMPARE(test->actionText(0, QAccessible::Name, 1), QString()); -// QCOMPARE(test->actionText(1, QAccessible::Name, 1), QString()); -// QCOMPARE(test->actionText(QAccessible::SetFocus, QAccessible::Name, -1), QString()); + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(widget); + QVERIFY(interface); + QVERIFY(interface->isValid()); + QAccessibleActionInterface *actions = interface->actionInterface(); + QVERIFY(actions); -// QCOMPARE(test->actionText(QAccessible::DefaultAction, QAccessible::Name, 0), QString("SetFocus")); -// QCOMPARE(test->actionText(QAccessible::SetFocus, QAccessible::Name, 0), QString("SetFocus")); + // no actions by default, except when focusable + QCOMPARE(actions->actionNames(), QStringList()); + widget->setFocusPolicy(Qt::StrongFocus); + QCOMPARE(actions->actionNames(), QStringList() << QAccessibleActionInterface::SetFocusAction); - delete test; + delete interface; delete widget; + } + QTestAccessibility::clearEvents(); + { + QPushButton *button = new QPushButton; + button->show(); + QCOMPARE(button->hasFocus(), false); + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(button); + QAccessibleActionInterface *actions = interface->actionInterface(); + QVERIFY(actions); + + // Make sure the "primary action" press comes first! + QCOMPARE(actions->actionNames(), QStringList() << QAccessibleActionInterface::PressAction << QAccessibleActionInterface::SetFocusAction); + + actions->doAction(QAccessibleActionInterface::SetFocusAction); + QTest::qWait(500); + QCOMPARE(button->hasFocus(), true); + + connect(button, SIGNAL(clicked()), this, SLOT(onClicked())); + QCOMPARE(click_count, 0); + actions->doAction(QAccessibleActionInterface::PressAction); + QTest::qWait(500); + QCOMPARE(click_count, 1); + + delete interface; + delete button; + } QTestAccessibility::clearEvents(); } @@ -1041,9 +1079,9 @@ void tst_QAccessibility::buttonTest() QVERIFY(actionInterface != 0); QCOMPARE(interface->role(), QAccessible::PushButton); - // currently our buttons only have click as action, press and release are missing - QCOMPARE(actionInterface->actionNames().size(), 1); - QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::PressAction); + // buttons only have a click action + QCOMPARE(actionInterface->actionNames().size(), 2); + QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::PressAction << QAccessibleActionInterface::SetFocusAction); QCOMPARE(pushButton.clickCount, 0); actionInterface->doAction(QAccessibleActionInterface::PressAction); QTest::qWait(500); @@ -1054,7 +1092,7 @@ void tst_QAccessibility::buttonTest() interface = QAccessible::queryAccessibleInterface(&toggleButton); actionInterface = interface->actionInterface(); QCOMPARE(interface->role(), QAccessible::CheckBox); - QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::CheckAction); + QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::CheckAction << QAccessibleActionInterface::SetFocusAction); QCOMPARE(actionInterface->localizedActionDescription(QAccessibleActionInterface::CheckAction), QString("Checks the checkbox")); QVERIFY(!toggleButton.isChecked()); QVERIFY((interface->state() & QAccessible::Checked) == 0); @@ -1077,7 +1115,7 @@ void tst_QAccessibility::buttonTest() QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&menuButton); QCOMPARE(interface->role(), QAccessible::ButtonMenu); QVERIFY(interface->state() & QAccessible::HasPopup); - QCOMPARE(interface->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::ShowMenuAction); + QCOMPARE(interface->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::ShowMenuAction << QAccessibleActionInterface::SetFocusAction); // showing the menu enters a new event loop... // interface->actionInterface()->doAction(QAccessibleActionInterface::ShowMenuAction); // QTest::qWait(500); @@ -1089,11 +1127,11 @@ void tst_QAccessibility::buttonTest() interface = QAccessible::queryAccessibleInterface(&checkBox); actionInterface = interface->actionInterface(); QCOMPARE(interface->role(), QAccessible::CheckBox); - QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::CheckAction); + QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::CheckAction << QAccessibleActionInterface::SetFocusAction); QVERIFY((interface->state() & QAccessible::Checked) == 0); actionInterface->doAction(QAccessibleActionInterface::CheckAction); QTest::qWait(500); - QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::UncheckAction); + QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::UncheckAction << QAccessibleActionInterface::SetFocusAction); QVERIFY(interface->state() & QAccessible::Checked); QVERIFY(checkBox.isChecked()); delete interface; @@ -1102,11 +1140,11 @@ void tst_QAccessibility::buttonTest() interface = QAccessible::queryAccessibleInterface(&radio); actionInterface = interface->actionInterface(); QCOMPARE(interface->role(), QAccessible::RadioButton); - QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::CheckAction); + QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::CheckAction << QAccessibleActionInterface::SetFocusAction); QVERIFY((interface->state() & QAccessible::Checked) == 0); actionInterface->doAction(QAccessibleActionInterface::CheckAction); QTest::qWait(500); - QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::CheckAction); + QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::CheckAction << QAccessibleActionInterface::SetFocusAction); QVERIFY(interface->state() & QAccessible::Checked); QVERIFY(checkBox.isChecked()); delete interface; @@ -1471,7 +1509,8 @@ void tst_QAccessibility::menuTest() QTest::qWait(menuFadeDelay); QVERIFY(!file->isVisible() && !edit->isVisible() && !help->isVisible()); - QVERIFY(!interface->actionInterface()); + QVERIFY(interface->actionInterface()); + QCOMPARE(interface->actionInterface()->actionNames(), QStringList()); delete interface; interface = QAccessible::queryAccessibleInterface(file); QCOMPARE(interface->childCount(), 5); -- 2.7.4