mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-04-02 21:47:40 -05:00
ui/ux: Rewrite of the entire hex editor view to make it more flexible (#512)
* ui/ux: Initial recreation of the hex editor view * ui/ux: Added back support for editing cells * ux: Make scrolling and selecting bytes feel nice again * ui/ux: Improved byte selecting, added footer * sys: Make math evaluator more generic to support integer only calculations * patterns: Moved value formatting into pattern language * ui/ux: Added Goto and Search popups, improved selection * ui: Added better tooltips for bookmarks and patterns * sys: Use worse hex search algorithm on macOS Sadly it still doesn't support `std::boyer_moore_horsepool_searcher` * ui: Added back missing events, menu items and shortcuts * fix: Bookmark highlighting being rendered off by one * fix: Various macOS build errors * fix: size_t is not u64 on macos * fix: std::fmod and std::pow not working with integer types on macos * fix: Missing semicolons * sys: Added proper integer pow function * ui: Added back support for custom encodings * fix: Editor not jumping to selection when selection gets changed * ui: Turn Hexii setting into a data visualizer * sys: Added back remaining shortcuts * sys: Remove old hex editor files * sys: Moved more legacy things away from the hex editor view, updated localization * fix: Hex editor scrolling behaving weirdly and inconsistently * sys: Cleaned up Hex editor code * sys: Added selection color setting, localized all new settings * fix: Search feature not working correctly * ui: Replace custom ImGui::Disabled function with native ImGui ones * ui: Fix bookmark tooltip rendering issues * fix: Another size_t not being 64 bit issue on MacOS
This commit is contained in:
@@ -20,6 +20,8 @@ add_library(${PROJECT_NAME} SHARED
|
||||
source/content/layouts.cpp
|
||||
source/content/main_menu_items.cpp
|
||||
source/content/welcome_screen.cpp
|
||||
source/content/data_visualizers.cpp
|
||||
source/content/events.cpp
|
||||
|
||||
source/content/providers/file_provider.cpp
|
||||
source/content/providers/gdb_provider.cpp
|
||||
|
||||
@@ -1,96 +1,131 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/helpers/concepts.hpp>
|
||||
#include <hex/helpers/encoding_file.hpp>
|
||||
|
||||
#include <imgui_memory_editor.h>
|
||||
|
||||
#include <list>
|
||||
#include <tuple>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
namespace hex::prv {
|
||||
class Provider;
|
||||
}
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
using SearchFunction = std::vector<std::pair<u64, u64>> (*)(prv::Provider *&provider, std::string string);
|
||||
|
||||
struct HighlightBlock {
|
||||
struct Highlight {
|
||||
color_t color;
|
||||
std::vector<std::string> tooltips;
|
||||
};
|
||||
|
||||
constexpr static size_t Size = 0x2000;
|
||||
|
||||
u64 base = 0x00;
|
||||
std::array<Highlight, Size> highlight;
|
||||
};
|
||||
|
||||
class ViewHexEditor : public View {
|
||||
public:
|
||||
ViewHexEditor();
|
||||
~ViewHexEditor() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawAlwaysVisible() override;
|
||||
|
||||
private:
|
||||
MemoryEditor m_memoryEditor;
|
||||
|
||||
std::vector<char> m_searchStringBuffer;
|
||||
std::vector<char> m_searchHexBuffer;
|
||||
SearchFunction m_searchFunction = nullptr;
|
||||
std::vector<std::pair<u64, u64>> *m_lastSearchBuffer = nullptr;
|
||||
bool m_searchRequested = false;
|
||||
|
||||
i64 m_lastSearchIndex = 0;
|
||||
std::vector<std::pair<u64, u64>> m_lastStringSearch;
|
||||
std::vector<std::pair<u64, u64>> m_lastHexSearch;
|
||||
|
||||
std::string m_gotoAddressInput;
|
||||
bool m_gotoRequested = false;
|
||||
bool m_evaluateGoto = false;
|
||||
|
||||
u64 m_baseAddress = 0;
|
||||
u64 m_resizeSize = 0;
|
||||
|
||||
std::vector<u8> m_dataToSave;
|
||||
std::set<pl::Pattern *> m_highlightedPatterns;
|
||||
|
||||
std::string m_loaderScriptScriptPath;
|
||||
std::string m_loaderScriptFilePath;
|
||||
|
||||
hex::EncodingFile m_currEncodingFile;
|
||||
u8 m_highlightAlpha = 0x80;
|
||||
|
||||
std::list<HighlightBlock> m_highlights;
|
||||
|
||||
bool m_processingImportExport = false;
|
||||
bool m_advancedDecodingEnabled = false;
|
||||
|
||||
void drawSearchPopup();
|
||||
void drawSearchInput(std::vector<char> *currBuffer, ImGuiInputTextFlags flags);
|
||||
void performSearch(const char *buffer);
|
||||
void performSearchNext();
|
||||
void performSearchPrevious();
|
||||
static int inputCallback(ImGuiInputTextCallbackData *data);
|
||||
|
||||
void drawGotoPopup();
|
||||
void drawEditPopup();
|
||||
constexpr static auto InvalidSelection = std::numeric_limits<u64>::max();
|
||||
|
||||
void openFile(const std::fs::path &path);
|
||||
|
||||
void copyBytes() const;
|
||||
void pasteBytes() const;
|
||||
void copyString() const;
|
||||
|
||||
void registerEvents();
|
||||
void registerShortcuts();
|
||||
void registerEvents();
|
||||
void registerMenuItems();
|
||||
|
||||
void drawCell(u64 address, u8 *data, size_t size, bool hovered);
|
||||
void drawPopup();
|
||||
void drawSelectionFrame(u32 x, u32 y, u64 byteAddress, u16 bytesPerCell, const ImVec2 &cellPos, const ImVec2 &cellSize);
|
||||
|
||||
public:
|
||||
void setSelection(const Region ®ion) { this->setSelection(region.getStartAddress(), region.getEndAddress()); }
|
||||
void setSelection(i128 start, i128 end) {
|
||||
if (!ImHexApi::Provider::isValid()) return;
|
||||
|
||||
const size_t maxAddress = ImHexApi::Provider::get()->getActualSize() - 1;
|
||||
|
||||
this->m_selectionChanged = this->m_selectionStart != start || this->m_selectionEnd != end;
|
||||
|
||||
this->m_selectionStart = std::clamp<decltype(start)>(start, 0, maxAddress);
|
||||
this->m_selectionEnd = std::clamp<decltype(end)>(end, 0, maxAddress);
|
||||
|
||||
if (this->m_selectionChanged) {
|
||||
EventManager::post<EventRegionSelected>(this->getSelection());
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] Region getSelection() const {
|
||||
const auto start = std::min(this->m_selectionStart, this->m_selectionEnd);
|
||||
const auto end = std::max(this->m_selectionStart, this->m_selectionEnd);
|
||||
const size_t size = end - start + 1;
|
||||
|
||||
return { start, size };
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isSelectionValid() const {
|
||||
return this->m_selectionStart != InvalidSelection && this->m_selectionEnd != InvalidSelection;
|
||||
}
|
||||
|
||||
void jumpToSelection() {
|
||||
this->m_shouldJumpToSelection = true;
|
||||
}
|
||||
|
||||
void scrollToSelection() {
|
||||
this->m_shouldScrollToSelection = true;
|
||||
}
|
||||
|
||||
public:
|
||||
class Popup {
|
||||
public:
|
||||
virtual ~Popup() = default;
|
||||
virtual void draw(ViewHexEditor *editor) = 0;
|
||||
};
|
||||
|
||||
[[nodiscard]] bool isAnyPopupOpen() const {
|
||||
return this->m_currPopup != nullptr;
|
||||
}
|
||||
|
||||
template<std::derived_from<Popup> T>
|
||||
[[nodiscard]] bool isPopupOpen() const {
|
||||
return dynamic_cast<T*>(this->m_currPopup.get()) != nullptr;
|
||||
}
|
||||
|
||||
template<std::derived_from<Popup> T, typename ... Args>
|
||||
void openPopup(Args && ...args) {
|
||||
this->m_currPopup = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
this->m_shouldOpenPopup = true;
|
||||
}
|
||||
|
||||
void closePopup() {
|
||||
this->m_currPopup.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
void drawEditor(const ImVec2 &size);
|
||||
void drawFooter(const ImVec2 &size);
|
||||
|
||||
void handleSelection(u64 address, u32 bytesPerCell, const u8 *data, bool cellHovered);
|
||||
|
||||
private:
|
||||
u16 m_bytesPerRow = 16;
|
||||
|
||||
ContentRegistry::HexEditor::DataVisualizer *m_currDataVisualizer;
|
||||
|
||||
bool m_shouldJumpToSelection = false;
|
||||
bool m_shouldScrollToSelection = false;
|
||||
|
||||
bool m_selectionChanged = false;
|
||||
u64 m_selectionStart = InvalidSelection;
|
||||
u64 m_selectionEnd = InvalidSelection;
|
||||
|
||||
u16 m_visibleRowCount = 0;
|
||||
|
||||
std::optional<u64> m_editingAddress;
|
||||
bool m_shouldModifyValue = false;
|
||||
bool m_enteredEditingMode = false;
|
||||
std::vector<u8> m_editingBytes;
|
||||
|
||||
color_t m_selectionColor = 0x00;
|
||||
bool m_upperCaseHex = true;
|
||||
bool m_grayOutZero = true;
|
||||
bool m_showAscii = true;
|
||||
|
||||
bool m_shouldOpenPopup = false;
|
||||
std::unique_ptr<Popup> m_currPopup;
|
||||
|
||||
std::optional<EncodingFile> m_currCustomEncoding;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
#include <TextEditor.h>
|
||||
|
||||
namespace pl { class Pattern; }
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class ViewPatternEditor : public View {
|
||||
@@ -91,6 +93,8 @@ namespace hex::plugin::builtin {
|
||||
void drawEnvVars(ImVec2 size);
|
||||
void drawVariableSettings(ImVec2 size);
|
||||
|
||||
void drawPatternTooltip(pl::Pattern *pattern);
|
||||
|
||||
void loadPatternFile(const std::fs::path &path);
|
||||
void clearPatterns();
|
||||
|
||||
|
||||
@@ -21,7 +21,9 @@ namespace hex::plugin::builtin {
|
||||
u64 address;
|
||||
size_t size;
|
||||
bool wholeDataMatch;
|
||||
|
||||
u32 highlightId;
|
||||
u32 tooltipId;
|
||||
};
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> m_rules;
|
||||
|
||||
@@ -11,83 +11,108 @@
|
||||
|
||||
namespace hex {
|
||||
|
||||
enum class TokenType
|
||||
{
|
||||
Number,
|
||||
Variable,
|
||||
Function,
|
||||
Operator,
|
||||
Bracket
|
||||
};
|
||||
|
||||
enum class Operator : u16
|
||||
{
|
||||
Invalid = 0x000,
|
||||
Assign = 0x010,
|
||||
Or = 0x020,
|
||||
Xor = 0x030,
|
||||
And = 0x040,
|
||||
BitwiseOr = 0x050,
|
||||
BitwiseXor = 0x060,
|
||||
BitwiseAnd = 0x070,
|
||||
Equals = 0x080,
|
||||
NotEquals = 0x081,
|
||||
GreaterThan = 0x090,
|
||||
LessThan = 0x091,
|
||||
GreaterThanOrEquals = 0x092,
|
||||
LessThanOrEquals = 0x093,
|
||||
ShiftLeft = 0x0A0,
|
||||
ShiftRight = 0x0A1,
|
||||
Addition = 0x0B0,
|
||||
Subtraction = 0x0B1,
|
||||
Multiplication = 0x0C0,
|
||||
Division = 0x0C1,
|
||||
Modulus = 0x0C2,
|
||||
Exponentiation = 0x1D0,
|
||||
Combine = 0x0E0,
|
||||
BitwiseNot = 0x0F0,
|
||||
Not = 0x0F1
|
||||
};
|
||||
|
||||
enum class BracketType : std::uint8_t
|
||||
{
|
||||
Left,
|
||||
Right
|
||||
};
|
||||
|
||||
struct Token {
|
||||
TokenType type;
|
||||
|
||||
union {
|
||||
long double number;
|
||||
Operator op;
|
||||
BracketType bracketType;
|
||||
};
|
||||
|
||||
std::string name;
|
||||
std::vector<long double> arguments;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class MathEvaluator {
|
||||
public:
|
||||
MathEvaluator() = default;
|
||||
|
||||
std::optional<long double> evaluate(const std::string &input);
|
||||
std::optional<T> evaluate(const std::string &input);
|
||||
|
||||
void registerStandardVariables();
|
||||
void registerStandardFunctions();
|
||||
|
||||
void setVariable(const std::string &name, long double value);
|
||||
void setFunction(const std::string &name, const std::function<std::optional<long double>(std::vector<long double>)> &function, size_t minNumArgs, size_t maxNumArgs);
|
||||
void setVariable(const std::string &name, T value);
|
||||
void setFunction(const std::string &name, const std::function<std::optional<T>(std::vector<T>)> &function, size_t minNumArgs, size_t maxNumArgs);
|
||||
|
||||
std::unordered_map<std::string, long double> &getVariables() { return this->m_variables; }
|
||||
std::unordered_map<std::string, T> &getVariables() { return this->m_variables; }
|
||||
|
||||
[[nodiscard]] bool hasError() const {
|
||||
return this->m_lastError.has_value();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::optional<std::string> getLastError() const {
|
||||
return this->m_lastError;
|
||||
}
|
||||
|
||||
private:
|
||||
std::queue<Token> parseInput(std::string input);
|
||||
std::optional<long double> evaluate(std::queue<Token> postfixTokens);
|
||||
void setError(const std::string &error) {
|
||||
this->m_lastError = error;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, long double> m_variables;
|
||||
std::unordered_map<std::string, std::function<std::optional<long double>(std::vector<long double>)>> m_functions;
|
||||
private:
|
||||
enum class TokenType
|
||||
{
|
||||
Number,
|
||||
Variable,
|
||||
Function,
|
||||
Operator,
|
||||
Bracket
|
||||
};
|
||||
|
||||
enum class Operator : u16
|
||||
{
|
||||
Invalid = 0x000,
|
||||
Assign = 0x010,
|
||||
Or = 0x020,
|
||||
Xor = 0x030,
|
||||
And = 0x040,
|
||||
BitwiseOr = 0x050,
|
||||
BitwiseXor = 0x060,
|
||||
BitwiseAnd = 0x070,
|
||||
Equals = 0x080,
|
||||
NotEquals = 0x081,
|
||||
GreaterThan = 0x090,
|
||||
LessThan = 0x091,
|
||||
GreaterThanOrEquals = 0x092,
|
||||
LessThanOrEquals = 0x093,
|
||||
ShiftLeft = 0x0A0,
|
||||
ShiftRight = 0x0A1,
|
||||
Addition = 0x0B0,
|
||||
Subtraction = 0x0B1,
|
||||
Multiplication = 0x0C0,
|
||||
Division = 0x0C1,
|
||||
Modulus = 0x0C2,
|
||||
Exponentiation = 0x1D0,
|
||||
Combine = 0x0E0,
|
||||
BitwiseNot = 0x0F0,
|
||||
Not = 0x0F1
|
||||
};
|
||||
|
||||
enum class BracketType : std::uint8_t
|
||||
{
|
||||
Left,
|
||||
Right
|
||||
};
|
||||
|
||||
struct Token {
|
||||
TokenType type;
|
||||
|
||||
union {
|
||||
T number;
|
||||
Operator op;
|
||||
BracketType bracketType;
|
||||
};
|
||||
|
||||
std::string name;
|
||||
std::vector<T> arguments;
|
||||
};
|
||||
|
||||
static i16 comparePrecedence(const Operator &a, const Operator &b);
|
||||
static bool isLeftAssociative(const Operator op);
|
||||
static std::pair<Operator, size_t> toOperator(const std::string &input);
|
||||
|
||||
private:
|
||||
std::optional<std::queue<Token>> parseInput(std::string input);
|
||||
std::optional<std::queue<Token>> toPostfix(std::queue<Token> inputQueue);
|
||||
std::optional<T> evaluate(std::queue<Token> postfixTokens);
|
||||
|
||||
std::unordered_map<std::string, T> m_variables;
|
||||
std::unordered_map<std::string, std::function<std::optional<T>(std::vector<T>)>> m_functions;
|
||||
|
||||
std::optional<std::string> m_lastError;
|
||||
};
|
||||
|
||||
extern template class MathEvaluator<long double>;
|
||||
extern template class MathEvaluator<i128>;
|
||||
|
||||
}
|
||||
@@ -16,19 +16,17 @@ namespace hex::plugin::builtin {
|
||||
"#",
|
||||
"hex.builtin.command.calc.desc",
|
||||
[](auto input) {
|
||||
hex::MathEvaluator evaluator;
|
||||
hex::MathEvaluator<long double> evaluator;
|
||||
evaluator.registerStandardVariables();
|
||||
evaluator.registerStandardFunctions();
|
||||
|
||||
std::optional<long double> result;
|
||||
|
||||
try {
|
||||
result = evaluator.evaluate(input);
|
||||
} catch (std::exception &e) { }
|
||||
|
||||
|
||||
result = evaluator.evaluate(input);
|
||||
if (result.has_value())
|
||||
return hex::format("#{0} = {1}", input.data(), result.value());
|
||||
else if (evaluator.hasError())
|
||||
return hex::format("Error: {}", *evaluator.getLastError());
|
||||
else
|
||||
return std::string("???");
|
||||
});
|
||||
|
||||
@@ -323,19 +323,25 @@ namespace hex::plugin::builtin {
|
||||
[](auto buffer, auto endian, auto style) {
|
||||
hex::unused(endian, style);
|
||||
|
||||
Region currSelection = { 0, 0 };
|
||||
EventManager::post<QuerySelection>(currSelection);
|
||||
auto currSelection = ImHexApi::HexEditor::getSelection();
|
||||
|
||||
constexpr static auto MaxStringLength = 32;
|
||||
|
||||
std::vector<u8> stringBuffer(std::min<size_t>(MaxStringLength, currSelection.size), 0x00);
|
||||
ImHexApi::Provider::get()->read(currSelection.address, stringBuffer.data(), stringBuffer.size());
|
||||
std::string value, copyValue;
|
||||
|
||||
auto value = hex::encodeByteString(stringBuffer);
|
||||
auto copyValue = hex::encodeByteString(buffer);
|
||||
if (currSelection.has_value()) {
|
||||
std::vector<u8> stringBuffer(std::min<size_t>(MaxStringLength, currSelection->size), 0x00);
|
||||
ImHexApi::Provider::get()->read(currSelection->address, stringBuffer.data(), stringBuffer.size());
|
||||
|
||||
if (currSelection.size > MaxStringLength)
|
||||
value += "...";
|
||||
value = hex::encodeByteString(stringBuffer);
|
||||
copyValue = hex::encodeByteString(buffer);
|
||||
|
||||
if (currSelection->size > MaxStringLength)
|
||||
value += "...";
|
||||
} else {
|
||||
value = "";
|
||||
copyValue = "";
|
||||
}
|
||||
|
||||
return [value, copyValue] { ImGui::TextFormatted("\"{0}\"", value.c_str()); return copyValue; };
|
||||
},
|
||||
|
||||
272
plugins/builtin/source/content/data_visualizers.cpp
Normal file
272
plugins/builtin/source/content/data_visualizers.cpp
Normal file
@@ -0,0 +1,272 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
template<typename T>
|
||||
constexpr ImGuiDataType getImGuiDataType() {
|
||||
if constexpr (std::same_as<T, u8>) return ImGuiDataType_U8;
|
||||
else if constexpr (std::same_as<T, u16>) return ImGuiDataType_U16;
|
||||
else if constexpr (std::same_as<T, u32>) return ImGuiDataType_U32;
|
||||
else if constexpr (std::same_as<T, u64>) return ImGuiDataType_U64;
|
||||
else if constexpr (std::same_as<T, i8>) return ImGuiDataType_S8;
|
||||
else if constexpr (std::same_as<T, i16>) return ImGuiDataType_S16;
|
||||
else if constexpr (std::same_as<T, i32>) return ImGuiDataType_S32;
|
||||
else if constexpr (std::same_as<T, i64>) return ImGuiDataType_S64;
|
||||
else if constexpr (std::same_as<T, float>) return ImGuiDataType_Float;
|
||||
else if constexpr (std::same_as<T, double>) return ImGuiDataType_Double;
|
||||
else static_assert(hex::always_false<T>::value, "Invalid data type!");
|
||||
}
|
||||
|
||||
template<hex::integral T>
|
||||
class DataVisualizerHexadecimal : public hex::ContentRegistry::HexEditor::DataVisualizer {
|
||||
public:
|
||||
DataVisualizerHexadecimal() : DataVisualizer(ByteCount, CharCount) { }
|
||||
|
||||
void draw(u64 address, const u8 *data, size_t size, bool upperCase) override {
|
||||
hex::unused(address);
|
||||
|
||||
if (size == ByteCount)
|
||||
ImGui::Text(getFormatString(upperCase), *reinterpret_cast<const T*>(data));
|
||||
else
|
||||
ImGui::TextFormatted("{: {}s}", CharCount);
|
||||
}
|
||||
|
||||
bool drawEditing(u64 address, u8 *data, size_t size, bool upperCase, bool startedEditing) override {
|
||||
hex::unused(address, startedEditing);
|
||||
|
||||
if (size == ByteCount) {
|
||||
return drawDefaultEditingTextBox(address, getFormatString(upperCase), getImGuiDataType<T>(), data, ImGuiInputTextFlags_CharsHexadecimal);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr static inline auto ByteCount = sizeof(T);
|
||||
constexpr static inline auto CharCount = ByteCount * 2;
|
||||
|
||||
const static inline auto FormattingUpperCase = hex::format("%0{}X", CharCount);
|
||||
const static inline auto FormattingLowerCase = hex::format("%0{}x", CharCount);
|
||||
|
||||
const char *getFormatString(bool upperCase) {
|
||||
if (upperCase)
|
||||
return FormattingUpperCase.c_str();
|
||||
else
|
||||
return FormattingLowerCase.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
class DataVisualizerHexii : public hex::ContentRegistry::HexEditor::DataVisualizer {
|
||||
public:
|
||||
DataVisualizerHexii() : DataVisualizer(ByteCount, CharCount) { }
|
||||
|
||||
void draw(u64 address, const u8 *data, size_t size, bool upperCase) override {
|
||||
hex::unused(address);
|
||||
|
||||
if (size == ByteCount) {
|
||||
const u8 c = data[0];
|
||||
switch (c) {
|
||||
case 0x00:
|
||||
ImGui::Text(" ");
|
||||
break;
|
||||
case 0xFF:
|
||||
ImGui::TextDisabled("##");
|
||||
break;
|
||||
case ' ' ... '~':
|
||||
ImGui::Text(".%c", c);
|
||||
break;
|
||||
default:
|
||||
ImGui::Text(getFormatString(upperCase), c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
ImGui::TextFormatted("{: {}s}", CharCount);
|
||||
}
|
||||
|
||||
bool drawEditing(u64 address, u8 *data, size_t size, bool upperCase, bool startedEditing) override {
|
||||
hex::unused(address, startedEditing);
|
||||
|
||||
if (size == ByteCount) {
|
||||
return drawDefaultEditingTextBox(address, getFormatString(upperCase), getImGuiDataType<u8>(), data, ImGuiInputTextFlags_CharsHexadecimal);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr static inline auto ByteCount = 1;
|
||||
constexpr static inline auto CharCount = ByteCount * 2;
|
||||
|
||||
const static inline auto FormattingUpperCase = hex::format("%0{}X", CharCount);
|
||||
const static inline auto FormattingLowerCase = hex::format("%0{}x", CharCount);
|
||||
|
||||
const char *getFormatString(bool upperCase) {
|
||||
if (upperCase)
|
||||
return FormattingUpperCase.c_str();
|
||||
else
|
||||
return FormattingLowerCase.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
template<hex::integral T>
|
||||
class DataVisualizerDecimal : public hex::ContentRegistry::HexEditor::DataVisualizer {
|
||||
public:
|
||||
DataVisualizerDecimal() : DataVisualizer(ByteCount, CharCount) { }
|
||||
|
||||
void draw(u64 address, const u8 *data, size_t size, bool upperCase) override {
|
||||
hex::unused(address, upperCase);
|
||||
|
||||
if (size == ByteCount) {
|
||||
if (hex::is_signed<T>::value)
|
||||
ImGui::Text(getFormatString(), static_cast<i64>(*reinterpret_cast<const T*>(data)));
|
||||
else
|
||||
ImGui::Text(getFormatString(), static_cast<u64>(*reinterpret_cast<const T*>(data)));
|
||||
}
|
||||
else
|
||||
ImGui::TextFormatted("{: {}s}", CharCount);
|
||||
}
|
||||
|
||||
bool drawEditing(u64 address, u8 *data, size_t size, bool upperCase, bool startedEditing) override {
|
||||
hex::unused(address, upperCase, startedEditing);
|
||||
|
||||
if (size == ByteCount) {
|
||||
return ImGui::InputScalar(
|
||||
"##hex_input",
|
||||
getImGuiDataType<T>(),
|
||||
data,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
DataVisualizer::TextInputFlags);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr static inline auto ByteCount = sizeof(T);
|
||||
constexpr static inline auto CharCount = std::numeric_limits<T>::digits10 + 2;
|
||||
|
||||
const static inline auto FormatString = hex::format("%{}{}", CharCount, hex::is_signed<T>::value ? "lld" : "llu");
|
||||
|
||||
const char *getFormatString() {
|
||||
return FormatString.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
template<hex::floating_point T>
|
||||
class DataVisualizerFloatingPoint : public hex::ContentRegistry::HexEditor::DataVisualizer {
|
||||
public:
|
||||
DataVisualizerFloatingPoint() : DataVisualizer(ByteCount, CharCount) { }
|
||||
|
||||
void draw(u64 address, const u8 *data, size_t size, bool upperCase) override {
|
||||
hex::unused(address);
|
||||
|
||||
if (size == ByteCount)
|
||||
ImGui::Text(getFormatString(upperCase), *reinterpret_cast<const T*>(data));
|
||||
else
|
||||
ImGui::TextFormatted("{: {}s}", CharCount);
|
||||
}
|
||||
|
||||
bool drawEditing(u64 address, u8 *data, size_t size, bool upperCase, bool startedEditing) override {
|
||||
hex::unused(address, upperCase, startedEditing);
|
||||
|
||||
if (size == ByteCount) {
|
||||
return ImGui::InputScalar(
|
||||
"##hex_input",
|
||||
getImGuiDataType<T>(),
|
||||
data,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
DataVisualizer::TextInputFlags | ImGuiInputTextFlags_CharsScientific);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr static inline auto ByteCount = sizeof(T);
|
||||
constexpr static inline auto CharCount = 14;
|
||||
|
||||
const static inline auto FormatStringUpperCase = hex::format("%{}E", CharCount);
|
||||
const static inline auto FormatStringLowerCase = hex::format("%{}e", CharCount);
|
||||
|
||||
const char *getFormatString(bool upperCase) {
|
||||
if (upperCase)
|
||||
return FormatStringUpperCase.c_str();
|
||||
else
|
||||
return FormatStringLowerCase.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
class DataVisualizerRGBA8 : public hex::ContentRegistry::HexEditor::DataVisualizer {
|
||||
public:
|
||||
DataVisualizerRGBA8() : DataVisualizer(4, 2) { }
|
||||
|
||||
void draw(u64 address, const u8 *data, size_t size, bool upperCase) override {
|
||||
hex::unused(address, upperCase);
|
||||
|
||||
if (size == 4)
|
||||
ImGui::ColorButton("##color", ImColor(data[0], data[1], data[2], data[3]), ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoDragDrop, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
|
||||
else
|
||||
ImGui::ColorButton("##color", ImColor(0, 0, 0, 0xFF), ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoDragDrop, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
|
||||
}
|
||||
|
||||
bool drawEditing(u64 address, u8 *data, size_t size, bool upperCase, bool startedEditing) override {
|
||||
hex::unused(address, data, size, upperCase);
|
||||
|
||||
if (startedEditing) {
|
||||
this->m_currColor = { float(data[0]) / 0xFF, float(data[1]) / 0xFF, float(data[2]) / 0xFF, float(data[3]) / 0xFF };
|
||||
ImGui::OpenPopup("##color_popup");
|
||||
}
|
||||
|
||||
ImGui::ColorButton("##color", ImColor(this->m_currColor[0], this->m_currColor[1], this->m_currColor[2], this->m_currColor[3]), ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoDragDrop, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
|
||||
|
||||
if (ImGui::BeginPopup("##color_popup")) {
|
||||
if (ImGui::ColorPicker4("##picker", this->m_currColor.data(), ImGuiColorEditFlags_AlphaBar)) {
|
||||
for (u8 i = 0; i < 4; i++)
|
||||
data[i] = this->m_currColor[i] * 0xFF;
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::array<float, 4> m_currColor;
|
||||
|
||||
};
|
||||
|
||||
void registerDataVisualizers() {
|
||||
ContentRegistry::HexEditor::addDataVisualizer<DataVisualizerHexadecimal<u8>>("hex.builtin.visualizer.hexadecimal.8bit");
|
||||
ContentRegistry::HexEditor::addDataVisualizer<DataVisualizerHexadecimal<u16>>("hex.builtin.visualizer.hexadecimal.16bit");
|
||||
ContentRegistry::HexEditor::addDataVisualizer<DataVisualizerHexadecimal<u32>>("hex.builtin.visualizer.hexadecimal.32bit");
|
||||
ContentRegistry::HexEditor::addDataVisualizer<DataVisualizerHexadecimal<u64>>("hex.builtin.visualizer.hexadecimal.64bit");
|
||||
|
||||
ContentRegistry::HexEditor::addDataVisualizer<DataVisualizerDecimal<u8>>("hex.builtin.visualizer.decimal.unsigned.8bit");
|
||||
ContentRegistry::HexEditor::addDataVisualizer<DataVisualizerDecimal<u16>>("hex.builtin.visualizer.decimal.unsigned.16bit");
|
||||
ContentRegistry::HexEditor::addDataVisualizer<DataVisualizerDecimal<u32>>("hex.builtin.visualizer.decimal.unsigned.32bit");
|
||||
ContentRegistry::HexEditor::addDataVisualizer<DataVisualizerDecimal<u64>>("hex.builtin.visualizer.decimal.unsigned.64bit");
|
||||
|
||||
ContentRegistry::HexEditor::addDataVisualizer<DataVisualizerDecimal<i8>>("hex.builtin.visualizer.decimal.signed.8bit");
|
||||
ContentRegistry::HexEditor::addDataVisualizer<DataVisualizerDecimal<i16>>("hex.builtin.visualizer.decimal.signed.16bit");
|
||||
ContentRegistry::HexEditor::addDataVisualizer<DataVisualizerDecimal<i32>>("hex.builtin.visualizer.decimal.signed.32bit");
|
||||
ContentRegistry::HexEditor::addDataVisualizer<DataVisualizerDecimal<i64>>("hex.builtin.visualizer.decimal.signed.64bit");
|
||||
|
||||
ContentRegistry::HexEditor::addDataVisualizer<DataVisualizerFloatingPoint<float>>("hex.builtin.visualizer.floating_point.32bit");
|
||||
ContentRegistry::HexEditor::addDataVisualizer<DataVisualizerFloatingPoint<double>>("hex.builtin.visualizer.floating_point.64bit");
|
||||
|
||||
ContentRegistry::HexEditor::addDataVisualizer<DataVisualizerRGBA8>("hex.builtin.visualizer.rgba8");
|
||||
ContentRegistry::HexEditor::addDataVisualizer<DataVisualizerHexii>("hex.builtin.visualizer.hexii");
|
||||
}
|
||||
|
||||
}
|
||||
91
plugins/builtin/source/content/events.cpp
Normal file
91
plugins/builtin/source/content/events.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
#include <hex/api/event.hpp>
|
||||
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/helpers/project_file_handler.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
#include <hex/helpers/file.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include "content/providers/file_provider.hpp"
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
static void openFile(const std::fs::path &path) {
|
||||
hex::prv::Provider *provider = nullptr;
|
||||
EventManager::post<RequestCreateProvider>("hex.builtin.provider.file", &provider);
|
||||
|
||||
if (auto fileProvider = dynamic_cast<prv::FileProvider *>(provider)) {
|
||||
fileProvider->setPath(path);
|
||||
if (!fileProvider->open()) {
|
||||
View::showErrorPopup("hex.builtin.popup.error.open"_lang);
|
||||
ImHexApi::Provider::remove(provider);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!provider->isWritable()) {
|
||||
View::showErrorPopup("hex.builtin.popup.error.read_only"_lang);
|
||||
}
|
||||
|
||||
if (!provider->isAvailable()) {
|
||||
View::showErrorPopup("hex.builtin.popup.error.open"_lang);
|
||||
ImHexApi::Provider::remove(provider);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ProjectFile::setFilePath(path);
|
||||
|
||||
EventManager::post<EventFileLoaded>(path);
|
||||
EventManager::post<EventDataChanged>();
|
||||
EventManager::post<EventHighlightingChanged>();
|
||||
}
|
||||
|
||||
void registerEventHandlers() {
|
||||
EventManager::subscribe<EventProjectFileLoad>([]() {
|
||||
EventManager::post<RequestOpenFile>(ProjectFile::getFilePath());
|
||||
});
|
||||
|
||||
EventManager::subscribe<EventWindowClosing>([](GLFWwindow *window) {
|
||||
if (ProjectFile::hasUnsavedChanges()) {
|
||||
glfwSetWindowShouldClose(window, GLFW_FALSE);
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.popup.exit_application.title"_lang); });
|
||||
}
|
||||
});
|
||||
|
||||
EventManager::subscribe<RequestOpenFile>(openFile);
|
||||
|
||||
EventManager::subscribe<RequestOpenWindow>([](const std::string &name) {
|
||||
if (name == "Create File") {
|
||||
fs::openFileBrowser(fs::DialogMode::Save, {}, [](const auto &path) {
|
||||
fs::File file(path, fs::File::Mode::Create);
|
||||
|
||||
if (!file.isValid()) {
|
||||
View::showErrorPopup("hex.builtin.popup.error.create"_lang);
|
||||
return;
|
||||
}
|
||||
|
||||
file.setSize(1);
|
||||
|
||||
EventManager::post<RequestOpenFile>(path);
|
||||
});
|
||||
} else if (name == "Open File") {
|
||||
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
|
||||
EventManager::post<RequestOpenFile>(path);
|
||||
});
|
||||
} else if (name == "Open Project") {
|
||||
fs::openFileBrowser(fs::DialogMode::Open, { {"Project File", "hexproj"} },
|
||||
[](const auto &path) {
|
||||
ProjectFile::load(path);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
EventManager::subscribe<EventProviderChanged>([](auto, auto) {
|
||||
EventManager::post<EventHighlightingChanged>();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,18 +4,267 @@
|
||||
#include <implot.h>
|
||||
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/helpers/project_file_handler.hpp>
|
||||
#include <hex/helpers/file.hpp>
|
||||
#include <hex/helpers/crypto.hpp>
|
||||
|
||||
#include <thread>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
static bool g_demoWindowOpen = false;
|
||||
|
||||
void registerMainMenuEntries() {
|
||||
|
||||
static void createFileMenu() {
|
||||
ContentRegistry::Interface::registerMainMenuItem("hex.builtin.menu.file", 1000);
|
||||
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1050, [&] {
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.open_file"_lang, "CTRL + O")) {
|
||||
|
||||
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
|
||||
EventManager::post<RequestOpenFile>(path);
|
||||
});
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("hex.builtin.menu.file.open_other"_lang)) {
|
||||
|
||||
for (const auto &unlocalizedProviderName : ContentRegistry::Provider::getEntries()) {
|
||||
if (ImGui::MenuItem(LangEntry(unlocalizedProviderName))) {
|
||||
EventManager::post<RequestCreateProvider>(unlocalizedProviderName, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
});
|
||||
|
||||
/* File open, quit imhex */
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1150, [&] {
|
||||
bool providerValid = ImHexApi::Provider::isValid();
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.close"_lang, "", false, providerValid)) {
|
||||
EventManager::post<EventFileUnloaded>();
|
||||
ImHexApi::Provider::remove(ImHexApi::Provider::get());
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.quit"_lang, "", false)) {
|
||||
ImHexApi::Common::closeImHex();
|
||||
}
|
||||
});
|
||||
|
||||
/* Project open / save */
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1250, [&] {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
bool providerValid = ImHexApi::Provider::isValid();
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.open_project"_lang, "")) {
|
||||
fs::openFileBrowser(fs::DialogMode::Open, { {"Project File", "hexproj"}
|
||||
},
|
||||
[](const auto &path) {
|
||||
ProjectFile::load(path);
|
||||
});
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.save_project"_lang, "", false, providerValid && provider->isWritable())) {
|
||||
if (ProjectFile::getProjectFilePath() == "") {
|
||||
fs::openFileBrowser(fs::DialogMode::Save, { {"Project File", "hexproj"}
|
||||
},
|
||||
[](std::fs::path path) {
|
||||
if (path.extension() != ".hexproj") {
|
||||
path.replace_extension(".hexproj");
|
||||
}
|
||||
|
||||
ProjectFile::store(path);
|
||||
});
|
||||
} else
|
||||
ProjectFile::store();
|
||||
}
|
||||
});
|
||||
|
||||
/* Import / Export */
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1300, [&] {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
bool providerValid = ImHexApi::Provider::isValid();
|
||||
|
||||
/* Import */
|
||||
if (ImGui::BeginMenu("hex.builtin.menu.file.import"_lang)) {
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.import.base64"_lang)) {
|
||||
|
||||
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
|
||||
fs::File inputFile(path, fs::File::Mode::Read);
|
||||
if (!inputFile.isValid()) {
|
||||
View::showErrorPopup("hex.builtin.menu.file.import.base64.popup.open_error"_lang);
|
||||
return;
|
||||
}
|
||||
|
||||
auto base64 = inputFile.readBytes();
|
||||
|
||||
if (!base64.empty()) {
|
||||
auto data = crypt::decode64(base64);
|
||||
|
||||
if (data.empty())
|
||||
View::showErrorPopup("hex.builtin.menu.file.import.base64.popup.import_error"_lang);
|
||||
else {
|
||||
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const std::fs::path &path) {
|
||||
fs::File outputFile(path, fs::File::Mode::Create);
|
||||
|
||||
if (!outputFile.isValid())
|
||||
View::showErrorPopup("hex.builtin.menu.file.import.base64.popup.import_error"_lang);
|
||||
|
||||
outputFile.write(data);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
View::showErrorPopup("hex.builtin.popup.file_open_error"_lang);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.import.ips"_lang, nullptr, false)) {
|
||||
|
||||
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
|
||||
std::thread([path] {
|
||||
auto task = ImHexApi::Tasks::createTask("hex.common.processing", 0);
|
||||
|
||||
auto patchData = fs::File(path, fs::File::Mode::Read).readBytes();
|
||||
auto patch = hex::loadIPSPatch(patchData);
|
||||
|
||||
task.setMaxValue(patch.size());
|
||||
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
|
||||
u64 progress = 0;
|
||||
for (auto &[address, value] : patch) {
|
||||
provider->addPatch(address, &value, 1);
|
||||
progress++;
|
||||
task.update(progress);
|
||||
}
|
||||
|
||||
provider->createUndoPoint();
|
||||
}).detach();
|
||||
});
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.import.ips32"_lang, nullptr, false)) {
|
||||
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
|
||||
std::thread([path] {
|
||||
auto task = ImHexApi::Tasks::createTask("hex.common.processing", 0);
|
||||
|
||||
auto patchData = fs::File(path, fs::File::Mode::Read).readBytes();
|
||||
auto patch = hex::loadIPS32Patch(patchData);
|
||||
|
||||
task.setMaxValue(patch.size());
|
||||
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
|
||||
u64 progress = 0;
|
||||
for (auto &[address, value] : patch) {
|
||||
provider->addPatch(address, &value, 1);
|
||||
progress++;
|
||||
task.update(progress);
|
||||
}
|
||||
|
||||
provider->createUndoPoint();
|
||||
}).detach();
|
||||
});
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
|
||||
/* Export */
|
||||
if (ImGui::BeginMenu("hex.builtin.menu.file.export"_lang, providerValid && provider->isWritable())) {
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.export.ips"_lang, nullptr, false)) {
|
||||
Patches patches = provider->getPatches();
|
||||
if (!patches.contains(0x00454F45) && patches.contains(0x00454F46)) {
|
||||
u8 value = 0;
|
||||
provider->read(0x00454F45, &value, sizeof(u8));
|
||||
patches[0x00454F45] = value;
|
||||
}
|
||||
|
||||
std::thread([patches] {
|
||||
auto task = ImHexApi::Tasks::createTask("hex.common.processing", 0);
|
||||
|
||||
auto data = generateIPSPatch(patches);
|
||||
|
||||
ImHexApi::Tasks::doLater([data] {
|
||||
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) {
|
||||
auto file = fs::File(path, fs::File::Mode::Create);
|
||||
if (!file.isValid()) {
|
||||
View::showErrorPopup("hex.builtin.menu.file.export.base64.popup.export_error"_lang);
|
||||
return;
|
||||
}
|
||||
|
||||
file.write(data);
|
||||
});
|
||||
});
|
||||
}).detach();
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.export.ips32"_lang, nullptr, false)) {
|
||||
Patches patches = provider->getPatches();
|
||||
if (!patches.contains(0x00454F45) && patches.contains(0x45454F46)) {
|
||||
u8 value = 0;
|
||||
provider->read(0x45454F45, &value, sizeof(u8));
|
||||
patches[0x45454F45] = value;
|
||||
}
|
||||
|
||||
std::thread([patches] {
|
||||
auto task = ImHexApi::Tasks::createTask("hex.common.processing", 0);
|
||||
|
||||
auto data = generateIPS32Patch(patches);
|
||||
|
||||
ImHexApi::Tasks::doLater([data] {
|
||||
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) {
|
||||
auto file = fs::File(path, fs::File::Mode::Create);
|
||||
if (!file.isValid()) {
|
||||
View::showErrorPopup("hex.builtin.menu.file.export.popup.create"_lang);
|
||||
return;
|
||||
}
|
||||
|
||||
file.write(data);
|
||||
});
|
||||
});
|
||||
}).detach();
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void createEditMenu() {
|
||||
ContentRegistry::Interface::registerMainMenuItem("hex.builtin.menu.edit", 2000);
|
||||
|
||||
/* Provider Undo / Redo */
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.edit", 1000, [&] {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
bool providerValid = ImHexApi::Provider::isValid();
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.edit.undo"_lang, "CTRL + Z", false, providerValid && provider->canUndo()))
|
||||
provider->undo();
|
||||
if (ImGui::MenuItem("hex.builtin.menu.edit.redo"_lang, "CTRL + Y", false, providerValid && provider->canRedo()))
|
||||
provider->redo();
|
||||
});
|
||||
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.edit", 1050, [&] {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
bool providerValid = ImHexApi::Provider::isValid();
|
||||
auto selection = ImHexApi::HexEditor::getSelection();
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.edit.bookmark"_lang, nullptr, false, selection.has_value() && providerValid)) {
|
||||
auto base = provider->getBaseAddress();
|
||||
|
||||
ImHexApi::Bookmarks::add(base + selection->getStartAddress(), selection->getEndAddress(), {}, {});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
static void createViewMenu() {
|
||||
ContentRegistry::Interface::registerMainMenuItem("hex.builtin.menu.view", 3000);
|
||||
ContentRegistry::Interface::registerMainMenuItem("hex.builtin.menu.layout", 4000);
|
||||
ContentRegistry::Interface::registerMainMenuItem("hex.builtin.menu.help", 5000);
|
||||
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.view", 1000, [] {
|
||||
for (auto &[name, view] : ContentRegistry::Views::getEntries()) {
|
||||
@@ -24,11 +273,15 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
});
|
||||
|
||||
#if defined(DEBUG)
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.view", 2000, [] {
|
||||
ImGui::MenuItem("hex.builtin.menu.view.demo"_lang, "", &g_demoWindowOpen);
|
||||
});
|
||||
#endif
|
||||
#if defined(DEBUG)
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.view", 2000, [] {
|
||||
ImGui::MenuItem("hex.builtin.menu.view.demo"_lang, "", &g_demoWindowOpen);
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
static void createLayoutMenu() {
|
||||
ContentRegistry::Interface::registerMainMenuItem("hex.builtin.menu.layout", 4000);
|
||||
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.layout", 1000, [] {
|
||||
for (auto &[layoutName, func] : ContentRegistry::Interface::getLayouts()) {
|
||||
@@ -46,7 +299,20 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void createHelpMenu() {
|
||||
ContentRegistry::Interface::registerMainMenuItem("hex.builtin.menu.help", 5000);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void registerMainMenuEntries() {
|
||||
createFileMenu();
|
||||
createEditMenu();
|
||||
createViewMenu();
|
||||
createLayoutMenu();
|
||||
createHelpMenu();
|
||||
|
||||
(void)EventManager::subscribe<EventFrameEnd>([] {
|
||||
if (g_demoWindowOpen) {
|
||||
|
||||
@@ -148,18 +148,32 @@ namespace hex::plugin::builtin {
|
||||
return false;
|
||||
});
|
||||
|
||||
ContentRegistry::Settings::add("hex.builtin.setting.interface", "hex.builtin.setting.interface.highlight_alpha", 0x80, [](auto name, nlohmann::json &setting) {
|
||||
static int alpha = static_cast<int>(setting);
|
||||
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.highlight_color", 0x60C08080, [](auto name, nlohmann::json &setting) {
|
||||
static auto color = static_cast<color_t>(setting);
|
||||
|
||||
std::array<float, 4> colorArray = {
|
||||
((color >> 0) & 0x000000FF) / float(0xFF),
|
||||
((color >> 8) & 0x000000FF) / float(0xFF),
|
||||
((color >> 16) & 0x000000FF) / float(0xFF),
|
||||
((color >> 24) & 0x000000FF) / float(0xFF)
|
||||
};
|
||||
|
||||
if (ImGui::ColorEdit4(name.data(), colorArray.data(), ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_AlphaPreviewHalf | ImGuiColorEditFlags_NoDragDrop | ImGuiColorEditFlags_NoInputs)) {
|
||||
color =
|
||||
(color_t(colorArray[0] * 0xFF) << 0) |
|
||||
(color_t(colorArray[1] * 0xFF) << 8) |
|
||||
(color_t(colorArray[2] * 0xFF) << 16) |
|
||||
(color_t(colorArray[3] * 0xFF) << 24);
|
||||
|
||||
setting = color;
|
||||
|
||||
if (ImGui::SliderInt(name.data(), &alpha, 0x00, 0xFF)) {
|
||||
setting = alpha;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.column_count", 16, [](auto name, nlohmann::json &setting) {
|
||||
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.bytes_per_row", 16, [](auto name, nlohmann::json &setting) {
|
||||
static int columns = static_cast<int>(setting);
|
||||
|
||||
if (ImGui::SliderInt(name.data(), &columns, 1, 32)) {
|
||||
@@ -170,17 +184,6 @@ namespace hex::plugin::builtin {
|
||||
return false;
|
||||
});
|
||||
|
||||
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.hexii", 0, [](auto name, nlohmann::json &setting) {
|
||||
static bool hexii = static_cast<int>(setting);
|
||||
|
||||
if (ImGui::Checkbox(name.data(), &hexii)) {
|
||||
setting = static_cast<int>(hexii);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.ascii", 1, [](auto name, nlohmann::json &setting) {
|
||||
static bool ascii = static_cast<int>(setting);
|
||||
|
||||
@@ -225,18 +228,30 @@ namespace hex::plugin::builtin {
|
||||
return false;
|
||||
});
|
||||
|
||||
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.extra_info", 1, [](auto name, nlohmann::json &setting) {
|
||||
static bool extraInfos = static_cast<int>(setting);
|
||||
ContentRegistry::Settings::add("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.visualizer", "hex.builtin.visualizer.hexadecimal.8bit", [](auto name, nlohmann::json &setting) {
|
||||
auto &visualizers = ContentRegistry::HexEditor::impl::getVisualizers();
|
||||
|
||||
if (ImGui::Checkbox(name.data(), &extraInfos)) {
|
||||
setting = static_cast<int>(extraInfos);
|
||||
return true;
|
||||
auto selectedVisualizer = setting;
|
||||
|
||||
bool result = false;
|
||||
if (ImGui::BeginCombo(name.data(), LangEntry(selectedVisualizer))) {
|
||||
|
||||
for (const auto &[unlocalizedName, visualizer] : visualizers) {
|
||||
if (ImGui::Selectable(LangEntry(unlocalizedName))) {
|
||||
setting = unlocalizedName;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
return false;
|
||||
return result;
|
||||
});
|
||||
|
||||
|
||||
/* Fonts */
|
||||
|
||||
static std::string fontPath;
|
||||
ContentRegistry::Settings::add(
|
||||
"hex.builtin.setting.font", "hex.builtin.setting.font.font_path", "", [](auto name, nlohmann::json &setting) {
|
||||
@@ -282,6 +297,8 @@ namespace hex::plugin::builtin {
|
||||
true);
|
||||
|
||||
|
||||
/* Folders */
|
||||
|
||||
static const std::string dirsSetting { "hex.builtin.setting.folders" };
|
||||
|
||||
ContentRegistry::Settings::addCategoryDescription(dirsSetting, "hex.builtin.setting.folders.description");
|
||||
|
||||
@@ -134,8 +134,8 @@ namespace hex::plugin::builtin {
|
||||
static std::string mathInput;
|
||||
bool evaluate = false;
|
||||
|
||||
static MathEvaluator mathEvaluator = [&] {
|
||||
MathEvaluator evaluator;
|
||||
static MathEvaluator<long double> mathEvaluator = [&] {
|
||||
MathEvaluator<long double> evaluator;
|
||||
|
||||
evaluator.registerStandardVariables();
|
||||
evaluator.registerStandardFunctions();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
@@ -15,6 +16,28 @@
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
static void drawGlobalPopups() {
|
||||
|
||||
// "Are you sure you want to exit?" Popup
|
||||
if (ImGui::BeginPopupModal("hex.builtin.popup.exit_application.title"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::NewLine();
|
||||
ImGui::TextUnformatted("hex.builtin.popup.exit_application.desc"_lang);
|
||||
ImGui::NewLine();
|
||||
|
||||
View::confirmButtons(
|
||||
"hex.builtin.common.yes"_lang, "hex.builtin.common.no"_lang, [] { ImHexApi::Common::closeImHex(true); }, [] { ImGui::CloseCurrentPopup(); });
|
||||
|
||||
if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape)))
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void addGlobalUIItems() {
|
||||
EventManager::subscribe<EventFrameEnd>(drawGlobalPopups);
|
||||
}
|
||||
|
||||
void addFooterItems() {
|
||||
|
||||
if (hex::isProcessElevated()) {
|
||||
@@ -68,19 +91,20 @@ namespace hex::plugin::builtin {
|
||||
bool providerValid = provider != nullptr;
|
||||
|
||||
// Undo
|
||||
ImGui::Disabled([&provider] {
|
||||
ImGui::BeginDisabled(!providerValid || !provider->canUndo());
|
||||
{
|
||||
if (ImGui::ToolBarButton(ICON_VS_DISCARD, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarBlue)))
|
||||
provider->undo();
|
||||
},
|
||||
!providerValid || !provider->canUndo());
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
// Redo
|
||||
ImGui::Disabled([&provider] {
|
||||
ImGui::BeginDisabled(!providerValid || !provider->canRedo());
|
||||
{
|
||||
if (ImGui::ToolBarButton(ICON_VS_REDO, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarBlue)))
|
||||
provider->redo();
|
||||
},
|
||||
!providerValid || !provider->canRedo());
|
||||
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||
|
||||
@@ -96,42 +120,45 @@ namespace hex::plugin::builtin {
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||
|
||||
// Save file
|
||||
ImGui::Disabled([&provider] {
|
||||
ImGui::BeginDisabled(!providerValid || !provider->isWritable() || !provider->isSavable());
|
||||
{
|
||||
if (ImGui::ToolBarButton(ICON_VS_SAVE, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarBlue)))
|
||||
provider->save();
|
||||
},
|
||||
!providerValid || !provider->isWritable() || !provider->isSavable());
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
// Save file as
|
||||
ImGui::Disabled([&provider] {
|
||||
ImGui::BeginDisabled(!providerValid || !provider->isSavable());
|
||||
{
|
||||
if (ImGui::ToolBarButton(ICON_VS_SAVE_AS, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarBlue)))
|
||||
fs::openFileBrowser(fs::DialogMode::Save, {}, [&provider](auto path) {
|
||||
provider->saveAs(path);
|
||||
});
|
||||
},
|
||||
!providerValid || !provider->isSavable());
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||
|
||||
|
||||
// Create bookmark
|
||||
ImGui::Disabled([] {
|
||||
ImGui::BeginDisabled(!providerValid || !provider->isReadable() || !ImHexApi::HexEditor::isSelectionValid());
|
||||
{
|
||||
if (ImGui::ToolBarButton(ICON_VS_BOOKMARK, ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen))) {
|
||||
Region region = { };
|
||||
EventManager::post<QuerySelection>(region);
|
||||
auto region = ImHexApi::HexEditor::getSelection();
|
||||
|
||||
ImHexApi::Bookmarks::add(region.address, region.size, {}, {});
|
||||
if (region.has_value())
|
||||
ImHexApi::Bookmarks::add(region->address, region->size, {}, {});
|
||||
}
|
||||
},
|
||||
!providerValid || !provider->isReadable() || ImHexApi::HexEditor::getSelection().size == 0);
|
||||
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||
ImGui::Spacing();
|
||||
|
||||
// Provider switcher
|
||||
ImGui::Disabled([] {
|
||||
ImGui::BeginDisabled(!providerValid);
|
||||
{
|
||||
auto &providers = ImHexApi::Provider::getProviders();
|
||||
|
||||
std::string preview;
|
||||
@@ -149,9 +176,10 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
},
|
||||
!providerValid);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,9 +23,8 @@ namespace hex::plugin::builtin {
|
||||
name,
|
||||
std::move(comment),
|
||||
color,
|
||||
false,
|
||||
|
||||
ImHexApi::HexEditor::addHighlight(region, color, name) });
|
||||
false
|
||||
});
|
||||
|
||||
ProjectFile::markDirty();
|
||||
});
|
||||
@@ -41,6 +40,75 @@ namespace hex::plugin::builtin {
|
||||
EventManager::subscribe<EventFileUnloaded>(this, [this] {
|
||||
this->m_bookmarks.clear();
|
||||
});
|
||||
|
||||
|
||||
ImHexApi::HexEditor::addBackgroundHighlightingProvider([this](u64 address, const u8* data, size_t size) -> std::optional<color_t> {
|
||||
hex::unused(data);
|
||||
|
||||
for (const auto &bookmark : this->m_bookmarks) {
|
||||
if (Region { address, size }.isWithin(bookmark.region))
|
||||
return bookmark.color;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
});
|
||||
|
||||
ImHexApi::HexEditor::addTooltipProvider([this](u64 address, const u8 *data, size_t size) {
|
||||
hex::unused(data);
|
||||
for (const auto &bookmark : this->m_bookmarks) {
|
||||
if (!Region { address, size }.isWithin(bookmark.region))
|
||||
continue;
|
||||
|
||||
ImGui::BeginTooltip();
|
||||
|
||||
if (ImGui::BeginTable("##tooltips", 1, ImGuiTableFlags_RowBg | ImGuiTableFlags_NoClip)) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::PushID(&bookmark);
|
||||
{
|
||||
ImGui::ColorButton("##color", ImColor(bookmark.color));
|
||||
ImGui::SameLine(0, 10);
|
||||
ImGui::TextUnformatted(bookmark.name.c_str());
|
||||
|
||||
if (ImGui::GetIO().KeyShift) {
|
||||
ImGui::Indent();
|
||||
if (ImGui::BeginTable("##extra_info", 2, ImGuiTableFlags_RowBg | ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_NoClip)) {
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("Region: ");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("[ 0x{:08X} - 0x{:08X} ]", bookmark.region.getStartAddress(), bookmark.region.getEndAddress());
|
||||
|
||||
if (!bookmark.comment.empty() && bookmark.comment[0] != '\x00') {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("Comment: ");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormattedWrapped("\"{}\"", bookmark.comment);
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::Unindent();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_TableRowBg, bookmark.color);
|
||||
ImGui::PushStyleColor(ImGuiCol_TableRowBgAlt, bookmark.color);
|
||||
ImGui::EndTable();
|
||||
ImGui::PopStyleColor(2);
|
||||
}
|
||||
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ViewBookmarks::~ViewBookmarks() {
|
||||
@@ -63,7 +131,7 @@ namespace hex::plugin::builtin {
|
||||
u32 id = 1;
|
||||
auto bookmarkToRemove = this->m_bookmarks.end();
|
||||
for (auto iter = this->m_bookmarks.begin(); iter != this->m_bookmarks.end(); iter++) {
|
||||
auto &[region, name, comment, color, locked, highlight] = *iter;
|
||||
auto &[region, name, comment, color, locked] = *iter;
|
||||
|
||||
auto headerColor = ImColor(color);
|
||||
auto hoverColor = ImColor(color);
|
||||
@@ -169,7 +237,6 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
if (bookmarkToRemove != this->m_bookmarks.end()) {
|
||||
ImHexApi::HexEditor::removeHighlight(bookmarkToRemove->highlightId);
|
||||
this->m_bookmarks.erase(bookmarkToRemove);
|
||||
ProjectFile::markDirty();
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
EventManager::subscribe<EventSettingsChanged>(this, [this] {
|
||||
{
|
||||
auto columnCount = ContentRegistry::Settings::getSetting("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.column_count");
|
||||
auto columnCount = ContentRegistry::Settings::getSetting("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.bytes_per_row");
|
||||
|
||||
if (columnCount.is_number())
|
||||
this->m_columnCount = static_cast<int>(columnCount);
|
||||
|
||||
@@ -322,11 +322,12 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::Disabled([this] {
|
||||
ImGui::BeginDisabled(this->m_disassembling);
|
||||
{
|
||||
if (ImGui::Button("hex.builtin.view.disassembler.disassemble"_lang))
|
||||
this->disassemble();
|
||||
},
|
||||
this->m_disassembling);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (this->m_disassembling) {
|
||||
ImGui::SameLine();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -135,11 +135,12 @@ namespace hex::plugin::builtin {
|
||||
ImGui::TextUnformatted("hex.builtin.view.information.control"_lang);
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Disabled([this] {
|
||||
ImGui::BeginDisabled(this->m_analyzing);
|
||||
{
|
||||
if (ImGui::Button("hex.builtin.view.information.analyze"_lang))
|
||||
this->analyze();
|
||||
},
|
||||
this->m_analyzing);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (this->m_analyzing) {
|
||||
ImGui::TextSpinner("hex.builtin.view.information.analyzing"_lang);
|
||||
|
||||
@@ -231,17 +231,44 @@ namespace hex::plugin::builtin {
|
||||
});
|
||||
|
||||
|
||||
ImHexApi::HexEditor::addHighlightingProvider([](u64 address) -> std::optional<ImHexApi::HexEditor::Highlighting> {
|
||||
ImHexApi::HexEditor::addBackgroundHighlightingProvider([](u64 address, const u8 *data, size_t size) -> std::optional<color_t> {
|
||||
hex::unused(data, size);
|
||||
|
||||
const auto &patterns = ImHexApi::Provider::get()->getPatternLanguageRuntime().getPatterns();
|
||||
for (const auto &pattern : patterns) {
|
||||
auto child = pattern->getPattern(address);
|
||||
if (child != nullptr) {
|
||||
return ImHexApi::HexEditor::Highlighting(Region { address, 1 }, child->getColor(), child->getDisplayName());
|
||||
return child->getColor();
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
});
|
||||
|
||||
ImHexApi::HexEditor::addTooltipProvider([this](u64 address, const u8 *data, size_t size) {
|
||||
hex::unused(data, size);
|
||||
|
||||
auto &patterns = ImHexApi::Provider::get()->getPatternLanguageRuntime().getPatterns();
|
||||
for (auto &pattern : patterns) {
|
||||
auto child = pattern->getPattern(address);
|
||||
if (child != nullptr) {
|
||||
ImGui::BeginTooltip();
|
||||
|
||||
if (ImGui::BeginTable("##tooltips", 1, ImGuiTableFlags_RowBg | ImGuiTableFlags_NoClip)) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
this->drawPatternTooltip(child);
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_TableRowBg, pattern->getColor());
|
||||
ImGui::PushStyleColor(ImGuiCol_TableRowBgAlt, pattern->getColor());
|
||||
ImGui::EndTable();
|
||||
ImGui::PopStyleColor(2);
|
||||
}
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ViewPatternEditor::~ViewPatternEditor() {
|
||||
@@ -608,6 +635,68 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
|
||||
void ViewPatternEditor::drawPatternTooltip(pl::Pattern *pattern) {
|
||||
ImGui::PushID(pattern);
|
||||
{
|
||||
ImGui::ColorButton(pattern->getVariableName().c_str(), ImColor(pattern->getColor()));
|
||||
ImGui::SameLine(0, 10);
|
||||
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{}", pattern->getFormattedName());
|
||||
ImGui::SameLine(0, 5);
|
||||
ImGui::TextFormatted("{}", pattern->getDisplayName());
|
||||
ImGui::SameLine();
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||
ImGui::SameLine();
|
||||
ImGui::TextFormatted("{}", pattern->getFormattedValue());
|
||||
|
||||
if (ImGui::GetIO().KeyShift) {
|
||||
ImGui::Indent();
|
||||
if (ImGui::BeginTable("##extra_info", 2, ImGuiTableFlags_RowBg | ImGuiTableFlags_NoClip)) {
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("Type: ");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}", pattern->getTypeName());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("Address: ");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("0x{:08X}", pattern->getOffset());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("Size: ");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{} {}", pattern->getSize(), pattern->getSize() > 1 ? "Bytes" : "Byte");
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("Endian: ");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}", pattern->getEndian() == std::endian::little ? "Little" : "Big");
|
||||
|
||||
if (auto comment = pattern->getComment(); comment.has_value()) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("Comment: ");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextWrapped("\"%s\"", pattern->getComment()->c_str());
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::Unindent();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
|
||||
void ViewPatternEditor::loadPatternFile(const std::fs::path &path) {
|
||||
fs::File file(path, fs::File::Mode::Read);
|
||||
if (file.isValid()) {
|
||||
|
||||
@@ -105,7 +105,8 @@ namespace hex::plugin::builtin {
|
||||
|
||||
if (ImGui::Begin(View::toWindowName("hex.builtin.view.strings.name").c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
|
||||
if (ImHexApi::Provider::isValid() && provider->isReadable()) {
|
||||
ImGui::Disabled([this] {
|
||||
ImGui::BeginDisabled(this->m_searching);
|
||||
{
|
||||
if (ImGui::InputInt("hex.builtin.view.strings.min_length"_lang, &this->m_minimumLength, 1, 0))
|
||||
this->m_foundStrings.clear();
|
||||
|
||||
@@ -158,8 +159,8 @@ namespace hex::plugin::builtin {
|
||||
|
||||
if (ImGui::Button("hex.builtin.view.strings.extract"_lang))
|
||||
this->searchStrings();
|
||||
},
|
||||
this->m_searching);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (this->m_searching) {
|
||||
ImGui::SameLine();
|
||||
|
||||
@@ -44,7 +44,8 @@ namespace hex::plugin::builtin {
|
||||
|
||||
if (ImGui::Button("hex.builtin.view.yara.reload"_lang)) this->reloadRules();
|
||||
} else {
|
||||
ImGui::Disabled([this] {
|
||||
ImGui::BeginDisabled(this->m_matching);
|
||||
{
|
||||
if (ImGui::BeginCombo("hex.builtin.view.yara.header.rules"_lang, this->m_rules[this->m_selectedRule].first.c_str())) {
|
||||
for (u32 i = 0; i < this->m_rules.size(); i++) {
|
||||
const bool selected = (this->m_selectedRule == i);
|
||||
@@ -59,8 +60,8 @@ namespace hex::plugin::builtin {
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("hex.builtin.view.yara.reload"_lang)) this->reloadRules();
|
||||
if (ImGui::Button("hex.builtin.view.yara.match"_lang)) this->applyRules();
|
||||
},
|
||||
this->m_matching);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (this->m_matching) {
|
||||
ImGui::SameLine();
|
||||
@@ -91,7 +92,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
while (clipper.Step()) {
|
||||
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
|
||||
auto &[identifier, variableName, address, size, wholeDataMatch, highlightId] = this->m_matches[i];
|
||||
auto &[identifier, variableName, address, size, wholeDataMatch, highlightId, tooltipId] = this->m_matches[i];
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushID(i);
|
||||
@@ -142,8 +143,10 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void ViewYara::clearResult() {
|
||||
for (const auto &match : this->m_matches)
|
||||
ImHexApi::HexEditor::removeHighlight(match.highlightId);
|
||||
for (const auto &match : this->m_matches) {
|
||||
ImHexApi::HexEditor::removeBackgroundHighlight(match.highlightId);
|
||||
ImHexApi::HexEditor::removeTooltip(match.tooltipId);
|
||||
}
|
||||
|
||||
this->m_matches.clear();
|
||||
this->m_consoleMessages.clear();
|
||||
@@ -310,11 +313,11 @@ namespace hex::plugin::builtin {
|
||||
if (rule->strings != nullptr) {
|
||||
yr_rule_strings_foreach(rule, string) {
|
||||
yr_string_matches_foreach(context, string, match) {
|
||||
results.newMatches.push_back({ rule->identifier, string->identifier, u64(match->offset), size_t(match->match_length), false, 0 });
|
||||
results.newMatches.push_back({ rule->identifier, string->identifier, u64(match->offset), size_t(match->match_length), false, 0, 0 });
|
||||
}
|
||||
}
|
||||
} else {
|
||||
results.newMatches.push_back({ rule->identifier, "", 0, 0, true, 0 });
|
||||
results.newMatches.push_back({ rule->identifier, "", 0, 0, true, 0, 0 });
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -337,8 +340,10 @@ namespace hex::plugin::builtin {
|
||||
this->m_matches = resultContext.newMatches;
|
||||
this->m_consoleMessages = resultContext.consoleMessages;
|
||||
|
||||
constexpr static color_t YaraColor = 0x70B4771F;
|
||||
for (auto &match : this->m_matches) {
|
||||
match.highlightId = ImHexApi::HexEditor::addHighlight({ match.address, match.size }, 0x70B4771F, hex::format("{0} [{1}]", match.identifier, match.variable));
|
||||
match.highlightId = ImHexApi::HexEditor::addBackgroundHighlight({ match.address, match.size }, YaraColor);
|
||||
match.tooltipId = ImHexApi::HexEditor::addTooltip({ match. address, match.size }, hex::format("{0} [{1}]", match.identifier, match.variable), YaraColor);
|
||||
}
|
||||
});
|
||||
}).detach();
|
||||
|
||||
@@ -417,15 +417,8 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
});
|
||||
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1050, [&] {
|
||||
if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.file.open_file"_lang, "CTRL + O")) {
|
||||
|
||||
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
|
||||
EventManager::post<RequestOpenFile>(path);
|
||||
});
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("hex.builtin.view.hex_editor.menu.file.open_recent"_lang, !s_recentFilePaths.empty())) {
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1075, [&] {
|
||||
if (ImGui::BeginMenu("hex.builtin.menu.file.open_recent"_lang, !s_recentFilePaths.empty())) {
|
||||
// Copy to avoid changing list while iteration
|
||||
std::list<std::fs::path> recentFilePaths = s_recentFilePaths;
|
||||
for (auto &path : recentFilePaths) {
|
||||
@@ -436,7 +429,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.file.clear_recent"_lang)) {
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.clear_recent"_lang)) {
|
||||
s_recentFilePaths.clear();
|
||||
ContentRegistry::Settings::write(
|
||||
"hex.builtin.setting.imhex",
|
||||
@@ -446,17 +439,6 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("hex.builtin.view.hex_editor.menu.file.open_other"_lang)) {
|
||||
|
||||
for (const auto &unlocalizedProviderName : ContentRegistry::Provider::getEntries()) {
|
||||
if (ImGui::MenuItem(LangEntry(unlocalizedProviderName))) {
|
||||
EventManager::post<RequestCreateProvider>(unlocalizedProviderName, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -80,12 +80,40 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.common.open", "Öffnen" },
|
||||
{ "hex.builtin.common.browse", "Druchsuchen..." },
|
||||
{ "hex.builtin.common.choose_file", "Datei auswählen" },
|
||||
{ "hex.builtin.common.processing", "Verarbeiten" },
|
||||
|
||||
{ "hex.builtin.message.file_handler_failed", "Datei konnte nicht mit registriertem Dateihandler geöffnet werden." },
|
||||
|
||||
{ "hex.builtin.popup.exit_application.title", "Applikation verlassen?" },
|
||||
{ "hex.builtin.popup.exit_application.desc", "Es wurden ungespeicherte Änderungen an diesem Projekt vorgenommen\nBist du sicher, dass du ImHex schliessen willst?" },
|
||||
{ "hex.builtin.popup.error.read_only", "Schreibzugriff konnte nicht erlangt werden. Datei wurde im Lesemodus geöffnet." },
|
||||
{ "hex.builtin.popup.error.open", "Öffnen der Datei fehlgeschlagen!" },
|
||||
{ "hex.builtin.popup.error.create", "Erstellen der neuen Datei fehlgeschlagen!" },
|
||||
|
||||
{ "hex.builtin.menu.file", "Datei" },
|
||||
{ "hex.builtin.file.open_file", "Datei öffnen..." },
|
||||
{ "hex.builtin.file.open_recent", "Kürzlich geöffnete Dateien" },
|
||||
{ "hex.builtin.file.clear_recent", "Löschen" },
|
||||
{ "hex.builtin.file.open_other", "Provider öffnen..." },
|
||||
{ "hex.builtin.file.close", "Schliessen" },
|
||||
{ "hex.builtin.file.quit", "ImHex Beenden" },
|
||||
{ "hex.builtin.file.open_project", "Projekt öffnen..." },
|
||||
{ "hex.builtin.file.save_project", "Projekt speichern..." },
|
||||
{ "hex.builtin.menu.file.import", "Importieren..." },
|
||||
{ "hex.builtin.menu.file.import.base64", "Base64 Datei" },
|
||||
{ "hex.builtin.menu.file.import.base64.popup.import_error", "Datei ist nicht in einem korrekten Base64 Format!" },
|
||||
{ "hex.builtin.menu.file.import.base64.popup.open_error", "Öffnen der Datei fehlgeschlagen!" },
|
||||
{ "hex.builtin.menu.file.import.ips", "IPS Patch" },
|
||||
{ "hex.builtin.menu.file.import.ips32", "IPS32 Patch" },
|
||||
{ "hex.builtin.menu.file.export", "Exportieren..." },
|
||||
{ "hex.builtin.menu.file.export.title", "Datei exportieren" },
|
||||
{ "hex.builtin.menu.file.export.ips", "IPS Patch" },
|
||||
{ "hex.builtin.menu.file.export.ips32", "IPS32 Patch" },
|
||||
{ "hex.builtin.menu.file.export.base64.popup.export_error", "File is not in a valid Base64 format!" },
|
||||
|
||||
{ "hex.builtin.menu.edit", "Bearbeiten" },
|
||||
{ "hex.builtin.menu.edit.undo", "Rückgängig" },
|
||||
{ "hex.builtin.menu.edit.redo", "Wiederholen" },
|
||||
{ "hex.builtin.menu.edit.bookmark", "Lesezeichen erstellen" },
|
||||
|
||||
{ "hex.builtin.menu.view", "Ansicht" },
|
||||
{ "hex.builtin.menu.layout", "Layout" },
|
||||
{ "hex.builtin.menu.view.fps", "FPS anzeigen" },
|
||||
@@ -207,48 +235,14 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.help.calc_cheat_sheet", "Rechner Cheat Sheet" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.name", "Hex editor" },
|
||||
{ "hex.builtin.view.hex_editor.create_file", "Neu" },
|
||||
{ "hex.builtin.view.hex_editor.open_file", "Öffnen" },
|
||||
{ "hex.builtin.view.hex_editor.open_project", "Projekt öffnen" },
|
||||
{ "hex.builtin.view.hex_editor.save_project", "Projekt speichern" },
|
||||
{ "hex.builtin.view.hex_editor.save_data", "Daten speichern" },
|
||||
{ "hex.builtin.view.hex_editor.open_base64", "Base64 Datei öffnen" },
|
||||
{ "hex.builtin.view.hex_editor.load_enconding_file", "Custom encoding Datei laden" },
|
||||
{ "hex.builtin.view.hex_editor.page", "Seite {0} / {1}" },
|
||||
{ "hex.builtin.view.hex_editor.save_as", "Speichern unter" },
|
||||
{ "hex.builtin.view.hex_editor.exit_application.title", "Applikation verlassen?" },
|
||||
{ "hex.builtin.view.hex_editor.exit_application.desc", "Es wurden ungespeicherte Änderungen an diesem Projekt vorgenommen\nBist du sicher, dass du ImHex schliessen willst?" },
|
||||
{ "hex.builtin.view.hex_editor.script.title", "Datei mit Loader Skript laden" },
|
||||
{ "hex.builtin.view.hex_editor.script.desc", "Lade eine Datei mit Hilfe eines Python Skriptes" },
|
||||
{ "hex.builtin.view.hex_editor.script.script", "Skript" },
|
||||
{ "hex.builtin.view.hex_editor.script.script.title", "Loader Script: Skript öffnen" },
|
||||
{ "hex.builtin.view.hex_editor.script.file", "Datei" },
|
||||
{ "hex.builtin.view.hex_editor.script.file.title", "Loader Script: Datei öffnen" },
|
||||
{ "hex.builtin.view.hex_editor.processing", "Importieren / Exportieren" },
|
||||
{ "hex.builtin.view.hex_editor.page", "Seite" },
|
||||
{ "hex.builtin.view.hex_editor.selection", "Auswahl" },
|
||||
{ "hex.builtin.view.hex_editor.selection.none", "Keine" },
|
||||
{ "hex.builtin.view.hex_editor.region", "Region" },
|
||||
{ "hex.builtin.view.hex_editor.data_size", "Datengrösse" },
|
||||
{ "hex.builtin.view.hex_editor.no_bytes", "Keine bytes verfügbar" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_file", "Datei öffnen..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_recent", "Kürzlich geöffnete Dateien" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.clear_recent", "Löschen" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_other", "Provider öffnen..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save", "Speichern" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_as", "Speichern unter..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.close", "Schliessen" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.quit", "ImHex Beenden" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_project", "Projekt öffnen..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_project", "Projekt speichern..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.load_encoding_file", "Custom encoding laden..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import", "Importieren..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.base64", "Base64 Datei" },
|
||||
{ "hex.builtin.view.hex_editor.base64.import_error", "Datei ist nicht in einem korrekten Base64 Format!" },
|
||||
{ "hex.builtin.view.hex_editor.file_open_error", "Öffnen der Datei fehlgeschlagen!" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.ips", "IPS Patch" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.ips32", "IPS32 Patch" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.script", "Datei mit Loader Script" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export", "Exportieren..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.title", "Datei exportieren" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.ips", "IPS Patch" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.ips32", "IPS32 Patch" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.search", "Suchen" },
|
||||
{ "hex.builtin.view.hex_editor.search.string", "String" },
|
||||
{ "hex.builtin.view.hex_editor.search.hex", "Hex" },
|
||||
@@ -260,11 +254,8 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.current", "Momentan" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.begin", "Beginn" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.end", "Ende" },
|
||||
{ "hex.builtin.view.hex_editor.error.read_only", "Schreibzugriff konnte nicht erlangt werden. Datei wurde im Lesemodus geöffnet." },
|
||||
{ "hex.builtin.view.hex_editor.error.open", "Öffnen der Datei fehlgeschlagen!" },
|
||||
{ "hex.builtin.view.hex_editor.error.create", "Erstellen der neuen Datei fehlgeschlagen!" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.undo", "Rückgängig" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.redo", "Wiederholen" },
|
||||
{ "hex.builtin.view.hex_editor.file.save", "Speichern" },
|
||||
{ "hex.builtin.view.hex_editor.file.save_as", "Speichern unter..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy", "Kopieren" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "Kopieren als..." },
|
||||
{ "hex.builtin.view.hex_editor.copy.hex", "String" },
|
||||
@@ -279,7 +270,6 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.paste", "Einfügen" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "Alles auswählen" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.bookmark", "Lesezeichen erstellen" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.set_base", "Basisadresse setzen" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.resize", "Grösse ändern..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.insert", "Einsetzen..." },
|
||||
@@ -666,22 +656,21 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.setting.interface.scaling.x1_5", "x1.5" },
|
||||
{ "hex.builtin.setting.interface.scaling.x2_0", "x2.0" },
|
||||
{ "hex.builtin.setting.interface.language", "Sprache" },
|
||||
//{ "hex.builtin.setting.interface.wiki_explain_language", "Wikipedia Language" },
|
||||
{ "hex.builtin.setting.interface.wiki_explain_language", "Wikipedia Sprache" },
|
||||
{ "hex.builtin.setting.interface.fps", "FPS Limite" },
|
||||
{ "hex.builtin.setting.interface.fps.unlocked", "Unbegrenzt" },
|
||||
{ "hex.builtin.setting.interface.highlight_alpha", "Markierungssichtbarkeit" },
|
||||
{ "hex.builtin.setting.hex_editor", "Hex Editor" },
|
||||
{ "hex.builtin.setting.hex_editor.column_count", "Anzahl Byte Spalten" },
|
||||
{ "hex.builtin.setting.hex_editor.hexii", "HexII anstatt Bytes anzeigen" },
|
||||
{ "hex.builtin.setting.hex_editor.highlight_color", "Auswahlfarbe" },
|
||||
{ "hex.builtin.setting.hex_editor.bytes_per_row", "Bytes pro Zeile" },
|
||||
{ "hex.builtin.setting.hex_editor.ascii", "ASCII Spalte anzeigen" },
|
||||
{ "hex.builtin.setting.hex_editor.advanced_decoding", "Erweiterte Dekodierungsspalte anzeigen" },
|
||||
{ "hex.builtin.setting.hex_editor.grey_zeros", "Nullen ausgrauen" },
|
||||
{ "hex.builtin.setting.hex_editor.uppercase_hex", "Hex Zeichen als Grossbuchstaben" },
|
||||
{ "hex.builtin.setting.hex_editor.extra_info", "Extra informationen anzeigen" },
|
||||
{ "hex.builtin.setting.hex_editor.visualizer", "Data visualizer" },
|
||||
{ "hex.builtin.setting.folders", "Ordner" },
|
||||
{ "hex.builtin.setting.folders.description", "Gib zusätzliche Orderpfade an in welchen Pattern, Scripts, Yara Rules und anderes gesucht wird" },
|
||||
// { "hex.builtin.setting.folders.add_folder", "Add new folder" },
|
||||
// { "hex.builtin.setting.folders.remove_folder", "Remove currently selected folder from list" },
|
||||
{ "hex.builtin.setting.folders.add_folder", "Neuer Ordner hinzufügen" },
|
||||
{ "hex.builtin.setting.folders.remove_folder", "Ausgewählter Ordner von Liste entfernen" },
|
||||
{ "hex.builtin.setting.font", "Schriftart" },
|
||||
{ "hex.builtin.setting.font.font_path", "Eigene Schriftart" },
|
||||
{ "hex.builtin.setting.font.font_size", "Schriftgrösse" },
|
||||
@@ -704,7 +693,24 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.provider.disk.sector_size", "Sektorgrösse" },
|
||||
{ "hex.builtin.provider.disk.reload", "Neu laden" },
|
||||
|
||||
{ "hex.builtin.layouts.default", "Standard" }
|
||||
{ "hex.builtin.layouts.default", "Standard" },
|
||||
|
||||
{ "hex.builtin.visualizer.hexadecimal.8bit", "Hexadezimal (8 bits)" },
|
||||
{ "hex.builtin.visualizer.hexadecimal.16bit", "Hexadezimal (16 bits)" },
|
||||
{ "hex.builtin.visualizer.hexadecimal.32bit", "Hexadezimal (32 bits)" },
|
||||
{ "hex.builtin.visualizer.hexadecimal.64bit", "Hexadezimal (64 bits)" },
|
||||
{ "hex.builtin.visualizer.decimal.signed.8bit", "Dezimal Signed (8 bits)" },
|
||||
{ "hex.builtin.visualizer.decimal.signed.16bit", "Dezimal Signed (16 bits)" },
|
||||
{ "hex.builtin.visualizer.decimal.signed.32bit", "Dezimal Signed (32 bits)" },
|
||||
{ "hex.builtin.visualizer.decimal.signed.64bit", "Dezimal Signed (64 bits)" },
|
||||
{ "hex.builtin.visualizer.decimal.unsigned.8bit", "Dezimal Unsigned (8 bits)" },
|
||||
{ "hex.builtin.visualizer.decimal.unsigned.16bit", "Dezimal Unsigned (16 bits)" },
|
||||
{ "hex.builtin.visualizer.decimal.unsigned.32bit", "Dezimal Unsigned (32 bits)" },
|
||||
{ "hex.builtin.visualizer.decimal.unsigned.64bit", "Dezimal Unsigned (64 bits)" },
|
||||
{ "hex.builtin.visualizer.floating_point.32bit", "Floating Point (32 bits)" },
|
||||
{ "hex.builtin.visualizer.floating_point.64bit", "Floating Point (64 bits)" },
|
||||
{ "hex.builtin.visualizer.hexii", "HexII" },
|
||||
{ "hex.builtin.visualizer.rgba8", "RGBA8 Farbe" },
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -81,11 +81,41 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.common.open", "Open" },
|
||||
{ "hex.builtin.common.browse", "Browse..." },
|
||||
{ "hex.builtin.common.choose_file", "Choose file" },
|
||||
{ "hex.common.processing", "Processing" },
|
||||
|
||||
{ "hex.builtin.message.file_handler_failed", "Failed to open file with registered file handler." },
|
||||
{ "hex.builtin.popup.exit_application.title", "Exit Application?" },
|
||||
{ "hex.builtin.popup.exit_application.desc", "You have unsaved changes made to your Project.\nAre you sure you want to exit?" },
|
||||
{ "hex.builtin.popup.error.read_only", "Couldn't get write access. File opened in read-only mode." },
|
||||
{ "hex.builtin.popup.error.open", "Failed to open file!" },
|
||||
{ "hex.builtin.popup.error.create", "Failed to create new file!" },
|
||||
|
||||
{ "hex.builtin.menu.file", "File" },
|
||||
{ "hex.builtin.menu.file.open_file", "Open File..." },
|
||||
{ "hex.builtin.menu.file.open_recent", "Open Recent" },
|
||||
{ "hex.builtin.menu.file.clear_recent", "Clear" },
|
||||
{ "hex.builtin.menu.file.open_other", "Open Other..." },
|
||||
{ "hex.builtin.menu.file.close", "Close" },
|
||||
{ "hex.builtin.menu.file.quit", "Quit ImHex" },
|
||||
{ "hex.builtin.menu.file.open_project", "Open Project..." },
|
||||
{ "hex.builtin.menu.file.save_project", "Save Project..." },
|
||||
{ "hex.builtin.menu.file.import", "Import..." },
|
||||
{ "hex.builtin.menu.file.import.base64", "Base64 File" },
|
||||
{ "hex.builtin.menu.file.import.base64.popup.import_error", "File is not in a valid Base64 format!" },
|
||||
{ "hex.builtin.menu.file.import.base64.popup.open_error", "Failed to open file!" },
|
||||
{ "hex.builtin.menu.file.import.ips", "IPS Patch" },
|
||||
{ "hex.builtin.menu.file.import.ips32", "IPS32 Patch" },
|
||||
{ "hex.builtin.menu.file.export", "Export..." },
|
||||
{ "hex.builtin.menu.file.export.title", "Export File" },
|
||||
{ "hex.builtin.menu.file.export.ips", "IPS Patch" },
|
||||
{ "hex.builtin.menu.file.export.ips32", "IPS32 Patch" },
|
||||
{ "hex.builtin.menu.file.export.base64.popup.export_error", "File is not in a valid Base64 format!" },
|
||||
{ "hex.builtin.menu.file.export.popup.create", "Cannot export data. Failed to create file!" },
|
||||
|
||||
{ "hex.builtin.menu.edit", "Edit" },
|
||||
{ "hex.builtin.menu.edit.undo", "Undo" },
|
||||
{ "hex.builtin.menu.edit.redo", "Redo" },
|
||||
{ "hex.builtin.menu.edit.bookmark", "Create bookmark" },
|
||||
|
||||
{ "hex.builtin.menu.view", "View" },
|
||||
{ "hex.builtin.menu.layout", "Layout" },
|
||||
{ "hex.builtin.menu.view.fps", "Display FPS" },
|
||||
@@ -211,64 +241,25 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.help.calc_cheat_sheet", "Calculator Cheat Sheet" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.name", "Hex editor" },
|
||||
{ "hex.builtin.view.hex_editor.create_file", "New" },
|
||||
{ "hex.builtin.view.hex_editor.open_file", "Open" },
|
||||
{ "hex.builtin.view.hex_editor.open_project", "Open Project" },
|
||||
{ "hex.builtin.view.hex_editor.save_project", "Save Project" },
|
||||
{ "hex.builtin.view.hex_editor.save_data", "Save Data" },
|
||||
{ "hex.builtin.view.hex_editor.open_base64", "Open Base64 File" },
|
||||
{ "hex.builtin.view.hex_editor.load_enconding_file", "Load custom encoding File" },
|
||||
{ "hex.builtin.view.hex_editor.page", "Page {0} / {1}" },
|
||||
{ "hex.builtin.view.hex_editor.save_as", "Save As" },
|
||||
{ "hex.builtin.view.hex_editor.exit_application.title", "Exit Application?" },
|
||||
{ "hex.builtin.view.hex_editor.exit_application.desc", "You have unsaved changes made to your Project.\nAre you sure you want to exit?" },
|
||||
{ "hex.builtin.view.hex_editor.script.title", "Load File with Loader Script" },
|
||||
{ "hex.builtin.view.hex_editor.script.desc", "Load a file using a Python loader script." },
|
||||
{ "hex.builtin.view.hex_editor.script.script", "Script" },
|
||||
{ "hex.builtin.view.hex_editor.script.script.title", "Loader Script: Open Script" },
|
||||
{ "hex.builtin.view.hex_editor.script.file", "File" },
|
||||
{ "hex.builtin.view.hex_editor.script.file.title", "Loader Script: Open File" },
|
||||
{ "hex.builtin.view.hex_editor.processing", "Importing / Exporting" },
|
||||
{ "hex.builtin.view.hex_editor.page", "Page" },
|
||||
{ "hex.builtin.view.hex_editor.selection", "Selection" },
|
||||
{ "hex.builtin.view.hex_editor.selection.none", "None" },
|
||||
{ "hex.builtin.view.hex_editor.region", "Region" },
|
||||
{ "hex.builtin.view.hex_editor.data_size", "Data Size" },
|
||||
{ "hex.builtin.view.hex_editor.no_bytes", "No bytes available" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_file", "Open File..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_recent", "Open Recent" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.clear_recent", "Clear" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_other", "Open Other..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save", "Save" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_as", "Save As..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.close", "Close" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.quit", "Quit ImHex" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_project", "Open Project..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_project", "Save Project..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.load_encoding_file", "Load custom encoding..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import", "Import..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.base64", "Base64 File" },
|
||||
{ "hex.builtin.view.hex_editor.base64.import_error", "File is not in a valid Base64 format!" },
|
||||
{ "hex.builtin.view.hex_editor.file_open_error", "Failed to open file!" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.ips", "IPS Patch" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.ips32", "IPS32 Patch" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.script", "File with Loader Script" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export", "Export..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.title", "Export File" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.ips", "IPS Patch" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.ips32", "IPS32 Patch" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.search", "Search" },
|
||||
{ "hex.builtin.view.hex_editor.search.string", "String" },
|
||||
{ "hex.builtin.view.hex_editor.search.hex", "Hex" },
|
||||
{ "hex.builtin.view.hex_editor.search.find", "Find" },
|
||||
{ "hex.builtin.view.hex_editor.search.find_next", "Find next" },
|
||||
{ "hex.builtin.view.hex_editor.search.find_prev", "Find previous" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.goto", "Goto" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.absolute", "Absolute" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.current", "Current" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.relative", "Relative" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.begin", "Begin" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.end", "End" },
|
||||
{ "hex.builtin.view.hex_editor.error.read_only", "Couldn't get write access. File opened in read-only mode." },
|
||||
{ "hex.builtin.view.hex_editor.error.open", "Failed to open file!" },
|
||||
{ "hex.builtin.view.hex_editor.error.create", "Failed to create new file!" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.undo", "Undo" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.redo", "Redo" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save", "Save" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_as", "Save As..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy", "Copy" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "Copy as..." },
|
||||
{ "hex.builtin.view.hex_editor.copy.hex", "String" },
|
||||
@@ -283,7 +274,6 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.paste", "Paste" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "Select all" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.bookmark", "Create bookmark" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.set_base", "Set base address" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.resize", "Resize..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.insert", "Insert..." },
|
||||
@@ -673,15 +663,14 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.setting.interface.wiki_explain_language", "Wikipedia Language" },
|
||||
{ "hex.builtin.setting.interface.fps", "FPS Limit" },
|
||||
{ "hex.builtin.setting.interface.fps.unlocked", "Unlocked" },
|
||||
{ "hex.builtin.setting.interface.highlight_alpha", "Highlighting opacity" },
|
||||
{ "hex.builtin.setting.hex_editor", "Hex Editor" },
|
||||
{ "hex.builtin.setting.hex_editor.column_count", "Byte column count" },
|
||||
{ "hex.builtin.setting.hex_editor.hexii", "Display HexII instead of Bytes" },
|
||||
{ "hex.builtin.setting.hex_editor.highlight_color", "Selection highlight color" },
|
||||
{ "hex.builtin.setting.hex_editor.bytes_per_row", "Bytes per row" },
|
||||
{ "hex.builtin.setting.hex_editor.ascii", "Display ASCII column" },
|
||||
{ "hex.builtin.setting.hex_editor.advanced_decoding", "Display advanced decoding column" },
|
||||
{ "hex.builtin.setting.hex_editor.grey_zeros", "Grey out zeros" },
|
||||
{ "hex.builtin.setting.hex_editor.uppercase_hex", "Upper case Hex characters" },
|
||||
{ "hex.builtin.setting.hex_editor.extra_info", "Display extra information" },
|
||||
{ "hex.builtin.setting.hex_editor.visualizer", "Data visualizer" },
|
||||
{ "hex.builtin.setting.folders", "Folders" },
|
||||
{ "hex.builtin.setting.folders.description", "Specify additional search paths for patterns, scripts, Yara rules and more" },
|
||||
{ "hex.builtin.setting.folders.add_folder", "Add new folder" },
|
||||
@@ -708,7 +697,24 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.provider.disk.sector_size", "Sector Size" },
|
||||
{ "hex.builtin.provider.disk.reload", "Reload" },
|
||||
|
||||
{ "hex.builtin.layouts.default", "Default" }
|
||||
{ "hex.builtin.layouts.default", "Default" },
|
||||
|
||||
{ "hex.builtin.visualizer.hexadecimal.8bit", "Hexadecimal (8 bits)" },
|
||||
{ "hex.builtin.visualizer.hexadecimal.16bit", "Hexadecimal (16 bits)" },
|
||||
{ "hex.builtin.visualizer.hexadecimal.32bit", "Hexadecimal (32 bits)" },
|
||||
{ "hex.builtin.visualizer.hexadecimal.64bit", "Hexadecimal (64 bits)" },
|
||||
{ "hex.builtin.visualizer.decimal.signed.8bit", "Decimal Signed (8 bits)" },
|
||||
{ "hex.builtin.visualizer.decimal.signed.16bit", "Decimal Signed (16 bits)" },
|
||||
{ "hex.builtin.visualizer.decimal.signed.32bit", "Decimal Signed (32 bits)" },
|
||||
{ "hex.builtin.visualizer.decimal.signed.64bit", "Decimal Signed (64 bits)" },
|
||||
{ "hex.builtin.visualizer.decimal.unsigned.8bit", "Decimal Unsigned (8 bits)" },
|
||||
{ "hex.builtin.visualizer.decimal.unsigned.16bit", "Decimal Unsigned (16 bits)" },
|
||||
{ "hex.builtin.visualizer.decimal.unsigned.32bit", "Decimal Unsigned (32 bits)" },
|
||||
{ "hex.builtin.visualizer.decimal.unsigned.64bit", "Decimal Unsigned (64 bits)" },
|
||||
{ "hex.builtin.visualizer.floating_point.32bit", "Floating Point (32 bits)" },
|
||||
{ "hex.builtin.visualizer.floating_point.64bit", "Floating Point (64 bits)" },
|
||||
{ "hex.builtin.visualizer.hexii", "HexII" },
|
||||
{ "hex.builtin.visualizer.rgba8", "RGBA8 Color" },
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -80,11 +80,42 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.common.open", "Apri" },
|
||||
{ "hex.builtin.common.browse", "Esplora..." },
|
||||
{ "hex.builtin.common.choose_file", "Scegli file" },
|
||||
//{ "hex.common.processing", "Processing" },
|
||||
|
||||
{ "hex.builtin.message.file_handler_failed", "Impossibile aprire il file con il gestore di file registrato." },
|
||||
{ "hex.builtin.popup.exit_application.title", "Uscire dall'applicazione?" },
|
||||
{ "hex.builtin.popup.exit_application.desc", "Hai delle modifiche non salvate nel tuo progetto.\nSei sicuro di voler uscire?" },
|
||||
{ "hex.builtin.popup.error.read_only", "Impossibile scrivere sul File. File aperto solo in modalità lettura" },
|
||||
{ "hex.builtin.popup.error.open", "Impossibile aprire il File!" },
|
||||
{ "hex.builtin.popup.error.create", "Impossibile creare il nuovo File!" },
|
||||
|
||||
{ "hex.builtin.menu.file", "File" },
|
||||
{ "hex.builtin.menu.file.open_file", "Apri File..." },
|
||||
{ "hex.builtin.menu.file.open_recent", "File recenti" },
|
||||
{ "hex.builtin.menu.file.clear_recent", "Pulisci" },
|
||||
{ "hex.builtin.menu.file.open_other", "Apri altro..." },
|
||||
{ "hex.builtin.menu.file.close", "Chiudi" },
|
||||
{ "hex.builtin.menu.file.quit", "Uscita ImHex" },
|
||||
{ "hex.builtin.menu.file.open_project", "Apri un Progetto..." },
|
||||
{ "hex.builtin.menu.file.save_project", "Salva Progetto..." },
|
||||
{ "hex.builtin.menu.file.import", "Importa..." },
|
||||
{ "hex.builtin.menu.file.import.base64", "Base64 File" },
|
||||
//{ "hex.builtin.menu.file.import.base64.popup.import_error", "File is not in a valid Base64 format!" },
|
||||
//{ "hex.builtin.menu.file.import.base64.popup.open_error", "Failed to open file!" },
|
||||
{ "hex.builtin.file_open_error", "Impossibile aprire il File!" },
|
||||
{ "hex.builtin.menu.file.import.ips", "IPS Patch" },
|
||||
{ "hex.builtin.menu.file.import.ips32", "IPS32 Patch" },
|
||||
{ "hex.builtin.menu.file.export", "Esporta..." },
|
||||
{ "hex.builtin.menu.file.export.title", "Esporta File" },
|
||||
{ "hex.builtin.menu.file.export.ips", "IPS Patch" },
|
||||
{ "hex.builtin.menu.file.export.ips32", "IPS32 Patch" },
|
||||
//{ "hex.builtin.menu.file.export.base64.popup.export_error", "File is not in a valid Base64 format!" },
|
||||
//{ "hex.builtin.menu.file.export.popup.create", "Cannot export data. Failed to create file!" },
|
||||
|
||||
{ "hex.builtin.menu.edit", "Modifica" },
|
||||
{ "hex.builtin.menu.edit.undo", "Annulla" },
|
||||
{ "hex.builtin.menu.edit.redo", "Ripeti" },
|
||||
{ "hex.builtin.menu.edit.bookmark", "Crea segnalibro" },
|
||||
|
||||
{ "hex.builtin.menu.view", "Vista" },
|
||||
{ "hex.builtin.menu.layout", "Layout" },
|
||||
{ "hex.builtin.menu.view.fps", "Mostra FPS" },
|
||||
@@ -206,48 +237,15 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.help.calc_cheat_sheet", "Calcolatrice Cheat Sheet" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.name", "Hex editor" },
|
||||
{ "hex.builtin.view.hex_editor.create_file", "Nuovo" },
|
||||
{ "hex.builtin.view.hex_editor.open_file", "Apri" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_recent", "File recenti" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.clear_recent", "Pulisci" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_other", "Apri altro..." },
|
||||
{ "hex.builtin.view.hex_editor.open_project", "Apri i Progetti" },
|
||||
{ "hex.builtin.view.hex_editor.save_project", "Salva i Progetti" },
|
||||
{ "hex.builtin.view.hex_editor.save_data", "Salva i Dati" },
|
||||
{ "hex.builtin.view.hex_editor.open_base64", "Apri Base64 File" },
|
||||
{ "hex.builtin.view.hex_editor.load_enconding_file", "Carica un File di codfica personalizzato" },
|
||||
{ "hex.builtin.view.hex_editor.page", "Pagina {0} / {1}" },
|
||||
{ "hex.builtin.view.hex_editor.save_as", "Salva come" },
|
||||
{ "hex.builtin.view.hex_editor.exit_application.title", "Uscire dall'applicazione?" },
|
||||
{ "hex.builtin.view.hex_editor.exit_application.desc", "Hai delle modifiche non salvate nel tuo progetto.\nSei sicuro di voler uscire?" },
|
||||
{ "hex.builtin.view.hex_editor.script.title", "Carica un File tramite il Caricatore di Script" },
|
||||
{ "hex.builtin.view.hex_editor.script.desc", "Carica un file tramite il Caricatore di Script di Python." },
|
||||
{ "hex.builtin.view.hex_editor.script.script", "Script" },
|
||||
{ "hex.builtin.view.hex_editor.script.script.title", "Caricatore Script: Apri Script" },
|
||||
{ "hex.builtin.view.hex_editor.script.file", "File" },
|
||||
{ "hex.builtin.view.hex_editor.script.file.title", "Caricatore Script: Apri File" },
|
||||
{ "hex.builtin.view.hex_editor.processing", "Importa / Esporta" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_file", "Apri File..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save", "Salva" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_as", "Salva come..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.close", "Chiudi" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.quit", "Uscita ImHex" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_project", "Apri un Progetto..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_project", "Salva Progetto..." },
|
||||
//{ "hex.builtin.view.hex_editor.page", "Page" },
|
||||
//{ "hex.builtin.view.hex_editor.selection", "Selection" },
|
||||
//{ "hex.builtin.view.hex_editor.selection.none", "None" },
|
||||
//{ "hex.builtin.view.hex_editor.region", "Region" },
|
||||
//{ "hex.builtin.view.hex_editor.data_size", "Data Size" },
|
||||
//{ "hex.builtin.view.hex_editor.no_bytes", "No bytes available" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.menu.file.load_encoding_file", "Carica una codifica personalizzata..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import", "Importa..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.base64", "Base64 File" },
|
||||
{ "hex.builtin.view.hex_editor.base64.import_error", "Il file non è in un formato bas64 corretto!" },
|
||||
{ "hex.builtin.view.hex_editor.file_open_error", "Impossibile aprire il File!" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.ips", "IPS Patch" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.ips32", "IPS32 Patch" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.script", "File con il Caricatore di Script" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export", "Esporta..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.title", "Esporta File" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.ips", "IPS Patch" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.ips32", "IPS32 Patch" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.search", "Cerca" },
|
||||
{ "hex.builtin.view.hex_editor.search.string", "Stringa" },
|
||||
{ "hex.builtin.view.hex_editor.search.hex", "Hex" },
|
||||
@@ -256,14 +254,11 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.search.find_prev", "Cerca il precedente" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.goto", "Vai a" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.absolute", "Assoluto" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.current", "Corrente" },
|
||||
//{ "hex.builtin.view.hex_editor.goto.offset.current", "Relative" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.begin", "Inizo" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.end", "Fine" },
|
||||
{ "hex.builtin.view.hex_editor.error.read_only", "Impossibile scrivere sul File. File aperto solo in modalità lettura" },
|
||||
{ "hex.builtin.view.hex_editor.error.open", "Impossibile aprire il File!" },
|
||||
{ "hex.builtin.view.hex_editor.error.create", "Impossibile creare il nuovo File!" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.undo", "Annulla" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.redo", "Ripeti" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save", "Salva" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_as", "Salva come..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy", "Copia" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "Copia come..." },
|
||||
{ "hex.builtin.view.hex_editor.copy.hex", "Stringa" },
|
||||
@@ -278,7 +273,6 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.paste", "Incolla" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "Seleziona tutti" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.bookmark", "Crea segnalibro" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.set_base", "Imposta indirizzo di base" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.resize", "Ridimensiona..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.insert", "Inserisci..." },
|
||||
@@ -671,15 +665,14 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.setting.interface.scaling.x2_0", "x2.0" },
|
||||
{ "hex.builtin.setting.interface.fps", "Limite FPS" },
|
||||
{ "hex.builtin.setting.interface.fps.unlocked", "Unblocca" },
|
||||
{ "hex.builtin.setting.interface.highlight_alpha", "Evidenziazione dell'opacità" },
|
||||
{ "hex.builtin.setting.hex_editor", "Hex Editor" },
|
||||
{ "hex.builtin.setting.hex_editor.column_count", "Conteggio della colonna dei byte" },
|
||||
{ "hex.builtin.setting.hex_editor.hexii", "Mostra HexII invece dei byte" },
|
||||
//{ "hex.builtin.setting.hex_editor.highlight_color", "Selection highlight color" },
|
||||
//{ "hex.builtin.setting.hex_editor.bytes_per_row", "Bytes per row" },
|
||||
{ "hex.builtin.setting.hex_editor.ascii", "Mostra la colonna ASCII" },
|
||||
{ "hex.builtin.setting.hex_editor.advanced_decoding", "Mostra la colonna di decodifica avanzata" },
|
||||
{ "hex.builtin.setting.hex_editor.grey_zeros", "Taglia fuori gli zeri" },
|
||||
{ "hex.builtin.setting.hex_editor.uppercase_hex", "Caratteri esadecimali maiuscoli" },
|
||||
{ "hex.builtin.setting.hex_editor.extra_info", "Mostra informazioni extra" },
|
||||
//{ "hex.builtin.setting.hex_editor.visualizer", "Data visualizer" },
|
||||
//{ "hex.builtin.setting.folders", "Folders" },
|
||||
//{ "hex.builtin.setting.folders.description", "Specify additional search paths for patterns, scripts, rules and more" },
|
||||
// { "hex.builtin.setting.folders.add_folder", "Add new folder" },
|
||||
@@ -706,7 +699,24 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.provider.disk.sector_size", "Dimensione settore" },
|
||||
{ "hex.builtin.provider.disk.reload", "Ricarica" },
|
||||
|
||||
{ "hex.builtin.layouts.default", "Default" }
|
||||
{ "hex.builtin.layouts.default", "Default" },
|
||||
|
||||
//{ "hex.builtin.visualizer.hexadecimal.8bit", "Hexadecimal (8 bits)" },
|
||||
//{ "hex.builtin.visualizer.hexadecimal.16bit", "Hexadecimal (16 bits)" },
|
||||
//{ "hex.builtin.visualizer.hexadecimal.32bit", "Hexadecimal (32 bits)" },
|
||||
//{ "hex.builtin.visualizer.hexadecimal.64bit", "Hexadecimal (64 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.signed.8bit", "Decimal Signed (8 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.signed.16bit", "Decimal Signed (16 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.signed.32bit", "Decimal Signed (32 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.signed.64bit", "Decimal Signed (64 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.unsigned.8bit", "Decimal Unsigned (8 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.unsigned.16bit", "Decimal Unsigned (16 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.unsigned.32bit", "Decimal Unsigned (32 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.unsigned.64bit", "Decimal Unsigned (64 bits)" },
|
||||
//{ "hex.builtin.visualizer.floating_point.32bit", "Floating Point (32 bits)" },
|
||||
//{ "hex.builtin.visualizer.floating_point.64bit", "Floating Point (64 bits)" },
|
||||
//{ "hex.builtin.visualizer.hexii", "HexII" },
|
||||
//{ "hex.builtin.visualizer.rgba8", "RGBA8 Color" },
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -80,11 +80,42 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.common.open", "開く" },
|
||||
{ "hex.builtin.common.browse", "ファイルを参照..." },
|
||||
{ "hex.builtin.common.choose_file", "ファイルを選択" },
|
||||
// { "hex.common.processing", "Processing" },
|
||||
|
||||
{ "hex.builtin.message.file_handler_failed", "登録されたファイルハンドラでファイルを開くのに失敗しました。" },
|
||||
{ "hex.builtin.popup.exit_application.title", "アプリケーションを終了しますか?" },
|
||||
{ "hex.builtin.popup.exit_application.desc", "プロジェクトに保存されていない変更があります。\n終了してもよろしいですか?" },
|
||||
{ "hex.builtin.popup.error.read_only", "書き込み権限を取得できませんでした。ファイルが読み取り専用で開かれました。" },
|
||||
{ "hex.builtin.popup.error.open", "ファイルを開けませんでした!" },
|
||||
{ "hex.builtin.popup.error.create", "新しいファイルを作成できませんでした!" },
|
||||
|
||||
{ "hex.builtin.menu.file", "ファイル" },
|
||||
{ "hex.builtin.menu.file.open_file", "ファイルを開く..." },
|
||||
{ "hex.builtin.menu.file.open_recent", "最近使用したファイルを開く" },
|
||||
{ "hex.builtin.menu.file.clear_recent", "消去" },
|
||||
{ "hex.builtin.menu.file.open_other", "その他の開くオプション..." },
|
||||
{ "hex.builtin.menu.file.close", "ファイルを閉じる" },
|
||||
{ "hex.builtin.menu.file.quit", "ImHexを終了" },
|
||||
{ "hex.builtin.menu.file.open_project", "プロジェクトを開く..." },
|
||||
{ "hex.builtin.menu.file.save_project", "プロジェクトを保存..." },
|
||||
{ "hex.builtin.menu.file.load_encoding_file", "カスタムエンコードを読み込み..." },
|
||||
{ "hex.builtin.menu.file.import", "インポート..." },
|
||||
{ "hex.builtin.menu.file.import.base64", "Base64ファイル" },
|
||||
{ "hex.builtin.menu.file.import.base64.popup.import_error", "ファイルが有効なBase64形式ではありません!" },
|
||||
{ "hex.builtin.menu.file.import.base64.popup.open_error", "ファイルを開けませんでした!" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.ips", "IPSパッチ" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.ips32", "IPS32パッチ" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export", "エクスポート..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.title", "ファイルをエクスポート" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.ips", "IPSパッチ" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.ips32", "IPS32パッチ" },
|
||||
{ "hex.builtin.menu.file.import.base64.popup.export_error", "ファイルが有効なBase64形式ではありません!" },
|
||||
//{ "hex.builtin.menu.file.export.popup.create", "Cannot export data. Failed to create file!" },
|
||||
|
||||
{ "hex.builtin.menu.edit", "編集" },
|
||||
{ "hex.builtin.menu.edit.undo", "もとに戻す" },
|
||||
{ "hex.builtin.menu.edit.redo", "やり直す" },
|
||||
{ "hex.builtin.menu.edit.bookmark", "ブックマークを作成" },
|
||||
|
||||
{ "hex.builtin.menu.view", "表示" },
|
||||
{ "hex.builtin.menu.layout", "レイアウト" },
|
||||
{ "hex.builtin.menu.view.fps", "FPSを表示" },
|
||||
@@ -210,48 +241,13 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.help.calc_cheat_sheet", "計算機チートシート" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.name", "Hexエディタ" },
|
||||
{ "hex.builtin.view.hex_editor.create_file", "新規" },
|
||||
{ "hex.builtin.view.hex_editor.open_file", "開く" },
|
||||
{ "hex.builtin.view.hex_editor.open_project", "プロジェクトを開く" },
|
||||
{ "hex.builtin.view.hex_editor.save_project", "プロジェクトを保存" },
|
||||
{ "hex.builtin.view.hex_editor.save_data", "データを保存" },
|
||||
{ "hex.builtin.view.hex_editor.open_base64", "Base64ファイルを開く" },
|
||||
{ "hex.builtin.view.hex_editor.load_enconding_file", "カスタムエンコードファイルの読み込み" }, //?
|
||||
{ "hex.builtin.view.hex_editor.page", "ページ {0} / {1}" },
|
||||
{ "hex.builtin.view.hex_editor.save_as", "名前をつけて保存" },
|
||||
{ "hex.builtin.view.hex_editor.exit_application.title", "アプリケーションを終了しますか?" },
|
||||
{ "hex.builtin.view.hex_editor.exit_application.desc", "プロジェクトに保存されていない変更があります。\n終了してもよろしいですか?" },
|
||||
{ "hex.builtin.view.hex_editor.script.title", "ローダースクリプトでファイルを読み込む" },
|
||||
{ "hex.builtin.view.hex_editor.script.desc", "Pythonのローダースクリプトを使用してファイルを読み込みます。" },
|
||||
{ "hex.builtin.view.hex_editor.script.script", "スクリプト" },
|
||||
{ "hex.builtin.view.hex_editor.script.script.title", "ローダースクリプト: スクリプトを開く" },
|
||||
{ "hex.builtin.view.hex_editor.script.file", "ファイル" },
|
||||
{ "hex.builtin.view.hex_editor.script.file.title", "ローダースクリプト: ファイルを開く" },
|
||||
{ "hex.builtin.view.hex_editor.processing", "インポート / エクスポート" },
|
||||
//{ "hex.builtin.view.hex_editor.page", "Page" },
|
||||
//{ "hex.builtin.view.hex_editor.selection", "Selection" },
|
||||
//{ "hex.builtin.view.hex_editor.selection.none", "None" },
|
||||
//{ "hex.builtin.view.hex_editor.region", "Region" },
|
||||
//{ "hex.builtin.view.hex_editor.data_size", "Data Size" },
|
||||
//{ "hex.builtin.view.hex_editor.no_bytes", "No bytes available" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_file", "ファイルを開く..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_recent", "最近使用したファイルを開く" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.clear_recent", "消去" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_other", "その他の開くオプション..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save", "保存" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_as", "名前をつけて保存..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.close", "ファイルを閉じる" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.quit", "ImHexを終了" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_project", "プロジェクトを開く..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_project", "プロジェクトを保存..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.load_encoding_file", "カスタムエンコードを読み込み..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import", "インポート..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.base64", "Base64ファイル" },
|
||||
{ "hex.builtin.view.hex_editor.base64.import_error", "ファイルが有効なBase64形式ではありません!" },
|
||||
{ "hex.builtin.view.hex_editor.file_open_error", "ファイルを開けませんでした!" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.ips", "IPSパッチ" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.ips32", "IPS32パッチ" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.script", "ローダースクリプト付きのファイル" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export", "エクスポート..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.title", "ファイルをエクスポート" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.ips", "IPSパッチ" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.ips32", "IPS32パッチ" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.search", "検索" },
|
||||
{ "hex.builtin.view.hex_editor.search.string", "文字列" },
|
||||
{ "hex.builtin.view.hex_editor.search.hex", "16進" },
|
||||
@@ -260,14 +256,11 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.search.find_prev", "前を検索" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.goto", "移動" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.absolute", "絶対値" }, //?
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.current", "現在" }, //?
|
||||
//{ "hex.builtin.view.hex_editor.goto.offset.relative", "Relative" }, //?
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.begin", "開始" }, //?
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.end", "終了" }, //?
|
||||
{ "hex.builtin.view.hex_editor.error.read_only", "書き込み権限を取得できませんでした。ファイルが読み取り専用で開かれました。" },
|
||||
{ "hex.builtin.view.hex_editor.error.open", "ファイルを開けませんでした!" },
|
||||
{ "hex.builtin.view.hex_editor.error.create", "新しいファイルを作成できませんでした!" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.undo", "もとに戻す" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.redo", "やり直す" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save", "保存" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_as", "名前をつけて保存..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy", "コピー" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "〜としてコピー..." },
|
||||
{ "hex.builtin.view.hex_editor.copy.hex", "文字列" },
|
||||
@@ -671,15 +664,15 @@ namespace hex::plugin::builtin {
|
||||
//{ "hex.builtin.setting.interface.wiki_explain_language", "Wikipedia Language" },
|
||||
{ "hex.builtin.setting.interface.fps", "FPS制限" },
|
||||
{ "hex.builtin.setting.interface.fps.unlocked", "無制限" },
|
||||
{ "hex.builtin.setting.interface.highlight_alpha", "ハイライトの不透明度" },
|
||||
{ "hex.builtin.setting.hex_editor", "Hexエディタ" },
|
||||
{ "hex.builtin.setting.hex_editor.column_count", "バイトのカラム数" },
|
||||
{ "hex.builtin.setting.hex_editor.hexii", "Bytesの代わりにHexIIを表示する" },
|
||||
//{ "hex.builtin.setting.hex_editor.highlight_color", "Selection highlight color" },
|
||||
//{ "hex.builtin.setting.hex_editor.bytes_per_row", "Bytes per row" },
|
||||
{ "hex.builtin.setting.hex_editor.ascii", "ASCIIカラムを表示" },
|
||||
{ "hex.builtin.setting.hex_editor.advanced_decoding", "高度なデコードカラムを表示" },
|
||||
{ "hex.builtin.setting.hex_editor.grey_zeros", "ゼロをグレーアウト" },
|
||||
{ "hex.builtin.setting.hex_editor.uppercase_hex", "16進数を大文字表記" },
|
||||
{ "hex.builtin.setting.hex_editor.extra_info", "追加情報を表示" },
|
||||
//{ "hex.builtin.setting.hex_editor.visualizer", "Data visualizer" },
|
||||
|
||||
//{ "hex.builtin.setting.folders", "Folders" },
|
||||
//{ "hex.builtin.setting.folders.description", "Specify additional search paths for patterns, scripts, rules and more" },
|
||||
// { "hex.builtin.setting.folders.add_folder", "Add new folder" },
|
||||
@@ -706,7 +699,24 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.provider.disk.sector_size", "セクタサイズ" },
|
||||
{ "hex.builtin.provider.disk.reload", "リロード" },
|
||||
|
||||
{ "hex.builtin.layouts.default", "標準" }
|
||||
{ "hex.builtin.layouts.default", "標準" },
|
||||
|
||||
//{ "hex.builtin.visualizer.hexadecimal.8bit", "Hexadecimal (8 bits)" },
|
||||
//{ "hex.builtin.visualizer.hexadecimal.16bit", "Hexadecimal (16 bits)" },
|
||||
//{ "hex.builtin.visualizer.hexadecimal.32bit", "Hexadecimal (32 bits)" },
|
||||
//{ "hex.builtin.visualizer.hexadecimal.64bit", "Hexadecimal (64 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.signed.8bit", "Decimal Signed (8 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.signed.16bit", "Decimal Signed (16 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.signed.32bit", "Decimal Signed (32 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.signed.64bit", "Decimal Signed (64 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.unsigned.8bit", "Decimal Unsigned (8 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.unsigned.16bit", "Decimal Unsigned (16 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.unsigned.32bit", "Decimal Unsigned (32 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.unsigned.64bit", "Decimal Unsigned (64 bits)" },
|
||||
//{ "hex.builtin.visualizer.floating_point.32bit", "Floating Point (32 bits)" },
|
||||
//{ "hex.builtin.visualizer.floating_point.64bit", "Floating Point (64 bits)" },
|
||||
//{ "hex.builtin.visualizer.hexii", "HexII" },
|
||||
//{ "hex.builtin.visualizer.rgba8", "RGBA8 Color" },
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -80,11 +80,41 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.common.open", "打开" },
|
||||
{ "hex.builtin.common.browse", "浏览..." },
|
||||
{ "hex.builtin.common.choose_file", "选择文件" },
|
||||
//{ "hex.common.processing", "Processing" },
|
||||
|
||||
{ "hex.builtin.message.file_handler_failed", "通过注册的文件处理器打开文件失败。" },
|
||||
{ "hex.builtin.popup.exit_application.title", "退出?" },
|
||||
{ "hex.builtin.popup.exit_application.desc", "工程还有为保存的更改。\n确定要退出吗?" },
|
||||
{ "hex.builtin.popup.error.read_only", "无法获得写权限,文件以只读方式打开。" },
|
||||
{ "hex.builtin.popup.error.open", "打开文件失败!" },
|
||||
{ "hex.builtin.popup.error.create", "创建新文件失败!" },
|
||||
|
||||
{ "hex.builtin.menu.file", "文件" },
|
||||
{ "hex.builtin.menu.file.open_file", "打开文件..." },
|
||||
{ "hex.builtin.menu.file.open_recent", "打开最近" },
|
||||
{ "hex.builtin.menu.file.clear_recent", "清除" },
|
||||
{ "hex.builtin.menu.file.open_other", "打开其他..." },
|
||||
{ "hex.builtin.menu.file.close", "关闭" },
|
||||
{ "hex.builtin.menu.file.quit", "退出ImHex" },
|
||||
{ "hex.builtin.menu.file.open_project", "打开项目..." },
|
||||
{ "hex.builtin.menu.file.save_project", "保存项目..." },
|
||||
{ "hex.builtin.menu.file.import", "导入..." },
|
||||
{ "hex.builtin.menu.file.import.base64", "Base64文件" },
|
||||
{ "hex.builtin.menu.file.import.base64.popup.import_error", "文件不是有效的Base64格式!" },
|
||||
{ "hex.builtin.menu.file.import.base64.popup.open_error", "打开文件失败!" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.ips", "IPS补丁" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.ips32", "IPS32补丁" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export", "导出..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.title", "导出文件" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.ips", "IPS补丁" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.ips32", "IPS32补丁" },
|
||||
//{ "hex.builtin.menu.file.export.base64.popup.export_error", "File is not in a valid Base64 format!" },
|
||||
//{ "hex.builtin.menu.file.export.popup.create", "Cannot export data. Failed to create file!" },
|
||||
|
||||
{ "hex.builtin.menu.edit", "编辑" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.undo", "撤销" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.redo", "重做" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.bookmark", "添加书签" },
|
||||
|
||||
{ "hex.builtin.menu.view", "视图" },
|
||||
{ "hex.builtin.menu.layout", "布局" },
|
||||
{ "hex.builtin.menu.view.fps", "显示FPS" },
|
||||
@@ -206,48 +236,14 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.help.calc_cheat_sheet", "计算器帮助" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.name", "Hex编辑器" },
|
||||
{ "hex.builtin.view.hex_editor.create_file", "新建" },
|
||||
{ "hex.builtin.view.hex_editor.open_file", "打开" },
|
||||
{ "hex.builtin.view.hex_editor.open_project", "打开项目" },
|
||||
{ "hex.builtin.view.hex_editor.save_project", "保存项目" },
|
||||
{ "hex.builtin.view.hex_editor.save_data", "保存数据" },
|
||||
{ "hex.builtin.view.hex_editor.open_base64", "打开Base64文件" },
|
||||
{ "hex.builtin.view.hex_editor.load_enconding_file", "加载自定义编码定义文件" },
|
||||
{ "hex.builtin.view.hex_editor.page", "页 {0} / {1}" },
|
||||
{ "hex.builtin.view.hex_editor.save_as", "另存为" },
|
||||
{ "hex.builtin.view.hex_editor.exit_application.title", "退出?" },
|
||||
{ "hex.builtin.view.hex_editor.exit_application.desc", "工程还有为保存的更改。\n确定要退出吗?" },
|
||||
{ "hex.builtin.view.hex_editor.script.title", "通过加载器脚本加载文件" },
|
||||
{ "hex.builtin.view.hex_editor.script.desc", "通过Python加载器脚本加载文件。" },
|
||||
{ "hex.builtin.view.hex_editor.script.script", "脚本" },
|
||||
{ "hex.builtin.view.hex_editor.script.script.title", "加载器脚本:打开脚本" },
|
||||
{ "hex.builtin.view.hex_editor.script.file", "文件" },
|
||||
{ "hex.builtin.view.hex_editor.script.file.title", "加载器脚本:打开文件" },
|
||||
{ "hex.builtin.view.hex_editor.processing", "导入 / 导出" },
|
||||
//{ "hex.builtin.view.hex_editor.page", "Page" },
|
||||
//{ "hex.builtin.view.hex_editor.selection", "Selection" },
|
||||
//{ "hex.builtin.view.hex_editor.selection.none", "None" },
|
||||
//{ "hex.builtin.view.hex_editor.region", "Region" },
|
||||
//{ "hex.builtin.view.hex_editor.data_size", "Data Size" },
|
||||
//{ "hex.builtin.view.hex_editor.no_bytes", "No bytes available" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_file", "打开文件..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_recent", "打开最近" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.clear_recent", "清除" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_other", "打开其他..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save", "保存" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_as", "另存为..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.close", "关闭" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.quit", "退出ImHex" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.open_project", "打开项目..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_project", "保存项目..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.load_encoding_file", "加载自定义编码..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import", "导入..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.base64", "Base64文件" },
|
||||
{ "hex.builtin.view.hex_editor.base64.import_error", "文件不是有效的Base64格式!" },
|
||||
{ "hex.builtin.view.hex_editor.file_open_error", "打开文件失败!" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.ips", "IPS补丁" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.ips32", "IPS32补丁" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.import.script", "带有加载器脚本的文件" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export", "导出..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.title", "导出文件" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.ips", "IPS补丁" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.export.ips32", "IPS32补丁" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.search", "搜索" },
|
||||
{ "hex.builtin.view.hex_editor.search.string", "字符串" },
|
||||
{ "hex.builtin.view.hex_editor.search.hex", "Hex" },
|
||||
@@ -256,14 +252,11 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.search.find_prev", "查找上一个" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.goto", "转到" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.absolute", "绝对" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.current", "当前" },
|
||||
//{ "hex.builtin.view.hex_editor.goto.offset.relative", "Relative" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.begin", "起始" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.end", "末尾" },
|
||||
{ "hex.builtin.view.hex_editor.error.read_only", "无法获得写权限,文件以只读方式打开。" },
|
||||
{ "hex.builtin.view.hex_editor.error.open", "打开文件失败!" },
|
||||
{ "hex.builtin.view.hex_editor.error.create", "创建新文件失败!" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.undo", "撤销" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.redo", "重做" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save", "保存" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_as", "另存为..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy", "复制" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "复制为..." },
|
||||
{ "hex.builtin.view.hex_editor.copy.hex", "字符串" },
|
||||
@@ -278,7 +271,6 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.paste", "粘贴" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "全选" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.bookmark", "添加书签" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.set_base", "设置基地址" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.resize", "修改大小..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.insert", "插入..." },
|
||||
@@ -665,16 +657,14 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.setting.interface.wiki_explain_language", "维基百科语种" },
|
||||
{ "hex.builtin.setting.interface.fps", "FPS限制" },
|
||||
{ "hex.builtin.setting.interface.fps.unlocked", "无限制" },
|
||||
{ "hex.builtin.setting.interface.highlight_alpha", "高亮不透明度" },
|
||||
{ "hex.builtin.setting.hex_editor", "Hex编辑器" },
|
||||
{ "hex.builtin.setting.hex_editor.column_count", "字节列数" },
|
||||
{ "hex.builtin.setting.hex_editor.hexii", "显示HexII替代字节" },
|
||||
//{ "hex.builtin.setting.hex_editor.highlight_color", "Selection highlight color" },
|
||||
//{ "hex.builtin.setting.hex_editor.bytes_per_row", "Bytes per row" },
|
||||
{ "hex.builtin.setting.hex_editor.ascii", "显示ASCII栏" },
|
||||
{ "hex.builtin.setting.hex_editor.advanced_decoding", "显示高级解码栏" },
|
||||
{ "hex.builtin.setting.hex_editor.grey_zeros", "显示零字节为灰色" },
|
||||
{ "hex.builtin.setting.hex_editor.uppercase_hex", "大写Hex字符" },
|
||||
{ "hex.builtin.setting.hex_editor.extra_info", "显示额外信息" },
|
||||
|
||||
//{ "hex.builtin.setting.hex_editor.visualizer", "Data visualizer" },
|
||||
{ "hex.builtin.setting.folders", "扩展搜索路径" },
|
||||
{ "hex.builtin.setting.folders.description", "为模式、脚本和规则等指定额外的搜索路径" },
|
||||
{ "hex.builtin.setting.folders.add_folder", "添加新的目录" },
|
||||
@@ -701,7 +691,24 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.provider.disk.sector_size", "扇区大小" },
|
||||
{ "hex.builtin.provider.disk.reload", "刷新" },
|
||||
|
||||
{ "hex.builtin.layouts.default", "默认" }
|
||||
{ "hex.builtin.layouts.default", "默认" },
|
||||
|
||||
//{ "hex.builtin.visualizer.hexadecimal.8bit", "Hexadecimal (8 bits)" },
|
||||
//{ "hex.builtin.visualizer.hexadecimal.16bit", "Hexadecimal (16 bits)" },
|
||||
//{ "hex.builtin.visualizer.hexadecimal.32bit", "Hexadecimal (32 bits)" },
|
||||
//{ "hex.builtin.visualizer.hexadecimal.64bit", "Hexadecimal (64 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.signed.8bit", "Decimal Signed (8 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.signed.16bit", "Decimal Signed (16 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.signed.32bit", "Decimal Signed (32 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.signed.64bit", "Decimal Signed (64 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.unsigned.8bit", "Decimal Unsigned (8 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.unsigned.16bit", "Decimal Unsigned (16 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.unsigned.32bit", "Decimal Unsigned (32 bits)" },
|
||||
//{ "hex.builtin.visualizer.decimal.unsigned.64bit", "Decimal Unsigned (64 bits)" },
|
||||
//{ "hex.builtin.visualizer.floating_point.32bit", "Floating Point (32 bits)" },
|
||||
//{ "hex.builtin.visualizer.floating_point.64bit", "Floating Point (64 bits)" },
|
||||
//{ "hex.builtin.visualizer.hexii", "HexII" },
|
||||
//{ "hex.builtin.visualizer.rgba8", "RGBA8 Color" },
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "math_evaluator.hpp"
|
||||
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/concepts.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <queue>
|
||||
#include <stack>
|
||||
@@ -10,15 +13,18 @@
|
||||
|
||||
namespace hex {
|
||||
|
||||
i16 comparePrecedence(const Operator &a, const Operator &b) {
|
||||
template<typename T>
|
||||
i16 MathEvaluator<T>::comparePrecedence(const Operator &a, const Operator &b) {
|
||||
return static_cast<i16>((static_cast<i8>(a) & 0x0F0) - (static_cast<i8>(b) & 0x0F0));
|
||||
}
|
||||
|
||||
bool isLeftAssociative(const Operator op) {
|
||||
template<typename T>
|
||||
bool MathEvaluator<T>::isLeftAssociative(const Operator op) {
|
||||
return (static_cast<u32>(op) & 0xF00) == 0;
|
||||
}
|
||||
|
||||
std::pair<Operator, size_t> toOperator(const std::string &input) {
|
||||
template<typename T>
|
||||
std::pair<typename MathEvaluator<T>::Operator, size_t> MathEvaluator<T>::toOperator(const std::string &input) {
|
||||
if (input.starts_with("##")) return { Operator::Combine, 2 };
|
||||
if (input.starts_with("==")) return { Operator::Equals, 2 };
|
||||
if (input.starts_with("!=")) return { Operator::NotEquals, 2 };
|
||||
@@ -47,7 +53,8 @@ namespace hex {
|
||||
return { Operator::Invalid, 0 };
|
||||
}
|
||||
|
||||
static std::queue<Token> toPostfix(std::queue<Token> inputQueue) {
|
||||
template<typename T>
|
||||
std::optional<std::queue<typename MathEvaluator<T>::Token>> MathEvaluator<T>::toPostfix(std::queue<Token> inputQueue) {
|
||||
std::queue<Token> outputQueue;
|
||||
std::stack<Token> operatorStack;
|
||||
|
||||
@@ -67,12 +74,16 @@ namespace hex {
|
||||
if (currToken.bracketType == BracketType::Left)
|
||||
operatorStack.push(currToken);
|
||||
else {
|
||||
if (operatorStack.empty())
|
||||
throw std::invalid_argument("Mismatching parenthesis!");
|
||||
if (operatorStack.empty()) {
|
||||
this->setError("Mismatching parenthesis!");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
while (operatorStack.top().type != TokenType::Bracket || (operatorStack.top().type == TokenType::Bracket && operatorStack.top().bracketType != BracketType::Left)) {
|
||||
if (operatorStack.empty())
|
||||
throw std::invalid_argument("Mismatching parenthesis!");
|
||||
if (operatorStack.empty()) {
|
||||
this->setError("Mismatching parenthesis!");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
outputQueue.push(operatorStack.top());
|
||||
operatorStack.pop();
|
||||
@@ -86,8 +97,10 @@ namespace hex {
|
||||
while (!operatorStack.empty()) {
|
||||
auto top = operatorStack.top();
|
||||
|
||||
if (top.type == TokenType::Bracket)
|
||||
throw std::invalid_argument("Mismatching parenthesis!");
|
||||
if (top.type == TokenType::Bracket) {
|
||||
this->setError("Mismatching parenthesis!");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
outputQueue.push(top);
|
||||
operatorStack.pop();
|
||||
@@ -96,13 +109,23 @@ namespace hex {
|
||||
return outputQueue;
|
||||
}
|
||||
|
||||
std::queue<Token> MathEvaluator::parseInput(std::string input) {
|
||||
template<typename T>
|
||||
std::optional<std::queue<typename MathEvaluator<T>::Token>> MathEvaluator<T>::parseInput(std::string input) {
|
||||
std::queue<Token> inputQueue;
|
||||
|
||||
char *prevPos = input.data();
|
||||
for (char *pos = prevPos; *pos != 0x00;) {
|
||||
if (std::isdigit(*pos) || *pos == '.') {
|
||||
auto number = std::strtold(pos, &pos);
|
||||
auto number = [&] {
|
||||
if constexpr (hex::floating_point<T>)
|
||||
return std::strtold(pos, &pos);
|
||||
else if constexpr (hex::signed_integral<T>)
|
||||
return std::strtoll(pos, &pos, 10);
|
||||
else if constexpr (hex::unsigned_integral<T>)
|
||||
return std::strtoull(pos, &pos, 10);
|
||||
else
|
||||
static_assert(hex::always_false<T>::value, "Can't parse literal of this type");
|
||||
}();
|
||||
|
||||
if (*pos == 'x') {
|
||||
pos--;
|
||||
@@ -159,17 +182,26 @@ namespace hex {
|
||||
pos++;
|
||||
|
||||
for (const auto &expression : expressions) {
|
||||
if (expression.empty() && expressions.size() > 1)
|
||||
throw std::invalid_argument("Invalid function call syntax!");
|
||||
if (expression.empty() && expressions.size() > 1) {
|
||||
this->setError("Invalid function call syntax!");
|
||||
return std::nullopt;
|
||||
}
|
||||
else if (expression.empty())
|
||||
break;
|
||||
|
||||
auto newInputQueue = parseInput(expression);
|
||||
auto postfixTokens = toPostfix(newInputQueue);
|
||||
auto result = evaluate(postfixTokens);
|
||||
if (!newInputQueue.has_value())
|
||||
return std::nullopt;
|
||||
|
||||
if (!result.has_value())
|
||||
throw std::invalid_argument("Invalid argument for function!");
|
||||
auto postfixTokens = toPostfix(*newInputQueue);
|
||||
if (!postfixTokens.has_value())
|
||||
return std::nullopt;
|
||||
|
||||
auto result = evaluate(*postfixTokens);
|
||||
if (!result.has_value()) {
|
||||
this->setError("Invalid argument for function!");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
token.arguments.push_back(result.value());
|
||||
}
|
||||
@@ -184,8 +216,10 @@ namespace hex {
|
||||
}
|
||||
}
|
||||
|
||||
if (prevPos == pos)
|
||||
throw std::invalid_argument("Invalid syntax!");
|
||||
if (prevPos == pos) {
|
||||
this->setError("Invalid syntax!");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
prevPos = pos;
|
||||
}
|
||||
@@ -193,8 +227,9 @@ namespace hex {
|
||||
return inputQueue;
|
||||
}
|
||||
|
||||
std::optional<long double> MathEvaluator::evaluate(std::queue<Token> postfixTokens) {
|
||||
std::stack<long double> evaluationStack;
|
||||
template<typename T>
|
||||
std::optional<T> MathEvaluator<T>::evaluate(std::queue<Token> postfixTokens) {
|
||||
std::stack<T> evaluationStack;
|
||||
|
||||
while (!postfixTokens.empty()) {
|
||||
auto front = postfixTokens.front();
|
||||
@@ -203,13 +238,16 @@ namespace hex {
|
||||
if (front.type == TokenType::Number)
|
||||
evaluationStack.push(front.number);
|
||||
else if (front.type == TokenType::Operator) {
|
||||
long double rightOperand, leftOperand;
|
||||
T rightOperand, leftOperand;
|
||||
if (evaluationStack.size() < 2) {
|
||||
if ((front.op == Operator::Addition || front.op == Operator::Subtraction || front.op == Operator::Not || front.op == Operator::BitwiseNot) && evaluationStack.size() == 1) {
|
||||
rightOperand = evaluationStack.top();
|
||||
evaluationStack.pop();
|
||||
leftOperand = 0;
|
||||
} else throw std::invalid_argument("Not enough operands for operator!");
|
||||
} else {
|
||||
this->setError("Not enough operands for operator!");
|
||||
return std::nullopt;
|
||||
}
|
||||
} else {
|
||||
rightOperand = evaluationStack.top();
|
||||
evaluationStack.pop();
|
||||
@@ -217,11 +255,17 @@ namespace hex {
|
||||
evaluationStack.pop();
|
||||
}
|
||||
|
||||
long double result = std::numeric_limits<long double>::quiet_NaN();
|
||||
T result = [] {
|
||||
if constexpr (std::numeric_limits<T>::has_quiet_NaN)
|
||||
return std::numeric_limits<T>::quiet_NaN();
|
||||
else
|
||||
return 0;
|
||||
}();
|
||||
switch (front.op) {
|
||||
default:
|
||||
case Operator::Invalid:
|
||||
throw std::invalid_argument("Invalid operator!");
|
||||
this->setError("Invalid operator!");
|
||||
return std::nullopt;
|
||||
case Operator::And:
|
||||
result = static_cast<i64>(leftOperand) && static_cast<i64>(rightOperand);
|
||||
break;
|
||||
@@ -283,10 +327,16 @@ namespace hex {
|
||||
result = leftOperand / rightOperand;
|
||||
break;
|
||||
case Operator::Modulus:
|
||||
result = std::fmod(leftOperand, rightOperand);
|
||||
if constexpr (std::floating_point<T>)
|
||||
result = std::fmod(leftOperand, rightOperand);
|
||||
else
|
||||
result = leftOperand % rightOperand;
|
||||
break;
|
||||
case Operator::Exponentiation:
|
||||
result = std::pow(leftOperand, rightOperand);
|
||||
if constexpr (std::floating_point<T>)
|
||||
result = std::pow(leftOperand, rightOperand);
|
||||
else
|
||||
result = hex::powi(leftOperand, rightOperand);
|
||||
break;
|
||||
case Operator::Combine:
|
||||
result = (static_cast<u64>(leftOperand) << (64 - __builtin_clzll(static_cast<u64>(rightOperand)))) | static_cast<u64>(rightOperand);
|
||||
@@ -297,51 +347,66 @@ namespace hex {
|
||||
} else if (front.type == TokenType::Variable) {
|
||||
if (this->m_variables.contains(front.name))
|
||||
evaluationStack.push(this->m_variables.at(front.name));
|
||||
else
|
||||
throw std::invalid_argument("Unknown variable!");
|
||||
else {
|
||||
this->setError("Unknown variable!");
|
||||
return std::nullopt;
|
||||
}
|
||||
} else if (front.type == TokenType::Function) {
|
||||
if (!this->m_functions[front.name])
|
||||
throw std::invalid_argument("Unknown function called!");
|
||||
if (!this->m_functions[front.name]) {
|
||||
this->setError("Unknown function called!");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto result = this->m_functions[front.name](front.arguments);
|
||||
|
||||
if (result.has_value())
|
||||
evaluationStack.push(result.value());
|
||||
} else
|
||||
throw std::invalid_argument("Parenthesis in postfix expression!");
|
||||
} else {
|
||||
this->setError("Parenthesis in postfix expression!");
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
if (evaluationStack.empty())
|
||||
if (evaluationStack.empty()) {
|
||||
return std::nullopt;
|
||||
else if (evaluationStack.size() > 1)
|
||||
throw std::invalid_argument("Undigested input left!");
|
||||
else
|
||||
}
|
||||
else if (evaluationStack.size() > 1) {
|
||||
this->setError("Undigested input left!");
|
||||
return std::nullopt;
|
||||
}
|
||||
else {
|
||||
return evaluationStack.top();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::optional<long double> MathEvaluator::evaluate(const std::string &input) {
|
||||
template<typename T>
|
||||
std::optional<T> MathEvaluator<T>::evaluate(const std::string &input) {
|
||||
auto inputQueue = parseInput(input);
|
||||
if (!inputQueue.has_value())
|
||||
return std::nullopt;
|
||||
|
||||
std::string resultVariable = "ans";
|
||||
|
||||
{
|
||||
std::queue<Token> queueCopy = inputQueue;
|
||||
auto queueCopy = *inputQueue;
|
||||
if (queueCopy.front().type == TokenType::Variable) {
|
||||
resultVariable = queueCopy.front().name;
|
||||
queueCopy.pop();
|
||||
if (queueCopy.front().type != TokenType::Operator || queueCopy.front().op != Operator::Assign)
|
||||
resultVariable = "ans";
|
||||
else {
|
||||
inputQueue.pop();
|
||||
inputQueue.pop();
|
||||
inputQueue->pop();
|
||||
inputQueue->pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto postfixTokens = toPostfix(inputQueue);
|
||||
auto postfixTokens = toPostfix(*inputQueue);
|
||||
if (!postfixTokens.has_value())
|
||||
return std::nullopt;
|
||||
|
||||
auto result = evaluate(postfixTokens);
|
||||
auto result = evaluate(*postfixTokens);
|
||||
|
||||
if (result.has_value()) {
|
||||
this->setVariable(resultVariable, result.value());
|
||||
@@ -350,48 +415,59 @@ namespace hex {
|
||||
return result;
|
||||
}
|
||||
|
||||
void MathEvaluator::setVariable(const std::string &name, long double value) {
|
||||
template<typename T>
|
||||
void MathEvaluator<T>::setVariable(const std::string &name, T value) {
|
||||
this->m_variables[name] = value;
|
||||
}
|
||||
|
||||
void MathEvaluator::setFunction(const std::string &name, const std::function<std::optional<long double>(std::vector<long double>)> &function, size_t minNumArgs, size_t maxNumArgs) {
|
||||
this->m_functions[name] = [minNumArgs, maxNumArgs, function](auto args) {
|
||||
if (args.size() < minNumArgs || args.size() > maxNumArgs)
|
||||
throw std::invalid_argument("Invalid number of function arguments!");
|
||||
template<typename T>
|
||||
void MathEvaluator<T>::setFunction(const std::string &name, const std::function<std::optional<T>(std::vector<T>)> &function, size_t minNumArgs, size_t maxNumArgs) {
|
||||
this->m_functions[name] = [this, minNumArgs, maxNumArgs, function](auto args) -> std::optional<T> {
|
||||
if (args.size() < minNumArgs || args.size() > maxNumArgs) {
|
||||
this->setError("Invalid number of function arguments!");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return function(args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void MathEvaluator::registerStandardVariables() {
|
||||
template<typename T>
|
||||
void MathEvaluator<T>::registerStandardVariables() {
|
||||
this->setVariable("ans", 0);
|
||||
}
|
||||
|
||||
void MathEvaluator::registerStandardFunctions() {
|
||||
this->setFunction(
|
||||
"sin", [](auto args) { return std::sin(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"cos", [](auto args) { return std::cos(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"tan", [](auto args) { return std::tan(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"sqrt", [](auto args) { return std::sqrt(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"ceil", [](auto args) { return std::ceil(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"floor", [](auto args) { return std::floor(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"sign", [](auto args) { return (args[0] > 0) ? 1 : (args[0] == 0) ? 0
|
||||
: -1; }, 1, 1);
|
||||
this->setFunction(
|
||||
"abs", [](auto args) { return std::abs(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"ln", [](auto args) { return std::log(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"lb", [](auto args) { return std::log2(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"log", [](auto args) { return args.size() == 1 ? std::log10(args[0]) : std::log(args[1]) / std::log(args[0]); }, 1, 2);
|
||||
template<typename T>
|
||||
void MathEvaluator<T>::registerStandardFunctions() {
|
||||
if constexpr (hex::floating_point<T>) {
|
||||
this->setFunction(
|
||||
"sin", [](auto args) { return std::sin(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"cos", [](auto args) { return std::cos(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"tan", [](auto args) { return std::tan(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"sqrt", [](auto args) { return std::sqrt(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"ceil", [](auto args) { return std::ceil(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"floor", [](auto args) { return std::floor(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"sign", [](auto args) { return (args[0] > 0) ? 1 : (args[0] == 0) ? 0
|
||||
: -1; }, 1, 1);
|
||||
this->setFunction(
|
||||
"abs", [](auto args) { return std::abs(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"ln", [](auto args) { return std::log(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"lb", [](auto args) { return std::log2(args[0]); }, 1, 1);
|
||||
this->setFunction(
|
||||
"log", [](auto args) { return args.size() == 1 ? std::log10(args[0]) : std::log(args[1]) / std::log(args[0]); }, 1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
template class MathEvaluator<long double>;
|
||||
template class MathEvaluator<i128>;
|
||||
|
||||
}
|
||||
|
||||
@@ -65,13 +65,10 @@ namespace hex {
|
||||
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "bits");
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
u64 extractedValue = pattern.getValue();
|
||||
ImGui::TextFormatted("{}", pattern.formatDisplayValue(hex::format("{0} (0x{1:X})", extractedValue, extractedValue), &pattern));
|
||||
ImGui::TextFormatted("{}", pattern.getFormattedValue());
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::PatternBitfield& pattern) {
|
||||
std::vector<u8> value = pattern.getValue();
|
||||
|
||||
bool open = true;
|
||||
if (!pattern.isInlined()) {
|
||||
ImGui::TableNextRow();
|
||||
@@ -85,12 +82,7 @@ namespace hex {
|
||||
drawSizeColumn(pattern);
|
||||
drawTypenameColumn(pattern, "bitfield");
|
||||
|
||||
std::string valueString = "{ ";
|
||||
for (auto i : value)
|
||||
valueString += hex::format("{0:02X} ", i);
|
||||
valueString += "}";
|
||||
|
||||
ImGui::TextFormatted("{}", pattern.formatDisplayValue(valueString, &pattern));
|
||||
ImGui::TextFormatted("{}", pattern.getFormattedValue());
|
||||
} else {
|
||||
ImGui::SameLine();
|
||||
ImGui::TreeNodeEx("", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf);
|
||||
@@ -106,50 +98,14 @@ namespace hex {
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::PatternBoolean& pattern) {
|
||||
u8 boolean = pattern.getValue();
|
||||
|
||||
if (boolean == 0)
|
||||
this->createDefaultEntry(pattern, "false", false);
|
||||
else if (boolean == 1)
|
||||
this->createDefaultEntry(pattern, "true", true);
|
||||
else
|
||||
this->createDefaultEntry(pattern, "true*", true);
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), static_cast<bool>(pattern.getValue()));
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::PatternCharacter& pattern) {
|
||||
char character = pattern.getValue();
|
||||
this->createDefaultEntry(pattern, hex::format("'{0}'", character), character);
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::PatternEnum& pattern) {
|
||||
u64 value = pattern.getValue();
|
||||
|
||||
std::string valueString = pattern.getTypeName() + "::";
|
||||
|
||||
bool foundValue = false;
|
||||
for (auto &[entryValueLiteral, entryName] : pattern.getEnumValues()) {
|
||||
auto visitor = overloaded {
|
||||
[&, name = entryName](auto &entryValue) {
|
||||
if (static_cast<decltype(entryValue)>(value) == entryValue) {
|
||||
valueString += name;
|
||||
foundValue = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
[](const std::string &) { return false; },
|
||||
[](pl::Pattern *) { return false; },
|
||||
};
|
||||
|
||||
bool matches = std::visit(visitor, entryValueLiteral);
|
||||
if (matches)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!foundValue)
|
||||
valueString += "???";
|
||||
|
||||
ImGui::TableNextRow();
|
||||
createLeafNode(pattern);
|
||||
drawCommentTooltip(pattern);
|
||||
@@ -161,20 +117,14 @@ namespace hex {
|
||||
drawOffsetColumn(pattern);
|
||||
drawSizeColumn(pattern);
|
||||
drawTypenameColumn(pattern, "enum");
|
||||
ImGui::TextFormatted("{}", pattern.formatDisplayValue(hex::format("{} (0x{:0{}X})", valueString.c_str(), value, pattern.getSize() * 2), &pattern));
|
||||
ImGui::TextFormatted("{}", pattern.getFormattedValue());
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::PatternFloat& pattern) {
|
||||
if (pattern.getSize() == 4) {
|
||||
float f32 = static_cast<float>(pattern.getValue());
|
||||
u32 integerResult = 0;
|
||||
std::memcpy(&integerResult, &f32, sizeof(float));
|
||||
this->createDefaultEntry(pattern, hex::format("{:e} (0x{:0{}X})", f32, integerResult, pattern.getSize() * 2), f32);
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), static_cast<float>(pattern.getValue()));
|
||||
} else if (pattern.getSize() == 8) {
|
||||
double f64 = pattern.getValue();
|
||||
u64 integerResult = 0;
|
||||
std::memcpy(&integerResult, &f64, sizeof(double));
|
||||
this->createDefaultEntry(pattern, hex::format("{:e} (0x{:0{}X})", f64, integerResult, pattern.getSize() * 2), f64);
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), static_cast<double>(pattern.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,8 +134,6 @@ namespace hex {
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::PatternPointer& pattern) {
|
||||
u64 data = pattern.getValue();
|
||||
|
||||
bool open = true;
|
||||
|
||||
if (!pattern.isInlined()) {
|
||||
@@ -201,7 +149,7 @@ namespace hex {
|
||||
drawSizeColumn(pattern);
|
||||
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{}", pattern.getFormattedName());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}", pattern.formatDisplayValue(hex::format("*(0x{0:X})", data), u128(data)));
|
||||
ImGui::TextFormatted("{}", pattern.getFormattedValue());
|
||||
} else {
|
||||
ImGui::SameLine();
|
||||
ImGui::TreeNodeEx("", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf);
|
||||
@@ -215,18 +163,11 @@ namespace hex {
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::PatternSigned& pattern) {
|
||||
i128 data = pattern.getValue();
|
||||
this->createDefaultEntry(pattern, hex::format("{:d} (0x{:0{}X})", data, data, 1 * 2), data);
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::PatternString& pattern) {
|
||||
auto size = std::min<size_t>(pattern.getSize(), 0x7F);
|
||||
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
std::string displayString = pattern.getValue(size);
|
||||
this->createDefaultEntry(pattern, hex::format("\"{0}\" {1}", displayString, size > pattern.getSize() ? "(truncated)" : ""), displayString);
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::PatternStruct& pattern) {
|
||||
@@ -243,7 +184,7 @@ namespace hex {
|
||||
drawOffsetColumn(pattern);
|
||||
drawSizeColumn(pattern);
|
||||
drawTypenameColumn(pattern, "struct");
|
||||
ImGui::TextFormatted("{}", pattern.formatDisplayValue("{ ... }", &pattern));
|
||||
ImGui::TextFormatted("{}", pattern.getFormattedValue());
|
||||
} else {
|
||||
ImGui::SameLine();
|
||||
ImGui::TreeNodeEx("", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf);
|
||||
@@ -272,7 +213,7 @@ namespace hex {
|
||||
drawOffsetColumn(pattern);
|
||||
drawSizeColumn(pattern);
|
||||
drawTypenameColumn(pattern, "union");
|
||||
ImGui::TextFormatted("{}", pattern.formatDisplayValue("{ ... }", &pattern));
|
||||
ImGui::TextFormatted("{}", pattern.getFormattedValue());
|
||||
} else {
|
||||
ImGui::SameLine();
|
||||
ImGui::TreeNodeEx("", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf);
|
||||
@@ -288,26 +229,17 @@ namespace hex {
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::PatternUnsigned& pattern) {
|
||||
u128 data = pattern.getValue();
|
||||
this->createDefaultEntry(pattern, hex::format("{:d} (0x{:0{}X})", data, data, pattern.getSize() * 2), data);
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::PatternWideCharacter& pattern) {
|
||||
char16_t character = pattern.getValue();
|
||||
u128 literal = character;
|
||||
auto str = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(character);
|
||||
this->createDefaultEntry(pattern, hex::format("'{0}'", str), literal);
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), u128(pattern.getValue()));
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::PatternWideString& pattern) {
|
||||
auto size = std::min<size_t>(pattern.getSize(), 0x100);
|
||||
std::string utf8String = pattern.getValue();
|
||||
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
std::string utf8String = pattern.getValue(size);
|
||||
|
||||
this->createDefaultEntry(pattern, hex::format("\"{0}\" {1}", utf8String, size > pattern.getSize() ? "(truncated)" : ""), utf8String);
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), utf8String);
|
||||
}
|
||||
|
||||
void PatternDrawer::createDefaultEntry(const pl::Pattern &pattern, const std::string &value, pl::Token::Literal &&literal) const {
|
||||
@@ -323,7 +255,7 @@ namespace hex {
|
||||
drawColorColumn(pattern);
|
||||
drawOffsetColumn(pattern);
|
||||
drawSizeColumn(pattern);
|
||||
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{}", pattern.getTypeName().empty() ? pattern.getFormattedName() : pattern.getTypeName());
|
||||
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{}", pattern.getFormattedName().empty() ? pattern.getTypeName() : pattern.getFormattedName());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}", pattern.formatDisplayValue(value, literal));
|
||||
}
|
||||
@@ -380,7 +312,7 @@ namespace hex {
|
||||
ImGui::TextUnformatted("]");
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}", pattern.formatDisplayValue("{ ... }", &pattern));
|
||||
ImGui::TextFormatted("{}", pattern.getFormattedValue());
|
||||
} else {
|
||||
ImGui::SameLine();
|
||||
ImGui::TreeNodeEx("", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf);
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
void registerViews();
|
||||
void registerEventHandlers();
|
||||
void registerDataVisualizers();
|
||||
void registerDataInspectorEntries();
|
||||
void registerToolEntries();
|
||||
void registerPatternLanguageFunctions();
|
||||
@@ -15,9 +16,11 @@ namespace hex::plugin::builtin {
|
||||
void registerLayouts();
|
||||
void registerMainMenuEntries();
|
||||
void createWelcomeScreen();
|
||||
void registerViews();
|
||||
|
||||
void addFooterItems();
|
||||
void addToolbarItems();
|
||||
void addGlobalUIItems();
|
||||
|
||||
void registerLanguageEnUS();
|
||||
void registerLanguageDeDE();
|
||||
@@ -37,7 +40,8 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") {
|
||||
registerLanguageJaJP();
|
||||
registerLanguageZhCN();
|
||||
|
||||
registerViews();
|
||||
registerEventHandlers();
|
||||
registerDataVisualizers();
|
||||
registerDataInspectorEntries();
|
||||
registerToolEntries();
|
||||
registerPatternLanguageFunctions();
|
||||
@@ -48,9 +52,12 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") {
|
||||
registerProviders();
|
||||
registerDataFormatters();
|
||||
createWelcomeScreen();
|
||||
registerViews();
|
||||
|
||||
addFooterItems();
|
||||
addToolbarItems();
|
||||
addGlobalUIItems();
|
||||
|
||||
registerLayouts();
|
||||
registerMainMenuEntries();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user