Make columns in flotten-updater configurable
This commit is contained in:
@ -15,10 +15,6 @@ endif(CCACHE_FOUND)
|
||||
add_definitions(-DQT_GUI_LIB)
|
||||
add_subdirectory(3rdparty)
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Quick WebSockets LinguistTools)
|
||||
|
||||
qt_standard_project_setup(REQUIRES 6.6 I18N_TRANSLATED_LANGUAGES de)
|
||||
|
||||
add_subdirectory(evcharger-app)
|
||||
if (NOT ANDROID)
|
||||
add_subdirectory(flotten-updater)
|
||||
|
@ -1,3 +1,7 @@
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Quick WebSockets LinguistTools)
|
||||
|
||||
qt_standard_project_setup(REQUIRES 6.6 I18N_TRANSLATED_LANGUAGES de)
|
||||
|
||||
qt_add_executable(evcharger-app WIN32 MACOSX_BUNDLE
|
||||
appsettings.cpp
|
||||
appsettings.h
|
||||
|
@ -576,92 +576,92 @@
|
||||
<context>
|
||||
<name>ChargersModel</name>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="264"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="286"/>
|
||||
<source>Serial</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="265"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="287"/>
|
||||
<source>WS Status</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="266"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="288"/>
|
||||
<source>Status</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="267"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="289"/>
|
||||
<source>Variant</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="268"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="290"/>
|
||||
<source>IsGo</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="269"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="291"/>
|
||||
<source>IsAustralien</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="270"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="292"/>
|
||||
<source>ResetCard</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="271"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="293"/>
|
||||
<source>ConnectedWifi</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="272"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="294"/>
|
||||
<source>Project</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="273"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="295"/>
|
||||
<source>Version</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="274"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="296"/>
|
||||
<source>IDF Version</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="275"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="297"/>
|
||||
<source>Update</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="276"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="298"/>
|
||||
<source>Reboots</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="277"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="299"/>
|
||||
<source>Uptime</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="278"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="300"/>
|
||||
<source>Current Partition</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="279"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="301"/>
|
||||
<source>Car state</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="280"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="302"/>
|
||||
<source>Energy</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="281"/>
|
||||
<location filename="../../flotten-updater/chargersmodel.cpp" line="303"/>
|
||||
<source>Livedata</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1687,64 +1687,64 @@
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="26"/>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="30"/>
|
||||
<source>Yes</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="26"/>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="30"/>
|
||||
<source>No</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="51"/>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="55"/>
|
||||
<source>Select certificate...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="58"/>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="62"/>
|
||||
<source>Could not open file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="63"/>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="67"/>
|
||||
<source>Please enter password</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="63"/>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="67"/>
|
||||
<source>Certificate password:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="77"/>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="82"/>
|
||||
<source>Failed to load openssl legacy provider!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="82"/>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="88"/>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="94"/>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="100"/>
|
||||
<source>Failed processing certificate!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="82"/>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="88"/>
|
||||
<source>Possible reasons: openssl has a problem, the file is corrupt/invalid or the password is incorrect.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="88"/>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="94"/>
|
||||
<source>The key seems to be invalid.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="94"/>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="100"/>
|
||||
<source>The cert seems to be invalid.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="149"/>
|
||||
<location filename="../../flotten-updater/importcertificatedialog.cpp" line="155"/>
|
||||
<source>Could not change active backend</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1869,72 +1869,97 @@
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="46"/>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="48"/>
|
||||
<source>Serial</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="55"/>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="57"/>
|
||||
<source>Not yet implemented!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="60"/>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="62"/>
|
||||
<source>%0 selected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="82"/>
|
||||
<source>Set update url...</source>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="69"/>
|
||||
<source>Add new column...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="83"/>
|
||||
<source>Start update...</source>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="76"/>
|
||||
<source>Remove column %0</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="84"/>
|
||||
<source>Enter api key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="84"/>
|
||||
<source>Api key:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="115"/>
|
||||
<source>Set update url...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="116"/>
|
||||
<source>Start update...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="117"/>
|
||||
<source>Reboot...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="85"/>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="118"/>
|
||||
<source>Set chargectrl override...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="86"/>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="119"/>
|
||||
<source>Set abitrary api key...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="90"/>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="120"/>
|
||||
<source>Open app(s)...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="124"/>
|
||||
<source>Enter update url...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="90"/>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="124"/>
|
||||
<source>Update url:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="106"/>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="140"/>
|
||||
<source>Select update release...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="108"/>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="142"/>
|
||||
<source>Update release</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="125"/>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="159"/>
|
||||
<source>Are you sure?</source>
|
||||
<translation type="unfinished">Sind Sie sicher?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="125"/>
|
||||
<location filename="../../flotten-updater/mainwindow.cpp" line="159"/>
|
||||
<source>Do you really want to reboot selected devices?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -1,4 +1,8 @@
|
||||
add_executable(flotten-updater
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Quick WebSockets LinguistTools)
|
||||
|
||||
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
|
||||
@ -22,6 +26,12 @@ add_executable(flotten-updater
|
||||
setarbitraryapikeydialog.ui
|
||||
)
|
||||
|
||||
qt_add_resources(flotten-updater
|
||||
PREFIX /
|
||||
FILES
|
||||
goe-root-ca.pem
|
||||
)
|
||||
|
||||
find_package(OpenSSL)
|
||||
if (OpenSSL_Found)
|
||||
target_compile_definitions(flotten-updater HAS_OPENSSL)
|
||||
@ -35,12 +45,13 @@ target_link_libraries(flotten-updater PUBLIC
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
Qt6::Quick
|
||||
Qt6::WebSockets
|
||||
goecommon
|
||||
)
|
||||
|
||||
qt_add_resources(flotten-updater
|
||||
PREFIX /
|
||||
FILES
|
||||
goe-root-ca.pem
|
||||
install(TARGETS flotten-updater
|
||||
BUNDLE DESTINATION .
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
|
@ -346,6 +346,11 @@ QString ChargerConnection::livedataText() const
|
||||
return {};
|
||||
}
|
||||
|
||||
QVariant ChargerConnection::getApiKey(const QString &apiKey) const
|
||||
{
|
||||
return m_fullStatus.value(apiKey);
|
||||
}
|
||||
|
||||
void ChargerConnection::sendMessage(const QJsonDocument &doc)
|
||||
{
|
||||
sendMessage(QString::fromUtf8(doc.toJson()));
|
||||
@ -384,6 +389,7 @@ void ChargerConnection::init()
|
||||
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);
|
||||
}
|
||||
else
|
||||
qWarning() << "unexpected parent";
|
||||
@ -396,7 +402,7 @@ void ChargerConnection::init()
|
||||
auto caCerts = QSslCertificate::fromPath(":/goe-root-ca.pem");
|
||||
if (caCerts.empty())
|
||||
qFatal("could not parse root ca");
|
||||
for (const auto &caCert : qAsConst(caCerts))
|
||||
for (const auto &caCert : std::as_const(caCerts))
|
||||
qDebug() << caCert.issuerDisplayName();
|
||||
sslConfig.setCaCertificates(std::move(caCerts));
|
||||
}
|
||||
@ -411,7 +417,7 @@ void ChargerConnection::init()
|
||||
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, qOverload<QAbstractSocket::SocketError>(&QWebSocket::error), this, &ChargerConnection::error);
|
||||
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);
|
||||
@ -465,6 +471,8 @@ void ChargerConnection::maintainStatus(const QJsonObject &msg, bool forceChange)
|
||||
energyChanged = true;
|
||||
else if (iter.key() == "nrg")
|
||||
livedataChanged = true;
|
||||
|
||||
emit apiKeyChanged(iter.key());
|
||||
}
|
||||
|
||||
if (variantChanged)
|
||||
@ -611,7 +619,7 @@ void ChargerConnection::binaryMessageReceived(const QByteArray &message)
|
||||
qDebug() << "called" << message;
|
||||
}
|
||||
|
||||
void ChargerConnection::error(QAbstractSocket::SocketError error)
|
||||
void ChargerConnection::errorOccurred(QAbstractSocket::SocketError error)
|
||||
{
|
||||
qDebug() << "called" << QMetaEnum::fromType<QAbstractSocket::SocketError>().valueToKey(error) << m_websocket.errorString();
|
||||
}
|
||||
|
@ -66,6 +66,8 @@ public:
|
||||
|
||||
QString livedataText() const;
|
||||
|
||||
QVariant getApiKey(const QString &apiKey) const;
|
||||
|
||||
void sendMessage(const QJsonDocument &doc);
|
||||
void sendMessage(const QJsonObject &obj);
|
||||
void sendMessage(const QString &msg);
|
||||
@ -90,6 +92,7 @@ signals:
|
||||
void carStateChanged();
|
||||
void energyChanged();
|
||||
void livedataChanged();
|
||||
void apiKeyChanged(const QString &apiKey);
|
||||
|
||||
private:
|
||||
void init();
|
||||
@ -101,7 +104,7 @@ private slots:
|
||||
void stateChanged(QAbstractSocket::SocketState state);
|
||||
void textMessageReceived(const QString &message);
|
||||
void binaryMessageReceived(const QByteArray &message);
|
||||
void error(QAbstractSocket::SocketError error);
|
||||
void errorOccurred(QAbstractSocket::SocketError error);
|
||||
void peerVerifyError(const QSslError &error);
|
||||
void sslErrors(const QList<QSslError> &errors);
|
||||
void alertReceived(QSsl::AlertLevel level, QSsl::AlertType type, const QString &description);
|
||||
|
@ -2,10 +2,12 @@
|
||||
|
||||
#include <QDebug>
|
||||
#include <QBrush>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "chargerconnection.h"
|
||||
#include "flottenupdatersettings.h"
|
||||
|
||||
namespace {
|
||||
enum {
|
||||
@ -31,10 +33,13 @@ enum {
|
||||
};
|
||||
}
|
||||
|
||||
ChargersModel::ChargersModel(const QSslKey &key, const QSslCertificate &cert, QObject *parent) :
|
||||
ChargersModel::ChargersModel(FlottenUpdaterSettings &settings, const QSslKey &key,
|
||||
const QSslCertificate &cert, QObject *parent) :
|
||||
QAbstractTableModel{parent},
|
||||
m_settings{settings},
|
||||
m_key{key},
|
||||
m_cert{cert}
|
||||
m_cert{cert},
|
||||
m_customColumns{settings.customColumns()}
|
||||
{
|
||||
constexpr const char *serials[] {
|
||||
"096850", "10000003",
|
||||
@ -49,6 +54,7 @@ ChargersModel::ChargersModel(const QSslKey &key, const QSslCertificate &cert, QO
|
||||
"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"
|
||||
};
|
||||
for (const auto &serial : serials)
|
||||
{
|
||||
@ -68,7 +74,7 @@ int ChargersModel::rowCount(const QModelIndex &parent) const
|
||||
|
||||
int ChargersModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return NumberOfColumns;
|
||||
return NumberOfColumns + m_customColumns.size();
|
||||
}
|
||||
|
||||
QVariant ChargersModel::data(const QModelIndex &index, int role) const
|
||||
@ -248,6 +254,22 @@ QVariant ChargersModel::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
if (index.column() >= NumberOfColumns && index.column() - NumberOfColumns < m_customColumns.size())
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
{
|
||||
auto variant = charger.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 {};
|
||||
}
|
||||
|
||||
@ -280,8 +302,14 @@ QVariant ChargersModel::headerData(int section, Qt::Orientation orientation, int
|
||||
case ColumnEnergy: return tr("Energy");
|
||||
case ColumnLivedata: return tr("Livedata");
|
||||
}
|
||||
|
||||
if (section >= NumberOfColumns && section - NumberOfColumns < m_customColumns.size())
|
||||
return m_customColumns[section - NumberOfColumns];
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void ChargersModel::addClient(const QString &serial)
|
||||
@ -312,6 +340,30 @@ std::shared_ptr<const ChargerConnection> ChargersModel::getCharger(QModelIndex i
|
||||
return m_chargers.at(index.row());
|
||||
}
|
||||
|
||||
void ChargersModel::addCustomColumn(const QString &apiKey)
|
||||
{
|
||||
beginInsertColumns({}, NumberOfColumns + m_customColumns.size(), NumberOfColumns + m_customColumns.size());
|
||||
m_customColumns.push_back(apiKey);
|
||||
endInsertColumns();
|
||||
m_settings.setCustomColumns(m_customColumns);
|
||||
}
|
||||
|
||||
bool ChargersModel::customColumnRemovable(int section)
|
||||
{
|
||||
return section >= NumberOfColumns && section - NumberOfColumns < m_customColumns.size();
|
||||
}
|
||||
|
||||
void ChargersModel::removeCustomColumn(int section)
|
||||
{
|
||||
if (section < NumberOfColumns || section - NumberOfColumns >= m_customColumns.size())
|
||||
return;
|
||||
|
||||
beginRemoveColumns({}, section, section);
|
||||
m_customColumns.erase(std::next(std::begin(m_customColumns), section - NumberOfColumns));
|
||||
endRemoveColumns();
|
||||
m_settings.setCustomColumns(m_customColumns);
|
||||
}
|
||||
|
||||
void ChargersModel::connectAll()
|
||||
{
|
||||
for (auto &charger : m_chargers)
|
||||
@ -409,6 +461,13 @@ void ChargersModel::livedataChanged()
|
||||
columnChanged(ColumnLivedata, {Qt::DisplayRole, Qt::EditRole});
|
||||
}
|
||||
|
||||
void ChargersModel::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<int> &roles)
|
||||
{
|
||||
auto charger = qobject_cast<ChargerConnection*>(sender());
|
||||
@ -430,5 +489,5 @@ void ChargersModel::columnChanged(int column, const QList<int> &roles)
|
||||
auto row = std::distance(std::cbegin(m_chargers), iter);
|
||||
|
||||
auto index = createIndex(row, column);
|
||||
dataChanged(index, index, roles);
|
||||
emit dataChanged(index, index, roles);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
class QSslKey;
|
||||
class QSslCertificate;
|
||||
|
||||
class FlottenUpdaterSettings;
|
||||
class ChargerConnection;
|
||||
|
||||
class ChargersModel : public QAbstractTableModel
|
||||
@ -15,7 +16,8 @@ class ChargersModel : public QAbstractTableModel
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ChargersModel(const QSslKey &key, const QSslCertificate &cert, QObject *parent = nullptr);
|
||||
explicit ChargersModel(FlottenUpdaterSettings &settings, const QSslKey &key,
|
||||
const QSslCertificate &cert, QObject *parent = nullptr);
|
||||
~ChargersModel() override;
|
||||
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
@ -28,6 +30,10 @@ public:
|
||||
std::shared_ptr<ChargerConnection> getCharger(QModelIndex index);
|
||||
std::shared_ptr<const ChargerConnection> getCharger(QModelIndex index) const;
|
||||
|
||||
void addCustomColumn(const QString &apiKey);
|
||||
bool customColumnRemovable(int section);
|
||||
void removeCustomColumn(int section);
|
||||
|
||||
public slots:
|
||||
void connectAll();
|
||||
void disconnectAll();
|
||||
@ -49,11 +55,15 @@ public slots:
|
||||
void carStateChanged();
|
||||
void energyChanged();
|
||||
void livedataChanged();
|
||||
void apiKeyChanged(const QString &apiKey);
|
||||
|
||||
private:
|
||||
FlottenUpdaterSettings &m_settings;
|
||||
const QSslKey &m_key;
|
||||
const QSslCertificate &m_cert;
|
||||
void columnChanged(int column, const QList<int> &roles = QList<int>());
|
||||
|
||||
std::vector<std::shared_ptr<ChargerConnection>> m_chargers;
|
||||
|
||||
QStringList m_customColumns;
|
||||
};
|
||||
|
@ -19,3 +19,13 @@ void FlottenUpdaterSettings::setPrivateCert(const QByteArray &cert)
|
||||
{
|
||||
setValue("privateCert", cert);
|
||||
}
|
||||
|
||||
QStringList FlottenUpdaterSettings::customColumns() const
|
||||
{
|
||||
return value("customColumns").toStringList();
|
||||
}
|
||||
|
||||
void FlottenUpdaterSettings::setCustomColumns(const QStringList &customColumns)
|
||||
{
|
||||
setValue("customColumns", customColumns);
|
||||
}
|
||||
|
@ -14,4 +14,7 @@ public:
|
||||
|
||||
QByteArray privateCert() const;
|
||||
void setPrivateCert(const QByteArray &cert);
|
||||
|
||||
QStringList customColumns() const;
|
||||
void setCustomColumns(const QStringList &customColumns);
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ MainWindow::MainWindow(FlottenUpdaterSettings &settings, const QSslKey &key,
|
||||
QMainWindow{parent},
|
||||
m_ui{std::make_unique<Ui::MainWindow>()},
|
||||
m_settings{settings},
|
||||
m_model{std::make_unique<ChargersModel>(key, cert, this)},
|
||||
m_model{std::make_unique<ChargersModel>(settings, key, cert, this)},
|
||||
m_proxyModel{std::make_unique<QSortFilterProxyModel>(this)}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
@ -35,6 +35,8 @@ MainWindow::MainWindow(FlottenUpdaterSettings &settings, const QSslKey &key,
|
||||
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);
|
||||
}
|
||||
|
||||
@ -60,6 +62,37 @@ void MainWindow::selectionChanged()
|
||||
m_ui->statusbar->showMessage(tr("%0 selected").arg(m_ui->treeView->selectionModel()->selectedRows().count()));
|
||||
}
|
||||
|
||||
void MainWindow::headerContextMenuRequested(const QPoint &pos)
|
||||
{
|
||||
QMenu menu;
|
||||
|
||||
auto addColumnAction = menu.addAction(tr("Add new column..."));
|
||||
|
||||
QAction *removeColumnAction{};
|
||||
auto header = m_ui->treeView->header();
|
||||
const auto section = header->logicalIndexAt(pos);
|
||||
if (section >= 0)
|
||||
{
|
||||
removeColumnAction = menu.addAction(tr("Remove column %0").arg(header->model()->headerData(section, Qt::Horizontal).toString()));
|
||||
if (!m_model->customColumnRemovable(section))
|
||||
removeColumnAction->setEnabled(false);
|
||||
}
|
||||
|
||||
if (auto selectedAction = menu.exec(header->mapToGlobal(pos)); selectedAction == addColumnAction)
|
||||
{
|
||||
bool ok{};
|
||||
auto apiKey = QInputDialog::getText(this, tr("Enter api key"), tr("Api key:"), QLineEdit::Normal, {}, &ok);
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
m_model->addCustomColumn(apiKey);
|
||||
}
|
||||
else if (removeColumnAction && selectedAction == removeColumnAction)
|
||||
{
|
||||
m_model->removeCustomColumn(section);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::contextMenuRequested(const QPoint &pos)
|
||||
{
|
||||
auto selectedRows = m_ui->treeView->selectionModel()->selectedRows();
|
||||
@ -84,6 +117,7 @@ void MainWindow::contextMenuRequested(const QPoint &pos)
|
||||
auto actionReboot = menu.addAction(tr("Reboot..."));
|
||||
auto actionSetChargectrlOverride = menu.addAction(tr("Set chargectrl override..."));
|
||||
auto actionSetAbitraryApiKey = menu.addAction(tr("Set abitrary api key..."));
|
||||
auto actionOpenApps = menu.addAction(tr("Open app(s)..."));
|
||||
if (const auto selected = menu.exec(m_ui->treeView->viewport()->mapToGlobal(pos)); selected == actionSetUpdateUrl)
|
||||
{
|
||||
bool ok{};
|
||||
@ -186,4 +220,8 @@ void MainWindow::contextMenuRequested(const QPoint &pos)
|
||||
RequestDialog{std::move(msg), std::move(chargers), this}.exec();
|
||||
}
|
||||
}
|
||||
else if (selected == actionOpenApps)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ private slots:
|
||||
void doAdd();
|
||||
void doRemove();
|
||||
void selectionChanged();
|
||||
void headerContextMenuRequested(const QPoint &pos);
|
||||
void contextMenuRequested(const QPoint &pos);
|
||||
|
||||
private:
|
||||
|
@ -1,10 +1,16 @@
|
||||
add_library(goecommon
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Quick WebSockets LinguistTools)
|
||||
|
||||
qt_standard_project_setup(REQUIRES 6.6 I18N_TRANSLATED_LANGUAGES de)
|
||||
|
||||
qt_add_library(goecommon
|
||||
goesettings.cpp
|
||||
goesettings.h
|
||||
)
|
||||
|
||||
target_link_libraries(goecommon
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
target_include_directories(goecommon PUBLIC
|
||||
|
Reference in New Issue
Block a user