From b5f6a85d2745ab6ac97f593664d255906923e737 Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Thu, 5 Mar 2020 10:08:40 +0100 Subject: Add a way to filter only rows or columns in QSortFilterProxyModel If we want to filter away a column without changing the filtering for the rows calling invalidateFilter() is wasteful because it will call filterAcceptsRow() for all rows even though that is not needed. This commit add two functions, invalidateRowsFilter() and invalidateColumnsFilter() that work the same way as invalidateFilter() except that they will invoke respectively only filterAcceptsRow() and filterAcceptsColumn(). Change-Id: Ib4351cf08c229bd97bbbfee6da92397dca579a84 Reviewed-by: David Faure --- .../tst_qsortfilterproxymodel.cpp | 80 ++++++++++++++++++++++ .../tst_qsortfilterproxymodel.h | 2 + 2 files changed, 82 insertions(+) (limited to 'tests/auto/corelib/itemmodels') diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp index 7f9a996136..a01f5bcf46 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp @@ -4940,4 +4940,84 @@ void tst_QSortFilterProxyModel::filterAndInsertRow() } } +void tst_QSortFilterProxyModel::invalidateColumnsOrRowsFilter() +{ + class FilterProxy : public QSortFilterProxyModel + { + public: + FilterProxy() + {} + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override + { + rowFiltered++; + + if (sourceModel()->data(sourceModel()->index(source_row, 0, source_parent)).toString() == QLatin1String("A1")) + return !rejectA1; + return true; + } + bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override + { + Q_UNUSED(source_column) + Q_UNUSED(source_parent) + + columnFiltered++; + return true; + } + + mutable int rowFiltered = 0; + mutable int columnFiltered = 0; + bool rejectA1 = false; + + using QSortFilterProxyModel::invalidateFilter; + using QSortFilterProxyModel::invalidateRowsFilter; + using QSortFilterProxyModel::invalidateColumnsFilter; + }; + QStandardItemModel model(10, 4); + for (int i = 0; i < model.rowCount(); ++i) { + for (int j = 0; j < model.columnCount(); ++j) { + model.setItem(i, j, new QStandardItem(QString('A' + j) + QString::number(i + 1))); + model.item(i, 0)->appendColumn({ new QStandardItem(QString("child col %0").arg(j)) }); + } + } + FilterProxy proxy; + proxy.setSourceModel(&model); + + QTreeView view; + view.setModel(&proxy); + view.expandAll(); + + QCOMPARE(proxy.rowFiltered, 20); //10 parents + 10 children + QCOMPARE(proxy.columnFiltered, 44); // 4 parents + 4 * 10 children + + proxy.rowFiltered = proxy.columnFiltered = 0; + proxy.invalidateFilter(); + + QCOMPARE(proxy.rowFiltered, 20); + QCOMPARE(proxy.columnFiltered, 44); + + proxy.rowFiltered = proxy.columnFiltered = 0; + proxy.invalidateRowsFilter(); + + QCOMPARE(proxy.rowFiltered, 20); + QCOMPARE(proxy.columnFiltered, 0); + + proxy.rowFiltered = proxy.columnFiltered = 0; + proxy.invalidateColumnsFilter(); + + QCOMPARE(proxy.rowFiltered, 0); + QCOMPARE(proxy.columnFiltered, 44); + + QCOMPARE(proxy.rowCount(), 10); + proxy.rejectA1 = true; + proxy.rowFiltered = proxy.columnFiltered = 0; + proxy.invalidateRowsFilter(); + QCOMPARE(proxy.rowCount(), 9); + QCOMPARE(proxy.rowFiltered, 19); // it will not check the child row of A1 + + proxy.rowFiltered = proxy.columnFiltered = 0; + proxy.setRecursiveFilteringEnabled(true); // this triggers invalidateRowsFilter() + QCOMPARE(proxy.rowCount(), 10); + QCOMPARE(proxy.rowFiltered, 20); +} + #include "tst_qsortfilterproxymodel.moc" diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h index 71662bda07..703f168cdb 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h @@ -159,6 +159,8 @@ private slots: void removeIntervals_data(); void removeIntervals(); + void invalidateColumnsOrRowsFilter(); + protected: void buildHierarchy(const QStringList &data, QAbstractItemModel *model); void checkHierarchy(const QStringList &data, const QAbstractItemModel *model); -- cgit v1.2.3