184 lines
6.8 KiB
C++
184 lines
6.8 KiB
C++
/****************************************************************************
|
|
** ScStw Libraries
|
|
** Copyright (C) 2020 Itsblue development
|
|
**
|
|
** This program 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.
|
|
**
|
|
** This program 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 "../headers/scstwsettings.h"
|
|
|
|
ScStwSettings::ScStwSettings(QObject *parent, bool overwriteFileOnErrors) : QObject(parent)
|
|
{
|
|
#ifdef RASPI
|
|
QString path = "/root/.config/ScStwBasestation";
|
|
#else
|
|
QString path = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
|
|
#endif
|
|
QDir dir(path);
|
|
if(!dir.mkpath(path))
|
|
qFatal("[FATAL] Failed to create writable directory for settings at %s", qPrintable(path));
|
|
|
|
this->settingsFile = new QFile(path + "/settings.json");
|
|
this->fileIsReadonly = false;
|
|
|
|
if(!this->settingsFile->open(QFile::ReadWrite))
|
|
qFatal("[FATAL] Couldn't open settings file %s", qPrintable(path + "/settings.json"));
|
|
|
|
if(this->settingsFile->size() != 0 && !this->loadSettingsFromFile()) {
|
|
if(overwriteFileOnErrors) {
|
|
this->writeSettingsToFile();
|
|
qWarning("[WARNING] Settings file (%s) was of invalid format and therefore overwritten!", qPrintable(path + "/settings.json"));
|
|
}
|
|
else {
|
|
qWarning("[WARNING] Settings file (%s) was of invalid format!", qPrintable(path + "/settings.json"));
|
|
this->fileIsReadonly = true;
|
|
}
|
|
}
|
|
|
|
connect(this, &ScStwSettings::settingChanged, this, &ScStwSettings::writeSettingsToFile);
|
|
|
|
this->registerKeyLevelConverters(ScStwSettings::KeyLevel, &ScStwSettings::keyToString, &ScStwSettings::keyToType);
|
|
|
|
this->setDefaultSetting(ScStwSettings::BaseStationSetting::ReadySoundEnableSetting, false);
|
|
this->setDefaultSetting(ScStwSettings::BaseStationSetting::ReadySoundDelaySetting, 0);
|
|
this->setDefaultSetting(ScStwSettings::BaseStationSetting::AtYourMarksSoundEnableSetting, false);
|
|
this->setDefaultSetting(ScStwSettings::BaseStationSetting::AtYourMarksSoundDelaySetting, 0);
|
|
this->setDefaultSetting(ScStwSettings::SoundVolumeSetting, 1);
|
|
this->setDefaultSetting(ScStwSettings::CompetitionModeSetting, false);
|
|
}
|
|
|
|
QVariant ScStwSettings::readSetting(BaseStationSetting key) {
|
|
return this->readSetting(key, 0);
|
|
}
|
|
|
|
QVariant ScStwSettings::readSetting(int key, int keyLevel) {
|
|
if(this->keyToStringConverters.contains(keyLevel))
|
|
return this->readSetting(this->keyToStringConverters[keyLevel](key), key, keyLevel);
|
|
else
|
|
return QVariant();
|
|
}
|
|
|
|
bool ScStwSettings::writeSetting(BaseStationSetting key, QVariant value) {
|
|
return this->writeSetting(key, 0, value);
|
|
}
|
|
|
|
bool ScStwSettings::writeSetting(int key, int keyLevel, QVariant value) {
|
|
if(this->keyToStringConverters.contains(keyLevel))
|
|
return this->writeSetting(this->keyToStringConverters[keyLevel](key), value, key, keyLevel);
|
|
else
|
|
return false;
|
|
}
|
|
|
|
bool ScStwSettings::setDefaultSetting(BaseStationSetting key, QVariant defaultValue) {
|
|
return this->setDefaultSetting(key, 0, defaultValue);
|
|
}
|
|
|
|
bool ScStwSettings::setDefaultSetting(int key, int keyLevel, QVariant defaultValue) {
|
|
if(this->keyToStringConverters.contains(keyLevel))
|
|
return this->setDefaultSetting(this->keyToStringConverters[keyLevel](key), defaultValue, key, keyLevel);
|
|
else
|
|
return false;
|
|
}
|
|
|
|
QVariant ScStwSettings::readSetting(QString key, int keyInt, int keyLevel) {
|
|
Q_UNUSED(keyInt)
|
|
Q_UNUSED(keyLevel)
|
|
|
|
if(this->settingsCache.contains(key))
|
|
return this->settingsCache[key];
|
|
else
|
|
return QVariant();
|
|
}
|
|
|
|
bool ScStwSettings::writeSetting(QString key, QVariant value, int keyInt, int keyLevel) {
|
|
|
|
// check if the value type is valid
|
|
if(!this->keyToTypeConverters.contains(keyLevel) || !value.convert(this->keyToTypeConverters[keyLevel](keyInt)) || value.type() == QVariant::Invalid) {
|
|
return false;
|
|
}
|
|
|
|
// write the setting
|
|
if(!this->settingsCache.contains(key))
|
|
this->settingsCache.insert(key, value);
|
|
else if (this->settingsCache[key] == value)
|
|
return true;
|
|
else
|
|
this->settingsCache[key] = value;
|
|
|
|
emit this->settingChanged(keyInt, keyLevel, value);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ScStwSettings::setDefaultSetting(QString key, QVariant defaultValue, int keyInt, int keyLevel) {
|
|
if(!this->settingsCache.contains(key))
|
|
return this->writeSetting(key, defaultValue, keyInt, keyLevel);
|
|
return true;
|
|
}
|
|
|
|
ScStwSetting * ScStwSettings::getSetting(int key, int keyLevel) {
|
|
if(!this->internalSettingHandlers.contains(keyLevel))
|
|
this->internalSettingHandlers.insert(keyLevel, {});
|
|
|
|
if(!this->internalSettingHandlers[keyLevel].contains(key))
|
|
this->internalSettingHandlers[keyLevel].insert(key, new ScStwSetting(key, keyLevel, this, this));
|
|
|
|
return this->internalSettingHandlers[keyLevel][key];
|
|
}
|
|
|
|
bool ScStwSettings::registerKeyLevelConverters(int keyLevel, keyToStringConverter keyToStringConverterFunction, keyToTypeConverter keyToTypeConverterFunction) {
|
|
if(this->keyToStringConverters.contains(keyLevel))
|
|
return false;
|
|
|
|
this->keyToStringConverters.insert(keyLevel, keyToStringConverterFunction);
|
|
this->keyToTypeConverters.insert(keyLevel, keyToTypeConverterFunction);
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* File handling
|
|
*/
|
|
|
|
bool ScStwSettings::writeSettingsToFile() {
|
|
if(this->fileIsReadonly) {
|
|
qWarning() << "[WARNING][SETTINS] Cannot write changes to file! It has been marked readonly due to parse errors (see above).";
|
|
return false;
|
|
}
|
|
|
|
QJsonDocument doc = QJsonDocument::fromVariant(this->settingsCache);
|
|
|
|
// overwrite file
|
|
this->settingsFile->resize(0);
|
|
this->settingsFile->reset();
|
|
this->settingsFile->write(doc.toJson(QJsonDocument::Indented));
|
|
this->settingsFile->flush();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ScStwSettings::loadSettingsFromFile() {
|
|
QJsonParseError error;
|
|
QJsonDocument doc = QJsonDocument::fromJson(this->settingsFile->readAll(), &error);
|
|
|
|
if(error.error != QJsonParseError::NoError) {
|
|
qWarning() << "[ERROR][SETTINGS] Error when parsing settings file: " << error.errorString() << " at offset " << error.offset;
|
|
return false;
|
|
}
|
|
|
|
if(doc.toVariant().type() != QVariant::Map)
|
|
return false;
|
|
|
|
this->settingsCache = doc.toVariant().toMap();
|
|
return true;
|
|
}
|