Add parent and child functions to QAccessibleInterface.

Stop the mis-use of navigate to find the parent.
In order to make navigation straight forward
parent and child functions are now part of
QAccessibleInterface.
This allows navigating the hierarchy of
accessible objects without the 1-based indexes in the
navigate function which lead to confusion.

Eventually the support for Ancestor in navigate can be completely removed
and forwarded in the windows bridge if needed.

In addition default parameters for virtual children.
This will make the transition smooth since it allows to remove the integer
already.

Change-Id: I278287ce17161f9fa46797ac244676778c859576
Reviewed-on: http://codereview.qt-project.org/5024
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@nokia.com>
Reviewed-by: Jan-Arve Sæther <jan-arve.saether@nokia.com>
This commit is contained in:
Frederik Gladhorn 2011-09-15 21:41:54 +02:00 committed by Qt by Nokia
parent 3647a00d47
commit 76d0d19264
16 changed files with 624 additions and 641 deletions

View File

@ -481,6 +481,17 @@ QAbstractItemView::CursorAction QAccessibleItemRow::toCursorAction(
return QAbstractItemView::MoveRight; return QAbstractItemView::MoveRight;
} }
QAccessibleInterface *QAccessibleItemRow::parent() const
{
return new QAccessibleItemView(view->viewport());
}
QAccessibleInterface *QAccessibleItemRow::child(int index) const
{
// FIXME? port to IA2 table2.
return 0;
}
int QAccessibleItemRow::navigate(RelationFlag relation, int index, int QAccessibleItemRow::navigate(RelationFlag relation, int index,
QAccessibleInterface **iface) const QAccessibleInterface **iface) const
{ {
@ -489,19 +500,9 @@ int QAccessibleItemRow::navigate(RelationFlag relation, int index,
return -1; return -1;
switch (relation) { switch (relation) {
case Ancestor: { case Ancestor:
if (!index) *iface = parent();
return -1; return *iface ? 0 : -1;
QAccessibleItemView *ancestor = new QAccessibleItemView(view->viewport());
if (index == 1) {
*iface = ancestor;
return 0;
} else if (index > 1) {
int ret = ancestor->navigate(Ancestor, index - 1, iface);
delete ancestor;
return ret;
}
}
case Child: { case Child: {
if (!index) if (!index)
return -1; return -1;
@ -1487,10 +1488,14 @@ public:
QString text(Text, int) const { return qt_accStripAmp(m_parent->tabText(m_index)); } QString text(Text, int) const { return qt_accStripAmp(m_parent->tabText(m_index)); }
void setText(Text, int, const QString &) {} void setText(Text, int, const QString &) {}
QAccessibleInterface *parent() const {
return QAccessible::queryAccessibleInterface(m_parent);
}
QAccessibleInterface *child(int) const { return 0; }
int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const
{ {
if (relation == QAccessible::Ancestor && index == 1) { if (relation == QAccessible::Ancestor && index == 1) {
*iface = QAccessible::queryAccessibleInterface(m_parent); *iface = parent();
return 0; return 0;
} }
return -1; return -1;
@ -1842,6 +1847,7 @@ int QAccessibleComboBox::childAt(int x, int y) const
if (rect(i).contains(x, y)) if (rect(i).contains(x, y))
return i; return i;
} }
Q_ASSERT(0);
return 0; return 0;
} }

View File

@ -139,6 +139,8 @@ public:
Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const; Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const;
int childAt(int x, int y) const; int childAt(int x, int y) const;
QAccessibleInterface *parent() const;
QAccessibleInterface *child(int index) const;
int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const; int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const;
int userActionCount(int child) const; int userActionCount(int child) const;

View File

@ -359,9 +359,7 @@ QAccessible2::TableModelChange QAccessibleTable2::modelChange() const
QAccessible::Role QAccessibleTable2::role(int child) const QAccessible::Role QAccessibleTable2::role(int child) const
{ {
Q_ASSERT(child >= 0); Q_ASSERT(child == 0);
if (child > 0)
return QAccessible::Cell;
return m_role; return m_role;
} }
@ -386,6 +384,8 @@ int QAccessibleTable2::childAt(int x, int y) const
int QAccessibleTable2::childCount() const int QAccessibleTable2::childCount() const
{ {
if (!view->model())
return 0;
int vHeader = verticalHeader() ? 1 : 0; int vHeader = verticalHeader() ? 1 : 0;
int hHeader = horizontalHeader() ? 1 : 0; int hHeader = horizontalHeader() ? 1 : 0;
return (view->model()->rowCount()+hHeader) * (view->model()->columnCount()+vHeader); return (view->model()->rowCount()+hHeader) * (view->model()->columnCount()+vHeader);
@ -430,21 +430,31 @@ QRect QAccessibleTable2::rect(int child) const
return QRect(pos.x(), pos.y(), view->width(), view->height()); return QRect(pos.x(), pos.y(), view->width(), view->height());
} }
QAccessibleInterface *QAccessibleTable2::parent() const
{
if (view->parent()) {
return QAccessible::queryAccessibleInterface(view->parent());
}
return 0;
}
QAccessibleInterface *QAccessibleTable2::child(int index) const
{
// Fixme: get rid of the +1 madness
return childFromLogical(index + 1);
}
int QAccessibleTable2::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const int QAccessibleTable2::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const
{ {
*iface = 0; *iface = 0;
switch (relation) { switch (relation) {
case Ancestor: { case Ancestor: {
if (index == 1 && view->parent()) { *iface = parent();
*iface = QAccessible::queryAccessibleInterface(view->parent()); return *iface ? 0 : -1;
if (*iface)
return 0;
}
break;
} }
case QAccessible::Child: { case QAccessible::Child: {
Q_ASSERT(index > 0); Q_ASSERT(index > 0);
*iface = childFromLogical(index); *iface = child(index - 1);
if (*iface) { if (*iface) {
return 0; return 0;
} }
@ -806,14 +816,23 @@ bool QAccessibleTable2Cell::isValid() const
return m_index.isValid(); return m_index.isValid();
} }
QAccessibleInterface *QAccessibleTable2Cell::parent() const
{
if (m_role == QAccessible::TreeItem)
return new QAccessibleTree(view);
return new QAccessibleTable2(view);
}
QAccessibleInterface *QAccessibleTable2Cell::child(int) const
{
return 0;
}
int QAccessibleTable2Cell::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const int QAccessibleTable2Cell::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const
{ {
if (relation == Ancestor && index == 1) { if (relation == Ancestor && index == 1) {
if (m_role == QAccessible::TreeItem) { *iface = parent();
*iface = new QAccessibleTree(view);
} else {
*iface = new QAccessibleTable2(view);
}
return 0; return 0;
} }
@ -978,19 +997,28 @@ bool QAccessibleTable2HeaderCell::isValid() const
return true; return true;
} }
QAccessibleInterface *QAccessibleTable2HeaderCell::parent() const
{
if (false) {
#ifndef QT_NO_TREEVIEW
} else if (qobject_cast<const QTreeView*>(view)) {
return new QAccessibleTree(view);
#endif
} else {
return new QAccessibleTable2(view);
}
}
QAccessibleInterface *QAccessibleTable2HeaderCell::child(int) const
{
return 0;
}
int QAccessibleTable2HeaderCell::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const int QAccessibleTable2HeaderCell::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const
{ {
if (relation == QAccessible::Ancestor && index == 1) { if (relation == QAccessible::Ancestor && index == 1) {
if (false) { *iface = parent();
#ifndef QT_NO_TREEVIEW return *iface ? 0 : -1;
} else if (qobject_cast<const QTreeView*>(view)) {
*iface = new QAccessibleTree(view);
return 0;
#endif
} else {
*iface = new QAccessibleTable2(view);
return 0;
}
} }
*iface = 0; *iface = 0;
return -1; return -1;

View File

@ -76,6 +76,8 @@ public:
int childCount() const; int childCount() const;
int indexOfChild(const QAccessibleInterface *) const; int indexOfChild(const QAccessibleInterface *) const;
QAccessibleInterface *parent() const;
QAccessibleInterface *child(int index) const;
int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const; int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const;
Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const; Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const;
@ -193,6 +195,8 @@ public:
QString text(Text t, int child) const; QString text(Text t, int child) const;
void setText(Text t, int child, const QString &text); void setText(Text t, int child, const QString &text);
QAccessibleInterface *parent() const;
QAccessibleInterface *child(int) const;
int navigate(RelationFlag relation, int m_index, QAccessibleInterface **iface) const; int navigate(RelationFlag relation, int m_index, QAccessibleInterface **iface) const;
Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const; Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const;
@ -246,6 +250,8 @@ public:
QString text(Text t, int child) const; QString text(Text t, int child) const;
void setText(Text t, int child, const QString &text); void setText(Text t, int child, const QString &text);
QAccessibleInterface *parent() const;
QAccessibleInterface *child(int index) const;
int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const; int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const;
Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const; Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const;
@ -287,11 +293,17 @@ public:
QString text(Text, int) const { return QString(); } QString text(Text, int) const { return QString(); }
void setText(Text, int, const QString &) {} void setText(Text, int, const QString &) {}
int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const QAccessibleInterface *parent() const {
return QAccessible::queryAccessibleInterface(view);
}
QAccessibleInterface *child(int) const {
return 0;
}
int navigate(RelationFlag relation, int, QAccessibleInterface **iface) const
{ {
if (relation == QAccessible::Ancestor && index == 1) { if (relation == QAccessible::Ancestor) {
*iface = QAccessible::queryAccessibleInterface(view); *iface = parent();
return 0; return *iface ? 0 : -1;
} }
return -1; return -1;
} }

View File

@ -73,13 +73,8 @@ int QAccessibleMenu::childCount() const
QRect QAccessibleMenu::rect(int child) const QRect QAccessibleMenu::rect(int child) const
{ {
if (!child || child > childCount()) Q_ASSERT(child == 0);
return QAccessibleWidget::rect(child); return QAccessibleWidget::rect(child);
QRect r = menu()->actionGeometry(menu()->actions()[child - 1]);
QPoint tlp = menu()->mapToGlobal(QPoint(0,0));
return QRect(tlp.x() + r.x(), tlp.y() + r.y(), r.width(), r.height());
} }
int QAccessibleMenu::childAt(int x, int y) const int QAccessibleMenu::childAt(int x, int y) const
@ -92,79 +87,38 @@ int QAccessibleMenu::childAt(int x, int y) const
QString QAccessibleMenu::text(Text t, int child) const QString QAccessibleMenu::text(Text t, int child) const
{ {
Q_ASSERT(child == 0);
QString tx = QAccessibleWidget::text(t, child); QString tx = QAccessibleWidget::text(t, child);
if (tx.size()) if (tx.size())
return tx; return tx;
switch (t) { if (t == Name)
case Name: return menu()->windowTitle();
if (!child)
return menu()->windowTitle();
return qt_accStripAmp(menu()->actions().at(child-1)->text());
case Help:
return child ? menu()->actions().at(child-1)->whatsThis() : tx;
#ifndef QT_NO_SHORTCUT
case Accelerator:
return child ? static_cast<QString>(menu()->actions().at(child-1)->shortcut()) : tx;
#endif
default:
break;
}
return tx; return tx;
} }
QAccessible::Role QAccessibleMenu::role(int child) const QAccessible::Role QAccessibleMenu::role(int child) const
{ {
if (!child) Q_ASSERT(child == 0);
return PopupMenu; return PopupMenu;
QAction *action = menu()->actions()[child-1];
if (action && action->isSeparator())
return Separator;
return MenuItem;
} }
QAccessible::State QAccessibleMenu::state(int child) const QAccessible::State QAccessibleMenu::state(int child) const
{ {
Q_ASSERT(child == 0);
State s = QAccessibleWidget::state(child); State s = QAccessibleWidget::state(child);
if (!child)
return s;
QAction *action = menu()->actions()[child-1];
if (!action)
return s;
if (menu()->style()->styleHint(QStyle::SH_Menu_MouseTracking))
s |= HotTracked;
if (action->isSeparator() || !action->isEnabled())
s |= Unavailable;
if (action->isChecked())
s |= Checked;
if (menu()->activeAction() == action)
s |= Focused;
return s; return s;
} }
QString QAccessibleMenu::actionText(int action, QAccessible::Text text, int child) const QString QAccessibleMenu::actionText(int action, QAccessible::Text text, int child) const
{ {
if (action == QAccessible::DefaultAction && child && text == QAccessible::Name) { Q_ASSERT(child == 0);
QAction *a = menu()->actions().value(child-1, 0);
if (!a || a->isSeparator())
return QString();
if (a->menu()) {
if (a->menu()->isVisible())
return QMenu::tr("Close");
return QMenu::tr("Open");
}
return QMenu::tr("Execute");
}
return QAccessibleWidget::actionText(action, text, child); return QAccessibleWidget::actionText(action, text, child);
} }
bool QAccessibleMenu::doAction(int act, int child, const QVariantList &) bool QAccessibleMenu::doAction(int act, int child, const QVariantList &)
{ {
// Q_ASSERT(child == 0);
if (!child || act != QAccessible::DefaultAction) if (!child || act != QAccessible::DefaultAction)
return false; return false;
@ -179,52 +133,35 @@ bool QAccessibleMenu::doAction(int act, int child, const QVariantList &)
return true; return true;
} }
QAccessibleInterface *QAccessibleMenu::child(int index) const
{
if (index < childCount())
return new QAccessibleMenuItem(menu(), menu()->actions().at(index));
return 0;
}
QAccessibleInterface *QAccessibleMenu::parent() const
{
QWidget *parent = menu()->parentWidget();
if (qobject_cast<QMenu*>(parent) || qobject_cast<QMenuBar*>(parent)) {
return new QAccessibleMenuItem(parent, menu()->menuAction());
}
return QAccessibleWidget::parent();
}
int QAccessibleMenu::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const int QAccessibleMenu::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
{ {
int ret = -1; Q_ASSERT(entry >= 0);
if (entry < 0) {
*target = 0;
return ret;
}
if (relation == Self || entry == 0) {
*target = new QAccessibleMenu(menu());
return 0;
}
switch (relation) { switch (relation) {
case Child: case Child:
if (entry <= childCount()) { *target = child(entry - 1);
*target = new QAccessibleMenuItem(menu(), menu()->actions().at( entry - 1 )); return *target ? 0 : -1;
ret = 0; case Ancestor:
} *target = parent();
break; return *target ? 0 : -1;
case Ancestor: {
QAccessibleInterface *iface;
QWidget *parent = menu()->parentWidget();
if (qobject_cast<QMenu*>(parent) || qobject_cast<QMenuBar*>(parent)) {
iface = new QAccessibleMenuItem(parent, menu()->menuAction());
if (entry == 1) {
*target = iface;
ret = 0;
} else {
ret = iface->navigate(Ancestor, entry - 1, target);
delete iface;
}
} else {
return QAccessibleWidget::navigate(relation, entry, target);
}
break;}
default: default:
return QAccessibleWidget::navigate(relation, entry, target); return QAccessibleWidget::navigate(relation, entry, target);
} }
if (ret == -1)
*target = 0;
return ret;
} }
int QAccessibleMenu::indexOfChild( const QAccessibleInterface *child ) const int QAccessibleMenu::indexOfChild( const QAccessibleInterface *child ) const
@ -258,12 +195,8 @@ int QAccessibleMenuBar::childCount() const
QRect QAccessibleMenuBar::rect(int child) const QRect QAccessibleMenuBar::rect(int child) const
{ {
if (!child) Q_ASSERT(child == 0);
return QAccessibleWidget::rect(child); return QAccessibleWidget::rect(child);
QRect r = menuBar()->actionGeometry(menuBar()->actions()[child - 1]);
QPoint tlp = menuBar()->mapToGlobal(QPoint(0,0));
return QRect(tlp.x() + r.x(), tlp.y() + r.y(), r.width(), r.height());
} }
int QAccessibleMenuBar::childAt(int x, int y) const int QAccessibleMenuBar::childAt(int x, int y) const
@ -275,38 +208,23 @@ int QAccessibleMenuBar::childAt(int x, int y) const
return -1; return -1;
} }
int QAccessibleMenuBar::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const QAccessibleInterface *QAccessibleMenuBar::child(int index) const
{ {
int ret = -1; if (index < childCount())
if (entry < 0) { return new QAccessibleMenuItem(menuBar(), menuBar()->actions().at(index));
*target = 0; return 0;
return ret;
}
if (relation == Self || entry == 0) {
*target = new QAccessibleMenuBar(menuBar());
return 0;
}
switch (relation) {
case Child:
if (entry <= childCount()) {
*target = new QAccessibleMenuItem(menuBar(), menuBar()->actions().at( entry - 1 ));
ret = 0;
}
break;
default:
return QAccessibleWidget::navigate(relation, entry, target);
}
if (ret == -1)
*target = 0;
return ret;
} }
int QAccessibleMenuBar::indexOfChild( const QAccessibleInterface *child ) const int QAccessibleMenuBar::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
{
if (relation == Child) {
*target = child(entry - 1);
return *target ? 0 : -1;
}
return QAccessibleWidget::navigate(relation, entry, target);
}
int QAccessibleMenuBar::indexOfChild(const QAccessibleInterface *child) const
{ {
int index = -1; int index = -1;
Role r = child->role(0); Role r = child->role(0);
@ -320,87 +238,43 @@ int QAccessibleMenuBar::indexOfChild( const QAccessibleInterface *child ) const
QString QAccessibleMenuBar::text(Text t, int child) const QString QAccessibleMenuBar::text(Text t, int child) const
{ {
QString str; Q_ASSERT(child == 0);
return QAccessibleWidget::text(t, child);
if (child) {
if (QAction *action = menuBar()->actions().value(child - 1, 0)) {
switch (t) {
case Name:
return qt_accStripAmp(action->text());
case Accelerator:
str = qt_accHotKey(action->text());
break;
default:
break;
}
}
}
if (str.isEmpty())
str = QAccessibleWidget::text(t, child);
return str;
} }
QAccessible::Role QAccessibleMenuBar::role(int child) const QAccessible::Role QAccessibleMenuBar::role(int child) const
{ {
if (!child) Q_ASSERT(child == 0);
return MenuBar; return MenuBar;
QAction *action = menuBar()->actions()[child-1];
if (action && action->isSeparator())
return Separator;
return MenuItem;
} }
QAccessible::State QAccessibleMenuBar::state(int child) const QAccessible::State QAccessibleMenuBar::state(int child) const
{ {
Q_ASSERT(child == 0);
State s = QAccessibleWidget::state(child); State s = QAccessibleWidget::state(child);
if (!child)
return s;
QAction *action = menuBar()->actions().value(child-1, 0);
if (!action)
return s;
if (menuBar()->style()->styleHint(QStyle::SH_Menu_MouseTracking))
s |= HotTracked;
if (action->isSeparator() || !action->isEnabled())
s |= Unavailable;
if (menuBar()->activeAction() == action)
s |= Focused;
return s; return s;
} }
QString QAccessibleMenuBar::actionText(int action, QAccessible::Text text, int child) const QString QAccessibleMenuBar::actionText(int action, QAccessible::Text text, int child) const
{ {
if (action == QAccessible::DefaultAction && child && text == QAccessible::Name) { Q_ASSERT(child == 0);
QAction *a = menuBar()->actions().value(child-1, 0);
if (!a || a->isSeparator())
return QString();
if (a->menu()) {
if (a->menu()->isVisible())
return QMenu::tr("Close");
return QMenu::tr("Open");
}
return QMenu::tr("Execute");
}
return QAccessibleWidget::actionText(action, text, child); return QAccessibleWidget::actionText(action, text, child);
} }
bool QAccessibleMenuBar::doAction(int act, int child, const QVariantList &) bool QAccessibleMenuBar::doAction(int, int child, const QVariantList &)
{ {
if (act != !child) // Q_ASSERT(child == 0);
return false;
QAction *action = menuBar()->actions().value(child-1, 0); QAction *action = menuBar()->actions().value(child-1, 0);
if (!action || !action->isEnabled()) if (!action || !action->isEnabled())
return false; return false;
if (action->menu() && action->menu()->isVisible()) if (action->menu() && action->menu()->isVisible())
action->menu()->hide(); action->menu()->hide();
else else {
menuBar()->setActiveAction(action); menuBar()->setActiveAction(action);
}
return true; return true;
return false;
} }
#endif // QT_NO_MENUBAR #endif // QT_NO_MENUBAR
@ -427,32 +301,69 @@ int QAccessibleMenuItem::childCount() const
return m_action->menu() ? 1 : 0; return m_action->menu() ? 1 : 0;
} }
QString QAccessibleMenuItem::actionText(int action, Text text, int child ) const QString QAccessibleMenuItem::actionText(int action, Text text, int child) const
{ {
if (text == Name && child == 0) { Q_ASSERT(child == 0);
switch (action) { if (!m_action || m_action->isSeparator())
case Press: return QString();
case DefaultAction:
return QMenu::tr("Execute"); if (text == Name && ((action == Press) || (action == DefaultAction))) {
break; if (m_action->menu()) {
default: return QMenu::tr("Open");
break;
} }
return QMenu::tr("Execute");
} }
return QString(); return QString();
} }
//QAction *action = menuBar()->actions().value(child-1, 0);
//if (!action || !action->isEnabled())
// return false;
//if (action->menu() && action->menu()->isVisible())
// action->menu()->hide();
//else
// menuBar()->setActiveAction(action);
//return true;
bool QAccessibleMenuItem::doAction(int action, int child, const QVariantList & /*params = QVariantList()*/ ) bool QAccessibleMenuItem::doAction(int action, int child, const QVariantList & /*params = QVariantList()*/ )
{ {
if ((action == Press || action == DefaultAction) && child == 0) { Q_ASSERT(child == 0);
if ((action != Press) && (action != DefaultAction))
return false;
if (!m_action->isEnabled())
return false;
if (QMenuBar *bar = qobject_cast<QMenuBar*>(owner())) {
if (m_action->menu() && m_action->menu()->isVisible()) {
m_action->menu()->hide();
return true;
} else {
bar->setActiveAction(m_action);
return true;
}
return false;
} else if (QMenu *menu = qobject_cast<QMenu*>(owner())){
if (m_action->menu() && m_action->menu()->isVisible()) {
m_action->menu()->hide();
return true;
} else {
menu->setActiveAction(m_action);
return true;
}
} else {
// no menu
m_action->trigger(); m_action->trigger();
return true; return true;
} }
return false; return false;
} }
int QAccessibleMenuItem::indexOfChild( const QAccessibleInterface * child ) const int QAccessibleMenuItem::indexOfChild(const QAccessibleInterface * child) const
{ {
Q_ASSERT(child == 0);
if (child->role(0) == PopupMenu && child->object() == m_action->menu()) if (child->role(0) == PopupMenu && child->object() == m_action->menu())
return 1; return 1;
@ -464,6 +375,18 @@ bool QAccessibleMenuItem::isValid() const
return m_action ? true : false; return m_action ? true : false;
} }
QAccessibleInterface *QAccessibleMenuItem::parent() const
{
return QAccessible::queryAccessibleInterface(owner());
}
QAccessibleInterface *QAccessibleMenuItem::child(int index) const
{
if (index == 0 && action()->menu())
return new QAccessibleMenu(action()->menu());
return 0;
}
int QAccessibleMenuItem::navigate(RelationFlag relation, int entry, QAccessibleInterface ** target ) const int QAccessibleMenuItem::navigate(RelationFlag relation, int entry, QAccessibleInterface ** target ) const
{ {
int ret = -1; int ret = -1;
@ -472,32 +395,14 @@ int QAccessibleMenuItem::navigate(RelationFlag relation, int entry, QAccessibleI
return ret; return ret;
} }
if (relation == Self || entry == 0) {
*target = new QAccessibleMenuItem(owner(), action());
return 0;
}
switch (relation) { switch (relation) {
case Child: case Child:
if (entry <= childCount()) { *target = child(entry - 1);
*target = new QAccessibleMenu(action()->menu()); ret = *target ? 0 : -1;
ret = 0;
}
break; break;
case Ancestor:
case Ancestor:{ *target = parent();
QWidget *parent = owner(); return 0;
QAccessibleInterface *ancestor = parent ? QAccessible::queryAccessibleInterface(parent) : 0;
if (ancestor) {
if (entry == 1) {
*target = ancestor;
ret = 0;
} else {
ret = ancestor->navigate(Ancestor, entry - 1, target);
delete ancestor;
}
}
break;}
case Up: case Up:
case Down:{ case Down:{
QAccessibleInterface *parent = 0; QAccessibleInterface *parent = 0;
@ -533,36 +438,29 @@ QObject *QAccessibleMenuItem::object() const
return m_action; return m_action;
} }
QRect QAccessibleMenuItem::rect (int child ) const QRect QAccessibleMenuItem::rect(int child) const
{ {
Q_ASSERT(child == 0);
QRect rect; QRect rect;
if (child == 0) { QWidget *own = owner();
QWidget *own = owner();
#ifndef QT_NO_MENUBAR #ifndef QT_NO_MENUBAR
if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) { if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
rect = menuBar->actionGeometry(m_action); rect = menuBar->actionGeometry(m_action);
QPoint globalPos = menuBar->mapToGlobal(QPoint(0,0)); QPoint globalPos = menuBar->mapToGlobal(QPoint(0,0));
rect = rect.translated(globalPos); rect = rect.translated(globalPos);
} else } else
#endif // QT_NO_MENUBAR #endif // QT_NO_MENUBAR
if (QMenu *menu = qobject_cast<QMenu*>(own)) { if (QMenu *menu = qobject_cast<QMenu*>(own)) {
rect = menu->actionGeometry(m_action); rect = menu->actionGeometry(m_action);
QPoint globalPos = menu->mapToGlobal(QPoint(0,0)); QPoint globalPos = menu->mapToGlobal(QPoint(0,0));
rect = rect.translated(globalPos); rect = rect.translated(globalPos);
}
} else if (child == 1) {
QMenu *menu = m_action->menu();
if (menu) {
rect = menu->rect();
QPoint globalPos = menu->mapToGlobal(QPoint(0,0));
rect = rect.translated(globalPos);
}
} }
return rect; return rect;
} }
QAccessible::Relation QAccessibleMenuItem::relationTo ( int child, const QAccessibleInterface * other, int otherChild ) const QAccessible::Relation QAccessibleMenuItem::relationTo ( int child, const QAccessibleInterface * other, int otherChild ) const
{ {
Q_ASSERT(child == 0);
if (other->object() == owner()) { if (other->object() == owner()) {
return Child; return Child;
} }
@ -573,81 +471,68 @@ QAccessible::Relation QAccessibleMenuItem::relationTo ( int child, const QAccess
return Unrelated; return Unrelated;
} }
QAccessible::Role QAccessibleMenuItem::role(int /*child*/ ) const QAccessible::Role QAccessibleMenuItem::role(int child) const
{ {
return m_action->isSeparator() ? Separator :MenuItem; Q_ASSERT(child == 0);
// if (m_action->menu())
// return PopupMenu;
return m_action->isSeparator() ? Separator : MenuItem;
} }
void QAccessibleMenuItem::setText ( Text /*t*/, int /*child*/, const QString & /*text */) void QAccessibleMenuItem::setText ( Text /*t*/, int /*child*/, const QString & /*text */)
{ {
} }
QAccessible::State QAccessibleMenuItem::state(int child ) const QAccessible::State QAccessibleMenuItem::state(int child) const
{ {
QAccessible::State s = Unavailable; Q_ASSERT(child == 0);
QAccessible::State s = Normal;
QWidget *own = owner();
if (child == 0) { if (own->testAttribute(Qt::WA_WState_Visible) == false || m_action->isVisible() == false) {
s = Normal; s |= Invisible;
QWidget *own = owner();
if (own->testAttribute(Qt::WA_WState_Visible) == false || m_action->isVisible() == false) {
s |= Invisible;
}
if (QMenu *menu = qobject_cast<QMenu*>(own)) {
if (menu->activeAction() == m_action)
s |= Focused;
#ifndef QT_NO_MENUBAR
} else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
if (menuBar->activeAction() == m_action)
s |= Focused;
#endif
}
if (own->style()->styleHint(QStyle::SH_Menu_MouseTracking))
s |= HotTracked;
if (m_action->isSeparator() || !m_action->isEnabled())
s |= Unavailable;
if (m_action->isChecked())
s |= Checked;
} else if (child == 1) {
QMenu *menu = m_action->menu();
if (menu) {
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(menu);
s = iface->state(0);
delete iface;
}
} }
if (QMenu *menu = qobject_cast<QMenu*>(own)) {
if (menu->activeAction() == m_action)
s |= Focused;
#ifndef QT_NO_MENUBAR
} else if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
if (menuBar->activeAction() == m_action)
s |= Focused;
#endif
}
if (own->style()->styleHint(QStyle::SH_Menu_MouseTracking))
s |= HotTracked;
if (m_action->isSeparator() || !m_action->isEnabled())
s |= Unavailable;
if (m_action->isChecked())
s |= Checked;
return s; return s;
} }
QString QAccessibleMenuItem::text ( Text t, int child ) const QString QAccessibleMenuItem::text ( Text t, int child ) const
{ {
Q_ASSERT(child == 0);
QString str; QString str;
switch (t) { switch (t) {
case Name: case Name:
if (child == 0) { str = m_action->text();
str = m_action->text();
} else if (child == 1) {
QMenu *m = m_action->menu();
if (m)
str = m->title();
}
str = qt_accStripAmp(str); str = qt_accStripAmp(str);
break; break;
case Accelerator: case Accelerator: {
if (child == 0) {
#ifndef QT_NO_SHORTCUT #ifndef QT_NO_SHORTCUT
QKeySequence key = m_action->shortcut(); QKeySequence key = m_action->shortcut();
if (!key.isEmpty()) { if (!key.isEmpty()) {
str = key.toString(); str = key.toString();
} else } else
#endif #endif
{ {
str = qt_accHotKey(m_action->text()); str = qt_accHotKey(m_action->text());
}
} }
break; break;
}
default: default:
break; break;
} }
@ -659,7 +544,6 @@ int QAccessibleMenuItem::userActionCount ( int /*child*/ ) const
return 0; return 0;
} }
QAction *QAccessibleMenuItem::action() const QAction *QAccessibleMenuItem::action() const
{ {
return m_action; return m_action;

View File

@ -65,6 +65,8 @@ public:
QString text(Text t, int child) const; QString text(Text t, int child) const;
Role role(int child) const; Role role(int child) const;
State state(int child) const; State state(int child) const;
QAccessibleInterface *child(int index) const;
QAccessibleInterface *parent() const;
int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const; int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const;
int indexOfChild( const QAccessibleInterface *child ) const; int indexOfChild( const QAccessibleInterface *child ) const;
@ -81,6 +83,7 @@ class QAccessibleMenuBar : public QAccessibleWidget
public: public:
explicit QAccessibleMenuBar(QWidget *w); explicit QAccessibleMenuBar(QWidget *w);
QAccessibleInterface *child(int index) const;
int childCount() const; int childCount() const;
int childAt(int x, int y) const; int childAt(int x, int y) const;
@ -113,6 +116,9 @@ public:
virtual bool doAction ( int action, int child, const QVariantList & params = QVariantList() ); virtual bool doAction ( int action, int child, const QVariantList & params = QVariantList() );
virtual int indexOfChild ( const QAccessibleInterface * child ) const; virtual int indexOfChild ( const QAccessibleInterface * child ) const;
virtual bool isValid () const; virtual bool isValid () const;
QAccessibleInterface *parent() const;
QAccessibleInterface *child(int index) const;
virtual int navigate ( RelationFlag relation, int entry, QAccessibleInterface ** target ) const; virtual int navigate ( RelationFlag relation, int entry, QAccessibleInterface ** target ) const;
virtual QObject * object () const; virtual QObject * object () const;
virtual QRect rect ( int child ) const; virtual QRect rect ( int child ) const;

View File

@ -414,22 +414,22 @@ int QAccessibleStackedWidget::indexOfChild(const QAccessibleInterface *child) co
return -1; return -1;
} }
QAccessibleInterface *QAccessibleStackedWidget::child(int index) const
{
if (index < 0 || index >= stackedWidget()->count())
return 0;
return QAccessible::queryAccessibleInterface(stackedWidget()->widget(index));
}
int QAccessibleStackedWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const int QAccessibleStackedWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
{ {
*target = 0;
QObject *targetObject = 0;
switch (relation) { switch (relation) {
case Child: case Child:
if (entry < 1 || entry > stackedWidget()->count()) *target = child(entry - 1);
return -1; return *target ? 0 : -1;
targetObject = stackedWidget()->widget(entry-1);
break;
default: default:
return QAccessibleWidget::navigate(relation, entry, target); return QAccessibleWidget::navigate(relation, entry, target);
} }
*target = QAccessible::queryAccessibleInterface(targetObject);
return *target ? 0 : -1;
} }
QStackedWidget *QAccessibleStackedWidget::stackedWidget() const QStackedWidget *QAccessibleStackedWidget::stackedWidget() const
@ -1069,15 +1069,37 @@ QAccessibleTitleBar::QAccessibleTitleBar(QDockWidget *widget)
} }
QAccessibleInterface *QAccessibleTitleBar::parent() const
{
return new QAccessibleDockWidget(dockWidget());
}
QAccessibleInterface *QAccessibleTitleBar::child(int index) const
{
if (index >= 0) {
QDockWidgetLayout *layout = dockWidgetLayout();
int role;
int currentIndex = 0;
for (role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) {
QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role);
if (!w || !w->isVisible())
continue;
if (currentIndex == index)
return QAccessible::queryAccessibleInterface(w);
++currentIndex;
}
}
return 0;
}
int QAccessibleTitleBar::navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const int QAccessibleTitleBar::navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const
{ {
if (entry == 0 || relation == Self) {
*iface = new QAccessibleTitleBar(dockWidget());
return 0;
}
switch (relation) { switch (relation) {
case Child: case Child:
*iface = child(entry - 1);
return *iface ? 0 : -1;
case FocusChild: case FocusChild:
// ###
if (entry >= 1) { if (entry >= 1) {
QDockWidgetLayout *layout = dockWidgetLayout(); QDockWidgetLayout *layout = dockWidgetLayout();
int index = 1; int index = 1;
@ -1095,18 +1117,8 @@ int QAccessibleTitleBar::navigate(RelationFlag relation, int entry, QAccessibleI
} }
break; break;
case Ancestor: case Ancestor:
{ *iface = parent();
QAccessibleDockWidget *target = new QAccessibleDockWidget(dockWidget()); return iface ? 0 : -1;
int index;
if (entry == 1) {
*iface = target;
return 0;
}
index = target->navigate(Ancestor, entry - 1, iface);
delete target;
return index;
break;}
case Sibling: case Sibling:
return navigate(Child, entry, iface); return navigate(Child, entry, iface);
break; break;

View File

@ -132,6 +132,7 @@ public:
int childAt(int x, int y) const; int childAt(int x, int y) const;
int childCount() const; int childCount() const;
int indexOfChild(const QAccessibleInterface *child) const; int indexOfChild(const QAccessibleInterface *child) const;
QAccessibleInterface *child(int index) const;
int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const; int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const;
protected: protected:
@ -273,6 +274,8 @@ public:
QString actionText(int action, Text t, int child) const; QString actionText(int action, Text t, int child) const;
bool doAction(int action, int child, const QVariantList& params = QVariantList()); bool doAction(int action, int child, const QVariantList& params = QVariantList());
int userActionCount ( int child) const; int userActionCount ( int child) const;
QAccessibleInterface *parent() const;
QAccessibleInterface *child(int index) const;
int navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const; int navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const;
int indexOfChild(const QAccessibleInterface *child) const; int indexOfChild(const QAccessibleInterface *child) const;
int childCount() const; int childCount() const;

View File

@ -106,8 +106,7 @@ QAbstractButton *QAccessibleButton::button() const
/*! \reimp */ /*! \reimp */
QString QAccessibleButton::actionText(int action, Text text, int child) const QString QAccessibleButton::actionText(int action, Text text, int child) const
{ {
if (child) Q_ASSERT(child == 0);
return QString();
if (text == Name) switch (action) { if (text == Name) switch (action) {
case Press: case Press:
@ -117,7 +116,7 @@ QString QAccessibleButton::actionText(int action, Text text, int child) const
return QPushButton::tr("Open"); return QPushButton::tr("Open");
case CheckBox: case CheckBox:
{ {
if (state(child) & Checked) if (state(0) & Checked)
return QCheckBox::tr("Uncheck"); return QCheckBox::tr("Uncheck");
QCheckBox *cb = qobject_cast<QCheckBox*>(object()); QCheckBox *cb = qobject_cast<QCheckBox*>(object());
if (!cb || !cb->isTristate() || cb->checkState() == Qt::PartiallyChecked) if (!cb || !cb->isTristate() || cb->checkState() == Qt::PartiallyChecked)
@ -138,7 +137,8 @@ QString QAccessibleButton::actionText(int action, Text text, int child) const
/*! \reimp */ /*! \reimp */
bool QAccessibleButton::doAction(int action, int child, const QVariantList &params) bool QAccessibleButton::doAction(int action, int child, const QVariantList &params)
{ {
if (child || !widget()->isEnabled()) Q_ASSERT(child == 0);
if (!widget()->isEnabled())
return false; return false;
switch (action) { switch (action) {
@ -161,6 +161,7 @@ bool QAccessibleButton::doAction(int action, int child, const QVariantList &para
/*! \reimp */ /*! \reimp */
QString QAccessibleButton::text(Text t, int child) const QString QAccessibleButton::text(Text t, int child) const
{ {
Q_ASSERT(child == 0);
QString str; QString str;
switch (t) { switch (t) {
case Accelerator: case Accelerator:
@ -190,7 +191,8 @@ QString QAccessibleButton::text(Text t, int child) const
/*! \reimp */ /*! \reimp */
QAccessible::State QAccessibleButton::state(int child) const QAccessible::State QAccessibleButton::state(int child) const
{ {
State state = QAccessibleWidget::state(child); Q_ASSERT(child == 0);
State state = QAccessibleWidget::state(0);
QAbstractButton *b = button(); QAbstractButton *b = button();
QCheckBox *cb = qobject_cast<QCheckBox *>(b); QCheckBox *cb = qobject_cast<QCheckBox *>(b);
@ -336,11 +338,16 @@ bool QAccessibleToolButton::isSplitButton() const
/*! \reimp */ /*! \reimp */
QAccessible::Role QAccessibleToolButton::role(int child) const QAccessible::Role QAccessibleToolButton::role(int child) const
{ {
if (isSplitButton()) switch(child) { Q_ASSERT(child == 0);
case ButtonExecute:
return PushButton; // FIXME
case ButtonDropMenu: if (isSplitButton()) {
return ButtonMenu; switch (child) {
case ButtonExecute:
return PushButton;
case ButtonDropMenu:
return ButtonMenu;
}
} }
return QAccessibleButton::role(child); return QAccessibleButton::role(child);
} }
@ -348,6 +355,7 @@ QAccessible::Role QAccessibleToolButton::role(int child) const
/*! \reimp */ /*! \reimp */
QAccessible::State QAccessibleToolButton::state(int child) const QAccessible::State QAccessibleToolButton::state(int child) const
{ {
Q_ASSERT(child == 0);
QAccessible::State st = QAccessibleButton::state(child); QAccessible::State st = QAccessibleButton::state(child);
if (toolButton()->autoRaise()) if (toolButton()->autoRaise())
st |= HotTracked; st |= HotTracked;
@ -374,22 +382,24 @@ int QAccessibleToolButton::childCount() const
*/ */
QRect QAccessibleToolButton::rect(int child) const QRect QAccessibleToolButton::rect(int child) const
{ {
Q_ASSERT(child == 0);
if (!toolButton()->isVisible()) if (!toolButton()->isVisible())
return QRect(); return QRect();
if (!child)
return QAccessibleButton::rect(child);
QStyleOptionToolButton opt; return QAccessibleButton::rect(child);
opt.init(widget());
QRect subrect = widget()->style()->subControlRect(QStyle::CC_ToolButton, &opt,
QStyle::SC_ToolButtonMenu, toolButton());
if (child == ButtonExecute) // FIXME: sub buttons when SplitButton
subrect = QRect(0, 0, subrect.x(), widget()->height()); // QStyleOptionToolButton opt;
// opt.init(widget());
// QRect subrect = widget()->style()->subControlRect(QStyle::CC_ToolButton, &opt,
// QStyle::SC_ToolButtonMenu, toolButton());
QPoint ntl = widget()->mapToGlobal(subrect.topLeft()); // if (child == ButtonExecute)
subrect.moveTopLeft(ntl); // subrect = QRect(0, 0, subrect.x(), widget()->height());
return subrect;
// QPoint ntl = widget()->mapToGlobal(subrect.topLeft());
// subrect.moveTopLeft(ntl);
// return subrect;
} }
/*! /*!
@ -400,6 +410,7 @@ QRect QAccessibleToolButton::rect(int child) const
*/ */
QString QAccessibleToolButton::text(Text t, int child) const QString QAccessibleToolButton::text(Text t, int child) const
{ {
Q_ASSERT(child == 0);
QString str; QString str;
switch (t) { switch (t) {
case Name: case Name:
@ -423,6 +434,7 @@ QString QAccessibleToolButton::text(Text t, int child) const
*/ */
int QAccessibleToolButton::actionCount(int child) const int QAccessibleToolButton::actionCount(int child) const
{ {
Q_ASSERT(child == 0);
// each subelement has one action // each subelement has one action
if (child) if (child)
return isSplitButton() ? 1 : 0; return isSplitButton() ? 1 : 0;
@ -445,6 +457,7 @@ int QAccessibleToolButton::actionCount(int child) const
*/ */
QString QAccessibleToolButton::actionText(int action, Text text, int child) const QString QAccessibleToolButton::actionText(int action, Text text, int child) const
{ {
Q_ASSERT(child == 0);
if (text == Name) switch(child) { if (text == Name) switch(child) {
case ButtonExecute: case ButtonExecute:
return QToolButton::tr("Press"); return QToolButton::tr("Press");
@ -472,6 +485,7 @@ QString QAccessibleToolButton::actionText(int action, Text text, int child) cons
*/ */
bool QAccessibleToolButton::doAction(int action, int child, const QVariantList &params) bool QAccessibleToolButton::doAction(int action, int child, const QVariantList &params)
{ {
Q_ASSERT(child == 0);
if (!widget()->isEnabled()) if (!widget()->isEnabled())
return false; return false;
if (action == 1 || child == ButtonDropMenu) { if (action == 1 || child == ButtonDropMenu) {
@ -507,6 +521,7 @@ QAccessibleDisplay::QAccessibleDisplay(QWidget *w, Role role)
/*! \reimp */ /*! \reimp */
QAccessible::Role QAccessibleDisplay::role(int child) const QAccessible::Role QAccessibleDisplay::role(int child) const
{ {
Q_ASSERT(child == 0);
QLabel *l = qobject_cast<QLabel*>(object()); QLabel *l = qobject_cast<QLabel*>(object());
if (l) { if (l) {
if (l->pixmap()) if (l->pixmap())
@ -530,6 +545,7 @@ QAccessible::Role QAccessibleDisplay::role(int child) const
/*! \reimp */ /*! \reimp */
QString QAccessibleDisplay::text(Text t, int child) const QString QAccessibleDisplay::text(Text t, int child) const
{ {
Q_ASSERT(child == 0);
QString str; QString str;
switch (t) { switch (t) {
case Name: case Name:
@ -570,6 +586,7 @@ QString QAccessibleDisplay::text(Text t, int child) const
QAccessible::Relation QAccessibleDisplay::relationTo(int child, const QAccessibleInterface *other, QAccessible::Relation QAccessibleDisplay::relationTo(int child, const QAccessibleInterface *other,
int otherChild) const int otherChild) const
{ {
Q_ASSERT(child == 0);
Relation relation = QAccessibleWidget::relationTo(child, other, otherChild); Relation relation = QAccessibleWidget::relationTo(child, other, otherChild);
if (child || otherChild) if (child || otherChild)
return relation; return relation;
@ -689,6 +706,7 @@ QLineEdit *QAccessibleLineEdit::lineEdit() const
/*! \reimp */ /*! \reimp */
QString QAccessibleLineEdit::text(Text t, int child) const QString QAccessibleLineEdit::text(Text t, int child) const
{ {
Q_ASSERT(child == 0);
QString str; QString str;
switch (t) { switch (t) {
case Value: case Value:
@ -723,6 +741,7 @@ void QAccessibleLineEdit::setText(Text t, int control, const QString &text)
/*! \reimp */ /*! \reimp */
QAccessible::State QAccessibleLineEdit::state(int child) const QAccessible::State QAccessibleLineEdit::state(int child) const
{ {
Q_ASSERT(child == 0);
State state = QAccessibleWidget::state(child); State state = QAccessibleWidget::state(child);
QLineEdit *l = lineEdit(); QLineEdit *l = lineEdit();
@ -744,8 +763,7 @@ QAccessible::State QAccessibleLineEdit::state(int child) const
QVariant QAccessibleLineEdit::invokeMethod(QAccessible::Method method, int child, QVariant QAccessibleLineEdit::invokeMethod(QAccessible::Method method, int child,
const QVariantList &params) const QVariantList &params)
{ {
if (child) Q_ASSERT(child == 0);
return QVariant();
switch (method) { switch (method) {
case ListSupportedMethods: { case ListSupportedMethods: {

View File

@ -868,6 +868,27 @@ QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > QAccessibleInterfa
\sa rect() \sa rect()
*/ */
/*!
\fn QAccessibleInterface *parent() const
Returns the QAccessibleInterface of the parent in the accessible object hierarchy.
Returns 0 if no parent exists (e.g. for the top level application object).
\sa child()
*/
/*!
\fn QAccessibleInterface *child(int index) const
Returns the accessible child with index \a index.
0-based index. The number of children of an object can be checked with childCount.
Returns 0 when asking for an invalid child (e.g. when the child became invalid in the meantime).
\sa childCount(), parent()
*/
/*! /*!
\fn int QAccessibleInterface::navigate(RelationFlag relation, int entry, QAccessibleInterface \fn int QAccessibleInterface::navigate(RelationFlag relation, int entry, QAccessibleInterface
**target) const **target) const
@ -909,7 +930,7 @@ QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > QAccessibleInterfa
All objects support navigation. All objects support navigation.
\sa relationTo(), childCount() \sa relationTo(), childCount(), parent(), child()
*/ */
/*! /*!

View File

@ -382,19 +382,21 @@ public:
virtual int childAt(int x, int y) const = 0; virtual int childAt(int x, int y) const = 0;
// navigation // navigation
virtual QAccessibleInterface *parent() const = 0;
virtual QAccessibleInterface *child(int index) const = 0;
virtual int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const = 0; virtual int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const = 0;
// properties and state // properties and state
virtual QString text(Text t, int child) const = 0; virtual QString text(Text t, int child = 0) const = 0;
virtual void setText(Text t, int child, const QString &text) = 0; virtual void setText(Text t, int child, const QString &text) = 0;
virtual QRect rect(int child) const = 0; virtual QRect rect(int child = 0) const = 0;
virtual Role role(int child) const = 0; virtual Role role(int child = 0) const = 0;
virtual State state(int child) const = 0; virtual State state(int child = 0) const = 0;
// action // action
virtual int userActionCount(int child) const = 0; virtual int userActionCount(int child = 0) const = 0;
virtual QString actionText(int action, Text t, int child) const = 0; virtual QString actionText(int action, Text t, int child = 0) const = 0;
virtual bool doAction(int action, int child, const QVariantList &params = QVariantList()) = 0; virtual bool doAction(int action, int child = 0, const QVariantList &params = QVariantList()) = 0;
virtual QVariant invokeMethod(Method method, int child = 0, virtual QVariant invokeMethod(Method method, int child = 0,
const QVariantList &params = QVariantList()); const QVariantList &params = QVariantList());

View File

@ -284,6 +284,20 @@ QAccessible::Relation QAccessibleApplication::relationTo(int child, const
return Unrelated; return Unrelated;
} }
QAccessibleInterface *QAccessibleApplication::parent() const
{
return 0;
}
QAccessibleInterface *QAccessibleApplication::child(int index) const
{
Q_ASSERT(index >= 0);
const QWidgetList tlw(topLevelWidgets());
if (index >= 0 && index < tlw.count())
return QAccessible::queryAccessibleInterface(tlw.at(index));
return 0;
}
/*! \reimp */ /*! \reimp */
int QAccessibleApplication::navigate(RelationFlag relation, int entry, int QAccessibleApplication::navigate(RelationFlag relation, int entry,
QAccessibleInterface **target) const QAccessibleInterface **target) const

View File

@ -91,7 +91,9 @@ public:
Relation relationTo(int, const QAccessibleInterface *, int) const; Relation relationTo(int, const QAccessibleInterface *, int) const;
// navigation // navigation
QAccessibleInterface *parent() const;
int childAt(int x, int y) const; int childAt(int x, int y) const;
QAccessibleInterface *child(int index) const;
int navigate(RelationFlag, int, QAccessibleInterface **) const; int navigate(RelationFlag, int, QAccessibleInterface **) const;
// properties and state // properties and state

View File

@ -447,6 +447,22 @@ QAccessible::Relation QAccessibleWidget::relationTo(int child,
return relation; return relation;
} }
QAccessibleInterface *QAccessibleWidget::parent() const
{
QObject *parentWidget= widget()->parentWidget();
if (!parentWidget)
parentWidget = qApp;
return QAccessible::queryAccessibleInterface(parentWidget);
}
QAccessibleInterface *QAccessibleWidget::child(int index) const
{
QWidgetList childList = childWidgets(widget());
if (index >= 0 && index < childList.size())
return QAccessible::queryAccessibleInterface(childList.at(index));
return 0;
}
/*! \reimp */ /*! \reimp */
int QAccessibleWidget::navigate(RelationFlag relation, int entry, int QAccessibleWidget::navigate(RelationFlag relation, int entry,
QAccessibleInterface **target) const QAccessibleInterface **target) const
@ -457,40 +473,19 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry,
*target = 0; *target = 0;
QObject *targetObject = 0; QObject *targetObject = 0;
QWidgetList childList = childWidgets(widget());
bool complexWidget = childList.size() < childCount();
switch (relation) { switch (relation) {
// Hierarchical // Hierarchical
case Self: case Self:
targetObject = object(); targetObject = object();
break; break;
case Child: case Child:
if (complexWidget) { qWarning() << "QAccessibleWidget::navigate is deprecated for QAccessible::Child in:" << object()->metaObject()->className();
if (entry > 0 && entry <= childList.size()) { *target = child(entry - 1);
targetObject = childList.at(entry - 1); return *target ? 0 : -1;
break;
} else if (entry > childList.size() && entry <= childCount()) {
return entry;
}
return -1;
}else {
if (entry > 0 && childList.size() >= entry)
targetObject = childList.at(entry - 1);
}
break;
case Ancestor: case Ancestor:
{ qWarning() << "QAccessibleWidget::navigate is deprecated for QAccessible::Ancestor in:" << object()->metaObject()->className();
if (entry <= 0) *target = parent();
return -1; return *target ? 0 : -1;
targetObject = widget()->parentWidget();
int i;
for (i = entry; i > 1 && targetObject; --i)
targetObject = targetObject->parent();
if (!targetObject && i == 1)
targetObject = qApp;
}
break;
case Sibling: case Sibling:
{ {
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(parentObject()); QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(parentObject());
@ -506,111 +501,92 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry,
// Geometrical // Geometrical
case QAccessible::Left: case QAccessible::Left:
if (complexWidget && entry) {
if (entry < 2 || widget()->height() > widget()->width() + 20) // looks vertical
return -1;
return entry - 1;
}
// fall through // fall through
case QAccessible::Right: case QAccessible::Right:
if (complexWidget && entry) {
if (entry >= childCount() || widget()->height() > widget()->width() + 20) // looks vertical
return -1;
return entry + 1;
}
// fall through // fall through
case QAccessible::Up: case QAccessible::Up:
if (complexWidget && entry) {
if (entry < 2 || widget()->width() > widget()->height() + 20) // looks horizontal
return - 1;
return entry - 1;
}
// fall through // fall through
case QAccessible::Down: case QAccessible::Down:
if (complexWidget && entry) { {
if (entry >= childCount() || widget()->width() > widget()->height() + 20) // looks horizontal QAccessibleInterface *pIface = parent();
return - 1; if (!pIface)
return entry + 1; return -1;
} else {
QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject());
if (!pIface)
return -1;
QRect startg = rect(0); QRect startg = rect(0);
QPoint startc = startg.center(); QPoint startc = startg.center();
QAccessibleInterface *candidate = 0; QAccessibleInterface *candidate = 0;
int mindist = 100000; int mindist = 100000;
int sibCount = pIface->childCount(); int sibCount = pIface->childCount();
for (int i = 0; i < sibCount; ++i) { for (int i = 0; i < sibCount; ++i) {
QAccessibleInterface *sibling = 0; QAccessibleInterface *sibling = 0;
pIface->navigate(Child, i+1, &sibling); sibling = pIface->child(i);
Q_ASSERT(sibling); Q_ASSERT(sibling);
if ((relationTo(0, sibling, 0) & Self) || (sibling->state(0) & QAccessible::Invisible)) { if ((relationTo(0, sibling, 0) & Self) || (sibling->state(0) & QAccessible::Invisible)) {
//ignore ourself and invisible siblings //ignore ourself and invisible siblings
delete sibling;
continue;
}
QRect sibg = sibling->rect(0);
QPoint sibc = sibg.center();
QPoint sibp;
QPoint startp;
QPoint distp;
switch (relation) {
case QAccessible::Left:
startp = QPoint(startg.left(), startg.top() + startg.height() / 2);
sibp = QPoint(sibg.right(), sibg.top() + sibg.height() / 2);
if (QPoint(sibc - startc).x() >= 0) {
delete sibling; delete sibling;
continue; continue;
} }
distp = sibp - startp;
QRect sibg = sibling->rect(0); break;
QPoint sibc = sibg.center(); case QAccessible::Right:
QPoint sibp; startp = QPoint(startg.right(), startg.top() + startg.height() / 2);
QPoint startp; sibp = QPoint(sibg.left(), sibg.top() + sibg.height() / 2);
QPoint distp; if (QPoint(sibc - startc).x() <= 0) {
switch (relation) {
case QAccessible::Left:
startp = QPoint(startg.left(), startg.top() + startg.height() / 2);
sibp = QPoint(sibg.right(), sibg.top() + sibg.height() / 2);
if (QPoint(sibc - startc).x() >= 0) {
delete sibling;
continue;
}
distp = sibp - startp;
break;
case QAccessible::Right:
startp = QPoint(startg.right(), startg.top() + startg.height() / 2);
sibp = QPoint(sibg.left(), sibg.top() + sibg.height() / 2);
if (QPoint(sibc - startc).x() <= 0) {
delete sibling;
continue;
}
distp = sibp - startp;
break;
case QAccessible::Up:
startp = QPoint(startg.left() + startg.width() / 2, startg.top());
sibp = QPoint(sibg.left() + sibg.width() / 2, sibg.bottom());
if (QPoint(sibc - startc).y() >= 0) {
delete sibling;
continue;
}
distp = sibp - startp;
break;
case QAccessible::Down:
startp = QPoint(startg.left() + startg.width() / 2, startg.bottom());
sibp = QPoint(sibg.left() + sibg.width() / 2, sibg.top());
if (QPoint(sibc - startc).y() <= 0) {
delete sibling;
continue;
}
distp = sibp - startp;
break;
default:
break;
}
int dist = (int)qSqrt((qreal)distp.x() * distp.x() + distp.y() * distp.y());
if (dist < mindist) {
delete candidate;
candidate = sibling;
mindist = dist;
} else {
delete sibling; delete sibling;
continue;
} }
distp = sibp - startp;
break;
case QAccessible::Up:
startp = QPoint(startg.left() + startg.width() / 2, startg.top());
sibp = QPoint(sibg.left() + sibg.width() / 2, sibg.bottom());
if (QPoint(sibc - startc).y() >= 0) {
delete sibling;
continue;
}
distp = sibp - startp;
break;
case QAccessible::Down:
startp = QPoint(startg.left() + startg.width() / 2, startg.bottom());
sibp = QPoint(sibg.left() + sibg.width() / 2, sibg.top());
if (QPoint(sibc - startc).y() <= 0) {
delete sibling;
continue;
}
distp = sibp - startp;
break;
default:
break;
}
int dist = (int)qSqrt((qreal)distp.x() * distp.x() + distp.y() * distp.y());
if (dist < mindist) {
delete candidate;
candidate = sibling;
mindist = dist;
} else {
delete sibling;
} }
delete pIface;
*target = candidate;
if (*target)
return 0;
} }
delete pIface;
*target = candidate;
if (*target)
return 0;
}
break; break;
case Covers: case Covers:
if (entry > 0) { if (entry > 0) {

View File

@ -65,6 +65,9 @@ public:
int childAt(int x, int y) const; int childAt(int x, int y) const;
QRect rect(int child) const; QRect rect(int child) const;
QAccessibleInterface *parent() const;
QAccessibleInterface *child(int index) const;
int navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const; int navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const;
QString text(Text t, int child) const; QString text(Text t, int child) const;

View File

@ -472,8 +472,7 @@ void tst_QAccessibility::navigateGeometric()
// arrange 360 widgets around it in a circle // arrange 360 widgets around it in a circle
QtTestAccessibleWidget *aw = 0; QtTestAccessibleWidget *aw = 0;
int i; for (int i = 0; i < 360; i += skip) {
for (i = 0; i < 360; i += skip) {
aw = new QtTestAccessibleWidget(w, QString::number(i).toLatin1()); aw = new QtTestAccessibleWidget(w, QString::number(i).toLatin1());
aw->move( int(200.0 + 100.0 * sin(step * (double)i)), int(200.0 + 100.0 * cos(step * (double)i)) ); aw->move( int(200.0 + 100.0 * sin(step * (double)i)), int(200.0 + 100.0 * cos(step * (double)i)) );
} }
@ -489,7 +488,7 @@ void tst_QAccessibility::navigateGeometric()
QTest::qWait(100); QTest::qWait(100);
// let one widget rotate around center // let one widget rotate around center
for (i = 0; i < 360; i+=skip) { for (int i = 0; i < 360; i+=skip) {
aw->move( int(200.0 + 75.0 * sin(step * (double)i)), int(200.0 + 75.0 * cos(step * (double)i)) ); aw->move( int(200.0 + 75.0 * sin(step * (double)i)), int(200.0 + 75.0 * cos(step * (double)i)) );
if (i < 45 || i > 315) { if (i < 45 || i > 315) {
@ -561,22 +560,11 @@ void tst_QAccessibility::navigateSlider()
slider->setObjectName(QString("Slidy")); slider->setObjectName(QString("Slidy"));
slider->show(); slider->show();
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(slider); QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(slider);
QAccessibleInterface *target = 0;
QVERIFY(iface != 0); QVERIFY(iface != 0);
QVERIFY(iface->isValid()); QVERIFY(iface->isValid());
QCOMPARE(iface->childCount(), 3);
QCOMPARE(iface->navigate(QAccessible::Child, 1, &target), 1); QEXPECT_FAIL("", "Implement slider with value interface and no children. Test value interface here.", Continue);
QVERIFY(target == 0); QCOMPARE(iface->childCount(), 0);
QCOMPARE(iface->navigate(QAccessible::Child, 2, &target), 2);
QVERIFY(target == 0);
QCOMPARE(iface->navigate(QAccessible::Child, 3, &target), 3);
QVERIFY(target == 0);
QCOMPARE(iface->navigate(QAccessible::Child, 4, &target), -1);
QVERIFY(target == 0);
QCOMPARE(iface->navigate(QAccessible::Child, 0, &target), -1);
QVERIFY(target == 0);
QCOMPARE(iface->navigate(QAccessible::Child, -42, &target), -1);
QVERIFY(target == 0);
delete iface; delete iface;
delete slider; delete slider;
@ -719,13 +707,20 @@ void tst_QAccessibility::navigateHierarchy()
QCOMPARE(iface->navigate(QAccessible::Sibling, 42, &target), -1); QCOMPARE(iface->navigate(QAccessible::Sibling, 42, &target), -1);
QVERIFY(target == 0); QVERIFY(target == 0);
QCOMPARE(iface->navigate(QAccessible::Child, 15, &target), -1); QCOMPARE(iface->navigate(QAccessible::Child, 15, &target), -1);
QVERIFY(iface->child(15) == 0);
QVERIFY(target == 0); QVERIFY(target == 0);
QCOMPARE(iface->navigate(QAccessible::Child, 0, &target), -1); QCOMPARE(iface->navigate(QAccessible::Child, 0, &target), -1);
QVERIFY(iface->child(-1) == 0);
QVERIFY(target == 0); QVERIFY(target == 0);
QCOMPARE(iface->navigate(QAccessible::Child, 1, &target), 0); QCOMPARE(iface->navigate(QAccessible::Child, 1, &target), 0);
QAccessibleInterface *interfaceW1 = iface->child(0);
QVERIFY(target != 0); QVERIFY(target != 0);
QVERIFY(target->isValid()); QVERIFY(target->isValid());
QCOMPARE(target->object(), (QObject*)w1); QCOMPARE(target->object(), (QObject*)w1);
QVERIFY(interfaceW1 != 0);
QVERIFY(interfaceW1->isValid());
QCOMPARE(interfaceW1->object(), (QObject*)w1);
delete interfaceW1;
delete iface; iface = 0; delete iface; iface = 0;
QCOMPARE(target->navigate(QAccessible::Sibling, 0, &iface), -1); QCOMPARE(target->navigate(QAccessible::Sibling, 0, &iface), -1);
@ -761,27 +756,11 @@ void tst_QAccessibility::navigateHierarchy()
QCOMPARE(target->object(), (QObject*)w31); QCOMPARE(target->object(), (QObject*)w31);
delete iface; iface = 0; delete iface; iface = 0;
QCOMPARE(target->navigate(QAccessible::Ancestor, 42, &iface), -1); iface = target->parent();
QVERIFY(iface == 0);
QCOMPARE(target->navigate(QAccessible::Ancestor, -1, &iface), -1);
QVERIFY(iface == 0);
QCOMPARE(target->navigate(QAccessible::Ancestor, 0, &iface), -1);
QVERIFY(iface == 0);
QCOMPARE(target->navigate(QAccessible::Ancestor, 1, &iface), 0);
QVERIFY(iface != 0); QVERIFY(iface != 0);
QVERIFY(iface->isValid()); QVERIFY(iface->isValid());
QCOMPARE(iface->object(), (QObject*)w3); QCOMPARE(iface->object(), (QObject*)w3);
delete iface; iface = 0; delete iface; iface = 0;
QCOMPARE(target->navigate(QAccessible::Ancestor, 2, &iface), 0);
QVERIFY(iface != 0);
QVERIFY(iface->isValid());
QCOMPARE(iface->object(), (QObject*)w);
delete iface; iface = 0;
QCOMPARE(target->navigate(QAccessible::Ancestor, 3, &iface), 0);
QVERIFY(iface != 0);
QVERIFY(iface->isValid());
QCOMPARE(iface->object(), (QObject*)qApp);
delete iface; iface = 0;
delete target; target = 0; delete target; target = 0;
delete w; delete w;
@ -1328,17 +1307,17 @@ void tst_QAccessibility::tabTest()
// Test that the Invisible bit for the navigation buttons gets set // Test that the Invisible bit for the navigation buttons gets set
// and cleared correctly. // and cleared correctly.
qWarning() << "Enable test again when child and parent functions are implemented"; QAccessibleInterface *child1 = interface->child(0);
#if 0 QVERIFY(child1);
QVERIFY(interface->state(1) & QAccessible::Invisible); QVERIFY(child1->state() & QAccessible::Invisible);
const int lots = 10; const int lots = 10;
for (int i = 0; i < lots; ++i) for (int i = 0; i < lots; ++i)
tabBar->addTab("Foo"); tabBar->addTab("Foo");
QVERIFY((interface->state(1) & QAccessible::Invisible) == false); QVERIFY((child1->state() & QAccessible::Invisible) == false);
tabBar->hide(); tabBar->hide();
QVERIFY(interface->state(1) & QAccessible::Invisible); QVERIFY(child1->state() & QAccessible::Invisible);
tabBar->show(); tabBar->show();
tabBar->setCurrentIndex(0); tabBar->setCurrentIndex(0);
@ -1350,7 +1329,7 @@ void tst_QAccessibility::tabTest()
// Test that sending a press action to a tab selects it. // Test that sending a press action to a tab selects it.
interface->doAction(QAccessible::Press, 2, QVariantList()); interface->doAction(QAccessible::Press, 2, QVariantList());
QCOMPARE(tabBar->currentIndex(), 1); QCOMPARE(tabBar->currentIndex(), 1);
#endif
delete tabBar; delete tabBar;
delete interface; delete interface;
QTestAccessibility::clearEvents(); QTestAccessibility::clearEvents();
@ -1377,46 +1356,51 @@ void tst_QAccessibility::tabWidgetTest()
QAccessibleInterface* tabBarInterface = 0; QAccessibleInterface* tabBarInterface = 0;
// there is no special logic to sort the children, so the contents will be 1, the tab bar 2 // there is no special logic to sort the children, so the contents will be 1, the tab bar 2
QCOMPARE(interface->navigate(QAccessible::Child, 2 , &tabBarInterface), 0); tabBarInterface = interface->child(1);
QVERIFY(tabBarInterface); QVERIFY(tabBarInterface);
QCOMPARE(tabBarInterface->childCount(), 4); QCOMPARE(tabBarInterface->childCount(), 4);
QCOMPARE(tabBarInterface->role(0), QAccessible::PageTabList); QCOMPARE(tabBarInterface->role(), QAccessible::PageTabList);
QAccessibleInterface* tabButton1Interface = 0; QAccessibleInterface* tabButton1Interface = tabBarInterface->child(0);
QCOMPARE(tabBarInterface->navigate(QAccessible::Child, 1 , &tabButton1Interface), 0);
QVERIFY(tabButton1Interface); QVERIFY(tabButton1Interface);
QCOMPARE(tabButton1Interface->role(), QAccessible::PageTab);
QCOMPARE(tabButton1Interface->text(QAccessible::Name), QLatin1String("Tab 1"));
QAccessibleInterface* tabButton2Interface = tabBarInterface->child(1);
QVERIFY(tabButton1Interface);
QCOMPARE(tabButton2Interface->role(), QAccessible::PageTab);
QCOMPARE(tabButton2Interface->text(QAccessible::Name), QLatin1String("Tab 2"));
QAccessibleInterface* tabButtonLeft = tabBarInterface->child(2);
QVERIFY(tabButtonLeft);
QCOMPARE(tabButtonLeft->role(), QAccessible::PushButton);
QCOMPARE(tabButtonLeft->text(QAccessible::Name), QLatin1String("Scroll Left"));
QAccessibleInterface* tabButtonRight = tabBarInterface->child(3);
QVERIFY(tabButtonRight);
QCOMPARE(tabButtonRight->role(), QAccessible::PushButton);
QCOMPARE(tabButtonRight->text(QAccessible::Name), QLatin1String("Scroll Right"));
delete tabButton1Interface; delete tabButton1Interface;
delete tabButton2Interface;
delete tabButtonLeft;
delete tabButtonRight;
qWarning() << "Enable test again when child and parent functions are implemented"; QAccessibleInterface* stackWidgetInterface = interface->child(0);
#if 0
QCOMPARE(tabBarInterface->role(1), QAccessible::PageTab);
QCOMPARE(tabBarInterface->text(QAccessible::Name, 1), QLatin1String("Tab 1"));
QCOMPARE(tabBarInterface->role(2), QAccessible::PageTab);
QCOMPARE(tabBarInterface->text(QAccessible::Name, 2), QLatin1String("Tab 2"));
QCOMPARE(tabBarInterface->role(3), QAccessible::PushButton);
QCOMPARE(tabBarInterface->text(QAccessible::Name, 3), QLatin1String("Scroll Left"));
QCOMPARE(tabBarInterface->role(4), QAccessible::PushButton);
QCOMPARE(tabBarInterface->text(QAccessible::Name, 4), QLatin1String("Scroll Right"));
QAccessibleInterface* stackWidgetInterface = 0;
QCOMPARE(interface->navigate(QAccessible::Child, 1, &stackWidgetInterface), 0);
QVERIFY(stackWidgetInterface); QVERIFY(stackWidgetInterface);
QCOMPARE(stackWidgetInterface->childCount(), 2); QCOMPARE(stackWidgetInterface->childCount(), 2);
QCOMPARE(stackWidgetInterface->role(0), QAccessible::LayeredPane); QCOMPARE(stackWidgetInterface->role(), QAccessible::LayeredPane);
QAccessibleInterface* stackChild1Interface = 0; QAccessibleInterface* stackChild1Interface = stackWidgetInterface->child(0);
QCOMPARE(stackWidgetInterface->navigate(QAccessible::Child, 1, &stackChild1Interface), 0);
QVERIFY(stackChild1Interface); QVERIFY(stackChild1Interface);
#ifndef Q_CC_INTEL #ifndef Q_CC_INTEL
QCOMPARE(stackChild1Interface->childCount(), 0); QCOMPARE(stackChild1Interface->childCount(), 0);
#endif #endif
QCOMPARE(stackChild1Interface->role(0), QAccessible::StaticText); QCOMPARE(stackChild1Interface->role(), QAccessible::StaticText);
QCOMPARE(stackChild1Interface->text(QAccessible::Name, 0), QLatin1String("Page 1")); QCOMPARE(stackChild1Interface->text(QAccessible::Name), QLatin1String("Page 1"));
QCOMPARE(label1, stackChild1Interface->object()); QCOMPARE(label1, stackChild1Interface->object());
// Navigation in stack widgets should be consistent // Navigation in stack widgets should be consistent
QAccessibleInterface* parent = 0; QAccessibleInterface* parent = stackChild1Interface->parent();
QCOMPARE(stackChild1Interface->navigate(QAccessible::Ancestor, 1, &parent), 0);
QVERIFY(parent); QVERIFY(parent);
#ifndef Q_CC_INTEL #ifndef Q_CC_INTEL
QCOMPARE(parent->childCount(), 2); QCOMPARE(parent->childCount(), 2);
@ -1424,25 +1408,25 @@ void tst_QAccessibility::tabWidgetTest()
QCOMPARE(parent->role(0), QAccessible::LayeredPane); QCOMPARE(parent->role(0), QAccessible::LayeredPane);
delete parent; delete parent;
QAccessibleInterface* stackChild2Interface = 0; QAccessibleInterface* stackChild2Interface = stackWidgetInterface->child(1);
QCOMPARE(stackWidgetInterface->navigate(QAccessible::Child, 2, &stackChild2Interface), 0);
QVERIFY(stackChild2Interface); QVERIFY(stackChild2Interface);
QCOMPARE(stackChild2Interface->childCount(), 0); QCOMPARE(stackChild2Interface->childCount(), 0);
QCOMPARE(stackChild2Interface->role(0), QAccessible::StaticText); QCOMPARE(stackChild2Interface->role(), QAccessible::StaticText);
QCOMPARE(label2, stackChild2Interface->object()); // the text will be empty since it is not visible QCOMPARE(label2, stackChild2Interface->object());
QCOMPARE(label2->text(), stackChild2Interface->text(QAccessible::Name));
QCOMPARE(stackChild2Interface->navigate(QAccessible::Ancestor, 1, &parent), 0); parent = stackChild2Interface->parent();
QVERIFY(parent); QVERIFY(parent);
#ifndef Q_CC_INTEL #ifndef Q_CC_INTEL
QCOMPARE(parent->childCount(), 2); QCOMPARE(parent->childCount(), 2);
#endif #endif
QCOMPARE(parent->role(0), QAccessible::LayeredPane); QCOMPARE(parent->role(), QAccessible::LayeredPane);
delete parent; delete parent;
delete tabBarInterface;
delete stackChild1Interface; delete stackChild1Interface;
delete stackChild2Interface; delete stackChild2Interface;
delete stackWidgetInterface; delete stackWidgetInterface;
#endif
delete tabBarInterface;
delete interface; delete interface;
delete tabWidget; delete tabWidget;
QTestAccessibility::clearEvents(); QTestAccessibility::clearEvents();
@ -1486,17 +1470,23 @@ void tst_QAccessibility::menuTest()
QTest::qWait(100); QTest::qWait(100);
QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(mw.menuBar()); QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(mw.menuBar());
QCOMPARE(verifyHierarchy(interface), 0); QCOMPARE(verifyHierarchy(interface), 0);
QVERIFY(interface); QVERIFY(interface);
QCOMPARE(interface->childCount(), 5); QCOMPARE(interface->childCount(), 5);
QCOMPARE(interface->role(0), QAccessible::MenuBar); QCOMPARE(interface->role(0), QAccessible::MenuBar);
QCOMPARE(interface->role(1), QAccessible::MenuItem);
QCOMPARE(interface->role(2), QAccessible::MenuItem); QAccessibleInterface *iFile = interface->child(0);
QCOMPARE(interface->role(3), QAccessible::Separator); QAccessibleInterface *iEdit = interface->child(1);
QCOMPARE(interface->role(4), QAccessible::MenuItem); QAccessibleInterface *iSeparator = interface->child(2);
QCOMPARE(interface->role(5), QAccessible::MenuItem); QAccessibleInterface *iHelp = interface->child(3);
QAccessibleInterface *iAction = interface->child(4);
QCOMPARE(iFile->role(0), QAccessible::MenuItem);
QCOMPARE(iEdit->role(0), QAccessible::MenuItem);
QCOMPARE(iSeparator->role(0), QAccessible::Separator);
QCOMPARE(iHelp->role(0), QAccessible::MenuItem);
QCOMPARE(iAction->role(0), QAccessible::MenuItem);
#ifndef Q_WS_MAC #ifndef Q_WS_MAC
#ifdef Q_OS_WINCE #ifdef Q_OS_WINCE
if (!IsValidCEPlatform()) { if (!IsValidCEPlatform()) {
@ -1506,73 +1496,79 @@ void tst_QAccessibility::menuTest()
QCOMPARE(mw.mapFromGlobal(interface->rect(0).topLeft()), mw.menuBar()->geometry().topLeft()); QCOMPARE(mw.mapFromGlobal(interface->rect(0).topLeft()), mw.menuBar()->geometry().topLeft());
QCOMPARE(interface->rect(0).size(), mw.menuBar()->size()); QCOMPARE(interface->rect(0).size(), mw.menuBar()->size());
QVERIFY(interface->rect(0).contains(interface->rect(1))); QVERIFY(interface->rect(0).contains(iFile->rect(0)));
QVERIFY(interface->rect(0).contains(interface->rect(2))); QVERIFY(interface->rect(0).contains(iEdit->rect(0)));
// QVERIFY(interface->rect(0).contains(interface->rect(3))); //separator might be invisible // QVERIFY(interface->rect(0).contains(childSeparator->rect(0))); //separator might be invisible
QVERIFY(interface->rect(0).contains(interface->rect(4))); QVERIFY(interface->rect(0).contains(iHelp->rect(0)));
QVERIFY(interface->rect(0).contains(interface->rect(5))); QVERIFY(interface->rect(0).contains(iAction->rect(0)));
#endif #endif
QCOMPARE(interface->text(QAccessible::Name, 1), QString("File")); QCOMPARE(iFile->text(QAccessible::Name, 0), QString("File"));
QCOMPARE(interface->text(QAccessible::Name, 2), QString("Edit")); QCOMPARE(iEdit->text(QAccessible::Name, 0), QString("Edit"));
QCOMPARE(interface->text(QAccessible::Name, 3), QString()); QCOMPARE(iSeparator->text(QAccessible::Name, 0), QString());
QCOMPARE(interface->text(QAccessible::Name, 4), QString("Help")); QCOMPARE(iHelp->text(QAccessible::Name, 0), QString("Help"));
QCOMPARE(interface->text(QAccessible::Name, 5), QString("Action!")); QCOMPARE(iAction->text(QAccessible::Name, 0), QString("Action!"));
// TODO: Currently not working, task to fix is #100019. // TODO: Currently not working, task to fix is #100019.
#ifndef Q_OS_MAC #ifndef Q_OS_MAC
QCOMPARE(interface->text(QAccessible::Accelerator, 1), tr("Alt+F")); QCOMPARE(iFile->text(QAccessible::Accelerator, 0), tr("Alt+F"));
QCOMPARE(interface->text(QAccessible::Accelerator, 2), tr("Alt+E")); QCOMPARE(iEdit->text(QAccessible::Accelerator, 0), tr("Alt+E"));
QCOMPARE(interface->text(QAccessible::Accelerator, 4), tr("Alt+H")); QCOMPARE(iSeparator->text(QAccessible::Accelerator, 0), QString());
QCOMPARE(interface->text(QAccessible::Accelerator, 3), QString()); QCOMPARE(iHelp->text(QAccessible::Accelerator, 0), tr("Alt+H"));
QCOMPARE(interface->text(QAccessible::Accelerator, 4), tr("Alt+H")); QCOMPARE(iAction->text(QAccessible::Accelerator, 0), QString());
QCOMPARE(interface->text(QAccessible::Accelerator, 5), QString());
#endif #endif
QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 1), QString("Open")); QCOMPARE(iFile->actionText(QAccessible::DefaultAction, QAccessible::Name), QString("Open"));
QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 2), QString("Open")); QCOMPARE(iEdit->actionText(QAccessible::DefaultAction, QAccessible::Name), QString("Open"));
QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 3), QString()); QCOMPARE(iSeparator->actionText(QAccessible::DefaultAction, QAccessible::Name), QString());
QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 4), QString("Open")); QCOMPARE(iHelp->actionText(QAccessible::DefaultAction, QAccessible::Name), QString("Open"));
QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 5), QString("Execute")); QCOMPARE(iAction->actionText(QAccessible::DefaultAction, QAccessible::Name), QString("Execute"));
bool menuFade = qApp->isEffectEnabled(Qt::UI_FadeMenu); bool menuFade = qApp->isEffectEnabled(Qt::UI_FadeMenu);
int menuFadeDelay = 300; int menuFadeDelay = 300;
interface->doAction(QAccessible::DefaultAction, 1); iFile->doAction(QAccessible::DefaultAction);
if(menuFade) if(menuFade)
QTest::qWait(menuFadeDelay); QTest::qWait(menuFadeDelay);
QVERIFY(file->isVisible() && !edit->isVisible() && !help->isVisible()); QVERIFY(file->isVisible() && !edit->isVisible() && !help->isVisible());
interface->doAction(QAccessible::DefaultAction, 2); iEdit->doAction(QAccessible::DefaultAction);
if(menuFade) if(menuFade)
QTest::qWait(menuFadeDelay); QTest::qWait(menuFadeDelay);
QVERIFY(!file->isVisible() && edit->isVisible() && !help->isVisible()); QVERIFY(!file->isVisible() && edit->isVisible() && !help->isVisible());
interface->doAction(QAccessible::DefaultAction, 3); iSeparator->doAction(QAccessible::DefaultAction);
if(menuFade) if(menuFade)
QTest::qWait(menuFadeDelay); QTest::qWait(menuFadeDelay);
QVERIFY(!file->isVisible() && !edit->isVisible() && !help->isVisible()); QVERIFY(!file->isVisible() && !edit->isVisible() && !help->isVisible());
interface->doAction(QAccessible::DefaultAction, 4); iHelp->doAction(QAccessible::DefaultAction);
if(menuFade) if(menuFade)
QTest::qWait(menuFadeDelay); QTest::qWait(menuFadeDelay);
QVERIFY(!file->isVisible() && !edit->isVisible() && help->isVisible()); QVERIFY(!file->isVisible() && !edit->isVisible() && help->isVisible());
interface->doAction(QAccessible::DefaultAction, 5); iAction->doAction(QAccessible::DefaultAction);
if(menuFade) if(menuFade)
QTest::qWait(menuFadeDelay); QTest::qWait(menuFadeDelay);
QVERIFY(!file->isVisible() && !edit->isVisible() && !help->isVisible()); QVERIFY(!file->isVisible() && !edit->isVisible() && !help->isVisible());
interface->doAction(QAccessible::DefaultAction, 1); interface->doAction(QAccessible::DefaultAction);
delete interface; delete interface;
interface = QAccessible::queryAccessibleInterface(file); interface = QAccessible::queryAccessibleInterface(file);
QCOMPARE(interface->childCount(), 5); QCOMPARE(interface->childCount(), 5);
QCOMPARE(interface->role(0), QAccessible::PopupMenu); QCOMPARE(interface->role(), QAccessible::PopupMenu);
QCOMPARE(interface->role(1), QAccessible::MenuItem);
QCOMPARE(interface->role(2), QAccessible::MenuItem); QAccessibleInterface *iFileNew = interface->child(0);
QCOMPARE(interface->role(3), QAccessible::MenuItem); QAccessibleInterface *iFileOpen = interface->child(1);
QCOMPARE(interface->role(4), QAccessible::Separator); QAccessibleInterface *iFileSave = interface->child(2);
QCOMPARE(interface->role(5), QAccessible::MenuItem); QAccessibleInterface *iFileSeparator = interface->child(3);
QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 1), QString("Open")); QAccessibleInterface *iFileExit = interface->child(4);
QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 2), QString("Execute"));
QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 3), QString("Execute")); QCOMPARE(iFileNew->role(), QAccessible::MenuItem);
QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 4), QString()); QCOMPARE(iFileOpen->role(), QAccessible::MenuItem);
QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 5), QString("Execute")); QCOMPARE(iFileSave->role(), QAccessible::MenuItem);
QCOMPARE(iFileSeparator->role(), QAccessible::Separator);
QCOMPARE(iFileExit->role(), QAccessible::MenuItem);
QCOMPARE(iFileNew->actionText(QAccessible::DefaultAction, QAccessible::Name, 0), QString("Open"));
QCOMPARE(iFileOpen->actionText(QAccessible::DefaultAction, QAccessible::Name, 0), QString("Execute"));
QCOMPARE(iFileSave->actionText(QAccessible::DefaultAction, QAccessible::Name, 0), QString("Execute"));
QCOMPARE(iFileSeparator->actionText(QAccessible::DefaultAction, QAccessible::Name, 0), QString());
QCOMPARE(iFileExit->actionText(QAccessible::DefaultAction, QAccessible::Name, 0), QString("Execute"));
QAccessibleInterface *iface = 0; QAccessibleInterface *iface = 0;
QAccessibleInterface *iface2 = 0; QAccessibleInterface *iface2 = 0;
@ -1653,12 +1649,6 @@ void tst_QAccessibility::menuTest()
QVERIFY(iface); QVERIFY(iface);
QCOMPARE(iface->role(0), QAccessible::MenuItem); QCOMPARE(iface->role(0), QAccessible::MenuItem);
// Traverse to the menubar.
QAccessibleInterface *ifaceMenuBar = 0;
entry = iface->navigate(QAccessible::Ancestor, 5, &ifaceMenuBar);
QCOMPARE(ifaceMenuBar->role(0), QAccessible::MenuBar);
delete ifaceMenuBar;
delete iface; delete iface;
// move mouse pointer away, since that might influence the // move mouse pointer away, since that might influence the
@ -1667,8 +1657,9 @@ void tst_QAccessibility::menuTest()
QTest::qWait(100); QTest::qWait(100);
if (menuFade) if (menuFade)
QTest::qWait(menuFadeDelay); QTest::qWait(menuFadeDelay);
interface->doAction(QAccessible::DefaultAction, 1);
QTestEventLoop::instance().enterLoop(2); iFile->doAction(QAccessible::DefaultAction);
iFileNew->doAction(QAccessible::DefaultAction);
QVERIFY(file->isVisible()); QVERIFY(file->isVisible());
QVERIFY(fileNew->isVisible()); QVERIFY(fileNew->isVisible());
@ -1678,6 +1669,12 @@ void tst_QAccessibility::menuTest()
QTestAccessibility::clearEvents(); QTestAccessibility::clearEvents();
mw.hide(); mw.hide();
delete iFile;
delete iFileNew;
delete iFileOpen;
delete iFileSave;
delete iFileSeparator;
delete iFileExit;
// Do not crash if the menu don't have a parent // Do not crash if the menu don't have a parent
QMenu *menu = new QMenu; QMenu *menu = new QMenu;
@ -1685,8 +1682,9 @@ void tst_QAccessibility::menuTest()
menu->addAction(QLatin1String("two")); menu->addAction(QLatin1String("two"));
menu->addAction(QLatin1String("three")); menu->addAction(QLatin1String("three"));
iface = QAccessible::queryAccessibleInterface(menu); iface = QAccessible::queryAccessibleInterface(menu);
QCOMPARE(iface->navigate(QAccessible::Ancestor, 1, &iface2), 0); iface2 = iface->parent();
QCOMPARE(iface2->role(0), QAccessible::Application); QVERIFY(iface2);
QCOMPARE(iface2->role(), QAccessible::Application);
// caused a *crash* // caused a *crash*
iface2->state(0); iface2->state(0);
delete iface2; delete iface2;
@ -2912,11 +2910,9 @@ void tst_QAccessibility::table2TreeTest()
treeView->resize(400,400); treeView->resize(400,400);
treeView->show(); treeView->show();
QTest::qWait(1); // Need this for indexOfchild to work.
#if defined(Q_OS_UNIX)
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QTest::qWait(100); QTest::qWait(100);
#endif
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(treeView); QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(treeView);
QEXPECT_FAIL("", "Implement Sibling navigation for table2 cells.", Continue); QEXPECT_FAIL("", "Implement Sibling navigation for table2 cells.", Continue);
@ -2975,11 +2971,9 @@ void tst_QAccessibility::table2TreeTest()
treeView->expandAll(); treeView->expandAll();
QTest::qWait(1); // Need this for indexOfchild to work. // Need this for indexOfchild to work.
#if defined(Q_OS_UNIX)
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QTest::qWait(100); QTest::qWait(100);
#endif
QCOMPARE(table2->columnCount(), 2); QCOMPARE(table2->columnCount(), 2);
QCOMPARE(table2->rowCount(), 5); QCOMPARE(table2->rowCount(), 5);