mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-20 03:46:11 +00:00
Refactored CutterSeekableWidget to CutterSeekable (#1099)
This commit refactors the CutterSeekableWidget class and adds some documentation.
This commit is contained in:
parent
bdc684769f
commit
f385cf26d5
@ -249,7 +249,7 @@ QString CutterCore::cmd(const char *str)
|
||||
QString o = QString(res ? res : "");
|
||||
r_mem_free(res);
|
||||
if (offset != core_->offset) {
|
||||
emit seekChanged(core_->offset);
|
||||
updateSeek();
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
@ -188,7 +188,6 @@ SOURCES += \
|
||||
common/NestedIPyKernel.cpp \
|
||||
dialogs/R2PluginsDialog.cpp \
|
||||
widgets/CutterDockWidget.cpp \
|
||||
widgets/CutterSeekableWidget.cpp \
|
||||
widgets/CutterTreeWidget.cpp \
|
||||
widgets/GraphWidget.cpp \
|
||||
common/JsonTreeItem.cpp \
|
||||
@ -219,7 +218,8 @@ SOURCES += \
|
||||
widgets/CutterTreeView.cpp \
|
||||
widgets/ComboQuickFilterView.cpp \
|
||||
dialogs/HexdumpRangeDialog.cpp \
|
||||
common/QtResImporter.cpp
|
||||
common/QtResImporter.cpp \
|
||||
widgets/CutterSeekable.cpp
|
||||
|
||||
HEADERS += \
|
||||
Cutter.h \
|
||||
@ -288,7 +288,6 @@ HEADERS += \
|
||||
dialogs/R2PluginsDialog.h \
|
||||
widgets/CutterDockWidget.h \
|
||||
widgets/CutterTreeWidget.h \
|
||||
widgets/CutterSeekableWidget.h \
|
||||
widgets/GraphWidget.h \
|
||||
common/JsonTreeItem.h \
|
||||
common/JsonModel.h \
|
||||
@ -322,7 +321,8 @@ HEADERS += \
|
||||
widgets/CutterTreeView.h \
|
||||
widgets/ComboQuickFilterView.h \
|
||||
dialogs/HexdumpRangeDialog.h \
|
||||
common/QtResImporter.h
|
||||
common/QtResImporter.h \
|
||||
widgets/CutterSeekable.h
|
||||
|
||||
FORMS += \
|
||||
dialogs/AboutDialog.ui \
|
||||
|
59
src/widgets/CutterSeekable.cpp
Normal file
59
src/widgets/CutterSeekable.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include "MainWindow.h"
|
||||
#include "CutterSeekable.h"
|
||||
|
||||
#include <QPlainTextEdit>
|
||||
|
||||
|
||||
CutterSeekable::CutterSeekable(QObject *parent)
|
||||
:
|
||||
QObject(parent)
|
||||
{
|
||||
connect(Core(), &CutterCore::seekChanged, this, &CutterSeekable::onCoreSeekChanged);
|
||||
}
|
||||
|
||||
CutterSeekable::~CutterSeekable() {}
|
||||
|
||||
void CutterSeekable::onCoreSeekChanged(RVA addr)
|
||||
{
|
||||
if (synchronized && widgetOffset != addr) {
|
||||
synchronized = false;
|
||||
seek(addr);
|
||||
synchronized = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CutterSeekable::seek(RVA addr)
|
||||
{
|
||||
previousOffset = widgetOffset;
|
||||
widgetOffset = addr;
|
||||
if (synchronized) {
|
||||
Core()->seek(addr);
|
||||
}
|
||||
|
||||
emit seekableSeekChanged(addr);
|
||||
}
|
||||
|
||||
|
||||
void CutterSeekable::seekPrev()
|
||||
{
|
||||
if (synchronized) {
|
||||
Core()->seekPrev();
|
||||
} else {
|
||||
this->seek(previousOffset);
|
||||
}
|
||||
}
|
||||
|
||||
RVA CutterSeekable::getOffset()
|
||||
{
|
||||
return (synchronized) ? Core()->getOffset() : widgetOffset;
|
||||
}
|
||||
|
||||
void CutterSeekable::toggleSynchronization()
|
||||
{
|
||||
synchronized = !synchronized;
|
||||
}
|
||||
|
||||
bool CutterSeekable::isSynchronized()
|
||||
{
|
||||
return synchronized;
|
||||
}
|
80
src/widgets/CutterSeekable.h
Normal file
80
src/widgets/CutterSeekable.h
Normal file
@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cutter.h"
|
||||
|
||||
class MainWindow;
|
||||
|
||||
class CutterSeekable : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CutterSeekable(QObject *parent = nullptr);
|
||||
~CutterSeekable();
|
||||
|
||||
/**
|
||||
* @brief seek changes current offset.
|
||||
* If the seekable is synchronized with Core, then
|
||||
* the Core offset will be modified and then the CutterCore::seekChanged
|
||||
* signal will be emitted.
|
||||
* In any case, CutterSeekable::seekableSeekChanged is emitted.
|
||||
* @param addr the location to seek at.
|
||||
*/
|
||||
void seek(RVA addr);
|
||||
|
||||
/**
|
||||
* @brief toggleSyncWithCore toggles
|
||||
* Core seek synchronization.
|
||||
*/
|
||||
void toggleSynchronization();
|
||||
|
||||
/**
|
||||
* @brief getOffset returns the seekable offset.
|
||||
* If the seekable is synchronized with Core, this function
|
||||
* is similar to Core()->getOffset.
|
||||
* If it's not synchronized, it will return the seekable current seek.
|
||||
* @return the seekable current offset.
|
||||
*/
|
||||
RVA getOffset();
|
||||
|
||||
/**
|
||||
* @brief isSynchronized tells whether the seekable
|
||||
* is synchronized with Core or not.
|
||||
* @return boolean
|
||||
*/
|
||||
bool isSynchronized();
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* @brief seekPrev seeks to last location.
|
||||
*/
|
||||
void seekPrev();
|
||||
|
||||
private slots:
|
||||
/**
|
||||
* @brief onCoreSeekChanged
|
||||
*/
|
||||
void onCoreSeekChanged(RVA addr);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief widgetOffset widget seek location.
|
||||
*/
|
||||
RVA widgetOffset = RVA_INVALID;
|
||||
|
||||
/**
|
||||
* @brief previousOffset last seek location.
|
||||
* @todo maybe use an actual history?
|
||||
*/
|
||||
RVA previousOffset = RVA_INVALID;
|
||||
|
||||
/**
|
||||
* @brief synchronized tells with the seekable's offset is
|
||||
* synchronized with core or not.
|
||||
*/
|
||||
bool synchronized = true;
|
||||
|
||||
signals:
|
||||
void seekableSeekChanged(RVA addr);
|
||||
|
||||
};
|
@ -1,66 +0,0 @@
|
||||
#include "MainWindow.h"
|
||||
#include "CutterSeekableWidget.h"
|
||||
|
||||
|
||||
CutterSeekableWidget::CutterSeekableWidget(QObject *parent)
|
||||
:
|
||||
QObject(parent)
|
||||
{
|
||||
connect(Core(), &CutterCore::seekChanged, this, &CutterSeekableWidget::onSeekChanged);
|
||||
}
|
||||
|
||||
void CutterSeekableWidget::onSeekChanged(RVA addr)
|
||||
{
|
||||
if (isInSyncWithCore) {
|
||||
emit seekChanged(addr);
|
||||
}
|
||||
}
|
||||
|
||||
void CutterSeekableWidget::seek(RVA addr)
|
||||
{
|
||||
if (isInSyncWithCore) {
|
||||
Core()->seek(addr);
|
||||
} else {
|
||||
prevIdenpendentOffset = independentOffset;
|
||||
independentOffset = addr;
|
||||
emit seekChanged(addr);
|
||||
}
|
||||
}
|
||||
|
||||
RVA CutterSeekableWidget::getOffset()
|
||||
{
|
||||
RVA addr;
|
||||
if (isInSyncWithCore) {
|
||||
addr = Core()->getOffset();
|
||||
} else {
|
||||
addr = independentOffset;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
void CutterSeekableWidget::toggleSyncWithCore()
|
||||
{
|
||||
isInSyncWithCore = !isInSyncWithCore;
|
||||
}
|
||||
|
||||
RVA CutterSeekableWidget::getIndependentOffset()
|
||||
{
|
||||
return independentOffset;
|
||||
}
|
||||
|
||||
RVA CutterSeekableWidget::getPrevIndependentOffset()
|
||||
{
|
||||
return prevIdenpendentOffset;
|
||||
}
|
||||
|
||||
bool CutterSeekableWidget::getSyncWithCore()
|
||||
{
|
||||
return isInSyncWithCore;
|
||||
}
|
||||
|
||||
void CutterSeekableWidget::setIndependentOffset(RVA addr)
|
||||
{
|
||||
independentOffset = addr;
|
||||
}
|
||||
|
||||
CutterSeekableWidget::~CutterSeekableWidget() {}
|
@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cutter.h"
|
||||
|
||||
class MainWindow;
|
||||
|
||||
class CutterSeekableWidget : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CutterSeekableWidget(QObject *parent = nullptr);
|
||||
~CutterSeekableWidget();
|
||||
void seek(RVA addr);
|
||||
void toggleSyncWithCore();
|
||||
RVA getOffset();
|
||||
RVA getIndependentOffset();
|
||||
RVA getPrevIndependentOffset();
|
||||
bool getSyncWithCore();
|
||||
void setIndependentOffset(RVA addr);
|
||||
void onSeekChanged(RVA addr);
|
||||
|
||||
private:
|
||||
RVA independentOffset = RVA_INVALID;
|
||||
RVA prevIdenpendentOffset = RVA_INVALID;
|
||||
bool isInSyncWithCore = true;
|
||||
|
||||
signals:
|
||||
void seekChanged(RVA addr);
|
||||
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
#include "DisassemblerGraphView.h"
|
||||
#include "CutterSeekableWidget.h"
|
||||
#include "CutterSeekable.h"
|
||||
#include <QPainter>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
@ -26,7 +26,7 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent)
|
||||
: GraphView(parent),
|
||||
mFontMetrics(nullptr),
|
||||
mMenu(new DisassemblyContextMenu(this)),
|
||||
seekable(new CutterSeekableWidget(this))
|
||||
seekable(new CutterSeekable(this))
|
||||
{
|
||||
highlight_token = nullptr;
|
||||
// Signals that require a refresh all
|
||||
@ -56,7 +56,7 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent)
|
||||
// ESC for previous
|
||||
QShortcut *shortcut_escape = new QShortcut(QKeySequence(Qt::Key_Escape), this);
|
||||
shortcut_escape->setContext(Qt::WidgetShortcut);
|
||||
connect(shortcut_escape, SIGNAL(activated()), this, SLOT(seekPrev()));
|
||||
connect(shortcut_escape, SIGNAL(activated()), seekable, SLOT(seekPrev()));
|
||||
|
||||
// Zoom shortcuts
|
||||
QShortcut *shortcut_zoom_in = new QShortcut(QKeySequence(Qt::Key_Plus), this);
|
||||
@ -124,10 +124,10 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent)
|
||||
void DisassemblerGraphView::connectSeekChanged(bool disconn)
|
||||
{
|
||||
if (disconn) {
|
||||
disconnect(seekable, &CutterSeekableWidget::seekChanged, this,
|
||||
disconnect(seekable, &CutterSeekable::seekableSeekChanged, this,
|
||||
&DisassemblerGraphView::onSeekChanged);
|
||||
} else {
|
||||
connect(seekable, &CutterSeekableWidget::seekChanged, this, &DisassemblerGraphView::onSeekChanged);
|
||||
connect(seekable, &CutterSeekable::seekableSeekChanged, this, &DisassemblerGraphView::onSeekChanged);
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,12 +140,11 @@ DisassemblerGraphView::~DisassemblerGraphView()
|
||||
|
||||
void DisassemblerGraphView::toggleSync()
|
||||
{
|
||||
seekable->toggleSyncWithCore();
|
||||
if (seekable->getSyncWithCore()) {
|
||||
seekable->toggleSynchronization();
|
||||
if (seekable->isSynchronized()) {
|
||||
parentWidget()->setWindowTitle(windowTitle);
|
||||
} else {
|
||||
parentWidget()->setWindowTitle(windowTitle + CutterSeekableWidget::tr(" (unsynced)"));
|
||||
seekable->setIndependentOffset(Core()->getOffset());
|
||||
parentWidget()->setWindowTitle(windowTitle + CutterSeekable::tr(" (unsynced)"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,8 +213,8 @@ void DisassemblerGraphView::loadCurrentGraph()
|
||||
} else if (!funcName.isEmpty()) {
|
||||
windowTitle += " (" + funcName + ")";
|
||||
}
|
||||
if (!seekable->getSyncWithCore()) {
|
||||
parentWidget()->setWindowTitle(windowTitle + CutterSeekableWidget::tr(" (unsynced)"));
|
||||
if (!seekable->isSynchronized()) {
|
||||
parentWidget()->setWindowTitle(windowTitle + CutterSeekable::tr(" (unsynced)"));
|
||||
} else {
|
||||
parentWidget()->setWindowTitle(windowTitle);
|
||||
}
|
||||
@ -775,15 +774,6 @@ void DisassemblerGraphView::seekLocal(RVA addr, bool update_viewport)
|
||||
}
|
||||
}
|
||||
|
||||
void DisassemblerGraphView::seekPrev()
|
||||
{
|
||||
if (seekable->getSyncWithCore()) {
|
||||
Core()->seekPrev();
|
||||
} else {
|
||||
seekable->seek(seekable->getPrevIndependentOffset());
|
||||
}
|
||||
}
|
||||
|
||||
DisassemblerGraphView::Token *DisassemblerGraphView::getToken(Instr *instr, int x)
|
||||
{
|
||||
x -= (3 * charWidth); // Ignore left margin
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "widgets/GraphView.h"
|
||||
#include "menus/DisassemblyContextMenu.h"
|
||||
#include "common/RichTextPainter.h"
|
||||
#include "CutterSeekableWidget.h"
|
||||
#include "CutterSeekable.h"
|
||||
|
||||
class QTextEdit;
|
||||
class SyntaxHighlighter;
|
||||
@ -149,8 +149,6 @@ protected:
|
||||
virtual void wheelEvent(QWheelEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void seekPrev();
|
||||
|
||||
void on_actionExportGraph_triggered();
|
||||
|
||||
private:
|
||||
@ -179,7 +177,7 @@ private:
|
||||
DisassemblyBlock *blockForAddress(RVA addr);
|
||||
void seekLocal(RVA addr, bool update_viewport = true);
|
||||
void seekInstruction(bool previous_instr);
|
||||
CutterSeekableWidget *seekable = nullptr;
|
||||
CutterSeekable *seekable = nullptr;
|
||||
QList<QShortcut *> shortcuts;
|
||||
QList<RVA> breakpoints;
|
||||
|
||||
|
@ -41,7 +41,7 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
|
||||
, mCtxMenu(new DisassemblyContextMenu(this))
|
||||
, mDisasScrollArea(new DisassemblyScrollArea(this))
|
||||
, mDisasTextEdit(new DisassemblyTextEdit(this))
|
||||
, seekable(new CutterSeekableWidget(this))
|
||||
, seekable(new CutterSeekable(this))
|
||||
{
|
||||
topOffset = bottomOffset = RVA_INVALID;
|
||||
cursorLineOffset = 0;
|
||||
@ -147,7 +147,7 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
|
||||
syncIt.setText(tr("Sync/unsync offset"));
|
||||
mCtxMenu->addAction(&syncIt);
|
||||
connect(&syncIt, SIGNAL(triggered(bool)), this, SLOT(toggleSync()));
|
||||
connect(seekable, &CutterSeekableWidget::seekChanged, this, &DisassemblyWidget::on_seekChanged);
|
||||
connect(seekable, &CutterSeekable::seekableSeekChanged, this, &DisassemblyWidget::on_seekChanged);
|
||||
|
||||
#define ADD_SHORTCUT(ksq, slot) { \
|
||||
QShortcut *s = new QShortcut((ksq), this); \
|
||||
@ -180,12 +180,11 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
|
||||
void DisassemblyWidget::toggleSync()
|
||||
{
|
||||
QString windowTitle = tr("Disassembly");
|
||||
seekable->toggleSyncWithCore();
|
||||
if (seekable->getSyncWithCore()) {
|
||||
seekable->toggleSynchronization();
|
||||
if (seekable->isSynchronized()) {
|
||||
setWindowTitle(windowTitle);
|
||||
} else {
|
||||
setWindowTitle(windowTitle + CutterSeekableWidget::tr(" (unsynced)"));
|
||||
seekable->setIndependentOffset(Core()->getOffset());
|
||||
setWindowTitle(windowTitle + CutterSeekable::tr(" (unsynced)"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include "Cutter.h"
|
||||
#include "CutterDockWidget.h"
|
||||
#include "CutterSeekableWidget.h"
|
||||
#include "CutterSeekable.h"
|
||||
#include <QTextEdit>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QShortcut>
|
||||
@ -72,7 +72,7 @@ private:
|
||||
|
||||
void moveCursorRelative(bool up, bool page);
|
||||
QAction syncIt;
|
||||
CutterSeekableWidget *seekable;
|
||||
CutterSeekable *seekable;
|
||||
};
|
||||
|
||||
class DisassemblyScrollArea : public QAbstractScrollArea
|
||||
|
@ -17,7 +17,7 @@
|
||||
HexdumpWidget::HexdumpWidget(MainWindow *main, QAction *action) :
|
||||
CutterDockWidget(main, action),
|
||||
ui(new Ui::HexdumpWidget),
|
||||
seekable(new CutterSeekableWidget(this))
|
||||
seekable(new CutterSeekable(this))
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@ -116,7 +116,7 @@ HexdumpWidget::HexdumpWidget(MainWindow *main, QAction *action) :
|
||||
connect(ui->hexHexText, &QTextEdit::cursorPositionChanged, this, &HexdumpWidget::selectionChanged);
|
||||
connect(ui->hexASCIIText, &QTextEdit::cursorPositionChanged, this,
|
||||
&HexdumpWidget::selectionChanged);
|
||||
connect(seekable, &CutterSeekableWidget::seekChanged, this, &HexdumpWidget::on_seekChanged);
|
||||
connect(seekable, &CutterSeekable::seekableSeekChanged, this, &HexdumpWidget::on_seekChanged);
|
||||
connect(&rangeDialog, &QDialog::accepted, this, &HexdumpWidget::on_rangeDialogAccepted);
|
||||
|
||||
format = Format::Hex;
|
||||
@ -652,12 +652,11 @@ void HexdumpWidget::showHexdumpContextMenu(const QPoint &pt)
|
||||
void HexdumpWidget::toggleSync()
|
||||
{
|
||||
QString windowTitle = tr("Hexdump");
|
||||
seekable->toggleSyncWithCore();
|
||||
if (seekable->getSyncWithCore()) {
|
||||
seekable->toggleSynchronization();
|
||||
if (seekable->isSynchronized()) {
|
||||
setWindowTitle(windowTitle);
|
||||
} else {
|
||||
setWindowTitle(windowTitle + CutterSeekableWidget::tr(" (unsynced)"));
|
||||
seekable->setIndependentOffset(Core()->getOffset());
|
||||
setWindowTitle(windowTitle + CutterSeekable::tr(" (unsynced)"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include "Cutter.h"
|
||||
#include "CutterDockWidget.h"
|
||||
#include "CutterSeekableWidget.h"
|
||||
#include "CutterSeekable.h"
|
||||
#include "dialogs/HexdumpRangeDialog.h"
|
||||
#include "common/Highlighter.h"
|
||||
#include "common/HexAsciiHighlighter.h"
|
||||
@ -107,7 +107,7 @@ private:
|
||||
ut64 requestedSelectionEndAddress=0;
|
||||
HexdumpRangeDialog rangeDialog;
|
||||
QAction syncAction;
|
||||
CutterSeekableWidget *seekable;
|
||||
CutterSeekable *seekable;
|
||||
|
||||
private slots:
|
||||
void on_seekChanged(RVA addr);
|
||||
|
Loading…
Reference in New Issue
Block a user