File indexing completed on 2024-10-06 03:40:28
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 protected: 0097 /** 0098 * Overridden from QSortFilterProxyModel. If you are subclassing 0099 * KCategorizedSortFilterProxyModel, you will probably not need to reimplement this 0100 * method. 0101 * 0102 * It calls compareCategories() to sort by category. If the both items are in the 0103 * same category (i.e. compareCategories returns 0), then subSortLessThan is called. 0104 * 0105 * @return Returns true if the item @p left is less than the item @p right when sorting. 0106 * 0107 * @warning You usually won't need to reimplement this method when subclassing 0108 * from KCategorizedSortFilterProxyModel. 0109 */ 0110 bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; 0111 0112 /** 0113 * This method has a similar purpose as lessThan() has on QSortFilterProxyModel. 0114 * It is used for sorting items that are in the same category. 0115 * 0116 * @return Returns true if the item @p left is less than the item @p right when sorting. 0117 */ 0118 virtual bool subSortLessThan(const QModelIndex &left, const QModelIndex &right) const; 0119 0120 /** 0121 * This method compares the category of the @p left index with the category 0122 * of the @p right index. 0123 * 0124 * Internally and if not reimplemented, this method will ask for @p left and 0125 * @p right models for role CategorySortRole. In order to correctly sort 0126 * categories, the data() method of the model should return a qlonglong (or numeric) value, or 0127 * a QString object. QString objects will be sorted with QString::localeAwareCompare if 0128 * sortCategoriesByNaturalComparison() is true. 0129 * 0130 * @note Please have present that: 0131 * QString(QChar(QChar::ObjectReplacementCharacter)) > 0132 * QString(QChar(QChar::ReplacementCharacter)) > 0133 * [ all possible strings ] > 0134 * QString(); 0135 * 0136 * This means that QString() will be sorted the first one, while 0137 * QString(QChar(QChar::ObjectReplacementCharacter)) and 0138 * QString(QChar(QChar::ReplacementCharacter)) will be sorted in last 0139 * position. 0140 * 0141 * @warning Please note that data() method of the model should return always 0142 * information of the same type. If you return a QString for an index, 0143 * you should return always QStrings for all indexes for role CategorySortRole 0144 * in order to correctly sort categories. You can't mix by returning 0145 * a QString for one index, and a qlonglong for other. 0146 * 0147 * @note If you need a more complex layout, you will have to reimplement this 0148 * method. 0149 * 0150 * @return A negative value if the category of @p left should be placed before the 0151 * category of @p right. 0 if @p left and @p right are on the same category, and 0152 * a positive value if the category of @p left should be placed after the 0153 * category of @p right. 0154 */ 0155 virtual int compareCategories(const QModelIndex &left, const QModelIndex &right) const; 0156 0157 private: 0158 std::unique_ptr<KCategorizedSortFilterProxyModelPrivate> const d; 0159 }; 0160 0161 #endif // KCATEGORIZEDSORTFILTERPROXYMODEL_H