Add default actions to QAccessibleWidget.

Change-Id: I9f251aad663fd0b8db2ef068c6581241d91c090d
Reviewed-by: Jan-Arve Sæther <jan-arve.saether@nokia.com>
bb10
Frederik Gladhorn 2011-10-11 16:20:47 +02:00 committed by Qt by Nokia
parent 8f912c5c0f
commit 5aa14793c4
8 changed files with 119 additions and 58 deletions

View 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

View 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; }

View 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:

View 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);

View 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)

View 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
{

View 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;

View 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());
QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(widget);
QVERIFY(interface);
QVERIFY(interface->isValid());
QAccessibleActionInterface *actions = interface->actionInterface();
QVERIFY(actions);
// 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());
// no actions by default, except when focusable
QCOMPARE(actions->actionNames(), QStringList());
widget->setFocusPolicy(Qt::StrongFocus);
QCOMPARE(actions->actionNames(), QStringList() << QAccessibleActionInterface::SetFocusAction);
// QCOMPARE(test->actionText(QAccessible::DefaultAction, QAccessible::Name, 0), QString("SetFocus"));
// QCOMPARE(test->actionText(QAccessible::SetFocus, QAccessible::Name, 0), QString("SetFocus"));
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);