save config back to soundboard.json
This commit is contained in:
parent
1ebc965066
commit
be931de6d0
|
@ -9,8 +9,8 @@ public:
|
||||||
Config(const std::string binaryArgument);
|
Config(const std::string binaryArgument);
|
||||||
~Config();
|
~Config();
|
||||||
|
|
||||||
bool hasChanged();
|
|
||||||
void load();
|
void load();
|
||||||
|
void save();
|
||||||
|
|
||||||
struct AudioConfig {
|
struct AudioConfig {
|
||||||
std::vector<std::string> devices;
|
std::vector<std::string> devices;
|
||||||
|
@ -33,6 +33,7 @@ public:
|
||||||
std::vector<SampleConfig> samples;
|
std::vector<SampleConfig> samples;
|
||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
const static uint8_t DEFAULTWIDTH = 6;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RootConfig {
|
struct RootConfig {
|
||||||
|
|
|
@ -35,6 +35,7 @@ public slots:
|
||||||
private slots:
|
private slots:
|
||||||
void alwaysOnTopSettingChange(int status);
|
void alwaysOnTopSettingChange(int status);
|
||||||
void addSample();
|
void addSample();
|
||||||
|
void saveConfig();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void newStatusMessage(const QString&);
|
void newStatusMessage(const QString&);
|
||||||
|
|
|
@ -10,14 +10,11 @@
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
#include <Log.h>
|
#include <Log.h>
|
||||||
|
|
||||||
template<typename T>
|
#include "config_json.cpp" // json parsing in diffrent file
|
||||||
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()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Config::Config(const std::string binaryArgument) {
|
Config::Config(const std::string binaryArgument) {
|
||||||
char* buff = realpath(binaryArgument.c_str(), NULL); // buff needs free !
|
char* buff = realpath(binaryArgument.c_str(), NULL); // buff needs free !
|
||||||
|
@ -36,50 +33,6 @@ Config::Config(const std::string binaryArgument) {
|
||||||
Config::~Config() {
|
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 {
|
bool Config::SampleConfig::isValid() const {
|
||||||
return !file.empty();
|
return !file.empty();
|
||||||
}
|
}
|
||||||
|
@ -104,3 +57,13 @@ void Config::load() {
|
||||||
Log::error << "config File not found";
|
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";
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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->reloadButton, SIGNAL(clicked()), this, SLOT(reloadConfig()));
|
||||||
QObject::connect(ui->stopButton, SIGNAL( clicked() ), this, SLOT( stop() ));
|
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(ui->allwaysOnTop, SIGNAL( stateChanged(int) ), this, SLOT( alwaysOnTopSettingChange(int) ));
|
||||||
QObject::connect(stopGlobal, SIGNAL( activated() ), this, SLOT( stop() ));
|
QObject::connect(stopGlobal, SIGNAL( activated() ), this, SLOT( stop() ));
|
||||||
QObject::connect(this, SIGNAL(newStatusMessage(const QString&)), ui->statusbar, SLOT(showMessage(const QString&)));
|
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() {
|
void MainWindow::loadSoundFromConfig() {
|
||||||
Sound& sound = Sound::instance(); // init sound
|
Sound& sound = Sound::instance(); // init sound
|
||||||
|
|
|
@ -40,16 +40,6 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="addButton">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>+</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -90,8 +80,32 @@
|
||||||
<height>24</height>
|
<height>24</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</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>
|
||||||
<widget class="QStatusBar" name="statusbar"/>
|
<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>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|
Loading…
Reference in New Issue