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/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 \
|
||||
|
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 "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()
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user