ux: Added undo and redo option
This commit is contained in:
parent
42461c467f
commit
688ca01b1b
@ -182,6 +182,8 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.view.hexeditor.goto.offset.end", "Ende" },
|
||||
{ "hex.view.hexeditor.error.read_only", "Schreibzugriff konnte nicht erlangt werden. Datei wurde im Lesemodus geöffnet." },
|
||||
{ "hex.view.hexeditor.error.open", "Öffnen der Datei fehlgeschlagen!" },
|
||||
{ "hex.view.hexeditor.menu.edit.undo", "Rückgängig" },
|
||||
{ "hex.view.hexeditor.menu.edit.redo", "Wiederholen" },
|
||||
{ "hex.view.hexeditor.menu.edit.copy", "Kopieren als..." },
|
||||
{ "hex.view.hexeditor.copy.bytes", "Bytes" },
|
||||
{ "hex.view.hexeditor.copy.hex", "Hex String" },
|
||||
|
@ -182,6 +182,8 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.view.hexeditor.goto.offset.end", "End" },
|
||||
{ "hex.view.hexeditor.error.read_only", "Couldn't get write access. File opened in read-only mode." },
|
||||
{ "hex.view.hexeditor.error.open", "Failed to open file!" },
|
||||
{ "hex.view.hexeditor.menu.edit.undo", "Undo" },
|
||||
{ "hex.view.hexeditor.menu.edit.redo", "Redo" },
|
||||
{ "hex.view.hexeditor.menu.edit.copy", "Copy as..." },
|
||||
{ "hex.view.hexeditor.copy.bytes", "Bytes" },
|
||||
{ "hex.view.hexeditor.copy.hex", "Hex String" },
|
||||
|
@ -182,6 +182,8 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.view.hexeditor.goto.offset.end", "Fine" },
|
||||
{ "hex.view.hexeditor.error.read_only", "Impossibile scrivere sul File. File aperto solo in modalità lettura" },
|
||||
{ "hex.view.hexeditor.error.open", "Impossibile aprire il File!" },
|
||||
// { "hex.view.hexeditor.menu.edit.undo", "" },
|
||||
// { "hex.view.hexeditor.menu.edit.redo", "" },
|
||||
{ "hex.view.hexeditor.menu.edit.copy", "Copia come..." },
|
||||
{ "hex.view.hexeditor.copy.bytes", "Bytes" },
|
||||
{ "hex.view.hexeditor.copy.hex", "Stringa esadecimale" },
|
||||
|
@ -50,10 +50,19 @@ namespace hex::prv {
|
||||
|
||||
virtual std::vector<std::pair<std::string, std::string>> getDataInformation() = 0;
|
||||
|
||||
void addPatch(u64 offset, const void *buffer, size_t size);
|
||||
|
||||
void undo();
|
||||
void redo();
|
||||
|
||||
bool canUndo();
|
||||
bool canRedo();
|
||||
|
||||
protected:
|
||||
u32 m_currPage = 0;
|
||||
u64 m_baseAddress = 0;
|
||||
|
||||
u32 m_patchTreeOffset = 0;
|
||||
std::vector<std::map<u64, u8>> m_patches;
|
||||
std::list<Overlay*> m_overlays;
|
||||
};
|
||||
|
@ -40,11 +40,11 @@ namespace hex::prv {
|
||||
|
||||
|
||||
std::map<u64, u8>& Provider::getPatches() {
|
||||
return this->m_patches.back();
|
||||
return *(this->m_patches.end() - 1 - this->m_patchTreeOffset);
|
||||
}
|
||||
|
||||
void Provider::applyPatches() {
|
||||
for (auto &[patchAddress, patch] : this->m_patches.back())
|
||||
for (auto &[patchAddress, patch] : getPatches())
|
||||
this->writeRaw(patchAddress, &patch, 1);
|
||||
}
|
||||
|
||||
@ -98,4 +98,34 @@ namespace hex::prv {
|
||||
return page;
|
||||
}
|
||||
|
||||
void Provider::addPatch(u64 offset, const void *buffer, size_t size) {
|
||||
if (this->m_patchTreeOffset > 0) {
|
||||
this->m_patches.erase(this->m_patches.end() - this->m_patchTreeOffset, this->m_patches.end());
|
||||
this->m_patchTreeOffset = 0;
|
||||
}
|
||||
|
||||
this->m_patches.push_back(getPatches());
|
||||
|
||||
for (u64 i = 0; i < size; i++)
|
||||
getPatches()[offset + this->getBaseAddress() + i] = reinterpret_cast<const u8*>(buffer)[i];
|
||||
}
|
||||
|
||||
void Provider::undo() {
|
||||
if (canUndo())
|
||||
this->m_patchTreeOffset++;
|
||||
}
|
||||
|
||||
void Provider::redo() {
|
||||
if (canRedo())
|
||||
this->m_patchTreeOffset--;
|
||||
}
|
||||
|
||||
bool Provider::canUndo() {
|
||||
return this->m_patchTreeOffset < this->m_patches.size() - 1;
|
||||
}
|
||||
|
||||
bool Provider::canRedo() {
|
||||
return this->m_patchTreeOffset > 0;
|
||||
}
|
||||
|
||||
}
|
@ -131,8 +131,8 @@ namespace hex::prv {
|
||||
std::memcpy(buffer, reinterpret_cast<u8*>(this->m_mappedFile) + PageSize * this->m_currPage + offset, size);
|
||||
|
||||
for (u64 i = 0; i < size; i++)
|
||||
if (this->m_patches.back().contains(offset + i))
|
||||
reinterpret_cast<u8*>(buffer)[i] = this->m_patches.back()[offset + PageSize * this->m_currPage + i];
|
||||
if (getPatches().contains(offset + i))
|
||||
reinterpret_cast<u8*>(buffer)[i] = getPatches()[offset + PageSize * this->m_currPage + i];
|
||||
|
||||
if (overlays)
|
||||
this->applyOverlays(offset, buffer, size);
|
||||
@ -142,10 +142,7 @@ namespace hex::prv {
|
||||
if ((offset + size) > this->getSize() || buffer == nullptr || size == 0)
|
||||
return;
|
||||
|
||||
this->m_patches.push_back(this->m_patches.back());
|
||||
|
||||
for (u64 i = 0; i < size; i++)
|
||||
this->m_patches.back()[offset + this->getBaseAddress() + i] = reinterpret_cast<const u8*>(buffer)[i];
|
||||
addPatch(offset, buffer, size);
|
||||
}
|
||||
|
||||
void FileProvider::readRaw(u64 offset, void *buffer, size_t size) {
|
||||
|
@ -508,6 +508,12 @@ namespace hex {
|
||||
saveAs();
|
||||
return true;
|
||||
} else if (mods == GLFW_MOD_CONTROL && key == 'Z') {
|
||||
if (SharedData::currentProvider != nullptr)
|
||||
SharedData::currentProvider->undo();
|
||||
} else if (mods == GLFW_MOD_CONTROL && key == 'Y') {
|
||||
if (SharedData::currentProvider != nullptr)
|
||||
SharedData::currentProvider->redo();
|
||||
} else if (mods == GLFW_MOD_CONTROL && key == 'F') {
|
||||
View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.menu.file.search"_lang); });
|
||||
return true;
|
||||
} else if (mods == GLFW_MOD_CONTROL && key == 'G') {
|
||||
@ -1060,6 +1066,11 @@ R"(
|
||||
}
|
||||
|
||||
void ViewHexEditor::drawEditPopup() {
|
||||
if (ImGui::MenuItem("hex.view.hexeditor.menu.edit.undo", "CTRL + Z", false, SharedData::currentProvider != nullptr))
|
||||
SharedData::currentProvider->undo();
|
||||
if (ImGui::MenuItem("hex.view.hexeditor.menu.edit.redo", "CTRL + Y", false, SharedData::currentProvider != nullptr))
|
||||
SharedData::currentProvider->redo();
|
||||
|
||||
if (ImGui::BeginMenu("hex.view.hexeditor.menu.edit.copy"_lang, this->m_memoryEditor.DataPreviewAddr != -1 && this->m_memoryEditor.DataPreviewAddrEnd != -1)) {
|
||||
if (ImGui::MenuItem("hex.view.hexeditor.copy.bytes"_lang, "CTRL + ALT + C"))
|
||||
this->copyBytes();
|
||||
|
Loading…
x
Reference in New Issue
Block a user