diff --git a/lib/external/pattern_language b/lib/external/pattern_language index 46f133bee..2233e1ab6 160000 --- a/lib/external/pattern_language +++ b/lib/external/pattern_language @@ -1 +1 @@ -Subproject commit 46f133bee5a2b5f2d465bb553204f76c088b4d54 +Subproject commit 2233e1ab6b1a29be8ee6a2074c88b2c4ed40503b diff --git a/lib/libimhex/include/hex/helpers/utils.hpp b/lib/libimhex/include/hex/helpers/utils.hpp index 5dec8b663..3419043ff 100644 --- a/lib/libimhex/include/hex/helpers/utils.hpp +++ b/lib/libimhex/include/hex/helpers/utils.hpp @@ -201,6 +201,7 @@ namespace hex { std::vector splitString(const std::string &string, const std::string &delimiter); std::string combineStrings(const std::vector &strings, const std::string &delimiter = ""); + std::string replaceStrings(std::string string, const std::string &search, const std::string &replace); std::string toEngineeringString(double value); diff --git a/lib/libimhex/source/helpers/utils.cpp b/lib/libimhex/source/helpers/utils.cpp index 77f1e185e..543aa442a 100644 --- a/lib/libimhex/source/helpers/utils.cpp +++ b/lib/libimhex/source/helpers/utils.cpp @@ -232,6 +232,17 @@ namespace hex { return result.substr(0, result.length() - delimiter.length()); } + std::string replaceStrings(std::string string, const std::string &search, const std::string &replace) { + if (search.empty()) + return string; + + std::size_t pos; + while ((pos = string.find(search)) != std::string::npos) + string.replace(pos, search.size(), replace); + + return string; + } + std::string toEngineeringString(double value) { constexpr static std::array Suffixes = { "a", "f", "p", "n", "u", "m", "", "k", "M", "G", "T", "P", "E" }; diff --git a/plugins/builtin/include/content/views/view_pattern_editor.hpp b/plugins/builtin/include/content/views/view_pattern_editor.hpp index e250aa51a..3fadb2558 100644 --- a/plugins/builtin/include/content/views/view_pattern_editor.hpp +++ b/plugins/builtin/include/content/views/view_pattern_editor.hpp @@ -104,6 +104,10 @@ namespace hex::plugin::builtin { void parsePattern(const std::string &code); void evaluatePattern(const std::string &code); + + void registerEvents(); + void registerMenuItems(); + void registerHandlers(); }; } diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index 771d7e77e..662d06e46 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -17,6 +18,7 @@ #include #include +#include namespace hex::plugin::builtin { @@ -89,247 +91,9 @@ namespace hex::plugin::builtin { this->m_envVarEntries.push_back({ 0, "", 0, EnvVarType::Integer }); this->m_envVarIdCounter = 1; - EventManager::subscribe(this, [this](const std::string &code) { - this->m_textEditor.SetText(code); - }); - - EventManager::subscribe(this, [this] { - { - auto syncPatternSource = ContentRegistry::Settings::getSetting("hex.builtin.setting.general", "hex.builtin.setting.general.sync_pattern_source"); - - if (syncPatternSource.is_number()) - this->m_syncPatternSourceCode = static_cast(syncPatternSource); - } - - { - auto autoLoadPatterns = ContentRegistry::Settings::getSetting("hex.builtin.setting.general", "hex.builtin.setting.general.auto_load_patterns"); - - if (autoLoadPatterns.is_number()) - this->m_autoLoadPatterns = static_cast(autoLoadPatterns); - } - }); - - EventManager::subscribe(this, [this](prv::Provider *provider) { - auto &patternLanguageData = ProviderExtraData::get(provider).patternLanguage; - patternLanguageData.runtime = std::make_unique(); - ContentRegistry::PatternLanguage::configureRuntime(*patternLanguageData.runtime, provider); - - TaskManager::createBackgroundTask("Analyzing file content", [this, provider, &data = patternLanguageData](auto &) { - if (!this->m_autoLoadPatterns) - return; - - // Copy over current pattern source code to the new provider - if (!this->m_syncPatternSourceCode) { - data.sourceCode = this->m_textEditor.GetText(); - } - - std::scoped_lock lock(data.runtimeMutex); - auto &runtime = data.runtime; - - auto mimeType = magic::getMIMEType(provider); - - bool foundCorrectType = false; - runtime->addPragma("MIME", [&mimeType, &foundCorrectType](pl::PatternLanguage &runtime, const std::string &value) { - hex::unused(runtime); - - if (value == mimeType) { - foundCorrectType = true; - return true; - } - return !std::all_of(value.begin(), value.end(), isspace) && !value.ends_with('\n') && !value.ends_with('\r'); - }); - - this->m_possiblePatternFiles.clear(); - - std::error_code errorCode; - for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Patterns)) { - for (auto &entry : std::fs::recursive_directory_iterator(dir, errorCode)) { - foundCorrectType = false; - if (!entry.is_regular_file()) - continue; - - fs::File file(entry.path(), fs::File::Mode::Read); - if (!file.isValid()) - continue; - - runtime->getInternals().preprocessor->preprocess(*runtime, file.readString()); - - if (foundCorrectType) - this->m_possiblePatternFiles.push_back(entry.path()); - - runtime->reset(); - } - } - - runtime->addPragma("MIME", [](pl::PatternLanguage&, const std::string &value) { return !value.empty(); }); - - if (!this->m_possiblePatternFiles.empty()) { - this->m_selectedPatternFile = 0; - EventManager::post("hex.builtin.view.pattern_editor.accept_pattern"_lang); - this->m_acceptPatternWindowOpen = true; - } - }); - }); - - EventManager::subscribe(this, [this](prv::Provider *oldProvider, prv::Provider *newProvider) { - if (!this->m_syncPatternSourceCode) { - if (oldProvider != nullptr) ProviderExtraData::get(oldProvider).patternLanguage.sourceCode = this->m_textEditor.GetText(); - - if (newProvider != nullptr) - this->m_textEditor.SetText(ProviderExtraData::get(newProvider).patternLanguage.sourceCode); - else - this->m_textEditor.SetText(""); - - auto lines = this->m_textEditor.GetTextLines(); - lines.pop_back(); - this->m_textEditor.SetTextLines(lines); - } - }); - - /* Settings */ - { - - EventManager::subscribe(this, [this](u32 theme) { - switch (theme) { - default: - case 1: /* Dark theme */ - this->m_textEditor.SetPalette(TextEditor::GetDarkPalette()); - break; - case 2: /* Light theme */ - this->m_textEditor.SetPalette(TextEditor::GetLightPalette()); - break; - case 3: /* Classic theme */ - this->m_textEditor.SetPalette(TextEditor::GetRetroBluePalette()); - break; - } - }); - } - - ContentRegistry::FileHandler::add({ ".hexpat", ".pat" }, [](const std::fs::path &path) -> bool { - fs::File file(path, fs::File::Mode::Read); - - if (file.isValid()) { - EventManager::post(file.readString()); - return true; - } else { - return false; - } - }); - - ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 2000, [&, this] { - bool providerValid = ImHexApi::Provider::isValid(); - - if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.file.load_pattern"_lang, nullptr, false, providerValid)) { - - std::vector paths; - - for (const auto &imhexPath : fs::getDefaultPaths(fs::ImHexPath::Patterns)) { - if (!fs::exists(imhexPath)) continue; - - std::error_code error; - for (auto &entry : std::fs::recursive_directory_iterator(imhexPath, error)) { - if (entry.is_regular_file() && entry.path().extension() == ".hexpat") { - paths.push_back(entry.path()); - } - } - } - - View::showFileChooserPopup(paths, { {"Pattern File", "hexpat"} }, - [this](const std::fs::path &path) { - this->loadPatternFile(path); - }); - } - - if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.file.save_pattern"_lang, nullptr, false, providerValid)) { - fs::openFileBrowser(fs::DialogMode::Save, { {"Pattern", "hexpat"} }, - [this](const auto &path) { - fs::File file(path, fs::File::Mode::Create); - - file.write(this->m_textEditor.GetText()); - }); - } - }); - - - ImHexApi::HexEditor::addBackgroundHighlightingProvider([this](u64 address, const u8 *data, size_t size, bool) -> std::optional { - hex::unused(data, size); - - if (this->m_runningEvaluators != 0) - return std::nullopt; - - std::optional color; - for (const auto &pattern : ProviderExtraData::getCurrent().patternLanguage.runtime->getPatternsAtAddress(address)) { - if (pattern->isHidden()) - continue; - - if (color.has_value()) - color = ImAlphaBlendColors(*color, pattern->getColor()); - else - color = pattern->getColor(); - } - - return color; - }); - - ImHexApi::HexEditor::addTooltipProvider([this](u64 address, const u8 *data, size_t size) { - hex::unused(data, size); - - auto patterns = ProviderExtraData::getCurrent().patternLanguage.runtime->getPatternsAtAddress(address); - if (!patterns.empty() && !std::all_of(patterns.begin(), patterns.end(), [](const auto &pattern) { return pattern->isHidden(); })) { - ImGui::BeginTooltip(); - - for (const auto &pattern : patterns) { - if (pattern->isHidden()) - continue; - - auto tooltipColor = (pattern->getColor() & 0x00FF'FFFF) | 0x7000'0000; - ImGui::PushID(pattern); - if (ImGui::BeginTable("##tooltips", 1, ImGuiTableFlags_RowBg | ImGuiTableFlags_NoClip)) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - - this->drawPatternTooltip(pattern); - - ImGui::PushStyleColor(ImGuiCol_TableRowBg, tooltipColor); - ImGui::PushStyleColor(ImGuiCol_TableRowBgAlt, tooltipColor); - ImGui::EndTable(); - ImGui::PopStyleColor(2); - } - ImGui::PopID(); - } - ImGui::EndTooltip(); - } - }); - - ProjectFile::registerPerProviderHandler({ - .basePath = "pattern_source_code.hexpat", - .required = false, - .load = [this](prv::Provider *provider, const std::fs::path &basePath, Tar &tar) { - std::string sourceCode = tar.readString(basePath); - - if (!this->m_syncPatternSourceCode) - ProviderExtraData::get(provider).patternLanguage.sourceCode = sourceCode; - - if (provider == ImHexApi::Provider::get()) - this->m_textEditor.SetText(sourceCode); - - return true; - }, - .store = [this](prv::Provider *provider, const std::fs::path &basePath, Tar &tar) { - std::string sourceCode; - - if (provider == ImHexApi::Provider::get()) - ProviderExtraData::get(provider).patternLanguage.sourceCode = this->m_textEditor.GetText(); - - if (this->m_syncPatternSourceCode) - sourceCode = this->m_textEditor.GetText(); - else - sourceCode = ProviderExtraData::get(provider).patternLanguage.sourceCode; - - tar.write(basePath, sourceCode); - return true; - } - }); + this->registerEvents(); + this->registerMenuItems(); + this->registerHandlers(); } ViewPatternEditor::~ViewPatternEditor() { @@ -871,4 +635,330 @@ namespace hex::plugin::builtin { }); } + void ViewPatternEditor::registerEvents() { + EventManager::subscribe(this, [this](const std::string &code) { + this->m_textEditor.SetText(code); + }); + + EventManager::subscribe(this, [this] { + { + auto syncPatternSource = ContentRegistry::Settings::getSetting("hex.builtin.setting.general", "hex.builtin.setting.general.sync_pattern_source"); + + if (syncPatternSource.is_number()) + this->m_syncPatternSourceCode = static_cast(syncPatternSource); + } + + { + auto autoLoadPatterns = ContentRegistry::Settings::getSetting("hex.builtin.setting.general", "hex.builtin.setting.general.auto_load_patterns"); + + if (autoLoadPatterns.is_number()) + this->m_autoLoadPatterns = static_cast(autoLoadPatterns); + } + }); + + EventManager::subscribe(this, [this](prv::Provider *provider) { + auto &patternLanguageData = ProviderExtraData::get(provider).patternLanguage; + patternLanguageData.runtime = std::make_unique(); + ContentRegistry::PatternLanguage::configureRuntime(*patternLanguageData.runtime, provider); + + TaskManager::createBackgroundTask("Analyzing file content", [this, provider, &data = patternLanguageData](auto &) { + if (!this->m_autoLoadPatterns) + return; + + // Copy over current pattern source code to the new provider + if (!this->m_syncPatternSourceCode) { + data.sourceCode = this->m_textEditor.GetText(); + } + + std::scoped_lock lock(data.runtimeMutex); + auto &runtime = data.runtime; + + auto mimeType = magic::getMIMEType(provider); + + bool foundCorrectType = false; + runtime->addPragma("MIME", [&mimeType, &foundCorrectType](pl::PatternLanguage &runtime, const std::string &value) { + hex::unused(runtime); + + if (value == mimeType) { + foundCorrectType = true; + return true; + } + return !std::all_of(value.begin(), value.end(), isspace) && !value.ends_with('\n') && !value.ends_with('\r'); + }); + + this->m_possiblePatternFiles.clear(); + + std::error_code errorCode; + for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Patterns)) { + for (auto &entry : std::fs::recursive_directory_iterator(dir, errorCode)) { + foundCorrectType = false; + if (!entry.is_regular_file()) + continue; + + fs::File file(entry.path(), fs::File::Mode::Read); + if (!file.isValid()) + continue; + + runtime->getInternals().preprocessor->preprocess(*runtime, file.readString()); + + if (foundCorrectType) + this->m_possiblePatternFiles.push_back(entry.path()); + + runtime->reset(); + } + } + + runtime->addPragma("MIME", [](pl::PatternLanguage&, const std::string &value) { return !value.empty(); }); + + if (!this->m_possiblePatternFiles.empty()) { + this->m_selectedPatternFile = 0; + EventManager::post("hex.builtin.view.pattern_editor.accept_pattern"_lang); + this->m_acceptPatternWindowOpen = true; + } + }); + }); + + EventManager::subscribe(this, [this](prv::Provider *oldProvider, prv::Provider *newProvider) { + if (!this->m_syncPatternSourceCode) { + if (oldProvider != nullptr) ProviderExtraData::get(oldProvider).patternLanguage.sourceCode = this->m_textEditor.GetText(); + + if (newProvider != nullptr) + this->m_textEditor.SetText(ProviderExtraData::get(newProvider).patternLanguage.sourceCode); + else + this->m_textEditor.SetText(""); + + auto lines = this->m_textEditor.GetTextLines(); + lines.pop_back(); + this->m_textEditor.SetTextLines(lines); + } + }); + + EventManager::subscribe(this, [this](u32 theme) { + switch (theme) { + default: + case 1: /* Dark theme */ + this->m_textEditor.SetPalette(TextEditor::GetDarkPalette()); + break; + case 2: /* Light theme */ + this->m_textEditor.SetPalette(TextEditor::GetLightPalette()); + break; + case 3: /* Classic theme */ + this->m_textEditor.SetPalette(TextEditor::GetRetroBluePalette()); + break; + } + }); + } + + static void createNestedMenu(const std::vector &menus, const std::function &function) { + if (menus.empty()) + return; + + if (menus.size() == 1) { + if (ImGui::MenuItem(menus.front().c_str())) + function(); + } else { + if (ImGui::BeginMenu(menus.front().c_str())) { + createNestedMenu({ menus.begin() + 1, menus.end() }, function); + ImGui::EndMenu(); + } + } + } + + void ViewPatternEditor::registerMenuItems() { + ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 2000, [&, this] { + bool providerValid = ImHexApi::Provider::isValid(); + + if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.file.load_pattern"_lang, nullptr, false, providerValid)) { + + std::vector paths; + + for (const auto &imhexPath : fs::getDefaultPaths(fs::ImHexPath::Patterns)) { + if (!fs::exists(imhexPath)) continue; + + std::error_code error; + for (auto &entry : std::fs::recursive_directory_iterator(imhexPath, error)) { + if (entry.is_regular_file() && entry.path().extension() == ".hexpat") { + paths.push_back(entry.path()); + } + } + } + + View::showFileChooserPopup(paths, { {"Pattern File", "hexpat"} }, + [this](const std::fs::path &path) { + this->loadPatternFile(path); + }); + } + + if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.file.save_pattern"_lang, nullptr, false, providerValid)) { + fs::openFileBrowser(fs::DialogMode::Save, { {"Pattern", "hexpat"} }, + [this](const auto &path) { + fs::File file(path, fs::File::Mode::Create); + + file.write(this->m_textEditor.GetText()); + }); + } + }); + + // Place Pattern Type... + ContentRegistry::Interface::addMenuItem("hex.builtin.menu.edit", 3000, [this] { + bool available = ImHexApi::Provider::isValid() && ImHexApi::HexEditor::isSelectionValid() && this->m_runningParsers == 0; + auto selection = ImHexApi::HexEditor::getSelection(); + + const auto &types = this->m_parserRuntime->getInternals().parser->getTypes(); + + const auto appendEditorText = [this](const std::string &text){ + this->m_textEditor.SetCursorPosition(TextEditor::Coordinates { this->m_textEditor.GetTotalLines(), 0 }); + this->m_textEditor.InsertText(hex::format("\n{0}", text)); + this->m_hasUnevaluatedChanges = true; + }; + + const auto appendVariable = [&](const std::string &type) { + appendEditorText(hex::format("{0} {0}_at_0x{1:02X} @ 0x{1:02X};", type, selection->getStartAddress())); + }; + + const auto appendArray = [&](const std::string &type, size_t size) { + appendEditorText(hex::format("{0} {0}_array_at_0x{1:02X}[0x{2:02X}] @ 0x{1:02X};", type, selection->getStartAddress(), (selection->getSize() + (size - 1)) / size)); + }; + + if (ImGui::BeginMenu("hex.builtin.view.pattern_editor.menu.edit.place_pattern"_lang, available)) { + if (ImGui::BeginMenu("hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin"_lang)) { + constexpr static std::array, 21> Types = {{ + { "u8", 1 }, { "u16", 2 }, { "u24", 3 }, { "u32", 4 }, { "u48", 6 }, { "u64", 8 }, { "u96", 12 }, { "u128", 16 }, + { "s8", 1 }, { "s16", 2 }, { "s24", 3 }, { "s32", 4 }, { "s48", 6 }, { "s64", 8 }, { "s96", 12 }, { "s128", 16 }, + { "float", 4 }, { "double", 8 }, + { "bool", 1 }, { "char", 1 }, { "char16", 2 } + }}; + + if (ImGui::BeginMenu("hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.single"_lang)) { + for (const auto &[type, size] : Types) + if (ImGui::MenuItem(type)) + appendVariable(type); + ImGui::EndMenu(); + } + + if (ImGui::BeginMenu("hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.array"_lang)) { + for (const auto &[type, size] : Types) + if (ImGui::MenuItem(type)) + appendArray(type, size); + ImGui::EndMenu(); + } + + ImGui::EndMenu(); + } + + if (ImGui::BeginMenu("hex.builtin.view.pattern_editor.menu.edit.place_pattern.custom"_lang, !types.empty())) { + for (const auto &[typeName, type] : types) { + if (type->isTemplateType()) + continue; + + createNestedMenu(hex::splitString(typeName, "::"), [&] { + std::string variableName; + for (char &c : hex::replaceStrings(typeName, "::", "_")) + variableName += static_cast(std::tolower(c)); + variableName += hex::format("_at_0x{:02X}", selection->getStartAddress()); + + appendEditorText(hex::format("{0} {1} @ 0x{2:02X};", typeName, variableName, selection->getStartAddress())); + }); + } + ImGui::EndMenu(); + } + + ImGui::EndMenu(); + } + }); + } + + void ViewPatternEditor::registerHandlers() { + ContentRegistry::FileHandler::add({ ".hexpat", ".pat" }, [](const std::fs::path &path) -> bool { + fs::File file(path, fs::File::Mode::Read); + + if (file.isValid()) { + EventManager::post(file.readString()); + return true; + } else { + return false; + } + }); + + ImHexApi::HexEditor::addBackgroundHighlightingProvider([this](u64 address, const u8 *data, size_t size, bool) -> std::optional { + hex::unused(data, size); + + if (this->m_runningEvaluators != 0) + return std::nullopt; + + std::optional color; + for (const auto &pattern : ProviderExtraData::getCurrent().patternLanguage.runtime->getPatternsAtAddress(address)) { + if (pattern->isHidden()) + continue; + + if (color.has_value()) + color = ImAlphaBlendColors(*color, pattern->getColor()); + else + color = pattern->getColor(); + } + + return color; + }); + + ImHexApi::HexEditor::addTooltipProvider([this](u64 address, const u8 *data, size_t size) { + hex::unused(data, size); + + auto patterns = ProviderExtraData::getCurrent().patternLanguage.runtime->getPatternsAtAddress(address); + if (!patterns.empty() && !std::all_of(patterns.begin(), patterns.end(), [](const auto &pattern) { return pattern->isHidden(); })) { + ImGui::BeginTooltip(); + + for (const auto &pattern : patterns) { + if (pattern->isHidden()) + continue; + + auto tooltipColor = (pattern->getColor() & 0x00FF'FFFF) | 0x7000'0000; + ImGui::PushID(pattern); + if (ImGui::BeginTable("##tooltips", 1, ImGuiTableFlags_RowBg | ImGuiTableFlags_NoClip)) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + + this->drawPatternTooltip(pattern); + + ImGui::PushStyleColor(ImGuiCol_TableRowBg, tooltipColor); + ImGui::PushStyleColor(ImGuiCol_TableRowBgAlt, tooltipColor); + ImGui::EndTable(); + ImGui::PopStyleColor(2); + } + ImGui::PopID(); + } + ImGui::EndTooltip(); + } + }); + + ProjectFile::registerPerProviderHandler({ + .basePath = "pattern_source_code.hexpat", + .required = false, + .load = [this](prv::Provider *provider, const std::fs::path &basePath, Tar &tar) { + std::string sourceCode = tar.readString(basePath); + + if (!this->m_syncPatternSourceCode) + ProviderExtraData::get(provider).patternLanguage.sourceCode = sourceCode; + + if (provider == ImHexApi::Provider::get()) + this->m_textEditor.SetText(sourceCode); + + return true; + }, + .store = [this](prv::Provider *provider, const std::fs::path &basePath, Tar &tar) { + std::string sourceCode; + + if (provider == ImHexApi::Provider::get()) + ProviderExtraData::get(provider).patternLanguage.sourceCode = this->m_textEditor.GetText(); + + if (this->m_syncPatternSourceCode) + sourceCode = this->m_textEditor.GetText(); + else + sourceCode = ProviderExtraData::get(provider).patternLanguage.sourceCode; + + tar.write(basePath, sourceCode); + return true; + } + }); + } + } diff --git a/plugins/builtin/source/lang/de_DE.cpp b/plugins/builtin/source/lang/de_DE.cpp index 26fffa870..e99dec985 100644 --- a/plugins/builtin/source/lang/de_DE.cpp +++ b/plugins/builtin/source/lang/de_DE.cpp @@ -374,6 +374,11 @@ namespace hex::plugin::builtin { { "hex.builtin.view.pattern_editor.accept_pattern.question", "Ausgewähltes Pattern anwenden?" }, { "hex.builtin.view.pattern_editor.menu.file.load_pattern", "Pattern laden..." }, { "hex.builtin.view.pattern_editor.menu.file.save_pattern", "Pattern speichern..." }, + { "hex.builtin.view.pattern_editor.menu.edit.place_pattern", "Pattern platzieren..." }, + { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin", "Built-in Type" }, + { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.single", "Einzeln" }, + { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.array", "Array" }, + { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.custom", "Benutzerdefinierter Type" }, { "hex.builtin.view.pattern_editor.open_pattern", "Pattern öffnen" }, { "hex.builtin.view.pattern_editor.evaluating", "Evaluieren..." }, { "hex.builtin.view.pattern_editor.auto", "Auto evaluieren" }, diff --git a/plugins/builtin/source/lang/en_US.cpp b/plugins/builtin/source/lang/en_US.cpp index 66caf6510..f3f9eac71 100644 --- a/plugins/builtin/source/lang/en_US.cpp +++ b/plugins/builtin/source/lang/en_US.cpp @@ -377,6 +377,11 @@ namespace hex::plugin::builtin { { "hex.builtin.view.pattern_editor.accept_pattern.question", "Do you want to apply the selected pattern?" }, { "hex.builtin.view.pattern_editor.menu.file.load_pattern", "Load pattern..." }, { "hex.builtin.view.pattern_editor.menu.file.save_pattern", "Save pattern..." }, + { "hex.builtin.view.pattern_editor.menu.edit.place_pattern", "Place pattern..." }, + { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin", "Built-in Type" }, + { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.single", "Single" }, + { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.array", "Array" }, + { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.custom", "Custom Type" }, { "hex.builtin.view.pattern_editor.open_pattern", "Open pattern" }, { "hex.builtin.view.pattern_editor.evaluating", "Evaluating..." }, { "hex.builtin.view.pattern_editor.auto", "Auto evaluate" }, diff --git a/plugins/builtin/source/lang/it_IT.cpp b/plugins/builtin/source/lang/it_IT.cpp index 44c564eab..655aa0f65 100644 --- a/plugins/builtin/source/lang/it_IT.cpp +++ b/plugins/builtin/source/lang/it_IT.cpp @@ -380,6 +380,11 @@ namespace hex::plugin::builtin { { "hex.builtin.view.pattern_editor.accept_pattern.question", "Vuoi applicare i patter selezionati" }, { "hex.builtin.view.pattern_editor.menu.file.load_pattern", "Caricamento dei pattern..." }, { "hex.builtin.view.pattern_editor.menu.file.save_pattern", "Salva pattern..." }, + //{ "hex.builtin.view.pattern_editor.menu.edit.place_pattern", "Place pattern..." }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin", "Built-in Type" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.single", "Single" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.array", "Array" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.custom", "Custom Type" }, { "hex.builtin.view.pattern_editor.open_pattern", "Apri pattern" }, { "hex.builtin.view.pattern_editor.evaluating", "Valutazione..." }, { "hex.builtin.view.pattern_editor.auto", "Auto valutazione" }, diff --git a/plugins/builtin/source/lang/ja_JP.cpp b/plugins/builtin/source/lang/ja_JP.cpp index 51b1a78e6..117752142 100644 --- a/plugins/builtin/source/lang/ja_JP.cpp +++ b/plugins/builtin/source/lang/ja_JP.cpp @@ -379,6 +379,11 @@ namespace hex::plugin::builtin { { "hex.builtin.view.pattern_editor.accept_pattern.question", "選択したパターンを反映してよろしいですか?" }, { "hex.builtin.view.pattern_editor.menu.file.load_pattern", "パターンを読み込み…" }, { "hex.builtin.view.pattern_editor.menu.file.save_pattern", "パターンを保存…" }, + //{ "hex.builtin.view.pattern_editor.menu.edit.place_pattern", "Place pattern..." }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin", "Built-in Type" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.single", "Single" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.array", "Array" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.custom", "Custom Type" }, { "hex.builtin.view.pattern_editor.open_pattern", "パターンを開く" }, { "hex.builtin.view.pattern_editor.evaluating", "実行中…" }, //? { "hex.builtin.view.pattern_editor.auto", "常に実行" }, //? diff --git a/plugins/builtin/source/lang/ko_KR.cpp b/plugins/builtin/source/lang/ko_KR.cpp index d5377eb45..6d61f7250 100644 --- a/plugins/builtin/source/lang/ko_KR.cpp +++ b/plugins/builtin/source/lang/ko_KR.cpp @@ -376,6 +376,11 @@ namespace hex::plugin::builtin { { "hex.builtin.view.pattern_editor.accept_pattern.question", "선택한 패턴을 적용하시겠습니까?" }, { "hex.builtin.view.pattern_editor.menu.file.load_pattern", "패턴 불러오기..." }, { "hex.builtin.view.pattern_editor.menu.file.save_pattern", "패턴 저장하기..." }, + //{ "hex.builtin.view.pattern_editor.menu.edit.place_pattern", "Place pattern..." }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin", "Built-in Type" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.single", "Single" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.array", "Array" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.custom", "Custom Type" }, { "hex.builtin.view.pattern_editor.open_pattern", "패턴 열기" }, { "hex.builtin.view.pattern_editor.evaluating", "평가 중..." }, { "hex.builtin.view.pattern_editor.auto", "자동 평가" }, diff --git a/plugins/builtin/source/lang/pt_BR.cpp b/plugins/builtin/source/lang/pt_BR.cpp index 5c1561df7..bf456f602 100644 --- a/plugins/builtin/source/lang/pt_BR.cpp +++ b/plugins/builtin/source/lang/pt_BR.cpp @@ -376,6 +376,11 @@ namespace hex::plugin::builtin { { "hex.builtin.view.pattern_editor.accept_pattern.question", "Deseja aplicar o padrão selecionado?" }, { "hex.builtin.view.pattern_editor.menu.file.load_pattern", "Carregando padrão..." }, { "hex.builtin.view.pattern_editor.menu.file.save_pattern", "Salvando padrão..." }, + //{ "hex.builtin.view.pattern_editor.menu.edit.place_pattern", "Place pattern..." }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin", "Built-in Type" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.single", "Single" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.array", "Array" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.custom", "Custom Type" }, { "hex.builtin.view.pattern_editor.open_pattern", "Abrir padrão" }, { "hex.builtin.view.pattern_editor.evaluating", "Avaliando..." }, { "hex.builtin.view.pattern_editor.auto", "Auto Avaliar" }, diff --git a/plugins/builtin/source/lang/zh_CN.cpp b/plugins/builtin/source/lang/zh_CN.cpp index b809034ed..740624e2b 100644 --- a/plugins/builtin/source/lang/zh_CN.cpp +++ b/plugins/builtin/source/lang/zh_CN.cpp @@ -379,6 +379,11 @@ namespace hex::plugin::builtin { { "hex.builtin.view.pattern_editor.accept_pattern.question", "是否应用找到的模式?" }, { "hex.builtin.view.pattern_editor.menu.file.load_pattern", "加载模式文件..." }, { "hex.builtin.view.pattern_editor.menu.file.save_pattern", "保存模式文件..." }, + //{ "hex.builtin.view.pattern_editor.menu.edit.place_pattern", "Place pattern..." }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin", "Built-in Type" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.single", "Single" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.array", "Array" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.custom", "Custom Type" }, { "hex.builtin.view.pattern_editor.open_pattern", "打开模式" }, { "hex.builtin.view.pattern_editor.evaluating", "计算中..." }, { "hex.builtin.view.pattern_editor.auto", "自动计算" }, diff --git a/plugins/builtin/source/lang/zh_TW.cpp b/plugins/builtin/source/lang/zh_TW.cpp index 1b3712f72..c3cc47330 100644 --- a/plugins/builtin/source/lang/zh_TW.cpp +++ b/plugins/builtin/source/lang/zh_TW.cpp @@ -376,6 +376,11 @@ namespace hex::plugin::builtin { { "hex.builtin.view.pattern_editor.accept_pattern.question", "Do you want to apply the selected pattern?" }, { "hex.builtin.view.pattern_editor.menu.file.load_pattern", "載入模式..." }, { "hex.builtin.view.pattern_editor.menu.file.save_pattern", "儲存模式..." }, + //{ "hex.builtin.view.pattern_editor.menu.edit.place_pattern", "Place pattern..." }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin", "Built-in Type" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.single", "Single" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.builtin.array", "Array" }, + // { "hex.builtin.view.pattern_editor.menu.edit.place_pattern.custom", "Custom Type" }, { "hex.builtin.view.pattern_editor.open_pattern", "開啟模式" }, { "hex.builtin.view.pattern_editor.evaluating", "Evaluating..." }, { "hex.builtin.view.pattern_editor.auto", "Auto evaluate" },