feat: Allow multiple yara files to be selected at once
This commit is contained in:
parent
800ffb5e56
commit
29c1a0cb78
@ -139,6 +139,6 @@ namespace hex {
|
||||
EVENT_DEF(RequestShowErrorPopup, std::string);
|
||||
EVENT_DEF(RequestShowFatalErrorPopup, std::string);
|
||||
EVENT_DEF(RequestShowYesNoQuestionPopup, std::string, std::function<void()>, std::function<void()>);
|
||||
EVENT_DEF(RequestShowFileChooserPopup, std::vector<std::fs::path>, std::vector<nfdfilteritem_t>, std::function<void(std::fs::path)>);
|
||||
EVENT_DEF(RequestShowFileChooserPopup, std::vector<std::fs::path>, std::vector<nfdfilteritem_t>, std::function<void(std::fs::path)>, bool);
|
||||
|
||||
}
|
@ -84,7 +84,7 @@ namespace hex::fs {
|
||||
};
|
||||
|
||||
void setFileBrowserErrorCallback(const std::function<void()> &callback);
|
||||
bool openFileBrowser(DialogMode mode, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &callback, const std::string &defaultPath = {});
|
||||
bool openFileBrowser(DialogMode mode, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &callback, const std::string &defaultPath = {}, bool multiple = false);
|
||||
|
||||
enum class ImHexPath : u32 {
|
||||
Patterns = 0,
|
||||
|
@ -39,7 +39,7 @@ namespace hex {
|
||||
static void showFatalPopup(const std::string &message);
|
||||
static void showYesNoQuestionPopup(const std::string &message, const std::function<void()> &yesCallback, const std::function<void()> &noCallback);
|
||||
|
||||
static void showFileChooserPopup(const std::vector<std::fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &callback);
|
||||
static void showFileChooserPopup(const std::vector<std::fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, bool multiple, const std::function<void(std::fs::path)> &callback);
|
||||
|
||||
[[nodiscard]] virtual bool hasViewMenuItemEntry() const;
|
||||
[[nodiscard]] virtual ImVec2 getMinSize() const;
|
||||
|
@ -81,20 +81,24 @@ namespace hex::fs {
|
||||
s_fileBrowserErrorCallback = callback;
|
||||
}
|
||||
|
||||
bool openFileBrowser(DialogMode mode, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &callback, const std::string &defaultPath) {
|
||||
bool openFileBrowser(DialogMode mode, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &callback, const std::string &defaultPath, bool multiple) {
|
||||
NFD::Init();
|
||||
|
||||
nfdchar_t *outPath = nullptr;
|
||||
NFD::UniquePathU8 outPath;
|
||||
NFD::UniquePathSet outPaths;
|
||||
nfdresult_t result;
|
||||
switch (mode) {
|
||||
case DialogMode::Open:
|
||||
result = NFD::OpenDialog(outPath, validExtensions.data(), validExtensions.size(), defaultPath.c_str());
|
||||
if (multiple)
|
||||
result = NFD::OpenDialogMultiple(outPaths, validExtensions.data(), validExtensions.size(), defaultPath.empty() ? nullptr : defaultPath.c_str());
|
||||
else
|
||||
result = NFD::OpenDialog(outPath, validExtensions.data(), validExtensions.size(), defaultPath.empty() ? nullptr : defaultPath.c_str());
|
||||
break;
|
||||
case DialogMode::Save:
|
||||
result = NFD::SaveDialog(outPath, validExtensions.data(), validExtensions.size(), defaultPath.c_str());
|
||||
result = NFD::SaveDialog(outPath, validExtensions.data(), validExtensions.size(), defaultPath.empty() ? nullptr : defaultPath.c_str());
|
||||
break;
|
||||
case DialogMode::Folder:
|
||||
result = NFD::PickFolder(outPath, defaultPath.c_str());
|
||||
result = NFD::PickFolder(outPath, defaultPath.empty() ? nullptr : defaultPath.c_str());
|
||||
break;
|
||||
default:
|
||||
hex::unreachable();
|
||||
@ -102,10 +106,19 @@ namespace hex::fs {
|
||||
|
||||
if (result == NFD_OKAY){
|
||||
if(outPath != nullptr) {
|
||||
callback(reinterpret_cast<char8_t*>(outPath));
|
||||
NFD::FreePath(outPath);
|
||||
callback(reinterpret_cast<char8_t*>(outPath.get()));
|
||||
}
|
||||
} else if (result==NFD_ERROR) {
|
||||
if (outPaths != nullptr) {
|
||||
nfdpathsetsize_t numPaths = 0;
|
||||
if (NFD::PathSet::Count(outPaths, numPaths) == NFD_OKAY) {
|
||||
for (size_t i = 0; i < numPaths; i++) {
|
||||
NFD::UniquePathSetPath path;
|
||||
if (NFD::PathSet::GetPath(outPaths, i, path) == NFD_OKAY)
|
||||
callback(reinterpret_cast<char8_t*>(path.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (result == NFD_ERROR) {
|
||||
if (s_fileBrowserErrorCallback != nullptr)
|
||||
s_fileBrowserErrorCallback();
|
||||
}
|
||||
|
@ -34,13 +34,13 @@ namespace hex {
|
||||
|
||||
}
|
||||
|
||||
void View::showFileChooserPopup(const std::vector<std::fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &callback) {
|
||||
void View::showFileChooserPopup(const std::vector<std::fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, bool multiple, const std::function<void(std::fs::path)> &callback) {
|
||||
if (paths.empty()) {
|
||||
fs::openFileBrowser(fs::DialogMode::Open, validExtensions, [callback](const auto &path) {
|
||||
callback(path);
|
||||
});
|
||||
}, {}, multiple);
|
||||
} else {
|
||||
EventManager::post<RequestShowFileChooserPopup>(paths, validExtensions, callback);
|
||||
EventManager::post<RequestShowFileChooserPopup>(paths, validExtensions, callback, multiple);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,11 @@ namespace hex::plugin::builtin {
|
||||
|
||||
static std::string s_popupMessage;
|
||||
static std::function<void()> s_yesCallback, s_noCallback;
|
||||
static u32 s_selectableFileIndex;
|
||||
static std::set<u32> s_selectableFileIndices;
|
||||
static std::vector<std::fs::path> s_selectableFiles;
|
||||
static std::function<void(std::fs::path)> s_selectableFileOpenCallback;
|
||||
static std::vector<nfdfilteritem_t> s_selectableFilesValidExtensions;
|
||||
static bool s_selectableFileMultiple;
|
||||
|
||||
static void drawGlobalPopups() {
|
||||
|
||||
@ -128,8 +129,22 @@ namespace hex::plugin::builtin {
|
||||
u32 index = 0;
|
||||
for (auto &path : s_selectableFiles) {
|
||||
ImGui::PushID(index);
|
||||
if (ImGui::Selectable(hex::toUTF8String(path.filename()).c_str(), index == s_selectableFileIndex))
|
||||
s_selectableFileIndex = index;
|
||||
|
||||
bool selected = s_selectableFileIndices.contains(index);
|
||||
if (ImGui::Selectable(hex::toUTF8String(path.filename()).c_str(), selected)) {
|
||||
if (!s_selectableFileMultiple) {
|
||||
s_selectableFileIndices.clear();
|
||||
s_selectableFileIndices.insert(index);
|
||||
} else {
|
||||
if (selected) {
|
||||
s_selectableFileIndices.erase(index);
|
||||
} else {
|
||||
s_selectableFileIndices.insert(index);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
index++;
|
||||
@ -139,7 +154,8 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
if (ImGui::Button("hex.builtin.common.open"_lang)) {
|
||||
s_selectableFileOpenCallback(s_selectableFiles[s_selectableFileIndex]);
|
||||
for (auto &index : s_selectableFileIndices)
|
||||
s_selectableFileOpenCallback(s_selectableFiles[index]);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
@ -149,7 +165,7 @@ namespace hex::plugin::builtin {
|
||||
fs::openFileBrowser(fs::DialogMode::Open, s_selectableFilesValidExtensions, [](const auto &path) {
|
||||
s_selectableFileOpenCallback(path);
|
||||
ImGui::CloseCurrentPopup();
|
||||
});
|
||||
}, {}, s_selectableFileMultiple);
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
@ -195,11 +211,12 @@ namespace hex::plugin::builtin {
|
||||
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.question"_lang); });
|
||||
});
|
||||
|
||||
EventManager::subscribe<RequestShowFileChooserPopup>([](const std::vector<std::fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &callback) {
|
||||
s_selectableFileIndex = 0;
|
||||
EventManager::subscribe<RequestShowFileChooserPopup>([](const std::vector<std::fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &callback, bool multiple) {
|
||||
s_selectableFileIndices = { };
|
||||
s_selectableFiles = paths;
|
||||
s_selectableFilesValidExtensions = validExtensions;
|
||||
s_selectableFileOpenCallback = callback;
|
||||
s_selectableFileMultiple = multiple;
|
||||
|
||||
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.choose_file"_lang); });
|
||||
});
|
||||
|
@ -944,7 +944,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
}
|
||||
|
||||
View::showFileChooserPopup(paths, { {"Thingy Table File", "tbl"} },
|
||||
View::showFileChooserPopup(paths, { {"Thingy Table File", "tbl"} }, false,
|
||||
[this](const auto &path) {
|
||||
this->m_hexEditor.setCustomEncoding(EncodingFile(EncodingFile::Type::Thingy, path));
|
||||
});
|
||||
|
@ -867,10 +867,10 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
}
|
||||
|
||||
View::showFileChooserPopup(paths, { {"Pattern File", "hexpat"} },
|
||||
[this, provider](const std::fs::path &path) {
|
||||
this->loadPatternFile(path, provider);
|
||||
});
|
||||
View::showFileChooserPopup(paths, { { "Pattern File", "hexpat" } }, false,
|
||||
[this, provider](const std::fs::path &path) {
|
||||
this->loadPatternFile(path, provider);
|
||||
});
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.file.save_pattern"_lang, nullptr, false, providerValid)) {
|
||||
|
@ -20,7 +20,7 @@ namespace hex::plugin::builtin {
|
||||
ViewYara::ViewYara() : View("hex.builtin.view.yara.name") {
|
||||
yr_initialize();
|
||||
|
||||
ContentRegistry::FileHandler::add({ ".yar" }, [](const auto &path) {
|
||||
ContentRegistry::FileHandler::add({ ".yar", ".yara" }, [](const auto &path) {
|
||||
for (const auto &destPath : fs::getDefaultPaths(fs::ImHexPath::Yara)) {
|
||||
if (fs::copyFile(path, destPath / path.filename(), std::fs::copy_options::overwrite_existing)) {
|
||||
View::showInfoPopup("hex.builtin.view.yara.rule_added"_lang);
|
||||
@ -64,9 +64,10 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
}
|
||||
|
||||
View::showFileChooserPopup(paths, { { "Yara File", "yara" }, { "Yara File", "yar" } }, [this](const auto &path) {
|
||||
this->m_rules.push_back({ path.filename(), path });
|
||||
});
|
||||
View::showFileChooserPopup(paths, { { "Yara File", "yara" }, { "Yara File", "yar" } }, true,
|
||||
[this](const auto &path) {
|
||||
this->m_rules.push_back({ path.filename(), path });
|
||||
});
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
Loading…
Reference in New Issue
Block a user