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)
 
const QList< QKeySequence > & zoomIn()
 
const QList< QKeySequence > & zoomOut()
 
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)