feat: New Settings class
This commit is contained in:
@ -16,10 +16,11 @@ add_library(common STATIC
|
|||||||
stdpre.h
|
stdpre.h
|
||||||
stdset.h
|
stdset.h
|
||||||
stdvector.h
|
stdvector.h
|
||||||
|
Settings.h
|
||||||
|
Settings.cpp
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/constants.h
|
${CMAKE_CURRENT_BINARY_DIR}/constants.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(common PROPERTIES LINKER_LANGUAGE CXX)
|
|
||||||
target_link_libraries(common PUBLIC Qt6::Core)
|
target_link_libraries(common PUBLIC Qt6::Core)
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
|
|||||||
158
src/lib/common/Settings.cpp
Normal file
158
src/lib/common/Settings.cpp
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* Deskflow -- mouse and keyboard sharing utility
|
||||||
|
* SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
|
Settings *Settings::instance()
|
||||||
|
{
|
||||||
|
static Settings m;
|
||||||
|
return &m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::setSettingFile(const QString &settingsFile)
|
||||||
|
{
|
||||||
|
if (instance()->m_portableSettingsFile == settingsFile) {
|
||||||
|
qDebug().noquote() << "settings file already in use";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance()->m_portableSettingsFile = settingsFile;
|
||||||
|
if (instance()->m_settings)
|
||||||
|
instance()->m_settings->deleteLater();
|
||||||
|
instance()->m_settings = new QSettings(instance()->m_portableSettingsFile, QSettings::IniFormat);
|
||||||
|
qInfo().noquote() << "settings file:" << instance()->m_settings->fileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings::Settings(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
m_portableSettingsFile = QStringLiteral("settings.ini");
|
||||||
|
if (QFile(m_portableSettingsFile).exists()) {
|
||||||
|
m_settings = new QSettings(m_portableSettingsFile, QSettings::IniFormat);
|
||||||
|
qInfo().noquote() << "settings file:" << m_settings->fileName();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
initSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::isPortableSettings()
|
||||||
|
{
|
||||||
|
return (QFile(instance()->m_portableSettingsFile).exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::initSettings()
|
||||||
|
{
|
||||||
|
if (m_settings)
|
||||||
|
m_settings->deleteLater();
|
||||||
|
|
||||||
|
const auto userScopeCheck = QSettings(UserSettingFile, QSettings::IniFormat).value(Core::Scope).toBool();
|
||||||
|
const auto systemScopeCheck = QSettings(SystemSettingFile, QSettings::IniFormat).value(Core::Scope).toBool();
|
||||||
|
const auto systemScope = (userScopeCheck && systemScopeCheck);
|
||||||
|
m_settings = new QSettings(systemScope ? SystemSettingFile : UserSettingFile, QSettings::IniFormat);
|
||||||
|
qInfo().noquote() << "settings file:" << m_settings->fileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::cleanSettings()
|
||||||
|
{
|
||||||
|
const QStringList keys = m_settings->allKeys();
|
||||||
|
for (const QString &key : keys) {
|
||||||
|
if (!m_validKeys.contains(key))
|
||||||
|
m_settings->remove(key);
|
||||||
|
if (m_settings->value(key).toString().isEmpty() && !m_settings->value(key).isValid())
|
||||||
|
m_settings->remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant Settings::defaultValue(const QString &key)
|
||||||
|
{
|
||||||
|
if (key == Core::Scope) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::isWritable()
|
||||||
|
{
|
||||||
|
return instance()->m_settings->isWritable();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::isSystemScope()
|
||||||
|
{
|
||||||
|
if (isPortableSettings()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return instance()->settingsFile() == SystemSettingFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::setScope(bool systemScope)
|
||||||
|
{
|
||||||
|
if (isPortableSettings()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (systemScope == isSystemScope())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const bool wasWritable = instance()->m_settings->isWritable();
|
||||||
|
|
||||||
|
QSettings userSettings(Settings::UserSettingFile, QSettings::IniFormat);
|
||||||
|
userSettings.setValue(Settings::Core::Scope, systemScope);
|
||||||
|
userSettings.sync();
|
||||||
|
|
||||||
|
QSettings systemSettings(Settings::SystemSettingFile, QSettings::IniFormat);
|
||||||
|
systemSettings.setValue(Settings::Core::Scope, systemScope);
|
||||||
|
systemSettings.sync();
|
||||||
|
|
||||||
|
instance()->initSettings();
|
||||||
|
|
||||||
|
const bool isWritable = instance()->m_settings->isWritable();
|
||||||
|
|
||||||
|
if (isWritable != wasWritable)
|
||||||
|
Q_EMIT instance()->writableChanged(isWritable);
|
||||||
|
|
||||||
|
Q_EMIT instance()->scopeChanged(systemScope);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString Settings::settingsFile()
|
||||||
|
{
|
||||||
|
return instance()->m_settings->fileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString Settings::settingsPath()
|
||||||
|
{
|
||||||
|
return QFileInfo(instance()->m_settings->fileName()).absolutePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::setValue(const QString &key, const QVariant &value)
|
||||||
|
{
|
||||||
|
if (instance()->m_settings->value(key) == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!value.isValid())
|
||||||
|
instance()->m_settings->remove(key);
|
||||||
|
else if (key == Core::Scope) {
|
||||||
|
instance()->setScope(value.value<QSettings::Scope>());
|
||||||
|
} else {
|
||||||
|
instance()->m_settings->setValue(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
instance()->m_settings->sync();
|
||||||
|
Q_EMIT instance()->settingsChanged(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant Settings::value(const QString &key)
|
||||||
|
{
|
||||||
|
return instance()->m_settings->value(key, defaultValue(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::restoreDefaultSettings()
|
||||||
|
{
|
||||||
|
for (const auto &key : m_validKeys) {
|
||||||
|
instance()->setValue(key, defaultValue(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
67
src/lib/common/Settings.h
Normal file
67
src/lib/common/Settings.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Deskflow -- mouse and keyboard sharing utility
|
||||||
|
* SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#include "common/constants.h"
|
||||||
|
|
||||||
|
class Settings : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
inline const static auto UserSettingFile =
|
||||||
|
QStringLiteral("%1/AppData/Local/%2/%3.conf").arg(QDir::homePath(), kAppName, kAppName);
|
||||||
|
inline const static auto SystemSettingFile = QStringLiteral("C:/ProgramData/%2/%3.conf").arg(kAppName, kAppName);
|
||||||
|
#elif defined(Q_OS_MAC)
|
||||||
|
inline const static auto UserSettingFile =
|
||||||
|
QStringLiteral("%1/Library/%2/%3.conf").arg(QDir::homePath(), kAppName, kAppName);
|
||||||
|
inline const static auto SystemSettingFile = QStringLiteral("/Libaray/%2/%3.conf").arg(kAppName, kAppName);
|
||||||
|
#else
|
||||||
|
inline const static auto UserSettingFile =
|
||||||
|
QStringLiteral("%1/.config/%2/%3.conf").arg(QDir::homePath(), kAppName, kAppName);
|
||||||
|
inline const static auto SystemSettingFile = QStringLiteral("/etc/%2/%3.conf").arg(kAppName, kAppName);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct Core
|
||||||
|
{
|
||||||
|
inline static const auto Scope = QStringLiteral("core/loadFromSystemScope");
|
||||||
|
};
|
||||||
|
|
||||||
|
static Settings *instance();
|
||||||
|
static void setSettingFile(const QString &settingsFile = QString());
|
||||||
|
static void setValue(const QString &key = QString(), const QVariant &value = QVariant());
|
||||||
|
static QVariant value(const QString &key = QString());
|
||||||
|
static void restoreDefaultSettings();
|
||||||
|
static QVariant defaultValue(const QString &key);
|
||||||
|
static bool isWritable();
|
||||||
|
static bool isSystemScope();
|
||||||
|
static void setScope(bool systemScope);
|
||||||
|
static const QString settingsFile();
|
||||||
|
static const QString settingsPath();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void scopeChanged(bool isSystemScope);
|
||||||
|
void writableChanged(bool canWrite);
|
||||||
|
void settingsChanged(const QString key);
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit Settings(QObject *parent = nullptr);
|
||||||
|
Settings *operator=(Settings &other) = delete;
|
||||||
|
Settings(const Settings &other) = delete;
|
||||||
|
~Settings() = default;
|
||||||
|
static bool isPortableSettings();
|
||||||
|
void cleanSettings();
|
||||||
|
void initSettings();
|
||||||
|
|
||||||
|
QSettings *m_settings = nullptr;
|
||||||
|
QString m_portableSettingsFile = QStringLiteral("%1.conf").arg(kAppName);
|
||||||
|
inline static const QStringList m_validKeys = {Settings::Core::Scope};
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user