summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2019-07-25 11:01:35 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2019-07-25 11:59:08 +0200
commit0a8f8f40c2fdfccc4bd1bf3c7411085ed634700e (patch)
tree05e10e315cc208aa83e6d34a262717e245330d5e
parent57d50ee43efd8e3c3e1c04f1aad3e0043e79096a (diff)
parentcd84a8cac6a43cfeede4d098ed72c9bd3ce4f111 (diff)
Merge "Merge remote-tracking branch 'origin/dev' into wip/qt6"
-rw-r--r--dist/changes-5.13.046
-rw-r--r--src/location/declarativemaps/locationvaluetypehelper.cpp2
-rw-r--r--src/location/declarativemaps/qdeclarativegeoroute.cpp2
-rw-r--r--src/location/declarativemaps/qdeclarativegeoroutemodel.cpp2
-rw-r--r--src/location/declarativemaps/qdeclarativegeoroutesegment.cpp2
-rw-r--r--src/location/declarativeplaces/qdeclarativesearchresultmodel.cpp5
-rw-r--r--src/location/declarativeplaces/qdeclarativesupportedcategoriesmodel.cpp22
-rw-r--r--src/location/doc/qtlocation.qdocconf1
-rw-r--r--src/location/labs/qdeclarativenavigator.cpp27
-rw-r--r--src/location/labs/qdeclarativenavigator_p.h2
-rw-r--r--src/location/labs/qdeclarativenavigator_p_p.h49
-rw-r--r--src/location/maps/qnavigationmanagerengine.cpp5
-rw-r--r--src/location/maps/qnavigationmanagerengine_p.h3
-rw-r--r--src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp33
-rw-r--r--src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.h8
-rw-r--r--src/positioning/doc/qtpositioning.qdocconf1
-rw-r--r--src/positioning/qgeopositioninfosource.cpp54
-rw-r--r--src/positioning/qgeopositioninfosource.h6
-rw-r--r--src/positioning/qgeopositioninfosource_p.h6
-rw-r--r--src/positioningquick/qdeclarativepositionsource.cpp229
-rw-r--r--src/positioningquick/qdeclarativepositionsource_p.h22
-rw-r--r--tests/auto/auto.pro1
-rw-r--r--tests/auto/declarative_core/tst_positionsource.qml133
-rw-r--r--tests/auto/positionplugin/plugin.cpp74
-rw-r--r--tests/auto/positionplugin/plugin.json2
-rw-r--r--tests/auto/positionplugin/positionplugin.pro4
-rw-r--r--tests/auto/positionpluginV1/plugin.cpp212
-rw-r--r--tests/auto/positionpluginV1/plugin.json9
-rw-r--r--tests/auto/positionpluginV1/positionpluginV1.pro12
29 files changed, 855 insertions, 119 deletions
diff --git a/dist/changes-5.13.0 b/dist/changes-5.13.0
new file mode 100644
index 00000000..564a37ec
--- /dev/null
+++ b/dist/changes-5.13.0
@@ -0,0 +1,46 @@
+Qt 5.13 introduces many new features and improvements as well as bugfixes
+over the 5.12.x series. For more details, refer to the online documentation
+included in this distribution. The documentation is also available online:
+
+https://doc.qt.io/qt-5/index.html
+
+The Qt version 5.13 series is binary compatible with the 5.12.x series.
+Applications compiled for 5.12 will continue to run with 5.13.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* QtLocation *
+****************************************************************************
+
+ - Added a GeoJSON parser which can be used to annotate maps with tracks,
+ polygonal boundaries, etc.
+ - GeoJSON returned in Nominatim queries is now converted into the corresponding
+ geoshapes using QGeoJson.
+ - GeoJSON returned in Nominatim queries is now converted into the corresponding
+ geoshapes using QGeoJson.
+ - Introduced Qt.labs.location QtLocationLabs singleton type, offering tech-preview
+ map related API.
+ - Added departure time attribute to route queries.
+ - Introduced QGeoMapObject::geoShape property.
+ - Additional navigation information now exposed via Navigator.
+ - Fixed crash when removing items from MapboxGL maps.
+ - Renamed MapIconObject.size to MapIconObject.iconSize.
+ - Added Map.fitViewportToGeoShape(shape, margins).
+ - Added Navigator currentRouteLeg property.
+ - Introduced extendedAttributes property to Geo Location types.
+ - Introduced extendedAttributes property to Geo Routes types.
+
+****************************************************************************
+* QtPositioning *
+****************************************************************************
+
+- Added holes support to QGeoPolygon, currently rendered only when using the
+ MapboxGL backend.
+
diff --git a/src/location/declarativemaps/locationvaluetypehelper.cpp b/src/location/declarativemaps/locationvaluetypehelper.cpp
index 8c96c8e7..3e2f3658 100644
--- a/src/location/declarativemaps/locationvaluetypehelper.cpp
+++ b/src/location/declarativemaps/locationvaluetypehelper.cpp
@@ -38,6 +38,8 @@
#include <QVariantMap>
#include <QtQml/QQmlInfo>
#include <private/qqmlengine_p.h>
+#include <private/qv4scopedvalue_p.h>
+#include <private/qv4arrayobject_p.h>
QGeoCoordinate parseCoordinate(const QJSValue &value, bool *ok)
diff --git a/src/location/declarativemaps/qdeclarativegeoroute.cpp b/src/location/declarativemaps/qdeclarativegeoroute.cpp
index 8f5ec5fe..c536b65b 100644
--- a/src/location/declarativemaps/qdeclarativegeoroute.cpp
+++ b/src/location/declarativemaps/qdeclarativegeoroute.cpp
@@ -43,6 +43,8 @@
#include <QtQml/QQmlEngine>
#include <QtQml/qqmlinfo.h>
#include <QtQml/private/qqmlengine_p.h>
+#include <QtQml/private/qv4scopedvalue_p.h>
+#include <QtQml/private/qv4arrayobject_p.h>
#include <QtPositioning/QGeoRectangle>
QT_BEGIN_NAMESPACE
diff --git a/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp b/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp
index 695f6972..f74557c0 100644
--- a/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp
+++ b/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp
@@ -43,6 +43,8 @@
#include <QtQml/QQmlEngine>
#include <QtQml/qqmlinfo.h>
#include <QtQml/private/qqmlengine_p.h>
+#include <QtQml/private/qv4scopedvalue_p.h>
+#include <QtQml/private/qv4arrayobject_p.h>
#include <QtLocation/QGeoRoutingManager>
#include <QtPositioning/QGeoRectangle>
#include "qdeclarativegeomapparameter_p.h"
diff --git a/src/location/declarativemaps/qdeclarativegeoroutesegment.cpp b/src/location/declarativemaps/qdeclarativegeoroutesegment.cpp
index b0e05f32..6751a47b 100644
--- a/src/location/declarativemaps/qdeclarativegeoroutesegment.cpp
+++ b/src/location/declarativemaps/qdeclarativegeoroutesegment.cpp
@@ -38,6 +38,8 @@
#include <QtQml/QQmlEngine>
#include <QtQml/private/qqmlengine_p.h>
+#include <QtQml/private/qv4scopedvalue_p.h>
+#include <QtQml/private/qv4arrayobject_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/location/declarativeplaces/qdeclarativesearchresultmodel.cpp b/src/location/declarativeplaces/qdeclarativesearchresultmodel.cpp
index 4cfd26dd..c620b9f7 100644
--- a/src/location/declarativeplaces/qdeclarativesearchresultmodel.cpp
+++ b/src/location/declarativeplaces/qdeclarativesearchresultmodel.cpp
@@ -973,16 +973,15 @@ QList<QPlaceSearchResult> QDeclarativeSearchResultModel::resultsFromPages() cons
void QDeclarativeSearchResultModel::removePageRow(int row)
{
- QMapIterator<int, QList<QPlaceSearchResult>> i(m_pages);
+ QMutableMapIterator<int, QList<QPlaceSearchResult>> i(m_pages);
int scanned = 0;
while (i.hasNext()) {
i.next();
- QList<QPlaceSearchResult> page = i.value();
+ QList<QPlaceSearchResult> &page = i.value();
scanned += page.size();
if (row >= scanned)
continue;
page.removeAt(row - scanned + page.size());
- m_pages.insert(i.key(), page);
return;
}
}
diff --git a/src/location/declarativeplaces/qdeclarativesupportedcategoriesmodel.cpp b/src/location/declarativeplaces/qdeclarativesupportedcategoriesmodel.cpp
index 38bfb249..08179c93 100644
--- a/src/location/declarativeplaces/qdeclarativesupportedcategoriesmodel.cpp
+++ b/src/location/declarativeplaces/qdeclarativesupportedcategoriesmodel.cpp
@@ -631,24 +631,24 @@ QStringList QDeclarativeSupportedCategoriesModel::populateCategories(QPlaceManag
Q_ASSERT(manager);
QStringList childIds;
- PlaceCategoryNode *node;
- QMap<QString, QPlaceCategory> sortedCategories;
- foreach ( const QPlaceCategory &category, manager->childCategories(parent.categoryId()))
- sortedCategories.insert(category.name(), category);
+ const auto byName = [](const QPlaceCategory &lhs, const QPlaceCategory &rhs) {
+ return lhs.name() < rhs.name();
+ };
- QMapIterator<QString, QPlaceCategory> iter(sortedCategories);
- while (iter.hasNext()) {
- iter.next();
- node = new PlaceCategoryNode;
+ auto categories = manager->childCategories(parent.categoryId());
+ std::sort(categories.begin(), categories.end(), byName);
+
+ for (const auto &category : qAsConst(categories)) {
+ auto node = new PlaceCategoryNode;
node->parentId = parent.categoryId();
- node->declCategory = QSharedPointer<QDeclarativeCategory>(new QDeclarativeCategory(iter.value(), m_plugin ,this));
+ node->declCategory = QSharedPointer<QDeclarativeCategory>(new QDeclarativeCategory(category, m_plugin ,this));
if (m_hierarchical)
- node->childIds = populateCategories(manager, iter.value());
+ node->childIds = populateCategories(manager, category);
m_categoriesTree.insert(node->declCategory->categoryId(), node);
- childIds.append(iter.value().categoryId());
+ childIds.append(category.categoryId());
if (!m_hierarchical) {
childIds.append(populateCategories(manager,node->declCategory->category()));
diff --git a/src/location/doc/qtlocation.qdocconf b/src/location/doc/qtlocation.qdocconf
index 0c43bfa7..0ffbe4d6 100644
--- a/src/location/doc/qtlocation.qdocconf
+++ b/src/location/doc/qtlocation.qdocconf
@@ -1,4 +1,5 @@
include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
+include($QT_INSTALL_DOCS/config/exampleurl-qtlocation.qdocconf)
project = QtLocation
description = Qt Location Reference Documentation
diff --git a/src/location/labs/qdeclarativenavigator.cpp b/src/location/labs/qdeclarativenavigator.cpp
index 89b5abef..ae273774 100644
--- a/src/location/labs/qdeclarativenavigator.cpp
+++ b/src/location/labs/qdeclarativenavigator.cpp
@@ -352,6 +352,12 @@ QString QDeclarativeNavigator::errorString() const
return d_ptr->m_errorString;
}
+void QDeclarativeNavigator::recalculateRoutes()
+{
+ if (d_ptr->m_navigator)
+ d_ptr->m_navigator->recalculateRoutes();
+}
+
/* !NOT DOCUMENTED YET!
\qmlproperty QAbstractNavigator *Qt.labs.location::Navigator::engineHandle
@@ -510,6 +516,8 @@ bool QDeclarativeNavigator::ensureEngine()
&d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::progressInformationChanged);
connect(d_ptr->m_navigator.get(), &QAbstractNavigator::isOnRouteChanged,
this, &QDeclarativeNavigator::isOnRouteChanged);
+ connect(d_ptr->m_navigator.get(), &QAbstractNavigator::alternativeRoutesChanged,
+ &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::onAlternativeRoutesChanged);
emit navigatorReadyChanged(true);
return true;
@@ -534,7 +542,7 @@ void QDeclarativeNavigator::setError(QDeclarativeNavigator::NavigationError erro
}
QDeclarativeNavigationBasicDirections::QDeclarativeNavigationBasicDirections(QDeclarativeNavigator *parent)
-: QObject(parent), m_navigator(parent)
+: QObject(parent), m_navigator(parent), m_routes(QByteArrayLiteral("routeData"), this)
{
if (m_navigator)
m_navigatorPrivate = m_navigator->d_ptr.data();
@@ -704,6 +712,11 @@ int QDeclarativeNavigationBasicDirections::currentSegment() const
return m_navigatorPrivate->m_navigator->currentSegment();
}
+QAbstractItemModel *QDeclarativeNavigationBasicDirections::alternativeRoutes()
+{
+ return &m_routes;
+}
+
void QDeclarativeNavigationBasicDirections::onCurrentRouteChanged()
{
if (m_currentRoute)
@@ -720,5 +733,17 @@ void QDeclarativeNavigationBasicDirections::onCurrentRouteLegChanged()
emit currentRouteLegChanged();
}
+void QDeclarativeNavigationBasicDirections::onAlternativeRoutesChanged()
+{
+ const QList<QGeoRoute> &routes = m_navigatorPrivate->m_navigator->alternativeRoutes();
+ QList<QDeclarativeGeoRoute *> declarativeRoutes;
+ for (int i = 0; i < routes.size(); ++i) {
+ QDeclarativeGeoRoute *route = new QDeclarativeGeoRoute(routes.at(i), &m_routes);
+ QQmlEngine::setContextForObject(route, QQmlEngine::contextForObject(this));
+ declarativeRoutes.append(route);
+ }
+ m_routes.updateData(declarativeRoutes);
+}
+
QT_END_NAMESPACE
diff --git a/src/location/labs/qdeclarativenavigator_p.h b/src/location/labs/qdeclarativenavigator_p.h
index 3c168c70..24ff798f 100644
--- a/src/location/labs/qdeclarativenavigator_p.h
+++ b/src/location/labs/qdeclarativenavigator_p.h
@@ -149,6 +149,8 @@ public:
NavigationError error() const;
QString errorString() const;
+ Q_INVOKABLE void recalculateRoutes();
+
signals:
void navigatorReadyChanged(bool ready);
void trackPositionSourceChanged(bool trackPositionSource);
diff --git a/src/location/labs/qdeclarativenavigator_p_p.h b/src/location/labs/qdeclarativenavigator_p_p.h
index 04b8b1ef..5bf1bd12 100644
--- a/src/location/labs/qdeclarativenavigator_p_p.h
+++ b/src/location/labs/qdeclarativenavigator_p_p.h
@@ -53,6 +53,9 @@
#include <QtCore/qpointer.h>
#include <QtLocation/qgeoroute.h>
#include <QtLocation/private/qdeclarativenavigator_p.h>
+#include <QAbstractListModel>
+#include <QtLocation/private/qdeclarativegeoroute_p.h>
+#include <QtLocation/private/qdeclarativegeoroutemodel_p.h>
QT_BEGIN_NAMESPACE
@@ -67,6 +70,48 @@ class QDeclarativeGeoRouteSegment;
class QParameterizableObject;
class QAbstractNavigator;
+template<typename T, int Role>
+class ReadOnlyListModel : public QAbstractListModel
+{
+public:
+ explicit ReadOnlyListModel(const QByteArray &dataRoleName, QObject *parent = nullptr)
+ : QAbstractListModel(parent)
+ {
+ m_roleNames.insert(Role, dataRoleName);
+ }
+
+ int rowCount(const QModelIndex &) const override
+ {
+ return m_data.size();
+ }
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
+ {
+ const int row = index.row();
+ if (!index.isValid() || row < 0 || row >= m_data.size() || role != Role)
+ return QVariant();
+
+ return QVariant::fromValue(m_data.at(row));
+ }
+
+ QHash<int, QByteArray> roleNames() const override
+ {
+ return m_roleNames;
+ }
+
+ void updateData(const QList<T*> &data)
+ {
+ beginResetModel();
+ qDeleteAll(m_data);
+ m_data = data;
+ endResetModel();
+ }
+
+protected:
+ QHash<int, QByteArray> m_roleNames;
+ QList<T*> m_data;
+};
+
class Q_LOCATION_PRIVATE_EXPORT QDeclarativeNavigationBasicDirections : public QObject
{
Q_OBJECT
@@ -83,6 +128,7 @@ class Q_LOCATION_PRIVATE_EXPORT QDeclarativeNavigationBasicDirections : public Q
Q_PROPERTY(QDeclarativeGeoRoute *currentRoute READ currentRoute NOTIFY currentRouteChanged)
Q_PROPERTY(QDeclarativeGeoRouteLeg *currentRouteLeg READ currentRouteLeg NOTIFY currentRouteChanged)
Q_PROPERTY(int currentSegment READ currentSegment NOTIFY currentSegmentChanged)
+ Q_PROPERTY(QAbstractItemModel *alternativeRoutes READ alternativeRoutes CONSTANT)
public:
explicit QDeclarativeNavigationBasicDirections(QDeclarativeNavigator *parent);
@@ -100,6 +146,7 @@ public:
QDeclarativeGeoRoute *currentRoute() const;
QDeclarativeGeoRouteLeg *currentRouteLeg() const;
int currentSegment() const;
+ QAbstractItemModel *alternativeRoutes();
Q_SIGNALS:
void progressInformationChanged();
@@ -113,12 +160,14 @@ Q_SIGNALS:
protected slots:
void onCurrentRouteChanged();
void onCurrentRouteLegChanged();
+ void onAlternativeRoutesChanged();
protected:
QDeclarativeNavigator *m_navigator;
QDeclarativeNavigatorPrivate *m_navigatorPrivate;
QPointer<QDeclarativeGeoRoute> m_currentRoute;
QPointer<QDeclarativeGeoRouteLeg> m_currentRouteLeg;
+ ReadOnlyListModel<QDeclarativeGeoRoute, QDeclarativeGeoRouteModel::RouteRole> m_routes;
friend class QDeclarativeNavigator;
};
diff --git a/src/location/maps/qnavigationmanagerengine.cpp b/src/location/maps/qnavigationmanagerengine.cpp
index 8837e5c6..aa5a980b 100644
--- a/src/location/maps/qnavigationmanagerengine.cpp
+++ b/src/location/maps/qnavigationmanagerengine.cpp
@@ -141,6 +141,11 @@ QGeoRouteLeg QAbstractNavigator::currentRouteLeg() const
return QGeoRouteLeg();
}
+QList<QGeoRoute> QAbstractNavigator::alternativeRoutes() const
+{
+ return QList<QGeoRoute>();
+}
+
int QAbstractNavigator::currentSegment() const
{
return 0;
diff --git a/src/location/maps/qnavigationmanagerengine_p.h b/src/location/maps/qnavigationmanagerengine_p.h
index 9089316f..8d2c9a99 100644
--- a/src/location/maps/qnavigationmanagerengine_p.h
+++ b/src/location/maps/qnavigationmanagerengine_p.h
@@ -98,10 +98,12 @@ public:
virtual int traveledTime() const;
virtual QGeoRoute currentRoute() const;
virtual QGeoRouteLeg currentRouteLeg() const;
+ virtual QList<QGeoRoute> alternativeRoutes() const = 0;
virtual int currentSegment() const;
virtual void setAutomaticReroutingEnabled(bool autoRerouting) = 0;
virtual bool automaticReroutingEnabled() const = 0; // configured via navigation params at construction time
virtual bool isOnRoute() = 0;
+ virtual void recalculateRoutes() = 0;
public slots:
virtual bool start() = 0;
@@ -120,6 +122,7 @@ signals:
void nextManeuverIconChanged();
void progressInformationChanged();
void isOnRouteChanged();
+ void alternativeRoutesChanged();
private:
QScopedPointer<QAbstractNavigatorPrivate> d;
diff --git a/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp b/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp
index 58092ea3..043f7682 100644
--- a/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp
+++ b/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp
@@ -49,18 +49,22 @@ Q_LOGGING_CATEGORY(lcSerial, "qt.positioning.serialnmea")
class NmeaSource : public QNmeaPositionInfoSource
{
public:
- NmeaSource(QObject *parent);
+ NmeaSource(QObject *parent, const QVariantMap &parameters);
bool isValid() const { return !m_port.isNull(); }
private:
QScopedPointer<QSerialPort> m_port;
};
-NmeaSource::NmeaSource(QObject *parent)
+NmeaSource::NmeaSource(QObject *parent, const QVariantMap &parameters)
: QNmeaPositionInfoSource(RealTimeMode, parent),
m_port(new QSerialPort)
{
- QByteArray requestedPort = qgetenv("QT_NMEA_SERIAL_PORT");
+ QByteArray requestedPort;
+ if (parameters.contains(QStringLiteral("serialnmea.serial_port")))
+ requestedPort = parameters.value(QStringLiteral("serialnmea.serial_port")).toString().toLatin1();
+ else
+ requestedPort = qgetenv("QT_NMEA_SERIAL_PORT");
if (requestedPort.isEmpty()) {
const QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts();
qCDebug(lcSerial) << "Found" << ports.count() << "serial ports";
@@ -110,18 +114,35 @@ NmeaSource::NmeaSource(QObject *parent)
QGeoPositionInfoSource *QGeoPositionInfoSourceFactorySerialNmea::positionInfoSource(QObject *parent)
{
- QScopedPointer<NmeaSource> src(new NmeaSource(parent));
- return src->isValid() ? src.take() : nullptr;
+ return positionInfoSourceWithParameters(parent, QVariantMap());
}
QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactorySerialNmea::satelliteInfoSource(QObject *parent)
{
+ return satelliteInfoSourceWithParameters(parent, QVariantMap());
+}
+
+QGeoAreaMonitorSource *QGeoPositionInfoSourceFactorySerialNmea::areaMonitor(QObject *parent)
+{
+ return areaMonitorWithParameters(parent, QVariantMap());
+}
+
+QGeoPositionInfoSource *QGeoPositionInfoSourceFactorySerialNmea::positionInfoSourceWithParameters(QObject *parent, const QVariantMap &parameters)
+{
+ QScopedPointer<NmeaSource> src(new NmeaSource(parent, parameters));
+ return src->isValid() ? src.take() : nullptr;
+}
+
+QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactorySerialNmea::satelliteInfoSourceWithParameters(QObject *parent, const QVariantMap &parameters)
+{
Q_UNUSED(parent);
+ Q_UNUSED(parameters)
return nullptr;
}
-QGeoAreaMonitorSource *QGeoPositionInfoSourceFactorySerialNmea::areaMonitor(QObject *parent)
+QGeoAreaMonitorSource *QGeoPositionInfoSourceFactorySerialNmea::areaMonitorWithParameters(QObject *parent, const QVariantMap &parameters)
{
Q_UNUSED(parent);
+ Q_UNUSED(parameters)
return nullptr;
}
diff --git a/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.h b/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.h
index e372d56f..c8ca0e7e 100644
--- a/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.h
+++ b/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.h
@@ -43,17 +43,21 @@
#include <QObject>
#include <qgeopositioninfosourcefactory.h>
-class QGeoPositionInfoSourceFactorySerialNmea : public QObject, public QGeoPositionInfoSourceFactory
+class QGeoPositionInfoSourceFactorySerialNmea : public QObject, public QGeoPositionInfoSourceFactoryV2
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/5.0"
FILE "plugin.json")
- Q_INTERFACES(QGeoPositionInfoSourceFactory)
+ Q_INTERFACES(QGeoPositionInfoSourceFactoryV2)
public:
QGeoPositionInfoSource *positionInfoSource(QObject *parent);
QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent);
QGeoAreaMonitorSource *areaMonitor(QObject *parent);
+
+ QGeoPositionInfoSource *positionInfoSourceWithParameters(QObject *parent, const QVariantMap &parameters);
+ QGeoSatelliteInfoSource *satelliteInfoSourceWithParameters(QObject *parent, const QVariantMap &parameters);
+ QGeoAreaMonitorSource *areaMonitorWithParameters(QObject *parent, const QVariantMap &parameters);
};
#endif
diff --git a/src/positioning/doc/qtpositioning.qdocconf b/src/positioning/doc/qtpositioning.qdocconf
index 3f6438ef..41a06c49 100644
--- a/src/positioning/doc/qtpositioning.qdocconf
+++ b/src/positioning/doc/qtpositioning.qdocconf
@@ -1,4 +1,5 @@
include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
+include($QT_INSTALL_DOCS/config/exampleurl-qtlocation.qdocconf)
project = QtPositioning
description = Qt Positioning Reference Documentation
diff --git a/src/positioning/qgeopositioninfosource.cpp b/src/positioning/qgeopositioninfosource.cpp
index 29a0d019..69fcdef0 100644
--- a/src/positioning/qgeopositioninfosource.cpp
+++ b/src/positioning/qgeopositioninfosource.cpp
@@ -108,6 +108,11 @@ QGeoPositionInfoSourcePrivate *QGeoPositionInfoSourcePrivate::get(const QGeoPosi
return source.d;
}
+QGeoPositionInfoSourcePrivate::~QGeoPositionInfoSourcePrivate()
+{
+
+}
+
void QGeoPositionInfoSourcePrivate::loadMeta()
{
metaData = plugins().value(providerName);
@@ -128,6 +133,16 @@ void QGeoPositionInfoSourcePrivate::loadPlugin()
factory = factoryV2;
}
+bool QGeoPositionInfoSourcePrivate::setBackendProperty(const QString &/*name*/, QVariant /*value*/)
+{
+ return false;
+}
+
+QVariant QGeoPositionInfoSourcePrivate::backendProperty(const QString &/*name*/) const
+{
+ return QVariant();
+}
+
QHash<QString, QJsonObject> QGeoPositionInfoSourcePrivate::plugins(bool reload)
{
static QHash<QString, QJsonObject> plugins;
@@ -216,6 +231,36 @@ QString QGeoPositionInfoSource::sourceName() const
}
/*!
+ Sets the backend-specific property named \a name to \a value.
+ Returns \c true on success, \c false otherwise.
+ Backend-specific properties can be used to configure the positioning subsystem behavior
+ at runtime.
+ Supported backend-specific properties are listed and described in
+ \l {Qt Positioning plugins#Default plugins}.
+
+ \sa backendProperty
+ \since Qt 5.14
+*/
+bool QGeoPositionInfoSource::setBackendProperty(const QString &name, QVariant value)
+{
+ return d->setBackendProperty(name, value);
+}
+
+/*!
+ Returns the value of the backend-specific property named \a name, if present.
+ Otherwise, the returned value will be invalid.
+ Supported backend-specific properties are listed and described in
+ \l {Qt Positioning plugins#Default plugins}.
+
+ \sa setBackendProperty
+ \since Qt 5.14
+*/
+QVariant QGeoPositionInfoSource::backendProperty(const QString &name) const
+{
+ return d->backendProperty(name);
+}
+
+/*!
\property QGeoPositionInfoSource::updateInterval
\brief This property holds the requested interval in milliseconds between each update.
@@ -382,6 +427,15 @@ QStringList QGeoPositionInfoSource::availableSources()
return plugins;
}
+QGeoPositionInfoSource::QGeoPositionInfoSource(QGeoPositionInfoSourcePrivate &dd, QObject *parent)
+: QObject(parent),
+ d(&dd)
+{
+ qRegisterMetaType<QGeoPositionInfo>();
+ d->interval = 0;
+ d->methods = NoPositioningMethods;
+}
+
/*!
\fn QGeoPositionInfo QGeoPositionInfoSource::lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const = 0;
diff --git a/src/positioning/qgeopositioninfosource.h b/src/positioning/qgeopositioninfosource.h
index 23b3ac46..eaf5e106 100644
--- a/src/positioning/qgeopositioninfosource.h
+++ b/src/positioning/qgeopositioninfosource.h
@@ -87,6 +87,9 @@ public:
QString sourceName() const;
+ bool setBackendProperty(const QString &name, QVariant value);
+ QVariant backendProperty(const QString &name) const;
+
static QGeoPositionInfoSource *createDefaultSource(QObject *parent);
static QGeoPositionInfoSource *createDefaultSource(const QVariantMap &parameters, QObject *parent);
static QGeoPositionInfoSource *createSource(const QString &sourceName, QObject *parent);
@@ -106,6 +109,9 @@ Q_SIGNALS:
void error(QGeoPositionInfoSource::Error);
void supportedPositioningMethodsChanged();
+protected:
+ QGeoPositionInfoSource(QGeoPositionInfoSourcePrivate &dd, QObject *parent);
+
private:
Q_DISABLE_COPY(QGeoPositionInfoSource)
QGeoPositionInfoSourcePrivate *d;
diff --git a/src/positioning/qgeopositioninfosource_p.h b/src/positioning/qgeopositioninfosource_p.h
index f5f85ec9..ccd92a4e 100644
--- a/src/positioning/qgeopositioninfosource_p.h
+++ b/src/positioning/qgeopositioninfosource_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <QtPositioning/private/qpositioningglobal_p.h>
#include "qgeopositioninfosource.h"
#include "qgeopositioninfosourcefactory.h"
#include <QJsonObject>
@@ -60,10 +61,11 @@
QT_BEGIN_NAMESPACE
-class QGeoPositionInfoSourcePrivate
+class Q_POSITIONING_PRIVATE_EXPORT QGeoPositionInfoSourcePrivate
{
public:
static QGeoPositionInfoSourcePrivate *get(const QGeoPositionInfoSource &source);
+ virtual ~QGeoPositionInfoSourcePrivate();
int interval;
QGeoPositionInfoSource::PositioningMethods methods;
@@ -74,6 +76,8 @@ public:
void loadMeta();
void loadPlugin();
+ virtual bool setBackendProperty(const QString &name, QVariant value);
+ virtual QVariant backendProperty(const QString &name) const;
static QHash<QString, QJsonObject> plugins(bool reload = false);
static void loadPluginMetadata(QHash<QString, QJsonObject> &list);
diff --git a/src/positioningquick/qdeclarativepositionsource.cpp b/src/positioningquick/qdeclarativepositionsource.cpp
index c9fd2c8e..cfbcc9da 100644
--- a/src/positioningquick/qdeclarativepositionsource.cpp
+++ b/src/positioningquick/qdeclarativepositionsource.cpp
@@ -43,7 +43,8 @@
#include <QtCore/QCoreApplication>
#include <QtQml/qqmlinfo.h>
#include <QtQml/qqml.h>
-#include <qnmeapositioninfosource.h>
+#include <QtPositioning/qnmeapositioninfosource.h>
+#include <qdeclarativepluginparameter_p.h>
#include <QFile>
#include <QtNetwork/QTcpSocket>
#include <QTimer>
@@ -109,7 +110,7 @@ QT_BEGIN_NAMESPACE
a PositionSource in your application to retrieve local data for users
from a REST web service.
- \sa {QtPositioning::Position}, {QGeoPositionInfoSource}
+ \sa {QtPositioning::Position}, {QGeoPositionInfoSource}, {PluginParameter}
*/
@@ -164,7 +165,7 @@ QString QDeclarativePositionSource::name() const
if (m_positionSource)
return m_positionSource->sourceName();
else
- return QString();
+ return m_providerName;
}
void QDeclarativePositionSource::setName(const QString &newName)
@@ -172,15 +173,41 @@ void QDeclarativePositionSource::setName(const QString &newName)
if (m_positionSource && m_positionSource->sourceName() == newName)
return;
+ if (m_providerName == newName && m_providerName.isEmpty())
+ return; // previously attached to a default source, now requesting the same.
+
const QString previousName = name();
+ m_providerName = newName;
+
+ if (!m_componentComplete || !m_parametersInitialized) {
+ if (previousName != name())
+ emit nameChanged();
+ return;
+ }
+
+ tryAttach(newName, false);
+}
+
+/*!
+ \internal
+*/
+void QDeclarativePositionSource::tryAttach(const QString &newName, bool useFallback)
+{
+ const QString previousName = name();
+ const bool sourceExisted = m_positionSource;
+ m_providerName = newName;
+
int previousUpdateInterval = updateInterval();
PositioningMethods previousPositioningMethods = supportedPositioningMethods();
PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods();
- if (newName.isEmpty())
- setSource(QGeoPositionInfoSource::createDefaultSource(this));
- else
- setSource(QGeoPositionInfoSource::createSource(newName, this));
+ if (newName.isEmpty()) {
+ setSource(QGeoPositionInfoSource::createDefaultSource(parameterMap(), this));
+ } else {
+ setSource(QGeoPositionInfoSource::createSource(newName, parameterMap(), this));
+ if (!m_positionSource && useFallback)
+ setSource(QGeoPositionInfoSource::createDefaultSource(parameterMap(), this));
+ }
if (m_positionSource) {
connect(m_positionSource, SIGNAL(positionUpdated(QGeoPositionInfo)),
@@ -194,7 +221,12 @@ void QDeclarativePositionSource::setName(const QString &newName)
m_positionSource->setPreferredPositioningMethods(
static_cast<QGeoPositionInfoSource::PositioningMethods>(int(m_preferredPositioningMethods)));
- setPosition(m_positionSource->lastKnownPosition());
+ const QGeoPositionInfo &lastKnown = m_positionSource->lastKnownPosition();
+ if (lastKnown.isValid())
+ setPosition(lastKnown);
+ } else if (m_active) {
+ m_active = false;
+ emit activeChanged();
}
if (previousUpdateInterval != updateInterval())
@@ -208,9 +240,13 @@ void QDeclarativePositionSource::setName(const QString &newName)
emit validityChanged();
- if (m_active) {
- m_active = false;
- emit activeChanged();
+ if (m_active) { // implies m_positionSource
+ if (!sourceExisted) {
+ QTimer::singleShot(0, this, SLOT(start())); // delay ensures all properties have been set
+ } else {
+ m_active = false;
+ emit activeChanged();
+ }
}
if (previousName != name())
@@ -232,9 +268,6 @@ bool QDeclarativePositionSource::isValid() const
return (m_positionSource != 0);
}
-/*!
- \internal
-*/
void QDeclarativePositionSource::setNmeaSource(const QUrl &nmeaSource)
{
if (nmeaSource.scheme() == QLatin1String("socket")) {
@@ -411,6 +444,24 @@ void QDeclarativePositionSource::updateTimeoutReceived()
emit updateTimeout();
}
+/*!
+ \internal
+*/
+void QDeclarativePositionSource::onParameterInitialized()
+{
+ m_parametersInitialized = true;
+ for (QDeclarativePluginParameter *p: qAsConst(m_parameters)) {
+ if (!p->isInitialized()) {
+ m_parametersInitialized = false;
+ break;
+ }
+ }
+
+ // If here, componentComplete has been called.
+ if (m_parametersInitialized)
+ tryAttach(m_providerName);
+}
+
void QDeclarativePositionSource::setPosition(const QGeoPositionInfo &pi)
{
m_position.setPosition(pi);
@@ -431,6 +482,30 @@ void QDeclarativePositionSource::setSource(QGeoPositionInfoSource *source)
}
}
+bool QDeclarativePositionSource::parametersReady()
+{
+ for (const QDeclarativePluginParameter *p: qAsConst(m_parameters)) {
+ if (!p->isInitialized())
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \internal
+*/
+QVariantMap QDeclarativePositionSource::parameterMap() const
+{
+ QVariantMap map;
+
+ for (int i = 0; i < m_parameters.size(); ++i) {
+ QDeclarativePluginParameter *parameter = m_parameters.at(i);
+ map.insert(parameter->name(), parameter->value());
+ }
+
+ return map;
+}
+
/*!
\internal
*/
@@ -717,47 +792,111 @@ QGeoPositionInfoSource *QDeclarativePositionSource::positionSource() const
return m_positionSource;
}
-void QDeclarativePositionSource::componentComplete()
+/*!
+ \qmlproperty list<PluginParameter> PositionSource::parameters
+ \default
+
+ This property holds the list of plugin parameters.
+
+ \since QtPositioning 5.14
+*/
+QQmlListProperty<QDeclarativePluginParameter> QDeclarativePositionSource::parameters()
{
- if (!m_positionSource) {
- int previousUpdateInterval = updateInterval();
- PositioningMethods previousPositioningMethods = supportedPositioningMethods();
- PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods();
+ return QQmlListProperty<QDeclarativePluginParameter>(this,
+ 0,
+ parameter_append,
+ parameter_count,
+ parameter_at,
+ parameter_clear);
+}
- setSource(QGeoPositionInfoSource::createDefaultSource(this));
- if (m_positionSource) {
- connect(m_positionSource, SIGNAL(positionUpdated(QGeoPositionInfo)),
- this, SLOT(positionUpdateReceived(QGeoPositionInfo)));
- connect(m_positionSource, SIGNAL(error(QGeoPositionInfoSource::Error)),
- this, SLOT(sourceErrorReceived(QGeoPositionInfoSource::Error)));
- connect(m_positionSource, SIGNAL(updateTimeout()),
- this, SLOT(updateTimeoutReceived()));
+/*!
+ \internal
+*/
+void QDeclarativePositionSource::parameter_append(QQmlListProperty<QDeclarativePluginParameter> *prop, QDeclarativePluginParameter *parameter)
+{
+ QDeclarativePositionSource *p = static_cast<QDeclarativePositionSource *>(prop->object);
+ p->m_parameters.append(parameter);
+}
- m_positionSource->setUpdateInterval(m_updateInterval);
- m_positionSource->setPreferredPositioningMethods(
- static_cast<QGeoPositionInfoSource::PositioningMethods>(int(m_preferredPositioningMethods)));
+/*!
+ \internal
+*/
+int QDeclarativePositionSource::parameter_count(QQmlListProperty<QDeclarativePluginParameter> *prop)
+{
+ return static_cast<QDeclarativePositionSource *>(prop->object)->m_parameters.count();
+}
- setPosition(m_positionSource->lastKnownPosition());
+/*!
+ \internal
+*/
+QDeclarativePluginParameter *QDeclarativePositionSource::parameter_at(QQmlListProperty<QDeclarativePluginParameter> *prop, int index)
+{
+ return static_cast<QDeclarativePositionSource *>(prop->object)->m_parameters[index];
+}
- if (m_active)
- QTimer::singleShot(0, this, SLOT(start())); // delay ensures all properties have been set
- } else if (m_active) {
- m_active = false;
- emit activeChanged();
+/*!
+ \internal
+*/
+void QDeclarativePositionSource::parameter_clear(QQmlListProperty<QDeclarativePluginParameter> *prop)
+{
+ QDeclarativePositionSource *p = static_cast<QDeclarativePositionSource *>(prop->object);
+ p->m_parameters.clear();
+}
+
+
+void QDeclarativePositionSource::componentComplete()
+{
+ m_componentComplete = true;
+ m_parametersInitialized = true;
+ for (QDeclarativePluginParameter *p: qAsConst(m_parameters)) {
+ if (!p->isInitialized()) {
+ m_parametersInitialized = false;
+ connect(p, &QDeclarativePluginParameter::initialized,
+ this, &QDeclarativePositionSource::onParameterInitialized);
}
+ }
- if (previousUpdateInterval != updateInterval())
- emit updateIntervalChanged();
+ if (m_parametersInitialized)
+ tryAttach(m_providerName);
+}
- if (previousPreferredPositioningMethods != preferredPositioningMethods())
- emit preferredPositioningMethodsChanged();
+/*!
+ \qmlmethod bool QtLocation::PositionSource::setBackendProperty(string name, Variant value)
- if (previousPositioningMethods != supportedPositioningMethods())
- emit supportedPositioningMethodsChanged();
+ Sets the backend-specific property named \a name to \a value.
+ Returns true on success, false otherwise, including if called on an uninitialized PositionSource.
+ Supported backend-specific properties are listed and described in
+ \l {Qt Positioning plugins#Default plugins}.
- emit validityChanged();
- emit nameChanged();
- }
+ \since Qt Positioning 5.14
+
+ \sa backendProperty, QGeoPositionInfoSource::setBackendProperty
+*/
+bool QDeclarativePositionSource::setBackendProperty(const QString &name, QVariant value)
+{
+ if (m_positionSource)
+ return m_positionSource->setBackendProperty(name, value);
+ return false;
+}
+
+/*!
+ \qmlmethod Variant QtLocation::PositionSource::backendProperty(string name)
+
+ Returns the value of the backend-specific property named \a name, if present.
+ Otherwise, including if called on an uninitialized PositionSource, the return value will be invalid.
+ Supported backend-specific properties are listed and described in
+ \l {Qt Positioning plugins#Default plugins}.
+
+ \since Qt Positioning 5.14
+
+ \sa backendProperty, QGeoPositionInfoSource::setBackendProperty
+*/
+QVariant QDeclarativePositionSource::backendProperty(const QString &name) const
+{
+ if (m_positionSource)
+ return m_positionSource->backendProperty(name);
+ return QVariant();
}
/*!
diff --git a/src/positioningquick/qdeclarativepositionsource_p.h b/src/positioningquick/qdeclarativepositionsource_p.h
index c6daaae5..dff0006c 100644
--- a/src/positioningquick/qdeclarativepositionsource_p.h
+++ b/src/positioningquick/qdeclarativepositionsource_p.h
@@ -56,7 +56,8 @@
#include <QtCore/QObject>
#include <QtNetwork/QAbstractSocket>
#include <QtQml/QQmlParserStatus>
-#include <QtPositioning/QGeoPositionInfoSource>
+#include <QtPositioning/qgeopositioninfosource.h>
+#include <QtPositioningQuick/private/qdeclarativepluginparameter_p.h>
QT_BEGIN_NAMESPACE
@@ -76,8 +77,10 @@ class Q_POSITIONINGQUICK_PRIVATE_EXPORT QDeclarativePositionSource : public QObj
Q_PROPERTY(PositioningMethods preferredPositioningMethods READ preferredPositioningMethods WRITE setPreferredPositioningMethods NOTIFY preferredPositioningMethodsChanged)
Q_PROPERTY(SourceError sourceError READ sourceError NOTIFY sourceErrorChanged)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+ Q_PROPERTY(QQmlListProperty<QDeclarativePluginParameter> parameters READ parameters REVISION 14)
Q_ENUMS(PositioningMethod)
+ Q_CLASSINFO("DefaultProperty", "parameters")
Q_INTERFACES(QQmlParserStatus)
public:
@@ -121,11 +124,16 @@ public:
PositioningMethods preferredPositioningMethods() const;
SourceError sourceError() const;
QGeoPositionInfoSource *positionSource() const;
+ QQmlListProperty<QDeclarativePluginParameter> parameters();
+ QVariantMap parameterMap() const;
// Virtuals from QQmlParserStatus
void classBegin() { }
void componentComplete();
+ Q_INVOKABLE bool setBackendProperty(const QString &name, QVariant value);
+ Q_INVOKABLE QVariant backendProperty(const QString &name) const;
+
public Q_SLOTS:
void update(); // TODO Qt 6 change to void update(int)
void start();
@@ -149,10 +157,18 @@ private Q_SLOTS:
void socketConnected();
void socketError(QAbstractSocket::SocketError error);
void updateTimeoutReceived();
+ void onParameterInitialized();
private:
void setPosition(const QGeoPositionInfo &pi);
void setSource(QGeoPositionInfoSource *source);
+ bool parametersReady();
+ void tryAttach(const QString &name, bool useFallback = true);
+
+ static void parameter_append(QQmlListProperty<QDeclarativePluginParameter> *prop, QDeclarativePluginParameter *mapObject);
+ static int parameter_count(QQmlListProperty<QDeclarativePluginParameter> *prop);
+ static QDeclarativePluginParameter *parameter_at(QQmlListProperty<QDeclarativePluginParameter> *prop, int index);
+ static void parameter_clear(QQmlListProperty<QDeclarativePluginParameter> *prop);
QGeoPositionInfoSource *m_positionSource;
QDeclarativePosition m_position;
@@ -161,10 +177,14 @@ private:
QTcpSocket *m_nmeaSocket;
QString m_nmeaFileName;
QUrl m_nmeaSource;
+ QString m_providerName;
bool m_active;
bool m_singleUpdate;
int m_updateInterval;
SourceError m_sourceError;
+ QList<QDeclarativePluginParameter *> m_parameters;
+ bool m_componentComplete = false;
+ bool m_parametersInitialized = false;
};
QT_END_NAMESPACE
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 745e264b..05559d12 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -86,6 +86,7 @@ SUBDIRS += \
!android: SUBDIRS += \
positionplugin \
+ positionpluginV1 \
positionplugintest \
qgeoareamonitor \
qgeopositioninfosource \
diff --git a/tests/auto/declarative_core/tst_positionsource.qml b/tests/auto/declarative_core/tst_positionsource.qml
index a663f3ab..7b787a0c 100644
--- a/tests/auto/declarative_core/tst_positionsource.qml
+++ b/tests/auto/declarative_core/tst_positionsource.qml
@@ -28,7 +28,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtPositioning 5.2
+import QtPositioning 5.14
TestCase {
id: testCase
@@ -106,6 +106,26 @@ TestCase {
SignalSpy { id: directionValidSpy; target: testingSource.position; signalName: "directionValidChanged" }
SignalSpy { id: directionSpy; target: testingSource.position; signalName: "directionChanged" }
+ PositionSource {
+ id: testingSourceWParams
+ name: "test.source"
+ updateInterval: 1000
+ PluginParameter {
+ id: altitudeParameter
+ name: "test.source.altitude"
+ value: 42.42
+ }
+ }
+
+ SignalSpy { id: updateSpyWParams; target: testingSourceWParams; signalName: "positionChanged" }
+ SignalSpy { id: directionValidSpyWParams; target: testingSourceWParams.position; signalName: "directionValidChanged" }
+ SignalSpy { id: directionSpyWParams; target: testingSourceWParams.position; signalName: "directionChanged" }
+
+ PositionSource { id: testingSourceV1; name: "test.source.v1"; updateInterval: 1000 }
+ SignalSpy { id: updateSpyV1; target: testingSourceV1; signalName: "positionChanged" }
+ SignalSpy { id: directionValidSpyV1; target: testingSourceV1.position; signalName: "directionValidChanged" }
+ SignalSpy { id: directionSpyV1; target: testingSourceV1.position; signalName: "directionChanged" }
+
function test_updateInterval() {
testingSource.updateInterval = 1000;
compare(testingSource.updateInterval, 1000);
@@ -125,40 +145,83 @@ TestCase {
}
function test_updates() {
- updateSpy.clear();
-
- compare(directionValidSpy.count, 0)
- compare(directionSpy.count, 0)
-
- testingSource.active = true;
-
- tryCompare(updateSpy, "count", 1, 1500);
- compare(testingSource.position.coordinate.longitude, 0.1);
- compare(testingSource.position.coordinate.latitude, 0.1);
- compare(directionValidSpy.count, 1)
- compare(directionSpy.count, 1)
- fuzzyCompare(testingSource.position.direction, 45, 0.1)
- verify(!testingSource.position.speedValid)
- verify(isNaN(testingSource.position.speed))
-
- tryCompare(updateSpy, "count", 2, 1500);
- compare(testingSource.position.coordinate.longitude, 0.2);
- compare(testingSource.position.coordinate.latitude, 0.2);
- compare(directionValidSpy.count, 1)
- compare(directionSpy.count, 2)
- fuzzyCompare(testingSource.position.direction, 45, 0.1)
- verify(testingSource.position.speedValid)
- verify(testingSource.position.speed > 10000)
-
- testingSource.active = false;
+ updateSpyV1.clear();
+
+ compare(directionValidSpyV1.count, 0)
+ compare(directionSpyV1.count, 0)
+
+ testingSourceV1.active = true;
+
+ tryCompare(updateSpyV1, "count", 1, 1500);
+ compare(testingSourceV1.position.coordinate.longitude, 0.1);
+ compare(testingSourceV1.position.coordinate.latitude, 0.1);
+ compare(directionValidSpyV1.count, 1)
+ compare(directionSpyV1.count, 1)
+ fuzzyCompare(testingSourceV1.position.direction, 45, 0.1)
+ verify(!testingSourceV1.position.speedValid)
+ verify(isNaN(testingSourceV1.position.speed))
+
+ tryCompare(updateSpyV1, "count", 2, 1500);
+ compare(testingSourceV1.position.coordinate.longitude, 0.2);
+ compare(testingSourceV1.position.coordinate.latitude, 0.2);
+ compare(directionValidSpyV1.count, 1)
+ compare(directionSpyV1.count, 2)
+ fuzzyCompare(testingSourceV1.position.direction, 45, 0.1)
+ verify(testingSourceV1.position.speedValid)
+ verify(testingSourceV1.position.speed > 10000)
+
+ testingSourceV1.active = false;
+ wait(2500);
+ compare(updateSpyV1.count, 2);
+ compare(testingSourceV1.position.coordinate.longitude, 0.2);
+ compare(testingSourceV1.position.coordinate.latitude, 0.2);
+ compare(directionValidSpyV1.count, 1)
+ compare(directionSpyV1.count, 2)
+ fuzzyCompare(testingSourceV1.position.direction, 45, 0.1)
+ verify(testingSourceV1.position.speedValid)
+ verify(testingSourceV1.position.speed > 10000)
+ }
+
+ function test_updates_w_params() {
+ updateSpyWParams.clear();
+
+ compare(directionValidSpyWParams.count, 0)
+ compare(directionSpyWParams.count, 0)
+ compare(testingSourceWParams.backendProperty("altitude"), altitudeParameter.value)
+ testingSourceWParams.active = true;
+
+ tryCompare(updateSpyWParams, "count", 1, 1500);
+ compare(testingSourceWParams.position.coordinate.longitude, 0.1);
+ compare(testingSourceWParams.position.coordinate.latitude, 0.1);
+ compare(testingSourceWParams.position.coordinate.altitude, altitudeParameter.value);
+ compare(directionValidSpyWParams.count, 1)
+ compare(directionSpyWParams.count, 1)
+ fuzzyCompare(testingSourceWParams.position.direction, 45, 0.1)
+ verify(!testingSourceWParams.position.speedValid)
+ verify(isNaN(testingSourceWParams.position.speed))
+ testingSourceWParams.setBackendProperty("altitude", 24.24)
+
+ tryCompare(updateSpyWParams, "count", 2, 1500);
+ compare(testingSourceWParams.position.coordinate.longitude, 0.2);
+ compare(testingSourceWParams.position.coordinate.latitude, 0.2);
+ compare(testingSourceWParams.position.coordinate.altitude, 24.24);
+ compare(directionValidSpyWParams.count, 1)
+ compare(directionSpyWParams.count, 2)
+ fuzzyCompare(testingSourceWParams.position.direction, 45, 0.1)
+ verify(testingSourceWParams.position.speedValid)
+ verify(testingSourceWParams.position.speed > 10000)
+ compare(testingSourceWParams.backendProperty("altitude"), 24.24)
+
+ testingSourceWParams.active = false;
wait(2500);
- compare(updateSpy.count, 2);
- compare(testingSource.position.coordinate.longitude, 0.2);
- compare(testingSource.position.coordinate.latitude, 0.2);
- compare(directionValidSpy.count, 1)
- compare(directionSpy.count, 2)
- fuzzyCompare(testingSource.position.direction, 45, 0.1)
- verify(testingSource.position.speedValid)
- verify(testingSource.position.speed > 10000)
+ compare(updateSpyWParams.count, 2);
+ compare(testingSourceWParams.position.coordinate.longitude, 0.2);
+ compare(testingSourceWParams.position.coordinate.latitude, 0.2);
+ compare(testingSourceWParams.position.coordinate.altitude, 24.24);
+ compare(directionValidSpyWParams.count, 1)
+ compare(directionSpyWParams.count, 2)
+ fuzzyCompare(testingSourceWParams.position.direction, 45, 0.1)
+ verify(testingSourceWParams.position.speedValid)
+ verify(testingSourceWParams.position.speed > 10000)
}
}
diff --git a/tests/auto/positionplugin/plugin.cpp b/tests/auto/positionplugin/plugin.cpp
index a15a89a5..9d5c7dd5 100644
--- a/tests/auto/positionplugin/plugin.cpp
+++ b/tests/auto/positionplugin/plugin.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include <QtPositioning/qgeopositioninfosource.h>
+#include <QtPositioning/private/qgeopositioninfosource_p.h>
#include <QtPositioning/qgeopositioninfosourcefactory.h>
#include <QObject>
#include <QtPlugin>
@@ -39,7 +40,7 @@ class DummySource : public QGeoPositionInfoSource
Q_OBJECT
public:
- DummySource(QObject *parent=0);
+ DummySource(const QVariantMap &parameters, QObject *parent=0);
~DummySource();
void startUpdates();
@@ -65,13 +66,42 @@ private slots:
void doTimeout();
};
-DummySource::DummySource(QObject *parent) :
- QGeoPositionInfoSource(parent),
+class DummySourcePrivate : public QGeoPositionInfoSourcePrivate
+{
+public:
+ bool setBackendProperty(const QString &name, QVariant value) override
+ {
+ if (name == QStringLiteral("altitude")) {
+ m_altitude = value.toReal();
+ return true;
+ }
+ return false;
+ }
+ QVariant backendProperty(const QString &name) const override
+ {
+ if (name == QStringLiteral("altitude"))
+ return m_altitude;
+ return QVariant();
+ }
+
+ qreal m_altitude = 0.0;
+};
+
+DummySource::DummySource(const QVariantMap &parameters, QObject *parent) :
+ QGeoPositionInfoSource(*new DummySourcePrivate, parent),
timer(new QTimer(this)),
timeoutTimer(new QTimer(this)),
singleTimer(new QTimer(this)),
lastPosition(QGeoCoordinate(0,0), QDateTime::currentDateTime())
{
+ DummySourcePrivate *dd = static_cast<DummySourcePrivate *>(QGeoPositionInfoSourcePrivate::get(*this));
+ if (parameters.contains(QStringLiteral("test.source.altitude"))) {
+ const qreal alti = parameters.value(QStringLiteral("test.source.altitude")).toReal();
+ dd->m_altitude = alti;
+ QGeoCoordinate crd = lastPosition.coordinate();
+ crd.setAltitude(alti);
+ lastPosition.setCoordinate(crd);
+ }
timer->setInterval(1000);
connect(timer, SIGNAL(timeout()),
this, SLOT(updatePosition()));
@@ -151,13 +181,15 @@ DummySource::~DummySource()
void DummySource::updatePosition()
{
+ DummySourcePrivate *dd = static_cast<DummySourcePrivate *>(QGeoPositionInfoSourcePrivate::get(*this));
timeoutTimer->stop();
singleTimer->stop();
const QDateTime now = QDateTime::currentDateTime();
QGeoCoordinate coord(lastPosition.coordinate().latitude() + 0.1,
- lastPosition.coordinate().longitude() + 0.1);
+ lastPosition.coordinate().longitude() + 0.1,
+ dd->m_altitude);
QGeoPositionInfo info(coord, now);
info.setAttribute(QGeoPositionInfo::Direction, lastPosition.coordinate().azimuthTo(coord));
@@ -179,35 +211,55 @@ void DummySource::doTimeout()
}
-class QGeoPositionInfoSourceFactoryTest : public QObject, public QGeoPositionInfoSourceFactory
+class QGeoPositionInfoSourceFactoryTest : public QObject, public QGeoPositionInfoSourceFactoryV2
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/5.0"
FILE "plugin.json")
- Q_INTERFACES(QGeoPositionInfoSourceFactory)
+ Q_INTERFACES(QGeoPositionInfoSourceFactoryV2)
public:
QGeoPositionInfoSource *positionInfoSource(QObject *parent);
QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent);
QGeoAreaMonitorSource *areaMonitor(QObject *parent);
+
+ QGeoPositionInfoSource *positionInfoSourceWithParameters(QObject *parent, const QVariantMap &parameters);
+ QGeoSatelliteInfoSource *satelliteInfoSourceWithParameters(QObject *parent, const QVariantMap &parameters);
+ QGeoAreaMonitorSource *areaMonitorWithParameters(QObject *parent, const QVariantMap &parameters);
};
QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryTest::positionInfoSource(QObject *parent)
{
- return new DummySource(parent);
+ return new DummySource(QVariantMap(), parent);
}
QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryTest::satelliteInfoSource(QObject *parent)
{
- Q_UNUSED(parent);
- // not implemented
- return 0;
+ return satelliteInfoSourceWithParameters(parent, QVariantMap());
}
QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryTest::areaMonitor(QObject* parent)
{
+ return areaMonitorWithParameters(parent, QVariantMap());
+}
+
+QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryTest::positionInfoSourceWithParameters(QObject *parent, const QVariantMap &parameters)
+{
+ return new DummySource(parameters, parent);
+}
+
+QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryTest::satelliteInfoSourceWithParameters(QObject *parent, const QVariantMap &parameters)
+{
+ Q_UNUSED(parent);
+ Q_UNUSED(parameters)
+ return nullptr;
+}
+
+QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryTest::areaMonitorWithParameters(QObject *parent, const QVariantMap &parameters)
+{
Q_UNUSED(parent);
- return 0;
+ Q_UNUSED(parameters)
+ return nullptr;
}
#include "plugin.moc"
diff --git a/tests/auto/positionplugin/plugin.json b/tests/auto/positionplugin/plugin.json
index 68acaded..a38d2a5a 100644
--- a/tests/auto/positionplugin/plugin.json
+++ b/tests/auto/positionplugin/plugin.json
@@ -4,6 +4,6 @@
"Position": true,
"Satellite": false,
"Monitor": false,
- "Priority": 0,
+ "Priority": 1,
"Testable": true
}
diff --git a/tests/auto/positionplugin/positionplugin.pro b/tests/auto/positionplugin/positionplugin.pro
index dd04e7fb..84d08ac0 100644
--- a/tests/auto/positionplugin/positionplugin.pro
+++ b/tests/auto/positionplugin/positionplugin.pro
@@ -1,8 +1,8 @@
TARGET = qtposition_testplugin
-QT += positioning
+QT += positioning-private
PLUGIN_TYPE = position
-PLUGIN_CLASS_NAME = TestPositionPlugin
+PLUGIN_CLASS_NAME = QGeoPositionInfoSourceFactoryTest
PLUGIN_EXTENDS = -
load(qt_plugin)
diff --git a/tests/auto/positionpluginV1/plugin.cpp b/tests/auto/positionpluginV1/plugin.cpp
new file mode 100644
index 00000000..bf8b8234
--- /dev/null
+++ b/tests/auto/positionpluginV1/plugin.cpp
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 <QtPositioning/qgeopositioninfosource.h>
+#include <QtPositioning/qgeopositioninfosourcefactory.h>
+#include <QObject>
+#include <QtPlugin>
+#include <QTimer>
+
+QT_USE_NAMESPACE
+
+class DummySource : public QGeoPositionInfoSource
+{
+ Q_OBJECT
+
+public:
+ DummySource(QObject *parent = nullptr);
+ ~DummySource();
+
+ void startUpdates();
+ void stopUpdates();
+ void requestUpdate(int timeout=5000);
+
+ QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const;
+ PositioningMethods supportedPositioningMethods() const;
+
+ void setUpdateInterval(int msec);
+ int minimumUpdateInterval() const;
+ Error error() const;
+
+private:
+ QTimer *timer;
+ QTimer *timeoutTimer;
+ QTimer *singleTimer;
+ QGeoPositionInfo lastPosition;
+ QDateTime lastUpdateTime;
+
+private slots:
+ void updatePosition();
+ void doTimeout();
+};
+
+DummySource::DummySource(QObject *parent) :
+ QGeoPositionInfoSource(parent),
+ timer(new QTimer(this)),
+ timeoutTimer(new QTimer(this)),
+ singleTimer(new QTimer(this)),
+ lastPosition(QGeoCoordinate(0,0), QDateTime::currentDateTime())
+{
+ timer->setInterval(1000);
+ connect(timer, SIGNAL(timeout()),
+ this, SLOT(updatePosition()));
+ connect(singleTimer, SIGNAL(timeout()),
+ this, SLOT(updatePosition()));
+ connect(timeoutTimer, SIGNAL(timeout()),
+ this, SLOT(doTimeout()));
+}
+
+QGeoPositionInfoSource::Error DummySource::error() const
+{
+ return QGeoPositionInfoSource::NoError;
+}
+
+
+void DummySource::setUpdateInterval(int msec)
+{
+ if (msec == 0) {
+ timer->setInterval(1000);
+ } else if (msec < 1000) {
+ msec = 1000;
+ timer->setInterval(msec);
+ } else {
+ timer->setInterval(msec);
+ }
+
+ QGeoPositionInfoSource::setUpdateInterval(msec);
+}
+
+int DummySource::minimumUpdateInterval() const
+{
+ return 1000;
+}
+
+QGeoPositionInfo DummySource::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
+{
+ Q_UNUSED(fromSatellitePositioningMethodsOnly);
+ return lastPosition;
+}
+
+QGeoPositionInfoSource::PositioningMethods DummySource::supportedPositioningMethods() const
+{
+ return QGeoPositionInfoSource::AllPositioningMethods;
+}
+
+void DummySource::startUpdates()
+{
+ timer->start();
+}
+
+void DummySource::stopUpdates()
+{
+ timer->stop();
+}
+
+void DummySource::requestUpdate(int timeout)
+{
+ if (timeout == 0)
+ timeout = 5000;
+ if (timeout < 0)
+ timeout = 0;
+
+ timeoutTimer->setInterval(timeout);
+ timeoutTimer->start();
+
+ if (timer->isActive()) {
+ timer->stop();
+ timer->start();
+ }
+
+ singleTimer->setInterval(1000);
+ singleTimer->start();
+}
+
+DummySource::~DummySource()
+{}
+
+void DummySource::updatePosition()
+{
+ timeoutTimer->stop();
+ singleTimer->stop();
+
+ const QDateTime now = QDateTime::currentDateTime();
+
+ QGeoCoordinate coord(lastPosition.coordinate().latitude() + 0.1,
+ lastPosition.coordinate().longitude() + 0.1);
+
+ QGeoPositionInfo info(coord, now);
+ info.setAttribute(QGeoPositionInfo::Direction, lastPosition.coordinate().azimuthTo(coord));
+ if (lastUpdateTime.isValid()) {
+ double speed = lastPosition.coordinate().distanceTo(coord) / lastUpdateTime.msecsTo(now);
+ info.setAttribute(QGeoPositionInfo::GroundSpeed, 1000 * speed);
+ }
+
+ lastUpdateTime = now;
+ lastPosition = info;
+ emit positionUpdated(info);
+}
+
+void DummySource::doTimeout()
+{
+ timeoutTimer->stop();
+ singleTimer->stop();
+ emit updateTimeout();
+}
+
+
+class QGeoPositionInfoSourceFactoryTestV1 : public QObject, public QGeoPositionInfoSourceFactory
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/5.0"
+ FILE "plugin.json")
+ Q_INTERFACES(QGeoPositionInfoSourceFactory)
+
+public:
+ QGeoPositionInfoSource *positionInfoSource(QObject *parent);
+ QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent);
+ QGeoAreaMonitorSource *areaMonitor(QObject *parent);
+};
+
+QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryTestV1::positionInfoSource(QObject *parent)
+{
+ return new DummySource(parent);
+}
+
+QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryTestV1::satelliteInfoSource(QObject *parent)
+{
+ Q_UNUSED(parent);
+ return nullptr;
+}
+
+QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryTestV1::areaMonitor(QObject* parent)
+{
+ Q_UNUSED(parent);
+ return nullptr;
+}
+
+#include "plugin.moc"
diff --git a/tests/auto/positionpluginV1/plugin.json b/tests/auto/positionpluginV1/plugin.json
new file mode 100644
index 00000000..9acf27e7
--- /dev/null
+++ b/tests/auto/positionpluginV1/plugin.json
@@ -0,0 +1,9 @@
+{
+ "Keys": ["test.source.v1"],
+ "Provider": "test.source.v1",
+ "Position": true,
+ "Satellite": false,
+ "Monitor": false,
+ "Priority": 0,
+ "Testable": true
+}
diff --git a/tests/auto/positionpluginV1/positionpluginV1.pro b/tests/auto/positionpluginV1/positionpluginV1.pro
new file mode 100644
index 00000000..925a7e29
--- /dev/null
+++ b/tests/auto/positionpluginV1/positionpluginV1.pro
@@ -0,0 +1,12 @@
+TARGET = qtposition_testpluginv1
+QT += positioning
+
+PLUGIN_TYPE = position
+PLUGIN_CLASS_NAME = QGeoPositionInfoSourceFactoryTestV1
+PLUGIN_EXTENDS = -
+load(qt_plugin)
+
+SOURCES += plugin.cpp
+
+OTHER_FILES += \
+ plugin.json