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

source code of kitemviews/src/kcategorizedsortfilterproxymodel.h