summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--src/location/declarativemaps/qdeclarativegeomapquickitem.cpp5
-rw-r--r--src/location/labs/qdeclarativenavigator.cpp18
-rw-r--r--src/location/labs/qmapobjectview.cpp28
-rw-r--r--src/location/labs/qmapobjectview_p.h3
-rw-r--r--src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp2
-rw-r--r--src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp238
-rw-r--r--src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h25
-rw-r--r--src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp6
-rw-r--r--src/positioning/qgeorectangle.cpp41
-rw-r--r--tests/applications/positioning_backend/main.cpp3
-rw-r--r--tests/applications/positioning_backend/widget.cpp13
-rw-r--r--tests/applications/positioning_backend/widget.h1
-rw-r--r--tests/applications/positioning_backend/widget.ui23
-rw-r--r--tests/auto/qgeorectangle/tst_qgeorectangle.cpp8
15 files changed, 257 insertions, 159 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 3dc70a37..be4c8740 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -1,7 +1,7 @@
load(qt_build_config)
CONFIG += warning_clean
-MODULE_VERSION = 5.12.1
+MODULE_VERSION = 5.12.2
# Adds a way to debug location. The define is needed for multiple subprojects as they
# include the essential headers.
diff --git a/src/location/declarativemaps/qdeclarativegeomapquickitem.cpp b/src/location/declarativemaps/qdeclarativegeomapquickitem.cpp
index 8c71e7be..5f9ecc8a 100644
--- a/src/location/declarativemaps/qdeclarativegeomapquickitem.cpp
+++ b/src/location/declarativemaps/qdeclarativegeomapquickitem.cpp
@@ -249,9 +249,10 @@ QGeoCoordinate QDeclarativeGeoMapQuickItem::coordinate()
*/
void QDeclarativeGeoMapQuickItem::setSourceItem(QQuickItem *sourceItem)
{
- if (sourceItem_.data() == sourceItem)
+ QQuickItem *item = qobject_cast<QQuickItem *>(sourceItem); // Workaround for QTBUG-72930
+ if (sourceItem_.data() == item)
return;
- sourceItem_ = sourceItem;
+ sourceItem_ = item;
polishAndUpdate();
emit sourceItemChanged();
}
diff --git a/src/location/labs/qdeclarativenavigator.cpp b/src/location/labs/qdeclarativenavigator.cpp
index 0bf5035f..5b98f27f 100644
--- a/src/location/labs/qdeclarativenavigator.cpp
+++ b/src/location/labs/qdeclarativenavigator.cpp
@@ -43,6 +43,24 @@
QT_BEGIN_NAMESPACE
/*!
+ \qmlmodule Qt.labs.location 1.0
+ \title Qt Labs Location QML Types
+ \ingroup qmlmodules
+ \brief Provides experimental QtLocation QML types, such as \l Navigator and
+ various map objects types (not to be confused with map items).
+
+ To use this module, import the module with the following line:
+
+ \code
+ import Qt.labs.location 1.0
+ \endcode
+
+ \note These types are experimental and subject to source-incompatible changes from one
+ Qt minor release to the next, until they are ready to be moved to the stable QtLocation QML
+ module.
+*/
+
+/*!
\qmltype Navigator
\instantiates QDeclarativeNavigator
\inqmlmodule Qt.labs.location
diff --git a/src/location/labs/qmapobjectview.cpp b/src/location/labs/qmapobjectview.cpp
index 2ffc27bc..fc583415 100644
--- a/src/location/labs/qmapobjectview.cpp
+++ b/src/location/labs/qmapobjectview.cpp
@@ -153,8 +153,8 @@ void QMapObjectView::classBegin()
QQmlInstanceModel *model = m_delegateModel;
connect(model, &QQmlInstanceModel::modelUpdated, this, &QMapObjectView::modelUpdated);
connect(model, &QQmlInstanceModel::createdItem, this, &QMapObjectView::createdItem);
- connect(model, &QQmlInstanceModel::destroyingItem, this, &QMapObjectView::destroyingItem);
- connect(model, &QQmlInstanceModel::initItem, this, &QMapObjectView::initItem);
+// connect(model, &QQmlInstanceModel::destroyingItem, this, &QMapObjectView::destroyingItem);
+// connect(model, &QQmlInstanceModel::initItem, this, &QMapObjectView::initItem);
}
void QMapObjectView::componentComplete()
@@ -278,11 +278,12 @@ void QMapObjectView::modelUpdated(const QQmlChangeSet &changeSet, bool reset)
}
}
+ QBoolBlocker createBlocker(m_creatingObject, true);
for (const QQmlChangeSet::Change &c: changeSet.inserts()) {
for (int idx = c.start(); idx < c.end(); idx++) {
m_instantiatedMapObjects.insert(idx, nullptr);
QGeoMapObject *mo = qobject_cast<QGeoMapObject *>(m_delegateModel->object(idx, incubationMode));
- if (mo) // if not, a createdItem signal will be emitted.
+ if (mo) // if not, a createdItem signal will be emitted later, else it has been emitted already while createBlocker is in effect.
addMapObjectToMap(mo, idx);
}
}
@@ -311,12 +312,17 @@ void QMapObjectView::removeMapObjectFromMap(int index)
{
if (index >= 0 && index < m_instantiatedMapObjects.size()) {
QGeoMapObject *mo = m_instantiatedMapObjects.takeAt(index);
- if (!mo) {
- m_delegateModel->cancel(index);
+ if (!mo)
return;
- }
+
mo->setMap(nullptr);
- m_delegateModel->release(mo);
+ QQmlInstanceModel::ReleaseFlags releaseStatus = m_delegateModel->release(mo);
+#ifdef QT_DEBUG
+ if (releaseStatus == QQmlInstanceModel::Referenced)
+ qWarning() << "object "<<mo<<" still referenced";
+#else
+ Q_UNUSED(releaseStatus)
+#endif
}
}
@@ -324,8 +330,10 @@ void QMapObjectView::removeMapObjectFromMap(int index)
// for explanation on when createdItem is emitted.
void QMapObjectView::createdItem(int index, QObject * /*object*/)
{
- if (m_instantiatedMapObjects.at(index))
- return; // The first call to object() apparently returned a valid item. Don't call it again.
+ if (m_creatingObject) {
+ // see QDeclarativeGeoMapItemView::createdItem
+ return;
+ }
// If here, according to the documentation above, object() should be called again for index,
// or else, it will be destroyed exiting this scope
@@ -333,6 +341,8 @@ void QMapObjectView::createdItem(int index, QObject * /*object*/)
mo = qobject_cast<QGeoMapObject *>(m_delegateModel->object(index, incubationMode));
if (mo)
addMapObjectToMap(mo, index);
+ else
+ qWarning() << "QQmlDelegateModel::object called in createdItem for " << index << " produced a null object";
}
diff --git a/src/location/labs/qmapobjectview_p.h b/src/location/labs/qmapobjectview_p.h
index 49b80883..76affced 100644
--- a/src/location/labs/qmapobjectview_p.h
+++ b/src/location/labs/qmapobjectview_p.h
@@ -107,8 +107,9 @@ protected:
QQmlComponent *m_delegate = nullptr;
QQmlDelegateModel *m_delegateModel = nullptr;
QVector<QPointer<QGeoMapObject>> m_instantiatedMapObjects;
- QVector<QPointer<QGeoMapObject>> m_pendingMapObjects;
+ QVector<QPointer<QGeoMapObject>> m_pendingMapObjects; // for items instantiated before the map is set
QVector<QPointer<QGeoMapObject>> m_userAddedMapObjects; // A third list containing the objects dynamically added through addMapObject
+ bool m_creatingObject = false;
};
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp b/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp
index 29cf0167..08a3b5a6 100644
--- a/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp
+++ b/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp
@@ -233,7 +233,7 @@ QGeoRoutingManagerEngineMapbox::QGeoRoutingManagerEngineMapbox(const QVariantMap
bool use_mapbox_text_instructions = true;
if (parameters.contains(QStringLiteral("mapbox.routing.use_mapbox_text_instructions"))) {
- use_mapbox_text_instructions = parameters.value(QStringLiteral("mapbox.use_mapbox_text_instructions")).toBool();
+ use_mapbox_text_instructions = parameters.value(QStringLiteral("mapbox.routing.use_mapbox_text_instructions")).toBool();
}
QGeoRouteParserOsrmV5 *parser = new QGeoRouteParserOsrmV5(this);
diff --git a/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp b/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp
index b55d2ba3..821d2e9f 100644
--- a/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp
+++ b/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp
@@ -57,11 +57,14 @@ using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;
typedef ITypedEventHandler<Geolocator *, PositionChangedEventArgs *> GeoLocatorPositionHandler;
+typedef ITypedEventHandler<Geolocator *, StatusChangedEventArgs *> GeoLocatorStatusHandler;
typedef IAsyncOperationCompletedHandler<Geoposition*> PositionHandler;
typedef IAsyncOperationCompletedHandler<GeolocationAccessStatus> AccessHandler;
Q_DECLARE_LOGGING_CATEGORY(lcPositioningWinRT)
+Q_DECLARE_METATYPE(QGeoPositionInfoSource::Error)
+
QT_BEGIN_NAMESPACE
#ifndef Q_OS_WINRT
@@ -103,51 +106,42 @@ static inline HRESULT await(const ComPtr<IAsyncOperation<GeolocationAccessStatus
}
#endif // !Q_OS_WINRT
+enum class InitializationState {
+ Uninitialized,
+ Initializing,
+ Initialized
+};
+
class QGeoPositionInfoSourceWinRTPrivate {
public:
ComPtr<IGeolocator> locator;
QTimer periodicTimer;
QTimer singleUpdateTimer;
QGeoPositionInfo lastPosition;
- QGeoPositionInfoSource::Error positionError;
+ QGeoPositionInfoSource::Error positionError = QGeoPositionInfoSource::NoError;
EventRegistrationToken statusToken;
EventRegistrationToken positionToken;
QMutex mutex;
- bool updatesOngoing;
- int minimumUpdateInterval;
+ bool updatesOngoing = false;
+ int minimumUpdateInterval = -1;
+ int updateInterval = -1;
+ InitializationState initState = InitializationState::Uninitialized;
- PositionStatus nativeStatus() const;
+ PositionStatus positionStatus = PositionStatus_NotInitialized;
};
-PositionStatus QGeoPositionInfoSourceWinRTPrivate::nativeStatus() const
-{
-#ifdef Q_OS_WINRT
- qCDebug(lcPositioningWinRT) << __FUNCTION__;
-
- PositionStatus status;
- HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, &status]() {
- return locator->get_LocationStatus(&status);
- });
- if (FAILED(hr)) {
- qErrnoWarning(hr, "Could not query status");
- return PositionStatus_NotAvailable;
- }
- return status;
-#else
- return PositionStatus_Ready;
-#endif
-}
-
-
QGeoPositionInfoSourceWinRT::QGeoPositionInfoSourceWinRT(QObject *parent)
: QGeoPositionInfoSource(parent)
, d_ptr(new QGeoPositionInfoSourceWinRTPrivate)
{
+ qRegisterMetaType<QGeoPositionInfoSource::Error>();
qCDebug(lcPositioningWinRT) << __FUNCTION__;
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
Q_D(QGeoPositionInfoSourceWinRT);
d->positionError = QGeoPositionInfoSource::NoError;
d->updatesOngoing = false;
+ d->positionToken.value = 0;
+ d->statusToken.value = 0;
}
QGeoPositionInfoSourceWinRT::~QGeoPositionInfoSourceWinRT()
@@ -158,9 +152,16 @@ QGeoPositionInfoSourceWinRT::~QGeoPositionInfoSourceWinRT()
int QGeoPositionInfoSourceWinRT::init()
{
- qCDebug(lcPositioningWinRT) << __FUNCTION__;
Q_D(QGeoPositionInfoSourceWinRT);
+ Q_ASSERT(d->initState != InitializationState::Initializing);
+ if (d->initState == InitializationState::Initialized)
+ return 0;
+
+ qCDebug(lcPositioningWinRT) << __FUNCTION__;
+ d->initState = InitializationState::Initializing;
if (!requestAccess()) {
+ d->initState = InitializationState::Uninitialized;
+ setError(QGeoPositionInfoSource::AccessError);
qWarning ("Location access failed.");
return -1;
}
@@ -169,37 +170,37 @@ int QGeoPositionInfoSourceWinRT::init()
&d->locator);
RETURN_HR_IF_FAILED("Could not initialize native location services.");
- UINT32 interval;
- hr = d->locator->get_ReportInterval(&interval);
- RETURN_HR_IF_FAILED("Could not retrieve report interval.");
- d->minimumUpdateInterval = static_cast<int>(interval);
- setUpdateInterval(d->minimumUpdateInterval);
+ if (d->minimumUpdateInterval == -1) {
+ UINT32 interval;
+ hr = d->locator->get_ReportInterval(&interval);
+ RETURN_HR_IF_FAILED("Could not retrieve report interval.");
+ d->minimumUpdateInterval = static_cast<int>(interval);
+ }
+ if (d->updateInterval == -1)
+ d->updateInterval = d->minimumUpdateInterval;
+ setUpdateInterval(d->updateInterval);
return hr;
});
if (FAILED(hr)) {
+ d->initState = InitializationState::Uninitialized;
setError(QGeoPositionInfoSource::UnknownSourceError);
return -1;
}
- hr = d->locator->put_DesiredAccuracy(PositionAccuracy::PositionAccuracy_Default);
- if (FAILED(hr)) {
- setError(QGeoPositionInfoSource::UnknownSourceError);
- qErrnoWarning(hr, "Could not initialize desired accuracy.");
- return -1;
- }
-
- d->positionToken.value = 0;
-
d->periodicTimer.setSingleShot(true);
connect(&d->periodicTimer, &QTimer::timeout, this, &QGeoPositionInfoSourceWinRT::virtualPositionUpdate);
d->singleUpdateTimer.setSingleShot(true);
connect(&d->singleUpdateTimer, &QTimer::timeout, this, &QGeoPositionInfoSourceWinRT::singleUpdateTimeOut);
- setPreferredPositioningMethods(QGeoPositionInfoSource::AllPositioningMethods);
+ QGeoPositionInfoSource::PositioningMethods preferredMethods = preferredPositioningMethods();
+ if (preferredMethods == QGeoPositionInfoSource::NoPositioningMethods)
+ preferredMethods = QGeoPositionInfoSource::AllPositioningMethods;
+ setPreferredPositioningMethods(preferredMethods);
connect(this, &QGeoPositionInfoSourceWinRT::nativePositionUpdate, this, &QGeoPositionInfoSourceWinRT::updateSynchronized);
+ d->initState = InitializationState::Initialized;
return 0;
}
@@ -213,19 +214,8 @@ QGeoPositionInfo QGeoPositionInfoSourceWinRT::lastKnownPosition(bool fromSatelli
QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSourceWinRT::supportedPositioningMethods() const
{
- Q_D(const QGeoPositionInfoSourceWinRT);
-
- PositionStatus status = d->nativeStatus();
- qCDebug(lcPositioningWinRT) << __FUNCTION__ << status;
-
- switch (status) {
- case PositionStatus::PositionStatus_NoData:
- case PositionStatus::PositionStatus_Disabled:
- case PositionStatus::PositionStatus_NotAvailable:
- return QGeoPositionInfoSource::NoPositioningMethods;
- }
-
- return QGeoPositionInfoSource::AllPositioningMethods;
+ return requestAccess() ? QGeoPositionInfoSource::AllPositioningMethods
+ : QGeoPositionInfoSource::NoPositioningMethods;
}
void QGeoPositionInfoSourceWinRT::setPreferredPositioningMethods(QGeoPositionInfoSource::PositioningMethods methods)
@@ -235,10 +225,12 @@ void QGeoPositionInfoSourceWinRT::setPreferredPositioningMethods(QGeoPositionInf
PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods();
QGeoPositionInfoSource::setPreferredPositioningMethods(methods);
- if (previousPreferredPositioningMethods == preferredPositioningMethods())
+ if (previousPreferredPositioningMethods == preferredPositioningMethods()
+ || d->initState == InitializationState::Uninitialized) {
return;
+ }
- const bool needsRestart = d->positionToken.value != 0;
+ const bool needsRestart = d->positionToken.value != 0 || d->statusToken.value != 0;
if (needsRestart)
stopHandler();
@@ -247,8 +239,7 @@ void QGeoPositionInfoSourceWinRT::setPreferredPositioningMethods(QGeoPositionInf
PositionAccuracy::PositionAccuracy_High :
PositionAccuracy::PositionAccuracy_Default;
HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([d, acc]() {
- HRESULT hr = d->locator->put_DesiredAccuracy(acc);
- return hr;
+ return d->locator->put_DesiredAccuracy(acc);
});
RETURN_VOID_IF_FAILED("Could not set positioning accuracy.");
@@ -260,13 +251,18 @@ void QGeoPositionInfoSourceWinRT::setUpdateInterval(int msec)
{
qCDebug(lcPositioningWinRT) << __FUNCTION__ << msec;
Q_D(QGeoPositionInfoSourceWinRT);
+ if (d->initState == InitializationState::Uninitialized) {
+ d->updateInterval = msec;
+ return;
+ }
+
// minimumUpdateInterval is initialized to the lowest possible update interval in init().
// Passing 0 will cause an error on Windows 10.
// See https://docs.microsoft.com/en-us/uwp/api/windows.devices.geolocation.geolocator.reportinterval
if (msec != 0 && msec < minimumUpdateInterval())
msec = minimumUpdateInterval();
- const bool needsRestart = d->positionToken.value != 0;
+ const bool needsRestart = d->positionToken.value != 0 || d->statusToken.value != 0;
if (needsRestart)
stopHandler();
@@ -278,9 +274,10 @@ void QGeoPositionInfoSourceWinRT::setUpdateInterval(int msec)
return;
}
- d->periodicTimer.setInterval(qMax(msec, minimumUpdateInterval()));
+ d->updateInterval = msec;
+ d->periodicTimer.setInterval(d->updateInterval);
- QGeoPositionInfoSource::setUpdateInterval(msec);
+ QGeoPositionInfoSource::setUpdateInterval(d->updateInterval);
if (needsRestart)
startHandler();
@@ -289,7 +286,7 @@ void QGeoPositionInfoSourceWinRT::setUpdateInterval(int msec)
int QGeoPositionInfoSourceWinRT::minimumUpdateInterval() const
{
Q_D(const QGeoPositionInfoSourceWinRT);
- return d->minimumUpdateInterval;
+ return d->minimumUpdateInterval == -1 ? 1000 : d->minimumUpdateInterval;
}
void QGeoPositionInfoSourceWinRT::startUpdates()
@@ -297,6 +294,10 @@ void QGeoPositionInfoSourceWinRT::startUpdates()
qCDebug(lcPositioningWinRT) << __FUNCTION__;
Q_D(QGeoPositionInfoSourceWinRT);
+ setError(QGeoPositionInfoSource::NoError);
+ if (init() < 0)
+ return;
+
if (d->updatesOngoing)
return;
@@ -311,6 +312,9 @@ void QGeoPositionInfoSourceWinRT::stopUpdates()
qCDebug(lcPositioningWinRT) << __FUNCTION__;
Q_D(QGeoPositionInfoSourceWinRT);
+ if (init() < 0)
+ return;
+
stopHandler();
d->updatesOngoing = false;
d->periodicTimer.stop();
@@ -330,8 +334,10 @@ bool QGeoPositionInfoSourceWinRT::startHandler()
return false;
}
- if (!requestAccess() || !checkNativeState())
+ if (!requestAccess()) {
+ setError(QGeoPositionInfoSource::AccessError);
return false;
+ }
HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
HRESULT hr;
@@ -348,6 +354,10 @@ bool QGeoPositionInfoSourceWinRT::startHandler()
&d->positionToken);
RETURN_HR_IF_FAILED("Could not add position handler");
+ hr = d->locator->add_StatusChanged(Callback<GeoLocatorStatusHandler>(this,
+ &QGeoPositionInfoSourceWinRT::onStatusChanged).Get(),
+ &d->statusToken);
+ RETURN_HR_IF_FAILED("Could not add status handler");
return hr;
});
if (FAILED(hr)) {
@@ -367,16 +377,22 @@ void QGeoPositionInfoSourceWinRT::stopHandler()
return;
QEventDispatcherWinRT::runOnXamlThread([d]() {
d->locator->remove_PositionChanged(d->positionToken);
+ d->locator->remove_StatusChanged(d->statusToken);
return S_OK;
});
d->positionToken.value = 0;
+ d->statusToken.value = 0;
}
void QGeoPositionInfoSourceWinRT::requestUpdate(int timeout)
{
- qCDebug(lcPositioningWinRT) << __FUNCTION__;
+ qCDebug(lcPositioningWinRT) << __FUNCTION__ << timeout;
Q_D(QGeoPositionInfoSourceWinRT);
+ if (init() < 0)
+ return;
+
+ setError(QGeoPositionInfoSource::NoError);
if (timeout != 0 && timeout < minimumUpdateInterval()) {
emit updateTimeout();
return;
@@ -395,12 +411,6 @@ void QGeoPositionInfoSourceWinRT::virtualPositionUpdate()
Q_D(QGeoPositionInfoSourceWinRT);
QMutexLocker locker(&d->mutex);
- // Need to check if services are still running and ok
- if (!checkNativeState()) {
- stopUpdates();
- return;
- }
-
// The operating system did not provide information in time
// Hence we send a virtual position update to keep same behavior
// between backends.
@@ -452,42 +462,33 @@ QGeoPositionInfoSource::Error QGeoPositionInfoSourceWinRT::error() const
{
Q_D(const QGeoPositionInfoSourceWinRT);
qCDebug(lcPositioningWinRT) << __FUNCTION__ << d->positionError;
+
+ // If the last encountered error was "Access denied", it is possible that the location service
+ // has been enabled by now so that we are clear again.
+ if ((d->positionError == QGeoPositionInfoSource::AccessError
+ || d->positionError == QGeoPositionInfoSource::UnknownSourceError) && requestAccess())
+ return QGeoPositionInfoSource::NoError;
+
return d->positionError;
}
void QGeoPositionInfoSourceWinRT::setError(QGeoPositionInfoSource::Error positionError)
{
- qCDebug(lcPositioningWinRT) << __FUNCTION__ << positionError;
Q_D(QGeoPositionInfoSourceWinRT);
if (positionError == d->positionError)
return;
+
+ qCDebug(lcPositioningWinRT) << __FUNCTION__ << positionError;
d->positionError = positionError;
- emit QGeoPositionInfoSource::error(positionError);
+ if (positionError != QGeoPositionInfoSource::NoError)
+ emit QGeoPositionInfoSource::error(positionError);
}
-bool QGeoPositionInfoSourceWinRT::checkNativeState()
+void QGeoPositionInfoSourceWinRT::reactOnError(QGeoPositionInfoSource::Error positionError)
{
- Q_D(QGeoPositionInfoSourceWinRT);
- qCDebug(lcPositioningWinRT) << __FUNCTION__;
-
- PositionStatus status = d->nativeStatus();
-
- bool result = false;
- switch (status) {
- case PositionStatus::PositionStatus_NotAvailable:
- setError(QGeoPositionInfoSource::UnknownSourceError);
- break;
- case PositionStatus::PositionStatus_Disabled:
- case PositionStatus::PositionStatus_NoData:
- setError(QGeoPositionInfoSource::ClosedError);
- break;
- default:
- setError(QGeoPositionInfoSource::NoError);
- result = true;
- break;
- }
- return result;
+ setError(positionError);
+ stopUpdates();
}
HRESULT QGeoPositionInfoSourceWinRT::onPositionChanged(IGeolocator *locator, IPositionChangedEventArgs *args)
@@ -597,24 +598,59 @@ HRESULT QGeoPositionInfoSourceWinRT::onPositionChanged(IGeolocator *locator, IPo
return S_OK;
}
+static inline bool isDisabledStatus(PositionStatus status)
+{
+ return status == PositionStatus_NoData || status == PositionStatus_Disabled
+ || status == PositionStatus_NotAvailable;
+}
+
+HRESULT QGeoPositionInfoSourceWinRT::onStatusChanged(IGeolocator *, IStatusChangedEventArgs *args)
+{
+ Q_D(QGeoPositionInfoSourceWinRT);
+
+ const PositionStatus oldStatus = d->positionStatus;
+ HRESULT hr = args->get_Status(&d->positionStatus);
+ RETURN_HR_IF_FAILED("Could not obtain position status");
+ qCDebug(lcPositioningWinRT) << __FUNCTION__ << d->positionStatus;
+ QGeoPositionInfoSource::Error error = QGeoPositionInfoSource::NoError;
+ switch (d->positionStatus) {
+ case PositionStatus::PositionStatus_NotAvailable:
+ error = QGeoPositionInfoSource::UnknownSourceError;
+ break;
+ case PositionStatus::PositionStatus_Disabled:
+ error = QGeoPositionInfoSource::AccessError;
+ break;
+ case PositionStatus::PositionStatus_NoData:
+ error = QGeoPositionInfoSource::ClosedError;
+ break;
+ }
+ if (error != QGeoPositionInfoSource::NoError) {
+ QMetaObject::invokeMethod(this, "reactOnError", Qt::QueuedConnection,
+ Q_ARG(QGeoPositionInfoSource::Error,
+ QGeoPositionInfoSource::UnknownSourceError));
+ }
+
+ if (isDisabledStatus(oldStatus) != isDisabledStatus(d->positionStatus))
+ emit supportedPositioningMethodsChanged();
+
+ return S_OK;
+}
+
bool QGeoPositionInfoSourceWinRT::requestAccess() const
{
qCDebug(lcPositioningWinRT) << __FUNCTION__;
- static GeolocationAccessStatus accessStatus = GeolocationAccessStatus_Unspecified;
+ GeolocationAccessStatus accessStatus;
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.");
+ if (!statics) {
+ 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;
diff --git a/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h b/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h
index 4319ccae..dbfde0e9 100644
--- a/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h
+++ b/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h
@@ -62,6 +62,7 @@ namespace ABI {
namespace Geolocation{
struct IGeolocator;
struct IPositionChangedEventArgs;
+ struct IStatusChangedEventArgs;
}
}
}
@@ -76,41 +77,43 @@ class QGeoPositionInfoSourceWinRT : public QGeoPositionInfoSource
Q_OBJECT
public:
QGeoPositionInfoSourceWinRT(QObject *parent = nullptr);
- ~QGeoPositionInfoSourceWinRT();
+ ~QGeoPositionInfoSourceWinRT() override;
int init();
- QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const;
- PositioningMethods supportedPositioningMethods() const;
+ QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const override;
+ PositioningMethods supportedPositioningMethods() const override;
- void setPreferredPositioningMethods(PositioningMethods methods);
+ void setPreferredPositioningMethods(PositioningMethods methods) override;
- void setUpdateInterval(int msec);
- int minimumUpdateInterval() const;
- Error error() const;
+ void setUpdateInterval(int msec) override;
+ int minimumUpdateInterval() const override;
+ Error error() const override;
HRESULT onPositionChanged(ABI::Windows::Devices::Geolocation::IGeolocator *locator,
ABI::Windows::Devices::Geolocation::IPositionChangedEventArgs *args);
+ HRESULT onStatusChanged(ABI::Windows::Devices::Geolocation::IGeolocator *locator,
+ ABI::Windows::Devices::Geolocation::IStatusChangedEventArgs *args);
bool requestAccess() const;
Q_SIGNALS:
void nativePositionUpdate(const QGeoPositionInfo);
public slots:
- void startUpdates();
- void stopUpdates();
+ void startUpdates() override;
+ void stopUpdates() override;
- void requestUpdate(int timeout = 0);
+ void requestUpdate(int timeout = 0) override;
private slots:
void stopHandler();
void virtualPositionUpdate();
void singleUpdateTimeOut();
void updateSynchronized(const QGeoPositionInfo info);
+ void reactOnError(QGeoPositionInfoSource::Error positionError);
private:
bool startHandler();
Q_DISABLE_COPY(QGeoPositionInfoSourceWinRT)
void setError(QGeoPositionInfoSource::Error positionError);
- bool checkNativeState();
QScopedPointer<QGeoPositionInfoSourceWinRTPrivate> d_ptr;
Q_DECLARE_PRIVATE(QGeoPositionInfoSourceWinRT)
diff --git a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp
index b1ec6fb3..03b86ca7 100644
--- a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp
+++ b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp
@@ -47,12 +47,6 @@ QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryWinRT::positionInfoSource(Q
{
qCDebug(lcPositioningWinRT) << __FUNCTION__;
QGeoPositionInfoSourceWinRT *src = new QGeoPositionInfoSourceWinRT(parent);
- if (src->init() < 0) {
- qCDebug(lcPositioningWinRT) << __FUNCTION__ << "Source initialization failed.";
- delete src;
- return nullptr;
- }
- qCDebug(lcPositioningWinRT) << __FUNCTION__ << "Created position info source.";
return src;
}
diff --git a/src/positioning/qgeorectangle.cpp b/src/positioning/qgeorectangle.cpp
index 337b4c76..a760831c 100644
--- a/src/positioning/qgeorectangle.cpp
+++ b/src/positioning/qgeorectangle.cpp
@@ -938,31 +938,36 @@ QGeoRectangle &QGeoRectangle::operator|=(const QGeoRectangle &rectangle)
bool joinWrapLeft = (nonWrapRight >= wrapLeft);
bool joinWrapRight = (nonWrapLeft <= wrapRight);
- if (joinWrapLeft) {
- if (joinWrapRight) {
- left = -180.0;
- right = 180.0;
- } else {
- left = nonWrapLeft;
- right = wrapRight;
- }
+ if (wrapLeft <= nonWrapLeft) { // The wrapping rectangle contains the non-wrapping one entirely
+ left = wrapLeft;
+ right = wrapRight;
} else {
- if (joinWrapRight) {
- left = wrapLeft;
- right = nonWrapRight;
- } else {
- double wrapRightDistance = nonWrapLeft - wrapRight;
- double wrapLeftDistance = wrapLeft - nonWrapRight;
-
- if (wrapLeftDistance == wrapRightDistance) {
+ if (joinWrapLeft) {
+ if (joinWrapRight) {
left = -180.0;
right = 180.0;
- } else if (wrapLeftDistance < wrapRightDistance) {
+ } else {
left = nonWrapLeft;
right = wrapRight;
- } else {
+ }
+ } else {
+ if (joinWrapRight) {
left = wrapLeft;
right = nonWrapRight;
+ } else {
+ double wrapRightDistance = nonWrapLeft - wrapRight;
+ double wrapLeftDistance = wrapLeft - nonWrapRight;
+
+ if (wrapLeftDistance == wrapRightDistance) {
+ left = -180.0;
+ right = 180.0;
+ } else if (wrapLeftDistance < wrapRightDistance) {
+ left = nonWrapLeft;
+ right = wrapRight;
+ } else {
+ left = wrapLeft;
+ right = nonWrapRight;
+ }
}
}
}
diff --git a/tests/applications/positioning_backend/main.cpp b/tests/applications/positioning_backend/main.cpp
index 52115556..2ed69cb6 100644
--- a/tests/applications/positioning_backend/main.cpp
+++ b/tests/applications/positioning_backend/main.cpp
@@ -31,8 +31,11 @@
#include <QApplication>
#include <QtWidgets>
+#include <QLoggingCategory>
+
int main(int argc, char *argv[])
{
+ //QLoggingCategory::setFilterRules("qt.positioning.*=true");
QApplication a(argc, argv);
LogWidget *log = new LogWidget;
diff --git a/tests/applications/positioning_backend/widget.cpp b/tests/applications/positioning_backend/widget.cpp
index efdaebdd..3244c478 100644
--- a/tests/applications/positioning_backend/widget.cpp
+++ b/tests/applications/positioning_backend/widget.cpp
@@ -102,7 +102,9 @@ void Widget::positionTimedOut()
void Widget::errorChanged(QGeoPositionInfoSource::Error err)
{
- ui->labelErrorState->setText(err == 3 ? QStringLiteral("OK") : QString::number(err));
+ ui->labelErrorState->setText(QString::number(err));
+ m_posSource->stopUpdates();
+ ui->checkBox->setChecked(false);
}
Widget::~Widget()
@@ -126,11 +128,11 @@ void Widget::on_buttonStart_clicked()
// Either start or stop the current position info source
bool running = ui->checkBox->isChecked();
if (running) {
- m_posSource->stopUpdates();
ui->checkBox->setChecked(false);
+ m_posSource->stopUpdates();
} else {
- m_posSource->startUpdates();
ui->checkBox->setChecked(true);
+ m_posSource->startUpdates();
}
}
@@ -175,3 +177,8 @@ void Widget::on_buttonUpdateSupported_clicked()
ui->labelSupported->setText(text);
}
+
+void Widget::on_buttonResetError_clicked()
+{
+ ui->labelErrorState->setText(QStringLiteral("N/A"));
+}
diff --git a/tests/applications/positioning_backend/widget.h b/tests/applications/positioning_backend/widget.h
index b67e53b8..e0dc68fc 100644
--- a/tests/applications/positioning_backend/widget.h
+++ b/tests/applications/positioning_backend/widget.h
@@ -59,6 +59,7 @@ private slots:
void on_radioButton_4_clicked();
void on_buttonUpdateSupported_clicked();
+ void on_buttonResetError_clicked();
private:
LogWidget *log = nullptr;
diff --git a/tests/applications/positioning_backend/widget.ui b/tests/applications/positioning_backend/widget.ui
index a96a83f6..9cb1566d 100644
--- a/tests/applications/positioning_backend/widget.ui
+++ b/tests/applications/positioning_backend/widget.ui
@@ -135,11 +135,22 @@
</widget>
</item>
<item row="11" column="1">
- <widget class="QLabel" name="labelErrorState">
- <property name="text">
- <string>N/A</string>
- </property>
- </widget>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QLabel" name="labelErrorState">
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonResetError">
+ <property name="text">
+ <string>Reset</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
<item row="10" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
@@ -199,7 +210,7 @@
<rect>
<x>43</x>
<y>21</y>
- <width>251</width>
+ <width>254</width>
<height>71</height>
</rect>
</property>
diff --git a/tests/auto/qgeorectangle/tst_qgeorectangle.cpp b/tests/auto/qgeorectangle/tst_qgeorectangle.cpp
index 01f0104b..219e8dfd 100644
--- a/tests/auto/qgeorectangle/tst_qgeorectangle.cpp
+++ b/tests/auto/qgeorectangle/tst_qgeorectangle.cpp
@@ -2080,6 +2080,14 @@ void tst_QGeoRectangle::unite_data()
<< QGeoRectangle(QGeoCoordinate(30.0, -180.0),
QGeoCoordinate(-30.0, 180.0));
+ QTest::newRow("wrapping and one containing other")
+ << QGeoRectangle(QGeoCoordinate(30.0, 40.0),
+ QGeoCoordinate(-30.0, -40.0))
+ << QGeoRectangle(QGeoCoordinate(30.0, 160.0),
+ QGeoCoordinate(-30.0, 170.0))
+ << QGeoRectangle(QGeoCoordinate(30.0, 40.0),
+ QGeoCoordinate(-30.0, -40.0));
+
QTest::newRow("small gap over zero line")
<< QGeoRectangle(QGeoCoordinate(30.0, -20.0),
QGeoCoordinate(-30.0, -10.0))