mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-04-02 13:37:42 -05:00
feat: Added Hex Editor "Decode as Encoding" option
This commit is contained in:
@@ -26,6 +26,9 @@ namespace hex::plugin::builtin {
|
||||
[[nodiscard]] virtual bool canBePinned() const { return false; }
|
||||
[[nodiscard]] bool isPinned() const { return m_isPinned; }
|
||||
void setPinned(const bool pinned) { m_isPinned = pinned; }
|
||||
|
||||
[[nodiscard]] virtual ImGuiWindowFlags getFlags() const { return ImGuiWindowFlags_AlwaysAutoResize; }
|
||||
|
||||
private:
|
||||
bool m_isPinned = false;
|
||||
};
|
||||
|
||||
@@ -877,6 +877,8 @@
|
||||
"hex.builtin.view.hex_editor.menu.edit.select_all": "Select all",
|
||||
"hex.builtin.view.hex_editor.menu.edit.set_base": "Set Base Address...",
|
||||
"hex.builtin.view.hex_editor.menu.edit.set_page_size": "Set Page Size...",
|
||||
"hex.builtin.view.hex_editor.menu.edit.decode_as_text": "Decode as Encoding",
|
||||
"hex.builtin.view.hex_editor.menu.edit.decoded_string.popup.title": "Decoded Text",
|
||||
"hex.builtin.view.hex_editor.menu.file.goto": "Go to address...",
|
||||
"hex.builtin.view.hex_editor.menu.file.skip_until": "Skip Until",
|
||||
"hex.builtin.view.hex_editor.menu.file.skip_until.previous_differing_byte": "Previous Differing Byte",
|
||||
|
||||
@@ -689,14 +689,7 @@ namespace hex::plugin::builtin {
|
||||
std::vector<u8> stringBuffer(std::min<size_t>(currSelection->size, 0x1000), 0x00);
|
||||
ImHexApi::Provider::get()->read(currSelection->address, stringBuffer.data(), stringBuffer.size());
|
||||
|
||||
u64 offset = 0;
|
||||
while (offset < stringBuffer.size()) {
|
||||
const auto [character, size] = encodingFile.getEncodingFor(std::span(stringBuffer).subspan(offset));
|
||||
value += character;
|
||||
offset += size;
|
||||
}
|
||||
copyValue = value;
|
||||
|
||||
copyValue = value = encodingFile.decodeAll(stringBuffer);
|
||||
|
||||
if (value.size() > MaxStringLength) {
|
||||
value.resize(MaxStringLength);
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <content/popups/hex_editor/popup_hex_editor_find.hpp>
|
||||
#include <pl/patterns/pattern.hpp>
|
||||
#include <hex/helpers/menu_items.hpp>
|
||||
#include <ui/text_editor.hpp>
|
||||
#include <wolv/literals.hpp>
|
||||
|
||||
using namespace std::literals::string_literals;
|
||||
@@ -545,6 +546,46 @@ namespace hex::plugin::builtin {
|
||||
std::function<void(const Region &selection, bool selectionCheck)> m_pasteCallback;
|
||||
};
|
||||
|
||||
class PopupDecodedString final : public ViewHexEditor::Popup {
|
||||
public:
|
||||
explicit PopupDecodedString(std::string decodedString) : m_decodedString(std::move(decodedString)) {
|
||||
}
|
||||
|
||||
void draw(ViewHexEditor *) override {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2());
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0F);
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4());
|
||||
|
||||
auto text = wolv::util::trim(wolv::util::wrapMonospacedString(
|
||||
m_decodedString,
|
||||
ImGui::CalcTextSize("M").x,
|
||||
std::max(100_scaled, ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ScrollbarSize - ImGui::GetStyle().FrameBorderSize)
|
||||
));
|
||||
|
||||
ImGui::InputTextMultiline(
|
||||
"##",
|
||||
text.data(),
|
||||
text.size() + 1,
|
||||
ImGui::GetContentRegionAvail(),
|
||||
ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_NoHorizontalScroll
|
||||
);
|
||||
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopStyleVar(2);
|
||||
}
|
||||
|
||||
[[nodiscard]] UnlocalizedString getTitle() const override {
|
||||
return "hex.builtin.view.hex_editor.menu.edit.decoded_string.popup.title";
|
||||
}
|
||||
|
||||
[[nodiscard]] bool canBePinned() const override { return true; }
|
||||
[[nodiscard]] ImGuiWindowFlags getFlags() const override { return ImGuiWindowFlags_None; }
|
||||
|
||||
private:
|
||||
std::string m_decodedString;
|
||||
ui::TextEditor m_editor;
|
||||
};
|
||||
|
||||
/* Hex Editor */
|
||||
|
||||
ViewHexEditor::ViewHexEditor() : View::Window("hex.builtin.view.hex_editor.name", ICON_VS_FILE_BINARY) {
|
||||
@@ -711,7 +752,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
if (m_currPopup != nullptr) {
|
||||
if (ImGui::Begin(fmt::format("##{}", m_currPopup->getTitle().get()).c_str(), &open, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDocking)) {
|
||||
if (ImGui::Begin(fmt::format("##{}", m_currPopup->getTitle().get()).c_str(), &open, m_currPopup->getFlags() | ImGuiWindowFlags_NoDocking)) {
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
this->closePopup();
|
||||
} else {
|
||||
@@ -1666,6 +1707,32 @@ namespace hex::plugin::builtin {
|
||||
},
|
||||
[] { return ImHexApi::HexEditor::isSelectionValid() && ImHexApi::Provider::isValid(); },
|
||||
this);
|
||||
|
||||
/* Decode as Text */
|
||||
ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.edit", "hex.builtin.view.hex_editor.menu.edit.decode_as_text" }, ICON_VS_CHAT_SPARKLE, 1960, Shortcut::None,
|
||||
[this] {
|
||||
const auto selection = ImHexApi::HexEditor::getSelection();
|
||||
|
||||
TaskManager::createTask("", TaskManager::NoProgress, [this, selection] {
|
||||
const auto &customEncoding = this->m_hexEditor.getCustomEncoding();
|
||||
if (!customEncoding.has_value())
|
||||
return;
|
||||
|
||||
std::vector<u8> buffer(selection->getSize());
|
||||
selection->getProvider()->read(selection->getStartAddress(), buffer.data(), buffer.size());
|
||||
|
||||
auto decodedString = customEncoding->decodeAll(buffer);
|
||||
TaskManager::doLater([this, decodedString = std::move(decodedString)]() mutable {
|
||||
this->openPopup<PopupDecodedString>(std::move(decodedString));
|
||||
});
|
||||
});
|
||||
},
|
||||
[this] {
|
||||
return ImHexApi::HexEditor::isSelectionValid() &&
|
||||
ImHexApi::Provider::isValid() &&
|
||||
this->m_hexEditor.getCustomEncoding().has_value();
|
||||
},
|
||||
this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user