summaryrefslogtreecommitdiff
path: root/dev-qt/qtcore/files/qtcore-5.7.1-qsfpm-1.patch
diff options
context:
space:
mode:
Diffstat (limited to 'dev-qt/qtcore/files/qtcore-5.7.1-qsfpm-1.patch')
-rw-r--r--dev-qt/qtcore/files/qtcore-5.7.1-qsfpm-1.patch252
1 files changed, 0 insertions, 252 deletions
diff --git a/dev-qt/qtcore/files/qtcore-5.7.1-qsfpm-1.patch b/dev-qt/qtcore/files/qtcore-5.7.1-qsfpm-1.patch
deleted file mode 100644
index 9edbe18617a2..000000000000
--- a/dev-qt/qtcore/files/qtcore-5.7.1-qsfpm-1.patch
+++ /dev/null
@@ -1,252 +0,0 @@
-From 3bd0fd8f97e7a33a874929a383a42e6c710bfff3 Mon Sep 17 00:00:00 2001
-From: Stephen Kelly <steveire@gmail.com>
-Date: Sat, 17 Dec 2016 06:20:06 +0000
-Subject: [PATCH] QSFPM: Fix handling of source model layout change
-
-In sourceLayoutAboutToBeChanged the source model update is ignored if
-the affected parents are filtered out anyway. The same logic is
-attempted in the sourceLayoutChanged slot, but there the early-return
-logic is applied too late - the mapping is cleared before performing the
-early-return. Because pointers into the mapping are used in the
-internalPointer of QModelIndexes in this class, persistent indexes used
-later will segfault when attempting to dereference it.
-
-Additionally, if a parent becomes invalid as a result of the
-layoutChange, it would be filtered out by the condition in the loop,
-resulting in a different result in the comparison of emptiness of the
-parents container.
-
-Fix that by persisting the parent's container, and performing the test
-for early-return before clearing the mapping.
-
-Task-number: QTBUG-47711
-Task-number: QTBUG-32981
-Change-Id: If45e8a1c97d39454160f52041bc9ae7e337dce97
-Reviewed-by: David Faure <david.faure@kdab.com>
----
- src/corelib/itemmodels/qsortfilterproxymodel.cpp | 31 ++---
- .../tst_qsortfilterproxymodel.cpp | 126 +++++++++++++++++++++
- 2 files changed, 137 insertions(+), 20 deletions(-)
-
-diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
-index b0ddfa8..3331521 100644
---- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
-+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
-@@ -171,6 +171,7 @@ public:
- QRowsRemoval itemsBeingRemoved;
-
- QModelIndexPairList saved_persistent_indexes;
-+ QList<QPersistentModelIndex> saved_layoutChange_parents;
-
- QHash<QModelIndex, Mapping *>::const_iterator create_mapping(
- const QModelIndex &source_parent) const;
-@@ -1331,23 +1332,23 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<Q
- Q_UNUSED(hint); // We can't forward Hint because we might filter additional rows or columns
- saved_persistent_indexes.clear();
-
-- QList<QPersistentModelIndex> parents;
-+ saved_layoutChange_parents.clear();
- for (const QPersistentModelIndex &parent : sourceParents) {
- if (!parent.isValid()) {
-- parents << QPersistentModelIndex();
-+ saved_layoutChange_parents << QPersistentModelIndex();
- continue;
- }
- const QModelIndex mappedParent = q->mapFromSource(parent);
- // Might be filtered out.
- if (mappedParent.isValid())
-- parents << mappedParent;
-+ saved_layoutChange_parents << mappedParent;
- }
-
- // All parents filtered out.
-- if (!sourceParents.isEmpty() && parents.isEmpty())
-+ if (!sourceParents.isEmpty() && saved_layoutChange_parents.isEmpty())
- return;
-
-- emit q->layoutAboutToBeChanged(parents);
-+ emit q->layoutAboutToBeChanged(saved_layoutChange_parents);
- if (persistent.indexes.isEmpty())
- return;
-
-@@ -1359,6 +1360,9 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged(const QList<QPersisten
- Q_Q(QSortFilterProxyModel);
- Q_UNUSED(hint); // We can't forward Hint because we might filter additional rows or columns
-
-+ if (!sourceParents.isEmpty() && saved_layoutChange_parents.isEmpty())
-+ return;
-+
- // Optimize: We only actually have to clear the mapping related to the contents of
- // sourceParents, not everything.
- qDeleteAll(source_index_mapping);
-@@ -1373,21 +1377,8 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged(const QList<QPersisten
- source_index_mapping.clear();
- }
-
-- QList<QPersistentModelIndex> parents;
-- for (const QPersistentModelIndex &parent : sourceParents) {
-- if (!parent.isValid()) {
-- parents << QPersistentModelIndex();
-- continue;
-- }
-- const QModelIndex mappedParent = q->mapFromSource(parent);
-- if (mappedParent.isValid())
-- parents << mappedParent;
-- }
--
-- if (!sourceParents.isEmpty() && parents.isEmpty())
-- return;
--
-- emit q->layoutChanged(parents);
-+ emit q->layoutChanged(saved_layoutChange_parents);
-+ saved_layoutChange_parents.clear();
- }
-
- void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeInserted(
-diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
-index 38e3c68..6b98d9f 100644
---- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
-+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
-@@ -145,6 +145,8 @@ private slots:
- void canDropMimeData();
- void filterHint();
-
-+ void sourceLayoutChangeLeavesValidPersistentIndexes();
-+
- protected:
- void buildHierarchy(const QStringList &data, QAbstractItemModel *model);
- void checkHierarchy(const QStringList &data, const QAbstractItemModel *model);
-@@ -4181,5 +4183,129 @@ void tst_QSortFilterProxyModel::filterHint()
- QAbstractItemModel::NoLayoutChangeHint);
- }
-
-+/**
-+
-+ Creates a model where each item has one child, to a set depth,
-+ and the last item has no children. For a model created with
-+ setDepth(4):
-+
-+ - 1
-+ - - 2
-+ - - - 3
-+ - - - - 4
-+*/
-+class StepTreeModel : public QAbstractItemModel
-+{
-+ Q_OBJECT
-+public:
-+ StepTreeModel(QObject * parent = 0)
-+ : QAbstractItemModel(parent), m_depth(0) {}
-+
-+ int columnCount(const QModelIndex& = QModelIndex()) const override { return 1; }
-+
-+ int rowCount(const QModelIndex& parent = QModelIndex()) const override
-+ {
-+ quintptr parentId = (parent.isValid()) ? parent.internalId() : 0;
-+ return (parentId < m_depth) ? 1 : 0;
-+ }
-+
-+ QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override
-+ {
-+ if (role != Qt::DisplayRole)
-+ return QVariant();
-+
-+ return QString::number(index.internalId());
-+ }
-+
-+ QModelIndex index(int, int, const QModelIndex& parent = QModelIndex()) const override
-+ {
-+ quintptr parentId = (parent.isValid()) ? parent.internalId() : 0;
-+ if (parentId >= m_depth)
-+ return QModelIndex();
-+
-+ return createIndex(0, 0, parentId + 1);
-+ }
-+
-+ QModelIndex parent(const QModelIndex& index) const override
-+ {
-+ if (index.internalId() == 0)
-+ return QModelIndex();
-+
-+ return createIndex(0, 0, index.internalId() - 1);
-+ }
-+
-+ void setDepth(quintptr depth)
-+ {
-+ int parentIdWithLayoutChange = (m_depth < depth) ? m_depth : depth;
-+
-+ QList<QPersistentModelIndex> parentsOfLayoutChange;
-+ parentsOfLayoutChange.push_back(createIndex(0, 0, parentIdWithLayoutChange));
-+
-+ layoutAboutToBeChanged(parentsOfLayoutChange);
-+
-+ auto existing = persistentIndexList();
-+
-+ QList<QModelIndex> updated;
-+
-+ for (auto idx : existing) {
-+ if (indexDepth(idx) <= depth)
-+ updated.push_back(idx);
-+ else
-+ updated.push_back({});
-+ }
-+
-+ m_depth = depth;
-+
-+ changePersistentIndexList(existing, updated);
-+
-+ layoutChanged(parentsOfLayoutChange);
-+ }
-+
-+private:
-+ static quintptr indexDepth(QModelIndex const& index)
-+ {
-+ return (index.isValid()) ? 1 + indexDepth(index.parent()) : 0;
-+ }
-+
-+private:
-+ quintptr m_depth;
-+};
-+
-+void tst_QSortFilterProxyModel::sourceLayoutChangeLeavesValidPersistentIndexes()
-+{
-+ StepTreeModel model;
-+ Q_SET_OBJECT_NAME(model);
-+ model.setDepth(4);
-+
-+ QSortFilterProxyModel proxy1;
-+ proxy1.setSourceModel(&model);
-+ Q_SET_OBJECT_NAME(proxy1);
-+
-+ proxy1.setFilterRegExp("1|2");
-+
-+ // The current state of things:
-+ // model proxy
-+ // - 1 - 1
-+ // - - 2 - - 2
-+ // - - - 3
-+ // - - - - 4
-+
-+ // The setDepth call below removes '4' with a layoutChanged call.
-+ // Because the proxy filters that out anyway, the proxy doesn't need
-+ // to emit any signals or update persistent indexes.
-+
-+ QPersistentModelIndex persistentIndex = proxy1.index(0, 0, proxy1.index(0, 0));
-+
-+ model.setDepth(3);
-+
-+ // Calling parent() causes the internalPointer to be used.
-+ // Before fixing QTBUG-47711, that could be a dangling pointer.
-+ // The use of qDebug here makes sufficient use of the heap to
-+ // cause corruption at runtime with normal use on linux (before
-+ // the fix). valgrind confirms the fix.
-+ qDebug() << persistentIndex.parent();
-+ QVERIFY(persistentIndex.parent().isValid());
-+}
-+
- QTEST_MAIN(tst_QSortFilterProxyModel)
- #include "tst_qsortfilterproxymodel.moc"
---
-2.7.4
-
-