Added QAccessibleGroupBox

Added a new accessible interface for QGroupBox, as QAccessibleDisplay
is not good enough when the QGroupBox is checkable.
AccessibleFactory was modified to return a QAccessibleGroupBox when
the accessible interface of a QGroupBox is requested.

Created tst_QAccessibility::groupBoxTest

Port to Qt5 of the patch by José Millán Soto <fid@gpul.org>

Change-Id: I6c23dcf5562b3ea269b04102e78463b65827188a
Reviewed-by: Jan-Arve Sæther <jan-arve.saether@nokia.com>
(cherry picked from commit c03ceb203c65d9e3485fad848bfc0c4b6ee3e9aa)
This commit is contained in:
Frederik Gladhorn 2012-02-13 14:05:51 +01:00 committed by Qt by Nokia
parent f49f94434e
commit f195a8e2b6
5 changed files with 180 additions and 14 deletions

View File

@ -236,8 +236,10 @@ QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObjec
#endif
} else if (classname == QLatin1String("QLabel") || classname == QLatin1String("QLCDNumber")) {
iface = new QAccessibleDisplay(widget);
#ifndef QT_NO_GROUPBOX
} else if (classname == QLatin1String("QGroupBox")) {
iface = new QAccessibleDisplay(widget, QAccessible::Grouping);
iface = new QAccessibleGroupBox(widget);
#endif
} else if (classname == QLatin1String("QStatusBar")) {
iface = new QAccessibleWidget(widget, QAccessible::StatusBar);
#ifndef QT_NO_PROGRESSBAR

View File

@ -399,10 +399,6 @@ QString QAccessibleDisplay::text(QAccessible::Text t) const
if (str.isEmpty()) {
if (qobject_cast<QLabel*>(object())) {
str = qobject_cast<QLabel*>(object())->text();
#ifndef QT_NO_GROUPBOX
} else if (qobject_cast<QGroupBox*>(object())) {
str = qobject_cast<QGroupBox*>(object())->title();
#endif
#ifndef QT_NO_LCDNUMBER
} else if (qobject_cast<QLCDNumber*>(object())) {
QLCDNumber *l = qobject_cast<QLCDNumber*>(object());
@ -439,15 +435,6 @@ QAccessibleDisplay::relations(QAccessible::Relation match /*= QAccessible::AllRe
#ifndef QT_NO_SHORTCUT
if (QLabel *label = qobject_cast<QLabel*>(object())) {
relatedObjects.append(label->buddy());
#endif
#ifndef QT_NO_GROUPBOX
} else if (QGroupBox *groupbox = qobject_cast<QGroupBox*>(object())) {
if (!groupbox->title().isEmpty()) {
const QList<QWidget*> kids = childWidgets(widget());
for (int i = 0; i < kids.count(); ++i) {
relatedObjects.append(kids.at(i));
}
}
#endif
}
for (int i = 0; i < relatedObjects.count(); ++i) {
@ -502,6 +489,87 @@ QRect QAccessibleDisplay::imagePosition() const
return QRect(label->mapToGlobal(label->pos()), label->size());
}
#ifndef QT_NO_GROUPBOX
QAccessibleGroupBox::QAccessibleGroupBox(QWidget *w)
: QAccessibleWidget(w)
{
}
QGroupBox* QAccessibleGroupBox::groupBox() const
{
return static_cast<QGroupBox *>(widget());
}
QString QAccessibleGroupBox::text(QAccessible::Text t) const
{
QString txt = QAccessibleWidget::text(t);
if (txt.isEmpty()) {
switch (t) {
case QAccessible::Name:
txt = qt_accStripAmp(groupBox()->title());
case QAccessible::Description:
txt = qt_accStripAmp(groupBox()->title());
default:
break;
}
}
return txt;
}
QAccessible::State QAccessibleGroupBox::state() const
{
QAccessible::State st = QAccessibleWidget::state();
st.checkable = groupBox()->isCheckable();
st.checked = groupBox()->isChecked();
return st;
}
QAccessible::Role QAccessibleGroupBox::role() const
{
return groupBox()->isCheckable() ? QAccessible::CheckBox : QAccessible::Grouping;
}
QVector<QPair<QAccessibleInterface*, QAccessible::Relation> >
QAccessibleGroupBox::relations(QAccessible::Relation match /*= QAccessible::AllRelations*/) const
{
QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > rels = QAccessibleWidget::relations(match);
if ((match & QAccessible::Labelled) && (!groupBox()->title().isEmpty())) {
const QList<QWidget*> kids = childWidgets(widget());
for (int i = 0; i < kids.count(); ++i) {
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(kids.at(i));
if (iface)
rels.append(qMakePair(iface, QAccessible::Relation(QAccessible::Labelled)));
}
}
return rels;
}
QStringList QAccessibleGroupBox::actionNames() const
{
QStringList actions = QAccessibleWidget::actionNames();
if (groupBox()->isCheckable()) {
actions.prepend(QAccessibleActionInterface::checkAction());
}
return actions;
}
void QAccessibleGroupBox::doAction(const QString &actionName)
{
if (actionName == QAccessibleActionInterface::checkAction())
groupBox()->setChecked(!groupBox()->isChecked());
}
QStringList QAccessibleGroupBox::keyBindingsForAction(const QString &) const
{
return QStringList();
}
#endif
#ifndef QT_NO_LINEEDIT
/*!
\class QAccessibleLineEdit

View File

@ -53,6 +53,7 @@ QT_BEGIN_NAMESPACE
class QAbstractButton;
class QLineEdit;
class QToolButton;
class QGroupBox;
class QProgressBar;
class QAccessibleButton : public QAccessibleWidget
@ -113,6 +114,28 @@ public:
QRect imagePosition() const;
};
#ifndef QT_NO_GROUPBOX
class QAccessibleGroupBox : public QAccessibleWidget
{
public:
explicit QAccessibleGroupBox(QWidget *w);
QAccessible::State state() const;
QAccessible::Role role() const;
QString text(QAccessible::Text t) const;
QVector<QPair<QAccessibleInterface*, QAccessible::Relation> >relations(QAccessible::Relation match = QAccessible::AllRelations) const;
//QAccessibleActionInterface
QStringList actionNames() const;
void doAction(const QString &actionName);
QStringList keyBindingsForAction(const QString &) const;
private:
QGroupBox *groupBox() const;
};
#endif
#ifndef QT_NO_LINEEDIT
class QAccessibleLineEdit : public QAccessibleWidget, public QAccessibleTextInterface,
public QAccessibleSimpleEditableTextInterface

View File

@ -643,6 +643,12 @@ void QGroupBox::setChecked(bool b)
update();
d->checked = b;
d->_q_setChildrenEnabled(b);
#ifndef QT_NO_ACCESSIBILITY
QAccessible::State st;
st.checked = true;
QAccessibleStateChangeEvent *ev = new QAccessibleStateChangeEvent(this, st);
QAccessible::updateAccessibility(ev);
#endif
emit toggled(b);
}
}

View File

@ -252,6 +252,7 @@ private slots:
void mdiAreaTest();
void mdiSubWindowTest();
void lineEditTest();
void groupBoxTest();
void workspaceTest();
void dialogButtonBoxTest();
void dialTest();
@ -1894,6 +1895,72 @@ void tst_QAccessibility::lineEditTest()
QTestAccessibility::clearEvents();
}
void tst_QAccessibility::groupBoxTest()
{
{
QGroupBox *groupBox = new QGroupBox();
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(groupBox);
groupBox->setTitle(QLatin1String("Test QGroupBox"));
QAccessibleEvent ev(groupBox, QAccessible::NameChanged);
QVERIFY_EVENT(&ev);
groupBox->setToolTip(QLatin1String("This group box will be used to test accessibility"));
QVBoxLayout *layout = new QVBoxLayout();
QRadioButton *rbutton = new QRadioButton();
layout->addWidget(rbutton);
groupBox->setLayout(layout);
QAccessibleInterface *rButtonIface = QAccessible::queryAccessibleInterface(rbutton);
QCOMPARE(iface->childCount(), 1);
QCOMPARE(iface->role(), QAccessible::Grouping);
QCOMPARE(iface->text(QAccessible::Name), QLatin1String("Test QGroupBox"));
QCOMPARE(iface->text(QAccessible::Description), QLatin1String("This group box will be used to test accessibility"));
QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > relations = rButtonIface->relations();
QVERIFY(relations.size() == 1);
QPair<QAccessibleInterface*, QAccessible::Relation> relation = relations.first();
QCOMPARE(relation.first->object(), groupBox);
QCOMPARE(relation.second, QAccessible::Label);
delete relation.first;
delete rButtonIface;
delete iface;
delete groupBox;
}
{
QGroupBox *groupBox = new QGroupBox();
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(groupBox);
QVERIFY(!iface->state().checkable);
groupBox->setCheckable(true);
groupBox->setChecked(false);
QAccessible::State st;
st.checked = true;
QAccessibleStateChangeEvent ev(groupBox, st);
QVERIFY_EVENT(&ev);
QCOMPARE(iface->role(), QAccessible::CheckBox);
QAccessibleActionInterface *actionIface = iface->actionInterface();
QVERIFY(actionIface);
QAccessible::State state = iface->state();
QVERIFY(state.checkable);
QVERIFY(!state.checked);
QVERIFY(actionIface->actionNames().contains(QAccessibleActionInterface::checkAction()));
actionIface->doAction(QAccessibleActionInterface::checkAction());
QVERIFY(groupBox->isChecked());
state = iface->state();
QVERIFY(state.checked);
QAccessibleStateChangeEvent ev2(groupBox, st);
QVERIFY_EVENT(&ev2);
delete iface;
delete groupBox;
}
}
void tst_QAccessibility::workspaceTest()
{
{