mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-19 11:26:11 +00:00
Added context menu with Set as option
This commit is contained in:
parent
f8a258f98c
commit
13d2c5ef02
@ -2,6 +2,7 @@
|
|||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QDebug>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
@ -772,6 +773,7 @@ void CutterCore::editBytesEndian(RVA addr, const QString &bytes)
|
|||||||
|
|
||||||
void CutterCore::setToCode(RVA addr)
|
void CutterCore::setToCode(RVA addr)
|
||||||
{
|
{
|
||||||
|
qDebug() << "setToCode" << addr << "\n";
|
||||||
CORE_LOCK();
|
CORE_LOCK();
|
||||||
rz_meta_del(core->analysis, RZ_META_TYPE_STRING, core->offset, 1);
|
rz_meta_del(core->analysis, RZ_META_TYPE_STRING, core->offset, 1);
|
||||||
rz_meta_del(core->analysis, RZ_META_TYPE_DATA, core->offset, 1);
|
rz_meta_del(core->analysis, RZ_META_TYPE_DATA, core->offset, 1);
|
||||||
@ -842,6 +844,7 @@ QString CutterCore::getMetaString(RVA addr)
|
|||||||
|
|
||||||
void CutterCore::setToData(RVA addr, int size, int repeat)
|
void CutterCore::setToData(RVA addr, int size, int repeat)
|
||||||
{
|
{
|
||||||
|
qDebug() << "setToData" << addr << size << repeat << "\n";
|
||||||
if (size <= 0 || repeat <= 0) {
|
if (size <= 0 || repeat <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "DisassemblyContextMenu.h"
|
#include "DisassemblyContextMenu.h"
|
||||||
|
#include "common/DisassemblyPreview.h"
|
||||||
#include "dialogs/preferences/PreferencesDialog.h"
|
#include "dialogs/preferences/PreferencesDialog.h"
|
||||||
#include "dialogs/EditInstructionDialog.h"
|
#include "dialogs/EditInstructionDialog.h"
|
||||||
#include "dialogs/CommentsDialog.h"
|
#include "dialogs/CommentsDialog.h"
|
||||||
@ -15,6 +16,8 @@
|
|||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QTextEdit>
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
@ -242,7 +245,7 @@ void DisassemblyContextMenu::addSetAsMenu()
|
|||||||
{
|
{
|
||||||
setAsMenu = addMenu(tr("Set as..."));
|
setAsMenu = addMenu(tr("Set as..."));
|
||||||
|
|
||||||
initAction(&actionSetToCode, tr("Code"), SLOT(on_actionSetToCode_triggered()),
|
initAction(&actionSetToCode, tr("Code"), SLOT(applySetToCode()),
|
||||||
getSetToCodeSequence());
|
getSetToCodeSequence());
|
||||||
setAsMenu->addAction(&actionSetToCode);
|
setAsMenu->addAction(&actionSetToCode);
|
||||||
|
|
||||||
@ -262,35 +265,83 @@ void DisassemblyContextMenu::addSetAsMenu()
|
|||||||
addSetToDataMenu();
|
addSetToDataMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisassemblyContextMenu::applySetToCode() {
|
||||||
|
qDebug() << "Applying set to code" << "\n";
|
||||||
|
if (selectedLines.size() > 1) {
|
||||||
|
QVector<QPair<int, RVA>> offsets;
|
||||||
|
for (const auto &selection : selectedLines) {
|
||||||
|
int startPos = selection.cursor.selectionStart();
|
||||||
|
RVA lineOffset = DisassemblyPreview::readDisassemblyOffset(selection.cursor);
|
||||||
|
offsets.append(qMakePair(startPos, lineOffset));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sorting by start position in descending order
|
||||||
|
std::sort(offsets.begin(), offsets.end(),
|
||||||
|
[](const QPair<int, RVA> &a, const QPair<int, RVA> &b) {
|
||||||
|
return a.first > b.first;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const auto &offset : offsets) {
|
||||||
|
qDebug() << "Offset:" << offset.second;
|
||||||
|
on_actionSetToCode_triggered(offset.second);
|
||||||
|
}
|
||||||
|
} else if (selectedLines.size() <= 1) {
|
||||||
|
on_actionSetToCode_triggered();
|
||||||
|
}
|
||||||
|
selectedLines.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void DisassemblyContextMenu::addSetToDataMenu()
|
void DisassemblyContextMenu::addSetToDataMenu()
|
||||||
{
|
{
|
||||||
setToDataMenu = setAsMenu->addMenu(tr("Data..."));
|
setToDataMenu = setAsMenu->addMenu(tr("Data..."));
|
||||||
|
|
||||||
initAction(&actionSetToDataByte, tr("Byte"));
|
initAction(&actionSetToDataByte, tr("Byte"));
|
||||||
setToDataMenu->addAction(&actionSetToDataByte);
|
setToDataMenu->addAction(&actionSetToDataByte);
|
||||||
connect(&actionSetToDataByte, &QAction::triggered, this, [this] { setToData(1); });
|
connect(&actionSetToDataByte, &QAction::triggered, this, [this] { applySetToData(1); });
|
||||||
|
|
||||||
initAction(&actionSetToDataWord, tr("Word"));
|
initAction(&actionSetToDataWord, tr("Word"));
|
||||||
setToDataMenu->addAction(&actionSetToDataWord);
|
setToDataMenu->addAction(&actionSetToDataWord);
|
||||||
connect(&actionSetToDataWord, &QAction::triggered, this, [this] { setToData(2); });
|
connect(&actionSetToDataWord, &QAction::triggered, this, [this] { applySetToData(2); });
|
||||||
|
|
||||||
initAction(&actionSetToDataDword, tr("Dword"));
|
initAction(&actionSetToDataDword, tr("Dword"));
|
||||||
setToDataMenu->addAction(&actionSetToDataDword);
|
setToDataMenu->addAction(&actionSetToDataDword);
|
||||||
connect(&actionSetToDataDword, &QAction::triggered, this, [this] { setToData(4); });
|
connect(&actionSetToDataDword, &QAction::triggered, this, [this] { applySetToData(4); });
|
||||||
|
|
||||||
initAction(&actionSetToDataQword, tr("Qword"));
|
initAction(&actionSetToDataQword, tr("Qword"));
|
||||||
setToDataMenu->addAction(&actionSetToDataQword);
|
setToDataMenu->addAction(&actionSetToDataQword);
|
||||||
connect(&actionSetToDataQword, &QAction::triggered, this, [this] { setToData(8); });
|
connect(&actionSetToDataQword, &QAction::triggered, this, [this] { applySetToData(8); });
|
||||||
|
|
||||||
initAction(&actionSetToDataEx, "...", SLOT(on_actionSetToDataEx_triggered()),
|
initAction(&actionSetToDataEx, "...", SLOT(on_actionSetToDataEx_triggered()), getSetToDataExSequence());
|
||||||
getSetToDataExSequence());
|
|
||||||
setToDataMenu->addAction(&actionSetToDataEx);
|
setToDataMenu->addAction(&actionSetToDataEx);
|
||||||
|
|
||||||
auto switchAction = new QAction(this);
|
|
||||||
initAction(switchAction, "Switch Data", SLOT(on_actionSetToData_triggered()),
|
|
||||||
getSetToDataSequence());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisassemblyContextMenu::applySetToData(int dataSize) {
|
||||||
|
qDebug() << "Applying set to data with size:" << dataSize << "\n";
|
||||||
|
if (selectedLines.size() > 1) {
|
||||||
|
QVector<QPair<int, RVA>> offsets;
|
||||||
|
for (const auto &selection : selectedLines) {
|
||||||
|
int startPos = selection.cursor.selectionStart();
|
||||||
|
RVA lineOffset = DisassemblyPreview::readDisassemblyOffset(selection.cursor);
|
||||||
|
offsets.append(qMakePair(startPos, lineOffset));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sorting by start position in descending order
|
||||||
|
std::sort(offsets.begin(), offsets.end(),
|
||||||
|
[](const QPair<int, RVA> &a, const QPair<int, RVA> &b) {
|
||||||
|
return a.first > b.first;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const auto &offset : offsets) {
|
||||||
|
qDebug() << "Offset:" << offset.second;
|
||||||
|
setToData(offset.second, dataSize);
|
||||||
|
}
|
||||||
|
} else if (selectedLines.size() <= 1) {
|
||||||
|
setToData(dataSize);
|
||||||
|
}
|
||||||
|
selectedLines.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DisassemblyContextMenu::addEditMenu()
|
void DisassemblyContextMenu::addEditMenu()
|
||||||
{
|
{
|
||||||
editMenu = addMenu(tr("Edit"));
|
editMenu = addMenu(tr("Edit"));
|
||||||
@ -365,6 +416,27 @@ QVector<DisassemblyContextMenu::ThingUsedHere> DisassemblyContextMenu::getThingU
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DisassemblyContextMenu::prepareMenu(const QList<QTextEdit::ExtraSelection>& selectedLines) {
|
||||||
|
this->clear();
|
||||||
|
this->selectedLines = selectedLines;
|
||||||
|
|
||||||
|
qDebug() << "Number of selected lines:" << selectedLines.size();
|
||||||
|
for (const auto& selection : selectedLines) {
|
||||||
|
int cursorPosition = selection.cursor.position();
|
||||||
|
int anchorPosition = selection.cursor.anchor();
|
||||||
|
auto offset = DisassemblyPreview::readDisassemblyOffset(selection.cursor);
|
||||||
|
|
||||||
|
qDebug() << "Cursor position:" << cursorPosition << "Anchor position:" << anchorPosition << "Offset:" << offset << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
addAction(&actionCopy);
|
||||||
|
|
||||||
|
if (selectedLines.size() > 1) {
|
||||||
|
addSetAsMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DisassemblyContextMenu::setOffset(RVA offset)
|
void DisassemblyContextMenu::setOffset(RVA offset)
|
||||||
{
|
{
|
||||||
this->offset = offset;
|
this->offset = offset;
|
||||||
@ -964,16 +1036,31 @@ void DisassemblyContextMenu::on_actionSetToCode_triggered()
|
|||||||
Core()->setToCode(offset);
|
Core()->setToCode(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisassemblyContextMenu::on_actionSetToCode_triggered(RVA offset)
|
||||||
|
{
|
||||||
|
Core()->setToCode(offset);
|
||||||
|
}
|
||||||
|
|
||||||
void DisassemblyContextMenu::on_actionSetAsString_triggered()
|
void DisassemblyContextMenu::on_actionSetAsString_triggered()
|
||||||
{
|
{
|
||||||
Core()->setAsString(offset);
|
Core()->setAsString(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisassemblyContextMenu::on_actionSetAsString_triggered(RVA offset)
|
||||||
|
{
|
||||||
|
Core()->setAsString(offset);
|
||||||
|
}
|
||||||
|
|
||||||
void DisassemblyContextMenu::on_actionSetAsStringRemove_triggered()
|
void DisassemblyContextMenu::on_actionSetAsStringRemove_triggered()
|
||||||
{
|
{
|
||||||
Core()->removeString(offset);
|
Core()->removeString(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisassemblyContextMenu::on_actionSetAsStringRemove_triggered(RVA offset)
|
||||||
|
{
|
||||||
|
Core()->removeString(offset);
|
||||||
|
}
|
||||||
|
|
||||||
void DisassemblyContextMenu::on_actionSetAsStringAdvanced_triggered()
|
void DisassemblyContextMenu::on_actionSetAsStringAdvanced_triggered()
|
||||||
{
|
{
|
||||||
EditStringDialog dialog(parentForDialog());
|
EditStringDialog dialog(parentForDialog());
|
||||||
@ -1116,6 +1203,11 @@ void DisassemblyContextMenu::setToData(int size, int repeat)
|
|||||||
Core()->setToData(offset, size, repeat);
|
Core()->setToData(offset, size, repeat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisassemblyContextMenu::setToData(RVA offset, int size, int repeat)
|
||||||
|
{
|
||||||
|
Core()->setToData(offset, size, repeat);
|
||||||
|
}
|
||||||
|
|
||||||
QAction *DisassemblyContextMenu::addAnonymousAction(QString name, const char *slot,
|
QAction *DisassemblyContextMenu::addAnonymousAction(QString name, const char *slot,
|
||||||
QKeySequence keySequence)
|
QKeySequence keySequence)
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include "core/Cutter.h"
|
#include "core/Cutter.h"
|
||||||
#include "common/IOModesController.h"
|
#include "common/IOModesController.h"
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
#include <QTextEdit>
|
||||||
|
#include <QSet>
|
||||||
#include <QKeySequence>
|
#include <QKeySequence>
|
||||||
|
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
@ -22,6 +24,8 @@ signals:
|
|||||||
public slots:
|
public slots:
|
||||||
void setOffset(RVA offset);
|
void setOffset(RVA offset);
|
||||||
void setCanCopy(bool enabled);
|
void setCanCopy(bool enabled);
|
||||||
|
void prepareMenu(const QList<QTextEdit::ExtraSelection>& selectedLines);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the value of curHighlightedWord
|
* @brief Sets the value of curHighlightedWord
|
||||||
@ -61,9 +65,13 @@ private slots:
|
|||||||
void on_actionContinueUntil_triggered();
|
void on_actionContinueUntil_triggered();
|
||||||
void on_actionSetPC_triggered();
|
void on_actionSetPC_triggered();
|
||||||
|
|
||||||
|
void applySetToCode();
|
||||||
void on_actionSetToCode_triggered();
|
void on_actionSetToCode_triggered();
|
||||||
|
void on_actionSetToCode_triggered(RVA offset);
|
||||||
void on_actionSetAsString_triggered();
|
void on_actionSetAsString_triggered();
|
||||||
|
void on_actionSetAsString_triggered(RVA offset);
|
||||||
void on_actionSetAsStringRemove_triggered();
|
void on_actionSetAsStringRemove_triggered();
|
||||||
|
void on_actionSetAsStringRemove_triggered(RVA offset);
|
||||||
void on_actionSetAsStringAdvanced_triggered();
|
void on_actionSetAsStringAdvanced_triggered();
|
||||||
void on_actionSetToData_triggered();
|
void on_actionSetToData_triggered();
|
||||||
void on_actionSetToDataEx_triggered();
|
void on_actionSetToDataEx_triggered();
|
||||||
@ -100,6 +108,7 @@ private:
|
|||||||
bool canCopy;
|
bool canCopy;
|
||||||
QString curHighlightedWord; // The current highlighted word
|
QString curHighlightedWord; // The current highlighted word
|
||||||
MainWindow *mainWindow;
|
MainWindow *mainWindow;
|
||||||
|
QList<QTextEdit::ExtraSelection> selectedLines;
|
||||||
IOModesController ioModesController;
|
IOModesController ioModesController;
|
||||||
|
|
||||||
QList<QAction *> anonymousActions;
|
QList<QAction *> anonymousActions;
|
||||||
@ -189,12 +198,13 @@ private:
|
|||||||
|
|
||||||
void setBase(QString base);
|
void setBase(QString base);
|
||||||
void setToData(int size, int repeat = 1);
|
void setToData(int size, int repeat = 1);
|
||||||
|
void setToData(RVA offset, int size, int repeat = 1);
|
||||||
void setBits(int bits);
|
void setBits(int bits);
|
||||||
|
|
||||||
void addSetBaseMenu();
|
void addSetBaseMenu();
|
||||||
void addSetBitsMenu();
|
void addSetBitsMenu();
|
||||||
void addSetAsMenu();
|
void addSetAsMenu();
|
||||||
void addSetToDataMenu();
|
void addSetToDataMenu();
|
||||||
|
void applySetToData(int datasize);
|
||||||
void addEditMenu();
|
void addEditMenu();
|
||||||
void addAddAtMenu();
|
void addAddAtMenu();
|
||||||
void addBreakpointMenu();
|
void addBreakpointMenu();
|
||||||
|
@ -464,6 +464,12 @@ void DisassemblyWidget::highlightMultiLineSelections()
|
|||||||
|
|
||||||
void DisassemblyWidget::showDisasContextMenu(const QPoint &pt)
|
void DisassemblyWidget::showDisasContextMenu(const QPoint &pt)
|
||||||
{
|
{
|
||||||
|
qDebug() << "showDisasContextMenu()" << "\n";
|
||||||
|
auto selectedLines = mDisasTextEdit->getMultiLineSelections();
|
||||||
|
if (selectedLines.size() > 1) {
|
||||||
|
mCtxMenu->prepareMenu(selectedLines);
|
||||||
|
}
|
||||||
|
|
||||||
mCtxMenu->exec(mDisasTextEdit->mapToGlobal(pt));
|
mCtxMenu->exec(mDisasTextEdit->mapToGlobal(pt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,7 +849,7 @@ void DisassemblyTextEdit::mousePressEvent(QMouseEvent *event)
|
|||||||
|
|
||||||
// Format selection
|
// Format selection
|
||||||
QTextEdit::ExtraSelection selection;
|
QTextEdit::ExtraSelection selection;
|
||||||
selection.format.setBackground(QColor("green"));
|
selection.format.setBackground(QColor("darkBlue"));
|
||||||
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
|
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
|
||||||
|
|
||||||
// Move cursor to start of the line
|
// Move cursor to start of the line
|
||||||
@ -881,6 +887,9 @@ void DisassemblyTextEdit::mousePressEvent(QMouseEvent *event)
|
|||||||
for (const auto &selection : multilineSelections) {
|
for (const auto &selection : multilineSelections) {
|
||||||
qDebug() << "Start:" << selection.cursor.selectionStart()
|
qDebug() << "Start:" << selection.cursor.selectionStart()
|
||||||
<< "End:" << selection.cursor.selectionEnd();
|
<< "End:" << selection.cursor.selectionEnd();
|
||||||
|
qDebug() << selection.cursor.block().text();
|
||||||
|
auto offset = DisassemblyPreview::readDisassemblyOffset(selection.cursor);
|
||||||
|
qDebug() << "Offset:" << offset << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user