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#include <QtCore/private/qobject_p.h>
44
45QT_BEGIN_NAMESPACE
46
47class QmlSensorPrivate : public QObjectPrivate
48{
49 Q_DECLARE_PUBLIC(QmlSensor)
50public:
51
52 QList<QmlSensorRange *> availableRanges;
53 QList<QmlSensorOutputRange *> outputRanges;
54};
55
56template<typename Item>
57int readonlyListCount(QQmlListProperty<Item> *p)
58{
59 return static_cast<const QList<Item *> *>(p->data)->count();
60}
61
62template<typename Item>
63Item *readonlyListAt(QQmlListProperty<Item> *p, int idx)
64{
65 return static_cast<const QList<Item *> *>(p->data)->at(idx);
66};
67
68template<typename Item>
69QQmlListProperty<Item> readonlyListProperty(const QObject *o, const QList<Item *> *list)
70{
71 // Unfortunately QQmlListProperty won't accept a const object, even on the readonly ctor.
72 return QQmlListProperty<Item>(const_cast<QObject *>(o), const_cast<QList<Item *> *>(list),
73 readonlyListCount<Item>, readonlyListAt<Item>);
74}
75
76/*!
77 \qmltype Sensor
78 \instantiates QmlSensor
79 \inqmlmodule QtSensors
80 \since QtSensors 5.0
81 \brief The Sensor element serves as a base type for sensors.
82
83 The Sensor element serves as a base type for sensors.
84
85 This element wraps the QSensor class. Please see the documentation for
86 QSensor for details.
87
88 This element cannot be directly created. Please use one of the sub-classes instead.
89*/
90
91QmlSensor::QmlSensor(QObject *parent)
92 : QObject(*(new QmlSensorPrivate), parent)
93 , m_parsed(false)
94 , m_active(false)
95 , m_reading(0)
96{
97}
98
99QmlSensor::~QmlSensor()
100{
101}
102
103/*!
104 \qmlproperty string Sensor::identifier
105 This property holds the backend identifier for the sensor.
106
107 Please see QSensor::identifier for information about this property.
108*/
109
110QString QmlSensor::identifier() const
111{
112 return m_identifier;
113}
114
115void QmlSensor::setIdentifier(const QString &identifier)
116{
117 if (m_parsed) return;
118 m_identifier = identifier;
119 Q_EMIT identifierChanged();
120}
121
122/*!
123 \qmlproperty string Sensor::type
124 This property holds the type of the sensor.
125*/
126
127QString QmlSensor::type() const
128{
129 return QString::fromLatin1(str: sensor()->type());
130}
131
132/*!
133 \qmlproperty bool Sensor::connectedToBackend
134 This property holds a value indicating if the sensor has connected to a backend.
135
136 Please see QSensor::connectedToBackend for information about this property.
137*/
138
139bool QmlSensor::isConnectedToBackend() const
140{
141 return sensor()->isConnectedToBackend();
142}
143
144/*!
145 \qmlproperty bool Sensor::busy
146 This property holds a value to indicate if the sensor is busy.
147
148 Please see QSensor::busy for information about this property.
149*/
150
151bool QmlSensor::isBusy() const
152{
153 return sensor()->isBusy();
154}
155
156/*!
157 \qmlproperty bool Sensor::active
158 This property holds a value to indicate if the sensor is active.
159
160 Please see QSensor::active for information about this property.
161*/
162
163void QmlSensor::setActive(bool active)
164{
165 m_active = active;
166 if (!m_parsed) return; // delay (it'll get called again later)!
167 bool wasActive = sensor()->isActive();
168 if (wasActive == active) return;
169 if (active) {
170 sensor()->start();
171 m_active = sensor()->isActive();
172 } else {
173 sensor()->stop();
174 }
175 if (m_active != wasActive)
176 emit activeChanged();
177}
178
179bool QmlSensor::isActive() const
180{
181 return m_active;
182}
183
184/*!
185 \qmlproperty bool Sensor::alwaysOn
186 This property holds a value to indicate if the sensor should remain running when the screen is off.
187
188 Please see QSensor::alwaysOn for information about this property.
189*/
190
191bool QmlSensor::isAlwaysOn() const
192{
193 return sensor()->isAlwaysOn();
194}
195
196void QmlSensor::setAlwaysOn(bool alwaysOn)
197{
198 sensor()->setAlwaysOn(alwaysOn);
199}
200
201/*!
202 \qmlproperty bool Sensor::skipDuplicates
203 \since QtSensors 5.1
204
205 This property indicates whether duplicate reading values should be omitted.
206
207 Please see QSensor::skipDuplicates for information about this property.
208*/
209
210bool QmlSensor::skipDuplicates() const
211{
212 return sensor()->skipDuplicates();
213}
214
215void QmlSensor::setSkipDuplicates(bool skipDuplicates)
216{
217 sensor()->setSkipDuplicates(skipDuplicates);
218}
219
220/*!
221 \qmlproperty list<Range> Sensor::availableDataRates
222 This property holds the data rates that the sensor supports.
223
224 Please see QSensor::availableDataRates for information about this property.
225*/
226QQmlListProperty<QmlSensorRange> QmlSensor::availableDataRates() const
227{
228 Q_D(const QmlSensor);
229 return readonlyListProperty<QmlSensorRange>(o: this, list: &d->availableRanges);
230}
231
232/*!
233 \qmlproperty int Sensor::dataRate
234 This property holds the data rate that the sensor should be run at.
235
236 Please see QSensor::dataRate for information about this property.
237*/
238
239int QmlSensor::dataRate() const
240{
241 return sensor()->dataRate();
242}
243
244void QmlSensor::setDataRate(int rate)
245{
246 if (rate != dataRate()) {
247 sensor()->setDataRate(rate);
248 Q_EMIT dataRateChanged();
249 }
250}
251
252/*!
253 \qmlproperty list<OutputRange> Sensor::outputRanges
254 This property holds a list of output ranges the sensor supports.
255
256 Please see QSensor::outputRanges for information about this property.
257*/
258
259QQmlListProperty<QmlSensorOutputRange> QmlSensor::outputRanges() const
260{
261 Q_D(const QmlSensor);
262 return readonlyListProperty<QmlSensorOutputRange>(o: this, list: &d->outputRanges);
263}
264
265/*!
266 \qmlproperty int Sensor::outputRange
267 This property holds the output range in use by the sensor.
268
269 Please see QSensor::outputRange for information about this property.
270*/
271
272int QmlSensor::outputRange() const
273{
274 return sensor()->outputRange();
275}
276
277void QmlSensor::setOutputRange(int index)
278{
279 int oldRange = outputRange();
280 if (oldRange == index) return;
281 sensor()->setOutputRange(index);
282 if (sensor()->outputRange() == index)
283 Q_EMIT outputRangeChanged();
284}
285
286/*!
287 \qmlproperty string Sensor::description
288 This property holds a descriptive string for the sensor.
289*/
290
291QString QmlSensor::description() const
292{
293 return sensor()->description();
294}
295
296/*!
297 \qmlproperty int Sensor::error
298 This property holds the last error code set on the sensor.
299*/
300
301int QmlSensor::error() const
302{
303 return sensor()->error();
304}
305
306/*!
307 \qmlproperty SensorReading Sensor::reading
308 This property holds the reading class.
309
310 Please see QSensor::reading for information about this property.
311 \sa {QML Reading types}
312*/
313
314QmlSensorReading *QmlSensor::reading() const
315{
316 return m_reading;
317}
318
319/*!
320 \qmlproperty Sensor::AxesOrientationMode Sensor::axesOrientationMode
321 \since QtSensors 5.1
322 This property holds the mode that affects how the screen orientation changes reading values.
323
324 Please see QSensor::axesOrientationMode for information about this property.
325*/
326
327QmlSensor::AxesOrientationMode QmlSensor::axesOrientationMode() const
328{
329 return static_cast<QmlSensor::AxesOrientationMode>(sensor()->axesOrientationMode());
330}
331
332void QmlSensor::setAxesOrientationMode(QmlSensor::AxesOrientationMode axesOrientationMode)
333{
334 sensor()->setAxesOrientationMode(static_cast<QSensor::AxesOrientationMode>(axesOrientationMode));
335}
336
337/*!
338 \qmlproperty int Sensor::currentOrientation
339 \since QtSensors 5.1
340 This property holds the current orientation that is used for rotating the reading values.
341
342 Please see QSensor::currentOrientation for information about this property.
343*/
344
345int QmlSensor::currentOrientation() const
346{
347 return sensor()->currentOrientation();
348}
349
350/*!
351 \qmlproperty int Sensor::userOrientation
352 \since QtSensors 5.1
353 This property holds the angle used for rotating the reading values in the UserOrientation mode.
354
355 Please see QSensor::userOrientation for information about this property.
356*/
357
358int QmlSensor::userOrientation() const
359{
360 return sensor()->userOrientation();
361}
362
363void QmlSensor::setUserOrientation(int userOrientation)
364{
365 sensor()->setUserOrientation(userOrientation);
366}
367
368/*!
369 \qmlproperty int Sensor::maxBufferSize
370 \since QtSensors 5.1
371 This property holds the maximum buffer size.
372
373 Please see QSensor::maxBufferSize for information about this property.
374*/
375
376int QmlSensor::maxBufferSize() const
377{
378 return sensor()->maxBufferSize();
379}
380
381/*!
382 \qmlproperty int Sensor::efficientBufferSize
383 \since QtSensors 5.1
384 The property holds the most efficient buffer size.
385
386 Please see QSensor::efficientBufferSize for information about this property.
387*/
388
389int QmlSensor::efficientBufferSize() const
390{
391 return sensor()->efficientBufferSize();
392}
393
394/*!
395 \qmlproperty int Sensor::bufferSize
396 \since QtSensors 5.1
397 This property holds the size of the buffer.
398
399 Please see QSensor::bufferSize for information about this property.
400*/
401
402int QmlSensor::bufferSize() const
403{
404 return sensor()->bufferSize();
405}
406
407void QmlSensor::setBufferSize(int bufferSize)
408{
409 sensor()->setBufferSize(bufferSize);
410}
411
412/*!
413 \qmlmethod bool Sensor::start()
414 Start retrieving values from the sensor. Returns true if the sensor
415 was started, false otherwise.
416
417 Please see QSensor::start() for information.
418*/
419
420bool QmlSensor::start()
421{
422 setActive(true);
423 return isActive();
424}
425
426/*!
427 \qmlmethod bool Sensor::stop()
428 Stop retrieving values from the sensor.
429 Returns true if the sensor was stopped, false otherwise.
430
431 Please see QSensor::stop() for information.
432*/
433
434void QmlSensor::stop()
435{
436 setActive(false);
437}
438
439void QmlSensor::classBegin()
440{
441}
442
443void QmlSensor::componentComplete()
444{
445 m_parsed = true;
446
447 connect(sender: sensor(), SIGNAL(sensorError(int)), receiver: this, SIGNAL(errorChanged()));
448 connect(sender: sensor(), SIGNAL(activeChanged()), receiver: this, SIGNAL(activeChanged()));
449 connect(sender: sensor(), SIGNAL(alwaysOnChanged()), receiver: this, SIGNAL(alwaysOnChanged()));
450 connect(sender: sensor(), SIGNAL(skipDuplicatesChanged(bool)), receiver: this, SIGNAL(skipDuplicatesChanged(bool)));
451 connect(sender: sensor(), SIGNAL(axesOrientationModeChanged(AxesOrientationMode)),
452 receiver: this, SIGNAL(axesOrientationModeChanged(AxesOrientationMode)));
453 connect(sender: sensor(), SIGNAL(userOrientationChanged(int)), receiver: this, SIGNAL(userOrientationChanged(int)));
454 connect(sender: sensor(), SIGNAL(currentOrientationChanged(int)), receiver: this, SIGNAL(currentOrientationChanged(int)));
455 connect(sender: sensor(), SIGNAL(bufferSizeChanged(int)), receiver: this, SIGNAL(bufferSizeChanged(int)));
456 connect(sender: sensor(), SIGNAL(maxBufferSizeChanged(int)), receiver: this, SIGNAL(maxBufferSizeChanged(int)));
457 connect(sender: sensor(), SIGNAL(efficientBufferSizeChanged(int)), receiver: this, SIGNAL(efficientBufferSizeChanged(int)));
458
459 // We need to set this on the sensor object now
460 sensor()->setIdentifier(m_identifier.toLocal8Bit());
461
462 // These can change!
463 QByteArray oldIdentifier = sensor()->identifier();
464 int oldDataRate = dataRate();
465 int oldOutputRange = outputRange();
466
467 bool ok = sensor()->connectToBackend();
468 if (ok) {
469 Q_EMIT connectedToBackendChanged();
470 m_reading = createReading();
471 m_reading->setParent(this);
472 }
473
474 if (oldIdentifier != sensor()->identifier()) {
475 m_identifier = QString::fromLatin1(str: sensor()->identifier());
476 Q_EMIT identifierChanged();
477 }
478 if (oldDataRate != dataRate())
479 Q_EMIT dataRateChanged();
480 if (oldOutputRange != outputRange())
481 Q_EMIT outputRangeChanged();
482
483 Q_D(QmlSensor);
484 const auto available = sensor()->availableDataRates();
485 d->availableRanges.reserve(alloc: available.size());
486 for (const qrange &r : available) {
487 auto *range = new QmlSensorRange(this);
488 range->setMinumum(r.first);
489 range->setMaximum(r.second);
490 d->availableRanges.append(t: range);
491 }
492 const auto output = sensor()->outputRanges();
493 d->outputRanges.reserve(alloc: output.size());
494 for (const qoutputrange &r : output) {
495 auto *range = new QmlSensorOutputRange(this);
496 range->setMinimum(r.minimum);
497 range->setMaximum(r.maximum);
498 range->setAccuracy(r.accuracy);
499 d->outputRanges.append(t: range);
500 }
501
502 // meta-data should become non-empty
503 if (!description().isEmpty())
504 Q_EMIT descriptionChanged();
505 if (available.count())
506 Q_EMIT availableDataRatesChanged();
507 if (output.count())
508 Q_EMIT outputRangesChanged();
509
510 _update();
511
512 connect(sender: sensor(), SIGNAL(readingChanged()), receiver: this, SLOT(updateReading()));
513 if (m_active) {
514 m_active = false;
515 start();
516 }
517}
518
519void QmlSensor::_update()
520{
521}
522
523void QmlSensor::updateReading()
524{
525 if (m_reading) {
526 m_reading->update();
527 Q_EMIT readingChanged();
528 }
529}
530
531/*!
532 \qmltype SensorReading
533 \instantiates QmlSensorReading
534 \inqmlmodule QtSensors
535 \since QtSensors 5.0
536 \brief The SensorReading element serves as a base type for sensor readings.
537
538 The SensorReading element serves as a base type for sensor readings.
539
540 This element wraps the QSensorReading class. Please see the documentation for
541 QSensorReading for details.
542
543 This element cannot be directly created.
544*/
545
546QmlSensorReading::QmlSensorReading(QSensor *)
547 : QObject(0)
548{
549}
550
551QmlSensorReading::~QmlSensorReading()
552{
553}
554
555/*!
556 \qmlproperty quint64 SensorReading::timestamp
557 A timestamp for the reading.
558
559 Please see QSensorReading::timestamp for information about this property.
560*/
561
562quint64 QmlSensorReading::timestamp() const
563{
564 return m_timestamp;
565}
566
567void QmlSensorReading::update()
568{
569 quint64 ts = reading()->timestamp();
570 if (m_timestamp != ts) {
571 m_timestamp = ts;
572 Q_EMIT timestampChanged();
573 }
574 readingUpdate();
575}
576
577QT_END_NAMESPACE
578

source code of qtsensors/src/imports/sensors/qmlsensor.cpp