QStandardItemModel: do not reset persisten index in setItem()

When an existing item is replaced with a new one in
QStandardItemModel::setItem() then the persitent index is invalidated
which leads to some unexpected behaviors (like e.g the header size and
resize mode are reset).
Therefore we have to make sure that the invalidation does not happen.
This can be achieved by delaying the call to QStandardItem::setModel()
for the old item until the new is properly added. After this, the old
item no longer gets a valid QModelIndex from the model and therefore
can't invalidate the persistent index anymore.

Fixes: QTBUG-13605
Fixes: QTBUG-73000
Fixes: QTBUG-80586
Change-Id: I4e45e6feb81b7287c0859f638d7ab1a576fc2f0f
Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
Christian Ehrlicher 2019-12-06 21:56:41 +01:00
parent e076965542
commit 4522b17159
2 changed files with 32 additions and 1 deletions

View File

@ -138,10 +138,19 @@ void QStandardItemPrivate::setChild(int row, int column, QStandardItem *item,
return;
}
}
// setting the model to nullptr invalidates the persistent index which we want to avoid
if (!item && oldItem)
oldItem->d_func()->setModel(nullptr);
children.replace(index, item);
// since now indexFromItem() does no longer return a valid index, the persistent index
// will not be invalidated anymore
if (oldItem)
oldItem->d_func()->setModel(nullptr);
delete oldItem;
children.replace(index, item);
if (item)
item->d_func()->lastKnownIndex = index;

View File

@ -131,6 +131,7 @@ private slots:
void supportedDragDropActions();
void taskQTBUG_45114_setItemData();
void setItemPersistentIndex();
private:
QStandardItemModel *m_model;
@ -1811,5 +1812,26 @@ void tst_QStandardItemModel::taskQTBUG_45114_setItemData()
QVERIFY(!itemRoles.keys().contains(Qt::UserRole + 3));
}
void tst_QStandardItemModel::setItemPersistentIndex()
{
QPersistentModelIndex persistentIndex;
// setItem on an already existing item should not destroy the persistent index
QStandardItemModel m;
persistentIndex = m.index(0, 0);
QVERIFY(!persistentIndex.isValid());
m.setItem(0, 0, new QStandardItem);
persistentIndex = m.index(0, 0);
QVERIFY(persistentIndex.isValid());
QCOMPARE(persistentIndex.row(), 0);
QCOMPARE(persistentIndex.column(), 0);
m.setItem(0, 0, new QStandardItem);
QVERIFY(persistentIndex.isValid());
m.setItem(0, 0, nullptr);
QVERIFY(!persistentIndex.isValid());
}
QTEST_MAIN(tst_QStandardItemModel)
#include "tst_qstandarditemmodel.moc"