File indexing completed on 2025-01-19 03:58:09

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2009-12-01
0007  * Description : An abstract base class for tiling of markers
0008  *
0009  * SPDX-FileCopyrightText: 2009-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2009-2011 by Michael G. Hansen <mike at mghansen dot de>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #ifndef DIGIKAM_ABSTRACT_MARKER_TILER_H
0017 #define DIGIKAM_ABSTRACT_MARKER_TILER_H
0018 
0019 // Qt includes
0020 
0021 #include <QBitArray>
0022 #include <QObject>
0023 #include <QPoint>
0024 
0025 // Local includes
0026 
0027 #include "tileindex.h"
0028 #include "geoifacetypes.h"
0029 #include "digikam_export.h"
0030 #include "geogroupstate.h"
0031 
0032 namespace Digikam
0033 {
0034 
0035 class DIGIKAM_EXPORT AbstractMarkerTiler : public QObject
0036 {
0037     Q_OBJECT
0038 
0039 public:
0040 
0041     enum TilerFlag
0042     {
0043         FlagNull    = 0,
0044         FlagMovable = 1
0045     };
0046 
0047     Q_DECLARE_FLAGS(TilerFlags, TilerFlag)
0048 
0049 public:
0050 
0051     class ClickInfo
0052     {
0053     public:
0054 
0055         TileIndex::List tileIndicesList;
0056         QVariant        representativeIndex;
0057         GeoGroupState   groupSelectionState;
0058         GeoMouseModes   currentMouseMode;
0059     };
0060 
0061 public:
0062 
0063     class Tile
0064     {
0065     public:
0066 
0067         explicit Tile();
0068         ~Tile();
0069 
0070     public:
0071 
0072         Tile* getChild(const int linearIndex);
0073 
0074         Tile* addChild(const int linearIndex, Tile* tilePointer);
0075 
0076         /**
0077          * @brief Sets the pointer to a child tile to zero and deletes the child.
0078          */
0079         void deleteChild(Tile* const childTile, const int knownLinearIndex = -1);
0080 
0081         bool childrenEmpty() const;
0082 
0083         /**
0084          * @brief returns the next non empty child index or -1.
0085          */
0086         int nextNonEmptyIndex(int linearIndex) const;
0087 
0088     private:
0089 
0090         // Disable
0091         Tile(const Tile&)            = delete;
0092         Tile& operator=(const Tile&) = delete;
0093 
0094     private:
0095 
0096         static int maxChildCount();
0097 
0098         void prepareForChildren();
0099 
0100     private:
0101 
0102         QVector<Tile*> children;
0103         QVector<int>   nonEmptyIndices;
0104     };
0105 
0106 public:
0107 
0108     class NonEmptyIterator
0109     {
0110     public:
0111 
0112         NonEmptyIterator(AbstractMarkerTiler* const model, const int level);
0113         NonEmptyIterator(AbstractMarkerTiler* const model, const int level, const TileIndex& startIndex, const TileIndex& endIndex);
0114         NonEmptyIterator(AbstractMarkerTiler* const model, const int level, const GeoCoordinates::PairList& normalizedMapBounds);
0115         ~NonEmptyIterator();
0116 
0117         bool                 atEnd()        const;
0118         TileIndex            nextIndex();
0119         TileIndex            currentIndex() const;
0120         AbstractMarkerTiler* model()        const;
0121 
0122     private:
0123 
0124         bool initializeNextBounds();
0125 
0126     private:
0127 
0128         // Disable
0129         NonEmptyIterator(const NonEmptyIterator&)            = delete;
0130         NonEmptyIterator& operator=(const NonEmptyIterator&) = delete;
0131 
0132     private:
0133 
0134         class Private;
0135         Private* const d;
0136     };
0137 
0138 public:
0139 
0140     explicit AbstractMarkerTiler(QObject* const parent = nullptr);
0141     ~AbstractMarkerTiler() override;
0142 
0143     /// these have to be implemented
0144     virtual TilerFlags tilerFlags() const;
0145     virtual Tile* tileNew()                                                                                 = 0;
0146     virtual void prepareTiles(const GeoCoordinates& upperLeft, const GeoCoordinates& lowerRight, int level) = 0;
0147     virtual void regenerateTiles()                                                                          = 0;
0148     virtual Tile* getTile(const TileIndex& tileIndex, const bool stopIfEmpty)                               = 0;
0149     virtual int getTileMarkerCount(const TileIndex& tileIndex)                                              = 0;
0150     virtual int getTileSelectedCount(const TileIndex& tileIndex)                                            = 0;
0151 
0152     /// these should be implemented for thumbnail handling
0153     virtual QVariant getTileRepresentativeMarker(const TileIndex& tileIndex, const int sortKey)             = 0;
0154     virtual QVariant bestRepresentativeIndexFromList(const QList<QVariant>& indices, const int sortKey)     = 0;
0155     virtual QPixmap pixmapFromRepresentativeIndex(const QVariant& index, const QSize& size)                 = 0;
0156     virtual bool indicesEqual(const QVariant& a, const QVariant& b) const                                   = 0;
0157     virtual GeoGroupState getTileGroupState(const TileIndex& tileIndex)                                     = 0;
0158     virtual GeoGroupState getGlobalGroupState()                                                             = 0;
0159 
0160     /// these can be implemented if you want to react to actions in geolocation interface
0161     virtual void onIndicesClicked(const ClickInfo& clickInfo);
0162     virtual void onIndicesMoved(const TileIndex::List& tileIndicesList, const GeoCoordinates& targetCoordinates,
0163                                 const QPersistentModelIndex& targetSnapIndex);
0164 
0165     virtual void setActive(const bool state)                                                                = 0;
0166     Tile* rootTile();
0167     bool indicesEqual(const QIntList& a, const QIntList& b, const int upToLevel) const;
0168     bool isDirty() const;
0169     void setDirty(const bool state = true);
0170     void resetRootTile();
0171 
0172 Q_SIGNALS:
0173 
0174     void signalTilesOrSelectionChanged();
0175     void signalThumbnailAvailableForIndex(const QVariant& index, const QPixmap& pixmap);
0176 
0177 private:
0178 
0179     class Private;
0180     Private* const d;
0181 };
0182 
0183 } // namespace Digikam
0184 
0185 Q_DECLARE_OPERATORS_FOR_FLAGS(Digikam::AbstractMarkerTiler::TilerFlags)
0186 
0187 #endif // DIGIKAM_ABSTRACT_MARKER_TILER_H