1 /* ============================================================ 2 * 3 * This file is a part of digiKam project 4 * https://www.digikam.org 5 * 6 * Date : 2007-01-05 7 * Description : Metadata handling 8 * 9 * Copyright (C) 2007-2012 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 10 * Copyright (C) 2007-2021 by Gilles Caulier <caulier dot gilles at gmail dot com> 11 * 12 * This program is free software; you can redistribute it 13 * and/or modify it under the terms of the GNU General 14 * Public License as published by the Free Software Foundation; 15 * either version 2, or (at your option) 16 * any later version. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 * 23 * ============================================================ */ 24 25 #ifndef DIGIKAM_METADATA_HUB_H 26 #define DIGIKAM_METADATA_HUB_H 27 28 // Qt includes 29 30 #include <QList> 31 #include <QStringList> 32 #include <QDateTime> 33 #include <QMap> 34 35 // Local includes 36 37 #include "metaenginesettings.h" 38 #include "captionvalues.h" 39 #include "dmetadata.h" 40 #include "dimg.h" 41 42 namespace Digikam 43 { 44 45 class ApplicationSettings; 46 class ItemInfo; 47 class Template; 48 49 class MetadataHub 50 { 51 public: 52 53 /** 54 * The status enum describes the result of joining several metadata sets. 55 * If only one set has been added, the status is always MetadataAvailable. 56 * If no set has been added, the status is always MetadataInvalid 57 */ 58 enum Status 59 { 60 MetadataInvalid, ///< not yet filled with any value 61 MetadataAvailable ///< only one data set has been added, or a common value is available 62 }; 63 64 enum WriteMode 65 { 66 /** 67 * Write all available information 68 */ 69 FullWrite, 70 71 /** 72 * Do a full write if and only if 73 * - metadata fields changed 74 * - the changed fields shall be written according to write settings 75 * "Changed" in this context means changed by one of the set... methods, 76 * the load() methods are ignored for this attribute. 77 * This mode allows to avoid write operations when e.g. the user does not want 78 * keywords to be written and only changes keywords. 79 */ 80 FullWriteIfChanged, 81 82 /** 83 * Write only the changed parts. 84 * Metadata fields which cannot be changed from MetadataHub (photographer ID etc.) 85 * will never be written 86 */ 87 PartialWrite 88 }; 89 90 enum WriteComponents 91 { 92 WRITE_DATETIME = 1, 93 WRITE_TITLE = 2, 94 WRITE_COMMENTS = 4, 95 WRITE_PICKLABEL = 8, 96 WRITE_COLORLABEL= 16, 97 WRITE_RATING = 32, 98 WRITE_TEMPLATE = 64, 99 WRITE_TAGS = 128, 100 WRITE_POSITION = 256, 101 WRITE_ALL = 511 102 }; 103 Q_DECLARE_FLAGS(WriteComponent, WriteComponents) 104 105 public: 106 107 /** 108 * Constructs a MetadataHub. 109 */ 110 MetadataHub(); 111 ~MetadataHub(); 112 113 void reset(); 114 115 // -------------------------------------------------- 116 117 /** 118 * Add metadata information contained in the ItemInfo object. 119 * This method (or in combination with the other load methods) 120 * can be called multiple times on the same MetadataHub object. 121 * In this case, the metadata will be combined. 122 */ 123 void load(const ItemInfo& info); 124 125 // /** 126 // * Add metadata information from the meta engine object 127 // */ 128 // void load(const DMetadata& metadata); 129 130 // /** 131 // * Load metadata information from the given file. 132 // * (Uses DMetadata, QFileInfo) 133 // * @returns True if the metadata could be loaded 134 // */ 135 // bool load(const QString& filePath, const MetaEngineSettingsContainer& settings = MetaEngineSettings::instance()->settings()); 136 137 // -------------------------------------------------- 138 139 /** 140 * @brief writeToMetadata - write to metadata using image info to retrieve tags and filepath 141 * use this method when multiple image infos are loaded in hub 142 * @param info - image info to retrieve current tags 143 * @param writeMode 144 * @param settings 145 * @return true - if everything is successful 146 */ 147 bool writeToMetadata(const ItemInfo& info, 148 WriteComponent writeMode = WRITE_ALL, 149 bool ignoreLazySync = false, 150 const MetaEngineSettingsContainer& settings = MetaEngineSettings::instance()->settings()); 151 152 153 /** 154 * Constructs a meta engine object for given filePath, 155 * calls the above method, writes the changes out to the file, 156 * and notifies the ItemAttributesWatch. 157 * WARNING: Do not use this method when multiple image infos are loaded 158 * It will result in disjoint tags not being written 159 * Use writeToMetadata(Image info ...) instead 160 * @return Returns if the file has been touched 161 */ 162 bool write(const QString& filePath, 163 WriteComponent writeMode = WRITE_ALL, 164 bool ignoreLazySync = false, 165 const MetaEngineSettingsContainer& settings = MetaEngineSettings::instance()->settings()); 166 167 /** 168 * Constructs a meta engine object from the metadata stored in the given DImg object, 169 * calls the above method, and changes the stored metadata in the DImg object. 170 * @return Returns if the DImg object has been touched 171 */ 172 bool write(const DImg& image, 173 WriteComponent writeMode = WRITE_ALL, 174 bool ignoreLazySync = false, 175 const MetaEngineSettingsContainer& settings = MetaEngineSettings::instance()->settings()); 176 177 /** 178 * Will write only Tags to image. Used by TagsManager to write tags to image 179 * Other metadata are not updated. 180 * @return if tags were successfully written. 181 */ 182 bool writeTags(const QString& filePath, 183 WriteComponent writeMode = WRITE_ALL, 184 const MetaEngineSettingsContainer& settings = MetaEngineSettings::instance()->settings()); 185 186 /** 187 * @brief writeTags - used to deduplicate code from writeTags and usual write, all write to tags 188 * operations must be done here 189 * @param metadata - meta engine object that apply changes 190 * @param saveTags - save switch 191 * @return - if tags were successfully set 192 */ 193 bool writeTags(const DMetadata& metadata, bool saveTags); 194 195 /** 196 * @brief cleanupTags - remove duplicates and obsolete tags before setting metadata 197 * @param toClean - tag list to be cleared and de-duplicated 198 * @return - clean tag list 199 */ 200 QStringList cleanupTags(const QStringList& toClean); 201 202 /** 203 * With the currently applied changes, the given writeMode and settings, 204 * returns if write(DMetadata), write(QString) or write(DImg) will actually 205 * apply any changes. 206 */ 207 bool willWriteMetadata(Digikam::MetadataHub::WriteComponent writeMode = WRITE_ALL, 208 const MetaEngineSettingsContainer& settings = MetaEngineSettings::instance()->settings()) const; 209 210 /** 211 * @brief writeToBaloo - write tags, comments and rating to KDE Nepomuk replacement: Baloo 212 * @param filePath - path to file to add comments, tags and rating 213 * @param settings - metadata settings to be set 214 */ 215 void writeToBaloo(const QString& filePath, 216 const MetaEngineSettingsContainer& settings = MetaEngineSettings::instance()->settings()); 217 218 219 // -------------------------------------------------- 220 221 /** 222 * Dedicated method to set face rectangles from database 223 * When called from outside the metadatahub and ItemInfo is cached, 224 * method dimension() can return wrong values, QSize must be specified 225 * manually 226 */ 227 void loadFaceTags(const ItemInfo& info, const QSize& size); 228 229 /** 230 * Get face tag names and face tag regions. 231 * This is used for metadata synchronization in Image Editor 232 */ 233 QMultiMap<QString, QVariant> getFaceTags(); 234 235 /** 236 * Set new face tags 237 */ 238 void setFaceTags(QMultiMap<QString, QVariant> newFaceTags, QSize size); 239 240 protected: 241 242 /** 243 * Applies the set of metadata contained in this MetadataHub 244 * to the given meta engine object. 245 * The MetaEngineSettingsContainer determine whether data is actually 246 * set or not. 247 * The following metadata fields may be set (depending on settings): 248 * - Comment 249 * - Date 250 * - Rating 251 * - Tags 252 * - Photographer ID (data from settings) 253 * - Credits (data from settings) 254 * 255 * The data fields taken from this MetadataHub object are only set if 256 * their status is MetadataAvailable. 257 * If the status is MetadataInvalid or MetadataDisjoint, the respective 258 * metadata field is not touched. 259 * @return Returns true if the metadata object has been touched 260 */ 261 bool write(DMetadata& metadata, 262 WriteComponent writeMode = WRITE_ALL, 263 const MetaEngineSettingsContainer& settings = MetaEngineSettings::instance()->settings()); 264 265 void load(const QDateTime& dateTime, 266 const CaptionsMap& titles, 267 const CaptionsMap& comment, 268 int colorLabel, int pickLabel, 269 int rating, const Template& t); 270 271 void loadTags(const QList<int>& loadedTagIds); 272 void loadTags(const QStringList& loadedTagPaths); 273 void notifyTagDeleted(int id); 274 275 void applyChangeNotifications(); 276 277 private: 278 279 bool writeFaceTagsMap(const DMetadata& metadata, bool saveFaces); 280 281 private: 282 283 class Private; 284 Private* const d; 285 286 private: 287 288 Q_DISABLE_COPY(MetadataHub) 289 }; 290 291 } // namespace Digikam 292 293 Q_DECLARE_OPERATORS_FOR_FLAGS(Digikam::MetadataHub::WriteComponent) 294 295 #endif // DIGIKAM_METADATA_HUB_H 296