1/*
2 * This file is part of the KDE project
3 * Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org>
4 * Copyright (C) 2007 John Tapsell <tapsell@kde.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22#ifndef KCATEGORIZEDSORTFILTERPROXYMODEL_H
23#define KCATEGORIZEDSORTFILTERPROXYMODEL_H
24
25#include <QtGui/QSortFilterProxyModel>
26
27#include <kdeui_export.h>
28
29class QItemSelection;
30
31
32/**
33 * This class lets you categorize a view. It is meant to be used along with
34 * KCategorizedView class.
35 *
36 * In general terms all you need to do is to reimplement subSortLessThan() and
37 * compareCategories() methods. In order to make categorization work, you need
38 * to also call setCategorizedModel() class to enable it, since the categorization
39 * is disabled by default.
40 *
41 * @see KCategorizedView
42 *
43 * @author Rafael Fernández López <ereslibre@kde.org>
44 */
45class KDEUI_EXPORT KCategorizedSortFilterProxyModel
46 : public QSortFilterProxyModel
47{
48public:
49 enum AdditionalRoles {
50 // Note: use printf "0x%08X\n" $(($RANDOM*$RANDOM))
51 // to define additional roles.
52 CategoryDisplayRole = 0x17CE990A, ///< This role is used for asking the category to a given index
53
54 CategorySortRole = 0x27857E60 ///< This role is used for sorting categories. You can return a
55 ///< string or a long long value. Strings will be sorted alphabetically
56 ///< while long long will be sorted by their value. Please note that this
57 ///< value won't be shown on the view, is only for sorting purposes. What will
58 ///< be shown as "Category" on the view will be asked with the role
59 ///< CategoryDisplayRole.
60 };
61
62 KCategorizedSortFilterProxyModel(QObject *parent = 0);
63 virtual ~KCategorizedSortFilterProxyModel();
64
65 /**
66 * Overridden from QSortFilterProxyModel. Sorts the source model using
67 * @p column for the given @p order.
68 */
69 virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
70
71 /**
72 * @return whether the model is categorized or not. Disabled by default.
73 */
74 bool isCategorizedModel() const;
75
76 /**
77 * Enables or disables the categorization feature.
78 *
79 * @param categorizedModel whether to enable or disable the categorization feature.
80 */
81 void setCategorizedModel(bool categorizedModel);
82
83 /**
84 * @return the column being used for sorting.
85 */
86 int sortColumn() const;
87
88 /**
89 * @return the sort order being used for sorting.
90 */
91 Qt::SortOrder sortOrder() const;
92
93 /**
94 * Set if the sorting using CategorySortRole will use a natural comparison
95 * in the case that strings were returned. If enabled, QString::localeAwareCompare
96 * will be used for sorting.
97 *
98 * @param sortCategoriesByNaturalComparison whether to sort using a natural comparison or not.
99 */
100 void setSortCategoriesByNaturalComparison(bool sortCategoriesByNaturalComparison);
101
102 /**
103 * @return whether it is being used a natural comparison for sorting. Enabled by default.
104 */
105 bool sortCategoriesByNaturalComparison() const;
106
107 /**
108 * Does a natural comparing of the strings. A negative value is returned if \a a
109 * is smaller than \a b. A positive value is returned if \a a is greater than \a b. 0
110 * is returned if both values are equal.
111 * @deprecated
112 * Use KStringHandler::naturalCompare() instead.
113 */
114#ifndef KDE_NO_DEPRECATED
115 KDE_DEPRECATED static int naturalCompare(const QString &a, const QString &b);
116#endif
117
118protected:
119 /**
120 * Overridden from QSortFilterProxyModel. If you are subclassing
121 * KCategorizedSortFilterProxyModel, you will probably not need to reimplement this
122 * method.
123 *
124 * It calls compareCategories() to sort by category. If the both items are in the
125 * same category (i.e. compareCategories returns 0), then subSortLessThan is called.
126 *
127 * @return Returns true if the item @p left is less than the item @p right when sorting.
128 *
129 * @warning You usually won't need to reimplement this method when subclassing
130 * from KCategorizedSortFilterProxyModel.
131 */
132 virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
133
134 /**
135 * This method has a similar purpose as lessThan() has on QSortFilterProxyModel.
136 * It is used for sorting items that are in the same category.
137 *
138 * @return Returns true if the item @p left is less than the item @p right when sorting.
139 */
140 virtual bool subSortLessThan(const QModelIndex &left, const QModelIndex &right) const;
141
142 /**
143 * This method compares the category of the @p left index with the category
144 * of the @p right index.
145 *
146 * Internally and if not reimplemented, this method will ask for @p left and
147 * @p right models for role CategorySortRole. In order to correctly sort
148 * categories, the data() metod of the model should return a qlonglong (or numeric) value, or
149 * a QString object. QString objects will be sorted with QString::localeAwareCompare if
150 * sortCategoriesByNaturalComparison() is true.
151 *
152 * @note Please have present that:
153 * QString(QChar(QChar::ObjectReplacementCharacter)) >
154 * QString(QChar(QChar::ReplacementCharacter)) >
155 * [ all possible strings ] >
156 * QString();
157 *
158 * This means that QString() will be sorted the first one, while
159 * QString(QChar(QChar::ObjectReplacementCharacter)) and
160 * QString(QChar(QChar::ReplacementCharacter)) will be sorted in last
161 * position.
162 *
163 * @warning Please note that data() method of the model should return always
164 * information of the same type. If you return a QString for an index,
165 * you should return always QStrings for all indexes for role CategorySortRole
166 * in order to correctly sort categories. You can't mix by returning
167 * a QString for one index, and a qlonglong for other.
168 *
169 * @note If you need a more complex layout, you will have to reimplement this
170 * method.
171 *
172 * @return A negative value if the category of @p left should be placed before the
173 * category of @p right. 0 if @p left and @p right are on the same category, and
174 * a positive value if the category of @p left should be placed after the
175 * category of @p right.
176 */
177 virtual int compareCategories(const QModelIndex &left, const QModelIndex &right) const;
178
179private:
180 class Private;
181 Private *const d;
182};
183
184
185#endif // KCATEGORIZEDSORTFILTERPROXYMODEL_H
186