1/*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2007 Rafael Fernández López <ereslibre@kde.org>
4 SPDX-FileCopyrightText: 2007 John Tapsell <tapsell@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#ifndef KCATEGORIZEDSORTFILTERPROXYMODEL_H
10#define KCATEGORIZEDSORTFILTERPROXYMODEL_H
11
12#include <QSortFilterProxyModel>
13#include <memory>
14
15#include <kitemviews_export.h>
16class KCategorizedSortFilterProxyModelPrivate;
17
18class QItemSelection;
19
20/**
21 * @class KCategorizedSortFilterProxyModel kcategorizedsortfilterproxymodel.h KCategorizedSortFilterProxyModel
22 *
23 * This class lets you categorize a view. It is meant to be used along with
24 * KCategorizedView class.
25 *
26 * In general terms all you need to do is to reimplement subSortLessThan() and
27 * compareCategories() methods. In order to make categorization work, you need
28 * to also call setCategorizedModel() class to enable it, since the categorization
29 * is disabled by default.
30 *
31 * @see KCategorizedView
32 *
33 * @author Rafael Fernández López <ereslibre@kde.org>
34 */
35class KITEMVIEWS_EXPORT KCategorizedSortFilterProxyModel : public QSortFilterProxyModel
36{
37 Q_OBJECT
38public:
39 enum AdditionalRoles {
40 // Note: use printf "0x%08X\n" $(($RANDOM*$RANDOM))
41 // to define additional roles.
42 CategoryDisplayRole = 0x17CE990A, ///< This role is used for asking the category to a given index
43
44 CategorySortRole = 0x27857E60, ///< This role is used for sorting categories. You can return a
45 ///< string or a long long value. Strings will be sorted alphabetically
46 ///< while long long will be sorted by their value. Please note that this
47 ///< value won't be shown on the view, is only for sorting purposes. What will
48 ///< be shown as "Category" on the view will be asked with the role
49 ///< CategoryDisplayRole.
50 };
51
52 KCategorizedSortFilterProxyModel(QObject *parent = nullptr);
53 ~KCategorizedSortFilterProxyModel() override;
54
55 /**
56 * Overridden from QSortFilterProxyModel. Sorts the source model using
57 * @p column for the given @p order.
58 */
59 void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override;
60
61 /**
62 * @return whether the model is categorized or not. Disabled by default.
63 */
64 bool isCategorizedModel() const;
65
66 /**
67 * Enables or disables the categorization feature.
68 *
69 * @param categorizedModel whether to enable or disable the categorization feature.
70 */
71 void setCategorizedModel(bool categorizedModel);
72
73 /**
74 * @return the column being used for sorting.
75 */
76 int sortColumn() const;
77
78 /**
79 * @return the sort order being used for sorting.
80 */
81 Qt::SortOrder sortOrder() const;
82
83 /**
84 * Set if the sorting using CategorySortRole will use a natural comparison
85 * in the case that strings were returned. If enabled, QCollator
86 * will be used for sorting.
87 *
88 * @param sortCategoriesByNaturalComparison whether to sort using a natural comparison or not.
89 */
90 void setSortCategoriesByNaturalComparison(bool sortCategoriesByNaturalComparison);
91
92 /**
93 * @return whether it is being used a natural comparison for sorting. Enabled by default.
94 */
95 bool sortCategoriesByNaturalComparison() const;
96
97protected:
98 /**
99 * Overridden from QSortFilterProxyModel. If you are subclassing
100 * KCategorizedSortFilterProxyModel, you will probably not need to reimplement this
101 * method.
102 *
103 * It calls compareCategories() to sort by category. If the both items are in the
104 * same category (i.e. compareCategories returns 0), then subSortLessThan is called.
105 *
106 * @return Returns true if the item @p left is less than the item @p right when sorting.
107 *
108 * @warning You usually won't need to reimplement this method when subclassing
109 * from KCategorizedSortFilterProxyModel.
110 */
111 bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
112
113 /**
114 * This method has a similar purpose as lessThan() has on QSortFilterProxyModel.
115 * It is used for sorting items that are in the same category.
116 *
117 * @return Returns true if the item @p left is less than the item @p right when sorting.
118 */
119 virtual bool subSortLessThan(const QModelIndex &left, const QModelIndex &right) const;
120
121 /**
122 * This method compares the category of the @p left index with the category
123 * of the @p right index.
124 *
125 * Internally and if not reimplemented, this method will ask for @p left and
126 * @p right models for role CategorySortRole. In order to correctly sort
127 * categories, the data() method of the model should return a qlonglong (or numeric) value, or
128 * a QString object. QString objects will be sorted with QString::localeAwareCompare if
129 * sortCategoriesByNaturalComparison() is true.
130 *
131 * @note Please have present that:
132 * QString(QChar(QChar::ObjectReplacementCharacter)) >
133 * QString(QChar(QChar::ReplacementCharacter)) >
134 * [ all possible strings ] >
135 * QString();
136 *
137 * This means that QString() will be sorted the first one, while
138 * QString(QChar(QChar::ObjectReplacementCharacter)) and
139 * QString(QChar(QChar::ReplacementCharacter)) will be sorted in last
140 * position.
141 *
142 * @warning Please note that data() method of the model should return always
143 * information of the same type. If you return a QString for an index,
144 * you should return always QStrings for all indexes for role CategorySortRole
145 * in order to correctly sort categories. You can't mix by returning
146 * a QString for one index, and a qlonglong for other.
147 *
148 * @note If you need a more complex layout, you will have to reimplement this
149 * method.
150 *
151 * @return A negative value if the category of @p left should be placed before the
152 * category of @p right. 0 if @p left and @p right are on the same category, and
153 * a positive value if the category of @p left should be placed after the
154 * category of @p right.
155 */
156 virtual int compareCategories(const QModelIndex &left, const QModelIndex &right) const;
157
158private:
159 std::unique_ptr<KCategorizedSortFilterProxyModelPrivate> const d;
160};
161
162#endif // KCATEGORIZEDSORTFILTERPROXYMODEL_H
163

source code of kitemviews/src/kcategorizedsortfilterproxymodel.h