1
0
Fork 0

GUI: implement context menus for adding/deleting loops

This commit is contained in:
Duncan Ogilvie 2020-06-03 11:06:57 +02:00
parent b9b8e52c4e
commit 7bdec6f195
3 changed files with 41 additions and 0 deletions

View File

@ -432,6 +432,11 @@ void CPUDisassembly::setupRightClickContextMenu()
toggleArgumentAction->setText(tr("Delete argument"));
return true;
});
analysisMenu->addAction(makeShortcutAction(tr("Add loop"), SLOT(addLoopSlot()), "ActionAddLoop"));
analysisMenu->addAction(makeShortcutAction(tr("Delete loop"), SLOT(deleteLoopSlot()), "ActionDeleteLoop"), [this](QMenu*)
{
return findDeepestLoopDepth(rvaToVa(getSelectionStart())) >= 0;
});
analysisMenu->addAction(makeShortcutAction(DIcon("analysis_single_function.png"), tr("Analyze single function"), SLOT(analyzeSingleFunctionSlot()), "ActionAnalyzeSingleFunction"));
analysisMenu->addSeparator();
@ -893,6 +898,29 @@ void CPUDisassembly::toggleArgumentSlot()
}
}
void CPUDisassembly::addLoopSlot()
{
if(!DbgIsDebugging())
return;
duint start = rvaToVa(getSelectionStart());
duint end = rvaToVa(getSelectionEnd());
if(start == end)
return;
auto depth = findDeepestLoopDepth(start);
DbgCmdExec(QString("loopadd %1, %2").arg(ToPtrString(start)).arg(ToPtrString(end)).arg(depth));
}
void CPUDisassembly::deleteLoopSlot()
{
if(!DbgIsDebugging())
return;
duint start = rvaToVa(getSelectionStart());
auto depth = findDeepestLoopDepth(start);
if(depth < 0)
return;
DbgCmdExec(QString("loopdel %1, .%2").arg(ToPtrString(start)).arg(depth));
}
void CPUDisassembly::assembleSlot()
{
if(!DbgIsDebugging())
@ -1763,6 +1791,14 @@ void CPUDisassembly::paintEvent(QPaintEvent* event)
Disassembly::paintEvent(event);
}
int CPUDisassembly::findDeepestLoopDepth(duint addr)
{
for(int depth = 0; ; depth++)
if(!DbgLoopGet(depth, addr, nullptr, nullptr))
return depth - 1;
return -1; // unreachable
}
bool CPUDisassembly::getLabelsFromInstruction(duint addr, QSet<QString> & labels)
{
BASIC_INSTRUCTION_INFO basicinfo;

View File

@ -45,6 +45,8 @@ public slots:
void setBookmarkSlot();
void toggleFunctionSlot();
void toggleArgumentSlot();
void addLoopSlot();
void deleteLoopSlot();
void assembleSlot();
void gotoExpressionSlot();
void gotoFileOffsetSlot();
@ -116,6 +118,7 @@ protected:
void paintEvent(QPaintEvent* event) override;
private:
int findDeepestLoopDepth(duint addr);
bool getLabelsFromInstruction(duint addr, QSet<QString> & labels);
bool getTokenValueText(QString & text);

View File

@ -486,6 +486,8 @@ Configuration::Configuration() : QObject(), noMoreMsgbox(false)
defaultShortcuts.insert("ActionSetLabelOperand", Shortcut({tr("Actions"), tr("Set Label for the Operand")}, "Alt+;"));
defaultShortcuts.insert("ActionSetComment", Shortcut({tr("Actions"), tr("Set Comment")}, ";"));
defaultShortcuts.insert("ActionToggleFunction", Shortcut({tr("Actions"), tr("Toggle Function")}, "Shift+F"));
defaultShortcuts.insert("ActionAddLoop", Shortcut({tr("Actions"), tr("Add Loop")}, "Shift+L"));
defaultShortcuts.insert("ActionDeleteLoop", Shortcut({tr("Actions"), tr("Delete Loop")}, "Ctrl+Shift+L"));
defaultShortcuts.insert("ActionToggleArgument", Shortcut({tr("Actions"), tr("Toggle Argument")}, "Shift+A"));
defaultShortcuts.insert("ActionAssemble", Shortcut({tr("Actions"), tr("Assemble")}, "Space"));
defaultShortcuts.insert("ActionSetNewOriginHere", Shortcut({tr("Actions"), tr("Set New Origin Here")}, "Ctrl+*"));