summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Kelly <stephen.kelly@kdab.com>2013-04-02 17:52:54 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-04-05 16:26:06 +0200
commit722798a359761a1eb635d18547b076615f192508 (patch)
tree4f8bf4bd68b21c7c3fa443da67843c68492e7cb7
parenta658d26d84d1fa2b45d8e39d45cf93040a384603 (diff)
Don't call virtual methods after the source model is destroyed.
Calling clear_mapping causes the persistent indexes to be queried, and mapped using map_to_source, so that they can be restored later. That is not the appropriate response to the source model being deleted because there won't be anything to restore. Simply clear the stored mapping information instead so that the source model actually exists when mapToSource is called by the framework. Change-Id: I99692ee7aa9c6714aec45c68fe4a2d62be189d60 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
-rw-r--r--src/corelib/itemmodels/qabstractproxymodel.cpp1
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp3
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp35
3 files changed, 38 insertions, 1 deletions
diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp
index d5887a52d5..0e1764ba7c 100644
--- a/src/corelib/itemmodels/qabstractproxymodel.cpp
+++ b/src/corelib/itemmodels/qabstractproxymodel.cpp
@@ -91,6 +91,7 @@ QT_BEGIN_NAMESPACE
//detects the deletion of the source model
void QAbstractProxyModelPrivate::_q_sourceModelDestroyed()
{
+ invalidatePersistentIndexes();
model = QAbstractItemModelPrivate::staticEmptyModel();
}
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index e5bdd83dc3..67b0d98402 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -295,7 +295,8 @@ typedef QHash<QModelIndex, QSortFilterProxyModelPrivate::Mapping *> IndexMap;
void QSortFilterProxyModelPrivate::_q_sourceModelDestroyed()
{
QAbstractProxyModelPrivate::_q_sourceModelDestroyed();
- _q_clearMapping();
+ qDeleteAll(source_index_mapping);
+ source_index_mapping.clear();
}
void QSortFilterProxyModelPrivate::remove_from_mapping(const QModelIndex &source_parent)
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
index 4578bcdab6..923b9a3a07 100644
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
@@ -148,6 +148,7 @@ private slots:
void chainedProxyModelRoleNames();
+ void noMapAfterSourceDelete();
protected:
void buildHierarchy(const QStringList &data, QAbstractItemModel *model);
void checkHierarchy(const QStringList &data, const QAbstractItemModel *model);
@@ -3809,5 +3810,39 @@ void tst_QSortFilterProxyModel::chainedProxyModelRoleNames()
QVERIFY(proxy2.roleNames().value(Qt::UserRole + 1) == "custom");
}
+class SourceAssertion : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ explicit SourceAssertion(QObject *parent = 0)
+ : QSortFilterProxyModel(parent)
+ {
+
+ }
+
+ QModelIndex mapToSource(const QModelIndex &proxyIndex) const
+ {
+ Q_ASSERT(sourceModel());
+ return QSortFilterProxyModel::mapToSource(proxyIndex);
+ }
+};
+
+void tst_QSortFilterProxyModel::noMapAfterSourceDelete()
+{
+ SourceAssertion proxy;
+ QStringListModel *model = new QStringListModel(QStringList() << "Foo" << "Bar");
+
+ proxy.setSourceModel(model);
+
+ // Create mappings
+ QPersistentModelIndex persistent = proxy.index(0, 0);
+
+ QVERIFY(persistent.isValid());
+
+ delete model;
+
+ QVERIFY(!persistent.isValid());
+}
+
QTEST_MAIN(tst_QSortFilterProxyModel)
#include "tst_qsortfilterproxymodel.moc"