Emit layoutChange signals when changing QPersistentModelIndexes.

This is necessary whenever QPersistentModelIndexes are changed. Omitting
it means that views are not able to react to the change, such as QTreeView
clearing its (manually held) QModelIndex cache, and the QItemSelectionModel
clearing the item from its storage.

It is necessary to change a QSortFilterProxyModel test which assumed setItem
does not have any such effect. That test is ported to setData instead.

Task-number: QTBUG-18539
Change-Id: Id7a602f18b9773ba4d11019418de886860d26d3e
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
bb10
Stephen Kelly 2012-08-13 11:53:05 +02:00 committed by Qt by Nokia
parent 72604f8eb9
commit 2ef3ac72fc
3 changed files with 49 additions and 1 deletions

View File

@ -139,6 +139,11 @@ void QStandardItemPrivate::setChild(int row, int column, QStandardItem *item,
QStandardItem *oldItem = children.at(index);
if (item == oldItem)
return;
if (model && emitChanged) {
emit model->layoutAboutToBeChanged();
}
if (item) {
if (item->d_func()->parent == 0) {
item->d_func()->setParentAndModel(q, model);
@ -152,6 +157,10 @@ void QStandardItemPrivate::setChild(int row, int column, QStandardItem *item,
oldItem->d_func()->setModel(0);
delete oldItem;
children.replace(index, item);
if (model && emitChanged)
emit model->layoutChanged();
if (emitChanged && model)
model->d_func()->itemChanged(item);
}

View File

@ -2496,7 +2496,7 @@ void tst_QSortFilterProxyModel::staticSorting()
}
//update one item.
model.setItem(0, 0, new QStandardItem("girafe"));
items.first()->setData("girafe", Qt::DisplayRole);
// make sure the proxy is updated but not sorted
expected.replaceInStrings("bateau", "girafe");

View File

@ -240,6 +240,7 @@ private slots:
void taskQTBUG_11466_keyboardNavigationRegression();
void taskQTBUG_13567_removeLastItemRegression();
void taskQTBUG_25333_adjustViewOptionsForIndex();
void taskQTBUG_18539_emitLayoutChanged();
};
class QtTestModel: public QAbstractItemModel
@ -4054,6 +4055,44 @@ void tst_QTreeView::taskQTBUG_25333_adjustViewOptionsForIndex()
}
void tst_QTreeView::taskQTBUG_18539_emitLayoutChanged()
{
QTreeView view;
QStandardItem* item = new QStandardItem("Orig");
QStandardItem* child = new QStandardItem("Child");
item->setChild(0, 0, child);
QStandardItemModel model;
model.appendRow(item);
view.setModel(&model);
QStandardItem* replacementItem = new QStandardItem("Replacement");
QStandardItem* replacementChild = new QStandardItem("ReplacementChild");
replacementItem->setChild(0, 0, replacementChild);
QSignalSpy beforeSpy(&model, SIGNAL(layoutAboutToBeChanged()));
QSignalSpy afterSpy(&model, SIGNAL(layoutChanged()));
QSignalSpy beforeRISpy(&model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
QSignalSpy afterRISpy(&model, SIGNAL(rowsInserted(QModelIndex,int,int)));
QSignalSpy beforeRRSpy(&model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
QSignalSpy afterRRSpy(&model, SIGNAL(rowsRemoved(QModelIndex,int,int)));
model.setItem(0, 0, replacementItem);
QCOMPARE(beforeSpy.size(), 1);
QCOMPARE(afterSpy.size(), 1);
QCOMPARE(beforeRISpy.size(), 0);
QCOMPARE(afterRISpy.size(), 0);
QCOMPARE(beforeRISpy.size(), 0);
QCOMPARE(afterRISpy.size(), 0);
}
QTEST_MAIN(tst_QTreeView)
#include "tst_qtreeview.moc"