File indexing completed on 2025-01-05 03:53:58

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2007-09-22
0007  * Description : Core database field enumerations.
0008  *
0009  * SPDX-FileCopyrightText: 2007-2012 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0010  * SPDX-FileCopyrightText: 2011-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0011  * SPDX-FileCopyrightText: 2013      by Michael G. Hansen <mike at mghansen dot de>
0012  *
0013  * SPDX-License-Identifier: GPL-2.0-or-later
0014  *
0015  * ============================================================ */
0016 
0017 #ifndef DIGIKAM_CORE_DB_FIELDS_H
0018 #define DIGIKAM_CORE_DB_FIELDS_H
0019 
0020 #include "digikam_config.h"
0021 
0022 // C++ includes
0023 
0024 #include <stdint.h>
0025 
0026 // Qt includes
0027 
0028 #include <QFlags>
0029 #include <QHash>
0030 #include <QVariant>
0031 
0032 // Local includes
0033 
0034 #include "digikam_export.h"
0035 
0036 #ifdef HAVE_DBUS
0037 class QDBusArgument;
0038 #endif
0039 
0040 namespace Digikam
0041 {
0042 
0043 namespace DatabaseFields
0044 {
0045 
0046 enum ImagesField
0047 {
0048     ImagesNone         = 0,
0049     Album              = 1 << 0,
0050     Name               = 1 << 1,
0051     Status             = 1 << 2,
0052     Category           = 1 << 3,
0053     ModificationDate   = 1 << 4,
0054     FileSize           = 1 << 5,
0055     UniqueHash         = 1 << 6,
0056     ManualOrder        = 1 << 7,
0057     ImagesAll          = Album            |
0058                          Name             |
0059                          Status           |
0060                          Category         |
0061                          ModificationDate |
0062                          FileSize         |
0063                          UniqueHash       |
0064                          ManualOrder,
0065     ImagesFirst        = Album,
0066     ImagesLast         = ManualOrder
0067 };
0068 
0069 typedef uint8_t ImagesMinSizeType;
0070 
0071 enum ItemInformationField
0072 {
0073     ItemInformationNone  = 0,
0074     Rating                = 1 << 0,
0075     CreationDate          = 1 << 1,
0076     DigitizationDate      = 1 << 2,
0077     Orientation           = 1 << 3,
0078     Width                 = 1 << 4,
0079     Height                = 1 << 5,
0080     Format                = 1 << 6,
0081     ColorDepth            = 1 << 7,
0082     ColorModel            = 1 << 8,
0083     ColorLabel            = 1 << 9,
0084     PickLabel             = 1 << 10,
0085     ItemInformationAll   = Rating           |
0086                            CreationDate     |
0087                            DigitizationDate |
0088                            Orientation      |
0089                            Width            |
0090                            Height           |
0091                            Format           |
0092                            ColorDepth       |
0093                            ColorModel       |
0094                            ColorLabel       |
0095                            PickLabel,
0096     ItemInformationFirst = Rating,
0097     ItemInformationLast  = PickLabel
0098 };
0099 
0100 typedef uint16_t ItemInformationMinSizeType;
0101 
0102 enum ImageMetadataField
0103 {
0104     ImageMetadataNone            = 0,
0105     Make                         = 1 << 0,
0106     Model                        = 1 << 1,
0107     Lens                         = 1 << 2,
0108     Aperture                     = 1 << 3,
0109     FocalLength                  = 1 << 4,
0110     FocalLength35                = 1 << 5,
0111     ExposureTime                 = 1 << 6,
0112     ExposureProgram              = 1 << 7,
0113     ExposureMode                 = 1 << 8,
0114     Sensitivity                  = 1 << 9,
0115     FlashMode                    = 1 << 10,
0116     WhiteBalance                 = 1 << 11,
0117     WhiteBalanceColorTemperature = 1 << 12,
0118     MeteringMode                 = 1 << 13,
0119     SubjectDistance              = 1 << 14,
0120     SubjectDistanceCategory      = 1 << 15,
0121     ImageMetadataAll             = Make                         |
0122                                    Model                        |
0123                                    Lens                         |
0124                                    Aperture                     |
0125                                    FocalLength                  |
0126                                    FocalLength35                |
0127                                    ExposureTime                 |
0128                                    ExposureProgram              |
0129                                    ExposureMode                 |
0130                                    Sensitivity                  |
0131                                    FlashMode                    |
0132                                    WhiteBalance                 |
0133                                    WhiteBalanceColorTemperature |
0134                                    MeteringMode                 |
0135                                    SubjectDistance              |
0136                                    SubjectDistanceCategory,
0137     ImageMetadataFirst           = Make,
0138     ImageMetadataLast            = SubjectDistanceCategory
0139 };
0140 
0141 typedef uint16_t ImageMetadataMinSizeType;
0142 
0143 enum ItemPositionsField
0144 {
0145     ItemPositionsNone   = 0,
0146     Latitude            = 1 << 0,
0147     LatitudeNumber      = 1 << 1,
0148     Longitude           = 1 << 2,
0149     LongitudeNumber     = 1 << 3,
0150     Altitude            = 1 << 4,
0151     PositionOrientation = 1 << 5,
0152     PositionTilt        = 1 << 6,
0153     PositionRoll        = 1 << 7,
0154     PositionAccuracy    = 1 << 8,
0155     PositionDescription = 1 << 9,
0156     ItemPositionsAll    = Latitude            |
0157                           LatitudeNumber      |
0158                           Longitude           |
0159                           LongitudeNumber     |
0160                           Altitude            |
0161                           PositionOrientation |
0162                           PositionTilt        |
0163                           PositionRoll        |
0164                           PositionAccuracy    |
0165                           PositionDescription,
0166     ItemPositionsFirst = Latitude,
0167     ItemPositionsLast  = PositionDescription
0168 };
0169 
0170 typedef uint16_t ItemPositionsMinSizeType;
0171 
0172 enum ItemCommentsField
0173 {
0174     ItemCommentsNone  = 0,
0175     CommentType       = 1 << 0,
0176     CommentLanguage   = 1 << 1,
0177     CommentAuthor     = 1 << 2,
0178     CommentDate       = 1 << 3,
0179     Comment           = 1 << 4,
0180     ItemCommentsAll   = CommentType     |
0181                         CommentLanguage |
0182                         CommentAuthor   |
0183                         CommentDate     |
0184                         Comment,
0185     ItemCommentsFirst = CommentType,
0186     ItemCommentsLast  = Comment
0187 };
0188 
0189 typedef uint8_t ItemCommentsMinSizeType;
0190 
0191 enum ImageHistoryInfoField
0192 {
0193     ImageHistoryInfoNone  = 0,
0194     ImageUUID             = 1 << 0,
0195     ImageHistory          = 1 << 1,
0196     ImageRelations        = 1 << 2,
0197     ImageHistoryInfoAll   = ImageUUID    |
0198                             ImageHistory |
0199                             ImageRelations,
0200     ImageHistoryInfoFirst = ImageUUID,
0201     ImageHistoryInfoLast  = ImageRelations
0202 };
0203 
0204 typedef uint8_t ImageHistoryInfoMinSizeType;
0205 
0206 enum VideoMetadataField
0207 {
0208     VideoMetadataNone            = 0,
0209     AspectRatio                  = 1 << 0,
0210     AudioBitRate                 = 1 << 1,
0211     AudioChannelType             = 1 << 2,
0212     AudioCodec                   = 1 << 3,
0213     Duration                     = 1 << 4,
0214     FrameRate                    = 1 << 5,
0215     VideoCodec                   = 1 << 6,
0216     VideoMetadataAll             = AspectRatio      |
0217                                    AudioBitRate     |
0218                                    AudioChannelType |
0219                                    AudioCodec       |
0220                                    Duration         |
0221                                    FrameRate        |
0222                                    VideoCodec,
0223     VideoMetadataFirst           = AspectRatio,
0224     VideoMetadataLast            = VideoCodec
0225 };
0226 
0227 typedef uint8_t VideoMetadataMinSizeType;
0228 
0229 Q_DECLARE_FLAGS(Images,           ImagesField)
0230 Q_DECLARE_FLAGS(ItemInformation,  ItemInformationField)
0231 Q_DECLARE_FLAGS(ImageMetadata,    ImageMetadataField)
0232 Q_DECLARE_FLAGS(ItemComments,     ItemCommentsField)
0233 Q_DECLARE_FLAGS(ItemPositions,    ItemPositionsField)
0234 Q_DECLARE_FLAGS(ImageHistoryInfo, ImageHistoryInfoField)
0235 Q_DECLARE_FLAGS(VideoMetadata,    VideoMetadataField)
0236 
0237 template<typename FieldName> class FieldMetaInfo
0238 {
0239 };
0240 
0241 #define DECLARE_FIELDMETAINFO(FieldName)                                                                    \
0242     template<> class DIGIKAM_DATABASE_EXPORT FieldMetaInfo <FieldName>                                      \
0243     {                                                                                                       \
0244         public:                                                                                             \
0245             static const FieldName##Field First = FieldName##First;                                         \
0246             static const FieldName##Field Last  = FieldName##Last;                                          \
0247             typedef FieldName##MinSizeType MinSizeType;                                                     \
0248             inline static MinSizeType toMinSizeType(const FieldName value)   { return MinSizeType(value); } \
0249             inline static FieldName fromMinSizeType(const MinSizeType value) { return FieldName(value);   } \
0250     };
0251 
0252 DECLARE_FIELDMETAINFO(Images)
0253 DECLARE_FIELDMETAINFO(ItemInformation)
0254 DECLARE_FIELDMETAINFO(ImageMetadata)
0255 DECLARE_FIELDMETAINFO(ItemComments)
0256 DECLARE_FIELDMETAINFO(ItemPositions)
0257 DECLARE_FIELDMETAINFO(ImageHistoryInfo)
0258 DECLARE_FIELDMETAINFO(VideoMetadata)
0259 
0260 /**
0261  * You can iterate over each of the Enumerations defined above:
0262  * ImagesIterator, ImageMetadataIterator etc.
0263  * for (ImagesIterator it ; !it.atEnd() ; ++it) {...}
0264  */
0265 template<typename FieldName> class DatabaseFieldsEnumIterator
0266 {
0267 
0268 public:
0269 
0270     DatabaseFieldsEnumIterator()
0271       : i(FieldMetaInfo<FieldName>::First)
0272     {
0273     }
0274 
0275     bool atEnd() const
0276     {
0277         return i > FieldMetaInfo<FieldName>::Last;
0278     }
0279 
0280     void operator++()
0281     {
0282         i = (i << 1);
0283     }
0284 
0285     FieldName operator*() const
0286     {
0287         return FieldName(i);
0288     }
0289 
0290 private:
0291 
0292     int i;
0293 };
0294 
0295 /**
0296  * An iterator that iterates only over the flags which are set
0297  */
0298 template<typename FieldName> class DatabaseFieldsEnumIteratorSetOnly
0299 {
0300 public:
0301 
0302     explicit DatabaseFieldsEnumIteratorSetOnly(const FieldName setValues)
0303       : i     (),
0304         values(setValues)
0305     {
0306         if (! (*i & values) )
0307         {
0308             operator++();
0309         }
0310     }
0311 
0312     bool atEnd() const
0313     {
0314         return i.atEnd();
0315     }
0316 
0317     void operator++()
0318     {
0319         while (!i.atEnd())
0320         {
0321             ++i;
0322 
0323             if (*i & values)
0324             {
0325                 break;
0326             }
0327         }
0328     }
0329 
0330     FieldName operator*() const
0331     {
0332         return *i;
0333     }
0334 
0335 private:
0336 
0337     DatabaseFieldsEnumIterator<FieldName> i;
0338     const FieldName                       values;
0339 };
0340 
0341 #define DATABASEFIELDS_ENUM_ITERATOR(Flag)                                      \
0342     typedef DatabaseFieldsEnumIterator<Flag> Flag##Iterator;                    \
0343     typedef DatabaseFieldsEnumIteratorSetOnly<Flag> Flag##IteratorSetOnly;
0344 
0345 DATABASEFIELDS_ENUM_ITERATOR(Images)
0346 DATABASEFIELDS_ENUM_ITERATOR(ItemInformation)
0347 DATABASEFIELDS_ENUM_ITERATOR(ImageMetadata)
0348 DATABASEFIELDS_ENUM_ITERATOR(VideoMetadata)
0349 DATABASEFIELDS_ENUM_ITERATOR(ItemPositions)
0350 DATABASEFIELDS_ENUM_ITERATOR(ItemComments)
0351 DATABASEFIELDS_ENUM_ITERATOR(ImageHistoryInfo)
0352 
0353 /**
0354  * For your custom enum, you need to use the CustomEnum class.
0355  * You need to do an explicit cast.
0356  */
0357 enum CustomEnumFlags
0358 {
0359 };
0360 Q_DECLARE_FLAGS(CustomEnum, CustomEnumFlags)
0361 
0362 #define DATABASEFIELDS_SET_DECLARE_METHODS(Flag, variable)                     \
0363     explicit Set(const Flag& f)             { initialize(); variable = f;    } \
0364     explicit Set(const Flag##Field& f)      { initialize(); variable = f;    } \
0365     inline Flag& operator=(const Flag& f)   { return variable.operator=(f);  } \
0366     inline Flag& operator|=(Flag f)         { return variable.operator|=(f); } \
0367     inline Flag& operator^=(Flag f)         { return variable.operator^=(f); } \
0368     inline Flag operator|(Flag f) const     { return variable.operator|(f);  } \
0369     inline Flag operator^(Flag f) const     { return variable.operator^(f);  } \
0370     inline Flag operator&(Flag f) const     { return variable.operator&(f);  } \
0371     inline operator Flag() const            { return variable;               } \
0372     inline bool hasFieldsFrom##Flag() const { return variable & Flag##All;   } \
0373     inline Flag get##Flag() const           { return variable;               }
0374 
0375 /**
0376  * This class provides a set of all DatabaseFields enums,
0377  * without resorting to a QSet.
0378  */
0379 class Set
0380 {
0381 public:
0382 
0383     Set()
0384     {
0385         initialize();
0386     }
0387 
0388     void initialize()
0389     {
0390         images           = ImagesNone;
0391         imageInformation = ItemInformationNone;
0392         imageMetadata    = ImageMetadataNone;
0393         imageComments    = ItemCommentsNone;
0394         imagePositions   = ItemPositionsNone;
0395         imageHistory     = ImageHistoryInfoNone;
0396         videoMetadata    = VideoMetadataNone;
0397         customEnum       = CustomEnum();
0398     }
0399 
0400 public:
0401 
0402     DATABASEFIELDS_SET_DECLARE_METHODS(Images,           images)
0403     DATABASEFIELDS_SET_DECLARE_METHODS(ItemInformation,  imageInformation)
0404     DATABASEFIELDS_SET_DECLARE_METHODS(VideoMetadata,    videoMetadata)
0405     DATABASEFIELDS_SET_DECLARE_METHODS(ImageMetadata,    imageMetadata)
0406     DATABASEFIELDS_SET_DECLARE_METHODS(ItemComments,     imageComments)
0407     DATABASEFIELDS_SET_DECLARE_METHODS(ItemPositions,    imagePositions)
0408     DATABASEFIELDS_SET_DECLARE_METHODS(ImageHistoryInfo, imageHistory)
0409 
0410     inline bool operator&(const Set& other)
0411     {
0412         return (images           & other.images)           ||
0413                (imageInformation & other.imageInformation) ||
0414                (imageMetadata    & other.imageMetadata)    ||
0415                (imageComments    & other.imageComments)    ||
0416                (imagePositions   & other.imagePositions)   ||
0417                (imageHistory     & other.imageHistory)     ||
0418                (customEnum       & other.customEnum)       ||
0419                (videoMetadata    & other.videoMetadata);
0420     }
0421 
0422     // overloading operator|= creates ambiguity with the database fields'
0423     // operator|=, therefore we give it another name.
0424     inline Set& setFields(const Set& otherSet)
0425     {
0426         images           |= otherSet.images;
0427         imageInformation |= otherSet.imageInformation;
0428         imageMetadata    |= otherSet.imageMetadata;
0429         imageComments    |= otherSet.imageComments;
0430         imagePositions   |= otherSet.imagePositions;
0431         imageHistory     |= otherSet.imageHistory;
0432         customEnum       |= otherSet.customEnum;
0433         videoMetadata    |= otherSet.videoMetadata;
0434 
0435         return *this;
0436     }
0437 
0438     inline CustomEnum& operator=(const CustomEnum& f)
0439     {
0440         return customEnum.operator=(f);
0441     }
0442 
0443     inline CustomEnum& operator|=(CustomEnum f)
0444     {
0445         return customEnum.operator|=(f);
0446     }
0447 
0448     inline CustomEnum& operator^=(CustomEnum f)
0449     {
0450         return customEnum.operator^=(f);
0451     }
0452 
0453     inline CustomEnum operator|(CustomEnum f) const
0454     {
0455         return customEnum.operator|(f);
0456     }
0457 
0458     inline CustomEnum operator^(CustomEnum f) const
0459     {
0460         return customEnum.operator^(f);
0461     }
0462 
0463     inline CustomEnum operator&(CustomEnum f) const
0464     {
0465         return customEnum.operator&(f);
0466     }
0467 
0468 #ifdef HAVE_DBUS
0469     // databasechangesets.cpp
0470     Set& operator<<(const QDBusArgument& argument);
0471     const Set& operator>>(QDBusArgument& argument) const;
0472 #endif
0473 
0474 private:
0475 
0476     Images           images;
0477     ItemInformation  imageInformation;
0478     ImageMetadata    imageMetadata;
0479     VideoMetadata    videoMetadata;
0480     ItemComments     imageComments;
0481     ItemPositions    imagePositions;
0482     ImageHistoryInfo imageHistory;
0483     CustomEnum       customEnum;
0484 };
0485 
0486 #define DATABASEFIELDS_HASH_DECLARE_METHODS(Key, method)                                                                            \
0487     void insertField(const Key& key, const T& value)           { QHash<unsigned int, T>::insert(method(key), value);              } \
0488     int remove(const Key& key)                                 { return QHash<unsigned int, T>::remove(method(key));              } \
0489     int removeAllFields(const Key& key)                                                                                             \
0490     {                                                                                                                               \
0491         int removedCount = 0;                                                                                                       \
0492                                                                                                                                     \
0493         for (DatabaseFieldsEnumIteratorSetOnly<Key> it(key) ; !it.atEnd() ; ++it)                                                   \
0494         {                                                                                                                           \
0495             removedCount += remove(*it);                                                                                            \
0496         }                                                                                                                           \
0497                                                                                                                                     \
0498         return removedCount;                                                                                                        \
0499     }                                                                                                                               \
0500                                                                                                                                     \
0501     T take(const Key& key)                                     { return QHash<unsigned int, T>::take(method(key));                } \
0502                                                                                                                                     \
0503     bool contains(const Key& key) const                        { return QHash<unsigned int, T>::contains(method(key));            } \
0504     const T value(const Key& key) const                        { return QHash<unsigned int, T>::value(method(key));               } \
0505     const T value(const Key& key, const T& defaultValue) const { return QHash<unsigned int, T>::value(method(key), defaultValue); } \
0506                                                                                                                                     \
0507     T& operator[](const Key& key)                              { return QHash<unsigned int, T>::operator[](method(key));          } \
0508     const T operator[](const Key& key) const                   { return QHash<unsigned int, T>::operator[](method(key));          } \
0509                                                                                                                                     \
0510     QList<T> values(const Key& key) const                      { return QHash<unsigned int, T>::value(method(key));               } \
0511     int count(const Key& key) const                            { return QHash<unsigned int, T>::count(method(key));               }
0512 
0513 /**
0514  * This class provides a hash on all DatabaseFields enums,
0515  * allowing to use the enum values as independent keys.
0516  * You can use the class like a normal QHash with the value type defined
0517  * by you, and as keys the members of the DatabaseFields enums.
0518  * You can only use single enum members as keys, not or'ed numbers.
0519  * You can use one custom enum, cast to DatabaseFields::CustomEnum,
0520  * which can have at most 26 flag values (1 << 0 to 1 << 26).
0521  * Pass this as the optional second template parameter.
0522  */
0523 template <class T>
0524 class Hash : public QHash<unsigned int, T>
0525 {
0526 public:
0527 
0528     // We use the upper 6 bits to distinguish the enums, and give the lower 26 bits to the flags.
0529     // So we can store up to 64 enums, with 26 flags each.
0530     static inline unsigned int uniqueKey(Images f)
0531     {
0532         return (unsigned int)f;
0533     }
0534 
0535     static inline unsigned int uniqueKey(ItemInformation f)
0536     {
0537         return (unsigned int)f | (1 << 26);
0538     }
0539 
0540     static inline unsigned int uniqueKey(ImageMetadata f)
0541     {
0542         return (unsigned int)f | (2 << 26);
0543     }
0544 
0545     static inline unsigned int uniqueKey(ItemComments f)
0546     {
0547         return (unsigned int)f | (3 << 26);
0548     }
0549 
0550     static inline unsigned int uniqueKey(ItemPositions f)
0551     {
0552         return (unsigned int)f | (4 << 26);
0553     }
0554 
0555     static inline unsigned int uniqueKey(ImageHistoryInfo f)
0556     {
0557         return (unsigned int)f | (5 << 26);
0558     }
0559 
0560     static inline unsigned int uniqueKey(VideoMetadata f)
0561     {
0562         return (unsigned int)f | (6 << 26);
0563     }
0564 
0565     static inline unsigned int uniqueKey(CustomEnum f)
0566     {
0567         return (unsigned int)f | (63 << 26);
0568     }
0569 
0570     // override relevant methods from QHash
0571     DATABASEFIELDS_HASH_DECLARE_METHODS(Images,           uniqueKey);
0572     DATABASEFIELDS_HASH_DECLARE_METHODS(ItemInformation,  uniqueKey);
0573     DATABASEFIELDS_HASH_DECLARE_METHODS(ImageMetadata,    uniqueKey);
0574     DATABASEFIELDS_HASH_DECLARE_METHODS(VideoMetadata,    uniqueKey);
0575     DATABASEFIELDS_HASH_DECLARE_METHODS(ItemComments,     uniqueKey);
0576     DATABASEFIELDS_HASH_DECLARE_METHODS(ItemPositions,    uniqueKey);
0577     DATABASEFIELDS_HASH_DECLARE_METHODS(ImageHistoryInfo, uniqueKey);
0578     DATABASEFIELDS_HASH_DECLARE_METHODS(CustomEnum,       uniqueKey);
0579 };
0580 
0581 } // namespace DatabaseFields
0582 
0583 } // namespace Digikam
0584 
0585 // NOTE: must be outside the namespace!
0586 Q_DECLARE_OPERATORS_FOR_FLAGS(Digikam::DatabaseFields::Images)
0587 Q_DECLARE_OPERATORS_FOR_FLAGS(Digikam::DatabaseFields::ItemInformation)
0588 Q_DECLARE_OPERATORS_FOR_FLAGS(Digikam::DatabaseFields::ImageMetadata)
0589 Q_DECLARE_OPERATORS_FOR_FLAGS(Digikam::DatabaseFields::VideoMetadata)
0590 Q_DECLARE_OPERATORS_FOR_FLAGS(Digikam::DatabaseFields::ItemComments)
0591 Q_DECLARE_OPERATORS_FOR_FLAGS(Digikam::DatabaseFields::ItemPositions)
0592 Q_DECLARE_OPERATORS_FOR_FLAGS(Digikam::DatabaseFields::ImageHistoryInfo)
0593 
0594 #endif // DIGIKAM_CORE_DB_FIELDS_H