summaryrefslogtreecommitdiff
path: root/src/location/labs/qdeclarativenavigator.cpp
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@qt.io>2018-01-19 18:52:14 +0100
committerPaolo Angelelli <paolo.angelelli@qt.io>2018-04-17 11:16:59 +0000
commit6909660b73b40681211493a039e72a701d5b4462 (patch)
tree85d3d59e8e2123f3b26c0dbe5cd23785ae7539ef /src/location/labs/qdeclarativenavigator.cpp
parent6c6a9e787c2e1443fc4318482504e672a6ca386e (diff)
downloadqtlocation-6909660b73b40681211493a039e72a701d5b4462.tar.gz
Introduce Navigator QML type
A new QML type, Navigator, is introduced in Qt.labs.location Its intended purpose is to be a front-end for the functionalities offered by NavigationManagerEngines. Change-Id: Ic93bed0bfaaf32453e759b12a348fa6ef1ae2c93 Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src/location/labs/qdeclarativenavigator.cpp')
-rw-r--r--src/location/labs/qdeclarativenavigator.cpp286
1 files changed, 286 insertions, 0 deletions
diff --git a/src/location/labs/qdeclarativenavigator.cpp b/src/location/labs/qdeclarativenavigator.cpp
new file mode 100644
index 00000000..d0131006
--- /dev/null
+++ b/src/location/labs/qdeclarativenavigator.cpp
@@ -0,0 +1,286 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativenavigator_p.h"
+#include "qdeclarativenavigator_p_p.h"
+#include <QtLocation/private/qdeclarativegeomap_p.h>
+#include <QtLocation/private/qdeclarativegeoserviceprovider_p.h>
+#include <QtLocation/private/qnavigationmanager_p.h>
+#include <QtLocation/private/qnavigationmanagerengine_p.h>
+#include <QtLocation/private/qgeomapparameter_p.h>
+#include <QtLocation/private/qdeclarativegeoroute_p.h>
+#include <QtLocation/private/qdeclarativegeoroutemodel_p.h>
+#include <QtLocation/private/qdeclarativegeoroutesegment_p.h>
+#include <QtQml/qqmlinfo.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype Navigator
+ \instantiates QDeclarativeNavigator
+ \inqmlmodule Qt.labs.location
+ \ingroup qml-QtLocation5-maps
+
+ \brief The Navigator type takes control of a \l Map to perform turn-by-turn navigation.
+
+ Its purpose is to include a plugin's turn-by-turn navigation implementation in a QML mapping application
+ in a seamless manner.
+ This may include controlling the map position, orientation, tilting and zoom, as well as changing
+ the map style, elements on the map such as direction information, as well as restricting interaction
+ with the Map and the items on it.
+*/
+
+
+QDeclarativeNavigator::QDeclarativeNavigator(QObject *parent)
+ : QParameterizableObject(parent), d_ptr(new QDeclarativeNavigatorPrivate)
+{
+}
+
+QDeclarativeNavigator::~QDeclarativeNavigator()
+{
+}
+
+void QDeclarativeNavigator::classBegin()
+{
+}
+
+void QDeclarativeNavigator::componentComplete()
+{
+ d_ptr->m_completed = true;
+ // Children have been completed
+ d_ptr->m_parameters = quickChildren<QGeoMapParameter>();
+ if (d_ptr->m_plugin && d_ptr->m_plugin->isAttached())
+ pluginReady();
+}
+
+QDeclarativeGeoServiceProvider *QDeclarativeNavigator::plugin() const
+{
+ return d_ptr->m_plugin;
+}
+
+void QDeclarativeNavigator::setMap(QDeclarativeGeoMap *map)
+{
+ if (d_ptr->m_map) // set once prop
+ return;
+
+ d_ptr->m_map = map;
+ emit mapChanged();
+ updateReadyState();
+}
+
+QDeclarativeGeoMap *QDeclarativeNavigator::map() const
+{
+ return d_ptr->m_map;
+}
+
+void QDeclarativeNavigator::setRoute(QDeclarativeGeoRoute *route)
+{
+ if (d_ptr->m_route == route) // This isn't set-once
+ return;
+
+ const bool isReady = d_ptr->m_navigationManager && d_ptr->m_navigationManager->ready();
+ const bool isActive = active();
+ if (isReady && isActive)
+ setActive(false); // Stop current session
+
+ d_ptr->m_route = route;
+ emit routeChanged();
+ updateReadyState();
+}
+
+QDeclarativeGeoRoute *QDeclarativeNavigator::route() const
+{
+ return d_ptr->m_route;
+}
+
+void QDeclarativeNavigator::setPositionSource(QDeclarativePositionSource *positionSource)
+{
+ if (d_ptr->m_positionSource) // set once prop
+ return;
+
+ d_ptr->m_positionSource = positionSource;
+ emit positionSourceChanged();
+ updateReadyState();
+}
+
+QDeclarativePositionSource *QDeclarativeNavigator::positionSource() const
+{
+ return d_ptr->m_positionSource;
+}
+
+QNavigationManager *QDeclarativeNavigator::navigationManager() const
+{
+ return d_ptr->m_navigationManager;
+}
+
+bool QDeclarativeNavigator::navigatorReady() const
+{
+ if (d_ptr->m_navigationManager)
+ return d_ptr->m_navigationManager->ready();
+ return d_ptr->m_ready;
+}
+
+QDeclarativeGeoRoute *QDeclarativeNavigator::currentRoute() const
+{
+ if (!d_ptr->m_ready || !d_ptr->m_navigationManager->active())
+ return d_ptr->m_route;
+ return d_ptr->m_currentRoute;
+}
+
+int QDeclarativeNavigator::currentSegment() const
+{
+ if (!d_ptr->m_ready || !d_ptr->m_navigationManager->active())
+ return 0;
+ return d_ptr->m_currentSegment;
+}
+
+bool QDeclarativeNavigator::active() const
+{
+ return d_ptr->m_active;
+}
+
+void QDeclarativeNavigator::setPlugin(QDeclarativeGeoServiceProvider *plugin)
+{
+ if (d_ptr->m_plugin)
+ return; // set once property.
+
+ d_ptr->m_plugin = plugin;
+ emit pluginChanged();
+
+ if (d_ptr->m_plugin->isAttached()) {
+ pluginReady();
+ } else {
+ connect(d_ptr->m_plugin, &QDeclarativeGeoServiceProvider::attached,
+ this, &QDeclarativeNavigator::pluginReady);
+ }
+}
+
+void QDeclarativeNavigator::setActive(bool active)
+{
+ if (d_ptr->m_active == active)
+ return;
+
+ d_ptr->m_active = active;
+ if (!d_ptr->m_plugin)
+ return;
+
+ if (active)
+ start();
+ else
+ stop();
+}
+
+void QDeclarativeNavigator::start()
+{
+ if (!d_ptr->m_ready) {
+ qmlWarning(this) << QStringLiteral("Navigation manager not ready.");
+ return;
+ }
+
+ if (d_ptr->m_active)
+ return;
+
+ d_ptr->m_active = d_ptr->m_navigationManager->start();
+}
+
+void QDeclarativeNavigator::stop()
+{
+ if (!ensureEngine()) { // If somebody re-set route to null or something, this may become !d_ptr->m_ready
+ qmlWarning(this) << QStringLiteral("Navigation manager not ready.");
+ return;
+ }
+
+ if (!d_ptr->m_active)
+ return;
+
+ d_ptr->m_active = d_ptr->m_navigationManager->stop();
+}
+
+void QDeclarativeNavigator::pluginReady()
+{
+ if (!d_ptr->m_completed)
+ return;
+
+ ensureEngine();
+ updateReadyState();
+ if (d_ptr->m_active)
+ start();
+}
+
+bool QDeclarativeNavigator::ensureEngine()
+{
+ if (d_ptr->m_navigationManager)
+ return true;
+ if (!d_ptr->m_completed || !d_ptr->m_plugin->isAttached())
+ return false;
+
+ d_ptr->m_navigationManager = d_ptr->m_plugin->sharedGeoServiceProvider()->navigationManager();
+ if (d_ptr->m_navigationManager) {
+ d_ptr->m_navigationManager->setNavigator(d_ptr.data());
+ d_ptr->m_navigationManager->setParameters(d_ptr->m_parameters);
+ connect(d_ptr->m_navigationManager, &QNavigationManager::waypointReached, this, &QDeclarativeNavigator::waypointReached);
+ connect(d_ptr->m_navigationManager, &QNavigationManager::destinationReached, this, &QDeclarativeNavigator::destinationReached);
+ connect(d_ptr->m_navigationManager, &QNavigationManager::currentRouteChanged, this, &QDeclarativeNavigator::onCurrentRouteChanged);
+ connect(d_ptr->m_navigationManager, &QNavigationManager::currentSegmentChanged, this, &QDeclarativeNavigator::onCurrentSegmentChanged);
+ connect(d_ptr->m_navigationManager, &QNavigationManager::activeChanged, this, [this](bool active){
+ d_ptr->m_active = active;
+ emit activeChanged(active);
+ });
+ emit navigatorReadyChanged(true);
+ return true;
+ }
+ return false;
+}
+
+void QDeclarativeNavigator::updateReadyState() {
+ const bool oldReady = d_ptr->m_ready;
+ if (!d_ptr->m_navigationManager)
+ d_ptr->m_ready = false;
+ else
+ d_ptr->m_ready = d_ptr->m_navigationManager->ready();
+
+ if (oldReady != d_ptr->m_ready)
+ emit navigatorReadyChanged(d_ptr->m_ready);
+}
+
+void QDeclarativeNavigator::onCurrentRouteChanged(const QGeoRoute &route)
+{
+ if (d_ptr->m_currentRoute)
+ d_ptr->m_currentRoute->deleteLater();
+ d_ptr->m_currentRoute = new QDeclarativeGeoRoute(route, this);
+ emit currentRouteChanged();
+}
+
+void QDeclarativeNavigator::onCurrentSegmentChanged(int segment)
+{
+ d_ptr->m_currentSegment = segment;
+ emit currentSegmentChanged();
+}
+
+QT_END_NAMESPACE