Initial commit (project based on widgets)
This commit is contained in:
589
parametereditor.cpp
Normal file
589
parametereditor.cpp
Normal file
@@ -0,0 +1,589 @@
|
||||
/*
|
||||
Original copyright 2018 Benjamin Vedder benjamin@vedder.se and the VESC Tool project ( https://github.com/vedderb/vesc_tool )
|
||||
|
||||
Forked to:
|
||||
Copyright 2018 Danny Bokma github@diebie.nl (https://github.com/DieBieEngineering/DieBieMS-Tool)
|
||||
|
||||
Now forked to:
|
||||
Copyright 2019 - 2020 Kevin Dionne kevin.dionne@ennoid.me (https://github.com/EnnoidMe/ENNOID-BMS-Tool)
|
||||
|
||||
This file is part of ENNOID-BMS Tool.
|
||||
|
||||
ENNOID-BMS Tool is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ENNOID-BMS Tool is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "parametereditor.h"
|
||||
#include "ui_parametereditor.h"
|
||||
#include <QStringList>
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
#include <QInputDialog>
|
||||
#include <QDebug>
|
||||
#include <cmath>
|
||||
|
||||
ParameterEditor::ParameterEditor(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::ParameterEditor)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setEditorValues("new_parameter", ConfigParam());
|
||||
|
||||
mStatusInfoTime = 0;
|
||||
mStatusLabel = new QLabel(this);
|
||||
ui->statusBar->addPermanentWidget(mStatusLabel);
|
||||
mTimer = new QTimer(this);
|
||||
mTimer->start(20);
|
||||
|
||||
connect(mTimer, SIGNAL(timeout()),
|
||||
this, SLOT(timerSlot()));
|
||||
}
|
||||
|
||||
ParameterEditor::~ParameterEditor()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ParameterEditor::setParams(const ConfigParams *params)
|
||||
{
|
||||
QStringList paramList = params->getParamOrder();
|
||||
mParams.clearParams();
|
||||
mParams.setSerializeOrder(params->getSerializeOrder());
|
||||
|
||||
for (int i = 0;i < paramList.size();i++) {
|
||||
QString name = paramList.at(i);
|
||||
mParams.addParam(name, params->getParamCopy(name));
|
||||
}
|
||||
|
||||
mParams.setUpdatesEnabled(false);
|
||||
|
||||
showStatusInfo(tr("Parameters Loaded"), true);
|
||||
|
||||
updateUi();
|
||||
}
|
||||
|
||||
void ParameterEditor::timerSlot()
|
||||
{
|
||||
// Update status label
|
||||
if (mStatusInfoTime) {
|
||||
mStatusInfoTime--;
|
||||
if (!mStatusInfoTime) {
|
||||
mStatusLabel->setStyleSheet(qApp->styleSheet());
|
||||
}
|
||||
} else {
|
||||
if (!mStatusLabel->text().isEmpty()) {
|
||||
mStatusLabel->clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterEditor::on_paramRemoveButton_clicked()
|
||||
{
|
||||
int row = ui->paramList->currentRow();
|
||||
|
||||
if (row >= 0) {
|
||||
mParams.deleteParam(ui->paramList->item(row)->text());
|
||||
delete ui->paramList->takeItem(row);
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterEditor::on_paramDownButton_clicked()
|
||||
{
|
||||
int row = ui->paramList->currentRow();
|
||||
QStringList order = mParams.getParamOrder();
|
||||
|
||||
if (row >= 0 && row < (order.size() - 1)) {
|
||||
QString name = order.at(row);
|
||||
order.removeAt(row);
|
||||
order.insert(row + 1, name);
|
||||
mParams.setParamOrder(order);
|
||||
updateUi();
|
||||
ui->paramList->setCurrentRow(row + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterEditor::on_paramUpButton_clicked()
|
||||
{
|
||||
int row = ui->paramList->currentRow();
|
||||
QStringList order = mParams.getParamOrder();
|
||||
|
||||
if (row >= 1) {
|
||||
QString name = order.at(row);
|
||||
order.removeAt(row);
|
||||
order.insert(row - 1, name);
|
||||
mParams.setParamOrder(order);
|
||||
updateUi();
|
||||
ui->paramList->setCurrentRow(row - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterEditor::on_paramOpenButton_clicked()
|
||||
{
|
||||
QListWidgetItem *item = ui->paramList->currentItem();
|
||||
QString selected;
|
||||
|
||||
if (item) {
|
||||
selected = item->text();
|
||||
}
|
||||
|
||||
ConfigParam *p = mParams.getParam(selected);
|
||||
|
||||
if (p) {
|
||||
setEditorValues(selected, *p);
|
||||
|
||||
if (ui->previewTable->rowCount() > 0) {
|
||||
ui->previewTable->removeRow(0);
|
||||
}
|
||||
|
||||
if (p->type != CFG_T_UNDEFINED) {
|
||||
ui->previewTable->addParamRow(&mParams, selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterEditor::on_paramSaveButton_clicked()
|
||||
{
|
||||
if (ui->nameEdit->text().contains(" ")) {
|
||||
QMessageBox::warning(this,
|
||||
tr("Save Parameter"),
|
||||
tr("Spaces are not allowed in the name."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ui->nameEdit->text().isEmpty()) {
|
||||
QMessageBox::warning(this,
|
||||
tr("Save Parameter"),
|
||||
tr("Name is empty."));
|
||||
return;
|
||||
}
|
||||
|
||||
QString name;
|
||||
ConfigParam p;
|
||||
|
||||
name = getEditorValues(&p);
|
||||
|
||||
if (mParams.hasParam(name)) {
|
||||
*mParams.getParam(name) = p;
|
||||
showStatusInfo(tr("Parameter updated: %1").arg(name), true);
|
||||
} else {
|
||||
mParams.addParam(name, p);
|
||||
|
||||
int row = ui->paramList->currentRow();
|
||||
QStringList order = mParams.getParamOrder();
|
||||
order.removeLast();
|
||||
|
||||
if (row < 0) {
|
||||
row = order.size();
|
||||
} else {
|
||||
row += 1;
|
||||
}
|
||||
|
||||
order.insert(row, name);
|
||||
mParams.setParamOrder(order);
|
||||
|
||||
updateUi();
|
||||
|
||||
ui->paramList->setCurrentRow(row);
|
||||
showStatusInfo(tr("New parameter added: %1").arg(name), true);
|
||||
}
|
||||
|
||||
if (ui->previewTable->rowCount() > 0) {
|
||||
ui->previewTable->removeRow(0);
|
||||
}
|
||||
|
||||
if (p.type != CFG_T_QSTRING && p.type != CFG_T_UNDEFINED) {
|
||||
ui->previewTable->addParamRow(&mParams, name);
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterEditor::on_paramResetButton_clicked()
|
||||
{
|
||||
setEditorValues("new_parameter", ConfigParam());
|
||||
}
|
||||
|
||||
void ParameterEditor::on_serRemoveButton_clicked()
|
||||
{
|
||||
int row = ui->paramSerialOrderList->currentRow();
|
||||
|
||||
if (row >= 0) {
|
||||
QStringList order = mParams.getSerializeOrder();
|
||||
order.removeAt(row);
|
||||
mParams.setSerializeOrder(order);
|
||||
delete ui->paramSerialOrderList->takeItem(row);
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterEditor::on_serDownButton_clicked()
|
||||
{
|
||||
int row = ui->paramSerialOrderList->currentRow();
|
||||
QStringList order = mParams.getSerializeOrder();
|
||||
|
||||
if (row >= 0 && row < (order.size() - 1)) {
|
||||
QString name = order.at(row);
|
||||
order.removeAt(row);
|
||||
order.insert(row + 1, name);
|
||||
mParams.setSerializeOrder(order);
|
||||
updateUi();
|
||||
ui->paramSerialOrderList->setCurrentRow(row + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterEditor::on_serUpButton_clicked()
|
||||
{
|
||||
int row = ui->paramSerialOrderList->currentRow();
|
||||
QStringList order = mParams.getSerializeOrder();
|
||||
|
||||
if (row >= 1) {
|
||||
QString name = order.at(row);
|
||||
order.removeAt(row);
|
||||
order.insert(row - 1, name);
|
||||
mParams.setSerializeOrder(order);
|
||||
updateUi();
|
||||
ui->paramSerialOrderList->setCurrentRow(row - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterEditor::on_serAddButton_clicked()
|
||||
{
|
||||
QListWidgetItem *item = ui->paramList->currentItem();
|
||||
QString selected = "";
|
||||
|
||||
if (item) {
|
||||
selected = item->text();
|
||||
}
|
||||
|
||||
bool ok;
|
||||
QString name = QInputDialog::getText(this,
|
||||
tr("Add to Serialization Order"),
|
||||
tr("Parameter Name"),
|
||||
QLineEdit::Normal,
|
||||
selected,
|
||||
&ok);
|
||||
|
||||
if (ok) {
|
||||
if (name.contains(" ")) {
|
||||
QMessageBox::warning(this,
|
||||
tr("Add"),
|
||||
tr("Spaces are not allowed in the name."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (name.isEmpty()) {
|
||||
QMessageBox::warning(this,
|
||||
tr("Add"),
|
||||
tr("Name is empty."));
|
||||
return;
|
||||
}
|
||||
|
||||
int row = ui->paramSerialOrderList->currentRow();
|
||||
QStringList order = mParams.getSerializeOrder();
|
||||
|
||||
if (row < 0 || row >= order.size()) {
|
||||
row = order.size() - 1;
|
||||
}
|
||||
|
||||
order.insert(row + 1, name);
|
||||
mParams.setSerializeOrder(order);
|
||||
updateUi();
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterEditor::on_paramList_doubleClicked(const QModelIndex &index)
|
||||
{
|
||||
(void)index;
|
||||
on_paramOpenButton_clicked();
|
||||
}
|
||||
|
||||
void ParameterEditor::on_enumAddButton_clicked()
|
||||
{
|
||||
addEnum(tr("<double-click to edit>"));
|
||||
}
|
||||
|
||||
void ParameterEditor::on_enumRemoveButton_clicked()
|
||||
{
|
||||
int row = ui->enumList->currentRow();
|
||||
|
||||
if (row >= 0) {
|
||||
delete ui->enumList->takeItem(row);
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterEditor::on_enumMoveUpButton_clicked()
|
||||
{
|
||||
int row = ui->enumList->currentRow();
|
||||
|
||||
if (row >= 1) {
|
||||
QListWidgetItem *item = ui->enumList->takeItem(row);
|
||||
ui->enumList->insertItem(row - 1, item);
|
||||
ui->enumList->setCurrentRow(row - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterEditor::on_enumMoveDownButton_clicked()
|
||||
{
|
||||
int row = ui->enumList->currentRow();
|
||||
|
||||
if (row >= 0 && row < (ui->enumList->count() - 1)) {
|
||||
QListWidgetItem *item = ui->enumList->takeItem(row);
|
||||
ui->enumList->insertItem(row + 1, item);
|
||||
ui->enumList->setCurrentRow(row + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterEditor::on_actionLoad_XML_triggered()
|
||||
{
|
||||
QString path;
|
||||
path = QFileDialog::getOpenFileName(this,
|
||||
tr("Choose parameter file to load"),
|
||||
".",
|
||||
tr("Xml files (*.xml)"));
|
||||
|
||||
if (path.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool res = mParams.loadParamsXml(path);
|
||||
|
||||
if (!res) {
|
||||
QMessageBox::information(this,
|
||||
tr("Load Parameters"),
|
||||
tr("Could not load parameters:<BR>"
|
||||
"%1").arg(mParams.xmlStatus()));
|
||||
} else {
|
||||
showStatusInfo(tr("Configuration Loaded"), true);
|
||||
}
|
||||
|
||||
updateUi();
|
||||
}
|
||||
|
||||
void ParameterEditor::on_actionSave_XML_as_triggered()
|
||||
{
|
||||
QString path;
|
||||
path = QFileDialog::getSaveFileName(this,
|
||||
tr("Choose where to save the parameter XML file"),
|
||||
".",
|
||||
tr("Xml files (*.xml)"));
|
||||
|
||||
if (path.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!path.toLower().endsWith(".xml")) {
|
||||
path += ".xml";
|
||||
}
|
||||
|
||||
bool res = mParams.saveParamsXml(path);
|
||||
|
||||
if (!res) {
|
||||
QMessageBox::information(this,
|
||||
tr("Save Parameters"),
|
||||
tr("Could not save parameters:<BR>"
|
||||
"%1").arg(mParams.xmlStatus()));
|
||||
} else {
|
||||
showStatusInfo(tr("Configuration Saved"), true);
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterEditor::on_actionDeleteAll_triggered()
|
||||
{
|
||||
QMessageBox::StandardButton reply;
|
||||
reply = QMessageBox::question(this,
|
||||
tr("Delete All"),
|
||||
tr("Are you sure that you want to delete all data?"),
|
||||
QMessageBox::Yes|QMessageBox::No);
|
||||
|
||||
if (reply == QMessageBox::Yes) {
|
||||
mParams.clearAll();
|
||||
updateUi();
|
||||
showStatusInfo(tr("Configuration Deleted"), true);
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterEditor::updateUi()
|
||||
{
|
||||
ui->paramList->clear();
|
||||
ui->paramList->addItems(mParams.getParamOrder());
|
||||
ui->paramSerialOrderList->clear();
|
||||
ui->paramSerialOrderList->addItems(mParams.getSerializeOrder());
|
||||
}
|
||||
|
||||
void ParameterEditor::setEditorValues(QString name, ConfigParam p)
|
||||
{
|
||||
ui->nameEdit->setText(name);
|
||||
ui->longNameEdit->setText(p.longName);
|
||||
ui->typeBox->setCurrentIndex(p.type);
|
||||
ui->transmittableBox->setCurrentIndex(p.transmittable ? 0 : 1);
|
||||
ui->descriptionEdit->document()->setHtml(p.description);
|
||||
ui->cDefineEdit->setText(p.cDefine);
|
||||
|
||||
// Double
|
||||
|
||||
ui->doubleEditorScaleBox->setValue(p.editorScale);
|
||||
ui->doubleEditPercentageBox->setChecked(p.editAsPercentage);
|
||||
ui->doubleDecimalsBox->setValue(p.editorDecimalsDouble);
|
||||
ui->doubleMaxBox->setValue(p.maxDouble);
|
||||
ui->doubleMinBox->setValue(p.minDouble);
|
||||
ui->doubleShowDisplayBox->setChecked(p.showDisplay);
|
||||
ui->doubleStep->setValue(p.stepDouble);
|
||||
ui->doubleSuffixEdit->setText(p.suffix);
|
||||
|
||||
double val = p.vTxDoubleScale;
|
||||
double power = floor(log10(val));
|
||||
val /= pow(10, power);
|
||||
|
||||
ui->doubleTxScaleBaseBox->setValue(val);
|
||||
ui->doubleTxScaleExpBox->setValue(power);
|
||||
|
||||
if (p.vTx == VESC_TX_DOUBLE16) {
|
||||
ui->doubleTxTypeBox->setCurrentIndex(0);
|
||||
} else if (p.vTx == VESC_TX_DOUBLE32) {
|
||||
ui->doubleTxTypeBox->setCurrentIndex(1);
|
||||
} else {
|
||||
ui->doubleTxTypeBox->setCurrentIndex(2);
|
||||
}
|
||||
|
||||
ui->doubleValBox->setValue(p.valDouble);
|
||||
|
||||
// Int
|
||||
ui->intEditorScaleBox->setValue(p.editorScale);
|
||||
ui->intEditPercentageBox->setChecked(p.editAsPercentage);
|
||||
ui->intMaxBox->setValue(p.maxInt);
|
||||
ui->intMinBox->setValue(p.minInt);
|
||||
ui->intShowDisplayBox->setChecked(p.showDisplay);
|
||||
ui->intStepBox->setValue(p.stepInt);
|
||||
ui->intSuffixEdit->setText(p.suffix);
|
||||
if (p.vTx <= 6 && p.vTx > 0) {
|
||||
ui->intTxTypeBox->setCurrentIndex(p.vTx - 1);
|
||||
}
|
||||
ui->intValBox->setValue(p.valInt);
|
||||
|
||||
// String
|
||||
ui->stringValEdit->setText(p.valString);
|
||||
|
||||
// Enum
|
||||
ui->enumList->clear();
|
||||
for (int i = 0;i < p.enumNames.size();i++) {
|
||||
addEnum(p.enumNames.at(i));
|
||||
}
|
||||
|
||||
if (p.valInt >= 0 && p.valInt < p.enumNames.size()) {
|
||||
ui->enumList->setCurrentRow(p.valInt);
|
||||
}
|
||||
|
||||
// Bool
|
||||
ui->boolBox->setCurrentIndex(p.valInt > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
QString ParameterEditor::getEditorValues(ConfigParam *p)
|
||||
{
|
||||
if (p) {
|
||||
p->longName = ui->longNameEdit->text();
|
||||
p->type = (CFG_T)ui->typeBox->currentIndex();
|
||||
p->transmittable = ui->transmittableBox->currentIndex() == 0;
|
||||
p->description = ui->descriptionEdit->toHtmlNoFontSize();
|
||||
p->cDefine = ui->cDefineEdit->text();
|
||||
|
||||
switch (p->type) {
|
||||
case CFG_T_DOUBLE:
|
||||
p->editorScale = ui->doubleEditorScaleBox->value();
|
||||
p->editAsPercentage = ui->doubleEditPercentageBox->isChecked();
|
||||
p->editorDecimalsDouble = ui->doubleDecimalsBox->value();
|
||||
p->maxDouble = ui->doubleMaxBox->value();
|
||||
p->minDouble = ui->doubleMinBox->value();
|
||||
p->showDisplay = ui->doubleShowDisplayBox->isChecked();
|
||||
p->stepDouble = ui->doubleStep->value();
|
||||
p->suffix = ui->doubleSuffixEdit->text();
|
||||
p->vTxDoubleScale = ui->doubleTxScaleBaseBox->value() *
|
||||
pow(10, ui->doubleTxScaleExpBox->value());
|
||||
p->vTx = (VESC_TX_T)(ui->doubleTxTypeBox->currentIndex() + 7);
|
||||
p->valDouble = ui->doubleValBox->value();
|
||||
break;
|
||||
|
||||
case CFG_T_INT:
|
||||
p->editorScale = ui->intEditorScaleBox->value();
|
||||
p->editAsPercentage = ui->intEditPercentageBox->isChecked();
|
||||
p->maxInt = ui->intMaxBox->value();
|
||||
p->minInt = ui->intMinBox->value();
|
||||
p->showDisplay = ui->intShowDisplayBox->isChecked();
|
||||
p->stepInt = ui->intStepBox->value();
|
||||
p->suffix = ui->intSuffixEdit->text();
|
||||
p->vTx = (VESC_TX_T)(ui->intTxTypeBox->currentIndex() + 1);
|
||||
p->valInt = ui->intValBox->value();
|
||||
break;
|
||||
|
||||
case CFG_T_QSTRING:
|
||||
p->valString = ui->stringValEdit->text();
|
||||
break;
|
||||
|
||||
case CFG_T_ENUM:
|
||||
p->enumNames.clear();
|
||||
for (int i = 0;i < ui->enumList->count();i++) {
|
||||
p->enumNames.append(ui->enumList->item(i)->text());
|
||||
}
|
||||
p->valInt = ui->enumList->currentRow();
|
||||
break;
|
||||
|
||||
case CFG_T_BOOL:
|
||||
p->valInt = ui->boolBox->currentIndex();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ui->nameEdit->text();
|
||||
}
|
||||
|
||||
void ParameterEditor::addEnum(QString name)
|
||||
{
|
||||
QListWidgetItem *item = new QListWidgetItem(name);
|
||||
item->setFlags (item->flags() | Qt :: ItemIsEditable);
|
||||
ui->enumList->addItem(item);
|
||||
}
|
||||
|
||||
void ParameterEditor::showStatusInfo(QString info, bool isGood)
|
||||
{
|
||||
if (isGood) {
|
||||
mStatusLabel->setStyleSheet("QLabel { background-color : lightgreen; color : black; }");
|
||||
} else {
|
||||
mStatusLabel->setStyleSheet("QLabel { background-color : red; color : black; }");
|
||||
}
|
||||
|
||||
mStatusInfoTime = 80;
|
||||
mStatusLabel->setText(info);
|
||||
}
|
||||
|
||||
void ParameterEditor::on_doubleTxTypeBox_currentIndexChanged(int index)
|
||||
{
|
||||
if (index == 2) {
|
||||
ui->doubleTxScaleBaseBox->setEnabled(false);
|
||||
ui->doubleTxScaleExpBox->setEnabled(false);
|
||||
ui->doubleTxScaleExpLabel->setEnabled(false);
|
||||
ui->doubleTxScaleLabel->setEnabled(false);
|
||||
} else {
|
||||
ui->doubleTxScaleBaseBox->setEnabled(true);
|
||||
ui->doubleTxScaleExpBox->setEnabled(true);
|
||||
ui->doubleTxScaleExpLabel->setEnabled(true);
|
||||
ui->doubleTxScaleLabel->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterEditor::on_actionCalculatePacketSize_triggered()
|
||||
{
|
||||
VByteArray bytes;
|
||||
mParams.serialize(bytes);
|
||||
QMessageBox::information(this,
|
||||
tr("Packet Size"),
|
||||
tr("%1 Bytes").arg(bytes.size()));
|
||||
}
|
||||
Reference in New Issue
Block a user