diff --git a/src/menus/DisassemblyContextMenu.cpp b/src/menus/DisassemblyContextMenu.cpp index 2cbda0b4..eb0baac6 100644 --- a/src/menus/DisassemblyContextMenu.cpp +++ b/src/menus/DisassemblyContextMenu.cpp @@ -5,23 +5,101 @@ #include "dialogs/RenameDialog.h" #include "dialogs/XrefsDialog.h" #include +#include DisassemblyContextMenu::DisassemblyContextMenu(RVA offset, QWidget *parent) : QMenu(parent), offset(offset) +{ + init(); +} + +DisassemblyContextMenu::DisassemblyContextMenu(QWidget*parent) + : QMenu(parent) +{ + init(); +} + +void DisassemblyContextMenu::setOffset(RVA offset) +{ + this->offset = offset; +} + +QKeySequence DisassemblyContextMenu::getCommentSequence() const +{ + return {";"}; +} + +QKeySequence DisassemblyContextMenu::getAddFlagSequence() const +{ + return {}; //TODO insert correct sequence +} + +QKeySequence DisassemblyContextMenu::getRenameSequence() const +{ + return {}; //TODO insert correct sequence +} + +QKeySequence DisassemblyContextMenu::getXRefSequence() const +{ + return {Qt::Key_X}; +} + +QKeySequence DisassemblyContextMenu::getDisplayOptionsSequence() const +{ + return {}; //TODO insert correct sequence +} + +void DisassemblyContextMenu::init() { actionAddComment.setText("Add comment"); this->addAction(&actionAddComment); + actionAddComment.setShortcut(getCommentSequence()); + actionAddFlag.setText("Add flag"); this->addAction(&actionAddFlag); + actionAddComment.setShortcut(getAddFlagSequence()); + actionRename.setText("Rename"); this->addAction(&actionRename); + actionAddComment.setShortcut(getRenameSequence()); + actionXRefs.setText("Show xrefs"); this->addAction(&actionXRefs); + actionAddComment.setShortcut(getXRefSequence()); + this->addSeparator(); actionDisplayOptions.setText("Show options"); + actionAddComment.setShortcut(getDisplayOptionsSequence()); this->addAction(&actionDisplayOptions); + auto pWidget = parentWidget(); + + QShortcut *shortcut_dispOptions = new QShortcut(getDisplayOptionsSequence(), pWidget); + shortcut_dispOptions->setContext(Qt::WidgetWithChildrenShortcut); + connect(shortcut_dispOptions, &QShortcut::activated, + this, &DisassemblyContextMenu::on_actionDisplayOptions_triggered); + + QShortcut *shortcut_x = new QShortcut(getXRefSequence(), pWidget); + shortcut_x->setContext(Qt::WidgetWithChildrenShortcut); + connect(shortcut_x, &QShortcut::activated, + this, &DisassemblyContextMenu::on_actionXRefs_triggered); + + QShortcut *shortcut_comment = new QShortcut(getCommentSequence(), pWidget); + shortcut_comment->setContext(Qt::WidgetWithChildrenShortcut); + connect(shortcut_comment, &QShortcut::activated, + this, &DisassemblyContextMenu::on_actionAddComment_triggered); + + QShortcut *shortcut_addFlag = new QShortcut(getAddFlagSequence(), pWidget); + shortcut_addFlag->setContext(Qt::WidgetWithChildrenShortcut); + connect(shortcut_addFlag, &QShortcut::activated, + this, &DisassemblyContextMenu::on_actionAddFlag_triggered); + + QShortcut *shortcut_renameSequence = new QShortcut(getRenameSequence(), pWidget); + shortcut_renameSequence->setContext(Qt::WidgetWithChildrenShortcut); + connect(shortcut_renameSequence, &QShortcut::activated, + this, &DisassemblyContextMenu::on_actionRename_triggered); + connect(&actionAddComment, SIGNAL(triggered(bool)), this, SLOT(on_actionAddComment_triggered())); connect(&actionAddFlag, SIGNAL(triggered(bool)), this, SLOT(on_actionAddFlag_triggered())); connect(&actionRename, SIGNAL(triggered(bool)), this, SLOT(on_actionRename_triggered())); @@ -29,10 +107,6 @@ DisassemblyContextMenu::DisassemblyContextMenu(RVA offset, QWidget *parent) : connect(&actionDisplayOptions, SIGNAL(triggered()), this, SLOT(on_actionDisplayOptions_triggered())); } -DisassemblyContextMenu::~DisassemblyContextMenu() -{ -} - void DisassemblyContextMenu::on_actionAddComment_triggered() { RAnalFunction *fcn = CutterCore::getInstance()->functionAt(offset); diff --git a/src/menus/DisassemblyContextMenu.h b/src/menus/DisassemblyContextMenu.h index 5e189a49..e347cfce 100644 --- a/src/menus/DisassemblyContextMenu.h +++ b/src/menus/DisassemblyContextMenu.h @@ -3,13 +3,33 @@ #include "cutter.h" #include +#include class DisassemblyContextMenu : public QMenu { Q_OBJECT public: DisassemblyContextMenu(RVA offset, QWidget *parent = nullptr); - ~DisassemblyContextMenu(); + ~DisassemblyContextMenu() = default; + DisassemblyContextMenu(QWidget *parent = nullptr); + +public slots: + void setOffset(RVA offset); + + void on_actionAddComment_triggered(); + void on_actionAddFlag_triggered(); + void on_actionRename_triggered(); + void on_actionXRefs_triggered(); + void on_actionDisplayOptions_triggered(); + +private: + void init(); + + QKeySequence getCommentSequence() const; + QKeySequence getAddFlagSequence() const; + QKeySequence getRenameSequence() const; + QKeySequence getXRefSequence() const; + QKeySequence getDisplayOptionsSequence() const; private: RVA offset; QAction actionAddComment; @@ -17,12 +37,5 @@ private: QAction actionRename; QAction actionXRefs; QAction actionDisplayOptions; - -private slots: - void on_actionAddComment_triggered(); - void on_actionAddFlag_triggered(); - void on_actionRename_triggered(); - void on_actionXRefs_triggered(); - void on_actionDisplayOptions_triggered(); }; #endif // DISASSEMBLYCONTEXTMENU_H diff --git a/src/widgets/DisassemblerGraphView.cpp b/src/widgets/DisassemblerGraphView.cpp index a836e61a..2b3c8953 100644 --- a/src/widgets/DisassemblerGraphView.cpp +++ b/src/widgets/DisassemblerGraphView.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -29,7 +30,7 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent) mHistoryLock(false), layoutType(LayoutType::Medium), mGoto(nullptr), - mXrefDlg(nullptr) + mMenu(new DisassemblyContextMenu(this)) { this->status = "Loading..."; @@ -661,15 +662,16 @@ void DisassemblerGraphView::mousePressEvent(QMouseEvent* event) //Update current instruction duint instr = this->getInstrForMouseEvent(event); - if(instr != 0) + if(instr != 0) { this->cur_instr = instr; + emit currentInstructionUpdated(instr); + } this->viewport()->update(); if(event->button() == Qt::RightButton) { - DisassemblyContextMenu cMenu(instr, this); - cMenu.exec(event->globalPos()); //execute context menu + mMenu->exec(event->globalPos()); //execute context menu } } else if(event->button() == Qt::LeftButton) @@ -1676,10 +1678,9 @@ void DisassemblerGraphView::addReferenceAction(QMenu* menu, duint addr) void DisassemblerGraphView::setupContextMenu() { + connect(this, &DisassemblerGraphView::currentInstructionUpdated, + mMenu, &DisassemblyContextMenu::setOffset); // TODO make this prettier - QShortcut *shortcut_x = new QShortcut(QKeySequence(Qt::Key_X), this); - shortcut_x->setContext(Qt::WidgetShortcut); - connect(shortcut_x, SIGNAL(activated()), this, SLOT(xrefSlot())); QShortcut *shortcut_escape = new QShortcut(QKeySequence(Qt::Key_Escape), this); shortcut_escape->setContext(Qt::WidgetShortcut); @@ -2030,14 +2031,6 @@ restart: */ } -void DisassemblerGraphView::xrefSlot() -{ - RVA addr = this->get_cursor_pos(); - XrefsDialog *dialog = new XrefsDialog(this); - dialog->fillRefsForAddress(addr, RAddressString(addr), false); - dialog->exec(); -} - void DisassemblerGraphView::decompileSlot() { /*std::vector ranges; diff --git a/src/widgets/DisassemblerGraphView.h b/src/widgets/DisassemblerGraphView.h index a6ab161b..bc128a52 100644 --- a/src/widgets/DisassemblerGraphView.h +++ b/src/widgets/DisassemblerGraphView.h @@ -29,6 +29,7 @@ class MenuBuilder; class CachedFontMetrics; class GotoDialog; class XrefBrowseDialog; +class DisassemblyContextMenu; class DisassemblerGraphView : public QAbstractScrollArea { @@ -255,6 +256,7 @@ public: signals: void displaySnowmanWidget(); + void currentInstructionUpdated(duint); public slots: void updateTimerEvent(); @@ -282,7 +284,6 @@ public slots: void saveImageSlot(); void setCommentSlot(); void setLabelSlot(); - void xrefSlot(); void decompileSlot(); void seekPrev(); @@ -358,7 +359,7 @@ private: std::unordered_map currentBlockMap; //QBeaEngine disasm; GotoDialog* mGoto; - XrefBrowseDialog* mXrefDlg; + DisassemblyContextMenu* mMenu; void addReferenceAction(QMenu* menu, duint addr); }; diff --git a/src/widgets/DisassemblyWidget.cpp b/src/widgets/DisassemblyWidget.cpp index 9bb441ce..33ab4d75 100644 --- a/src/widgets/DisassemblyWidget.cpp +++ b/src/widgets/DisassemblyWidget.cpp @@ -1,6 +1,5 @@ #include "DisassemblyWidget.h" #include "menus/DisassemblyContextMenu.h" -#include "dialogs/XrefsDialog.h" #include "utils/HexAsciiHighlighter.h" #include "utils/HexHighlighter.h" #include "utils/Configuration.h" @@ -9,12 +8,14 @@ #include #include #include +#include -DisassemblyWidget::DisassemblyWidget(QWidget *parent) : - QDockWidget(parent), - mDisasScrollArea(new DisassemblyScrollArea(this)), - mDisasTextEdit(new DisassemblyTextEdit(this)) +DisassemblyWidget::DisassemblyWidget(QWidget *parent) + : QDockWidget(parent) + , mCtxMenu(new DisassemblyContextMenu(this)) + , mDisasScrollArea(new DisassemblyScrollArea(this)) + , mDisasTextEdit(new DisassemblyTextEdit(this)) { topOffset = bottomOffset = RVA_INVALID; @@ -49,16 +50,9 @@ DisassemblyWidget::DisassemblyWidget(QWidget *parent) : connect(mDisasTextEdit, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(showDisasContextMenu(const QPoint &))); - // x to show XRefs - QShortcut *shortcut_x = new QShortcut(QKeySequence(Qt::Key_X), mDisasTextEdit); - shortcut_x->setContext(Qt::WidgetShortcut); - connect(shortcut_x, SIGNAL(activated()), this, SLOT(showXrefsDialog())); - - maxLines = 0; updateMaxLines(); - connect(mDisasScrollArea, SIGNAL(scrollLines(int)), this, SLOT(scrollInstructions(int))); connect(mDisasScrollArea, SIGNAL(disassemblyResized()), this, SLOT(updateMaxLines())); @@ -243,12 +237,12 @@ void DisassemblyWidget::highlightCurrentLine() cursor2.endEditBlock(); mDisasTextEdit->setExtraSelections(extraSelections); + mCtxMenu->setOffset(readCurrentDisassemblyOffset()); } void DisassemblyWidget::showDisasContextMenu(const QPoint &pt) { - DisassemblyContextMenu menu(this->readCurrentDisassemblyOffset(), mDisasTextEdit); - menu.exec(mDisasTextEdit->mapToGlobal(pt)); + mCtxMenu->exec(mDisasTextEdit->mapToGlobal(pt)); } RVA DisassemblyWidget::readCurrentDisassemblyOffset() @@ -398,6 +392,7 @@ void DisassemblyWidget::on_seekChanged(RVA offset) this->raise(); } + if (topOffset != RVA_INVALID && bottomOffset != RVA_INVALID && offset >= topOffset && offset <= bottomOffset) { @@ -409,6 +404,7 @@ void DisassemblyWidget::on_seekChanged(RVA offset) // otherwise scroll there refreshDisasm(offset); } + mCtxMenu->setOffset(offset); } void DisassemblyWidget::fontsUpdatedSlot() @@ -417,22 +413,6 @@ void DisassemblyWidget::fontsUpdatedSlot() refreshDisasm(); } -void DisassemblyWidget::showXrefsDialog() -{ - // Get current offset - QTextCursor tc = mDisasTextEdit->textCursor(); - tc.select(QTextCursor::LineUnderCursor); - QString lastline = tc.selectedText(); - QString ele = lastline.split(" ", QString::SkipEmptyParts)[0]; - if (ele.contains("0x")) - { - RVA addr = ele.toLongLong(0, 16); - XrefsDialog *dialog = new XrefsDialog(this); - dialog->fillRefsForAddress(addr, RAddressString(addr), false); - dialog->exec(); - } -} - DisassemblyScrollArea::DisassemblyScrollArea(QWidget *parent) : QAbstractScrollArea(parent) { } diff --git a/src/widgets/DisassemblyWidget.h b/src/widgets/DisassemblyWidget.h index da5f0c88..e217fd78 100644 --- a/src/widgets/DisassemblyWidget.h +++ b/src/widgets/DisassemblyWidget.h @@ -3,12 +3,14 @@ #include "cutter.h" #include +#include #include #include class DisassemblyTextEdit; class DisassemblyScrollArea; +class DisassemblyContextMenu; class DisassemblyWidget : public QDockWidget { @@ -24,7 +26,6 @@ public slots: void on_seekChanged(RVA offset); void refreshDisasm(RVA offset = RVA_INVALID); void fontsUpdatedSlot(); - void showXrefsDialog(); private slots: void scrollInstructions(int count); @@ -33,6 +34,7 @@ private slots: void cursorPositionChanged(); private: + DisassemblyContextMenu *mCtxMenu; DisassemblyScrollArea *mDisasScrollArea; DisassemblyTextEdit *mDisasTextEdit;