1
0
mirror of synced 2025-02-20 04:01:01 +01:00

ux: Added undo and redo option

This commit is contained in:
WerWolv 2021-03-26 21:43:24 +01:00
parent 42461c467f
commit 688ca01b1b
7 changed files with 61 additions and 8 deletions

View File

@ -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" },

View File

@ -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" },

View File

@ -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" },

View File

@ -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;
};

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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();