Paste P505

Masterwork From Distant Lands
ActivePublic

Authored by davidedmundson on Dec 13 2019, 9:44 AM.
commit 23d37f3e68c46345fb7b58c67ef9c56a2474e4f9
Author: David Edmundson <kde@davidedmundson.co.uk>
Date: Thu Dec 12 23:53:47 2019 +0100
Move Plasma's SortFilterProxyModel into KItemModel's QML plugin
Summary:
It exposes QSFPM in a usable way from QML, but also exposes a way to
perform JS callbacks as an advanced filter method.
This is mostly a 1-1 move from plasma-frameworks, but with the following
change.
- Removing a broken workaround for trying to handle Plasma's DataModel
having dynamic role names.
- port to the new connect syntax
- removing the plasma namespace
I don't know if we want to change the name to match the others having a
K prefix?
Subscribers: broulik, ahiemstra, mart, kde-frameworks-devel
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D25326
diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt
index 719e56c..a9f3f89 100644
--- a/autotests/CMakeLists.txt
+++ b/autotests/CMakeLists.txt
@@ -32,7 +32,8 @@ ecm_add_tests(
if (${Qt5Qml_FOUND})
ecm_add_tests(
kconcatenaterows_qml.cpp
- LINK_LIBRARIES KF5::ItemModels Qt5::Test Qt5::Qml
+ ksortfilterproxymodel_qml.cpp
+ LINK_LIBRARIES KF5::ItemModels Qt5::Test Qt5::Qml Qt5::Gui
)
endif()
diff --git a/autotests/ksortfilterproxymodel_qml.cpp b/autotests/ksortfilterproxymodel_qml.cpp
new file mode 100644
index 0000000..3d4291b
--- /dev/null
+++ b/autotests/ksortfilterproxymodel_qml.cpp
@@ -0,0 +1,186 @@
+/*
+ Copyright (C) 2019 David Edmundson <davidedmundson@kde.org>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#include <QObject>
+
+#include <QTest>
+#include <QSignalSpy>
+
+#include <QQmlApplicationEngine>
+#include <QQmlContext>
+
+#include <QAbstractItemModel>
+#include <QStandardItemModel>
+
+class tst_KSortFilterProxyModelQml : public QObject
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void testFilterCallback();
+ void testSortRole_data();
+ void testSortRole();
+ void testFilterRegExp();
+ void testFilterRegExpReset();
+private:
+ QAbstractItemModel* createMonthTestModel(QObject *parent);
+};
+
+QAbstractItemModel* tst_KSortFilterProxyModelQml::createMonthTestModel(QObject *parent)
+{
+ auto testModel = new QStandardItemModel(parent);
+ for (int i = 1; i <= 12 ; i++) {
+ auto entry = new QStandardItem();
+ entry->setData(QLocale::c().monthName(i), Qt::DisplayRole);
+ entry->setData(i, Qt::UserRole);
+ testModel->appendRow(entry);
+ }
+ testModel->setItemRoleNames({{Qt::UserRole, "user"}, {Qt::DisplayRole, "display"}});
+ return testModel;
+}
+
+void tst_KSortFilterProxyModelQml::testFilterCallback()
+{
+ QQmlApplicationEngine app;
+ app.loadData("import QtQml 2.0\n"
+ "import org.kde.kitemmodels 1.0\n"
+ "KSortFilterProxyModel\n"
+ "{\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"
+ " };\n"
+ "}\n");
+ QCOMPARE(app.rootObjects().count(), 1);
+
+ auto filterModel = qobject_cast<QAbstractItemModel*>(app.rootObjects().first());
+ QVERIFY(filterModel);
+
+ 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");
+}
+
+
+void tst_KSortFilterProxyModelQml::testSortRole_data()
+{
+ // test model consists of all month names + month number as Display and UserRoler respectively
+
+ QTest::addColumn<QString>("qmlContents");
+ QTest::addColumn<QString>("result");
+
+ QTest::newRow("sort by role name - display") << "KSortFilterProxyModel {"
+ " sourceModel: testModel;"
+ " sortRole: \"display\";"
+ "}"
+ << "April";
+ QTest::newRow("sort by role ID - display") << "KSortFilterProxyModel {"
+ " sourceModel: testModel;"
+ " sortRole: Qt.DisplayRole"
+ "}"
+ << "April";
+ QTest::newRow("sort by role name - value") << "KSortFilterProxyModel {"
+ " sourceModel: testModel;"
+ " sortRole: \"user\";"
+ "}"
+ << "January";
+ QTest::newRow("sort by role ID - value") << "KSortFilterProxyModel {"
+ " sourceModel: testModel;"
+ " sortRole: Qt.UserRole"
+ "}"
+ << "January";
+ QTest::newRow("sort by role name - reset") << "KSortFilterProxyModel {"
+ " sourceModel: testModel;"
+ " sortRole: \"display\";"
+ " Component.onCompleted: sortRole = undefined;"
+ "}"
+ << "January";
+}
+
+void tst_KSortFilterProxyModelQml::testSortRole()
+{
+ QQmlApplicationEngine app;
+ QFETCH(QString, qmlContents);
+ QFETCH(QString, result);
+
+ qmlContents = "import org.kde.kitemmodels 1.0\n"
+ "import QtQuick 2.0\n"
+ + qmlContents;
+
+ app.rootContext()->setContextProperty("testModel", createMonthTestModel(&app));
+
+ app.loadData(qmlContents.toLatin1());
+
+ QCOMPARE(app.rootObjects().count(), 1);
+ auto filterModel = qobject_cast<QAbstractItemModel*>(app.rootObjects().first());
+ QVERIFY(filterModel);
+ QCOMPARE(filterModel->rowCount(), 12);
+ QCOMPARE(filterModel->data(filterModel->index(0, 0), Qt::DisplayRole).toString(), result);
+}
+
+void tst_KSortFilterProxyModelQml::testFilterRegExp()
+{
+ QQmlApplicationEngine app;
+
+ app.rootContext()->setContextProperty("testModel", createMonthTestModel(&app));
+
+ app.loadData("import QtQml 2.0\n"
+ "import org.kde.kitemmodels 1.0\n"
+ "KSortFilterProxyModel {\n"
+ " sourceModel: testModel\n"
+ " filterRegExp: /Ma.*/\n"
+ "}\n");
+
+ QCOMPARE(app.rootObjects().count(), 1);
+ auto filterModel = qobject_cast<QAbstractItemModel*>(app.rootObjects().first());
+ QVERIFY(filterModel);
+ QCOMPARE(filterModel->rowCount(), 2);
+ QCOMPARE(filterModel->data(filterModel->index(0, 0), Qt::DisplayRole).toString(), "March");
+ QCOMPARE(filterModel->data(filterModel->index(1, 0), Qt::DisplayRole).toString(), "May");
+}
+
+void tst_KSortFilterProxyModelQml::testFilterRegExpReset()
+{
+ QQmlApplicationEngine app;
+
+ app.rootContext()->setContextProperty("testModel", createMonthTestModel(&app));
+
+ app.loadData("import QtQml 2.0\n"
+ "import org.kde.kitemmodels 1.0\n"
+ "KSortFilterProxyModel {\n"
+ " sourceModel: testModel\n"
+ " filterRegExp: /Ma.*/\n"
+ " Component.onCompleted: filterRegExp = undefined"
+ "}\n");
+
+ QCOMPARE(app.rootObjects().count(), 1);
+ auto filterModel = qobject_cast<QAbstractItemModel*>(app.rootObjects().first());
+ QVERIFY(filterModel);
+ QCOMPARE(filterModel->rowCount(), 12);
+}
+
+
+QTEST_GUILESS_MAIN(tst_KSortFilterProxyModelQml)
+
+#include "ksortfilterproxymodel_qml.moc"
diff --git a/autotests/ksortfilterproxymodeltest_callback.qml b/autotests/ksortfilterproxymodeltest_callback.qml
new file mode 100644
index 0000000..9f9f6a4
--- /dev/null
+++ b/autotests/ksortfilterproxymodeltest_callback.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.0
+import org.kde.kitemmodels 1.0
+
+// only include odd_numbers
+
+KSortFilterProxyModel
+{
+ sourceModel: KNumberModel {
+ minimumValue: 1
+ maximumValue: 10
+ }
+ filterRowCallback: function(source_row, source_parent) {
+ return sourceModel.data(sourceModel.index(source_row, 0, source_parent), Qt.DisplayRole) % 2 == 1;
+ };
+}
+
diff --git a/autotests/ksortfilterproxymodeltest_sortRoleDisplay.qml b/autotests/ksortfilterproxymodeltest_sortRoleDisplay.qml
new file mode 100644
index 0000000..22b4fb2
--- /dev/null
+++ b/autotests/ksortfilterproxymodeltest_sortRoleDisplay.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+import org.kde.kitemmodels 1.0
+
+KSortFilterProxyModel
+{
+ sourceModel: testModel
+ sortRole: Qt.DisplayRole
+}
+
diff --git a/autotests/ksortfilterproxymodeltest_sortRoleNameDisplay.qml b/autotests/ksortfilterproxymodeltest_sortRoleNameDisplay.qml
new file mode 100644
index 0000000..ad9ace4
--- /dev/null
+++ b/autotests/ksortfilterproxymodeltest_sortRoleNameDisplay.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+import org.kde.kitemmodels 1.0
+
+KSortFilterProxyModel
+{
+ sourceModel: testModel
+ sortRole: "text"
+}
+
diff --git a/autotests/ksortfilterproxymodeltest_sortRoleNameValue.qml b/autotests/ksortfilterproxymodeltest_sortRoleNameValue.qml
new file mode 100644
index 0000000..c886e15
--- /dev/null
+++ b/autotests/ksortfilterproxymodeltest_sortRoleNameValue.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+import org.kde.kitemmodels 1.0
+
+KSortFilterProxyModel
+{
+ sourceModel: testModel
+ sortRole: "value"
+}
+
diff --git a/autotests/ksortfilterproxymodeltest_sortRoleValue.qml b/autotests/ksortfilterproxymodeltest_sortRoleValue.qml
new file mode 100644
index 0000000..9c7a381
--- /dev/null
+++ b/autotests/ksortfilterproxymodeltest_sortRoleValue.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+import org.kde.kitemmodels 1.0
+
+KSortFilterProxyModel
+{
+ sourceModel: testModel
+ sortRole: Qt.UserRole
+}
+
diff --git a/src/qml/CMakeLists.txt b/src/qml/CMakeLists.txt
index 5597bf2..da37ab7 100644
--- a/src/qml/CMakeLists.txt
+++ b/src/qml/CMakeLists.txt
@@ -1,8 +1,11 @@
set(corebindings_SRCS
plugin.cpp
kconcatenaterowsproxymodel_qml.cpp
+ ksortfilterproxymodel.cpp
)
+ecm_qt_declare_logging_category(corebindings_SRCS HEADER kitemmodels_debug.h IDENTIFIER KITEMMODELS_LOG CATEGORY_NAME kf5.kitemmodels)
+
add_library(itemmodelsplugin SHARED ${corebindings_SRCS})
target_link_libraries(itemmodelsplugin
Qt5::Qml
diff --git a/src/qml/ksortfilterproxymodel.cpp b/src/qml/ksortfilterproxymodel.cpp
new file mode 100644
index 0000000..918cd5a
--- /dev/null
+++ b/src/qml/ksortfilterproxymodel.cpp
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2010 by Marco Martin <mart@kde.org>
+ * Copyright 2019 by David Edmundson <davidedmundson@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "ksortfilterproxymodel.h"
+
+#include <QQmlContext>
+#include <QQmlEngine>
+
+#include "kitemmodels_debug.h"
+
+KSortFilterProxyModel::KSortFilterProxyModel(QObject *parent)
+ : QSortFilterProxyModel(parent)
+{
+ setDynamicSortFilter(true);
+}
+
+KSortFilterProxyModel::~KSortFilterProxyModel()
+{
+}
+
+void KSortFilterProxyModel::syncRoleNames()
+{
+ if (!sourceModel()) {
+ return;
+ }
+
+ m_roleIds.clear();
+ const QHash<int, QByteArray> rNames = roleNames();
+ m_roleIds.reserve(rNames.count());
+ for (auto i = rNames.constBegin(); i != rNames.constEnd(); ++i) {
+ m_roleIds[QString::fromUtf8(i.value())] = i.key();
+ }
+}
+
+int KSortFilterProxyModel::roleNameToId(const QString &name) const
+{
+ return m_roleIds.value(name, Qt::DisplayRole);
+}
+
+void KSortFilterProxyModel::setModel(QAbstractItemModel *model)
+{
+ if (model == sourceModel()) {
+ return;
+ }
+
+ QSortFilterProxyModel::setSourceModel(model);
+ syncRoleNames();
+ setFilterRole(m_filterRole);
+ setSortRole(m_sortRole);
+}
+
+bool KSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
+{
+ if (m_filterCallback.isCallable()) {
+ auto engine = qjsEngine(this);
+ QJSValueList args = {QJSValue(source_row), engine->toScriptValue(source_parent)};
+ return const_cast<KSortFilterProxyModel *>(this)->m_filterCallback.call(args).toBool();
+ }
+
+ return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
+}
+
+bool KSortFilterProxyModel::filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const
+{
+ if (m_filterColumnCallback.isCallable()) {
+ auto engine = qjsEngine(this);
+ QJSValueList args = {QJSValue(source_column), engine->toScriptValue(source_parent)};
+ return const_cast<KSortFilterProxyModel *>(this)->m_filterCallback.call(args).toBool();
+ }
+
+ return QSortFilterProxyModel::filterAcceptsColumn(source_column, source_parent);
+}
+
+void KSortFilterProxyModel::setFilterRegularExpression(const QRegularExpression &exp)
+{
+ if (exp == filterRegularExpression()) {
+ return;
+ }
+ QSortFilterProxyModel::setFilterRegularExpression(exp);
+ Q_EMIT filterRegularExpressionChanged();
+}
+
+QRegularExpression KSortFilterProxyModel::filterRegularExpression() const
+{
+ return QSortFilterProxyModel::filterRegularExpression();
+}
+
+void KSortFilterProxyModel::setFilterString(const QString &filterString)
+{
+ if (filterString == m_filterString) {
+ return;
+ }
+ m_filterString = filterString;
+ QSortFilterProxyModel::setFilterFixedString(filterString);
+ Q_EMIT filterStringChanged(filterString);
+}
+
+QString KSortFilterProxyModel::filterString() const
+{
+ return m_filterString;
+}
+
+QJSValue KSortFilterProxyModel::filterRowCallback() const
+{
+ return m_filterCallback;
+}
+
+void KSortFilterProxyModel::setFilterRowCallback(const QJSValue& callback)
+{
+ if (m_filterCallback.strictlyEquals(callback)) {
+ return;
+ }
+
+ if (!callback.isNull() && !callback.isCallable()) {
+ return;
+ }
+
+ m_filterCallback = callback;
+ invalidateFilter();
+
+ Q_EMIT filterRowCallbackChanged(callback);
+}
+
+void KSortFilterProxyModel::setFilterColumnCallback(const QJSValue &callback)
+{
+ if (m_filterColumnCallback.strictlyEquals(callback)) {
+ return;
+ }
+
+ if (!callback.isNull() && !callback.isCallable()) {
+ return;
+ }
+
+ m_filterColumnCallback = callback;
+ invalidateFilter();
+
+ Q_EMIT filterColumnCallbackChanged(callback);
+}
+
+QJSValue KSortFilterProxyModel::filterColumnCallback() const
+{
+ return m_filterColumnCallback;
+}
+
+void KSortFilterProxyModel::setFilterRole(const QString &role)
+{
+ QSortFilterProxyModel::setFilterRole(roleNameToId(role));
+ m_filterRole = role;
+}
+
+QString KSortFilterProxyModel::filterRole() const
+{
+ return m_filterRole;
+}
+
+void KSortFilterProxyModel::setSortRole(const QString &role)
+{
+ m_sortRole = role;
+ if (role.isEmpty()) {
+ sort(-1, Qt::AscendingOrder);
+ } else if (sourceModel()) {
+ QSortFilterProxyModel::setSortRole(roleNameToId(role));
+ sort(std::max(sortColumn(), 0), sortOrder());
+ }
+}
+
+QString KSortFilterProxyModel::sortRole() const
+{
+ return m_sortRole;
+}
+
+void KSortFilterProxyModel::resetSortRole()
+{
+ setSortRole(QString());
+}
+
+void KSortFilterProxyModel::setSortOrder(const Qt::SortOrder order)
+{
+ sort(std::max(sortColumn(), 0), order);
+}
+
+void KSortFilterProxyModel::setSortColumn(int column)
+{
+ if (column == sortColumn()) {
+ return;
+ }
+ sort(column, sortOrder());
+ emit sortColumnChanged();
+}
diff --git a/src/qml/ksortfilterproxymodel.h b/src/qml/ksortfilterproxymodel.h
new file mode 100644
index 0000000..d8eb169
--- /dev/null
+++ b/src/qml/ksortfilterproxymodel.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2010 by Marco Martin <mart@kde.org>
+ * Copyright 2019 by David Edmundson <davidedmundson@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KSORTFILTERPROXYMODEL_H
+#define KSORTFILTERPROXYMODEL_H
+
+#include <QAbstractItemModel>
+#include <QJSValue>
+#include <QSortFilterProxyModel>
+#include <QVector>
+
+/**
+ * @class SortFilterModel
+ * @short Filter and sort an existing QAbstractItemModel
+ * @since 5.66
+ */
+class KSortFilterProxyModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+ /**
+ * The source model of this sorting proxy model.
+ */
+ Q_PROPERTY(QAbstractItemModel *sourceModel READ sourceModel WRITE setModel NOTIFY sourceModelChanged)
+
+ /**
+ * The regular expression for the filter, only items with their filterRole matching filterRegExp will be displayed
+ */
+ Q_PROPERTY(QRegularExpression filterRegularExpression READ filterRegularExpression WRITE setFilterRegularExpression NOTIFY filterRegularExpressionChanged)
+
+ /**
+ * The string for the filter, only items with their filterRole matching filterString will be displayed
+ */
+ Q_PROPERTY(QString filterString READ filterString WRITE setFilterString NOTIFY filterStringChanged)
+
+ /**
+ * A JavaScript callable that can be used to perform advanced filters on a given row.
+ * The callback is passed the source row, and source parent for a given row as arguments
+ *
+ * The callable's return value is evaluated as boolean to determine
+ * whether the row is accepted (true) or filtered out (false). It overrides the default implementation
+ * that uses filterRegExp or filterString; while filterCallback is set those two properties are
+ * ignored. Attempts to write a non-callable to this property are silently ignored, but you can set
+ * it to null.
+ *
+ * @code
+ * filterRowCallback: function(source_row, source_parent) {
+ * return sourceModel.data(sourceModel.index(source_row, 0, source_parent), Qt.DisplayRole) == "...";
+ * };
+ * @endcode
+ */
+ Q_PROPERTY(QJSValue filterRowCallback READ filterRowCallback WRITE setFilterRowCallback NOTIFY filterRowCallbackChanged)
+
+ /**
+ * A JavaScript callable that can be used to perform advanced filters on a given column.
+ * The callback is passed the source column, and source parent for a given column as arguments.
+ *
+ * @see filterRowCallback
+ */
+ Q_PROPERTY(QJSValue filterColumnCallback READ filterColumnCallback WRITE setFilterColumnCallback NOTIFY filterColumnCallbackChanged)
+
+ /**
+ * The role of the sourceModel on which filterRegExp will be applied.
+ */
+ Q_PROPERTY(QString filterRole READ filterRole WRITE setFilterRole)
+
+ /**
+ * The role of the sourceModel that will be used for sorting. if empty the order will be left unaltered
+ */
+ Q_PROPERTY(QString sortRole READ sortRole WRITE setSortRole RESET resetSortRole)
+
+ /**
+ * One of Qt.Ascending or Qt.Descending
+ */
+ Q_PROPERTY(Qt::SortOrder sortOrder READ sortOrder WRITE setSortOrder)
+
+ /**
+ * Specify which column shoud be used for sorting
+ */
+ Q_PROPERTY(int sortColumn READ sortColumn WRITE setSortColumn NOTIFY sortColumnChanged)
+
+public:
+ explicit KSortFilterProxyModel(QObject *parent = nullptr);
+ ~KSortFilterProxyModel();
+
+ void setModel(QAbstractItemModel *source);
+
+ void setFilterRegularExpression(const QRegularExpression &exp);
+ QRegularExpression filterRegularExpression() const;
+
+ void setFilterString(const QString &filterString);
+ QString filterString() const;
+
+ void setFilterRowCallback(const QJSValue &callback);
+ QJSValue filterRowCallback() const;
+
+ void setFilterColumnCallback(const QJSValue &callback);
+ QJSValue filterColumnCallback() const;
+
+ void setFilterRole(const QString &role);
+ QString filterRole() const;
+
+ void setSortRole(const QString &role);
+ QString sortRole() const;
+ void resetSortRole();
+
+ void setSortOrder(const Qt::SortOrder order);
+ void setSortColumn(int column);
+
+Q_SIGNALS:
+ void sortColumnChanged();
+ void sourceModelChanged(QObject *);
+ void filterRegularExpressionChanged();
+ void filterStringChanged(const QString &);
+ void filterRowCallbackChanged(const QJSValue &);
+ void filterColumnCallbackChanged(const QJSValue &);
+
+
+protected:
+ int roleNameToId(const QString &name) const;
+ bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
+ bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override;
+
+protected Q_SLOTS:
+ void syncRoleNames();
+
+private:
+ QString m_filterRole;
+ QString m_sortRole;
+ QString m_filterString;
+ QJSValue m_filterCallback;
+ QJSValue m_filterColumnCallback;
+ QHash<QString, int> m_roleIds;
+};
+#endif
diff --git a/src/qml/plugin.cpp b/src/qml/plugin.cpp
index 4448cef..8949302 100644
--- a/src/qml/plugin.cpp
+++ b/src/qml/plugin.cpp
@@ -25,6 +25,7 @@
#include <KDescendantsProxyModel>
#include <KNumberModel>
#include <KColumnHeadersModel>
+#include "ksortfilterproxymodel.h"
#include "kconcatenaterowsproxymodel_qml.h"
void Plugin::initializeEngine(QQmlEngine *engine, const char *uri)
@@ -44,4 +45,5 @@ void Plugin::registerTypes(const char *uri)
qmlRegisterType<KDescendantsProxyModel>(uri, 1, 0, "KDescendantsProxyModel");
qmlRegisterType<KNumberModel>(uri, 1, 0, "KNumberModel");
qmlRegisterType<KColumnHeadersModel>(uri, 1, 0, "KColumnHeadersModel");
+ qmlRegisterType<KSortFilterProxyModel>(uri, 1, 0, "KSortFilterProxyModel");
}
davidedmundson edited the content of this paste. (Show Details)Dec 13 2019, 9:44 AM
davidedmundson changed the title of this paste from untitled to Masterwork From Distant Lands.