diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2016-01-26 14:25:06 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2016-01-26 14:25:06 +0100 |
commit | c6a28570a7300788127117378eb7cd36dcd0953f (patch) | |
tree | b8e56b1bd18fb4438de171004d588d12dbf7abec | |
parent | e9ead74ec4169d483de0b711986b5b560bbb730a (diff) | |
parent | 24e50e40caaa2f2e057180b8ed8179795e605e2a (diff) | |
download | qtlocation-c6a28570a7300788127117378eb7cd36dcd0953f.tar.gz |
Merge remote-tracking branch 'origin/5.6' into dev
Change-Id: I23c874c5dcd0452142c3cf8abff65415ad31a1e7
25 files changed, 576 insertions, 176 deletions
diff --git a/examples/location/mapviewer/mapviewer.qml b/examples/location/mapviewer/mapviewer.qml index 2cb4e0d0..929ea4ba 100644 --- a/examples/location/mapviewer/mapviewer.qml +++ b/examples/location/mapviewer/mapviewer.qml @@ -231,6 +231,12 @@ ApplicationWindow { stackView.currentItem.selectLanguage.connect(setLanguage) stackView.currentItem.closeForm.connect(stackView.closeForm) break + case "Clear": + map.clearData() + break + case "Prefetch": + map.prefetchData() + break default: console.log("Unsupported operation") } diff --git a/examples/location/mapviewer/menus/MainMenu.qml b/examples/location/mapviewer/menus/MainMenu.qml index 3dc3e9fb..7054c40d 100644 --- a/examples/location/mapviewer/menus/MainMenu.qml +++ b/examples/location/mapviewer/menus/MainMenu.qml @@ -125,6 +125,8 @@ MenuBar { item.triggered.connect(function() {toggleMapState("FollowMe")}) addItem(qsTr("Language")).triggered.connect(function(){selectTool("Language")}) + addItem(qsTr("Prefetch Map Data")).triggered.connect(function(){selectTool("Prefetch")}) + addItem(qsTr("Clear Map Data")).triggered.connect(function(){selectTool("Clear")}) } } } diff --git a/examples/positioning/weatherinfo/appmodel.cpp b/examples/positioning/weatherinfo/appmodel.cpp index a773cfca..4d8806b8 100644 --- a/examples/positioning/weatherinfo/appmodel.cpp +++ b/examples/positioning/weatherinfo/appmodel.cpp @@ -154,6 +154,7 @@ public: int minMsBeforeNewRequest; QTimer delayedCityRequestTimer; QTimer requestNewWeatherTimer; + QString app_ident; AppModelPrivate() : src(NULL), @@ -170,6 +171,7 @@ public: requestNewWeatherTimer.setSingleShot(false); requestNewWeatherTimer.setInterval(20*60*1000); // 20 min throttle.invalidate(); + app_ident = QStringLiteral("36496bad1955bf3365448965a42b9eac"); } }; @@ -304,6 +306,7 @@ void AppModel::queryCity() query.addQueryItem("lat", latitude); query.addQueryItem("lon", longitude); query.addQueryItem("mode", "json"); + query.addQueryItem("APPID", d->app_ident); url.setQuery(query); qCDebug(requestsLog) << "submitting request"; @@ -385,6 +388,7 @@ void AppModel::refreshWeather() query.addQueryItem("q", d->city); query.addQueryItem("mode", "json"); + query.addQueryItem("APPID", d->app_ident); url.setQuery(query); QNetworkReply *rep = d->nam->get(QNetworkRequest(url)); @@ -443,6 +447,7 @@ void AppModel::handleWeatherNetworkData(QObject *replyObj) query.addQueryItem("q", d->city); query.addQueryItem("mode", "json"); query.addQueryItem("cnt", "5"); + query.addQueryItem("APPID", d->app_ident); url.setQuery(query); QNetworkReply *rep = d->nam->get(QNetworkRequest(url)); diff --git a/src/imports/location/qdeclarativegeomap.cpp b/src/imports/location/qdeclarativegeomap.cpp index 67f723b9..8fbe6e32 100644 --- a/src/imports/location/qdeclarativegeomap.cpp +++ b/src/imports/location/qdeclarativegeomap.cpp @@ -944,6 +944,18 @@ void QDeclarativeGeoMap::prefetchData() } /*! + \qmlmethod void QtLocation::Map::clearData() + + Clears map data collected by the currently selected plugin. + \note This method will delete cached files. + \sa plugin +*/ +void QDeclarativeGeoMap::clearData() +{ + m_map->clearData(); +} + +/*! \qmlproperty string QtLocation::Map::errorString This read-only property holds the textual presentation of the latest mapping provider error. diff --git a/src/imports/location/qdeclarativegeomap_p.h b/src/imports/location/qdeclarativegeomap_p.h index 69d4687d..06c39640 100644 --- a/src/imports/location/qdeclarativegeomap_p.h +++ b/src/imports/location/qdeclarativegeomap_p.h @@ -131,6 +131,7 @@ public: Q_INVOKABLE void fitViewportToMapItems(); Q_INVOKABLE void pan(int dx, int dy); Q_INVOKABLE void prefetchData(); // optional hint for prefetch + Q_INVOKABLE void clearData(); QString errorString() const; QGeoServiceProvider::Error error() const; diff --git a/src/imports/location/qdeclarativepolylinemapitem.cpp b/src/imports/location/qdeclarativepolylinemapitem.cpp index 71a205d3..f2373abf 100644 --- a/src/imports/location/qdeclarativepolylinemapitem.cpp +++ b/src/imports/location/qdeclarativepolylinemapitem.cpp @@ -199,6 +199,7 @@ void QGeoMapPolylineGeometry::updateSourcePoints(const QGeoMap &map, QDoubleVector2D origin, lastPoint, lastAddedPoint; + const double mapWidthHalf = map.width()/2.0; double unwrapBelowX = 0; if (preserveGeometry_) unwrapBelowX = map.coordinateToItemPosition(geoLeftBound_, false).x(); @@ -219,7 +220,8 @@ void QGeoMapPolylineGeometry::updateSourcePoints(const QGeoMap &map, // unwrap x to preserve geometry if moved to border of map if (preserveGeometry_ && point.x() < unwrapBelowX && !qFuzzyCompare(geoLeftBound_.longitude(), coord.longitude()) - && !qFuzzyCompare(point.x(), unwrapBelowX)) + && !qFuzzyCompare(point.x(), unwrapBelowX) + && !qFuzzyCompare(mapWidthHalf, point.x())) point.setX(unwrapBelowX + geoDistanceToScreenWidth(map, geoLeftBound_, coord)); if (!foundValid) { @@ -534,7 +536,6 @@ void QDeclarativePolylineMapItem::setPath(const QJSValue &value) setPathFromGeoList(pathList); } - /*! \internal */ @@ -551,13 +552,26 @@ void QDeclarativePolylineMapItem::setPathFromGeoList(const QList<QGeoCoordinate> } /*! - \qmlmethod void MapPolyline::addCoordinate(coordinate) + \qmlmethod int MapPolyline::pathLength() + + Returns the number of coordinates of the polyline. - Adds a coordinate to the path. + \since Qt Location 5.6 - \sa removeCoordinate, path + \sa path */ +int QDeclarativePolylineMapItem::pathLength() const +{ + return path_.size(); +} + +/*! + \qmlmethod void MapPolyline::addCoordinate(coordinate) + + Adds a coordinate to the end of the path. + \sa insertCoordinate, removeCoordinate, path +*/ void QDeclarativePolylineMapItem::addCoordinate(const QGeoCoordinate &coordinate) { path_.append(coordinate); @@ -568,6 +582,78 @@ void QDeclarativePolylineMapItem::addCoordinate(const QGeoCoordinate &coordinate } /*! + \qmlmethod void MapPolyline::insertCoordinate(index, coordinate) + + Inserts a \a coordinate to the path at the given \a index. + + \since Qt Location 5.6 + + \sa addCoordinate, removeCoordinate, path +*/ +void QDeclarativePolylineMapItem::insertCoordinate(int index, const QGeoCoordinate &coordinate) +{ + if (index < 0 || index > path_.size()) + return; + + path_.insert(index, coordinate); + + geometry_.markSourceDirty(); + polishAndUpdate(); + emit pathChanged(); +} + +/*! + \qmlmethod void MapPolyline::replaceCoordinate(index, coordinate) + + Replaces the coordinate in the current path at the given \a index + with the new \a coordinate. + + \since Qt Location 5.6 + + \sa addCoordinate, insertCoordinate, removeCoordinate, path +*/ +void QDeclarativePolylineMapItem::replaceCoordinate(int index, const QGeoCoordinate &coordinate) +{ + if (index < 0 || index >= path_.size()) + return; + + path_[index] = coordinate; + + geometry_.markSourceDirty(); + polishAndUpdate(); + emit pathChanged(); +} + +/*! + \qmlmethod coordinate MapPolyline::coordinateAt(index) + + Gets the coordinate of the polyline at the given \a index. + If the index is outside the path's bounds then an invalid + coordinate is returned. + + \since Qt Location 5.6 +*/ +QGeoCoordinate QDeclarativePolylineMapItem::coordinateAt(int index) const +{ + if (index < 0 || index >= path_.size()) + return QGeoCoordinate(); + + return path_.at(index); +} + +/*! + \qmlmethod coordinate MapPolyline::containsCoordinate(coordinate) + + Returns true if the given \a coordinate is part of the path. + + \since Qt Location 5.6 +*/ +bool QDeclarativePolylineMapItem::containsCoordinate(const QGeoCoordinate &coordinate) +{ + return path_.indexOf(coordinate) > -1; +} + +/*! \qmlmethod void MapPolyline::removeCoordinate(coordinate) Removes \a coordinate from the path. If there are multiple instances of the @@ -575,7 +661,7 @@ void QDeclarativePolylineMapItem::addCoordinate(const QGeoCoordinate &coordinate If \a coordinate is not in the path this method does nothing. - \sa addCoordinate, path + \sa addCoordinate, insertCoordinate, path */ void QDeclarativePolylineMapItem::removeCoordinate(const QGeoCoordinate &coordinate) { @@ -591,6 +677,29 @@ void QDeclarativePolylineMapItem::removeCoordinate(const QGeoCoordinate &coordin } /*! + \qmlmethod void MapPolyline::removeCoordinate(index) + + Removes a coordinate from the path at the given \a index. + + If \a index is invalid then this method does nothing. + + \since Qt Location 5.6 + + \sa addCoordinate, insertCoordinate, path +*/ +void QDeclarativePolylineMapItem::removeCoordinate(int index) +{ + if (index < 0 || index >= path_.size()) + return; + + path_.removeAt(index); + + geometry_.markSourceDirty(); + polishAndUpdate(); + emit pathChanged(); +} + +/*! \qmlpropertygroup Location::MapPolyline::line \qmlproperty int MapPolyline::line.width \qmlproperty color MapPolyline::line.color @@ -736,9 +845,10 @@ QSGNode *QDeclarativePolylineMapItem::updateMapItemPaintNode(QSGNode *oldNode, U bool QDeclarativePolylineMapItem::contains(const QPointF &point) const { + QVector<QPointF> vertices = geometry_.vertices(); QPolygonF tri; - for (int i = 0; i < geometry_.vertices().size(); ++i) { - tri << geometry_.vertices()[i]; + for (int i = 0; i < vertices.size(); ++i) { + tri << vertices[i]; if (tri.size() == 3) { if (tri.containsPoint(point,Qt::OddEvenFill)) return true; diff --git a/src/imports/location/qdeclarativepolylinemapitem_p.h b/src/imports/location/qdeclarativepolylinemapitem_p.h index a7b7f167..298dc3bc 100644 --- a/src/imports/location/qdeclarativepolylinemapitem_p.h +++ b/src/imports/location/qdeclarativepolylinemapitem_p.h @@ -116,8 +116,14 @@ public: //from QuickItem virtual QSGNode *updateMapItemPaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE; + Q_INVOKABLE int pathLength() const; Q_INVOKABLE void addCoordinate(const QGeoCoordinate &coordinate); + Q_INVOKABLE void insertCoordinate(int index, const QGeoCoordinate &coordinate); + Q_INVOKABLE void replaceCoordinate(int index, const QGeoCoordinate &coordinate); + Q_INVOKABLE QGeoCoordinate coordinateAt(int index) const; + Q_INVOKABLE bool containsCoordinate(const QGeoCoordinate &coordinate); Q_INVOKABLE void removeCoordinate(const QGeoCoordinate &coordinate); + Q_INVOKABLE void removeCoordinate(int index); QJSValue path() const; virtual void setPath(const QJSValue &value); diff --git a/src/location/maps/qabstractgeotilecache_p.h b/src/location/maps/qabstractgeotilecache_p.h index e368066f..141aa9b4 100644 --- a/src/location/maps/qabstractgeotilecache_p.h +++ b/src/location/maps/qabstractgeotilecache_p.h @@ -102,6 +102,7 @@ public: virtual int maxTextureUsage() const = 0; virtual int minTextureUsage() const = 0; virtual int textureUsage() const = 0; + virtual void clearAll() = 0; virtual QSharedPointer<QGeoTileTexture> get(const QGeoTileSpec &spec) = 0; diff --git a/src/location/maps/qgeofiletilecache.cpp b/src/location/maps/qgeofiletilecache.cpp index 6202f7fb..3d381dc2 100644 --- a/src/location/maps/qgeofiletilecache.cpp +++ b/src/location/maps/qgeofiletilecache.cpp @@ -261,6 +261,19 @@ int QGeoFileTileCache::textureUsage() const return textureCache_.totalCost(); } +void QGeoFileTileCache::clearAll() +{ + textureCache_.clear(); + memoryCache_.clear(); + diskCache_.clear(); + QDir dir(directory_); + dir.setNameFilters(QStringList() << QLatin1String("*-*-*-*.*")); + dir.setFilter(QDir::Files); + foreach (QString dirFile, dir.entryList()) { + dir.remove(dirFile); + } +} + QSharedPointer<QGeoTileTexture> QGeoFileTileCache::get(const QGeoTileSpec &spec) { QSharedPointer<QGeoTileTexture> tt = textureCache_.object(spec); diff --git a/src/location/maps/qgeofiletilecache_p.h b/src/location/maps/qgeofiletilecache_p.h index 8afb4c8d..bd3e684b 100644 --- a/src/location/maps/qgeofiletilecache_p.h +++ b/src/location/maps/qgeofiletilecache_p.h @@ -115,6 +115,7 @@ public: int maxTextureUsage() const Q_DECL_OVERRIDE; int minTextureUsage() const Q_DECL_OVERRIDE; int textureUsage() const Q_DECL_OVERRIDE; + void clearAll() Q_DECL_OVERRIDE; QSharedPointer<QGeoTileTexture> get(const QGeoTileSpec &spec) Q_DECL_OVERRIDE; diff --git a/src/location/maps/qgeomap.cpp b/src/location/maps/qgeomap.cpp index edc64839..37bf139a 100644 --- a/src/location/maps/qgeomap.cpp +++ b/src/location/maps/qgeomap.cpp @@ -109,6 +109,7 @@ void QGeoMap::setActiveMapType(const QGeoMapType type) d->m_activeMapType = type; d->changeActiveMapType(type); d->setCameraData(d->m_cameraData); + emit activeMapTypeChanged(); update(); } @@ -132,6 +133,11 @@ void QGeoMap::prefetchData() } +void QGeoMap::clearData() +{ + +} + QGeoMapPrivate::QGeoMapPrivate(QGeoMappingManagerEngine *engine) : QObjectPrivate(), m_width(0), diff --git a/src/location/maps/qgeomap_p.h b/src/location/maps/qgeomap_p.h index 58a020dc..acc928ea 100644 --- a/src/location/maps/qgeomap_p.h +++ b/src/location/maps/qgeomap_p.h @@ -84,9 +84,11 @@ public: virtual QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const = 0; virtual QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport = true) const = 0; virtual void prefetchData(); + virtual void clearData(); QGeoCameraCapabilities cameraCapabilities(); + protected: QGeoMap(QGeoMapPrivate &dd, QObject *parent = 0); void setCameraData(const QGeoCameraData &cameraData); diff --git a/src/location/maps/qgeotiledmap.cpp b/src/location/maps/qgeotiledmap.cpp index d561c011..97747049 100644 --- a/src/location/maps/qgeotiledmap.cpp +++ b/src/location/maps/qgeotiledmap.cpp @@ -103,6 +103,12 @@ void QGeoTiledMap::prefetchData() d->prefetchTiles(); } +void QGeoTiledMap::clearData() +{ + Q_D(QGeoTiledMap); + d->m_cache->clearAll(); +} + void QGeoTiledMap::handleTileVersionChanged() { Q_D(QGeoTiledMap); diff --git a/src/location/maps/qgeotiledmap_p.h b/src/location/maps/qgeotiledmap_p.h index 111056d2..87dac5d1 100644 --- a/src/location/maps/qgeotiledmap_p.h +++ b/src/location/maps/qgeotiledmap_p.h @@ -86,6 +86,7 @@ public: QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const Q_DECL_OVERRIDE; QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport = true) const Q_DECL_OVERRIDE; void prefetchData() Q_DECL_OVERRIDE; + void clearData() Q_DECL_OVERRIDE; protected: QSGNode *updateSceneGraph(QSGNode *, QQuickWindow *window) Q_DECL_OVERRIDE; diff --git a/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp b/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp index cbc64f41..a104df54 100644 --- a/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp +++ b/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp @@ -350,10 +350,10 @@ void QGeoRouteReplyOsm::networkReplyFinished() int status = object.value(QStringLiteral("status")).toDouble(); QString statusMessage = object.value(QStringLiteral("status_message")).toString(); - // status code is 0 in case of success + // status code 0 or 200 are case of success // status code is 207 if no route was found // an error occurred when trying to find a route - if (0 != status) { + if (0 != status && 200 != status) { setError(QGeoRouteReply::UnknownError, statusMessage); m_reply->deleteLater(); m_reply = 0; diff --git a/src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java b/src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java index 4723a805..43767f0e 100644 --- a/src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java +++ b/src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java @@ -179,6 +179,58 @@ public class QtPositioning implements LocationListener return false; } + + static private void addActiveListener(QtPositioning listener, String provider) + { + int androidClassKey = listener.nativeClassReference; + //start update thread + listener.setActiveLooper(true); + + if (runningListeners.containsKey(androidClassKey) && runningListeners.get(androidClassKey) != listener) { + removeActiveListener(androidClassKey); + } + + locationManager.requestSingleUpdate(provider, + listener, + listener.looper()); + + runningListeners.put(androidClassKey, listener); + } + + + static private void addActiveListener(QtPositioning listener, String provider, long minTime, float minDistance) + { + int androidClassKey = listener.nativeClassReference; + //start update thread + listener.setActiveLooper(true); + + if (runningListeners.containsKey(androidClassKey) && runningListeners.get(androidClassKey) != listener) { + removeActiveListener(androidClassKey); + } + + locationManager.requestLocationUpdates(provider, + minTime, minDistance, + listener, + listener.looper()); + + runningListeners.put(androidClassKey, listener); + } + + + static private void removeActiveListener(QtPositioning listener) + { + removeActiveListener(listener.nativeClassReference); + } + + + static private void removeActiveListener(int androidClassKey) + { + QtPositioning listener = runningListeners.remove(androidClassKey); + locationManager.removeUpdates(listener); + listener.setActiveLooper(false); + } + + static public int startUpdates(int androidClassKey, int locationProvider, int updateInterval) { synchronized (m_syncObject) { @@ -188,8 +240,6 @@ public class QtPositioning implements LocationListener positioningListener.nativeClassReference = androidClassKey; positioningListener.expectedProviders = locationProvider; positioningListener.isSatelliteUpdate = false; - //start update thread - positioningListener.setActiveLooper(true); if (updateInterval == 0) updateInterval = 1000; //don't update more often than once per second @@ -198,10 +248,9 @@ public class QtPositioning implements LocationListener if ((locationProvider & QT_GPS_PROVIDER) > 0) { Log.d(TAG, "Regular updates using GPS " + updateInterval); try { - locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, - updateInterval, 0, - positioningListener, - positioningListener.looper()); + addActiveListener(positioningListener, + LocationManager.GPS_PROVIDER, + updateInterval, 0); } catch (SecurityException se) { se.printStackTrace(); exceptionOccurred = true; @@ -211,18 +260,16 @@ public class QtPositioning implements LocationListener if ((locationProvider & QT_NETWORK_PROVIDER) > 0) { Log.d(TAG, "Regular updates using network " + updateInterval); try { - locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, - updateInterval, 0, - positioningListener, - positioningListener.looper()); + addActiveListener(positioningListener, + LocationManager.NETWORK_PROVIDER, + updateInterval, 0); } catch (SecurityException se) { se.printStackTrace(); exceptionOccurred = true; } } if (exceptionOccurred) { - positioningListener.setActiveLooper(false); - locationManager.removeUpdates(positioningListener); + removeActiveListener(positioningListener); return QT_ACCESS_ERROR; } @@ -231,7 +278,6 @@ public class QtPositioning implements LocationListener return QT_CLOSED_ERROR; } - runningListeners.put(androidClassKey, positioningListener); } catch(Exception e) { e.printStackTrace(); return QT_POSITION_UNKNOWN_SOURCE_ERROR; @@ -246,9 +292,7 @@ public class QtPositioning implements LocationListener synchronized (m_syncObject) { try { Log.d(TAG, "Stopping updates"); - QtPositioning listener = runningListeners.remove(androidClassKey); - locationManager.removeUpdates(listener); - listener.setActiveLooper(false); + removeActiveListener(androidClassKey); } catch(Exception e) { e.printStackTrace(); return; @@ -266,15 +310,11 @@ public class QtPositioning implements LocationListener positioningListener.isSingleUpdate = true; positioningListener.expectedProviders = locationProvider; positioningListener.isSatelliteUpdate = false; - //start update thread - positioningListener.setActiveLooper(true); if ((locationProvider & QT_GPS_PROVIDER) > 0) { Log.d(TAG, "Single update using GPS"); try { - locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, - positioningListener, - positioningListener.looper()); + addActiveListener(positioningListener, LocationManager.GPS_PROVIDER); } catch (SecurityException se) { se.printStackTrace(); exceptionOccurred = true; @@ -284,17 +324,14 @@ public class QtPositioning implements LocationListener if ((locationProvider & QT_NETWORK_PROVIDER) > 0) { Log.d(TAG, "Single update using network"); try { - locationManager.requestSingleUpdate(LocationManager.NETWORK_PROVIDER, - positioningListener, - positioningListener.looper()); + addActiveListener(positioningListener, LocationManager.NETWORK_PROVIDER); } catch (SecurityException se) { se.printStackTrace(); exceptionOccurred = true; } } if (exceptionOccurred) { - positioningListener.setActiveLooper(false); - locationManager.removeUpdates(positioningListener); + removeActiveListener(positioningListener); return QT_ACCESS_ERROR; } @@ -304,7 +341,6 @@ public class QtPositioning implements LocationListener return QT_CLOSED_ERROR; } - runningListeners.put(androidClassKey, positioningListener); } catch(Exception e) { e.printStackTrace(); return QT_POSITION_UNKNOWN_SOURCE_ERROR; @@ -324,8 +360,6 @@ public class QtPositioning implements LocationListener positioningListener.nativeClassReference = androidClassKey; positioningListener.expectedProviders = 1; //always satellite provider positioningListener.isSingleUpdate = isSingleRequest; - //start update thread - positioningListener.setActiveLooper(true); if (updateInterval == 0) updateInterval = 1000; //don't update more often than once per second @@ -335,18 +369,15 @@ public class QtPositioning implements LocationListener else Log.d(TAG, "Regular updates for Satellites " + updateInterval); try { - locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, - updateInterval, 0, - positioningListener, - positioningListener.looper()); + addActiveListener(positioningListener, LocationManager.GPS_PROVIDER, + updateInterval, 0); } catch (SecurityException se) { se.printStackTrace(); exceptionOccurred = true; } if (exceptionOccurred) { - positioningListener.setActiveLooper(false); - locationManager.removeUpdates(positioningListener); + removeActiveListener(positioningListener); return QT_ACCESS_ERROR; } @@ -356,7 +387,6 @@ public class QtPositioning implements LocationListener return QT_CLOSED_ERROR; } - runningListeners.put(androidClassKey, positioningListener); } catch(Exception e) { e.printStackTrace(); return QT_SATELLITE_UNKNOWN_SOURCE_ERROR; diff --git a/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp b/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp index c9b209e8..1d1a6f4f 100644 --- a/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp +++ b/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp @@ -42,6 +42,7 @@ #include <QtSerialPort/qserialport.h> #include <QtSerialPort/qserialportinfo.h> #include <QtCore/qloggingcategory.h> +#include <QSet> Q_LOGGING_CATEGORY(lcSerial, "qt.positioning.serialnmea") @@ -70,16 +71,13 @@ NmeaSource::NmeaSource(QObject *parent) } // Try to find a well-known device. + QSet<int> supportedDevices; + supportedDevices << 0x67b; // GlobalSat (BU-353S4 and probably others) + supportedDevices << 0xe8d; // Qstarz MTK II QString portName; - for (int i = 0; i < ports.count(); ++i) { - const QString candidatePortName = ports[i].portName(); - bool acceptThis = false; - - // GlobalSat (BU-353S4 and probably others) - acceptThis |= ports[i].hasVendorIdentifier() && ports[i].vendorIdentifier() == 0x67b; - - if (acceptThis) { - portName = candidatePortName; + foreach (const QSerialPortInfo& port, ports) { + if (port.hasVendorIdentifier() && supportedDevices.contains(port.vendorIdentifier())) { + portName = port.portName(); break; } } diff --git a/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp b/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp index 4e70cc07..5dbbacb5 100644 --- a/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp +++ b/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp @@ -37,75 +37,119 @@ #include "qgeopositioninfosource_winrt_p.h" #include <QCoreApplication> +#include <QMutex> +#include <qfunctions_winrt.h> +#include <private/qeventdispatcher_winrt_p.h> +#include <functional> #include <windows.system.h> #include <windows.devices.geolocation.h> +#include <windows.foundation.h> #include <windows.foundation.collections.h> using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers; using namespace ABI::Windows::Devices::Geolocation; using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::System; +using namespace ABI::Windows::Foundation::Collections; typedef ITypedEventHandler<Geolocator *, PositionChangedEventArgs *> GeoLocatorPositionHandler; typedef ITypedEventHandler<Geolocator *, StatusChangedEventArgs *> GeoLocatorStatusHandler; +typedef IAsyncOperationCompletedHandler<Geoposition*> PositionHandler; +#if _MSC_VER >= 1900 +typedef IAsyncOperationCompletedHandler<GeolocationAccessStatus> AccessHandler; +#endif QT_BEGIN_NAMESPACE -QGeoPositionInfoSourceWinrt::QGeoPositionInfoSourceWinrt(QObject *parent) +Q_DECLARE_METATYPE(QGeoPositionInfo) + +class QGeoPositionInfoSourceWinRTPrivate { +public: + ComPtr<IGeolocator> locator; + QTimer periodicTimer; + QTimer singleUpdateTimer; + QGeoPositionInfo lastPosition; + QGeoPositionInfoSource::Error positionError; + EventRegistrationToken statusToken; + EventRegistrationToken positionToken; + QMutex mutex; + bool updatesOngoing; +}; + + +QGeoPositionInfoSourceWinRT::QGeoPositionInfoSourceWinRT(QObject *parent) : QGeoPositionInfoSource(parent) - , m_positionError(QGeoPositionInfoSource::NoError) - , m_updatesOngoing(false) + , d_ptr(new QGeoPositionInfoSourceWinRTPrivate) { - HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Devices_Geolocation_Geolocator).Get(), - &m_locator); + Q_D(QGeoPositionInfoSourceWinRT); + d->positionError = QGeoPositionInfoSource::NoError; + d->updatesOngoing = false; + + qRegisterMetaType<QGeoPositionInfo>(); + + requestAccess(); + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() { + HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Devices_Geolocation_Geolocator).Get(), + &d->locator); + RETURN_HR_IF_FAILED("Could not initialize native location services."); + + // StatusChanged throws an exception on Windows 8.1 +#if _MSC_VER >= 1900 + hr = d->locator->add_StatusChanged(Callback<GeoLocatorStatusHandler>(this, + &QGeoPositionInfoSourceWinRT::onStatusChanged).Get(), + &d->statusToken); + RETURN_HR_IF_FAILED("Could not add status callback."); +#endif - if (FAILED(hr)) { - setError(QGeoPositionInfoSource::UnknownSourceError); - qErrnoWarning(hr, "Could not initialize native location services"); - return; - } + hr = d->locator->put_ReportInterval(1000); + RETURN_HR_IF_FAILED("Could not initialize report interval."); - hr = m_locator->put_ReportInterval(minimumUpdateInterval()); - if (FAILED(hr)) { - setError(QGeoPositionInfoSource::UnknownSourceError); - qErrnoWarning(hr, "Could not initialize report interval"); - return; - } - hr = m_locator->put_DesiredAccuracy(PositionAccuracy::PositionAccuracy_High); + return hr; + }); + Q_ASSERT_SUCCEEDED(hr); + + hr = d->locator->put_DesiredAccuracy(PositionAccuracy::PositionAccuracy_Default); if (FAILED(hr)) { setError(QGeoPositionInfoSource::UnknownSourceError); - qErrnoWarning(hr, "Could not initialize desired accuracy"); + qErrnoWarning(hr, "Could not initialize desired accuracy."); return; } - m_positionToken.value = 0; + d->positionToken.value = 0; - m_periodicTimer.setSingleShot(true); - m_periodicTimer.setInterval(minimumUpdateInterval()); - connect(&m_periodicTimer, SIGNAL(timeout()), this, SLOT(virtualPositionUpdate())); + d->periodicTimer.setSingleShot(true); + d->periodicTimer.setInterval(minimumUpdateInterval()); + connect(&d->periodicTimer, &QTimer::timeout, this, &QGeoPositionInfoSourceWinRT::virtualPositionUpdate); - m_singleUpdateTimer.setSingleShot(true); - connect(&m_singleUpdateTimer, SIGNAL(timeout()), this, SLOT(singleUpdateTimeOut())); + d->singleUpdateTimer.setSingleShot(true); + connect(&d->singleUpdateTimer, &QTimer::timeout, this, &QGeoPositionInfoSourceWinRT::singleUpdateTimeOut); setPreferredPositioningMethods(QGeoPositionInfoSource::AllPositioningMethods); + + connect(this, &QGeoPositionInfoSourceWinRT::nativePositionUpdate, this, &QGeoPositionInfoSourceWinRT::updateSynchronized); } -QGeoPositionInfoSourceWinrt::~QGeoPositionInfoSourceWinrt() +QGeoPositionInfoSourceWinRT::~QGeoPositionInfoSourceWinRT() { } -QGeoPositionInfo QGeoPositionInfoSourceWinrt::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const +QGeoPositionInfo QGeoPositionInfoSourceWinRT::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const { + Q_D(const QGeoPositionInfoSourceWinRT); Q_UNUSED(fromSatellitePositioningMethodsOnly) - return m_lastPosition; + return d->lastPosition; } -QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSourceWinrt::supportedPositioningMethods() const +QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSourceWinRT::supportedPositioningMethods() const { + Q_D(const QGeoPositionInfoSourceWinRT); + PositionStatus status; - HRESULT hr = m_locator->get_LocationStatus(&status); + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([d, &status]() { + HRESULT hr = d->locator->get_LocationStatus(&status); + return hr; + }); if (FAILED(hr)) return QGeoPositionInfoSource::NoPositioningMethods; @@ -119,88 +163,94 @@ QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSourceWinrt::supporte return QGeoPositionInfoSource::AllPositioningMethods; } -void QGeoPositionInfoSourceWinrt::setPreferredPositioningMethods(QGeoPositionInfoSource::PositioningMethods methods) +void QGeoPositionInfoSourceWinRT::setPreferredPositioningMethods(QGeoPositionInfoSource::PositioningMethods methods) { + Q_D(QGeoPositionInfoSourceWinRT); + PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods(); QGeoPositionInfoSource::setPreferredPositioningMethods(methods); if (previousPreferredPositioningMethods == preferredPositioningMethods()) return; - bool needsRestart = m_positionToken.value != 0; + bool needsRestart = d->positionToken.value != 0; if (needsRestart) stopHandler(); - HRESULT hr; - if (methods & PositioningMethod::SatellitePositioningMethods) - hr = m_locator->put_DesiredAccuracy(PositionAccuracy::PositionAccuracy_High); - else - hr = m_locator->put_DesiredAccuracy(PositionAccuracy::PositionAccuracy_Default); - - if (FAILED(hr)) { - qErrnoWarning(hr, "Could not set positioning accuracy"); - return; - } + PositionAccuracy acc = methods & PositioningMethod::SatellitePositioningMethods ? + PositionAccuracy::PositionAccuracy_High : + PositionAccuracy::PositionAccuracy_Default; + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([d, acc]() { + HRESULT hr = d->locator->put_DesiredAccuracy(acc); + return hr; + }); + RETURN_VOID_IF_FAILED("Could not set positioning accuracy."); if (needsRestart) startHandler(); } -void QGeoPositionInfoSourceWinrt::setUpdateInterval(int msec) +void QGeoPositionInfoSourceWinRT::setUpdateInterval(int msec) { - // Windows Phone does not support 0 interval -#ifdef Q_OS_WINPHONE + Q_D(QGeoPositionInfoSourceWinRT); + // Windows Phone 8.1 and Windows 10 do not support 0 interval +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) if (msec == 0) msec = minimumUpdateInterval(); #endif + // If msec is 0 we send updates as data becomes available, otherwise we force msec to be equal // to or larger than the minimum update interval. if (msec != 0 && msec < minimumUpdateInterval()) msec = minimumUpdateInterval(); - HRESULT hr = m_locator->put_ReportInterval(msec); + HRESULT hr = d->locator->put_ReportInterval(msec); if (FAILED(hr)) { setError(QGeoPositionInfoSource::UnknownSourceError); qErrnoWarning(hr, "Failed to set update interval"); return; } - if (msec != 0) - m_periodicTimer.setInterval(msec); - else - m_periodicTimer.setInterval(minimumUpdateInterval()); + + d->periodicTimer.setInterval(qMax(msec, minimumUpdateInterval())); QGeoPositionInfoSource::setUpdateInterval(msec); } -int QGeoPositionInfoSourceWinrt::minimumUpdateInterval() const +int QGeoPositionInfoSourceWinRT::minimumUpdateInterval() const { // We use one second to reduce potential timer events // in case the platform itself stops reporting return 1000; } -void QGeoPositionInfoSourceWinrt::startUpdates() +void QGeoPositionInfoSourceWinRT::startUpdates() { - if (m_updatesOngoing) + Q_D(QGeoPositionInfoSourceWinRT); + + if (d->updatesOngoing) return; if (!startHandler()) return; - m_updatesOngoing = true; - m_periodicTimer.start(); + d->updatesOngoing = true; + d->periodicTimer.start(); } -void QGeoPositionInfoSourceWinrt::stopUpdates() +void QGeoPositionInfoSourceWinRT::stopUpdates() { + Q_D(QGeoPositionInfoSourceWinRT); + stopHandler(); - m_updatesOngoing = false; - m_periodicTimer.stop(); + d->updatesOngoing = false; + d->periodicTimer.stop(); } -bool QGeoPositionInfoSourceWinrt::startHandler() +bool QGeoPositionInfoSourceWinRT::startHandler() { + Q_D(QGeoPositionInfoSourceWinRT); + // Check if already attached - if (m_positionToken.value != 0) + if (d->positionToken.value != 0) return true; if (preferredPositioningMethods() == QGeoPositionInfoSource::NoPositioningMethods) { @@ -208,31 +258,49 @@ bool QGeoPositionInfoSourceWinrt::startHandler() return false; } - if (!checkNativeState()) + if (!requestAccess() || !checkNativeState()) return false; - HRESULT hr = m_locator->add_PositionChanged(Callback<GeoLocatorPositionHandler>(this, - &QGeoPositionInfoSourceWinrt::onPositionChanged).Get(), - &m_positionToken); + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() { + HRESULT hr; + // We need to call this at least once on Windows 10 Mobile. + // Unfortunately this operation does not have a completion handler + // registered. That could have helped in the single update case + ComPtr<IAsyncOperation<Geoposition*>> op; + hr = d->locator->GetGeopositionAsync(&op); + + hr = d->locator->add_PositionChanged(Callback<GeoLocatorPositionHandler>(this, + &QGeoPositionInfoSourceWinRT::onPositionChanged).Get(), + &d->positionToken); + return hr; + }); if (FAILED(hr)) { setError(QGeoPositionInfoSource::UnknownSourceError); qErrnoWarning(hr, "Could not add position handler"); return false; } + return true; } -void QGeoPositionInfoSourceWinrt::stopHandler() +void QGeoPositionInfoSourceWinRT::stopHandler() { - if (!m_positionToken.value) + Q_D(QGeoPositionInfoSourceWinRT); + + if (!d->positionToken.value) return; - m_locator->remove_PositionChanged(m_positionToken); - m_positionToken.value = 0; + QEventDispatcherWinRT::runOnXamlThread([d]() { + d->locator->remove_PositionChanged(d->positionToken); + return S_OK; + }); + d->positionToken.value = 0; } -void QGeoPositionInfoSourceWinrt::requestUpdate(int timeout) +void QGeoPositionInfoSourceWinRT::requestUpdate(int timeout) { + Q_D(QGeoPositionInfoSourceWinRT); + if (timeout != 0 && timeout < minimumUpdateInterval()) { emit updateTimeout(); return; @@ -242,11 +310,14 @@ void QGeoPositionInfoSourceWinrt::requestUpdate(int timeout) timeout = 2*60*1000; // Maximum time for cold start (see Android) startHandler(); - m_singleUpdateTimer.start(timeout); + d->singleUpdateTimer.start(timeout); } -void QGeoPositionInfoSourceWinrt::virtualPositionUpdate() +void QGeoPositionInfoSourceWinRT::virtualPositionUpdate() { + Q_D(QGeoPositionInfoSourceWinRT); + QMutexLocker locker(&d->mutex); + // Need to check if services are still running and ok if (!checkNativeState()) { stopUpdates(); @@ -258,39 +329,69 @@ void QGeoPositionInfoSourceWinrt::virtualPositionUpdate() // between backends. // This only applies to the periodic timer, not for single requests // We can only do this if we received a valid position before - if (m_lastPosition.isValid()) { - QGeoPositionInfo sent = m_lastPosition; + if (d->lastPosition.isValid()) { + QGeoPositionInfo sent = d->lastPosition; sent.setTimestamp(QDateTime::currentDateTime()); - m_lastPosition = sent; + d->lastPosition = sent; emit positionUpdated(sent); } - m_periodicTimer.start(); + d->periodicTimer.start(); } -void QGeoPositionInfoSourceWinrt::singleUpdateTimeOut() +void QGeoPositionInfoSourceWinRT::singleUpdateTimeOut() { - emit updateTimeout(); - if (!m_updatesOngoing) + Q_D(QGeoPositionInfoSourceWinRT); + QMutexLocker locker(&d->mutex); + + if (d->singleUpdateTimer.isActive()) { + emit updateTimeout(); + if (!d->updatesOngoing) + stopHandler(); + } +} + +void QGeoPositionInfoSourceWinRT::updateSynchronized(QGeoPositionInfo currentInfo) +{ + Q_D(QGeoPositionInfoSourceWinRT); + QMutexLocker locker(&d->mutex); + + d->periodicTimer.stop(); + d->lastPosition = currentInfo; + + if (d->updatesOngoing) + d->periodicTimer.start(); + + if (d->singleUpdateTimer.isActive()) { + d->singleUpdateTimer.stop(); + if (!d->updatesOngoing) stopHandler(); + } + + emit positionUpdated(currentInfo); } -QGeoPositionInfoSource::Error QGeoPositionInfoSourceWinrt::error() const +QGeoPositionInfoSource::Error QGeoPositionInfoSourceWinRT::error() const { - return m_positionError; + Q_D(const QGeoPositionInfoSourceWinRT); + return d->positionError; } -void QGeoPositionInfoSourceWinrt::setError(QGeoPositionInfoSource::Error positionError) +void QGeoPositionInfoSourceWinRT::setError(QGeoPositionInfoSource::Error positionError) { - if (positionError == m_positionError) + Q_D(QGeoPositionInfoSourceWinRT); + + if (positionError == d->positionError) return; - m_positionError = positionError; + d->positionError = positionError; emit QGeoPositionInfoSource::error(positionError); } -bool QGeoPositionInfoSourceWinrt::checkNativeState() +bool QGeoPositionInfoSourceWinRT::checkNativeState() { + Q_D(QGeoPositionInfoSourceWinRT); + PositionStatus status; - HRESULT hr = m_locator->get_LocationStatus(&status); + HRESULT hr = d->locator->get_LocationStatus(&status); if (FAILED(hr)) { setError(QGeoPositionInfoSource::UnknownSourceError); qErrnoWarning(hr, "Could not query status"); @@ -314,17 +415,14 @@ bool QGeoPositionInfoSourceWinrt::checkNativeState() return result; } -HRESULT QGeoPositionInfoSourceWinrt::onPositionChanged(IGeolocator *locator, IPositionChangedEventArgs *args) +HRESULT QGeoPositionInfoSourceWinRT::onPositionChanged(IGeolocator *locator, IPositionChangedEventArgs *args) { Q_UNUSED(locator); - m_periodicTimer.stop(); - HRESULT hr; ComPtr<IGeoposition> pos; hr = args->get_Position(&pos); - if (FAILED(hr)) - qErrnoWarning(hr, "Could not access position object"); + RETURN_HR_IF_FAILED("Could not access position object."); QGeoPositionInfo currentInfo; @@ -378,19 +476,48 @@ HRESULT QGeoPositionInfoSourceWinrt::onPositionChanged(IGeolocator *locator, IPo currentInfo.setTimestamp(QDateTime::currentDateTime()); - m_lastPosition = currentInfo; + emit nativePositionUpdate(currentInfo); - if (m_updatesOngoing) - m_periodicTimer.start(); - - if (m_singleUpdateTimer.isActive()) { - m_singleUpdateTimer.stop(); - if (!m_updatesOngoing) - stopHandler(); - } + return S_OK; +} - emit positionUpdated(currentInfo); +HRESULT QGeoPositionInfoSourceWinRT::onStatusChanged(IGeolocator*, IStatusChangedEventArgs *args) +{ + PositionStatus st; + args->get_Status(&st); return S_OK; } +bool QGeoPositionInfoSourceWinRT::requestAccess() const +{ +#if _MSC_VER >= 1900 + static GeolocationAccessStatus accessStatus = GeolocationAccessStatus_Unspecified; + static ComPtr<IGeolocatorStatics> statics; + + if (accessStatus == GeolocationAccessStatus_Allowed) + return true; + else if (accessStatus == GeolocationAccessStatus_Denied) + return false; + + ComPtr<IAsyncOperation<GeolocationAccessStatus>> op; + HRESULT hr; + hr = QEventDispatcherWinRT::runOnXamlThread([&op]() { + HRESULT hr; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Devices_Geolocation_Geolocator).Get(), + IID_PPV_ARGS(&statics)); + RETURN_HR_IF_FAILED("Could not access Geolocation Statics."); + + hr = statics->RequestAccessAsync(&op); + return hr; + }); + Q_ASSERT_SUCCEEDED(hr); + + // We cannot wait inside the XamlThread as that would deadlock + QWinRTFunctions::await(op, &accessStatus); + return accessStatus == GeolocationAccessStatus_Allowed; +#else // _MSC_VER < 1900 + return true; +#endif // _MSC_VER < 1900 +} + QT_END_NAMESPACE diff --git a/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h b/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h index 45c22847..b8820dd2 100644 --- a/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h +++ b/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h @@ -70,12 +70,14 @@ namespace ABI { QT_BEGIN_NAMESPACE -class QGeoPositionInfoSourceWinrt : public QGeoPositionInfoSource +class QGeoPositionInfoSourceWinRTPrivate; + +class QGeoPositionInfoSourceWinRT : public QGeoPositionInfoSource { Q_OBJECT public: - QGeoPositionInfoSourceWinrt(QObject *parent = 0); - ~QGeoPositionInfoSourceWinrt(); + QGeoPositionInfoSourceWinRT(QObject *parent = 0); + ~QGeoPositionInfoSourceWinRT(); QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const; PositioningMethods supportedPositioningMethods() const; @@ -89,6 +91,12 @@ public: HRESULT onPositionChanged(ABI::Windows::Devices::Geolocation::IGeolocator *locator, ABI::Windows::Devices::Geolocation::IPositionChangedEventArgs *args); + HRESULT onStatusChanged(ABI::Windows::Devices::Geolocation::IGeolocator*, + ABI::Windows::Devices::Geolocation::IStatusChangedEventArgs *args); + + bool requestAccess() const; +Q_SIGNALS: + void nativePositionUpdate(const QGeoPositionInfo); public slots: void startUpdates(); void stopUpdates(); @@ -99,23 +107,16 @@ private slots: void stopHandler(); void virtualPositionUpdate(); void singleUpdateTimeOut(); + void updateSynchronized(const QGeoPositionInfo info); private: bool startHandler(); - Q_DISABLE_COPY(QGeoPositionInfoSourceWinrt) + Q_DISABLE_COPY(QGeoPositionInfoSourceWinRT) void setError(QGeoPositionInfoSource::Error positionError); bool checkNativeState(); - Microsoft::WRL::ComPtr<ABI::Windows::Devices::Geolocation::IGeolocator> m_locator; - EventRegistrationToken m_positionToken; - - QGeoPositionInfo m_lastPosition; - QGeoPositionInfoSource::Error m_positionError; - - //EventRegistrationToken m_StatusToken; - QTimer m_periodicTimer; - QTimer m_singleUpdateTimer; - bool m_updatesOngoing; + QScopedPointer<QGeoPositionInfoSourceWinRTPrivate> d_ptr; + Q_DECLARE_PRIVATE(QGeoPositionInfoSourceWinRT) }; QT_END_NAMESPACE diff --git a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp index 0f9a21f2..81656c21 100644 --- a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp +++ b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp @@ -37,18 +37,18 @@ #include "qgeopositioninfosourcefactory_winrt.h" #include "qgeopositioninfosource_winrt_p.h" -QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryWinrt::positionInfoSource(QObject *parent) +QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryWinRT::positionInfoSource(QObject *parent) { - return new QGeoPositionInfoSourceWinrt(parent); + return new QGeoPositionInfoSourceWinRT(parent); } -QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryWinrt::satelliteInfoSource(QObject *parent) +QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryWinRT::satelliteInfoSource(QObject *parent) { Q_UNUSED(parent); return 0; } -QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryWinrt::areaMonitor(QObject *parent) +QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryWinRT::areaMonitor(QObject *parent) { Q_UNUSED(parent); return 0; diff --git a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h index 0627abc4..46cd3853 100644 --- a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h +++ b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h @@ -42,7 +42,7 @@ QT_BEGIN_NAMESPACE -class QGeoPositionInfoSourceFactoryWinrt : public QObject, public QGeoPositionInfoSourceFactory +class QGeoPositionInfoSourceFactoryWinRT : public QObject, public QGeoPositionInfoSourceFactory { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/5.0" diff --git a/src/plugins/position/winrt/winrt.pro b/src/plugins/position/winrt/winrt.pro index 228a9e78..c58c6c18 100644 --- a/src/plugins/position/winrt/winrt.pro +++ b/src/plugins/position/winrt/winrt.pro @@ -1,8 +1,8 @@ TARGET = qtposition_winrt -QT = core positioning +QT = core core-private positioning PLUGIN_TYPE = position -PLUGIN_CLASS_NAME = QGeoPositionInfoSourceFactoryWinrt +PLUGIN_CLASS_NAME = QGeoPositionInfoSourceFactoryWinRT load(qt_plugin) SOURCES += qgeopositioninfosource_winrt.cpp \ diff --git a/src/positioning/doc/src/examples/weatherinfo.qdoc b/src/positioning/doc/src/examples/weatherinfo.qdoc index e32127d4..3db6fcbf 100644 --- a/src/positioning/doc/src/examples/weatherinfo.qdoc +++ b/src/positioning/doc/src/examples/weatherinfo.qdoc @@ -45,6 +45,8 @@ \include examples-run.qdocinc + The example uses weather data provided by \l http://www.openweathermap.org. + The key part of this example is the application's data model, contained in the WeatherData and AppModel classes. WeatherData represents the weather information taken from the HTTP service. It is a simple data class, but we diff --git a/src/positioning/qpositioningglobal_p.h b/src/positioning/qpositioningglobal_p.h index 653fcf77..747e450e 100644 --- a/src/positioning/qpositioningglobal_p.h +++ b/src/positioning/qpositioningglobal_p.h @@ -39,6 +39,17 @@ #ifndef QPOSITIONINGGLOBAL_P_H #define QPOSITIONINGGLOBAL_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include "qpositioningglobal.h" QT_BEGIN_NAMESPACE diff --git a/tests/auto/declarative_geoshape/tst_locationsingleton.qml b/tests/auto/declarative_geoshape/tst_locationsingleton.qml index ce5b7c4b..4b0a55ae 100644 --- a/tests/auto/declarative_geoshape/tst_locationsingleton.qml +++ b/tests/auto/declarative_geoshape/tst_locationsingleton.qml @@ -29,6 +29,7 @@ import QtQuick 2.0 import QtTest 1.0 import QtPositioning 5.2 +import QtLocation 5.5 Item { id: testCase @@ -186,4 +187,62 @@ Item { verify(rectangle.isValid) } } + + + MapPolyline { + id: mapPolyline + path: [ + { latitude: -27, longitude: 153.0 }, + { latitude: -27, longitude: 154.1 }, + { latitude: -28, longitude: 153.5 }, + { latitude: -29, longitude: 153.5 } + ] + } + + TestCase { + name: "MapPolyline path" + function test_path_operations() { + compare(mapPolyline.path[1].latitude, -27) + compare(mapPolyline.path[1].longitude, 154.1) + compare(mapPolyline.coordinateAt(1), QtPositioning.coordinate(27, 154.1)) + compare(mapPolyline.path.length, mapPolyline.pathLength()) + + mapPolyline.removeCoordinate(1); + compare(mapPolyline.path[1].latitude, -28) + compare(mapPolyline.path[1].longitude, 153.5) + compare(mapPolyline.coordinateAt(1), QtPositioning.coordinate(-28, 153.5)) + compare(mapPolyline.path.length, mapPolyline.pathLength()) + + mapPolyline.addCoordinate(QtPositioning.coordinate(30, 153.1)) + compare(mapPolyline.path[mapPolyline.path.length-1].latitude, 30) + compare(mapPolyline.path[mapPolyline.path.length-1].longitude, 153.1) + compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(30, 153.1)), true) + compare(mapPolyline.path.length, mapPolyline.pathLength()) + + mapPolyline.removeCoordinate(QtPositioning.coordinate(30, 153.1)) + compare(mapPolyline.path[mapPolyline.path.length-1].latitude, -29) + compare(mapPolyline.path[mapPolyline.path.length-1].longitude, 153.5) + compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(30, 153.1)), false) + compare(mapPolyline.path.length, mapPolyline.pathLength()) + + mapPolyline.insertCoordinate(2, QtPositioning.coordinate(35, 153.1)) + compare(mapPolyline.path[2].latitude, 35) + compare(mapPolyline.path[2].longitude, 153.1) + compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(35, 153.1)), true) + compare(mapPolyline.path.length, mapPolyline.pathLength()) + + mapPolyline.replaceCoordinate(2, QtPositioning.coordinate(45, 150.1)) + compare(mapPolyline.path[2].latitude, 45) + compare(mapPolyline.path[2].longitude, 150.1) + compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(35, 153.1)), false) + compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(45, 150.1)), true) + compare(mapPolyline.path.length, mapPolyline.pathLength()) + + mapPolyline.insertCoordinate(2, QtPositioning.coordinate(35, 153.1)) + compare(mapPolyline.coordinateAt(2).latitude, 35) + compare(mapPolyline.coordinateAt(2).longitude, 153.1) + compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(35, 153.1)), true) + compare(mapPolyline.path.length, mapPolyline.pathLength()) + } + } } |