2021-12-07 22:47:41 +01:00
|
|
|
#include "content/views/view_hashes.hpp"
|
2020-11-11 00:13:09 +01:00
|
|
|
|
2021-02-03 11:54:41 +01:00
|
|
|
#include <hex/helpers/crypto.hpp>
|
2020-11-11 00:13:09 +01:00
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
2021-12-07 22:47:41 +01:00
|
|
|
namespace hex::plugin::builtin {
|
2020-11-11 00:13:09 +01:00
|
|
|
|
2021-12-07 22:47:41 +01:00
|
|
|
ViewHashes::ViewHashes() : View("hex.builtin.view.hashes.name") {
|
2022-05-30 16:36:46 +02:00
|
|
|
EventManager::subscribe<EventRegionSelected>(this, [this](const Region &) {
|
|
|
|
for (auto &function : this->m_hashFunctions)
|
|
|
|
function.reset();
|
2020-11-28 15:53:11 +01:00
|
|
|
});
|
2020-11-11 00:13:09 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImHexApi::HexEditor::addTooltipProvider([this](u64 address, const u8 *data, size_t size) {
|
|
|
|
hex::unused(data);
|
2020-11-11 00:13:09 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
auto selection = ImHexApi::HexEditor::getSelection();
|
2020-11-11 09:18:35 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
if (ImGui::GetIO().KeyShift) {
|
|
|
|
if (!this->m_hashFunctions.empty() && selection.has_value() && selection->overlaps(Region { address, size })) {
|
|
|
|
ImGui::BeginTooltip();
|
2021-10-26 17:21:48 +02:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
if (ImGui::BeginTable("##tooltips", 1, ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoClip)) {
|
|
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableNextColumn();
|
2021-10-26 17:21:48 +02:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::TextUnformatted("hex.builtin.view.hashes.name"_lang);
|
|
|
|
ImGui::Separator();
|
2021-10-26 17:21:48 +02:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::Indent();
|
|
|
|
if (ImGui::BeginTable("##hashes_tooltip", 3, ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit)) {
|
|
|
|
auto provider = ImHexApi::Provider::get();
|
|
|
|
for (auto &function : this->m_hashFunctions) {
|
|
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::TextFormatted("{}", function.getName());
|
2021-10-26 17:21:48 +02:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::TextFormatted(" ");
|
2021-10-26 17:21:48 +02:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
if (provider != nullptr)
|
|
|
|
ImGui::TextFormatted("{}", crypt::encode16(function.get(*selection, provider)));
|
2022-02-01 22:09:44 +01:00
|
|
|
}
|
2021-10-26 17:21:48 +02:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::EndTable();
|
|
|
|
}
|
|
|
|
ImGui::Unindent();
|
2020-11-12 12:00:50 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::EndTable();
|
|
|
|
}
|
2020-11-12 12:00:50 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::EndTooltip();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2020-11-28 15:53:11 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ViewHashes::~ViewHashes() {
|
|
|
|
EventManager::unsubscribe<EventRegionSelected>(this);
|
|
|
|
}
|
2020-11-12 12:00:50 +01:00
|
|
|
|
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
void ViewHashes::drawContent() {
|
|
|
|
const auto &hashes = ContentRegistry::Hashes::impl::getHashes();
|
2020-11-28 15:53:11 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
if (this->m_selectedHash == nullptr && !hashes.empty()) {
|
|
|
|
this->m_selectedHash = hashes.front();
|
|
|
|
}
|
2021-10-26 17:21:48 +02:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
if (ImGui::Begin(View::toWindowName("hex.builtin.view.hashes.name").c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
|
2022-06-14 11:54:34 +02:00
|
|
|
if (ImGui::BeginCombo("hex.builtin.view.hashes.function"_lang, this->m_selectedHash != nullptr ? LangEntry(this->m_selectedHash->getUnlocalizedName()) : "")) {
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
for (const auto hash : hashes) {
|
2022-06-14 11:54:34 +02:00
|
|
|
if (ImGui::Selectable(LangEntry(hash->getUnlocalizedName()), this->m_selectedHash == hash)) {
|
2022-05-30 16:36:46 +02:00
|
|
|
this->m_selectedHash = hash;
|
|
|
|
this->m_newHashName.clear();
|
|
|
|
}
|
|
|
|
}
|
2021-10-26 17:21:48 +02:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::EndCombo();
|
|
|
|
}
|
2021-10-26 17:21:48 +02:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
if (this->m_newHashName.empty() && this->m_selectedHash != nullptr)
|
2022-06-14 11:54:34 +02:00
|
|
|
this->m_newHashName = hex::format("{} {}", LangEntry(this->m_selectedHash->getUnlocalizedName()), static_cast<const char *>("hex.builtin.view.hashes.hash"_lang));
|
2021-10-26 17:21:48 +02:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
if (ImGui::BeginChild("##settings", ImVec2(ImGui::GetContentRegionAvailWidth(), 200_scaled), true)) {
|
|
|
|
if (this->m_selectedHash != nullptr) {
|
|
|
|
auto startPos = ImGui::GetCursorPosY();
|
|
|
|
this->m_selectedHash->draw();
|
2021-10-26 17:21:48 +02:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
// Check if no elements have been added
|
|
|
|
if (startPos == ImGui::GetCursorPosY()) {
|
|
|
|
ImGui::TextFormattedCentered("hex.builtin.view.hashes.no_settings"_lang);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::EndChild();
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::NewLine();
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::InputText("##Name", this->m_newHashName);
|
|
|
|
ImGui::SameLine();
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::BeginDisabled(this->m_newHashName.empty() || this->m_selectedHash == nullptr);
|
|
|
|
if (ImGui::IconButton(ICON_VS_ADD, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
|
|
|
|
if (this->m_selectedHash != nullptr)
|
|
|
|
this->m_hashFunctions.push_back(this->m_selectedHash->create(this->m_newHashName));
|
|
|
|
}
|
|
|
|
ImGui::EndDisabled();
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
if (ImGui::BeginTable("##hashes", 3, ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Borders, ImVec2(ImGui::GetContentRegionAvailWidth(), ImGui::GetTextLineHeightWithSpacing() * 10))) {
|
|
|
|
ImGui::TableSetupColumn("hex.builtin.view.hashes.name"_lang);
|
|
|
|
ImGui::TableSetupColumn("hex.builtin.view.hashes.type"_lang);
|
|
|
|
ImGui::TableSetupColumn("hex.builtin.view.hashes.result"_lang, ImGuiTableColumnFlags_WidthStretch);
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::TableHeadersRow();
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
auto provider = ImHexApi::Provider::get();
|
|
|
|
auto selection = ImHexApi::HexEditor::getSelection();
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
std::optional<u32> indexToRemove;
|
|
|
|
for (u32 i = 0; i < this->m_hashFunctions.size(); i++) {
|
|
|
|
auto &function = this->m_hashFunctions[i];
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::PushID(i);
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableNextColumn();
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::PushStyleColor(ImGuiCol_Header, 0x00);
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_HeaderActive, 0x00);
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, 0x00);
|
|
|
|
ImGui::Selectable(function.getName().c_str(), false);
|
|
|
|
ImGui::PopStyleColor(3);
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
{
|
|
|
|
const auto ContextMenuId = hex::format("Context Menu {}", i);
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Right))
|
|
|
|
ImGui::OpenPopup(ContextMenuId.c_str());
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
if (ImGui::BeginPopup(ContextMenuId.c_str())) {
|
|
|
|
if (ImGui::MenuItem("hex.builtin.view.hashes.remove"_lang))
|
|
|
|
indexToRemove = i;
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::EndPopup();
|
|
|
|
}
|
|
|
|
}
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::TableNextColumn();
|
2022-06-14 11:54:34 +02:00
|
|
|
ImGui::TextFormatted("{}", LangEntry(function.getType()->getUnlocalizedName()));
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
std::string result;
|
|
|
|
if (provider != nullptr && selection.has_value())
|
|
|
|
result = crypt::encode16(function.get(*selection, provider));
|
|
|
|
else
|
|
|
|
result = "???";
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::PushItemWidth(ImGui::GetContentRegionAvailWidth());
|
|
|
|
ImGui::InputText("##result", result, ImGuiInputTextFlags_ReadOnly);
|
|
|
|
ImGui::PopItemWidth();
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::PopID();
|
|
|
|
}
|
2022-02-01 22:09:44 +01:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
if (indexToRemove.has_value()) {
|
|
|
|
this->m_hashFunctions.erase(this->m_hashFunctions.begin() + indexToRemove.value());
|
2020-11-11 00:13:09 +01:00
|
|
|
}
|
2021-10-26 17:21:48 +02:00
|
|
|
|
2022-05-30 16:36:46 +02:00
|
|
|
ImGui::EndTable();
|
2020-11-11 00:13:09 +01:00
|
|
|
}
|
2022-05-30 16:36:46 +02:00
|
|
|
|
|
|
|
ImGui::NewLine();
|
|
|
|
ImGui::TextWrapped("%s", static_cast<const char *>("hex.builtin.view.hashes.hover_info"_lang));
|
2020-11-11 00:13:09 +01:00
|
|
|
}
|
2020-11-11 10:47:02 +01:00
|
|
|
ImGui::End();
|
2020-11-11 00:13:09 +01:00
|
|
|
}
|
|
|
|
|
2021-10-26 17:21:48 +02:00
|
|
|
}
|