mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
feat(paths): create class to combine all qTox managed paths
This will be the central location for all of qTox managed directories.
This commit is contained in:
parent
e1201f901f
commit
3ee8c665df
@ -319,6 +319,8 @@ set(${PROJECT_NAME}_SOURCES
|
|||||||
src/persistence/ifriendsettings.h
|
src/persistence/ifriendsettings.h
|
||||||
src/persistence/offlinemsgengine.cpp
|
src/persistence/offlinemsgengine.cpp
|
||||||
src/persistence/offlinemsgengine.h
|
src/persistence/offlinemsgengine.h
|
||||||
|
src/persistence/paths.cpp
|
||||||
|
src/persistence/paths.h
|
||||||
src/persistence/profile.cpp
|
src/persistence/profile.cpp
|
||||||
src/persistence/profile.h
|
src/persistence/profile.h
|
||||||
src/persistence/profilelocker.cpp
|
src/persistence/profilelocker.cpp
|
||||||
|
234
src/persistence/paths.cpp
Normal file
234
src/persistence/paths.cpp
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
#include "paths.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringBuilder>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const QLatin1Literal globalSettingsFile{"qtox.ini"};
|
||||||
|
const QLatin1Literal profileFolder{"profiles"};
|
||||||
|
const QLatin1Literal themeFolder{"themes"};
|
||||||
|
const QLatin1Literal avatarsFolder{"avatars"};
|
||||||
|
const QLatin1Literal transfersFolder{"transfers"};
|
||||||
|
const QLatin1Literal screenshotsFolder{"screenshots"};
|
||||||
|
|
||||||
|
// NOTE(sudden6): currently unused, but reflects the TCS at 2018-11
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
const QLatin1Literal TCSToxFileFolder{"%APPDATA%/tox/"};
|
||||||
|
#elif defined(Q_OS_OSX)
|
||||||
|
const QLatin1Literal TCSToxFileFolder{"~/Library/Application Support/Tox"};
|
||||||
|
#else
|
||||||
|
const QLatin1Literal TCSToxFileFolder{"~/.config/tox/"};
|
||||||
|
#endif
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Profile
|
||||||
|
* @brief Handles all qTox internal paths
|
||||||
|
*
|
||||||
|
* The qTox internal file layout starts at `<BASE_PATH>`. This directory is platform
|
||||||
|
* specific and depends on if qTox runs in portable mode.
|
||||||
|
*
|
||||||
|
* Example file layout for non-portable mode:
|
||||||
|
* @code
|
||||||
|
* <BASE_PATH>/themes/
|
||||||
|
* /profiles/
|
||||||
|
* /...
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* Example file layout for portable mode:
|
||||||
|
* @code
|
||||||
|
* <BASE_PATH>/themes/
|
||||||
|
* /profiles/
|
||||||
|
* /qtox.ini
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* All qTox or Tox specific directories should be looked up through this module.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Paths::makePaths Factory method for the Paths object
|
||||||
|
* @param mode
|
||||||
|
* @return Pointer to Paths object on success, nullptr else
|
||||||
|
*/
|
||||||
|
Paths* Paths::makePaths(Portable mode)
|
||||||
|
{
|
||||||
|
bool portable = false;
|
||||||
|
const QString basePortable = qApp->applicationDirPath();
|
||||||
|
const QString baseNonPortable = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
||||||
|
const QString portableSettingsPath = basePortable % QDir::separator() % globalSettingsFile;
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case Portable::Portable:
|
||||||
|
qDebug() << "Forcing portable";
|
||||||
|
portable = true;
|
||||||
|
break;
|
||||||
|
case Portable::NonPortable:
|
||||||
|
qDebug() << "Forcing non-portable";
|
||||||
|
portable = false;
|
||||||
|
break;
|
||||||
|
case Portable::Auto:
|
||||||
|
// auto detect
|
||||||
|
if (QFile{portableSettingsPath}.exists()) {
|
||||||
|
qDebug() << "Automatic portable";
|
||||||
|
portable = true;
|
||||||
|
} else {
|
||||||
|
qDebug() << "Automatic non-portable";
|
||||||
|
portable = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString basePath = portable ? basePortable : baseNonPortable;
|
||||||
|
|
||||||
|
if (basePath.isEmpty()) {
|
||||||
|
qCritical() << "Couldn't find writeable path";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Paths(basePath, portable);
|
||||||
|
}
|
||||||
|
|
||||||
|
Paths::Paths(const QString& basePath, bool portable)
|
||||||
|
: basePath{basePath}
|
||||||
|
, portable{portable}
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if qTox is running in portable mode.
|
||||||
|
* @return True if running in portable mode, false else.
|
||||||
|
*/
|
||||||
|
bool Paths::isPortable() const
|
||||||
|
{
|
||||||
|
return portable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the path to the global settings file "qtox.ini"
|
||||||
|
* @return The path to the folder.
|
||||||
|
*/
|
||||||
|
QString Paths::getGlobalSettingsPath() const
|
||||||
|
{
|
||||||
|
QString path;
|
||||||
|
|
||||||
|
if (portable) {
|
||||||
|
path = basePath;
|
||||||
|
} else {
|
||||||
|
path = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
|
||||||
|
if (path.isEmpty()) {
|
||||||
|
qDebug() << "Can't find writable location for settings file";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we assume a writeable path for portable mode
|
||||||
|
|
||||||
|
return path % QDir::separator() % globalSettingsFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the folder where profile specific information is stored, e.g. <profile>.ini
|
||||||
|
* @return The path to the folder.
|
||||||
|
*/
|
||||||
|
QString Paths::getProfilesDir() const
|
||||||
|
{
|
||||||
|
return basePath % QDir::separator() % profileFolder % QDir::separator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the folder where the <profile>.tox file is stored
|
||||||
|
* @note Expect a change here, since TCS will probably be updated.
|
||||||
|
* @return The path to the folder on success, empty string else.
|
||||||
|
*/
|
||||||
|
QString Paths::getToxSaveDir() const
|
||||||
|
{
|
||||||
|
if (isPortable()) {
|
||||||
|
return basePath % QDir::separator() % profileFolder % QDir::separator();
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenericDataLocation would be a better solution, but we keep this code for backward
|
||||||
|
// compatibility
|
||||||
|
|
||||||
|
// workaround for https://bugreports.qt-project.org/browse/QTBUG-38845
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
// TODO(sudden6): this doesn't really follow the Tox Client Standard and probably
|
||||||
|
// breaks when %APPDATA% is changed
|
||||||
|
return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)
|
||||||
|
+ QDir::separator() + "AppData" + QDir::separator() + "Roaming"
|
||||||
|
+ QDir::separator() + "tox")
|
||||||
|
+ QDir::separator();
|
||||||
|
#elif defined(Q_OS_OSX)
|
||||||
|
return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)
|
||||||
|
+ QDir::separator() + "Library" + QDir::separator()
|
||||||
|
+ "Application Support" + QDir::separator() + "Tox")
|
||||||
|
+ QDir::separator();
|
||||||
|
#else
|
||||||
|
// TODO(sudden6): This does not respect the XDG_* environment variables and also
|
||||||
|
// stores user data in a config location
|
||||||
|
return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)
|
||||||
|
+ QDir::separator() + "tox")
|
||||||
|
+ QDir::separator();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the folder where avatar files are stored
|
||||||
|
* @note Expect a change here, since TCS will probably be updated.
|
||||||
|
* @return The path to the folder on success, empty string else.
|
||||||
|
*/
|
||||||
|
QString Paths::getAvatarsDir() const
|
||||||
|
{
|
||||||
|
// follow the layout in
|
||||||
|
// https://tox.gitbooks.io/tox-client-standard/content/data_storage/export_format.html
|
||||||
|
QString path = getToxSaveDir();
|
||||||
|
if (path.isEmpty()) {
|
||||||
|
qDebug() << "Can't find location for avatars directory";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return path % QDir::separator() % avatarsFolder % QDir::separator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the folder where screenshots are stored
|
||||||
|
* @return The path to the folder.
|
||||||
|
*/
|
||||||
|
QString Paths::getScreenshotsDir() const
|
||||||
|
{
|
||||||
|
return basePath % QDir::separator() % screenshotsFolder % QDir::separator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the folder where file transfer data is stored
|
||||||
|
* @return The path to the folder.
|
||||||
|
*/
|
||||||
|
QString Paths::getTransfersDir() const
|
||||||
|
{
|
||||||
|
return basePath % QDir::separator() % transfersFolder % QDir::separator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a prioritized list with directories that contain themes.
|
||||||
|
* @return A list of directories sorted from most important to least important.
|
||||||
|
* @note Users of this function should use the theme from the folder that appears first in the list.
|
||||||
|
*/
|
||||||
|
QStringList Paths::getThemeDirs() const
|
||||||
|
{
|
||||||
|
QStringList themeFolders{};
|
||||||
|
|
||||||
|
if (!isPortable()) {
|
||||||
|
themeFolders += QStandardPaths::locate(QStandardPaths::AppDataLocation, themeFolder,
|
||||||
|
QStandardPaths::LocateDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
// look for themes beside the qTox binary with lowest priority
|
||||||
|
const QString curPath = qApp->applicationDirPath();
|
||||||
|
themeFolders += curPath % QDir::separator() % themeFolder % QDir::separator();
|
||||||
|
|
||||||
|
return themeFolders;
|
||||||
|
}
|
35
src/persistence/paths.h
Normal file
35
src/persistence/paths.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef PATHS_H
|
||||||
|
#define PATHS_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
class Paths
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class Portable {
|
||||||
|
Auto, /** Auto detect if portable or non-portable */
|
||||||
|
Portable, /** Force portable mode */
|
||||||
|
NonPortable /** Force non-portable mode */
|
||||||
|
};
|
||||||
|
|
||||||
|
static Paths* makePaths(Portable mode = Portable::Auto);
|
||||||
|
|
||||||
|
bool isPortable() const;
|
||||||
|
QString getGlobalSettingsPath() const;
|
||||||
|
QString getProfilesDir() const;
|
||||||
|
QString getToxSaveDir() const;
|
||||||
|
QString getAvatarsDir() const;
|
||||||
|
QString getTransfersDir() const;
|
||||||
|
QStringList getThemeDirs() const;
|
||||||
|
QString getScreenshotsDir() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Paths(const QString &basePath, bool portable);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString basePath{};
|
||||||
|
bool portable = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PATHS_H
|
Loading…
x
Reference in New Issue
Block a user