From b06080e2e7106a8fd04c670840c77a9a983c3563 Mon Sep 17 00:00:00 2001 From: Eugene Shalygin Date: Tue, 18 Apr 2017 15:29:10 +0200 Subject: [PATCH] Replace platform-specific code in Private::DefaultProfile with QStandardPaths. This should also fix Profile::location(SpecialFolder::Config) on Windows. --- src/base/private/profile_p.cpp | 108 ++++++++------------------------- src/base/private/profile_p.h | 18 +++++- src/base/profile.cpp | 4 +- src/base/profile.h | 2 +- 4 files changed, 45 insertions(+), 87 deletions(-) diff --git a/src/base/private/profile_p.cpp b/src/base/private/profile_p.cpp index d57bf53a5..156ac1148 100644 --- a/src/base/private/profile_p.cpp +++ b/src/base/private/profile_p.cpp @@ -32,29 +32,21 @@ #include -#include - -#ifdef Q_OS_MAC -#include -#include -#endif - -#ifdef Q_OS_WIN -#include -#endif - #include "base/utils/fs.h" Private::Profile::Profile(const QString &configurationName) - : m_configurationName {configurationName.isEmpty() - ? QCoreApplication::applicationName() - : QCoreApplication::applicationName() + QLatin1Char('_') + configurationName} + : m_configurationSuffix {configurationName.isEmpty() ? QString() : QLatin1Char('_') + configurationName} { } -QString Private::Profile::configurationName() const +QString Private::Profile::configurationSuffix() const { - return m_configurationName; + return m_configurationSuffix; +} + +QString Private::Profile::profileName() const +{ + return QCoreApplication::applicationName() + configurationSuffix(); } Private::DefaultProfile::DefaultProfile(const QString &configurationName) @@ -69,81 +61,28 @@ QString Private::DefaultProfile::baseDirectory() const QString Private::DefaultProfile::cacheLocation() const { - QString result; -#if defined(Q_OS_WIN) || defined(Q_OS_OS2) - result = dataLocation() + QLatin1String("cache"); -#else -#ifdef Q_OS_MAC - // http://developer.apple.com/documentation/Carbon/Reference/Folder_Manager/Reference/reference.html - FSRef ref; - OSErr err = FSFindFolder(kUserDomain, kCachedDataFolderType, false, &ref); - if (err) - return QString(); - QByteArray ba(2048, 0); - if (FSRefMakePath(&ref, reinterpret_cast(ba.data()), ba.size()) == noErr) - result = QString::fromUtf8(ba).normalized(QString::NormalizationForm_C); - result += QLatin1Char('/') + configurationName(); -#else - QString xdgCacheHome = QLatin1String(qgetenv("XDG_CACHE_HOME")); - if (xdgCacheHome.isEmpty()) - xdgCacheHome = QDir::homePath() + QLatin1String("/.cache"); - xdgCacheHome += QLatin1Char('/') + configurationName(); - result = xdgCacheHome; -#endif -#endif - if (!result.endsWith("/")) - result += "/"; - return result; + return locationWithConfigurationName(QStandardPaths::CacheLocation); } QString Private::DefaultProfile::configLocation() const { - QString result; -#if defined(Q_OS_WIN) || defined(Q_OS_OS2) - result = dataLocation() + QLatin1String("config"); -#else -#ifdef Q_OS_MAC - result = QDir::homePath() + QLatin1String("/Library/Preferences/") + configurationName(); +#if defined(Q_OS_WIN) + // On Windows QSettings stores files in FOLDERID_RoamingAppData\AppName + return locationWithConfigurationName(QStandardPaths::AppDataLocation); #else - QString xdgConfigHome = QLatin1String(qgetenv("XDG_CONFIG_HOME")); - if (xdgConfigHome.isEmpty()) - xdgConfigHome = QDir::homePath() + QLatin1String("/.config"); - xdgConfigHome += QLatin1Char('/') + configurationName(); - result = xdgConfigHome; + return locationWithConfigurationName(QStandardPaths::AppConfigLocation); #endif -#endif - return result; } QString Private::DefaultProfile::dataLocation() const { - QString result; -#if defined(Q_OS_WIN) - wchar_t path[MAX_PATH + 1] = {L'\0'}; - if (SHGetSpecialFolderPathW(0, path, CSIDL_LOCAL_APPDATA, FALSE)) - result = Utils::Fs::fromNativePath(QString::fromWCharArray(path)); - if (!QCoreApplication::applicationName().isEmpty()) - result += QLatin1String("/") + qApp->applicationName(); -#elif defined(Q_OS_MAC) - FSRef ref; - OSErr err = FSFindFolder(kUserDomain, kApplicationSupportFolderType, false, &ref); - if (err) - return QString(); - QByteArray ba(2048, 0); - if (FSRefMakePath(&ref, reinterpret_cast(ba.data()), ba.size()) == noErr) - result = QString::fromUtf8(ba).normalized(QString::NormalizationForm_C); - result += QLatin1Char('/') + qApp->applicationName(); +#if defined(Q_OS_WIN) || defined (Q_OS_MAC) + return locationWithConfigurationName(QStandardPaths::AppLocalDataLocation); #else - QString xdgDataHome = QLatin1String(qgetenv("XDG_DATA_HOME")); - if (xdgDataHome.isEmpty()) - xdgDataHome = QDir::homePath() + QLatin1String("/.local/share"); - xdgDataHome += QLatin1String("/data/") - + qApp->applicationName(); - result = xdgDataHome; + // on Linux gods know why qBittorrent creates 'data' subdirectory in ~/.local/share/ + return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + + QLatin1String("/data/") + profileName() + QLatin1Char('/'); #endif - if (!result.endsWith("/")) - result += "/"; - return result; } QString Private::DefaultProfile::downloadLocation() const @@ -159,15 +98,20 @@ QString Private::DefaultProfile::downloadLocation() const SettingsPtr Private::DefaultProfile::applicationSettings(const QString &name) const { #if defined(Q_OS_WIN) || defined(Q_OS_MAC) - return SettingsPtr(new QSettings(QSettings::IniFormat, QSettings::UserScope, configurationName(), name)); + return SettingsPtr(new QSettings(QSettings::IniFormat, QSettings::UserScope, profileName(), name)); #else - return SettingsPtr(new QSettings(configurationName(), name)); + return SettingsPtr(new QSettings(profileName(), name)); #endif } +QString Private::DefaultProfile::locationWithConfigurationName(QStandardPaths::StandardLocation location) const +{ + return QStandardPaths::writableLocation(location) + configurationSuffix(); +} + Private::CustomProfile::CustomProfile(const QString &rootPath, const QString &configurationName) : Profile {configurationName} - , m_rootDirectory {QDir(rootPath).absoluteFilePath(this->configurationName())} + , m_rootDirectory {QDir(rootPath).absoluteFilePath(this->profileName())} { } diff --git a/src/base/private/profile_p.h b/src/base/private/profile_p.h index 46f381b9c..7e6d9a7ea 100644 --- a/src/base/private/profile_p.h +++ b/src/base/private/profile_p.h @@ -32,6 +32,7 @@ #define QBT_PROFILE_P_H #include +#include #include "base/profile.h" namespace Private @@ -48,13 +49,17 @@ namespace Private virtual ~Profile() = default; - QString configurationName() const; + /** + * @brief QCoreApplication::applicationName() with optional configuration name appended + */ + QString profileName() const; protected: Profile(const QString &configurationName); + QString configurationSuffix() const; private: - QString m_configurationName; + QString m_configurationSuffix; }; /// Default implementation. Takes paths from system @@ -69,6 +74,15 @@ namespace Private QString dataLocation() const override; QString downloadLocation() const override; SettingsPtr applicationSettings(const QString &name) const override; + + private: + /** + * @brief Standard path writable location for profile files + * + * @param location location kind + * @return QStandardPaths::writableLocation(location) / configurationName() + */ + QString locationWithConfigurationName(QStandardPaths::StandardLocation location) const; }; /// Custom tree: creates directories under the specified root directory diff --git a/src/base/profile.cpp b/src/base/profile.cpp index 112303300..d2fd9c310 100644 --- a/src/base/profile.cpp +++ b/src/base/profile.cpp @@ -90,9 +90,9 @@ QString Profile::location(SpecialFolder folder) const return result; } -QString Profile::configurationName() const +QString Profile::profileName() const { - return m_profileImpl->configurationName(); + return m_profileImpl->profileName(); } SettingsPtr Profile::applicationSettings(const QString &name) const diff --git a/src/base/profile.h b/src/base/profile.h index a278af39f..85557633a 100644 --- a/src/base/profile.h +++ b/src/base/profile.h @@ -63,7 +63,7 @@ public: /// Returns either default name for configuration file (QCoreApplication::applicationName()) /// or the value, supplied via parameters - QString configurationName() const; + QString profileName() const; QString toPortablePath(const QString &absolutePath) const; QString fromPortablePath(const QString &portablePath) const;