2024-08-08 17:41:59 +00:00
|
|
|
/*
|
2024-09-17 19:00:25 +00:00
|
|
|
* Deskflow -- mouse and keyboard sharing utility
|
2024-08-08 17:41:59 +00:00
|
|
|
* Copyright (C) 2024 Symless Ltd.
|
|
|
|
|
*
|
|
|
|
|
* This package is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
|
* found in the file LICENSE that should have accompanied this file.
|
|
|
|
|
*
|
|
|
|
|
* This package 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 "QSettingsProxy.h"
|
|
|
|
|
|
2024-08-09 18:20:10 +00:00
|
|
|
#include "common/constants.h"
|
|
|
|
|
#include "gui/Logger.h"
|
|
|
|
|
|
|
|
|
|
#include <QCoreApplication>
|
|
|
|
|
#include <QDir>
|
|
|
|
|
#include <QFile>
|
|
|
|
|
#include <QSettings>
|
|
|
|
|
#include <memory>
|
|
|
|
|
|
2024-09-17 19:00:25 +00:00
|
|
|
namespace deskflow::gui::proxy {
|
2024-08-08 17:41:59 +00:00
|
|
|
|
2024-08-09 18:20:10 +00:00
|
|
|
const auto kLegacyOrgDomain = "http-symless-com";
|
2024-08-12 15:39:18 +00:00
|
|
|
const auto kLegacySystemConfigFilename = "SystemConfig.ini";
|
2024-08-09 18:20:10 +00:00
|
|
|
|
|
|
|
|
#if defined(Q_OS_UNIX)
|
2024-08-12 15:39:18 +00:00
|
|
|
const auto kUnixSystemConfigPath = "/usr/local/etc/";
|
2024-08-09 18:20:10 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Free functions
|
|
|
|
|
//
|
|
|
|
|
|
2024-08-12 15:39:18 +00:00
|
|
|
/**
|
|
|
|
|
* @brief The base dir for the system settings file.
|
|
|
|
|
*
|
|
|
|
|
* Important: Qt will append the org name as a dir, and the app name as the
|
2024-09-17 19:00:25 +00:00
|
|
|
* settings filename, i.e.: `{base-dir}/Deskflow/Deskflow.ini`
|
2024-08-12 15:39:18 +00:00
|
|
|
*/
|
|
|
|
|
QString getSystemSettingsBaseDir() {
|
2024-08-09 18:20:10 +00:00
|
|
|
#if defined(Q_OS_WIN)
|
2024-08-12 15:39:18 +00:00
|
|
|
return QCoreApplication::applicationDirPath();
|
|
|
|
|
#elif defined(Q_OS_UNIX)
|
|
|
|
|
// Qt already adds application and filename to the end of the path.
|
|
|
|
|
// On macOS, it would be nice to use /Library dir, but qt has no elevate
|
|
|
|
|
// system.
|
2024-08-09 18:20:10 +00:00
|
|
|
return kUnixSystemConfigPath;
|
|
|
|
|
#else
|
|
|
|
|
#error "unsupported platform"
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void migrateLegacySystemSettings(QSettings &settings) {
|
|
|
|
|
if (QFile(settings.fileName()).exists()) {
|
|
|
|
|
qDebug("system settings already exist, skipping migration");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QSettings::setPath(
|
2024-08-12 15:39:18 +00:00
|
|
|
QSettings::IniFormat, QSettings::SystemScope,
|
|
|
|
|
kLegacySystemConfigFilename);
|
2024-08-09 18:20:10 +00:00
|
|
|
QSettings oldSystemSettings(
|
|
|
|
|
QSettings::IniFormat, QSettings::SystemScope,
|
|
|
|
|
QCoreApplication::organizationName(),
|
|
|
|
|
QCoreApplication::applicationName());
|
|
|
|
|
|
|
|
|
|
if (QFile(oldSystemSettings.fileName()).exists()) {
|
|
|
|
|
for (const auto &key : oldSystemSettings.allKeys()) {
|
|
|
|
|
settings.setValue(key, oldSystemSettings.value(key));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QSettings::setPath(
|
2024-08-12 15:39:18 +00:00
|
|
|
QSettings::IniFormat, QSettings::SystemScope, getSystemSettingsBaseDir());
|
2024-08-09 18:20:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void migrateLegacyUserSettings(QSettings &newSettings) {
|
|
|
|
|
QString newPath = newSettings.fileName();
|
|
|
|
|
QFile newFile(newPath);
|
|
|
|
|
if (newFile.exists()) {
|
|
|
|
|
qInfo("user settings already exist, skipping migration");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QSettings oldSettings(kLegacyOrgDomain, kAppName);
|
|
|
|
|
QString oldPath = oldSettings.fileName();
|
|
|
|
|
|
|
|
|
|
if (oldPath.isEmpty()) {
|
|
|
|
|
qInfo("no legacy settings to migrate, filename empty");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!QFile(oldPath).exists()) {
|
|
|
|
|
qInfo("no legacy settings to migrate, file does not exist");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QFileInfo oldFileInfo(oldPath);
|
|
|
|
|
QFileInfo newFileInfo(newPath);
|
|
|
|
|
|
|
|
|
|
qDebug(
|
|
|
|
|
"migrating legacy settings: '%s' -> '%s'", //
|
|
|
|
|
qPrintable(oldFileInfo.fileName()), qPrintable(newFileInfo.fileName()));
|
|
|
|
|
|
|
|
|
|
QStringList keys = oldSettings.allKeys();
|
|
|
|
|
for (const QString &key : keys) {
|
|
|
|
|
QVariant oldValue = oldSettings.value(key);
|
|
|
|
|
newSettings.setValue(key, oldValue);
|
|
|
|
|
logVerbose(
|
|
|
|
|
QString("migrating setting '%1' = '%2'").arg(key, oldValue.toString()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
newSettings.sync();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// QSettingsProxy
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
void QSettingsProxy::loadUser() {
|
|
|
|
|
m_pSettings = std::make_unique<QSettings>();
|
|
|
|
|
|
|
|
|
|
#if defined(Q_OS_MAC)
|
2024-09-17 19:00:25 +00:00
|
|
|
// on mac, we used to save settings to "com.http-symless-com.Deskflow.plist"
|
2024-08-09 18:20:10 +00:00
|
|
|
// because `setOrganizationName` was historically called using a url instead
|
|
|
|
|
// of an actual domain (e.g. symless.com).
|
|
|
|
|
migrateLegacyUserSettings(*m_pSettings);
|
|
|
|
|
#endif // Q_OS_MAC
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QSettingsProxy::loadSystem() {
|
|
|
|
|
auto orgName = QCoreApplication::organizationName();
|
|
|
|
|
if (orgName.isEmpty()) {
|
|
|
|
|
qFatal("unable to load config, organization name is empty");
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
qDebug() << "org name for config:" << orgName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto appName = QCoreApplication::applicationName();
|
|
|
|
|
if (appName.isEmpty()) {
|
|
|
|
|
qFatal("unable to load config, application name is empty");
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
qDebug() << "app name for config:" << appName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QSettings::setPath(
|
|
|
|
|
QSettings::Format::IniFormat, QSettings::Scope::SystemScope,
|
2024-08-12 15:39:18 +00:00
|
|
|
getSystemSettingsBaseDir());
|
2024-08-09 18:20:10 +00:00
|
|
|
|
|
|
|
|
m_pSettings = std::make_unique<QSettings>(
|
|
|
|
|
QSettings::Format::IniFormat, QSettings::Scope::SystemScope, orgName,
|
|
|
|
|
appName);
|
|
|
|
|
|
|
|
|
|
#if defined(Q_OS_WIN)
|
|
|
|
|
migrateLegacySystemSettings(*m_pSettings);
|
|
|
|
|
#endif // Q_OS_WIN
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-08 17:41:59 +00:00
|
|
|
int QSettingsProxy::beginReadArray(const QString &prefix) {
|
|
|
|
|
return m_pSettings->beginReadArray(prefix);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QSettingsProxy::setArrayIndex(int i) { m_pSettings->setArrayIndex(i); }
|
|
|
|
|
|
|
|
|
|
QVariant QSettingsProxy::value(const QString &key) const {
|
|
|
|
|
return m_pSettings->value(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant
|
|
|
|
|
QSettingsProxy::value(const QString &key, const QVariant &defaultValue) const {
|
|
|
|
|
return m_pSettings->value(key, defaultValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QSettingsProxy::endArray() { m_pSettings->endArray(); }
|
|
|
|
|
|
|
|
|
|
void QSettingsProxy::beginWriteArray(const QString &prefix) {
|
|
|
|
|
m_pSettings->beginWriteArray(prefix);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QSettingsProxy::setValue(const QString &key, const QVariant &value) {
|
|
|
|
|
m_pSettings->setValue(key, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QSettingsProxy::beginGroup(const QString &prefix) {
|
|
|
|
|
m_pSettings->beginGroup(prefix);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QSettingsProxy::remove(const QString &key) { m_pSettings->remove(key); }
|
|
|
|
|
|
|
|
|
|
void QSettingsProxy::endGroup() { m_pSettings->endGroup(); }
|
|
|
|
|
|
|
|
|
|
bool QSettingsProxy::isWritable() const { return m_pSettings->isWritable(); }
|
|
|
|
|
|
|
|
|
|
bool QSettingsProxy::contains(const QString &key) const {
|
|
|
|
|
return m_pSettings->contains(key);
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-17 19:00:25 +00:00
|
|
|
} // namespace deskflow::gui::proxy
|