File indexing completed on 2024-10-13 12:16:00
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 2007 Rafael Fernández López <ereslibre@kde.org> 0004 SPDX-FileCopyrightText: 2007 John Tapsell <tapsell@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #ifndef KCATEGORIZEDSORTFILTERPROXYMODEL_H 0010 #define KCATEGORIZEDSORTFILTERPROXYMODEL_H 0011 0012 #include <QSortFilterProxyModel> 0013 #include <memory> 0014 0015 #include <kitemviews_export.h> 0016 class KCategorizedSortFilterProxyModelPrivate; 0017 0018 class QItemSelection; 0019 0020 /** 0021 * @class KCategorizedSortFilterProxyModel kcategorizedsortfilterproxymodel.h KCategorizedSortFilterProxyModel 0022 * 0023 * This class lets you categorize a view. It is meant to be used along with 0024 * KCategorizedView class. 0025 * 0026 * In general terms all you need to do is to reimplement subSortLessThan() and 0027 * compareCategories() methods. In order to make categorization work, you need 0028 * to also call setCategorizedModel() class to enable it, since the categorization 0029 * is disabled by default. 0030 * 0031 * @see KCategorizedView 0032 * 0033 * @author Rafael Fernández López <ereslibre@kde.org> 0034 */ 0035 class KITEMVIEWS_EXPORT KCategorizedSortFilterProxyModel : public QSortFilterProxyModel 0036 { 0037 public: 0038 enum AdditionalRoles { 0039 // Note: use printf "0x%08X\n" $(($RANDOM*$RANDOM)) 0040 // to define additional roles. 0041 CategoryDisplayRole = 0x17CE990A, ///< This role is used for asking the category to a given index 0042 0043 CategorySortRole = 0x27857E60, ///< This role is used for sorting categories. You can return a 0044 ///< string or a long long value. Strings will be sorted alphabetically 0045 ///< while long long will be sorted by their value. Please note that this 0046 ///< value won't be shown on the view, is only for sorting purposes. What will 0047 ///< be shown as "Category" on the view will be asked with the role 0048 ///< CategoryDisplayRole. 0049 }; 0050 0051 KCategorizedSortFilterProxyModel(QObject *parent = nullptr); 0052 ~KCategorizedSortFilterProxyModel() override; 0053 0054 /** 0055 * Overridden from QSortFilterProxyModel. Sorts the source model using 0056 * @p column for the given @p order. 0057 */ 0058 void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override; 0059 0060 /** 0061 * @return whether the model is categorized or not. Disabled by default. 0062 */ 0063 bool isCategorizedModel() const; 0064 0065 /** 0066 * Enables or disables the categorization feature. 0067 * 0068 * @param categorizedModel whether to enable or disable the categorization feature. 0069 */ 0070 void setCategorizedModel(bool categorizedModel); 0071 0072 /** 0073 * @return the column being used for sorting. 0074 */ 0075 int sortColumn() const; 0076 0077 /** 0078 * @return the sort order being used for sorting. 0079 */ 0080 Qt::SortOrder sortOrder() const; 0081 0082 /** 0083 * Set if the sorting using CategorySortRole will use a natural comparison 0084 * in the case that strings were returned. If enabled, QCollator 0085 * will be used for sorting. 0086 * 0087 * @param sortCategoriesByNaturalComparison whether to sort using a natural comparison or not. 0088 */ 0089 void setSortCategoriesByNaturalComparison(bool sortCategoriesByNaturalComparison); 0090 0091 /** 0092 * @return whether it is being used a natural comparison for sorting. Enabled by default. 0093 */ 0094 bool sortCategoriesByNaturalComparison() const; 0095 0096 #if KITEMVIEWS_ENABLE_DEPRECATED_SINCE(4, 4) 0097 /** 0098 * Does a natural comparing of the strings. A negative value is returned if \a a 0099 * is smaller than \a b. A positive value is returned if \a a is greater than \a b. 0 0100 * is returned if both values are equal. 0101 * @deprecated Since 4.4. Use QCollator instead. 0102 */ 0103 KITEMVIEWS_DEPRECATED_VERSION(4, 4, "Use QCollator") 0104 static int naturalCompare(const QString &a, const QString &b); 0105 #endif 0106 0107 protected: 0108 /** 0109 * Overridden from QSortFilterProxyModel. If you are subclassing 0110 * KCategorizedSortFilterProxyModel, you will probably not need to reimplement this 0111 * method. 0112 * 0113 * It calls compareCategories() to sort by category. If the both items are in the 0114 * same category (i.e. compareCategories returns 0), then subSortLessThan is called. 0115 * 0116 * @return Returns true if the item @p left is less than the item @p right when sorting. 0117 * 0118 * @warning You usually won't need to reimplement this method when subclassing 0119 * from KCategorizedSortFilterProxyModel. 0120 */ 0121 bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; 0122 0123 /** 0124 * This method has a similar purpose as lessThan() has on QSortFilterProxyModel. 0125 * It is used for sorting items that are in the same category. 0126 * 0127 * @return Returns true if the item @p left is less than the item @p right when sorting. 0128 */ 0129 virtual bool subSortLessThan(const QModelIndex &left, const QModelIndex &right) const; 0130 0131 /** 0132 * This method compares the category of the @p left index with the category 0133 * of the @p right index. 0134 * 0135 * Internally and if not reimplemented, this method will ask for @p left and 0136 * @p right models for role CategorySortRole. In order to correctly sort 0137 * categories, the data() method of the model should return a qlonglong (or numeric) value, or 0138 * a QString object. QString objects will be sorted with QString::localeAwareCompare if 0139 * sortCategoriesByNaturalComparison() is true. 0140 * 0141 * @note Please have present that: 0142 * QString(QChar(QChar::ObjectReplacementCharacter)) > 0143 * QString(QChar(QChar::ReplacementCharacter)) > 0144 * [ all possible strings ] > 0145 * QString(); 0146 * 0147 * This means that QString() will be sorted the first one, while 0148 * QString(QChar(QChar::ObjectReplacementCharacter)) and 0149 * QString(QChar(QChar::ReplacementCharacter)) will be sorted in last 0150 * position. 0151 * 0152 * @warning Please note that data() method of the model should return always 0153 * information of the same type. If you return a QString for an index, 0154 * you should return always QStrings for all indexes for role CategorySortRole 0155 * in order to correctly sort categories. You can't mix by returning 0156 * a QString for one index, and a qlonglong for other. 0157 * 0158 * @note If you need a more complex layout, you will have to reimplement this 0159 * method. 0160 * 0161 * @return A negative value if the category of @p left should be placed before the 0162 * category of @p right. 0 if @p left and @p right are on the same category, and 0163 * a positive value if the category of @p left should be placed after the 0164 * category of @p right. 0165 */ 0166 virtual int compareCategories(const QModelIndex &left, const QModelIndex &right) const; 0167 0168 private: 0169 std::unique_ptr<KCategorizedSortFilterProxyModelPrivate> const d; 0170 }; 0171 0172 #endif // KCATEGORIZEDSORTFILTERPROXYMODEL_H