mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-18 19:06:10 +00:00
Skelton for dedicated context menu + action to copy selection (#2256)
This commit is contained in:
parent
2e573cc171
commit
ea9f3f1831
@ -336,6 +336,7 @@ SOURCES += \
|
|||||||
widgets/StringsWidget.cpp \
|
widgets/StringsWidget.cpp \
|
||||||
widgets/SymbolsWidget.cpp \
|
widgets/SymbolsWidget.cpp \
|
||||||
menus/DisassemblyContextMenu.cpp \
|
menus/DisassemblyContextMenu.cpp \
|
||||||
|
menus/DecompilerContextMenu.cpp \
|
||||||
widgets/DisassemblyWidget.cpp \
|
widgets/DisassemblyWidget.cpp \
|
||||||
widgets/HexdumpWidget.cpp \
|
widgets/HexdumpWidget.cpp \
|
||||||
common/Configuration.cpp \
|
common/Configuration.cpp \
|
||||||
@ -485,6 +486,7 @@ HEADERS += \
|
|||||||
widgets/StringsWidget.h \
|
widgets/StringsWidget.h \
|
||||||
widgets/SymbolsWidget.h \
|
widgets/SymbolsWidget.h \
|
||||||
menus/DisassemblyContextMenu.h \
|
menus/DisassemblyContextMenu.h \
|
||||||
|
menus/DecompilerContextMenu.h \
|
||||||
widgets/DisassemblyWidget.h \
|
widgets/DisassemblyWidget.h \
|
||||||
widgets/HexdumpWidget.h \
|
widgets/HexdumpWidget.h \
|
||||||
common/Configuration.h \
|
common/Configuration.h \
|
||||||
|
59
src/menus/DecompilerContextMenu.cpp
Normal file
59
src/menus/DecompilerContextMenu.cpp
Normal 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();
|
||||||
|
}
|
59
src/menus/DecompilerContextMenu.h
Normal file
59
src/menus/DecompilerContextMenu.h
Normal 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
|
@ -1,6 +1,6 @@
|
|||||||
#include "DecompilerWidget.h"
|
#include "DecompilerWidget.h"
|
||||||
#include "ui_DecompilerWidget.h"
|
#include "ui_DecompilerWidget.h"
|
||||||
#include "menus/DisassemblyContextMenu.h"
|
#include "menus/DecompilerContextMenu.h"
|
||||||
|
|
||||||
#include "common/Configuration.h"
|
#include "common/Configuration.h"
|
||||||
#include "common/Helpers.h"
|
#include "common/Helpers.h"
|
||||||
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
DecompilerWidget::DecompilerWidget(MainWindow *main) :
|
DecompilerWidget::DecompilerWidget(MainWindow *main) :
|
||||||
MemoryDockWidget(MemoryWidgetType::Decompiler, main),
|
MemoryDockWidget(MemoryWidgetType::Decompiler, main),
|
||||||
mCtxMenu(new DisassemblyContextMenu(this, main)),
|
mCtxMenu(new DecompilerContextMenu(this, main)),
|
||||||
ui(new Ui::DecompilerWidget),
|
ui(new Ui::DecompilerWidget),
|
||||||
code(Decompiler::makeWarning(tr("Choose an offset and refresh to get decompiled code")), &r_annotated_code_free)
|
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::fontsUpdated, this, &DecompilerWidget::fontsUpdatedSlot);
|
||||||
connect(Config(), &Configuration::colorsUpdated, this, &DecompilerWidget::colorsUpdatedSlot);
|
connect(Config(), &Configuration::colorsUpdated, this, &DecompilerWidget::colorsUpdatedSlot);
|
||||||
connect(Core(), &CutterCore::registersChanged, this, &DecompilerWidget::highlightPC);
|
connect(Core(), &CutterCore::registersChanged, this, &DecompilerWidget::highlightPC);
|
||||||
|
connect(mCtxMenu, &DecompilerContextMenu::copy, ui->textEdit, &QPlainTextEdit::copy);
|
||||||
|
|
||||||
decompiledFunctionAddr = RVA_INVALID;
|
decompiledFunctionAddr = RVA_INVALID;
|
||||||
decompilerWasBusy = false;
|
decompilerWasBusy = false;
|
||||||
@ -61,7 +62,6 @@ DecompilerWidget::DecompilerWidget(MainWindow *main) :
|
|||||||
// If no decompiler was previously chosen. set r2ghidra as default decompiler
|
// If no decompiler was previously chosen. set r2ghidra as default decompiler
|
||||||
selectedDecompilerId = "r2ghidra";
|
selectedDecompilerId = "r2ghidra";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto dec : decompilers) {
|
for (auto dec : decompilers) {
|
||||||
ui->decompilerComboBox->addItem(dec->getName(), dec->getId());
|
ui->decompilerComboBox->addItem(dec->getName(), dec->getId());
|
||||||
if (dec->getId() == selectedDecompilerId) {
|
if (dec->getId() == selectedDecompilerId) {
|
||||||
@ -278,12 +278,11 @@ void DecompilerWidget::connectCursorPositionChanged(bool disconnect)
|
|||||||
|
|
||||||
void DecompilerWidget::cursorPositionChanged()
|
void DecompilerWidget::cursorPositionChanged()
|
||||||
{
|
{
|
||||||
|
mCtxMenu->setCanCopy(ui->textEdit->textCursor().hasSelection());
|
||||||
// Do not perform seeks along with the cursor while selecting multiple lines
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pos = ui->textEdit->textCursor().position();
|
size_t pos = ui->textEdit->textCursor().position();
|
||||||
RVA offset = offsetForPosition(*code, pos);
|
RVA offset = offsetForPosition(*code, pos);
|
||||||
if (offset != RVA_INVALID && offset != Core()->getOffset()) {
|
if (offset != RVA_INVALID && offset != Core()->getOffset()) {
|
||||||
@ -349,7 +348,6 @@ void DecompilerWidget::updateSelection()
|
|||||||
ui->textEdit->setExtraSelections(extraSelections);
|
ui->textEdit->setExtraSelections(extraSelections);
|
||||||
// Highlight PC after updating the selected line
|
// Highlight PC after updating the selected line
|
||||||
highlightPC();
|
highlightPC();
|
||||||
mCtxMenu->setCurHighlightedWord(searchString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DecompilerWidget::getWindowTitle() const
|
QString DecompilerWidget::getWindowTitle() const
|
||||||
@ -404,7 +402,7 @@ void DecompilerWidget::highlightPC()
|
|||||||
if (!cursor.isNull()) {
|
if (!cursor.isNull()) {
|
||||||
colorLine(createLineHighlightPC(cursor));
|
colorLine(createLineHighlightPC(cursor));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecompilerWidget::highlightBreakpoints()
|
void DecompilerWidget::highlightBreakpoints()
|
||||||
|
@ -15,14 +15,14 @@ class DecompilerWidget;
|
|||||||
class QTextEdit;
|
class QTextEdit;
|
||||||
class QSyntaxHighlighter;
|
class QSyntaxHighlighter;
|
||||||
class QTextCursor;
|
class QTextCursor;
|
||||||
class DisassemblyContextMenu;
|
class DecompilerContextMenu;
|
||||||
struct DecompiledCodeTextLine;
|
struct DecompiledCodeTextLine;
|
||||||
|
|
||||||
class DecompilerWidget : public MemoryDockWidget
|
class DecompilerWidget : public MemoryDockWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
protected:
|
protected:
|
||||||
DisassemblyContextMenu *mCtxMenu;
|
DecompilerContextMenu *mCtxMenu;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DecompilerWidget(MainWindow *main);
|
explicit DecompilerWidget(MainWindow *main);
|
||||||
|
Loading…
Reference in New Issue
Block a user