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;
}
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,
QAccessibleInterface **iface) const
{
@ -489,19 +500,9 @@ int QAccessibleItemRow::navigate(RelationFlag relation, int index,
return -1;
switch (relation) {
case Ancestor: {
if (!index)
return -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 Ancestor:
*iface = parent();
return *iface ? 0 : -1;
case Child: {
if (!index)
return -1;
@ -1487,10 +1488,14 @@ public:
QString text(Text, int) const { return qt_accStripAmp(m_parent->tabText(m_index)); }
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
{
if (relation == QAccessible::Ancestor && index == 1) {
*iface = QAccessible::queryAccessibleInterface(m_parent);
*iface = parent();
return 0;
}
return -1;
@ -1842,6 +1847,7 @@ int QAccessibleComboBox::childAt(int x, int y) const
if (rect(i).contains(x, y))
return i;
}
Q_ASSERT(0);
return 0;
}

View File

@ -139,6 +139,8 @@ public:
Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) 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 userActionCount(int child) const;

View File

@ -359,9 +359,7 @@ QAccessible2::TableModelChange QAccessibleTable2::modelChange() const
QAccessible::Role QAccessibleTable2::role(int child) const
{
Q_ASSERT(child >= 0);
if (child > 0)
return QAccessible::Cell;
Q_ASSERT(child == 0);
return m_role;
}
@ -386,6 +384,8 @@ int QAccessibleTable2::childAt(int x, int y) const
int QAccessibleTable2::childCount() const
{
if (!view->model())
return 0;
int vHeader = verticalHeader() ? 1 : 0;
int hHeader = horizontalHeader() ? 1 : 0;
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());
}
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
{
*iface = 0;
switch (relation) {
case Ancestor: {
if (index == 1 && view->parent()) {
*iface = QAccessible::queryAccessibleInterface(view->parent());
if (*iface)
return 0;
}
break;
*iface = parent();
return *iface ? 0 : -1;
}
case QAccessible::Child: {
Q_ASSERT(index > 0);
*iface = childFromLogical(index);
*iface = child(index - 1);
if (*iface) {
return 0;
}
@ -806,14 +816,23 @@ bool QAccessibleTable2Cell::isValid() const
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
{
if (relation == Ancestor && index == 1) {
if (m_role == QAccessible::TreeItem) {
*iface = new QAccessibleTree(view);
} else {
*iface = new QAccessibleTable2(view);
}
*iface = parent();
return 0;
}
@ -978,19 +997,28 @@ bool QAccessibleTable2HeaderCell::isValid() const
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
{
if (relation == QAccessible::Ancestor && index == 1) {
if (false) {
#ifndef QT_NO_TREEVIEW
} else if (qobject_cast<const QTreeView*>(view)) {
*iface = new QAccessibleTree(view);
return 0;
#endif
} else {
*iface = new QAccessibleTable2(view);
return 0;
}
*iface = parent();
return *iface ? 0 : -1;
}
*iface = 0;
return -1;

View File

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

View File

@ -73,13 +73,8 @@ int QAccessibleMenu::childCount() const
QRect QAccessibleMenu::rect(int child) const
{
if (!child || child > childCount())
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());
Q_ASSERT(child == 0);
return QAccessibleWidget::rect(child);
}
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
{
Q_ASSERT(child == 0);
QString tx = QAccessibleWidget::text(t, child);
if (tx.size())
return tx;
switch (t) {
case Name:
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;
}
if (t == Name)
return menu()->windowTitle();
return tx;
}
QAccessible::Role QAccessibleMenu::role(int child) const
{
if (!child)
return PopupMenu;
QAction *action = menu()->actions()[child-1];
if (action && action->isSeparator())
return Separator;
return MenuItem;
Q_ASSERT(child == 0);
return PopupMenu;
}
QAccessible::State QAccessibleMenu::state(int child) const
{
Q_ASSERT(child == 0);
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;
}
QString QAccessibleMenu::actionText(int action, QAccessible::Text text, int child) const
{
if (action == QAccessible::DefaultAction && child && text == QAccessible::Name) {
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");
}
Q_ASSERT(child == 0);
return QAccessibleWidget::actionText(action, text, child);
}
bool QAccessibleMenu::doAction(int act, int child, const QVariantList &)
{
// Q_ASSERT(child == 0);
if (!child || act != QAccessible::DefaultAction)
return false;
@ -179,52 +133,35 @@ bool QAccessibleMenu::doAction(int act, int child, const QVariantList &)
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 ret = -1;
if (entry < 0) {
*target = 0;
return ret;
}
if (relation == Self || entry == 0) {
*target = new QAccessibleMenu(menu());
return 0;
}
Q_ASSERT(entry >= 0);
switch (relation) {
case Child:
if (entry <= childCount()) {
*target = new QAccessibleMenuItem(menu(), menu()->actions().at( entry - 1 ));
ret = 0;
}
break;
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;}
*target = child(entry - 1);
return *target ? 0 : -1;
case Ancestor:
*target = parent();
return *target ? 0 : -1;
default:
return QAccessibleWidget::navigate(relation, entry, target);
}
if (ret == -1)
*target = 0;
return ret;
}
int QAccessibleMenu::indexOfChild( const QAccessibleInterface *child ) const
@ -258,12 +195,8 @@ int QAccessibleMenuBar::childCount() const
QRect QAccessibleMenuBar::rect(int child) const
{
if (!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());
Q_ASSERT(child == 0);
return QAccessibleWidget::rect(child);
}
int QAccessibleMenuBar::childAt(int x, int y) const
@ -275,38 +208,23 @@ int QAccessibleMenuBar::childAt(int x, int y) const
return -1;
}
int QAccessibleMenuBar::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const
QAccessibleInterface *QAccessibleMenuBar::child(int index) const
{
int ret = -1;
if (entry < 0) {
*target = 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;
if (index < childCount())
return new QAccessibleMenuItem(menuBar(), menuBar()->actions().at(index));
return 0;
}
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;
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 str;
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;
Q_ASSERT(child == 0);
return QAccessibleWidget::text(t, child);
}
QAccessible::Role QAccessibleMenuBar::role(int child) const
{
if (!child)
return MenuBar;
QAction *action = menuBar()->actions()[child-1];
if (action && action->isSeparator())
return Separator;
return MenuItem;
Q_ASSERT(child == 0);
return MenuBar;
}
QAccessible::State QAccessibleMenuBar::state(int child) const
{
Q_ASSERT(child == 0);
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;
}
QString QAccessibleMenuBar::actionText(int action, QAccessible::Text text, int child) const
{
if (action == QAccessible::DefaultAction && child && text == QAccessible::Name) {
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");
}
Q_ASSERT(child == 0);
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)
return false;
// Q_ASSERT(child == 0);
QAction *action = menuBar()->actions().value(child-1, 0);
if (!action || !action->isEnabled())
return false;
if (action->menu() && action->menu()->isVisible())
action->menu()->hide();
else
else {
menuBar()->setActiveAction(action);
}
return true;
return false;
}
#endif // QT_NO_MENUBAR
@ -427,32 +301,69 @@ int QAccessibleMenuItem::childCount() const
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) {
switch (action) {
case Press:
case DefaultAction:
return QMenu::tr("Execute");
break;
default:
break;
Q_ASSERT(child == 0);
if (!m_action || m_action->isSeparator())
return QString();
if (text == Name && ((action == Press) || (action == DefaultAction))) {
if (m_action->menu()) {
return QMenu::tr("Open");
}
return QMenu::tr("Execute");
}
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()*/ )
{
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();
return true;
}
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())
return 1;
@ -464,6 +375,18 @@ bool QAccessibleMenuItem::isValid() const
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 ret = -1;
@ -472,32 +395,14 @@ int QAccessibleMenuItem::navigate(RelationFlag relation, int entry, QAccessibleI
return ret;
}
if (relation == Self || entry == 0) {
*target = new QAccessibleMenuItem(owner(), action());
return 0;
}
switch (relation) {
case Child:
if (entry <= childCount()) {
*target = new QAccessibleMenu(action()->menu());
ret = 0;
}
*target = child(entry - 1);
ret = *target ? 0 : -1;
break;
case Ancestor:{
QWidget *parent = owner();
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 Ancestor:
*target = parent();
return 0;
case Up:
case Down:{
QAccessibleInterface *parent = 0;
@ -533,36 +438,29 @@ QObject *QAccessibleMenuItem::object() const
return m_action;
}
QRect QAccessibleMenuItem::rect (int child ) const
QRect QAccessibleMenuItem::rect(int child) const
{
Q_ASSERT(child == 0);
QRect rect;
if (child == 0) {
QWidget *own = owner();
QWidget *own = owner();
#ifndef QT_NO_MENUBAR
if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
rect = menuBar->actionGeometry(m_action);
QPoint globalPos = menuBar->mapToGlobal(QPoint(0,0));
rect = rect.translated(globalPos);
} else
if (QMenuBar *menuBar = qobject_cast<QMenuBar*>(own)) {
rect = menuBar->actionGeometry(m_action);
QPoint globalPos = menuBar->mapToGlobal(QPoint(0,0));
rect = rect.translated(globalPos);
} else
#endif // QT_NO_MENUBAR
if (QMenu *menu = qobject_cast<QMenu*>(own)) {
rect = menu->actionGeometry(m_action);
QPoint globalPos = menu->mapToGlobal(QPoint(0,0));
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);
}
if (QMenu *menu = qobject_cast<QMenu*>(own)) {
rect = menu->actionGeometry(m_action);
QPoint globalPos = menu->mapToGlobal(QPoint(0,0));
rect = rect.translated(globalPos);
}
return rect;
}
QAccessible::Relation QAccessibleMenuItem::relationTo ( int child, const QAccessibleInterface * other, int otherChild ) const
{
Q_ASSERT(child == 0);
if (other->object() == owner()) {
return Child;
}
@ -573,81 +471,68 @@ QAccessible::Relation QAccessibleMenuItem::relationTo ( int child, const QAccess
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 */)
{
}
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) {
s = Normal;
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 (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;
return s;
}
QString QAccessibleMenuItem::text ( Text t, int child ) const
{
Q_ASSERT(child == 0);
QString str;
switch (t) {
case Name:
if (child == 0) {
str = m_action->text();
} else if (child == 1) {
QMenu *m = m_action->menu();
if (m)
str = m->title();
}
str = m_action->text();
str = qt_accStripAmp(str);
break;
case Accelerator:
if (child == 0) {
case Accelerator: {
#ifndef QT_NO_SHORTCUT
QKeySequence key = m_action->shortcut();
if (!key.isEmpty()) {
str = key.toString();
} else
QKeySequence key = m_action->shortcut();
if (!key.isEmpty()) {
str = key.toString();
} else
#endif
{
str = qt_accHotKey(m_action->text());
}
{
str = qt_accHotKey(m_action->text());
}
break;
}
default:
break;
}
@ -659,7 +544,6 @@ int QAccessibleMenuItem::userActionCount ( int /*child*/ ) const
return 0;
}
QAction *QAccessibleMenuItem::action() const
{
return m_action;

View File

@ -65,6 +65,8 @@ public:
QString text(Text t, int child) const;
Role role(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 indexOfChild( const QAccessibleInterface *child ) const;
@ -81,6 +83,7 @@ class QAccessibleMenuBar : public QAccessibleWidget
public:
explicit QAccessibleMenuBar(QWidget *w);
QAccessibleInterface *child(int index) const;
int childCount() 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 int indexOfChild ( const QAccessibleInterface * child ) const;
virtual bool isValid () const;
QAccessibleInterface *parent() const;
QAccessibleInterface *child(int index) const;
virtual int navigate ( RelationFlag relation, int entry, QAccessibleInterface ** target ) const;
virtual QObject * object () const;
virtual QRect rect ( int child ) const;

View File

@ -414,22 +414,22 @@ int QAccessibleStackedWidget::indexOfChild(const QAccessibleInterface *child) co
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
{
*target = 0;
QObject *targetObject = 0;
switch (relation) {
case Child:
if (entry < 1 || entry > stackedWidget()->count())
return -1;
targetObject = stackedWidget()->widget(entry-1);
break;
*target = child(entry - 1);
return *target ? 0 : -1;
default:
return QAccessibleWidget::navigate(relation, entry, target);
}
*target = QAccessible::queryAccessibleInterface(targetObject);
return *target ? 0 : -1;
}
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
{
if (entry == 0 || relation == Self) {
*iface = new QAccessibleTitleBar(dockWidget());
return 0;
}
switch (relation) {
case Child:
*iface = child(entry - 1);
return *iface ? 0 : -1;
case FocusChild:
// ###
if (entry >= 1) {
QDockWidgetLayout *layout = dockWidgetLayout();
int index = 1;
@ -1095,18 +1117,8 @@ int QAccessibleTitleBar::navigate(RelationFlag relation, int entry, QAccessibleI
}
break;
case Ancestor:
{
QAccessibleDockWidget *target = new QAccessibleDockWidget(dockWidget());
int index;
if (entry == 1) {
*iface = target;
return 0;
}
index = target->navigate(Ancestor, entry - 1, iface);
delete target;
return index;
break;}
*iface = parent();
return iface ? 0 : -1;
case Sibling:
return navigate(Child, entry, iface);
break;

View File

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

View File

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

View File

@ -868,6 +868,27 @@ QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > QAccessibleInterfa
\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
**target) const
@ -909,7 +930,7 @@ QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > QAccessibleInterfa
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;
// navigation
virtual QAccessibleInterface *parent() const = 0;
virtual QAccessibleInterface *child(int index) const = 0;
virtual int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const = 0;
// 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 QRect rect(int child) const = 0;
virtual Role role(int child) const = 0;
virtual State state(int child) const = 0;
virtual QRect rect(int child = 0) const = 0;
virtual Role role(int child = 0) const = 0;
virtual State state(int child = 0) const = 0;
// action
virtual int userActionCount(int child) const = 0;
virtual QString actionText(int action, Text t, int child) const = 0;
virtual bool doAction(int action, int child, const QVariantList &params = QVariantList()) = 0;
virtual int userActionCount(int child = 0) const = 0;
virtual QString actionText(int action, Text t, int child = 0) const = 0;
virtual bool doAction(int action, int child = 0, const QVariantList &params = QVariantList()) = 0;
virtual QVariant invokeMethod(Method method, int child = 0,
const QVariantList &params = QVariantList());

View File

@ -284,6 +284,20 @@ QAccessible::Relation QAccessibleApplication::relationTo(int child, const
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 */
int QAccessibleApplication::navigate(RelationFlag relation, int entry,
QAccessibleInterface **target) const

View File

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

View File

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

View File

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