Cockatrice/libcockatrice_settings/libcockatrice/settings/settings_manager.cpp
BruebachL 5134e72eb4
[Settings] Store server profiles with QSettings arrays (#7629)
The server list used hand-numbered saveName%1/server%1 keys and an O(n)
shift loop to delete entries. Store the profiles with beginReadArray and
beginWriteArray instead, and migrate the legacy keys once in the
constructor so existing profiles and saved passwords survive.

SettingsManager::batchWrite no longer disables atomic sync, so a batch is
still written through QSettings' atomic save. Add tests for add, update,
remove, password updates and the legacy migration.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-11-02 07:30:29 +01:00

212 lines
4.8 KiB
C++

#include "settings_manager.h"
SettingsManager::SettingsManager(const QString &_settingPath,
const QString &_defaultGroup,
const QString &_defaultSubGroup,
QObject *parent)
: QObject(parent), settingPath(_settingPath), defaultGroup(_defaultGroup), defaultSubGroup(_defaultSubGroup)
{
}
QSettings SettingsManager::getSettings() const
{
// Do not store the QSettings instance in a field, as that is not threadsafe (see #6747)
return QSettings(settingPath, QSettings::IniFormat);
}
void SettingsManager::setValue(const QVariant &value, const QString &name)
{
auto settings = getSettings();
if (!defaultGroup.isEmpty()) {
settings.beginGroup(defaultGroup);
}
if (!defaultSubGroup.isEmpty()) {
settings.beginGroup(defaultSubGroup);
}
settings.setValue(name, value);
if (!defaultSubGroup.isEmpty()) {
settings.endGroup();
}
if (!defaultGroup.isEmpty()) {
settings.endGroup();
}
}
void SettingsManager::setValue(const QVariant &value,
const QString &name,
const QString &group,
const QString &subGroup)
{
auto settings = getSettings();
if (!group.isEmpty()) {
settings.beginGroup(group);
}
if (!subGroup.isEmpty()) {
settings.beginGroup(subGroup);
}
settings.setValue(name, value);
if (!subGroup.isEmpty()) {
settings.endGroup();
}
if (!group.isEmpty()) {
settings.endGroup();
}
}
void SettingsManager::deleteValue(const QString &name)
{
auto settings = getSettings();
if (!defaultGroup.isEmpty()) {
settings.beginGroup(defaultGroup);
}
if (!defaultSubGroup.isEmpty()) {
settings.beginGroup(defaultSubGroup);
}
settings.remove(name);
if (!defaultSubGroup.isEmpty()) {
settings.endGroup();
}
if (!defaultGroup.isEmpty()) {
settings.endGroup();
}
}
void SettingsManager::deleteValue(const QString &name, const QString &group, const QString &subGroup)
{
auto settings = getSettings();
if (!group.isEmpty()) {
settings.beginGroup(group);
}
if (!subGroup.isEmpty()) {
settings.beginGroup(subGroup);
}
settings.remove(name);
if (!subGroup.isEmpty()) {
settings.endGroup();
}
if (!group.isEmpty()) {
settings.endGroup();
}
}
QVariant SettingsManager::getValue(const QString &name) const
{
auto settings = getSettings();
if (!defaultGroup.isEmpty()) {
settings.beginGroup(defaultGroup);
}
if (!defaultSubGroup.isEmpty()) {
settings.beginGroup(defaultSubGroup);
}
QVariant value = settings.value(name);
if (!defaultSubGroup.isEmpty()) {
settings.endGroup();
}
if (!defaultGroup.isEmpty()) {
settings.endGroup();
}
return value;
}
QVariant SettingsManager::getValue(const QString &name, const QString &group, const QString &subGroup) const
{
auto settings = getSettings();
QString effectiveGroup = group.isEmpty() ? defaultGroup : group;
QString effectiveSubGroup = subGroup.isEmpty() ? defaultSubGroup : subGroup;
if (!effectiveGroup.isEmpty()) {
settings.beginGroup(effectiveGroup);
}
if (!effectiveSubGroup.isEmpty()) {
settings.beginGroup(effectiveSubGroup);
}
QVariant value = settings.value(name);
if (!effectiveSubGroup.isEmpty()) {
settings.endGroup();
}
if (!effectiveGroup.isEmpty()) {
settings.endGroup();
}
return value;
}
QVariant SettingsManager::getValue(const QString &name,
const QString &group,
const QString &subGroup,
const QVariant &defaultValue) const
{
auto settings = getSettings();
QString effectiveGroup = group.isEmpty() ? defaultGroup : group;
QString effectiveSubGroup = subGroup.isEmpty() ? defaultSubGroup : subGroup;
if (!effectiveGroup.isEmpty()) {
settings.beginGroup(effectiveGroup);
}
if (!effectiveSubGroup.isEmpty()) {
settings.beginGroup(effectiveSubGroup);
}
QVariant value = settings.value(name, defaultValue);
if (!effectiveSubGroup.isEmpty()) {
settings.endGroup();
}
if (!effectiveGroup.isEmpty()) {
settings.endGroup();
}
return value;
}
QSettings::Status SettingsManager::batchWrite(std::function<void(QSettings &)> batchWriteFunction)
{
auto settings = getSettings();
batchWriteFunction(settings);
settings.sync(); // single flush
return settings.status();
}
/**
* Calls sync on the underlying QSettings object
*/
void SettingsManager::sync()
{
auto settings = getSettings();
settings.sync();
}