From 33389b9b63aaea8b998e0e6bdd240769dd90562c Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 26 Dec 2013 01:24:43 +0100 Subject: [PATCH] XDG compliant paths --- apps/launcher/maindialog.cpp | 10 +-- apps/opencs/editor.cpp | 4 - apps/opencs/model/doc/document.cpp | 4 +- apps/opencs/model/doc/documentmanager.cpp | 4 +- apps/opencs/model/settings/usersettings.cpp | 2 +- apps/openmw/engine.cpp | 6 +- components/files/configurationmanager.cpp | 8 +- components/files/configurationmanager.hpp | 2 +- components/files/fixedpath.hpp | 19 ++--- components/files/linuxpath.cpp | 86 ++++++++++----------- components/files/linuxpath.hpp | 2 + components/files/macospath.cpp | 79 +++++++++---------- components/files/macospath.hpp | 2 + components/files/windowspath.cpp | 6 ++ components/files/windowspath.hpp | 2 + 15 files changed, 119 insertions(+), 117 deletions(-) diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index a6ac3d78d..9b3c4e1b0 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -219,7 +219,7 @@ bool Launcher::MainDialog::showFirstRunDialog() } // Create the file if it doesn't already exist, else the importer will fail - QString path = QString::fromStdString(mCfgMgr.getUserPath().string()) + QString("openmw.cfg"); + QString path = QString::fromStdString(mCfgMgr.getUserConfigPath().string()) + QString("openmw.cfg"); QFile file(path); if (!file.exists()) { @@ -334,7 +334,7 @@ bool Launcher::MainDialog::setupLauncherSettings() { mLauncherSettings.setMultiValueEnabled(true); - QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string()); + QString userPath = QString::fromStdString(mCfgMgr.getUserConfigPath().string()); QStringList paths; paths.append(QString("launcher.cfg")); @@ -440,7 +440,7 @@ bool Launcher::expansions(Launcher::UnshieldThread& cd) bool Launcher::MainDialog::setupGameSettings() { - QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string()); + QString userPath = QString::fromStdString(mCfgMgr.getUserConfigPath().string()); QString globalPath = QString::fromStdString(mCfgMgr.getGlobalPath().string()); // Load the user config file first, separately @@ -591,7 +591,7 @@ bool Launcher::MainDialog::setupGraphicsSettings() { mGraphicsSettings.setMultiValueEnabled(false); - QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string()); + QString userPath = QString::fromStdString(mCfgMgr.getUserConfigPath().string()); QString globalPath = QString::fromStdString(mCfgMgr.getGlobalPath().string()); QFile localDefault(QString("settings-default.cfg")); @@ -678,7 +678,7 @@ bool Launcher::MainDialog::writeSettings() mGraphicsPage->saveSettings(); mDataFilesPage->saveSettings(); - QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string()); + QString userPath = QString::fromStdString(mCfgMgr.getUserConfigPath().string()); QDir dir(userPath); if (!dir.exists()) { diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 1c1e37c2d..44926610b 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -86,10 +86,6 @@ void CS::Editor::setupDataFiles() return; } - // Set the charset for reading the esm/esp files - // QString encoding = QString::fromStdString(variables["encoding"].as()); - //mFileDialog.setEncoding(encoding); - dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end()); mDocumentManager.setResourceDir (variables["resources"].as()); diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 27f4f498a..3ef14ee7e 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2221,7 +2221,7 @@ void CSMDoc::Document::createBase() CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, bool new_) : mSavePath (savePath), mContentFiles (files), mTools (mData), mResDir(resDir), - mProjectPath ((configuration.getUserPath() / "projects") / + mProjectPath ((configuration.getUserDataPath() / "projects") / (savePath.filename().string() + ".project")), mSaving (*this, mProjectPath) { @@ -2254,7 +2254,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, co } else { - boost::filesystem::path locCustomFiltersPath (configuration.getUserPath()); + boost::filesystem::path locCustomFiltersPath (configuration.getUserDataPath()); locCustomFiltersPath /= "defaultfilters"; if (boost::filesystem::exists(locCustomFiltersPath)) diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index 024c46bea..3ff75c9c1 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -15,7 +15,7 @@ CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& configuration) : mConfiguration (configuration) { - boost::filesystem::path projectPath = configuration.getUserPath() / "projects"; + boost::filesystem::path projectPath = configuration.getUserDataPath() / "projects"; if (!boost::filesystem::is_directory (projectPath)) boost::filesystem::create_directories (projectPath); @@ -53,4 +53,4 @@ bool CSMDoc::DocumentManager::removeDocument (Document *document) void CSMDoc::DocumentManager::setResourceDir (const boost::filesystem::path& parResDir) { mResDir = boost::filesystem::system_complete(parResDir); -} \ No newline at end of file +} diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 1ce28ed75..94cee8a43 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -251,7 +251,7 @@ void CSMSettings::UserSettings::loadSettings (const QString &fileName) bool localOk = loadFromFile(localFilePath); //user - mUserFilePath = QString::fromStdString(mCfgMgr.getUserPath().string()) + fileName; + mUserFilePath = QString::fromStdString(mCfgMgr.getUserConfigPath().string()) + fileName; loadFromFile(mUserFilePath); if (!(localOk || globalOk)) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index f2afb3ba5..01cca1b78 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -301,7 +301,7 @@ std::string OMW::Engine::loadSettings (Settings::Manager & settings) throw std::runtime_error ("No default settings file found! Make sure the file \"settings-default.cfg\" was properly installed."); // load user settings if they exist, otherwise just load the default settings as user settings - const std::string settingspath = mCfgMgr.getUserPath().string() + "/settings.cfg"; + const std::string settingspath = mCfgMgr.getUserConfigPath().string() + "/settings.cfg"; if (boost::filesystem::exists(settingspath)) settings.loadUser(settingspath); else if (boost::filesystem::exists(localdefault)) @@ -373,7 +373,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) // Create input and UI first to set up a bootstrapping environment for // showing a loading screen and keeping the window responsive while doing so - std::string keybinderUser = (mCfgMgr.getUserPath() / "input.xml").string(); + std::string keybinderUser = (mCfgMgr.getUserConfigPath() / "input.xml").string(); bool keybinderUserExists = boost::filesystem::exists(keybinderUser); MWInput::InputManager* input = new MWInput::InputManager (*mOgre, *this, keybinderUser, keybinderUserExists, mGrab); mEnvironment.setInputManager (input); @@ -536,7 +536,7 @@ void OMW::Engine::screenshot() // Count screenshots. int shotCount = 0; - const std::string screenshotPath = mCfgMgr.getUserPath().string(); + const std::string& screenshotPath = mCfgMgr.getUserDataPath().string(); // Find the first unused filename with a do-while std::ostringstream stream; diff --git a/components/files/configurationmanager.cpp b/components/files/configurationmanager.cpp index 056adb8ce..761b7ca5a 100644 --- a/components/files/configurationmanager.cpp +++ b/components/files/configurationmanager.cpp @@ -27,6 +27,7 @@ ConfigurationManager::ConfigurationManager() setupTokensMapping(); boost::filesystem::create_directories(mFixedPath.getUserConfigPath()); + boost::filesystem::create_directories(mFixedPath.getUserDataPath()); mLogPath = mFixedPath.getUserConfigPath(); } @@ -144,11 +145,16 @@ const boost::filesystem::path& ConfigurationManager::getGlobalPath() const return mFixedPath.getGlobalConfigPath(); } -const boost::filesystem::path& ConfigurationManager::getUserPath() const +const boost::filesystem::path& ConfigurationManager::getUserConfigPath() const { return mFixedPath.getUserConfigPath(); } +const boost::filesystem::path& ConfigurationManager::getUserDataPath() const +{ + return mFixedPath.getUserDataPath(); +} + const boost::filesystem::path& ConfigurationManager::getLocalPath() const { return mFixedPath.getLocalPath(); diff --git a/components/files/configurationmanager.hpp b/components/files/configurationmanager.hpp index 4df871664..35144fe04 100644 --- a/components/files/configurationmanager.hpp +++ b/components/files/configurationmanager.hpp @@ -36,7 +36,7 @@ struct ConfigurationManager /**< Fixed paths */ const boost::filesystem::path& getGlobalPath() const; - const boost::filesystem::path& getUserPath() const; + const boost::filesystem::path& getUserConfigPath() const; const boost::filesystem::path& getLocalPath() const; const boost::filesystem::path& getGlobalDataPath() const; diff --git a/components/files/fixedpath.hpp b/components/files/fixedpath.hpp index b3708a477..cfd3458ce 100644 --- a/components/files/fixedpath.hpp +++ b/components/files/fixedpath.hpp @@ -48,7 +48,8 @@ struct FixedPath */ FixedPath(const std::string& application_name) : mPath(application_name + "/") - , mUserPath(mPath.getUserConfigPath()) + , mUserConfigPath(mPath.getUserConfigPath()) + , mUserDataPath(mPath.getUserDataPath()) , mGlobalConfigPath(mPath.getGlobalConfigPath()) , mLocalPath(mPath.getLocalPath()) , mGlobalDataPath(mPath.getGlobalDataPath()) @@ -59,18 +60,19 @@ struct FixedPath /** * \brief Return path pointing to the user local configuration directory. - * - * \return boost::filesystem::path */ const boost::filesystem::path& getUserConfigPath() const { - return mUserPath; + return mUserConfigPath; + } + + const boost::filesystem::path& getUserDataPath() const + { + return mUserDataPath; } /** * \brief Return path pointing to the global (system) configuration directory. - * - * \return boost::filesystem::path */ const boost::filesystem::path& getGlobalConfigPath() const { @@ -79,8 +81,6 @@ struct FixedPath /** * \brief Return path pointing to the directory where application was started. - * - * \return boost::filesystem::path */ const boost::filesystem::path& getLocalPath() const { @@ -105,7 +105,8 @@ struct FixedPath private: PathType mPath; - boost::filesystem::path mUserPath; /**< User path */ + boost::filesystem::path mUserConfigPath; /**< User path */ + boost::filesystem::path mUserDataPath; boost::filesystem::path mGlobalConfigPath; /**< Global path */ boost::filesystem::path mLocalPath; /**< It is the same directory where application was run */ diff --git a/components/files/linuxpath.cpp b/components/files/linuxpath.cpp index 0dcc10595..d285f4229 100644 --- a/components/files/linuxpath.cpp +++ b/components/files/linuxpath.cpp @@ -8,6 +8,39 @@ #include #include + +namespace +{ + boost::filesystem::path getUserHome() + { + const char* dir = getenv("HOME"); + if (dir == NULL) + { + struct passwd* pwd = getpwuid(getuid()); + if (pwd != NULL) + { + dir = pwd->pw_dir; + } + } + if (dir == NULL) + return boost::filesystem::path(); + else + return boost::filesystem::path(dir); + } + + boost::filesystem::path getEnv(const std::string& envVariable, const boost::filesystem::path& fallback) + { + const char* result = getenv(envVariable.c_str()); + if (!result) + return fallback; + boost::filesystem::path dir(result); + if (dir.empty()) + return fallback; + else + return dir; + } +} + /** * \namespace Files */ @@ -21,46 +54,17 @@ LinuxPath::LinuxPath(const std::string& application_name) boost::filesystem::path LinuxPath::getUserConfigPath() const { - boost::filesystem::path userPath("."); - - const char* theDir = getenv("HOME"); - if (theDir == NULL) - { - struct passwd* pwd = getpwuid(getuid()); - if (pwd != NULL) - { - theDir = pwd->pw_dir; - } - } - - if (theDir != NULL) - { - userPath = boost::filesystem::path(theDir); - } + return getEnv("XDG_CONFIG_HOME", getUserHome() / ".config") / mName; +} - return userPath / ".config" / mName; +boost::filesystem::path LinuxPath::getUserDataPath() const +{ + return getEnv("XDG_DATA_HOME", getUserHome() / ".local/share") / mName; } boost::filesystem::path LinuxPath::getCachePath() const { - boost::filesystem::path userPath("."); - - const char* theDir = getenv("HOME"); - if (theDir == NULL) - { - struct passwd* pwd = getpwuid(getuid()); - if (pwd != NULL) - { - theDir = pwd->pw_dir; - } - } - - if (theDir != NULL) - { - userPath = boost::filesystem::path(theDir); - } - - return userPath / ".cache" / mName; + return getEnv("XDG_CACHE_HOME", getUserHome() / ".cache") / mName; } boost::filesystem::path LinuxPath::getGlobalConfigPath() const @@ -84,17 +88,9 @@ boost::filesystem::path LinuxPath::getInstallPath() const { boost::filesystem::path installPath; - char *homePath = getenv("HOME"); - if (homePath == NULL) - { - struct passwd* pwd = getpwuid(getuid()); - if (pwd != NULL) - { - homePath = pwd->pw_dir; - } - } + boost::filesystem::path homePath = getUserHome(); - if (homePath != NULL) + if (!homePath.empty()) { boost::filesystem::path wineDefaultRegistry(homePath); wineDefaultRegistry /= ".wine/system.reg"; diff --git a/components/files/linuxpath.hpp b/components/files/linuxpath.hpp index 191f779b6..b710165b4 100644 --- a/components/files/linuxpath.hpp +++ b/components/files/linuxpath.hpp @@ -23,6 +23,8 @@ struct LinuxPath */ boost::filesystem::path getUserConfigPath() const; + boost::filesystem::path getUserDataPath() const; + /** * \brief Return path to the global (system) directory where config files can be placed. */ diff --git a/components/files/macospath.cpp b/components/files/macospath.cpp index f9f988995..3e53f5306 100644 --- a/components/files/macospath.cpp +++ b/components/files/macospath.cpp @@ -11,9 +11,26 @@ * FIXME: Someone with MacOS system should check this and correct if necessary */ -/** - * \namespace Files - */ +namespace +{ + boost::filesystem::path getUserHome() + { + const char* dir = getenv("HOME"); + if (dir == NULL) + { + struct passwd* pwd = getpwuid(getuid()); + if (pwd != NULL) + { + dir = pwd->pw_dir; + } + } + if (dir == NULL) + return boost::filesystem::path(); + else + return boost::filesystem::path(dir); + } +} + namespace Files { @@ -24,21 +41,17 @@ MacOsPath::MacOsPath(const std::string& application_name) boost::filesystem::path MacOsPath::getUserConfigPath() const { - boost::filesystem::path userPath("."); + boost::filesystem::path userPath (getUserHome()); + userPath /= "Library/Preferences/"; - const char* theDir = getenv("HOME"); - if (theDir == NULL) - { - struct passwd* pwd = getpwuid(getuid()); - if (pwd != NULL) - { - theDir = pwd->pw_dir; - } - } - if (theDir != NULL) - { - userPath = boost::filesystem::path(theDir) / "Library/Preferences/"; - } + return userPath / mName; +} + +boost::filesystem::path MacOsPath::getUserDataPath() const +{ + // TODO: probably wrong? + boost::filesystem::path userPath (getUserHome()); + userPath /= "Library/Preferences/"; return userPath / mName; } @@ -51,23 +64,9 @@ boost::filesystem::path MacOsPath::getGlobalConfigPath() const boost::filesystem::path MacOsPath::getCachePath() const { - boost::filesystem::path userPath("."); - - const char* theDir = getenv("HOME"); - if (theDir == NULL) - { - struct passwd* pwd = getpwuid(getuid()); - if (pwd != NULL) - { - theDir = pwd->pw_dir; - } - } - if (theDir != NULL) - { - userPath = boost::filesystem::path(theDir) / "Library/Caches" / mName; - } - - return userPath; + boost::filesystem::path userPath (getUserHome()); + userPath /= "Library/Caches"; + return userPath / mName; } boost::filesystem::path MacOsPath::getLocalPath() const @@ -85,17 +84,9 @@ boost::filesystem::path MacOsPath::getInstallPath() const { boost::filesystem::path installPath; - char *homePath = getenv("HOME"); - if (homePath == NULL) - { - struct passwd* pwd = getpwuid(getuid()); - if (pwd != NULL) - { - homePath = pwd->pw_dir; - } - } + boost::filesystem::path homePath = getUserHome(); - if (homePath != NULL) + if (!homePath.empty()) { boost::filesystem::path wineDefaultRegistry(homePath); wineDefaultRegistry /= ".wine/system.reg"; diff --git a/components/files/macospath.hpp b/components/files/macospath.hpp index e9307c464..7a7dc5577 100644 --- a/components/files/macospath.hpp +++ b/components/files/macospath.hpp @@ -25,6 +25,8 @@ struct MacOsPath */ boost::filesystem::path getUserConfigPath() const; + boost::filesystem::path getUserDataPath() const; + /** * \brief Return path to the global (system) directory. * diff --git a/components/files/windowspath.cpp b/components/files/windowspath.cpp index 001611f99..5bb8a6a02 100644 --- a/components/files/windowspath.cpp +++ b/components/files/windowspath.cpp @@ -41,6 +41,12 @@ boost::filesystem::path WindowsPath::getUserConfigPath() const return userPath / mName; } +boost::filesystem::path WindowsPath::getUserDataPath() const +{ + // Have some chaos, windows people! + return getUserConfigPath(); +} + boost::filesystem::path WindowsPath::getGlobalConfigPath() const { boost::filesystem::path globalPath("."); diff --git a/components/files/windowspath.hpp b/components/files/windowspath.hpp index dc3b71d91..31d0e0e7c 100644 --- a/components/files/windowspath.hpp +++ b/components/files/windowspath.hpp @@ -31,6 +31,8 @@ struct WindowsPath */ boost::filesystem::path getUserConfigPath() const; + boost::filesystem::path getUserDataPath() const; + /** * \brief Returns "X:\Program Files\" *