/* * synergy -- mouse and keyboard sharing utility * 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 . */ #include "QSettingsProxy.h" #include "common/constants.h" #include "gui/Logger.h" #include #include #include #include #include namespace synergy::gui::proxy { const auto kLegacyOrgDomain = "http-symless-com"; const auto kSystemConfigFilename = "SystemConfig.ini"; #if defined(Q_OS_UNIX) const auto kUnixSystemConfigPath = "/usr/local/etc/symless/"; #endif // // Free functions // QString getSystemSettingPath() { const QString settingFilename(kSystemConfigFilename); #if defined(Q_OS_WIN) return QCoreApplication::applicationDirPath() + QDir::separator(); #elif defined(Q_OS_MAC) // it would be nice to use /Library dir, but qt has no elevate system. return kUnixSystemConfigPath + settingFilename; #elif defined(Q_OS_LINUX) // qt already adds application and filename to the end of the path on linux. 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( QSettings::IniFormat, QSettings::SystemScope, kSystemConfigFilename); 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( QSettings::IniFormat, QSettings::SystemScope, getSystemSettingPath()); } 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(); #if defined(Q_OS_MAC) // on mac, we used to save settings to "com.http-symless-com.Synergy.plist" // 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, getSystemSettingPath()); m_pSettings = std::make_unique( QSettings::Format::IniFormat, QSettings::Scope::SystemScope, orgName, appName); #if defined(Q_OS_WIN) migrateLegacySystemSettings(*m_pSettings); #endif // Q_OS_WIN } 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); } } // namespace synergy::gui::proxy