Skip to content
Permalink
Browse files

Multiple graph/disasm/hexdump widgets and independent seeks (#504)

  • Loading branch information...
fcasal authored and xarkes committed May 25, 2018
1 parent f2dab2d commit 0cea9e3287fa12a8a240834a7484c1a957f686c1
@@ -55,7 +55,7 @@ CutterCore::CutterCore(QObject *parent) :

// Otherwise r2 may ask the user for input and Cutter would freeze
setConfig("scr.interactive", false);

#if defined(APPIMAGE) || defined(MACOS_R2_BUNDLED)
auto prefix = QDir(QCoreApplication::applicationDirPath());
# ifdef APPIMAGE
@@ -155,6 +155,7 @@ SOURCES += \
utils/NestedIPyKernel.cpp \
dialogs/R2PluginsDialog.cpp \
widgets/CutterDockWidget.cpp \
widgets/CutterSeekableWidget.cpp \
widgets/GraphWidget.cpp \
utils/JsonTreeItem.cpp \
utils/JsonModel.cpp \
@@ -229,6 +230,7 @@ HEADERS += \
utils/NestedIPyKernel.h \
dialogs/R2PluginsDialog.h \
widgets/CutterDockWidget.h \
widgets/CutterSeekableWidget.h \
widgets/GraphWidget.h \
utils/JsonTreeItem.h \
utils/JsonModel.h \
@@ -223,6 +223,32 @@ void MainWindow::initUI()
connect(core, SIGNAL(projectSaved(const QString &)), this, SLOT(projectSaved(const QString &)));
}

void MainWindow::on_actionExtraGraph_triggered()
{
QDockWidget *extraDock = new GraphWidget(this, 0);
addExtraWidget(extraDock);
}

void MainWindow::on_actionExtraHexdump_triggered()
{
QDockWidget *extraDock = new HexdumpWidget(this, 0);
addExtraWidget(extraDock);
}

void MainWindow::on_actionExtraDisassembly_triggered()
{
QDockWidget *extraDock = new DisassemblyWidget(this, 0);
addExtraWidget(extraDock);
}

void MainWindow::addExtraWidget(QDockWidget *extraDock)
{
addDockWidget(Qt::TopDockWidgetArea, extraDock);
auto restoreExtraDock = qhelpers::forceWidth(extraDock->widget(), 600);
qApp->processEvents();
restoreExtraDock.restoreWidth(extraDock->widget());
}

void MainWindow::openNewFile(const QString &fn, int analLevel, QList<QString> advancedOptions)
{
setFilename(fn);
@@ -525,6 +551,23 @@ void MainWindow::showDefaultDocks()
updateDockActionsChecked();
}

void MainWindow::showZenDocks()
{
const QList<QDockWidget *> zenDocks = { functionsDock,
stringsDock,
graphDock,
disassemblyDock,
hexdumpDock,
searchDock
};
for (auto w : dockWidgets) {
if (zenDocks.contains(w)) {
w->show();
}
}
updateDockActionsChecked();
}

void MainWindow::resetToDefaultLayout()
{
hideAllDocks();
@@ -545,6 +588,24 @@ void MainWindow::resetToDefaultLayout()
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Disassembly);
}

void MainWindow::resetToZenLayout()
{
hideAllDocks();
restoreDocks();
showZenDocks();
disassemblyDock->raise();

// ugly workaround to set the default widths of functions
// if anyone finds a way to do this cleaner that also works, feel free to change it!
auto restoreFunctionDock = qhelpers::forceWidth(functionsDock->widget(), 200);

qApp->processEvents();

restoreFunctionDock.restoreWidth(functionsDock->widget());

Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Disassembly);
}

void MainWindow::addOutput(const QString &msg)
{
consoleDock->addOutput(msg);
@@ -590,6 +651,11 @@ void MainWindow::on_actionDefault_triggered()
resetToDefaultLayout();
}

void MainWindow::on_actionZen_triggered()
{
resetToZenLayout();
}

void MainWindow::on_actionNew_triggered()
{
on_actionOpen_triggered();
@@ -761,7 +827,6 @@ bool MainWindow::eventFilter(QObject *, QEvent *event)
return true;
}
}

return false;
}

@@ -95,6 +95,8 @@ class MainWindow : public QMainWindow

void addToDockWidgetList(QDockWidget *dockWidget);
void addDockWidgetAction(QDockWidget *dockWidget, QAction *action);
void addExtraWidget(QDockWidget *extraDock);


public slots:

@@ -119,12 +121,16 @@ public slots:

private slots:
void on_actionAbout_triggered();
void on_actionExtraGraph_triggered();
void on_actionExtraHexdump_triggered();
void on_actionExtraDisassembly_triggered();

void on_actionRefresh_Panels_triggered();

void on_actionDisasAdd_comment_triggered();

void on_actionDefault_triggered();
void on_actionZen_triggered();

void on_actionFunctionsRename_triggered();

@@ -211,10 +217,12 @@ private slots:
#endif

void resetToDefaultLayout();
void resetToZenLayout();

void restoreDocks();
void hideAllDocks();
void showDefaultDocks();
void showZenDocks();
void updateDockActionsChecked();

void toggleDockWidget(QDockWidget *dock_widget, bool show);
@@ -201,6 +201,7 @@ border-top: 0px;
<addaction name="actionRefresh_contents"/>
<addaction name="separator"/>
<addaction name="actionDefault"/>
<addaction name="actionZen"/>
<addaction name="actionReset_settings"/>
<addaction name="separator"/>
<addaction name="actionLock"/>
@@ -256,6 +257,8 @@ border-top: 0px;
<addaction name="actionComments"/>
<addaction name="actionConsole"/>
<addaction name="actionJupyter"/>
<addaction name="separator"/>
<addaction name="addExtraWidgets"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuEdit"/>
@@ -322,6 +325,14 @@ background-color: palette(dark);
<string>Reset layout</string>
</property>
</action>
<action name="actionZen">
<property name="text">
<string>Zen Mode</string>
</property>
<property name="toolTip">
<string>Zen mode</string>
</property>
</action>
<action name="actionAbout">
<property name="text">
<string>About</string>
@@ -1093,6 +1104,29 @@ background-color: palette(dark);
<string>Jupyter</string>
</property>
</action>
<action name="actionExtraGraph">
<property name="text">
<string>Graph view</string>
</property>
</action>
<action name="actionExtraHexdump">
<property name="text">
<string>Hexdump view</string>
</property>
</action>
<action name="actionExtraDisassembly">
<property name="text">
<string>Disassembly view</string>
</property>
</action>
<widget class="QMenu" name="addExtraWidgets">
<property name="title">
<string>Add extra...</string>
</property>
<addaction name="actionExtraGraph"/>
<addaction name="actionExtraHexdump"/>
<addaction name="actionExtraDisassembly"/>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
@@ -6,8 +6,8 @@ CutterDockWidget::CutterDockWidget(MainWindow *main, QAction *action) :
QDockWidget(main),
action(action)
{
main->addToDockWidgetList(this);
if (action) {
main->addToDockWidgetList(this);
main->addDockWidgetAction(this, action);
connect(action, &QAction::triggered, this, &CutterDockWidget::toggleDockWidget);
}
@@ -0,0 +1,67 @@
#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() {}
@@ -0,0 +1,32 @@
#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);

};
Oops, something went wrong.

0 comments on commit 0cea9e3

Please sign in to comment.
You can’t perform that action at this time.