Skelton for dedicated context menu + action to copy selection (#2256)

This commit is contained in:
NIRMAL MANOJ C 2020-06-23 01:55:30 +05:30
parent 2e573cc171
commit ea9f3f1831
5 changed files with 128 additions and 10 deletions

View File

@ -336,6 +336,7 @@ SOURCES += \
widgets/StringsWidget.cpp \
widgets/SymbolsWidget.cpp \
menus/DisassemblyContextMenu.cpp \
menus/DecompilerContextMenu.cpp \
widgets/DisassemblyWidget.cpp \
widgets/HexdumpWidget.cpp \
common/Configuration.cpp \
@ -485,6 +486,7 @@ HEADERS += \
widgets/StringsWidget.h \
widgets/SymbolsWidget.h \
menus/DisassemblyContextMenu.h \
menus/DecompilerContextMenu.h \
widgets/DisassemblyWidget.h \
widgets/HexdumpWidget.h \
common/Configuration.h \

View File

@ -0,0 +1,59 @@
#include "DecompilerContextMenu.h"
#include "dialogs/preferences/PreferencesDialog.h"
#include "MainWindow.h"
#include <QtCore>
#include <QShortcut>
#include <QJsonArray>
#include <QClipboard>
#include <QApplication>
#include <QPushButton>
DecompilerContextMenu::DecompilerContextMenu(QWidget *parent, MainWindow *mainWindow)
: QMenu(parent),
offset(0),
mainWindow(mainWindow),
actionCopy(tr("Copy"), this)
{
setActionCopy();
addSeparator();
connect(this, &DecompilerContextMenu::aboutToShow,
this, &DecompilerContextMenu::aboutToShowSlot);
}
DecompilerContextMenu::~DecompilerContextMenu()
{
}
void DecompilerContextMenu::setOffset(RVA offset)
{
this->offset = offset;
// this->actionSetFunctionVarTypes.setVisible(true);
}
void DecompilerContextMenu::setCanCopy(bool enabled)
{
actionCopy.setVisible(enabled);
}
void DecompilerContextMenu::aboutToShowSlot()
{
}
// Set up actions
void DecompilerContextMenu::setActionCopy(){
connect(&actionCopy, &QAction::triggered, this, &DecompilerContextMenu::actionCopyTriggered);
addAction(&actionCopy);
actionCopy.setShortcut(QKeySequence::Copy);
actionCopy.setShortcutContext(Qt::WidgetWithChildrenShortcut);
}
// Set up action responses
void DecompilerContextMenu::actionCopyTriggered()
{
emit copy();
}

View File

@ -0,0 +1,59 @@
#ifndef DECOMPILERCONTEXTMENU_H
#define DECOMPILERCONTEXTMENU_H
#include "core/Cutter.h"
#include <QMenu>
#include <QKeySequence>
class DecompilerContextMenu : public QMenu
{
Q_OBJECT
public:
DecompilerContextMenu(QWidget *parent, MainWindow *mainWindow);
~DecompilerContextMenu();
signals:
void copy();
public slots:
void setOffset(RVA offset);
void setCanCopy(bool enabled);
private slots:
void aboutToShowSlot();
void actionCopyTriggered();
private:
QKeySequence getCopySequence() const;
RVA offset;
MainWindow *mainWindow;
QAction actionCopy;
QAction *copySeparator;
void setActionCopy();
// I left out the following part from RAnnotatedCode. Probably, we will be returning/passing annotations
// from/to the function getThingUsedHere() and updateTargetMenuActions(). This block of comment will get removed in
// future PRs.
//
// struct ThingUsedHere {
// QString name;
// RVA offset;
// enum class Type {
// Var,
// Function,
// Flag,
// Address
// };
// Type type;
// };
// QVector<ThingUsedHere> getThingUsedHere(RVA offset);
// void updateTargetMenuActions(const QVector<ThingUsedHere> &targets);
};
#endif // DECOMPILERCONTEXTMENU_H

View File

@ -1,6 +1,6 @@
#include "DecompilerWidget.h"
#include "ui_DecompilerWidget.h"
#include "menus/DisassemblyContextMenu.h"
#include "menus/DecompilerContextMenu.h"
#include "common/Configuration.h"
#include "common/Helpers.h"
@ -17,7 +17,7 @@
DecompilerWidget::DecompilerWidget(MainWindow *main) :
MemoryDockWidget(MemoryWidgetType::Decompiler, main),
mCtxMenu(new DisassemblyContextMenu(this, main)),
mCtxMenu(new DecompilerContextMenu(this, main)),
ui(new Ui::DecompilerWidget),
code(Decompiler::makeWarning(tr("Choose an offset and refresh to get decompiled code")), &r_annotated_code_free)
{
@ -34,6 +34,7 @@ DecompilerWidget::DecompilerWidget(MainWindow *main) :
connect(Config(), &Configuration::fontsUpdated, this, &DecompilerWidget::fontsUpdatedSlot);
connect(Config(), &Configuration::colorsUpdated, this, &DecompilerWidget::colorsUpdatedSlot);
connect(Core(), &CutterCore::registersChanged, this, &DecompilerWidget::highlightPC);
connect(mCtxMenu, &DecompilerContextMenu::copy, ui->textEdit, &QPlainTextEdit::copy);
decompiledFunctionAddr = RVA_INVALID;
decompilerWasBusy = false;
@ -61,7 +62,6 @@ DecompilerWidget::DecompilerWidget(MainWindow *main) :
// If no decompiler was previously chosen. set r2ghidra as default decompiler
selectedDecompilerId = "r2ghidra";
}
for (auto dec : decompilers) {
ui->decompilerComboBox->addItem(dec->getName(), dec->getId());
if (dec->getId() == selectedDecompilerId) {
@ -278,12 +278,11 @@ void DecompilerWidget::connectCursorPositionChanged(bool disconnect)
void DecompilerWidget::cursorPositionChanged()
{
mCtxMenu->setCanCopy(ui->textEdit->textCursor().hasSelection());
// Do not perform seeks along with the cursor while selecting multiple lines
if (!ui->textEdit->textCursor().selectedText().isEmpty())
{
if (!ui->textEdit->textCursor().selectedText().isEmpty()) {
return;
}
size_t pos = ui->textEdit->textCursor().position();
RVA offset = offsetForPosition(*code, pos);
if (offset != RVA_INVALID && offset != Core()->getOffset()) {
@ -349,7 +348,6 @@ void DecompilerWidget::updateSelection()
ui->textEdit->setExtraSelections(extraSelections);
// Highlight PC after updating the selected line
highlightPC();
mCtxMenu->setCurHighlightedWord(searchString);
}
QString DecompilerWidget::getWindowTitle() const
@ -404,7 +402,7 @@ void DecompilerWidget::highlightPC()
if (!cursor.isNull()) {
colorLine(createLineHighlightPC(cursor));
}
}
void DecompilerWidget::highlightBreakpoints()

View File

@ -15,14 +15,14 @@ class DecompilerWidget;
class QTextEdit;
class QSyntaxHighlighter;
class QTextCursor;
class DisassemblyContextMenu;
class DecompilerContextMenu;
struct DecompiledCodeTextLine;
class DecompilerWidget : public MemoryDockWidget
{
Q_OBJECT
protected:
DisassemblyContextMenu *mCtxMenu;
DecompilerContextMenu *mCtxMenu;
public:
explicit DecompilerWidget(MainWindow *main);