10#include "CurrentLocationWidget.h"
13#include "GeoDataCoordinates.h"
14#include "MarbleDebug.h"
15#include "MarbleLocale.h"
18#include "MarbleWidgetPopupMenu.h"
19#include "PluginManager.h"
20#include "PositionProviderPlugin.h"
21#include "PositionTracking.h"
22#include "routing/RoutingManager.h"
28#include "ui_CurrentLocationWidget.h"
37class CurrentLocationWidgetPrivate
40 CurrentLocationWidgetPrivate();
42 Ui::CurrentLocationWidget m_currentLocationUi;
43 MarbleWidget *m_widget;
44 AutoNavigation *m_adjustNavigation;
46 QList<const PositionProviderPlugin *> m_positionProviderPlugins;
47 GeoDataCoordinates m_currentPosition;
49 QString m_lastOpenPath;
50 QString m_lastSavePath;
52 void receiveGpsCoordinates(
const GeoDataCoordinates &position, qreal speed);
53 void adjustPositionTrackingStatus(PositionProviderStatus
status);
54 void centerOnCurrentLocation();
55 void updateRecenterComboBox(AutoNavigation::CenterMode centerMode);
56 void updateAutoZoomCheckBox(
bool autoZoom);
57 void updateActivePositionProvider(PositionProviderPlugin *);
58 void updateGuidanceMode();
64CurrentLocationWidgetPrivate::CurrentLocationWidgetPrivate()
66 , m_adjustNavigation(nullptr)
67 , m_positionProviderPlugins()
76 , d(new CurrentLocationWidgetPrivate())
78 d->m_currentLocationUi.
setupUi(
this);
79 layout()->setContentsMargins({});
85 bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
86 d->m_currentLocationUi.positionTrackingComboBox->setVisible(!smallScreen);
87 d->m_currentLocationUi.locationLabel->setVisible(!smallScreen);
90CurrentLocationWidget::~CurrentLocationWidget()
95void CurrentLocationWidget::setMarbleWidget(
MarbleWidget *widget)
99 delete d->m_adjustNavigation;
100 d->m_adjustNavigation =
new AutoNavigation(widget->
model(), widget->viewport(),
this);
102 const PluginManager *pluginManager = d->m_widget->model()->pluginManager();
104 for (
const PositionProviderPlugin *plugin : std::as_const(d->m_positionProviderPlugins)) {
105 d->m_currentLocationUi.positionTrackingComboBox->addItem(plugin->guiString());
107 if (d->m_positionProviderPlugins.isEmpty()) {
108 d->m_currentLocationUi.positionTrackingComboBox->setEnabled(
false);
109 QString html =
tr(
"<p>No Position Tracking Plugin installed.</p>");
110 d->m_currentLocationUi.locationLabel->setText(html);
111 d->m_currentLocationUi.locationLabel->setEnabled(
true);
112 bool const hasTrack = !d->m_widget->model()->positionTracking()->isTrackEmpty();
113 d->m_currentLocationUi.showTrackCheckBox->setEnabled(hasTrack);
114 d->m_currentLocationUi.saveTrackButton->setEnabled(hasTrack);
115 d->m_currentLocationUi.clearTrackButton->setEnabled(hasTrack);
119 disconnect(d->m_widget->model()->positionTracking(),
120 SIGNAL(gpsLocation(GeoDataCoordinates, qreal)),
122 SLOT(receiveGpsCoordinates(GeoDataCoordinates, qreal)));
123 disconnect(d->m_widget->model()->positionTracking(),
124 SIGNAL(positionProviderPluginChanged(PositionProviderPlugin *)),
126 SLOT(updateActivePositionProvider(PositionProviderPlugin *)));
127 disconnect(d->m_currentLocationUi.positionTrackingComboBox, SIGNAL(currentIndexChanged(
int)),
this, SLOT(changePositionProvider(
int)));
128 disconnect(d->m_currentLocationUi.locationLabel, SIGNAL(linkActivated(QString)),
this, SLOT(centerOnCurrentLocation()));
129 disconnect(d->m_widget->model()->positionTracking(),
130 SIGNAL(statusChanged(PositionProviderStatus)),
132 SLOT(adjustPositionTrackingStatus(PositionProviderStatus)));
134 disconnect(d->m_widget->model(), SIGNAL(trackedPlacemarkChanged(
const GeoDataPlacemark *)),
this, SLOT(trackPlacemark()));
137 connect(d->m_widget->model()->positionTracking(),
138 SIGNAL(gpsLocation(GeoDataCoordinates, qreal)),
140 SLOT(receiveGpsCoordinates(GeoDataCoordinates, qreal)));
141 connect(d->m_widget->model()->positionTracking(),
142 SIGNAL(positionProviderPluginChanged(PositionProviderPlugin *)),
144 SLOT(updateActivePositionProvider(PositionProviderPlugin *)));
145 d->updateActivePositionProvider(d->m_widget->model()->positionTracking()->positionProviderPlugin());
146 connect(d->m_currentLocationUi.positionTrackingComboBox, SIGNAL(currentIndexChanged(
int)),
this, SLOT(changePositionProvider(
int)));
147 connect(d->m_currentLocationUi.locationLabel, SIGNAL(linkActivated(QString)),
this, SLOT(centerOnCurrentLocation()));
148 connect(d->m_widget->model()->positionTracking(),
149 SIGNAL(statusChanged(PositionProviderStatus)),
151 SLOT(adjustPositionTrackingStatus(PositionProviderStatus)));
153 connect(d->m_adjustNavigation, SIGNAL(recenterModeChanged(AutoNavigation::CenterMode)),
this, SLOT(updateRecenterComboBox(AutoNavigation::CenterMode)));
154 connect(d->m_adjustNavigation, SIGNAL(autoZoomToggled(
bool)),
this, SLOT(updateAutoZoomCheckBox(
bool)));
157 connect(d->m_adjustNavigation, SIGNAL(centerOn(GeoDataCoordinates,
bool)), d->m_widget, SLOT(centerOn(GeoDataCoordinates,
bool)));
159 connect(d->m_widget, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)), d->m_adjustNavigation, SLOT(inhibitAutoAdjustments()));
160 connect(d->m_widget->model()->routingManager(), SIGNAL(guidanceModeEnabledChanged(
bool)),
this, SLOT(updateGuidanceMode()));
162 connect(d->m_currentLocationUi.showTrackCheckBox, SIGNAL(clicked(
bool)), d->m_widget->model()->positionTracking(), SLOT(setTrackVisible(
bool)));
163 connect(d->m_currentLocationUi.showTrackCheckBox, SIGNAL(clicked(
bool)), d->m_widget, SLOT(
update()));
164 if (d->m_widget->model()->positionTracking()->trackVisible()) {
165 d->m_currentLocationUi.showTrackCheckBox->setCheckState(
Qt::Checked);
167 connect(d->m_currentLocationUi.saveTrackButton, SIGNAL(clicked(
bool)),
this, SLOT(saveTrack()));
168 connect(d->m_currentLocationUi.openTrackButton, SIGNAL(clicked(
bool)),
this, SLOT(openTrack()));
169 connect(d->m_currentLocationUi.clearTrackButton, SIGNAL(clicked(
bool)),
this, SLOT(clearTrack()));
170 connect(d->m_widget->model(), SIGNAL(trackedPlacemarkChanged(
const GeoDataPlacemark *)),
this, SLOT(trackPlacemark()));
173void CurrentLocationWidgetPrivate::adjustPositionTrackingStatus(PositionProviderStatus
status)
175 if (
status == PositionProviderStatusAvailable) {
179 QString html = QStringLiteral(
"<html><body><p>");
182 case PositionProviderStatusUnavailable:
185 case PositionProviderStatusAcquiring:
186 html +=
QObject::tr(
"Waiting for current location information...");
188 case PositionProviderStatusAvailable:
191 case PositionProviderStatusError:
192 html +=
QObject::tr(
"Error when determining current location: ");
193 html += m_widget->model()->positionTracking()->error();
197 html += QLatin1StringView(
"</p></body></html>");
198 m_currentLocationUi.locationLabel->setEnabled(
true);
199 m_currentLocationUi.locationLabel->setText(html);
204 m_currentLocationUi.positionTrackingComboBox->blockSignals(
true);
206 m_currentLocationUi.positionTrackingComboBox->setCurrentIndex(0);
208 for (
int i = 0; i < m_currentLocationUi.positionTrackingComboBox->count(); ++i) {
209 if (m_currentLocationUi.positionTrackingComboBox->itemText(i) == plugin->
guiString()) {
210 m_currentLocationUi.positionTrackingComboBox->setCurrentIndex(i);
215 m_currentLocationUi.positionTrackingComboBox->blockSignals(
false);
216 m_currentLocationUi.recenterLabel->setEnabled(plugin);
217 m_currentLocationUi.recenterComboBox->setEnabled(plugin);
218 m_currentLocationUi.autoZoomCheckBox->setEnabled(plugin);
221void CurrentLocationWidgetPrivate::updateGuidanceMode()
223 const bool enabled = m_widget->model()->routingManager()->guidanceModeEnabled();
225 m_adjustNavigation->setAutoZoom(enabled);
226 m_adjustNavigation->setRecenter(enabled ? AutoNavigation::RecenterOnBorder : AutoNavigation::DontRecenter);
229void CurrentLocationWidgetPrivate::receiveGpsCoordinates(
const GeoDataCoordinates &position, qreal speed)
231 m_currentPosition = position;
233 QString altitudeUnitString;
234 QString distanceUnitString;
235 qreal unitSpeed = 0.0;
236 qreal altitude = 0.0;
237 qreal length = m_widget->model()->positionTracking()->length(m_widget->model()->planetRadius());
239 QString html = QLatin1StringView(
241 "<table cellspacing=\"2\" cellpadding=\"2\">"
242 "<tr><td>Longitude</td><td><a href=\"https://edu.kde.org/marble\">%1</a></td></tr>"
243 "<tr><td>Latitude</td><td><a href=\"https://edu.kde.org/marble\">%2</a></td></tr>"
244 "<tr><td>Altitude</td><td>%3</td></tr>"
245 "<tr><td>Speed</td><td>%4</td></tr>"
246 "<tr><td>Distance</td><td>%5</td></tr>"
250 switch (MarbleGlobal::getInstance()->locale()->measurementSystem()) {
251 case MarbleLocale::MetricSystem:
254 unitSpeed = speed * HOUR2SEC * METER2KM;
257 if (length > 1000.0) {
263 case MarbleLocale::ImperialSystem:
266 unitSpeed = speed * HOUR2SEC * METER2KM * KM2MI;
269 altitude = position.
altitude() * M2FT;
273 case MarbleLocale::NauticalSystem:
276 unitSpeed = speed * HOUR2SEC * METER2KM * KM2NM;
280 length *= METER2KM * KM2NM;
285 const QString altitudeString = QStringLiteral(
"%1 %2").
arg(altitude, 0,
'f', 1, QLatin1Char(
' ')).
arg(altitudeUnitString);
286 const QString distanceString = QStringLiteral(
"%1 %2").
arg(length, 0,
'f', 1, QLatin1Char(
' ')).
arg(distanceUnitString);
289 html = html.
arg(altitudeString, speedString + QLatin1Char(
' ') + unitString);
290 html = html.
arg(distanceString);
291 m_currentLocationUi.locationLabel->setText(html);
292 m_currentLocationUi.showTrackCheckBox->setEnabled(
true);
293 m_currentLocationUi.saveTrackButton->setEnabled(
true);
294 m_currentLocationUi.clearTrackButton->setEnabled(
true);
297void CurrentLocationWidget::changePositionProvider(
int index)
299 auto const combo =
dynamic_cast<QComboBox *
>(
sender());
304 QString provider = combo->itemText(index);
306 changePositionProvider(provider);
309void CurrentLocationWidget::changePositionProvider(
const QString &provider)
311 for (
const PositionProviderPlugin *plugin : std::as_const(d->m_positionProviderPlugins)) {
313 d->m_currentLocationUi.locationLabel->setEnabled(
true);
314 PositionProviderPlugin *instance = plugin->
newInstance();
315 PositionTracking *tracking = d->m_widget->model()->positionTracking();
316 tracking->setPositionProviderPlugin(instance);
317 d->m_widget->update();
323 d->m_currentLocationUi.locationLabel->setEnabled(
false);
324 d->m_widget->model()->positionTracking()->setPositionProviderPlugin(
nullptr);
325 d->m_widget->update();
328void CurrentLocationWidget::trackPlacemark()
331 d->m_adjustNavigation->setRecenter(AutoNavigation::AlwaysRecenter);
334void CurrentLocationWidget::setRecenterMode(
int mode)
336 if (mode >= 0 && mode <= AutoNavigation::RecenterOnBorder) {
337 auto centerMode = (AutoNavigation::CenterMode)mode;
338 d->m_adjustNavigation->setRecenter(centerMode);
342void CurrentLocationWidget::setAutoZoom(
bool autoZoom)
344 d->m_adjustNavigation->setAutoZoom(autoZoom);
347void CurrentLocationWidgetPrivate::updateAutoZoomCheckBox(
bool autoZoom)
349 m_currentLocationUi.autoZoomCheckBox->setChecked(autoZoom);
352void CurrentLocationWidgetPrivate::updateRecenterComboBox(AutoNavigation::CenterMode centerMode)
354 m_currentLocationUi.recenterComboBox->setCurrentIndex(centerMode);
357void CurrentLocationWidgetPrivate::centerOnCurrentLocation()
359 m_widget->centerOn(m_currentPosition,
true);
362void CurrentLocationWidgetPrivate::saveTrack()
364 QString suggested = m_lastSavePath;
374 fileName += QLatin1StringView(
".kml");
376 QFileInfo file(fileName);
377 m_lastSavePath = file.absolutePath();
378 m_widget->model()->positionTracking()->saveTrack(fileName);
381void CurrentLocationWidgetPrivate::openTrack()
383 QString suggested = m_lastOpenPath;
389 QFileInfo file(fileName);
390 m_lastOpenPath = file.absolutePath();
391 m_widget->model()->addGeoDataFile(fileName);
395void CurrentLocationWidgetPrivate::clearTrack()
399 QObject::tr(
"Are you sure you want to clear the current track?"),
404 m_widget->model()->positionTracking()->clearTrack();
406 m_currentLocationUi.saveTrackButton->setEnabled(
false);
407 m_currentLocationUi.clearTrackButton->setEnabled(
false);
411AutoNavigation::CenterMode CurrentLocationWidget::recenterMode()
const
413 return d->m_adjustNavigation->recenterMode();
416bool CurrentLocationWidget::autoZoom()
const
418 return d->m_adjustNavigation->autoZoom();
421bool CurrentLocationWidget::trackVisible()
const
423 return d->m_widget->model()->positionTracking()->trackVisible();
426QString CurrentLocationWidget::lastOpenPath()
const
428 return d->m_lastOpenPath;
431QString CurrentLocationWidget::lastSavePath()
const
433 return d->m_lastSavePath;
436void CurrentLocationWidget::setTrackVisible(
bool visible)
438 d->m_currentLocationUi.showTrackCheckBox->setChecked(
visible);
439 d->m_widget->model()->positionTracking()->setTrackVisible(
visible);
442void CurrentLocationWidget::setLastOpenPath(
const QString &path)
444 d->m_lastOpenPath =
path;
447void CurrentLocationWidget::setLastSavePath(
const QString &path)
449 d->m_lastSavePath =
path;
454#include "moc_CurrentLocationWidget.cpp"
This file contains the headers for MarbleModel.
A 3d point representation.
static QString latToString(qreal lat, GeoDataCoordinates::Notation notation, GeoDataCoordinates::Unit unit=Radian, int precision=-1, char format='f')
qreal altitude() const
return the altitude of the Point in meters
static QString lonToString(qreal lon, GeoDataCoordinates::Notation notation, GeoDataCoordinates::Unit unit=Radian, int precision=-1, char format='f')
QList< const PositionProviderPlugin * > positionProviderPlugins() const
Returns all available PositionProviderPlugins.
The abstract class that provides position information.
virtual QString guiString() const =0
Returns the string that should appear in the user interface.
virtual PositionProviderPlugin * newInstance() const =0
Create a new PositionProvider Plugin and return it.
Q_SCRIPTABLE CaptureState status()
char * toString(const EngineQuery &query)
QString path(const QString &relativePath)
QAction * zoomIn(const QObject *recvr, const char *slot, QObject *parent)
QAction * zoomOut(const QObject *recvr, const char *slot, QObject *parent)
Binds a QML item to a specific geodetic location in screen coordinates.
FlyToMode
Describes possible flight mode (interpolation between source and target camera positions)
void currentIndexChanged(int index)
QDateTime currentDateTime()
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
QString toString(QDate date, FormatType format) const const
StandardButton question(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons, StandardButton defaultButton)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
QObject * sender() const const
QString tr(const char *sourceText, const char *disambiguation, int n)
QString & append(QChar ch)
QString arg(Args &&... args) const const
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)