File indexing completed on 2025-03-09 03:52:55
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2007-09-19 0007 * Description : Scanning a single item. 0008 * 0009 * SPDX-FileCopyrightText: 2007-2013 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0010 * SPDX-FileCopyrightText: 2013-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #ifndef DIGIKAM_ITEM_SCANNER_H 0017 #define DIGIKAM_ITEM_SCANNER_H 0018 0019 // Qt includes 0020 0021 #include <QFileInfo> 0022 0023 // Local includes 0024 0025 #include "dimg.h" 0026 #include "iteminfo.h" 0027 #include "dmetadata.h" 0028 #include "coredbalbuminfo.h" 0029 #include "coredbinfocontainers.h" 0030 0031 namespace Digikam 0032 { 0033 0034 class DIGIKAM_DATABASE_EXPORT ItemScanner 0035 { 0036 0037 public: 0038 0039 enum ScanMode 0040 { 0041 NewScan, 0042 ModifiedScan, 0043 Rescan, 0044 CleanScan 0045 }; 0046 0047 public: 0048 0049 /** 0050 * Construct an ItemScanner object from an existing QFileInfo 0051 * and ItemScanInfo object. 0052 * This constructor shall be used with fileModified() or fullScan(). 0053 */ 0054 ItemScanner(const QFileInfo& info, const ItemScanInfo& Iteminfo); 0055 0056 /** 0057 * Construct an ItemScanner from an existing QFileInfo object. 0058 * Use this constructor if you intend to call newFile(). 0059 */ 0060 explicit ItemScanner(const QFileInfo& info); 0061 0062 /** 0063 * Construct an ItemScanner for an image in the database. 0064 * File info, Scan info and the category will be retrieved from the database. 0065 */ 0066 explicit ItemScanner(qlonglong imageid); 0067 0068 ~ItemScanner(); 0069 0070 /** 0071 * Inform the scanner about the category of the file. 0072 * Required at least for newFile() calls, recommended for calls with the 0073 * first constructor above as well. 0074 */ 0075 void setCategory(DatabaseItem::Category category); 0076 0077 /** 0078 * Provides access to the information retrieved by scanning. 0079 * The validity depends on the previously executed scan. 0080 */ 0081 const ItemScanInfo& itemScanInfo() const; 0082 0083 /** 0084 * Loads data from disk (metadata, image file properties). 0085 * This method is called from any of the main entry points above. 0086 * You can call it before if you want to control the time when it is executed. 0087 * Calling it a second time with data already loaded will do nothing. 0088 */ 0089 void loadFromDisk(); 0090 0091 /** 0092 * Helper method to translate enum values to user presentable strings 0093 */ 0094 static QString formatToString(const QString& format); 0095 0096 private: 0097 0098 static bool hasValidField(const QVariantList& list); 0099 static bool lessThanForIdentity(const ItemScanInfo& a, const ItemScanInfo& b); 0100 0101 // ----------------------------------------------------------------------------- 0102 0103 /** @name Operations with Database 0104 */ 0105 0106 //@{ 0107 0108 public: 0109 0110 /** 0111 * Call this when you want ItemScanner to add a new file to the database 0112 * and read all information into the database. 0113 */ 0114 void newFile(int albumId); 0115 0116 /** 0117 * Call this when you want ItemScanner to add a new file to the database 0118 * and read all information into the database. This variant will not use 0119 * the unique hash to establish identify with an existing entry, but 0120 * read all information newly from the file. 0121 */ 0122 void newFileFullScan(int albumId); 0123 0124 /** 0125 * Call this to take an existing image in the database, but re-read 0126 * all information from the file into the database, possibly overwriting 0127 * information there. 0128 */ 0129 void rescan(); 0130 0131 /** 0132 * This is the same as rescan() but the database metadata 0133 * will be cleaned up if the corresponding metadata 0134 * write option is enabled. 0135 */ 0136 void cleanScan(); 0137 0138 /** 0139 * Commits the scanned information to the database. 0140 * You must call this after scanning was done for any changes to take effect. 0141 * Only this method will perform write operations to the database. 0142 */ 0143 void commit(); 0144 0145 /** 0146 * Returns the image id of the scanned file, if (yet) available. 0147 */ 0148 qlonglong id() const; 0149 0150 /** 0151 * Similar to newFile. 0152 * Call this when you want ItemScanner to add a new file to the database 0153 * which is a copy of another file, copying attributes from the src 0154 * and rescanning other attributes as appropriate. 0155 * Give the id of the album of the new file, and the id of the src file. 0156 */ 0157 void copiedFrom(int albumId, qlonglong srcId); 0158 0159 /** 0160 * Sort a list of infos by proximity to the given subject. 0161 * Infos are near if they are e.g. in the same album. 0162 * They are not near if they are e.g. in different collections. 0163 */ 0164 static void sortByProximity(QList<ItemInfo>& infos, const ItemInfo& subject); 0165 0166 protected: 0167 0168 bool copyFromSource(qlonglong src); 0169 void commitCopyImageAttributes(); 0170 void cleanDatabaseMetadata(); 0171 0172 void prepareAddImage(int albumId); 0173 bool commitAddImage(); 0174 0175 //@} 0176 0177 // ----------------------------------------------------------------------------- 0178 0179 /** @name Operations on File Metadata 0180 */ 0181 0182 //@{ 0183 0184 public: 0185 0186 /** 0187 * Call this when you have detected that a file in the database has been 0188 * modified on disk. Only two groups of fields will be updated in the database: 0189 * - filesystem specific properties (those that signaled you that the file has been modified 0190 * because their state on disk differed from the state in the database) 0191 * - image specific properties, for which a difference in the database independent from 0192 * the actual file does not make sense (width/height, bit depth, color model) 0193 */ 0194 void fileModified(); 0195 0196 /** 0197 * Returns File-metadata container with user-presentable information. 0198 * These methods provide the reverse service: Not writing into the db, but reading from the db. 0199 */ 0200 static void fillCommonContainer(qlonglong imageid, ImageCommonContainer* const container); 0201 0202 /** 0203 * Returns a suitable creation date from file system information. 0204 * Use this as a fallback if metadata is not available. 0205 */ 0206 static QDateTime creationDateFromFilesystem(const QFileInfo& info); 0207 0208 protected: 0209 0210 void prepareUpdateImage(); 0211 void commitUpdateImage(); 0212 0213 bool scanFromIdenticalFile(); 0214 void scanFile(ScanMode mode); 0215 0216 void scanItemInformation(); 0217 void commitItemInformation(); 0218 0219 //@} 0220 0221 // ----------------------------------------------------------------------------- 0222 0223 /** @name Operations on Photo Metadata 0224 */ 0225 0226 //@{ 0227 0228 public: 0229 0230 /** 0231 * Helper method to return official property name by which 0232 * IPTC core properties are stored in the database (ItemCopyright and ImageProperties table). 0233 * Allowed arguments: All MetadataInfo::Fields starting with "IptcCore..." 0234 */ 0235 static QString iptcCorePropertyName(MetadataInfo::Field field); 0236 0237 static MetadataFields allImageMetadataFields(); 0238 0239 protected: 0240 0241 QString detectImageFormat() const; 0242 0243 void scanImageMetadata(); 0244 void commitImageMetadata(); 0245 void scanItemPosition(); 0246 void commitItemPosition(); 0247 void scanItemComments(); 0248 void commitItemComments(); 0249 void scanItemCopyright(); 0250 void commitItemCopyright(); 0251 void scanIPTCCore(); 0252 void commitIPTCCore(); 0253 void scanTags(); 0254 void commitTags(); 0255 void scanFaces(); 0256 void commitFaces(); 0257 0258 bool checkRatingFromMetadata(const QVariant& ratingFromMetadata) const; 0259 void checkCreationDateFromMetadata(QVariant& dateFromMetadata) const; 0260 0261 //@} 0262 0263 // ----------------------------------------------------------------------------- 0264 0265 /** @name Operations on Video Metadata 0266 */ 0267 0268 //@{ 0269 0270 public: 0271 0272 /** 0273 * Returns Video container with user-presentable information. 0274 * These methods provide the reverse service: Not writing into the db, but reading from the db. 0275 */ 0276 static void fillVideoMetadataContainer(qlonglong imageid, VideoMetadataContainer* const container); 0277 0278 protected: 0279 0280 void scanVideoInformation(); 0281 void scanVideoMetadata(); 0282 void commitVideoMetadata(); 0283 QString detectVideoFormat() const; 0284 QString detectAudioFormat() const; 0285 static MetadataFields allVideoMetadataFields(); 0286 0287 //@} 0288 0289 // ----------------------------------------------------------------------------- 0290 0291 /** @name Operations on History Metadata 0292 */ 0293 0294 //@{ 0295 0296 public: 0297 0298 /** 0299 * Returns true if this file has been marked as needing history resolution at a later stage 0300 */ 0301 bool hasHistoryToResolve() const; 0302 0303 //@{ 0304 /** 0305 * Resolves the image history of the image id by filling the ImageRelations table 0306 * for all contained referred images. 0307 * If needTaggingIds is given, all ids marked for needing tagging of the history graph are added. 0308 */ 0309 static bool resolveImageHistory(qlonglong id, QList<qlonglong>* needTaggingIds = nullptr); 0310 static bool resolveImageHistory(qlonglong imageId, const QString& historyXml, QList<qlonglong>* needTaggingIds = nullptr); 0311 //@} 0312 0313 /** 0314 * Takes the history graph reachable from the given image, and assigns 0315 * versioning tags to all entries based on history image types and graph structure 0316 */ 0317 static void tagItemHistoryGraph(qlonglong id); 0318 0319 /** 0320 * All referred images of the given history will be resolved. 0321 * In the returned history, the actions are the same, while each 0322 * referred image actually exists in the collection 0323 * (if mustBeAvailable is true, it is even in a currently available collection). 0324 * That means the number of referred images may be less or greater than initially. 0325 * Note that this history may have peculiar properties, like multiple Original or Current entries 0326 * (if the source entry resolves to multiple collection images), so this history 0327 * is only for internal use, not for storage. 0328 */ 0329 static DImageHistory resolvedImageHistory(const DImageHistory& history, bool mustBeAvailable = false); 0330 0331 /** 0332 * Determines if the two ids refer to the same image. 0333 * Does not check if such a referred image really exists. 0334 */ 0335 static bool sameReferredImage(const HistoryImageId& id1, const HistoryImageId& id2); 0336 0337 /** 0338 * Returns all image ids fulfilling the given image id. 0339 */ 0340 static QList<qlonglong> resolveHistoryImageId(const HistoryImageId& historyId); 0341 0342 protected: 0343 0344 void scanImageHistory(); 0345 void commitImageHistory(); 0346 void scanImageHistoryIfModified(); 0347 0348 QString uniqueHash() const; 0349 0350 //@} 0351 0352 public: 0353 0354 /** 0355 * @brief scanBalooInfo - retrieve tags, comments and rating from Baloo Desktop service. 0356 */ 0357 void scanBalooInfo(); 0358 0359 private: 0360 0361 // Disable 0362 ItemScanner(const ItemScanner&) = delete; 0363 ItemScanner& operator=(const ItemScanner&) = delete; 0364 0365 private: 0366 0367 class Private; 0368 Private* const d; 0369 }; 0370 0371 } // namespace Digikam 0372 0373 #endif // DIGIKAM_ITEM_SCANNER_H