1 /*
2   geopositioninfosource.cpp
3 
4   This file is part of GammaRay, the Qt application inspection and
5   manipulation tool.
6 
7   Copyright (C) 2015-2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
8   Author: Volker Krause <volker.krause@kdab.com>
9 
10   Licensees holding valid commercial KDAB GammaRay licenses may use this file in
11   accordance with GammaRay Commercial License Agreement provided with the Software.
12 
13   Contact info@kdab.com if any conditions of this licensing are not clear to you.
14 
15   This program is free software; you can redistribute it and/or modify
16   it under the terms of the GNU General Public License as published by
17   the Free Software Foundation, either version 2 of the License, or
18   (at your option) any later version.
19 
20   This program is distributed in the hope that it will be useful,
21   but WITHOUT ANY WARRANTY; without even the implied warranty of
22   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23   GNU General Public License for more details.
24 
25   You should have received a copy of the GNU General Public License
26   along with this program.  If not, see <http://www.gnu.org/licenses/>.
27 */
28 
29 #include "geopositioninfosource.h"
30 #include "positioninginterface.h"
31 
32 #include <QDebug>
33 
34 using namespace GammaRay;
35 
GeoPositionInfoSource(QObject * parent)36 GeoPositionInfoSource::GeoPositionInfoSource(QObject* parent) :
37     QGeoPositionInfoSource(parent),
38     m_source(nullptr),
39     m_interface(nullptr)
40 {
41 }
42 
43 GeoPositionInfoSource::~GeoPositionInfoSource() = default;
44 
setSource(QGeoPositionInfoSource * source)45 void GeoPositionInfoSource::setSource(QGeoPositionInfoSource* source)
46 {
47     Q_ASSERT(!m_source);
48     m_source = source;
49     if (source && !overrideEnabled())
50         connectSource();
51     setupSourceUpdate();
52 }
53 
error() const54 QGeoPositionInfoSource::Error GeoPositionInfoSource::error() const
55 {
56     if (m_source)
57         return m_source->error();
58     return UnknownSourceError;
59 }
60 
lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const61 QGeoPositionInfo GeoPositionInfoSource::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
62 {
63     if (m_source && !overrideEnabled())
64         return m_source->lastKnownPosition(fromSatellitePositioningMethodsOnly);
65 
66     if (m_interface)
67         return m_interface->positionInfoOverride();
68     return QGeoPositionInfo();
69 }
70 
minimumUpdateInterval() const71 int GeoPositionInfoSource::minimumUpdateInterval() const
72 {
73     if (m_source)
74         return m_source->minimumUpdateInterval();
75     return 10000;
76 }
77 
setPreferredPositioningMethods(PositioningMethods methods)78 void GeoPositionInfoSource::setPreferredPositioningMethods(PositioningMethods methods)
79 {
80     if (m_source) {
81         m_source->setPreferredPositioningMethods(methods);
82         QGeoPositionInfoSource::setPreferredPositioningMethods(m_source->preferredPositioningMethods());
83     } else {
84         QGeoPositionInfoSource::setPreferredPositioningMethods(methods);
85     }
86 }
87 
setUpdateInterval(int msec)88 void GeoPositionInfoSource::setUpdateInterval(int msec)
89 {
90   if (m_source) {
91     m_source->setUpdateInterval(msec);
92     QGeoPositionInfoSource::setUpdateInterval(m_source->updateInterval());
93   } else {
94     QGeoPositionInfoSource::setUpdateInterval(msec);
95   }
96 }
97 
supportedPositioningMethods() const98 QGeoPositionInfoSource::PositioningMethods GeoPositionInfoSource::supportedPositioningMethods() const
99 {
100     if (m_source)
101         return m_source->supportedPositioningMethods();
102     return AllPositioningMethods;
103 }
104 
requestUpdate(int timeout)105 void GeoPositionInfoSource::requestUpdate(int timeout)
106 {
107     if (m_source)
108         m_source->requestUpdate(timeout);
109 }
110 
startUpdates()111 void GeoPositionInfoSource::startUpdates()
112 {
113     if (m_source)
114         m_source->startUpdates();
115 }
116 
stopUpdates()117 void GeoPositionInfoSource::stopUpdates()
118 {
119     if (m_source)
120         m_source->stopUpdates();
121 }
122 
setInterface(PositioningInterface * iface)123 void GeoPositionInfoSource::setInterface(PositioningInterface* iface)
124 {
125     Q_ASSERT(iface);
126     m_interface = iface;
127     m_interface->setPositioningOverrideAvailable(true);
128     connect(m_interface, &PositioningInterface::positioningOverrideEnabledChanged, this, &GeoPositionInfoSource::overrideChanged);
129     connect(m_interface, &PositioningInterface::positionInfoOverrideChanged, this, &GeoPositionInfoSource::positionInfoOverrideChanged);
130     if (overrideEnabled())
131         emit positionUpdated(lastKnownPosition());
132     setupSourceUpdate();
133 }
134 
overrideEnabled() const135 bool GeoPositionInfoSource::overrideEnabled() const
136 {
137     return m_interface && m_interface->positioningOverrideEnabled();
138 }
139 
overrideChanged()140 void GeoPositionInfoSource::overrideChanged()
141 {
142     if (!overrideEnabled())
143         connectSource();
144     else
145         disconnectSource();
146     emit positionUpdated(lastKnownPosition());
147 }
148 
positionInfoOverrideChanged()149 void GeoPositionInfoSource::positionInfoOverrideChanged()
150 {
151     if (overrideEnabled())
152         emit positionUpdated(lastKnownPosition());
153 }
154 
connectSource()155 void GeoPositionInfoSource::connectSource()
156 {
157     if (!m_source)
158         return;
159     connect(m_source, QOverload<QGeoPositionInfoSource::Error>::of(&QGeoPositionInfoSource::error), this, &GeoPositionInfoSource::error, Qt::UniqueConnection);
160     connect(m_source, &QGeoPositionInfoSource::positionUpdated, this, &GeoPositionInfoSource::positionUpdated, Qt::UniqueConnection);
161     connect(m_source, &QGeoPositionInfoSource::updateTimeout, this, &GeoPositionInfoSource::updateTimeout, Qt::UniqueConnection);
162     QGeoPositionInfoSource::setPreferredPositioningMethods(m_source->preferredPositioningMethods());
163     QGeoPositionInfoSource::setUpdateInterval(m_source->updateInterval());
164 }
165 
disconnectSource()166 void GeoPositionInfoSource::disconnectSource()
167 {
168     if (!m_source)
169         return;
170     disconnect(m_source, QOverload<QGeoPositionInfoSource::Error>::of(&QGeoPositionInfoSource::error), this, &GeoPositionInfoSource::error);
171     disconnect(m_source, &QGeoPositionInfoSource::positionUpdated, this, &GeoPositionInfoSource::positionUpdated);
172     disconnect(m_source, &QGeoPositionInfoSource::updateTimeout, this, &GeoPositionInfoSource::updateTimeout);
173 }
174 
setupSourceUpdate()175 void GeoPositionInfoSource::setupSourceUpdate()
176 {
177     if (!m_source || !m_interface)
178         return;
179     connect(m_source, &QGeoPositionInfoSource::positionUpdated, m_interface, &PositioningInterface::setPositionInfo);
180 }
181