diff --git a/CMakeLists.txt b/CMakeLists.txt index 36393470..bbdfeb5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ ENDIF () message(STATUS "Git revision: ${GIT_COMMIT_STRING}") # Write to file. -configure_file("${CMAKE_SOURCE_DIR}/src/backend/globals.cpp.in" "${CMAKE_BINARY_DIR}/generated/globals.cpp" @ONLY) +configure_file("${CMAKE_SOURCE_DIR}/src/backend/app/loot_version.cpp.in" "${CMAKE_BINARY_DIR}/generated/loot_version.cpp" @ONLY) ############################## # External Projects @@ -120,8 +120,10 @@ IF (NOT DEFINED CEF_ROOT) set (CEF_ROOT "../../cef") ENDIF () -set (LOOT_SRC "${CMAKE_SOURCE_DIR}/src/backend/app/loot_settings.cpp" +set (LOOT_SRC "${CMAKE_SOURCE_DIR}/src/backend/app/loot_paths.cpp" + "${CMAKE_SOURCE_DIR}/src/backend/app/loot_settings.cpp" "${CMAKE_SOURCE_DIR}/src/backend/app/loot_state.cpp" + "${CMAKE_BINARY_DIR}/generated/loot_version.cpp" "${CMAKE_SOURCE_DIR}/src/backend/metadata/conditional_metadata.cpp" "${CMAKE_SOURCE_DIR}/src/backend/metadata/file.cpp" "${CMAKE_SOURCE_DIR}/src/backend/metadata/location.cpp" @@ -141,11 +143,12 @@ set (LOOT_SRC "${CMAKE_SOURCE_DIR}/src/backend/app/loot_settings.cpp" "${CMAKE_SOURCE_DIR}/src/backend/helpers/git_helper.cpp" "${CMAKE_SOURCE_DIR}/src/backend/helpers/helpers.cpp" "${CMAKE_SOURCE_DIR}/src/backend/helpers/language.cpp" - "${CMAKE_SOURCE_DIR}/src/backend/helpers/version.cpp" - "${CMAKE_BINARY_DIR}/generated/globals.cpp") + "${CMAKE_SOURCE_DIR}/src/backend/helpers/version.cpp") -set (LOOT_HEADERS "${CMAKE_SOURCE_DIR}/src/backend/app/loot_settings.h" +set (LOOT_HEADERS "${CMAKE_SOURCE_DIR}/src/backend/app/loot_paths.h" + "${CMAKE_SOURCE_DIR}/src/backend/app/loot_settings.h" "${CMAKE_SOURCE_DIR}/src/backend/app/loot_state.h" + "${CMAKE_SOURCE_DIR}/src/backend/app/loot_version.h" "${CMAKE_SOURCE_DIR}/src/backend/metadata/condition_grammar.h" "${CMAKE_SOURCE_DIR}/src/backend/metadata/conditional_metadata.h" "${CMAKE_SOURCE_DIR}/src/backend/metadata/file.h" @@ -169,7 +172,6 @@ set (LOOT_HEADERS "${CMAKE_SOURCE_DIR}/src/backend/app/loot_settings.h" "${CMAKE_SOURCE_DIR}/src/backend/helpers/language.h" "${CMAKE_SOURCE_DIR}/src/backend/helpers/version.h" "${CMAKE_SOURCE_DIR}/src/backend/helpers/yaml_set_helpers.h" - "${CMAKE_SOURCE_DIR}/src/backend/globals.h" "${CMAKE_SOURCE_DIR}/src/backend/error.h") set (LOOT_GUI_SRC ${LOOT_SRC} @@ -223,6 +225,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/api/loot_write_minimal_list_test.h" "${CMAKE_SOURCE_DIR}/src/tests/api/test_api.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/app/loot_paths_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/app/loot_settings_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/app/loot_state_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/game_test.h" diff --git a/src/api/api.cpp b/src/api/api.cpp index cf108c5f..54462bb3 100644 --- a/src/api/api.cpp +++ b/src/api/api.cpp @@ -25,7 +25,8 @@ #include "loot/api.h" #include "loot_db.h" #include "../backend/error.h" -#include "../backend/globals.h" +#include "../backend/app/loot_paths.h" +#include "../backend/app/loot_version.h" #include "../backend/plugin/plugin_sorter.h" #include @@ -121,9 +122,9 @@ LOOT_API unsigned int loot_get_error_message(const char ** const message) { // LOOT version. Abstracts LOOT API stability policy away from clients. LOOT_API bool loot_is_compatible(const unsigned int versionMajor, const unsigned int versionMinor, const unsigned int versionPatch) { if (versionMajor > 0) - return versionMajor == loot::g_version_major; + return versionMajor == loot::LootVersion::major; else - return versionMinor == loot::g_version_minor; + return versionMinor == loot::LootVersion::minor; } // Returns the version string for this version of LOOT. @@ -133,9 +134,9 @@ LOOT_API unsigned int loot_get_version(unsigned int * const versionMajor, unsign if (versionMajor == nullptr || versionMinor == nullptr || versionPatch == nullptr) return c_error(loot_error_invalid_args, "Null pointer passed."); - *versionMajor = loot::g_version_major; - *versionMinor = loot::g_version_minor; - *versionPatch = loot::g_version_patch; + *versionMajor = loot::LootVersion::major; + *versionMinor = loot::LootVersion::minor; + *versionPatch = loot::LootVersion::patch; return loot_ok; } @@ -144,7 +145,7 @@ LOOT_API unsigned int loot_get_build_id(const char ** const revision) { if (revision == nullptr) return c_error(loot_error_invalid_args, "Null message pointer passed."); - *revision = loot::g_build_revision; + *revision = loot::LootVersion::revision.c_str(); return loot_ok; } @@ -172,9 +173,7 @@ LOOT_API unsigned int loot_create_db(loot_db ** const db, && clientGame != loot_game_fo4)) return c_error(loot_error_invalid_args, "Null pointer passed."); - //Set the locale to get encoding conversions working correctly. - std::locale::global(boost::locale::generator().generate("")); - boost::filesystem::path::imbue(std::locale()); + loot::LootPaths::initialise(); //Disable logging or else stdout will get overrun. boost::log::core::get()->set_logging_enabled(false); diff --git a/src/backend/app/loot_paths.cpp b/src/backend/app/loot_paths.cpp new file mode 100644 index 00000000..8c1ba8fa --- /dev/null +++ b/src/backend/app/loot_paths.cpp @@ -0,0 +1,118 @@ +/* LOOT + +A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and +Fallout: New Vegas. + + Copyright(C) 2012 - 2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software : you can redistribute + it and / or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT.If not, see + . +*/ + +#include "loot_paths.h" +#include "../helpers/helpers.h" +#include "../error.h" + +#include + +#include + +#ifdef _WIN32 +# ifndef UNICODE +# define UNICODE +# endif +# ifndef _UNICODE +# define _UNICODE +# endif +# include "windows.h" +# include "shlobj.h" +#endif + +namespace loot { + boost::filesystem::path LootPaths::getReadmePath() { + return lootAppPath / "docs" / "LOOT Readme.html"; + } + + boost::filesystem::path LootPaths::getUIIndexPath() { + return lootAppPath / "resources" / "ui" / "index.html"; + } + + boost::filesystem::path LootPaths::getL10nPath() { + return lootAppPath / "resources" / "l10n"; + } + + boost::filesystem::path LootPaths::getLootDataPath() { + return lootDataPath; + } + + boost::filesystem::path LootPaths::getSettingsPath() { + return lootDataPath / "settings.yaml"; + } + + boost::filesystem::path LootPaths::getLogPath() { + return lootDataPath / "LOOTDebugLog.txt"; + } + + void LootPaths::initialise() { + // Set the locale to get UTF-8 conversions working correctly. + std::locale::global(boost::locale::generator().generate("")); + boost::filesystem::path::imbue(std::locale()); + + lootAppPath = boost::filesystem::current_path(); + lootDataPath = getLocalAppDataPath() / "LOOT"; + } + + void LootPaths::setLootAppPath(const boost::filesystem::path& path) { + lootAppPath = path; + } + + void LootPaths::setLootDataPath(const boost::filesystem::path& path) { + lootDataPath = path; + } + + boost::filesystem::path LootPaths::getLocalAppDataPath() { +#ifdef _WIN32 + HWND owner = 0; + PWSTR path; + + if (SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &path) != S_OK) + throw error(error::windows_error, boost::locale::translate("Failed to get %LOCALAPPDATA% path.")); + + boost::filesystem::path localAppDataPath(FromWinWide(path)); + CoTaskMemFree(path); + + return localAppDataPath; +#else + // Use XDG_CONFIG_HOME environmental variable if it's available. + const char * xdgConfigHome = getenv("XDG_CONFIG_HOME"); + + if (xdgConfigHome != nullptr) + return boost::filesystem::path(xdgConfigHome); + + // Otherwise, use the HOME env. var. if it's available. + xdgConfigHome = getenv("HOME"); + + if (xdgConfigHome != nullptr) + return boost::filesystem::path(xdgConfigHome) / ".config"; + + // If somehow both are missing, use the current path. + return boost::filesystem::current_path(); +#endif + } + + boost::filesystem::path LootPaths::lootAppPath = boost::filesystem::path(); + boost::filesystem::path LootPaths::lootDataPath = boost::filesystem::path(); +} diff --git a/src/backend/app/loot_paths.h b/src/backend/app/loot_paths.h new file mode 100644 index 00000000..b5ecb4f1 --- /dev/null +++ b/src/backend/app/loot_paths.h @@ -0,0 +1,54 @@ +/* LOOT + +A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and +Fallout: New Vegas. + +Copyright (C) 2014-2016 WrinklyNinja + +This file is part of LOOT. + +LOOT is free software: you can redistribute +it and/or modify it under the terms of the GNU General Public License +as published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. + +LOOT is distributed in the hope that it will +be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LOOT. If not, see +. +*/ + +#ifndef LOOT_BACKEND_LOOT_PATHS +#define LOOT_BACKEND_LOOT_PATHS + +#include + +namespace loot { + class LootPaths { + public: + static boost::filesystem::path getReadmePath(); + static boost::filesystem::path getUIIndexPath(); + static boost::filesystem::path getL10nPath(); + static boost::filesystem::path getLootDataPath(); + static boost::filesystem::path getSettingsPath(); + static boost::filesystem::path getLogPath(); + + // Sets the app path to the current path, and the data path to the user + // local app data path / "LOOT". + static void initialise(); + static void setLootAppPath(const boost::filesystem::path& path); + static void setLootDataPath(const boost::filesystem::path& path); + private: + static boost::filesystem::path lootAppPath; + static boost::filesystem::path lootDataPath; + + //Get the local application data path. + static boost::filesystem::path getLocalAppDataPath(); + }; +} + +#endif diff --git a/src/backend/app/loot_settings.cpp b/src/backend/app/loot_settings.cpp index 434a71a9..1cf6d161 100644 --- a/src/backend/app/loot_settings.cpp +++ b/src/backend/app/loot_settings.cpp @@ -23,7 +23,7 @@ */ #include "loot_settings.h" -#include "backend/globals.h" +#include "backend/app/loot_version.h" #include @@ -195,7 +195,7 @@ namespace loot { void LootSettings::updateLastVersion() { std::lock_guard guard(mutex); - lastVersion = std::to_string(g_version_major) + "." + std::to_string(g_version_minor) + "." + std::to_string(g_version_patch); + lastVersion = std::to_string(LootVersion::major) + "." + std::to_string(LootVersion::minor) + "." + std::to_string(LootVersion::patch); } YAML::Node LootSettings::toYaml() const { diff --git a/src/backend/app/loot_state.cpp b/src/backend/app/loot_state.cpp index 4285a911..7aa20298 100644 --- a/src/backend/app/loot_state.cpp +++ b/src/backend/app/loot_state.cpp @@ -23,9 +23,10 @@ */ #include "loot_state.h" +#include "loot_paths.h" #include "backend/error.h" -#include "backend/globals.h" +#include "backend/app/loot_version.h" #include "backend/helpers/helpers.h" #include "backend/helpers/language.h" @@ -104,7 +105,7 @@ namespace loot { // Do some preliminary locale / UTF-8 support setup here, in case the settings file reading requires it. //Boost.Locale initialisation: Specify location of language dictionaries. boost::locale::generator gen; - gen.add_messages_path(g_path_l10n.string()); + gen.add_messages_path(LootPaths::getL10nPath().string()); gen.add_messages_domain("loot"); //Boost.Locale initialisation: Generate and imbue locales. @@ -112,18 +113,18 @@ namespace loot { boost::filesystem::path::imbue(locale()); // Check if the LOOT local app data folder exists, and create it if not. - if (!fs::exists(g_path_local)) { + if (!fs::exists(LootPaths::getLootDataPath())) { BOOST_LOG_TRIVIAL(info) << "Local app data LOOT folder doesn't exist, creating it."; try { - fs::create_directory(g_path_local); + fs::create_directory(LootPaths::getLootDataPath()); } catch (exception& e) { _initErrors.push_back((format(translate("Error: Could not create LOOT settings file. %1%")) % e.what()).str()); } } - if (fs::exists(g_path_settings)) { + if (fs::exists(LootPaths::getSettingsPath())) { try { - LootSettings::load(g_path_settings); + LootSettings::load(LootPaths::getSettingsPath()); } catch (exception& e) { _initErrors.push_back((format(translate("Error: Settings parsing failed. %1%")) % e.what()).str()); @@ -132,7 +133,7 @@ namespace loot { //Set up logging. boost::log::add_file_log( - boost::log::keywords::file_name = g_path_log.string().c_str(), + boost::log::keywords::file_name = LootPaths::getLogPath().string().c_str(), boost::log::keywords::auto_flush = true, boost::log::keywords::format = ( boost::log::expressions::stream @@ -140,13 +141,13 @@ namespace loot { << " [" << boost::log::trivial::severity << "]: " << boost::log::expressions::smessage ) - ); + ); boost::log::add_common_attributes(); boost::log::core::get()->set_logging_enabled(isDebugLoggingEnabled()); // Log some useful info. - BOOST_LOG_TRIVIAL(info) << "LOOT Version: " << g_version_major << "." << g_version_minor << "." << g_version_patch; - BOOST_LOG_TRIVIAL(info) << "LOOT Build Revision: " << g_build_revision; + BOOST_LOG_TRIVIAL(info) << "LOOT Version: " << LootVersion::major << "." << LootVersion::minor << "." << LootVersion::patch; + BOOST_LOG_TRIVIAL(info) << "LOOT Build Revision: " << LootVersion::revision; #ifdef _WIN32 // Check if LOOT is being run through Mod Organiser. bool runFromMO = GetModuleHandle(ToWinWide("hook.dll").c_str()) != NULL; @@ -157,7 +158,7 @@ namespace loot { // The CEF debug log is appended to, not overwritten, so it gets really long. // Delete the current CEF debug log. - fs::remove(g_path_local / "CEFDebugLog.txt"); + fs::remove(LootPaths::getLootDataPath() / "CEFDebugLog.txt"); // Now that settings have been loaded, set the locale again to handle translations. if (getLanguage().Code() != Language::english) { diff --git a/src/backend/globals.h b/src/backend/app/loot_version.cpp.in similarity index 55% rename from src/backend/globals.h rename to src/backend/app/loot_version.cpp.in index 58f2ac9e..8609e161 100644 --- a/src/backend/globals.h +++ b/src/backend/app/loot_version.cpp.in @@ -21,27 +21,12 @@ along with LOOT. If not, see . */ -#ifndef __LOOT_GLOBALS__ -#define __LOOT_GLOBALS__ -#include +#include "backend/app/loot_version.h" namespace loot { - //Version numbers. - extern const unsigned int g_version_major; - extern const unsigned int g_version_minor; - extern const unsigned int g_version_patch; - - // Build revision - extern const char * g_build_revision; - - //Common paths. - extern const boost::filesystem::path g_path_readme; - extern const boost::filesystem::path g_path_report; - extern const boost::filesystem::path g_path_l10n; - extern const boost::filesystem::path g_path_local; - extern const boost::filesystem::path g_path_settings; - extern const boost::filesystem::path g_path_log; + const unsigned int LootVersion::major = 0; + const unsigned int LootVersion::minor = 9; + const unsigned int LootVersion::patch = 0; + const std::string LootVersion::revision = "@GIT_COMMIT_STRING@"; } - -#endif diff --git a/src/backend/app/loot_version.h b/src/backend/app/loot_version.h new file mode 100644 index 00000000..d3d68d3f --- /dev/null +++ b/src/backend/app/loot_version.h @@ -0,0 +1,40 @@ +/* LOOT + +A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and +Fallout: New Vegas. + +Copyright (C) 2014-2016 WrinklyNinja + +This file is part of LOOT. + +LOOT is free software: you can redistribute +it and/or modify it under the terms of the GNU General Public License +as published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. + +LOOT is distributed in the hope that it will +be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LOOT. If not, see +. +*/ + +#ifndef LOOT_BACKEND_LOOT_VERSION +#define LOOT_BACKEND_LOOT_VERSION + +#include + +namespace loot { + class LootVersion { + public: + static const unsigned int major; + static const unsigned int minor; + static const unsigned int patch; + static const std::string revision; + }; +} + +#endif diff --git a/src/backend/game/game.cpp b/src/backend/game/game.cpp index 6d55ace0..d317723e 100644 --- a/src/backend/game/game.cpp +++ b/src/backend/game/game.cpp @@ -23,7 +23,7 @@ */ #include "game.h" -#include "../globals.h" +#include "../app/loot_paths.h" #include "../helpers/helpers.h" #include "../error.h" @@ -67,8 +67,8 @@ namespace loot { if (createFolder) { //Make sure that the LOOT game path exists. try { - if (!fs::exists(g_path_local / FolderName())) - fs::create_directories(g_path_local / FolderName()); + if (!fs::exists(LootPaths::getLootDataPath() / FolderName())) + fs::create_directories(LootPaths::getLootDataPath() / FolderName()); } catch (fs::filesystem_error& e) { BOOST_LOG_TRIVIAL(error) << "Could not create LOOT folder for game. Details: " << e.what(); diff --git a/src/backend/game/game_cache.cpp b/src/backend/game/game_cache.cpp index 9dd71763..813726bb 100644 --- a/src/backend/game/game_cache.cpp +++ b/src/backend/game/game_cache.cpp @@ -23,7 +23,6 @@ */ #include "game_cache.h" -#include "../globals.h" #include "../helpers/helpers.h" #include "../error.h" diff --git a/src/backend/game/game_settings.cpp b/src/backend/game/game_settings.cpp index 604e8832..12001ede 100644 --- a/src/backend/game/game_settings.cpp +++ b/src/backend/game/game_settings.cpp @@ -23,7 +23,7 @@ */ #include "game_settings.h" -#include "../globals.h" +#include "../app/loot_paths.h" #include "../helpers/helpers.h" #include "../error.h" @@ -181,14 +181,14 @@ namespace loot { if (_lootFolderName.empty()) return ""; else - return g_path_local / _lootFolderName / "masterlist.yaml"; + return LootPaths::getLootDataPath() / _lootFolderName / "masterlist.yaml"; } fs::path GameSettings::UserlistPath() const { if (_lootFolderName.empty()) return ""; else - return g_path_local / _lootFolderName / "userlist.yaml"; + return LootPaths::getLootDataPath() / _lootFolderName / "userlist.yaml"; } GameSettings& GameSettings::SetName(const std::string& name) { diff --git a/src/backend/globals.cpp.in b/src/backend/globals.cpp.in deleted file mode 100644 index 5e3d579e..00000000 --- a/src/backend/globals.cpp.in +++ /dev/null @@ -1,44 +0,0 @@ -/* LOOT - - A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and - Fallout: New Vegas. - - Copyright (C) 2012-2016 WrinklyNinja - - This file is part of LOOT. - - LOOT is free software: you can redistribute - it and/or modify it under the terms of the GNU General Public License - as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - LOOT is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with LOOT. If not, see - . - */ - -#include "backend/globals.h" -#include "backend/helpers/helpers.h" - -namespace loot { - //Version numbers. - const unsigned int g_version_major = 0; - const unsigned int g_version_minor = 9; - const unsigned int g_version_patch = 0; - - // Build revision - const char * g_build_revision = "@GIT_COMMIT_STRING@"; - - //Common paths. - const boost::filesystem::path g_path_readme = boost::filesystem::current_path() / "docs" / "LOOT Readme.html"; - const boost::filesystem::path g_path_report = boost::filesystem::current_path() / "resources" / "ui" / "index.html"; - const boost::filesystem::path g_path_l10n = boost::filesystem::current_path() / "resources" / "l10n"; - const boost::filesystem::path g_path_local = GetLocalAppDataPath() / "LOOT"; - const boost::filesystem::path g_path_settings = g_path_local / "settings.yaml"; - const boost::filesystem::path g_path_log = g_path_local / "LOOTDebugLog.txt"; -} diff --git a/src/backend/helpers/helpers.cpp b/src/backend/helpers/helpers.cpp index 2dc54f6c..0f7732e4 100644 --- a/src/backend/helpers/helpers.cpp +++ b/src/backend/helpers/helpers.cpp @@ -131,42 +131,6 @@ namespace loot { #endif } - boost::filesystem::path GetLocalAppDataPath() { -#ifdef _WIN32 - HWND owner = 0; - PWSTR path; - - if (SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &path) != S_OK) - throw error(error::windows_error, lc::translate("Failed to get %LOCALAPPDATA% path.")); - - // This code runs to set the value for a global constant, so before the - // main initialisation code, which means it needs to imbue a UTF-8 - // codecvt for paths itself. - std::locale::global(std::locale(std::locale(), new std::codecvt_utf8_utf16)); - boost::filesystem::path::imbue(std::locale()); - - fs::path localAppDataPath(FromWinWide(path)); - CoTaskMemFree(path); - - return localAppDataPath; -#else - // Use XDG_CONFIG_HOME environmental variable if it's available. - const char * xdgConfigHome = getenv("XDG_CONFIG_HOME"); - - if (xdgConfigHome != nullptr) - return fs::path(xdgConfigHome); - - // Otherwise, use the HOME env. var. if it's available. - xdgConfigHome = getenv("HOME"); - - if (xdgConfigHome != nullptr) - return fs::path(xdgConfigHome) / ".config"; - - // If somehow both are missing, use the current path. - return fs::current_path(); -#endif - } - #ifdef _WIN32 //Get registry subkey value string. string RegKeyStringValue(const std::string& keyStr, const std::string& subkey, const std::string& value) { diff --git a/src/backend/helpers/helpers.h b/src/backend/helpers/helpers.h index f4ed208f..338df43a 100644 --- a/src/backend/helpers/helpers.h +++ b/src/backend/helpers/helpers.h @@ -42,9 +42,6 @@ namespace loot { //Opens the file in its registered default application. void OpenInDefaultApplication(const boost::filesystem::path& file); - //Get the local application data path, within which LOOT's data folder should be stored. - boost::filesystem::path GetLocalAppDataPath(); - #ifdef _WIN32 //Get registry subkey value string. std::string RegKeyStringValue(const std::string& keyStr, const std::string& subkey, const std::string& value); diff --git a/src/backend/metadata_list.cpp b/src/backend/metadata_list.cpp index 719a330a..48c6c341 100644 --- a/src/backend/metadata_list.cpp +++ b/src/backend/metadata_list.cpp @@ -23,7 +23,6 @@ */ #include "metadata_list.h" -#include "globals.h" #include "error.h" #include diff --git a/src/gui/handler.cpp b/src/gui/handler.cpp index 9f7d6a56..ad98fbaf 100644 --- a/src/gui/handler.cpp +++ b/src/gui/handler.cpp @@ -28,7 +28,8 @@ #include "loot_handler.h" #include "../backend/error.h" -#include "../backend/globals.h" +#include "../backend/app/loot_paths.h" +#include "../backend/app/loot_version.h" #include "../backend/plugin/plugin_sorter.h" #include "../backend/helpers/helpers.h" #include "../backend/helpers/json.h" @@ -558,18 +559,18 @@ namespace loot { void Handler::OpenReadme() { BOOST_LOG_TRIVIAL(info) << "Opening LOOT readme."; // Open readme in default application. - OpenInDefaultApplication(g_path_readme); + OpenInDefaultApplication(LootPaths::getReadmePath()); } void Handler::OpenLogLocation() { BOOST_LOG_TRIVIAL(info) << "Opening LOOT local appdata folder."; //Open debug log folder. - OpenInDefaultApplication(g_path_log.parent_path()); + OpenInDefaultApplication(LootPaths::getLogPath().parent_path()); } std::string Handler::GetVersion() { BOOST_LOG_TRIVIAL(info) << "Getting LOOT version."; - YAML::Node version(to_string(g_version_major) + "." + to_string(g_version_minor) + "." + to_string(g_version_patch) + "." + g_build_revision); + YAML::Node version(to_string(LootVersion::major) + "." + to_string(LootVersion::minor) + "." + to_string(LootVersion::patch) + "." + LootVersion::revision); return JSON::stringify(version); } @@ -653,7 +654,7 @@ namespace loot { "This probably happened because an update to LOOT changed " "its metadata syntax support. Try updating your masterlist " "to resolve the error." - )) % e.what()).str())); + )) % e.what()).str())); } } @@ -676,7 +677,7 @@ namespace loot { "[syntax documentation](http://loot.github.io/docs/%2%.%3%.%4%/LOOT%%20Metadata%%20Syntax.html).\n\n" "You can also seek support on LOOT's forum thread, which is " "linked to on [LOOT's website](http://loot.github.io/)." - )) % e.what() % g_version_major % g_version_minor % g_version_patch).str())); + )) % e.what() % LootVersion::major % LootVersion::minor % LootVersion::patch).str())); } } } diff --git a/src/gui/loot_app.cpp b/src/gui/loot_app.cpp index 36aedb7a..07ac9c52 100644 --- a/src/gui/loot_app.cpp +++ b/src/gui/loot_app.cpp @@ -26,7 +26,7 @@ #include "loot_handler.h" #include "scheme.h" -#include "../backend/globals.h" +#include "../backend/app/loot_paths.h" #include "../backend/helpers/helpers.h" #include "../backend/helpers/language.h" @@ -47,7 +47,9 @@ using boost::format; namespace fs = boost::filesystem; namespace loot { - LootApp::LootApp() {} + LootApp::LootApp() { + LootPaths::initialise(); + } void LootApp::OnBeforeCommandLineProcessing(const CefString& process_type, CefRefPtr command_line) { @@ -98,7 +100,7 @@ namespace loot { BOOST_LOG_TRIVIAL(debug) << "Initialising language settings in UI thread."; if (lootState.getLanguage().Code() != Language::english) { boost::locale::generator gen; - gen.add_messages_path(g_path_l10n.string()); + gen.add_messages_path(LootPaths::getL10nPath().string()); gen.add_messages_domain("loot"); BOOST_LOG_TRIVIAL(debug) << "Selected language: " << lootState.getLanguage().Name(); @@ -107,7 +109,7 @@ namespace loot { } // Set URL to load. Ignore any command line values. - std::string url = ToFileURL(g_path_report); + std::string url = ToFileURL(LootPaths::getUIIndexPath()); // Create the first browser window. CefBrowserHost::CreateBrowser(window_info, handler.get(), url, browser_settings, NULL); diff --git a/src/gui/loot_handler.cpp b/src/gui/loot_handler.cpp index dd4fbb77..c738964b 100644 --- a/src/gui/loot_handler.cpp +++ b/src/gui/loot_handler.cpp @@ -28,7 +28,7 @@ #include "loot_app.h" #include "../backend/error.h" -#include "../backend/globals.h" +#include "../backend/app/loot_paths.h" #include "../backend/helpers/helpers.h" #include "../backend/helpers/json.h" @@ -186,7 +186,7 @@ namespace loot { #endif try { - _lootState.save(g_path_settings); + _lootState.save(LootPaths::getSettingsPath()); } catch (std::exception &e) { BOOST_LOG_TRIVIAL(error) << "Failed to save LOOT's settings. Error: " << e.what(); @@ -241,9 +241,9 @@ namespace loot { CefRefPtr< CefRequest > request, bool is_redirect) { BOOST_LOG_TRIVIAL(trace) << "Attempting to open link: " << request->GetURL().ToString(); - BOOST_LOG_TRIVIAL(trace) << "Comparing with URL: " << ToFileURL(g_path_report); + BOOST_LOG_TRIVIAL(trace) << "Comparing with URL: " << ToFileURL(LootPaths::getUIIndexPath()); - if (boost::iequals(request->GetURL().ToString(), ToFileURL(g_path_report))) { + if (boost::iequals(request->GetURL().ToString(), ToFileURL(LootPaths::getUIIndexPath()))) { BOOST_LOG_TRIVIAL(trace) << "Link is to LOOT page, allowing CEF's default handling."; return false; } diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 2b7149c2..a10d541b 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -23,8 +23,7 @@ */ #include "loot_app.h" -#include "backend/app/loot_state.h" -#include "backend/globals.h" +#include "backend/app/loot_paths.h" #ifdef _WIN32 #include @@ -57,10 +56,10 @@ CefSettings GetCefSettings() { cef_settings.command_line_args_disabled = false; // Set CEF logging. - CefString(&cef_settings.log_file).FromString((g_path_local / "CEFDebugLog.txt").string()); + CefString(&cef_settings.log_file).FromString((LootPaths::getLootDataPath() / "CEFDebugLog.txt").string()); // Load locale pack files from LOOT's l10n path. - CefString(&cef_settings.locales_dir_path).FromString(g_path_l10n.string()); + CefString(&cef_settings.locales_dir_path).FromString(LootPaths::getL10nPath().string()); return cef_settings; } diff --git a/src/gui/scheme.cpp b/src/gui/scheme.cpp index f006ddb1..38b3118e 100644 --- a/src/gui/scheme.cpp +++ b/src/gui/scheme.cpp @@ -24,7 +24,7 @@ along with LOOT. If not, see #include "scheme.h" -#include "../backend/globals.h" +#include "backend/app/loot_paths.h" #include @@ -47,7 +47,7 @@ namespace loot { // Get the path from the custom URL, which is of the form // loot://l10n/ - string file = (g_path_l10n / request->GetURL().ToString().substr(12)).string(); + string file = (LootPaths::getL10nPath() / request->GetURL().ToString().substr(12)).string(); CefResponse::HeaderMap headers; headers.emplace("Access-Control-Allow-Origin", "*"); diff --git a/src/tests/backend/app/loot_paths_test.h b/src/tests/backend/app/loot_paths_test.h new file mode 100644 index 00000000..a2d55f11 --- /dev/null +++ b/src/tests/backend/app/loot_paths_test.h @@ -0,0 +1,86 @@ +/* LOOT + +A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and +Fallout: New Vegas. + +Copyright (C) 2014-2016 WrinklyNinja + +This file is part of LOOT. + +LOOT is free software: you can redistribute +it and/or modify it under the terms of the GNU General Public License +as published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. + +LOOT is distributed in the hope that it will +be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LOOT. If not, see +. +*/ + +#ifndef LOOT_TEST_BACKEND_LOOT_PATHS +#define LOOT_TEST_BACKEND_LOOT_PATHS + +#include "backend/app/loot_paths.h" + +namespace loot { + namespace test { + TEST(LootPaths, getReadmePathShouldUseLootAppPath) { + LootPaths::setLootAppPath("readme"); + + EXPECT_EQ(boost::filesystem::path("readme") / "docs" / "LOOT Readme.html", LootPaths::getReadmePath()); + } + + TEST(LootPaths, getUIIndexPathShouldUseLootAppPath) { + LootPaths::setLootAppPath("ui"); + + EXPECT_EQ(boost::filesystem::path("ui") / "resources" / "ui" / "index.html", LootPaths::getUIIndexPath()); + } + + TEST(LootPaths, getL10nPathShouldUseLootAppPath) { + LootPaths::setLootAppPath("l10n"); + + EXPECT_EQ(boost::filesystem::path("l10n") / "resources" / "l10n", LootPaths::getL10nPath()); + } + + TEST(LootPaths, getLootDataPathShouldReturnTheSetPath) { + LootPaths::setLootDataPath("data"); + + EXPECT_EQ("data", LootPaths::getLootDataPath()); + } + + TEST(LootPaths, getSettingsPathShouldUseLootDataPath) { + LootPaths::setLootDataPath("settings"); + + EXPECT_EQ(boost::filesystem::path("settings") / "settings.yaml", LootPaths::getSettingsPath()); + } + + TEST(LootPaths, getLogPathShouldUseLootDataPath) { + LootPaths::setLootDataPath("log"); + + EXPECT_EQ(boost::filesystem::path("log") / "LOOTDebugLog.txt", LootPaths::getLogPath()); + } + + TEST(LootPaths, initialiseShouldSetTheAppPathToTheCurrentPath) { + LootPaths::initialise(); + + EXPECT_EQ(boost::filesystem::current_path(), LootPaths::getReadmePath().parent_path().parent_path()); + } + + TEST(LootPaths, initialiseShouldSetTheAppPathToTheLocalAppDataPathSlashLoot) { + LootPaths::initialise(); + + // Can't actually know what the path should be, but we can check + // its properties. + EXPECT_EQ("LOOT", LootPaths::getLootDataPath().filename()); + EXPECT_FALSE(LootPaths::getLootDataPath().parent_path().empty()); + EXPECT_TRUE(boost::filesystem::exists(LootPaths::getLootDataPath().parent_path())); + } + } +} + +#endif diff --git a/src/tests/backend/app/loot_settings_test.h b/src/tests/backend/app/loot_settings_test.h index 8941db8a..a12949f2 100644 --- a/src/tests/backend/app/loot_settings_test.h +++ b/src/tests/backend/app/loot_settings_test.h @@ -26,7 +26,7 @@ along with LOOT. If not, see #define LOOT_TEST_GUI_LOOT_SETTINGS #include "backend/app/loot_settings.h" -#include "backend/globals.h" +#include "backend/app/loot_version.h" namespace loot { namespace test { @@ -43,7 +43,7 @@ namespace loot { }; TEST_F(LootSettingsTest, defaultConstructorShouldSetDefaultValues) { - const std::string currentVersion = std::to_string(g_version_major) + "." + std::to_string(g_version_minor) + "." + std::to_string(g_version_patch); + const std::string currentVersion = std::to_string(LootVersion::major) + "." + std::to_string(LootVersion::minor) + "." + std::to_string(LootVersion::patch); const std::vector expectedGameSettings({ GameSettings(GameSettings::tes4), GameSettings(GameSettings::tes5), @@ -408,7 +408,7 @@ namespace loot { } TEST_F(LootSettingsTest, updateLastVersionShouldSetValueToCurrentLootVersion) { - const std::string currentVersion = std::to_string(g_version_major) + "." + std::to_string(g_version_minor) + "." + std::to_string(g_version_patch); + const std::string currentVersion = std::to_string(LootVersion::major) + "." + std::to_string(LootVersion::minor) + "." + std::to_string(LootVersion::patch); YAML::Node inputYaml; inputYaml["lastVersion"] = "v0.7.1"; diff --git a/src/tests/backend/game/game_settings_test.h b/src/tests/backend/game/game_settings_test.h index c56adcf9..69c7a780 100644 --- a/src/tests/backend/game/game_settings_test.h +++ b/src/tests/backend/game/game_settings_test.h @@ -25,7 +25,7 @@ along with LOOT. If not, see #ifndef LOOT_TEST_BACKEND_GAME_SETTINGS #define LOOT_TEST_BACKEND_GAME_SETTINGS -#include "backend/globals.h" +#include "backend/app/loot_paths.h" #include "backend/game/game_settings.h" #include "tests/base_game_test.h" @@ -75,16 +75,16 @@ namespace loot { EXPECT_EQ("", game.GamePath()); EXPECT_EQ("", game.DataPath()); - EXPECT_EQ(g_path_local / "Skyrim" / "masterlist.yaml", game.MasterlistPath()); - EXPECT_EQ(g_path_local / "Skyrim" / "userlist.yaml", game.UserlistPath()); + EXPECT_EQ(LootPaths::getLootDataPath() / "Skyrim" / "masterlist.yaml", game.MasterlistPath()); + EXPECT_EQ(LootPaths::getLootDataPath() / "Skyrim" / "userlist.yaml", game.UserlistPath()); } TEST_P(GameSettingsTest, idConstructorShouldSetGameFolderIfGiven) { game = GameSettings(GameSettings::tes5, "folder"); EXPECT_EQ("folder", game.FolderName()); - EXPECT_EQ(g_path_local / "folder" / "masterlist.yaml", game.MasterlistPath()); - EXPECT_EQ(g_path_local / "folder" / "userlist.yaml", game.UserlistPath()); + EXPECT_EQ(LootPaths::getLootDataPath() / "folder" / "masterlist.yaml", game.MasterlistPath()); + EXPECT_EQ(LootPaths::getLootDataPath() / "folder" / "userlist.yaml", game.UserlistPath()); } TEST_P(GameSettingsTest, isInstalledShouldBeFalseIfGamePathIsNotSet) { diff --git a/src/tests/backend/game/game_test.h b/src/tests/backend/game/game_test.h index 52150702..a5f02c59 100644 --- a/src/tests/backend/game/game_test.h +++ b/src/tests/backend/game/game_test.h @@ -26,7 +26,7 @@ along with LOOT. If not, see #define LOOT_TEST_BACKEND_GAME #include "backend/error.h" -#include "backend/globals.h" +#include "backend/app/loot_paths.h" #include "backend/game/game.h" #include "load_order_handler_test.h" @@ -39,7 +39,7 @@ namespace loot { void TearDown() { BaseGameTest::TearDown(); - ASSERT_NO_THROW(boost::filesystem::remove_all(g_path_local)); + ASSERT_NO_THROW(boost::filesystem::remove_all(LootPaths::getLootDataPath())); } #endif }; @@ -121,7 +121,7 @@ namespace loot { TEST_P(GameTest, initShouldThrowOnLinuxIfLocalPathIsNotGiven) { Game game = Game(GetParam()).SetGamePath(dataPath.parent_path()); - ASSERT_FALSE(boost::filesystem::exists(g_path_local / game.FolderName())); + ASSERT_FALSE(boost::filesystem::exists(LootPaths::getLootDataPath() / game.FolderName())); EXPECT_THROW(game.Init(false), error); } @@ -130,19 +130,19 @@ namespace loot { TEST_P(GameTest, initShouldNotCreateAGameFolderIfTheCreateFolderArgumentIsFalse) { Game game = Game(GetParam()).SetGamePath(dataPath.parent_path()); - ASSERT_FALSE(boost::filesystem::exists(g_path_local / game.FolderName())); + ASSERT_FALSE(boost::filesystem::exists(LootPaths::getLootDataPath() / game.FolderName())); EXPECT_NO_THROW(game.Init(false, localPath)); - EXPECT_FALSE(boost::filesystem::exists(g_path_local / game.FolderName())); + EXPECT_FALSE(boost::filesystem::exists(LootPaths::getLootDataPath() / game.FolderName())); } TEST_P(GameTest, initShouldCreateAGameFolderIfTheCreateFolderArgumentIsTrue) { Game game = Game(GetParam()).SetGamePath(dataPath.parent_path()); - ASSERT_FALSE(boost::filesystem::exists(g_path_local / game.FolderName())); + ASSERT_FALSE(boost::filesystem::exists(LootPaths::getLootDataPath() / game.FolderName())); EXPECT_NO_THROW(game.Init(true, localPath)); - EXPECT_TRUE(boost::filesystem::exists(g_path_local / game.FolderName())); + EXPECT_TRUE(boost::filesystem::exists(LootPaths::getLootDataPath() / game.FolderName())); } #else TEST_P(GameTest, initShouldNotThrowOnWindowsIfLocalPathIsNotGiven) { diff --git a/src/tests/backend/helpers/version_test.h b/src/tests/backend/helpers/version_test.h index 6f540899..5ce5a158 100644 --- a/src/tests/backend/helpers/version_test.h +++ b/src/tests/backend/helpers/version_test.h @@ -25,7 +25,6 @@ along with LOOT. If not, see #ifndef LOOT_TEST_BACKEND_HELPERS_VERSION #define LOOT_TEST_BACKEND_HELPERS_VERSION -#include "backend/globals.h" #include "backend/helpers/version.h" #include @@ -37,10 +36,10 @@ namespace loot { // Use the API DLL built. Version version(boost::filesystem::path("loot_api.dll")); std::string expected( - std::to_string(g_version_major) + "." + - std::to_string(g_version_minor) + "." + - std::to_string(g_version_patch) + ".0" - ); + std::to_string(LootVersion::major) + "." + + std::to_string(LootVersion::minor) + "." + + std::to_string(LootVersion::patch) + ".0" + ); EXPECT_EQ(expected, version.AsString()); } #endif diff --git a/src/tests/backend/masterlist_test.h b/src/tests/backend/masterlist_test.h index a663ac51..54519c0c 100644 --- a/src/tests/backend/masterlist_test.h +++ b/src/tests/backend/masterlist_test.h @@ -26,6 +26,7 @@ along with LOOT. If not, see #define LOOT_TEST_BACKEND_MASTERLIST #include "backend/masterlist.h" +#include "backend/app/loot_paths.h" #include "tests/base_game_test.h" namespace loot { @@ -43,7 +44,7 @@ namespace loot { ASSERT_FALSE(boost::filesystem::exists(masterlistPath)); ASSERT_FALSE(boost::filesystem::exists(localPath / ".git")); - ASSERT_NO_THROW(boost::filesystem::create_directories(g_path_local / Game(GetParam()).FolderName())); + ASSERT_NO_THROW(boost::filesystem::create_directories(LootPaths::getLootDataPath() / Game(GetParam()).FolderName())); } void TearDown() { @@ -52,8 +53,8 @@ namespace loot { ASSERT_NO_THROW(boost::filesystem::remove(masterlistPath)); ASSERT_NO_THROW(boost::filesystem::remove_all(localPath / ".git")); - ASSERT_NO_THROW(boost::filesystem::remove(g_path_local / Game(GetParam()).FolderName() / "masterlist.yaml")); - ASSERT_NO_THROW(boost::filesystem::remove_all(g_path_local / Game(GetParam()).FolderName() / ".git")); + ASSERT_NO_THROW(boost::filesystem::remove(LootPaths::getLootDataPath() / Game(GetParam()).FolderName() / "masterlist.yaml")); + ASSERT_NO_THROW(boost::filesystem::remove_all(LootPaths::getLootDataPath() / Game(GetParam()).FolderName() / ".git")); } const std::string repoUrl; diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 2ba489de..9de3a2c4 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -41,6 +41,7 @@ #include "api/loot_update_masterlist_test.h" #include "api/loot_write_minimal_list_test.h" #include "api/test_api.h" +#include "backend/app/loot_paths_test.h" #include "backend/app/loot_settings_test.h" #include "backend/app/loot_state_test.h" #include "backend/game/game_test.h" diff --git a/src/validator/main.cpp b/src/validator/main.cpp index f3337598..b1df79d4 100644 --- a/src/validator/main.cpp +++ b/src/validator/main.cpp @@ -27,7 +27,7 @@ #define BOOST_NO_CXX11_SCOPED_ENUMS #endif -#include "backend/globals.h" +#include "backend/app/loot_version.h" #include "backend/metadata_list.h" #include @@ -54,9 +54,9 @@ int main(int argc, char **argv) { // Print version info if -v or --version are given. if ((strcmp(argv[1], "-v") == 0) || (strcmp(argv[1], "--version") == 0)) { std::cout << std::endl << "LOOT Metadata Validator" << std::endl - << "v" << loot::g_version_major << "." << loot::g_version_minor - << "." << loot::g_version_patch << std::endl - << "build revision " << loot::g_build_revision << std::endl << std::endl; + << "v" << loot::LootVersion::major << "." << loot::LootVersion::minor + << "." << loot::LootVersion::patch << std::endl + << "build revision " << loot::LootVersion::revision << std::endl << std::endl; return 0; }