1 /* ============================================================
2  *
3  * This file is a part of digiKam project
4  * https://www.digikam.org
5  *
6  * Date        : 2005-04-21
7  * Description : Handling access to one item and associated data
8  *
9  * Copyright (C) 2005      by Renchi Raju <renchi dot raju at gmail dot com>
10  * Copyright (C) 2007-2013 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
11  * Copyright (C) 2009-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
12  * Copyright (C) 2013      by Michael G. Hansen <mike at mghansen dot de>
13  *
14  * This program is free software; you can redistribute it
15  * and/or modify it under the terms of the GNU General
16  * Public License as published by the Free Software Foundation;
17  * either version 2, or (at your option)
18  * any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * ============================================================ */
26 
27 #ifndef DIGIKAM_ITEM_INFO_H
28 #define DIGIKAM_ITEM_INFO_H
29 
30 // Qt includes
31 
32 #include <QUrl>
33 #include <QList>
34 #include <QSize>
35 #include <QString>
36 #include <QDateTime>
37 #include <QExplicitlySharedDataPointer>
38 
39 // Local includes
40 
41 #include "digikam_export.h"
42 #include "coredbalbuminfo.h"
43 #include "coredburl.h"
44 #include "coredbfields.h"
45 #include "iteminfolist.h"
46 
47 namespace Digikam
48 {
49 
50 class DImageHistory;
51 class HistoryImageId;
52 class ItemComments;
53 class ImageCommonContainer;
54 class ItemCopyright;
55 class ItemExtendedProperties;
56 class ItemInfoData;
57 class ItemListerRecord;
58 class ImageMetadataContainer;
59 class VideoMetadataContainer;
60 class ItemPosition;
61 class ItemTagPair;
62 class PhotoInfoContainer;
63 class VideoInfoContainer;
64 class Template;
65 class ThumbnailIdentifier;
66 class ThumbnailInfo;
67 
68 /**
69  * The ItemInfo class contains provides access to the database for a single image.
70  * The properties can be read and written. Information will be cached.
71  *
72  * NOTE: access rules for all methods in this class:
73  * ItemInfoData members shall be accessed only under CoreDbAccess lock.
74  * The id and albumId are the exception to this rule, as they are
75  * primitive and will never change during the lifetime of an object.
76  */
77 class DIGIKAM_DATABASE_EXPORT ItemInfo
78 {
79 public:
80 
81     typedef DatabaseFields::Hash<QVariant> DatabaseFieldsHashRaw;
82 
83 public:
84 
85     /**
86      * Constructor
87      * Creates a null image info
88      */
89     ItemInfo();
90 
91     /**
92      * Constructor. Creates an ItemInfo object without any cached data initially.
93      * @param ID the unique ID for this image
94      */
95     explicit ItemInfo(qlonglong ID);
96 
97     /**
98      * Constructor. Creates an ItemInfo object where the provided information
99      * will initially be available cached, without database access.
100      */
101     explicit ItemInfo(const ItemListerRecord& record);
102 
103     /**
104      * Copy constructor.
105      */
106     ItemInfo(const ItemInfo& info);
107 
108     /**
109      * Destructor
110      */
111     ~ItemInfo();
112 
113     /**
114      * Creates an ItemInfo object from a file url.
115      */
116     static ItemInfo fromLocalFile(const QString& path);
117     static ItemInfo fromUrl(const QUrl& url);
118 
119     /**
120      * Create an ItemInfo object from the given combination, which
121      * must be cleaned and corresponding to the values in the database
122      */
123     static ItemInfo fromLocationAlbumAndName(int locationId, const QString& album, const QString& name);
124 
125     ItemInfo& operator=(const ItemInfo& info);
126 
127     bool operator==(const ItemInfo& info)                                               const;
128     bool operator!=(const ItemInfo& info)                                               const;
129     bool operator<(const ItemInfo& info)                                                const;
130 
131     /**
132      * Copy database information of this item to a newly created item
133      * @param  dstAlbumID  destination album id
134      * @param  dstFileName new filename
135      * @return an ItemInfo object of the new item
136      */
137     ItemInfo copyItem(int dstAlbumID, const QString& dstFileName);
138 
139     /**
140      * Returns true if this is a valid ItemInfo,
141      * and the location of the image is currently available
142      * (information freshly obtained from CollectionManager)
143      */
144     bool isLocationAvailable()                                                          const;
145 
146 public:
147 
148     // -----------------------------------------------------------------------------
149 
150     /** @name Operations with Properties
151      */
152 
153     //@{
154 
155     /**
156      * Returns if this objects contains valid data
157      */
158     bool isNull()                                                                       const;
159 
160     /**
161      * @return the name of the image
162      */
163     QString name()                                                                      const;
164 
165     /**
166      * @return the datetime of the image
167      */
168     QDateTime dateTime()                                                                const;
169 
170     /**
171      * @return the modification datetime of the image
172      */
173     QDateTime modDateTime()                                                             const;
174 
175     /**
176      * @return the filesize of the image
177      */
178     qlonglong fileSize()                                                                const;
179 
180     /**
181      * @return the dimensions of the image (valid only if dimensions
182      * have been requested)
183      */
184     QSize dimensions()                                                                  const;
185 
186     /**
187      * Returns the file:// url.
188      * This is equivalent to QUrl::fromLocalFile(filePath())
189      */
190     QUrl fileUrl()                                                                      const;
191 
192     /**
193      * Returns the file path to the image
194      */
195     QString filePath()                                                                  const;
196 
197     /**
198      * @return the unique image id for this item
199      */
200     qlonglong id()                                                                      const;
201 
202     /**
203      * @return the id of the PAlbum to which this item belongs
204      */
205     int albumId()                                                                       const;
206 
207     /**
208      * The album root id
209      */
210     int albumRootId()                                                                   const;
211 
212     /**
213      * @return the id of the Aspect Ratio for this item
214      */
215     double aspectRatio()                                                                const;
216 
217     /**
218      * Returns the manual sort order
219      */
220     qlonglong manualOrder()                                                             const;
221 
222     /**
223      * Returns the category of the item: Image, Audio, Video
224      */
225     DatabaseItem::Category category()                                                   const;
226 
227     /**
228      * Returns the image format / mimetype as a standardized
229      * string (see project/documents/DBSCHEMA.ODS).
230      */
231     QString format()                                                                    const;
232 
233     /**
234      * Returns true if the image is marked as visible in the database.
235      */
236     bool isVisible()                                                                    const;
237 
238     /**
239      * Returns true if the corresponding file was not deleted.
240      */
241     bool isRemoved()                                                                    const;
242 
243     /**
244      * Returns the orientation of the image,
245      * (MetaEngine::ImageOrientation, EXIF standard)
246      */
247     int orientation()                                                                   const;
248 
249     /**
250      * @return the default title for this item
251      */
252     QString title()                                                                     const;
253 
254     /**
255      * @return the default comment for this item
256      */
257     QString comment()                                                                   const;
258 
259     /**
260      * @return the number of Unconfirmed Faces in this item.
261      */
262     int unconfirmedFaceCount()                                                          const;
263 
264     /**
265      * @return the map of Tag Region (in XML form) to Suggested Names for all
266      * Faces in the Image.
267      * Used to categorize images based on Face Suggestions.
268      */
269     QMap<QString, QString> getSuggestedNames()                                          const;
270 
271     /**
272      * Set the name (write it to database)
273      * @param newName the new name.
274      */
275     void setName(const QString& newName);
276 
277     /**
278      * Set the date and time (write it to database)
279      * @param dateTime the new date and time.
280      */
281     void setDateTime(const QDateTime& dateTime);
282 
283     /**
284      * Set the modification date and time (write it to database)
285      * @param dateTime the new modification date and time.
286      */
287     void setModDateTime(const QDateTime& dateTime);
288 
289     /**
290      * Set the manual sorting order for the item
291      */
292     void setManualOrder(qlonglong value);
293 
294     /**
295      * Set the orientation for the item
296      */
297     void setOrientation(int value);
298 
299     /**
300      * Set the visibility flag - triggers between Visible and Hidden
301      */
302     void setVisible(bool isVisible);
303 
304     /**
305      * @todo Supports only VideoMetadataField and ImageMetadataField values for now.
306      */
307     DatabaseFieldsHashRaw getDatabaseFieldsRaw(const DatabaseFields::Set& requestedSet) const;
308     QVariant getDatabaseFieldRaw(const DatabaseFields::Set& requestedField)             const;
309 
310     //@}
311 
312 public:
313 
314     // -----------------------------------------------------------------------------
315 
316     /** @name Operations with Geolocation
317      */
318 
319     //@{
320 
321     /**
322      * Retrieve the ItemPosition object for this item.
323      */
324     ItemPosition imagePosition()                                                        const;
325 
326     /**
327      * Retrieves the coordinates and the altitude.
328      * Returns 0 if hasCoordinates(), or hasAltitude resp, is false.
329      */
330     double longitudeNumber()                                                            const;
331     double latitudeNumber()                                                             const;
332     double altitudeNumber()                                                             const;
333     bool   hasCoordinates()                                                             const;
334     bool   hasAltitude()                                                                const;
335 
336     //@}
337 
338 public:
339 
340     // -----------------------------------------------------------------------------
341 
342     /** @name Operations with History
343      */
344 
345     //@{
346 
347     /**
348      * Retrieves and sets the image history from the database.
349      * Note: The image history retrieved here does typically include all
350      * steps from the original to this image, but does not reference this image
351      * itself.
352      */
353     DImageHistory imageHistory()                                                        const;
354     void setItemHistory(const DImageHistory& history);
355     bool hasImageHistory()                                                              const;
356 
357     /**
358      * Retrieves and sets this' images UUID
359      */
360     QString uuid()                                                                      const;
361     void setUuid(const QString& uuid);
362 
363     /**
364      * Constructs a HistoryImageId with all available information for this image.
365      */
366     HistoryImageId historyImageId()                                                     const;
367 
368     /**
369      * Retrieve information about images from which this image
370      * is derived (ancestorImages) and images that have been derived
371      * from this images (derivedImages).
372      */
373     bool hasDerivedImages()                                                             const;
374     bool hasAncestorImages()                                                            const;
375 
376     QList<ItemInfo> derivedImages()                                                     const;
377     QList<ItemInfo> ancestorImages()                                                    const;
378 
379     /**
380      * Returns the cloud of all directly or indirectly related images,
381      * derived images or ancestors, in from of "a derived from b" pairs.
382      */
383     QList<QPair<qlonglong, qlonglong> > relationCloud()                                 const;
384 
385     /**
386      * Add a relation to the database:
387      * This image is derived from the ancestorImage.
388      */
389     void markDerivedFrom(const ItemInfo& ancestorImage);
390 
391     //@}
392 
393 public:
394 
395     // -----------------------------------------------------------------------------
396 
397     /** @name Operations with Groups
398      */
399 
400     //@{
401 
402     /**
403      * The image is grouped in the group of another (leading) image.
404      */
405     bool isGrouped()                                                                    const;
406     /**
407      * The image is the leading image of a group,
408      * there are other images grouped behind this one.
409      */
410     bool hasGroupedImages()                                                             const;
411     int  numberOfGroupedImages()                                                        const;
412 
413     /**
414      * Returns the leading image of the group.
415      * Returns a null image if this image is not grouped (isGrouped())
416      */
417     ItemInfo groupImage()                                                               const;
418     qlonglong groupImageId()                                                            const;
419 
420     /**
421      * Returns the list of images grouped behind this image (not including this
422      * image itself) and an empty list if there is none.
423      */
424     QList<ItemInfo> groupedImages()                                                     const;
425 
426     /**
427      * Group this image behind the given image
428      */
429     void addToGroup(const ItemInfo& info);
430 
431     /**
432      * This image is grouped behind another image:
433      * Remove this image from its group
434      */
435     void removeFromGroup();
436 
437     /**
438      * This image hasGroupedImages(): Split up the group,
439      * remove all groupedImages() from this image's group.
440      */
441     void clearGroup();
442 
443     //@}
444 
445 public:
446 
447     // -----------------------------------------------------------------------------
448 
449     /** @name Operations with Containers
450      */
451 
452     //@{
453 
454     /**
455      * Retrieve information about the image,
456      * in form of numbers and user presentable strings,
457      * for certain defined fields of information (see databaseinfocontainers.h)
458      */
459     ImageCommonContainer   imageCommonContainer()                                       const;
460     ImageMetadataContainer imageMetadataContainer()                                     const;
461     VideoMetadataContainer videoMetadataContainer()                                     const;
462     PhotoInfoContainer     photoInfoContainer()                                         const;
463     VideoInfoContainer     videoInfoContainer()                                         const;
464 
465     /**
466      * Retrieve metadata template information about the image.
467      */
468     Template metadataTemplate()                                                         const;
469 
470     /**
471      * Set metadata template information (write it to database)
472      * @param t the new template data.
473      */
474     void setMetadataTemplate(const Template& t);
475 
476     /**
477      * Remove all template info about the image from database.
478      */
479     void removeMetadataTemplate();
480 
481     /**
482      * Retrieve the ItemComments object for this item.
483      * This object allows full read and write access to all comments
484      * and their properties.
485      * You need to hold CoreDbAccess to ensure the validity.
486      * For simple, cached read access see comment().
487      */
488     ItemComments imageComments(CoreDbAccess& access)                                    const;
489 
490     /**
491      * Retrieve the ItemCopyright object for this item.
492      * This object allows full read and write access to all copyright
493      * values.
494      */
495     ItemCopyright imageCopyright()                                                      const;
496 
497     /**
498      * Retrieve the ItemExtendedProperties object for this item.
499      * This object allows full read and write access to all extended properties
500      * values.
501      */
502     ItemExtendedProperties imageExtendedProperties()                                    const;
503 
504     //@}
505 
506 public:
507 
508     // -----------------------------------------------------------------------------
509 
510     /** @name Operations with Tags
511      */
512 
513     //@{
514 
515     /**
516      * Adds a tag to the item (writes it to database)
517      * @param tagID the ID of the tag to add
518      */
519     void setTag(int tagID);
520 
521     /**
522      * Adds tags in the list to the item.
523      * Tags are created if they do not yet exist
524      */
525     void addTagPaths(const QStringList& tagPaths);
526 
527     /**
528      * Remove a tag from the item (removes it from database)
529      * @param tagID the ID of the tag to remove
530      */
531     void removeTag(int tagID);
532 
533     /**
534      * Remove all tags from the item (removes it from database)
535      */
536     void removeAllTags();
537 
538     /**
539      * Retrieve an ItemTagPair object for a single tag, or for all
540      * image/tag pairs for which properties are available
541      * (not necessarily the assigned tags)
542      */
543     ItemTagPair imageTagPair(int tagId)                                                 const;
544     QList<ItemTagPair> availableItemTagPairs()                                          const;
545 
546     /**
547      * @return a list of IDs of tags assigned to this item
548      * @see tagNames
549      * @see tagPaths
550      * @see Album::id()
551      */
552     QList<int> tagIds()                                                                 const;
553 
554 private:
555 
556     void loadTagIds()                                                                   const;
557 
558     //@}
559 
560 public:
561 
562     // -----------------------------------------------------------------------------
563 
564     /**
565      * @name Operations with Labels
566      */
567 
568     //@{
569 
570     /**
571      * Returns the Pick Label Id (see PickLabel values in globals.h)
572      */
573     int pickLabel()                                                                     const;
574 
575     /**
576      * Returns the Color Label Id (see ColorLabel values in globals.h)
577      */
578     int colorLabel()                                                                    const;
579 
580     /**
581      * Returns the rating
582      */
583     int rating()                                                                        const;
584 
585     /**
586      * Set the pick Label Id for the item (see PickLabel values from globals.h)
587      */
588     void setPickLabel(int value);
589 
590     /**
591      * Set the color Label Id for the item (see ColorLabel values from globals.h)
592      */
593     void setColorLabel(int value);
594 
595     /**
596      * Set the rating for the item
597      */
598     void setRating(int value);
599 
600     //@}
601 
602 public:
603 
604     // -----------------------------------------------------------------------------
605 
606     /**
607      * @name Operations with Thumbnails
608      */
609 
610     //@{
611 
612     /**
613      * Fills a ThumbnailIdentifier / ThumbnailInfo from this ItemInfo
614      */
615     ThumbnailIdentifier thumbnailIdentifier()                                           const;
616     ThumbnailInfo thumbnailInfo()                                                       const;
617     static ThumbnailIdentifier thumbnailIdentifier(qlonglong id);
618 
619     //@}
620 
621 public:
622 
623     // -----------------------------------------------------------------------------
624 
625     /**
626      * @name Operations with Similarity
627      */
628 
629     //@{
630 
631     double similarityTo(const qlonglong imageId)                                        const;
632     double currentSimilarity()                                                          const;
633 
634     /**
635      * Returns the id of the current fuzzy search reference image.
636      */
637     qlonglong currentReferenceImage()                                                   const;
638 
639     /**
640      * Return a signature for the item.
641      */
642     uint hash()                                                                         const;
643 
644     /**
645      * Scans the database for items with the given signature.
646      */
647     QList<ItemInfo> fromUniqueHash(const QString& uniqueHash, qlonglong fileSize);
648 
649     /**
650      * @return the unique hash signature as string of the image.
651      */
652     QString uniqueHash()                                                                const;
653 
654     //@}
655 
656 private:
657 
658     friend class ItemInfoCache;
659     friend class ItemInfoList;
660 
661     QExplicitlySharedDataPointer<ItemInfoData> m_data;
662 };
663 
qHash(const ItemInfo & info)664 inline uint qHash(const ItemInfo& info)
665 {
666     return info.hash();
667 }
668 
669 //! qDebug() stream operator. Writes property @a info to the debug output in a nicely formatted way.
670 DIGIKAM_DATABASE_EXPORT QDebug operator<<(QDebug stream, const ItemInfo& info);
671 
672 } // namespace Digikam
673 
674 Q_DECLARE_TYPEINFO(Digikam::ItemInfo, Q_MOVABLE_TYPE);
675 Q_DECLARE_METATYPE(Digikam::ItemInfo)
676 
677 #endif // DIGIKAM_ITEM_INFO_H
678