1
0
mirror of synced 2025-01-19 01:24:15 +01:00

fs: Refactored default path handling (#637)

This commit is contained in:
WerWolv 2022-08-02 22:55:01 +02:00 committed by GitHub
parent f1c61f44c6
commit 30b2378778
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 88 additions and 190 deletions

View File

@ -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;
}

View File

@ -104,224 +104,122 @@ namespace hex::fs {
return result == NFD_OKAY;
}
static std::vector<std::fs::path> getDataPaths() {
std::vector<std::fs::path> 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<std::fs::path> getConfigPaths() {
#if defined(OS_WINDOWS)
return getDataPaths();
#elif defined(OS_MACOS)
return getDataPaths();
#elif defined(OS_LINUX)
std::vector<std::fs::path> 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<std::fs::path> getDefaultPaths(ImHexPath path, bool listNonExisting) {
std::vector<std::fs::path> 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<std::fs::path> paths, const std::fs::path &folder) {
for (auto &path : paths)
path = path / folder;
return paths;
};
#if defined(OS_WINDOWS)
std::vector<std::fs::path> 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<std::fs::path> 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<std::fs::path> configDirs = xdg::ConfigDirs();
std::vector<std::fs::path> 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;