mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-24 05:45:27 +00:00
Added seeking, editing and colors to stack widget
This commit is contained in:
parent
9f0599d542
commit
c869a34d99
@ -397,6 +397,12 @@ void CutterCore::editBytes(RVA addr, const QString &bytes)
|
|||||||
emit instructionChanged(addr);
|
emit instructionChanged(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CutterCore::editBytesEndian(RVA addr, const QString &bytes)
|
||||||
|
{
|
||||||
|
cmd("wv " + bytes + " @ " + RAddressString(addr));
|
||||||
|
emit stackChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void CutterCore::setComment(RVA addr, const QString &cmt)
|
void CutterCore::setComment(RVA addr, const QString &cmt)
|
||||||
{
|
{
|
||||||
cmd("CCu base64:" + cmt.toLocal8Bit().toBase64() + " @ " + QString::number(addr));
|
cmd("CCu base64:" + cmt.toLocal8Bit().toBase64() + " @ " + QString::number(addr));
|
||||||
@ -806,6 +812,7 @@ void CutterCore::startDebug()
|
|||||||
emit flagsChanged();
|
emit flagsChanged();
|
||||||
emit refreshCodeViews();
|
emit refreshCodeViews();
|
||||||
}
|
}
|
||||||
|
emit stackChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CutterCore::startEmulation()
|
void CutterCore::startEmulation()
|
||||||
@ -826,6 +833,7 @@ void CutterCore::startEmulation()
|
|||||||
emit changeDebugView();
|
emit changeDebugView();
|
||||||
emit flagsChanged();
|
emit flagsChanged();
|
||||||
}
|
}
|
||||||
|
emit stackChanged();
|
||||||
emit refreshCodeViews();
|
emit refreshCodeViews();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,6 +410,7 @@ public:
|
|||||||
void nopInstruction(RVA addr);
|
void nopInstruction(RVA addr);
|
||||||
void jmpReverse(RVA addr);
|
void jmpReverse(RVA addr);
|
||||||
void editBytes(RVA addr, const QString &inst);
|
void editBytes(RVA addr, const QString &inst);
|
||||||
|
void editBytesEndian(RVA addr, const QString &bytes);
|
||||||
|
|
||||||
/* Comments */
|
/* Comments */
|
||||||
void setComment(RVA addr, const QString &cmt);
|
void setComment(RVA addr, const QString &cmt);
|
||||||
@ -605,6 +606,7 @@ signals:
|
|||||||
void instructionChanged(RVA offset);
|
void instructionChanged(RVA offset);
|
||||||
void breakpointsChanged();
|
void breakpointsChanged();
|
||||||
void refreshCodeViews();
|
void refreshCodeViews();
|
||||||
|
void stackChanged();
|
||||||
|
|
||||||
void notesChanged(const QString ¬es);
|
void notesChanged(const QString ¬es);
|
||||||
void projectSaved(const QString &name);
|
void projectSaved(const QString &name);
|
||||||
|
@ -2,9 +2,11 @@
|
|||||||
#include "ui_StackWidget.h"
|
#include "ui_StackWidget.h"
|
||||||
#include "utils/JsonModel.h"
|
#include "utils/JsonModel.h"
|
||||||
#include "utils/Helpers.h"
|
#include "utils/Helpers.h"
|
||||||
|
#include "dialogs/EditInstructionDialog.h"
|
||||||
|
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "QHeaderView"
|
#include "QHeaderView"
|
||||||
|
#include "QMenu"
|
||||||
|
|
||||||
StackWidget::StackWidget(MainWindow *main, QAction *action) :
|
StackWidget::StackWidget(MainWindow *main, QAction *action) :
|
||||||
CutterDockWidget(main, action),
|
CutterDockWidget(main, action),
|
||||||
@ -23,9 +25,19 @@ StackWidget::StackWidget(MainWindow *main, QAction *action) :
|
|||||||
viewStack->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
|
viewStack->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||||
ui->verticalLayout->addWidget(viewStack);
|
ui->verticalLayout->addWidget(viewStack);
|
||||||
|
|
||||||
|
seekAction = new QAction(tr("Seek to this offset"));
|
||||||
|
editAction = new QAction(tr("Edit stack value..."));
|
||||||
|
viewStack->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
|
||||||
connect(Core(), &CutterCore::refreshAll, this, &StackWidget::updateContents);
|
connect(Core(), &CutterCore::refreshAll, this, &StackWidget::updateContents);
|
||||||
connect(Core(), &CutterCore::seekChanged, this, &StackWidget::updateContents);
|
connect(Core(), &CutterCore::seekChanged, this, &StackWidget::updateContents);
|
||||||
|
connect(Core(), &CutterCore::stackChanged, this, &StackWidget::updateContents);
|
||||||
connect(Config(), &Configuration::fontsUpdated, this, &StackWidget::fontsUpdatedSlot);
|
connect(Config(), &Configuration::fontsUpdated, this, &StackWidget::fontsUpdatedSlot);
|
||||||
|
connect(viewStack, SIGNAL(doubleClicked(const QModelIndex &)), this,
|
||||||
|
SLOT(onDoubleClicked(const QModelIndex &)));
|
||||||
|
connect(viewStack, SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint)));
|
||||||
|
connect(seekAction, &QAction::triggered, this, &StackWidget::seekOffset);
|
||||||
|
connect(editAction, &QAction::triggered, this, &StackWidget::editStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
StackWidget::~StackWidget() {}
|
StackWidget::~StackWidget() {}
|
||||||
@ -44,14 +56,27 @@ void StackWidget::setStackGrid()
|
|||||||
QString addr = RAddressString(stackItem["addr"].toVariant().toULongLong());
|
QString addr = RAddressString(stackItem["addr"].toVariant().toULongLong());
|
||||||
QString valueStack = RAddressString(stackItem["value"].toVariant().toULongLong());
|
QString valueStack = RAddressString(stackItem["value"].toVariant().toULongLong());
|
||||||
QStandardItem *rowOffset = new QStandardItem(addr);
|
QStandardItem *rowOffset = new QStandardItem(addr);
|
||||||
|
rowOffset->setEditable(false);
|
||||||
QStandardItem *rowValue = new QStandardItem(valueStack);
|
QStandardItem *rowValue = new QStandardItem(valueStack);
|
||||||
modelStack->setItem(i, 0, rowOffset);
|
modelStack->setItem(i, 0, rowOffset);
|
||||||
modelStack->setItem(i, 1, rowValue);
|
modelStack->setItem(i, 1, rowValue);
|
||||||
QJsonValue refObject = stackItem["ref"];
|
QJsonValue refObject = stackItem["ref"];
|
||||||
if (!refObject.isUndefined()) { // check that the key exists
|
if (!refObject.isUndefined()) { // check that the key exists
|
||||||
QString ref = refObject.toString();
|
QString ref = refObject.toString();
|
||||||
|
if (ref.contains("ascii") && ref.count("-->") == 1) {
|
||||||
|
ref = Core()->cmd("psz @ [" + addr + "]");
|
||||||
|
}
|
||||||
QStandardItem *rowRef = new QStandardItem(ref);
|
QStandardItem *rowRef = new QStandardItem(ref);
|
||||||
modelStack->setItem(i, 2, rowRef);
|
modelStack->setItem(i, 2, rowRef);
|
||||||
|
if (refObject.toString().contains("ascii") && refObject.toString().count("-->") == 1) {
|
||||||
|
modelStack->setData(modelStack->index(i, 2, QModelIndex()), QVariant(QColor(243, 156, 17)), Qt::ForegroundRole); // orange
|
||||||
|
} else if (ref.contains("program R X") && ref.count("-->") == 0) {
|
||||||
|
modelStack->setData(modelStack->index(i, 2, QModelIndex()), QVariant(QColor(Qt::red)), Qt::ForegroundRole);
|
||||||
|
} else if (ref.contains("stack") && ref.count("-->") == 0) {
|
||||||
|
modelStack->setData(modelStack->index(i, 2, QModelIndex()), QVariant(QColor(Qt::cyan)), Qt::ForegroundRole);
|
||||||
|
} else if (ref.contains("library") && ref.count("-->") == 0) {
|
||||||
|
modelStack->setData(modelStack->index(i, 2, QModelIndex()), QVariant(QColor(Qt::green)), Qt::ForegroundRole);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@ -62,4 +87,48 @@ void StackWidget::setStackGrid()
|
|||||||
void StackWidget::fontsUpdatedSlot()
|
void StackWidget::fontsUpdatedSlot()
|
||||||
{
|
{
|
||||||
viewStack->setFont(Config()->getFont());
|
viewStack->setFont(Config()->getFont());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StackWidget::onDoubleClicked(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return;
|
||||||
|
// check if we are clicking on the offset or value columns and seek if it is the case
|
||||||
|
if (index.column() <= 1) {
|
||||||
|
QString item = index.data().toString();
|
||||||
|
Core()->seek(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StackWidget::customMenuRequested(QPoint pos)
|
||||||
|
{
|
||||||
|
QMenu *menu = new QMenu(this);
|
||||||
|
menu->addAction(seekAction);
|
||||||
|
menu->addAction(editAction);
|
||||||
|
menu->popup(viewStack->viewport()->mapToGlobal(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
void StackWidget::seekOffset()
|
||||||
|
{
|
||||||
|
QString offset = viewStack->selectionModel()->currentIndex().data().toString();
|
||||||
|
Core()->seek(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StackWidget::editStack()
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
int row = viewStack->selectionModel()->currentIndex().row();
|
||||||
|
QString offset = viewStack->selectionModel()->currentIndex().sibling(row, 0).data().toString();
|
||||||
|
EditInstructionDialog *e = new EditInstructionDialog(this);
|
||||||
|
e->setWindowTitle(tr("Edit stack at %1").arg(offset));
|
||||||
|
|
||||||
|
QString oldBytes = viewStack->selectionModel()->currentIndex().sibling(row, 1).data().toString();
|
||||||
|
e->setInstruction(oldBytes);
|
||||||
|
|
||||||
|
if (e->exec()) {
|
||||||
|
QString bytes = e->getInstruction();
|
||||||
|
if (bytes != oldBytes) {
|
||||||
|
Core()->editBytesEndian((RVA)offset.toULongLong(&ok, 16), bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -26,9 +26,15 @@ private slots:
|
|||||||
void updateContents();
|
void updateContents();
|
||||||
void setStackGrid();
|
void setStackGrid();
|
||||||
void fontsUpdatedSlot();
|
void fontsUpdatedSlot();
|
||||||
|
void onDoubleClicked(const QModelIndex &index);
|
||||||
|
void customMenuRequested(QPoint pos);
|
||||||
|
void seekOffset();
|
||||||
|
void editStack();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Ui::StackWidget> ui;
|
std::unique_ptr<Ui::StackWidget> ui;
|
||||||
QTableView *viewStack = new QTableView;
|
QTableView *viewStack = new QTableView;
|
||||||
QStandardItemModel *modelStack = new QStandardItemModel(1, 3, this);
|
QStandardItemModel *modelStack = new QStandardItemModel(1, 3, this);
|
||||||
|
QAction *seekAction;
|
||||||
|
QAction *editAction;
|
||||||
};
|
};
|
Loading…
Reference in New Issue
Block a user