summaryrefslogtreecommitdiffstats
path: root/basicsuite/ebike-ui/datamodelplugin
diff options
context:
space:
mode:
Diffstat (limited to 'basicsuite/ebike-ui/datamodelplugin')
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/brightnesscontroller.cpp91
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/brightnesscontroller.h69
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/datamodelplugin.pro54
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/datastore.cpp300
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/datastore.h163
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/fpscounter.cpp79
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/fpscounter.h77
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/mapbox.cpp89
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/mapbox.h68
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/mapboxsuggestions.cpp109
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/mapboxsuggestions.h89
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/navigation.cpp97
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/navigation.h103
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/plugin.cpp4
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/socketclient.cpp152
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/socketclient.h86
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/suggestionsmodel.cpp157
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/suggestionsmodel.h82
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/tripdatamodel.cpp135
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/tripdatamodel.h96
20 files changed, 2067 insertions, 33 deletions
diff --git a/basicsuite/ebike-ui/datamodelplugin/brightnesscontroller.cpp b/basicsuite/ebike-ui/datamodelplugin/brightnesscontroller.cpp
new file mode 100644
index 0000000..a6e2e30
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/brightnesscontroller.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QFile>
+
+#include "brightnesscontroller.h"
+
+static const char brightnessSource[] = "/sys/class/backlight/backlight/brightness";
+static const int brightnessMax = 6;
+static const int brightnessMin = 1;
+
+BrightnessController::BrightnessController(QObject *parent)
+ : QObject(parent)
+ , m_automatic(false)
+{
+ QFile brightnessfile(brightnessSource);
+ if (brightnessfile.exists() && brightnessfile.open(QIODevice::ReadOnly)) {
+ char data[1];
+ if (brightnessfile.read(data, 1)) {
+ m_brightness = static_cast<int>(data[0] - '0');
+ }
+ } else {
+ // By default set to half
+ m_brightness = (brightnessMax + brightnessMin) / 2;
+ }
+}
+
+void BrightnessController::setBrightness(int brightness)
+{
+ if (m_brightness == brightness)
+ return;
+
+ // Valid values are between 1-6
+ if (brightness < brightnessMin || brightness > brightnessMax)
+ return;
+
+ QFile brightnessfile(brightnessSource);
+ if (brightnessfile.exists() && brightnessfile.open(QIODevice::WriteOnly)) {
+ char data[1] = {static_cast<char>('0' + brightness)};
+ if (brightnessfile.write(data, 1) == 1) {
+ m_brightness = brightness;
+ emit brightnessChanged(m_brightness);
+ }
+ } else {
+ // File does not exists, simulate changes
+ m_brightness = brightness;
+ emit brightnessChanged(m_brightness);
+ }
+}
+
+void BrightnessController::setAutomatic(bool automatic)
+{
+ if (m_automatic == automatic)
+ return;
+
+ m_automatic = automatic;
+ emit automaticChanged(m_automatic);
+}
diff --git a/basicsuite/ebike-ui/datamodelplugin/brightnesscontroller.h b/basicsuite/ebike-ui/datamodelplugin/brightnesscontroller.h
new file mode 100644
index 0000000..7b85f58
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/brightnesscontroller.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BRIGHTNESSCONTROLLER_H
+#define BRIGHTNESSCONTROLLER_H
+
+#include <QObject>
+
+class BrightnessController : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged)
+ Q_PROPERTY(bool automatic READ automatic WRITE setAutomatic NOTIFY automaticChanged)
+
+public:
+ explicit BrightnessController(QObject *parent = nullptr);
+
+public:
+ int brightness() const { return m_brightness; }
+ bool automatic() const { return m_automatic; }
+
+ void setBrightness(int brightness);
+ void setAutomatic(bool automatic);
+
+signals:
+ void brightnessChanged(int brightness);
+ void automaticChanged(bool automatic);
+
+public slots:
+
+private:
+ int m_brightness;
+ bool m_automatic;
+};
+
+#endif // BRIGHTNESSCONTROLLER_H
diff --git a/basicsuite/ebike-ui/datamodelplugin/datamodelplugin.pro b/basicsuite/ebike-ui/datamodelplugin/datamodelplugin.pro
index ce22eec..98515ef 100644
--- a/basicsuite/ebike-ui/datamodelplugin/datamodelplugin.pro
+++ b/basicsuite/ebike-ui/datamodelplugin/datamodelplugin.pro
@@ -1,39 +1,31 @@
TEMPLATE = lib
CONFIG += plugin
-QT += qml quick positioning charts
+QT += quick positioning
TARGET = ebikedatamodelplugin
+QML_MODULENAME = DataStore
SOURCES += plugin.cpp \
- $$PWD/../socketclient.cpp \
- $$PWD/../datastore.cpp \
- $$PWD/../navigation.cpp \
- $$PWD/../mapboxsuggestions.cpp \
- $$PWD/../suggestionsmodel.cpp \
- $$PWD/../mapbox.cpp \
- $$PWD/../brightnesscontroller.cpp \
- $$PWD/../fpscounter.cpp \
- $$PWD/../tripdatamodel.cpp
+ socketclient.cpp \
+ datastore.cpp \
+ navigation.cpp \
+ mapboxsuggestions.cpp \
+ suggestionsmodel.cpp \
+ mapbox.cpp \
+ brightnesscontroller.cpp \
+ fpscounter.cpp \
+ tripdatamodel.cpp
HEADERS += \
- $$PWD/../socketclient.h \
- $$PWD/../datastore.h \
- $$PWD/../navigation.h \
- $$PWD/../mapboxsuggestions.h \
- $$PWD/../suggestionsmodel.h \
- $$PWD/../mapbox.h \
- $$PWD/../brightnesscontroller.h \
- $$PWD/../fpscounter.h \
- $$PWD/../tripdatamodel.h
-
-INCLUDEPATH += $$PWD/../
-
-pluginfiles.files += \
- qmldir \
-
-B2QT_DEPLOYPATH = /data/user/qt/qmlplugins/DataStore
-target.path += $$B2QT_DEPLOYPATH
-pluginfiles.path += $$B2QT_DEPLOYPATH
-
-INSTALLS += target pluginfiles
-
+ socketclient.h \
+ datastore.h \
+ navigation.h \
+ mapboxsuggestions.h \
+ suggestionsmodel.h \
+ mapbox.h \
+ brightnesscontroller.h \
+ fpscounter.h \
+ tripdatamodel.h
+
+top_builddir=$$shadowed($$PWD/../)
+include(../../shared/shared_plugin.pri)
diff --git a/basicsuite/ebike-ui/datamodelplugin/datastore.cpp b/basicsuite/ebike-ui/datamodelplugin/datastore.cpp
new file mode 100644
index 0000000..73567ac
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/datastore.cpp
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QJsonArray>
+#include <QMetaObject>
+#include <QMetaMethod>
+
+#include "socketclient.h"
+#include "datastore.h"
+#include "tripdatamodel.h"
+
+// Speed conversions from m/s to km/h and mph
+static const double msToKmh = 3.6;
+static const double msToMph = 2.2369418519393043;
+// Distance conversions to and from m to km and mi
+static const double mToKm = 0.001;
+static const double mToMi = 0.000621371;
+static const double kmToM = 1000.0;
+static const double miToM = 1609.344;
+static const double mToYd = 1760.0 / 1609.344;
+
+DataStore::DataStore(QObject *parent)
+ : QObject(parent)
+ , m_client(new SocketClient(this))
+ , m_unit(Mph)
+ , m_trips(new TripDataModel(this, this))
+{
+ connect(m_client, &SocketClient::connected, this, &DataStore::requestStatus);
+ connect(m_client, &SocketClient::newMessage, this, &DataStore::parseMessage);
+}
+
+void DataStore::connectToServer(const QString &servername)
+{
+ m_client->connectToServer(servername);
+}
+
+void DataStore::getTrips()
+{
+ m_client->sendToServer(QJsonObject{{"method", "gettrips"}});
+}
+
+void DataStore::endTrip()
+{
+ m_client->sendToServer(QJsonObject{{"method", "endtrip"}});
+}
+
+void DataStore::toggleMode()
+{
+ setMode(mode() == Cruise ? Sport : Cruise);
+}
+
+void DataStore::resetDemo()
+{
+ m_client->sendToServer(QJsonObject{{"method", "reset"}});
+}
+
+double DataStore::speed() const
+{
+ return convertSpeed(m_properties.value("speed").toDouble());
+}
+
+double DataStore::topSpeed() const
+{
+ return convertSpeed(m_properties.value("topspeed").toDouble());
+}
+
+double DataStore::averageSpeed() const
+{
+ return convertSpeed(m_current.value("distance").toDouble() / m_current.value("duration").toDouble());
+}
+
+double DataStore::odometer() const
+{
+ return convertDistance(m_properties.value("odometer").toDouble());
+}
+
+double DataStore::trip() const
+{
+ return convertDistance(m_current.value("distance").toDouble());
+}
+
+double DataStore::calories() const
+{
+ return m_current.value("calories").toDouble();
+}
+
+double DataStore::assistDistance() const
+{
+ return convertDistance(m_properties.value("assistdistance").toDouble());
+}
+
+double DataStore::assistPower() const
+{
+ return m_properties.value("assistpower").toDouble();
+}
+
+double DataStore::batteryLevel() const
+{
+ return m_properties.value("batterylevel").toDouble();
+}
+
+bool DataStore::lights() const
+{
+ return m_properties.value("lights").toBool();
+}
+
+DataStore::Mode DataStore::mode() const
+{
+ return static_cast<Mode>(m_properties.value("mode").toInt());
+}
+
+DataStore::Unit DataStore::unit() const
+{
+ return m_unit;
+}
+
+int DataStore::arrow() const
+{
+ return m_properties.value("arrow").toInt();
+}
+
+double DataStore::legDistance() const
+{
+ return m_properties.value("legdistance").toDouble();
+}
+
+double DataStore::tripRemaining() const
+{
+ return m_properties.value("tripremaining").toDouble();
+}
+
+QString DataStore::smallUnit() const
+{
+ return m_unit == Kmh ? "m" : "yd";
+}
+
+void DataStore::setLights(bool lights)
+{
+ if (m_properties.value("lights").toBool() == lights)
+ return;
+
+ m_properties.insert("lights", lights);
+ m_client->sendToServer(QJsonObject{{"method", "set"}, {"key", "lights"}, {"value", lights}});
+ emit lightsChanged();
+}
+
+void DataStore::setMode(Mode mode)
+{
+ if (DataStore::mode() == mode)
+ return;
+
+ m_properties.insert("mode", mode);
+ m_client->sendToServer(QJsonObject{{"method", "set"}, {"key", "mode"}, {"value", static_cast<int>(mode)}});
+ emit modeChanged();
+}
+
+void DataStore::setUnit(DataStore::Unit unit)
+{
+ if (m_unit == unit)
+ return;
+
+ m_unit = unit;
+ emit unitChanged();
+ // Also emit all the other signals that are affected by mode change
+ emit speedChanged();
+ emit averagespeedChanged();
+ emit odometerChanged();
+ emit tripChanged();
+ emit assistdistanceChanged();
+ emit smallUnitChanged(smallUnit());
+}
+
+double DataStore::convertSpeed(double speed) const
+{
+ return speed * (m_unit == Kmh ? msToKmh : msToMph);
+}
+
+double DataStore::convertDistance(double distance) const
+{
+ return distance * (m_unit == Kmh ? mToKm : mToMi);
+}
+
+double DataStore::convertSmallDistance(double distance) const
+{
+ return distance * (m_unit == Kmh ? 1.0 : mToYd);
+}
+
+QString DataStore::getSmallUnit() const
+{
+ return m_unit == Kmh ? "m" : "yd";
+}
+
+QJsonObject DataStore::splitDistance(double distance, bool round) const
+{
+ if (m_unit == Kmh) {
+ if (distance >= kmToM)
+ return QJsonObject{{"value", distance * mToKm}, {"unit", "km"}, {"decimal", true}};
+ else {
+ if (round)
+ distance = qRound(distance / 10) * 10;
+ return QJsonObject{{"value", distance}, {"unit", "m"}, {"decimal", false}};
+ }
+ } else {
+ if (distance >= miToM)
+ return QJsonObject{{"value", distance * mToMi}, {"unit", "mi."}, {"decimal", true}};
+ else {
+ distance *= mToYd;
+ if (round)
+ distance = qRound(distance / 10) * 10;
+ return QJsonObject{{"value", distance}, {"unit", "yd"}, {"decimal", false}};
+ }
+ }
+}
+
+QJsonObject DataStore::splitDuration(double duration) const
+{
+ if (duration >= 60.0)
+ return QJsonObject{{"value", duration / 60.0}, {"unit", "min"}};
+ else
+ return QJsonObject{{"value", duration}, {"unit", "s"}};
+}
+
+void DataStore::requestStatus()
+{
+ m_client->sendToServer(QJsonObject{{"method", "getall"}});
+}
+
+void DataStore::emitByName(const QString &valuename)
+{
+ // Use QMetaObject information to find a proper signal
+ const QMetaObject *meta = metaObject();
+
+ // Find the notifier signal
+ QString signalName = QString("%1Changed()").arg(valuename);
+ int methodIndex = meta->indexOfSignal(signalName.toLatin1().constData());
+ meta->method(methodIndex).invoke(this, Qt::AutoConnection);
+}
+
+void DataStore::parseMessage(const QJsonObject &message)
+{
+ QString method = message.value("method").toString();
+
+ // If we are updating just one, simply insert new value and emit
+ if (method == "updateone") {
+ QString key = message.value("key").toString();
+ m_properties.insert(key, message.value("value"));
+ emitByName(key);
+ // If we are updating many, then iterate over the list and update each value
+ } else if (method == "updatemany") {
+ foreach (const QJsonValue &value, message.value("values").toArray()) {
+ QJsonObject obj = value.toObject();
+ QString key = obj.value("key").toString();
+ m_properties.insert(key, obj.value("value"));
+ emitByName(key);
+ }
+ } else if (method == "trips") {
+ m_trips->setTrips(message.value("trips").toArray());
+ } else if (method == "trip") {
+ m_trips->addTrip(message.value("trip").toObject());
+ } else if (method == "currenttrip") {
+ m_current = message.value("currenttrip").toObject();
+ m_trips->setCurrentTrip(m_current);
+ emit currentTripChanged();
+ } else if (method == "reset") {
+ emit demoReset();
+ }
+}
diff --git a/basicsuite/ebike-ui/datamodelplugin/datastore.h b/basicsuite/ebike-ui/datamodelplugin/datastore.h
new file mode 100644
index 0000000..20fa388
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/datastore.h
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DATASTORE_H
+#define DATASTORE_H
+
+#include <QObject>
+#include <QJsonObject>
+
+class SocketClient;
+class TripDataModel;
+
+class DataStore: public QObject
+{
+ Q_OBJECT
+
+ // Different measured properties
+ Q_PROPERTY(double speed READ speed NOTIFY speedChanged)
+ Q_PROPERTY(double topspeed READ topSpeed NOTIFY topspeedChanged)
+ Q_PROPERTY(double averagespeed READ averageSpeed NOTIFY currentTripChanged)
+ Q_PROPERTY(double odometer READ odometer NOTIFY odometerChanged)
+ Q_PROPERTY(double trip READ trip NOTIFY currentTripChanged)
+ Q_PROPERTY(double calories READ calories NOTIFY currentTripChanged)
+ Q_PROPERTY(double assistdistance READ assistDistance NOTIFY assistdistanceChanged)
+ Q_PROPERTY(double assistpower READ assistPower NOTIFY assistpowerChanged)
+ Q_PROPERTY(double batterylevel READ batteryLevel NOTIFY batterylevelChanged)
+
+ // Toggles for lights and mode
+ Q_PROPERTY(bool lights READ lights WRITE setLights NOTIFY lightsChanged)
+ Q_PROPERTY(Mode mode READ mode WRITE setMode NOTIFY modeChanged)
+
+ // Current units
+ Q_PROPERTY(Unit unit READ unit WRITE setUnit NOTIFY unitChanged)
+ Q_PROPERTY(QString smallUnit READ smallUnit NOTIFY smallUnitChanged)
+
+ // Navigation
+ Q_PROPERTY(int arrow READ arrow NOTIFY arrowChanged)
+ Q_PROPERTY(double legdistance READ legDistance NOTIFY legdistanceChanged)
+ Q_PROPERTY(double tripremaining READ tripRemaining NOTIFY tripremainingChanged)
+
+public:
+ explicit DataStore(QObject *parent = nullptr);
+
+ enum Mode { Cruise, Sport };
+ Q_ENUM(Mode)
+
+ enum Unit { Kmh, Mph };
+ Q_ENUM(Unit)
+
+public:
+ // Getters
+ double speed() const;
+ double topSpeed() const;
+ double averageSpeed() const;
+ double odometer() const;
+ double trip() const;
+ double calories() const;
+ double assistDistance() const;
+ double assistPower() const;
+ double batteryLevel() const;
+ bool lights() const;
+ Mode mode() const;
+ Unit unit() const;
+ int arrow() const;
+ double legDistance() const;
+ double tripRemaining() const;
+ QString smallUnit() const;
+
+ // Setters
+ void setLights(bool lights);
+ void setMode(Mode mode);
+ void setUnit(Unit unit);
+
+ // Get trip data model
+ TripDataModel *tripDataModel() const { return m_trips; }
+
+ // Convert speed and distance to proper units
+ Q_INVOKABLE double convertSpeed(double speed) const;
+ Q_INVOKABLE double convertDistance(double distance) const;
+ Q_INVOKABLE double convertSmallDistance(double distance) const;
+ Q_INVOKABLE QString getSmallUnit() const;
+
+ // Split and convert distance and duration to value and unit
+ Q_INVOKABLE QJsonObject splitDistance(double distance, bool round=false) const;
+ Q_INVOKABLE QJsonObject splitDuration(double duration) const;
+
+private:
+ void emitByName(const QString &valuename);
+
+signals:
+ void speedChanged();
+ void topspeedChanged();
+ void averagespeedChanged();
+ void odometerChanged();
+ void tripChanged();
+ void caloriesChanged();
+ void assistdistanceChanged();
+ void assistpowerChanged();
+ void batterylevelChanged();
+ void lightsChanged();
+ void modeChanged();
+ void unitChanged();
+ void arrowChanged();
+ void legdistanceChanged();
+ void tripremainingChanged();
+ void currentTripChanged();
+ void smallUnitChanged(QString smallUnit);
+ void demoReset();
+
+public slots:
+ void connectToServer(const QString &servername);
+ void getTrips();
+ void endTrip();
+ void toggleMode();
+ void resetDemo();
+
+private slots:
+ void requestStatus();
+ void parseMessage(const QJsonObject &message);
+
+private:
+ SocketClient *m_client;
+ QJsonObject m_properties;
+ QJsonObject m_current;
+ Unit m_unit;
+ TripDataModel *m_trips;
+ int m_smallUnit;
+};
+
+#endif // DATASTORE_H
diff --git a/basicsuite/ebike-ui/datamodelplugin/fpscounter.cpp b/basicsuite/ebike-ui/datamodelplugin/fpscounter.cpp
new file mode 100644
index 0000000..137dcb4
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/fpscounter.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QQuickWindow>
+
+#include "fpscounter.h"
+
+FpsCounter::FpsCounter(QObject *parent)
+ : QObject(parent)
+ , m_frameCounter(0)
+ , m_fps(0.0)
+ , m_visible(false)
+{
+}
+
+void FpsCounter::setVisible(bool visible)
+{
+ if (m_visible == visible)
+ return;
+
+ m_visible = visible;
+ emit visibleChanged(m_visible);
+}
+
+void FpsCounter::setWindow(QQuickWindow *window)
+{
+ connect(window, &QQuickWindow::frameSwapped, this, &FpsCounter::frameUpdated);
+ startTimer(1000);
+ m_timer.start();
+}
+
+void FpsCounter::timerEvent(QTimerEvent *)
+{
+ // Calculate new FPS
+ qreal newfps = qRound(m_frameCounter * 1000.0 / m_timer.elapsed());
+ m_frameCounter = 0;
+ m_timer.start();
+
+ // If there is no change, do nothing
+ if (qFuzzyCompare(m_fps, newfps))
+ return;
+
+ // Otherwise emit new fps
+ m_fps = newfps;
+ emit fpsChanged(m_fps);
+}
diff --git a/basicsuite/ebike-ui/datamodelplugin/fpscounter.h b/basicsuite/ebike-ui/datamodelplugin/fpscounter.h
new file mode 100644
index 0000000..7828844
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/fpscounter.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FPSCOUNTER_H
+#define FPSCOUNTER_H
+
+#include <QObject>
+#include <QElapsedTimer>
+
+class QQuickWindow;
+
+class FpsCounter : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal fps READ fps NOTIFY fpsChanged)
+ Q_PROPERTY(bool visible READ visible WRITE setVisible NOTIFY visibleChanged)
+
+public:
+ explicit FpsCounter(QObject *parent = nullptr);
+
+public:
+ qreal fps() const { return m_fps; }
+ bool visible() const { return m_visible; }
+ void setVisible(bool visible);
+ void setWindow(QQuickWindow *window);
+
+protected:
+ void timerEvent(QTimerEvent *);
+
+signals:
+ void fpsChanged(qreal fps);
+ void visibleChanged(bool visible);
+
+private slots:
+ void frameUpdated() { m_frameCounter++; }
+
+private:
+ QElapsedTimer m_timer;
+ int m_frameCounter;
+ qreal m_fps;
+ bool m_visible;
+};
+
+#endif // FPSCOUNTER_H
diff --git a/basicsuite/ebike-ui/datamodelplugin/mapbox.cpp b/basicsuite/ebike-ui/datamodelplugin/mapbox.cpp
new file mode 100644
index 0000000..9d2303d
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/mapbox.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QNetworkAccessManager>
+#include <QUrlQuery>
+
+#include "mapbox.h"
+
+#define MAPBOX_URL "https://api.mapbox.com/"
+#define MAPBOX_TOKEN "pk.eyJ1IjoibWFwYm94NHF0IiwiYSI6ImNpd3J3eDE0eDEzdm8ydHM3YzhzajlrN2oifQ.keEkjqm79SiFDFjnesTcgQ"
+
+MapBox::MapBox(QObject *parent)
+ : QObject(parent)
+ , m_nam(new QNetworkAccessManager(this))
+{
+}
+
+const QUrl MapBox::createUrl(const QString &path, QUrlQuery params) const
+{
+ // Create URL and set path
+ QUrl url(MAPBOX_URL);
+ url.setPath(path, QUrl::TolerantMode);
+
+ // Add access token to query params
+ params.addQueryItem("access_token", MAPBOX_TOKEN);
+ url.setQuery(params);
+
+ return url;
+}
+
+QNetworkReply *MapBox::get(const QUrl &url) const
+{
+ return m_nam->get(QNetworkRequest(url));
+}
+
+QNetworkReply *MapBox::getGeocoding(const QString &query, const QGeoCoordinate &proximity)
+{
+ QUrlQuery params;
+ params.addQueryItem("autocomplete", "true");
+ params.addQueryItem("limit", "3");
+ if (proximity.isValid())
+ params.addQueryItem("proximity", QString("%1,%2").arg(proximity.longitude()).arg(proximity.latitude()));
+ QUrl url = createUrl(QString("/geocoding/v5/mapbox.places/%1.json").arg(QString(QUrl::toPercentEncoding(query))), params);
+
+ return get(url);
+}
+
+QNetworkReply *MapBox::getDirections(const QGeoCoordinate &source, const QGeoCoordinate &destination, const QString &type)
+{
+ QString where = QString("%1,%2;%3,%4").arg(source.longitude()).arg(source.latitude()).arg(destination.longitude()).arg(destination.latitude());
+ QUrlQuery params;
+ params.addQueryItem("steps", "true");
+ params.addQueryItem("geometries", "geojson");
+ QUrl url = createUrl(QString("/directions/v5/mapbox/%1/%2.json").arg(type).arg(QString(QUrl::toPercentEncoding(where))), params);
+
+ return get(url);
+}
diff --git a/basicsuite/ebike-ui/datamodelplugin/mapbox.h b/basicsuite/ebike-ui/datamodelplugin/mapbox.h
new file mode 100644
index 0000000..5bd295f
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/mapbox.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAPBOX_H
+#define MAPBOX_H
+
+#include <QObject>
+#include <QUrl>
+#include <QGeoCoordinate>
+
+class QNetworkAccessManager;
+class QNetworkReply;
+
+class MapBox : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit MapBox(QObject *parent = nullptr);
+
+public:
+ const QUrl createUrl(const QString &path, QUrlQuery params) const;
+ QNetworkReply *get(const QUrl &url) const;
+ QNetworkReply *getGeocoding(const QString &query, const QGeoCoordinate &proximity=QGeoCoordinate());
+ QNetworkReply *getDirections(const QGeoCoordinate &source, const QGeoCoordinate &destination, const QString &type=QString("cycling"));
+
+signals:
+
+public slots:
+
+private:
+ QNetworkAccessManager *m_nam;
+};
+
+#endif // MAPBOX_H
diff --git a/basicsuite/ebike-ui/datamodelplugin/mapboxsuggestions.cpp b/basicsuite/ebike-ui/datamodelplugin/mapboxsuggestions.cpp
new file mode 100644
index 0000000..3f66766
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/mapboxsuggestions.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QTimer>
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QUrl>
+#include <QUrlQuery>
+#include <QJsonDocument>
+#include <QJsonParseError>
+#include <QJsonObject>
+
+#include "mapboxsuggestions.h"
+#include "mapbox.h"
+#include "suggestionsmodel.h"
+
+MapBoxSuggestions::MapBoxSuggestions(MapBox *mapbox, QObject *parent)
+ : QObject(parent)
+ , m_mapbox(mapbox)
+ , m_timer(new QTimer(this))
+ , m_suggestions(new SuggestionsModel(this))
+{
+ // Setup timer to request 500ms after user stops typing
+ m_timer->setSingleShot(true);
+ m_timer->setInterval(500);
+
+ // Connect timer signal
+ connect(m_timer, &QTimer::timeout, this, &MapBoxSuggestions::loadSuggestions);
+}
+
+void MapBoxSuggestions::stopSuggest()
+{
+ m_timer->stop();
+}
+
+void MapBoxSuggestions::setSearch(const QString &search)
+{
+ if (m_search == search)
+ return;
+
+ m_search = search;
+ m_timer->start();
+ emit searchChanged(m_search);
+}
+
+void MapBoxSuggestions::loadSuggestions()
+{
+ QNetworkReply *reply = m_mapbox->getGeocoding(m_search, m_center);
+ connect(reply, &QNetworkReply::finished, this, &MapBoxSuggestions::handleReply);
+ m_requests.append(reply);
+ emit loadingChanged();
+}
+
+void MapBoxSuggestions::handleReply()
+{
+ QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
+ QJsonParseError error;
+ QJsonDocument doc = QJsonDocument::fromJson(reply->readAll(), &error);
+ if (error.error == QJsonParseError::NoError) {
+ QJsonObject obj = doc.object();
+ m_suggestions->setSuggestions(obj.value("features").toArray());
+ emit suggestionsChanged();
+ }
+
+ m_requests.removeOne(reply);
+ emit loadingChanged();
+ reply->deleteLater();
+}
+
+void MapBoxSuggestions::setCenter(const QGeoCoordinate &center)
+{
+ if (m_center != center) {
+ m_center = center;
+ emit centerChanged();
+ }
+}
diff --git a/basicsuite/ebike-ui/datamodelplugin/mapboxsuggestions.h b/basicsuite/ebike-ui/datamodelplugin/mapboxsuggestions.h
new file mode 100644
index 0000000..8dc1506
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/mapboxsuggestions.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAPBOXSUGGESTIONS_H
+#define MAPBOXSUGGESTIONS_H
+
+#include <QObject>
+#include <QGeoCoordinate>
+
+class MapBox;
+class QNetworkReply;
+class QTimer;
+class SuggestionsModel;
+
+class MapBoxSuggestions : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(SuggestionsModel suggestions READ suggestions NOTIFY suggestionsChanged)
+ Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged)
+ Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter NOTIFY centerChanged)
+ Q_PROPERTY(QString search READ search WRITE setSearch NOTIFY searchChanged)
+
+public:
+ explicit MapBoxSuggestions(MapBox *mapbox, QObject *parent = nullptr);
+
+public:
+ SuggestionsModel *suggestions() const { return m_suggestions; }
+ bool loading() const { return m_requests.size() > 0; }
+ const QGeoCoordinate center() { return m_center; }
+ void setCenter(const QGeoCoordinate &center);
+ const QString search() const { return m_search; }
+ void setSearch(const QString &search);
+
+signals:
+ void suggestionsChanged();
+ void loadingChanged();
+ void centerChanged();
+ void searchChanged(QString search);
+
+public slots:
+ void stopSuggest();
+
+private slots:
+ void loadSuggestions();
+ void handleReply();
+
+private:
+ MapBox *m_mapbox;
+ QTimer *m_timer;
+ QList<QNetworkReply *> m_requests;
+ SuggestionsModel *m_suggestions;
+ QGeoCoordinate m_center;
+ QString m_search;
+};
+
+#endif // MAPBOXSUGGESTIONS_H
diff --git a/basicsuite/ebike-ui/datamodelplugin/navigation.cpp b/basicsuite/ebike-ui/datamodelplugin/navigation.cpp
new file mode 100644
index 0000000..067636e
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/navigation.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QNetworkReply>
+
+#include "navigation.h"
+#include "mapbox.h"
+
+Navigation::Navigation(MapBox *mapbox, QObject *parent)
+ : QObject(parent)
+ , m_mapbox(mapbox)
+ , m_position(QGeoCoordinate(36.131961, -115.153048), QDateTime::currentDateTime())
+ , m_zoomlevel(18)
+ , m_active(false)
+ , m_routeDirection(0)
+ , m_routePosition(m_position.coordinate())
+{
+ m_position.setAttribute(QGeoPositionInfo::Direction, 0);
+}
+
+void Navigation::setPosition(const QGeoPositionInfo &position)
+{
+ if (m_position != position) {
+ m_position = position;
+ emit positionChanged(m_position);
+ }
+}
+
+void Navigation::setCoordinate(const QGeoCoordinate &coordinate)
+{
+ if (m_position.coordinate() != coordinate) {
+ m_position.setCoordinate(coordinate);
+ emit coordinateChanged(m_position.coordinate());
+ }
+}
+
+void Navigation::setDirection(qreal direction)
+{
+ if (qFuzzyCompare(m_position.attribute(QGeoPositionInfo::Direction), direction))
+ return;
+
+ m_position.setAttribute(QGeoPositionInfo::Direction, direction);
+ emit directionChanged(direction);
+}
+
+void Navigation::setZoomLevel(qreal zoomlevel)
+{
+ if (qFuzzyCompare(m_zoomlevel, zoomlevel))
+ return;
+
+ m_zoomlevel = zoomlevel;
+ emit zoomLevelChanged(m_zoomlevel);
+}
+
+void Navigation::setActive(bool active)
+{
+ if (m_active == active)
+ return;
+
+ m_active = active;
+ emit activeChanged(m_active);
+}
diff --git a/basicsuite/ebike-ui/datamodelplugin/navigation.h b/basicsuite/ebike-ui/datamodelplugin/navigation.h
new file mode 100644
index 0000000..6c9533f
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/navigation.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NAVIGATION_H
+#define NAVIGATION_H
+
+#include <QObject>
+#include <QGeoPositionInfo>
+#include <QJsonObject>
+#include <QJSValue>
+#include <QTimer>
+
+#include <QDebug>
+
+class MapBox;
+
+class Navigation : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QGeoPositionInfo position READ position WRITE setPosition NOTIFY positionChanged)
+ Q_PROPERTY(QGeoCoordinate coordinate READ coordinate WRITE setCoordinate NOTIFY coordinateChanged)
+ Q_PROPERTY(qreal direction READ direction WRITE setDirection NOTIFY directionChanged)
+ Q_PROPERTY(qreal zoomlevel READ zoomLevel WRITE setZoomLevel NOTIFY zoomLevelChanged)
+ Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
+ Q_PROPERTY(qreal routeDirection READ routeDirection NOTIFY routeDirectionChanged)
+ Q_PROPERTY(QGeoCoordinate routePosition READ routePosition NOTIFY routePositionChanged)
+
+public:
+ explicit Navigation(MapBox *mapbox, QObject *parent = nullptr);
+
+public:
+ // Getters
+ const QGeoPositionInfo &position() const { return m_position; }
+ QGeoCoordinate coordinate() const { return m_position.coordinate(); }
+ qreal direction() const { return m_position.attribute(QGeoPositionInfo::Direction); }
+ qreal zoomLevel() const { return m_zoomlevel; }
+ bool active() const { return m_active; }
+
+ qreal routeDirection() const { return m_routeDirection; }
+ QGeoCoordinate routePosition() const { return m_routePosition; }
+
+ // Setters
+ void setPosition(const QGeoPositionInfo &position);
+ void setCoordinate(const QGeoCoordinate &coordinate);
+ void setDirection(qreal direction);
+ void setZoomLevel(qreal zoomlevel);
+ void setActive(bool active);
+
+signals:
+ void positionChanged(QGeoPositionInfo position);
+ void coordinateChanged(QGeoCoordinate coordinate);
+ void directionChanged(qreal direction);
+ void zoomLevelChanged(qreal zoomlevel);
+ void activeChanged(bool active);
+
+ void routeDirectionChanged(qreal routeDirection);
+ void routePositionChanged(QGeoCoordinate routePosition);
+
+private:
+ MapBox *m_mapbox;
+ QGeoPositionInfo m_position;
+ qreal m_zoomlevel;
+ bool m_active;
+
+ qreal m_routeDirection;
+ QGeoCoordinate m_routePosition;
+};
+
+#endif // NAVIGATION_H
diff --git a/basicsuite/ebike-ui/datamodelplugin/plugin.cpp b/basicsuite/ebike-ui/datamodelplugin/plugin.cpp
index 098a6a8..870d418 100644
--- a/basicsuite/ebike-ui/datamodelplugin/plugin.cpp
+++ b/basicsuite/ebike-ui/datamodelplugin/plugin.cpp
@@ -70,7 +70,7 @@ class QExampleQmlPlugin : public QQmlExtensionPlugin
public:
- void registerTypes(const char *uri)
+ void registerTypes(const char *uri)
{
Q_UNUSED(uri);
qmlRegisterType<DataStore>("DataStore", 1, 0, "DataStore");
@@ -89,7 +89,7 @@ public:
MapBoxSuggestions *suggest = new MapBoxSuggestions(mapbox, engine);
// Setup navigation container
- Navigation *navi = new Navigation(mapbox, engine);
+ Navigation *navi = new Navigation(nullptr, engine);
// Brightness controller
BrightnessController *brightness = new BrightnessController(engine);
diff --git a/basicsuite/ebike-ui/datamodelplugin/socketclient.cpp b/basicsuite/ebike-ui/datamodelplugin/socketclient.cpp
new file mode 100644
index 0000000..d40d268
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/socketclient.cpp
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDataStream>
+#include <QJsonDocument>
+
+#include "socketclient.h"
+
+SocketClient::SocketClient(QObject *parent)
+ : QObject(parent)
+ , m_socket(new QLocalSocket(this))
+{
+ // Connect socket signals
+ connect(m_socket, &QLocalSocket::connected, this, &SocketClient::connected);
+ connect(m_socket, &QLocalSocket::disconnected, this, &SocketClient::disconnected);
+ connect(m_socket, &QLocalSocket::readyRead, this, &SocketClient::readyRead);
+
+ // Setup timer to try to reconnect after disconnect
+ m_connectionTimer.setInterval(5000);
+ connect(&m_connectionTimer, &QTimer::timeout, this, &SocketClient::reconnect);
+ connect(m_socket, &QLocalSocket::connected, &m_connectionTimer, &QTimer::stop);
+ connect(m_socket, &QLocalSocket::disconnected,
+ &m_connectionTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
+ connect(m_socket, static_cast<void(QLocalSocket::*)(QLocalSocket::LocalSocketError)>(&QLocalSocket::error),
+ &m_connectionTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
+}
+
+void SocketClient::connectToServer(const QString &servername)
+{
+ m_servername = servername;
+ reconnect();
+}
+
+void SocketClient::reconnect()
+{
+ qDebug("Connecting to server...");
+ m_socket->connectToServer(m_servername);
+}
+
+qint64 SocketClient::write(const QByteArray &data)
+{
+ return m_socket->write(data);
+}
+
+/**
+ * @brief send a QByteArray to the server
+ * @param message
+ *
+ * Adds the length of the message as a header and sends the message to the server.
+ */
+void SocketClient::sendToServer(const QByteArray &message)
+{
+ // Prepend the message length
+ QByteArray data;
+ QDataStream stream(&data, QIODevice::WriteOnly);
+ stream << static_cast<qint32>(message.size() + 4);
+ data.append(message);
+
+ write(data);
+}
+
+/**
+ * @brief send a Json object to the server
+ * @param message
+ *
+ * Sends a QJsonObject object to the server, encoded in Qt's internal binary format.
+ */
+void SocketClient::sendToServer(const QJsonObject &message)
+{
+ QJsonDocument doc(message);
+ sendToServer(doc.toBinaryData());
+}
+
+/**
+ * @brief reads incoming data from the server
+ *
+ * Parses only message headers and body as QByteArray, but does not care about
+ * the contents. All complete messages are processed at @see parseMessage.
+ */
+void SocketClient::readyRead()
+{
+ m_data += m_socket->readAll();
+
+ bool messagefound = true;
+ while (messagefound) {
+ messagefound = false;
+ // If we have at least some data
+ if (m_data.size() >= 4) {
+ // Extract message size
+ qint32 messagesize;
+ QDataStream stream(m_data.left(4));
+ stream >> messagesize;
+
+ // If we have enough data for at least one message
+ if (m_data.size() >= messagesize) {
+ // Extract actual message
+ QByteArray message = m_data.mid(4, messagesize - 4);
+ parseMessage(message);
+ // Drop necessary amount of bytes
+ m_data = m_data.mid(messagesize);
+ messagefound = true; // Try to parse another message
+ }
+ }
+ }
+}
+
+/**
+ * @brief parse the contents of a QByteArray
+ * @param message
+ *
+ * Contents are parsed from QJsonDocument's binary data. This separation allows
+ * the format to be changed later on, if need be.
+ */
+void SocketClient::parseMessage(const QByteArray &message)
+{
+ // Parse message from raw format
+ QJsonDocument doc = QJsonDocument::fromBinaryData(message);
+ emit newMessage(doc.object());
+}
diff --git a/basicsuite/ebike-ui/datamodelplugin/socketclient.h b/basicsuite/ebike-ui/datamodelplugin/socketclient.h
new file mode 100644
index 0000000..dc100a2
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/socketclient.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SOCKETCLIENT_H
+#define SOCKETCLIENT_H
+
+#include <QObject>
+#include <QLocalSocket>
+#include <QTimer>
+#include <QJsonObject>
+
+/**
+ * @brief The SocketClient class
+ *
+ * Socket container and message parser for client communications.
+ */
+class SocketClient : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit SocketClient(QObject *parent = nullptr);
+
+public:
+ QLocalSocket* socket(void) const { return m_socket; }
+ qint64 write(const QByteArray &data);
+ void sendToServer(const QByteArray &message);
+ void sendToServer(const QJsonObject &message);
+
+private:
+ void parseMessage(const QByteArray &message);
+
+signals:
+ void connected();
+ void disconnected();
+
+ void newMessage(const QJsonObject &message);
+
+public slots:
+ void connectToServer(const QString &servername);
+
+private slots:
+ void reconnect();
+ void readyRead();
+
+private:
+ QLocalSocket *m_socket;
+ QString m_servername;
+ QTimer m_connectionTimer;
+ QByteArray m_data;
+};
+
+#endif // SOCKETCLIENT_H
diff --git a/basicsuite/ebike-ui/datamodelplugin/suggestionsmodel.cpp b/basicsuite/ebike-ui/datamodelplugin/suggestionsmodel.cpp
new file mode 100644
index 0000000..fa028f0
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/suggestionsmodel.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QCoreApplication>
+#include <QDir>
+#include <QFile>
+#include <QJsonDocument>
+
+#include "suggestionsmodel.h"
+
+#define EBIKE_DEMO_MODE
+
+static const char mostRecentFilename[] = "mostrecent.bson";
+
+SuggestionsModel::SuggestionsModel(QObject *parent)
+ : QAbstractListModel(parent)
+{
+ loadMostRecent();
+}
+
+SuggestionsModel::SuggestionsModel(const QJsonArray &suggestions, QObject *parent)
+ : QAbstractListModel(parent)
+ , m_suggestions(suggestions)
+{
+ loadMostRecent();
+}
+
+QVariant SuggestionsModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ // Only horizontal header
+ if (orientation == Qt::Vertical)
+ return QVariant();
+
+ if (role == Qt::DisplayRole && section == 0)
+ return tr("Place");
+
+ return QAbstractListModel::headerData(section, orientation, role);
+}
+
+int SuggestionsModel::rowCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent)
+ return m_suggestions.isEmpty() ? m_mostrecent.size() : m_suggestions.size();
+}
+
+QVariant SuggestionsModel::data(const QModelIndex &index, int role) const
+{
+ QJsonObject obj = get(index.row());
+ if (role == Qt::DisplayRole) {
+ return obj.value("place_name").toVariant();
+ } else if (role == PlaceNameRole) {
+ return obj.value("place_name").toVariant();
+ }
+
+ return QVariant();
+}
+
+QHash<int, QByteArray> SuggestionsModel::roleNames() const
+{
+ QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
+ roles[PlaceNameRole] = "placename";
+ return roles;
+}
+
+const QJsonObject SuggestionsModel::get(int index) const
+{
+ return m_suggestions.isEmpty() ?
+ m_mostrecent[index].toObject() :
+ m_suggestions[index].toObject();
+}
+
+void SuggestionsModel::setSuggestions(const QJsonArray &suggestions)
+{
+ beginResetModel();
+ m_suggestions = suggestions;
+ endResetModel();
+ emit emptyChanged();
+}
+
+void SuggestionsModel::clear()
+{
+ beginResetModel();
+ m_suggestions = QJsonArray();
+ endResetModel();
+ emit emptyChanged();
+}
+
+void SuggestionsModel::addToMostRecent(const QJsonObject &place)
+{
+ Q_UNUSED(place)
+ // For the demo, do not add new most recent places
+#ifndef EBIKE_DEMO_MODE
+ if (!m_mostrecent.contains(place))
+ m_mostrecent.prepend(place);
+ if (m_mostrecent.size() > 3)
+ m_mostrecent.pop_back();
+ saveMostRecent();
+#endif
+}
+
+void SuggestionsModel::loadMostRecent()
+{
+ QDir dir(QCoreApplication::applicationDirPath());
+
+ // Load most recent places
+ QString mostRecentFilepath = dir.absoluteFilePath(mostRecentFilename);
+ QFile mostRecentFile(mostRecentFilepath);
+ if (mostRecentFile.open(QIODevice::ReadOnly)) {
+ QJsonDocument doc = QJsonDocument::fromBinaryData(mostRecentFile.readAll());
+ m_mostrecent = doc.array();
+ }
+}
+
+void SuggestionsModel::saveMostRecent() const
+{
+ QDir dir(QCoreApplication::applicationDirPath());
+
+ // Load most recent places
+ QString mostRecentFilepath = dir.absoluteFilePath(mostRecentFilename);
+ QFile mostRecentFile(mostRecentFilepath);
+ if (mostRecentFile.open(QIODevice::WriteOnly)) {
+ QJsonDocument doc(m_mostrecent);
+ mostRecentFile.write(doc.toBinaryData());
+ }
+}
diff --git a/basicsuite/ebike-ui/datamodelplugin/suggestionsmodel.h b/basicsuite/ebike-ui/datamodelplugin/suggestionsmodel.h
new file mode 100644
index 0000000..5bf22b5
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/suggestionsmodel.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SUGGESTIONSMODEL_H
+#define SUGGESTIONSMODEL_H
+
+#include <QAbstractListModel>
+#include <QJsonArray>
+#include <QJsonObject>
+
+class SuggestionsModel : public QAbstractListModel
+{
+ Q_OBJECT
+ Q_PROPERTY(bool empty READ isEmpty RESET clear NOTIFY emptyChanged)
+
+public:
+ explicit SuggestionsModel(QObject *parent = nullptr);
+ explicit SuggestionsModel(const QJsonArray &suggestions, QObject *parent = nullptr);
+ enum SuggestionRoles {
+ PlaceNameRole = Qt::UserRole + 1
+ };
+
+public:
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+ virtual int rowCount(const QModelIndex &parent) const;
+ virtual QVariant data(const QModelIndex &index, int role) const;
+ virtual QHash<int, QByteArray> roleNames() const;
+
+ Q_INVOKABLE const QJsonObject get(int index) const;
+ bool isEmpty() const { return m_suggestions.size() == 0; }
+
+ void setSuggestions(const QJsonArray &suggestions);
+ Q_INVOKABLE void clear();
+
+ Q_INVOKABLE void addToMostRecent(const QJsonObject &place);
+
+private:
+ void loadMostRecent();
+ void saveMostRecent() const;
+
+signals:
+ void emptyChanged();
+
+private:
+ QJsonArray m_mostrecent;
+ QJsonArray m_suggestions;
+};
+
+#endif // SUGGESTIONSMODEL_H
diff --git a/basicsuite/ebike-ui/datamodelplugin/tripdatamodel.cpp b/basicsuite/ebike-ui/datamodelplugin/tripdatamodel.cpp
new file mode 100644
index 0000000..b74605f
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/tripdatamodel.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "datastore.h"
+#include "tripdatamodel.h"
+
+#include <QDebug>
+
+TripDataModel::TripDataModel(DataStore *datastore, QObject *parent)
+ : QAbstractListModel(parent)
+ , m_datastore(datastore)
+ , m_refreshing(false)
+ , m_saving(false)
+{
+}
+
+int TripDataModel::rowCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent)
+ return m_trips.count() + 1; // +1 for current trip
+}
+
+QVariant TripDataModel::data(const QModelIndex &index, int role) const
+{
+ QJsonObject obj = get(index.row());
+ if (role == DurationRole)
+ return obj.value("duration").toDouble(); // Seconds
+ else if (role == DistanceRole)
+ return m_datastore->convertDistance(obj.value("distance").toDouble());
+ else if (role == CaloriesRole)
+ return obj.value("calories").toDouble();
+ else if (role == MaxspeedRole)
+ return m_datastore->convertSpeed(obj.value("maxspeed").toDouble());
+ else if (role == AvgspeedRole)
+ return m_datastore->convertSpeed(obj.value("distance").toDouble() / obj.value("duration").toDouble());
+ else if (role == AscentRole)
+ return obj.value("ascent").toDouble();
+ else if (role == StartTimeRole)
+ return obj.value("starttime").toDouble();
+
+ return QVariant();
+}
+
+QHash<int, QByteArray> TripDataModel::roleNames() const
+{
+ QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
+ roles[DurationRole] = "duration";
+ roles[DistanceRole] = "distance";
+ roles[CaloriesRole] = "calories";
+ roles[MaxspeedRole] = "maxspeed";
+ roles[AvgspeedRole] = "avgspeed";
+ roles[AscentRole] = "ascent";
+ roles[StartTimeRole] = "starttime";
+
+ return roles;
+}
+
+void TripDataModel::setTrips(const QJsonArray &trips)
+{
+ beginResetModel();
+ m_trips = trips;
+ endResetModel();
+ m_refreshing = false;
+ emit refreshingChanged(m_refreshing);
+ emit refreshed();
+}
+
+void TripDataModel::addTrip(const QJsonObject &trip)
+{
+ // Always append at the beginning of the list, easy to calculate
+ int newRow = 0;
+ beginInsertRows(QModelIndex(), newRow, newRow);
+ m_trips.append(trip);
+ endInsertRows();
+ emit tripDataSaved(newRow);
+}
+
+const QJsonObject TripDataModel::get(int index) const
+{
+ return index == 0 ? m_current : m_trips.at(m_trips.count() - index).toObject();
+}
+
+void TripDataModel::refresh()
+{
+ m_refreshing = true;
+ emit refreshingChanged(m_refreshing);
+ m_datastore->getTrips();
+}
+
+void TripDataModel::endTrip()
+{
+ m_saving = true;
+ emit savingChanged(m_saving);
+ m_datastore->endTrip();
+}
+
+void TripDataModel::setCurrentTrip(const QJsonObject &current)
+{
+ m_current = current;
+ QModelIndex currentIndex = index(0);
+ emit dataChanged(currentIndex, currentIndex);
+}
diff --git a/basicsuite/ebike-ui/datamodelplugin/tripdatamodel.h b/basicsuite/ebike-ui/datamodelplugin/tripdatamodel.h
new file mode 100644
index 0000000..56be84e
--- /dev/null
+++ b/basicsuite/ebike-ui/datamodelplugin/tripdatamodel.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TRIPDATAMODEL_H
+#define TRIPDATAMODEL_H
+
+#include <QAbstractListModel>
+#include <QJsonObject>
+#include <QJsonArray>
+
+class DataStore;
+
+class TripDataModel : public QAbstractListModel
+{
+ Q_OBJECT
+ Q_PROPERTY(bool refreshing READ refreshing NOTIFY refreshingChanged)
+ Q_PROPERTY(bool saving READ saving NOTIFY savingChanged)
+
+public:
+ explicit TripDataModel(DataStore *datastore, QObject *parent = nullptr);
+ enum TripDataRoles {
+ DurationRole = Qt::UserRole + 1,
+ DistanceRole,
+ CaloriesRole,
+ MaxspeedRole,
+ AvgspeedRole,
+ AscentRole,
+ StartTimeRole
+ };
+
+public:
+ virtual int rowCount(const QModelIndex &parent) const;
+ virtual QVariant data(const QModelIndex &index, int role) const;
+ virtual QHash<int, QByteArray> roleNames() const;
+
+ Q_INVOKABLE const QJsonObject get(int index) const;
+
+ void setTrips(const QJsonArray &trips);
+ void addTrip(const QJsonObject &trip);
+
+ bool refreshing() const { return m_refreshing; }
+ bool saving() const { return m_saving; }
+
+signals:
+ void refreshed();
+ void refreshingChanged(bool refreshing);
+ void savingChanged(bool saving);
+ void tripDataSaved(int index);
+
+public slots:
+ void refresh();
+ void endTrip();
+ void setCurrentTrip(const QJsonObject &current);
+
+private:
+ DataStore *m_datastore;
+ QJsonArray m_trips;
+ QJsonObject m_current;
+ bool m_refreshing;
+ bool m_saving;
+};
+
+#endif // TRIPDATAMODEL_H