diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-01-22 09:29:14 +0100 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-01-22 09:29:14 +0100 |
commit | d369cf01b5617961c2d0c9db7a7be6c25b42954a (patch) | |
tree | bcd31b4ca0edc5c554483f88cc0e9d5dc16e934a | |
parent | 9485871222fb3c8f5f2d058ae8c5c0ca13b0ce2c (diff) | |
parent | b17c07dc0b947c979372fbaf558ce9acc07d1837 (diff) | |
download | qtlocation-d369cf01b5617961c2d0c9db7a7be6c25b42954a.tar.gz |
Merge remote-tracking branch 'origin/5.12' into dev
Conflicts:
.qmake.conf
Change-Id: I8d0881209c8b0a0dce4ed949ef89ee2679448420
10 files changed, 212 insertions, 149 deletions
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/qmapobjectview.cpp b/src/location/labs/qmapobjectview.cpp index 7a7d7d3d..27b0ecb8 100644 --- a/src/location/labs/qmapobjectview.cpp +++ b/src/location/labs/qmapobjectview.cpp @@ -185,8 +185,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() @@ -315,11 +315,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); } } @@ -348,12 +349,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 } } @@ -361,8 +367,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 @@ -370,6 +378,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 5e85aa7a..be5801d3 100644 --- a/src/location/labs/qmapobjectview_p.h +++ b/src/location/labs/qmapobjectview_p.h @@ -105,8 +105,9 @@ protected: 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..fe783bd2 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,13 @@ 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; + Q_ASSERT(d->initState != InitializationState::Initializing); + const bool needsRestart = d->positionToken.value != 0 || d->statusToken.value != 0; if (needsRestart) stopHandler(); @@ -247,8 +240,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 +252,19 @@ void QGeoPositionInfoSourceWinRT::setUpdateInterval(int msec) { qCDebug(lcPositioningWinRT) << __FUNCTION__ << msec; Q_D(QGeoPositionInfoSourceWinRT); + if (d->initState == InitializationState::Uninitialized) { + d->updateInterval = msec; + return; + } + + Q_ASSERT(d->initState != InitializationState::Initializing); // 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 +276,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 +288,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 +296,10 @@ void QGeoPositionInfoSourceWinRT::startUpdates() qCDebug(lcPositioningWinRT) << __FUNCTION__; Q_D(QGeoPositionInfoSourceWinRT); + setError(QGeoPositionInfoSource::NoError); + if (init() < 0) + return; + if (d->updatesOngoing) return; @@ -311,6 +314,9 @@ void QGeoPositionInfoSourceWinRT::stopUpdates() qCDebug(lcPositioningWinRT) << __FUNCTION__; Q_D(QGeoPositionInfoSourceWinRT); + if (init() < 0) + return; + stopHandler(); d->updatesOngoing = false; d->periodicTimer.stop(); @@ -330,8 +336,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 +356,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 +379,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 +413,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 +464,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 +600,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 bb2debcf..80dd41b4 100644 --- a/src/positioning/qgeorectangle.cpp +++ b/src/positioning/qgeorectangle.cpp @@ -939,31 +939,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/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)) |