summaryrefslogtreecommitdiffstats
path: root/CenterConsole/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'CenterConsole/plugins')
-rw-r--r--CenterConsole/plugins/clusterdatasource/clusterdatabackend.cpp736
-rw-r--r--CenterConsole/plugins/clusterdatasource/clusterdatabackend.h139
-rw-r--r--CenterConsole/plugins/clusterdatasource/clusterdatasource.pro31
-rw-r--r--CenterConsole/plugins/clusterdatasource/plugin.cpp56
-rw-r--r--CenterConsole/plugins/clusterdatasource/qmldir2
-rw-r--r--CenterConsole/plugins/clusterdatasource/qtiviclusterdata.cpp388
-rw-r--r--CenterConsole/plugins/clusterdatasource/qtiviclusterdata.h189
-rw-r--r--CenterConsole/plugins/datasource/datasource.cpp46
-rw-r--r--CenterConsole/plugins/datasource/datasource.h49
-rw-r--r--CenterConsole/plugins/datasource/datasource.pro30
-rw-r--r--CenterConsole/plugins/datasource/plugin.cpp45
-rw-r--r--CenterConsole/plugins/datasource/plugin.h45
-rw-r--r--CenterConsole/plugins/datasource/qmldir3
-rw-r--r--CenterConsole/plugins/datasource/sqlquerydatasource.cpp154
-rw-r--r--CenterConsole/plugins/datasource/sqlquerydatasource.h96
-rw-r--r--CenterConsole/plugins/datasource/sqlquerymodel.cpp75
-rw-r--r--CenterConsole/plugins/datasource/sqlquerymodel.h50
-rw-r--r--CenterConsole/plugins/datasource/sqltabledatasource.cpp199
-rw-r--r--CenterConsole/plugins/datasource/sqltabledatasource.h99
-rw-r--r--CenterConsole/plugins/datasource/sqltablemodel.cpp93
-rw-r--r--CenterConsole/plugins/datasource/sqltablemodel.h57
-rw-r--r--CenterConsole/plugins/plugins.pro6
-rw-r--r--CenterConsole/plugins/screenManager/plugin.cpp57
-rw-r--r--CenterConsole/plugins/screenManager/qmldir2
-rw-r--r--CenterConsole/plugins/screenManager/screenManager.pro23
-rw-r--r--CenterConsole/plugins/screenManager/screenmanager.cpp61
-rw-r--r--CenterConsole/plugins/screenManager/screenmanager.h54
-rw-r--r--CenterConsole/plugins/scripts/README.md9
-rw-r--r--CenterConsole/plugins/scripts/scanmovies.py123
-rw-r--r--CenterConsole/plugins/scripts/scanmusic.py149
30 files changed, 3066 insertions, 0 deletions
diff --git a/CenterConsole/plugins/clusterdatasource/clusterdatabackend.cpp b/CenterConsole/plugins/clusterdatasource/clusterdatabackend.cpp
new file mode 100644
index 0000000..43edf93
--- /dev/null
+++ b/CenterConsole/plugins/clusterdatasource/clusterdatabackend.cpp
@@ -0,0 +1,736 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "clusterdatabackend.h"
+
+#include <QDebug>
+#include <QtGlobal>
+#include <QHostAddress>
+#include <QNetworkInterface>
+
+#ifndef CLUSTERDATA_SIMULATION
+// #define DEBUG_CAN
+#include <QtMath>
+#include <QCanBus>
+#define SOCKETCAN "socketcan"
+#define CANINTERFACE "can0"
+
+// J1939 PGNs
+#define PGN_65268 0xFEF4 // Tire Condition - TIRE
+#define PGN_64933 0xFDA5 // Door Control 2 - DC2
+#define PGN_64972 0xFDCC // Light Control
+#define PGN_61445 0xF005 // Electronic Transmission Controller 2 - ETC2
+#define PGN_65265 0xFEF1 // Cruise Control/Vehicle Speed - CCVS
+#define PGN_65267 0xFEF3 // vehicle position - VP
+#define PGN_65256 0xFEE8 // vehicle direction/speed
+#define PGN_65262 0xFEEE // Engine Temperature 1 - ET1
+#define PGN_65263 0xFEEF // Engine Fluid Level/Pressure 1 - EFL/P1
+#define PGN_65271 0xFEF7 // Vehicle Electrical Power - VEP
+#define PGN_65276 0xFEFC // Dash Display - DD
+#define PGN_61444 0xF004 // Electronic Engine Controller 1 - EEC1
+#define PGN_60928 0xEE00 // Address Calimed - ACL
+#endif
+
+// door defines
+#define OPEN_DOOR_1 0x400000000000000
+#define OPEN_DOOR_2 0x1000000000000
+#define OPEN_DOOR_3 0x40000000000000
+#define OPEN_DOOR_4 0x100000000000
+#define OPEN_DOOR_5 0x400000000
+#define OPEN_DOOR_6 0x1000000
+
+// light defines
+#define HEAD_LIGHT 0x200000000000000
+#define PARK_LIGHT 0x100000000000000
+#define LIGHT_ERROR 0x400000000000000
+#define LEFT_TURN_SIGNAL 0x10000000000000
+#define RIGHT_TURN_SIGNAL 0x20000000000000
+#define HAZARD_SIGNAL 0x4000000000000
+
+#define LEFT_BLINK_ON 0x01
+#define RIGHT_BLINK_ON 0x02
+#define HAZARD_ON 0x4
+
+// Current gear defines
+#define GEAR_PARK 0xFB
+#define GEAR_REVERSE 0x7C
+#define GEAR_NEUTRAL 0x7D
+// #define GEAR_1 0x7E
+// #define GEAR_2 0x7F
+// #define GEAR_3 0x80
+// #define GEAR_4 0x81
+// #define GEAR_5 0x82
+// #define GEAR_6 0x83
+
+ClusterDataBackend::ClusterDataBackend(QObject* parent) :
+ QObject(parent),
+#ifndef CLUSTERDATA_SIMULATION
+ m_canDevice(Q_NULLPTR),
+#endif
+ m_vehicleSpeed(0.0),
+ m_latitude(52.53471566),
+ m_longitude(13.29339621),
+ m_direction(0.0),
+ m_flatTire(false),
+ m_lightFailure(false),
+ m_gear(1),
+ m_signalLights(0x0),
+ m_headLight(false),
+ m_parkLight(false),
+ m_carId(2),
+ m_brake(false),
+ m_engineTemp(60),
+ m_oilTemp(0.0),
+ m_oilPressure(0),
+ m_batteryPotential(80.0),
+ m_gasLevel(67.0),
+ m_rpm(4000)
+{
+
+ m_doorOpen.insert("frontLeft", false);
+ m_doorOpen.insert("frontRight", false);
+ m_doorOpen.insert("rearLeft", false);
+ m_doorOpen.insert("rearRight", false);
+ m_doorOpen.insert("trunk", false);
+ m_doorOpen.insert("hood", false);
+
+#ifndef CLUSTERDATA_SIMULATION
+ QCanBus* canBus(QCanBus::instance());
+ QList<QByteArray> plugins(canBus->plugins());
+ if (plugins.contains(SOCKETCAN)) {
+ m_canDevice = canBus->createDevice(SOCKETCAN, CANINTERFACE);
+ if (m_canDevice) {
+ connect(m_canDevice, SIGNAL(errorOccurred(QCanBusDevice::CanBusError)), this, SLOT(canError(QCanBusDevice::CanBusError)));
+ connect(m_canDevice, SIGNAL(framesReceived()), this, SLOT(canFramesReceived()));
+#ifdef DEBUG_CAN
+ connect(m_canDevice, SIGNAL(stateChanged(QCanBusDevice::CanBusDeviceState)), this, SLOT(canStateChanged(QCanBusDevice::CanBusDeviceState)));
+ qDebug() << "ClusterDataBackend::ClusterDataBackend - connectDevice:" <<
+#endif // DEBUG_CAN
+ m_canDevice->connectDevice();
+ }
+ }
+#endif // !CLUSTERDATA_SIMULATION
+}
+
+ClusterDataBackend::~ClusterDataBackend()
+{
+#ifndef CLUSTERDATA_SIMULATION
+ if (m_canDevice) {
+ m_canDevice->disconnectDevice();
+ }
+#else
+ if (m_tcpServerConnection)
+ m_tcpServerConnection->close();
+ m_tcpServer.close();
+#endif
+}
+
+QStringList ClusterDataBackend::availableZones() const
+{
+ return m_doorOpen.keys();
+}
+
+QMap<QString, QVariantMap> ClusterDataBackend::zoneMap() const
+{
+ return m_zonedFeatures;
+}
+
+void ClusterDataBackend::initializeAttributes()
+{
+ emit vehicleSpeedChanged(m_vehicleSpeed);
+ emit latitudeChanged(m_latitude);
+ emit longitudeChanged(m_longitude);
+ emit directionChanged(m_direction);
+ emit flatTireChanged(m_flatTire);
+ foreach (QString zone, m_doorOpen.keys()) {
+ emit doorOpenChanged(m_doorOpen.value(zone), zone);
+ }
+ emit lightFailureChanged(m_lightFailure);
+ emit reverseChanged(m_gear < 0);
+ emit leftTurnLightChanged(m_signalLights & LEFT_BLINK_ON);
+ emit rightTurnLightChanged(m_signalLights & RIGHT_BLINK_ON);
+ emit headLightChanged(m_headLight);
+ emit carIdChanged(m_carId);
+
+#ifdef CLUSTERDATA_SIMULATION
+ QHostAddress simuAddr("127.0.0.1");
+
+ QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
+ foreach (QNetworkInterface interface, interfaces) {
+ QList<QNetworkAddressEntry> addressEntries = interface.addressEntries();
+
+ foreach (QNetworkAddressEntry entry, addressEntries) {
+ if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
+ simuAddr = entry.ip();
+ }
+ }
+ }
+ if (m_tcpServer.listen(simuAddr, 32123)) {
+ connect(&m_tcpServer, SIGNAL(newConnection()),
+ this, SLOT(acceptConnection()));
+ qDebug() << "ClusterData server listening " << simuAddr << m_tcpServer.serverPort();
+ } else {
+ qWarning() << m_tcpServer.errorString();
+ }
+#endif
+}
+
+#ifdef CLUSTERDATA_SIMULATION
+void ClusterDataBackend::acceptConnection()
+{
+ m_tcpServerConnection = m_tcpServer.nextPendingConnection();
+ connect(m_tcpServerConnection, &QTcpSocket::readyRead,
+ this, &ClusterDataBackend::updateServerProgress);
+}
+
+void ClusterDataBackend::updateServerProgress()
+{
+ QString msg(m_tcpServerConnection->readAll());
+
+ foreach (QString msgAttr, msg.split(" ",QString::SkipEmptyParts)) {
+ QString attribute = msgAttr.section(':',0,0);
+ QString value = msgAttr.section(':',1,1);
+ if (attribute == "vehicleSpeed") {
+ emit vehicleSpeedChanged(value.toDouble());
+ } else if (attribute == "latitude") {
+ emit latitudeChanged(value.toDouble());
+ } else if (attribute == "longitude") {
+ emit longitudeChanged(value.toDouble());
+ } else if (attribute == "direction") {
+ emit directionChanged(value.toDouble());
+ } else if (attribute == "headLight") {
+ emit headLightChanged((bool)value.toInt());
+ } else if (attribute == "lightFailure") {
+ emit lightFailureChanged((bool)value.toInt());
+ } else if (attribute == "flatTire") {
+ emit flatTireChanged((bool)value.toInt());
+ } else if (attribute == "reverse") {
+ emit reverseChanged((bool)value.toInt());
+ } else if (attribute == "leftTurnLight") {
+ emit leftTurnLightChanged((bool)value.toInt());
+ } else if (attribute == "rightTurnLight") {
+ emit rightTurnLightChanged((bool)value.toInt());
+ } else if (attribute == "headLight") {
+ emit headLightChanged((bool)value.toInt());
+ } else if (attribute == "parkLight") {
+ emit parkLightChanged((bool)value.toInt());
+ } else if (attribute == "carId") {
+ emit carIdChanged(value.toInt());
+ } else if (attribute == "frontLeftDoorOpen") {
+ emit doorOpenChanged((bool)value.toInt(), "frontLeft");
+ } else if (attribute == "frontRightDoorOpen") {
+ emit doorOpenChanged((bool)value.toInt(), "frontRight");
+ } else if (attribute == "rearLeftDoorOpen") {
+ emit doorOpenChanged((bool)value.toInt(), "rearLeft");
+ } else if (attribute == "rearRightDoorOpen") {
+ emit doorOpenChanged((bool)value.toInt(), "rearRight");
+ } else if (attribute == "hoodOpen") {
+ emit doorOpenChanged((bool)value.toInt(), "hood");
+ } else if (attribute == "trunkOpen") {
+ emit doorOpenChanged((bool)value.toInt(), "trunk");
+ } else if (attribute == "hazardSignal") {
+ emit leftTurnLightChanged((bool)value.toInt());
+ emit rightTurnLightChanged((bool)value.toInt());
+ } else if (attribute == "brake") {
+ emit brakeChanged((bool)value.toInt());
+ } else if (attribute == "engineTemp") {
+ emit engineTempChanged(value.toInt());
+ } else if (attribute == "oilTemp") {
+ emit oilTempChanged(value.toDouble());
+ } else if (attribute == "oilPressure") {
+ emit oilPressureChanged(value.toInt());
+ } else if (attribute == "batteryPotential") {
+ emit batteryPotentialChanged(value.toDouble());
+ } else if (attribute == "gasLevel") {
+ emit gasLevelChanged(value.toDouble());
+ } else if (attribute == "rpm") {
+ emit rpmChanged(value.toInt());
+ } else if (attribute == "gear") {
+ emit gearChanged(value.toInt());
+ }
+ else {
+ qWarning() << "Unknown msg" << msg;
+ }
+ }
+}
+#else
+// Tire Condition - TIRE
+void ClusterDataBackend::handlePGN65268(const QCanBusFrame& frame)
+{
+ QByteArray data(frame.payload());
+ if (data.size() == 8) {
+// char tireId(data.at(0));
+// char pressure(data.at(1));
+// quint16 temperatureData(data.at(2) << 8);
+// temperatureData |= data.at(3);
+// double tireTemperature((0.03125 * (double)temperatureData) - 273);
+ m_flatTire = (data.at(4) & 0x30);
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN65268 - m_flatTire: %s", (m_flatTire ? "true" : "false"));
+#endif // DEBUG_CAN
+ emit flatTireChanged(m_flatTire);
+ }
+}
+
+// Door Control 2 - DC2
+void ClusterDataBackend::handlePGN64933(const QCanBusFrame& frame)
+{
+ QByteArray data(frame.payload());
+ if (data.size() == 8) {
+ quint64 doorData((quint64)data.at(0) << 56);
+ doorData |= ((quint64)data.at(1) << 48);
+ doorData |= ((quint64)data.at(2) << 40);
+ doorData |= ((quint64)data.at(3) << 32);
+ doorData |= ((quint64)data.at(4) << 24);
+ doorData |= ((quint64)data.at(5) << 16);
+ doorData |= ((quint64)data.at(6) << 8);
+ doorData |= (quint64)data.at(7);
+
+ bool frontLeft(doorData & OPEN_DOOR_1);
+ bool frontRight(doorData & OPEN_DOOR_2);
+ bool rearLeft(doorData & OPEN_DOOR_3);
+ bool rearRight(doorData & OPEN_DOOR_4);
+ bool trunk(doorData & OPEN_DOOR_5);
+ bool hood(doorData & OPEN_DOOR_6);
+
+ if (m_doorOpen.value("frontLeft") != frontLeft) {
+ m_doorOpen.insert("frontLeft", frontLeft);
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN64933 - doorOpenChanged, frontLeft: %s", (frontLeft ? "true" : "false"));
+#endif // DEBUG_CAN
+ emit doorOpenChanged(frontLeft, "frontLeft");
+ }
+ if (m_doorOpen.value("frontRight") != frontRight) {
+ m_doorOpen.insert("frontRight", frontRight);
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN64933 - doorOpenChanged, frontRight: %s", (frontRight ? "true" : "false"));
+#endif // DEBUG_CAN
+ emit doorOpenChanged(frontRight, "frontRight");
+ }
+ if (m_doorOpen.value("rearLeft") != rearLeft) {
+ m_doorOpen.insert("rearLeft", rearLeft);
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN64933 - doorOpenChanged, rearLeft: %s", (rearLeft ? "true" : "false"));
+#endif // DEBUG_CAN
+ emit doorOpenChanged(rearLeft, "rearLeft");
+ }
+ if (m_doorOpen.value("rearRight") != rearRight) {
+ m_doorOpen.insert("rearRight", rearRight);
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN64933 - doorOpenChanged, rearRight: %s", (rearRight ? "true" : "false"));
+#endif // DEBUG_CAN
+ emit doorOpenChanged(rearRight, "rearRight");
+ }
+ if (m_doorOpen.value("trunk") != trunk) {
+ m_doorOpen.insert("trunk", trunk);
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN64933 - doorOpenChanged, trunk: %s", (trunk ? "true" : "false"));
+#endif // DEBUG_CAN
+ emit doorOpenChanged(trunk, "trunk");
+ }
+ if (m_doorOpen.value("hood") != hood) {
+ m_doorOpen.insert("hood", hood);
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN64933 - doorOpenChanged, hood: %s", (hood ? "true" : "false"));
+#endif // DEBUG_CAN
+ emit doorOpenChanged(hood, "hood");
+ }
+ }
+}
+
+// Light Control
+void ClusterDataBackend::handlePGN64972(const QCanBusFrame& frame)
+{
+ QByteArray data(frame.payload());
+ if (data.size() == 8) {
+ quint64 lightData((quint64)data.at(0) << 56);
+ lightData |= ((quint64)data.at(1) << 48);
+ lightData |= ((quint64)data.at(2) << 40);
+ lightData |= ((quint64)data.at(3) << 32);
+ lightData |= ((quint64)data.at(4) << 24);
+ lightData |= ((quint64)data.at(5) << 16);
+ lightData |= ((quint64)data.at(6) << 8);
+ lightData |= data.at(7);
+
+ if (m_headLight != (lightData & HEAD_LIGHT)) {
+ m_headLight = (lightData & HEAD_LIGHT);
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN64972 - m_headLight: %s", (m_headLight ? "true" : "false"));
+#endif // DEBUG_CAN
+ emit headLightChanged(m_headLight);
+ }
+ if (m_parkLight != (lightData & PARK_LIGHT)) {
+ m_parkLight = (lightData & PARK_LIGHT);
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN64972 - m_parkLight: %s", (m_parkLight ? "true" : "false"));
+#endif // DEBUG_CAN
+ emit parkLightChanged(m_parkLight);
+ }
+ if (m_lightFailure != (lightData & LIGHT_ERROR)) {
+ m_lightFailure = (lightData & LIGHT_ERROR);
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN64972 - m_lightFailure: %s", (m_lightFailure ? "true" : "false"));
+#endif // DEBUG_CAN
+ emit lightFailureChanged(m_lightFailure);
+ }
+ if ((bool)(m_signalLights & LEFT_BLINK_ON) != (bool)(lightData & LEFT_TURN_SIGNAL)) {
+ if (lightData & LEFT_TURN_SIGNAL) {
+ m_signalLights |= LEFT_BLINK_ON;
+ }
+ else {
+ m_signalLights &= ~LEFT_BLINK_ON;
+ }
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN64972 - leftTurnLight: %s", ((lightData & LEFT_TURN_SIGNAL) ? "true" : "false"));
+#endif // DEBUG_CAN
+ emit leftTurnLightChanged(lightData & LEFT_TURN_SIGNAL);
+ }
+ if ((bool)(m_signalLights & RIGHT_BLINK_ON) != (bool)(lightData & RIGHT_TURN_SIGNAL)) {
+ if (lightData & RIGHT_TURN_SIGNAL) {
+ m_signalLights |= RIGHT_BLINK_ON;
+ }
+ else {
+ m_signalLights &= ~RIGHT_BLINK_ON;
+ }
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN64972 - rightTurnLight: %s", ((lightData & RIGHT_TURN_SIGNAL) ? "true" : "false"));
+#endif // DEBUG_CAN
+ emit rightTurnLightChanged(lightData & RIGHT_TURN_SIGNAL);
+ }
+ if ((bool)(m_signalLights & HAZARD_ON) != (bool)(lightData & HAZARD_SIGNAL)) {
+ if (lightData & HAZARD_SIGNAL) {
+ m_signalLights |= HAZARD_ON;
+ if (!(m_signalLights & LEFT_BLINK_ON)) {
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN64972 - hazard ON, leftTurnLight: true");
+#endif // DEBUG_CAN
+ emit leftTurnLightChanged(true);
+ }
+ if (!(m_signalLights & RIGHT_BLINK_ON)) {
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN64972 - hazard ON, rightTurnLight: true");
+#endif // DEBUG_CAN
+ emit rightTurnLightChanged(true);
+ }
+ }
+ else {
+ m_signalLights &= ~HAZARD_ON;
+ if (!(m_signalLights & LEFT_BLINK_ON)) {
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN64972 - hazard OFF, leftTurnLight: false");
+#endif // DEBUG_CAN
+ emit leftTurnLightChanged(false);
+ }
+ if (!(m_signalLights & RIGHT_BLINK_ON)) {
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN64972 - hazard OFF, rightTurnLight: false");
+#endif // DEBUG_CAN
+ emit rightTurnLightChanged(false);
+ }
+ }
+ }
+ }
+}
+
+// Electronic Transmission Controller 2 - ETC2
+void ClusterDataBackend::handlePGN61445(const QCanBusFrame& frame)
+{
+ QByteArray data(frame.payload());
+ if (data.size() == 8) {
+ char gear(data.at(3));
+ if (gear == (char)GEAR_PARK) {
+ m_gear = 0xff;
+ }
+ else if (m_gear == -1 && gear != (char)GEAR_REVERSE) {
+ m_gear = (gear - GEAR_NEUTRAL);
+ emit reverseChanged(false);
+ }
+ else if (m_gear != -1 && gear == (char)GEAR_REVERSE) {
+ m_gear = -1;
+ emit reverseChanged(true);
+ }
+ else {
+ m_gear = (gear - GEAR_NEUTRAL);
+ }
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN61445 - gear: %d", m_gear);
+#endif // DEBUG_CAN
+ emit gearChanged(m_gear);
+ }
+}
+
+// Cruise Control/Vehicle Speed - CCVS
+void ClusterDataBackend::handlePGN65265(const QCanBusFrame& frame)
+{
+ QByteArray data(frame.payload());
+ if (data.size() == 8) {
+ qint16 speed((data.at(1) << 8));
+ speed |= data.at(2);
+ double vehicleSpeed(0.00390625 * (double)speed);
+
+ if (m_vehicleSpeed != vehicleSpeed) {
+ m_vehicleSpeed = vehicleSpeed;
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN65265 - vehicle speed: %f", m_vehicleSpeed);
+#endif // DEBUG_CAN
+ emit vehicleSpeedChanged(m_vehicleSpeed);
+ }
+
+ bool brakeOn(data.at(3) & 0x10);
+ if (m_brake != brakeOn) {
+ m_brake = brakeOn;
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN65265 - m_brake: %s", (m_brake ? "true" : "false"));
+#endif // DEBUG_CAN
+ emit brakeChanged(m_brake);
+ }
+ }
+}
+
+// vehicle position - VP
+void ClusterDataBackend::handlePGN65267(const QCanBusFrame& frame)
+{
+ QByteArray data(frame.payload());
+
+ if (data.size() == 8) {
+ quint32 lat((data.at(0) << 24));
+ lat |= ((data.at(1) << 16));
+ lat |= ((data.at(2) << 8));
+ lat |= data.at(3);
+
+ quint32 lon(data.at(4) << 24);
+ lon |= (data.at(5) << 16);
+ lon |= (data.at(6) << 8);
+ lon |= data.at(7);
+
+ double latitude((((double)lat) * 1e-7) - 210);
+ double longitude((((double)lon) * 1e-7) - 210);
+
+ bool positionChanged(false);
+ if (m_latitude != latitude) {
+ m_latitude = latitude;
+ positionChanged = true;
+ }
+ if (m_longitude != longitude) {
+ m_longitude = longitude;
+ positionChanged = true;
+ }
+ if (positionChanged) {
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN129025 - lat: %f, lon: %f", m_latitude, m_longitude);
+#endif // DEBUG_CAN
+ emit latitudeChanged(m_latitude);
+ emit longitudeChanged(m_longitude);
+ }
+ }
+}
+
+// vehicle direction/speed
+void ClusterDataBackend::handlePGN65256(const QCanBusFrame& frame)
+{
+ QByteArray data(frame.payload());
+ if (data.size() == 8) {
+ quint16 directionData((data.at(0) << 8));
+ directionData |= data.at(1);
+ double direction(0.0078125 * (double)directionData); // 1/128 deg/bit
+
+ if (m_direction != direction) {
+ m_direction = direction;
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN65256 - m_direction: %f", m_direction);
+#endif // DEBUG_CAN
+ emit directionChanged(m_direction);
+ }
+ }
+}
+
+// Engine Temperature 1 - ET1
+void ClusterDataBackend::handlePGN65262(const QCanBusFrame& frame)
+{
+ QByteArray data(frame.payload());
+ if (data.size() == 8) {
+ qint8 engineTemp(data.at(0) - 40);
+ if (m_engineTemp != engineTemp) {
+ m_engineTemp = engineTemp;
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN65262 - m_engineTemp: %d", m_engineTemp);
+#endif // DEBUG_CAN
+ emit engineTempChanged(m_engineTemp);
+ }
+ quint16 oilTempData(data.at(2) << 8);
+ oilTempData |= data.at(3);
+ double oilTemp(0.03125 * ((double)oilTempData) - 273.0);
+ if (m_oilTemp != oilTemp) {
+ m_oilTemp = oilTemp;
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN65262 - m_oilTemp: %f", m_oilTemp);
+#endif // DEBUG_CAN
+ emit oilTempChanged(m_oilTemp);
+ }
+ }
+}
+
+// Engine Fluid Level/Pressure 1 - EFL/P1
+void ClusterDataBackend::handlePGN65263(const QCanBusFrame& frame)
+{
+ QByteArray data(frame.payload());
+ if (data.size() == 8) {
+ int oilPressure(4 * data.at(3));
+ if (m_oilPressure != oilPressure) {
+ m_oilPressure = oilPressure;
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN65263 - m_oilPressure: %d", m_oilPressure);
+#endif // DEBUG_CAN
+ emit oilPressureChanged(m_oilPressure);
+ }
+ }
+}
+
+// Vehicle Electrical Power - VEP
+void ClusterDataBackend::handlePGN65271(const QCanBusFrame& frame)
+{
+ QByteArray data(frame.payload());
+ if (data.size() == 8) {
+ quint16 batteryPotentialData(data.at(6) << 8);
+ batteryPotentialData |= data.at(7);
+ double batteryPotential(0.05 * (double)batteryPotentialData);
+ if (m_batteryPotential != batteryPotential) {
+ m_batteryPotential = batteryPotential;
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN65271 - m_batteryPotential: %f", m_batteryPotential);
+#endif // DEBUG_CAN
+ emit batteryPotentialChanged(m_batteryPotential);
+ }
+ }
+}
+
+// Dash Display - DD
+void ClusterDataBackend::handlePGN65276(const QCanBusFrame& frame)
+{
+ QByteArray data(frame.payload());
+ if (data.size() == 8) {
+ double gasLevel(0.4 * (double)data.at(1));
+ if (m_gasLevel != gasLevel) {
+ m_gasLevel = gasLevel;
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN65276 - m_gasLevel: %f", m_gasLevel);
+#endif // DEBUG_CAN
+ emit gasLevelChanged(m_gasLevel);
+ }
+ }
+}
+
+// Electronic Engine Controller 1 - EEC1
+void ClusterDataBackend::handlePGN61444(const QCanBusFrame& frame)
+{
+ QByteArray data(frame.payload());
+ if (data.size() == 8) {
+ quint16 rpmData(data.at(3) << 8);
+ rpmData |= data.at(4);
+ int rpm(0.125 * (double)rpmData);
+ if (m_rpm != rpm) {
+ m_rpm = rpm;
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN61444 - m_rpm: %d", m_rpm);
+#endif // DEBUG_CAN
+ emit rpmChanged(m_rpm);
+ }
+ }
+}
+
+// Address Claimed - ACL
+void ClusterDataBackend::handlePGN60928(const QCanBusFrame &frame)
+{
+ QByteArray data(frame.payload());
+ if (data.size() == 8) {
+ // only 21 bits allowed (0x0 - 0x1FFFFF), pos 1.1 - 3.5 in message
+ quint16 carIdData((data.at(0) & 0xff) << 13);
+ carIdData |= ((data.at(1) & 0xff) << 5);
+ carIdData |= ((data.at(2) & 0xf8) >> 3);
+ if (m_carId != (int)carIdData) {
+ m_carId = carIdData;
+#ifdef DEBUG_CAN
+ qDebug("ClusterDataBackend::handlePGN60928 - carId: %d", m_carId);
+#endif // DEBUG_CAN
+ emit carIdChanged(m_carId);
+ }
+ }
+}
+
+void ClusterDataBackend::canError(QCanBusDevice::CanBusError error)
+{
+ qWarning("ClusterDataBackend::canError - code: %d, error: %s", (int)error, qPrintable(m_canDevice->errorString()));
+ m_canDevice->disconnectDevice();
+}
+
+void ClusterDataBackend::canFramesReceived()
+{
+ while (m_canDevice && m_canDevice->framesAvailable() > 0) {
+ QCanBusFrame frame(m_canDevice->readFrame());
+
+ quint32 frameId(frame.frameId());
+
+ switch (frameId) {
+ case PGN_65268 : handlePGN65268(frame); break; // Tire Condition - TIRE
+ case PGN_64933 : handlePGN64933(frame); break; // Door Control 2 - DC2
+ case PGN_64972 : handlePGN64972(frame); break; // Light Control
+ case PGN_61445 : handlePGN61445(frame); break; // Electronic Transmission Controller 2 - ETC2
+ case PGN_65265 : handlePGN65265(frame); break; // Cruise Control/Vehicle Speed - CCVS
+ case PGN_65267 : handlePGN65267(frame); break; // vehicle position - VP
+ case PGN_65256 : handlePGN65256(frame); break; // vehicle direction/speed
+ case PGN_65262 : handlePGN65262(frame); break; // Engine Temperature 1 - ET1
+ case PGN_65263 : handlePGN65263(frame); break; // Engine Fluid Level/Pressure 1 - EFL/P1
+ case PGN_65271 : handlePGN65271(frame); break; // Vehicle Electrical Power - VEP
+ case PGN_65276 : handlePGN65276(frame); break; // Dash Display - DD
+ case PGN_61444 : handlePGN61444(frame); break; // Electronic Engine Controller 1 - EEC1
+ case PGN_60928 : handlePGN60928(frame); break; // Address Claimed - ACL
+ default: qWarning("canFramesReceived - unknown frame id: %d", frameId);
+ }
+#ifdef DEBUG_CAN
+ QByteArray data(frame.payload());
+ const char* constData(data.constData());
+ int payLoadSize(data.size());
+ QString dataString;
+ for (int i(0); i < payLoadSize; i++) {
+ if (!dataString.isEmpty()) dataString.append(".");
+ dataString.append(QString::fromLatin1("%1").arg((int)constData[i], 2, 16, QChar('0')));
+ }
+ qDebug() << "ClusterDataBackend::canFramesReceived - id:" << frameId << "- data:" << dataString.toLatin1().constData();
+#endif // DEBUG_CAN
+ }
+}
+
+void ClusterDataBackend::canStateChanged(QCanBusDevice::CanBusDeviceState state)
+{
+#ifdef DEBUG_CAN
+ qDebug() << "ClusterDataBackend::canStateChanged - state:" << state;
+#else
+ Q_UNUSED(state)
+#endif // DEBUG_CAN
+}
+#endif
diff --git a/CenterConsole/plugins/clusterdatasource/clusterdatabackend.h b/CenterConsole/plugins/clusterdatasource/clusterdatabackend.h
new file mode 100644
index 0000000..944aacd
--- /dev/null
+++ b/CenterConsole/plugins/clusterdatasource/clusterdatabackend.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Pelagicore AG
+** Contact: http://www.qt.io/ or http://www.pelagicore.com/
+**
+** This file is part of the QtIVI module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3-PELAGICORE$
+** Commercial License Usage
+** Licensees holding valid commercial Qt IVI 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 Pelagicore. For licensing terms
+** and conditions, contact us at http://www.pelagicore.com.
+**
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+#ifndef CLUSTERDATABACKEND_H
+#define CLUSTERDATABACKEND_H
+
+#include <QObject>
+#include <QMap>
+#include <QVariant>
+
+#ifndef CLUSTERDATA_SIMULATION
+#include <QCanBusDevice>
+#include <QCanBusFrame>
+#else
+#include <QTcpServer>
+#include <QTcpSocket>
+class QTimer;
+#endif
+
+class ClusterDataBackend : public QObject
+{
+ Q_OBJECT
+
+public:
+ ClusterDataBackend(QObject* parent=0);
+ ~ClusterDataBackend();
+
+public:
+ QStringList availableZones() const;
+ QMap<QString, QVariantMap> zoneMap() const;
+ void initializeAttributes();
+
+signals:
+ void vehicleSpeedChanged(double vehicleSpeed, const QString &zone = QString());
+ void latitudeChanged(double latitude, const QString &zone = QString());
+ void longitudeChanged(double longitude, const QString &zone = QString());
+ void directionChanged(double direction, const QString &zone = QString());
+ void flatTireChanged(bool flatTire, const QString &zone = QString());
+ void doorOpenChanged(bool doorOpen, const QString &zone = QString());
+ void lightFailureChanged(bool lightFailure, const QString &zone = QString());
+ void reverseChanged(bool Reverse, const QString &zone = QString());
+ void leftTurnLightChanged(bool leftTurnLight, const QString &zone = QString());
+ void rightTurnLightChanged(bool rightTurnLight, const QString &zone = QString());
+ void headLightChanged(bool headLight, const QString &zone = QString());
+ void parkLightChanged(bool parkLight, const QString &zone = QString());
+ void carIdChanged(int carId, const QString &zone = QString());
+ void brakeChanged(bool brakeOn, const QString &zone = QString());
+ void engineTempChanged(int engineTemp, const QString &zone = QString());
+ void oilTempChanged(double oilTemp, const QString &zone = QString());
+ void oilPressureChanged(int oilPressure, const QString &zone = QString());
+ void batteryPotentialChanged(double batteryPotential, const QString &zone = QString());
+ void gasLevelChanged(double gasLevel, const QString &zone = QString());
+ void rpmChanged(int rpm, const QString &zone = QString());
+ void gearChanged(int gear, const QString &zone = QString());
+
+private:
+#ifndef CLUSTERDATA_SIMULATION
+ void handlePGN65268(const QCanBusFrame& frame); // Tire Condition - TIRE
+ void handlePGN64933(const QCanBusFrame& frame); // Door Control 2 - DC2
+ void handlePGN64972(const QCanBusFrame& frame); // Light Control
+ void handlePGN61445(const QCanBusFrame& frame); // Electronic Transmission Controller 2 - ETC2
+ void handlePGN65265(const QCanBusFrame& frame); // Cruise Control/Vehicle Speed - CCVS
+ void handlePGN65267(const QCanBusFrame& frame); // vehicle position - VP
+ void handlePGN65256(const QCanBusFrame& frame); // vehicle direction/speed
+ void handlePGN65262(const QCanBusFrame& frame); // Engine Temperature 1 - ET1
+ void handlePGN65263(const QCanBusFrame& frame); // Engine Fluid Level/Pressure 1 - EFL/P1
+ void handlePGN65271(const QCanBusFrame& frame); // Vehicle Electrical Power - VEP
+ void handlePGN65276(const QCanBusFrame& frame); // Dash Display - DD
+ void handlePGN61444(const QCanBusFrame& frame); // Electronic Engine Controller 1 - EEC1
+ void handlePGN60928(const QCanBusFrame& frame); // Address Claimed - ACL
+
+private slots:
+ void canError(QCanBusDevice::CanBusError error);
+ void canFramesReceived();
+ void canStateChanged(QCanBusDevice::CanBusDeviceState state);
+#else
+public slots:
+ void acceptConnection();
+private slots:
+ void updateServerProgress();
+#endif
+
+private:
+#ifndef CLUSTERDATA_SIMULATION
+ QCanBusDevice* m_canDevice;
+#else
+ QTcpServer m_tcpServer;
+ QTcpSocket *m_tcpServerConnection;
+#endif
+ double m_vehicleSpeed;
+ double m_latitude;
+ double m_longitude;
+ double m_direction;
+ bool m_flatTire;
+ QMap<QString,bool> m_doorOpen;
+ QMap<QString, QVariantMap> m_zonedFeatures;
+ bool m_lightFailure;
+ int m_gear;
+ char m_signalLights;
+ bool m_headLight;
+ bool m_parkLight;
+ int m_carId;
+ bool m_brake;
+ qint8 m_engineTemp;
+ double m_oilTemp;
+ int m_oilPressure;
+ double m_batteryPotential;
+ double m_gasLevel;
+ int m_rpm;
+
+};
+
+#endif // CLUSTERDATABACKEND_H
diff --git a/CenterConsole/plugins/clusterdatasource/clusterdatasource.pro b/CenterConsole/plugins/clusterdatasource/clusterdatasource.pro
new file mode 100644
index 0000000..513b9d8
--- /dev/null
+++ b/CenterConsole/plugins/clusterdatasource/clusterdatasource.pro
@@ -0,0 +1,31 @@
+include (../../../deployment.pri)
+TEMPLATE = lib
+TARGET = clusterdatasourceplugin
+QT += qml quick
+CONFIG += qt plugin c++11
+
+TARGET = clusterdatasourceplugin
+uri = com.qtcompany.clusterdemodata
+
+SOURCES += \
+ plugin.cpp \
+ qtiviclusterdata.cpp \
+ clusterdatabackend.cpp
+
+HEADERS += \
+ qtiviclusterdata.h \
+ clusterdatabackend.h
+
+#qtHaveModule(serialbus):!simulation_only {
+#QT += serialbus
+#} else: {
+DEFINES += CLUSTERDATA_SIMULATION
+#}
+
+OTHER_FILES = qmldir
+
+qmldir.files = qmldir
+
+qmldir.path = $$TARGET_PATH/qml/$$replace(uri, \\., /)
+target.path = $$TARGET_PATH/qml/$$replace(uri, \\., /)
+INSTALLS += target qmldir
diff --git a/CenterConsole/plugins/clusterdatasource/plugin.cpp b/CenterConsole/plugins/clusterdatasource/plugin.cpp
new file mode 100644
index 0000000..83b7fd2
--- /dev/null
+++ b/CenterConsole/plugins/clusterdatasource/plugin.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#include <QtQml/qqmlextensionplugin.h>
+#include <qqml.h>
+#include "qtiviclusterdata.h"
+
+static QObject *clusterDataSingletonFactory(QQmlEngine *engine, QJSEngine *scriptEngine)
+{
+ Q_UNUSED(scriptEngine)
+ Q_UNUSED(engine)
+
+ return new QtIVIClusterData();
+}
+
+class HoundPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
+public:
+ virtual void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("com.qtcompany.clusterdemodata"));
+ Q_UNUSED(uri);
+ qmlRegisterType<QtIVIClusterData>(uri, 1, 0, "ClusterData");
+ }
+};
+
+#include "plugin.moc"
diff --git a/CenterConsole/plugins/clusterdatasource/qmldir b/CenterConsole/plugins/clusterdatasource/qmldir
new file mode 100644
index 0000000..d53a57e
--- /dev/null
+++ b/CenterConsole/plugins/clusterdatasource/qmldir
@@ -0,0 +1,2 @@
+module com.qtcompany.clusterdemodata
+plugin clusterdatasourceplugin
diff --git a/CenterConsole/plugins/clusterdatasource/qtiviclusterdata.cpp b/CenterConsole/plugins/clusterdatasource/qtiviclusterdata.cpp
new file mode 100644
index 0000000..d3d4339
--- /dev/null
+++ b/CenterConsole/plugins/clusterdatasource/qtiviclusterdata.cpp
@@ -0,0 +1,388 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#include "qtiviclusterdata.h"
+
+QtIVIClusterData::QtIVIClusterData(QObject *parent)
+ : QObject(parent),
+ backend(new ClusterDataBackend),
+ m_vehicleSpeed(0),
+ m_latitude(0),
+ m_longitude(0),
+ m_direction(0),
+ m_flatTire(false),
+ m_doorOpen(false),
+ m_lightFailure(false),
+ m_reverse(false),
+ m_leftTurnLight(false),
+ m_rightTurnLight(false),
+ m_headLight(false),
+ m_parkLight(false),
+ m_carId(2),
+ m_brake(false),
+ m_engineTemp(60),
+ m_oilTemp(0.0),
+ m_oilPressure(0),
+ m_batteryPotential(80.0),
+ m_gasLevel(67.0),
+ m_rpm(4000),
+ m_gear(1)
+{
+ connectToServiceObject();
+}
+
+
+void QtIVIClusterData::connectToServiceObject()
+{
+ if (!backend)
+ return;
+ connect(backend, &ClusterDataBackend::vehicleSpeedChanged,
+ this, &QtIVIClusterData::onVehicleSpeedChanged);
+ connect(backend, &ClusterDataBackend::latitudeChanged,
+ this, &QtIVIClusterData::onLatitudeChanged);
+ connect(backend, &ClusterDataBackend::longitudeChanged,
+ this, &QtIVIClusterData::onLongitudeChanged);
+ connect(backend, &ClusterDataBackend::directionChanged,
+ this, &QtIVIClusterData::onDirectionChanged);
+ connect(backend, &ClusterDataBackend::flatTireChanged,
+ this, &QtIVIClusterData::onFlatTireChanged);
+ connect(backend, &ClusterDataBackend::doorOpenChanged,
+ this, &QtIVIClusterData::onDoorOpenChanged);
+ connect(backend, &ClusterDataBackend::lightFailureChanged,
+ this, &QtIVIClusterData::onLightFailureChanged);
+ connect(backend, &ClusterDataBackend::reverseChanged,
+ this, &QtIVIClusterData::onReverseChanged);
+ connect(backend, &ClusterDataBackend::leftTurnLightChanged,
+ this, &QtIVIClusterData::onLeftTurnLightChanged);
+ connect(backend, &ClusterDataBackend::rightTurnLightChanged,
+ this, &QtIVIClusterData::onRightTurnLightChanged);
+ connect(backend, &ClusterDataBackend::headLightChanged,
+ this, &QtIVIClusterData::onHeadLightChanged);
+ connect(backend, &ClusterDataBackend::carIdChanged,
+ this, &QtIVIClusterData::onCarIdChanged);
+ connect(backend, &ClusterDataBackend::brakeChanged,
+ this, &QtIVIClusterData::onBrakeChanged);
+ connect(backend, &ClusterDataBackend::engineTempChanged,
+ this, &QtIVIClusterData::onEngineTempChanged);
+ connect(backend, &ClusterDataBackend::oilTempChanged,
+ this, &QtIVIClusterData::onOilTempChanged);
+ connect(backend, &ClusterDataBackend::oilPressureChanged,
+ this, &QtIVIClusterData::onOilPressureChanged);
+ connect(backend, &ClusterDataBackend::batteryPotentialChanged,
+ this, &QtIVIClusterData::onBatteryPotentialChanged);
+ connect(backend, &ClusterDataBackend::gasLevelChanged,
+ this, &QtIVIClusterData::onGasLevelChanged);
+ connect(backend, &ClusterDataBackend::rpmChanged,
+ this, &QtIVIClusterData::onRpmChanged);
+ connect(backend, &ClusterDataBackend::gearChanged,
+ this, &QtIVIClusterData::onGearChanged);
+ connect(backend, &ClusterDataBackend::parkLightChanged,
+ this, &QtIVIClusterData::onParkLightChanged);
+ backend->initializeAttributes();
+ initializeZones();
+}
+ZonedProperties *QtIVIClusterData::zoneAt(const QString &zone) const
+{
+ foreach (ZonedProperties *f, m_zoneFeatures)
+ if (f->zone() == zone)
+ return f;
+ return 0;
+}
+void QtIVIClusterData::initializeZones()
+{
+ foreach (const QString &zone, backend->availableZones()) {
+ ZonedProperties* f = zoneAt(zone);
+ if (!f) {
+ f = new ZonedProperties;
+ f->setZone(zone);
+ }
+ if (f) {
+ m_zoneFeatures.append(f);
+ m_zoneFeatureList.append(QVariant::fromValue(f));
+ m_zoneFeatureMap.insert(f->zone(), QVariant::fromValue(f));
+ emit zonesChanged();
+ }
+ }
+}
+QVariantMap QtIVIClusterData::zoneFeatureMap() const
+{
+ return m_zoneFeatureMap;
+
+}
+double QtIVIClusterData::vehicleSpeed() const
+{
+ return m_vehicleSpeed;
+}
+double QtIVIClusterData::latitude() const
+{
+ return m_latitude;
+}
+double QtIVIClusterData::longitude() const
+{
+ return m_longitude;
+}
+double QtIVIClusterData::direction() const
+{
+ return m_direction;
+}
+bool QtIVIClusterData::flatTire() const
+{
+ return m_flatTire;
+}
+bool QtIVIClusterData::doorOpen() const
+{
+ return m_doorOpen;
+}
+bool QtIVIClusterData::lightFailure() const
+{
+ return m_lightFailure;
+}
+bool QtIVIClusterData::reverse() const
+{
+ return m_reverse;
+}
+
+bool QtIVIClusterData::leftTurnLight() const
+{
+ return m_leftTurnLight;
+}
+
+bool QtIVIClusterData::rightTurnLight() const
+{
+ return m_rightTurnLight;
+}
+
+bool QtIVIClusterData::headLight() const
+{
+ return m_headLight;
+}
+
+bool QtIVIClusterData::parkLight() const
+{
+ return m_parkLight;
+}
+
+int QtIVIClusterData::carId() const
+{
+ return m_carId;
+}
+
+bool QtIVIClusterData::brake() const
+{
+ return m_brake;
+}
+
+int QtIVIClusterData::engineTemp() const
+{
+ return m_engineTemp;
+}
+
+double QtIVIClusterData::oilTemp() const
+{
+ return m_oilTemp;
+}
+
+int QtIVIClusterData::oilPressure() const
+{
+ return m_oilPressure;
+}
+
+double QtIVIClusterData::batteryPotential() const
+{
+ return m_batteryPotential;
+}
+
+double QtIVIClusterData::gasLevel() const
+{
+ return m_gasLevel;
+}
+
+int QtIVIClusterData::rpm() const
+{
+ return m_rpm;
+}
+
+int QtIVIClusterData::gear() const
+{
+ return m_gear;
+}
+void QtIVIClusterData::classBegin()
+{
+}
+void QtIVIClusterData::componentComplete()
+{
+}
+void QtIVIClusterData::onVehicleSpeedChanged(double vehicleSpeed, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_vehicleSpeed = vehicleSpeed;
+ emit vehicleSpeedChanged(vehicleSpeed);
+}
+
+void QtIVIClusterData::onLatitudeChanged(double latitude, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_latitude = latitude;
+ emit latitudeChanged(latitude);
+}
+
+void QtIVIClusterData::onLongitudeChanged(double longitude, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_longitude = longitude;
+ emit longitudeChanged(longitude);
+}
+
+void QtIVIClusterData::onDirectionChanged(double direction, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_direction = direction;
+ emit directionChanged(direction);
+}
+
+void QtIVIClusterData::onFlatTireChanged(bool flatTire, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_flatTire = flatTire;
+ emit flatTireChanged(flatTire);
+}
+
+void QtIVIClusterData::onDoorOpenChanged(bool doorOpen, const QString &zone)
+{
+ ZonedProperties *z = zoneAt(zone);
+ if (z) {
+ z->setDoorOpen(doorOpen);
+ }
+}
+
+void QtIVIClusterData::onLightFailureChanged(bool lightFailure, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_lightFailure = lightFailure;
+ emit lightFailureChanged(lightFailure);
+}
+
+void QtIVIClusterData::onReverseChanged(bool reverse, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_reverse = reverse;
+ emit reverseChanged(reverse);
+}
+
+void QtIVIClusterData::onLeftTurnLightChanged(bool leftTurnLight, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_leftTurnLight = leftTurnLight;
+ emit leftTurnLightChanged(leftTurnLight);
+}
+
+void QtIVIClusterData::onRightTurnLightChanged(bool rightTurnLight, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_rightTurnLight = rightTurnLight;
+ emit rightTurnLightChanged(rightTurnLight);
+}
+
+void QtIVIClusterData::onHeadLightChanged(bool headLight, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_headLight = headLight;
+ emit headLightChanged(headLight);
+}
+
+void QtIVIClusterData::onParkLightChanged(bool parkLight, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_parkLight = parkLight;
+ emit parkLightChanged(parkLight);
+}
+
+void QtIVIClusterData::onCarIdChanged(int carId, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_carId = carId;
+ emit carIdChanged(carId);
+}
+
+void QtIVIClusterData::onBrakeChanged(bool brakeOn, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_brake = brakeOn;
+ emit brakeChanged(brakeOn);
+}
+
+void QtIVIClusterData::onEngineTempChanged(int engineTemp, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_engineTemp = engineTemp;
+ emit engineTempChanged(engineTemp);
+}
+
+void QtIVIClusterData::onOilTempChanged(double oilTemp, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_oilTemp = oilTemp;
+ emit oilTempChanged(oilTemp);
+}
+
+void QtIVIClusterData::onOilPressureChanged(int oilPressure, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_oilPressure = oilPressure;
+ emit oilPressureChanged(oilPressure);
+}
+
+void QtIVIClusterData::onBatteryPotentialChanged(double batteryPotential, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_batteryPotential = batteryPotential;
+ emit batteryPotentialChanged(batteryPotential);
+}
+
+void QtIVIClusterData::onGasLevelChanged(double gasLevel, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_gasLevel = gasLevel;
+ emit gasLevelChanged(gasLevel);
+}
+
+void QtIVIClusterData::onRpmChanged(int rpm, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_rpm = rpm;
+ emit rpmChanged(rpm);
+}
+
+void QtIVIClusterData::onGearChanged(int gear, const QString &zone)
+{
+ Q_UNUSED(zone);
+ m_gear = gear;
+ emit gearChanged(gear);
+}
diff --git a/CenterConsole/plugins/clusterdatasource/qtiviclusterdata.h b/CenterConsole/plugins/clusterdatasource/qtiviclusterdata.h
new file mode 100644
index 0000000..4318eef
--- /dev/null
+++ b/CenterConsole/plugins/clusterdatasource/qtiviclusterdata.h
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#ifndef CLUSTERDATA_H
+#define CLUSTERDATA_H
+
+#include <QObject>
+#include <QQmlParserStatus>
+#include <QQmlProperty>
+#include "clusterdatabackend.h"
+
+class ClusterDataBackend;
+class ZonedProperties : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool doorOpen READ doorOpen NOTIFY doorOpenChanged)
+public:
+ ZonedProperties(QObject *parent=0) : QObject(parent), m_zone(""), m_doorOpen(false) {}
+ void setZone(const QString &zone) { m_zone = zone; }
+ QString zone() { return m_zone; }
+ bool doorOpen() { return m_doorOpen; }
+ void setDoorOpen(const bool &d) { m_doorOpen = d; emit doorOpenChanged(); }
+signals:
+ void zoneChanged(const QString &zone);
+ void doorOpenChanged();
+private:
+ QString m_zone;
+ bool m_doorOpen;
+};
+class QtIVIClusterData : public QObject, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+
+ Q_PROPERTY(double vehicleSpeed READ vehicleSpeed NOTIFY vehicleSpeedChanged)
+ Q_PROPERTY(double latitude READ latitude NOTIFY latitudeChanged)
+ Q_PROPERTY(double longitude READ longitude NOTIFY longitudeChanged)
+ Q_PROPERTY(double direction READ direction NOTIFY directionChanged)
+ Q_PROPERTY(bool flatTire READ flatTire NOTIFY flatTireChanged)
+ Q_PROPERTY(bool lightFailure READ lightFailure NOTIFY lightFailureChanged)
+ Q_PROPERTY(bool reverse READ reverse NOTIFY reverseChanged)
+ Q_PROPERTY(bool leftTurnLight READ leftTurnLight NOTIFY leftTurnLightChanged)
+ Q_PROPERTY(bool rightTurnLight READ rightTurnLight NOTIFY rightTurnLightChanged)
+ Q_PROPERTY(bool headLight READ headLight NOTIFY headLightChanged)
+ Q_PROPERTY(bool parkLight READ parkLight NOTIFY parkLightChanged)
+ Q_PROPERTY(int carId READ carId NOTIFY carIdChanged)
+ Q_PROPERTY(bool brake READ brake NOTIFY brakeChanged)
+ Q_PROPERTY(int engineTemp READ engineTemp NOTIFY engineTempChanged)
+ Q_PROPERTY(double oilTemp READ oilTemp NOTIFY oilTempChanged)
+ Q_PROPERTY(int oilPressure READ oilPressure NOTIFY oilPressureChanged)
+ Q_PROPERTY(double batteryPotential READ batteryPotential NOTIFY batteryPotentialChanged)
+ Q_PROPERTY(double gasLevel READ gasLevel NOTIFY gasLevelChanged)
+ Q_PROPERTY(int rpm READ rpm NOTIFY rpmChanged)
+ Q_PROPERTY(int gear READ gear NOTIFY gearChanged)
+ Q_PROPERTY(QVariantMap zoneAt READ zoneFeatureMap NOTIFY zonesChanged)
+public:
+ explicit QtIVIClusterData(QObject *parent = 0);
+
+ double vehicleSpeed() const;
+ double latitude() const;
+ double longitude() const;
+ double direction() const;
+ bool flatTire() const;
+ bool doorOpen() const;
+ bool lightFailure() const;
+ bool reverse() const;
+ bool leftTurnLight() const;
+ bool rightTurnLight() const;
+ bool headLight() const;
+ bool parkLight() const;
+ int carId() const;
+ bool brake() const;
+ int engineTemp() const;
+ double oilTemp() const;
+ int oilPressure() const;
+ double batteryPotential() const;
+ double gasLevel() const;
+ int rpm() const;
+ int gear() const;
+Q_SIGNALS:
+ void vehicleSpeedChanged(double vehicleSpeed);
+ void latitudeChanged(double latitude);
+ void longitudeChanged(double longitude);
+ void directionChanged(double direction);
+ void flatTireChanged(bool flatTire);
+ void doorOpenChanged(bool doorOpen);
+ void lightFailureChanged(bool lightFailure);
+ void reverseChanged(bool Reverse);
+ void leftTurnLightChanged(bool leftTurnLight);
+ void rightTurnLightChanged(bool rightTurnLight);
+ void headLightChanged(bool headLight);
+ void parkLightChanged(bool parkLight);
+ void carIdChanged(int carId);
+ void brakeChanged(bool brakeOn );
+ void engineTempChanged(int engineTemp);
+ void oilTempChanged(double oilTemp);
+ void oilPressureChanged(int oilPressure);
+ void batteryPotentialChanged(double batteryPotential);
+ void gasLevelChanged(double gasLevel);
+ void rpmChanged(int rpm);
+ void gearChanged(int gear);
+ void zonesChanged();
+protected:
+ virtual void classBegin();
+ virtual void componentComplete();
+private Q_SLOTS:
+ void onVehicleSpeedChanged(double vehicleSpeed, const QString &zone);
+ void onLatitudeChanged(double latitude, const QString &zone);
+ void onLongitudeChanged(double longitude, const QString &zone);
+ void onDirectionChanged(double direction, const QString &zone);
+ void onFlatTireChanged(bool flatTire, const QString &zone);
+ void onDoorOpenChanged(bool doorOpen, const QString &zone);
+ void onLightFailureChanged(bool lightFailure, const QString &zone);
+ void onReverseChanged(bool reverse, const QString &zone);
+ void onLeftTurnLightChanged(bool leftTurnLight, const QString &zone);
+ void onRightTurnLightChanged(bool rightTurnLight, const QString &zone);
+ void onHeadLightChanged(bool headLight, const QString &zone);
+ void onParkLightChanged(bool parkLight, const QString &zone);
+ void onCarIdChanged(int carId, const QString &zone);
+ void onBrakeChanged(bool brakeOn, const QString &zone );
+ void onEngineTempChanged(int engineTemp, const QString &zone);
+ void onOilTempChanged(double oilTemp, const QString &zone);
+ void onOilPressureChanged(int oilPressure, const QString &zone);
+ void onBatteryPotentialChanged(double batteryPotential, const QString &zone);
+ void onGasLevelChanged(double gasLevel, const QString &zone);
+ void onRpmChanged(int rpm, const QString &zone);
+ void onGearChanged(int gear, const QString &zone);
+protected:
+private:
+ void connectToServiceObject();
+ QVariantMap zoneFeatureMap() const;
+ void initializeZones();
+ ZonedProperties *zoneAt(const QString &zone) const;
+private:
+ ClusterDataBackend *backend;
+ double m_vehicleSpeed;
+ double m_latitude;
+ double m_longitude;
+ double m_direction;
+ bool m_flatTire;
+ bool m_doorOpen;
+ bool m_lightFailure;
+ bool m_reverse;
+ bool m_leftTurnLight;
+ bool m_rightTurnLight;
+ bool m_headLight;
+ bool m_parkLight;
+ int m_carId;
+ bool m_brake;
+ qint8 m_engineTemp;
+ double m_oilTemp;
+ int m_oilPressure;
+ double m_batteryPotential;
+ double m_gasLevel;
+ int m_rpm;
+ int m_gear;
+ QVariantMap m_zoneFeatureMap;
+ QList<ZonedProperties*> m_zoneFeatures;
+ QVariantList m_zoneFeatureList;
+};
+
+#endif // CLUSTERDATA_H
diff --git a/CenterConsole/plugins/datasource/datasource.cpp b/CenterConsole/plugins/datasource/datasource.cpp
new file mode 100644
index 0000000..457c31d
--- /dev/null
+++ b/CenterConsole/plugins/datasource/datasource.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#include "datasource.h"
+
+DataSource::DataSource(QQuickItem *parent):
+ QQuickItem(parent)
+{
+ // By default, QQuickItem does not draw anything. If you subclass
+ // QQuickItem to create a visual item, you will need to uncomment the
+ // following line and re-implement updatePaintNode()
+
+ // setFlag(ItemHasContents, true);
+}
+
+DataSource::~DataSource()
+{
+}
+
diff --git a/CenterConsole/plugins/datasource/datasource.h b/CenterConsole/plugins/datasource/datasource.h
new file mode 100644
index 0000000..11d97b7
--- /dev/null
+++ b/CenterConsole/plugins/datasource/datasource.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#ifndef DATASOURCE_H
+#define DATASOURCE_H
+
+#include <QQuickItem>
+
+class DataSource : public QQuickItem
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(DataSource)
+
+public:
+ DataSource(QQuickItem *parent = 0);
+ ~DataSource();
+};
+
+QML_DECLARE_TYPE(DataSource)
+
+#endif // DATASOURCE_H
+
diff --git a/CenterConsole/plugins/datasource/datasource.pro b/CenterConsole/plugins/datasource/datasource.pro
new file mode 100644
index 0000000..8dd0d60
--- /dev/null
+++ b/CenterConsole/plugins/datasource/datasource.pro
@@ -0,0 +1,30 @@
+include (../../../deployment.pri)
+TEMPLATE = lib
+TARGET = qmldatasources
+QT += qml quick sql
+CONFIG += qt plugin
+
+TARGET = $$qtLibraryTarget($$TARGET)
+uri = com.pelagicore.datasource
+
+# Input
+SOURCES += \
+ sqlquerydatasource.cpp \
+ plugin.cpp \
+ sqlquerymodel.cpp \
+ sqltablemodel.cpp \
+ sqltabledatasource.cpp
+
+HEADERS += \
+ sqlquerydatasource.h \
+ plugin.h \
+ sqlquerymodel.h \
+ sqltablemodel.h \
+ sqltabledatasource.h
+
+OTHER_FILES = qmldir
+
+qmldir.files = qmldir
+qmldir.path = $$TARGET_PATH/qml/$$replace(uri, \\., /)
+target.path = $$TARGET_PATH/qml/$$replace(uri, \\., /)
+INSTALLS += target qmldir
diff --git a/CenterConsole/plugins/datasource/plugin.cpp b/CenterConsole/plugins/datasource/plugin.cpp
new file mode 100644
index 0000000..ee53f2c
--- /dev/null
+++ b/CenterConsole/plugins/datasource/plugin.cpp
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#include "plugin.h"
+
+#include <qqml.h>
+
+#include "sqlquerydatasource.h"
+#include "sqltabledatasource.h"
+
+void Plugin::registerTypes(const char *uri)
+{
+ // @uri com.pelagicore.datasource
+ qmlRegisterType<SqlQueryDataSource>(uri, 1, 0, "SqlQueryDataSource");
+ qmlRegisterType<SqlTableDataSource>(uri, 1, 0, "SqlTableDataSource");
+}
+
+
diff --git a/CenterConsole/plugins/datasource/plugin.h b/CenterConsole/plugins/datasource/plugin.h
new file mode 100644
index 0000000..0e268f1
--- /dev/null
+++ b/CenterConsole/plugins/datasource/plugin.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#ifndef PLUGIN_H
+#define PLUGIN_H
+
+#include <QQmlExtensionPlugin>
+
+class Plugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+
+public:
+ void registerTypes(const char *uri);
+};
+
+#endif // PLUGIN_H
diff --git a/CenterConsole/plugins/datasource/qmldir b/CenterConsole/plugins/datasource/qmldir
new file mode 100644
index 0000000..213a63d
--- /dev/null
+++ b/CenterConsole/plugins/datasource/qmldir
@@ -0,0 +1,3 @@
+module com.pelagicore.datasource
+plugin qmldatasources
+
diff --git a/CenterConsole/plugins/datasource/sqlquerydatasource.cpp b/CenterConsole/plugins/datasource/sqlquerydatasource.cpp
new file mode 100644
index 0000000..723a4fa
--- /dev/null
+++ b/CenterConsole/plugins/datasource/sqlquerydatasource.cpp
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#include "sqlquerydatasource.h"
+#include "sqlquerymodel.h"
+
+SqlQueryDataSource::SqlQueryDataSource(QObject *parent)
+ : QObject(parent)
+ , m_storageLocation(QDir::homePath())
+ , m_model(new SqlQueryModel(this))
+ , m_status(SqlQueryDataSource::Null)
+{
+ connect(m_model, &SqlQueryModel::rowsInserted, this, &SqlQueryDataSource::countChanged);
+ connect(m_model, &SqlQueryModel::rowsRemoved, this, &SqlQueryDataSource::countChanged);
+ connect(m_model, &SqlQueryModel::layoutChanged, this, &SqlQueryDataSource::countChanged);
+ connect(m_model, &SqlQueryModel::modelReset, this, &SqlQueryDataSource::countChanged);
+}
+
+QVariantMap SqlQueryDataSource::get(int index) const
+{
+ if (!m_model) { return QVariantMap(); }
+ return m_model->get(index);
+}
+
+QString SqlQueryDataSource::database() const
+{
+ return m_database.connectionName();
+}
+
+SqlQueryDataSource::Status SqlQueryDataSource::status() const
+{
+ return m_status;
+}
+
+
+int SqlQueryDataSource::count() const
+{
+ if (!m_model) { return 0; }
+ return m_model->rowCount();
+}
+
+QString SqlQueryDataSource::query() const
+{
+ if (!m_query.isValid()) {
+ return QString();
+ }
+ return m_query.lastQuery();
+}
+
+void SqlQueryDataSource::setQuery(QString queryString)
+{
+ qDebug() << "SqlQueryDataSource::setQuery() " << queryString;
+ if (m_queryString != queryString) {
+ m_queryString = queryString;
+ updateModel();
+ emit queryChanged(queryString);
+ }
+}
+
+void SqlQueryDataSource::setDatabase(QString databaseName)
+{
+ if (m_databaseName != databaseName) {
+ m_databaseName = databaseName;
+ updateModel();
+ emit databaseChanged(databaseName);
+ }
+}
+
+void SqlQueryDataSource::updateModel()
+{
+ if (m_databaseName.isEmpty() || m_queryString.isEmpty()) {
+ setStatus(Null);
+ return;
+ }
+ if (!m_databaseName.isEmpty()) {
+ if (QSqlDatabase::contains(m_databaseName)) {
+ m_database = QSqlDatabase::database(m_databaseName);
+ } else {
+ m_database = QSqlDatabase::addDatabase("QSQLITE", m_databaseName);
+ QString databasePath = QDir(m_storageLocation).filePath(m_databaseName + ".db");
+ m_database.setDatabaseName(databasePath);
+ qDebug() << "database path: " << databasePath;
+ }
+ if (!m_database.isOpen()) {
+ m_database.open();
+ }
+ }
+ if (m_database.isValid() && !m_queryString.isEmpty()) {
+ setStatus(Loading);
+ m_query = QSqlQuery(m_queryString, m_database);
+ m_model->setQuery(m_query);
+ m_model->updateRoleNames();
+ if (m_query.lastError().isValid()) {
+ qDebug() << "Error" << m_query.lastError().text();
+ setStatus(Error);
+ } else {
+ setStatus(Ready);
+ }
+ }
+ emit modelChanged(m_model);
+}
+
+
+QObject *SqlQueryDataSource::model() const
+{
+ return m_model;
+}
+
+
+void SqlQueryDataSource::setStatus(SqlQueryDataSource::Status arg)
+{
+ if (m_status != arg) {
+ m_status = arg;
+ emit statusChanged(arg);
+ }
+}
+
+QString SqlQueryDataSource::storageLocation() const
+{
+ return m_storageLocation;
+}
+
+void SqlQueryDataSource::setStorageLocation(QString path)
+{
+ m_storageLocation = QDir(path).absolutePath();
+}
+
diff --git a/CenterConsole/plugins/datasource/sqlquerydatasource.h b/CenterConsole/plugins/datasource/sqlquerydatasource.h
new file mode 100644
index 0000000..eaf92f1
--- /dev/null
+++ b/CenterConsole/plugins/datasource/sqlquerydatasource.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#ifndef SQLQUERYDATASOURCE_H
+#define SQLQUERYDATASOURCE_H
+
+#include <QtCore>
+#include <QtSql>
+
+class SqlQueryModel;
+
+class SqlQueryDataSource : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString query READ query WRITE setQuery NOTIFY queryChanged)
+ Q_PROPERTY(QString database READ database WRITE setDatabase NOTIFY databaseChanged)
+ Q_PROPERTY(QObject* model READ model NOTIFY modelChanged)
+ Q_PROPERTY(int count READ count NOTIFY countChanged)
+ Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+ Q_PROPERTY(QString storageLocation READ storageLocation WRITE setStorageLocation NOTIFY storageLocationChanged)
+ Q_ENUMS(Status)
+
+public:
+ enum Status { Null, Loading, Ready, Error };
+ explicit SqlQueryDataSource(QObject *parent = 0);
+
+ void setQuery(QString queryString);
+ QString query() const;
+
+ QString database() const;
+ void setDatabase(QString databaseName);
+
+ int count() const;
+ Q_INVOKABLE QVariantMap get(int index) const;
+
+ QObject* model() const;
+
+ Status status() const;
+
+ QString storageLocation() const;
+ void setStorageLocation(QString path);
+private:
+ void updateModel();
+ void setStatus(Status arg);
+
+
+signals:
+ void countChanged();
+ void queryChanged(QString query);
+
+ void databaseChanged(QString arg);
+ void statusChanged(Status arg);
+
+ void modelChanged(QObject* model);
+ void storageLocationChanged();
+
+private:
+ QString m_queryString;
+ QString m_databaseName;
+ QString m_storageLocation;
+ SqlQueryModel *m_model;
+ QSqlQuery m_query;
+ QSqlDatabase m_database;
+ Status m_status;
+};
+
+
+
+#endif // SQLQUERYMODEL_H
diff --git a/CenterConsole/plugins/datasource/sqlquerymodel.cpp b/CenterConsole/plugins/datasource/sqlquerymodel.cpp
new file mode 100644
index 0000000..2b7aeb5
--- /dev/null
+++ b/CenterConsole/plugins/datasource/sqlquerymodel.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#include "sqlquerymodel.h"
+
+SqlQueryModel::SqlQueryModel(QObject *parent) :
+ QSqlQueryModel(parent)
+{
+}
+
+void SqlQueryModel::updateRoleNames()
+{
+ m_roleNames.clear();
+ for (int i = 0; i < record().count(); i++) {
+ m_roleNames[Qt::UserRole + i + 1] = record().fieldName(i).toLatin1();
+ }
+}
+
+QHash<int, QByteArray> SqlQueryModel::roleNames() const
+{
+ return m_roleNames;
+}
+
+QVariantMap SqlQueryModel::get(int row) const
+{
+ QVariantMap map;
+ QModelIndex index = createIndex(row, 0);
+ foreach (int role, m_roleNames.keys()) {
+ map.insert(m_roleNames.value(role), data(index, role));
+ }
+ return map;
+}
+
+QVariant SqlQueryModel::data(const QModelIndex &index, int role) const
+{
+ QVariant value = QSqlQueryModel::data(index, role);
+ if (role < Qt::UserRole) {
+ value = QSqlQueryModel::data(index, role);
+ } else {
+ int columnIdx = role - Qt::UserRole - 1;
+ QModelIndex modelIndex = this->index(index.row(), columnIdx);
+ value = QSqlQueryModel::data(modelIndex, Qt::DisplayRole);
+ }
+ return value;
+}
+
+
+
diff --git a/CenterConsole/plugins/datasource/sqlquerymodel.h b/CenterConsole/plugins/datasource/sqlquerymodel.h
new file mode 100644
index 0000000..fde340f
--- /dev/null
+++ b/CenterConsole/plugins/datasource/sqlquerymodel.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#ifndef SQLQUERYMODEL_H
+#define SQLQUERYMODEL_H
+
+#include <QtSql/QSqlQueryModel>
+#include <QtSql/QSqlRecord>
+
+class SqlQueryModel : public QSqlQueryModel
+{
+ Q_OBJECT
+public:
+ explicit SqlQueryModel(QObject *parent = 0);
+ void updateRoleNames();
+ QHash<int, QByteArray> roleNames() const;
+ QVariantMap get(int row) const;
+ QVariant data(const QModelIndex &item, int role) const;
+private:
+ QHash<int, QByteArray> m_roleNames;
+};
+
+#endif // SQLQUERYMODEL_H
diff --git a/CenterConsole/plugins/datasource/sqltabledatasource.cpp b/CenterConsole/plugins/datasource/sqltabledatasource.cpp
new file mode 100644
index 0000000..9beebcb
--- /dev/null
+++ b/CenterConsole/plugins/datasource/sqltabledatasource.cpp
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#include "sqltabledatasource.h"
+#include "sqltablemodel.h"
+
+#include <QtCore/QtDebug>
+#include <QtCore/QStandardPaths>
+#include <QtCore/QDir>
+#include <QtSql/QSqlError>
+
+
+SqlTableDataSource::SqlTableDataSource(QObject *parent)
+ : QObject(parent)
+ , m_model(0)
+ , m_status(Null)
+ , m_componentCompleted(false)
+{
+}
+
+QString SqlTableDataSource::table() const
+{
+ return m_tableName;
+}
+
+QString SqlTableDataSource::database() const
+{
+ return m_databaseName;
+}
+
+QAbstractItemModel *SqlTableDataSource::model() const
+{
+ return m_model;
+}
+
+int SqlTableDataSource::count() const
+{
+ if (!m_model) { return 0; }
+ return m_model->rowCount();
+}
+
+SqlTableDataSource::Status SqlTableDataSource::status() const
+{
+ return m_status;
+}
+
+void SqlTableDataSource::setStatus(SqlTableDataSource::Status status)
+{
+ if (m_status != status) {
+ m_status = status;
+ emit statusChanged(status);
+ }
+}
+
+QString SqlTableDataSource::filter() const
+{
+ return m_model->filter();
+}
+
+QVariantMap SqlTableDataSource::get(int index) const
+{
+ if (!m_model) { return QVariantMap(); }
+ return m_model->get(index);
+}
+
+void SqlTableDataSource::classBegin()
+{
+}
+
+void SqlTableDataSource::componentComplete()
+{
+ qDebug() << "componentComplete";
+ m_componentCompleted = true;
+ updateModel();
+}
+
+QString SqlTableDataSource::storageLocation() const
+{
+ return QDir::homePath();
+}
+
+void SqlTableDataSource::setFilter(QString filter)
+{
+ qDebug() << "SqlTableDataSource::setFilter(): " << filter;
+ if (m_model->filter() != filter) {
+ m_model->setFilter(filter);
+ m_model->select();
+ emit filterChanged(filter);
+ }
+}
+
+void SqlTableDataSource::setTable(QString tableName)
+{
+ if (m_tableName != tableName) {
+ m_tableName = tableName;
+ updateModel();
+ emit tableChanged(tableName);
+ }
+}
+
+void SqlTableDataSource::setDatabase(QString databaseName)
+{
+ if (m_databaseName != databaseName) {
+ m_databaseName = databaseName;
+ updateModel();
+ emit databaseChanged(databaseName);
+ }
+}
+
+
+void SqlTableDataSource::updateModel()
+{
+ if (!m_componentCompleted) { return; }
+ qDebug() << "SqlTableDataSource::updateModel()";
+ if (m_databaseName.isEmpty() || m_tableName.isEmpty()) {
+ setStatus(Null);
+ qDebug() << " not configure; return";
+ return;
+ }
+ if (!m_databaseName.isEmpty()) {
+ if (QSqlDatabase::contains(m_databaseName)) {
+ qDebug() << " found existing db connection";
+ m_database = QSqlDatabase::database(m_databaseName);
+ } else {
+ qDebug() << " init new db connection";
+ m_database = QSqlDatabase::addDatabase("QSQLITE", m_databaseName);
+ QString databasePath = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(m_databaseName + ".db");
+ m_database.setDatabaseName(databasePath);
+ qDebug() << "database path: " << databasePath;
+ }
+ if (!m_database.isOpen()) {
+ qDebug() << " open database";
+ m_database.open();
+ qDebug() << " tables: " << m_database.tables();
+ }
+ }
+ if (m_database.isValid() && !m_tableName.isEmpty()) {
+ if (!m_model || m_model->tableName() != m_tableName) {
+ if (m_model) {
+ delete m_model;
+ m_model = 0;
+ emit modelChanged(m_model);
+ }
+ m_model = new SqlTableModel(this, m_database);
+ emit modelChanged(m_model);
+ }
+ qDebug() << " update table";
+ setStatus(Loading);
+ m_model->setTable(m_tableName);
+ qDebug() << " update role names";
+ m_model->updateRoleNames();
+ qDebug() << " select data";
+ if (!m_model->select()) {
+ qDebug() << " error: select data from model";
+ }
+ while (m_model->canFetchMore()) {
+ m_model->fetchMore(QModelIndex());
+ }
+ qDebug() << " finish select data";
+ if (m_model->lastError().isValid()) {
+ qDebug() << " error: " << m_model->lastError().text();
+ setStatus(Error);
+ } else {
+ qDebug() << " ready";
+ setStatus(Ready);
+ }
+ }
+ qDebug() << "update model: " << count();
+ emit modelChanged(m_model);
+ emit countChanged(count());
+}
+
diff --git a/CenterConsole/plugins/datasource/sqltabledatasource.h b/CenterConsole/plugins/datasource/sqltabledatasource.h
new file mode 100644
index 0000000..cbb94a3
--- /dev/null
+++ b/CenterConsole/plugins/datasource/sqltabledatasource.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#ifndef SQLTABLEDATASOURCE_H
+#define SQLTABLEDATASOURCE_H
+
+#include <QtCore/QAbstractItemModel>
+#include <QtSql/QSqlDatabase>
+#include <QtQml/QQmlParserStatus>
+
+class SqlTableModel;
+
+class SqlTableDataSource : public QObject, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+ Q_PROPERTY(QString database READ database WRITE setDatabase NOTIFY databaseChanged)
+ Q_PROPERTY(QString table READ table WRITE setTable NOTIFY tableChanged)
+ Q_PROPERTY(QString filter READ filter WRITE setFilter NOTIFY filterChanged)
+ Q_PROPERTY(QObject* model READ model NOTIFY modelChanged)
+ Q_PROPERTY(int count READ count NOTIFY countChanged)
+ Q_PROPERTY(QString storageLocation READ storageLocation CONSTANT)
+ Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+ Q_ENUMS(Status)
+
+public:
+ enum Status { Null, Loading, Ready, Error };
+ explicit SqlTableDataSource(QObject *parent = 0);
+
+ QString table() const;
+ void setTable(QString tableName);
+
+ QString database() const;
+ void setDatabase(QString databaseName);
+
+ QAbstractItemModel* model() const;
+ int count() const;
+ Status status() const;
+ void setStatus(Status status);
+ QString filter() const;
+
+ Q_INVOKABLE QVariantMap get(int index) const;
+ // parser status
+ void classBegin();
+ void componentComplete();
+
+ QString storageLocation() const;
+
+public slots:
+ void setFilter(QString filter);
+
+signals:
+ void tableChanged(QString table);
+ void databaseChanged(QString database);
+ void countChanged(int count);
+ void statusChanged(Status status);
+ void modelChanged(QObject* model);
+ void filterChanged(QString arg);
+
+private:
+ void updateModel();
+private:
+ QString m_tableName;
+ QString m_databaseName;
+ QSqlDatabase m_database;
+ SqlTableModel* m_model;
+ Status m_status;
+ QString m_filter;
+ bool m_componentCompleted;
+};
+
+#endif // SQLTABLEDATASOURCE_H
diff --git a/CenterConsole/plugins/datasource/sqltablemodel.cpp b/CenterConsole/plugins/datasource/sqltablemodel.cpp
new file mode 100644
index 0000000..7b3179e
--- /dev/null
+++ b/CenterConsole/plugins/datasource/sqltablemodel.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#include "sqltablemodel.h"
+
+#include <QtCore/QtDebug>
+#include <QtSql/QSqlRecord>
+
+SqlTableModel::SqlTableModel(QObject *parent, QSqlDatabase db) :
+ QSqlTableModel(parent, db)
+{
+ connect(this, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), this, SLOT(notifyCount()));
+ connect(this, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(notifyCount()));
+
+}
+
+void SqlTableModel::updateRoleNames()
+{
+ qDebug() << "SqlTableModel::updateRoleNames()";
+ m_roleNames.clear();
+ for (int i = 0; i < record().count(); i++) {
+ m_roleNames[Qt::UserRole + i + 1] = record().fieldName(i).toLatin1();
+ }
+ qDebug() << " role names: " << m_roleNames.values();
+}
+
+
+QHash<int, QByteArray> SqlTableModel::roleNames() const
+{
+ return m_roleNames;
+}
+
+
+QVariantMap SqlTableModel::get(int row) const
+{
+ QVariantMap map;
+ QModelIndex index = createIndex(row, 0);
+ foreach (int role, m_roleNames.keys()) {
+ map.insert(m_roleNames.value(role), data(index, role));
+ }
+ return map;
+}
+
+QVariant SqlTableModel::data(const QModelIndex &index, int role) const
+{
+ QVariant value = QSqlTableModel::data(index, role);
+ if (role < Qt::UserRole) {
+ value = QSqlTableModel::data(index, role);
+ } else {
+ int columnIdx = role - Qt::UserRole - 1;
+ QModelIndex modelIndex = this->index(index.row(), columnIdx);
+ value = QSqlTableModel::data(modelIndex, Qt::DisplayRole);
+ }
+ return value;
+}
+
+int SqlTableModel::count() const
+{
+ return rowCount();
+}
+
+void SqlTableModel::notifyCount()
+{
+ emit countChanged(rowCount());
+}
+
diff --git a/CenterConsole/plugins/datasource/sqltablemodel.h b/CenterConsole/plugins/datasource/sqltablemodel.h
new file mode 100644
index 0000000..736a30d
--- /dev/null
+++ b/CenterConsole/plugins/datasource/sqltablemodel.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#ifndef SQLTABLEMODEL_H
+#define SQLTABLEMODEL_H
+
+#include <QtSql/QSqlTableModel>
+
+class SqlTableModel : public QSqlTableModel
+{
+ Q_OBJECT
+ Q_PROPERTY(int count READ count NOTIFY countChanged)
+public:
+ explicit SqlTableModel(QObject *parent = 0, QSqlDatabase db = QSqlDatabase());
+
+ void updateRoleNames();
+ QHash<int, QByteArray> roleNames() const;
+ Q_INVOKABLE QVariantMap get(int row) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ int count() const;
+private slots:
+ void notifyCount();
+signals:
+ void countChanged(int count);
+
+private:
+ QHash<int, QByteArray> m_roleNames;
+};
+
+#endif // SQLTABLEMODEL_H
diff --git a/CenterConsole/plugins/plugins.pro b/CenterConsole/plugins/plugins.pro
new file mode 100644
index 0000000..f7a91e6
--- /dev/null
+++ b/CenterConsole/plugins/plugins.pro
@@ -0,0 +1,6 @@
+TEMPLATE = subdirs
+
+SUBDIRS = \
+ clusterdatasource \
+ datasource \
+ screenManager
diff --git a/CenterConsole/plugins/screenManager/plugin.cpp b/CenterConsole/plugins/screenManager/plugin.cpp
new file mode 100644
index 0000000..f4639a2
--- /dev/null
+++ b/CenterConsole/plugins/screenManager/plugin.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#include <QtQml/qqmlextensionplugin.h>
+#include <qqml.h>
+#include "screenmanager.h"
+
+static QObject *screenManagerSingletonFactory(QQmlEngine *engine, QJSEngine *scriptEngine)
+{
+ Q_UNUSED(scriptEngine)
+ Q_UNUSED(engine)
+
+ return new ScreenManager();
+}
+
+class HoundPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
+public:
+ virtual void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("com.pelagicore.ScreenManager"));
+ Q_UNUSED(uri);
+
+ qmlRegisterSingletonType<ScreenManager>(uri, 1, 0, "ScreenManager", screenManagerSingletonFactory);
+ }
+};
+
+#include "plugin.moc"
diff --git a/CenterConsole/plugins/screenManager/qmldir b/CenterConsole/plugins/screenManager/qmldir
new file mode 100644
index 0000000..5472c91
--- /dev/null
+++ b/CenterConsole/plugins/screenManager/qmldir
@@ -0,0 +1,2 @@
+module com.pelagicore.ScreenManager
+plugin screenmanagerplugin
diff --git a/CenterConsole/plugins/screenManager/screenManager.pro b/CenterConsole/plugins/screenManager/screenManager.pro
new file mode 100644
index 0000000..44a0a0c
--- /dev/null
+++ b/CenterConsole/plugins/screenManager/screenManager.pro
@@ -0,0 +1,23 @@
+include (../../../deployment.pri)
+TEMPLATE = lib
+TARGET = screenmanagerplugin
+QT += qml quick
+CONFIG += qt plugin c++11
+
+TARGET = $$qtLibraryTarget($$TARGET)
+uri = com.pelagicore.ScreenManager
+
+SOURCES += \
+ plugin.cpp \
+ screenmanager.cpp \
+
+HEADERS += \
+ screenmanager.h \
+
+OTHER_FILES = qmldir
+
+qmldir.files = qmldir
+
+qmldir.path = $$TARGET_PATH/qml/$$replace(uri, \\., /)
+target.path = $$TARGET_PATH/qml/$$replace(uri, \\., /)
+INSTALLS += target qmldir
diff --git a/CenterConsole/plugins/screenManager/screenmanager.cpp b/CenterConsole/plugins/screenManager/screenmanager.cpp
new file mode 100644
index 0000000..06bc4dc
--- /dev/null
+++ b/CenterConsole/plugins/screenManager/screenmanager.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#include "screenmanager.h"
+#include <QGuiApplication>
+#include <QScreen>
+#include <QDebug>
+
+ScreenManager::ScreenManager(QObject *parent)
+ : QObject(parent)
+{
+ connect(qApp, &QGuiApplication::screenAdded, this, &ScreenManager::availableScreensChanged);
+ connect(qApp, &QGuiApplication::screenAdded, this, &ScreenManager::availableScreensChanged);
+}
+
+void ScreenManager::setScreen(QWindow *window, int screen)
+{
+ if (screen >= 0 && screen < QGuiApplication::screens().count()) {
+ window->setScreen(QGuiApplication::screens().at(screen));
+ } else {
+ qWarning() << "invalid Screen";
+ }
+}
+
+QList<QScreen *> ScreenManager::availableScreens() const
+{
+ return QGuiApplication::screens();
+}
+
+int ScreenManager::screenCount() const
+{
+ return QGuiApplication::screens().count();
+}
+
diff --git a/CenterConsole/plugins/screenManager/screenmanager.h b/CenterConsole/plugins/screenManager/screenmanager.h
new file mode 100644
index 0000000..b12f860
--- /dev/null
+++ b/CenterConsole/plugins/screenManager/screenmanager.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+#ifndef SCREENMANAGER_H
+#define SCREENMANAGER_H
+
+#include <QtCore/QObject>
+#include <QWindow>
+
+class ScreenManager : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QList<QScreen*> availableScreens READ availableScreens NOTIFY availableScreensChanged)
+
+public:
+ explicit ScreenManager(QObject *parent = 0);
+
+ Q_INVOKABLE int screenCount() const;
+ Q_INVOKABLE void setScreen(QWindow * window, int screen);
+ QList<QScreen*> availableScreens() const;
+
+signals:
+ void availableScreensChanged();
+};
+
+#endif // SCREENMANAGER_H
diff --git a/CenterConsole/plugins/scripts/README.md b/CenterConsole/plugins/scripts/README.md
new file mode 100644
index 0000000..94f1060
--- /dev/null
+++ b/CenterConsole/plugins/scripts/README.md
@@ -0,0 +1,9 @@
+# Scripts usage
+
+Scan scripts are used for for creating the SQL lite database and filling it with the music and movies. The data is later read with datasource project and in the end used from the QML.
+
+# Requirements
+
+Scan scripts require the mutagen Python package.
+
+https://bitbucket.org/lazka/mutagen
diff --git a/CenterConsole/plugins/scripts/scanmovies.py b/CenterConsole/plugins/scripts/scanmovies.py
new file mode 100644
index 0000000..b4786fe
--- /dev/null
+++ b/CenterConsole/plugins/scripts/scanmovies.py
@@ -0,0 +1,123 @@
+# -*- coding: utf-8 -*-
+
+"""
+/****************************************************************************
+**
+** Copyright (C) 2016 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+"""
+
+# scanmovies.py
+# scans the ~/media/movies folder and generates all covers
+# and a ~/media.db database with alll tracks.
+
+import os
+import sqlite3 as db
+import argparse
+from mutagen.mp4 import MP4
+
+
+parser = argparse.ArgumentParser(description='scan movie folder')
+
+parser.add_argument('--source', default='~/media/movies', help='movie dir to scan')
+
+args = parser.parse_args()
+
+source = os.path.expanduser(args.source)
+
+albums = set()
+
+connection = db.connect(os.path.expanduser('~/media.db'))
+
+cursor = connection.cursor()
+
+
+sql_drop = 'drop table if exists movies'
+
+sql_create = """
+create table movies (
+ pk integer primary key,
+ title text,
+ year integer,
+ genre text,
+ desc text,
+ source text,
+ cover text
+ )
+"""
+
+sql_insert = """
+insert into movies (title,year,genre,desc,source,cover) VALUES (?,?,?,?,?,?)
+"""
+
+def createTable():
+ print('create table')
+ cursor.execute(sql_drop)
+ cursor.execute(sql_create)
+
+
+def extractTag(media, tag):
+ obj = media.get(tag)
+ if obj:
+ return ''.join(obj)#.encode('utf-8')
+ return ''
+
+def scanFolder(source):
+ print('scan folder: ' + source)
+ start = os.path.abspath(source)
+ for root, dirnames, filenames in os.walk(start):
+ for filename in filenames:
+ if not filename[-3:] == 'm4v':
+ continue
+ filepath = os.path.join(root, filename)
+ folderpath = os.path.relpath(root, start)
+ name = filename[0:-4]
+ print('analyze: ' + filepath)
+ try:
+ movie = MP4(filepath)
+ except:
+ print 'error reading: ', filepath
+ continue
+ title = extractTag(movie, '\xa9nam')
+ year = extractTag(movie, '\xa9day')
+ genre = extractTag(movie, '\xa9gen')
+ coverData = movie['covr'][0]
+ cover = os.path.join(folderpath, 'cover.jpg')
+ desc = extractTag(movie, 'desc')
+ source = os.path.join(folderpath, filename)
+ coverArt = file(os.path.join(start, cover), 'w')
+ coverArt.write(coverData)
+ coverArt.close()
+ cursor.execute(sql_insert, (title, year, genre, desc, source, cover))
+
+
+createTable()
+scanFolder(source)
+
+connection.commit()
diff --git a/CenterConsole/plugins/scripts/scanmusic.py b/CenterConsole/plugins/scripts/scanmusic.py
new file mode 100644
index 0000000..439935b
--- /dev/null
+++ b/CenterConsole/plugins/scripts/scanmusic.py
@@ -0,0 +1,149 @@
+# -*- coding: utf-8 -*-
+
+"""
+/****************************************************************************
+**
+** Copyright (C) 2016 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+"""
+
+# scanmusic.py
+# scans the ~/media/music folder and generates all covers
+# and a ~/media.db database with alll tracks.
+
+import os
+import sqlite3 as db
+import argparse
+from mutagen.id3 import ID3, ID3NoHeaderError
+
+
+parser = argparse.ArgumentParser(description='scan music folder')
+
+parser.add_argument('--source', default='~/media/music', help='music dir to scan')
+
+args = parser.parse_args()
+
+source = os.path.expanduser(args.source)
+
+albums = set()
+
+connection = db.connect(os.path.expanduser('~/media.db'))
+
+cursor = connection.cursor()
+
+
+sql_drop = 'drop table if exists music'
+
+sql_create = """
+create table music (
+ pk integer primary key,
+ album text,
+ title text,
+ track text,
+ artist text,
+ source text,
+ cover text
+ )
+"""
+
+sql_insert = """
+insert into music (album,title,track,artist,source,cover) VALUES (?,?,?,?,?,?)
+"""
+
+def createTable():
+ print('create table')
+ cursor.execute(sql_drop)
+ cursor.execute(sql_create)
+
+
+def extractTag(media, tag):
+ obj = media.get(tag)
+ if obj:
+ return ''.join(obj.text)#.encode('utf-8')
+ return ''
+
+def scanFolder(source):
+ print('scan folder: ' + source)
+ start = os.path.abspath(source)
+ for root, dirnames, filenames in os.walk(start):
+ for filename in filenames:
+ if not filename[-4:] == '.mp3':
+ continue
+ filepath = os.path.join(root, filename)
+ name = filename[0:-4]
+ folderpath = os.path.relpath(root, start)
+ print('analyze: ' + filepath)
+ try:
+ audio = ID3(filepath)
+ except ID3NoHeaderError:
+ print 'error reading: ', filepath
+ continue
+
+
+ # import pdb; pdb.set_trace()
+ title = extractTag(audio, 'TIT2')
+ album = extractTag(audio, 'TALB')
+ artist = extractTag(audio, 'TPE1')
+ track = extractTag(audio, 'TRCK')
+ source = os.path.join(folderpath, filename).decode('utf-8')
+
+ apics = audio.getall('APIC')[:1]
+ apic = None
+ if len(apics):
+ apic = apics[0]
+ coverName = ''
+ if apic:
+ if apic.mime == 'image/jpeg':
+ coverName = 'cover.jpg'
+ elif apic.mime == 'image/png':
+ coverName = 'cover.png'
+ else:
+ print('unknown cover mime type: ' + mime)
+ else:
+ import pdb; pdb.set_trace()
+ print('!!! NO COVER')
+
+ cover = os.path.join(folderpath, coverName).decode('utf-8')
+ album_id = '%s/%s'%(album, artist)
+ if not album_id in albums:
+ albums.add(album_id)
+ if apic: # save new cover
+ art = file(os.path.join(root, coverName), 'w')
+ art.write(apic.data)
+ art.close()
+ cursor.execute(sql_insert, (album, title, track, artist, source, cover))
+
+
+createTable()
+scanFolder(source)
+
+connection.commit()
+
+
+