Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Accessibility: Checked state for check boxes and radio buttons.
Also adapt to new api in qtbase - state is now a bit field.

Change-Id: Ia4266f3d5094a6c32e0ace3499910b57c3e71c25
Reviewed-by: Jan-Arve Sæther <jan-arve.saether@nokia.com>
  • Loading branch information
Frederik Gladhorn authored and Qt by Nokia committed Jan 10, 2012
1 parent 6ffcd09 commit 1b4897f
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 67 deletions.
Expand Up @@ -171,13 +171,10 @@ int QAccessibleDeclarativeItem::indexOfChild(const QAccessibleInterface *iface)
return index;
}

QFlags<QAccessible::StateFlag> QAccessibleDeclarativeItem::state() const
QAccessible::State QAccessibleDeclarativeItem::state() const
{
QAccessible::State state = QAccessible::Normal;

if (m_item->hasFocus()) {
state |= QAccessible::Focused;
}
QAccessible::State state;
state.focused = m_item->hasFocus();
return state;
}

Expand Down
Expand Up @@ -65,7 +65,7 @@ class QAccessibleDeclarativeItem : public QDeclarativeAccessible
int navigate(QAccessible::RelationFlag rel, int entry, QAccessibleInterface **target) const;
int indexOfChild(const QAccessibleInterface *iface) const;

QFlags<QAccessible::StateFlag> state() const;
QAccessible::State state() const;
QAccessible::Role role() const;
QString text(QAccessible::Text) const;

Expand Down
29 changes: 23 additions & 6 deletions src/plugins/accessible/quick/qaccessiblequickitem.cpp
Expand Up @@ -174,17 +174,34 @@ QList<QQuickItem *> QAccessibleQuickItem::childItems() const
return item()->childItems();
}

QFlags<QAccessible::StateFlag> QAccessibleQuickItem::state() const
QAccessible::State QAccessibleQuickItem::state() const
{
QAccessible::State state = QAccessible::Normal;

if (item()->hasActiveFocus()) {
state |= QAccessible::Focused;
QAccessible::State state;

if (item()->hasActiveFocus())
state.focused = true;

QAccessible::Role r = role();
switch (r) {
case QAccessible::Button: {
QVariant checkable = item()->property("checkable");
if (!checkable.toBool())
break;
// fall through
}
case QAccessible::CheckBox:
case QAccessible::RadioButton: {
// FIXME when states are extended: state.checkable = true;
state.checked = item()->property("checked").toBool();
break;
}
default:
break;
}

return state;
}


QAccessible::Role QAccessibleQuickItem::role() const
{
// Workaround for setAccessibleRole() not working for
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/accessible/quick/qaccessiblequickitem.h
Expand Up @@ -67,7 +67,7 @@ class QAccessibleQuickItem : public QDeclarativeAccessible
int indexOfChild(const QAccessibleInterface *iface) const;
QList<QQuickItem *> childItems() const;

QFlags<QAccessible::StateFlag> state() const;
QAccessible::State state() const;
QAccessible::Role role() const;
QString text(QAccessible::Text) const;

Expand Down
2 changes: 1 addition & 1 deletion src/plugins/accessible/quick/qaccessiblequickview.cpp
Expand Up @@ -82,7 +82,7 @@ QAccessible::Role QAccessibleQuickView::role() const

QAccessible::State QAccessibleQuickView::state() const
{
return QAccessible::Normal; // FIXME
return QAccessible::State(); // FIXME
}

QRect QAccessibleQuickView::rect() const
Expand Down
18 changes: 9 additions & 9 deletions src/plugins/accessible/shared/qdeclarativeaccessible.cpp
Expand Up @@ -82,7 +82,7 @@ QAccessibleInterface *QDeclarativeAccessible::childAt(int x, int y) const

for (int i = childCount() - 1; i >= 0; --i) {
QAccessibleInterface *childIface = child(i);
if (childIface && !(childIface->state() & QAccessible::Invisible)) {
if (childIface && !childIface->state().invisible) {
if (childIface->rect().contains(x, y))
return childIface;
}
Expand All @@ -91,9 +91,9 @@ QAccessibleInterface *QDeclarativeAccessible::childAt(int x, int y) const
return 0;
}

QFlags<QAccessible::StateFlag> QDeclarativeAccessible::state() const
QAccessible::State QDeclarativeAccessible::state() const
{
QAccessible::State state;// = state();
QAccessible::State state;

//QRect viewRect(QPoint(0, 0), m_implementation->size());
//QRect itemRect(m_item->scenePos().toPoint(), m_item->boundingRect().size().toSize());
Expand All @@ -104,24 +104,24 @@ QFlags<QAccessible::StateFlag> QDeclarativeAccessible::state() const
// qDebug() << "viewRect" << viewRect << "itemRect" << itemRect;
// error case:
if (viewRect_.isNull() || itemRect.isNull()) {
state |= QAccessible::Invisible;
state.invisible = true;
}

if (!viewRect_.intersects(itemRect)) {
state |= QAccessible::Offscreen;
// state |= QAccessible::Invisible; // no set at this point to ease development
state.offscreen = true;
// state.invisible = true; // no set at this point to ease development
}

if (!object()->property("visible").toBool() || qFuzzyIsNull(object()->property("opacity").toDouble())) {
state |= QAccessible::Invisible;
state.invisible = true;
}

if ((role() == QAccessible::CheckBox || role() == QAccessible::RadioButton) && object()->property("checked").toBool()) {
state |= QAccessible::Checked;
state.checked = true;
}

if (role() == QAccessible::EditableText)
state |= QAccessible::Focusable;
state.focusable = true;

//qDebug() << "state?" << m_item->property("state").toString() << m_item->property("status").toString() << m_item->property("visible").toString();

Expand Down
2 changes: 1 addition & 1 deletion src/plugins/accessible/shared/qdeclarativeaccessible.h
Expand Up @@ -78,7 +78,7 @@ class QDeclarativeAccessible: public QAccessibleObject, public QAccessibleAction
virtual QRect viewRect() const = 0;
QFlags<QAccessible::RelationFlag> relationTo(const QAccessibleInterface*) const;
QAccessibleInterface *childAt(int, int) const;
QFlags<QAccessible::StateFlag> state() const;
QAccessible::State state() const;
QVariant invokeMethod(QAccessible::Method, const QVariantList &);

QStringList actionNames() const;
Expand Down
29 changes: 29 additions & 0 deletions src/quick/items/qquickaccessibleattached.cpp
Expand Up @@ -102,6 +102,35 @@ QT_BEGIN_NAMESPACE
Accessible.role: Accessible.Button
}
\endqml
Some roles have special semantics.
In order to implement check boxes for example a "checked" property is expected.
\table
\header
\o \bold {Role}
\o \bold {Expected property}
\o
\row
\o CheckBox
\o checked
\o The check state of the check box.
\row
\o RadioButton
\o checked
\o The selected state of the radio button.
\row
\o Button
\o checkable
\o Whether the button is checkable.
\row
\o Button
\o checked
\o Whether the button is checked (only if checkable is true).
\endtable
*/

QQuickAccessibleAttached::QQuickAccessibleAttached(QObject *parent)
Expand Down
@@ -0,0 +1,47 @@
import QtQuick 2.0

Item {
width: 400
height: 400

// button, not checkable
Rectangle {
y: 20
width: 100; height: 20
Accessible.role : Accessible.Button
}

// button, checkable, not checked
Rectangle {
y: 40
width: 100; height: 20
Accessible.role : Accessible.Button
property bool checkable: true
property bool checked: false
}

// button, checkable, checked
Rectangle {
y: 60
width: 100; height: 20
Accessible.role : Accessible.Button
property bool checkable: true
property bool checked: true
}

// check box, checked
Rectangle {
y: 80
width: 100; height: 20
Accessible.role : Accessible.CheckBox
property bool checked: true
}
// check box, not checked
Rectangle {
y: 100
width: 100; height: 20
Accessible.role : Accessible.CheckBox
property bool checked: false
}
}

Expand Up @@ -203,6 +203,7 @@ private slots:
void declarativeAttachedProperties();
void basicPropertiesTest();
void hitTest();
void checkableTest();
};

tst_QDeclarativeAccessibility::tst_QDeclarativeAccessibility()
Expand Down Expand Up @@ -287,48 +288,6 @@ QString eventName(const int ev)
}
}

static QString stateNames(int state)
{
QString stateString;
if (state == 0x00000000) stateString += " Normal";
if (state & 0x00000001) stateString += " Unavailable";
if (state & 0x00000002) stateString += " Selected";
if (state & 0x00000004) stateString += " Focused";
if (state & 0x00000008) stateString += " Pressed";
if (state & 0x00000010) stateString += " Checked";
if (state & 0x00000020) stateString += " Mixed";
if (state & 0x00000040) stateString += " ReadOnly";
if (state & 0x00000080) stateString += " HotTracked";
if (state & 0x00000100) stateString += " DefaultButton";
if (state & 0x00000200) stateString += " Expanded";
if (state & 0x00000400) stateString += " Collapsed";
if (state & 0x00000800) stateString += " Busy";
if (state & 0x00001000) stateString += " Floating";
if (state & 0x00002000) stateString += " Marqueed";
if (state & 0x00004000) stateString += " Animated";
if (state & 0x00008000) stateString += " Invisible";
if (state & 0x00010000) stateString += " Offscreen";
if (state & 0x00020000) stateString += " Sizeable";
if (state & 0x00040000) stateString += " Moveable";
if (state & 0x00080000) stateString += " SelfVoicing";
if (state & 0x00100000) stateString += " Focusable";
if (state & 0x00200000) stateString += " Selectable";
if (state & 0x00400000) stateString += " Linked";
if (state & 0x00800000) stateString += " Traversed";
if (state & 0x01000000) stateString += " MultiSelectable";
if (state & 0x02000000) stateString += " ExtSelectable";
if (state & 0x04000000) stateString += " AlertLow";
if (state & 0x08000000) stateString += " AlertMedium";
if (state & 0x10000000) stateString += " AlertHigh";
if (state & 0x20000000) stateString += " Protected";
if (state & 0x3fffffff) stateString += " Valid";

if (stateString.isEmpty())
stateString = "Unknown state " + QString::number(state);

return stateString;
}

void tst_QDeclarativeAccessibility::declarativeAttachedProperties()
{
{
Expand Down Expand Up @@ -492,6 +451,32 @@ void tst_QDeclarativeAccessibility::hitTest()

delete canvas;
}

void tst_QDeclarativeAccessibility::checkableTest()
{
QQuickView *canvas = new QQuickView();
canvas->setSource(testFileUrl("checkbuttons.qml"));
canvas->show();

QAI iface = QAI(QAccessible::queryAccessibleInterface(canvas));
QVERIFY(iface.data());
QAI root = QAI(iface->child(0));

QAI button1 = QAI(root->child(0));
QCOMPARE(button1->role(), QAccessible::Button);
QVERIFY(!(button1->state().checked));
QAI button2 = QAI(root->child(1));
QVERIFY(!(button2->state().checked));
QAI button3 = QAI(root->child(2));
QVERIFY(button3->state().checked);

QAI checkBox1 = QAI(root->child(3));
QCOMPARE(checkBox1->role(), QAccessible::CheckBox);
QVERIFY((checkBox1->state().checked));
QAI checkBox2 = QAI(root->child(4));
QVERIFY(!(checkBox2->state().checked));
}

QTEST_MAIN(tst_QDeclarativeAccessibility)

#include "tst_qdeclarativeaccessibility.moc"

0 comments on commit 1b4897f

Please sign in to comment.