mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-29 00:10:02 -05:00
feat: Add keyboard shortcuts to jump to the prev/next differences in diff view (#2445)
Adds keyboard shortcuts (currently `n` and `N`) in the diffing plugin view to jump to the next/prev difference in the list. IMPORTANT NOTE: Depends on changes made in a library submodule. [This PR](https://github.com/WerWolv/libwolv/pull/34) must be accepted first. --------- Co-authored-by: Nik <werwolv98@gmail.com>
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
#include "content/views/view_diff.hpp"
|
||||
#include <toasts/toast_notification.hpp>
|
||||
|
||||
#include <hex/api/imhex_api/provider.hpp>
|
||||
#include <hex/api/events/requests_gui.hpp>
|
||||
#include <hex/api/content_registry/user_interface.hpp>
|
||||
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <hex/providers/buffered_reader.hpp>
|
||||
|
||||
#include <fonts/vscode_icons.hpp>
|
||||
#include <fonts/tabler_icons.hpp>
|
||||
#include <wolv/utils/guards.hpp>
|
||||
|
||||
namespace hex::plugin::diffing {
|
||||
@@ -22,14 +25,28 @@ namespace hex::plugin::diffing {
|
||||
m_analysisInterrupted = m_analyzed = false;
|
||||
});
|
||||
|
||||
// Handle region selection
|
||||
EventRegionSelected::subscribe(this, [this](const auto ®ion) {
|
||||
// Save current selection
|
||||
if (!ImHexApi::Provider::isValid() || region == Region::Invalid()) {
|
||||
m_selectedProvider = nullptr;
|
||||
} else {
|
||||
m_selectedAddress = region.address;
|
||||
m_selectedProvider = region.getProvider();
|
||||
}
|
||||
});
|
||||
|
||||
// Set the background highlight callbacks for the two hex editor columns
|
||||
m_columns[0].hexEditor.setBackgroundHighlightCallback(this->createCompareFunction(1));
|
||||
m_columns[1].hexEditor.setBackgroundHighlightCallback(this->createCompareFunction(0));
|
||||
|
||||
this->registerMenuItems();
|
||||
}
|
||||
|
||||
ViewDiff::~ViewDiff() {
|
||||
EventProviderClosed::unsubscribe(this);
|
||||
EventDataChanged::unsubscribe(this);
|
||||
EventRegionSelected::unsubscribe(this);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -133,6 +150,7 @@ namespace hex::plugin::diffing {
|
||||
column.diffTree.clear();
|
||||
column.differences.clear();
|
||||
}
|
||||
m_analysisInterrupted = m_analyzed = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -441,5 +459,88 @@ namespace hex::plugin::diffing {
|
||||
}
|
||||
}
|
||||
|
||||
void ViewDiff::registerMenuItems() {
|
||||
ContentRegistry::UserInterface::addMenuItemSeparator({ "hex.builtin.menu.file" }, 1700, this);
|
||||
|
||||
ContentRegistry::UserInterface::addMenuItemSubMenu({ "hex.builtin.menu.file", "hex.diffing.view.diff.menu.file.jumping" }, ICON_TA_ARROWS_MOVE_HORIZONTAL, 1710,
|
||||
[]{},
|
||||
[this]{ return (bool) m_analyzed; },
|
||||
this);
|
||||
|
||||
ContentRegistry::UserInterface::addMenuItem({
|
||||
"hex.builtin.menu.file",
|
||||
"hex.diffing.view.diff.menu.file.jumping",
|
||||
"hex.diffing.view.diff.menu.file.jumping.prev_diff"
|
||||
},
|
||||
ICON_TA_ARROW_BAR_TO_LEFT_DASHED,
|
||||
1720,
|
||||
CTRLCMD + Keys::Left,
|
||||
[this] {
|
||||
if (m_selectedProvider == nullptr)
|
||||
return;
|
||||
|
||||
// Get the column of the currently selected region
|
||||
auto providers = ImHexApi::Provider::getProviders();
|
||||
Column *selectedColumn = nullptr;
|
||||
for (auto &column : m_columns) {
|
||||
if (providers[column.provider] == m_selectedProvider) {
|
||||
selectedColumn = &column;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedColumn == nullptr)
|
||||
return;
|
||||
|
||||
// Jump to previous difference
|
||||
auto prevRange = selectedColumn->diffTree.prevInterval(m_selectedAddress);
|
||||
if (prevRange.has_value()) {
|
||||
selectedColumn->hexEditor.setSelection(prevRange->interval.start, prevRange->interval.end);
|
||||
selectedColumn->hexEditor.jumpToSelection();
|
||||
} else {
|
||||
ui::ToastInfo::open("hex.diffing.view.diff.jumping.beginning_reached"_lang);
|
||||
}
|
||||
},
|
||||
[this]{ return (bool) m_analyzed; },
|
||||
this
|
||||
);
|
||||
|
||||
ContentRegistry::UserInterface::addMenuItem({
|
||||
"hex.builtin.menu.file",
|
||||
"hex.diffing.view.diff.menu.file.jumping",
|
||||
"hex.diffing.view.diff.menu.file.jumping.next_diff"
|
||||
},
|
||||
ICON_TA_ARROW_BAR_TO_RIGHT_DASHED,
|
||||
1730,
|
||||
CTRLCMD + Keys::Right,
|
||||
[this] {
|
||||
if (m_selectedProvider == nullptr)
|
||||
return;
|
||||
|
||||
// Get the column of the currently selected region
|
||||
auto providers = ImHexApi::Provider::getProviders();
|
||||
Column *selectedColumn = nullptr;
|
||||
for (auto &column : m_columns) {
|
||||
if (providers[column.provider] == m_selectedProvider) {
|
||||
selectedColumn = &column;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedColumn == nullptr)
|
||||
return;
|
||||
|
||||
// Jump to next difference
|
||||
auto nextRange = selectedColumn->diffTree.nextInterval(m_selectedAddress);
|
||||
if (nextRange.has_value()) {
|
||||
selectedColumn->hexEditor.setSelection(nextRange->interval.start, nextRange->interval.end);
|
||||
selectedColumn->hexEditor.jumpToSelection();
|
||||
} else {
|
||||
ui::ToastInfo::open("hex.diffing.view.diff.jumping.end_reached"_lang);
|
||||
}
|
||||
},
|
||||
[this]{ return (bool) m_analyzed; },
|
||||
this
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user