From 46bf0761bb682b081d59447abb75c671a84569f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Sat, 4 Nov 2017 12:46:29 +0100 Subject: [PATCH] Dynamic Memory Widget Priority (#86) * Memory Widget priority from last user-selected widget * CutterCore::raisePrioritizedMemoryWidget signal * Space shortcut to switch between Disassembly/Graph * Set default memory widget priority to Disassembly --- src/MainWindow.cpp | 15 +++++++++ src/cutter.cpp | 1 + src/cutter.h | 12 ++++++-- src/widgets/DisassemblerGraphView.cpp | 15 ++++++--- src/widgets/DisassemblyWidget.cpp | 44 +++++++++++++++++++++------ src/widgets/DisassemblyWidget.h | 5 ++- src/widgets/HexdumpWidget.cpp | 18 +++++++++++ src/widgets/HexdumpWidget.h | 1 + 8 files changed, 93 insertions(+), 18 deletions(-) diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index b0339df3..0ad7611f 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -205,6 +205,19 @@ void MainWindow::initUI() graphDock->setAllowedAreas(Qt::AllDockWidgetAreas); graphView = new DisassemblerGraphView(graphDock); graphDock->setWidget(graphView); + connect(graphDock, &QDockWidget::visibilityChanged, graphDock, [](bool visibility) { + if (visibility) + { + Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Graph); + } + }); + connect(Core(), &CutterCore::raisePrioritizedMemoryWidget, graphDock, [=](CutterCore::MemoryWidgetType type) { + if (type == CutterCore::MemoryWidgetType::Graph) + { + graphDock->raise(); + graphView->setFocus(); + } + }); dockWidgets.push_back(graphDock); // Add Sections dock panel @@ -815,6 +828,8 @@ void MainWindow::resetToDefaultLayout() restoreFunctionDock.restoreWidth(functionsDock->widget()); restoreSidebarDock.restoreWidth(sidebarDock->widget()); + + Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Disassembly); } void MainWindow::on_actionDefaut_triggered() diff --git a/src/cutter.cpp b/src/cutter.cpp index 469a4f79..099ad4ed 100644 --- a/src/cutter.cpp +++ b/src/cutter.cpp @@ -192,6 +192,7 @@ QString CutterCore::cmd(const QString &str) if (offset != core_->offset) { emit seekChanged(core_->offset); + triggerRaisePrioritizedMemoryWidget(); } return o; } diff --git a/src/cutter.h b/src/cutter.h index 68c1b895..99552b6d 100644 --- a/src/cutter.h +++ b/src/cutter.h @@ -218,9 +218,11 @@ public: RVA prevOpAddr(RVA startAddr, int count); RVA nextOpAddr(RVA startAddr, int count); - // Graph - Disassembly view priority - bool graphPriority = false; - bool graphDisplay = false; + // Disassembly/Graph/Hexdump view priority + enum class MemoryWidgetType { Disassembly, Graph, Hexdump }; + MemoryWidgetType getMemoryWidgetPriority() const { return memoryWidgetPriority; } + void setMemoryWidgetPriority(MemoryWidgetType type) { memoryWidgetPriority = type; } + void triggerRaisePrioritizedMemoryWidget() { emit raisePrioritizedMemoryWidget(memoryWidgetPriority); } ut64 math(const QString &expr); QString itoa(ut64 num, int rdx = 16); @@ -329,6 +331,8 @@ signals: */ void seekChanged(RVA offset); + void raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type); + public slots: private: @@ -336,6 +340,8 @@ private: QString default_cpu; int default_bits; + MemoryWidgetType memoryWidgetPriority; + QString notes; RCore *core_; diff --git a/src/widgets/DisassemblerGraphView.cpp b/src/widgets/DisassemblerGraphView.cpp index 2b3c8953..e9bd1a01 100644 --- a/src/widgets/DisassemblerGraphView.cpp +++ b/src/widgets/DisassemblerGraphView.cpp @@ -77,6 +77,15 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent) //Setup context menu setupContextMenu(); + + // Space to switch to disassembly + QShortcut *disassemblyShortcut = new QShortcut(QKeySequence(Qt::Key_Space), this); + disassemblyShortcut->setContext(Qt::WidgetShortcut); + connect(disassemblyShortcut, &QShortcut::activated, this, []{ + Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Disassembly); + Core()->triggerRaisePrioritizedMemoryWidget(); + }); + //Connect to bridge connect(Core(), SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA))); //connect(Bridge::getBridge(), SIGNAL(loadGraph(BridgeCFGraphList*, duint)), this, SLOT(loadGraphSlot(BridgeCFGraphList*, duint))); @@ -1645,11 +1654,7 @@ void DisassemblerGraphView::on_seekChanged(RVA addr) { Q_UNUSED(addr); loadCurrentGraph(); - Function f = this->analysis.functions[this->function]; - Core()->graphDisplay = f.blocks.size() > 0; - if (Core()->graphDisplay && Core()->graphPriority) { - this->parentWidget()->raise(); - } + this->renderFunction(this->analysis.functions[this->function]); } diff --git a/src/widgets/DisassemblyWidget.cpp b/src/widgets/DisassemblyWidget.cpp index 33ab4d75..087f935c 100644 --- a/src/widgets/DisassemblyWidget.cpp +++ b/src/widgets/DisassemblyWidget.cpp @@ -53,6 +53,16 @@ DisassemblyWidget::DisassemblyWidget(QWidget *parent) maxLines = 0; updateMaxLines(); + + // Space to switch to graph + QShortcut *graphShortcut = new QShortcut(QKeySequence(Qt::Key_Space), this); + graphShortcut->setContext(Qt::WidgetWithChildrenShortcut); + connect(graphShortcut, &QShortcut::activated, this, []{ + Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Graph); + Core()->triggerRaisePrioritizedMemoryWidget(); + }); + + connect(mDisasScrollArea, SIGNAL(scrollLines(int)), this, SLOT(scrollInstructions(int))); connect(mDisasScrollArea, SIGNAL(disassemblyResized()), this, SLOT(updateMaxLines())); @@ -64,10 +74,18 @@ DisassemblyWidget::DisassemblyWidget(QWidget *parent) } }); - // Seek signal - connect(CutterCore::getInstance(), SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA))); - connect(CutterCore::getInstance(), SIGNAL(commentsChanged()), this, SLOT(refreshDisasm())); + connect(Core(), SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA))); + connect(Core(), SIGNAL(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)), this, SLOT(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType))); + connect(Core(), SIGNAL(commentsChanged()), this, SLOT(refreshDisasm())); + connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdatedSlot())); + + connect(this, &QDockWidget::visibilityChanged, this, [](bool visibility) { + if (visibility) + { + Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Disassembly); + } + }); } DisassemblyWidget::DisassemblyWidget(const QString &title, QWidget *parent) : @@ -387,12 +405,6 @@ bool DisassemblyWidget::eventFilter(QObject *obj, QEvent *event) void DisassemblyWidget::on_seekChanged(RVA offset) { - Q_UNUSED(offset); - if (!Core()->graphDisplay || !Core()->graphPriority) { - this->raise(); - } - - if (topOffset != RVA_INVALID && bottomOffset != RVA_INVALID && offset >= topOffset && offset <= bottomOffset) { @@ -407,6 +419,15 @@ void DisassemblyWidget::on_seekChanged(RVA offset) mCtxMenu->setOffset(offset); } +void DisassemblyWidget::raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type) +{ + if (type == CutterCore::MemoryWidgetType::Disassembly) + { + raise(); + setFocus(); + } +} + void DisassemblyWidget::fontsUpdatedSlot() { mDisasTextEdit->setFont(Config()->getFont()); @@ -460,3 +481,8 @@ void DisassemblyTextEdit::scrollContentsBy(int dx, int dy) QPlainTextEdit::scrollContentsBy(dx, dy); } } + +void DisassemblyTextEdit::keyPressEvent(QKeyEvent *event) +{ + //QPlainTextEdit::keyPressEvent(event); +} diff --git a/src/widgets/DisassemblyWidget.h b/src/widgets/DisassemblyWidget.h index e217fd78..fa0c5149 100644 --- a/src/widgets/DisassemblyWidget.h +++ b/src/widgets/DisassemblyWidget.h @@ -23,11 +23,13 @@ public: public slots: void highlightCurrentLine(); void showDisasContextMenu(const QPoint &pt); - void on_seekChanged(RVA offset); void refreshDisasm(RVA offset = RVA_INVALID); void fontsUpdatedSlot(); private slots: + void on_seekChanged(RVA offset); + void raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type); + void scrollInstructions(int count); void updateMaxLines(); @@ -84,6 +86,7 @@ public: protected: bool viewportEvent(QEvent *event) override; void scrollContentsBy(int dx, int dy) override; + void keyPressEvent(QKeyEvent *event) override; private: bool lockScroll; diff --git a/src/widgets/HexdumpWidget.cpp b/src/widgets/HexdumpWidget.cpp index f6deb4c3..b9d9e0b6 100644 --- a/src/widgets/HexdumpWidget.cpp +++ b/src/widgets/HexdumpWidget.cpp @@ -75,6 +75,14 @@ HexdumpWidget::HexdumpWidget(QWidget *parent, Qt::WindowFlags flags) : connect(this->hexASCIIText->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hexScrolled())); connect(core, SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA))); + connect(Core(), SIGNAL(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)), this, SLOT(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType))); + + connect(this, &QDockWidget::visibilityChanged, this, [](bool visibility) { + if (visibility) + { + Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Hexdump); + } + }); fillPlugins(); } @@ -91,6 +99,16 @@ void HexdumpWidget::on_seekChanged(RVA addr) refresh(addr); } + +void HexdumpWidget::raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type) +{ + if (type == CutterCore::MemoryWidgetType::Hexdump) + { + raise(); + } +} + + HexdumpWidget::~HexdumpWidget() {} /* diff --git a/src/widgets/HexdumpWidget.h b/src/widgets/HexdumpWidget.h index 10428a1d..c881eb54 100644 --- a/src/widgets/HexdumpWidget.h +++ b/src/widgets/HexdumpWidget.h @@ -68,6 +68,7 @@ private: private slots: void on_seekChanged(RVA addr); + void raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type); void highlightHexCurrentLine(); void setFonts(QFont font);