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) 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; } }