diff --git a/evcharger-app/i18n/qml_de.ts b/evcharger-app/i18n/qml_de.ts
index 005b85d..3f8820a 100644
--- a/evcharger-app/i18n/qml_de.ts
+++ b/evcharger-app/i18n/qml_de.ts
@@ -80,6 +80,39 @@
Zurück
+
+ AddSerialsRangeDialog
+
+
+ Add serials range
+
+
+
+
+ From:
+
+
+
+
+ To:
+
+
+
+
+ Count:
+
+
+
+
+ ???
+
+
+
+
+ %0 serials
+
+
+
ApiSettingsPage
@@ -1257,92 +1290,92 @@
DevicesModel
-
+
Serial
-
+
WS Status
-
+
Status
-
+
Variant
-
+
IsGo
-
+
IsAustralien
-
+
ResetCard
-
+
ConnectedWifi
-
+
Project
-
+
Version
-
+
IDF Version
-
+
Update
-
+
Reboots
-
+
Uptime
-
+
Current Partition
-
+
Car state
-
+
Energy
-
+
Livedata
@@ -1905,132 +1938,147 @@
-
+
Serial
-
+
+ Error while adding serial!
+
+
+
+
+ Error while adding!
+
+
+
+
+ %0 rows could not be adding!
+
+
+
+
%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!
diff --git a/flotten-updater/CMakeLists.txt b/flotten-updater/CMakeLists.txt
index dc9077d..3547a2f 100644
--- a/flotten-updater/CMakeLists.txt
+++ b/flotten-updater/CMakeLists.txt
@@ -3,6 +3,9 @@ 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
+ addserialsrangedialog.h
+ addserialsrangedialog.cpp
+ addserialsrangedialog.ui
deviceconnection.cpp
deviceconnection.h
devicesmodel.cpp
diff --git a/flotten-updater/addserialsrangedialog.cpp b/flotten-updater/addserialsrangedialog.cpp
new file mode 100644
index 0000000..d9e7e03
--- /dev/null
+++ b/flotten-updater/addserialsrangedialog.cpp
@@ -0,0 +1,61 @@
+#include "addserialsrangedialog.h"
+#include "ui_addserialsrangedialog.h"
+
+AddSerialsRangeDialog::AddSerialsRangeDialog(QWidget *parent) :
+ QDialog{parent},
+ m_ui{std::make_unique()}
+{
+ m_ui->setupUi(this);
+
+ connect(m_ui->spinBoxFrom, &QSpinBox::valueChanged,
+ this, &AddSerialsRangeDialog::updatePreview);
+ connect(m_ui->spinBoxTo, &QSpinBox::valueChanged,
+ this, &AddSerialsRangeDialog::updatePreview);
+ updatePreview();
+}
+
+AddSerialsRangeDialog::~AddSerialsRangeDialog() = default;
+
+void AddSerialsRangeDialog::accept()
+{
+ if (from() > to())
+ return;
+ QDialog::accept();
+}
+
+int AddSerialsRangeDialog::from() const
+{
+ return m_ui->spinBoxFrom->value();
+}
+
+int AddSerialsRangeDialog::to() const
+{
+ return m_ui->spinBoxTo->value();
+}
+
+void AddSerialsRangeDialog::updatePreview()
+{
+ const auto from = this->from();
+ const auto to = this->to();
+
+ QString text;
+ QColor color;
+ if (from > to)
+ {
+ text = tr("???");
+ color = Qt::red;
+ }
+ else
+ {
+ const auto count = to - from + 1;
+ text = tr("%0 serials").arg(count);
+ color = count > 100 ? Qt::yellow : Qt::green;
+ }
+
+ m_ui->labelCountDisplay->setText(text);
+
+ QPalette palette = m_ui->labelCountDisplay->palette();
+ palette.setColor(m_ui->labelCountDisplay->backgroundRole(), color);
+ palette.setColor(m_ui->labelCountDisplay->foregroundRole(), color);
+ m_ui->labelCountDisplay->setPalette(palette);
+}
diff --git a/flotten-updater/addserialsrangedialog.h b/flotten-updater/addserialsrangedialog.h
new file mode 100644
index 0000000..0067aa5
--- /dev/null
+++ b/flotten-updater/addserialsrangedialog.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include
+
+#include
+
+namespace Ui { class AddSerialsRangeDialog; }
+
+class AddSerialsRangeDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit AddSerialsRangeDialog(QWidget *parent = nullptr);
+ ~AddSerialsRangeDialog();
+
+ void accept() override;
+
+ int from() const;
+ int to() const;
+
+private:
+ void updatePreview();
+
+private:
+ const std::unique_ptr m_ui;
+};
diff --git a/flotten-updater/addserialsrangedialog.ui b/flotten-updater/addserialsrangedialog.ui
new file mode 100644
index 0000000..c64c5b0
--- /dev/null
+++ b/flotten-updater/addserialsrangedialog.ui
@@ -0,0 +1,109 @@
+
+
+ AddSerialsRangeDialog
+
+
+
+ 0
+ 0
+ 194
+ 140
+
+
+
+ Add serials range
+
+
+ -
+
+
-
+
+
+ From:
+
+
+
+ -
+
+
+ To:
+
+
+
+ -
+
+
+ Count:
+
+
+
+ -
+
+
+ -
+
+
+ 2147483647
+
+
+ 999930
+
+
+
+ -
+
+
+ 2147483647
+
+
+ 999940
+
+
+
+
+
+ -
+
+
+ QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ AddSerialsRangeDialog
+ accept()
+
+
+ 96
+ 118
+
+
+ 96
+ 69
+
+
+
+
+ buttonBox
+ rejected()
+ AddSerialsRangeDialog
+ reject()
+
+
+ 96
+ 118
+
+
+ 96
+ 69
+
+
+
+
+
diff --git a/flotten-updater/devicesmodel.cpp b/flotten-updater/devicesmodel.cpp
index b07ec9c..69ca9d5 100644
--- a/flotten-updater/devicesmodel.cpp
+++ b/flotten-updater/devicesmodel.cpp
@@ -321,8 +321,15 @@ bool DevicesModel::removeRows(int row, int count, const QModelIndex &parent)
return true;
}
-void DevicesModel::addClient(const QString &serial)
+bool DevicesModel::addClient(const QString &serial)
{
+ if (std::any_of(std::cbegin(m_devices), std::cend(m_devices),
+ [&](const auto &device){ return device->serial() == serial; }))
+ {
+ qWarning() << "duplicate serial";
+ return false;
+ }
+
beginInsertRows({}, m_devices.size(), m_devices.size());
auto clientPtr = std::make_shared(m_key, m_cert, serial, this);
@@ -332,6 +339,8 @@ void DevicesModel::addClient(const QString &serial)
endInsertRows();
client->start();
+
+ return true;
}
std::shared_ptr DevicesModel::getDevice(QModelIndex index)
diff --git a/flotten-updater/devicesmodel.h b/flotten-updater/devicesmodel.h
index 27426ee..16c58d3 100644
--- a/flotten-updater/devicesmodel.h
+++ b/flotten-updater/devicesmodel.h
@@ -28,7 +28,7 @@ public:
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);
+ bool addClient(const QString &serial);
std::shared_ptr getDevice(QModelIndex index);
std::shared_ptr getDevice(QModelIndex index) const;
diff --git a/flotten-updater/mainwindow.cpp b/flotten-updater/mainwindow.cpp
index 2e0c6f2..a4be53c 100644
--- a/flotten-updater/mainwindow.cpp
+++ b/flotten-updater/mainwindow.cpp
@@ -16,6 +16,7 @@
#include "devicesmodel.h"
#include "requestdialog.h"
#include "setarbitraryapikeydialog.h"
+#include "addserialsrangedialog.h"
MainWindow::MainWindow(FlottenUpdaterSettings &settings, const QSslKey &key,
const QSslCertificate &cert, QWidget *parent) :
@@ -35,6 +36,7 @@ MainWindow::MainWindow(FlottenUpdaterSettings &settings, const QSslKey &key,
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->pushButtonAddRange, &QAbstractButton::pressed, this, &MainWindow::doAddRange);
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);
@@ -50,8 +52,10 @@ void MainWindow::doAdd()
const auto serial = QInputDialog::getText(this, tr("Serial"), tr("Serial"), QLineEdit::Normal, {}, &ok);
if (!ok)
return;
- m_model->addClient(serial);
- m_settings.setSerials(m_model->serials());
+ if (m_model->addClient(serial))
+ m_settings.setSerials(m_model->serials());
+ else
+ QMessageBox::warning(this, tr("Error while adding serial!"), tr("Error while adding serial!"));
}
void MainWindow::doRemove()
@@ -67,6 +71,32 @@ void MainWindow::doRemove()
removeRows(std::move(selectedRows));
}
+void MainWindow::doAddRange()
+{
+ AddSerialsRangeDialog dialog{this};
+ if (dialog.exec() != QDialog::Accepted)
+ return;
+
+ int succeeded{}, failed{};
+
+ for (auto serial = dialog.from(); serial <= dialog.to(); serial++)
+ {
+ if (m_model->addClient(QString::number(serial)))
+ succeeded++;
+ else
+ {
+ qWarning() << "adding serial" << serial << "failed";
+ failed++;
+ }
+ }
+
+ if (succeeded > 0)
+ m_settings.setSerials(m_model->serials());
+
+ if (failed > 0)
+ QMessageBox::warning(this, tr("Error while adding!"), tr("%0 rows could not be adding!").arg(failed));
+}
+
void MainWindow::selectionChanged()
{
auto count = m_ui->treeView->selectionModel()->selectedRows().count();
diff --git a/flotten-updater/mainwindow.h b/flotten-updater/mainwindow.h
index 8c6cec8..590666d 100644
--- a/flotten-updater/mainwindow.h
+++ b/flotten-updater/mainwindow.h
@@ -25,6 +25,7 @@ public:
private slots:
void doAdd();
void doRemove();
+ void doAddRange();
void selectionChanged();
void headerContextMenuRequested(const QPoint &pos);
void contextMenuRequested(const QPoint &pos);