From be931de6d0907041c4c1d2cdc5ab44154850e7cf Mon Sep 17 00:00:00 2001 From: mrbesen Date: Mon, 20 Dec 2021 21:59:20 +0100 Subject: [PATCH] save config back to soundboard.json --- include/config.h | 3 +- include/mainwindow.h | 1 + src/config.cpp | 63 +++++------------------ src/config_json.cpp | 120 +++++++++++++++++++++++++++++++++++++++++++ src/mainwindow.cpp | 7 ++- ui/mainwindow.ui | 34 ++++++++---- 6 files changed, 166 insertions(+), 62 deletions(-) create mode 100644 src/config_json.cpp diff --git a/include/config.h b/include/config.h index a847be3..48cd1a5 100644 --- a/include/config.h +++ b/include/config.h @@ -9,8 +9,8 @@ public: Config(const std::string binaryArgument); ~Config(); - bool hasChanged(); void load(); + void save(); struct AudioConfig { std::vector devices; @@ -33,6 +33,7 @@ public: std::vector samples; bool isValid() const; + const static uint8_t DEFAULTWIDTH = 6; }; struct RootConfig { diff --git a/include/mainwindow.h b/include/mainwindow.h index 77a8452..2099aaf 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -35,6 +35,7 @@ public slots: private slots: void alwaysOnTopSettingChange(int status); void addSample(); + void saveConfig(); signals: void newStatusMessage(const QString&); diff --git a/src/config.cpp b/src/config.cpp index 3ca8c81..64283f6 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -10,14 +10,11 @@ #include using json = nlohmann::json; +#include + #include -template -static void readVector(std::vector& v, const json& j) { - v.clear(); - v.reserve(j.size()); - std::copy(j.begin(), j.end(), std::insert_iterator>(v, v.begin())); -} +#include "config_json.cpp" // json parsing in diffrent file Config::Config(const std::string binaryArgument) { char* buff = realpath(binaryArgument.c_str(), NULL); // buff needs free ! @@ -36,50 +33,6 @@ Config::Config(const std::string binaryArgument) { Config::~Config() { } -void from_json(const json& j, Config::AudioConfig& ac) { - readVector(ac.devices, j.value("devices", json::array())); -} - -void from_json(const json& j, Config::SampleConfig& sc) { - sc.file = j.value("file", ""); - sc.offset = j.value("offset", 0); - sc.length = j.value("length", 0); - sc.volume = j.value("volume", 1.f); -} - -void from_json(const json& j, Config::ButtonConfig& bc) { - bc.name = j.value("name", ""); - bc.key = j.value("key", ""); - bc.width = j.value("width", 6); - - // make it possible to volume control all samples from one value - float volume = j.value("value", 1.0); - - if(j.contains("samples")) { - // sample liste - readVector(bc.samples, j["samples"]); - for(Config::SampleConfig& sc : bc.samples) { - sc.volume *= volume; - } - } else if(j.contains("file")) { - bc.samples.push_back(j); // implizit cast - } -} - -void from_json(const json& j, Config::RootConfig& rc) { - rc.audio = j.value("audio", {}); - json barr = j.value("buttons", json::array()); - if(barr.is_array() && !barr.empty()) { - rc.buttons.reserve(barr.size()); - for(const json& line : barr) { - std::vector btns; - readVector(btns, line); - rc.buttons.push_back(btns); - } - } - rc.audioPath = j.value("audioPath", ""); -} - bool Config::SampleConfig::isValid() const { return !file.empty(); } @@ -104,3 +57,13 @@ void Config::load() { Log::error << "config File not found"; } } + +void Config::save() { + std::ofstream stream(binaryPath + file); + if(stream) { + json j = rootConfig; + stream << j.dump(1, '\t'); + } else { + Log::error << "could not write configfile"; + } +} \ No newline at end of file diff --git a/src/config_json.cpp b/src/config_json.cpp new file mode 100644 index 0000000..5779c6a --- /dev/null +++ b/src/config_json.cpp @@ -0,0 +1,120 @@ +// This file contains the json parsing components required for the config to work + +#include +using json = nlohmann::json; + +#include "config.h" + +// json::array -> std::vector +template +static void readVector(std::vector& v, const json& j) { + v.clear(); + v.reserve(j.size()); + std::copy(j.begin(), j.end(), std::insert_iterator>(v, v.begin())); +} + +// std::vector -> json::array +template +static void writeVector(json& j, const std::vector& v) { + j = json::array(); + std::copy(v.begin(), v.end(), std::insert_iterator(j, j.begin())); +} + +void from_json(const json& j, Config::AudioConfig& ac) { + readVector(ac.devices, j.value("devices", json::array())); +} + +void from_json(const json& j, Config::SampleConfig& sc) { + sc.file = j.value("file", ""); + sc.offset = j.value("offset", 0); + sc.length = j.value("length", 0); + sc.volume = j.value("volume", 1.f); +} + +void from_json(const json& j, Config::ButtonConfig& bc) { + bc.name = j.value("name", ""); + bc.key = j.value("key", ""); + bc.width = j.value("width", Config::ButtonConfig::DEFAULTWIDTH); + + // make it possible to volume control all samples from one value + float volume = j.value("value", 1.0); + + if(j.contains("samples")) { + // sample liste + readVector(bc.samples, j["samples"]); + for(Config::SampleConfig& sc : bc.samples) { + sc.volume *= volume; + } + } else if(j.contains("file")) { + bc.samples.push_back(j); // implizit cast + } +} + +void from_json(const json& j, Config::RootConfig& rc) { + rc.audio = j.value("audio", {}); + json barr = j.value("buttons", json::array()); + if(barr.is_array() && !barr.empty()) { + rc.buttons.reserve(barr.size()); + for(const json& line : barr) { + std::vector btns; + readVector(btns, line); + rc.buttons.push_back(btns); + } + } + rc.audioPath = j.value("audioPath", ""); +} + + +void to_json(json& j, const Config::AudioConfig& ac) { + json devarr = json::array(); + writeVector(devarr, ac.devices); + j["devices"] = devarr; +} + +void to_json(json& j, const Config::SampleConfig& sc) { + j["file"] = sc.file; + if(sc.offset != 0) + j["offset"] = sc.offset; + if(sc.length != 0) + j["length"] = sc.length; + if(sc.volume != 1.f) + j["volume"] = sc.volume; +} + +void to_json(json& j, const Config::ButtonConfig& bc) { + j["name"] = bc.name; + + if(!bc.key.empty()) + j["key"] = bc.key; + + if(bc.width != Config::ButtonConfig::DEFAULTWIDTH) + j["width"] = bc.width; + + if(bc.samples.size() == 1) { + //dont use a json array when only one sample is present (inline instead) + to_json(j, bc.samples.at(0)); + } else if(!bc.samples.empty()) { + json samples = json::array(); + writeVector(samples, bc.samples); + j["samples"] = samples; + } +} + +void to_json(json& j, const Config::RootConfig& rc) { + j["audio"] = rc.audio; + j["audioPath"] = rc.audioPath; + json buttonarr = json::array(); + + for(const std::vector& row : rc.buttons) { + if(row.empty()) continue; + json jsonrow = json::array(); + + for(const Config::ButtonConfig& btn : row) { + jsonrow.push_back(btn); // implicit convert btn to json + } + + buttonarr.push_back(jsonrow); + } + + j["buttons"] = buttonarr; +} \ No newline at end of file diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 0e3ce0d..971e772 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -26,7 +26,8 @@ MainWindow::MainWindow(const std::string& binary, QWidget* parent) : QMainWindow QObject::connect(ui->reloadButton, SIGNAL(clicked()), this, SLOT(reloadConfig())); QObject::connect(ui->stopButton, SIGNAL( clicked() ), this, SLOT( stop() )); - QObject::connect(ui->addButton, SIGNAL( clicked() ), this, SLOT( addSample() )); + QObject::connect(ui->actionAddButton, SIGNAL( triggered() ), this, SLOT( addSample() )); + QObject::connect(ui->actionSaveConfig, SIGNAL( triggered() ), this, SLOT( saveConfig() )); QObject::connect(ui->allwaysOnTop, SIGNAL( stateChanged(int) ), this, SLOT( alwaysOnTopSettingChange(int) )); QObject::connect(stopGlobal, SIGNAL( activated() ), this, SLOT( stop() )); QObject::connect(this, SIGNAL(newStatusMessage(const QString&)), ui->statusbar, SLOT(showMessage(const QString&))); @@ -158,6 +159,10 @@ void MainWindow::addSample() { } } +void MainWindow::saveConfig() { + Log::info << "save Config"; + config.save(); +} void MainWindow::loadSoundFromConfig() { Sound& sound = Sound::instance(); // init sound diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index b845542..d0ae413 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -40,16 +40,6 @@ - - - - true - - - + - - - @@ -90,8 +80,32 @@ 24 + + + Edit + + + + + + + + AddButton + + + Ctrl+A + + + + + SaveConfig + + + Ctrl+S + +