From e77e820191919aaf54c85f599cf71cfbecd1ee14 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 25 Feb 2011 14:06:57 +0100 Subject: QSortFilterProxyModel::reset() should invalidate. This was broken by: d149a3faca9b97ce806249bc7ef73fe2f59589d5 The connection was removed in that commit because we did not want the layoutChanged signal to be emitted. So instead of calling invalidate(), we call clearMapping() directly. In order to do that, clear_mapping has been turned into a private slot Task-number: QTBUG-17812 Reviewed-by: Gabriel --- src/gui/itemviews/qsortfilterproxymodel.cpp | 15 +++--- src/gui/itemviews/qsortfilterproxymodel.h | 1 + .../tst_qsortfilterproxymodel.cpp | 57 ++++++++++++++++++++++ 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index e54cbd2..9f89bf5 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -227,7 +227,7 @@ public: void _q_sourceColumnsRemoved(const QModelIndex &source_parent, int start, int end); - void clear_mapping(); + void _q_clearMapping(); void sort(); bool update_source_sort_column(); @@ -281,7 +281,7 @@ typedef QHash IndexMap; void QSortFilterProxyModelPrivate::_q_sourceModelDestroyed() { QAbstractProxyModelPrivate::_q_sourceModelDestroyed(); - clear_mapping(); + _q_clearMapping(); } void QSortFilterProxyModelPrivate::remove_from_mapping(const QModelIndex &source_parent) @@ -293,7 +293,7 @@ void QSortFilterProxyModelPrivate::remove_from_mapping(const QModelIndex &source } } -void QSortFilterProxyModelPrivate::clear_mapping() +void QSortFilterProxyModelPrivate::_q_clearMapping() { // store the persistent indexes QModelIndexPairList source_indexes = store_persistent_indexes(); @@ -1223,7 +1223,7 @@ void QSortFilterProxyModelPrivate::_q_sourceReset() { Q_Q(QSortFilterProxyModel); invalidatePersistentIndexes(); - clear_mapping(); + _q_clearMapping(); // All internal structures are deleted in clear() q->endResetModel(); update_source_sort_column(); @@ -1519,6 +1519,7 @@ QSortFilterProxyModel::QSortFilterProxyModel(QObject *parent) d->filter_column = 0; d->filter_role = Qt::DisplayRole; d->dynamic_sortfilter = false; + connect(this, SIGNAL(modelReset()), this, SLOT(_q_clearMapping())); } /*! @@ -1620,7 +1621,7 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) connect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset())); connect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset())); - d->clear_mapping(); + d->_q_clearMapping(); endResetModel(); if (d->update_source_sort_column() && d->dynamic_sortfilter) d->sort(); @@ -2311,7 +2312,7 @@ void QSortFilterProxyModel::clear() { Q_D(QSortFilterProxyModel); emit layoutAboutToBeChanged(); - d->clear_mapping(); + d->_q_clearMapping(); emit layoutChanged(); } @@ -2326,7 +2327,7 @@ void QSortFilterProxyModel::invalidate() { Q_D(QSortFilterProxyModel); emit layoutAboutToBeChanged(); - d->clear_mapping(); + d->_q_clearMapping(); emit layoutChanged(); } diff --git a/src/gui/itemviews/qsortfilterproxymodel.h b/src/gui/itemviews/qsortfilterproxymodel.h index 09fd20f..afeaa69 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.h +++ b/src/gui/itemviews/qsortfilterproxymodel.h @@ -189,6 +189,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsInserted(const QModelIndex &source_parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeRemoved(const QModelIndex &source_parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsRemoved(const QModelIndex &source_parent, int start, int end)) + Q_PRIVATE_SLOT(d_func(), void _q_clearMapping()) }; QT_END_NAMESPACE diff --git a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index bce7281..dfe47cb 100644 --- a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -144,6 +144,8 @@ private slots: void taskQTBUG_7537_appearsAndSort(); void taskQTBUG_7716_unnecessaryDynamicSorting(); void taskQTBUG_10287_unnecessaryMapCreation(); + void taskQTBUG_17812_resetInvalidate_data(); + void taskQTBUG_17812_resetInvalidate(); void testMultipleProxiesWithSelection(); void mapSelectionFromSource(); @@ -3213,5 +3215,60 @@ void tst_QSortFilterProxyModel::filteredColumns() } +void tst_QSortFilterProxyModel::taskQTBUG_17812_resetInvalidate_data() +{ + QTest::addColumn("test"); + QTest::addColumn("works"); + + QTest::newRow("nothing") << 0 << false; + QTest::newRow("reset") << 1 << true; + QTest::newRow("invalidate") << 2 << true; + QTest::newRow("invalidate_filter") << 3 << true; +} + +void tst_QSortFilterProxyModel::taskQTBUG_17812_resetInvalidate() +{ + QFETCH(int, test); + QFETCH(bool, works); + + struct Proxy : QSortFilterProxyModel { + QString pattern; + virtual bool filterAcceptsRow(int source_row, const QModelIndex&) const { + return sourceModel()->data(sourceModel()->index(source_row, 0)).toString().contains(pattern); + } + void notifyChange(int test) { + switch (test) { + case 0: break; + case 1: reset(); break; + case 2: invalidate(); break; + case 3: invalidateFilter(); break; + } + } + }; + + QStringListModel sourceModel(QStringList() << "Poisson" << "Vache" << "Brebis" + << "Elephant" << "Cochon" << "Serpent" + << "Mouton" << "Ecureuil" << "Mouche"); + Proxy proxy; + proxy.pattern = QString::fromLatin1("n"); + proxy.setSourceModel(&sourceModel); + + QCOMPARE(proxy.rowCount(), 5); + for (int i = 0; i < proxy.rowCount(); i++) { + QVERIFY(proxy.data(proxy.index(i,0)).toString().contains('n')); + } + + proxy.pattern = QString::fromLatin1("o"); + proxy.notifyChange(test); + + QCOMPARE(proxy.rowCount(), works ? 4 : 5); + bool ok = true; + for (int i = 0; i < proxy.rowCount(); i++) { + if (!proxy.data(proxy.index(i,0)).toString().contains('o')) + ok = false; + } + QCOMPARE(ok, works); +} + QTEST_MAIN(tst_QSortFilterProxyModel) #include "tst_qsortfilterproxymodel.moc" -- cgit v0.12