File indexing completed on 2025-01-05 03:54:12

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2009-05-31
0007  * Description : Sort settings for use with ItemFilterModel
0008  *
0009  * SPDX-FileCopyrightText: 2009 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #ifndef DIGIKAM_ITEM_SORT_SETTINGS_H
0016 #define DIGIKAM_ITEM_SORT_SETTINGS_H
0017 
0018 // Qt includes
0019 
0020 #include <QString>
0021 #include <QVariant>
0022 
0023 // Local includes
0024 
0025 #include "digikam_export.h"
0026 #include "itemsortcollator.h"
0027 
0028 namespace Digikam
0029 {
0030 
0031 class ItemInfo;
0032 class FaceTagsIface;
0033 
0034 namespace DatabaseFields
0035 {
0036     class Set;
0037 }
0038 
0039 class DIGIKAM_DATABASE_EXPORT ItemSortSettings
0040 {
0041 public:
0042 
0043     enum SortOrder
0044     {
0045         AscendingOrder  = Qt::AscendingOrder,
0046         DescendingOrder = Qt::DescendingOrder,
0047         DefaultOrder                ///< sort order depends on the chosen sort role
0048     };
0049 
0050     enum CategorizationMode
0051     {
0052         NoCategories,               ///< categorization switched off
0053         OneCategory,                ///< all items in one global category
0054         CategoryByAlbum,
0055         CategoryByFormat,
0056         CategoryByMonth,
0057         CategoryByFaces
0058     };
0059 
0060     enum SortRole
0061     {
0062         // Note: For legacy reasons, the order of the first five entries must remain unchanged
0063         SortByFileName,
0064         SortByFilePath,
0065         SortByCreationDate,
0066         SortByModificationDate,
0067         SortByFileSize,
0068         SortByRating,
0069         SortByImageSize,            ///< pixel number
0070         SortByAspectRatio,          ///< width / height * 100000
0071         SortByFaces,                ///< count of unconfirmed faces
0072         SortBySimilarity,
0073         SortByManualOrderAndName,
0074         SortByManualOrderAndDate
0075     };
0076 
0077 public:
0078 
0079     explicit ItemSortSettings();
0080 
0081     bool operator==(const ItemSortSettings& other) const;
0082 
0083     /**
0084      * Compares the categories of left and right.
0085      * Return -1 if left is less than right, 0 if both fall in the same category,
0086      * and 1 if left is greater than right.
0087      * Adheres to set categorization mode and current category sort order.
0088      * Face passed in to allow Categorization by Faces. Pass in an empty
0089      * Face if not needed.
0090      */
0091     int compareCategories(const ItemInfo& left, const ItemInfo& right,
0092                           const FaceTagsIface& leftFace, const FaceTagsIface& rightFace) const;
0093 
0094     /**
0095      * Returns true if left is less than right.
0096      * Adheres to current sort role and sort order.
0097      */
0098     bool lessThan(const ItemInfo& left, const ItemInfo& right) const;
0099 
0100     /**
0101      * Compares the ItemInfos left and right.
0102      * Return -1 if left is less than right, 1 if left is greater than right,
0103      * and 0 if left equals right comparing the current sort role's value.
0104      * Adheres to set sort role and sort order.
0105      */
0106     int compare(const ItemInfo& left, const ItemInfo& right) const;
0107 
0108     /**
0109      * Returns true if left QVariant is less than right.
0110      * Adheres to current sort role and sort order.
0111      * Use for extraValue, if necessary.
0112      */
0113     bool lessThan(const QVariant& left, const QVariant& right) const;
0114 
0115     void setSortRole(SortRole role);
0116     void setSortOrder(SortOrder order);
0117     void setStringTypeNatural(bool natural);
0118 
0119 public:
0120 
0121     /// --- Categories ---
0122 
0123     void setCategorizationMode(CategorizationMode mode);
0124     void setCategorizationSortOrder(SortOrder order);
0125 
0126 
0127     bool isCategorized() const
0128     {
0129         return (categorizationMode >= CategoryByAlbum);
0130     }
0131 
0132 public:
0133 
0134     /// --- Image Sorting ---
0135 
0136     int compare(const ItemInfo& left, const ItemInfo& right, SortRole sortRole) const;
0137 
0138     static Qt::SortOrder defaultSortOrderForCategorizationMode(CategorizationMode mode);
0139     static Qt::SortOrder defaultSortOrderForSortRole(SortRole role);
0140 
0141 public:
0142 
0143     /// --- Change notification ---
0144 
0145     /**
0146      * Returns database fields a change in which would affect the current sorting.
0147      */
0148     DatabaseFields::Set watchFlags() const;
0149 
0150 public:
0151 
0152     /// --- Utilities ---
0153 
0154     /**
0155      * Returns a < b if sortOrder is Ascending, or b < a if order is descending.
0156      */
0157     template <typename T>
0158     static inline bool lessThanByOrder(const T& a, const T& b, Qt::SortOrder sortOrder)
0159     {
0160         if (sortOrder == Qt::AscendingOrder)
0161         {
0162             return (a < b);
0163         }
0164 
0165         return (b < a);
0166     }
0167 
0168     /**
0169      * Returns the usual compare result of -1, 0, or 1 for lessThan, equals and greaterThan.
0170      */
0171     template <typename T>
0172     static inline int compareValue(const T& a, const T& b)
0173     {
0174         if (a == b)
0175         {
0176             return 0;
0177         }
0178 
0179         if (a > b)
0180         {
0181             return 1;
0182         }
0183 
0184         return (-1);
0185     }
0186 
0187     /**
0188      * Takes a typical result from a compare method (0 is equal, -1 is less than, 1 is greater than)
0189      * and applies the given sort order to it.
0190      */
0191     static inline int compareByOrder(int compareResult, Qt::SortOrder sortOrder)
0192     {
0193         if (sortOrder == Qt::AscendingOrder)
0194         {
0195             return compareResult;
0196         }
0197 
0198         return (- compareResult);
0199     }
0200 
0201     template <typename T>
0202     static inline int compareByOrder(const T& a, const T& b, Qt::SortOrder sortOrder)
0203     {
0204         return compareByOrder(compareValue(a, b), sortOrder);
0205     }
0206 
0207     /**
0208      * Compares the two string by natural comparison and adheres to given sort order
0209      */
0210     static inline int naturalCompare(const QString& a,
0211                                      const QString& b,
0212                                      Qt::SortOrder sortOrder,
0213                                      Qt::CaseSensitivity caseSensitive = Qt::CaseSensitive,
0214                                      bool natural = true)
0215     {
0216         ItemSortCollator* const sorter = ItemSortCollator::instance();
0217 
0218         return compareByOrder(sorter->itemCompare(a, b, caseSensitive, natural), sortOrder);
0219     }
0220 
0221 public:
0222 
0223     CategorizationMode   categorizationMode;
0224     SortOrder            categorizationSortOrder;
0225 
0226     /// Only Ascending or Descending, never DefaultOrder
0227     Qt::SortOrder        currentCategorizationSortOrder;
0228     Qt::CaseSensitivity  categorizationCaseSensitivity;
0229 
0230     SortRole             sortRole;
0231     SortOrder            sortOrder;
0232     bool                 strTypeNatural;
0233 
0234     Qt::SortOrder        currentSortOrder;
0235     Qt::CaseSensitivity  sortCaseSensitivity;
0236 };
0237 
0238 } // namespace Digikam
0239 
0240 #endif // DIGIKAM_ITEM_SORT_SETTINGS_H