GUI: implement context menus for adding/deleting loops
This commit is contained in:
parent
b9b8e52c4e
commit
7bdec6f195
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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+*"));
|
||||
|
|
Loading…
Reference in New Issue