KItemModels

ksortfilterproxymodel.h
1/*
2 * Copyright 2010 by Marco Martin <mart@kde.org>
3 * Copyright 2019 by David Edmundson <davidedmundson@kde.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Library General Public License as
7 * published by the Free Software Foundation; either version 2, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#ifndef KSORTFILTERPROXYMODEL_H
22#define KSORTFILTERPROXYMODEL_H
23
24#include <QAbstractItemModel>
25#include <QJSValue>
26#include <QList>
27#include <QQmlParserStatus>
28#include <QSortFilterProxyModel>
29
30#include <array>
31
32/**
33 * @class SortFilterModel
34 * @short Filter and sort an existing QAbstractItemModel
35 *
36 * @since 5.67
37 */
38class KSortFilterProxyModel : public QSortFilterProxyModel, public QQmlParserStatus
39{
42
43 /**
44 * The string for the filter, only rows with their filterRole matching filterString will be displayed
45 */
46 Q_PROPERTY(QString filterString READ filterString WRITE setFilterString NOTIFY filterStringChanged)
47 /**
48 * A JavaScript callable that can be used to perform advanced filters on a given row.
49 * The callback is passed the source row, and source parent for a given row as arguments
50 *
51 * The callable's return value is evaluated as boolean to determine
52 * whether the row is accepted (true) or filtered out (false). It overrides the default implementation
53 * that uses filterRegExp or filterString; while filterCallback is set those two properties are
54 * ignored. Attempts to write a non-callable to this property are silently ignored, but you can set
55 * it to null.
56 *
57 * @code
58 * filterRowCallback: function(source_row, source_parent) {
59 * return sourceModel.data(sourceModel.index(source_row, 0, source_parent), Qt.DisplayRole) == "...";
60 * };
61 * @endcode
62 */
63 Q_PROPERTY(QJSValue filterRowCallback READ filterRowCallback WRITE setFilterRowCallback NOTIFY filterRowCallbackChanged)
64
65 /**
66 * A JavaScript callable that can be used to perform advanced filters on a given column.
67 * The callback is passed the source column, and source parent for a given column as arguments.
68 *
69 * @see filterRowCallback
70 */
71 Q_PROPERTY(QJSValue filterColumnCallback READ filterColumnCallback WRITE setFilterColumnCallback NOTIFY filterColumnCallbackChanged)
72
73 /**
74 * The role of the sourceModel on which the filter will be applied.
75 * This can either be the numerical role value or the role name as a string.
76 */
77 Q_PROPERTY(QString filterRoleName READ filterRoleName WRITE setFilterRoleName NOTIFY filterRoleNameChanged)
78
79 /**
80 * The role of the sourceModel that will be used for sorting. if empty the order will be left unaltered
81 * This can either be the numerical role value or the role name as a string.
82 */
83 Q_PROPERTY(QString sortRoleName READ sortRoleName WRITE setSortRoleName NOTIFY sortRoleNameChanged)
84
85 /**
86 * One of Qt.AscendingOrder or Qt.DescendingOrder
87 */
88 Q_PROPERTY(Qt::SortOrder sortOrder READ sortOrder WRITE setSortOrder NOTIFY sortOrderChanged)
89
90 /**
91 * Specify which column should be used for sorting
92 * The default value is -1.
93 * If \a sortRole is set, the default value is 0.
94 */
95 Q_PROPERTY(int sortColumn READ sortColumn WRITE setSortColumn NOTIFY sortColumnChanged)
96
97 /**
98 * The number of top level rows.
99 */
100 Q_PROPERTY(int count READ rowCount NOTIFY rowCountChanged)
101
102public:
103 explicit KSortFilterProxyModel(QObject *parent = nullptr);
104 ~KSortFilterProxyModel() override;
105
106 void setSourceModel(QAbstractItemModel *sourceModel) override;
107
108 void setFilterRowCallback(const QJSValue &callback);
109 QJSValue filterRowCallback() const;
110
111 void setFilterString(const QString &filterString);
112 QString filterString() const;
113
114 void setFilterColumnCallback(const QJSValue &callback);
115 QJSValue filterColumnCallback() const;
116
117 void setFilterRoleName(const QString &roleName);
118 QString filterRoleName() const;
119
120 void setSortRoleName(const QString &roleName);
121 QString sortRoleName() const;
122
123 void setSortOrder(const Qt::SortOrder order);
124 void setSortColumn(int column);
125
126 void classBegin() override;
127 void componentComplete() override;
128
129public Q_SLOTS:
130 /**
131 * Invalidates the current filtering.
132 *
133 * This function should be called if you are implementing custom filtering through
134 * filterRowCallback or filterColumnCallback, and your filter parameters have changed.
135 *
136 * @since 5.70
137 */
138 void invalidateFilter();
139
141 void filterStringChanged();
142 void filterRoleNameChanged();
143 void sortRoleNameChanged();
144 void sortOrderChanged();
145 void sortColumnChanged();
146 void filterRowCallbackChanged(const QJSValue &);
147 void filterColumnCallbackChanged(const QJSValue &);
148 void rowCountChanged();
149
150protected:
151 int roleNameToId(const QString &name) const;
152 bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
153 bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override;
154
155protected Q_SLOTS:
156 // This method is called whenever we suspect that role names mapping might have gone stale.
157 // It must not alter the source of truth for sort/filter properties.
158 void syncRoleNames();
159 // These methods are dealing with individual pairs of properties. They are
160 // called on various occasions, and need to check whether the invocation
161 // has been caused by a standalone base type's property change
162 // (switching source of truth to role ID) or as a side-effect of a sync.
163 void syncSortRoleProperties();
164 void syncFilterRoleProperties();
165
166private:
167 // conveniently, role ID is the default source of truth, turning it into
168 // zero-initialization.
169 enum SourceOfTruthForRoleProperty : bool {
170 SourceOfTruthIsRoleID = false,
171 SourceOfTruthIsRoleName = true,
172 };
173
174 bool m_componentCompleted : 1;
175 SourceOfTruthForRoleProperty m_sortRoleSourceOfTruth : 1;
176 SourceOfTruthForRoleProperty m_filterRoleSourceOfTruth : 1;
177 bool m_sortRoleGuard : 1;
178 bool m_filterRoleGuard : 1;
179 // default role name corresponds to the standard mapping of the default Qt::DisplayRole in QAbstractItemModel::roleNames
180 QString m_sortRoleName{QStringLiteral("display")};
181 QString m_filterRoleName{QStringLiteral("display")};
182 QString m_filterString;
183 QJSValue m_filterRowCallback;
184 QJSValue m_filterColumnCallback;
185 QHash<QString, int> m_roleIds;
186 std::array<QMetaObject::Connection, 3> m_sourceModelConnections;
187};
188
189#endif
Q_INTERFACES(...)
Q_OBJECTQ_OBJECT
Q_PROPERTY(...)
Q_SIGNALSQ_SIGNALS
Q_SLOTSQ_SLOTS
QObject * parent() const const
T qobject_cast(QObject *object)
virtual int rowCount(const QModelIndex &parent) const const override
SortOrder
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:20:34 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.