Enable customizing the save statistics time interval
[qBittorrent.git] / src / base / profile_p.cpp
blob1f94af6a2db12ca611d3a20950442500d41dd5ab
1 /*
2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2016 Eugene Shalygin <eugene.shalygin@gmail.com>
4 * Copyright (C) 2012 Christophe Dumez
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * In addition, as a special exception, the copyright holders give permission to
21 * link this program with the OpenSSL project's "OpenSSL" library (or with
22 * modified versions of it that use the same license as the "OpenSSL" library),
23 * and distribute the linked executables. You must obey the GNU General Public
24 * License in all respects for all of the code used other than "OpenSSL". If you
25 * modify file(s), you may extend this exception to your version of the file(s),
26 * but you are not obligated to do so. If you do not wish to do so, delete this
27 * exception statement from your version.
30 #include "profile_p.h"
32 #include <QCoreApplication>
34 #include "base/global.h"
35 #include "base/utils/fs.h"
37 Private::Profile::Profile(const QString &configurationName)
38 : m_configurationName {configurationName}
42 QString Private::Profile::configurationName() const
44 return m_configurationName;
47 QString Private::Profile::configurationSuffix() const
49 return (m_configurationName.isEmpty() ? QString() : (u'_' + m_configurationName));
52 QString Private::Profile::profileName() const
54 return QCoreApplication::applicationName() + configurationSuffix();
57 Private::DefaultProfile::DefaultProfile(const QString &configurationName)
58 : Profile {configurationName}
62 Path Private::DefaultProfile::rootPath() const
64 return {};
67 Path Private::DefaultProfile::basePath() const
69 return Utils::Fs::homePath();
72 Path Private::DefaultProfile::cacheLocation() const
74 return locationWithConfigurationName(QStandardPaths::CacheLocation);
77 Path Private::DefaultProfile::configLocation() const
79 #if defined(Q_OS_WIN)
80 // On Windows QSettings stores files in FOLDERID_RoamingAppData\AppName
81 return locationWithConfigurationName(QStandardPaths::AppDataLocation);
82 #else
83 return locationWithConfigurationName(QStandardPaths::AppConfigLocation);
84 #endif
87 Path Private::DefaultProfile::dataLocation() const
89 #if defined(Q_OS_WIN) || defined (Q_OS_MACOS)
90 return locationWithConfigurationName(QStandardPaths::AppLocalDataLocation);
91 #else
92 // On Linux keep using the legacy directory ~/.local/share/data/ if it exists
93 const Path genericDataPath {QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)};
94 const Path profilePath {profileName()};
95 const Path legacyDir = genericDataPath / Path(u"data"_s) / profilePath;
97 const Path dataDir = genericDataPath / profilePath;
99 if (!dataDir.exists() && legacyDir.exists())
101 qWarning("The legacy data directory '%s' is used. It is recommended to move its content to '%s'",
102 qUtf8Printable(legacyDir.toString()), qUtf8Printable(dataDir.toString()));
104 return legacyDir;
107 return dataDir;
108 #endif
111 Path Private::DefaultProfile::downloadLocation() const
113 return Path(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
116 std::unique_ptr<QSettings> Private::DefaultProfile::applicationSettings(const QString &name) const
118 #if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
119 return std::make_unique<QSettings>(QSettings::IniFormat, QSettings::UserScope, profileName(), name);
120 #else
121 return std::make_unique<QSettings>(profileName(), name);
122 #endif
125 Path Private::DefaultProfile::locationWithConfigurationName(const QStandardPaths::StandardLocation location) const
127 return Path(QStandardPaths::writableLocation(location) + configurationSuffix());
130 Private::CustomProfile::CustomProfile(const Path &rootPath, const QString &configurationName)
131 : Profile {configurationName}
132 , m_rootPath {rootPath}
133 , m_basePath {m_rootPath / Path(profileName())}
134 , m_cacheLocation {m_basePath / Path(u"cache"_s)}
135 , m_configLocation {m_basePath / Path(u"config"_s)}
136 , m_dataLocation {m_basePath / Path(u"data"_s)}
137 , m_downloadLocation {m_basePath / Path(u"downloads"_s)}
141 Path Private::CustomProfile::rootPath() const
143 return m_rootPath;
146 Path Private::CustomProfile::basePath() const
148 return m_basePath;
151 Path Private::CustomProfile::cacheLocation() const
153 return m_cacheLocation;
156 Path Private::CustomProfile::configLocation() const
158 return m_configLocation;
161 Path Private::CustomProfile::dataLocation() const
163 return m_dataLocation;
166 Path Private::CustomProfile::downloadLocation() const
168 return m_downloadLocation;
171 std::unique_ptr<QSettings> Private::CustomProfile::applicationSettings(const QString &name) const
173 // here we force QSettings::IniFormat format always because we need it to be portable across platforms
174 #if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
175 const auto CONF_FILE_EXTENSION = u".ini"_s;
176 #else
177 const auto CONF_FILE_EXTENSION = u".conf"_s;
178 #endif
179 const Path settingsFilePath = configLocation() / Path(name + CONF_FILE_EXTENSION);
180 return std::make_unique<QSettings>(settingsFilePath.data(), QSettings::IniFormat);
183 Path Private::NoConvertConverter::fromPortablePath(const Path &portablePath) const
185 return portablePath;
188 Path Private::NoConvertConverter::toPortablePath(const Path &path) const
190 return path;
193 Private::Converter::Converter(const Path &basePath)
194 : m_basePath {basePath}
196 Q_ASSERT(basePath.isAbsolute());
199 Path Private::Converter::toPortablePath(const Path &path) const
201 if (path.isEmpty())
202 return path;
204 #ifdef Q_OS_WIN
205 if (path.isAbsolute())
207 const QChar driveLetter = path.data()[0].toUpper();
208 const QChar baseDriveLetter = m_basePath.data()[0].toUpper();
209 const bool onSameDrive = (driveLetter.category() == QChar::Letter_Uppercase) && (driveLetter == baseDriveLetter);
210 if (!onSameDrive)
211 return path;
213 #endif
214 return m_basePath.relativePathOf(path);
217 Path Private::Converter::fromPortablePath(const Path &portablePath) const
219 if (portablePath.isEmpty() || portablePath.isAbsolute())
220 return portablePath;
222 return m_basePath / portablePath;