blob: 752cdb1822cd983d910194844803565066c67830 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtSensors module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qmlsensor.h"
#include <QtSensors/QSensor>
#include <QDebug>
#include <QtCore/private/qobject_p.h>
QT_BEGIN_NAMESPACE
class QmlSensorPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QmlSensor)
public:
QList<QmlSensorRange *> availableRanges;
QList<QmlSensorOutputRange *> outputRanges;
};
template<typename Item>
int readonlyListCount(QQmlListProperty<Item> *p)
{
return static_cast<const QList<Item *> *>(p->data)->count();
}
template<typename Item>
Item *readonlyListAt(QQmlListProperty<Item> *p, int idx)
{
return static_cast<const QList<Item *> *>(p->data)->at(idx);
};
template<typename Item>
QQmlListProperty<Item> readonlyListProperty(const QObject *o, const QList<Item *> *list)
{
// Unfortunately QQmlListProperty won't accept a const object, even on the readonly ctor.
return QQmlListProperty<Item>(const_cast<QObject *>(o), const_cast<QList<Item *> *>(list),
readonlyListCount<Item>, readonlyListAt<Item>);
}
/*!
\qmltype Sensor
\instantiates QmlSensor
\inqmlmodule QtSensors
\since QtSensors 5.0
\brief The Sensor element serves as a base type for sensors.
The Sensor element serves as a base type for sensors.
This element wraps the QSensor class. Please see the documentation for
QSensor for details.
This element cannot be directly created. Please use one of the sub-classes instead.
*/
QmlSensor::QmlSensor(QObject *parent)
: QObject(*(new QmlSensorPrivate), parent)
, m_parsed(false)
, m_active(false)
, m_reading(0)
{
}
QmlSensor::~QmlSensor()
{
}
/*!
\qmlproperty string Sensor::identifier
This property holds the backend identifier for the sensor.
Please see QSensor::identifier for information about this property.
*/
QString QmlSensor::identifier() const
{
return m_identifier;
}
void QmlSensor::setIdentifier(const QString &identifier)
{
if (m_parsed) return;
m_identifier = identifier;
Q_EMIT identifierChanged();
}
/*!
\qmlproperty string Sensor::type
This property holds the type of the sensor.
*/
QString QmlSensor::type() const
{
return QString::fromLatin1(sensor()->type());
}
/*!
\qmlproperty bool Sensor::connectedToBackend
This property holds a value indicating if the sensor has connected to a backend.
Please see QSensor::connectedToBackend for information about this property.
*/
bool QmlSensor::isConnectedToBackend() const
{
return sensor()->isConnectedToBackend();
}
/*!
\qmlproperty bool Sensor::busy
This property holds a value to indicate if the sensor is busy.
Please see QSensor::busy for information about this property.
*/
bool QmlSensor::isBusy() const
{
return sensor()->isBusy();
}
/*!
\qmlproperty bool Sensor::active
This property holds a value to indicate if the sensor is active.
Please see QSensor::active for information about this property.
*/
void QmlSensor::setActive(bool active)
{
m_active = active;
if (!m_parsed) return; // delay (it'll get called again later)!
bool wasActive = sensor()->isActive();
if (wasActive == active) return;
if (active) {
sensor()->start();
m_active = sensor()->isActive();
} else {
sensor()->stop();
}
if (m_active != wasActive)
emit activeChanged();
}
bool QmlSensor::isActive() const
{
return m_active;
}
/*!
\qmlproperty bool Sensor::alwaysOn
This property holds a value to indicate if the sensor should remain running when the screen is off.
Please see QSensor::alwaysOn for information about this property.
*/
bool QmlSensor::isAlwaysOn() const
{
return sensor()->isAlwaysOn();
}
void QmlSensor::setAlwaysOn(bool alwaysOn)
{
sensor()->setAlwaysOn(alwaysOn);
}
/*!
\qmlproperty bool Sensor::skipDuplicates
\since QtSensors 5.1
This property indicates whether duplicate reading values should be omitted.
Please see QSensor::skipDuplicates for information about this property.
*/
bool QmlSensor::skipDuplicates() const
{
return sensor()->skipDuplicates();
}
void QmlSensor::setSkipDuplicates(bool skipDuplicates)
{
sensor()->setSkipDuplicates(skipDuplicates);
}
/*!
\qmlproperty list<Range> Sensor::availableDataRates
This property holds the data rates that the sensor supports.
Please see QSensor::availableDataRates for information about this property.
*/
QQmlListProperty<QmlSensorRange> QmlSensor::availableDataRates() const
{
Q_D(const QmlSensor);
return readonlyListProperty<QmlSensorRange>(this, &d->availableRanges);
}
/*!
\qmlproperty int Sensor::dataRate
This property holds the data rate that the sensor should be run at.
Please see QSensor::dataRate for information about this property.
*/
int QmlSensor::dataRate() const
{
return sensor()->dataRate();
}
void QmlSensor::setDataRate(int rate)
{
if (rate != dataRate()) {
sensor()->setDataRate(rate);
Q_EMIT dataRateChanged();
}
}
/*!
\qmlproperty list<OutputRange> Sensor::outputRanges
This property holds a list of output ranges the sensor supports.
Please see QSensor::outputRanges for information about this property.
*/
QQmlListProperty<QmlSensorOutputRange> QmlSensor::outputRanges() const
{
Q_D(const QmlSensor);
return readonlyListProperty<QmlSensorOutputRange>(this, &d->outputRanges);
}
/*!
\qmlproperty int Sensor::outputRange
This property holds the output range in use by the sensor.
Please see QSensor::outputRange for information about this property.
*/
int QmlSensor::outputRange() const
{
return sensor()->outputRange();
}
void QmlSensor::setOutputRange(int index)
{
int oldRange = outputRange();
if (oldRange == index) return;
sensor()->setOutputRange(index);
if (sensor()->outputRange() == index)
Q_EMIT outputRangeChanged();
}
/*!
\qmlproperty string Sensor::description
This property holds a descriptive string for the sensor.
*/
QString QmlSensor::description() const
{
return sensor()->description();
}
/*!
\qmlproperty int Sensor::error
This property holds the last error code set on the sensor.
*/
int QmlSensor::error() const
{
return sensor()->error();
}
/*!
\qmlproperty SensorReading Sensor::reading
This property holds the reading class.
Please see QSensor::reading for information about this property.
\sa {QML Reading types}
*/
QmlSensorReading *QmlSensor::reading() const
{
return m_reading;
}
/*!
\qmlproperty Sensor::AxesOrientationMode Sensor::axesOrientationMode
\since QtSensors 5.1
This property holds the mode that affects how the screen orientation changes reading values.
Please see QSensor::axesOrientationMode for information about this property.
*/
QmlSensor::AxesOrientationMode QmlSensor::axesOrientationMode() const
{
return static_cast<QmlSensor::AxesOrientationMode>(sensor()->axesOrientationMode());
}
void QmlSensor::setAxesOrientationMode(QmlSensor::AxesOrientationMode axesOrientationMode)
{
sensor()->setAxesOrientationMode(static_cast<QSensor::AxesOrientationMode>(axesOrientationMode));
}
/*!
\qmlproperty int Sensor::currentOrientation
\since QtSensors 5.1
This property holds the current orientation that is used for rotating the reading values.
Please see QSensor::currentOrientation for information about this property.
*/
int QmlSensor::currentOrientation() const
{
return sensor()->currentOrientation();
}
/*!
\qmlproperty int Sensor::userOrientation
\since QtSensors 5.1
This property holds the angle used for rotating the reading values in the UserOrientation mode.
Please see QSensor::userOrientation for information about this property.
*/
int QmlSensor::userOrientation() const
{
return sensor()->userOrientation();
}
void QmlSensor::setUserOrientation(int userOrientation)
{
sensor()->setUserOrientation(userOrientation);
}
/*!
\qmlproperty int Sensor::maxBufferSize
\since QtSensors 5.1
This property holds the maximum buffer size.
Please see QSensor::maxBufferSize for information about this property.
*/
int QmlSensor::maxBufferSize() const
{
return sensor()->maxBufferSize();
}
/*!
\qmlproperty int Sensor::efficientBufferSize
\since QtSensors 5.1
The property holds the most efficient buffer size.
Please see QSensor::efficientBufferSize for information about this property.
*/
int QmlSensor::efficientBufferSize() const
{
return sensor()->efficientBufferSize();
}
/*!
\qmlproperty int Sensor::bufferSize
\since QtSensors 5.1
This property holds the size of the buffer.
Please see QSensor::bufferSize for information about this property.
*/
int QmlSensor::bufferSize() const
{
return sensor()->bufferSize();
}
void QmlSensor::setBufferSize(int bufferSize)
{
sensor()->setBufferSize(bufferSize);
}
/*!
\qmlmethod bool Sensor::start()
Start retrieving values from the sensor. Returns true if the sensor
was started, false otherwise.
Please see QSensor::start() for information.
*/
bool QmlSensor::start()
{
setActive(true);
return isActive();
}
/*!
\qmlmethod bool Sensor::stop()
Stop retrieving values from the sensor.
Returns true if the sensor was stopped, false otherwise.
Please see QSensor::stop() for information.
*/
void QmlSensor::stop()
{
setActive(false);
}
void QmlSensor::classBegin()
{
}
void QmlSensor::componentComplete()
{
m_parsed = true;
connect(sensor(), SIGNAL(sensorError(int)), this, SIGNAL(errorChanged()));
connect(sensor(), SIGNAL(activeChanged()), this, SIGNAL(activeChanged()));
connect(sensor(), SIGNAL(alwaysOnChanged()), this, SIGNAL(alwaysOnChanged()));
connect(sensor(), SIGNAL(skipDuplicatesChanged(bool)), this, SIGNAL(skipDuplicatesChanged(bool)));
connect(sensor(), SIGNAL(axesOrientationModeChanged(AxesOrientationMode)),
this, SIGNAL(axesOrientationModeChanged(AxesOrientationMode)));
connect(sensor(), SIGNAL(userOrientationChanged(int)), this, SIGNAL(userOrientationChanged(int)));
connect(sensor(), SIGNAL(currentOrientationChanged(int)), this, SIGNAL(currentOrientationChanged(int)));
connect(sensor(), SIGNAL(bufferSizeChanged(int)), this, SIGNAL(bufferSizeChanged(int)));
connect(sensor(), SIGNAL(maxBufferSizeChanged(int)), this, SIGNAL(maxBufferSizeChanged(int)));
connect(sensor(), SIGNAL(efficientBufferSizeChanged(int)), this, SIGNAL(efficientBufferSizeChanged(int)));
// We need to set this on the sensor object now
sensor()->setIdentifier(m_identifier.toLocal8Bit());
// These can change!
QByteArray oldIdentifier = sensor()->identifier();
int oldDataRate = dataRate();
int oldOutputRange = outputRange();
bool ok = sensor()->connectToBackend();
if (ok) {
Q_EMIT connectedToBackendChanged();
m_reading = createReading();
m_reading->setParent(this);
}
if (oldIdentifier != sensor()->identifier()) {
m_identifier = QString::fromLatin1(sensor()->identifier());
Q_EMIT identifierChanged();
}
if (oldDataRate != dataRate())
Q_EMIT dataRateChanged();
if (oldOutputRange != outputRange())
Q_EMIT outputRangeChanged();
Q_D(QmlSensor);
const auto available = sensor()->availableDataRates();
d->availableRanges.reserve(available.size());
for (const qrange &r : available) {
auto *range = new QmlSensorRange(this);
range->setMinumum(r.first);
range->setMaximum(r.second);
d->availableRanges.append(range);
}
const auto output = sensor()->outputRanges();
d->outputRanges.reserve(output.size());
for (const qoutputrange &r : output) {
auto *range = new QmlSensorOutputRange(this);
range->setMinimum(r.minimum);
range->setMaximum(r.maximum);
range->setAccuracy(r.accuracy);
d->outputRanges.append(range);
}
// meta-data should become non-empty
if (!description().isEmpty())
Q_EMIT descriptionChanged();
if (available.count())
Q_EMIT availableDataRatesChanged();
if (output.count())
Q_EMIT outputRangesChanged();
_update();
connect(sensor(), SIGNAL(readingChanged()), this, SLOT(updateReading()));
if (m_active) {
m_active = false;
start();
}
}
void QmlSensor::_update()
{
}
void QmlSensor::updateReading()
{
if (m_reading) {
m_reading->update();
Q_EMIT readingChanged();
}
}
/*!
\qmltype SensorReading
\instantiates QmlSensorReading
\inqmlmodule QtSensors
\since QtSensors 5.0
\brief The SensorReading element serves as a base type for sensor readings.
The SensorReading element serves as a base type for sensor readings.
This element wraps the QSensorReading class. Please see the documentation for
QSensorReading for details.
This element cannot be directly created.
*/
QmlSensorReading::QmlSensorReading(QSensor *)
: QObject(0)
{
}
QmlSensorReading::~QmlSensorReading()
{
}
/*!
\qmlproperty quint64 SensorReading::timestamp
A timestamp for the reading.
Please see QSensorReading::timestamp for information about this property.
*/
quint64 QmlSensorReading::timestamp() const
{
return m_timestamp;
}
void QmlSensorReading::update()
{
quint64 ts = reading()->timestamp();
if (m_timestamp != ts) {
m_timestamp = ts;
Q_EMIT timestampChanged();
}
readingUpdate();
}
QT_END_NAMESPACE