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
This commit is contained in:
Florian Märkl 2017-11-04 12:46:29 +01:00 committed by Maijin
parent 0b5a351d5f
commit 46bf0761bb
8 changed files with 93 additions and 18 deletions

View File

@ -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()

View File

@ -192,6 +192,7 @@ QString CutterCore::cmd(const QString &str)
if (offset != core_->offset)
{
emit seekChanged(core_->offset);
triggerRaisePrioritizedMemoryWidget();
}
return o;
}

View File

@ -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_;

View File

@ -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]);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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() {}
/*

View File

@ -68,6 +68,7 @@ private:
private slots:
void on_seekChanged(RVA addr);
void raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type);
void highlightHexCurrentLine();
void setFonts(QFont font);