diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.cpp index 053f4802..7d651686 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.cpp @@ -242,6 +242,10 @@ namespace Widgets this->byteItemGraphicsScene->addExternalContextMenuAction(action); } + void HexViewerWidget::selectByteItems(const std::set& addresses) { + this->byteItemGraphicsScene->selectByteItems(addresses); + } + void HexViewerWidget::highlightPrimaryByteItemRanges( const std::set& addressRanges ) { diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.hpp index f0cf9cf9..a5083708 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/HexViewerWidget/HexViewerWidget.hpp @@ -42,6 +42,7 @@ namespace Widgets void refreshRegions(); void setStackPointer(Targets::TargetStackPointer stackPointer); void addExternalContextMenuAction(ContextMenuAction* action); + void selectByteItems(const std::set& addresses); void highlightPrimaryByteItemRanges(const std::set& addressRanges); void clearHighlighting(); void centerOnByte(Targets::TargetMemoryAddress address); diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/ChangeListPane/ChangeListPane.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/ChangeListPane/ChangeListPane.cpp index 627f8ea7..df5cf55b 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/ChangeListPane/ChangeListPane.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/ChangeListPane/ChangeListPane.cpp @@ -69,6 +69,41 @@ namespace Widgets &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(); } @@ -85,6 +120,10 @@ namespace Widgets this->resize(this->size()); } + void ChangeListPane::setRestoreEnabled(bool restoreEnabled) { + this->restoreEnabled = restoreEnabled; + } + void ChangeListPane::resizeEvent(QResizeEvent* event) { const auto size = this->size(); this->container->setFixedSize(size.width() - 1, size.height()); @@ -105,6 +144,9 @@ namespace Widgets } const auto* item = dynamic_cast(selectedItems.front()); + assert(item != nullptr); + + this->selectedChangeListItem = item; this->hexViewerWidgetA->highlightPrimaryByteItemRanges({item->addressRange}); this->hexViewerWidgetA->centerOnByte(item->addressRange.startAddress); @@ -113,6 +155,23 @@ namespace Widgets this->hexViewerWidgetB->centerOnByte(item->addressRange.startAddress); } + void ChangeListPane::onItemContextMenu(ListItem *item, QPoint sourcePosition) { + auto* changeListItem = dynamic_cast(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() { this->changeListView->setFixedWidth( this->container->width() - ( diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/ChangeListPane/ChangeListPane.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/ChangeListPane/ChangeListPane.hpp index c5b91769..3d8125ba 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/ChangeListPane/ChangeListPane.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/ChangeListPane/ChangeListPane.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "src/Insight/UserInterfaces/InsightWindow/Widgets/PaneWidget.hpp" #include "src/Insight/UserInterfaces/InsightWindow/Widgets/ListView/ListView.hpp" @@ -27,6 +28,10 @@ namespace Widgets ); void setDiffRanges(const std::vector& diffRanges); + void setRestoreEnabled(bool restoreEnabled); + + signals: + void restoreBytesRequested(const std::set& addresses); protected: void resizeEvent(QResizeEvent* event) override; @@ -41,7 +46,15 @@ namespace Widgets ListView* changeListView = 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& selectedItems); + void onItemContextMenu(ListItem* item, QPoint sourcePosition); void refreshChangeListViewSize(); }; } diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/SnapshotDiff.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/SnapshotDiff.cpp index 8a13f4d3..b81e8509 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/SnapshotDiff.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/SnapshotDiff.cpp @@ -27,6 +27,7 @@ namespace Widgets MemorySnapshot& snapshotA, MemorySnapshot& snapshotB, const Targets::TargetMemoryDescriptor& memoryDescriptor, + Targets::TargetState currentTargetState, QWidget* parent ) : QWidget(parent) @@ -39,8 +40,10 @@ namespace Widgets , focusedRegionsB(snapshotB.focusedRegions) , excludedRegionsB(snapshotB.excludedRegions) , stackPointerB(snapshotB.stackPointer) + , comparingWithCurrent(false) { this->init(); + this->onTargetStateChanged(currentTargetState); this->setWindowTitle( "Comparing snapshot \"" + snapshotA.name + "\" with snapshot \"" + snapshotB.name + "\"" @@ -59,6 +62,7 @@ namespace Widgets std::vector excludedRegionsB, Targets::TargetStackPointer stackPointerB, const Targets::TargetMemoryDescriptor& memoryDescriptor, + Targets::TargetState currentTargetState, QWidget* parent ) : QWidget(parent) @@ -71,8 +75,10 @@ namespace Widgets , focusedRegionsB(focusedRegionsB) , excludedRegionsB(excludedRegionsB) , stackPointerB(stackPointerB) + , comparingWithCurrent(true) { this->init(); + this->onTargetStateChanged(currentTargetState); this->setWindowTitle( "Comparing snapshot \"" + snapshotA.name + "\" with current memory" @@ -86,7 +92,9 @@ namespace Widgets this->restoreBytesAction = new ContextMenuAction( "Restore Selection", [this] (const std::set&) { - return this->memoryDescriptor.access.writeableDuringDebugSession; + return + this->memoryDescriptor.access.writeableDuringDebugSession + && this->targetState == Targets::TargetState::STOPPED; }, this ); @@ -99,6 +107,15 @@ namespace Widgets this->restoreSelectedBytes(selectedByteItemAddresses, true); } ); + + QObject::connect( + this->changeListPane, + &ChangeListPane::restoreBytesRequested, + this, + [this] (const std::set& addresses) { + this->restoreSelectedBytes(addresses, true); + } + ); } void SnapshotDiff::refreshB( @@ -255,6 +272,13 @@ namespace Widgets this->changeListPaneState, this->leftPanel ); + + this->changeListPane->setRestoreEnabled( + this->comparingWithCurrent + && this->memoryDescriptor.access.writeableDuringDebugSession + && this->targetState == Targets::TargetState::STOPPED + ); + this->leftPanel->layout()->addWidget(this->changeListPane); 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->hexViewerWidgetB, &HexViewerWidget::ready, this, &SnapshotDiff::onHexViewerBReady); @@ -557,4 +590,14 @@ namespace Widgets this->taskProgressIndicator->addTask(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 + ); + } } diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/SnapshotDiff.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/SnapshotDiff.hpp index 2ad9d730..59629b45 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/SnapshotDiff.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotDiff/SnapshotDiff.hpp @@ -33,6 +33,7 @@ namespace Widgets MemorySnapshot& snapshotA, MemorySnapshot& snapshotB, const Targets::TargetMemoryDescriptor& memoryDescriptor, + Targets::TargetState currentTargetState, QWidget* parent = nullptr ); @@ -43,6 +44,7 @@ namespace Widgets std::vector excludedRegionsB, Targets::TargetStackPointer stackPointerB, const Targets::TargetMemoryDescriptor& memoryDescriptor, + Targets::TargetState currentTargetState, QWidget* parent = nullptr ); @@ -62,6 +64,7 @@ namespace Widgets SnapshotDiffSettings settings; const Targets::TargetMemoryDescriptor& memoryDescriptor; + Targets::TargetState targetState = Targets::TargetState::UNKNOWN; QWidget* container = nullptr; @@ -103,6 +106,8 @@ namespace Widgets DifferentialHexViewerWidget* hexViewerWidgetB = nullptr; HexViewerWidgetSettings hexViewerWidgetSettingsB = HexViewerWidgetSettings(); + bool comparingWithCurrent = false; + ContextMenuAction* restoreBytesAction = nullptr; QWidget* bottomBar = nullptr; @@ -131,5 +136,7 @@ namespace Widgets std::set addresses, bool confirmationPromptEnabled ); + + void onTargetStateChanged(Targets::TargetState newState); }; } diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotManager.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotManager.cpp index 72e25b73..4c6dcddb 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotManager.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/SnapshotManager/SnapshotManager.cpp @@ -364,6 +364,7 @@ namespace Widgets snapshotItA.value(), snapshotItB.value(), this->memoryDescriptor, + this->targetState, this ) ); @@ -411,6 +412,7 @@ namespace Widgets this->excludedMemoryRegions, this->stackPointer.value_or(0), this->memoryDescriptor, + this->targetState, this ) );