1 /* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2010-07-14
7 * Description : Common internal data structures for geolocation interface
8 *
9 * Copyright (C) 2010-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
10 * Copyright (C) 2010-2014 by Michael G. Hansen <mike at mghansen dot de>
11 * Copyright (C) 2014 by Justus Schwartz <justus at gmx dot li>
12 *
13 * This program is free software; you can redistribute it
14 * and/or modify it under the terms of the GNU General
15 * Public License as published by the Free Software Foundation;
16 * either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * ============================================================ */
25
26 #ifndef DIGIKAM_GEO_IFACE_COMMON_H
27 #define DIGIKAM_GEO_IFACE_COMMON_H
28
29 // Qt includes
30
31 #include <QFlags>
32 #include <QPoint>
33 #include <QPointer>
34 #include <QSharedData>
35 #include <QSize>
36 #include <QWidget>
37 #include <QPixmap>
38
39 // Local includes
40
41 #include "geoifacetypes.h"
42 #include "tileindex.h"
43 #include "groupstatecomputer.h"
44 #include "digikam_export.h"
45
46 namespace Digikam
47 {
48 class MapWidget;
49 class AbstractMarkerTiler;
50 class TileGrouper;
51 class TrackManager;
52 class MapBackend;
53 class GeoModelHelper;
54
55 /**
56 * @brief Class to hold information about map widgets stored in the GeoIfaceGlobalObject
57 *
58 * @todo The list of these info structures has to be cleaned up periodically
59 */
60 class DIGIKAM_EXPORT GeoIfaceInternalWidgetInfo
61 {
62 public:
63
64 typedef void (*DeleteFunction)(GeoIfaceInternalWidgetInfo* const info);
65
66 enum InternalWidgetState
67 {
68 InternalWidgetReleased = 1,
69 InternalWidgetUndocked = 2,
70 InternalWidgetStillDocked = 4
71 };
72
73 // cppcheck-suppress unknownMacro
Q_DECLARE_FLAGS(InternalWidgetStates,InternalWidgetState)74 Q_DECLARE_FLAGS(InternalWidgetStates, InternalWidgetState)
75
76 GeoIfaceInternalWidgetInfo()
77 : state (),
78 widget (),
79 backendData (),
80 backendName (),
81 currentOwner (nullptr),
82 deleteFunction(nullptr)
83 {
84 }
85
86 public:
87
88 InternalWidgetStates state;
89 QPointer<QWidget> widget;
90 QVariant backendData;
91 QString backendName;
92 QPointer<QObject> currentOwner;
93 DeleteFunction deleteFunction;
94 };
95
Q_DECLARE_OPERATORS_FOR_FLAGS(GeoIfaceInternalWidgetInfo::InternalWidgetStates)96 Q_DECLARE_OPERATORS_FOR_FLAGS(GeoIfaceInternalWidgetInfo::InternalWidgetStates)
97
98 // ----------------------------------------------------------------------------------------------
99
100 /**
101 * @brief Global object for geolocation interface to hold items common to all
102 * geolocation interface Widget instances
103 */
104 class DIGIKAM_EXPORT GeoIfaceGlobalObject : public QObject
105 {
106 Q_OBJECT
107
108 public:
109
110 static GeoIfaceGlobalObject* instance();
111
112 /// @name Shared pixmaps
113 //@{
114 QPixmap getMarkerPixmap(const QString& pixmapId);
115 QPixmap getStandardMarkerPixmap();
116 QUrl locateDataFile(const QString& filename);
117 //@}
118
119 /// @name Shared internal map widgets
120 //@{
121 void removeMyInternalWidgetFromPool(const MapBackend* const mapBackend);
122 bool getInternalWidgetFromPool(const MapBackend* const mapBackend, GeoIfaceInternalWidgetInfo* const targetInfo);
123 void addMyInternalWidgetToPool(const GeoIfaceInternalWidgetInfo& info);
124 void updatePooledWidgetState(const QWidget* const widget, const GeoIfaceInternalWidgetInfo::InternalWidgetState newState);
125 void clearWidgetPool();
126 //@}
127
128 private:
129
130 // Disable
131 explicit GeoIfaceGlobalObject(QObject*) = delete;
132 GeoIfaceGlobalObject();
133 ~GeoIfaceGlobalObject() override;
134
135 Q_DISABLE_COPY(GeoIfaceGlobalObject)
136
137 private:
138
139 class Private;
140 Private* const d;
141
142 friend class GeoIfaceGlobalObjectCreator;
143 };
144
145 // ----------------------------------------------------------------------------------------------
146
147 class DIGIKAM_EXPORT GeoIfaceCluster
148 {
149
150 public:
151
152 enum PixmapType
153 {
154 PixmapMarker,
155 PixmapCircle,
156 PixmapImage
157 } pixmapType;
158
159 typedef QList<GeoIfaceCluster> List;
160
161 public:
162
GeoIfaceCluster()163 GeoIfaceCluster()
164 : pixmapType (PixmapMarker),
165 tileIndicesList (),
166 markerCount (0),
167 markerSelectedCount (0),
168 coordinates (),
169 pixelPos (),
170 groupState (SelectedNone),
171 representativeMarkers (),
172 pixmapSize (),
173 pixmapOffset ()
174 {
175 }
176
177 QList<TileIndex> tileIndicesList;
178 int markerCount;
179 int markerSelectedCount;
180 GeoCoordinates coordinates;
181 QPoint pixelPos;
182 GeoGroupState groupState;
183 QMap<int, QVariant> representativeMarkers;
184
185 QSize pixmapSize;
186
187 /// anchor point of the image, measured from bottom-left
188 QPoint pixmapOffset;
189 };
190
191 // ----------------------------------------------------------------------------------------------
192
193 /// @todo Move these somewhere else
194 const int GeoIfaceMinMarkerGroupingRadius = 1;
195 const int GeoIfaceMinThumbnailGroupingRadius = 15;
196 const int GeoIfaceMinThumbnailSize = GeoIfaceMinThumbnailGroupingRadius * 2;
197
198 // ----------------------------------------------------------------------------------------------
199
200 /**
201 * @brief Helper function, returns the square of the distance between two points
202 * @todo Move this function somewhere else
203 *
204 * @param a Point a
205 * @param b Point b
206 * @return Square of the distance between a and b
207 */
208 DIGIKAM_EXPORT int QPointSquareDistance(const QPoint& a, const QPoint& b);
209
210 // ----------------------------------------------------------------------------------------------
211
212 class DIGIKAM_EXPORT GeoIfaceSharedData : public QSharedData
213 {
214 public:
215
GeoIfaceSharedData()216 GeoIfaceSharedData()
217 : QSharedData (),
218 worldMapWidget (nullptr),
219 tileGrouper (nullptr),
220 markerModel (nullptr),
221 clusterList (),
222 trackManager (nullptr),
223 showThumbnails (true),
224 thumbnailSize (GeoIfaceMinThumbnailSize),
225 thumbnailGroupingRadius (GeoIfaceMinThumbnailGroupingRadius),
226 markerGroupingRadius (GeoIfaceMinMarkerGroupingRadius),
227 previewSingleItems (true),
228 previewGroupedItems (true),
229 showNumbersOnItems (true),
230 sortKey (0),
231 modificationsAllowed (true),
232 selectionRectangle (),
233 haveMovingCluster (false),
234 currentMouseMode (),
235 availableMouseModes (),
236 visibleMouseModes (),
237 activeState (false)
238 {
239 }
240
241 /// @todo De-inline?
hasRegionSelection()242 bool hasRegionSelection() const
243 {
244 return selectionRectangle.first.hasCoordinates();
245 }
246
247 public:
248
249 /// @name Objects
250 //@{
251 MapWidget* worldMapWidget;
252 TileGrouper* tileGrouper;
253 AbstractMarkerTiler* markerModel;
254 GeoIfaceCluster::List clusterList;
255 QList<GeoModelHelper*> ungroupedModels;
256 TrackManager* trackManager;
257 //@}
258
259 /// @name Display options
260 //@{
261 bool showThumbnails;
262 int thumbnailSize;
263 int thumbnailGroupingRadius;
264 int markerGroupingRadius;
265 bool previewSingleItems;
266 bool previewGroupedItems;
267 bool showNumbersOnItems;
268 int sortKey;
269 bool modificationsAllowed;
270 //@}
271
272 /// @name Current map state
273 //@{
274 GeoCoordinates::Pair selectionRectangle;
275 bool haveMovingCluster;
276 GeoMouseModes currentMouseMode;
277 GeoMouseModes availableMouseModes;
278 GeoMouseModes visibleMouseModes;
279 bool activeState;
280 //@}
281 };
282
283 // ----------------------------------------------------------------------------------------------
284
285 /// helper functions
286
287 DIGIKAM_EXPORT bool GeoIfaceHelperParseLatLonString(const QString& latLonString,
288 GeoCoordinates* const coordinates);
289
290 DIGIKAM_EXPORT bool GeoIfaceHelperParseXYStringToPoint(const QString& xyString,
291 QPoint* const point);
292
293 DIGIKAM_EXPORT bool GeoIfaceHelperParseBoundsString(const QString& boundsString,
294 QPair<GeoCoordinates, GeoCoordinates>* const boundsCoordinates);
295
296 DIGIKAM_EXPORT GeoCoordinates::PairList GeoIfaceHelperNormalizeBounds(const GeoCoordinates::Pair& boundsPair);
297
298 DIGIKAM_EXPORT void GeoIface_assert(const char* const condition,
299 const char* const filename,
300 const int lineNumber);
301
302 } // namespace Digikam
303
304 #define GEOIFACE_ASSERT(cond) ((!(cond)) ? Digikam::GeoIface_assert(#cond,__FILE__,__LINE__) : qt_noop())
305
306 #endif // DIGIKAM_GEO_IFACE_COMMON_H
307