Support external context menu actions in the HexViewerWidget
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
#include "ContextMenuAction.hpp"
|
||||||
|
|
||||||
|
namespace Bloom::Widgets
|
||||||
|
{
|
||||||
|
ContextMenuAction::ContextMenuAction(
|
||||||
|
const QString& text,
|
||||||
|
std::optional<IsEnabledCallbackType> isEnabledCallback,
|
||||||
|
QWidget* parent
|
||||||
|
)
|
||||||
|
: isEnabledCallback(isEnabledCallback)
|
||||||
|
, QAction(text, parent)
|
||||||
|
{}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <functional>
|
||||||
|
#include <QString>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "src/Targets/TargetMemory.hpp"
|
||||||
|
#include "ByteItem.hpp"
|
||||||
|
|
||||||
|
namespace Bloom::Widgets
|
||||||
|
{
|
||||||
|
class ContextMenuAction: public QAction
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ContextMenuAction::isEnabledCallback member is just a callback function that implements any specific
|
||||||
|
* rules which determine if the action should be enabled (in the context menu).
|
||||||
|
*
|
||||||
|
* If the callback returns false, the menu action will be disabled.
|
||||||
|
*
|
||||||
|
* The callback is called just before the context menu is presented to the user, everytime the context menu
|
||||||
|
* is requested.
|
||||||
|
*
|
||||||
|
* If no callback is specified (ContextMenuAction::isEnabledCallback == std::nullopt), the menu action will
|
||||||
|
* always be enabled.
|
||||||
|
*/
|
||||||
|
using IsEnabledCallbackType = std::function<
|
||||||
|
bool(const std::unordered_map<Targets::TargetMemoryAddress, ByteItem*>&)
|
||||||
|
>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::optional<IsEnabledCallbackType> isEnabledCallback;
|
||||||
|
|
||||||
|
ContextMenuAction(
|
||||||
|
const QString& text,
|
||||||
|
std::optional<IsEnabledCallbackType> isEnabledCallback,
|
||||||
|
QWidget* parent
|
||||||
|
);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void invoked(const std::unordered_map<Targets::TargetMemoryAddress, ByteItem*>& selectedByteItemsByAddress);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -237,6 +237,11 @@ namespace Bloom::Widgets
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HexViewerWidget::addExternalContextMenuAction(ContextMenuAction* action) {
|
||||||
|
assert(this->byteItemGraphicsScene != nullptr);
|
||||||
|
this->byteItemGraphicsScene->addExternalContextMenuAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
void HexViewerWidget::resizeEvent(QResizeEvent* event) {
|
void HexViewerWidget::resizeEvent(QResizeEvent* event) {
|
||||||
this->container->setFixedSize(
|
this->container->setFixedSize(
|
||||||
this->width(),
|
this->width(),
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "HexViewerWidgetSettings.hpp"
|
#include "HexViewerWidgetSettings.hpp"
|
||||||
#include "ItemGraphicsView.hpp"
|
#include "ItemGraphicsView.hpp"
|
||||||
|
#include "ContextMenuAction.hpp"
|
||||||
|
|
||||||
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegion.hpp"
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/MemoryRegion.hpp"
|
||||||
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/FocusedMemoryRegion.hpp"
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/FocusedMemoryRegion.hpp"
|
||||||
@@ -40,6 +41,7 @@ namespace Bloom::Widgets
|
|||||||
void updateValues();
|
void updateValues();
|
||||||
void refreshRegions();
|
void refreshRegions();
|
||||||
void setStackPointer(Targets::TargetStackPointer stackPointer);
|
void setStackPointer(Targets::TargetStackPointer stackPointer);
|
||||||
|
void addExternalContextMenuAction(ContextMenuAction* action);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void ready();
|
void ready();
|
||||||
|
|||||||
@@ -321,6 +321,14 @@ namespace Bloom::Widgets
|
|||||||
this->update();
|
this->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemGraphicsScene::addExternalContextMenuAction(ContextMenuAction* action) {
|
||||||
|
QObject::connect(action, &QAction::triggered, this, [this, action] () {
|
||||||
|
emit action->invoked(this->selectedByteItemsByAddress);
|
||||||
|
});
|
||||||
|
|
||||||
|
this->externalContextMenuActions.push_back(action);
|
||||||
|
}
|
||||||
|
|
||||||
bool ItemGraphicsScene::event(QEvent* event) {
|
bool ItemGraphicsScene::event(QEvent* event) {
|
||||||
if (event->type() == QEvent::Type::GraphicsSceneLeave && this->state.hoveredByteItem != nullptr) {
|
if (event->type() == QEvent::Type::GraphicsSceneLeave && this->state.hoveredByteItem != nullptr) {
|
||||||
this->onByteItemLeave();
|
this->onByteItemLeave();
|
||||||
@@ -549,6 +557,23 @@ namespace Bloom::Widgets
|
|||||||
this->deselectByteItemsAction->setEnabled(itemsSelected);
|
this->deselectByteItemsAction->setEnabled(itemsSelected);
|
||||||
|
|
||||||
menu->addMenu(copyMenu);
|
menu->addMenu(copyMenu);
|
||||||
|
|
||||||
|
if (!this->externalContextMenuActions.empty()) {
|
||||||
|
menu->addSeparator();
|
||||||
|
|
||||||
|
for (auto& externalAction : this->externalContextMenuActions) {
|
||||||
|
menu->addAction(externalAction);
|
||||||
|
externalAction->setEnabled(
|
||||||
|
itemsSelected
|
||||||
|
&& (
|
||||||
|
!externalAction->isEnabledCallback.has_value()
|
||||||
|
|| externalAction->isEnabledCallback.value()(this->selectedByteItemsByAddress)
|
||||||
|
)
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
menu->exec(event->screenPos());
|
menu->exec(event->screenPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "GroupItem.hpp"
|
#include "GroupItem.hpp"
|
||||||
#include "ByteItem.hpp"
|
#include "ByteItem.hpp"
|
||||||
#include "ByteAddressContainer.hpp"
|
#include "ByteAddressContainer.hpp"
|
||||||
|
#include "ContextMenuAction.hpp"
|
||||||
|
|
||||||
#include "HexViewerSharedState.hpp"
|
#include "HexViewerSharedState.hpp"
|
||||||
|
|
||||||
@@ -60,6 +61,7 @@ namespace Bloom::Widgets
|
|||||||
void refreshValues();
|
void refreshValues();
|
||||||
QPointF getByteItemPositionByAddress(Targets::TargetMemoryAddress address);
|
QPointF getByteItemPositionByAddress(Targets::TargetMemoryAddress address);
|
||||||
void allocateGraphicsItems();
|
void allocateGraphicsItems();
|
||||||
|
void addExternalContextMenuAction(ContextMenuAction* action);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void ready();
|
void ready();
|
||||||
@@ -121,6 +123,8 @@ namespace Bloom::Widgets
|
|||||||
QAction* displayRelativeAddressAction = new QAction("Relative", this);
|
QAction* displayRelativeAddressAction = new QAction("Relative", this);
|
||||||
QAction* displayAbsoluteAddressAction = new QAction("Absolute", this);
|
QAction* displayAbsoluteAddressAction = new QAction("Absolute", this);
|
||||||
|
|
||||||
|
std::vector<ContextMenuAction*> externalContextMenuActions;
|
||||||
|
|
||||||
int getSceneWidth() {
|
int getSceneWidth() {
|
||||||
/*
|
/*
|
||||||
* Minus 2 for the QSS margin on the vertical scrollbar (which isn't accounted for during viewport
|
* Minus 2 for the QSS margin on the vertical scrollbar (which isn't accounted for during viewport
|
||||||
|
|||||||
Reference in New Issue
Block a user