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