From 3f0261ebe3010f12a887869ff5adf7ad30f5e4c7 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Mon, 2 Jun 2025 14:30:26 +0200 Subject: [PATCH] QSFPM: Support source model undergoing reset during setSourceModel Since 9d8663c18e88cb0b5a65f86cfd7726f3d31e04d6, we print a warning when endResetModel is called without beginResetModel. This however triggers false positives with a QSFPM if we set a source model which is resetting at this point in time: The QSFPM reacts to the endResetModel signal in _q_sourceReset by calling its own endResetModel, but it does not have the resetting flag set. Fix this by deferring the endResetModel work that we are doing in setSourceModel if the source is undergoing reset. Task-number: QTBUG-132775 Pick-to: 6.10 6.9 6.8 6.5 Change-Id: I363f2f34a06cc5de031fa87c6274322bf03bd77f Reviewed-by: David Faure --- src/corelib/itemmodels/qsortfilterproxymodel.cpp | 7 +++++++ .../tst_qsortfilterproxymodel.cpp | 12 ++++++++++++ .../tst_qsortfilterproxymodel.h | 1 + 3 files changed, 20 insertions(+) diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index 44f3bd33a69..c078fe06d0c 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -2110,6 +2110,13 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) QObjectPrivate::connect(d->model, &QAbstractItemModel::modelReset, d, &QSortFilterProxyModelPrivate::_q_sourceReset) }; + /* check whether we are connecting to a model that is undergoing a reset currently. + If it is, _q_sourceReset will take care of calling endResetModel, and of + calling sort if necessary. + */ + auto modelPrivate = d->model ? QAbstractItemModelPrivate::get(d->model) : nullptr; + if (modelPrivate && modelPrivate->resetting) + return; endResetModel(); if (d->update_source_sort_column() && d->dynamic_sortfilter) d->sort(); diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index ece1bfd912c..a53b34170ac 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -3663,6 +3663,18 @@ void tst_QSortFilterProxyModel::resetInvalidate() QCOMPARE(ok, works); } +void tst_QSortFilterProxyModel::sourceModelInReset() +{ + QTest::failOnWarning(); + QStandardItemModel m1; + QSortFilterProxyModel sfpm; + connect(&m1, &QAbstractItemModel::modelAboutToBeReset, &sfpm, [&]() { + sfpm.setSourceModel(&m1); + }); + m1.clear(); + QCOMPARE_EQ(sfpm.sourceModel(), &m1); +} + /** * A proxy which changes the background color for items ending in 'y' or 'r' */ diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.h b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.h index 78d06f32dab..e91fae84042 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.h +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.h @@ -104,6 +104,7 @@ private slots: void unnecessaryMapCreation(); void resetInvalidate_data(); void resetInvalidate(); + void sourceModelInReset(); void testMultipleProxiesWithSelection(); void mapSelectionFromSource();