diff --git a/plugins/builtin/include/content/popups/popup_file_chooser.hpp b/plugins/builtin/include/content/popups/popup_file_chooser.hpp index 3c84c7127..a8007399d 100644 --- a/plugins/builtin/include/content/popups/popup_file_chooser.hpp +++ b/plugins/builtin/include/content/popups/popup_file_chooser.hpp @@ -13,14 +13,29 @@ namespace hex::plugin::builtin { class PopupFileChooser : public Popup { public: - PopupFileChooser(const std::vector &files, const std::vector &validExtensions, bool multiple, const std::function &callback) + PopupFileChooser(const std::vector &basePaths, const std::vector &files, const std::vector &validExtensions, bool multiple, const std::function &callback) : hex::Popup("hex.builtin.common.choose_file"), - m_indices({ }), m_files(files), + m_indices({ }), m_openCallback(callback), m_validExtensions(validExtensions), m_multiple(multiple) { - std::sort(this->m_files.begin(), this->m_files.end(), [](const std::fs::path &a, const std::fs::path &b) { - return a.filename() < b.filename(); + for (const auto &path : files) { + std::fs::path adjustedPath; + for (const auto &basePath : basePaths) { + if (isSubpath(basePath, path)) { + adjustedPath = std::fs::relative(path, basePath); + break; + } + } + + if (adjustedPath.empty()) + adjustedPath = path.filename(); + + this->m_files.push_back({ path, adjustedPath }); + } + + std::sort(this->m_files.begin(), this->m_files.end(), [](const auto &a, const auto &b) { + return a.first < b.first; }); } @@ -29,11 +44,11 @@ namespace hex::plugin::builtin { if (ImGui::BeginListBox("##files", scaled(ImVec2(500, 400)))) { u32 index = 0; - for (auto &path : this->m_files) { + for (auto &[path, pathName] : this->m_files) { ImGui::PushID(index); bool selected = this->m_indices.contains(index); - if (ImGui::Selectable(wolv::util::toUTF8String(path.filename()).c_str(), selected, ImGuiSelectableFlags_DontClosePopups)) { + if (ImGui::Selectable(wolv::util::toUTF8String(pathName).c_str(), selected, ImGuiSelectableFlags_DontClosePopups)) { if (!this->m_multiple) { this->m_indices.clear(); this->m_indices.insert(index); @@ -60,7 +75,7 @@ namespace hex::plugin::builtin { if (ImGui::Button("hex.builtin.common.open"_lang) || doubleClicked) { for (const auto &index : this->m_indices) - this->m_openCallback(this->m_files[index]); + this->m_openCallback(this->m_files[index].first); Popup::close(); } @@ -78,9 +93,16 @@ namespace hex::plugin::builtin { return ImGuiWindowFlags_AlwaysAutoResize; } + private: + static bool isSubpath(const std::fs::path &basePath, const std::fs::path &path) { + auto relativePath = std::fs::relative(path, basePath); + + return !relativePath.empty() && relativePath.native()[0] != '.'; + } + private: std::set m_indices; - std::vector m_files; + std::vector> m_files; std::function m_openCallback; std::vector m_validExtensions; bool m_multiple = false; diff --git a/plugins/builtin/source/content/views/view_hex_editor.cpp b/plugins/builtin/source/content/views/view_hex_editor.cpp index e4b0f5fa4..aeb9a0b76 100644 --- a/plugins/builtin/source/content/views/view_hex_editor.cpp +++ b/plugins/builtin/source/content/views/view_hex_editor.cpp @@ -1067,8 +1067,9 @@ namespace hex::plugin::builtin { ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.custom_encoding" }, 5050, Shortcut::None, [this]{ + const auto basePaths = fs::getDefaultPaths(fs::ImHexPath::Encodings); std::vector paths; - for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Encodings)) { + for (const auto &path : basePaths) { std::error_code error; for (const auto &entry : std::fs::recursive_directory_iterator(path, error)) { if (!entry.is_regular_file()) continue; @@ -1077,7 +1078,7 @@ namespace hex::plugin::builtin { } } - PopupFileChooser::open(paths, std::vector{ {"Thingy Table File", "tbl"} }, false, + PopupFileChooser::open(basePaths, paths, std::vector{ {"Thingy Table File", "tbl"} }, false, [this](const auto &path) { TaskManager::createTask("Loading encoding file", 0, [this, path](auto&) { auto encoding = EncodingFile(EncodingFile::Type::Thingy, path); diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index 9a36a7d1d..8e694bdc1 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -1159,9 +1159,10 @@ namespace hex::plugin::builtin { ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.pattern" }, 4050, Shortcut::None, [this] { auto provider = ImHexApi::Provider::get(); + const auto basePaths = fs::getDefaultPaths(fs::ImHexPath::Patterns); std::vector paths; - for (const auto &imhexPath : fs::getDefaultPaths(fs::ImHexPath::Patterns)) { + for (const auto &imhexPath : basePaths) { if (!wolv::io::fs::exists(imhexPath)) continue; std::error_code error; @@ -1172,7 +1173,7 @@ namespace hex::plugin::builtin { } } - PopupFileChooser::open(paths, std::vector{ { "Pattern File", "hexpat" } }, false, + PopupFileChooser::open(basePaths, paths, std::vector{ { "Pattern File", "hexpat" } }, false, [this, provider](const std::fs::path &path) { this->loadPatternFile(path, provider); AchievementManager::unlockAchievement("hex.builtin.achievement.patterns", "hex.builtin.achievement.patterns.load_existing.name"); diff --git a/plugins/builtin/source/content/views/view_yara.cpp b/plugins/builtin/source/content/views/view_yara.cpp index 95e053787..1308714b0 100644 --- a/plugins/builtin/source/content/views/view_yara.cpp +++ b/plugins/builtin/source/content/views/view_yara.cpp @@ -114,8 +114,9 @@ namespace hex::plugin::builtin { } if (ImGui::IconButton(ICON_VS_ADD, ImGui::GetStyleColorVec4(ImGuiCol_Text))) { + const auto basePaths = fs::getDefaultPaths(fs::ImHexPath::Yara); std::vector paths; - for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Yara)) { + for (const auto &path : basePaths) { std::error_code error; for (const auto &entry : std::fs::recursive_directory_iterator(path, error)) { if (!entry.is_regular_file()) continue; @@ -125,7 +126,7 @@ namespace hex::plugin::builtin { } } - PopupFileChooser::open(paths, std::vector{ { "Yara File", "yara" }, { "Yara File", "yar" } }, true, + PopupFileChooser::open(basePaths, paths, std::vector{ { "Yara File", "yara" }, { "Yara File", "yar" } }, true, [&](const auto &path) { this->m_rules->push_back({ path.filename(), path }); });