2022-06-19 16:17:38 +08:00
|
|
|
// SPDX-FileCopyrightText: 2022 Gary Wang <wzc782970009@gmail.com>
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
2020-07-28 21:14:38 +08:00
|
|
|
#include "settings.h"
|
|
|
|
|
|
|
|
#include <QApplication>
|
|
|
|
#include <QStandardPaths>
|
2024-10-21 21:26:41 +08:00
|
|
|
#include <QStringBuilder>
|
2020-07-28 21:14:38 +08:00
|
|
|
#include <QDebug>
|
|
|
|
#include <QDir>
|
2022-03-12 10:35:23 +08:00
|
|
|
#include <QMetaEnum>
|
|
|
|
|
|
|
|
namespace QEnumHelper
|
|
|
|
{
|
|
|
|
template <typename E>
|
|
|
|
E fromString(const QString &text, const E defaultValue)
|
|
|
|
{
|
|
|
|
bool ok;
|
|
|
|
E result = static_cast<E>(QMetaEnum::fromType<E>().keyToValue(text.toUtf8(), &ok));
|
|
|
|
if (!ok) {
|
|
|
|
return defaultValue;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename E>
|
|
|
|
QString toString(E value)
|
|
|
|
{
|
|
|
|
const int intValue = static_cast<int>(value);
|
|
|
|
return QString::fromUtf8(QMetaEnum::fromType<E>().valueToKey(intValue));
|
|
|
|
}
|
|
|
|
}
|
2020-07-28 21:14:38 +08:00
|
|
|
|
|
|
|
Settings *Settings::m_settings_instance = nullptr;
|
|
|
|
|
|
|
|
Settings *Settings::instance()
|
|
|
|
{
|
|
|
|
if (!m_settings_instance) {
|
|
|
|
m_settings_instance = new Settings;
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_settings_instance;
|
|
|
|
}
|
|
|
|
|
2020-07-29 00:57:43 +08:00
|
|
|
bool Settings::stayOnTop()
|
2020-07-28 21:14:38 +08:00
|
|
|
{
|
2020-07-29 00:57:43 +08:00
|
|
|
return m_qsettings->value("stay_on_top", true).toBool();
|
2020-07-28 21:14:38 +08:00
|
|
|
}
|
|
|
|
|
2024-10-10 22:58:11 +08:00
|
|
|
bool Settings::useLightCheckerboard()
|
|
|
|
{
|
|
|
|
return m_qsettings->value("use_light_checkerboard", false).toBool();
|
|
|
|
}
|
|
|
|
|
2022-03-12 10:35:23 +08:00
|
|
|
Settings::DoubleClickBehavior Settings::doubleClickBehavior() const
|
2020-07-28 21:14:38 +08:00
|
|
|
{
|
2022-03-12 10:35:23 +08:00
|
|
|
QString result = m_qsettings->value("double_click_behavior", "Close").toString();
|
2020-07-28 21:14:38 +08:00
|
|
|
|
2022-03-12 10:35:23 +08:00
|
|
|
return QEnumHelper::fromString<DoubleClickBehavior>(result, DoubleClickBehavior::Close);
|
2020-07-28 21:14:38 +08:00
|
|
|
}
|
|
|
|
|
2022-03-12 10:35:23 +08:00
|
|
|
Settings::MouseWheelBehavior Settings::mouseWheelBehavior() const
|
2021-01-24 00:07:58 +08:00
|
|
|
{
|
2022-03-12 10:35:23 +08:00
|
|
|
QString result = m_qsettings->value("mouse_wheel_behavior", "Zoom").toString();
|
2021-01-24 00:07:58 +08:00
|
|
|
|
2022-03-12 10:35:23 +08:00
|
|
|
return QEnumHelper::fromString<MouseWheelBehavior>(result, MouseWheelBehavior::Zoom);
|
2021-01-24 00:07:58 +08:00
|
|
|
}
|
|
|
|
|
2022-03-12 10:35:23 +08:00
|
|
|
Settings::WindowSizeBehavior Settings::initWindowSizeBehavior() const
|
2022-03-11 16:21:56 +08:00
|
|
|
{
|
2022-03-12 10:35:23 +08:00
|
|
|
QString result = m_qsettings->value("init_window_size_behavior", "Auto").toString();
|
2022-03-11 16:21:56 +08:00
|
|
|
|
2022-03-12 10:35:23 +08:00
|
|
|
return QEnumHelper::fromString<WindowSizeBehavior>(result, WindowSizeBehavior::Auto);
|
2022-03-11 16:21:56 +08:00
|
|
|
}
|
|
|
|
|
2023-07-10 01:07:01 +08:00
|
|
|
Qt::HighDpiScaleFactorRoundingPolicy Settings::hiDpiScaleFactorBehavior() const
|
|
|
|
{
|
|
|
|
QString result = m_qsettings->value("hidpi_scale_factor_behavior", "PassThrough").toString();
|
|
|
|
|
|
|
|
return QEnumHelper::fromString<Qt::HighDpiScaleFactorRoundingPolicy>(result, Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
|
|
|
}
|
|
|
|
|
2020-07-29 00:57:43 +08:00
|
|
|
void Settings::setStayOnTop(bool on)
|
|
|
|
{
|
|
|
|
m_qsettings->setValue("stay_on_top", on);
|
|
|
|
m_qsettings->sync();
|
|
|
|
}
|
|
|
|
|
2024-10-10 22:58:11 +08:00
|
|
|
void Settings::setUseLightCheckerboard(bool light)
|
|
|
|
{
|
|
|
|
m_qsettings->setValue("use_light_checkerboard", light);
|
|
|
|
m_qsettings->sync();
|
|
|
|
}
|
|
|
|
|
2020-07-29 00:57:43 +08:00
|
|
|
void Settings::setDoubleClickBehavior(DoubleClickBehavior dcb)
|
|
|
|
{
|
2022-03-12 10:35:23 +08:00
|
|
|
m_qsettings->setValue("double_click_behavior", QEnumHelper::toString(dcb));
|
2020-07-29 00:57:43 +08:00
|
|
|
m_qsettings->sync();
|
|
|
|
}
|
|
|
|
|
2021-01-24 00:07:58 +08:00
|
|
|
void Settings::setMouseWheelBehavior(MouseWheelBehavior mwb)
|
|
|
|
{
|
2022-03-12 10:35:23 +08:00
|
|
|
m_qsettings->setValue("mouse_wheel_behavior", QEnumHelper::toString(mwb));
|
2021-01-24 00:07:58 +08:00
|
|
|
m_qsettings->sync();
|
|
|
|
}
|
|
|
|
|
2022-03-11 16:21:56 +08:00
|
|
|
void Settings::setInitWindowSizeBehavior(WindowSizeBehavior wsb)
|
|
|
|
{
|
2022-03-12 10:35:23 +08:00
|
|
|
m_qsettings->setValue("init_window_size_behavior", QEnumHelper::toString(wsb));
|
2022-03-11 16:21:56 +08:00
|
|
|
m_qsettings->sync();
|
|
|
|
}
|
|
|
|
|
2023-07-10 01:07:01 +08:00
|
|
|
void Settings::setHiDpiScaleFactorBehavior(Qt::HighDpiScaleFactorRoundingPolicy hidpi)
|
|
|
|
{
|
|
|
|
m_qsettings->setValue("hidpi_scale_factor_behavior", QEnumHelper::toString(hidpi));
|
|
|
|
m_qsettings->sync();
|
|
|
|
}
|
|
|
|
|
2023-07-27 23:15:22 +08:00
|
|
|
#if defined(FLAG_PORTABLE_MODE_SUPPORT) && defined(Q_OS_WIN)
|
|
|
|
#include <windows.h>
|
|
|
|
// QCoreApplication::applicationDirPath() parses the "applicationDirPath" from arg0, which...
|
|
|
|
// 1. rely on a QApplication object instance
|
|
|
|
// but we need to call QGuiApplication::setHighDpiScaleFactorRoundingPolicy() before QApplication get created
|
|
|
|
// 2. arg0 is NOT garanteed to be the path of execution
|
|
|
|
// see also: https://stackoverflow.com/questions/383973/is-args0-guaranteed-to-be-the-path-of-execution
|
|
|
|
// This function is here mainly for #1.
|
|
|
|
QString getApplicationDirPath()
|
|
|
|
{
|
|
|
|
WCHAR buffer[MAX_PATH];
|
|
|
|
GetModuleFileNameW(NULL, buffer, MAX_PATH);
|
|
|
|
QString appPath = QString::fromWCharArray(buffer);
|
|
|
|
|
|
|
|
return appPath.left(appPath.lastIndexOf('\\'));
|
|
|
|
}
|
|
|
|
#endif // defined(FLAG_PORTABLE_MODE_SUPPORT) && defined(Q_OS_WIN)
|
|
|
|
|
2020-07-28 21:14:38 +08:00
|
|
|
Settings::Settings()
|
|
|
|
: QObject(qApp)
|
|
|
|
{
|
|
|
|
QString configPath;
|
|
|
|
|
2023-07-27 23:15:22 +08:00
|
|
|
#if defined(FLAG_PORTABLE_MODE_SUPPORT) && defined(Q_OS_WIN)
|
|
|
|
QString portableConfigDirPath = QDir(getApplicationDirPath()).absoluteFilePath("data");
|
2020-07-28 21:14:38 +08:00
|
|
|
QFileInfo portableConfigDirInfo(portableConfigDirPath);
|
|
|
|
if (portableConfigDirInfo.exists() && portableConfigDirInfo.isDir() && portableConfigDirInfo.isWritable()) {
|
|
|
|
// we can use it.
|
|
|
|
configPath = portableConfigDirPath;
|
|
|
|
}
|
2023-07-27 23:15:22 +08:00
|
|
|
#endif // defined(FLAG_PORTABLE_MODE_SUPPORT) && defined(Q_OS_WIN)
|
2020-07-28 21:14:38 +08:00
|
|
|
|
|
|
|
if (configPath.isEmpty()) {
|
2024-10-21 21:26:41 +08:00
|
|
|
// Should be %LOCALAPPDATA%\<APPNAME> under Windows, ~/.config/<APPNAME> under Linux.
|
|
|
|
// Sadly <APPNAME> is unknown when Settings object is created (it's before the creation
|
|
|
|
// of QApplication), so we'll need to append the app name manually.
|
|
|
|
configPath = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) %
|
|
|
|
QDir::separator() % QLatin1String("Pineapple Pictures");
|
2020-07-28 21:14:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
m_qsettings = new QSettings(QDir(configPath).absoluteFilePath("config.ini"), QSettings::IniFormat, this);
|
|
|
|
}
|
|
|
|
|