File indexing completed on 2025-04-27 03:57:26
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2015-08-17 0007 * Description : Helper class for Image Description Editor Tab 0008 * 0009 * SPDX-FileCopyrightText: 2015 by Veaceslav Munteanu <veaceslav dot munteanu90 at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #ifndef DIGIKAM_DISJOINT_METADATA_H 0016 #define DIGIKAM_DISJOINT_METADATA_H 0017 0018 // Qt includes 0019 0020 #include <QString> 0021 #include <QMap> 0022 #include <QObject> 0023 #include <QDateTime> 0024 0025 // Local includes 0026 0027 #include "digikam_export.h" 0028 #include "disjointmetadatadatafields.h" 0029 #include "metaenginesettings.h" 0030 0031 namespace Digikam 0032 { 0033 0034 class ItemInfo; 0035 class CaptionsMap; 0036 class Template; 0037 0038 class DIGIKAM_GUI_EXPORT DisjointMetadata : public QObject 0039 { 0040 Q_OBJECT 0041 0042 public: 0043 0044 enum WriteMode 0045 { 0046 /** 0047 * Write all available information 0048 */ 0049 FullWrite, 0050 0051 /** 0052 * Do a full write if and only if 0053 * - metadata fields changed 0054 * - the changed fields shall be written according to write settings 0055 * "Changed" in this context means changed by one of the set... methods, 0056 * the load() methods are ignored for this attribute. 0057 * This mode allows to avoid write operations when e.g. the user does not want 0058 * keywords to be written and only changes keywords. 0059 */ 0060 FullWriteIfChanged, 0061 0062 /** 0063 * Write only the changed parts. 0064 * Metadata fields which cannot be changed from MetadataHub (photographer ID etc.) 0065 * will never be written 0066 */ 0067 PartialWrite 0068 }; 0069 0070 public: 0071 0072 DisjointMetadata(); 0073 ~DisjointMetadata() override; 0074 0075 0076 DisjointMetadataDataFields dataFields() const; 0077 void setDataFields(const DisjointMetadataDataFields& data); 0078 0079 void reset(); 0080 0081 void load(const ItemInfo& info); 0082 0083 //@{ 0084 0085 /** 0086 * Returns the metadata field Status. 0087 */ 0088 DisjointMetadataDataFields::Status dateTimeStatus() const; 0089 DisjointMetadataDataFields::Status titlesStatus() const; 0090 DisjointMetadataDataFields::Status commentsStatus() const; 0091 DisjointMetadataDataFields::Status pickLabelStatus() const; 0092 DisjointMetadataDataFields::Status colorLabelStatus() const; 0093 DisjointMetadataDataFields::Status ratingStatus() const; 0094 DisjointMetadataDataFields::Status templateStatus() const; 0095 0096 DisjointMetadataDataFields::Status tagStatus(int albumId) const; 0097 DisjointMetadataDataFields::Status tagStatus(const QString& tagPath) const; 0098 0099 //@} 0100 0101 //@{ 0102 0103 /** 0104 * Returns if the metadata field has been changed 0105 * with the corresponding setter method. 0106 */ 0107 bool dateTimeChanged() const; 0108 bool titlesChanged() const; 0109 bool commentsChanged() const; 0110 bool pickLabelChanged() const; 0111 bool colorLabelChanged() const; 0112 bool ratingChanged() const; 0113 bool templateChanged() const; 0114 bool tagsChanged() const; 0115 0116 //@} 0117 0118 //@{ 0119 0120 /** 0121 * Set metadata field to the given value, 0122 * and the metadata field status to the corresponding DisjointMetadataDataFields::MetadataAvailable. 0123 */ 0124 void setDateTime(const QDateTime& dateTime, 0125 DisjointMetadataDataFields::Status status = DisjointMetadataDataFields::MetadataAvailable); 0126 void setTitles(const CaptionsMap& titles, 0127 DisjointMetadataDataFields::Status status = DisjointMetadataDataFields::MetadataAvailable); 0128 void setComments(const CaptionsMap& comments, 0129 DisjointMetadataDataFields::Status status = DisjointMetadataDataFields::MetadataAvailable); 0130 void setPickLabel(int pickId, 0131 DisjointMetadataDataFields::Status status = DisjointMetadataDataFields::MetadataAvailable); 0132 void setColorLabel(int colorId, 0133 DisjointMetadataDataFields::Status status = DisjointMetadataDataFields::MetadataAvailable); 0134 void setRating(int rating, 0135 DisjointMetadataDataFields::Status status = DisjointMetadataDataFields::MetadataAvailable); 0136 void setMetadataTemplate(const Template& t, 0137 DisjointMetadataDataFields::Status status = DisjointMetadataDataFields::MetadataAvailable); 0138 void setTag(int albumID, 0139 DisjointMetadataDataFields::Status status = DisjointMetadataDataFields::MetadataAvailable); 0140 0141 /** 0142 * Special case if the metadata of color, pick or rating has already been changed outside. 0143 * Replace with current values as if there is no change. 0144 */ 0145 void replaceColorLabel(int colorId); 0146 void replacePickLabel(int pickId); 0147 void replaceRating(int rating); 0148 0149 //@} 0150 0151 /** 0152 * Returns the dateTime. 0153 * If status is DisjointMetadataDataFields::MetadataDisjoint, the earliest date is returned. 0154 * (see dateTimeInterval()) 0155 * If status is DisjointMetadataDataFields::MetadataInvalid, an invalid date is returned. 0156 */ 0157 QDateTime dateTime() const; 0158 0159 /** 0160 * Returns a map all alternate language titles. 0161 * If status is DisjointMetadataDataFields::MetadataDisjoint, the first loaded map is returned. 0162 * If status is DisjointMetadataDataFields::MetadataInvalid, CaptionMap() is returned. 0163 */ 0164 CaptionsMap titles() const; 0165 0166 /** 0167 * Returns a map all alternate language omments . 0168 * If status is DisjointMetadataDataFields::MetadataDisjoint, the first loaded map is returned. 0169 * If status is DisjointMetadataDataFields::MetadataInvalid, CaptionMap() is returned. 0170 */ 0171 CaptionsMap comments() const; 0172 0173 /** 0174 * Returns the Pick Label id (see PickLabel values in globals.h). 0175 * If status is DisjointMetadataDataFields::MetadataDisjoint, the None Label is returned. 0176 * (see pickLabelInterval()) 0177 * If status is DisjointMetadataDataFields::MetadataInvalid, -1 is returned. 0178 */ 0179 int pickLabel() const; 0180 0181 /** 0182 * Returns the Color Label id (see ColorLabel values in globals.h). 0183 * If status is DisjointMetadataDataFields::MetadataDisjoint, the None Label is returned. 0184 * (see colorLabelInterval()) 0185 * If status is DisjointMetadataDataFields::MetadataInvalid, -1 is returned. 0186 */ 0187 int colorLabel() const; 0188 0189 /** 0190 * Returns the rating. 0191 * If status is DisjointMetadataDataFields::MetadataDisjoint, the lowest rating is returned. 0192 * (see ratingInterval()) 0193 * If status is DisjointMetadataDataFields::MetadataInvalid, -1 is returned. 0194 */ 0195 int rating() const; 0196 0197 /** 0198 * Returns the metadata template. 0199 * If status is DisjointMetadataDataFields::MetadataDisjoint, the first loaded template is returned. 0200 * If status is DisjointMetadataDataFields::MetadataInvalid, 0 is returned. 0201 */ 0202 Template metadataTemplate() const; 0203 0204 /** 0205 * Returns the earliest and latest date. 0206 * If status is DisjointMetadataDataFields::MetadataAvailable, the values are the same. 0207 * If status is DisjointMetadataDataFields::MetadataInvalid, invalid dates are returned. 0208 */ 0209 void dateTimeInterval(QDateTime& lowest, 0210 QDateTime& highest) const; 0211 0212 /** 0213 * Returns the lowest and highest Pick Label id (see PickLabel values from globals.h). 0214 * If status is DisjointMetadataDataFields::MetadataAvailable, the values are the same. 0215 * If status is DisjointMetadataDataFields::MetadataInvalid, -1 is returned. 0216 */ 0217 void pickLabelInterval(int& lowest, 0218 int& highest) const; 0219 0220 /** 0221 * Returns the lowest and highest Color Label id (see ColorLabel values from globals.h). 0222 * If status is DisjointMetadataDataFields::MetadataAvailable, the values are the same. 0223 * If status is DisjointMetadataDataFields::MetadataInvalid, -1 is returned. 0224 */ 0225 void colorLabelInterval(int& lowest, 0226 int& highest) const; 0227 0228 /** 0229 * Returns the lowest and highest rating. 0230 * If status is DisjointMetadataDataFields::MetadataAvailable, the values are the same. 0231 * If status is DisjointMetadataDataFields::MetadataInvalid, -1 is returned. 0232 */ 0233 void ratingInterval(int& lowest, 0234 int& highest) const; 0235 0236 /** 0237 * Returns a QStringList with all tags with status DisjointMetadataDataFields::MetadataAvailable. 0238 * (i.e., the intersection of tags from all loaded metadata sets) 0239 */ 0240 QStringList keywords() const; 0241 0242 /** 0243 * Returns a map with the status for each tag. 0244 * Any tag that was set on one of the loaded images is contained in the map. 0245 * (If a tag is not contained in the map, it was not set on any of the loaded images) 0246 * If the tag was set on all loaded images, the status is DisjointMetadataDataFields::MetadataAvailable. 0247 * If the tag was set on at least one, but not all of the loaded images, the status is DisjointMetadataDataFields::MetadataDisjoint. 0248 */ 0249 QMap<int, DisjointMetadataDataFields::Status> tags() const; 0250 0251 void resetChanged(); 0252 0253 /** 0254 * Applies the set of metadata contained in this MetadataHub 0255 * to the given ItemInfo object. 0256 * @return Returns true if the info object has been changed 0257 */ 0258 bool write(ItemInfo info, WriteMode writeMode = FullWrite); 0259 0260 /** 0261 * With the currently applied changes, the given writeMode and settings, 0262 * returns if write(DMetadata), write(QString) or write(DImg) will actually 0263 * apply any changes. 0264 */ 0265 bool willWriteMetadata(WriteMode writeMode, 0266 const MetaEngineSettingsContainer& settings = 0267 MetaEngineSettings::instance()->settings()) const; 0268 0269 /** 0270 * @brief changedFlags - used for selective metadata write. The result will be passed to metadatahub and it will 0271 * - write it to disk 0272 * @return - metadatahub flags encoded as int 0273 */ 0274 int changedFlags(); 0275 0276 private Q_SLOTS: 0277 0278 void slotTagDeleted(int tagId); 0279 void slotInvalidate(); 0280 0281 private: 0282 0283 void load(const QDateTime& dateTime, 0284 const CaptionsMap& titles, 0285 const CaptionsMap& comment, 0286 int colorLabel, int pickLabel, 0287 int rating, const Template& t); 0288 0289 void loadTags(const QList<int>& tagIds); 0290 void notifyTagDeleted(int id); 0291 void applyChangeNotifications(); 0292 0293 private: 0294 0295 // Disable 0296 explicit DisjointMetadata(QObject*) = delete; 0297 0298 // Disable copy constructor and operator to prevent potential slicing with this class, reported by Clazy static analyzer. 0299 // https://github.com/KDE/clazy/blob/master/docs/checks/README-copyable-polymorphic.md 0300 // Use DisjointMetadataDataFields container setter and getter instead. 0301 // TODO: remove legacy implementations for these methods later if no side effect. 0302 DisjointMetadata(const DisjointMetadata& other); 0303 DisjointMetadata& operator=(const DisjointMetadata& other); 0304 0305 private: 0306 0307 class Private; 0308 Private* d; 0309 }; 0310 0311 } // namespace Digikam 0312 0313 #endif // DIGIKAM_DISJOINT_METADATA_H