diff --git a/evcharger-app/i18n/qml_de.ts b/evcharger-app/i18n/qml_de.ts index 6d93e1f..005b85d 100644 --- a/evcharger-app/i18n/qml_de.ts +++ b/evcharger-app/i18n/qml_de.ts @@ -4,25 +4,35 @@ AboutPage - + About Über - + Firmware Firmware - + Hardware information Hardwareinformationen - + Licenses Lizenzen + + + Enable demo mode + + + + + Set charging color to new + + AccessPage @@ -307,91 +317,6 @@ IP Adresse: - - ChargerConnection - - - - Unknown - Unbekannt - - - - Ok - - - - - Offline - - - - - - Idle - - - - - Updating - - - - - Failed - - - - - Succeeded - - - - - NotReady - - - - - Verifying - - - - - %0 %1% - - - - - %0 %1/? - - - - - %0 ?/%1 - - - - - Charging - - - - - WaitCar - - - - - Complete - - - - - Error - - - ChargerTabPage @@ -573,99 +498,6 @@ Daily trip - - ChargersModel - - - Serial - - - - - WS Status - - - - - Status - - - - - Variant - - - - - IsGo - - - - - IsAustralien - - - - - ResetCard - - - - - ConnectedWifi - - - - - Project - - - - - Version - - - - - IDF Version - - - - - Update - - - - - Reboots - - - - - Uptime - - - - - Current Partition - - - - - Car state - - - - - Energy - - - - - Livedata - - - ChargingConfigurationPage @@ -960,6 +792,10 @@ DeviceConnection + + Unknown + Unbekannt + Connecting to %0 @@ -1333,8 +1169,183 @@ Verbindung schwer gestört + + DevicesConnection + + + + Unknown + Unbekannt + + + + Ok + + + + + Offline + + + + + + Idle + + + + + Updating + + + + + Failed + + + + + Succeeded + + + + + NotReady + + + + + Verifying + + + + + %0 %1% + + + + + %0 %1/? + + + + + %0 ?/%1 + + + + + Charging + + + + + WaitCar + + + + + Complete + + + + + Error + + + DevicesModel + + + Serial + + + + + WS Status + + + + + Status + + + + + Variant + + + + + IsGo + + + + + IsAustralien + + + + + ResetCard + + + + + ConnectedWifi + + + + + Project + + + + + Version + + + + + IDF Version + + + + + Update + + + + + Reboots + + + + + Uptime + + + + + Current Partition + + + + + Car state + + + + + Energy + + + + + Livedata + + @@ -1762,22 +1773,22 @@ - + HEADERS_RECEIVED - + LOADING - + Request started... - + Download informations Informationen herunterladen @@ -1889,115 +1900,140 @@ - + + Add range + + + + Serial - - Not yet implemented! - - - - + %0 selected - + Add new column... - + Remove column %0 - + Enter api key - + Api key: - + Set update url... - + Start update... - + Reboot... - + Set chargectrl override... - + Set abitrary api key... - + Reset nvs key... - + Open app(s)... - + + Remove... + + + + Enter update url... - + Update url: - + Select update release... - + Update release - + Are you sure? Sind Sie sicher? - + Do you really want to reboot selected devices? - + Please input nvs key to be reset - + Nvs key + + + Confirm deletion of devices + + + + + Do you really want to remove %0 devices? + + + + + Error while removing! + + + + + %0 rows could not be removed! + + MqttPage diff --git a/flotten-updater/CMakeLists.txt b/flotten-updater/CMakeLists.txt index a15daf9..dc9077d 100644 --- a/flotten-updater/CMakeLists.txt +++ b/flotten-updater/CMakeLists.txt @@ -3,10 +3,10 @@ find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Quick WebSockets LinguistT qt_standard_project_setup(REQUIRES 6.6 I18N_TRANSLATED_LANGUAGES de) qt_add_executable(flotten-updater WIN32 MACOSX_BUNDLE - chargerconnection.cpp - chargerconnection.h - chargersmodel.cpp - chargersmodel.h + deviceconnection.cpp + deviceconnection.h + devicesmodel.cpp + devicesmodel.h flottenupdatersettings.cpp flottenupdatersettings.h importcertificatedialog.cpp diff --git a/flotten-updater/chargerconnection.cpp b/flotten-updater/deviceconnection.cpp similarity index 72% rename from flotten-updater/chargerconnection.cpp rename to flotten-updater/deviceconnection.cpp index 6140dc4..1fd90e9 100644 --- a/flotten-updater/chargerconnection.cpp +++ b/flotten-updater/deviceconnection.cpp @@ -1,4 +1,4 @@ -#include "chargerconnection.h" +#include "deviceconnection.h" #include #include @@ -13,7 +13,7 @@ #include -#include "chargersmodel.h" +#include "devicesmodel.h" namespace { const constexpr QColor red{255, 150, 150}; @@ -24,7 +24,7 @@ const constexpr QColor blue{150, 150, 255}; const constexpr QColor magenta{255, 150, 255}; } -ChargerConnection::ChargerConnection(const QSslKey &key, const QSslCertificate &cert, QString &&serial, QObject *parent) : +DevicesConnection::DevicesConnection(const QSslKey &key, const QSslCertificate &cert, QString &&serial, QObject *parent) : QObject{parent}, m_serial(std::move(serial)), m_key{key}, @@ -33,7 +33,7 @@ ChargerConnection::ChargerConnection(const QSslKey &key, const QSslCertificate & init(); } -ChargerConnection::ChargerConnection(const QSslKey &key, const QSslCertificate &cert, const QString &serial, QObject *parent) : +DevicesConnection::DevicesConnection(const QSslKey &key, const QSslCertificate &cert, const QString &serial, QObject *parent) : QObject{parent}, m_serial(serial), m_key{key}, @@ -42,24 +42,24 @@ ChargerConnection::ChargerConnection(const QSslKey &key, const QSslCertificate & init(); } -void ChargerConnection::start() +void DevicesConnection::start() { const QUrl url{QString("wss://solalaweb.com/%0").arg(m_serial)}; qDebug() << url; m_websocket.open(url); } -void ChargerConnection::stop() +void DevicesConnection::stop() { m_websocket.close(); } -QString ChargerConnection::wsStatusText() const +QString DevicesConnection::wsStatusText() const { return QMetaEnum::fromType().valueToKey(m_websocket.state()); } -QBrush ChargerConnection::wsStatusBackground() const +QBrush DevicesConnection::wsStatusBackground() const { switch (m_websocket.state()) { @@ -72,7 +72,7 @@ QBrush ChargerConnection::wsStatusBackground() const return {}; } -QString ChargerConnection::statusText() const +QString DevicesConnection::statusText() const { switch (m_status) { @@ -84,7 +84,7 @@ QString ChargerConnection::statusText() const return QString::number(std::to_underlying(m_status)); } -QBrush ChargerConnection::statusBackground() const +QBrush DevicesConnection::statusBackground() const { switch (m_status) { @@ -95,7 +95,7 @@ QBrush ChargerConnection::statusBackground() const return {}; } -QString ChargerConnection::variantText() const +QString DevicesConnection::variantText() const { if (!m_fullStatus.contains("var")) return {}; @@ -103,7 +103,7 @@ QString ChargerConnection::variantText() const return m_fullStatus.value("var").toString(); } -QBrush ChargerConnection::variantBackground() const +QBrush DevicesConnection::variantBackground() const { if (!m_fullStatus.contains("var")) return {}; @@ -116,7 +116,7 @@ QBrush ChargerConnection::variantBackground() const return red; } -QString ChargerConnection::isGoText() const +QString DevicesConnection::isGoText() const { if (!m_fullStatus.contains("isgo")) return {}; @@ -124,7 +124,7 @@ QString ChargerConnection::isGoText() const return m_fullStatus.value("isgo").toBool() ? "yes" : "no"; } -QBrush ChargerConnection::isGoBackground() const +QBrush DevicesConnection::isGoBackground() const { if (!m_fullStatus.contains("isgo")) return {}; @@ -132,7 +132,7 @@ QBrush ChargerConnection::isGoBackground() const return m_fullStatus.value("isgo").toBool() ? blue : yellow; } -QString ChargerConnection::isAustralienText() const +QString DevicesConnection::isAustralienText() const { if (!m_fullStatus.contains("aus")) return {}; @@ -140,7 +140,7 @@ QString ChargerConnection::isAustralienText() const return m_fullStatus.value("aus").toBool() ? "yes" : "no"; } -QBrush ChargerConnection::isAustralienBackground() const +QBrush DevicesConnection::isAustralienBackground() const { if (!m_fullStatus.contains("aus")) return {}; @@ -148,7 +148,7 @@ QBrush ChargerConnection::isAustralienBackground() const return m_fullStatus.value("aus").toBool() ? yellow : blue; } -QString ChargerConnection::resetCardText() const +QString DevicesConnection::resetCardText() const { if (!m_fullStatus.contains("frci")) return {}; @@ -156,7 +156,7 @@ QString ChargerConnection::resetCardText() const return m_fullStatus.value("frci").toBool() ? "yes" : "no"; } -QBrush ChargerConnection::resetCardBackground() const +QBrush DevicesConnection::resetCardBackground() const { if (!m_fullStatus.contains("frci")) return {}; @@ -164,7 +164,7 @@ QBrush ChargerConnection::resetCardBackground() const return m_fullStatus.value("frci").toBool() ? green : red; } -QString ChargerConnection::connectedWifiText() const +QString DevicesConnection::connectedWifiText() const { if (!m_fullStatus.contains("ccw")) return {}; @@ -176,7 +176,7 @@ QString ChargerConnection::connectedWifiText() const return apd.value("ssid").toString(); } -QString ChargerConnection::projectText() const +QString DevicesConnection::projectText() const { if (!m_fullStatus.contains("apd")) return {}; @@ -188,7 +188,7 @@ QString ChargerConnection::projectText() const return apd.value("project_name").toString(); } -QString ChargerConnection::versionText() const +QString DevicesConnection::versionText() const { if (!m_fullStatus.contains("apd")) return {}; @@ -200,7 +200,7 @@ QString ChargerConnection::versionText() const return apd.value("version").toString(); } -QString ChargerConnection::idfVersionText() const +QString DevicesConnection::idfVersionText() const { if (!m_fullStatus.contains("apd")) return {}; @@ -212,7 +212,7 @@ QString ChargerConnection::idfVersionText() const return apd.value("idf_ver").toString(); } -QString ChargerConnection::updateText() const +QString DevicesConnection::updateText() const { if (!m_fullStatus.contains("ocs")) return {}; @@ -241,7 +241,7 @@ QString ChargerConnection::updateText() const return QString::number(ocs); } -QBrush ChargerConnection::updateBackground() const +QBrush DevicesConnection::updateBackground() const { if (!m_fullStatus.contains("ocs")) return {}; @@ -259,7 +259,7 @@ QBrush ChargerConnection::updateBackground() const return {}; } -std::optional ChargerConnection::uptime() const +std::optional DevicesConnection::uptime() const { if (!m_fullStatus.contains("rbt")) return {}; @@ -267,7 +267,7 @@ std::optional ChargerConnection::uptime() const return m_fullStatus.value("rbt").toULongLong(); } -QString ChargerConnection::uptimeText() const +QString DevicesConnection::uptimeText() const { if (!m_fullStatus.contains("rbt")) return {}; @@ -275,7 +275,7 @@ QString ChargerConnection::uptimeText() const return QString::number(m_fullStatus.value("rbt").toULongLong()); } -QString ChargerConnection::currentPartition() const +QString DevicesConnection::currentPartition() const { if (!m_fullStatus.contains("otap")) return {}; @@ -287,7 +287,7 @@ QString ChargerConnection::currentPartition() const return otap.value("label").toString(); } -std::optional ChargerConnection::reboots() const +std::optional DevicesConnection::reboots() const { if (!m_fullStatus.contains("rbc")) return {}; @@ -295,7 +295,7 @@ std::optional ChargerConnection::reboots() const return m_fullStatus.value("rbc").toInt(); } -QString ChargerConnection::rebootsText() const +QString DevicesConnection::rebootsText() const { if (!m_fullStatus.contains("rbc")) return {}; @@ -303,7 +303,7 @@ QString ChargerConnection::rebootsText() const return QString::number(m_fullStatus.value("rbc").toInt()); } -QString ChargerConnection::carStateText() const +QString DevicesConnection::carStateText() const { if (!m_fullStatus.contains("car")) return {}; @@ -315,7 +315,7 @@ QString ChargerConnection::carStateText() const return QString::number(car); } -std::optional ChargerConnection::energy() const +std::optional DevicesConnection::energy() const { if (!m_fullStatus.contains("eto")) return {}; @@ -323,7 +323,7 @@ std::optional ChargerConnection::energy() const return m_fullStatus.value("eto").toDouble(); } -QString ChargerConnection::energyText() const +QString DevicesConnection::energyText() const { if (!m_fullStatus.contains("eto")) return {}; @@ -331,7 +331,7 @@ QString ChargerConnection::energyText() const return QString("%0kWh").arg(m_fullStatus.value("eto").toDouble() / 1000.); } -QString ChargerConnection::livedataText() const +QString DevicesConnection::livedataText() const { if (!m_fullStatus.contains("nrg")) return {}; @@ -346,50 +346,50 @@ QString ChargerConnection::livedataText() const return {}; } -QVariant ChargerConnection::getApiKey(const QString &apiKey) const +QVariant DevicesConnection::getApiKey(const QString &apiKey) const { return m_fullStatus.value(apiKey); } -void ChargerConnection::sendMessage(const QJsonDocument &doc) +void DevicesConnection::sendMessage(const QJsonDocument &doc) { sendMessage(QString::fromUtf8(doc.toJson())); } -void ChargerConnection::sendMessage(const QJsonObject &obj) +void DevicesConnection::sendMessage(const QJsonObject &obj) { sendMessage(QJsonDocument{obj}); } -void ChargerConnection::sendMessage(const QString &msg) +void DevicesConnection::sendMessage(const QString &msg) { qDebug() << msg << m_websocket.errorString(); if (const auto written = m_websocket.sendTextMessage(msg); written != msg.size()) qCritical() << "sending message failed" << written << "(expected:" << msg.size() << ')'; } -void ChargerConnection::init() +void DevicesConnection::init() { - if (auto model = qobject_cast(parent())) + if (auto model = qobject_cast(parent())) { - connect(this, &ChargerConnection::wsStatusChanged, model, &ChargersModel::wsStatusChanged); - connect(this, &ChargerConnection::statusChanged, model, &ChargersModel::statusChanged); - connect(this, &ChargerConnection::variantChanged, model, &ChargersModel::variantChanged); - connect(this, &ChargerConnection::isGoChanged, model, &ChargersModel::isGoChanged); - connect(this, &ChargerConnection::isAustralienChanged, model, &ChargersModel::isAustralienChanged); - connect(this, &ChargerConnection::resetCardChanged, model, &ChargersModel::resetCardChanged); - connect(this, &ChargerConnection::connectedWifiChanged, model, &ChargersModel::connectedWifiChanged); - connect(this, &ChargerConnection::projectChanged, model, &ChargersModel::projectChanged); - connect(this, &ChargerConnection::versionChanged, model, &ChargersModel::versionChanged); - connect(this, &ChargerConnection::idfVersionChanged, model, &ChargersModel::idfVersionChanged); - connect(this, &ChargerConnection::updateChanged, model, &ChargersModel::updateChanged); - connect(this, &ChargerConnection::uptimeChanged, model, &ChargersModel::uptimeChanged); - connect(this, &ChargerConnection::currentPartitionChanged, model, &ChargersModel::currentPartitionChanged); - connect(this, &ChargerConnection::rebootsChanged, model, &ChargersModel::rebootsChanged); - connect(this, &ChargerConnection::carStateChanged, model, &ChargersModel::carStateChanged); - connect(this, &ChargerConnection::energyChanged, model, &ChargersModel::energyChanged); - connect(this, &ChargerConnection::livedataChanged, model, &ChargersModel::livedataChanged); - connect(this, &ChargerConnection::apiKeyChanged, model, &ChargersModel::apiKeyChanged); + connect(this, &DevicesConnection::wsStatusChanged, model, &DevicesModel::wsStatusChanged); + connect(this, &DevicesConnection::statusChanged, model, &DevicesModel::statusChanged); + connect(this, &DevicesConnection::variantChanged, model, &DevicesModel::variantChanged); + connect(this, &DevicesConnection::isGoChanged, model, &DevicesModel::isGoChanged); + connect(this, &DevicesConnection::isAustralienChanged, model, &DevicesModel::isAustralienChanged); + connect(this, &DevicesConnection::resetCardChanged, model, &DevicesModel::resetCardChanged); + connect(this, &DevicesConnection::connectedWifiChanged, model, &DevicesModel::connectedWifiChanged); + connect(this, &DevicesConnection::projectChanged, model, &DevicesModel::projectChanged); + connect(this, &DevicesConnection::versionChanged, model, &DevicesModel::versionChanged); + connect(this, &DevicesConnection::idfVersionChanged, model, &DevicesModel::idfVersionChanged); + connect(this, &DevicesConnection::updateChanged, model, &DevicesModel::updateChanged); + connect(this, &DevicesConnection::uptimeChanged, model, &DevicesModel::uptimeChanged); + connect(this, &DevicesConnection::currentPartitionChanged, model, &DevicesModel::currentPartitionChanged); + connect(this, &DevicesConnection::rebootsChanged, model, &DevicesModel::rebootsChanged); + connect(this, &DevicesConnection::carStateChanged, model, &DevicesModel::carStateChanged); + connect(this, &DevicesConnection::energyChanged, model, &DevicesModel::energyChanged); + connect(this, &DevicesConnection::livedataChanged, model, &DevicesModel::livedataChanged); + connect(this, &DevicesConnection::apiKeyChanged, model, &DevicesModel::apiKeyChanged); } else qWarning() << "unexpected parent"; @@ -412,19 +412,19 @@ void ChargerConnection::init() m_websocket.ignoreSslErrors(); } - connect(&m_websocket, &QWebSocket::connected, this, &ChargerConnection::connected); - connect(&m_websocket, &QWebSocket::disconnected, this, &ChargerConnection::disconnected); - connect(&m_websocket, &QWebSocket::stateChanged, this, &ChargerConnection::stateChanged); - connect(&m_websocket, &QWebSocket::textMessageReceived, this, &ChargerConnection::textMessageReceived); - connect(&m_websocket, &QWebSocket::binaryMessageReceived, this, &ChargerConnection::binaryMessageReceived); - connect(&m_websocket, &QWebSocket::errorOccurred, this, &ChargerConnection::errorOccurred); - connect(&m_websocket, &QWebSocket::peerVerifyError, this, &ChargerConnection::peerVerifyError); - connect(&m_websocket, &QWebSocket::sslErrors, this, &ChargerConnection::sslErrors); - connect(&m_websocket, &QWebSocket::alertReceived, this, &ChargerConnection::alertReceived); - connect(&m_websocket, &QWebSocket::handshakeInterruptedOnError, this, &ChargerConnection::handshakeInterruptedOnError); + connect(&m_websocket, &QWebSocket::connected, this, &DevicesConnection::connected); + connect(&m_websocket, &QWebSocket::disconnected, this, &DevicesConnection::disconnected); + connect(&m_websocket, &QWebSocket::stateChanged, this, &DevicesConnection::stateChanged); + connect(&m_websocket, &QWebSocket::textMessageReceived, this, &DevicesConnection::textMessageReceived); + connect(&m_websocket, &QWebSocket::binaryMessageReceived, this, &DevicesConnection::binaryMessageReceived); + connect(&m_websocket, &QWebSocket::errorOccurred, this, &DevicesConnection::errorOccurred); + connect(&m_websocket, &QWebSocket::peerVerifyError, this, &DevicesConnection::peerVerifyError); + connect(&m_websocket, &QWebSocket::sslErrors, this, &DevicesConnection::sslErrors); + connect(&m_websocket, &QWebSocket::alertReceived, this, &DevicesConnection::alertReceived); + connect(&m_websocket, &QWebSocket::handshakeInterruptedOnError, this, &DevicesConnection::handshakeInterruptedOnError); } -void ChargerConnection::maintainStatus(const QJsonObject &msg, bool forceChange) +void DevicesConnection::maintainStatus(const QJsonObject &msg, bool forceChange) { bool variantChanged{forceChange}; bool isGoChanged{forceChange}; @@ -507,17 +507,17 @@ void ChargerConnection::maintainStatus(const QJsonObject &msg, bool forceChange) emit this->livedataChanged(); } -void ChargerConnection::connected() +void DevicesConnection::connected() { qDebug() << "called"; } -void ChargerConnection::disconnected() +void DevicesConnection::disconnected() { qDebug() << "called"; } -void ChargerConnection::stateChanged(QAbstractSocket::SocketState state) +void DevicesConnection::stateChanged(QAbstractSocket::SocketState state) { // qDebug() << "called" << state; @@ -533,7 +533,7 @@ void ChargerConnection::stateChanged(QAbstractSocket::SocketState state) emit wsStatusChanged(); } -void ChargerConnection::textMessageReceived(const QString &message) +void DevicesConnection::textMessageReceived(const QString &message) { // qDebug() << "called" << message; @@ -614,32 +614,32 @@ void ChargerConnection::textMessageReceived(const QString &message) qWarning() << "unknown message type" << msgObj; } -void ChargerConnection::binaryMessageReceived(const QByteArray &message) +void DevicesConnection::binaryMessageReceived(const QByteArray &message) { qDebug() << "called" << message; } -void ChargerConnection::errorOccurred(QAbstractSocket::SocketError error) +void DevicesConnection::errorOccurred(QAbstractSocket::SocketError error) { qDebug() << "called" << QMetaEnum::fromType().valueToKey(error) << m_websocket.errorString(); } -void ChargerConnection::peerVerifyError(const QSslError &error) +void DevicesConnection::peerVerifyError(const QSslError &error) { qDebug() << "called" << error; } -void ChargerConnection::sslErrors(const QList &errors) +void DevicesConnection::sslErrors(const QList &errors) { qDebug() << "called" << errors; } -void ChargerConnection::alertReceived(QSsl::AlertLevel level, QSsl::AlertType type, const QString &description) +void DevicesConnection::alertReceived(QSsl::AlertLevel level, QSsl::AlertType type, const QString &description) { qDebug() << "called" << std::to_underlying(level) << std::to_underlying(type) << description; } -void ChargerConnection::handshakeInterruptedOnError(const QSslError &error) +void DevicesConnection::handshakeInterruptedOnError(const QSslError &error) { qDebug() << "called" << error; } diff --git a/flotten-updater/chargerconnection.h b/flotten-updater/deviceconnection.h similarity index 94% rename from flotten-updater/chargerconnection.h rename to flotten-updater/deviceconnection.h index 78de5a0..c10f653 100644 --- a/flotten-updater/chargerconnection.h +++ b/flotten-updater/deviceconnection.h @@ -9,13 +9,13 @@ class QSslKey; class QSslCertificate; class QJsonObject; -class ChargerConnection : public QObject +class DevicesConnection : public QObject { Q_OBJECT public: - explicit ChargerConnection(const QSslKey &key, const QSslCertificate &cert, QString &&serial, QObject *parent = nullptr); - explicit ChargerConnection(const QSslKey &key, const QSslCertificate &cert, const QString &serial, QObject *parent = nullptr); + explicit DevicesConnection(const QSslKey &key, const QSslCertificate &cert, QString &&serial, QObject *parent = nullptr); + explicit DevicesConnection(const QSslKey &key, const QSslCertificate &cert, const QString &serial, QObject *parent = nullptr); void start(); void stop(); diff --git a/flotten-updater/chargersmodel.cpp b/flotten-updater/devicesmodel.cpp similarity index 69% rename from flotten-updater/chargersmodel.cpp rename to flotten-updater/devicesmodel.cpp index 10c6fc4..fb94c5f 100644 --- a/flotten-updater/chargersmodel.cpp +++ b/flotten-updater/devicesmodel.cpp @@ -1,4 +1,4 @@ -#include "chargersmodel.h" +#include "devicesmodel.h" #include #include @@ -6,7 +6,7 @@ #include -#include "chargerconnection.h" +#include "deviceconnection.h" #include "flottenupdatersettings.h" namespace { @@ -33,7 +33,7 @@ enum { }; } -ChargersModel::ChargersModel(FlottenUpdaterSettings &settings, const QSslKey &key, +DevicesModel::DevicesModel(FlottenUpdaterSettings &settings, const QSslKey &key, const QSslCertificate &cert, QObject *parent) : QAbstractTableModel{parent}, m_settings{settings}, @@ -54,38 +54,43 @@ ChargersModel::ChargersModel(FlottenUpdaterSettings &settings, const QSslKey &ke "000043", "000044", "000047", "000050", "900001", "900103", "900104", "900105", "900107", "900108", "900113", "900117", "900118", "900123", "900126", "900127", "91028339", "91028457", "91028482", "91028368", "91028336", "91028374", "91028371", "91028452", "91028481", "91028455", "91028334", "91028456", "91028351", "91028367", "91028346", "91028459", "91028366", "91028335", "91028483", "91028372", "91028337", "91028338", "91008954", "91008978", "91008282", "91009008", "91008953", "91009000", "91009024", "91048840", "91048873", "91045590", "91045593", "91045586", "91048874", "91048879", "91048882", "91048878", "91048860", "91048865", "91048853", "91048864", "91048867", "91021261", "91021260", "91021379", "91021135", "91021266", "91021259", "91021374", "91021381", "91021258", "91021275", "91021380", "91021382", "91021377", "91021240", "91021371", "91021376", "91021255", "91021378", "91021383", "91021354", "91021195", "91021370", "91021278", "91021234", "91021256", "91021257", "91021360", "91021248", "91021363", "91021270", "91021267", "91021239", "91021193", "91021268", "91028339", "91028457", "91028482", "91028368", "91036167", "91028374", "91028371", "91028452", "91028481", "91028455", "91028334", "91028456", "91028351", "91028367", "91028346", "91028459", "91028366", "91028335", "91028483", "91028372", "91028337", "91028338", - "91100000", "91100001", "91100002", "91100003", "91100004", "91100005", "91100006", "91100007", "91100008", "91100009", "91100010", "91100011", "91100012", "91100013", "91100014", "91100015", "91100016", "91100017", "91100018", "91100019", "91100020", "91100021", "91100022", "91100023", "91100024", "91100025", "91100026", "91100027", "91100028", "91100029", "91100030", "91100031" + "91100000", "91100001", "91100002", "91100003", "91100004", "91100005", "91100006", "91100007", "91100008", "91100009", "91100010", "91100011", "91100012", "91100013", "91100014", "91100015", "91100016", "91100017", "91100018", "91100019", "91100020", "91100021", "91100022", "91100023", "91100024", "91100025", "91100026", "91100027", "91100028", "91100029", "91100030", "91100031", + "402557", + "402558", + "402564", + "402567", + "402577", }; for (const auto &serial : serials) { - if (std::none_of(std::cbegin(m_chargers), std::cend(m_chargers), [&serial](auto &ptr){ + if (std::none_of(std::cbegin(m_devices), std::cend(m_devices), [&serial](auto &ptr){ return ptr->serial() == serial; })) - m_chargers.emplace_back(std::make_shared(m_key, m_cert, serial, this)); + m_devices.emplace_back(std::make_shared(m_key, m_cert, serial, this)); } } -ChargersModel::~ChargersModel() = default; +DevicesModel::~DevicesModel() = default; -int ChargersModel::rowCount(const QModelIndex &parent) const +int DevicesModel::rowCount(const QModelIndex &parent) const { - return m_chargers.size(); + return m_devices.size(); } -int ChargersModel::columnCount(const QModelIndex &parent) const +int DevicesModel::columnCount(const QModelIndex &parent) const { return NumberOfColumns + m_customColumns.size(); } -QVariant ChargersModel::data(const QModelIndex &index, int role) const +QVariant DevicesModel::data(const QModelIndex &index, int role) const { - if (index.row() < 0 || index.row() >= m_chargers.size()) + if (index.row() < 0 || index.row() >= m_devices.size()) { qWarning() << "row out of bounds"; return {}; } - const ChargerConnection &charger = **std::next(std::begin(m_chargers), index.row()); + const DevicesConnection &device = **std::next(std::begin(m_devices), index.row()); switch (index.column()) { @@ -94,7 +99,7 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: case Qt::EditRole: - return charger.serial(); + return device.serial(); } return {}; case ColumnWsStatus: @@ -102,9 +107,9 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: case Qt::EditRole: - return charger.wsStatusText(); + return device.wsStatusText(); case Qt::BackgroundRole: - return charger.wsStatusBackground(); + return device.wsStatusBackground(); } return {}; case ColumnStatus: @@ -112,9 +117,9 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: case Qt::EditRole: - return charger.statusText(); + return device.statusText(); case Qt::BackgroundRole: - return charger.statusBackground(); + return device.statusBackground(); } return {}; case ColumnVariant: @@ -122,9 +127,9 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: case Qt::EditRole: - return charger.variantText(); + return device.variantText(); case Qt::BackgroundRole: - return charger.variantBackground(); + return device.variantBackground(); } return {}; case ColumnIsGo: @@ -132,9 +137,9 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: case Qt::EditRole: - return charger.isGoText(); + return device.isGoText(); case Qt::BackgroundRole: - return charger.isGoBackground(); + return device.isGoBackground(); } return {}; case ColumnIsAustralien: @@ -142,9 +147,9 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: case Qt::EditRole: - return charger.isAustralienText(); + return device.isAustralienText(); case Qt::BackgroundRole: - return charger.isAustralienBackground(); + return device.isAustralienBackground(); } return {}; case ColumnResetCard: @@ -152,9 +157,9 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: case Qt::EditRole: - return charger.resetCardText(); + return device.resetCardText(); case Qt::BackgroundRole: - return charger.resetCardBackground(); + return device.resetCardBackground(); } return {}; case ColumnConnectedWifi: @@ -162,7 +167,7 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: case Qt::EditRole: - return charger.connectedWifiText(); + return device.connectedWifiText(); } return {}; case ColumnProject: @@ -170,7 +175,7 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: case Qt::EditRole: - return charger.projectText(); + return device.projectText(); } return {}; case ColumnVersion: @@ -178,7 +183,7 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: case Qt::EditRole: - return charger.versionText(); + return device.versionText(); } return {}; case ColumnIdfVersion: @@ -186,7 +191,7 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: case Qt::EditRole: - return charger.idfVersionText(); + return device.idfVersionText(); } return {}; case ColumnUpdate: @@ -194,18 +199,18 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: case Qt::EditRole: - return charger.updateText(); + return device.updateText(); case Qt::BackgroundRole: - return charger.updateBackground(); + return device.updateBackground(); } return {}; case ColumnUptime: switch (role) { case Qt::DisplayRole: - return charger.uptimeText(); + return device.uptimeText(); case Qt::EditRole: - if (const auto uptime = charger.uptime(); uptime) + if (const auto uptime = device.uptime(); uptime) return *uptime; } return {}; @@ -214,16 +219,16 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: case Qt::EditRole: - return charger.currentPartition(); + return device.currentPartition(); } return {}; case ColumnReboots: switch (role) { case Qt::DisplayRole: - return charger.rebootsText(); + return device.rebootsText(); case Qt::EditRole: - if (const auto reboots = charger.reboots(); reboots) + if (const auto reboots = device.reboots(); reboots) return *reboots; } return {}; @@ -232,16 +237,16 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: case Qt::EditRole: - return charger.carStateText(); + return device.carStateText(); } return {}; case ColumnEnergy: switch (role) { case Qt::DisplayRole: - return charger.energyText(); + return device.energyText(); case Qt::EditRole: - if (const auto energy = charger.energy(); energy) + if (const auto energy = device.energy(); energy) return *energy; } return {}; @@ -250,7 +255,7 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: case Qt::EditRole: - return charger.livedataText(); + return device.livedataText(); } return {}; } @@ -260,20 +265,20 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: { - auto variant = charger.getApiKey(m_customColumns.at(index.column() - NumberOfColumns)); + auto variant = device.getApiKey(m_customColumns.at(index.column() - NumberOfColumns)); auto str = variant.toString(); if (str.isEmpty()) str = QJsonDocument::fromVariant(variant).toJson(QJsonDocument::Compact); return str; } case Qt::EditRole: - return charger.getApiKey(m_customColumns.at(index.column() - NumberOfColumns)); + return device.getApiKey(m_customColumns.at(index.column() - NumberOfColumns)); } return {}; } -QVariant ChargersModel::headerData(int section, Qt::Orientation orientation, int role) const +QVariant DevicesModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole && role != Qt::EditRole) return {}; @@ -312,35 +317,58 @@ QVariant ChargersModel::headerData(int section, Qt::Orientation orientation, int return {}; } -void ChargersModel::addClient(const QString &serial) +bool DevicesModel::removeRows(int row, int count, const QModelIndex &parent) { - beginInsertRows({}, m_chargers.size(), m_chargers.size()); + if (row < 0 || std::size_t(row) >= m_devices.size()) + { + qWarning() << "unexpected row" << row; + return false; + } - auto clientPtr = std::make_shared(m_key, m_cert, serial, this); + if (count < 0 || std::size_t(count) > m_devices.size() - row) + { + qWarning() << "unexpected row+count" << count << row; + return false; + } + + beginRemoveRows({}, row, row + count - 1); + auto begin = std::next(std::begin(m_devices), row); + auto end = std::next(begin, count); + m_devices.erase(begin, end); + endRemoveRows(); + + return true; +} + +void DevicesModel::addClient(const QString &serial) +{ + beginInsertRows({}, m_devices.size(), m_devices.size()); + + auto clientPtr = std::make_shared(m_key, m_cert, serial, this); auto client = clientPtr.get(); - m_chargers.emplace_back(std::move(clientPtr)); + m_devices.emplace_back(std::move(clientPtr)); endInsertRows(); client->start(); } -std::shared_ptr ChargersModel::getCharger(QModelIndex index) +std::shared_ptr DevicesModel::getDevice(QModelIndex index) { Q_ASSERT(!index.parent().isValid()); - Q_ASSERT(index.row() >= 0 && index.row() < m_chargers.size()); - auto charger = m_chargers.at(index.row()); - Q_ASSERT(charger); - return charger; + Q_ASSERT(index.row() >= 0 && index.row() < m_devices.size()); + auto device = m_devices.at(index.row()); + Q_ASSERT(device); + return device; } -std::shared_ptr ChargersModel::getCharger(QModelIndex index) const +std::shared_ptr DevicesModel::getDevice(QModelIndex index) const { Q_ASSERT(!index.parent().isValid()); - return m_chargers.at(index.row()); + return m_devices.at(index.row()); } -void ChargersModel::addCustomColumn(const QString &apiKey) +void DevicesModel::addCustomColumn(const QString &apiKey) { beginInsertColumns({}, NumberOfColumns + m_customColumns.size(), NumberOfColumns + m_customColumns.size()); m_customColumns.push_back(apiKey); @@ -348,12 +376,12 @@ void ChargersModel::addCustomColumn(const QString &apiKey) m_settings.setCustomColumns(m_customColumns); } -bool ChargersModel::customColumnRemovable(int section) +bool DevicesModel::customColumnRemovable(int section) { return section >= NumberOfColumns && section - NumberOfColumns < m_customColumns.size(); } -void ChargersModel::removeCustomColumn(int section) +void DevicesModel::removeCustomColumn(int section) { if (section < NumberOfColumns || section - NumberOfColumns >= m_customColumns.size()) return; @@ -364,129 +392,129 @@ void ChargersModel::removeCustomColumn(int section) m_settings.setCustomColumns(m_customColumns); } -void ChargersModel::connectAll() +void DevicesModel::connectAll() { - for (auto &charger : m_chargers) - charger->start(); + for (auto &device : m_devices) + device->start(); } -void ChargersModel::disconnectAll() +void DevicesModel::disconnectAll() { - for (auto &charger : m_chargers) - charger->stop(); + for (auto &device : m_devices) + device->stop(); } -void ChargersModel::wsStatusChanged() +void DevicesModel::wsStatusChanged() { columnChanged(ColumnWsStatus, {Qt::DisplayRole, Qt::EditRole, Qt::BackgroundRole}); } -void ChargersModel::statusChanged() +void DevicesModel::statusChanged() { columnChanged(ColumnStatus, {Qt::DisplayRole, Qt::EditRole, Qt::BackgroundRole}); } -void ChargersModel::variantChanged() +void DevicesModel::variantChanged() { columnChanged(ColumnVariant, {Qt::DisplayRole, Qt::EditRole, Qt::BackgroundRole}); } -void ChargersModel::isGoChanged() +void DevicesModel::isGoChanged() { columnChanged(ColumnIsGo, {Qt::DisplayRole, Qt::EditRole, Qt::BackgroundRole}); } -void ChargersModel::isAustralienChanged() +void DevicesModel::isAustralienChanged() { columnChanged(ColumnIsAustralien, {Qt::DisplayRole, Qt::EditRole, Qt::BackgroundRole}); } -void ChargersModel::resetCardChanged() +void DevicesModel::resetCardChanged() { columnChanged(ColumnResetCard, {Qt::DisplayRole, Qt::EditRole, Qt::BackgroundRole}); } -void ChargersModel::connectedWifiChanged() +void DevicesModel::connectedWifiChanged() { columnChanged(ColumnConnectedWifi, {Qt::DisplayRole, Qt::EditRole}); } -void ChargersModel::projectChanged() +void DevicesModel::projectChanged() { columnChanged(ColumnProject, {Qt::DisplayRole, Qt::EditRole}); } -void ChargersModel::versionChanged() +void DevicesModel::versionChanged() { columnChanged(ColumnVersion, {Qt::DisplayRole, Qt::EditRole}); } -void ChargersModel::idfVersionChanged() +void DevicesModel::idfVersionChanged() { columnChanged(ColumnIdfVersion, {Qt::DisplayRole, Qt::EditRole}); } -void ChargersModel::updateChanged() +void DevicesModel::updateChanged() { columnChanged(ColumnUpdate, {Qt::DisplayRole, Qt::EditRole, Qt::BackgroundRole}); } -void ChargersModel::uptimeChanged() +void DevicesModel::uptimeChanged() { columnChanged(ColumnUptime, {Qt::DisplayRole, Qt::EditRole}); } -void ChargersModel::currentPartitionChanged() +void DevicesModel::currentPartitionChanged() { columnChanged(ColumnCurrentPartition, {Qt::DisplayRole, Qt::EditRole}); } -void ChargersModel::rebootsChanged() +void DevicesModel::rebootsChanged() { columnChanged(ColumnReboots, {Qt::DisplayRole, Qt::EditRole}); } -void ChargersModel::carStateChanged() +void DevicesModel::carStateChanged() { columnChanged(ColumnCarState, {Qt::DisplayRole, Qt::EditRole}); } -void ChargersModel::energyChanged() +void DevicesModel::energyChanged() { columnChanged(ColumnEnergy, {Qt::DisplayRole, Qt::EditRole}); } -void ChargersModel::livedataChanged() +void DevicesModel::livedataChanged() { columnChanged(ColumnLivedata, {Qt::DisplayRole, Qt::EditRole}); } -void ChargersModel::apiKeyChanged(const QString &apiKey) +void DevicesModel::apiKeyChanged(const QString &apiKey) { for (auto iter = std::cbegin(m_customColumns); iter != std::cend(m_customColumns); iter++) if (*iter == apiKey) columnChanged(NumberOfColumns + std::distance(std::cbegin(m_customColumns), iter), {Qt::DisplayRole, Qt::EditRole}); } -void ChargersModel::columnChanged(int column, const QList &roles) +void DevicesModel::columnChanged(int column, const QList &roles) { - auto charger = qobject_cast(sender()); - if (!charger) + auto device = qobject_cast(sender()); + if (!device) { qWarning() << "unknown sender" << sender(); return; } - auto iter = std::find_if(std::cbegin(m_chargers), std::cend(m_chargers), [&charger](const std::shared_ptr &ptr){ return charger == ptr.get(); }); - if (iter == std::cend(m_chargers)) + auto iter = std::find_if(std::cbegin(m_devices), std::cend(m_devices), [&device](const std::shared_ptr &ptr){ return device == ptr.get(); }); + if (iter == std::cend(m_devices)) { - qWarning() << "unknown sender" << charger; - for (const auto &charger : m_chargers) - qDebug() << charger.get(); + qWarning() << "unknown sender" << device; + for (const auto &device : m_devices) + qDebug() << device.get(); return; } - auto row = std::distance(std::cbegin(m_chargers), iter); + auto row = std::distance(std::cbegin(m_devices), iter); auto index = createIndex(row, column); emit dataChanged(index, index, roles); diff --git a/flotten-updater/chargersmodel.h b/flotten-updater/devicesmodel.h similarity index 75% rename from flotten-updater/chargersmodel.h rename to flotten-updater/devicesmodel.h index 30b447b..bac8ab8 100644 --- a/flotten-updater/chargersmodel.h +++ b/flotten-updater/devicesmodel.h @@ -9,26 +9,29 @@ class QSslKey; class QSslCertificate; class FlottenUpdaterSettings; -class ChargerConnection; +class DevicesConnection; -class ChargersModel : public QAbstractTableModel +class DevicesModel : public QAbstractTableModel { Q_OBJECT + using base = QAbstractTableModel; + public: - explicit ChargersModel(FlottenUpdaterSettings &settings, const QSslKey &key, + explicit DevicesModel(FlottenUpdaterSettings &settings, const QSslKey &key, const QSslCertificate &cert, QObject *parent = nullptr); - ~ChargersModel() override; + ~DevicesModel() override; int rowCount(const QModelIndex &parent) const override; int columnCount(const QModelIndex &parent) const override; QVariant data(const QModelIndex &index, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + bool removeRows(int row, int count, const QModelIndex &parent) override; void addClient(const QString &serial); - std::shared_ptr getCharger(QModelIndex index); - std::shared_ptr getCharger(QModelIndex index) const; + std::shared_ptr getDevice(QModelIndex index); + std::shared_ptr getDevice(QModelIndex index) const; void addCustomColumn(const QString &apiKey); bool customColumnRemovable(int section); @@ -63,7 +66,7 @@ private: const QSslCertificate &m_cert; void columnChanged(int column, const QList &roles = QList()); - std::vector> m_chargers; + std::vector> m_devices; QStringList m_customColumns; }; diff --git a/flotten-updater/mainwindow.cpp b/flotten-updater/mainwindow.cpp index 1df1ade..2525e87 100644 --- a/flotten-updater/mainwindow.cpp +++ b/flotten-updater/mainwindow.cpp @@ -10,9 +10,10 @@ #include #include +#include #include "flottenupdatersettings.h" -#include "chargersmodel.h" +#include "devicesmodel.h" #include "requestdialog.h" #include "setarbitraryapikeydialog.h" @@ -21,7 +22,7 @@ MainWindow::MainWindow(FlottenUpdaterSettings &settings, const QSslKey &key, QMainWindow{parent}, m_ui{std::make_unique()}, m_settings{settings}, - m_model{std::make_unique(settings, key, cert, this)}, + m_model{std::make_unique(settings, key, cert, this)}, m_proxyModel{std::make_unique(this)} { m_ui->setupUi(this); @@ -30,14 +31,15 @@ MainWindow::MainWindow(FlottenUpdaterSettings &settings, const QSslKey &key, m_proxyModel->setSortRole(Qt::EditRole); m_ui->treeView->setModel(m_proxyModel.get()); - connect(m_ui->pushButtonConnectAll, &QAbstractButton::pressed, m_model.get(), &ChargersModel::connectAll); - connect(m_ui->pushButtonDisconnectAll, &QAbstractButton::pressed, m_model.get(), &ChargersModel::disconnectAll); + connect(m_ui->pushButtonConnectAll, &QAbstractButton::pressed, m_model.get(), &DevicesModel::connectAll); + connect(m_ui->pushButtonDisconnectAll, &QAbstractButton::pressed, m_model.get(), &DevicesModel::disconnectAll); connect(m_ui->pushButtonAdd, &QAbstractButton::pressed, this, &MainWindow::doAdd); connect(m_ui->pushButtonRemove, &QAbstractButton::pressed, this, &MainWindow::doRemove); connect(m_ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &MainWindow::selectionChanged); m_ui->treeView->header()->setContextMenuPolicy(Qt::CustomContextMenu); connect(m_ui->treeView->header(), &QTreeView::customContextMenuRequested, this, &MainWindow::headerContextMenuRequested); connect(m_ui->treeView, &QTreeView::customContextMenuRequested, this, &MainWindow::contextMenuRequested); + selectionChanged(); } MainWindow::~MainWindow() = default; @@ -54,11 +56,21 @@ void MainWindow::doAdd() void MainWindow::doRemove() { - QMessageBox::warning(this, tr("Not yet implemented!"), tr("Not yet implemented!")); + auto selectedRows = m_ui->treeView->selectionModel()->selectedRows(); + if (selectedRows.isEmpty()) + return; + + // map proxied indices to those from the model + std::transform(std::begin(selectedRows), std::end(selectedRows), std::begin(selectedRows), + [&](const QModelIndex &index){ return m_proxyModel->mapToSource(index); }); + + removeRows(std::move(selectedRows)); } void MainWindow::selectionChanged() { + auto count = m_ui->treeView->selectionModel()->selectedRows().count(); + m_ui->pushButtonRemove->setEnabled(count > 0); m_ui->statusbar->showMessage(tr("%0 selected").arg(m_ui->treeView->selectionModel()->selectedRows().count())); } @@ -103,13 +115,13 @@ void MainWindow::contextMenuRequested(const QPoint &pos) std::transform(std::begin(selectedRows), std::end(selectedRows), std::begin(selectedRows), [&](const QModelIndex &index){ return m_proxyModel->mapToSource(index); }); - // get all the chargers for selected indices - std::vector> chargers; - chargers.reserve(selectedRows.size()); - std::transform(std::begin(selectedRows), std::end(selectedRows), std::back_inserter(chargers), - [&](const QModelIndex &index){ auto charger = m_model->getCharger(index); Q_ASSERT(charger); return charger; }); + // get all the devices for selected indices + std::vector> devices; + devices.reserve(selectedRows.size()); + std::transform(std::begin(selectedRows), std::end(selectedRows), std::back_inserter(devices), + [&](const QModelIndex &index){ auto device = m_model->getDevice(index); Q_ASSERT(device); return device; }); - Q_ASSERT(std::all_of(std::begin(chargers), std::end(chargers), [](const auto &charger)->bool{ return charger.get(); })); + Q_ASSERT(std::all_of(std::begin(devices), std::end(devices), [](const auto &device)->bool{ return device.get(); })); QMenu menu; auto actionSetUpdateUrl = menu.addAction(tr("Set update url...")); @@ -119,6 +131,7 @@ void MainWindow::contextMenuRequested(const QPoint &pos) auto actionSetAbitraryApiKey = menu.addAction(tr("Set abitrary api key...")); auto resetNvsKey = menu.addAction(tr("Reset nvs key...")); auto actionOpenApps = menu.addAction(tr("Open app(s)...")); + auto actionRemove = menu.addAction(tr("Remove...")); if (const auto selected = menu.exec(m_ui->treeView->viewport()->mapToGlobal(pos)); selected == actionSetUpdateUrl) { bool ok{}; @@ -131,7 +144,7 @@ void MainWindow::contextMenuRequested(const QPoint &pos) { "value", url }, { "sudo", true } }; - RequestDialog{std::move(msg), std::move(chargers), this}.exec(); + RequestDialog{std::move(msg), std::move(devices), this}.exec(); } else if (selected == actionStartUpdate) { @@ -153,7 +166,7 @@ void MainWindow::contextMenuRequested(const QPoint &pos) { "value", branch }, { "sudo", true } }; - RequestDialog{std::move(msg), std::move(chargers), this}.exec(); + RequestDialog{std::move(msg), std::move(devices), this}.exec(); } else if (selected == actionReboot) { @@ -165,7 +178,7 @@ void MainWindow::contextMenuRequested(const QPoint &pos) { "value", 1 }, { "sudo", true } }; - RequestDialog{std::move(msg), std::move(chargers), this}.exec(); + RequestDialog{std::move(msg), std::move(devices), this}.exec(); } } else if (selected == actionSetChargectrlOverride) @@ -204,7 +217,7 @@ void MainWindow::contextMenuRequested(const QPoint &pos) } }, { "sudo", true } }; - RequestDialog{std::move(msg), std::move(chargers), this}.exec(); + RequestDialog{std::move(msg), std::move(devices), this}.exec(); } else if (selected == actionSetAbitraryApiKey) { @@ -218,7 +231,7 @@ void MainWindow::contextMenuRequested(const QPoint &pos) }; if (dialog.sudo()) msg["sudo"] = true; - RequestDialog{std::move(msg), std::move(chargers), this}.exec(); + RequestDialog{std::move(msg), std::move(devices), this}.exec(); } } else if (selected == resetNvsKey) @@ -233,10 +246,41 @@ void MainWindow::contextMenuRequested(const QPoint &pos) { "key", nvsKey }, { "sudo", true } }; - RequestDialog{std::move(msg), std::move(chargers), this}.exec(); + RequestDialog{std::move(msg), std::move(devices), this}.exec(); } else if (selected == actionOpenApps) { } + else if (selected == actionRemove) + { + removeRows(std::move(selectedRows)); + } +} + +void MainWindow::removeRows(QModelIndexList &&indexes) +{ + if (QMessageBox::question( + this, + tr("Confirm deletion of devices"), + tr("Do you really want to remove %0 devices?").arg(indexes.count()) + ) != QMessageBox::Yes) + return; + + int failed{}; + + std::sort(indexes.begin(), indexes.end(), + [](const QModelIndex &a, const QModelIndex &b) { + return a.row() > b.row(); + }); + + for (const QModelIndex &index : std::as_const(indexes)) + if (!m_model->removeRows(index.row(), 1, index.parent())) + { + failed++; + qWarning() << "removing row" << index.row() << "failed"; + } + + if (failed > 0) + QMessageBox::warning(this, tr("Error while removing!"), tr("%0 rows could not be removed!").arg(failed)); } diff --git a/flotten-updater/mainwindow.h b/flotten-updater/mainwindow.h index 0798564..8c6cec8 100644 --- a/flotten-updater/mainwindow.h +++ b/flotten-updater/mainwindow.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include @@ -8,7 +9,7 @@ namespace Ui { class MainWindow; } class QSslKey; class QSslCertificate; class QItemSelection; -class ChargersModel; +class DevicesModel; class QSortFilterProxyModel; class FlottenUpdaterSettings; @@ -29,8 +30,10 @@ private slots: void contextMenuRequested(const QPoint &pos); private: + void removeRows(QModelIndexList &&indexes); + const std::unique_ptr m_ui; FlottenUpdaterSettings &m_settings; - const std::unique_ptr m_model; + const std::unique_ptr m_model; const std::unique_ptr m_proxyModel; }; diff --git a/flotten-updater/mainwindow.ui b/flotten-updater/mainwindow.ui index 9ed4fdd..69b0266 100644 --- a/flotten-updater/mainwindow.ui +++ b/flotten-updater/mainwindow.ui @@ -45,6 +45,13 @@ + + + + Add range + + + @@ -61,6 +68,9 @@ true + + true + diff --git a/flotten-updater/requestdialog.cpp b/flotten-updater/requestdialog.cpp index 7394363..2de53d0 100644 --- a/flotten-updater/requestdialog.cpp +++ b/flotten-updater/requestdialog.cpp @@ -4,13 +4,13 @@ #include #include -#include "chargerconnection.h" +#include "deviceconnection.h" #include "requestmodel.h" -RequestDialog::RequestDialog(QJsonObject &&msg, std::vector> &&chargers, QWidget *parent) : +RequestDialog::RequestDialog(QJsonObject &&msg, std::vector> &&devices, QWidget *parent) : QDialog{parent}, m_ui{std::make_unique()}, - m_model{std::make_unique(std::move(msg), std::move(chargers), this)} + m_model{std::make_unique(std::move(msg), std::move(devices), this)} { m_ui->setupUi(this); m_ui->treeView->setModel(m_model.get()); diff --git a/flotten-updater/requestdialog.h b/flotten-updater/requestdialog.h index 9bd213f..c9e4367 100644 --- a/flotten-updater/requestdialog.h +++ b/flotten-updater/requestdialog.h @@ -5,7 +5,7 @@ #include class QJsonObject; -class ChargerConnection; +class DevicesConnection; class RequestModel; namespace Ui { class RequestDialog; } @@ -15,7 +15,7 @@ class RequestDialog : public QDialog Q_OBJECT public: - explicit RequestDialog(QJsonObject &&msg, std::vector> &&chargers, QWidget *parent = nullptr); + explicit RequestDialog(QJsonObject &&msg, std::vector> &&devices, QWidget *parent = nullptr); ~RequestDialog(); private: diff --git a/flotten-updater/requestmodel.cpp b/flotten-updater/requestmodel.cpp index 2c8bd7d..1c66110 100644 --- a/flotten-updater/requestmodel.cpp +++ b/flotten-updater/requestmodel.cpp @@ -7,7 +7,7 @@ #include #include -#include "chargerconnection.h" +#include "deviceconnection.h" namespace { enum { @@ -21,24 +21,24 @@ enum { QString getRandomString(); } -RequestModel::RequestModel(QJsonObject &&msg, std::vector> &&chargers, QObject *parent) : +RequestModel::RequestModel(QJsonObject &&msg, std::vector> &&devices, QObject *parent) : QAbstractTableModel{parent} { - m_requests.reserve(chargers.size()); + m_requests.reserve(devices.size()); - for (auto &charger : chargers) + for (auto &device : devices) { Request request { - .charger = std::move(charger), + .device = std::move(device), .requestId = getRandomString() }; - connect(request.charger.get(), &ChargerConnection::responseReceived, this, &RequestModel::responseReceived); + connect(request.device.get(), &DevicesConnection::responseReceived, this, &RequestModel::responseReceived); { QJsonObject msg2 = msg; msg2["requestId"] = request.requestId; - request.charger->sendMessage(msg2); + request.device->sendMessage(msg2); } m_requests.emplace_back(std::move(request)); @@ -74,7 +74,7 @@ QVariant RequestModel::data(const QModelIndex &index, int role) const { case Qt::DisplayRole: case Qt::EditRole: - return request.charger->serial(); + return request.device->serial(); } return {}; case ColumnRequestId: diff --git a/flotten-updater/requestmodel.h b/flotten-updater/requestmodel.h index c2d7438..445ccde 100644 --- a/flotten-updater/requestmodel.h +++ b/flotten-updater/requestmodel.h @@ -6,14 +6,14 @@ #include class QJsonObject; -class ChargerConnection; +class DevicesConnection; class RequestModel : public QAbstractTableModel { Q_OBJECT public: - explicit RequestModel(QJsonObject &&msg, std::vector> &&chargers, QObject *parent = nullptr); + explicit RequestModel(QJsonObject &&msg, std::vector> &&devices, QObject *parent = nullptr); ~RequestModel() override; // QAbstractItemModel interface @@ -27,7 +27,7 @@ private slots: private: struct Request { - std::shared_ptr charger; + std::shared_ptr device; QString requestId; enum class Status { Pending, Failed, Succeeded }; Status status{Status::Pending};