File indexing completed on 2024-05-12 11:55:20
0001 /* 0002 * Copyright 2010 by Marco Martin <mart@kde.org> 0003 * Copyright 2019 by David Edmundson <davidedmundson@kde.org> 0004 * 0005 * This program is free software; you can redistribute it and/or modify 0006 * it under the terms of the GNU Library General Public License as 0007 * published by the Free Software Foundation; either version 2, or 0008 * (at your option) any later version. 0009 * 0010 * This program is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details 0014 * 0015 * You should have received a copy of the GNU Library General Public 0016 * License along with this program; if not, write to the 0017 * Free Software Foundation, Inc., 0018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #ifndef KSORTFILTERPROXYMODEL_H 0022 #define KSORTFILTERPROXYMODEL_H 0023 0024 #include <QAbstractItemModel> 0025 #include <QJSValue> 0026 #include <QQmlParserStatus> 0027 #include <QSortFilterProxyModel> 0028 #include <QVector> 0029 0030 /** 0031 * @class SortFilterModel 0032 * @short Filter and sort an existing QAbstractItemModel 0033 * 0034 * @since 5.67 0035 */ 0036 class KSortFilterProxyModel : public QSortFilterProxyModel, public QQmlParserStatus 0037 { 0038 Q_OBJECT 0039 Q_INTERFACES(QQmlParserStatus) 0040 /** 0041 * The source model of this sorting proxy model. 0042 */ 0043 Q_PROPERTY(QAbstractItemModel *sourceModel READ sourceModel WRITE setModel NOTIFY sourceModelChanged) 0044 0045 /** 0046 * The string for the filter, only rows with their filterRole matching filterString will be displayed 0047 */ 0048 Q_PROPERTY(QString filterString READ filterString WRITE setFilterString NOTIFY filterStringChanged) 0049 /** 0050 * A JavaScript callable that can be used to perform advanced filters on a given row. 0051 * The callback is passed the source row, and source parent for a given row as arguments 0052 * 0053 * The callable's return value is evaluated as boolean to determine 0054 * whether the row is accepted (true) or filtered out (false). It overrides the default implementation 0055 * that uses filterRegExp or filterString; while filterCallback is set those two properties are 0056 * ignored. Attempts to write a non-callable to this property are silently ignored, but you can set 0057 * it to null. 0058 * 0059 * @code 0060 * filterRowCallback: function(source_row, source_parent) { 0061 * return sourceModel.data(sourceModel.index(source_row, 0, source_parent), Qt.DisplayRole) == "..."; 0062 * }; 0063 * @endcode 0064 */ 0065 Q_PROPERTY(QJSValue filterRowCallback READ filterRowCallback WRITE setFilterRowCallback NOTIFY filterRowCallbackChanged) 0066 0067 /** 0068 * A JavaScript callable that can be used to perform advanced filters on a given column. 0069 * The callback is passed the source column, and source parent for a given column as arguments. 0070 * 0071 * @see filterRowCallback 0072 */ 0073 Q_PROPERTY(QJSValue filterColumnCallback READ filterColumnCallback WRITE setFilterColumnCallback NOTIFY filterColumnCallbackChanged) 0074 0075 /** 0076 * The role of the sourceModel on which the filter will be applied. 0077 * This can either be the numerical role value or the role name as a string. 0078 */ 0079 Q_PROPERTY(QVariant filterRole READ filterRole WRITE setFilterRole NOTIFY filterRoleChanged) 0080 0081 /** 0082 * The role of the sourceModel that will be used for sorting. if empty the order will be left unaltered 0083 * This can either be the numerical role value or the role name as a string. 0084 */ 0085 Q_PROPERTY(QVariant sortRole READ sortRole WRITE setSortRole NOTIFY sortRoleChanged) 0086 0087 /** 0088 * One of Qt.AscendingOrder or Qt.DescendingOrder 0089 */ 0090 Q_PROPERTY(Qt::SortOrder sortOrder READ sortOrder WRITE setSortOrder NOTIFY sortOrderChanged) 0091 0092 /** 0093 * Specify which column should be used for sorting 0094 * The default value is -1. 0095 * If \a sortRole is set, the default value is 0. 0096 */ 0097 Q_PROPERTY(int sortColumn READ sortColumn WRITE setSortColumn NOTIFY sortColumnChanged) 0098 0099 /** 0100 * The number of top level rows. 0101 */ 0102 Q_PROPERTY(int count READ rowCount NOTIFY rowCountChanged) 0103 0104 public: 0105 explicit KSortFilterProxyModel(QObject *parent = nullptr); 0106 ~KSortFilterProxyModel() override; 0107 0108 void setModel(QAbstractItemModel *source); 0109 0110 void setFilterRowCallback(const QJSValue &callback); 0111 QJSValue filterRowCallback() const; 0112 0113 void setFilterString(const QString &filterString); 0114 QString filterString() const; 0115 0116 void setFilterColumnCallback(const QJSValue &callback); 0117 QJSValue filterColumnCallback() const; 0118 0119 void setFilterRole(const QVariant &role); 0120 QVariant filterRole() const; 0121 0122 void setSortRole(const QVariant &role); 0123 QVariant sortRole() const; 0124 0125 void setSortOrder(const Qt::SortOrder order); 0126 void setSortColumn(int column); 0127 0128 void classBegin() override; 0129 void componentComplete() override; 0130 0131 // TODO KF6: those two can be dropped once we depend on Qt 6.4 0132 Q_INVOKABLE bool removeRow(int row, const QModelIndex &parent = QModelIndex()); 0133 Q_INVOKABLE bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; 0134 0135 public Q_SLOTS: 0136 /** 0137 * Invalidates the current filtering. 0138 * 0139 * This function should be called if you are implementing custom filtering through 0140 * filterRowCallback or filterColumnCallback, and your filter parameters have changed. 0141 * 0142 * @since 5.70 0143 */ 0144 void invalidateFilter(); 0145 0146 Q_SIGNALS: 0147 void filterStringChanged(); 0148 void filterRoleChanged(); 0149 void sortRoleChanged(); 0150 void sortOrderChanged(); 0151 void sortColumnChanged(); 0152 void sourceModelChanged(QObject *); 0153 void filterRowCallbackChanged(const QJSValue &); 0154 void filterColumnCallbackChanged(const QJSValue &); 0155 void rowCountChanged(); 0156 0157 protected: 0158 int roleNameToId(const QString &name) const; 0159 bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; 0160 bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override; 0161 0162 protected Q_SLOTS: 0163 void syncRoleNames(); 0164 0165 private: 0166 bool m_componentCompleted = false; 0167 QVariant m_filterRole; 0168 QString m_filterString; 0169 QVariant m_sortRole; 0170 QJSValue m_filterRowCallback; 0171 QJSValue m_filterColumnCallback; 0172 QHash<QString, int> m_roleIds; 0173 }; 0174 #endif