1 /* ============================================================
2  *
3  * This file is a part of digiKam project
4  * https://www.digikam.org
5  *
6  * Date        : 2009-12-01
7  * Description : world map widget library
8  *
9  * Copyright (C) 2010-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
10  * Copyright (C) 2009-2011 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_MAP_WIDGET_H
27 #define DIGIKAM_MAP_WIDGET_H
28 
29 // Qt includes
30 
31 #include <QWidget>
32 #include <QStringList>
33 
34 // local includes
35 
36 #include "geoifacetypes.h"
37 #include "geocoordinates.h"
38 #include "geogroupstate.h"
39 #include "digikam_export.h"
40 
41 class QAction;
42 class QDragEnterEvent;
43 class QDropEvent;
44 class QMenu;
45 
46 class KConfigGroup;
47 
48 namespace Digikam
49 {
50 
51 class GeoIfaceSharedData;
52 class GeoModelHelper;
53 class GeoDragDropHandler;
54 class AbstractMarkerTiler;
55 class TrackManager;
56 
57 class DIGIKAM_EXPORT MapWidget : public QWidget
58 {
59   Q_OBJECT
60 
61 public:
62 
63     explicit MapWidget(QWidget* const parent = nullptr);
64     ~MapWidget() override;
65 
66     void saveSettingsToGroup(KConfigGroup* const group);
67     void readSettingsFromGroup(const KConfigGroup* const group);
68 
69     /// @name Data
70     //@{
71     void addUngroupedModel(GeoModelHelper* const modelHelper);
72     void removeUngroupedModel(GeoModelHelper* const modelHelper);
73     void setGroupedModel(AbstractMarkerTiler* const markerModel);
74     void setDragDropHandler(GeoDragDropHandler* const dragDropHandler);
75     void setTrackManager(TrackManager* const trackManager);
76     //@}
77 
78     /// @name UI setup
79     //@{
80     QAction* getControlAction(const QString& actionName);
81     QWidget* getControlWidget();
82     void addWidgetToControlWidget(QWidget* const newWidget);
83     void setSortOptionsMenu(QMenu* const sortMenu);
84     void setMouseMode(const GeoMouseModes mouseMode);
85     void setAvailableMouseModes(const GeoMouseModes mouseModes);
86     void setVisibleMouseModes(const GeoMouseModes mouseModes);
87     void setAllowModifications(const bool state);
88     void setActive(const bool state);
89     bool getActiveState();
90     bool getStickyModeState() const;
91     void setStickyModeState(const bool state);
92     void setVisibleExtraActions(const GeoExtraActions actions);
93     void setEnabledExtraActions(const GeoExtraActions actions);
94     //@}
95 
96     /// @name Map related functions
97     //@{
98     QStringList availableBackends() const;
99     bool setBackend(const QString& backendName);
100 
101     GeoCoordinates getCenter() const;
102     void setCenter(const GeoCoordinates& coordinate);
103 
104     void setZoom(const QString& newZoom);
105     QString getZoom();
106 
107     void adjustBoundariesToGroupedMarkers(const bool useSaneZoomLevel = true);
108     void refreshMap();
109     //@}
110 
111     /// @name Appearance
112     //@{
113     void setSortKey(const int sortKey);
114     void setThumnailSize(const int newThumbnailSize);
115     void setThumbnailGroupingRadius(const int newGroupingRadius);
116     void setMarkerGroupingRadius(const int newGroupingRadius);
117     int  getThumbnailSize() const;
118     int  getUndecoratedThumbnailSize() const;
119     void setShowThumbnails(const bool state);
120     //@}
121 
122     /// @name Region selection
123     //@{
124     void setRegionSelection(const GeoCoordinates::Pair& region);
125     GeoCoordinates::Pair getRegionSelection();
126     void clearRegionSelection();
127     //@}
128 
129     /**
130      * @name Internal
131      * Functions that are only used internally and should be hidden from the public interface
132      */
133     //@{
134     void updateMarkers();
135     void updateClusters();
136     void markClustersAsDirty();
137 
138     void getColorInfos(const int clusterIndex, QColor* fillColor, QColor* strokeColor,
139                        Qt::PenStyle* strokeStyle, QString* labelText, QColor* labelColor,
140                        const GeoGroupState* const overrideSelection = nullptr,
141                        const int* const overrideCount = nullptr) const;
142 
143     void getColorInfos(const GeoGroupState groupState,
144                        const int nMarkers,
145                        QColor* fillColor, QColor* strokeColor,
146                        Qt::PenStyle* strokeStyle, QString* labelText, QColor* labelColor) const;
147 
148     QString convertZoomToBackendZoom(const QString& someZoom, const QString& targetBackend) const;
149     QPixmap getDecoratedPixmapForCluster(const int clusterId, const GeoGroupState* const selectedStateOverride,
150                                          const int* const countOverride, QPoint* const centerPoint);
151     QVariant getClusterRepresentativeMarker(const int clusterIndex, const int sortKey);
152     //@}
153 
154 public Q_SLOTS:
155 
156     /// @name Appearance
157     //@{
158     void slotZoomIn();
159     void slotZoomOut();
160     void slotDecreaseThumbnailSize();
161     void slotIncreaseThumbnailSize();
162     //@}
163 
164     /// @name Internal?
165     //@{
166     void slotUpdateActionsEnabled();
167     void slotClustersNeedUpdating();
168     void stopThumbnailTimer();
169     void slotStickyModeChanged();
170     //@}
171 
172 Q_SIGNALS:
173 
174     void signalUngroupedModelChanged(const int index);
175     void signalRegionSelectionChanged();
176     void signalRemoveCurrentFilter();
177     void signalStickyModeChanged();
178     void signalMouseModeChanged(const Digikam::GeoMouseModes& currentMouseMode);
179 
180 public:
181 
182     /**
183      * Return a string version of LibMarbleWidget release in format "major.minor.patch"
184      */
185     static QString MarbleWidgetVersion();
186 
187 protected:
188 
189     bool currentBackendReady() const;
190     void applyCacheToBackend();
191     void saveBackendToCache();
192     void rebuildConfigurationMenu();
193     void dropEvent(QDropEvent* event)           override;
194     void dragMoveEvent(QDragMoveEvent* event)   override;
195     void dragEnterEvent(QDragEnterEvent* event) override;
196     void dragLeaveEvent(QDragLeaveEvent* event) override;
197     void createActions();
198     void createActionsForBackendSelection();
199     void setShowPlaceholderWidget(const bool state);
200     void setMapWidgetInFrame(QWidget* const widgetForFrame);
201     void removeMapWidgetFromFrame();
202 
203 protected Q_SLOTS:
204 
205     void slotBackendReadyChanged(const QString& backendName);
206     void slotChangeBackend(QAction* action);
207     void slotBackendZoomChanged(const QString& newZoom);
208     void slotClustersMoved(const QIntList& clusterIndices, const QPair<int, QModelIndex>& snapTarget);
209     void slotClustersClicked(const QIntList& clusterIndices);
210     void slotShowThumbnailsChanged();
211     void slotRequestLazyReclustering();
212     void slotLazyReclusteringRequestCallBack();
213     void slotItemDisplaySettingsChanged();
214     void slotUngroupedModelChanged();
215     void slotNewSelectionFromMap(const Digikam::GeoCoordinates::Pair& sel);
216 
217     /// @name Mouse modes
218     //@{
219     void slotMouseModeChanged(QAction* triggeredAction);
220     void slotRemoveCurrentRegionSelection();
221     //@}
222 
223 private:
224 
225     const QExplicitlySharedDataPointer<GeoIfaceSharedData> s;
226 
227     class Private;
228     Private* const                                         d;
229 
230     Q_DISABLE_COPY(MapWidget)
231 };
232 
233 } // namespace Digikam
234 
235 #endif // DIGIKAM_MAP_WIDGET_H
236