QSortFilterProxyModel: don't assert when old model gets destroyed

When a new model was set with setSourceModel() and the mapping was
built up, the destruction of the old model caused a reset in the
QSortFilterProxyModel which lead to an empty view or an assertion.
Now we properly disconnect the old model again and also clean up the old
mapping/persistent indexes when a new source model is set.

Task-number: QTBUG-44962
Task-number: QTBUG-67948
Task-number: QTBUG-68427
Change-Id: I2e0612899c210bde3ac0cfa59aefd78269deee5b
Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
Christian Ehrlicher 2018-05-25 21:06:43 +02:00
parent 8050f1c287
commit e15fc26e9f
2 changed files with 18 additions and 5 deletions

View File

@ -1910,7 +1910,10 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset()));
disconnect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset()));
d->_q_sourceModelDestroyed();
// same as in _q_sourceReset()
d->invalidatePersistentIndexes();
d->_q_clearMapping();
QAbstractProxyModel::setSourceModel(sourceModel);
connect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),

View File

@ -4516,15 +4516,25 @@ void tst_QSortFilterProxyModel::checkSetNewModel()
QTreeView tv;
StepTreeModel model1;
model1.setDepth(4);
StepTreeModel model2;
model2.setDepth(4);
QSortFilterProxyModel proxy;
proxy.setSourceModel(&model1);
tv.setModel(&proxy);
tv.show();
tv.expandAll(); // create persistent indexes
proxy.setSourceModel(&model2);
QVERIFY(QTest::qWaitForWindowExposed(&tv));
tv.expandAll();
{
StepTreeModel model2;
model2.setDepth(4);
proxy.setSourceModel(&model2);
tv.expandAll();
proxy.setSourceModel(&model1);
tv.expandAll();
// the destruction of model2 here caused a proxy model reset due to
// missing disconnect in setSourceModel()
}
// handle repaint events, will assert when qsortfilterproxymodel is in wrong state
QCoreApplication::processEvents();
}
QTEST_MAIN(tst_QSortFilterProxyModel)