Fixed not switching Disassembly to not opened Graph view using <space> (#1370)

+ a bit refactor
This commit is contained in:
Anton Krasnokutskiy 2019-03-27 01:24:54 -07:00 committed by Florian Märkl
parent b3e27f713b
commit 5818998bb3
16 changed files with 164 additions and 110 deletions

View File

@ -312,7 +312,8 @@ SOURCES += \
plugins/PluginManager.cpp \
common/BasicBlockHighlighter.cpp \
dialogs/LinkTypeDialog.cpp \
common/UpdateWorker.cpp
common/UpdateWorker.cpp \
widgets/MemoryDockWidget.cpp
HEADERS += \
core/Cutter.h \
@ -428,7 +429,8 @@ HEADERS += \
plugins/PluginManager.h \
common/BasicBlockHighlighter.h \
common/UpdateWorker.h \
dialogs/LinkTypeDialog.h
dialogs/LinkTypeDialog.h \
widgets/MemoryDockWidget.h
FORMS += \
dialogs/AboutDialog.ui \

View File

@ -239,7 +239,7 @@ void MainWindow::initDocks()
graphDock = new GraphWidget(this, ui->actionGraph);
connect(ui->actionOverview, &QAction::toggled, [this](bool checked) {
if (checked) {
overviewDock->userClosed = false;
overviewDock->setUserClosed(false);
forceUpdateOverview();
if (targetGraphDock) {
toggleOverview(true, targetGraphDock);
@ -292,25 +292,25 @@ void MainWindow::toggleOverview(bool visibility, GraphWidget *targetGraph)
return;
}
ui->actionOverview->setEnabled(visibility);
if (overviewDock->userClosed || !visibility) {
if (overviewDock->getUserClosed() || !visibility) {
return;
}
targetGraphDock = targetGraph;
connect(targetGraphDock->graphView, SIGNAL(refreshBlock()), this, SLOT(updateOverview()));
connect(targetGraphDock->graphView, SIGNAL(viewRefreshed()), this, SLOT(forceUpdateOverview()));
connect(targetGraphDock->graphView, SIGNAL(viewZoomed()), this, SLOT(updateOverview()));
connect(targetGraphDock->getGraphView(), SIGNAL(refreshBlock()), this, SLOT(updateOverview()));
connect(targetGraphDock->getGraphView(), SIGNAL(viewRefreshed()), this, SLOT(forceUpdateOverview()));
connect(targetGraphDock->getGraphView(), SIGNAL(viewZoomed()), this, SLOT(updateOverview()));
connect(targetGraphDock, &GraphWidget::graphClose, [this]() {
disconnectOverview();
enableOverviewMenu(false);
overviewDock->hide();
});
connect(overviewDock->graphView, SIGNAL(mouseMoved()), this, SLOT(adjustGraph()));
connect(overviewDock->graphView, SIGNAL(refreshBlock()), this, SLOT(updateOverviewAddr()));
connect(overviewDock->getGraphView(), SIGNAL(mouseMoved()), this, SLOT(adjustGraph()));
connect(overviewDock->getGraphView(), SIGNAL(refreshBlock()), this, SLOT(updateOverviewAddr()));
connect(overviewDock, &QDockWidget::dockLocationChanged, this, &MainWindow::forceUpdateOverview);
connect(overviewDock, &OverviewWidget::graphClose, [this]() {
ui->actionOverview->setChecked(false);
if (!core->isGraphEmpty()) {
overviewDock->userClosed = true;
overviewDock->setUserClosed(true);
}
});
connect(overviewDock, SIGNAL(resized()), this, SLOT(forceUpdateOverview()));
@ -319,13 +319,13 @@ void MainWindow::toggleOverview(bool visibility, GraphWidget *targetGraph)
void MainWindow::disconnectOverview()
{
if (targetGraphDock) {
disconnect(targetGraphDock->graphView, SIGNAL(refreshBlock()), this, SLOT(updateOverview()));
disconnect(targetGraphDock->graphView, SIGNAL(viewRefreshed()), this, SLOT(updateOverview()));
disconnect(targetGraphDock->graphView, SIGNAL(viewZoomed()), this, SLOT(updateOverview()));
disconnect(targetGraphDock->getGraphView(), SIGNAL(refreshBlock()), this, SLOT(updateOverview()));
disconnect(targetGraphDock->getGraphView(), SIGNAL(viewRefreshed()), this, SLOT(updateOverview()));
disconnect(targetGraphDock->getGraphView(), SIGNAL(viewZoomed()), this, SLOT(updateOverview()));
}
if (overviewDock) {
disconnect(overviewDock->graphView, SIGNAL(mouseMoved()), this, SLOT(adjustGraph()));
disconnect(overviewDock->graphView, SIGNAL(refreshBlock()), this, SLOT(updateOverviewAddr()));
disconnect(overviewDock->getGraphView(), SIGNAL(mouseMoved()), this, SLOT(adjustGraph()));
disconnect(overviewDock->getGraphView(), SIGNAL(refreshBlock()), this, SLOT(updateOverviewAddr()));
disconnect(overviewDock, &QDockWidget::dockLocationChanged, this, &MainWindow::forceUpdateOverview);
disconnect(overviewDock, SIGNAL(resized()), this, SLOT(forceUpdateOverview()));
}
@ -333,13 +333,13 @@ void MainWindow::disconnectOverview()
void MainWindow::setOverviewData()
{
overviewDock->graphView->setData(targetGraphDock->graphView->getWidth(),
targetGraphDock->graphView->getHeight(), targetGraphDock->graphView->getBlocks());
overviewDock->getGraphView()->setData(targetGraphDock->getGraphView()->getWidth(),
targetGraphDock->getGraphView()->getHeight(), targetGraphDock->getGraphView()->getBlocks());
}
bool MainWindow::isOverviewActive()
{
if (!overviewDock || overviewDock->userClosed) {
if (!overviewDock || overviewDock->getUserClosed()) {
return false;
}
if (core->isGraphEmpty()) {
@ -352,7 +352,7 @@ bool MainWindow::isOverviewActive()
void MainWindow::updateOverviewAddr()
{
overviewDock->graphView->currentFcnAddr = targetGraphDock->graphView->currentFcnAddr;
overviewDock->getGraphView()->currentFcnAddr = targetGraphDock->getGraphView()->currentFcnAddr;
}
void MainWindow::forceUpdateOverview()
@ -360,7 +360,7 @@ void MainWindow::forceUpdateOverview()
if (!isOverviewActive()) {
return;
}
overviewDock->graphView->useCache = false;
overviewDock->getGraphView()->useCache = false;
setOverviewData();
drawOverview();
}
@ -370,30 +370,30 @@ void MainWindow::updateOverview()
if (!isOverviewActive()) {
return;
}
if (overviewDock->graphView->currentFcnAddr != targetGraphDock->graphView->currentFcnAddr) {
overviewDock->graphView->useCache = false;
if (overviewDock->getGraphView()->currentFcnAddr != targetGraphDock->getGraphView()->currentFcnAddr) {
overviewDock->getGraphView()->useCache = false;
setOverviewData();
} else {
overviewDock->graphView->useCache = true;
overviewDock->getGraphView()->useCache = true;
}
drawOverview();
}
void MainWindow::drawOverview()
{
qreal curScale = overviewDock->graphView->current_scale;
qreal baseScale = targetGraphDock->graphView->current_scale;
qreal w = targetGraphDock->graphView->viewport()->width() * curScale / baseScale;
qreal h = targetGraphDock->graphView->viewport()->height() * curScale / baseScale;
int graph_offset_x = targetGraphDock->graphView->offset.x();
int graph_offset_y = targetGraphDock->graphView->offset.y();
int overview_offset_x = overviewDock->graphView->offset.x();
int overview_offset_y = overviewDock->graphView->offset.y();
qreal curScale = overviewDock->getGraphView()->current_scale;
qreal baseScale = targetGraphDock->getGraphView()->current_scale;
qreal w = targetGraphDock->getGraphView()->viewport()->width() * curScale / baseScale;
qreal h = targetGraphDock->getGraphView()->viewport()->height() * curScale / baseScale;
int graph_offset_x = targetGraphDock->getGraphView()->offset.x();
int graph_offset_y = targetGraphDock->getGraphView()->offset.y();
int overview_offset_x = overviewDock->getGraphView()->offset.x();
int overview_offset_y = overviewDock->getGraphView()->offset.y();
int rangeRectX = graph_offset_x * curScale - overview_offset_x * curScale;
int rangeRectY = graph_offset_y * curScale - overview_offset_y * curScale;
overviewDock->graphView->rangeRect = QRectF(rangeRectX, rangeRectY, w, h);
overviewDock->graphView->viewport()->update();
overviewDock->getGraphView()->rangeRect = QRectF(rangeRectX, rangeRectY, w, h);
overviewDock->getGraphView()->viewport()->update();
enableOverviewMenu(true);
overviewDock->show();
}
@ -403,14 +403,15 @@ void MainWindow::adjustGraph()
if (!overviewDock) {
return;
}
qreal curScale = overviewDock->graphView->current_scale;
int rectx = overviewDock->graphView->rangeRect.x();
int recty = overviewDock->graphView->rangeRect.y();
int overview_offset_x = overviewDock->graphView->offset.x();
int overview_offset_y = overviewDock->graphView->offset.y();
targetGraphDock->graphView->offset.rx() = rectx /curScale + overview_offset_x;
targetGraphDock->graphView->offset.ry() = recty /curScale + overview_offset_y;
targetGraphDock->graphView->viewport()->update();
qreal curScale = overviewDock->getGraphView()->current_scale;
int rectx = overviewDock->getGraphView()->rangeRect.x();
int recty = overviewDock->getGraphView()->rangeRect.y();
int overview_offset_x = overviewDock->getGraphView()->offset.x();
int overview_offset_y = overviewDock->getGraphView()->offset.y();
targetGraphDock->getGraphView()->offset.rx() = rectx /curScale + overview_offset_x;
targetGraphDock->getGraphView()->offset.ry() = recty /curScale + overview_offset_y;
targetGraphDock->getGraphView()->viewport()->update();
}
void MainWindow::updateTasksIndicator()

View File

@ -44,6 +44,11 @@ void CutterDockWidget::toggleDockWidget(bool show)
}
}
QWidget *CutterDockWidget::widgetToFocusOnRaise()
{
return this;
}
void CutterDockWidget::updateIsVisibleToUser()
{
// Check if the user can actually see the widget.
@ -65,3 +70,8 @@ void CutterDockWidget::closeEvent(QCloseEvent *event)
QDockWidget::closeEvent(event);
}
QAction *CutterDockWidget::getBoundAction() const
{
return action;
}

View File

@ -49,20 +49,23 @@ public:
return deferrer;
}
signals:
void becameVisibleToUser();
public slots:
void toggleDockWidget(bool show);
signals:
void becameVisibleToUser();
protected:
virtual QWidget* widgetToFocusOnRaise();
void closeEvent(QCloseEvent *event) override;
QAction *getBoundAction() const;
private:
QAction *action;
bool isVisibleToUserCurrent = false;
void updateIsVisibleToUser();
protected:
void closeEvent(QCloseEvent *event) override;
};
#endif // CUTTERWIDGET_H

View File

@ -36,7 +36,7 @@ static DisassemblyTextBlockUserData *getUserData(const QTextBlock &block)
}
DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
: CutterDockWidget(main, action)
: MemoryDockWidget(CutterCore::MemoryWidgetType::Disassembly, main, action)
, mCtxMenu(new DisassemblyContextMenu(this))
, mDisasScrollArea(new DisassemblyScrollArea(this))
, mDisasTextEdit(new DisassemblyTextEdit(this))
@ -119,8 +119,6 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
}
});
connect(Core(), SIGNAL(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)), this,
SLOT(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)));
connect(Core(), SIGNAL(commentsChanged()), this, SLOT(refreshDisasm()));
connect(Core(), SIGNAL(flagsChanged()), this, SLOT(refreshDisasm()));
connect(Core(), SIGNAL(functionsChanged()), this, SLOT(refreshDisasm()));
@ -645,15 +643,6 @@ void DisassemblyWidget::on_seekChanged(RVA offset)
mCtxMenu->setOffset(offset);
}
void DisassemblyWidget::raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type)
{
bool emptyGraph = (type == CutterCore::MemoryWidgetType::Graph && Core()->isGraphEmpty());
if (type == CutterCore::MemoryWidgetType::Disassembly || emptyGraph) {
raise();
setFocus();
}
}
void DisassemblyWidget::fontsUpdatedSlot()
{
setupFonts();

View File

@ -2,7 +2,7 @@
#define DISASSEMBLYWIDGET_H
#include "core/Cutter.h"
#include "CutterDockWidget.h"
#include "MemoryDockWidget.h"
#include "common/CutterSeekable.h"
#include "common/RefreshDeferrer.h"
@ -16,7 +16,7 @@ class DisassemblyTextEdit;
class DisassemblyScrollArea;
class DisassemblyContextMenu;
class DisassemblyWidget : public CutterDockWidget
class DisassemblyWidget : public MemoryDockWidget
{
Q_OBJECT
public:
@ -34,7 +34,6 @@ public slots:
private slots:
void on_seekChanged(RVA offset);
void refreshDisasm(RVA offset = RVA_INVALID);
void raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type);
void scrollInstructions(int count);
bool updateMaxLines();

View File

@ -4,7 +4,7 @@
#include "WidgetShortcuts.h"
GraphWidget::GraphWidget(MainWindow *main, QAction *action) :
CutterDockWidget(main, action)
MemoryDockWidget(CutterCore::MemoryWidgetType::Graph, main, action)
{
/*
* Ugly hack just for the layout issue
@ -34,7 +34,6 @@ GraphWidget::GraphWidget(MainWindow *main, QAction *action) :
main->toggleOverview(visibility, this);
if (visibility) {
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Graph);
graphView->refreshView();
graphView->onSeekChanged(Core()->getOffset());
}
});
@ -42,21 +41,20 @@ GraphWidget::GraphWidget(MainWindow *main, QAction *action) :
connect(graphView, &DisassemblerGraphView::graphMoved, this, [ = ]() {
main->toggleOverview(true, this);
});
connect(Core(), &CutterCore::raisePrioritizedMemoryWidget,
this, [ = ](CutterCore::MemoryWidgetType type) {
bool emptyGraph = (type == CutterCore::MemoryWidgetType::Graph && Core()->isGraphEmpty());
if (type == CutterCore::MemoryWidgetType::Graph && !emptyGraph) {
raise();
graphView->setFocus();
}
});
}
GraphWidget::~GraphWidget() {}
QWidget *GraphWidget::widgetToFocusOnRaise()
{
return graphView;
}
void GraphWidget::closeEvent(QCloseEvent *event)
{
CutterDockWidget::closeEvent(event);
emit graphClose();
}
DisassemblerGraphView *GraphWidget::getGraphView() const
{
return graphView;
}

View File

@ -1,25 +1,31 @@
#ifndef GRAPHWIDGET_H
#define GRAPHWIDGET_H
#include "CutterDockWidget.h"
#include "MemoryDockWidget.h"
class MainWindow;
class DisassemblerGraphView;
class GraphWidget : public CutterDockWidget
class GraphWidget : public MemoryDockWidget
{
Q_OBJECT
public:
explicit GraphWidget(MainWindow *main, QAction *action = nullptr);
~GraphWidget();
DisassemblerGraphView *graphView;
~GraphWidget() {}
DisassemblerGraphView *getGraphView() const;
signals:
void graphClose();
protected:
QWidget *widgetToFocusOnRaise() override;
private:
void closeEvent(QCloseEvent *event) override;
signals:
void graphClose();
DisassemblerGraphView *graphView;
};
#endif // GRAPHWIDGET_H

View File

@ -15,7 +15,7 @@
#include <QInputDialog>
HexdumpWidget::HexdumpWidget(MainWindow *main, QAction *action) :
CutterDockWidget(main, action),
MemoryDockWidget(CutterCore::MemoryWidgetType::Hexdump, main, action),
ui(new Ui::HexdumpWidget),
seekable(new CutterSeekable(this))
{
@ -115,9 +115,6 @@ HexdumpWidget::HexdumpWidget(MainWindow *main, QAction *action) :
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdated()));
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(colorsUpdatedSlot()));
connect(Core(), SIGNAL(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)), this,
SLOT(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)));
connect(this, &QDockWidget::visibilityChanged, this, [](bool visibility) {
if (visibility) {
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Hexdump);
@ -234,13 +231,6 @@ void HexdumpWidget::onSeekChanged(RVA)
refresh();
}
void HexdumpWidget::raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type)
{
if (type == CutterCore::MemoryWidgetType::Hexdump) {
raise();
}
}
void HexdumpWidget::connectScroll(bool disconnect_)
{
scroll_disabled = disconnect_;

View File

@ -10,7 +10,7 @@
#include <memory>
#include "core/Cutter.h"
#include "CutterDockWidget.h"
#include "MemoryDockWidget.h"
#include "common/CutterSeekable.h"
#include "dialogs/HexdumpRangeDialog.h"
#include "common/Highlighter.h"
@ -26,11 +26,9 @@ namespace Ui {
class RefreshDeferrer;
class HexdumpWidget : public CutterDockWidget
class HexdumpWidget : public MemoryDockWidget
{
Q_OBJECT
public:
explicit HexdumpWidget(MainWindow *main, QAction *action = nullptr);
~HexdumpWidget();
@ -118,7 +116,6 @@ private:
private slots:
void onSeekChanged(RVA addr);
void raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type);
// Currently unused/untested
// void highlightHexCurrentLine();

View File

@ -0,0 +1,26 @@
#include "MemoryDockWidget.h"
#include <QAction>
MemoryDockWidget::MemoryDockWidget(CutterCore::MemoryWidgetType type, MainWindow *parent, QAction *action)
: CutterDockWidget(parent, action)
, mType(type)
{
connect(Core(), &CutterCore::raisePrioritizedMemoryWidget, this, &MemoryDockWidget::handleRaiseMemoryWidget);
}
void MemoryDockWidget::handleRaiseMemoryWidget(CutterCore::MemoryWidgetType raiseType)
{
bool raisingEmptyGraph = (raiseType == CutterCore::MemoryWidgetType::Graph && Core()->isGraphEmpty());
if (raisingEmptyGraph) {
raiseType = CutterCore::MemoryWidgetType::Disassembly;
}
if (raiseType == mType) {
getBoundAction()->setChecked(true);
show();
raise();
widgetToFocusOnRaise()->setFocus(Qt::FocusReason::TabFocusReason);
}
}

View File

@ -0,0 +1,20 @@
#ifndef MEMORYDOCKWIDGET_H
#define MEMORYDOCKWIDGET_H
#include "CutterDockWidget.h"
#include "core/Cutter.h"
class MemoryDockWidget : public CutterDockWidget
{
Q_OBJECT
public:
MemoryDockWidget(CutterCore::MemoryWidgetType type, MainWindow *parent, QAction *action = nullptr);
~MemoryDockWidget() {}
private:
void handleRaiseMemoryWidget(CutterCore::MemoryWidgetType raiseType);
CutterCore::MemoryWidgetType mType;
};
#endif // MEMORYDOCKWIDGET_H

View File

@ -43,3 +43,18 @@ void OverviewWidget::closeEvent(QCloseEvent *event)
CutterDockWidget::closeEvent(event);
emit graphClose();
}
void OverviewWidget::setUserClosed(bool value)
{
userClosed = value;
}
bool OverviewWidget::getUserClosed() const
{
return userClosed;
}
OverviewView *OverviewWidget::getGraphView() const
{
return graphView;
}

View File

@ -13,12 +13,15 @@ class OverviewWidget : public CutterDockWidget
public:
explicit OverviewWidget(MainWindow *main, QAction *action = nullptr);
~OverviewWidget();
OverviewView *graphView;
OverviewView *getGraphView() const;
/*
* @brief if user closed this widget explicitly
*/
bool userClosed = false;
bool getUserClosed() const;
void setUserClosed(bool value);
private:
RefreshDeferrer *refreshDeferrer;
/**
@ -45,6 +48,11 @@ signals:
* @brief emit signal to notify when this widget is closed
*/
void graphClose();
private:
OverviewView *graphView;
bool userClosed = false;
};
#endif // OverviewWIDGET_H

View File

@ -9,7 +9,7 @@
#include "common/TempConfig.h"
PseudocodeWidget::PseudocodeWidget(MainWindow *main, QAction *action) :
CutterDockWidget(main, action),
MemoryDockWidget(CutterCore::MemoryWidgetType::Pseudocode, main, action),
ui(new Ui::PseudocodeWidget)
{
ui->setupUi(this);
@ -22,8 +22,6 @@ PseudocodeWidget::PseudocodeWidget(MainWindow *main, QAction *action) :
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdated()));
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(colorsUpdatedSlot()));
connect(Core(), SIGNAL(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)), this,
SLOT(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)));
connect(this, &QDockWidget::visibilityChanged, this, [](bool visibility) {
if (visibility) {
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Pseudocode);
@ -82,13 +80,6 @@ void PseudocodeWidget::refreshPseudocode()
doRefresh(Core()->getOffset());
}
void PseudocodeWidget::raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type)
{
if (type == CutterCore::MemoryWidgetType::Pseudocode) {
raise();
}
}
void PseudocodeWidget::setupFonts()
{
QFont font = Config()->getFont();

View File

@ -4,7 +4,7 @@
#include <memory>
#include "core/Cutter.h"
#include "CutterDockWidget.h"
#include "MemoryDockWidget.h"
namespace Ui {
class PseudocodeWidget;
@ -13,7 +13,7 @@ class PseudocodeWidget;
class QTextEdit;
class SyntaxHighlighter;
class PseudocodeWidget : public CutterDockWidget
class PseudocodeWidget : public MemoryDockWidget
{
Q_OBJECT
@ -22,7 +22,6 @@ public:
~PseudocodeWidget();
private slots:
void raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type);
void fontsUpdated();
void colorsUpdatedSlot();
void refreshPseudocode();