File indexing completed on 2025-01-05 03:53:55

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2008-09-09
0007  * Description : Hint data containers for the collection scanner
0008  *
0009  * SPDX-FileCopyrightText: 2008      by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0010  * SPDX-FileCopyrightText: 2009-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_COLLECTION_SCANNER_HINTS_H
0017 #define DIGIKAM_COLLECTION_SCANNER_HINTS_H
0018 
0019 #include "digikam_config.h"
0020 
0021 // Qt includes
0022 
0023 #include <QDateTime>
0024 #include <QList>
0025 #include <QStringList>
0026 
0027 #ifdef HAVE_DBUS
0028 #   include <QDBusArgument>
0029 #   include "dbenginedbusutils.h"
0030 #endif
0031 
0032 // Local includes
0033 
0034 #include "digikam_export.h"
0035 #include "digikam_globals.h"
0036 
0037 namespace Digikam
0038 {
0039 
0040 class AlbumCopyMoveHint;
0041 class CollectionLocation;
0042 class CollectionScannerObserver;
0043 class ItemInfo;
0044 class ItemCopyMoveHint;
0045 class ItemChangeHint;
0046 class ItemMetadataAdjustmentHint;
0047 
0048 class CollectionScannerHintContainer
0049 {
0050 public:
0051 
0052     /// Note: All methods of this class must be thread-safe.
0053 
0054     CollectionScannerHintContainer()                                 = default;
0055     virtual ~CollectionScannerHintContainer()                        = default;
0056 
0057     virtual void recordHints(const QList<AlbumCopyMoveHint>& hints)  = 0;
0058     virtual void recordHints(const QList<ItemCopyMoveHint>& hints)   = 0;
0059     virtual void recordHints(const QList<ItemChangeHint>& hints)     = 0;
0060     virtual void recordHint(const ItemMetadataAdjustmentHint& hints) = 0;
0061 
0062     virtual void clear()                                             = 0;
0063 
0064 private:
0065 
0066     Q_DISABLE_COPY(CollectionScannerHintContainer)
0067 };
0068 
0069 // ------------------------------------------------------------------------------
0070 
0071 namespace CollectionScannerHints
0072 {
0073 
0074 class DIGIKAM_DATABASE_EXPORT Album
0075 {
0076 public:
0077 
0078     Album();
0079     Album(int albumRootId, int albumId);
0080 
0081     bool isNull()                       const;
0082     QT_HASH_TYPE qHash()                const;
0083     bool operator==(const Album& other) const;
0084 
0085 public:
0086 
0087     int albumRootId;
0088     int albumId;
0089 };
0090 
0091 // ---------------------------------------------------------------------------
0092 
0093 class DIGIKAM_DATABASE_EXPORT DstPath
0094 {
0095 public:
0096 
0097     DstPath();
0098     DstPath(int albumRootId, const QString& relativePath);
0099 
0100     bool isNull()                         const;
0101     QT_HASH_TYPE qHash()                  const;
0102     bool operator==(const DstPath& other) const;
0103 
0104 public:
0105 
0106     int     albumRootId;
0107     QString relativePath;
0108 };
0109 
0110 // ---------------------------------------------------------------------------
0111 
0112 class DIGIKAM_DATABASE_EXPORT Item
0113 {
0114 public:
0115 
0116     Item();
0117     explicit Item(qlonglong id);
0118 
0119     bool isNull()                      const;
0120     QT_HASH_TYPE qHash()               const;
0121     bool operator==(const Item& other) const;
0122 
0123 public:
0124 
0125     qlonglong id;
0126 };
0127 
0128 inline QT_HASH_TYPE qHash(const Album& src)
0129 {
0130     return src.qHash();
0131 }
0132 
0133 inline QT_HASH_TYPE qHash(const DstPath& dst)
0134 {
0135     return dst.qHash();
0136 }
0137 
0138 inline QT_HASH_TYPE qHash(const Item& item)
0139 {
0140     return item.qHash();
0141 }
0142 
0143 } // namespace CollectionScannerHints
0144 
0145 // ---------------------------------------------------------------------------
0146 
0147 class DIGIKAM_DATABASE_EXPORT AlbumCopyMoveHint
0148 {
0149 public:
0150 
0151     /**
0152      * An AlbumCopyMoveHint describes an existing album
0153      * and a destination to which this album is expected to be
0154      * copied, moved or renamed.
0155      */
0156     AlbumCopyMoveHint();
0157     AlbumCopyMoveHint(int srcAlbumRootId, int srcAlbum,
0158                       int dstAlbumRootId, const QString& dstRelativePath);
0159 
0160     int albumRootIdSrc()                                          const;
0161     int albumIdSrc()                                              const;
0162     bool isSrcAlbum(int albumRootId, int albumId)                 const;
0163 
0164     CollectionScannerHints::Album src()                           const
0165     {
0166         return m_src;
0167     }
0168 
0169     int albumRootIdDst()                                          const;
0170     QString relativePathDst()                                     const;
0171     bool isDstAlbum(int albumRootId, const QString& relativePath) const;
0172 
0173     CollectionScannerHints::DstPath dst()                         const
0174     {
0175         return m_dst;
0176     }
0177 
0178     QT_HASH_TYPE qHash()                                          const;
0179 
0180     bool operator==(const CollectionScannerHints::Album& src)     const
0181     {
0182         return (src == m_src);
0183     }
0184 
0185     bool operator==(const CollectionScannerHints::DstPath& dst)   const
0186     {
0187         return (dst == m_dst);
0188     }
0189 
0190 #ifdef HAVE_DBUS
0191 
0192     AlbumCopyMoveHint& operator<<(const QDBusArgument& argument);
0193     const AlbumCopyMoveHint& operator>>(QDBusArgument& argument)  const;
0194 
0195 #endif
0196 
0197     operator const CollectionScannerHints::Album& ()              const
0198     {
0199         return m_src;
0200     }
0201 
0202     operator const CollectionScannerHints::DstPath& ()            const
0203     {
0204         return m_dst;
0205     }
0206 
0207 protected:
0208 
0209     CollectionScannerHints::Album   m_src;
0210     CollectionScannerHints::DstPath m_dst;
0211 };
0212 
0213 // ---------------------------------------------------------------------------
0214 
0215 class DIGIKAM_DATABASE_EXPORT ItemCopyMoveHint
0216 {
0217 public:
0218 
0219     /**
0220      * An ItemCopyMoveHint describes a list of existing items that will
0221      * be copied, moved or renamed to an album given by album root id and album id.
0222      * In the new album, the items will have the filenames given in dstNames.
0223      */
0224 
0225     ItemCopyMoveHint();
0226     ItemCopyMoveHint(const QList<qlonglong>& srcIds,
0227                      int dstAlbumRootId,
0228                      int albumId,
0229                      const QStringList& dstNames);
0230 
0231     QList<qlonglong> srcIds()                                   const;
0232     bool isSrcId(qlonglong id)                                  const;
0233     int albumRootIdDst()                                        const;
0234     int albumIdDst()                                            const;
0235     bool isDstAlbum(int albumRootId, int albumId)               const;
0236 
0237     CollectionScannerHints::Album dst()                         const
0238     {
0239         return m_dst;
0240     }
0241 
0242     QStringList dstNames()                                      const;
0243     QString dstName(qlonglong id)                               const;
0244 
0245     bool operator==(const CollectionScannerHints::Album& dst)   const
0246     {
0247         return (dst == m_dst);
0248     }
0249 
0250 #ifdef HAVE_DBUS
0251 
0252     ItemCopyMoveHint& operator<<(const QDBusArgument& argument);
0253     const ItemCopyMoveHint& operator>>(QDBusArgument& argument) const;
0254 
0255 #endif
0256 
0257     operator const CollectionScannerHints::Album& ()            const
0258     {
0259         return m_dst;
0260     }
0261 
0262 protected:
0263 
0264     QList<qlonglong>              m_srcIds;
0265     CollectionScannerHints::Album m_dst;
0266     QStringList                   m_dstNames;
0267 };
0268 
0269 // ---------------------------------------------------------------------------
0270 
0271 class DIGIKAM_DATABASE_EXPORT ItemChangeHint
0272 {
0273 public:
0274 
0275     /**
0276      * An ItemCopyMoveHint describes a list of existing items that
0277      * should be updated although the modification date may not have changed.
0278      */
0279 
0280     enum ChangeType
0281     {
0282         ItemModified, ///< treat as if modification date changed
0283         ItemRescan    ///< reread metadata
0284     };
0285 
0286 public:
0287 
0288     ItemChangeHint();
0289     explicit ItemChangeHint(const QList<qlonglong>& srcIds,
0290                             ChangeType type = ItemModified);
0291 
0292     QList<qlonglong> ids()                                      const;
0293     bool isId(qlonglong id)                                     const;
0294     ChangeType changeType()                                     const;
0295 
0296     bool isModified()                                           const
0297     {
0298         return (changeType() == ItemModified);
0299     }
0300 
0301     bool needsRescan()                                          const
0302     {
0303         return (changeType() == ItemRescan);
0304     }
0305 
0306 #ifdef HAVE_DBUS
0307 
0308     ItemChangeHint& operator<<(const QDBusArgument& argument);
0309     const ItemChangeHint& operator>>(QDBusArgument& argument)   const;
0310 
0311 #endif
0312 
0313 protected:
0314 
0315     QList<qlonglong>  m_ids;
0316     ChangeType        m_type;
0317 };
0318 
0319 // ---------------------------------------------------------------------------
0320 
0321 class DIGIKAM_DATABASE_EXPORT ItemMetadataAdjustmentHint
0322 {
0323 public:
0324 
0325     /**
0326      * The file's has been edited writing out information from
0327      * the database, i.e., the db is already guaranteed to contain
0328      * all changed information in the file's metadata.
0329      * There is no need for a full rescan, optimizations are possible.
0330      */
0331 
0332     enum AdjustmentStatus
0333     {
0334         AboutToEditMetadata,       ///< The file is about to be edited. Suspends scanning. The Finished hint must follow.
0335         MetadataEditingFinished,   ///< The file's metadata has been edited as described above.
0336         MetadataEditingAborted     ///< The file's metadata has not been edited, despite sending AboutToEditMedata
0337     };
0338 
0339 public:
0340 
0341     ItemMetadataAdjustmentHint();
0342     explicit ItemMetadataAdjustmentHint(qlonglong id,
0343                                         AdjustmentStatus status,
0344                                         const QDateTime& modificationDateOnDisk,
0345                                         qlonglong fileSize);
0346 
0347     qlonglong id()                                                          const;
0348     AdjustmentStatus adjustmentStatus()                                     const;
0349     QDateTime modificationDate()                                            const;
0350     qlonglong fileSize()                                                    const;
0351 
0352     bool isAboutToEdit()                                                    const
0353     {
0354         return (adjustmentStatus() == AboutToEditMetadata);
0355     }
0356 
0357     bool isEditingFinished()                                                const
0358     {
0359         return (adjustmentStatus() == MetadataEditingFinished);
0360     }
0361 
0362     bool isEditingFinishedAborted()                                         const
0363     {
0364         return (adjustmentStatus() == MetadataEditingAborted);
0365     }
0366 
0367 #ifdef HAVE_DBUS
0368 
0369     ItemMetadataAdjustmentHint& operator<<(const QDBusArgument& argument);
0370     const ItemMetadataAdjustmentHint& operator>>(QDBusArgument& argument)   const;
0371 
0372 #endif
0373 
0374 protected:
0375 
0376     qlonglong         m_id;
0377     AdjustmentStatus  m_status;
0378     QDateTime         m_modificationDate;
0379     qlonglong         m_fileSize;
0380 };
0381 
0382 inline QT_HASH_TYPE qHash(const Digikam::AlbumCopyMoveHint& hint)
0383 {
0384     return hint.qHash();
0385 }
0386 
0387 } // namespace Digikam
0388 
0389 #ifdef HAVE_DBUS
0390 
0391 DECLARE_METATYPE_FOR_DBUS(Digikam::AlbumCopyMoveHint)
0392 DECLARE_METATYPE_FOR_DBUS(Digikam::ItemCopyMoveHint)
0393 DECLARE_METATYPE_FOR_DBUS(Digikam::ItemChangeHint)
0394 
0395 #endif
0396 
0397 #endif // DIGIKAM_COLLECTION_SCANNER_HINTS_H