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>
This commit is contained in:
Stephen Kelly 2016-12-20 00:44:12 +00:00
parent 0874861bcc
commit baad82d242
2 changed files with 85 additions and 9 deletions

View File

@ -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)

View File

@ -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"