Added context menu actions in ChangeListPane widget
This commit is contained in:
@@ -242,6 +242,10 @@ namespace Widgets
|
|||||||
this->byteItemGraphicsScene->addExternalContextMenuAction(action);
|
this->byteItemGraphicsScene->addExternalContextMenuAction(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HexViewerWidget::selectByteItems(const std::set<Targets::TargetMemoryAddress>& addresses) {
|
||||||
|
this->byteItemGraphicsScene->selectByteItems(addresses);
|
||||||
|
}
|
||||||
|
|
||||||
void HexViewerWidget::highlightPrimaryByteItemRanges(
|
void HexViewerWidget::highlightPrimaryByteItemRanges(
|
||||||
const std::set<Targets::TargetMemoryAddressRange>& addressRanges
|
const std::set<Targets::TargetMemoryAddressRange>& addressRanges
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ namespace Widgets
|
|||||||
void refreshRegions();
|
void refreshRegions();
|
||||||
void setStackPointer(Targets::TargetStackPointer stackPointer);
|
void setStackPointer(Targets::TargetStackPointer stackPointer);
|
||||||
void addExternalContextMenuAction(ContextMenuAction* action);
|
void addExternalContextMenuAction(ContextMenuAction* action);
|
||||||
|
void selectByteItems(const std::set<Targets::TargetMemoryAddress>& addresses);
|
||||||
void highlightPrimaryByteItemRanges(const std::set<Targets::TargetMemoryAddressRange>& addressRanges);
|
void highlightPrimaryByteItemRanges(const std::set<Targets::TargetMemoryAddressRange>& addressRanges);
|
||||||
void clearHighlighting();
|
void clearHighlighting();
|
||||||
void centerOnByte(Targets::TargetMemoryAddress address);
|
void centerOnByte(Targets::TargetMemoryAddress address);
|
||||||
|
|||||||
@@ -69,6 +69,41 @@ namespace Widgets
|
|||||||
&ChangeListPane::onItemSelectionChanged
|
&ChangeListPane::onItemSelectionChanged
|
||||||
);
|
);
|
||||||
|
|
||||||
|
QObject::connect(
|
||||||
|
this->changeListScene,
|
||||||
|
&ListScene::itemContextMenu,
|
||||||
|
this,
|
||||||
|
&ChangeListPane::onItemContextMenu
|
||||||
|
);
|
||||||
|
|
||||||
|
QObject::connect(
|
||||||
|
this->selectBytesAction,
|
||||||
|
&QAction::triggered,
|
||||||
|
this,
|
||||||
|
[this] {
|
||||||
|
if (this->selectedChangeListItem == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto addresses = this->selectedChangeListItem->addressRange.addresses();
|
||||||
|
this->hexViewerWidgetA->selectByteItems(addresses);
|
||||||
|
this->hexViewerWidgetB->selectByteItems(addresses);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
QObject::connect(
|
||||||
|
this->restoreBytesAction,
|
||||||
|
&QAction::triggered,
|
||||||
|
this,
|
||||||
|
[this] {
|
||||||
|
if (this->selectedChangeListItem == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit this->restoreBytesRequested(this->selectedChangeListItem->addressRange.addresses());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
this->show();
|
this->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,6 +120,10 @@ namespace Widgets
|
|||||||
this->resize(this->size());
|
this->resize(this->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChangeListPane::setRestoreEnabled(bool restoreEnabled) {
|
||||||
|
this->restoreEnabled = restoreEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
void ChangeListPane::resizeEvent(QResizeEvent* event) {
|
void ChangeListPane::resizeEvent(QResizeEvent* event) {
|
||||||
const auto size = this->size();
|
const auto size = this->size();
|
||||||
this->container->setFixedSize(size.width() - 1, size.height());
|
this->container->setFixedSize(size.width() - 1, size.height());
|
||||||
@@ -105,6 +144,9 @@ namespace Widgets
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto* item = dynamic_cast<ChangeListItem*>(selectedItems.front());
|
const auto* item = dynamic_cast<ChangeListItem*>(selectedItems.front());
|
||||||
|
assert(item != nullptr);
|
||||||
|
|
||||||
|
this->selectedChangeListItem = item;
|
||||||
|
|
||||||
this->hexViewerWidgetA->highlightPrimaryByteItemRanges({item->addressRange});
|
this->hexViewerWidgetA->highlightPrimaryByteItemRanges({item->addressRange});
|
||||||
this->hexViewerWidgetA->centerOnByte(item->addressRange.startAddress);
|
this->hexViewerWidgetA->centerOnByte(item->addressRange.startAddress);
|
||||||
@@ -113,6 +155,23 @@ namespace Widgets
|
|||||||
this->hexViewerWidgetB->centerOnByte(item->addressRange.startAddress);
|
this->hexViewerWidgetB->centerOnByte(item->addressRange.startAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChangeListPane::onItemContextMenu(ListItem *item, QPoint sourcePosition) {
|
||||||
|
auto* changeListItem = dynamic_cast<ChangeListItem*>(item);
|
||||||
|
|
||||||
|
if (changeListItem == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* menu = new QMenu(this);
|
||||||
|
|
||||||
|
menu->addAction(this->selectBytesAction);
|
||||||
|
menu->addSeparator();
|
||||||
|
menu->addAction(this->restoreBytesAction);
|
||||||
|
this->restoreBytesAction->setEnabled(this->restoreEnabled);
|
||||||
|
|
||||||
|
menu->exec(sourcePosition);
|
||||||
|
}
|
||||||
|
|
||||||
void ChangeListPane::refreshChangeListViewSize() {
|
void ChangeListPane::refreshChangeListViewSize() {
|
||||||
this->changeListView->setFixedWidth(
|
this->changeListView->setFixedWidth(
|
||||||
this->container->width() - (
|
this->container->width() - (
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QResizeEvent>
|
#include <QResizeEvent>
|
||||||
#include <QShowEvent>
|
#include <QShowEvent>
|
||||||
|
#include <QAction>
|
||||||
|
|
||||||
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/PaneWidget.hpp"
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/PaneWidget.hpp"
|
||||||
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ListView/ListView.hpp"
|
#include "src/Insight/UserInterfaces/InsightWindow/Widgets/ListView/ListView.hpp"
|
||||||
@@ -27,6 +28,10 @@ namespace Widgets
|
|||||||
);
|
);
|
||||||
|
|
||||||
void setDiffRanges(const std::vector<Targets::TargetMemoryAddressRange>& diffRanges);
|
void setDiffRanges(const std::vector<Targets::TargetMemoryAddressRange>& diffRanges);
|
||||||
|
void setRestoreEnabled(bool restoreEnabled);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void restoreBytesRequested(const std::set<Targets::TargetMemoryAddress>& addresses);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent* event) override;
|
void resizeEvent(QResizeEvent* event) override;
|
||||||
@@ -41,7 +46,15 @@ namespace Widgets
|
|||||||
ListView* changeListView = nullptr;
|
ListView* changeListView = nullptr;
|
||||||
ListScene* changeListScene = nullptr;
|
ListScene* changeListScene = nullptr;
|
||||||
|
|
||||||
|
const ChangeListItem* selectedChangeListItem = nullptr;
|
||||||
|
|
||||||
|
QAction* selectBytesAction = new QAction("Select", this);
|
||||||
|
QAction* restoreBytesAction = new QAction("Restore", this);
|
||||||
|
|
||||||
|
bool restoreEnabled = false;
|
||||||
|
|
||||||
void onItemSelectionChanged(const std::list<ListItem*>& selectedItems);
|
void onItemSelectionChanged(const std::list<ListItem*>& selectedItems);
|
||||||
|
void onItemContextMenu(ListItem* item, QPoint sourcePosition);
|
||||||
void refreshChangeListViewSize();
|
void refreshChangeListViewSize();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ namespace Widgets
|
|||||||
MemorySnapshot& snapshotA,
|
MemorySnapshot& snapshotA,
|
||||||
MemorySnapshot& snapshotB,
|
MemorySnapshot& snapshotB,
|
||||||
const Targets::TargetMemoryDescriptor& memoryDescriptor,
|
const Targets::TargetMemoryDescriptor& memoryDescriptor,
|
||||||
|
Targets::TargetState currentTargetState,
|
||||||
QWidget* parent
|
QWidget* parent
|
||||||
)
|
)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
@@ -39,8 +40,10 @@ namespace Widgets
|
|||||||
, focusedRegionsB(snapshotB.focusedRegions)
|
, focusedRegionsB(snapshotB.focusedRegions)
|
||||||
, excludedRegionsB(snapshotB.excludedRegions)
|
, excludedRegionsB(snapshotB.excludedRegions)
|
||||||
, stackPointerB(snapshotB.stackPointer)
|
, stackPointerB(snapshotB.stackPointer)
|
||||||
|
, comparingWithCurrent(false)
|
||||||
{
|
{
|
||||||
this->init();
|
this->init();
|
||||||
|
this->onTargetStateChanged(currentTargetState);
|
||||||
|
|
||||||
this->setWindowTitle(
|
this->setWindowTitle(
|
||||||
"Comparing snapshot \"" + snapshotA.name + "\" with snapshot \"" + snapshotB.name + "\""
|
"Comparing snapshot \"" + snapshotA.name + "\" with snapshot \"" + snapshotB.name + "\""
|
||||||
@@ -59,6 +62,7 @@ namespace Widgets
|
|||||||
std::vector<ExcludedMemoryRegion> excludedRegionsB,
|
std::vector<ExcludedMemoryRegion> excludedRegionsB,
|
||||||
Targets::TargetStackPointer stackPointerB,
|
Targets::TargetStackPointer stackPointerB,
|
||||||
const Targets::TargetMemoryDescriptor& memoryDescriptor,
|
const Targets::TargetMemoryDescriptor& memoryDescriptor,
|
||||||
|
Targets::TargetState currentTargetState,
|
||||||
QWidget* parent
|
QWidget* parent
|
||||||
)
|
)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
@@ -71,8 +75,10 @@ namespace Widgets
|
|||||||
, focusedRegionsB(focusedRegionsB)
|
, focusedRegionsB(focusedRegionsB)
|
||||||
, excludedRegionsB(excludedRegionsB)
|
, excludedRegionsB(excludedRegionsB)
|
||||||
, stackPointerB(stackPointerB)
|
, stackPointerB(stackPointerB)
|
||||||
|
, comparingWithCurrent(true)
|
||||||
{
|
{
|
||||||
this->init();
|
this->init();
|
||||||
|
this->onTargetStateChanged(currentTargetState);
|
||||||
|
|
||||||
this->setWindowTitle(
|
this->setWindowTitle(
|
||||||
"Comparing snapshot \"" + snapshotA.name + "\" with current memory"
|
"Comparing snapshot \"" + snapshotA.name + "\" with current memory"
|
||||||
@@ -86,7 +92,9 @@ namespace Widgets
|
|||||||
this->restoreBytesAction = new ContextMenuAction(
|
this->restoreBytesAction = new ContextMenuAction(
|
||||||
"Restore Selection",
|
"Restore Selection",
|
||||||
[this] (const std::set<Targets::TargetMemoryAddress>&) {
|
[this] (const std::set<Targets::TargetMemoryAddress>&) {
|
||||||
return this->memoryDescriptor.access.writeableDuringDebugSession;
|
return
|
||||||
|
this->memoryDescriptor.access.writeableDuringDebugSession
|
||||||
|
&& this->targetState == Targets::TargetState::STOPPED;
|
||||||
},
|
},
|
||||||
this
|
this
|
||||||
);
|
);
|
||||||
@@ -99,6 +107,15 @@ namespace Widgets
|
|||||||
this->restoreSelectedBytes(selectedByteItemAddresses, true);
|
this->restoreSelectedBytes(selectedByteItemAddresses, true);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
QObject::connect(
|
||||||
|
this->changeListPane,
|
||||||
|
&ChangeListPane::restoreBytesRequested,
|
||||||
|
this,
|
||||||
|
[this] (const std::set<Targets::TargetMemoryAddress>& addresses) {
|
||||||
|
this->restoreSelectedBytes(addresses, true);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SnapshotDiff::refreshB(
|
void SnapshotDiff::refreshB(
|
||||||
@@ -255,6 +272,13 @@ namespace Widgets
|
|||||||
this->changeListPaneState,
|
this->changeListPaneState,
|
||||||
this->leftPanel
|
this->leftPanel
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this->changeListPane->setRestoreEnabled(
|
||||||
|
this->comparingWithCurrent
|
||||||
|
&& this->memoryDescriptor.access.writeableDuringDebugSession
|
||||||
|
&& this->targetState == Targets::TargetState::STOPPED
|
||||||
|
);
|
||||||
|
|
||||||
this->leftPanel->layout()->addWidget(this->changeListPane);
|
this->leftPanel->layout()->addWidget(this->changeListPane);
|
||||||
this->viewChangeListButton->setChecked(this->changeListPane->state.activated);
|
this->viewChangeListButton->setChecked(this->changeListPane->state.activated);
|
||||||
|
|
||||||
@@ -321,6 +345,15 @@ namespace Widgets
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
auto* insightSignals = InsightSignals::instance();
|
||||||
|
|
||||||
|
QObject::connect(
|
||||||
|
insightSignals,
|
||||||
|
&InsightSignals::targetStateUpdated,
|
||||||
|
this,
|
||||||
|
&SnapshotDiff::onTargetStateChanged
|
||||||
|
);
|
||||||
|
|
||||||
QObject::connect(this->hexViewerWidgetA, &HexViewerWidget::ready, this, &SnapshotDiff::onHexViewerAReady);
|
QObject::connect(this->hexViewerWidgetA, &HexViewerWidget::ready, this, &SnapshotDiff::onHexViewerAReady);
|
||||||
QObject::connect(this->hexViewerWidgetB, &HexViewerWidget::ready, this, &SnapshotDiff::onHexViewerBReady);
|
QObject::connect(this->hexViewerWidgetB, &HexViewerWidget::ready, this, &SnapshotDiff::onHexViewerBReady);
|
||||||
|
|
||||||
@@ -557,4 +590,14 @@ namespace Widgets
|
|||||||
this->taskProgressIndicator->addTask(writeMemoryTask);
|
this->taskProgressIndicator->addTask(writeMemoryTask);
|
||||||
InsightWorker::queueTask(writeMemoryTask);
|
InsightWorker::queueTask(writeMemoryTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SnapshotDiff::onTargetStateChanged(Targets::TargetState newState) {
|
||||||
|
this->targetState = newState;
|
||||||
|
|
||||||
|
this->changeListPane->setRestoreEnabled(
|
||||||
|
this->comparingWithCurrent
|
||||||
|
&& this->memoryDescriptor.access.writeableDuringDebugSession
|
||||||
|
&& this->targetState == Targets::TargetState::STOPPED
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ namespace Widgets
|
|||||||
MemorySnapshot& snapshotA,
|
MemorySnapshot& snapshotA,
|
||||||
MemorySnapshot& snapshotB,
|
MemorySnapshot& snapshotB,
|
||||||
const Targets::TargetMemoryDescriptor& memoryDescriptor,
|
const Targets::TargetMemoryDescriptor& memoryDescriptor,
|
||||||
|
Targets::TargetState currentTargetState,
|
||||||
QWidget* parent = nullptr
|
QWidget* parent = nullptr
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -43,6 +44,7 @@ namespace Widgets
|
|||||||
std::vector<ExcludedMemoryRegion> excludedRegionsB,
|
std::vector<ExcludedMemoryRegion> excludedRegionsB,
|
||||||
Targets::TargetStackPointer stackPointerB,
|
Targets::TargetStackPointer stackPointerB,
|
||||||
const Targets::TargetMemoryDescriptor& memoryDescriptor,
|
const Targets::TargetMemoryDescriptor& memoryDescriptor,
|
||||||
|
Targets::TargetState currentTargetState,
|
||||||
QWidget* parent = nullptr
|
QWidget* parent = nullptr
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -62,6 +64,7 @@ namespace Widgets
|
|||||||
SnapshotDiffSettings settings;
|
SnapshotDiffSettings settings;
|
||||||
|
|
||||||
const Targets::TargetMemoryDescriptor& memoryDescriptor;
|
const Targets::TargetMemoryDescriptor& memoryDescriptor;
|
||||||
|
Targets::TargetState targetState = Targets::TargetState::UNKNOWN;
|
||||||
|
|
||||||
QWidget* container = nullptr;
|
QWidget* container = nullptr;
|
||||||
|
|
||||||
@@ -103,6 +106,8 @@ namespace Widgets
|
|||||||
DifferentialHexViewerWidget* hexViewerWidgetB = nullptr;
|
DifferentialHexViewerWidget* hexViewerWidgetB = nullptr;
|
||||||
HexViewerWidgetSettings hexViewerWidgetSettingsB = HexViewerWidgetSettings();
|
HexViewerWidgetSettings hexViewerWidgetSettingsB = HexViewerWidgetSettings();
|
||||||
|
|
||||||
|
bool comparingWithCurrent = false;
|
||||||
|
|
||||||
ContextMenuAction* restoreBytesAction = nullptr;
|
ContextMenuAction* restoreBytesAction = nullptr;
|
||||||
|
|
||||||
QWidget* bottomBar = nullptr;
|
QWidget* bottomBar = nullptr;
|
||||||
@@ -131,5 +136,7 @@ namespace Widgets
|
|||||||
std::set<Targets::TargetMemoryAddress> addresses,
|
std::set<Targets::TargetMemoryAddress> addresses,
|
||||||
bool confirmationPromptEnabled
|
bool confirmationPromptEnabled
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void onTargetStateChanged(Targets::TargetState newState);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -364,6 +364,7 @@ namespace Widgets
|
|||||||
snapshotItA.value(),
|
snapshotItA.value(),
|
||||||
snapshotItB.value(),
|
snapshotItB.value(),
|
||||||
this->memoryDescriptor,
|
this->memoryDescriptor,
|
||||||
|
this->targetState,
|
||||||
this
|
this
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -411,6 +412,7 @@ namespace Widgets
|
|||||||
this->excludedMemoryRegions,
|
this->excludedMemoryRegions,
|
||||||
this->stackPointer.value_or(0),
|
this->stackPointer.value_or(0),
|
||||||
this->memoryDescriptor,
|
this->memoryDescriptor,
|
||||||
|
this->targetState,
|
||||||
this
|
this
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user