diff --git a/lib/libimhex/source/api/imhex_api.cpp b/lib/libimhex/source/api/imhex_api.cpp index 30bf5c3b0..ff3c7d7a2 100644 --- a/lib/libimhex/source/api/imhex_api.cpp +++ b/lib/libimhex/source/api/imhex_api.cpp @@ -344,7 +344,7 @@ namespace hex { s_customFontPath = path; } - static float s_fontSize; + static float s_fontSize = 13.0; void setFontSize(float size) { s_fontSize = size; } diff --git a/lib/libimhex/source/helpers/fs.cpp b/lib/libimhex/source/helpers/fs.cpp index 2bb3bd155..d5b602c71 100644 --- a/lib/libimhex/source/helpers/fs.cpp +++ b/lib/libimhex/source/helpers/fs.cpp @@ -104,224 +104,122 @@ namespace hex::fs { return result == NFD_OKAY; } + static std::vector getDataPaths() { + std::vector paths; + + #if defined(OS_WINDOWS) + + if (!ImHexApi::System::isPortableVersion()) { + PWSTR wAppDataPath = nullptr; + if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_CREATE, nullptr, &wAppDataPath))) { + paths.emplace_back(wAppDataPath); + CoTaskMemFree(wAppDataPath); + } + } + + #elif defined(OS_MACOS) + + std::fs::path applicationSupportDirPath; + { + auto string = getMacApplicationSupportDirectoryPath(); + applicationSupportDirPath = std::string(string); + macFree(string); + } + + paths.push_back(applicationSupportDirPath); + + #elif defined(OS_LINUX) + + auto dataDirs = xdg::DataDirs(); + auto dataDirsHome = xdg::DataHomeDir(); + + std::copy(dataDirs.begin(), dataDirs.end(), std::back_inserter(paths)); + std::copy(dataDirsHome.begin(), dataDirsHome.end(), std::back_inserter(paths)); + + #endif + + for (auto &path : paths) { + path = path / "imhex"; + } + + if (auto executablePath = fs::getExecutablePath(); executablePath.has_value()) + paths.push_back(executablePath->parent_path()); + + auto additionalDirs = ImHexApi::System::getAdditionalFolderPaths(); + std::copy(additionalDirs.begin(), additionalDirs.end(), std::back_inserter(paths)); + + return paths; + } + + static std::vector getConfigPaths() { + #if defined(OS_WINDOWS) + return getDataPaths(); + #elif defined(OS_MACOS) + return getDataPaths(); + #elif defined(OS_LINUX) + std::vector paths; + + auto configDirs = xdg::ConfigDirs(); + auto configDirsHome = xdg::ConfigHomeDir(); + + std::copy(configDirs.begin(), configDirs.end(), std::back_inserter(paths)); + std::copy(configDirsHome.begin(), configDirsHome.end(), std::back_inserter(paths)); + + return paths; + #endif + } + std::vector getDefaultPaths(ImHexPath path, bool listNonExisting) { std::vector result; - const auto exePath = getExecutablePath(); - auto userDirs = ImHexApi::System::getAdditionalFolderPaths(); - [[maybe_unused]] - auto addUserDirs = [&userDirs](auto &paths) { - std::transform(userDirs.begin(), userDirs.end(), std::back_inserter(paths), [](auto &item) { - return std::move(item); - }); + constexpr auto appendPath = [](std::vector paths, const std::fs::path &folder) { + for (auto &path : paths) + path = path / folder; + + return paths; }; -#if defined(OS_WINDOWS) - std::vector paths; - - if (!ImHexApi::System::isPortableVersion()) { - std::fs::path appDataDir; - { - PWSTR wAppDataPath = nullptr; - if (!SUCCEEDED(SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_CREATE, nullptr, &wAppDataPath))) - throw std::runtime_error("Failed to get APPDATA folder path"); - - appDataDir = std::wstring(wAppDataPath); - CoTaskMemFree(wAppDataPath); - } - - paths.push_back(appDataDir / "imhex"); - } - - if (exePath) - paths.push_back(exePath->parent_path()); - switch (path) { - case ImHexPath::Patterns: - addUserDirs(paths); - std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return path / "patterns"; - }); - break; - case ImHexPath::PatternsInclude: - addUserDirs(paths); - std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return path / "includes"; - }); - break; - case ImHexPath::Magic: - addUserDirs(paths); - std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return path / "magic"; - }); - break; - case ImHexPath::Python: - addUserDirs(paths); - std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return path / "python"; - }); - break; - case ImHexPath::Plugins: - std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return path / "plugins"; - }); - break; - case ImHexPath::Yara: - addUserDirs(paths); - std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return path / "yara"; - }); + case ImHexPath::Constants: + result = appendPath(getDataPaths(), "constants"); break; case ImHexPath::Config: - std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return path / "config"; - }); - break; - case ImHexPath::Resources: - std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return path / "resources"; - }); - break; - case ImHexPath::Constants: - addUserDirs(paths); - std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return path / "constants"; - }); + result = appendPath(getConfigPaths(), "config"); break; case ImHexPath::Encodings: - addUserDirs(paths); - std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return path / "encodings"; - }); + result = appendPath(getDataPaths(), "encodings"); break; case ImHexPath::Logs: - std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return path / "logs"; - }); - break; - default: - hex::unreachable(); - } -#elif defined(OS_MACOS) - // Get path to special directories - std::string applicationSupportDir; - { - auto string = getMacApplicationSupportDirectoryPath(); - applicationSupportDir = string; - macFree(string); - } - const std::fs::path applicationSupportDirPath(applicationSupportDir); - - std::vector paths = { applicationSupportDirPath }; - - if (exePath.has_value()) - paths.push_back(exePath.value()); - - switch (path) { - case ImHexPath::Patterns: - result.push_back(applicationSupportDirPath / "patterns"); - break; - case ImHexPath::PatternsInclude: - result.push_back(applicationSupportDirPath / "includes"); - break; - case ImHexPath::Magic: - result.push_back(applicationSupportDirPath / "magic"); - break; - case ImHexPath::Python: - result.push_back(applicationSupportDirPath / "python"); + result = appendPath(getConfigPaths(), "logs"); break; case ImHexPath::Plugins: - std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path) { - return path / "plugins"; - }); - break; - case ImHexPath::Yara: - result.push_back(applicationSupportDirPath / "yara"); - break; - case ImHexPath::Config: - result.push_back(applicationSupportDirPath / "config"); + result = appendPath(getDataPaths(), "plugins"); break; case ImHexPath::Resources: - result.push_back(applicationSupportDirPath / "resources"); - break; - case ImHexPath::Constants: - result.push_back(applicationSupportDirPath / "constants"); - break; - case ImHexPath::Encodings: - result.push_back(applicationSupportDirPath / "encodings"); - break; - case ImHexPath::Logs: - result.push_back(applicationSupportDirPath / "logs"); - break; - default: - hex::unreachable(); - } -#else - std::vector configDirs = xdg::ConfigDirs(); - std::vector dataDirs = xdg::DataDirs(); - - configDirs.insert(configDirs.begin(), xdg::ConfigHomeDir()); - dataDirs.insert(dataDirs.begin(), xdg::DataHomeDir()); - - for (auto &dir : dataDirs) - dir = dir / "imhex"; - - if (exePath && !exePath->empty()) - dataDirs.push_back(exePath->parent_path()); - - switch (path) { - case ImHexPath::Patterns: - addUserDirs(dataDirs); - std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "patterns"; }); - break; - case ImHexPath::PatternsInclude: - addUserDirs(dataDirs); - std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "includes"; }); + result = appendPath(getDataPaths(), "resources"); break; case ImHexPath::Magic: - addUserDirs(dataDirs); - std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "magic"; }); + result = appendPath(getDataPaths(), "magic"); + break; + case ImHexPath::Patterns: + result = appendPath(getDataPaths(), "patterns"); + break; + case ImHexPath::PatternsInclude: + result = appendPath(getDataPaths(), "includes"); break; case ImHexPath::Python: - addUserDirs(dataDirs); - std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p; }); - break; - case ImHexPath::Plugins: - std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "plugins"; }); + result = appendPath(getDataPaths(), "python"); break; case ImHexPath::Yara: - addUserDirs(dataDirs); - std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "yara"; }); + result = appendPath(getDataPaths(), "yara"); break; - case ImHexPath::Config: - std::transform(configDirs.begin(), configDirs.end(), std::back_inserter(result), [](auto p) { return p / "imhex"; }); - break; - case ImHexPath::Resources: - std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "resources"; }); - break; - case ImHexPath::Constants: - addUserDirs(dataDirs); - std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "constants"; }); - break; - case ImHexPath::Encodings: - addUserDirs(dataDirs); - std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "encodings"; }); - break; - case ImHexPath::Logs: - std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result), [](auto p) { return p / "logs"; }); - break; - default: - hex::unreachable(); } -#endif - if (!listNonExisting) { result.erase(std::remove_if(result.begin(), result.end(), [](const auto &path) { return !fs::isDirectory(path); - }), - result.end()); + }), result.end()); } return result;