summaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/gui/accessible/qaccessible.cpp5
-rw-r--r--src/gui/accessible/qaccessible.h10
-rw-r--r--src/gui/accessible/qaccessible2.h112
-rw-r--r--src/gui/accessible/qaccessible_unix.cpp11
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp95
-rw-r--r--src/gui/itemviews/qabstractitemview.h1
-rw-r--r--src/gui/itemviews/qabstractitemview_p.h1
-rw-r--r--src/gui/itemviews/qlistview.cpp12
-rw-r--r--src/gui/itemviews/qtableview.cpp17
-rw-r--r--src/gui/itemviews/qtableview_p.h5
-rw-r--r--src/gui/itemviews/qtreeview.cpp52
-rw-r--r--src/gui/itemviews/qtreeview.h3
-rw-r--r--src/gui/itemviews/qtreeview_p.h6
-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
17 files changed, 1693 insertions, 29 deletions
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index 337bb9992d..10e5785cd5 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -1048,6 +1048,11 @@ const QAccessibleInterface *other, int otherChild) const
*/
/*!
+ \fn QAccessibleTable2Interface *QAccessibleInterface::table2Interface()
+ \internal
+*/
+
+/*!
\fn QAccessibleActionInterface *QAccessibleInterface::actionInterface()
\internal
*/
diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h
index fc03e1cec7..16869bb926 100644
--- a/src/gui/accessible/qaccessible.h
+++ b/src/gui/accessible/qaccessible.h
@@ -151,6 +151,7 @@ public:
ReadOnly = 0x00000040,
HotTracked = 0x00000080,
DefaultButton = 0x00000100,
+ // #### Qt5 Expandable
Expanded = 0x00000200,
Collapsed = 0x00000400,
Busy = 0x00000800,
@@ -178,6 +179,8 @@ public:
HasPopup = 0x40000000,
Modal = 0x80000000,
+ // #### Qt5 ManagesDescendants
+ // #### Qt5 remove HasInvokeExtension
HasInvokeExtension = 0x10000000 // internal
};
Q_DECLARE_FLAGS(State, StateFlag)
@@ -348,7 +351,8 @@ namespace QAccessible2
ValueInterface,
TableInterface,
ActionInterface,
- ImageInterface
+ ImageInterface,
+ Table2Interface
};
}
@@ -359,6 +363,7 @@ class QAccessibleValueInterface;
class QAccessibleTableInterface;
class QAccessibleActionInterface;
class QAccessibleImageInterface;
+class QAccessibleTable2Interface;
class Q_GUI_EXPORT QAccessibleInterface : public QAccessible
{
@@ -422,6 +427,9 @@ public:
inline QAccessibleImageInterface *imageInterface()
{ return reinterpret_cast<QAccessibleImageInterface *>(cast_helper(QAccessible2::ImageInterface)); }
+ inline QAccessibleTable2Interface *table2Interface()
+ { return reinterpret_cast<QAccessibleTable2Interface *>(cast_helper(QAccessible2::Table2Interface)); }
+
private:
QAccessible2Interface *cast_helper(QAccessible2::InterfaceType);
};
diff --git a/src/gui/accessible/qaccessible2.h b/src/gui/accessible/qaccessible2.h
index 5cb03239ef..106b69efcf 100644
--- a/src/gui/accessible/qaccessible2.h
+++ b/src/gui/accessible/qaccessible2.h
@@ -52,6 +52,8 @@ QT_MODULE(Gui)
#ifndef QT_NO_ACCESSIBILITY
+class QModelIndex;
+
namespace QAccessible2
{
enum CoordinateType
@@ -68,6 +70,24 @@ namespace QAccessible2
LineBoundary,
NoBoundary
};
+
+ enum TableModelChangeType {
+ TableModelChangeInsert,
+ TableModelChangeDelete,
+ TableModelChangeUpdate
+ };
+
+ struct TableModelChange {
+ int firstColumn;
+ int firstRow;
+ int lastColumn;
+ int lastRow;
+ TableModelChangeType type;
+
+ TableModelChange()
+ : firstColumn(0), firstRow(0), lastColumn(0), lastRow(0), type(TableModelChangeUpdate)
+ {}
+ };
}
class Q_GUI_EXPORT QAccessible2Interface
@@ -83,6 +103,7 @@ inline QAccessible2Interface *qAccessibleEditableTextCastHelper() { return 0; }
inline QAccessible2Interface *qAccessibleTableCastHelper() { return 0; }
inline QAccessible2Interface *qAccessibleActionCastHelper() { return 0; }
inline QAccessible2Interface *qAccessibleImageCastHelper() { return 0; }
+inline QAccessible2Interface *qAccessibleTable2CastHelper() { return 0; }
#define Q_ACCESSIBLE_OBJECT \
public: \
@@ -101,6 +122,8 @@ inline QAccessible2Interface *qAccessibleImageCastHelper() { return 0; }
return qAccessibleActionCastHelper(); \
case QAccessible2::ImageInterface: \
return qAccessibleImageCastHelper(); \
+ case QAccessible2::Table2Interface: \
+ return qAccessibleTable2CastHelper(); \
} \
return 0; \
} \
@@ -214,6 +237,95 @@ public:
int *columnSpan, bool *isSelected) = 0;
};
+class Q_GUI_EXPORT QAccessibleTable2CellInterface: public QAccessibleInterface
+{
+public:
+ // Returns the number of columns occupied by this cell accessible.
+ virtual int columnExtent() const = 0;
+
+ // Returns the column headers as an array of cell accessibles.
+ virtual QList<QAccessibleInterface*> columnHeaderCells() const = 0;
+
+ // Translates this cell accessible into the corresponding column index.
+ virtual int columnIndex() const = 0;
+ // Returns the number of rows occupied by this cell accessible.
+ virtual int rowExtent() const = 0;
+ // Returns the row headers as an array of cell accessibles.
+ virtual QList<QAccessibleInterface*> rowHeaderCells() const = 0;
+ // Translates this cell accessible into the corresponding row index.
+ virtual int rowIndex() const = 0;
+ // Returns a boolean value indicating whether this cell is selected.
+ virtual bool isSelected() const = 0;
+
+ // Gets the row and column indexes and extents of this cell accessible and whether or not it is selected.
+ virtual void rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const = 0;
+ // Returns a reference to the accessbile of the containing table.
+ virtual QAccessibleTable2Interface* table() const = 0;
+
+ // #### Qt5 this should not be here but part of the state
+ virtual bool isExpandable() const = 0;
+};
+
+class Q_GUI_EXPORT QAccessibleTable2Interface: public QAccessible2Interface
+{
+public:
+ inline QAccessible2Interface *qAccessibleTable2CastHelper() { return this; }
+
+ // Returns the cell at the specified row and column in the table.
+ virtual QAccessibleTable2CellInterface *cellAt (int row, int column) const = 0;
+ // Returns the caption for the table.
+ virtual QAccessibleInterface *caption() const = 0;
+ // Returns the description text of the specified column in the table.
+ virtual QString columnDescription(int column) const = 0;
+ // Returns the total number of columns in table.
+ virtual int columnCount() const = 0;
+ // Returns the total number of rows in table.
+ virtual int rowCount() const = 0;
+ // Returns the total number of selected cells.
+ virtual int selectedCellCount() const = 0;
+ // Returns the total number of selected columns.
+ virtual int selectedColumnCount() const = 0;
+ // Returns the total number of selected rows.
+ virtual int selectedRowCount() const = 0;
+ // Returns the description text of the specified row in the table.
+ virtual QString rowDescription(int row) const = 0;
+ // Returns a list of accessibles currently selected.
+ virtual QList<QAccessibleTable2CellInterface*> selectedCells() const = 0;
+ // Returns a list of column indexes currently selected (0 based).
+ virtual QList<int> selectedColumns() const = 0;
+ // Returns a list of row indexes currently selected (0 based).
+ virtual QList<int> selectedRows() const = 0;
+ // Returns the summary description of the table.
+ virtual QAccessibleInterface *summary() const = 0;
+ // Returns a boolean value indicating whether the specified column is completely selected.
+ virtual bool isColumnSelected(int column) const = 0;
+ // Returns a boolean value indicating whether the specified row is completely selected.
+ virtual bool isRowSelected(int row) const = 0;
+ // Selects a row and unselects all previously selected rows.
+ virtual bool selectRow(int row) = 0;
+ // Selects a column and unselects all previously selected columns.
+ virtual bool selectColumn(int column) = 0;
+ // Unselects one row, leaving other selected rows selected (if any).
+ virtual bool unselectRow(int row) = 0;
+ // Unselects one column, leaving other selected columns selected (if any).
+ virtual bool unselectColumn(int column) = 0;
+ // Returns the type and extents describing how a table changed.
+ virtual QAccessible2::TableModelChange modelChange() const = 0;
+
+protected:
+ // These functions are called when the model changes.
+ virtual void modelReset() = 0;
+ virtual void rowsInserted(const QModelIndex &parent, int first, int last) = 0;
+ virtual void rowsRemoved(const QModelIndex &parent, int first, int last) = 0;
+ virtual void columnsInserted(const QModelIndex &parent, int first, int last) = 0;
+ virtual void columnsRemoved(const QModelIndex &parent, int first, int last) = 0;
+ virtual void rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row) = 0;
+ virtual void columnsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int column) = 0;
+
+friend class QAbstractItemView;
+friend class QAbstractItemViewPrivate;
+};
+
class Q_GUI_EXPORT QAccessibleActionInterface : public QAccessible2Interface
{
public:
diff --git a/src/gui/accessible/qaccessible_unix.cpp b/src/gui/accessible/qaccessible_unix.cpp
index a6b7ec3345..19fbe78301 100644
--- a/src/gui/accessible/qaccessible_unix.cpp
+++ b/src/gui/accessible/qaccessible_unix.cpp
@@ -103,6 +103,17 @@ void QAccessible::updateAccessibility(QObject *o, int who, Event reason)
if (!iface)
return;
+ // updates for List/Table/Tree should send child
+ if (who) {
+ QAccessibleInterface *child;
+ iface->navigate(QAccessible::Child, who, &child);
+ if (child) {
+ delete iface;
+ iface = child;
+ who = 0;
+ }
+ }
+
for (int i = 0; i < bridges()->count(); ++i)
bridges()->at(i)->notifyAccessibilityUpdate(reason, iface, who);
delete iface;
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index 6aed17c049..d3875c8961 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -60,6 +60,7 @@
#include <private/qabstractitemmodel_p.h>
#ifndef QT_NO_ACCESSIBILITY
#include <qaccessible.h>
+#include <qaccessible2.h>
#endif
#include <private/qsoftkeymanager_p.h>
#ifndef QT_NO_GESTURE
@@ -682,6 +683,8 @@ void QAbstractItemView::setModel(QAbstractItemModel *model)
this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+ disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
@@ -712,6 +715,8 @@ void QAbstractItemView::setModel(QAbstractItemModel *model)
this, SLOT(_q_headerDataChanged()));
connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(rowsInserted(QModelIndex,int,int)));
+ connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
connect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
@@ -1095,6 +1100,14 @@ void QAbstractItemView::reset()
setRootIndex(QModelIndex());
if (d->selectionModel)
d->selectionModel->reset();
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(this)->table2Interface()->modelReset();
+ QAccessible::updateAccessibility(this, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
/*!
@@ -2849,7 +2862,7 @@ void QAbstractItemView::editorDestroyed(QObject *editor)
*/
void QAbstractItemView::setHorizontalStepsPerItem(int steps)
{
- Q_UNUSED(steps);
+ Q_UNUSED(steps)
// do nothing
}
@@ -2878,7 +2891,7 @@ int QAbstractItemView::horizontalStepsPerItem() const
*/
void QAbstractItemView::setVerticalStepsPerItem(int steps)
{
- Q_UNUSED(steps);
+ Q_UNUSED(steps)
// do nothing
}
@@ -3311,12 +3324,24 @@ void QAbstractItemView::rowsAboutToBeRemoved(const QModelIndex &parent, int star
rows are those under the given \a parent from \a start to \a end
inclusive.
*/
-void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &, int, int)
+void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &index, int start, int end)
{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
Q_Q(QAbstractItemView);
if (q->isVisible())
q->updateEditorGeometries();
q->setState(QAbstractItemView::NoState);
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->rowsRemoved(index, start, end);
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
/*!
@@ -3379,27 +3404,72 @@ void QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &par
rows are those under the given \a parent from \a start to \a end
inclusive.
*/
-void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &, int, int)
+void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &index, int start, int end)
{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
Q_Q(QAbstractItemView);
if (q->isVisible())
q->updateEditorGeometries();
q->setState(QAbstractItemView::NoState);
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->columnsRemoved(index, start, end);
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
+
/*!
\internal
This slot is called when rows have been inserted.
*/
-void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &, int, int)
+void QAbstractItemViewPrivate::_q_rowsInserted(const QModelIndex &index, int start, int end)
{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
Q_Q(QAbstractItemView);
- if (q->isVisible())
- q->updateEditorGeometries();
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->rowsInserted(index, start, end);
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
+/*!
+ \internal
+ This slot is called when columns have been inserted.
+*/
+void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &index, int start, int end)
+{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ Q_Q(QAbstractItemView);
+ if (q->isVisible())
+ q->updateEditorGeometries();
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->columnsInserted(index, start, end);
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
+}
/*!
\internal
@@ -3417,7 +3487,16 @@ void QAbstractItemViewPrivate::_q_modelDestroyed()
*/
void QAbstractItemViewPrivate::_q_layoutChanged()
{
+ Q_Q(QAbstractItemView);
doDelayedItemsLayout();
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->modelReset();
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
/*!
@@ -3742,7 +3821,7 @@ QItemSelectionModel::SelectionFlags QAbstractItemView::selectionCommand(const QM
QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::multiSelectionCommand(
const QModelIndex &index, const QEvent *event) const
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
if (event) {
switch (event->type()) {
diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h
index e4766afbd6..e49ce0b6d0 100644
--- a/src/gui/itemviews/qabstractitemview.h
+++ b/src/gui/itemviews/qabstractitemview.h
@@ -355,6 +355,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_columnsAboutToBeRemoved(const QModelIndex&, int, int))
Q_PRIVATE_SLOT(d_func(), void _q_columnsRemoved(const QModelIndex&, int, int))
Q_PRIVATE_SLOT(d_func(), void _q_columnsInserted(const QModelIndex&, int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex&, int, int))
Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex&, int, int))
Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged())
diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h
index 5b4b1790d6..c1b4ca3e12 100644
--- a/src/gui/itemviews/qabstractitemview_p.h
+++ b/src/gui/itemviews/qabstractitemview_p.h
@@ -108,6 +108,7 @@ public:
void init();
virtual void _q_rowsRemoved(const QModelIndex &parent, int start, int end);
+ virtual void _q_rowsInserted(const QModelIndex &parent, int start, int end);
virtual void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
virtual void _q_columnsRemoved(const QModelIndex &parent, int start, int end);
virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end);
diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp
index a234fdee85..a0955d256e 100644
--- a/src/gui/itemviews/qlistview.cpp
+++ b/src/gui/itemviews/qlistview.cpp
@@ -3168,7 +3168,11 @@ void QListView::currentChanged(const QModelIndex &current, const QModelIndex &pr
if (QAccessible::isActive()) {
if (current.isValid()) {
int entry = visualIndex(current) + 1;
+#ifdef Q_WS_X11
+ QAccessible::updateAccessibility(this, entry, QAccessible::Focus);
+#else
QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus);
+#endif
}
}
#endif
@@ -3187,12 +3191,20 @@ void QListView::selectionChanged(const QItemSelection &selected,
QModelIndex sel = selected.indexes().value(0);
if (sel.isValid()) {
int entry = visualIndex(sel) + 1;
+#ifdef Q_WS_X11
+ QAccessible::updateAccessibility(this, entry, QAccessible::Selection);
+#else
QAccessible::updateAccessibility(viewport(), entry, QAccessible::Selection);
+#endif
}
QModelIndex desel = deselected.indexes().value(0);
if (desel.isValid()) {
int entry = visualIndex(desel) + 1;
+#ifdef Q_WS_X11
+ QAccessible::updateAccessibility(this, entry, QAccessible::SelectionRemove);
+#else
QAccessible::updateAccessibility(viewport(), entry, QAccessible::SelectionRemove);
+#endif
}
}
#endif
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
index 617409ff3f..6f532eb7c7 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/gui/itemviews/qtableview.cpp
@@ -3164,10 +3164,16 @@ void QTableView::currentChanged(const QModelIndex &current, const QModelIndex &p
#ifndef QT_NO_ACCESSIBILITY
if (QAccessible::isActive()) {
if (current.isValid()) {
+#ifdef Q_WS_X11
+ Q_D(QTableView);
+ int entry = d->accessibleTable2Index(current);
+ QAccessible::updateAccessibility(this, entry, QAccessible::Focus);
+#else
int entry = visualIndex(current) + 1;
if (horizontalHeader())
++entry;
QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus);
+#endif
}
}
#endif
@@ -3180,22 +3186,33 @@ void QTableView::currentChanged(const QModelIndex &current, const QModelIndex &p
void QTableView::selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected)
{
+ Q_D(QTableView);
#ifndef QT_NO_ACCESSIBILITY
if (QAccessible::isActive()) {
// ### does not work properly for selection ranges.
QModelIndex sel = selected.indexes().value(0);
if (sel.isValid()) {
+#ifdef Q_WS_X11
+ int entry = d->accessibleTable2Index(sel);
+ QAccessible::updateAccessibility(this, entry, QAccessible::Selection);
+#else
int entry = visualIndex(sel);
if (horizontalHeader())
++entry;
QAccessible::updateAccessibility(viewport(), entry, QAccessible::Selection);
+#endif
}
QModelIndex desel = deselected.indexes().value(0);
if (desel.isValid()) {
+#ifdef Q_WS_X11
+ int entry = d->accessibleTable2Index(sel);
+ QAccessible::updateAccessibility(this, entry, QAccessible::SelectionRemove);
+#else
int entry = visualIndex(sel);
if (horizontalHeader())
++entry;
QAccessible::updateAccessibility(viewport(), entry, QAccessible::SelectionRemove);
+#endif
}
}
#endif
diff --git a/src/gui/itemviews/qtableview_p.h b/src/gui/itemviews/qtableview_p.h
index f973acf3ce..dce0ed06ac 100644
--- a/src/gui/itemviews/qtableview_p.h
+++ b/src/gui/itemviews/qtableview_p.h
@@ -167,6 +167,11 @@ public:
return horizontalHeader->logicalIndex(visualCol);
}
+ inline int accessibleTable2Index(const QModelIndex &index) const {
+ return (index.row() + (horizontalHeader ? 1 : 0)) * (index.model()->columnCount() + (verticalHeader ? 1 : 0))
+ + index.column() + (verticalHeader ? 1 : 0) + 1;
+ }
+
int sectionSpanEndLogical(const QHeaderView *header, int logical, int span) const;
int sectionSpanSize(const QHeaderView *header, int logical, int span) const;
bool spanContainsSection(const QHeaderView *header, int logical, int spanLogical, int span) const;
diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp
index 6a992dbab6..9228ac82a2 100644
--- a/src/gui/itemviews/qtreeview.cpp
+++ b/src/gui/itemviews/qtreeview.cpp
@@ -54,6 +54,7 @@
#include <qdebug.h>
#ifndef QT_NO_ACCESSIBILITY
#include <qaccessible.h>
+#include <qaccessible2.h>
#endif
#include <private/qtreeview_p.h>
@@ -2883,20 +2884,36 @@ void QTreeViewPrivate::expand(int item, bool emitSignal)
void QTreeViewPrivate::insertViewItems(int pos, int count, const QTreeViewItem &viewItem)
{
+ Q_Q(QTreeView);
viewItems.insert(pos, count, viewItem);
QTreeViewItem *items = viewItems.data();
for (int i = pos + count; i < viewItems.count(); i++)
if (items[i].parentItem >= pos)
items[i].parentItem += count;
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
void QTreeViewPrivate::removeViewItems(int pos, int count)
{
+ Q_Q(QTreeView);
viewItems.remove(pos, count);
QTreeViewItem *items = viewItems.data();
for (int i = pos; i < viewItems.count(); i++)
if (items[i].parentItem >= pos)
items[i].parentItem -= count;
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
#if 0
@@ -3687,14 +3704,6 @@ void QTreeViewPrivate::_q_sortIndicatorChanged(int column, Qt::SortOrder order)
*/
void QTreeView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
-#ifndef QT_NO_ACCESSIBILITY
- if (QAccessible::isActive()) {
- int entry = visualIndex(current) + 1;
- if (header())
- ++entry;
- QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus);
- }
-#endif
QAbstractItemView::currentChanged(current, previous);
if (allColumnsShowFocus()) {
@@ -3711,6 +3720,19 @@ void QTreeView::currentChanged(const QModelIndex &current, const QModelIndex &pr
viewport()->update(currentRect);
}
}
+#ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive() && current.isValid()) {
+#ifdef Q_WS_X11
+ int entry = (visualIndex(current) + (header()?1:0))*current.model()->columnCount()+current.column() + 1;
+ QAccessible::updateAccessibility(this, entry, QAccessible::Focus);
+#else
+ int entry = visualIndex(current) + 1;
+ if (header())
+ ++entry;
+ QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus);
+#endif
+ }
+#endif
}
/*!
@@ -3719,26 +3741,38 @@ void QTreeView::currentChanged(const QModelIndex &current, const QModelIndex &pr
void QTreeView::selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected)
{
+ QAbstractItemView::selectionChanged(selected, deselected);
#ifndef QT_NO_ACCESSIBILITY
if (QAccessible::isActive()) {
// ### does not work properly for selection ranges.
QModelIndex sel = selected.indexes().value(0);
if (sel.isValid()) {
+#ifdef Q_WS_X11
+ int entry = (visualIndex(sel) + (header()?1:0))*sel.model()->columnCount()+sel.column() + 1;
+ Q_ASSERT(entry > 0);
+ QAccessible::updateAccessibility(this, entry, QAccessible::Selection);
+#else
int entry = visualIndex(sel) + 1;
if (header())
++entry;
QAccessible::updateAccessibility(viewport(), entry, QAccessible::Selection);
+#endif
}
QModelIndex desel = deselected.indexes().value(0);
if (desel.isValid()) {
+#ifdef Q_WS_X11
+ int entry = (visualIndex(desel) + (header()?1:0))*desel.model()->columnCount()+desel.column() + 1;
+ Q_ASSERT(entry > 0);
+ QAccessible::updateAccessibility(this, entry, QAccessible::SelectionRemove);
+#else
int entry = visualIndex(desel) + 1;
if (header())
++entry;
QAccessible::updateAccessibility(viewport(), entry, QAccessible::SelectionRemove);
+#endif
}
}
#endif
- QAbstractItemView::selectionChanged(selected, deselected);
}
int QTreeView::visualIndex(const QModelIndex &index) const
diff --git a/src/gui/itemviews/qtreeview.h b/src/gui/itemviews/qtreeview.h
index 26c73153e9..b77da4e89a 100644
--- a/src/gui/itemviews/qtreeview.h
+++ b/src/gui/itemviews/qtreeview.h
@@ -219,6 +219,9 @@ protected:
private:
friend class QAccessibleItemView;
+ friend class QAccessibleTable2;
+ friend class QAccessibleTree;
+ friend class QAccessibleTable2Cell;
int visualIndex(const QModelIndex &index) const;
Q_DECLARE_PRIVATE(QTreeView)
diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h
index b6d84586ee..a9dc452398 100644
--- a/src/gui/itemviews/qtreeview_p.h
+++ b/src/gui/itemviews/qtreeview_p.h
@@ -78,7 +78,7 @@ struct QTreeViewItem
Q_DECLARE_TYPEINFO(QTreeViewItem, Q_MOVABLE_TYPE);
-class QTreeViewPrivate : public QAbstractItemViewPrivate
+class Q_GUI_EXPORT QTreeViewPrivate : public QAbstractItemViewPrivate
{
Q_DECLARE_PUBLIC(QTreeView)
public:
@@ -223,6 +223,10 @@ public:
inline void invalidateHeightCache(int item) const
{ viewItems[item].height = 0; }
+ inline int accessibleTable2Index(const QModelIndex &index) const {
+ return (viewIndex(index) + (header ? 1 : 0)) * model->columnCount()+index.column() + 1;
+ }
+
// used for spanning rows
QVector<QPersistentModelIndex> spanningIndexes;
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
+
+