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

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2010-06-02
0007  * Description : class for manipulating modifications changeset for non-destruct. editing
0008  *
0009  * SPDX-FileCopyrightText: 2010 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0010  * SPDX-FileCopyrightText: 2010 by Martin Klapetek <martin dot klapetek at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #ifndef DIGIKAM_DIMAGE_HISTORY_H
0017 #define DIGIKAM_DIMAGE_HISTORY_H
0018 
0019 // Qt includes
0020 
0021 #include <QXmlStreamWriter>
0022 #include <QXmlStreamReader>
0023 #include <QHash>
0024 #include <QList>
0025 #include <QMetaType>
0026 #include <QSharedDataPointer>
0027 #include <QString>
0028 #include <QVariant>
0029 
0030 // Local includes
0031 
0032 #include "digikam_export.h"
0033 #include "filteraction.h"
0034 #include "historyimageid.h"
0035 
0036 namespace Digikam
0037 {
0038 
0039 class DIGIKAM_EXPORT DImageHistory
0040 {
0041 public:
0042 
0043     class Entry
0044     {
0045     public:
0046 
0047         /**
0048          * A DImageHistory is a list of entries.
0049          *
0050          * Each entry has one action. The action can be null,
0051          * but it shall be null only if it is the action of the first
0052          * entry, with the "Original" as referred image,
0053          * representing the action of digitization.
0054          *
0055          * There can be zero, one or any number
0056          * of referred images per entry.
0057          * A referred image is a file in the state after the action is applied.
0058          */
0059         FilterAction          action;
0060         QList<HistoryImageId> referredImages;
0061     };
0062 
0063 public:
0064 
0065     DImageHistory();
0066     DImageHistory(const DImageHistory& other);
0067     ~DImageHistory();
0068 
0069     DImageHistory& operator=(const DImageHistory& other);
0070 
0071     /**
0072      * A history is null if it is constructed with the default constructor
0073      */
0074     bool isNull()                                                           const;
0075 
0076     /**
0077      * A history is considered empty if there are no entries.
0078      */
0079     bool isEmpty()                                                          const;
0080 
0081     /**
0082      * A history is a valid history (telling something about the past),
0083      * if the history is not empty, and there is at least one
0084      * referred image other than the "Current" entry,
0085      * or there is a valid action.
0086      */
0087     bool isValid()                                                          const;
0088 
0089     /// Returns the number of entries
0090     int size()                                                              const;
0091 
0092     bool operator==(const DImageHistory& other)                             const;
0093 
0094     bool operator!=(const DImageHistory& other)                             const
0095     {
0096         return !operator==(other);
0097     }
0098 
0099     bool operator<(const DImageHistory& other)                              const;
0100     bool operator>(const DImageHistory& other)                              const;
0101 
0102     /**
0103      * Appends a new filter action to the history.
0104      */
0105     DImageHistory& operator<<(const FilterAction& action);
0106 
0107     /**
0108      * Appends a new referred image, representing the current state
0109      * of the history.
0110      * If you add an id of type Current, adjustReferredImages() will be called.
0111      */
0112     DImageHistory& operator<<(const HistoryImageId& imageId);
0113 
0114     void appendReferredImage(const HistoryImageId& id);
0115     void insertReferredImage(int entryIndex, const HistoryImageId& id);
0116 
0117     /// Removes the last entry from the history
0118     void removeLast();
0119 
0120     /**
0121      * Access entries.
0122      * There are size() entries.
0123      */
0124     QList<DImageHistory::Entry>&       entries();
0125     const QList<DImageHistory::Entry>& entries()                            const;
0126     Entry&                             operator[](int i);
0127     const Entry&                       operator[](int i)                    const;
0128 
0129     /**
0130      * Access actions.
0131      *
0132      * There is one action per entry,
0133      * but the action may be null.
0134      */
0135 
0136     /// Returns if there is any non-null action
0137     bool hasActions()                                                       const;
0138     bool hasFilters()                                                       const
0139     {
0140         return hasActions();
0141     }
0142 
0143     /// Returns the number of non-null actions
0144     int actionCount()                                                       const;
0145 
0146     /// Gets all actions which are not null
0147     QList<FilterAction> allActions()                                        const;
0148     const FilterAction& action(int i)                                       const;
0149 
0150     /**
0151      * Access referred images
0152      */
0153     QList<HistoryImageId>& referredImages(int i);
0154     const QList<HistoryImageId>& referredImages(int i)                      const;
0155     QList<HistoryImageId> allReferredImages()                               const;
0156     HistoryImageId currentReferredImage()                                   const;
0157     HistoryImageId originalReferredImage()                                  const;
0158     QList<HistoryImageId> referredImagesOfType(HistoryImageId::Type type)   const;
0159     bool hasReferredImages()                                                const;
0160     bool hasReferredImageOfType(HistoryImageId::Type type)                  const;
0161     bool hasCurrentReferredImage()                                          const;
0162     bool hasOriginalReferredImage()                                         const;
0163 
0164     /**
0165      * Edit referred images
0166      */
0167 
0168     /// Remove all referredImages, leaving the entries list untouched
0169     void clearReferredImages();
0170 
0171     /**
0172      * Adjusts the type of a Current HistoryImageId:
0173      * If it is the first entry, it becomes Original,
0174      * if it is in an intermediate entry, it becomes Intermediate,
0175      * if in the last entry, it stays current.
0176      */
0177     void adjustReferredImages();
0178 
0179     /// Changes the UUID of the current (last added current) referred image
0180     void adjustCurrentUuid(const QString& uuid);
0181 
0182     /**
0183      * Remove file path entries pointing to the given absolute path
0184      * from any referred images. This is useful when said file
0185      * is about to be overwritten.
0186      * All other HistoryImageId fields remain unchanged, no HistoryImageId is removed.
0187      * path: directory path, without filename.
0188      */
0189     void purgePathFromReferredImages(const QString& path, const QString& fileName);
0190 
0191     /**
0192      * Change file path entries of the current referred image
0193      */
0194     void moveCurrentReferredImage(const QString& newPath, const QString& newFileName);
0195 
0196     /**
0197      * Serialize toand from XML.
0198      *
0199      * Note: The "Current" entry is skipped when writing to XML,
0200      * so make sure the file into the metadata of which you write the XML,
0201      * is the file marked as "Current" in this history.
0202      */
0203     QString toXml()                                                         const;
0204     static DImageHistory fromXml(const QString& xml);
0205 
0206 public:
0207 
0208     /// Set as public there because of PrivateSharedNull
0209     class Private;
0210 
0211 private:
0212 
0213     QSharedDataPointer<Private> d;
0214 };
0215 
0216 } // namespace Digikam
0217 
0218 Q_DECLARE_METATYPE(Digikam::DImageHistory)
0219 
0220 #endif // DIGIKAM_DIMAGE_HISTORY_H