diff options
author | Andreas Sturmlechner <asturm@gentoo.org> | 2017-04-23 15:54:19 +0200 |
---|---|---|
committer | Andreas Sturmlechner <asturm@gentoo.org> | 2017-04-23 21:07:31 +0200 |
commit | 87e6967f8b82468e077a8f2004732e2db1cbf751 (patch) | |
tree | 160d57d4bb1c65498069219e4756d4a35be8dec6 /dev-qt | |
parent | kde-apps: Add blockers against kde-apps/kdepim-l10n (diff) | |
download | gentoo-87e6967f8b82468e077a8f2004732e2db1cbf751.tar.gz gentoo-87e6967f8b82468e077a8f2004732e2db1cbf751.tar.bz2 gentoo-87e6967f8b82468e077a8f2004732e2db1cbf751.zip |
dev-qt/qtcore: Try to fix random plasmashell crashes
Backports from Qt-5.8.0.
See also: https://bugs.kde.org/show_bug.cgi?id=342763
Package-Manager: Portage-2.3.3, Repoman-2.3.1
Diffstat (limited to 'dev-qt')
-rw-r--r-- | dev-qt/qtcore/files/qtcore-5.7.1-qipm.patch | 152 | ||||
-rw-r--r-- | dev-qt/qtcore/files/qtcore-5.7.1-qsfpm-1.patch | 252 | ||||
-rw-r--r-- | dev-qt/qtcore/files/qtcore-5.7.1-qsfpm-2.patch | 195 | ||||
-rw-r--r-- | dev-qt/qtcore/qtcore-5.7.1-r3.ebuild | 48 |
4 files changed, 647 insertions, 0 deletions
diff --git a/dev-qt/qtcore/files/qtcore-5.7.1-qipm.patch b/dev-qt/qtcore/files/qtcore-5.7.1-qipm.patch new file mode 100644 index 000000000000..abea14588075 --- /dev/null +++ b/dev-qt/qtcore/files/qtcore-5.7.1-qipm.patch @@ -0,0 +1,152 @@ +From baad82d242a4d8c1af6c87faaa7f25584183fd53 Mon Sep 17 00:00:00 2001 +From: Stephen Kelly <steveire@gmail.com> +Date: Tue, 20 Dec 2016 00:44:12 +0000 +Subject: [PATCH] QIPM: Persist model indexes after emitting layoutChange, not + before + +Callers can persist a QModelIndex which was not persisted before in a +slot connected to the signal, and such a persisted index must be updated +in the course of the layoutChange. + +Store the indexes to persist after emitting the signal. + +Task-number: QTBUG-32981 +Change-Id: Ibee4c0d84817d72603a03fe5b22fdeefeac0695e +Reviewed-by: David Faure <david.faure@kdab.com> +--- + src/corelib/itemmodels/qidentityproxymodel.cpp | 18 ++--- + .../tst_qidentityproxymodel.cpp | 76 ++++++++++++++++++++++ + 2 files changed, 85 insertions(+), 9 deletions(-) + +diff --git a/src/corelib/itemmodels/qidentityproxymodel.cpp b/src/corelib/itemmodels/qidentityproxymodel.cpp +index e537793..7c30679 100644 +--- a/src/corelib/itemmodels/qidentityproxymodel.cpp ++++ b/src/corelib/itemmodels/qidentityproxymodel.cpp +@@ -496,15 +496,6 @@ void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<QPe + { + Q_Q(QIdentityProxyModel); + +- const auto proxyPersistentIndexes = q->persistentIndexList(); +- for (const QPersistentModelIndex &proxyPersistentIndex : proxyPersistentIndexes) { +- proxyIndexes << proxyPersistentIndex; +- Q_ASSERT(proxyPersistentIndex.isValid()); +- const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex); +- Q_ASSERT(srcPersistentIndex.isValid()); +- layoutChangePersistentIndexes << srcPersistentIndex; +- } +- + QList<QPersistentModelIndex> parents; + parents.reserve(sourceParents.size()); + for (const QPersistentModelIndex &parent : sourceParents) { +@@ -518,6 +509,15 @@ void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<QPe + } + + q->layoutAboutToBeChanged(parents, hint); ++ ++ const auto proxyPersistentIndexes = q->persistentIndexList(); ++ for (const QPersistentModelIndex &proxyPersistentIndex : proxyPersistentIndexes) { ++ proxyIndexes << proxyPersistentIndex; ++ Q_ASSERT(proxyPersistentIndex.isValid()); ++ const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex); ++ Q_ASSERT(srcPersistentIndex.isValid()); ++ layoutChangePersistentIndexes << srcPersistentIndex; ++ } + } + + void QIdentityProxyModelPrivate::_q_sourceLayoutChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint) +diff --git a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp +index e946f31..564b854 100644 +--- a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp ++++ b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp +@@ -68,6 +68,8 @@ private slots: + + void itemData(); + ++ void persistIndexOnLayoutChange(); ++ + protected: + void verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent = QModelIndex()); + +@@ -377,5 +379,79 @@ void tst_QIdentityProxyModel::itemData() + QCOMPARE(proxy.itemData(topIndex).value(Qt::DisplayRole).toString(), QStringLiteral("Monday_appended")); + } + ++void dump(QAbstractItemModel* model, QString const& indent = " - ", QModelIndex const& parent = {}) ++{ ++ for (auto row = 0; row < model->rowCount(parent); ++row) ++ { ++ auto idx = model->index(row, 0, parent); ++ qDebug() << (indent + idx.data().toString()); ++ dump(model, indent + "- ", idx); ++ } ++} ++ ++void tst_QIdentityProxyModel::persistIndexOnLayoutChange() ++{ ++ DynamicTreeModel model; ++ ++ QList<int> ancestors; ++ for (auto i = 0; i < 3; ++i) ++ { ++ Q_UNUSED(i); ++ ModelInsertCommand insertCommand(&model); ++ insertCommand.setAncestorRowNumbers(ancestors); ++ insertCommand.setStartRow(0); ++ insertCommand.setEndRow(0); ++ insertCommand.doCommand(); ++ ancestors.push_back(0); ++ } ++ ModelInsertCommand insertCommand(&model); ++ insertCommand.setAncestorRowNumbers(ancestors); ++ insertCommand.setStartRow(0); ++ insertCommand.setEndRow(1); ++ insertCommand.doCommand(); ++ ++ // dump(&model); ++ // " - 1" ++ // " - - 2" ++ // " - - - 3" ++ // " - - - - 4" ++ // " - - - - 5" ++ ++ QIdentityProxyModel proxy; ++ proxy.setSourceModel(&model); ++ ++ QPersistentModelIndex persistentIndex; ++ ++ QPersistentModelIndex sourcePersistentIndex = model.match(model.index(0, 0), Qt::DisplayRole, "5", 1, Qt::MatchRecursive).first(); ++ ++ QCOMPARE(sourcePersistentIndex.data().toString(), QStringLiteral("5")); ++ ++ bool gotLayoutAboutToBeChanged = false; ++ bool gotLayoutChanged = false; ++ ++ QObject::connect(&proxy, &QAbstractItemModel::layoutAboutToBeChanged, &proxy, [&proxy, &persistentIndex, &gotLayoutAboutToBeChanged] ++ { ++ gotLayoutAboutToBeChanged = true; ++ persistentIndex = proxy.match(proxy.index(0, 0), Qt::DisplayRole, "5", 1, Qt::MatchRecursive).first(); ++ }); ++ ++ QObject::connect(&proxy, &QAbstractItemModel::layoutChanged, &proxy, [&proxy, &persistentIndex, &sourcePersistentIndex, &gotLayoutChanged] ++ { ++ gotLayoutChanged = true; ++ QCOMPARE(QModelIndex(persistentIndex), proxy.mapFromSource(sourcePersistentIndex)); ++ }); ++ ++ ModelChangeChildrenLayoutsCommand layoutChangeCommand(&model, 0); ++ ++ layoutChangeCommand.setAncestorRowNumbers(QList<int>{0, 0, 0}); ++ layoutChangeCommand.setSecondAncestorRowNumbers(QList<int>{0, 0}); ++ ++ layoutChangeCommand.doCommand(); ++ ++ QVERIFY(gotLayoutAboutToBeChanged); ++ QVERIFY(gotLayoutChanged); ++ QVERIFY(persistentIndex.isValid()); ++} ++ + QTEST_MAIN(tst_QIdentityProxyModel) + #include "tst_qidentityproxymodel.moc" +-- +2.7.4 + 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 new file mode 100644 index 000000000000..9edbe18617a2 --- /dev/null +++ b/dev-qt/qtcore/files/qtcore-5.7.1-qsfpm-1.patch @@ -0,0 +1,252 @@ +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 + + diff --git a/dev-qt/qtcore/files/qtcore-5.7.1-qsfpm-2.patch b/dev-qt/qtcore/files/qtcore-5.7.1-qsfpm-2.patch new file mode 100644 index 000000000000..973649637e66 --- /dev/null +++ b/dev-qt/qtcore/files/qtcore-5.7.1-qsfpm-2.patch @@ -0,0 +1,195 @@ +From 0874861bcc70313c343aba5e5566ed30b69eed1c Mon Sep 17 00:00:00 2001 +From: Stephen Kelly <steveire@gmail.com> +Date: Mon, 19 Dec 2016 21:13:57 +0000 +Subject: [PATCH] QSFPM: Remove data manipulation from move handlers + +Similar to the fix in the parent commit, incorrect updating of the +internal data structures during layout changes can lead to dangling +pointers being dereferenced later. Moves are treated as layoutChanges +by this proxy by forwarding to the appropriate method. However, data is +incorrectly cleared prior to that forwarding. Remove that, and let the +layoutChange handling take appropriate action. + +Change-Id: Iee951e37152328a4e6a5fb8e5385c32a2fe4c0bd +Reviewed-by: David Faure <david.faure@kdab.com> +--- + src/corelib/itemmodels/qsortfilterproxymodel.cpp | 67 ++++------------------ + .../tst_qsortfilterproxymodel.cpp | 46 +++++++++++++++ + 2 files changed, 58 insertions(+), 55 deletions(-) + +diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp +index 3331521..226a240 100644 +--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp ++++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp +@@ -1418,49 +1418,27 @@ void QSortFilterProxyModelPrivate::_q_sourceRowsRemoved( + void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeMoved( + const QModelIndex &sourceParent, int /* sourceStart */, int /* sourceEnd */, const QModelIndex &destParent, int /* dest */) + { +- Q_Q(QSortFilterProxyModel); + // Because rows which are contiguous in the source model might not be contiguous + // in the proxy due to sorting, the best thing we can do here is be specific about what + // parents are having their children changed. + // Optimize: Emit move signals if the proxy is not sorted. Will need to account for rows + // being filtered out though. + +- saved_persistent_indexes.clear(); +- + QList<QPersistentModelIndex> parents; +- parents << q->mapFromSource(sourceParent); ++ parents << sourceParent; + if (sourceParent != destParent) +- parents << q->mapFromSource(destParent); +- emit q->layoutAboutToBeChanged(parents); +- if (persistent.indexes.isEmpty()) +- return; +- saved_persistent_indexes = store_persistent_indexes(); ++ parents << destParent; ++ _q_sourceLayoutAboutToBeChanged(parents, QAbstractItemModel::NoLayoutChangeHint); + } + + void QSortFilterProxyModelPrivate::_q_sourceRowsMoved( + const QModelIndex &sourceParent, int /* sourceStart */, int /* sourceEnd */, const QModelIndex &destParent, int /* dest */) + { +- Q_Q(QSortFilterProxyModel); +- +- // Optimize: We only need to clear and update the persistent indexes which are children of +- // sourceParent or destParent +- qDeleteAll(source_index_mapping); +- source_index_mapping.clear(); +- +- update_persistent_indexes(saved_persistent_indexes); +- saved_persistent_indexes.clear(); +- +- if (dynamic_sortfilter && update_source_sort_column()) { +- //update_source_sort_column might have created wrong mapping so we have to clear it again +- qDeleteAll(source_index_mapping); +- source_index_mapping.clear(); +- } +- + QList<QPersistentModelIndex> parents; +- parents << q->mapFromSource(sourceParent); ++ parents << sourceParent; + if (sourceParent != destParent) +- parents << q->mapFromSource(destParent); +- emit q->layoutChanged(parents); ++ parents << destParent; ++ _q_sourceLayoutChanged(parents, QAbstractItemModel::NoLayoutChangeHint); + } + + void QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeInserted( +@@ -1522,42 +1500,21 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsRemoved( + void QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeMoved( + const QModelIndex &sourceParent, int /* sourceStart */, int /* sourceEnd */, const QModelIndex &destParent, int /* dest */) + { +- Q_Q(QSortFilterProxyModel); +- +- saved_persistent_indexes.clear(); +- + QList<QPersistentModelIndex> parents; +- parents << q->mapFromSource(sourceParent); ++ parents << sourceParent; + if (sourceParent != destParent) +- parents << q->mapFromSource(destParent); +- emit q->layoutAboutToBeChanged(parents); +- +- if (persistent.indexes.isEmpty()) +- return; +- saved_persistent_indexes = store_persistent_indexes(); ++ parents << destParent; ++ _q_sourceLayoutAboutToBeChanged(parents, QAbstractItemModel::NoLayoutChangeHint); + } + + void QSortFilterProxyModelPrivate::_q_sourceColumnsMoved( + const QModelIndex &sourceParent, int /* sourceStart */, int /* sourceEnd */, const QModelIndex &destParent, int /* dest */) + { +- Q_Q(QSortFilterProxyModel); +- +- qDeleteAll(source_index_mapping); +- source_index_mapping.clear(); +- +- update_persistent_indexes(saved_persistent_indexes); +- saved_persistent_indexes.clear(); +- +- if (dynamic_sortfilter && update_source_sort_column()) { +- qDeleteAll(source_index_mapping); +- source_index_mapping.clear(); +- } +- + QList<QPersistentModelIndex> parents; +- parents << q->mapFromSource(sourceParent); ++ parents << sourceParent; + if (sourceParent != destParent) +- parents << q->mapFromSource(destParent); +- emit q->layoutChanged(parents); ++ parents << destParent; ++ _q_sourceLayoutChanged(parents, QAbstractItemModel::NoLayoutChangeHint); + } + + /*! +diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +index 6b98d9f..7b6c470 100644 +--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp ++++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +@@ -146,6 +146,7 @@ private slots: + void filterHint(); + + void sourceLayoutChangeLeavesValidPersistentIndexes(); ++ void rowMoveLeavesValidPersistentIndexes(); + + protected: + void buildHierarchy(const QStringList &data, QAbstractItemModel *model); +@@ -4307,5 +4308,50 @@ void tst_QSortFilterProxyModel::sourceLayoutChangeLeavesValidPersistentIndexes() + QVERIFY(persistentIndex.parent().isValid()); + } + ++void tst_QSortFilterProxyModel::rowMoveLeavesValidPersistentIndexes() ++{ ++ DynamicTreeModel model; ++ Q_SET_OBJECT_NAME(model); ++ ++ QList<int> ancestors; ++ for (auto i = 0; i < 5; ++i) ++ { ++ Q_UNUSED(i); ++ ModelInsertCommand insertCommand(&model); ++ insertCommand.setAncestorRowNumbers(ancestors); ++ insertCommand.setStartRow(0); ++ insertCommand.setEndRow(0); ++ insertCommand.doCommand(); ++ ancestors.push_back(0); ++ } ++ ++ QSortFilterProxyModel proxy1; ++ proxy1.setSourceModel(&model); ++ Q_SET_OBJECT_NAME(proxy1); ++ ++ proxy1.setFilterRegExp("1|2"); ++ ++ auto item5 = model.match(model.index(0, 0), Qt::DisplayRole, "5", 1, Qt::MatchRecursive).first(); ++ auto item3 = model.match(model.index(0, 0), Qt::DisplayRole, "3", 1, Qt::MatchRecursive).first(); ++ ++ Q_ASSERT(item5.isValid()); ++ Q_ASSERT(item3.isValid()); ++ ++ QPersistentModelIndex persistentIndex = proxy1.match(proxy1.index(0, 0), Qt::DisplayRole, "2", 1, Qt::MatchRecursive).first(); ++ ++ ModelMoveCommand moveCommand(&model, 0); ++ moveCommand.setAncestorRowNumbers(QList<int>{0, 0, 0, 0}); ++ moveCommand.setStartRow(0); ++ moveCommand.setEndRow(0); ++ moveCommand.setDestRow(0); ++ moveCommand.setDestAncestors(QList<int>{0, 0, 0}); ++ moveCommand.doCommand(); ++ ++ // Calling parent() causes the internalPointer to be used. ++ // Before fixing QTBUG-47711 (moveRows case), that could be ++ // a dangling pointer. ++ QVERIFY(persistentIndex.parent().isValid()); ++} ++ + QTEST_MAIN(tst_QSortFilterProxyModel) + #include "tst_qsortfilterproxymodel.moc" +-- +2.7.4 + + diff --git a/dev-qt/qtcore/qtcore-5.7.1-r3.ebuild b/dev-qt/qtcore/qtcore-5.7.1-r3.ebuild new file mode 100644 index 000000000000..93fad42b1eba --- /dev/null +++ b/dev-qt/qtcore/qtcore-5.7.1-r3.ebuild @@ -0,0 +1,48 @@ +# Copyright 1999-2017 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +EAPI=6 +QT5_MODULE="qtbase" +inherit qt5-build + +DESCRIPTION="Cross-platform application development framework" + +if [[ ${QT5_BUILD_TYPE} == release ]]; then + KEYWORDS="~amd64 ~arm ~arm64 ~hppa ~ppc ~ppc64 ~x86" +fi + +IUSE="icu systemd" + +DEPEND=" + dev-libs/double-conversion:= + dev-libs/glib:2 + >=dev-libs/libpcre-8.38[pcre16,unicode] + >=sys-libs/zlib-1.2.5 + virtual/libiconv + icu? ( dev-libs/icu:= ) + systemd? ( sys-apps/systemd:= ) +" +RDEPEND="${DEPEND}" + +PATCHES=( + "${FILESDIR}"/${PN}-5.6.2-plugins.patch + "${FILESDIR}"/${P}-qipm.patch + "${FILESDIR}"/${P}-qsfpm-{1,2}.patch +) + +QT5_TARGET_SUBDIRS=( + src/tools/bootstrap + src/tools/moc + src/tools/rcc + src/corelib + src/tools/qlalr + doc +) + +src_configure() { + local myconf=( + $(qt_use icu) + $(qt_use systemd journald) + ) + qt5-build_src_configure +} |