diff --git a/autotests/ksortfilterproxymodel_qml.cpp b/autotests/ksortfilterproxymodel_qml.cpp --- a/autotests/ksortfilterproxymodel_qml.cpp +++ b/autotests/ksortfilterproxymodel_qml.cpp @@ -61,12 +61,13 @@ "import org.kde.kitemmodels 1.0\n" "KSortFilterProxyModel\n" "{\n" + " property int modulo: 2\n" " sourceModel: KNumberModel {\n" " minimumValue: 1\n" " maximumValue: 10\n" " }\n" " filterRowCallback: function(source_row, source_parent) {\n" - " return sourceModel.data(sourceModel.index(source_row, 0, source_parent), Qt.DisplayRole) % 2 == 1;\n" + " return sourceModel.data(sourceModel.index(source_row, 0, source_parent), Qt.DisplayRole) % modulo == 1;\n" " };\n" "}\n"); QCOMPARE(app.rootObjects().count(), 1); @@ -80,8 +81,27 @@ QCOMPARE(filterModel->data(filterModel->index(2, 0)).toString(), "5"); QCOMPARE(filterModel->data(filterModel->index(3, 0)).toString(), "7"); QCOMPARE(filterModel->data(filterModel->index(4, 0)).toString(), "9"); -} + filterModel->setProperty("modulo", 3); + + // Nothing should change until we call invalidateFilter + QCOMPARE(filterModel->rowCount(), 5); + QCOMPARE(filterModel->data(filterModel->index(0, 0)).toString(), "1"); + QCOMPARE(filterModel->data(filterModel->index(1, 0)).toString(), "3"); + QCOMPARE(filterModel->data(filterModel->index(2, 0)).toString(), "5"); + QCOMPARE(filterModel->data(filterModel->index(3, 0)).toString(), "7"); + QCOMPARE(filterModel->data(filterModel->index(4, 0)).toString(), "9"); + + // Simulate call from QML by going through metaobject rather than calling it directly + const bool invalidateFilterCallOk = QMetaObject::invokeMethod(filterModel, "invalidateFilter"); + QVERIFY(invalidateFilterCallOk); + + QCOMPARE(filterModel->rowCount(), 4); + QCOMPARE(filterModel->data(filterModel->index(0, 0)).toString(), "1"); + QCOMPARE(filterModel->data(filterModel->index(1, 0)).toString(), "4"); + QCOMPARE(filterModel->data(filterModel->index(2, 0)).toString(), "7"); + QCOMPARE(filterModel->data(filterModel->index(3, 0)).toString(), "10"); +} void tst_KSortFilterProxyModelQml::testSortRole_data() { diff --git a/src/qml/ksortfilterproxymodel.h b/src/qml/ksortfilterproxymodel.h --- a/src/qml/ksortfilterproxymodel.h +++ b/src/qml/ksortfilterproxymodel.h @@ -122,6 +122,17 @@ void classBegin() override; void componentComplete() override; +public Q_SLOTS: + /** + * Invalidates the current filtering. + * + * This function should be called if you are implementing custom filtering through + * filterRowCallback or filterColumnCallback, and your filter parameters have changed. + * + * @since 5.70 + */ + void invalidateFilter(); + Q_SIGNALS: void filterStringChanged(); void filterRoleChanged(); diff --git a/src/qml/ksortfilterproxymodel.cpp b/src/qml/ksortfilterproxymodel.cpp --- a/src/qml/ksortfilterproxymodel.cpp +++ b/src/qml/ksortfilterproxymodel.cpp @@ -220,3 +220,8 @@ setSortRole(m_sortRole); } } + +void KSortFilterProxyModel::invalidateFilter() +{ + QSortFilterProxyModel::invalidateFilter(); +}