Skip to content

Commit

Permalink
FEAT(client): Settings Profiles (backend)
Browse files Browse the repository at this point in the history
TODO: Write commit message
  • Loading branch information
Hartmnt committed Jan 5, 2025
1 parent e64f334 commit 430c7fa
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/mumble/Global.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ struct Global Q_DECL_FINAL {

MainWindow *mw;
Settings s;
Profiles profiles;
boost::shared_ptr< ServerHandler > sh;
boost::shared_ptr< AudioInput > ai;
boost::shared_ptr< AudioOutput > ao;
Expand Down
15 changes: 15 additions & 0 deletions src/mumble/JSONSerialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,21 @@ void from_json(const nlohmann::json &j, OverlaySettings &settings) {
}


void to_json(nlohmann::json &j, const Profiles &settings) {
#define PROCESS(category, key, variable) save(j, SettingsKeys::key, settings.variable);

PROCESS_ALL_PROFILE_SETTINGS

#undef PROCESS
}

void from_json(const nlohmann::json &j, Profiles &settings) {
#define PROCESS(category, key, variable) load(j, SettingsKeys::key, settings.variable, settings.variable, true);

PROCESS_ALL_PROFILE_SETTINGS

#undef PROCESS
}

void to_json(nlohmann::json &j, const QString &string) {
j = string.toStdString();
Expand Down
2 changes: 2 additions & 0 deletions src/mumble/JSONSerialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ void to_json(nlohmann::json &j, const Settings &settings);
void from_json(const nlohmann::json &j, Settings &settings);
void to_json(nlohmann::json &j, const OverlaySettings &settings);
void from_json(const nlohmann::json &j, OverlaySettings &settings);
void to_json(nlohmann::json &j, const Profiles &settings);
void from_json(const nlohmann::json &j, Profiles &settings);

void to_json(nlohmann::json &j, const QString &string);
void from_json(const nlohmann::json &j, QString &string);
Expand Down
58 changes: 56 additions & 2 deletions src/mumble/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,16 @@ void Settings::save(const QString &path) const {
throw std::runtime_error("Expected settings file to have \".json\" extension");
}

nlohmann::json settingsJSON = *this;
Profiles &profiles = Global::get().profiles;
nlohmann::json settingsJSON = profiles;
nlohmann::json &profilesJSON = settingsJSON.at(SettingsKeys::PROFILES);
nlohmann::json activeProfileJSON = *this;

qInfo("Saving settings profile '%s'", qUtf8Printable(profiles.activeProfileName));

// Replace the settings loaded from disk with the current (possibly modified) settings
profilesJSON.erase(profiles.activeProfileName.toStdString());
profilesJSON.push_back({ profiles.activeProfileName, activeProfileJSON });

QFile tmpFile(QString::fromLatin1("%1/mumble_settings.json.tmp")
.arg(QStandardPaths::writableLocation(QStandardPaths::TempLocation)));
Expand Down Expand Up @@ -216,6 +225,33 @@ void Settings::save() const {
}
}

void Settings::loadProfile(std::optional< QString > requestedProfile) {
Profiles &profiles = Global::get().profiles;

QString profileName;
if (!requestedProfile) {
profileName = profiles.activeProfileName;
} else {
profileName = requestedProfile.value();
}

if (!profiles.allProfiles.contains(profileName)) {
qWarning("Failed to load settings profile '%s'. Falling back to '%s'...", qUtf8Printable(profileName),
qUtf8Printable(Profiles::s_default_profile_name));
profileName = Profiles::s_default_profile_name;

if (!profiles.allProfiles.contains(profileName)) {
qWarning("Failed to load fallback settings profile '%s'", qUtf8Printable(Profiles::s_default_profile_name));
return;
}
}

qInfo("Loading settings profile '%s'", qUtf8Printable(profileName));

*this = profiles.allProfiles[profileName];
profiles.activeProfileName = profileName;
}

void Settings::load(const QString &path) {
if (path.endsWith(QLatin1String(BACKUP_FILE_EXTENSION))) {
// Trim away the backup extension
Expand All @@ -230,7 +266,16 @@ void Settings::load(const QString &path) {
try {
stream >> settingsJSON;

settingsJSON.get_to(*this);
if (settingsJSON.contains(SettingsKeys::ACTIVE_PROFILE)) {
settingsJSON.get_to(Global::get().profiles);
loadProfile();
} else {
// The file does not contain the key "SettingsKeys::ACTIVE_PROFILE"
// We assume the JSON file does not contain any profiles, because it is
// old. We load the file raw instead and convert it to the s_default_profile_name profile.
qWarning("Migrating settings file to 'default' profile");
settingsJSON.get_to(*this);
}

if (!mumbleQuitNormally) {
// These settings were saved without Mumble quitting normally afterwards. In order to prevent loading
Expand Down Expand Up @@ -401,6 +446,8 @@ std::size_t qHash(const ChannelTarget &target) {
return qHash(target.channelID);
}

const QString Profiles::s_default_profile_name = QLatin1String("default");

const QString Settings::cqsDefaultPushClickOn = QLatin1String(":/on.ogg");
const QString Settings::cqsDefaultPushClickOff = QLatin1String(":/off.ogg");

Expand Down Expand Up @@ -1222,6 +1269,7 @@ void Settings::verifySettingsKeys() const {
#define INTERMEDIATE_OPERATION categoryNames.push_back(currentCategoryName);
PROCESS_ALL_SETTINGS_WITH_INTERMEDIATE_OPERATION
PROCESS_ALL_OVERLAY_SETTINGS_WITH_INTERMEDIATE_OPERATION
PROCESS_ALL_PROFILE_SETTINGS_WITH_INTERMEDIATE_OPERATION

// Assert that all entries in categoryNames are unique
std::sort(categoryNames.begin(), categoryNames.end());
Expand All @@ -1241,6 +1289,7 @@ void Settings::verifySettingsKeys() const {
keyNames.clear();
PROCESS_ALL_SETTINGS_WITH_INTERMEDIATE_OPERATION
PROCESS_ALL_OVERLAY_SETTINGS_WITH_INTERMEDIATE_OPERATION
PROCESS_ALL_PROFILE_SETTINGS_WITH_INTERMEDIATE_OPERATION
#undef PROCESS
#undef INTERMEDIATE_OPERATION

Expand All @@ -1255,6 +1304,11 @@ void Settings::verifySettingsKeys() const {
PROCESS_ALL_OVERLAY_SETTINGS
std::sort(variableNames.begin(), variableNames.end());
assert(std::unique(variableNames.begin(), variableNames.end()) == variableNames.end());
variableNames.clear();

PROCESS_ALL_PROFILE_SETTINGS
std::sort(variableNames.begin(), variableNames.end());
assert(std::unique(variableNames.begin(), variableNames.end()) == variableNames.end());
#undef PROCESS
}

Expand Down
10 changes: 10 additions & 0 deletions src/mumble/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@
#include <nlohmann/json_fwd.hpp>

#include <array>
#include <optional>

class QSettings;
struct MigratedPath;
struct Settings;

// Global helper classes to spread variables around across threads
// especially helpful to initialize things like the stored
Expand Down Expand Up @@ -184,6 +186,13 @@ struct OverlaySettings {
friend bool operator!=(const OverlaySettings &lhs, const OverlaySettings &rhs);
};

struct Profiles {
static const QString s_default_profile_name;

QString activeProfileName = s_default_profile_name;
QMap< QString, Settings > allProfiles = {};
};

struct Settings {
enum AudioTransmit { Continuous, VAD, PushToTalk };
enum VADSource { Amplitude, SignalToNoise };
Expand Down Expand Up @@ -566,6 +575,7 @@ struct Settings {
void save(const QString &path) const;
void save() const;

void loadProfile(std::optional< QString > requestedProfile = {});
void load(const QString &path);
void load();

Expand Down
4 changes: 4 additions & 0 deletions src/mumble/SettingsKeys.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ namespace SettingsKeys {
* loading settings.
*/

// Meta
const SettingsKey ACTIVE_PROFILE = { "active_profile" };
const SettingsKey PROFILES = { "profiles" };

// Audio settings
const SettingsKey UNMUTE_ON_UNDEAF_KEY = { "unmute_on_undeaf" };
const SettingsKey MUTE_KEY = { "mute" };
Expand Down
9 changes: 9 additions & 0 deletions src/mumble/SettingsMacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@

// Mappings between SettingsKey objects and the corresponding fields in the Settings struct

#define PROFILE_SETTINGS \
PROCESS(profiles, ACTIVE_PROFILE, activeProfileName) \
PROCESS(profiles, PROFILES, allProfiles)

#define MISC_SETTINGS \
PROCESS(misc, DATABASE_LOCATION_KEY, qsDatabaseLocation) \
PROCESS(misc, IMAGE_DIRECTORY_KEY, qsImagePath) \
Expand Down Expand Up @@ -342,6 +346,7 @@

#define PROCESS_ALL_OVERLAY_SETTINGS OVERLAY_SETTINGS

#define PROCESS_ALL_PROFILE_SETTINGS PROFILE_SETTINGS

#define PROCESS_ALL_SETTINGS_WITH_INTERMEDIATE_OPERATION \
MISC_SETTINGS \
Expand Down Expand Up @@ -391,5 +396,9 @@
OVERLAY_SETTINGS \
INTERMEDIATE_OPERATION

#define PROCESS_ALL_PROFILE_SETTINGS_WITH_INTERMEDIATE_OPERATION \
PROFILE_SETTINGS \
INTERMEDIATE_OPERATION


#endif // MUMBLE_MUMBLE_SETTINGS_MACROS_H_

0 comments on commit 430c7fa

Please sign in to comment.