1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtSensors module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qmlsensor.h"
41#include <QtSensors/QSensor>
42#include <QDebug>
43
44QT_BEGIN_NAMESPACE
45
46/*!
47 \qmltype Sensor
48 \instantiates QmlSensor
49 \inqmlmodule QtSensors
50 \since QtSensors 5.0
51 \brief The Sensor element serves as a base type for sensors.
52
53 The Sensor element serves as a base type for sensors.
54
55 This element wraps the QSensor class. Please see the documentation for
56 QSensor for details.
57
58 This element cannot be directly created. Please use one of the sub-classes instead.
59*/
60
61QmlSensor::QmlSensor(QObject *parent)
62 : QObject(parent)
63 , m_parsed(false)
64 , m_active(false)
65 , m_reading(0)
66{
67}
68
69QmlSensor::~QmlSensor()
70{
71}
72
73/*!
74 \qmlproperty string Sensor::identifier
75 This property holds the backend identifier for the sensor.
76
77 Please see QSensor::identifier for information about this property.
78*/
79
80QString QmlSensor::identifier() const
81{
82 return m_identifier;
83}
84
85void QmlSensor::setIdentifier(const QString &identifier)
86{
87 if (m_parsed) return;
88 m_identifier = identifier;
89 Q_EMIT identifierChanged();
90}
91
92/*!
93 \qmlproperty string Sensor::type
94 This property holds the type of the sensor.
95*/
96
97QString QmlSensor::type() const
98{
99 return QString::fromLatin1(sensor()->type());
100}
101
102/*!
103 \qmlproperty bool Sensor::connectedToBackend
104 This property holds a value indicating if the sensor has connected to a backend.
105
106 Please see QSensor::connectedToBackend for information about this property.
107*/
108
109bool QmlSensor::isConnectedToBackend() const
110{
111 return sensor()->isConnectedToBackend();
112}
113
114/*!
115 \qmlproperty bool Sensor::busy
116 This property holds a value to indicate if the sensor is busy.
117
118 Please see QSensor::busy for information about this property.
119*/
120
121bool QmlSensor::isBusy() const
122{
123 return sensor()->isBusy();
124}
125
126/*!
127 \qmlproperty bool Sensor::active
128 This property holds a value to indicate if the sensor is active.
129
130 Please see QSensor::active for information about this property.
131*/
132
133void QmlSensor::setActive(bool active)
134{
135 m_active = active;
136 if (!m_parsed) return; // delay (it'll get called again later)!
137 bool wasActive = sensor()->isActive();
138 if (wasActive == active) return;
139 if (active) {
140 sensor()->start();
141 m_active = sensor()->isActive();
142 } else {
143 sensor()->stop();
144 }
145 if (m_active != wasActive)
146 emit activeChanged();
147}
148
149bool QmlSensor::isActive() const
150{
151 return m_active;
152}
153
154/*!
155 \qmlproperty bool Sensor::alwaysOn
156 This property holds a value to indicate if the sensor should remain running when the screen is off.
157
158 Please see QSensor::alwaysOn for information about this property.
159*/
160
161bool QmlSensor::isAlwaysOn() const
162{
163 return sensor()->isAlwaysOn();
164}
165
166void QmlSensor::setAlwaysOn(bool alwaysOn)
167{
168 sensor()->setAlwaysOn(alwaysOn);
169}
170
171/*!
172 \qmlproperty bool Sensor::skipDuplicates
173 \since QtSensors 5.1
174
175 This property indicates whether duplicate reading values should be omitted.
176
177 Please see QSensor::skipDuplicates for information about this property.
178*/
179
180bool QmlSensor::skipDuplicates() const
181{
182 return sensor()->skipDuplicates();
183}
184
185void QmlSensor::setSkipDuplicates(bool skipDuplicates)
186{
187 sensor()->setSkipDuplicates(skipDuplicates);
188}
189
190/*!
191 \qmlproperty list<Range> Sensor::availableDataRates
192 This property holds the data rates that the sensor supports.
193
194 Please see QSensor::availableDataRates for information about this property.
195*/
196
197QQmlListProperty<QmlSensorRange> QmlSensor::availableDataRates() const
198{
199 QList<QmlSensorRange*> ret;
200 ret.reserve(sensor()->availableDataRates().size());
201 foreach (const qrange &r, sensor()->availableDataRates()) {
202 QmlSensorRange *range = new QmlSensorRange;
203 //QQmlEngine::setObjectOwnership(range, QQmlEngine::JavaScriptOwnership);
204 range->setMinumum(r.first);
205 range->setMaximum(r.second);
206 ret << range;
207 }
208 return QQmlListProperty<QmlSensorRange>(const_cast<QmlSensor*>(this), ret);
209}
210
211/*!
212 \qmlproperty int Sensor::dataRate
213 This property holds the data rate that the sensor should be run at.
214
215 Please see QSensor::dataRate for information about this property.
216*/
217
218int QmlSensor::dataRate() const
219{
220 return sensor()->dataRate();
221}
222
223void QmlSensor::setDataRate(int rate)
224{
225 if (rate != dataRate()) {
226 sensor()->setDataRate(rate);
227 Q_EMIT dataRateChanged();
228 }
229}
230
231/*!
232 \qmlproperty list<OutputRange> Sensor::outputRanges
233 This property holds a list of output ranges the sensor supports.
234
235 Please see QSensor::outputRanges for information about this property.
236*/
237
238QQmlListProperty<QmlSensorOutputRange> QmlSensor::outputRanges() const
239{
240 QList<QmlSensorOutputRange*> ret;
241 ret.reserve(sensor()->outputRanges().size());
242 foreach (const qoutputrange &r, sensor()->outputRanges()) {
243 QmlSensorOutputRange *range = new QmlSensorOutputRange;
244 //QQmlEngine::setObjectOwnership(range, QQmlEngine::JavaScriptOwnership);
245 range->setMinimum(r.minimum);
246 range->setMaximum(r.maximum);
247 range->setAccuracy(r.accuracy);
248 ret << range;
249 }
250 return QQmlListProperty<QmlSensorOutputRange>(const_cast<QmlSensor*>(this), ret);
251}
252
253/*!
254 \qmlproperty int Sensor::outputRange
255 This property holds the output range in use by the sensor.
256
257 Please see QSensor::outputRange for information about this property.
258*/
259
260int QmlSensor::outputRange() const
261{
262 return sensor()->outputRange();
263}
264
265void QmlSensor::setOutputRange(int index)
266{
267 int oldRange = outputRange();
268 if (oldRange == index) return;
269 sensor()->setOutputRange(index);
270 if (sensor()->outputRange() == index)
271 Q_EMIT outputRangeChanged();
272}
273
274/*!
275 \qmlproperty string Sensor::description
276 This property holds a descriptive string for the sensor.
277*/
278
279QString QmlSensor::description() const
280{
281 return sensor()->description();
282}
283
284/*!
285 \qmlproperty int Sensor::error
286 This property holds the last error code set on the sensor.
287*/
288
289int QmlSensor::error() const
290{
291 return sensor()->error();
292}
293
294/*!
295 \qmlproperty SensorReading Sensor::reading
296 This property holds the reading class.
297
298 Please see QSensor::reading for information about this property.
299 \sa {QML Reading types}
300*/
301
302QmlSensorReading *QmlSensor::reading() const
303{
304 return m_reading;
305}
306
307/*!
308 \qmlproperty Sensor::AxesOrientationMode Sensor::axesOrientationMode
309 \since QtSensors 5.1
310 This property holds the mode that affects how the screen orientation changes reading values.
311
312 Please see QSensor::axesOrientationMode for information about this property.
313*/
314
315QmlSensor::AxesOrientationMode QmlSensor::axesOrientationMode() const
316{
317 return static_cast<QmlSensor::AxesOrientationMode>(sensor()->axesOrientationMode());
318}
319
320void QmlSensor::setAxesOrientationMode(QmlSensor::AxesOrientationMode axesOrientationMode)
321{
322 sensor()->setAxesOrientationMode(static_cast<QSensor::AxesOrientationMode>(axesOrientationMode));
323}
324
325/*!
326 \qmlproperty int Sensor::currentOrientation
327 \since QtSensors 5.1
328 This property holds the current orientation that is used for rotating the reading values.
329
330 Please see QSensor::currentOrientation for information about this property.
331*/
332
333int QmlSensor::currentOrientation() const
334{
335 return sensor()->currentOrientation();
336}
337
338/*!
339 \qmlproperty int Sensor::userOrientation
340 \since QtSensors 5.1
341 This property holds the angle used for rotating the reading values in the UserOrientation mode.
342
343 Please see QSensor::userOrientation for information about this property.
344*/
345
346int QmlSensor::userOrientation() const
347{
348 return sensor()->userOrientation();
349}
350
351void QmlSensor::setUserOrientation(int userOrientation)
352{
353 sensor()->setUserOrientation(userOrientation);
354}
355
356/*!
357 \qmlproperty int Sensor::maxBufferSize
358 \since QtSensors 5.1
359 This property holds the maximum buffer size.
360
361 Please see QSensor::maxBufferSize for information about this property.
362*/
363
364int QmlSensor::maxBufferSize() const
365{
366 return sensor()->maxBufferSize();
367}
368
369/*!
370 \qmlproperty int Sensor::efficientBufferSize
371 \since QtSensors 5.1
372 The property holds the most efficient buffer size.
373
374 Please see QSensor::efficientBufferSize for information about this property.
375*/
376
377int QmlSensor::efficientBufferSize() const
378{
379 return sensor()->efficientBufferSize();
380}
381
382/*!
383 \qmlproperty int Sensor::bufferSize
384 \since QtSensors 5.1
385 This property holds the size of the buffer.
386
387 Please see QSensor::bufferSize for information about this property.
388*/
389
390int QmlSensor::bufferSize() const
391{
392 return sensor()->bufferSize();
393}
394
395void QmlSensor::setBufferSize(int bufferSize)
396{
397 sensor()->setBufferSize(bufferSize);
398}
399
400/*!
401 \qmlmethod bool Sensor::start()
402 Start retrieving values from the sensor. Returns true if the sensor
403 was started, false otherwise.
404
405 Please see QSensor::start() for information.
406*/
407
408bool QmlSensor::start()
409{
410 setActive(true);
411 return isActive();
412}
413
414/*!
415 \qmlmethod bool Sensor::stop()
416 Stop retrieving values from the sensor.
417 Returns true if the sensor was stopped, false otherwise.
418
419 Please see QSensor::stop() for information.
420*/
421
422void QmlSensor::stop()
423{
424 setActive(false);
425}
426
427void QmlSensor::classBegin()
428{
429}
430
431void QmlSensor::componentComplete()
432{
433 m_parsed = true;
434
435 connect(sensor(), SIGNAL(sensorError(int)), this, SIGNAL(errorChanged()));
436 connect(sensor(), SIGNAL(activeChanged()), this, SIGNAL(activeChanged()));
437 connect(sensor(), SIGNAL(alwaysOnChanged()), this, SIGNAL(alwaysOnChanged()));
438 connect(sensor(), SIGNAL(skipDuplicatesChanged(bool)), this, SIGNAL(skipDuplicatesChanged(bool)));
439 connect(sensor(), SIGNAL(axesOrientationModeChanged(AxesOrientationMode)),
440 this, SIGNAL(axesOrientationModeChanged(AxesOrientationMode)));
441 connect(sensor(), SIGNAL(userOrientationChanged(int)), this, SIGNAL(userOrientationChanged(int)));
442 connect(sensor(), SIGNAL(currentOrientationChanged(int)), this, SIGNAL(currentOrientationChanged(int)));
443 connect(sensor(), SIGNAL(bufferSizeChanged(int)), this, SIGNAL(bufferSizeChanged(int)));
444 connect(sensor(), SIGNAL(maxBufferSizeChanged(int)), this, SIGNAL(maxBufferSizeChanged(int)));
445 connect(sensor(), SIGNAL(efficientBufferSizeChanged(int)), this, SIGNAL(efficientBufferSizeChanged(int)));
446
447 // We need to set this on the sensor object now
448 sensor()->setIdentifier(m_identifier.toLocal8Bit());
449
450 // These can change!
451 QByteArray oldIdentifier = sensor()->identifier();
452 int oldDataRate = dataRate();
453 int oldOutputRange = outputRange();
454
455 bool ok = sensor()->connectToBackend();
456 if (ok) {
457 Q_EMIT connectedToBackendChanged();
458 m_reading = createReading();
459 m_reading->setParent(this);
460 }
461
462 if (oldIdentifier != sensor()->identifier()) {
463 m_identifier = QString::fromLatin1(sensor()->identifier());
464 Q_EMIT identifierChanged();
465 }
466 if (oldDataRate != dataRate())
467 Q_EMIT dataRateChanged();
468 if (oldOutputRange != outputRange())
469 Q_EMIT outputRangeChanged();
470
471 // meta-data should become non-empty
472 if (!description().isEmpty())
473 Q_EMIT descriptionChanged();
474 if (sensor()->availableDataRates().count())
475 Q_EMIT availableDataRatesChanged();
476 if (sensor()->outputRanges().count())
477 Q_EMIT outputRangesChanged();
478
479 _update();
480
481 connect(sensor(), SIGNAL(readingChanged()), this, SLOT(updateReading()));
482 if (m_active) {
483 m_active = false;
484 start();
485 }
486}
487
488void QmlSensor::_update()
489{
490}
491
492void QmlSensor::updateReading()
493{
494 if (m_reading) {
495 m_reading->update();
496 Q_EMIT readingChanged();
497 }
498}
499
500/*!
501 \qmltype SensorReading
502 \instantiates QmlSensorReading
503 \inqmlmodule QtSensors
504 \since QtSensors 5.0
505 \brief The SensorReading element serves as a base type for sensor readings.
506
507 The SensorReading element serves as a base type for sensor readings.
508
509 This element wraps the QSensorReading class. Please see the documentation for
510 QSensorReading for details.
511
512 This element cannot be directly created.
513*/
514
515QmlSensorReading::QmlSensorReading(QSensor *)
516 : QObject(0)
517{
518}
519
520QmlSensorReading::~QmlSensorReading()
521{
522}
523
524/*!
525 \qmlproperty quint64 SensorReading::timestamp
526 A timestamp for the reading.
527
528 Please see QSensorReading::timestamp for information about this property.
529*/
530
531quint64 QmlSensorReading::timestamp() const
532{
533 return m_timestamp;
534}
535
536void QmlSensorReading::update()
537{
538 quint64 ts = reading()->timestamp();
539 if (m_timestamp != ts) {
540 m_timestamp = ts;
541 Q_EMIT timestampChanged();
542 }
543 readingUpdate();
544}
545
546QT_END_NAMESPACE
547