diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index 36b1189..5aba1a4 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -18,6 +18,7 @@ ecm_add_tests( kdescendantsproxymodel_smoketest.cpp klinkitemselectionmodeltest.cpp testmodelqueuedconnections.cpp + kselectionproxymodeltest.cpp LINK_LIBRARIES KF5::ItemModels Qt5::Test Qt5::Widgets proxymodeltestsuite ) diff --git a/autotests/kselectionproxymodeltest.cpp b/autotests/kselectionproxymodeltest.cpp new file mode 100644 index 0000000..3464c00 --- /dev/null +++ b/autotests/kselectionproxymodeltest.cpp @@ -0,0 +1,51 @@ + +#include +#include + +#include + +class KSelectionProxyModelTest : public QObject +{ + Q_OBJECT +public: + KSelectionProxyModelTest(QObject* parent = 0) + : QObject(parent) + { + + } + +private Q_SLOTS: + void selectOnSourceReset(); +}; + +void KSelectionProxyModelTest::selectOnSourceReset() +{ + QStringListModel strings({ + "Monday", + "Tuesday", + "Wednesday", + "Thursday" + }); + QItemSelectionModel selectionModel(&strings); + + connect(&strings, &QAbstractItemModel::modelReset, [&] { + selectionModel.select(QItemSelection(strings.index(0, 0), strings.index(2, 0)), + QItemSelectionModel::Select); + }); + + KSelectionProxyModel proxy(&selectionModel); + proxy.setSourceModel(&strings); + + selectionModel.select(QItemSelection(strings.index(0, 0), strings.index(2, 0)), + QItemSelectionModel::Select); + + strings.setStringList({ "One", "Two", "Three", "Four" }); + + QVERIFY(selectionModel.selection().contains(strings.index(0, 0))); + QVERIFY(selectionModel.selection().contains(strings.index(1, 0))); + QVERIFY(selectionModel.selection().contains(strings.index(2, 0))); +} + +QTEST_MAIN(KSelectionProxyModelTest) + +#include "kselectionproxymodeltest.moc" diff --git a/src/kselectionproxymodel.cpp b/src/kselectionproxymodel.cpp index 42e5404..42ba106 100644 --- a/src/kselectionproxymodel.cpp +++ b/src/kselectionproxymodel.cpp @@ -439,6 +439,7 @@ public: m_rowsRemoved(false), m_rowsMoved(false), m_resetting(false), + m_sourceModelResetting(false), m_doubleResetting(false), m_layoutChanging(false), m_ignoreNextLayoutAboutToBeChanged(false), @@ -621,6 +622,7 @@ public: QPair m_proxyRemoveRows; bool m_rowsMoved; bool m_resetting; + bool m_sourceModelResetting; bool m_doubleResetting; bool m_layoutChanging; bool m_ignoreNextLayoutAboutToBeChanged; @@ -863,6 +865,7 @@ void KSelectionProxyModelPrivate::sourceModelDestroyed() // There is very little we can do here. resetInternalData(); m_resetting = false; + m_sourceModelResetting = false; } void KSelectionProxyModelPrivate::sourceModelAboutToBeReset() @@ -887,6 +890,7 @@ void KSelectionProxyModelPrivate::sourceModelAboutToBeReset() q->beginResetModel(); m_resetting = true; + m_sourceModelResetting = true; } void KSelectionProxyModelPrivate::sourceModelReset() @@ -899,11 +903,7 @@ void KSelectionProxyModelPrivate::sourceModelReset() } resetInternalData(); - // No need to try to refill this. When the model is reset it doesn't have a meaningful selection anymore, - // but when it gets one we'll be notified anyway. - if (!m_selectionModel.isNull()) { - m_selectionModel.data()->reset(); - } + m_sourceModelResetting = false; m_resetting = false; q->endResetModel(); } @@ -1860,6 +1860,10 @@ void KSelectionProxyModelPrivate::selectionChanged(const QItemSelection &_select return; } + if (m_sourceModelResetting) { + return; + } + if (m_rowsInserted || m_rowsRemoved) { m_pendingSelectionChanges.append(PendingSelectionChange(_selected, _deselected)); return;