summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@nokia.com>2011-06-27 16:28:50 +0200
committerQt by Nokia <qt-info@nokia.com>2011-08-22 15:24:32 +0200
commit1b7b3377971832f56414c65063c7307202e09d7c (patch)
treef69b39ae1e5a0ac3b1a827e0eecfaa94009298e1 /src/plugins
parent15575fb280e1489157d0be44d00ab57aecc19320 (diff)
Add IAccessible2 table2 implementation.
Implement the IAccessible table2 interface for itemviews. This is simpler than what we have in complexwidgets. For now it is only used on Linux. The new table2 interface is ifdef'ed to only be used on X11. Improve handling of accessible events and clean up. There are two xfails for the Table and Tree where sibling navigation is not implemented yet. Reviewed-by: Gabi (cherry picked from commit e797ba558dddd45522b5a317316e497e9efc44a8) (cherry picked from commit eff5ecc5d8f65fa25d6cfd6ed96a9d2a00d0c663) (cherry picked from commit d29876008fad400bca8d6b37e5d5f61dd1bcb39d) (cherry picked from commit 2a326fdc8f8bf2bd2c5764394616100906d9db2d) (cherry picked from commit 9b72e79e20d0d3560e0b064b8b0d75e35feb720e) (cherry picked from commit 075b0f744363842ed4179c644d933d461389544f) Change-Id: I654f74991830ae1fc7df7cc91d930390fb88b2a4 Reviewed-on: http://codereview.qt.nokia.com/3274 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@nokia.com> Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/accessible/widgets/itemviews.cpp1029
-rw-r--r--src/plugins/accessible/widgets/itemviews.h319
-rw-r--r--src/plugins/accessible/widgets/main.cpp22
-rw-r--r--src/plugins/accessible/widgets/widgets.pro22
4 files changed, 1382 insertions, 10 deletions
diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp
new file mode 100644
index 0000000000..4618f873d3
--- /dev/null
+++ b/src/plugins/accessible/widgets/itemviews.cpp
@@ -0,0 +1,1029 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "itemviews.h"
+
+#include <qheaderview.h>
+#include <qtableview.h>
+#include <qlistview.h>
+#include <qtreeview.h>
+#include <private/qtreewidget_p.h>
+#include <qaccessible2.h>
+#include <QDebug>
+
+#ifndef QT_NO_ACCESSIBILITY
+
+QT_BEGIN_NAMESPACE
+
+QString Q_GUI_EXPORT qt_accStripAmp(const QString &text);
+
+#ifndef QT_NO_ITEMVIEWS
+/*
+Implementation of the IAccessible2 table2 interface. Much simpler than
+the other table interfaces since there is only the main table and cells:
+
+TABLE/LIST/TREE
+ |- HEADER CELL
+ |- CELL
+ |- CELL
+ ...
+*/
+
+int QAccessibleTable2::logicalIndex(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return -1;
+ int vHeader = verticalHeader() ? 1 : 0;
+ int hHeader = horizontalHeader() ? 1 : 0;
+ // row * number columns + column + 1 for one based counting
+ return (index.row() + hHeader)*(index.model()->columnCount() + vHeader) + (index.column() + vHeader) + 1;
+}
+
+QAccessibleInterface *QAccessibleTable2::childFromLogical(int logicalIndex) const
+{
+ logicalIndex--; // one based counting ftw
+ int vHeader = verticalHeader() ? 1 : 0;
+ int hHeader = horizontalHeader() ? 1 : 0;
+
+ int columns = view->model()->columnCount() + vHeader;
+
+ int row = logicalIndex / columns;
+ int column = logicalIndex % columns;
+
+ if (vHeader) {
+ if (column == 0) {
+ if (row == 0) {
+ return new QAccessibleTable2CornerButton(view);
+ }
+ return new QAccessibleTable2HeaderCell(view, row-1, Qt::Vertical);
+ }
+ --column;
+ }
+ if (hHeader) {
+ if (row == 0) {
+ return new QAccessibleTable2HeaderCell(view, column, Qt::Horizontal);
+ }
+ --row;
+ }
+ return new QAccessibleTable2Cell(view, view->model()->index(row, column), cellRole());
+}
+
+QAccessibleTable2::QAccessibleTable2(QWidget *w)
+ : QAccessibleObjectEx(w)
+{
+ view = qobject_cast<QAbstractItemView *>(w);
+ Q_ASSERT(view);
+
+ if (qobject_cast<const QTableView*>(view)) {
+ m_role = QAccessible::Table;
+ } else if (qobject_cast<const QTreeView*>(view)) {
+ m_role = QAccessible::Tree;
+ } else if (qobject_cast<const QListView*>(view)) {
+ m_role = QAccessible::List;
+ } else {
+ // is this our best guess?
+ m_role = QAccessible::Table;
+ }
+}
+
+QAccessibleTable2::~QAccessibleTable2()
+{
+}
+
+QHeaderView *QAccessibleTable2::horizontalHeader() const
+{
+ QHeaderView *header = 0;
+ if (false) {
+#ifndef QT_NO_TABLEVIEW
+ } else if (const QTableView *tv = qobject_cast<const QTableView*>(view)) {
+ header = tv->horizontalHeader();
+#endif
+#ifndef QT_NO_TREEVIEW
+ } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view)) {
+ header = tv->header();
+#endif
+ }
+ return header;
+}
+
+QHeaderView *QAccessibleTable2::verticalHeader() const
+{
+ QHeaderView *header = 0;
+ if (false) {
+#ifndef QT_NO_TABLEVIEW
+ } else if (const QTableView *tv = qobject_cast<const QTableView*>(view)) {
+ header = tv->verticalHeader();
+#endif
+ }
+ return header;
+}
+
+void QAccessibleTable2::modelReset()
+{}
+
+void QAccessibleTable2::rowsInserted(const QModelIndex &, int first, int last)
+{
+ lastChange.firstRow = first;
+ lastChange.lastRow = last;
+ lastChange.firstColumn = 0;
+ lastChange.lastColumn = 0;
+ lastChange.type = QAccessible2::TableModelChangeInsert;
+}
+
+void QAccessibleTable2::rowsRemoved(const QModelIndex &, int first, int last)
+{
+ lastChange.firstRow = first;
+ lastChange.lastRow = last;
+ lastChange.firstColumn = 0;
+ lastChange.lastColumn = 0;
+ lastChange.type = QAccessible2::TableModelChangeDelete;
+}
+
+void QAccessibleTable2::columnsInserted(const QModelIndex &, int first, int last)
+{
+ lastChange.firstRow = 0;
+ lastChange.lastRow = 0;
+ lastChange.firstColumn = first;
+ lastChange.lastColumn = last;
+ lastChange.type = QAccessible2::TableModelChangeInsert;
+}
+
+void QAccessibleTable2::columnsRemoved(const QModelIndex &, int first, int last)
+{
+ lastChange.firstRow = 0;
+ lastChange.lastRow = 0;
+ lastChange.firstColumn = first;
+ lastChange.lastColumn = last;
+ lastChange.type = QAccessible2::TableModelChangeDelete;
+}
+
+void QAccessibleTable2::rowsMoved( const QModelIndex &, int, int, const QModelIndex &, int)
+{
+ lastChange.firstRow = 0;
+ lastChange.lastRow = 0;
+ lastChange.firstColumn = 0;
+ lastChange.lastColumn = 0;
+ lastChange.type = QAccessible2::TableModelChangeUpdate;
+}
+
+void QAccessibleTable2::columnsMoved( const QModelIndex &, int, int, const QModelIndex &, int)
+{
+ lastChange.firstRow = 0;
+ lastChange.lastRow = 0;
+ lastChange.firstColumn = 0;
+ lastChange.lastColumn = 0;
+ lastChange.type = QAccessible2::TableModelChangeUpdate;
+}
+
+QAccessibleTable2Cell *QAccessibleTable2::cell(const QModelIndex &index) const
+{
+ if (index.isValid())
+ return new QAccessibleTable2Cell(view, index, cellRole());
+ return 0;
+}
+
+QAccessibleTable2CellInterface *QAccessibleTable2::cellAt(int row, int column) const
+{
+ Q_ASSERT(role(0) != QAccessible::Tree);
+ QModelIndex index = view->model()->index(row, column);
+ //Q_ASSERT(index.isValid());
+ if (!index.isValid()) {
+ qWarning() << "QAccessibleTable2::cellAt: invalid index: " << index << " for " << view;
+ return 0;
+ }
+ return cell(index);
+}
+
+QAccessibleInterface *QAccessibleTable2::caption() const
+{
+ return 0;
+}
+
+QString QAccessibleTable2::columnDescription(int column) const
+{
+ return view->model()->headerData(column, Qt::Horizontal).toString();
+}
+
+int QAccessibleTable2::columnCount() const
+{
+ return view->model()->columnCount();
+}
+
+int QAccessibleTable2::rowCount() const
+{
+ return view->model()->rowCount();
+}
+
+int QAccessibleTable2::selectedCellCount() const
+{
+ return view->selectionModel()->selectedIndexes().count();
+}
+
+int QAccessibleTable2::selectedColumnCount() const
+{
+ return view->selectionModel()->selectedColumns().count();
+}
+
+int QAccessibleTable2::selectedRowCount() const
+{
+ return view->selectionModel()->selectedRows().count();
+}
+
+QString QAccessibleTable2::rowDescription(int row) const
+{
+ return view->model()->headerData(row, Qt::Vertical).toString();
+}
+
+QList<QAccessibleTable2CellInterface*> QAccessibleTable2::selectedCells() const
+{
+ QList<QAccessibleTable2CellInterface*> cells;
+ Q_FOREACH (const QModelIndex &index, view->selectionModel()->selectedIndexes()) {
+ cells.append(cell(index));
+ }
+ return cells;
+}
+
+QList<int> QAccessibleTable2::selectedColumns() const
+{
+ QList<int> columns;
+ Q_FOREACH (const QModelIndex &index, view->selectionModel()->selectedColumns()) {
+ columns.append(index.column());
+ }
+ return columns;
+}
+
+QList<int> QAccessibleTable2::selectedRows() const
+{
+ QList<int> rows;
+ Q_FOREACH (const QModelIndex &index, view->selectionModel()->selectedRows()) {
+ rows.append(index.row());
+ }
+ return rows;
+}
+
+QAccessibleInterface *QAccessibleTable2::summary() const
+{
+ return 0;
+}
+
+bool QAccessibleTable2::isColumnSelected(int column) const
+{
+ return view->selectionModel()->isColumnSelected(column, QModelIndex());
+}
+
+bool QAccessibleTable2::isRowSelected(int row) const
+{
+ return view->selectionModel()->isRowSelected(row, QModelIndex());
+}
+
+bool QAccessibleTable2::selectRow(int row)
+{
+ QModelIndex index = view->model()->index(row, 0);
+ if (!index.isValid() || view->selectionMode() & QAbstractItemView::NoSelection)
+ return false;
+ view->selectionModel()->select(index, QItemSelectionModel::Select);
+ return true;
+}
+
+bool QAccessibleTable2::selectColumn(int column)
+{
+ QModelIndex index = view->model()->index(0, column);
+ if (!index.isValid() || view->selectionMode() & QAbstractItemView::NoSelection)
+ return false;
+ view->selectionModel()->select(index, QItemSelectionModel::Select);
+ return true;
+}
+
+bool QAccessibleTable2::unselectRow(int row)
+{
+ QModelIndex index = view->model()->index(row, 0);
+ if (!index.isValid() || view->selectionMode() & QAbstractItemView::NoSelection)
+ return false;
+ view->selectionModel()->select(index, QItemSelectionModel::Deselect);
+ return true;
+}
+
+bool QAccessibleTable2::unselectColumn(int column)
+{
+ QModelIndex index = view->model()->index(0, column);
+ if (!index.isValid() || view->selectionMode() & QAbstractItemView::NoSelection)
+ return false;
+ view->selectionModel()->select(index, QItemSelectionModel::Columns & QItemSelectionModel::Deselect);
+ return true;
+}
+
+QAccessible2::TableModelChange QAccessibleTable2::modelChange() const
+{
+ QAccessible2::TableModelChange change;
+ // FIXME
+ return change;
+}
+
+QAccessible::Role QAccessibleTable2::role(int child) const
+{
+ Q_ASSERT(child >= 0);
+ if (child > 0)
+ return QAccessible::Cell;
+ return m_role;
+}
+
+QAccessible::State QAccessibleTable2::state(int child) const
+{
+ Q_ASSERT(child == 0);
+ return QAccessible::Normal | HasInvokeExtension;
+}
+
+int QAccessibleTable2::childAt(int x, int y) const
+{
+ QPoint viewportOffset = view->viewport()->mapTo(view, QPoint(0,0));
+ QPoint indexPosition = view->mapFromGlobal(QPoint(x, y) - viewportOffset);
+ // FIXME: if indexPosition < 0 in one coordinate, return header
+
+ QModelIndex index = view->indexAt(indexPosition);
+ if (index.isValid()) {
+ return logicalIndex(index);
+ }
+ return -1;
+}
+
+int QAccessibleTable2::childCount() const
+{
+ int vHeader = verticalHeader() ? 1 : 0;
+ int hHeader = horizontalHeader() ? 1 : 0;
+ return (view->model()->rowCount()+hHeader) * (view->model()->columnCount()+vHeader);
+}
+
+int QAccessibleTable2::indexOfChild(const QAccessibleInterface *iface) const
+{
+ Q_ASSERT(iface->role(0) != QAccessible::TreeItem); // should be handled by tree class
+ if (iface->role(0) == QAccessible::Cell || iface->role(0) == QAccessible::ListItem) {
+ const QAccessibleTable2Cell* cell = static_cast<const QAccessibleTable2Cell*>(iface);
+ return logicalIndex(cell->m_index);
+ } else if (iface->role(0) == QAccessible::ColumnHeader){
+ const QAccessibleTable2HeaderCell* cell = static_cast<const QAccessibleTable2HeaderCell*>(iface);
+ return cell->index + (verticalHeader() ? 1 : 0) + 1;
+ } else if (iface->role(0) == QAccessible::RowHeader){
+ const QAccessibleTable2HeaderCell* cell = static_cast<const QAccessibleTable2HeaderCell*>(iface);
+ return (cell->index+1) * (view->model()->rowCount()+1) + 1;
+ } else if (iface->role(0) == QAccessible::Pane) {
+ return 1; // corner button
+ } else {
+ qWarning() << "WARNING QAccessibleTable2::indexOfChild Fix my children..."
+ << iface->role(0) << iface->text(QAccessible::Name, 0);
+ }
+ // FIXME: we are in denial of our children. this should stop.
+ return -1;
+}
+
+QString QAccessibleTable2::text(Text t, int child) const
+{
+ Q_ASSERT(child == 0);
+ if (t == QAccessible::Description)
+ return view->accessibleDescription();
+ return view->accessibleName();
+}
+
+QRect QAccessibleTable2::rect(int child) const
+{
+ Q_ASSERT(!child);
+ if (!view->isVisible())
+ return QRect();
+ QPoint pos = view->mapToGlobal(QPoint(0, 0));
+ return QRect(pos.x(), pos.y(), view->width(), view->height());
+}
+
+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;
+ }
+ case QAccessible::Child: {
+ Q_ASSERT(index > 0);
+ *iface = childFromLogical(index);
+ if (*iface) {
+ return 0;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return -1;
+}
+
+QAccessible::Relation QAccessibleTable2::relationTo(int, const QAccessibleInterface *, int) const
+{
+ return QAccessible::Unrelated;
+}
+
+#ifndef QT_NO_ACTION
+int QAccessibleTable2::userActionCount(int) const
+{
+ return 0;
+}
+QString QAccessibleTable2::actionText(int, Text, int) const
+{
+ return QString();
+}
+bool QAccessibleTable2::doAction(int, int, const QVariantList &)
+{
+ return false;
+}
+#endif
+
+
+// TREE VIEW
+
+QModelIndex QAccessibleTree::indexFromLogical(int row, int column) const
+{
+ const QTreeView *treeView = qobject_cast<const QTreeView*>(view);
+ QModelIndex modelIndex = treeView->d_func()->viewItems.at(row).index;
+
+ if (modelIndex.isValid() && column > 0) {
+ modelIndex = view->model()->index(modelIndex.row(), column, modelIndex.parent());
+ }
+ return modelIndex;
+}
+
+int QAccessibleTree::childAt(int x, int y) const
+{
+ QPoint viewportOffset = view->viewport()->mapTo(view, QPoint(0,0));
+ QPoint indexPosition = view->mapFromGlobal(QPoint(x, y) - viewportOffset);
+
+ QModelIndex index = view->indexAt(indexPosition);
+ if (!index.isValid())
+ return -1;
+
+ const QTreeView *treeView = qobject_cast<const QTreeView*>(view);
+ int row = treeView->d_func()->viewIndex(index) + (horizontalHeader() ? 1 : 0);
+ int column = index.column();
+
+ int i = row * view->model()->columnCount() + column + 1;
+ Q_ASSERT(i > view->model()->columnCount());
+ return i;
+}
+
+int QAccessibleTree::childCount() const
+{
+ const QTreeView *treeView = qobject_cast<const QTreeView*>(view);
+ Q_ASSERT(treeView);
+ if (!view->model())
+ return 0;
+
+ int hHeader = horizontalHeader() ? 1 : 0;
+ return (treeView->d_func()->viewItems.count() + hHeader)* view->model()->columnCount();
+}
+
+int QAccessibleTree::rowCount() const
+{
+ const QTreeView *treeView = qobject_cast<const QTreeView*>(view);
+ Q_ASSERT(treeView);
+ return treeView->d_func()->viewItems.count();
+}
+
+int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const
+{
+ if (iface->role(0) == QAccessible::TreeItem) {
+ const QAccessibleTable2Cell* cell = static_cast<const QAccessibleTable2Cell*>(iface);
+ const QTreeView *treeView = qobject_cast<const QTreeView*>(view);
+ Q_ASSERT(treeView);
+ int row = treeView->d_func()->viewIndex(cell->m_index) + (horizontalHeader() ? 1 : 0);
+ int column = cell->m_index.column();
+
+ int index = row * view->model()->columnCount() + column + 1;
+ //qDebug() << "QAccessibleTree::indexOfChild r " << row << " c " << column << "index " << index;
+ Q_ASSERT(index > treeView->model()->columnCount());
+ return index;
+ } else if (iface->role(0) == QAccessible::ColumnHeader){
+ const QAccessibleTable2HeaderCell* cell = static_cast<const QAccessibleTable2HeaderCell*>(iface);
+ //qDebug() << "QAccessibleTree::indexOfChild header " << cell->index << "is: " << cell->index + 1;
+ return cell->index + 1;
+ } else {
+ qWarning() << "WARNING QAccessibleTable2::indexOfChild invalid child"
+ << iface->role(0) << iface->text(QAccessible::Name, 0);
+ }
+ // FIXME: add scrollbars and don't just ignore them
+ return -1;
+}
+
+int QAccessibleTree::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const
+{
+ switch (relation) {
+ case QAccessible::Child: {
+ Q_ASSERT(index > 0);
+ --index;
+ int hHeader = horizontalHeader() ? 1 : 0;
+
+ if (hHeader) {
+ if (index < view->model()->columnCount()) {
+ *iface = new QAccessibleTable2HeaderCell(view, index, Qt::Horizontal);
+ return 0;
+ } else {
+ index -= view->model()->columnCount();
+ }
+ }
+
+ int row = index / view->model()->columnCount();
+ int column = index % view->model()->columnCount();
+ QModelIndex modelIndex = indexFromLogical(row, column);
+ if (modelIndex.isValid()) {
+ *iface = cell(modelIndex);
+ return 0;
+ }
+ return -1;
+ }
+ default:
+ break;
+ }
+ return QAccessibleTable2::navigate(relation, index, iface);
+}
+
+QAccessible::Relation QAccessibleTree::relationTo(int, const QAccessibleInterface *, int) const
+{
+ return QAccessible::Unrelated;
+}
+
+QAccessibleTable2CellInterface *QAccessibleTree::cellAt(int row, int column) const
+{
+ QModelIndex index = indexFromLogical(row, column);
+ if (!index.isValid()) {
+ qWarning() << "Requested invalid tree cell: " << row << column;
+ return 0;
+ }
+ return new QAccessibleTable2Cell(view, index, cellRole());
+}
+
+QString QAccessibleTree::rowDescription(int) const
+{
+ return QString(); // no headers for rows in trees
+}
+
+bool QAccessibleTree::isRowSelected(int row) const
+{
+ QModelIndex index = indexFromLogical(row);
+ return view->selectionModel()->isRowSelected(index.row(), index.parent());
+}
+
+bool QAccessibleTree::selectRow(int row)
+{
+ QModelIndex index = indexFromLogical(row);
+ if (!index.isValid() || view->selectionMode() & QAbstractItemView::NoSelection)
+ return false;
+ view->selectionModel()->select(index, QItemSelectionModel::Select);
+ return true;
+}
+
+// TABLE CELL
+
+QAccessibleTable2Cell::QAccessibleTable2Cell(QAbstractItemView *view_, const QModelIndex &index_, QAccessible::Role role_)
+ : /* QAccessibleSimpleEditableTextInterface(this), */ view(view_), m_index(index_), m_role(role_)
+{
+ Q_ASSERT(index_.isValid());
+}
+
+int QAccessibleTable2Cell::columnExtent() const { return 1; }
+int QAccessibleTable2Cell::rowExtent() const { return 1; }
+
+QList<QAccessibleInterface*> QAccessibleTable2Cell::rowHeaderCells() const
+{
+ QList<QAccessibleInterface*> headerCell;
+ if (verticalHeader()) {
+ headerCell.append(new QAccessibleTable2HeaderCell(view, m_index.row(), Qt::Vertical));
+ }
+ return headerCell;
+}
+
+QList<QAccessibleInterface*> QAccessibleTable2Cell::columnHeaderCells() const
+{
+ QList<QAccessibleInterface*> headerCell;
+ if (horizontalHeader()) {
+ headerCell.append(new QAccessibleTable2HeaderCell(view, m_index.column(), Qt::Horizontal));
+ }
+ return headerCell;
+}
+
+QHeaderView *QAccessibleTable2Cell::horizontalHeader() const
+{
+ QHeaderView *header = 0;
+
+ if (false) {
+#ifndef QT_NO_TABLEVIEW
+ } else if (const QTableView *tv = qobject_cast<const QTableView*>(view)) {
+ header = tv->horizontalHeader();
+#endif
+#ifndef QT_NO_TREEVIEW
+ } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view)) {
+ header = tv->header();
+#endif
+ }
+
+ return header;
+}
+
+QHeaderView *QAccessibleTable2Cell::verticalHeader() const
+{
+ QHeaderView *header = 0;
+#ifndef QT_NO_TABLEVIEW
+ if (const QTableView *tv = qobject_cast<const QTableView*>(view))
+ header = tv->verticalHeader();
+#endif
+ return header;
+}
+
+int QAccessibleTable2Cell::columnIndex() const
+{
+ return m_index.column();
+}
+
+int QAccessibleTable2Cell::rowIndex() const
+{
+ if (role(0) == QAccessible::TreeItem) {
+ const QTreeView *treeView = qobject_cast<const QTreeView*>(view);
+ Q_ASSERT(treeView);
+ int row = treeView->d_func()->viewIndex(m_index);
+ return row;
+ }
+ return m_index.row();
+}
+
+bool QAccessibleTable2Cell::isSelected() const
+{
+ return view->selectionModel()->isSelected(m_index);
+}
+
+void QAccessibleTable2Cell::rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const
+{
+ *row = m_index.row();
+ *column = m_index.column();
+ *rowExtents = 1;
+ *columnExtents = 1;
+ *selected = isSelected();
+}
+
+QAccessibleTable2Interface* QAccessibleTable2Cell::table() const
+{
+ return QAccessible::queryAccessibleInterface(view)->table2Interface();
+}
+
+QAccessible::Role QAccessibleTable2Cell::role(int child) const
+{
+ Q_ASSERT(child == 0);
+ return m_role;
+}
+
+QAccessible::State QAccessibleTable2Cell::state(int child) const
+{
+ Q_ASSERT(child == 0);
+ State st = Normal;
+
+ QRect globalRect = view->rect();
+ globalRect.translate(view->mapToGlobal(QPoint(0,0)));
+ if (!globalRect.intersects(rect(0)))
+ st |= Invisible;
+
+ if (view->selectionModel()->isSelected(m_index))
+ st |= Selected;
+ if (view->selectionModel()->currentIndex() == m_index)
+ st |= Focused;
+ if (m_index.model()->data(m_index, Qt::CheckStateRole).toInt() == Qt::Checked)
+ st |= Checked;
+
+ Qt::ItemFlags flags = m_index.flags();
+ if (flags & Qt::ItemIsSelectable) {
+ st |= Selectable;
+ st |= Focusable;
+ if (view->selectionMode() == QAbstractItemView::MultiSelection)
+ st |= MultiSelectable;
+ if (view->selectionMode() == QAbstractItemView::ExtendedSelection)
+ st |= ExtSelectable;
+ }
+ if (m_role == QAccessible::TreeItem) {
+ const QTreeView *treeView = qobject_cast<const QTreeView*>(view);
+ if (treeView->isExpanded(m_index))
+ st |= Expanded;
+ }
+ return st;
+}
+
+bool QAccessibleTable2Cell::isExpandable() const
+{
+ return view->model()->hasChildren(m_index);
+}
+
+QRect QAccessibleTable2Cell::rect(int child) const
+{
+ Q_ASSERT(child == 0);
+
+ QRect r;
+ r = view->visualRect(m_index);
+
+ if (!r.isNull())
+ r.translate(view->viewport()->mapTo(view, QPoint(0,0)));
+ r.translate(view->mapToGlobal(QPoint(0, 0)));
+ return r;
+}
+
+QString QAccessibleTable2Cell::text(Text t, int child) const
+{
+ Q_ASSERT(child == 0);
+ QAbstractItemModel *model = view->model();
+ QString value;
+ switch (t) {
+ case QAccessible::Value:
+ case QAccessible::Name:
+ value = model->data(m_index, Qt::AccessibleTextRole).toString();
+ if (value.isEmpty())
+ value = model->data(m_index, Qt::DisplayRole).toString();
+ break;
+ case QAccessible::Description:
+ value = model->data(m_index, Qt::AccessibleDescriptionRole).toString();
+ break;
+ default:
+ break;
+ }
+ return value;
+}
+
+void QAccessibleTable2Cell::setText(Text /*t*/, int child, const QString &text)
+{
+ Q_ASSERT(child == 0);
+ if (!m_index.flags() & Qt::ItemIsEditable)
+ return;
+ view->model()->setData(m_index, text);
+}
+
+bool QAccessibleTable2Cell::isValid() const
+{
+ if (!m_index.isValid()) {
+ qDebug() << "Interface is not valid";
+ }
+
+ return m_index.isValid();
+}
+
+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);
+ }
+ return 0;
+ }
+
+ *iface = 0;
+ if (!view)
+ return -1;
+
+ switch (relation) {
+
+ case Child: {
+ return -1;
+ }
+ case Sibling:
+ if (index > 0) {
+ QAccessibleInterface *parent = queryAccessibleInterface(view);
+ int ret = parent->navigate(QAccessible::Child, index, iface);
+ delete parent;
+ if (*iface)
+ return ret;
+ }
+ return -1;
+
+// From table1 implementation:
+// case Up:
+// case Down:
+// case Left:
+// case Right: {
+// // This is in the "not so nice" category. In order to find out which item
+// // is geometrically around, we have to set the current index, navigate
+// // and restore the index as well as the old selection
+// view->setUpdatesEnabled(false);
+// const QModelIndex oldIdx = view->currentIndex();
+// QList<QModelIndex> kids = children();
+// const QModelIndex currentIndex = index ? kids.at(index - 1) : QModelIndex(row);
+// const QItemSelection oldSelection = view->selectionModel()->selection();
+// view->setCurrentIndex(currentIndex);
+// const QModelIndex idx = view->moveCursor(toCursorAction(relation), Qt::NoModifier);
+// view->setCurrentIndex(oldIdx);
+// view->selectionModel()->select(oldSelection, QItemSelectionModel::ClearAndSelect);
+// view->setUpdatesEnabled(true);
+// if (!idx.isValid())
+// return -1;
+
+// if (idx.parent() != row.parent() || idx.row() != row.row())
+// *iface = cell(idx);
+// return index ? kids.indexOf(idx) + 1 : 0; }
+ default:
+ break;
+ }
+
+ return -1;
+}
+
+QAccessible::Relation QAccessibleTable2Cell::relationTo(int child, const QAccessibleInterface *other, int otherChild) const
+{
+ Q_ASSERT(child == 0);
+ Q_ASSERT(otherChild == 0);
+ // we only check for parent-child relationships in trees
+ if (m_role == QAccessible::TreeItem && other->role(0) == QAccessible::TreeItem) {
+ QModelIndex otherIndex = static_cast<const QAccessibleTable2Cell*>(other)->m_index;
+ // is the other our parent?
+ if (otherIndex.parent() == m_index)
+ return QAccessible::Ancestor;
+ // are we the other's child?
+ if (m_index.parent() == otherIndex)
+ return QAccessible::Child;
+ }
+ return QAccessible::Unrelated;
+}
+
+#ifndef QT_NO_ACTION
+int QAccessibleTable2Cell::userActionCount(int) const
+{
+ return 0;
+}
+
+QString QAccessibleTable2Cell::actionText(int, Text, int) const
+{
+ return QString();
+}
+
+bool QAccessibleTable2Cell::doAction(int, int, const QVariantList &)
+{
+ return false;
+}
+
+QAccessibleTable2HeaderCell::QAccessibleTable2HeaderCell(QAbstractItemView *view_, int index_, Qt::Orientation orientation_)
+ : view(view_), index(index_), orientation(orientation_)
+{
+ Q_ASSERT(index_ >= 0);
+}
+
+QAccessible::Role QAccessibleTable2HeaderCell::role(int child) const
+{
+ Q_ASSERT(child == 0);
+ if (orientation == Qt::Horizontal)
+ return QAccessible::ColumnHeader;
+ return QAccessible::RowHeader;
+}
+
+QAccessible::State QAccessibleTable2HeaderCell::state(int child) const
+{
+ Q_ASSERT(child == 0);
+ return QAccessible::Normal;
+}
+
+QRect QAccessibleTable2HeaderCell::rect(int child) const
+{
+ Q_ASSERT(child == 0);
+
+ QHeaderView *header = 0;
+ if (false) {
+#ifndef QT_NO_TABLEVIEW
+ } else if (const QTableView *tv = qobject_cast<const QTableView*>(view)) {
+ if (orientation == Qt::Horizontal) {
+ header = tv->horizontalHeader();
+ } else {
+ header = tv->verticalHeader();
+ }
+#endif
+#ifndef QT_NO_TREEVIEW
+ } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view)) {
+ header = tv->header();
+#endif
+ }
+ QPoint zero = header->mapToGlobal(QPoint(0, 0));
+ int sectionSize = header->sectionSize(index);
+ int sectionPos = header->sectionPosition(index);
+ return orientation == Qt::Horizontal
+ ? QRect(zero.x() + sectionPos, zero.y(), sectionSize, header->height())
+ : QRect(zero.x(), zero.y() + sectionPos, header->width(), sectionSize);
+}
+
+QString QAccessibleTable2HeaderCell::text(Text t, int child) const
+{
+ Q_ASSERT(child == 0);
+ QAbstractItemModel *model = view->model();
+ QString value;
+ switch (t) {
+ case QAccessible::Value:
+ case QAccessible::Name:
+ value = model->headerData(index, orientation, Qt::AccessibleTextRole).toString();
+ if (value.isEmpty())
+ value = model->headerData(index, orientation, Qt::DisplayRole).toString();
+ break;
+ case QAccessible::Description:
+ value = model->headerData(index, orientation, Qt::AccessibleDescriptionRole).toString();
+ break;
+ default:
+ break;
+ }
+ return value;
+}
+
+void QAccessibleTable2HeaderCell::setText(Text, int, const QString &)
+{
+ return;
+}
+
+bool QAccessibleTable2HeaderCell::isValid() const
+{
+ return true;
+}
+
+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 = 0;
+ return -1;
+}
+
+QAccessible::Relation QAccessibleTable2HeaderCell::relationTo(int, const QAccessibleInterface *, int) const
+{
+ return QAccessible::Unrelated;
+}
+
+#ifndef QT_NO_ACTION
+int QAccessibleTable2HeaderCell::userActionCount(int) const
+{
+ return 0;
+}
+
+QString QAccessibleTable2HeaderCell::actionText(int, Text, int) const
+{
+ return QString();
+}
+
+bool QAccessibleTable2HeaderCell::doAction(int, int, const QVariantList &)
+{
+ return false;
+}
+#endif
+
+
+
+#endif
+
+#endif // QT_NO_ITEMVIEWS
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_ACCESSIBILITY
diff --git a/src/plugins/accessible/widgets/itemviews.h b/src/plugins/accessible/widgets/itemviews.h
new file mode 100644
index 0000000000..c8492e3c89
--- /dev/null
+++ b/src/plugins/accessible/widgets/itemviews.h
@@ -0,0 +1,319 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ACCESSIBLE_ITEMVIEWS_H
+#define ACCESSIBLE_ITEMVIEWS_H
+
+#include <QtGui/qabstractitemview.h>
+#include <QtGui/qheaderview.h>
+#include <QtGui/qaccessible.h>
+#include <QtGui/qaccessible2.h>
+#include <QtGui/qaccessiblewidget.h>
+
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_ACCESSIBILITY
+
+#ifndef QT_NO_ITEMVIEWS
+
+class QAccessibleTable2Cell;
+class QAccessibleTable2HeaderCell;
+
+class QAccessibleTable2: public QAccessibleTable2Interface, public QAccessibleObjectEx
+{
+ Q_ACCESSIBLE_OBJECT
+public:
+ explicit QAccessibleTable2(QWidget *w);
+
+ virtual ~QAccessibleTable2();
+
+ QObject *object() const { return view; }
+ Role role(int child) const;
+ State state(int child) const;
+ QString text(Text t, int child) const;
+ QRect rect(int child) const;
+
+ int childAt(int x, int y) const;
+ int childCount() const;
+ int indexOfChild(const QAccessibleInterface *) const;
+
+ int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const;
+ Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const;
+
+#ifndef QT_NO_ACTION
+ int userActionCount(int child) const;
+ QString actionText(int action, Text t, int child) const;
+ bool doAction(int action, int child, const QVariantList &params);
+#endif
+ QVariant invokeMethodEx(Method, int, const QVariantList &) { return QVariant(); }
+
+ // table2 interface
+ virtual QAccessibleTable2CellInterface *cellAt(int row, int column) const;
+ virtual QAccessibleInterface *caption() const;
+ virtual QAccessibleInterface *summary() const;
+ virtual QString columnDescription(int column) const;
+ virtual QString rowDescription(int row) const;
+ virtual int columnCount() const;
+ virtual int rowCount() const;
+ virtual QAccessible2::TableModelChange modelChange() const;
+
+ // selection
+ virtual int selectedCellCount() const;
+ virtual int selectedColumnCount() const;
+ virtual int selectedRowCount() const;
+ virtual QList<QAccessibleTable2CellInterface*> selectedCells() const;
+ virtual QList<int> selectedColumns() const;
+ virtual QList<int> selectedRows() const;
+ virtual bool isColumnSelected(int column) const;
+ virtual bool isRowSelected(int row) const;
+ virtual bool selectRow(int row);
+ virtual bool selectColumn(int column);
+ virtual bool unselectRow(int row);
+ virtual bool unselectColumn(int column);
+
+protected:
+ virtual void modelReset();
+ virtual void rowsInserted(const QModelIndex &parent, int first, int last);
+ virtual void rowsRemoved(const QModelIndex &parent, int first, int last);
+ virtual void columnsInserted(const QModelIndex &parent, int first, int last);
+ virtual void columnsRemoved(const QModelIndex &parent, int first, int last);
+ virtual void rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row);
+ virtual void columnsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int column);
+
+protected:
+ QAbstractItemView* view;
+ QAccessible2::TableModelChange lastChange;
+ inline QAccessibleTable2Cell *cell(const QModelIndex &index) const;
+ inline QAccessible::Role cellRole() const {
+ switch (m_role) {
+ case QAccessible::List:
+ return QAccessible::ListItem;
+ case QAccessible::Table:
+ return QAccessible::Cell;
+ case QAccessible::Tree:
+ return QAccessible::TreeItem;
+ default:
+ Q_ASSERT(0);
+ }
+ return QAccessible::NoRole;
+ }
+
+ QHeaderView *horizontalHeader() const;
+ QHeaderView *verticalHeader() const;
+private:
+ // the child index for a model index
+ inline int logicalIndex(const QModelIndex &index) const;
+ // the model index from the child index
+ QAccessibleInterface *childFromLogical(int logicalIndex) const;
+ QAccessible::Role m_role;
+};
+
+class QAccessibleTree :public QAccessibleTable2
+{
+public:
+ explicit QAccessibleTree(QWidget *w)
+ : QAccessibleTable2(w)
+ {}
+
+ virtual ~QAccessibleTree() {}
+
+ int childAt(int x, int y) const;
+ int childCount() const;
+ int indexOfChild(const QAccessibleInterface *) const;
+
+ int rowCount() const;
+
+ int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const;
+ Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const;
+
+ // table2 interface
+ QAccessibleTable2CellInterface *cellAt(int row, int column) const;
+ QString rowDescription(int row) const;
+ bool isRowSelected(int row) const;
+ bool selectRow(int row);
+
+private:
+ QModelIndex indexFromLogical(int row, int column = 0) const;
+};
+
+class QAccessibleTable2Cell: public QAccessibleTable2CellInterface /*), public QAccessibleTextInterface, public QAccessibleSimpleEditableTextInterface*/
+{
+public:
+ QAccessibleTable2Cell(QAbstractItemView *view, const QModelIndex &m_index, QAccessible::Role role);
+
+ QObject *object() const { return 0; }
+ Role role(int child) const;
+ State state(int child) const;
+ QRect rect(int child) const;
+ bool isValid() const;
+
+ int childAt(int, int) const { return 0; }
+ int childCount() const { return 0; }
+ int indexOfChild(const QAccessibleInterface *) const { return -1; }
+
+ QString text(Text t, int child) const;
+ void setText(Text t, int child, const QString &text);
+
+ int navigate(RelationFlag relation, int m_index, QAccessibleInterface **iface) const;
+ Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const;
+
+ bool isExpandable() const;
+
+#ifndef QT_NO_ACTION
+ int userActionCount(int child) const;
+ QString actionText(int action, Text t, int child) const;
+ bool doAction(int action, int child, const QVariantList &params);
+#endif
+
+ // cell interface
+ virtual int columnExtent() const;
+ virtual QList<QAccessibleInterface*> columnHeaderCells() const;
+ virtual int columnIndex() const;
+ virtual int rowExtent() const;
+ virtual QList<QAccessibleInterface*> rowHeaderCells() const;
+ virtual int rowIndex() const;
+ virtual bool isSelected() const;
+ virtual void rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const;
+ virtual QAccessibleTable2Interface* table() const;
+
+private:
+ QHeaderView *verticalHeader() const;
+ QHeaderView *horizontalHeader() const;
+ QAbstractItemView *view;
+ QModelIndex m_index;
+ QAccessible::Role m_role;
+
+friend class QAccessibleTable2;
+friend class QAccessibleTree;
+};
+
+
+class QAccessibleTable2HeaderCell: public QAccessibleInterface /*), public QAccessibleTextInterface, public QAccessibleSimpleEditableTextInterface*/
+{
+public:
+ // For header cells, pass the header view in addition
+ QAccessibleTable2HeaderCell(QAbstractItemView *view, int index, Qt::Orientation orientation);
+
+ QObject *object() const { return 0; }
+ Role role(int child) const;
+ State state(int child) const;
+ QRect rect(int child) const;
+ bool isValid() const;
+
+ int childAt(int, int) const { return 0; }
+ int childCount() const { return 0; }
+ int indexOfChild(const QAccessibleInterface *) const { return -1; }
+
+ QString text(Text t, int child) const;
+ void setText(Text t, int child, const QString &text);
+
+ int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const;
+ Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const;
+
+#ifndef QT_NO_ACTION
+ int userActionCount(int child) const;
+ QString actionText(int action, Text t, int child) const;
+ bool doAction(int action, int child, const QVariantList &params);
+#endif
+
+private:
+ QAbstractItemView *view;
+ int index;
+ Qt::Orientation orientation;
+
+friend class QAccessibleTable2;
+friend class QAccessibleTree;
+};
+
+// This is the corner button on the top left of a table.
+// It can be used to select all cells or it is not active at all.
+// For now it is ignored.
+class QAccessibleTable2CornerButton: public QAccessibleInterface
+{
+public:
+ QAccessibleTable2CornerButton(QAbstractItemView *view_)
+ :view(view_)
+ {}
+
+ QObject *object() const { return 0; }
+ Role role(int child) const { Q_ASSERT(child == 0); return QAccessible::Pane; }
+ State state(int child) const { Q_ASSERT(child == 0); return QAccessible::Normal; }
+ QRect rect(int child) const { Q_ASSERT(child == 0); return QRect(); }
+ bool isValid() const { return true; }
+
+ int childAt(int, int) const { return 0; }
+ int childCount() const { return 0; }
+ int indexOfChild(const QAccessibleInterface *) const { return -1; }
+
+ QString text(Text, int) const { return QString(); }
+ void setText(Text, int, const QString &) {}
+
+ int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const
+ {
+ if (relation == QAccessible::Ancestor && index == 1) {
+ *iface = QAccessible::queryAccessibleInterface(view);
+ return 0;
+ }
+ return -1;
+ }
+ Relation relationTo(int, const QAccessibleInterface *, int) const
+ {
+ return QAccessible::Unrelated;
+ }
+
+#ifndef QT_NO_ACTION
+ int userActionCount(int) const { return 0; }
+ QString actionText(int, Text, int) const { return QString(); }
+ bool doAction(int, int, const QVariantList &) { return false; }
+#endif
+private:
+ QAbstractItemView *view;
+};
+
+
+#endif
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
+#endif // ACCESSIBLE_ITEMVIEWS_H
diff --git a/src/plugins/accessible/widgets/main.cpp b/src/plugins/accessible/widgets/main.cpp
index aa5459c066..cd17a6e80b 100644
--- a/src/plugins/accessible/widgets/main.cpp
+++ b/src/plugins/accessible/widgets/main.cpp
@@ -44,11 +44,13 @@
#include "simplewidgets.h"
#include "rangecontrols.h"
#include "complexwidgets.h"
+#include "itemviews.h"
#include <qaccessibleplugin.h>
#include <qplugin.h>
#include <qpushbutton.h>
#include <qtoolbutton.h>
+#include <qtreeview.h>
#include <qvariant.h>
#include <qaccessible.h>
@@ -56,6 +58,7 @@
QT_BEGIN_NAMESPACE
+
class AccessibleFactory : public QAccessiblePlugin
{
public:
@@ -251,6 +254,22 @@ QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObjec
iface = new QAccessibleMenu(widget);
#endif
#ifndef QT_NO_ITEMVIEWS
+#ifdef Q_WS_X11
+ } else if (classname == QLatin1String("QAbstractItemView")) {
+ if (qobject_cast<const QTreeView*>(widget)) {
+ iface = new QAccessibleTree(widget);
+ } else {
+ iface = new QAccessibleTable2(widget);
+ }
+ } else if (classname == QLatin1String("QWidget")
+ && widget->objectName() == QLatin1String("qt_scrollarea_viewport")
+ && qobject_cast<QAbstractItemView*>(widget->parentWidget())) {
+ if (qobject_cast<const QTreeView*>(widget->parentWidget())) {
+ iface = new QAccessibleTree(widget->parentWidget());
+ } else {
+ iface = new QAccessibleTable2(widget->parentWidget());
+ }
+#else
} else if (classname == QLatin1String("QHeaderView")) {
iface = new QAccessibleHeader(widget);
} else if (classname == QLatin1String("QAbstractItemView")) {
@@ -259,7 +278,8 @@ QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObjec
&& widget->objectName() == QLatin1String("qt_scrollarea_viewport")
&& qobject_cast<QAbstractItemView*>(widget->parentWidget())) {
iface = new QAccessibleItemView(widget);
-#endif
+#endif // Q_WS_X11
+#endif // QT_NO_ITEMVIEWS
#ifndef QT_NO_TABBAR
} else if (classname == QLatin1String("QTabBar")) {
iface = new QAccessibleTabBar(widget);
diff --git a/src/plugins/accessible/widgets/widgets.pro b/src/plugins/accessible/widgets/widgets.pro
index 00d99f94e7..d1a121ec94 100644
--- a/src/plugins/accessible/widgets/widgets.pro
+++ b/src/plugins/accessible/widgets/widgets.pro
@@ -8,14 +8,18 @@ DESTDIR = $$QT.gui.plugins/accessible
QTDIR_build:REQUIRES += "contains(QT_CONFIG, accessibility)"
SOURCES += main.cpp \
- simplewidgets.cpp \
- rangecontrols.cpp \
- complexwidgets.cpp \
- qaccessiblewidgets.cpp \
- qaccessiblemenu.cpp
+ simplewidgets.cpp \
+ rangecontrols.cpp \
+ complexwidgets.cpp \
+ qaccessiblewidgets.cpp \
+ qaccessiblemenu.cpp \
+ itemviews.cpp
HEADERS += qaccessiblewidgets.h \
- simplewidgets.h \
- rangecontrols.h \
- complexwidgets.h \
- qaccessiblemenu.h
+ simplewidgets.h \
+ rangecontrols.h \
+ complexwidgets.h \
+ qaccessiblemenu.h \
+ itemviews.h
+
+