summarylogtreecommitdiffstats
path: root/plasma-crash-3.patch
blob: 467390a946e7da0f80a33e7c8e20bf043a71f01c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
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 e537793146..7c306799d0 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 e946f3104a..564b8547b1 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"