2025-03-06 22:37:37 +00:00
|
|
|
/*
|
|
|
|
|
* 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"
|
|
|
|
|
|
2025-03-21 00:36:09 +00:00
|
|
|
#include "UrlConstants.h"
|
|
|
|
|
|
2025-03-30 12:06:41 +00:00
|
|
|
#include <QCoreApplication>
|
2025-03-06 22:37:37 +00:00
|
|
|
#include <QFile>
|
2025-03-05 05:28:05 +00:00
|
|
|
#include <QRect>
|
2025-03-06 22:37:37 +00:00
|
|
|
|
|
|
|
|
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);
|
2025-03-15 02:17:08 +00:00
|
|
|
instance()->m_settingsProxy->load(instance()->m_portableSettingsFile);
|
2025-03-06 22:37:37 +00:00
|
|
|
qInfo().noquote() << "settings file:" << instance()->m_settings->fileName();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Settings::Settings(QObject *parent) : QObject(parent)
|
|
|
|
|
{
|
2025-03-15 03:24:22 +00:00
|
|
|
QString fileToLoad;
|
2025-03-31 17:38:36 +00:00
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
|
m_portableSettingsFile = m_portableSettingsFile.arg(QCoreApplication::applicationDirPath(), kAppName);
|
2025-03-06 22:37:37 +00:00
|
|
|
if (QFile(m_portableSettingsFile).exists()) {
|
2025-03-15 03:24:22 +00:00
|
|
|
fileToLoad = m_portableSettingsFile;
|
2025-03-31 17:38:36 +00:00
|
|
|
m_settings = new QSettings(fileToLoad, QSettings::IniFormat);
|
2025-03-15 03:24:22 +00:00
|
|
|
} else {
|
2025-03-31 17:38:36 +00:00
|
|
|
m_settings = new QSettings(QSettings::NativeFormat, QSettings::UserScope, kAppName, kAppName);
|
2025-03-06 22:37:37 +00:00
|
|
|
}
|
2025-03-31 17:38:36 +00:00
|
|
|
#else
|
|
|
|
|
if (!qEnvironmentVariable("XDG_CONFIG_HOME").isEmpty())
|
|
|
|
|
fileToLoad = QStringLiteral("%1/%2/%2.conf").arg(qEnvironmentVariable("XDG_CONFIG_HOME"), kAppName);
|
|
|
|
|
else if (QFile(UserSettingFile).exists())
|
|
|
|
|
fileToLoad = UserSettingFile;
|
|
|
|
|
else if (QFile(SystemSettingFile).exists())
|
|
|
|
|
fileToLoad = SystemSettingFile;
|
|
|
|
|
else
|
|
|
|
|
fileToLoad = UserSettingFile;
|
2025-03-15 03:24:22 +00:00
|
|
|
m_settings = new QSettings(fileToLoad, QSettings::IniFormat);
|
2025-03-31 17:38:36 +00:00
|
|
|
#endif
|
|
|
|
|
|
2025-03-15 03:24:22 +00:00
|
|
|
m_settingsProxy = std::make_shared<QSettingsProxy>();
|
|
|
|
|
m_settingsProxy->load(fileToLoad);
|
|
|
|
|
qInfo().noquote() << "settings file:" << m_settings->fileName();
|
2025-03-06 22:37:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2025-03-15 03:24:22 +00:00
|
|
|
if ((key == Gui::Autohide) || (key == Core::StartedBefore) || (key == Core::PreventSleep) ||
|
2025-04-02 21:48:06 +00:00
|
|
|
(key == Server::ExternalConfig) || (key == Client::InvertScrollDirection) || (key == Log::ToFile) ||
|
|
|
|
|
(key == Core::StopOnDeskSwitch)) {
|
2025-03-06 22:37:37 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-09 00:34:50 +00:00
|
|
|
if ((key == Gui::CloseToTray) || (key == Gui::LogExpanded) || (key == Gui::SymbolicTrayIcon) ||
|
|
|
|
|
(key == Gui::CloseReminder) || (key == Security::TlsEnabled) || (key == Security::CheckPeers) ||
|
|
|
|
|
(key == Client::LanguageSync)) {
|
2025-03-08 15:10:42 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-09 03:09:38 +00:00
|
|
|
if (key == Core::ScreenName)
|
|
|
|
|
return QSysInfo::machineHostName();
|
|
|
|
|
|
2025-03-05 05:28:05 +00:00
|
|
|
if (key == Gui::WindowGeometry)
|
|
|
|
|
return QRect();
|
|
|
|
|
|
2025-03-07 00:42:16 +00:00
|
|
|
if (key == Security::Certificate)
|
2025-03-18 01:18:37 +00:00
|
|
|
return QStringLiteral("%1/%2").arg(instance()->tlsDir(), kTlsCertificateFilename);
|
2025-03-07 00:04:55 +00:00
|
|
|
|
2025-03-09 00:25:57 +00:00
|
|
|
if (key == Security::KeySize)
|
|
|
|
|
return 2048;
|
|
|
|
|
|
2025-03-09 01:56:29 +00:00
|
|
|
if (key == Log::File)
|
|
|
|
|
return QStringLiteral("%1/%2").arg(QDir::homePath(), kDefaultLogFile);
|
|
|
|
|
|
2025-03-09 01:13:26 +00:00
|
|
|
if (key == Log::Level)
|
|
|
|
|
return 0;
|
|
|
|
|
|
2025-03-08 12:11:51 +00:00
|
|
|
if (key == Client::Binary)
|
|
|
|
|
return kClientBinName;
|
|
|
|
|
|
2025-03-08 12:16:18 +00:00
|
|
|
if (key == Server::Binary)
|
|
|
|
|
return kServerBinName;
|
|
|
|
|
|
2025-03-31 18:47:22 +00:00
|
|
|
if (key == Core::ElevateMode) {
|
2025-03-31 19:06:52 +00:00
|
|
|
if (instance()->isNativeMode())
|
|
|
|
|
return Settings::ElevateMode::Always;
|
|
|
|
|
else
|
|
|
|
|
return Settings::ElevateMode::Never;
|
2025-03-31 18:47:22 +00:00
|
|
|
}
|
2025-03-09 05:54:47 +00:00
|
|
|
|
2025-03-21 00:36:09 +00:00
|
|
|
if (key == Core::UpdateUrl)
|
|
|
|
|
return kUrlUpdateCheck;
|
|
|
|
|
|
2025-03-09 00:25:57 +00:00
|
|
|
if (key == Server::ExternalConfigFile)
|
|
|
|
|
return QStringLiteral("%1/%2.conf").arg(instance()->settingsPath(), kAppId);
|
|
|
|
|
|
|
|
|
|
if (key == Core::Port)
|
|
|
|
|
return 24800;
|
2025-03-08 16:37:04 +00:00
|
|
|
|
2025-03-31 18:47:22 +00:00
|
|
|
if (key == Core::ProcessMode) {
|
|
|
|
|
if (instance()->isNativeMode())
|
|
|
|
|
return Settings::ProcessMode::Service;
|
|
|
|
|
else
|
|
|
|
|
return Settings::ProcessMode::Desktop;
|
|
|
|
|
}
|
2025-03-09 04:14:26 +00:00
|
|
|
|
2025-03-14 21:18:54 +00:00
|
|
|
if (key == Daemon::LogFile) {
|
2025-03-29 19:53:36 +00:00
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
|
return QStringLiteral("%1/%2").arg(QCoreApplication::applicationDirPath(), kDaemonLogFilename);
|
|
|
|
|
#else
|
2025-03-14 21:18:54 +00:00
|
|
|
return QStringLiteral("%1/%2").arg(instance()->settingsPath(), kDaemonLogFilename);
|
2025-03-29 19:53:36 +00:00
|
|
|
#endif
|
2025-03-14 21:18:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (key == Daemon::Elevate)
|
|
|
|
|
return true;
|
|
|
|
|
|
2025-03-06 22:37:37 +00:00
|
|
|
return QVariant();
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-09 01:13:26 +00:00
|
|
|
const QString Settings::logLevelText()
|
|
|
|
|
{
|
|
|
|
|
return instance()->m_logLevels.at(instance()->value(Log::Level).toInt());
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-15 02:17:08 +00:00
|
|
|
QSettingsProxy &Settings::proxy()
|
|
|
|
|
{
|
|
|
|
|
return *instance()->m_settingsProxy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Settings::save(bool emitSaving)
|
|
|
|
|
{
|
|
|
|
|
if (emitSaving)
|
|
|
|
|
Q_EMIT instance()->serverSettingsChanged();
|
|
|
|
|
instance()->m_settings->sync();
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-30 11:59:13 +00:00
|
|
|
const QStringList Settings::validKeys()
|
|
|
|
|
{
|
|
|
|
|
return instance()->m_validKeys;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-06 22:37:37 +00:00
|
|
|
bool Settings::isWritable()
|
|
|
|
|
{
|
2025-03-31 17:38:36 +00:00
|
|
|
if (instance()->isNativeMode())
|
|
|
|
|
return true;
|
2025-03-06 22:37:37 +00:00
|
|
|
return instance()->m_settings->isWritable();
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-31 17:38:36 +00:00
|
|
|
bool Settings::isNativeMode()
|
|
|
|
|
{
|
|
|
|
|
return instance()->m_settings->format() == QSettings::NativeFormat;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-06 22:37:37 +00:00
|
|
|
const QString Settings::settingsFile()
|
|
|
|
|
{
|
|
|
|
|
return instance()->m_settings->fileName();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QString Settings::settingsPath()
|
|
|
|
|
{
|
2025-03-31 17:38:36 +00:00
|
|
|
if (instance()->isNativeMode())
|
|
|
|
|
return SystemDir;
|
2025-03-06 22:37:37 +00:00
|
|
|
return QFileInfo(instance()->m_settings->fileName()).absolutePath();
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-18 01:18:37 +00:00
|
|
|
const QString Settings::tlsDir()
|
|
|
|
|
{
|
|
|
|
|
return QStringLiteral("%1/%2").arg(instance()->settingsPath(), kTlsDirName);
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-18 01:36:37 +00:00
|
|
|
const QString Settings::tlsLocalDb()
|
|
|
|
|
{
|
|
|
|
|
return QStringLiteral("%1/%2").arg(instance()->tlsDir(), kTlsFingerprintLocalFilename);
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-18 01:41:14 +00:00
|
|
|
const QString Settings::tlsTrustedServersDb()
|
|
|
|
|
{
|
|
|
|
|
return QStringLiteral("%1/%2").arg(instance()->tlsDir(), kTlsFingerprintTrustedServersFilename);
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-18 01:47:21 +00:00
|
|
|
const QString Settings::tlsTrustedClientsDb()
|
|
|
|
|
{
|
|
|
|
|
return QStringLiteral("%1/%2").arg(instance()->tlsDir(), kTlsFingerprintTrustedClientsFilename);
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-06 22:37:37 +00:00
|
|
|
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);
|
2025-03-15 03:24:22 +00:00
|
|
|
else
|
2025-03-06 22:37:37 +00:00
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
}
|