Add default actions to QAccessibleWidget.
authorFrederik Gladhorn <frederik.gladhorn@nokia.com>
Tue, 11 Oct 2011 14:20:47 +0000 (16:20 +0200)
committerQt by Nokia <qt-info@nokia.com>
Thu, 27 Oct 2011 09:12:38 +0000 (11:12 +0200)
Change-Id: I9f251aad663fd0b8db2ef068c6581241d91c090d
Reviewed-by: Jan-Arve Sæther <jan-arve.saether@nokia.com>
src/gui/accessible/qaccessible2.cpp
src/gui/accessible/qaccessible2.h
src/plugins/accessible/widgets/complexwidgets.h
src/plugins/accessible/widgets/simplewidgets.cpp
src/plugins/accessible/widgets/simplewidgets.h
src/widgets/accessible/qaccessiblewidget.cpp
src/widgets/accessible/qaccessiblewidget.h
tests/auto/integrationtests/qaccessibility/tst_qaccessibility.cpp

index b33d975..b3ad00c 100644 (file)
@@ -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
index 65e63b4..d3777d6 100644 (file)
@@ -43,6 +43,7 @@
 #define QACCESSIBLE2_H
 
 #include <QtGui/qaccessible.h>
+#include <QtCore/qcoreapplication.h>
 
 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; }
 
index 980eee2..13fe9be 100644 (file)
@@ -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:
index 4771d93..d2c5256 100644 (file)
@@ -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<QGroupBox*>(object());
-       if (groupbox && !groupbox->title().isEmpty())
-           if (groupbox->children().contains(o))
-               relation |= Label;
+        QGroupBox *groupbox = qobject_cast<QGroupBox*>(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<QGroupBox*>(object());
-           if (groupbox && !groupbox->title().isEmpty())
-               rel = Child;
+            QGroupBox *groupbox = qobject_cast<QGroupBox*>(object());
+            if (groupbox && !groupbox->title().isEmpty())
+                rel = Child;
 #endif
         }
         *target = QAccessible::queryAccessibleInterface(targetObject);
index 252d994..8642f8d 100644 (file)
@@ -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)
index 9e11ab8..b4613a6 100644 (file)
@@ -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
 {
index 9a6dae6..e3b5a86 100644 (file)
@@ -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 &params);
 
+    // QAccessibleActionInterface
+    QStringList actionNames() const;
+    void doAction(const QString &actionName);
+    QStringList keyBindingsForAction(const QString &actionName) const;
+
 protected:
     ~QAccessibleWidget();
     QWidget *widget() const;
index fdd120e..a87ffb0 100644 (file)
@@ -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);