cabana: save settings to user-specific directory (#30328)

* save settings to user-specific directory

* include
old-commit-hash: b73329092c
testing-closet
Dean Lee 2 years ago committed by GitHub
parent 920bc9acea
commit 03ba671b96
  1. 1
      tools/cabana/.gitignore
  2. 2
      tools/cabana/cabana.cc
  3. 6
      tools/cabana/mainwin.cc
  4. 1
      tools/cabana/messageswidget.cc
  5. 128
      tools/cabana/settings.cc
  6. 13
      tools/cabana/settings.h
  7. 1
      tools/cabana/streams/pandastream.cc
  8. 1
      tools/cabana/tools/findsignal.h

@ -2,6 +2,5 @@ moc_*
*.moc
cabana
settings
dbc/car_fingerprint_to_dbc.json
tests/test_cabana

@ -18,8 +18,6 @@ int main(int argc, char *argv[]) {
app.setWindowIcon(QIcon(":cabana-icon.png"));
UnixSignalHandler signalHandler;
settings.load();
utils::setTheme(settings.theme);
QCommandLineParser cmd_parser;

@ -608,12 +608,6 @@ void MainWindow::closeEvent(QCloseEvent *event) {
}
settings.message_header_state = messages_widget->saveHeaderState();
auto status = settings.save();
if (status == QSettings::AccessError) {
QString error = tr("Failed to write settings to [%1]: access denied").arg(Settings::filePath());
qDebug() << error;
QMessageBox::warning(this, tr("Failed to write settings"), error);
}
QWidget::closeEvent(event);
}

@ -2,6 +2,7 @@
#include <limits>
#include <QCheckBox>
#include <QHBoxLayout>
#include <QPainter>
#include <QPushButton>

@ -6,65 +6,51 @@
#include <QFileDialog>
#include <QFormLayout>
#include <QPushButton>
#include <QSettings>
#include <QStandardPaths>
#include <type_traits>
#include "tools/cabana/util.h"
Settings settings;
QSettings::Status Settings::save() {
QSettings s(filePath(), QSettings::IniFormat);
s.setValue("absolute_time", absolute_time);
s.setValue("fps", fps);
s.setValue("max_cached_minutes", max_cached_minutes);
s.setValue("chart_height", chart_height);
s.setValue("chart_range", chart_range);
s.setValue("chart_column_count", chart_column_count);
s.setValue("last_dir", last_dir);
s.setValue("last_route_dir", last_route_dir);
s.setValue("window_state", window_state);
s.setValue("geometry", geometry);
s.setValue("video_splitter_state", video_splitter_state);
s.setValue("recent_files", recent_files);
s.setValue("message_header_state_v3", message_header_state);
s.setValue("chart_series_type", chart_series_type);
s.setValue("theme", theme);
s.setValue("sparkline_range", sparkline_range);
s.setValue("multiple_lines_bytes", multiple_lines_bytes);
s.setValue("log_livestream", log_livestream);
s.setValue("log_path", log_path);
s.setValue("drag_direction", drag_direction);
s.setValue("suppress_defined_signals", suppress_defined_signals);
s.sync();
return s.status();
template <class SettingOperation>
void settings_op(SettingOperation op) {
QSettings s("cabana");
op(s, "absolute_time", settings.absolute_time);
op(s, "fps", settings.fps);
op(s, "max_cached_minutes", settings.max_cached_minutes);
op(s, "chart_height", settings.chart_height);
op(s, "chart_range", settings.chart_range);
op(s, "chart_column_count", settings.chart_column_count);
op(s, "last_dir", settings.last_dir);
op(s, "last_route_dir", settings.last_route_dir);
op(s, "window_state", settings.window_state);
op(s, "geometry", settings.geometry);
op(s, "video_splitter_state", settings.video_splitter_state);
op(s, "recent_files", settings.recent_files);
op(s, "message_header_state", settings.message_header_state);
op(s, "chart_series_type", settings.chart_series_type);
op(s, "theme", settings.theme);
op(s, "sparkline_range", settings.sparkline_range);
op(s, "multiple_lines_bytes", settings.multiple_lines_bytes);
op(s, "log_livestream", settings.log_livestream);
op(s, "log_path", settings.log_path);
op(s, "drag_direction", (int &)settings.drag_direction);
op(s, "suppress_defined_signals", settings.suppress_defined_signals);
}
void Settings::load() {
QSettings s(filePath(), QSettings::IniFormat);
absolute_time = s.value("absolute_time", false).toBool();
fps = s.value("fps", 10).toInt();
max_cached_minutes = s.value("max_cached_minutes", 30).toInt();
chart_height = s.value("chart_height", 200).toInt();
chart_range = s.value("chart_range", 3 * 60).toInt();
chart_column_count = s.value("chart_column_count", 1).toInt();
last_dir = s.value("last_dir", QDir::homePath()).toString();
last_route_dir = s.value("last_route_dir", QDir::homePath()).toString();
window_state = s.value("window_state").toByteArray();
geometry = s.value("geometry").toByteArray();
video_splitter_state = s.value("video_splitter_state").toByteArray();
recent_files = s.value("recent_files").toStringList();
message_header_state = s.value("message_header_state_v3").toByteArray();
chart_series_type = s.value("chart_series_type", 0).toInt();
theme = s.value("theme", 0).toInt();
sparkline_range = s.value("sparkline_range", 15).toInt();
multiple_lines_bytes = s.value("multiple_lines_bytes", true).toBool();
log_livestream = s.value("log_livestream", true).toBool();
log_path = s.value("log_path").toString();
drag_direction = (Settings::DragDirection)s.value("drag_direction", 0).toInt();
suppress_defined_signals = s.value("suppress_defined_signals", false).toBool();
if (log_path.isEmpty()) {
log_path = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/cabana_live_stream/";
}
Settings::Settings() {
last_dir = last_route_dir = QDir::homePath();
log_path = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/cabana_live_stream/";
settings_op([](QSettings &s, const QString &key, auto &value) {
if (auto v = s.value(key); v.canConvert<std::decay_t<decltype(value)>>())
value = v.value<std::decay_t<decltype(value)>>();
});
}
Settings::~Settings() {
settings_op([](QSettings &s, const QString &key, auto &v) { s.setValue(key, v); });
}
// SettingsDlg
@ -75,45 +61,39 @@ SettingsDlg::SettingsDlg(QWidget *parent) : QDialog(parent) {
QGroupBox *groupbox = new QGroupBox("General");
QFormLayout *form_layout = new QFormLayout(groupbox);
theme = new QComboBox(this);
form_layout->addRow(tr("Color Theme"), theme = new QComboBox(this));
theme->setToolTip(tr("You may need to restart cabana after changes theme"));
theme->addItems({tr("Automatic"), tr("Light"), tr("Dark")});
theme->setCurrentIndex(settings.theme);
form_layout->addRow(tr("Color Theme"), theme);
fps = new QSpinBox(this);
form_layout->addRow("FPS", fps = new QSpinBox(this));
fps->setRange(10, 100);
fps->setSingleStep(10);
fps->setValue(settings.fps);
form_layout->addRow("FPS", fps);
cached_minutes = new QSpinBox(this);
form_layout->addRow(tr("Max Cached Minutes"), cached_minutes = new QSpinBox(this));
cached_minutes->setRange(5, 60);
cached_minutes->setSingleStep(1);
cached_minutes->setValue(settings.max_cached_minutes);
form_layout->addRow(tr("Max Cached Minutes"), cached_minutes);
main_layout->addWidget(groupbox);
groupbox = new QGroupBox("New Signal Settings");
form_layout = new QFormLayout(groupbox);
drag_direction = new QComboBox(this);
form_layout->addRow(tr("Drag Direction"), drag_direction = new QComboBox(this));
drag_direction->addItems({tr("MSB First"), tr("LSB First"), tr("Always Little Endian"), tr("Always Big Endian")});
drag_direction->setCurrentIndex(settings.drag_direction);
form_layout->addRow(tr("Drag Direction"), drag_direction);
main_layout->addWidget(groupbox);
groupbox = new QGroupBox("Chart");
form_layout = new QFormLayout(groupbox);
chart_series_type = new QComboBox(this);
form_layout->addRow(tr("Default Series Type"), chart_series_type = new QComboBox(this));
chart_series_type->addItems({tr("Line"), tr("Step Line"), tr("Scatter")});
chart_series_type->setCurrentIndex(settings.chart_series_type);
form_layout->addRow(tr("Chart Default Series Type"), chart_series_type);
chart_height = new QSpinBox(this);
form_layout->addRow(tr("Chart Height"), chart_height = new QSpinBox(this));
chart_height->setRange(100, 500);
chart_height->setSingleStep(10);
chart_height->setValue(settings.chart_height);
form_layout->addRow(tr("Chart Height"), chart_height);
main_layout->addWidget(groupbox);
log_livestream = new QGroupBox(tr("Enable live stream logging"), this);
@ -125,10 +105,9 @@ SettingsDlg::SettingsDlg(QWidget *parent) : QDialog(parent) {
path_layout->addWidget(browse_btn);
main_layout->addWidget(log_livestream);
auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply);
auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
main_layout->addWidget(buttonBox);
main_layout->addStretch(1);
setFixedSize(400, sizeHint().height());
QObject::connect(browse_btn, &QPushButton::clicked, [this]() {
QString fn = QFileDialog::getExistingDirectory(
@ -139,31 +118,22 @@ SettingsDlg::SettingsDlg(QWidget *parent) : QDialog(parent) {
log_path->setText(fn);
}
});
QObject::connect(buttonBox, &QDialogButtonBox::clicked, [=](QAbstractButton *button) {
auto role = buttonBox->buttonRole(button);
if (role == QDialogButtonBox::AcceptRole) {
save();
accept();
} else if (role == QDialogButtonBox::ApplyRole) {
save();
} else if (role == QDialogButtonBox::RejectRole) {
reject();
}
});
QObject::connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
QObject::connect(buttonBox, &QDialogButtonBox::accepted, this, &SettingsDlg::save);
}
void SettingsDlg::save() {
settings.fps = fps->value();
if (std::exchange(settings.theme, theme->currentIndex()) != settings.theme) {
// set theme before emit changed
utils::setTheme(settings.theme);
}
settings.fps = fps->value();
settings.max_cached_minutes = cached_minutes->value();
settings.chart_series_type = chart_series_type->currentIndex();
settings.chart_height = chart_height->value();
settings.log_livestream = log_livestream->isChecked();
settings.log_path = log_path->text();
settings.drag_direction = (Settings::DragDirection)drag_direction->currentIndex();
settings.save();
emit settings.changed();
QDialog::accept();
}

@ -1,13 +1,10 @@
#pragma once
#include <QApplication>
#include <QByteArray>
#include <QCheckBox>
#include <QComboBox>
#include <QDialog>
#include <QGroupBox>
#include <QLineEdit>
#include <QSettings>
#include <QSpinBox>
#define LIGHT_THEME 1
@ -24,10 +21,8 @@ public:
AlwaysBE,
};
Settings() {}
QSettings::Status save();
void load();
inline static QString filePath() { return QApplication::applicationDirPath() + "/settings"; }
Settings();
~Settings();
bool absolute_time = false;
int fps = 10;
@ -49,15 +44,13 @@ public:
QByteArray window_state;
QStringList recent_files;
QByteArray message_header_state;
DragDirection drag_direction;
DragDirection drag_direction = MsbFirst;
signals:
void changed();
};
class SettingsDlg : public QDialog {
Q_OBJECT
public:
SettingsDlg(QWidget *parent);
void save();

@ -2,6 +2,7 @@
#include <vector>
#include <QCheckBox>
#include <QLabel>
#include <QMessageBox>
#include <QPushButton>

@ -4,6 +4,7 @@
#include <limits>
#include <QAbstractTableModel>
#include <QCheckBox>
#include <QLabel>
#include <QPushButton>
#include <QTableView>

Loading…
Cancel
Save