File indexing completed on 2025-01-19 03:53:35

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2010-10-23
0007  * Description : Graph data class for item history
0008  *
0009  * SPDX-FileCopyrightText: 2010-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #ifndef DIGIKAM_ITEM_HISTORY_GRAPH_H
0016 #define DIGIKAM_ITEM_HISTORY_GRAPH_H
0017 
0018 // Qt includes
0019 
0020 #include <QFlags>
0021 #include <QSharedDataPointer>
0022 #include <QDebug>
0023 
0024 // Local includes
0025 
0026 #include "iteminfo.h"
0027 #include "historyimageid.h"
0028 #include "digikam_export.h"
0029 
0030 namespace Digikam
0031 {
0032 
0033 class ItemHistoryGraphData;
0034 class DImageHistory;
0035 
0036 class DIGIKAM_DATABASE_EXPORT ItemHistoryGraph
0037 {
0038 public:
0039 
0040     enum HistoryLoadingFlag
0041     {
0042         /// Load the relation cloud to the graph. Will give all edges, but no further info
0043         LoadRelationCloud  = 1 << 0,
0044 
0045         /// Will load the DImageHistory of the given subject
0046         LoadSubjectHistory = 1 << 1,
0047 
0048         /// Will load the DImageHistory of all leave vertices of the graph
0049         LoadLeavesHistory  = 1 << 2,
0050 
0051         LoadAll            = LoadRelationCloud | LoadSubjectHistory | LoadLeavesHistory
0052     };
0053     Q_DECLARE_FLAGS(HistoryLoadingMode, HistoryLoadingFlag)
0054 
0055     enum ProcessingMode
0056     {
0057         NoProcessing,
0058         PrepareForDisplay
0059     };
0060 
0061 public:
0062 
0063     ItemHistoryGraph();
0064     ItemHistoryGraph(const ItemHistoryGraph& other);
0065     ~ItemHistoryGraph();
0066 
0067     ItemHistoryGraph& operator=(const ItemHistoryGraph& other);
0068 
0069     bool isNull()                                                       const;
0070     bool isEmpty()                                                      const;
0071     bool isSingleVertex()                                               const;
0072 
0073     /**
0074      * Returns if the graph contains any edges. Because loops are not allowed,
0075      * this also means (!isEmpty() && !isSingleVertex()).
0076      */
0077     bool hasEdges()                                                     const;
0078 
0079     ItemHistoryGraphData& data();
0080     const ItemHistoryGraphData& data()                                  const;
0081 
0082     /**
0083      * Convenience: Reads all available history for the given info from the database
0084      * and returns the created graph.
0085      * Depending on mode, the graph will be preparedForDisplay().
0086      * If no history is recorded and no relations found, a single-vertex graph is returned.
0087      */
0088     static ItemHistoryGraph fromInfo(const ItemInfo& info,
0089                                       HistoryLoadingMode loadingMode = LoadAll,
0090                                       ProcessingMode processingMode  = PrepareForDisplay);
0091 
0092     /**
0093      * Add the given history.
0094      * The optionally given info or id is used as the "current" image of the history.
0095      * If you read a history from a file's metadata or the database, you shall give the
0096      * relevant subject.
0097      */
0098     void addHistory(const DImageHistory& history, const ItemInfo& historySubject = ItemInfo());
0099     void addHistory(const DImageHistory& history, const HistoryImageId& historySubject = HistoryImageId());
0100 
0101     /**
0102      * This is very similar to addHistory. The only difference is that
0103      * no attempt is made to retrieve an ItemInfo for the historySubjectId.
0104      * Can be useful in the context of scanning
0105      */
0106     void addScannedHistory(const DImageHistory& history, qlonglong historySubjectId);
0107 
0108     /**
0109      * Add images and their relations from the given pairs.
0110      * Each pair (a,b) means "a is derived from b".
0111      */
0112     void addRelations(const QList<QPair<qlonglong, qlonglong> >& pairs);
0113 
0114     /**
0115      * Clears this graph.
0116      */
0117     void clear();
0118 
0119     /**
0120      * Remove edges which provide only duplicate information
0121      * (performs a transitive reduction).
0122      * Especially call this when addRelations() was used.
0123      */
0124     void reduceEdges();
0125 
0126     /**
0127      * Returns true if for any entry no ItemInfo could be located.
0128      */
0129     bool hasUnresolvedEntries()                                         const;
0130 
0131     /**
0132      * Remove all vertices from the graph for which no existing ItemInfo
0133      * could be found in the database
0134      */
0135     void dropUnresolvedEntries();
0136 
0137     /**
0138      * Sort vertex information prioritizing for the given vertex
0139      */
0140     void sortForInfo(const ItemInfo& subject);
0141 
0142     /**
0143      * Combines reduceEdges(), dropOrphans() and sortForInfo()
0144      */
0145     void prepareForDisplay(const ItemInfo& subject);
0146 
0147     /**
0148      * Returns all possible relations between images in this graph,
0149      * the edges of the transitive closure.
0150      * The first variant returns (1,2),(3,4),(6,8), the second (1,3,6)(2,4,8).
0151      */
0152     QList<QPair<qlonglong, qlonglong> > relationCloud()                 const;
0153     QPair<QList<qlonglong>, QList<qlonglong> > relationCloudParallel()  const;
0154 
0155     /**
0156      * Returns image infos / ids from all vertices in this graph
0157      */
0158     QList<ItemInfo> allImages()                                         const;
0159     QList<qlonglong> allImageIds()                                      const;
0160 
0161     /**
0162      * Returns image infos / ids from all root vertices in this graph,
0163      * i.e. vertices with no precedent history.
0164      */
0165     QList<ItemInfo> rootImages()                                        const;
0166 
0167     /**
0168      * Returns image infos / ids from all leaf vertices in this graph,
0169      * i.e. vertices with no subsequent history.
0170      */
0171     QList<ItemInfo> leafImages()                                        const;
0172 
0173     /**
0174      * Attempts at a categorization of all images in the graph
0175      * into the types defined by HistoryImageId.
0176      * The type will be invalid if no decision can be made due to conflicting data.
0177      */
0178     QHash<ItemInfo, HistoryImageId::Types> categorize()                 const;
0179 
0180 private:
0181 
0182     QSharedDataPointer<ItemHistoryGraphData> d;
0183 };
0184 
0185 QDebug DIGIKAM_DATABASE_EXPORT operator<<(QDebug dbg, const ItemHistoryGraph& g);
0186 
0187 } // namespace Digikam
0188 
0189 Q_DECLARE_OPERATORS_FOR_FLAGS(Digikam::ItemHistoryGraph::HistoryLoadingMode)
0190 
0191 #endif // DIGIKAM_ITEM_HISTORY_GRAPH_H