summaryrefslogtreecommitdiffstats
path: root/src/plugins/accessible
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-01-03 17:18:40 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-04-02 14:32:25 +0200
commitb2ec0da95641d9cec006fa9699e6d082ad35db0b (patch)
treec6ceef7e1527b98f3eda33b6e525d65ee1d810a6 /src/plugins/accessible
parent8dfe1385b5f05b7242802a72897258a63af1ca1d (diff)
Cache QAccessibleInterfaces.
Since there already is a one-to-one relationship between QObject and QAccessibleInterface it makes little sense to create and destroy the interfaces on each call to queryAccessibleInterface. Add a cache and keep created interfaces around for the lifetime of the corresponding QObject. This changes the memory management rules: accessible interfaces must no longer be deleted. If you get an QAccessibleIntrface pointer that pointer will stay valid as long as the corresponding QObject is not deleted. This also re-enables accessibility for Mac. We limit the range of the IDs so that they are useable for Windows directly. That means we can get rid of the event cache there. This is based on: Iebf2f374916fc70a9dd29e95f45a6444b85f6cee Change-Id: I9fe6531812c0dbc5b41101ac05830a6dd75e13a3 Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
Diffstat (limited to 'src/plugins/accessible')
-rw-r--r--src/plugins/accessible/widgets/complexwidgets.cpp12
-rw-r--r--src/plugins/accessible/widgets/complexwidgets.h3
-rw-r--r--src/plugins/accessible/widgets/itemviews.cpp309
-rw-r--r--src/plugins/accessible/widgets/itemviews.h23
-rw-r--r--src/plugins/accessible/widgets/main.cpp8
-rw-r--r--src/plugins/accessible/widgets/qaccessiblemenu.cpp24
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.cpp1
7 files changed, 269 insertions, 111 deletions
diff --git a/src/plugins/accessible/widgets/complexwidgets.cpp b/src/plugins/accessible/widgets/complexwidgets.cpp
index b805e8c967..9dbf7d7e0f 100644
--- a/src/plugins/accessible/widgets/complexwidgets.cpp
+++ b/src/plugins/accessible/widgets/complexwidgets.cpp
@@ -96,7 +96,6 @@ public:
QAccessible::State state() const {
QAccessibleInterface *parentInterface = parent();
QAccessible::State state = parentInterface->state();
- delete parentInterface;
return state;
}
QRect rect() const {
@@ -153,6 +152,12 @@ QAccessibleTabBar::QAccessibleTabBar(QWidget *w)
Q_ASSERT(tabBar());
}
+QAccessibleTabBar::~QAccessibleTabBar()
+{
+ foreach (QAccessible::Id id, m_childInterfaces.values())
+ QAccessible::deleteAccessibleInterface(id);
+}
+
/*! Returns the QTabBar. */
QTabBar *QAccessibleTabBar::tabBar() const
{
@@ -161,9 +166,14 @@ QTabBar *QAccessibleTabBar::tabBar() const
QAccessibleInterface* QAccessibleTabBar::child(int index) const
{
+ if (QAccessible::Id id = m_childInterfaces.value(index))
+ return QAccessible::accessibleInterface(id);
+
// first the tabs, then 2 buttons
if (index < tabBar()->count()) {
QAccessibleTabButton *button = new QAccessibleTabButton(tabBar(), index);
+ QAccessible::registerAccessibleInterface(button);
+ m_childInterfaces.insert(index, QAccessible::uniqueId(button));
return button;
} else if (index >= tabBar()->count()) {
// left button
diff --git a/src/plugins/accessible/widgets/complexwidgets.h b/src/plugins/accessible/widgets/complexwidgets.h
index 32f67c9c69..306eae4a72 100644
--- a/src/plugins/accessible/widgets/complexwidgets.h
+++ b/src/plugins/accessible/widgets/complexwidgets.h
@@ -47,6 +47,7 @@
#include <QtWidgets/qabstractitemview.h>
#include <QtGui/private/qaccessible2_p.h>
+
QT_BEGIN_NAMESPACE
#ifndef QT_NO_ACCESSIBILITY
@@ -101,6 +102,7 @@ class QAccessibleTabBar : public QAccessibleWidget
{
public:
explicit QAccessibleTabBar(QWidget *w);
+ ~QAccessibleTabBar();
int childCount() const;
QString text(QAccessible::Text t) const;
@@ -113,6 +115,7 @@ public:
protected:
QTabBar *tabBar() const;
+ mutable QHash<int, QAccessible::Id> m_childInterfaces;
};
#endif // QT_NO_TABBAR
diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp
index 822d9d8c77..4ddd39f7ea 100644
--- a/src/plugins/accessible/widgets/itemviews.cpp
+++ b/src/plugins/accessible/widgets/itemviews.cpp
@@ -47,7 +47,6 @@
#include <qtreeview.h>
#include <private/qtreewidget_p.h>
#include <QtGui/private/qaccessible2_p.h>
-#include <QtWidgets/private/qwidget_p.h>
#ifndef QT_NO_ACCESSIBILITY
@@ -82,43 +81,6 @@ int QAccessibleTable::logicalIndex(const QModelIndex &index) const
return (index.row() + hHeader)*(index.model()->columnCount() + vHeader) + (index.column() + vHeader);
}
-QAccessibleInterface *QAccessibleTable::childFromLogical(int logicalIndex) const
-{
- if (!view()->model())
- return 0;
-
- 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 QAccessibleTableCornerButton(view());
- }
- return new QAccessibleTableHeaderCell(view(), row-1, Qt::Vertical);
- }
- --column;
- }
- if (hHeader) {
- if (row == 0) {
- return new QAccessibleTableHeaderCell(view(), column, Qt::Horizontal);
- }
- --row;
- }
-
- QModelIndex index = view()->model()->index(row, column, view()->rootIndex());
- if (!index.isValid()) {
- qWarning() << "QAccessibleTable::childFromLogical: Invalid index at: " << row << column;
- return 0;
- }
- return new QAccessibleTableCell(view(), index, cellRole());
-}
-
QAccessibleTable::QAccessibleTable(QWidget *w)
: QAccessibleObject(w)
{
@@ -143,6 +105,8 @@ bool QAccessibleTable::isValid() const
QAccessibleTable::~QAccessibleTable()
{
+ Q_FOREACH (QAccessible::Id id, childToId.values())
+ QAccessible::deleteAccessibleInterface(id);
}
QHeaderView *QAccessibleTable::horizontalHeader() const
@@ -173,13 +137,6 @@ QHeaderView *QAccessibleTable::verticalHeader() const
return header;
}
-QAccessibleTableCell *QAccessibleTable::cell(const QModelIndex &index) const
-{
- if (index.isValid())
- return new QAccessibleTableCell(view(), index, cellRole());
- return 0;
-}
-
QAccessibleInterface *QAccessibleTable::cellAt(int row, int column) const
{
if (!view()->model())
@@ -190,7 +147,7 @@ QAccessibleInterface *QAccessibleTable::cellAt(int row, int column) const
qWarning() << "QAccessibleTable::cellAt: invalid index: " << index << " for " << view();
return 0;
}
- return cell(index);
+ return child(logicalIndex(index));
}
QAccessibleInterface *QAccessibleTable::caption() const
@@ -252,9 +209,8 @@ QList<QAccessibleInterface *> QAccessibleTable::selectedCells() const
QList<QAccessibleInterface*> cells;
if (!view()->selectionModel())
return cells;
- Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedIndexes()) {
- cells.append(cell(index));
- }
+ Q_FOREACH (const QModelIndex &index, view()->selectionModel()->selectedIndexes())
+ cells.append(child(logicalIndex(index)));
return cells;
}
@@ -447,7 +403,7 @@ QAccessibleInterface *QAccessibleTable::childAt(int x, int y) const
QModelIndex index = view()->indexAt(indexPosition);
if (index.isValid()) {
- return childFromLogical(logicalIndex(index));
+ return child(logicalIndex(index));
}
return 0;
}
@@ -465,7 +421,7 @@ int QAccessibleTable::indexOfChild(const QAccessibleInterface *iface) const
{
if (!view()->model())
return -1;
- QSharedPointer<QAccessibleInterface> parent(iface->parent());
+ QAccessibleInterface *parent = iface->parent();
if (parent->object() != view())
return -1;
@@ -478,7 +434,7 @@ int QAccessibleTable::indexOfChild(const QAccessibleInterface *iface) const
return cell->index + (verticalHeader() ? 1 : 0);
} else if (iface->role() == QAccessible::RowHeader){
const QAccessibleTableHeaderCell* cell = static_cast<const QAccessibleTableHeaderCell*>(iface);
- return (cell->index + 1) * (view()->model()->rowCount() + 1);
+ return (cell->index + 1) * (view()->model()->columnCount() + 1);
} else if (iface->role() == QAccessible::Pane) {
return 0; // corner button
} else {
@@ -515,9 +471,55 @@ QAccessibleInterface *QAccessibleTable::parent() const
return 0;
}
-QAccessibleInterface *QAccessibleTable::child(int index) const
+QAccessibleInterface *QAccessibleTable::child(int logicalIndex) const
{
- return childFromLogical(index);
+ if (!view()->model())
+ return 0;
+
+ if (childToId.contains(logicalIndex)) {
+ QAccessible::Id id = childToId.value(logicalIndex);
+ return QAccessible::accessibleInterface(id);
+ }
+
+ int vHeader = verticalHeader() ? 1 : 0;
+ int hHeader = horizontalHeader() ? 1 : 0;
+
+ int columns = view()->model()->columnCount() + vHeader;
+
+ int row = logicalIndex / columns;
+ int column = logicalIndex % columns;
+
+ QAccessibleInterface *iface = 0;
+
+ if (vHeader) {
+ if (column == 0) {
+ if (hHeader && row == 0) {
+ iface = new QAccessibleTableCornerButton(view());
+ } else {
+ iface = new QAccessibleTableHeaderCell(view(), row - hHeader, Qt::Vertical);
+ }
+ }
+ --column;
+ }
+ if (!iface && hHeader) {
+ if (row == 0) {
+ iface = new QAccessibleTableHeaderCell(view(), column, Qt::Horizontal);
+ }
+ --row;
+ }
+
+ if (!iface) {
+ QModelIndex index = view()->model()->index(row, column, view()->rootIndex());
+ if (!index.isValid()) {
+ qWarning() << "QAccessibleTable::child: Invalid index at: " << row << column;
+ return 0;
+ }
+ iface = new QAccessibleTableCell(view(), index, cellRole());
+ }
+
+ QAccessible::registerAccessibleInterface(iface);
+ childToId.insert(logicalIndex, QAccessible::uniqueId(iface));
+ return iface;
}
void *QAccessibleTable::interface_cast(QAccessible::InterfaceType t)
@@ -527,6 +529,140 @@ void *QAccessibleTable::interface_cast(QAccessible::InterfaceType t)
return 0;
}
+void QAccessibleTable::modelChange(QAccessibleTableModelChangeEvent *event)
+{
+ // if there is no cache yet, we don't update anything
+ if (childToId.isEmpty())
+ return;
+
+ switch (event->modelChangeType()) {
+ case QAccessibleTableModelChangeEvent::ModelReset:
+ Q_FOREACH (QAccessible::Id id, childToId.values())
+ QAccessible::deleteAccessibleInterface(id);
+ childToId.clear();
+ break;
+
+ // rows are inserted: move every row after that
+ case QAccessibleTableModelChangeEvent::RowsInserted:
+ case QAccessibleTableModelChangeEvent::ColumnsInserted: {
+ int newRows = event->lastRow() - event->firstRow() + 1;
+ int newColumns = event->lastColumn() - event->firstColumn() + 1;
+
+ ChildCache newCache;
+ ChildCache::ConstIterator iter = childToId.constBegin();
+
+ while (iter != childToId.constEnd()) {
+ QAccessible::Id id = iter.value();
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(id);
+ Q_ASSERT(iface);
+ if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) {
+ Q_ASSERT(iface->tableCellInterface());
+ QAccessibleTableCell *cell = static_cast<QAccessibleTableCell*>(iface->tableCellInterface());
+ if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsInserted
+ && cell->m_index.row() >= event->firstRow()) {
+ int newRow = cell->m_index.row() + newRows;
+ cell->m_index = cell->m_index.sibling(newRow, cell->m_index.column());
+ } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsInserted
+ && cell->m_index.column() >= event->firstColumn()) {
+ int newColumn = cell->m_index.column() + newColumns;
+ cell->m_index = cell->m_index.sibling(cell->m_index.row(), newColumn);
+ }
+ } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsInserted
+ && iface->role() == QAccessible::RowHeader) {
+ QAccessibleTableHeaderCell *cell = static_cast<QAccessibleTableHeaderCell*>(iface);
+ if (cell->index >= event->firstRow()) {
+ cell->index += newRows;
+ }
+ } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsInserted
+ && iface->role() == QAccessible::ColumnHeader) {
+ QAccessibleTableHeaderCell *cell = static_cast<QAccessibleTableHeaderCell*>(iface);
+ if (cell->index >= event->firstColumn()) {
+ cell->index += newColumns;
+ }
+ }
+ if (indexOfChild(iface) >= 0) {
+ newCache.insert(indexOfChild(iface), id);
+ } else {
+ // ### This should really not happen,
+ // but it might if the view has a root index set.
+ // This needs to be fixed.
+ QAccessible::deleteAccessibleInterface(id);
+ }
+ ++iter;
+ }
+ childToId = newCache;
+ break;
+ }
+
+ case QAccessibleTableModelChangeEvent::ColumnsRemoved:
+ case QAccessibleTableModelChangeEvent::RowsRemoved: {
+ int deletedColumns = event->lastColumn() - event->firstColumn() + 1;
+ int deletedRows = event->lastRow() - event->firstRow() + 1;
+ ChildCache newCache;
+ ChildCache::ConstIterator iter = childToId.constBegin();
+ while (iter != childToId.constEnd()) {
+ QAccessible::Id id = iter.value();
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(id);
+ Q_ASSERT(iface);
+ if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) {
+ Q_ASSERT(iface->tableCellInterface());
+ QAccessibleTableCell *cell = static_cast<QAccessibleTableCell*>(iface->tableCellInterface());
+ if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsRemoved) {
+ if (cell->m_index.row() < event->firstRow()) {
+ newCache.insert(indexOfChild(cell), id);
+ } else if (cell->m_index.row() > event->lastRow()) {
+ int newRow = cell->m_index.row() - deletedRows;
+ cell->m_index = cell->m_index.sibling(newRow, cell->m_index.column());
+ newCache.insert(indexOfChild(cell), id);
+ } else {
+ QAccessible::deleteAccessibleInterface(id);
+ }
+ } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsRemoved) {
+ if (cell->m_index.column() < event->firstColumn()) {
+ newCache.insert(indexOfChild(cell), id);
+ } else if (cell->m_index.column() > event->lastColumn()) {
+ int newColumn = cell->m_index.column() - deletedColumns;
+ cell->m_index = cell->m_index.sibling(cell->m_index.row(), newColumn);
+ newCache.insert(indexOfChild(cell), id);
+ } else {
+ QAccessible::deleteAccessibleInterface(id);
+ }
+ }
+ } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::RowsRemoved
+ && iface->role() == QAccessible::RowHeader) {
+ QAccessibleTableHeaderCell *cell = static_cast<QAccessibleTableHeaderCell*>(iface);
+ if (cell->index < event->firstRow()) {
+ newCache.insert(indexOfChild(cell), id);
+ } else if (cell->index > event->lastRow()) {
+ cell->index -= deletedRows;
+ newCache.insert(indexOfChild(cell), id);
+ } else {
+ QAccessible::deleteAccessibleInterface(id);
+ }
+ } else if (event->modelChangeType() == QAccessibleTableModelChangeEvent::ColumnsRemoved
+ && iface->role() == QAccessible::ColumnHeader) {
+ QAccessibleTableHeaderCell *cell = static_cast<QAccessibleTableHeaderCell*>(iface);
+ if (cell->index < event->firstColumn()) {
+ newCache.insert(indexOfChild(cell), id);
+ } else if (cell->index > event->lastColumn()) {
+ cell->index -= deletedColumns;
+ newCache.insert(indexOfChild(cell), id);
+ } else {
+ QAccessible::deleteAccessibleInterface(id);
+ }
+ }
+ ++iter;
+ }
+ childToId = newCache;
+ break;
+ }
+
+ case QAccessibleTableModelChangeEvent::DataChanged:
+ // nothing to do in this case
+ break;
+ }
+}
+
// TREE VIEW
QModelIndex QAccessibleTree::indexFromLogical(int row, int column) const
@@ -578,27 +714,33 @@ int QAccessibleTree::childCount() const
}
-QAccessibleInterface *QAccessibleTree::child(int index) const
+QAccessibleInterface *QAccessibleTree::child(int logicalIndex) const
{
- if (index < 0 || !view()->model() || !view()->model()->columnCount())
+ if (logicalIndex < 0 || !view()->model() || !view()->model()->columnCount())
return 0;
- int hHeader = horizontalHeader() ? 1 : 0;
- if (hHeader) {
+ QAccessibleInterface *iface = 0;
+ int index = logicalIndex;
+
+ if (horizontalHeader()) {
if (index < view()->model()->columnCount()) {
- return new QAccessibleTableHeaderCell(view(), index, Qt::Horizontal);
+ iface = new QAccessibleTableHeaderCell(view(), index, Qt::Horizontal);
} 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()) {
- return cell(modelIndex);
+ if (!iface) {
+ int row = index / view()->model()->columnCount();
+ int column = index % view()->model()->columnCount();
+ QModelIndex modelIndex = indexFromLogical(row, column);
+ if (!modelIndex.isValid())
+ return 0;
+ iface = new QAccessibleTableCell(view(), modelIndex, cellRole());
}
- return 0;
+ QAccessible::registerAccessibleInterface(iface);
+ // ### FIXME: get interfaces from the cache instead of re-creating them
+ return iface;
}
int QAccessibleTree::rowCount() const
@@ -612,7 +754,7 @@ int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const
{
if (!view()->model())
return -1;
- QSharedPointer<QAccessibleInterface> parent(iface->parent());
+ QAccessibleInterface *parent = iface->parent();
if (parent->object() != view())
return -1;
@@ -624,12 +766,10 @@ int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const
int column = cell->m_index.column();
int index = row * view()->model()->columnCount() + column;
- //qDebug() << "QAccessibleTree::indexOfChild r " << row << " c " << column << "index " << index;
Q_ASSERT(index >= treeView->model()->columnCount());
return index;
} else if (iface->role() == QAccessible::ColumnHeader){
const QAccessibleTableHeaderCell* cell = static_cast<const QAccessibleTableHeaderCell*>(iface);
- //qDebug() << "QAccessibleTree::indexOfChild header " << cell->index;
return cell->index;
} else {
qWarning() << "WARNING QAccessibleTable::indexOfChild invalid child"
@@ -646,7 +786,11 @@ QAccessibleInterface *QAccessibleTree::cellAt(int row, int column) const
qWarning() << "Requested invalid tree cell: " << row << column;
return 0;
}
- return new QAccessibleTableCell(view(), index, cellRole());
+ const QTreeView *treeView = qobject_cast<const QTreeView*>(view());
+ Q_ASSERT(treeView);
+ int logicalIndex = treeView->d_func()->accessibleTable2Index(index);
+
+ return child(logicalIndex); // FIXME ### new QAccessibleTableCell(view(), index, cellRole());
}
QString QAccessibleTree::rowDescription(int) const
@@ -717,6 +861,7 @@ QList<QAccessibleInterface*> QAccessibleTableCell::rowHeaderCells() const
{
QList<QAccessibleInterface*> headerCell;
if (verticalHeader()) {
+ // FIXME
headerCell.append(new QAccessibleTableHeaderCell(view, m_index.row(), Qt::Vertical));
}
return headerCell;
@@ -726,6 +871,7 @@ QList<QAccessibleInterface*> QAccessibleTableCell::columnHeaderCells() const
{
QList<QAccessibleInterface*> headerCell;
if (horizontalHeader()) {
+ // FIXME
headerCell.append(new QAccessibleTableHeaderCell(view, m_index.column(), Qt::Horizontal));
}
return headerCell;
@@ -808,18 +954,18 @@ void QAccessibleTableCell::selectCell()
QAbstractItemView::SelectionMode selectionMode = view->selectionMode();
if (!m_index.isValid() || (selectionMode == QAbstractItemView::NoSelection))
return;
-
- QSharedPointer<QAccessibleTableInterface> cellTable(table()->tableInterface());
+ Q_ASSERT(table());
+ QAccessibleTableInterface *cellTable = table()->tableInterface();
switch (view->selectionBehavior()) {
case QAbstractItemView::SelectItems:
break;
case QAbstractItemView::SelectColumns:
- if (cellTable.data())
+ if (cellTable)
cellTable->selectColumn(m_index.column());
return;
case QAbstractItemView::SelectRows:
- if (cellTable.data())
+ if (cellTable)
cellTable->selectRow(m_index.row());
return;
}
@@ -838,17 +984,17 @@ void QAccessibleTableCell::unselectCell()
if (!m_index.isValid() || (selectionMode & QAbstractItemView::NoSelection))
return;
- QSharedPointer<QAccessibleTableInterface> cellTable(table()->tableInterface());
+ QAccessibleTableInterface *cellTable = table()->tableInterface();
switch (view->selectionBehavior()) {
case QAbstractItemView::SelectItems:
break;
case QAbstractItemView::SelectColumns:
- if (cellTable.data())
+ if (cellTable)
cellTable->unselectColumn(m_index.column());
return;
case QAbstractItemView::SelectRows:
- if (cellTable.data())
+ if (cellTable)
cellTable->unselectRow(m_index.row());
return;
}
@@ -962,10 +1108,7 @@ bool QAccessibleTableCell::isValid() const
QAccessibleInterface *QAccessibleTableCell::parent() const
{
- if (m_role == QAccessible::TreeItem)
- return new QAccessibleTree(view);
-
- return new QAccessibleTable(view);
+ return QAccessible::queryAccessibleInterface(view);
}
QAccessibleInterface *QAccessibleTableCell::child(int) const
@@ -1051,11 +1194,7 @@ bool QAccessibleTableHeaderCell::isValid() const
QAccessibleInterface *QAccessibleTableHeaderCell::parent() const
{
-#ifndef QT_NO_TREEVIEW
- if (qobject_cast<const QTreeView*>(view))
- return new QAccessibleTree(view);
-#endif
- return new QAccessibleTable(view);
+ return QAccessible::queryAccessibleInterface(view);
}
QAccessibleInterface *QAccessibleTableHeaderCell::child(int) const
diff --git a/src/plugins/accessible/widgets/itemviews.h b/src/plugins/accessible/widgets/itemviews.h
index af885fe6c1..09dacde7a2 100644
--- a/src/plugins/accessible/widgets/itemviews.h
+++ b/src/plugins/accessible/widgets/itemviews.h
@@ -65,8 +65,6 @@ public:
explicit QAccessibleTable(QWidget *w);
bool isValid() const;
- virtual ~QAccessibleTable();
-
QAccessible::Role role() const;
QAccessible::State state() const;
QString text(QAccessible::Text t) const;
@@ -106,9 +104,9 @@ public:
QAbstractItemView *view() const;
-protected:
- inline QAccessibleTableCell *cell(const QModelIndex &index) const;
+ void modelChange(QAccessibleTableModelChangeEvent *event);
+protected:
inline QAccessible::Role cellRole() const {
switch (m_role) {
case QAccessible::List:
@@ -125,11 +123,16 @@ protected:
QHeaderView *horizontalHeader() const;
QHeaderView *verticalHeader() const;
+
+ // maybe vector
+ typedef QHash<int, QAccessible::Id> ChildCache;
+ mutable ChildCache childToId;
+
+ virtual ~QAccessibleTable();
+
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;
};
@@ -140,7 +143,6 @@ public:
: QAccessibleTable(w)
{}
- virtual ~QAccessibleTree() {}
QAccessibleInterface *childAt(int x, int y) const;
int childCount() const;
@@ -158,6 +160,8 @@ public:
private:
QModelIndex indexFromLogical(int row, int column = 0) const;
+
+ inline int logicalIndex(const QModelIndex &index) const;
};
class QAccessibleTableCell: public QAccessibleInterface, public QAccessibleTableCellInterface, public QAccessibleActionInterface
@@ -236,7 +240,7 @@ public:
QAccessibleInterface *child(int index) const;
private:
- QAbstractItemView *view;
+ QPointer<QAbstractItemView> view;
int index;
Qt::Orientation orientation;
@@ -273,8 +277,9 @@ public:
QAccessibleInterface *child(int) const {
return 0;
}
+
private:
- QAbstractItemView *view;
+ QPointer<QAbstractItemView> view;
};
diff --git a/src/plugins/accessible/widgets/main.cpp b/src/plugins/accessible/widgets/main.cpp
index ade4979256..686a90ca96 100644
--- a/src/plugins/accessible/widgets/main.cpp
+++ b/src/plugins/accessible/widgets/main.cpp
@@ -177,14 +177,6 @@ QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObjec
} else if (classname == QLatin1String("QTableView") || classname == QLatin1String("QListView")) {
iface = new QAccessibleTable(widget);
// ### This should be cleaned up. We return the parent for the scrollarea to hide it.
- } 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 QAccessibleTable(widget->parentWidget());
- }
#endif // QT_NO_ITEMVIEWS
#ifndef QT_NO_TABBAR
} else if (classname == QLatin1String("QTabBar")) {
diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.cpp b/src/plugins/accessible/widgets/qaccessiblemenu.cpp
index e467ef50bd..f248e6d05e 100644
--- a/src/plugins/accessible/widgets/qaccessiblemenu.cpp
+++ b/src/plugins/accessible/widgets/qaccessiblemenu.cpp
@@ -55,6 +55,16 @@ QT_BEGIN_NAMESPACE
QString Q_GUI_EXPORT qt_accStripAmp(const QString &text);
QString Q_GUI_EXPORT qt_accHotKey(const QString &text);
+QAccessibleInterface *getOrCreateMenu(QWidget *menu, QAction *action)
+{
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(action);
+ if (!iface) {
+ iface = new QAccessibleMenuItem(menu, action);
+ QAccessible::registerAccessibleInterface(iface);
+ }
+ return iface;
+}
+
QAccessibleMenu::QAccessibleMenu(QWidget *w)
: QAccessibleWidget(w)
{
@@ -76,7 +86,7 @@ QAccessibleInterface *QAccessibleMenu::childAt(int x, int y) const
QAction *act = menu()->actionAt(menu()->mapFromGlobal(QPoint(x,y)));
if(act && act->isSeparator())
act = 0;
- return act ? new QAccessibleMenuItem(menu(), act) : 0;
+ return act ? getOrCreateMenu(menu(), act) : 0;
}
QString QAccessibleMenu::text(QAccessible::Text t) const
@@ -98,7 +108,7 @@ QAccessible::Role QAccessibleMenu::role() const
QAccessibleInterface *QAccessibleMenu::child(int index) const
{
if (index < childCount())
- return new QAccessibleMenuItem(menu(), menu()->actions().at(index));
+ return getOrCreateMenu(menu(), menu()->actions().at(index));
return 0;
}
@@ -111,7 +121,7 @@ QAccessibleInterface *QAccessibleMenu::parent() const
foreach (QWidget *w, parentCandidates) {
if (qobject_cast<QMenu*>(w) || qobject_cast<QMenuBar*>(w)) {
if (w->actions().indexOf(menuAction) != -1)
- return new QAccessibleMenuItem(w, menuAction);
+ return getOrCreateMenu(w, menuAction);
}
}
}
@@ -146,8 +156,9 @@ int QAccessibleMenuBar::childCount() const
QAccessibleInterface *QAccessibleMenuBar::child(int index) const
{
- if (index < childCount())
- return new QAccessibleMenuItem(menuBar(), menuBar()->actions().at(index));
+ if (index < childCount()) {
+ return getOrCreateMenu(menuBar(), menuBar()->actions().at(index));
+ }
return 0;
}
@@ -177,7 +188,6 @@ QAccessibleInterface *QAccessibleMenuItem::childAt(int x, int y ) const
if (childInterface->rect().contains(x,y)) {
return childInterface;
}
- delete childInterface;
}
return 0;
}
@@ -207,7 +217,7 @@ QAccessibleInterface *QAccessibleMenuItem::parent() const
QAccessibleInterface *QAccessibleMenuItem::child(int index) const
{
if (index == 0 && action()->menu())
- return new QAccessibleMenu(action()->menu());
+ return QAccessible::queryAccessibleInterface(action()->menu());
return 0;
}
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
index b5ee4a6046..751a722bb8 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
@@ -718,7 +718,6 @@ QAccessibleInterface *QAccessibleTitleBar::childAt(int x, int y) const
if (childIface->rect().contains(x,y)) {
return childIface;
}
- delete childIface;
}
return 0;
}