save config back to soundboard.json

This commit is contained in:
mrbesen 2021-12-20 21:59:20 +01:00
parent 1ebc965066
commit be931de6d0
Signed by untrusted user: MrBesen
GPG Key ID: 596B2350DCD67504
6 changed files with 166 additions and 62 deletions

View File

@ -9,8 +9,8 @@ public:
Config(const std::string binaryArgument);
~Config();
bool hasChanged();
void load();
void save();
struct AudioConfig {
std::vector<std::string> devices;
@ -33,6 +33,7 @@ public:
std::vector<SampleConfig> samples;
bool isValid() const;
const static uint8_t DEFAULTWIDTH = 6;
};
struct RootConfig {

View File

@ -35,6 +35,7 @@ public slots:
private slots:
void alwaysOnTopSettingChange(int status);
void addSample();
void saveConfig();
signals:
void newStatusMessage(const QString&);

View File

@ -10,14 +10,11 @@
#include <nlohmann/json.hpp>
using json = nlohmann::json;
#include <iomanip>
#include <Log.h>
template<typename T>
static void readVector(std::vector<T>& v, const json& j) {
v.clear();
v.reserve(j.size());
std::copy(j.begin(), j.end(), std::insert_iterator<std::vector<T>>(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<Config::AudioConfig>("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<Config::ButtonConfig> 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";
}
}

120
src/config_json.cpp Normal file
View File

@ -0,0 +1,120 @@
// This file contains the json parsing components required for the config to work
#include <nlohmann/json.hpp>
using json = nlohmann::json;
#include "config.h"
// json::array -> std::vector
template<typename T>
static void readVector(std::vector<T>& v, const json& j) {
v.clear();
v.reserve(j.size());
std::copy(j.begin(), j.end(), std::insert_iterator<std::vector<T>>(v, v.begin()));
}
// std::vector -> json::array
template<typename T>
static void writeVector(json& j, const std::vector<T>& v) {
j = json::array();
std::copy(v.begin(), v.end(), std::insert_iterator<json>(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<Config::AudioConfig>("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<Config::ButtonConfig> 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<Config::ButtonConfig>& 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;
}

View File

@ -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

View File

@ -40,16 +40,6 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="addButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>+</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@ -90,8 +80,32 @@
<height>24</height>
</rect>
</property>
<widget class="QMenu" name="menuEdit">
<property name="title">
<string>Edit</string>
</property>
<addaction name="actionAddButton"/>
<addaction name="actionSaveConfig"/>
</widget>
<addaction name="menuEdit"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="actionAddButton">
<property name="text">
<string>AddButton</string>
</property>
<property name="shortcut">
<string>Ctrl+A</string>
</property>
</action>
<action name="actionSaveConfig">
<property name="text">
<string>SaveConfig</string>
</property>
<property name="shortcut">
<string>Ctrl+S</string>
</property>
</action>
</widget>
<resources/>
<connections/>