File indexing completed on 2024-04-28 15:39:57
0001 // SPDX-FileCopyrightText: 2003-2012 Jesper K. Pedersen <jesper.pedersen@kdab.com> 0002 // SPDX-FileCopyrightText: 2005-2007 Dirk Mueller <mueller@kde.org> 0003 // SPDX-FileCopyrightText: 2006-2008 Tuomas Suutari <tuomas@nepnep.net> 0004 // SPDX-FileCopyrightText: 2007-2008 Jan Kundrát <jkt@flaska.net> 0005 // SPDX-FileCopyrightText: 2008 Henner Zeller <h.zeller@acm.org> 0006 // SPDX-FileCopyrightText: 2010 Wes Hardaker <kpa@capturedonearth.com> 0007 // SPDX-FileCopyrightText: 2012 Miika Turkia <miika.turkia@gmail.com> 0008 // SPDX-FileCopyrightText: 2013-2023 Johannes Zarl-Zierl <johannes@zarl-zierl.at> 0009 // SPDX-FileCopyrightText: 2014-2019 Tobias Leupold <tl@stonemx.de> 0010 // SPDX-FileCopyrightText: 2017-2020 Robert Krawitz <rlk@alum.mit.edu> 0011 // 0012 // SPDX-License-Identifier: GPL-2.0-or-later 0013 0014 #ifndef IMAGEINFO_H 0015 #define IMAGEINFO_H 0016 0017 #include <kpabase/config-kpa-marble.h> 0018 0019 #include "CategoryPtr.h" 0020 #include "ExifMode.h" 0021 #include "ImageDate.h" 0022 #include "MD5.h" 0023 0024 #ifdef HAVE_MARBLE 0025 #include <Map/GeoCoordinates.h> 0026 #endif 0027 #include <kpabase/FileName.h> 0028 #include <kpabase/StringSet.h> 0029 0030 #include <QHash> 0031 #include <QRect> 0032 #include <QSize> 0033 #include <QString> 0034 #include <QStringList> 0035 0036 namespace Plugins 0037 { 0038 class ImageInfo; 0039 } 0040 0041 namespace XMLDB 0042 { 0043 class Database; 0044 } 0045 0046 namespace DB 0047 { 0048 enum RotationMode { 0049 RotateImageInfoAndAreas, 0050 RotateImageInfoOnly 0051 }; 0052 0053 using Utilities::StringSet; 0054 class ImageDB; 0055 class MemberMap; 0056 0057 /** 0058 * @brief The FileInformation enum controls the behaviour of the ImageInfo constructor. 0059 * Depending on the value, metadata is read from the image file and optionally the Exif database is updated. 0060 */ 0061 enum class FileInformation { 0062 Ignore, ///< Do not read additional information from the image file. 0063 Read, ///< Read metadata from the image file, but do not update metadata in the Exif database. 0064 ReadAndUpdateExifDB ///< Read metadata from the image file and update the Exif database. 0065 }; 0066 0067 enum MediaType { Image = 0x01, 0068 Video = 0x02 }; 0069 constexpr MediaType anyMediaType = MediaType(Image | Video); 0070 typedef unsigned int StackID; 0071 0072 typedef QHash<QString, QRect> PositionTags; 0073 typedef QHashIterator<QString, QRect> PositionTagsIterator; 0074 typedef QHash<QString, PositionTags> TaggedAreas; 0075 typedef QHashIterator<QString, PositionTags> TaggedAreasIterator; 0076 typedef QHash<QString, StringSet> CategoryInformation; 0077 0078 class ImageInfo : public QSharedData 0079 { 0080 0081 public: 0082 /** 0083 * @brief ImageInfo constructs an empty ImageInfo. 0084 * An empty imageInfo can be detected by calling \c isNull(). 0085 */ 0086 ImageInfo(); 0087 /** 0088 * @brief ImageInfo constructor to create an ImageInfo for a file. 0089 * This constructor is typically called by the new image finder. 0090 * @param fileName 0091 * @param type 0092 * @param infoMode 0093 */ 0094 explicit ImageInfo(const DB::FileName &fileName, MediaType type = Image, FileInformation infoMode = FileInformation::ReadAndUpdateExifDB); 0095 /** 0096 * @brief ImageInfo constructor including all fields. 0097 * This constructor is typically called when reading ImageInfos from the database file, or when doing an import. 0098 * @param fileName 0099 * @param label 0100 * @param description 0101 * @param date 0102 * @param angle 0103 * @param md5sum 0104 * @param size 0105 * @param type 0106 * @param rating 0107 * @param stackId 0108 * @param stackOrder 0109 */ 0110 ImageInfo(const DB::FileName &fileName, 0111 const QString &label, 0112 const QString &description, 0113 const ImageDate &date, 0114 int angle, 0115 const MD5 &md5sum, 0116 const QSize &size, 0117 MediaType type, 0118 short rating = -1, 0119 StackID stackId = 0, 0120 unsigned int stackOrder = 0); 0121 ImageInfo(const ImageInfo &other); 0122 0123 FileName fileName() const; 0124 void setFileName(const DB::FileName &relativeFileName); 0125 0126 void setLabel(const QString &); 0127 QString label() const; 0128 0129 void setDescription(const QString &); 0130 QString description() const; 0131 0132 void setDate(const ImageDate &); 0133 ImageDate date() const; 0134 ImageDate &date(); 0135 void readExif(const DB::FileName &fullPath, DB::ExifMode mode); 0136 0137 void rotate(int degrees, RotationMode mode = RotateImageInfoAndAreas); 0138 int angle() const; 0139 void setAngle(int angle); 0140 0141 short rating() const; 0142 void setRating(short rating); 0143 0144 bool isStacked() const { return m_stackId != 0; } 0145 StackID stackId() const; 0146 0147 unsigned int stackOrder() const; 0148 void setStackOrder(const unsigned int stackOrder); 0149 0150 void setVideoLength(int seconds); 0151 int videoLength() const; 0152 0153 void setCategoryInfo(const QString &key, const StringSet &value); 0154 void addCategoryInfo(const QString &category, const StringSet &values); 0155 /** 0156 * Enable a tag within a category for this image. 0157 * Optionally, the tag's position can be given (for positionable categories). 0158 * @param category the category name 0159 * @param value the tag name 0160 * @param area the image region that the tag applies to. 0161 */ 0162 void addCategoryInfo(const QString &category, const QString &value, const QRect &area = QRect()); 0163 void clearAllCategoryInfo(); 0164 void removeCategoryInfo(const QString &category, const StringSet &values); 0165 void removeCategoryInfo(const QString &category, const QString &value); 0166 /** 0167 * Set the tagged areas for the image. 0168 * It is assumed that the positioned tags have already been set to the ImageInfo 0169 * using one of the functions <code>setCategoryInfo</code> or <code>addCategoryInfo</code>. 0170 * 0171 * @param category the category name. 0172 * @param positionedTags a mapping of tag names to image areas. 0173 */ 0174 void setPositionedTags(const QString &category, const PositionTags &positionedTags); 0175 0176 bool hasCategoryInfo(const QString &key, const QString &value) const; 0177 bool hasCategoryInfo(const QString &key, const StringSet &values) const; 0178 0179 QStringList availableCategories() const; 0180 StringSet itemsOfCategory(const QString &category) const; 0181 void renameItem(const QString &key, const QString &oldValue, const QString &newValue); 0182 void renameCategory(const QString &oldName, const QString &newName); 0183 0184 bool operator!=(const ImageInfo &other) const; 0185 bool operator==(const ImageInfo &other) const; 0186 ImageInfo &operator=(const ImageInfo &other); 0187 0188 static bool imageOnDisk(const DB::FileName &fileName); 0189 0190 const MD5 &MD5Sum() const { return m_md5sum; } 0191 void setMD5Sum(const MD5 &sum, bool storeEXIF = true); 0192 0193 void setLocked(bool); 0194 bool isLocked() const; 0195 0196 bool isNull() const { return m_null; } 0197 QSize size() const; 0198 void setSize(const QSize &size); 0199 0200 MediaType mediaType() const; 0201 void setMediaType(MediaType type) 0202 { 0203 if (type != m_type) 0204 m_dirty = true; 0205 m_type = type; 0206 } 0207 bool isVideo() const; 0208 0209 void createFolderCategoryItem(DB::CategoryPtr, DB::MemberMap &memberMap); 0210 0211 void copyExtraData(const ImageInfo &from, bool copyAngle = true); 0212 void removeExtraData(); 0213 /** 0214 * Merge another ImageInfo into this one. 0215 * The other ImageInfo is not altered in any way or removed. 0216 */ 0217 void merge(const ImageInfo &other); 0218 0219 TaggedAreas taggedAreas() const; 0220 /** 0221 * Return the area associated with a tag. 0222 * @param category the category name 0223 * @param tag the tag name 0224 * @return the associated area, or <code>QRect()</code> if no association exists. 0225 */ 0226 QRect areaForTag(QString category, QString tag) const; 0227 void setIsMatched(bool isMatched); 0228 bool isMatched() const; 0229 void setMatchGeneration(int matchGeneration); 0230 int matchGeneration() const; 0231 #ifdef HAVE_MARBLE 0232 Map::GeoCoordinates coordinates() const; 0233 #endif 0234 0235 protected: 0236 void setIsNull(bool b) 0237 { 0238 m_null = b; 0239 } 0240 bool isDirty() const 0241 { 0242 return m_dirty; 0243 } 0244 void markDirty(); 0245 bool updateDateInformation(int mode) const; 0246 0247 void setStackId(const StackID stackId); 0248 friend class XMLDB::Database; 0249 friend class DB::ImageDB; 0250 0251 private: 0252 DB::FileName m_fileName; 0253 QString m_label; 0254 QString m_description; 0255 ImageDate m_date; 0256 CategoryInformation m_categoryInfomation; 0257 TaggedAreas m_taggedAreas; 0258 int m_angle; 0259 enum OnDisk { YesOnDisk, 0260 NoNotOnDisk, 0261 Unchecked }; 0262 mutable OnDisk m_imageOnDisk = OnDisk::Unchecked; 0263 MD5 m_md5sum; 0264 bool m_null = true; 0265 QSize m_size; 0266 MediaType m_type; 0267 short m_rating; 0268 StackID m_stackId; 0269 unsigned int m_stackOrder; 0270 int m_videoLength; 0271 bool m_isMatched = false; 0272 int m_matchGeneration; 0273 #ifdef HAVE_MARBLE 0274 mutable Map::GeoCoordinates m_coordinates; 0275 mutable bool m_coordsIsSet = false; 0276 #endif 0277 0278 // Cache information 0279 bool m_locked = false; 0280 0281 // Will be set to true after every change 0282 bool m_dirty = false; 0283 }; 0284 } 0285 0286 #endif /* IMAGEINFO_H */ 0287 0288 // vi:expandtab:tabstop=4 shiftwidth=4: