summaryrefslogtreecommitdiffstats
path: root/src/plugins/accessible/widgets
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2011-08-25 10:11:49 +0200
committerGunnar Sletta <gunnar.sletta@nokia.com>2011-08-25 12:48:52 +0200
commit04d0a9626ce61b2e05a40f9562c2bcf12e234639 (patch)
treef1643f829aedc9ac51fcc260f7df2639dfe08360 /src/plugins/accessible/widgets
parent17f3451daa286b88a52f18c802d7b158dfb653b2 (diff)
parentbdc417b3828737334723eae23097c85f70c23a33 (diff)
Merge branch 'master' into refactor
Conflicts: src/gui/kernel/qapplication_qpa.cpp src/gui/kernel/qcursor_qpa.cpp src/gui/kernel/qwindowsysteminterface_qpa.cpp src/gui/kernel/qwindowsysteminterface_qpa.h src/gui/kernel/qwindowsysteminterface_qpa_p.h src/gui/text/qtextcontrol.cpp src/plugins/platforms/wayland/wayland.pro src/widgets/accessible/qaccessible2.h src/widgets/widgets/qwidgetlinecontrol_p.h Change-Id: I5e6f4eb184159dccc67e8f13673edb884d179c74
Diffstat (limited to 'src/plugins/accessible/widgets')
-rw-r--r--src/plugins/accessible/widgets/complexwidgets.cpp12
-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/qaccessiblewidgets.cpp132
-rw-r--r--src/plugins/accessible/widgets/rangecontrols.cpp18
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.cpp57
-rw-r--r--src/plugins/accessible/widgets/widgets.pro22
8 files changed, 1550 insertions, 61 deletions
diff --git a/src/plugins/accessible/widgets/complexwidgets.cpp b/src/plugins/accessible/widgets/complexwidgets.cpp
index 8843d3edcb..563d3b9472 100644
--- a/src/plugins/accessible/widgets/complexwidgets.cpp
+++ b/src/plugins/accessible/widgets/complexwidgets.cpp
@@ -1776,16 +1776,12 @@ QString QAccessibleComboBox::text(Text t, int child) const
switch (t) {
case Name:
+#ifndef Q_WS_X11 // on Linux we use relations for this, name is text (fall through to Value)
if (child == OpenList)
str = QComboBox::tr("Open");
else
str = QAccessibleWidgetEx::text(t, 0);
break;
-#ifndef QT_NO_SHORTCUT
- case Accelerator:
- if (child == OpenList)
- str = (QString)QKeySequence(Qt::Key_Down);
- // missing break?
#endif
case Value:
if (comboBox()->isEditable())
@@ -1793,6 +1789,12 @@ QString QAccessibleComboBox::text(Text t, int child) const
else
str = comboBox()->currentText();
break;
+#ifndef QT_NO_SHORTCUT
+ case Accelerator:
+ if (child == OpenList)
+ str = (QString)QKeySequence(Qt::Key_Down);
+ break;
+#endif
default:
break;
}
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..2c981ef0e8
--- /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 <QtWidgets/qabstractitemview.h>
+#include <QtWidgets/qheaderview.h>
+#include <QtWidgets/qaccessible.h>
+#include <QtWidgets/qaccessible2.h>
+#include <QtWidgets/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/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
index b14ee88bc8..a8f38b61a3 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
@@ -73,6 +73,9 @@ QT_BEGIN_NAMESPACE
using namespace QAccessible2;
+QString Q_GUI_EXPORT qt_accStripAmp(const QString &text);
+QString Q_GUI_EXPORT qt_accHotKey(const QString &text);
+
QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel)
{
if (widget == 0)
@@ -1139,8 +1142,8 @@ int QAccessibleTitleBar::childCount() const
QString QAccessibleTitleBar::text(Text t, int child) const
{
if (!child) {
- if (t == Value) {
- return dockWidget()->windowTitle();
+ if (t == Name || t == Value) {
+ return qt_accStripAmp(dockWidget()->windowTitle());
}
}
return QString();
@@ -1171,17 +1174,19 @@ QAccessible::State QAccessibleTitleBar::state(int child) const
return state;
}
-QRect QAccessibleTitleBar::rect (int child ) const
+QRect QAccessibleTitleBar::rect(int child) const
{
bool mapToGlobal = true;
QRect rect;
if (child == 0) {
if (dockWidget()->isFloating()) {
rect = dockWidget()->frameGeometry();
- QPoint globalPos = dockWidget()->mapToGlobal( dockWidget()->widget()->rect().topLeft() );
- globalPos.ry()--;
- rect.setBottom(globalPos.y());
- mapToGlobal = false;
+ if (dockWidget()->widget()) {
+ QPoint globalPos = dockWidget()->mapToGlobal(dockWidget()->widget()->rect().topLeft());
+ globalPos.ry()--;
+ rect.setBottom(globalPos.y());
+ mapToGlobal = false;
+ }
} else {
QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
rect = layout->titleArea();
@@ -1316,11 +1321,112 @@ void QAccessibleTextEdit::addSelection(int startOffset, int endOffset)
QString QAccessibleTextEdit::attributes(int offset, int *startOffset, int *endOffset)
{
- // TODO - wait for a definition of attributes
- Q_UNUSED(offset);
- Q_UNUSED(startOffset);
- Q_UNUSED(endOffset);
- return QString();
+ /* The list of attributes can be found at:
+ http://linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2/textattributes
+ */
+
+ if (offset >= characterCount()) {
+ *startOffset = -1;
+ *endOffset = -1;
+ return QString();
+ }
+
+ QMap<QString, QString> attrs;
+
+ QTextCursor cursor = textEdit()->textCursor();
+
+ //cursor.charFormat returns the format of the previous character
+ cursor.setPosition(offset + 1);
+ QTextCharFormat charFormat = cursor.charFormat();
+
+ cursor.setPosition(offset);
+ QTextBlockFormat blockFormat = cursor.blockFormat();
+
+ QTextCharFormat charFormatComp;
+ QTextBlockFormat blockFormatComp;
+
+ *startOffset = offset;
+ cursor.setPosition(*startOffset);
+ while (*startOffset > 0) {
+ charFormatComp = cursor.charFormat();
+ cursor.setPosition(*startOffset - 1);
+ blockFormatComp = cursor.blockFormat();
+ if ((charFormat == charFormatComp) && (blockFormat == blockFormatComp))
+ (*startOffset)--;
+ else
+ break;
+ }
+
+ int limit = characterCount() + 1;
+ *endOffset = offset + 1;
+ cursor.setPosition(*endOffset);
+ while (*endOffset < limit) {
+ blockFormatComp = cursor.blockFormat();
+ cursor.setPosition(*endOffset + 1);
+ charFormatComp = cursor.charFormat();
+ if ((charFormat == charFormatComp) && (cursor.blockFormat() == blockFormatComp))
+ (*endOffset)++;
+ else
+ break;
+ }
+
+ QString family = charFormat.fontFamily();
+ if (!family.isEmpty()) {
+ family = family.replace('\\',"\\\\");
+ family = family.replace(':',"\\:");
+ family = family.replace(',',"\\,");
+ family = family.replace('=',"\\=");
+ family = family.replace(';',"\\;");
+ family = family.replace('\"',"\\\"");
+ attrs["font-family"] = '"'+family+'"';
+ }
+
+ int fontSize = int(charFormat.fontPointSize());
+ if (fontSize)
+ attrs["font-size"] = QString::number(fontSize).append("pt");
+
+ //Different weight values are not handled
+ attrs["font-weight"] = (charFormat.fontWeight() > QFont::Normal) ? "bold" : "normal";
+
+ QFont::Style style = charFormat.font().style();
+ attrs["font-style"] = (style == QFont::StyleItalic) ? "italic" : ((style == QFont::StyleOblique) ? "oblique": "normal");
+
+ attrs["text-underline-style"] = charFormat.font().underline() ? "solid" : "none";
+
+ QTextCharFormat::VerticalAlignment alignment = charFormat.verticalAlignment();
+ attrs["text-position"] = (alignment == QTextCharFormat::AlignSubScript) ? "sub" : ((alignment == QTextCharFormat::AlignSuperScript) ? "super" : "baseline" );
+
+ QBrush background = charFormat.background();
+ if (background.style() == Qt::SolidPattern) {
+ attrs["background-color"] = QString("rgb(%1,%2,%3)").arg(background.color().red()).arg(background.color().green()).arg(background.color().blue());
+ }
+
+ QBrush foreground = charFormat.foreground();
+ if (foreground.style() == Qt::SolidPattern) {
+ attrs["color"] = QString("rgb(%1,%2,%3)").arg(foreground.color().red()).arg(foreground.color().green()).arg(foreground.color().blue());
+ }
+
+ switch (blockFormat.alignment() & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignHCenter | Qt::AlignJustify)) {
+ case Qt::AlignLeft:
+ attrs["text-align"] = "left";
+ break;
+ case Qt::AlignRight:
+ attrs["text-align"] = "right";
+ break;
+ case Qt::AlignHCenter:
+ attrs["text-align"] = "center";
+ break;
+ case Qt::AlignJustify:
+ attrs["text-align"] = "left";
+ break;
+ }
+
+ QString result;
+ foreach (const QString &attributeName, attrs.keys()) {
+ result.append(attributeName).append(':').append(attrs[attributeName]).append(';');
+ }
+
+ return result;
}
int QAccessibleTextEdit::cursorPosition()
@@ -1435,9 +1541,9 @@ QString QAccessibleTextEdit::textAtOffset(int offset, BoundaryType boundaryType,
if (offset >= characterCount())
return QString();
+ cursor.setPosition(offset);
switch (boundaryType) {
case CharBoundary:
- cursor.setPosition(offset);
*startOffset = cursor.position();
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
*endOffset = cursor.position();
diff --git a/src/plugins/accessible/widgets/rangecontrols.cpp b/src/plugins/accessible/widgets/rangecontrols.cpp
index fb53b10567..8868d53dc7 100644
--- a/src/plugins/accessible/widgets/rangecontrols.cpp
+++ b/src/plugins/accessible/widgets/rangecontrols.cpp
@@ -83,8 +83,6 @@ QAbstractSpinBox *QAccessibleAbstractSpinBox::abstractSpinBox() const
/*! \reimp */
int QAccessibleAbstractSpinBox::childCount() const
{
- if (!abstractSpinBox()->isVisible())
- return 0;
return ValueDown;
}
@@ -344,8 +342,6 @@ QDoubleSpinBox *QAccessibleDoubleSpinBox::doubleSpinBox() const
/*! \reimp */
int QAccessibleDoubleSpinBox::childCount() const
{
- if (!doubleSpinBox()->isVisible())
- return 0;
return ValueDown;
}
@@ -410,8 +406,6 @@ QVariant QAccessibleDoubleSpinBox::invokeMethodEx(QAccessible::Method, int, cons
/*! \reimp */
QString QAccessibleDoubleSpinBox::text(Text textType, int child) const
{
- if (!doubleSpinBox()->isVisible())
- return QString();
switch (textType) {
case Name:
if (child == ValueUp)
@@ -540,16 +534,12 @@ QRect QAccessibleScrollBar::rect(int child) const
/*! \reimp */
int QAccessibleScrollBar::childCount() const
{
- if (!scrollBar()->isVisible())
- return 0;
return LineDown;
}
/*! \reimp */
QString QAccessibleScrollBar::text(Text t, int child) const
{
- if (!scrollBar()->isVisible())
- return QString();
switch (t) {
case Value:
if (!child || child == Position)
@@ -698,16 +688,12 @@ QRect QAccessibleSlider::rect(int child) const
/*! \reimp */
int QAccessibleSlider::childCount() const
{
- if (!slider()->isVisible())
- return 0;
return PageRight;
}
/*! \reimp */
QString QAccessibleSlider::text(Text t, int child) const
{
- if (!slider()->isVisible())
- return QString();
switch (t) {
case Value:
if (!child || child == 2)
@@ -932,15 +918,11 @@ QRect QAccessibleDial::rect(int child) const
int QAccessibleDial::childCount() const
{
- if (!dial()->isVisible())
- return 0;
return SliderHandle;
}
QString QAccessibleDial::text(Text textType, int child) const
{
- if (!dial()->isVisible())
- return QString();
if (textType == Value && child >= Self && child <= SliderHandle)
return QString::number(dial()->value());
if (textType == Name) {
diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp
index 70a182f2df..36e786ff6b 100644
--- a/src/plugins/accessible/widgets/simplewidgets.cpp
+++ b/src/plugins/accessible/widgets/simplewidgets.cpp
@@ -68,6 +68,13 @@ extern QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel
QString Q_GUI_EXPORT qt_accStripAmp(const QString &text);
QString Q_GUI_EXPORT qt_accHotKey(const QString &text);
+QString Q_GUI_EXPORT qTextBeforeOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset, const QString& text);
+QString Q_GUI_EXPORT qTextAtOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset, const QString& text);
+QString Q_GUI_EXPORT qTextAfterOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset, const QString& text);
+
/*!
\class QAccessibleButton
\brief The QAccessibleButton class implements the QAccessibleInterface for button type widgets.
@@ -176,7 +183,7 @@ QString QAccessibleButton::text(Text t, int child) const
break;
}
if (str.isEmpty())
- str = QAccessibleWidgetEx::text(t, child);;
+ str = QAccessibleWidgetEx::text(t, child);
return qt_accStripAmp(str);
}
@@ -396,7 +403,7 @@ QString QAccessibleToolButton::text(Text t, int child) const
QString str;
switch (t) {
case Name:
- str = toolButton()->text();
+ str = toolButton()->accessibleName();
if (str.isEmpty())
str = toolButton()->text();
break;
@@ -703,7 +710,14 @@ void QAccessibleLineEdit::setText(Text t, int control, const QString &text)
QAccessibleWidgetEx::setText(t, control, text);
return;
}
- lineEdit()->setText(text);
+
+ QString newText = text;
+ if (lineEdit()->validator()) {
+ int pos = 0;
+ if (lineEdit()->validator()->validate(newText, pos) != QValidator::Acceptable)
+ return;
+ }
+ lineEdit()->setText(newText);
}
/*! \reimp */
@@ -801,28 +815,41 @@ QString QAccessibleLineEdit::text(int startOffset, int endOffset)
{
if (startOffset > endOffset)
return QString();
+
+ if (lineEdit()->echoMode() != QLineEdit::Normal)
+ return QString();
+
return lineEdit()->text().mid(startOffset, endOffset - startOffset);
}
-QString QAccessibleLineEdit::textBeforeOffset (int /*offset*/, BoundaryType /*boundaryType*/,
- int * /*startOffset*/, int * /*endOffset*/)
+QString QAccessibleLineEdit::textBeforeOffset(int offset, BoundaryType boundaryType,
+ int *startOffset, int *endOffset)
{
- // TODO
- return QString();
+ if (lineEdit()->echoMode() != QLineEdit::Normal) {
+ *startOffset = *endOffset = -1;
+ return QString();
+ }
+ return qTextBeforeOffsetFromString(offset, boundaryType, startOffset, endOffset, lineEdit()->text());
}
-QString QAccessibleLineEdit::textAfterOffset(int /*offset*/, BoundaryType /*boundaryType*/,
- int * /*startOffset*/, int * /*endOffset*/)
+QString QAccessibleLineEdit::textAfterOffset(int offset, BoundaryType boundaryType,
+ int *startOffset, int *endOffset)
{
- // TODO
- return QString();
+ if (lineEdit()->echoMode() != QLineEdit::Normal) {
+ *startOffset = *endOffset = -1;
+ return QString();
+ }
+ return qTextAfterOffsetFromString(offset, boundaryType, startOffset, endOffset, lineEdit()->text());
}
-QString QAccessibleLineEdit::textAtOffset(int /*offset*/, BoundaryType /*boundaryType*/,
- int * /*startOffset*/, int * /*endOffset*/)
+QString QAccessibleLineEdit::textAtOffset(int offset, BoundaryType boundaryType,
+ int *startOffset, int *endOffset)
{
- // TODO
- return QString();
+ if (lineEdit()->echoMode() != QLineEdit::Normal) {
+ *startOffset = *endOffset = -1;
+ return QString();
+ }
+ return qTextAtOffsetFromString(offset, boundaryType, startOffset, endOffset, lineEdit()->text());
}
void QAccessibleLineEdit::removeSelection(int selectionIndex)
diff --git a/src/plugins/accessible/widgets/widgets.pro b/src/plugins/accessible/widgets/widgets.pro
index 6dd7e5022b..3bf7dede56 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
+
+