diff --git a/lib/libimhex/include/hex/api/task.hpp b/lib/libimhex/include/hex/api/task.hpp index 4f0fd49c0..a5b8a2fbc 100644 --- a/lib/libimhex/include/hex/api/task.hpp +++ b/lib/libimhex/include/hex/api/task.hpp @@ -10,9 +10,12 @@ namespace hex { class Task { public: + Task() = default; Task(const std::string &unlocalizedName, u64 maxValue); ~Task(); + Task(Task &&other) noexcept; + void setMaxValue(u64 maxValue); void update(u64 currValue); void finish(); @@ -29,7 +32,7 @@ namespace hex { private: std::string m_name; - u64 m_maxValue, m_currValue; + u64 m_maxValue = 0, m_currValue = 0; static std::list s_runningTasks; static std::mutex s_taskMutex; diff --git a/lib/libimhex/source/api/task.cpp b/lib/libimhex/source/api/task.cpp index 6a9c1d8be..b6d2f15d3 100644 --- a/lib/libimhex/source/api/task.cpp +++ b/lib/libimhex/source/api/task.cpp @@ -2,6 +2,8 @@ #include +#include + namespace hex { std::list Task::s_runningTasks; @@ -17,6 +19,19 @@ namespace hex { this->finish(); } + Task::Task(hex::Task &&other) noexcept { + std::scoped_lock lock(Task::s_taskMutex); + + this->m_name = other.m_name; + this->m_maxValue = other.m_maxValue; + this->m_currValue = other.m_currValue; + + auto it = std::find(Task::s_runningTasks.begin(), Task::s_runningTasks.end(), &other); + if (it != Task::s_runningTasks.end()) { + *it = this; + } + } + void Task::finish() { std::scoped_lock lock(Task::s_taskMutex); diff --git a/plugins/builtin/include/content/views/view_find.hpp b/plugins/builtin/include/content/views/view_find.hpp index bbbe5b289..afd6bc2d7 100644 --- a/plugins/builtin/include/content/views/view_find.hpp +++ b/plugins/builtin/include/content/views/view_find.hpp @@ -55,10 +55,11 @@ namespace hex::plugin::builtin { std::atomic m_searchRunning; bool m_settingsValid = false; + std::string m_currFilter; private: - static std::vector searchStrings(prv::Provider *provider, Region searchRegion, SearchSettings::Strings settings); - static std::vector searchSequence(prv::Provider *provider, Region searchRegion, SearchSettings::Bytes settings); - static std::vector searchRegex(prv::Provider *provider, Region searchRegion, SearchSettings::Regex settings); + static std::vector searchStrings(Task &&task, prv::Provider *provider, Region searchRegion, SearchSettings::Strings settings); + static std::vector searchSequence(Task &&task, prv::Provider *provider, Region searchRegion, SearchSettings::Bytes settings); + static std::vector searchRegex(Task &&task, prv::Provider *provider, Region searchRegion, SearchSettings::Regex settings); void runSearch(); std::string decodeValue(prv::Provider *provider, Region region); diff --git a/plugins/builtin/source/content/views/view_find.cpp b/plugins/builtin/source/content/views/view_find.cpp index 3ca22d7ea..88344ae71 100644 --- a/plugins/builtin/source/content/views/view_find.cpp +++ b/plugins/builtin/source/content/views/view_find.cpp @@ -100,7 +100,7 @@ namespace hex::plugin::builtin { }); } - std::vector ViewFind::searchStrings(prv::Provider *provider, hex::Region searchRegion, SearchSettings::Strings settings) { + std::vector ViewFind::searchStrings(Task &&task, prv::Provider *provider, hex::Region searchRegion, SearchSettings::Strings settings) { std::vector results; auto reader = prv::BufferedReader(provider); @@ -140,13 +140,14 @@ namespace hex::plugin::builtin { startAddress += countedCharacters + 1; countedCharacters = 0; + task.update(startAddress - searchRegion.getStartAddress()); } } return results; } - std::vector ViewFind::searchSequence(prv::Provider *provider, hex::Region searchRegion, SearchSettings::Bytes settings) { + std::vector ViewFind::searchSequence(Task &&task, prv::Provider *provider, hex::Region searchRegion, SearchSettings::Bytes settings) { std::vector results; auto reader = prv::BufferedReader(provider); @@ -160,15 +161,17 @@ namespace hex::plugin::builtin { if (occurrence == reader.end()) break; - reader.seek(occurrence.getAddress() + sequence.size()); - results.push_back(Region { occurrence.getAddress(), sequence.size() }); + auto address = occurrence.getAddress(); + reader.seek(address + sequence.size()); + results.push_back(Region { address, sequence.size() }); + task.update(address - searchRegion.getStartAddress()); } return results; } - std::vector ViewFind::searchRegex(prv::Provider *provider, hex::Region searchRegion, SearchSettings::Regex settings) { - auto stringRegions = searchStrings(provider, searchRegion, SearchSettings::Strings { + std::vector ViewFind::searchRegex(Task &&task, prv::Provider *provider, hex::Region searchRegion, SearchSettings::Regex settings) { + auto stringRegions = searchStrings(std::move(task), provider, searchRegion, SearchSettings::Strings { .minLength = 1, .type = SearchSettings::Strings::Type::ASCII, .m_lowerCaseLetters = true, @@ -205,19 +208,19 @@ namespace hex::plugin::builtin { this->m_searchRunning = true; std::thread([this, settings = this->m_searchSettings, searchRegion]{ - auto task = ImHexApi::Tasks::createTask("hex.builtin.view.find.searching", 0); + auto task = ImHexApi::Tasks::createTask("hex.builtin.view.find.searching", searchRegion.getSize()); auto provider = ImHexApi::Provider::get(); switch (settings.mode) { using enum SearchSettings::Mode; case Strings: - this->m_foundRegions[provider] = searchStrings(provider, searchRegion, settings.strings); + this->m_foundRegions[provider] = searchStrings(std::move(task), provider, searchRegion, settings.strings); break; case Sequence: - this->m_foundRegions[provider] = searchSequence(provider, searchRegion, settings.bytes); + this->m_foundRegions[provider] = searchSequence(std::move(task), provider, searchRegion, settings.bytes); break; case Regex: - this->m_foundRegions[provider] = searchRegex(provider, searchRegion, settings.regex); + this->m_foundRegions[provider] = searchRegex(std::move(task), provider, searchRegion, settings.regex); break; } @@ -280,6 +283,7 @@ namespace hex::plugin::builtin { void ViewFind::drawContent() { if (ImGui::Begin(View::toWindowName("hex.builtin.view.find.name").c_str(), &this->getWindowOpenState())) { + auto provider = ImHexApi::Provider::get(); ImGui::BeginDisabled(this->m_searchRunning); { @@ -373,6 +377,8 @@ namespace hex::plugin::builtin { } ImGui::EndDisabled(); + ImGui::SameLine(); + ImGui::TextFormatted("hex.builtin.view.find.search.entries"_lang, this->m_foundRegions[provider].size()); } ImGui::EndDisabled(); @@ -380,19 +386,28 @@ namespace hex::plugin::builtin { ImGui::Separator(); ImGui::NewLine(); + auto &currRegion = this->m_sortedRegions[provider]; + + ImGui::PushItemWidth(ImGui::GetContentRegionAvailWidth()); + if (ImGui::InputTextWithHint("##filter", "hex.builtin.common.filter"_lang, this->m_currFilter)) { + this->m_sortedRegions = this->m_foundRegions; + + currRegion.erase(std::remove_if(currRegion.begin(), currRegion.end(), [this, provider](const auto ®ion) { + return !this->decodeValue(provider, region).contains(this->m_currFilter); + }), currRegion.end()); + } + ImGui::PopItemWidth(); + if (ImGui::BeginTable("##entries", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) { ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableSetupColumn("hex.builtin.common.offset"_lang, 0, -1, ImGui::GetID("offset")); ImGui::TableSetupColumn("hex.builtin.common.size"_lang, 0, -1, ImGui::GetID("size")); ImGui::TableSetupColumn("hex.builtin.common.value"_lang, 0, -1, ImGui::GetID("value")); - auto provider = ImHexApi::Provider::get(); - auto ®ions = this->m_sortedRegions[provider]; - auto sortSpecs = ImGui::TableGetSortSpecs(); if (sortSpecs->SpecsDirty) { - std::sort(regions.begin(), regions.end(), [this, &sortSpecs, provider](Region &left, Region &right) -> bool { + std::sort(currRegion.begin(), currRegion.end(), [this, &sortSpecs, provider](Region &left, Region &right) -> bool { if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("offset")) { if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending) return left.getStartAddress() > right.getStartAddress(); @@ -419,11 +434,11 @@ namespace hex::plugin::builtin { ImGui::TableHeadersRow(); ImGuiListClipper clipper; - clipper.Begin(regions.size()); + clipper.Begin(currRegion.size(), ImGui::GetTextLineHeightWithSpacing()); while (clipper.Step()) { - for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) { - auto &foundItem = regions[i]; + for (size_t i = clipper.DisplayStart; i < std::min(clipper.DisplayEnd, currRegion.size()); i++) { + auto &foundItem = currRegion[i]; ImGui::TableNextRow(); ImGui::TableNextColumn(); diff --git a/plugins/builtin/source/lang/de_DE.cpp b/plugins/builtin/source/lang/de_DE.cpp index 1103dc320..6f108b4a7 100644 --- a/plugins/builtin/source/lang/de_DE.cpp +++ b/plugins/builtin/source/lang/de_DE.cpp @@ -404,6 +404,7 @@ namespace hex::plugin::builtin { { "hex.builtin.view.find.search", "Suchen" }, { "hex.builtin.view.find.context.copy", "Wert Kopieren" }, { "hex.builtin.view.find.context.copy_demangle", "Demangled Wert Kopieren" }, + { "hex.builtin.view.find.search.entries", "{} Einträge gefunden" }, { "hex.builtin.command.calc.desc", "Rechner" }, { "hex.builtin.command.cmd.desc", "Command" }, diff --git a/plugins/builtin/source/lang/en_US.cpp b/plugins/builtin/source/lang/en_US.cpp index 156525bc5..240bf8c2c 100644 --- a/plugins/builtin/source/lang/en_US.cpp +++ b/plugins/builtin/source/lang/en_US.cpp @@ -408,6 +408,7 @@ namespace hex::plugin::builtin { { "hex.builtin.view.find.search", "Search" }, { "hex.builtin.view.find.context.copy", "Copy Value" }, { "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" }, + { "hex.builtin.view.find.search.entries", "{} entries found" }, { "hex.builtin.command.calc.desc", "Calculator" }, diff --git a/plugins/builtin/source/lang/it_IT.cpp b/plugins/builtin/source/lang/it_IT.cpp index 0c44213d7..8935551a5 100644 --- a/plugins/builtin/source/lang/it_IT.cpp +++ b/plugins/builtin/source/lang/it_IT.cpp @@ -407,6 +407,7 @@ namespace hex::plugin::builtin { // { "hex.builtin.view.find.search", "Search" }, // { "hex.builtin.view.find.context.copy", "Copy Value" }, // { "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" }, + // { "hex.builtin.view.find.search.entries", "{} entries found" }, { "hex.builtin.command.calc.desc", "Calcolatrice" }, { "hex.builtin.command.cmd.desc", "Comando" }, diff --git a/plugins/builtin/source/lang/ja_JP.cpp b/plugins/builtin/source/lang/ja_JP.cpp index 24f3a2d60..e99a68bc0 100644 --- a/plugins/builtin/source/lang/ja_JP.cpp +++ b/plugins/builtin/source/lang/ja_JP.cpp @@ -408,6 +408,7 @@ namespace hex::plugin::builtin { // { "hex.builtin.view.find.search", "Search" }, // { "hex.builtin.view.find.context.copy", "Copy Value" }, // { "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" }, + // { "hex.builtin.view.find.search.entries", "{} entries found" }, { "hex.builtin.command.calc.desc", "計算機" }, { "hex.builtin.command.cmd.desc", "コマンド" }, diff --git a/plugins/builtin/source/lang/pt_BR.cpp b/plugins/builtin/source/lang/pt_BR.cpp index ae89ac344..723a2ca74 100644 --- a/plugins/builtin/source/lang/pt_BR.cpp +++ b/plugins/builtin/source/lang/pt_BR.cpp @@ -405,6 +405,7 @@ namespace hex::plugin::builtin { // { "hex.builtin.view.find.search", "Search" }, // { "hex.builtin.view.find.context.copy", "Copy Value" }, // { "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" }, + // { "hex.builtin.view.find.search.entries", "{} entries found" }, { "hex.builtin.command.calc.desc", "Calculadora" }, { "hex.builtin.command.cmd.desc", "Comando" }, diff --git a/plugins/builtin/source/lang/zh_CN.cpp b/plugins/builtin/source/lang/zh_CN.cpp index dd9b5ced7..f0faff4cf 100644 --- a/plugins/builtin/source/lang/zh_CN.cpp +++ b/plugins/builtin/source/lang/zh_CN.cpp @@ -408,6 +408,7 @@ namespace hex::plugin::builtin { // { "hex.builtin.view.find.search", "Search" }, // { "hex.builtin.view.find.context.copy", "Copy Value" }, // { "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" }, + // { "hex.builtin.view.find.search.entries", "{} entries found" }, { "hex.builtin.command.calc.desc", "计算器" }, { "hex.builtin.command.cmd.desc", "指令" }, diff --git a/plugins/builtin/source/lang/zh_TW.cpp b/plugins/builtin/source/lang/zh_TW.cpp index 1df73e1d8..5d823a876 100644 --- a/plugins/builtin/source/lang/zh_TW.cpp +++ b/plugins/builtin/source/lang/zh_TW.cpp @@ -406,6 +406,7 @@ namespace hex::plugin::builtin { // { "hex.builtin.view.find.search", "Search" }, // { "hex.builtin.view.find.context.copy", "Copy Value" }, // { "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" }, + // { "hex.builtin.view.find.search.entries", "{} entries found" }, { "hex.builtin.command.calc.desc", "計算機" }, { "hex.builtin.command.cmd.desc", "命令" },