summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Hartmetz <andreas.hartmetz@kdab.com>2014-08-28 18:23:11 (GMT)
committerAndreas Hartmetz <ahartmetz@gmail.com>2014-09-03 19:35:08 (GMT)
commit8e720177ef18d471c8ffa455750fdcd375d7a8da (patch)
tree203eacfc2a01d9d7eb2d87476cee7a60824fab30
parent997d626173d9aba5b01b35e4d95ad162771ba789 (diff)
downloadQt-8e720177ef18d471c8ffa455750fdcd375d7a8da.zip
Qt-8e720177ef18d471c8ffa455750fdcd375d7a8da.tar.gz
Qt-8e720177ef18d471c8ffa455750fdcd375d7a8da.tar.bz2
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. Backport of 722798a359761a1eb635d18547b076615f192508 from qt5/qtbase Change-Id: I9c74f97855046b968dfba7a35134c234b974e63b Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
-rw-r--r--src/gui/itemviews/qabstractproxymodel.cpp1
-rw-r--r--src/gui/itemviews/qsortfilterproxymodel.cpp3
-rw-r--r--tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp34
3 files changed, 37 insertions, 1 deletions
diff --git a/src/gui/itemviews/qabstractproxymodel.cpp b/src/gui/itemviews/qabstractproxymodel.cpp
index b2a936a..7c239b2 100644
--- a/src/gui/itemviews/qabstractproxymodel.cpp
+++ b/src/gui/itemviews/qabstractproxymodel.cpp
@@ -84,6 +84,7 @@ QT_BEGIN_NAMESPACE
//detects the deletion of the source model
void QAbstractProxyModelPrivate::_q_sourceModelDestroyed()
{
+ invalidatePersistentIndexes();
model = QAbstractItemModelPrivate::staticEmptyModel();
}
diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp
index 7e2faeb..45433e2 100644
--- a/src/gui/itemviews/qsortfilterproxymodel.cpp
+++ b/src/gui/itemviews/qsortfilterproxymodel.cpp
@@ -281,7 +281,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/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
index 82cc693..cb49037 100644
--- a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
+++ b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
@@ -154,6 +154,7 @@ private slots:
void hierarchyFilterInvalidation();
void simpleFilterInvalidation();
+ void noMapAfterSourceDelete();
protected:
void buildHierarchy(const QStringList &data, QAbstractItemModel *model);
void checkHierarchy(const QStringList &data, const QAbstractItemModel *model);
@@ -3535,6 +3536,39 @@ void tst_QSortFilterProxyModel::simpleFilterInvalidation()
model.insertRow(0, new QStandardItem("extra"));
}
+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"