mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-19 03:16:10 +00:00
Fix a bug which causes segfault when adding another Graph (#1202)
This commit is contained in:
parent
a8fbe72bf7
commit
4a9b6182f5
@ -62,6 +62,7 @@
|
||||
#include "widgets/GraphView.h"
|
||||
#include "widgets/GraphWidget.h"
|
||||
#include "widgets/OverviewWidget.h"
|
||||
#include "widgets/OverviewView.h"
|
||||
#include "widgets/FunctionsWidget.h"
|
||||
#include "widgets/SectionsWidget.h"
|
||||
#include "widgets/SegmentsWidget.h"
|
||||
@ -192,17 +193,8 @@ void MainWindow::initUI()
|
||||
|
||||
// Add graph view as dockable
|
||||
overviewDock = new OverviewWidget(this, ui->actionOverview);
|
||||
graphDock = new GraphWidget(this, overviewDock, ui->actionGraph);
|
||||
|
||||
connect(graphDock, &QDockWidget::visibilityChanged, this, [ = ](bool visible) {
|
||||
ui->actionOverview->setChecked(visible);
|
||||
if (visible) {
|
||||
overviewDock->show();
|
||||
} else {
|
||||
overviewDock->hide();
|
||||
}
|
||||
});
|
||||
|
||||
graphDock = new GraphWidget(this, ui->actionGraph);
|
||||
sectionsDock = new SectionsWidget(this, ui->actionSections);
|
||||
segmentsDock = new SegmentsWidget(this, ui->actionSegments);
|
||||
entrypointDock = new EntrypointWidget(this, ui->actionEntrypoints);
|
||||
@ -290,6 +282,72 @@ void MainWindow::initUI()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::toggleOverview(bool visibility, GraphWidget *targetGraph)
|
||||
{
|
||||
if (!overviewDock) {
|
||||
return;
|
||||
}
|
||||
targetGraphDock = targetGraph;
|
||||
ui->actionOverview->setChecked(visibility);
|
||||
if (visibility) {
|
||||
connect(targetGraphDock->graphView, SIGNAL(refreshBlock()), this, SLOT(adjustOverview()));
|
||||
connect(targetGraphDock->graphView, SIGNAL(viewZoomed()), this, SLOT(adjustOverview()));
|
||||
connect(overviewDock->graphView, SIGNAL(mouseMoved()), this, SLOT(adjustGraph()));
|
||||
connect(overviewDock, &QDockWidget::dockLocationChanged, this, &MainWindow::adjustOverview);
|
||||
connect(overviewDock, SIGNAL(resized()), this, SLOT(adjustOverview()));
|
||||
overviewDock->show();
|
||||
} else {
|
||||
disconnect(targetGraphDock->graphView, SIGNAL(refreshBlock()), this, SLOT(adjustOverview()));
|
||||
disconnect(targetGraphDock->graphView, SIGNAL(viewZoomed()), this, SLOT(adjustOverview()));
|
||||
disconnect(overviewDock->graphView, SIGNAL(mouseMoved()), this, SLOT(adjustGraph()));
|
||||
disconnect(overviewDock, &QDockWidget::dockLocationChanged, this, &MainWindow::adjustOverview);
|
||||
disconnect(overviewDock, SIGNAL(resized()), this, SLOT(adjustOverview()));
|
||||
overviewDock->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setOverviewData()
|
||||
{
|
||||
overviewDock->graphView->setData(targetGraphDock->graphView->getWidth(),
|
||||
targetGraphDock->graphView->getHeight(), targetGraphDock->graphView->getBlocks());
|
||||
}
|
||||
|
||||
void MainWindow::adjustOverview()
|
||||
{
|
||||
if (!overviewDock) {
|
||||
return;
|
||||
}
|
||||
setOverviewData();
|
||||
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;
|
||||
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();
|
||||
}
|
||||
|
||||
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_x = rectx /curScale + overview_offset_x;
|
||||
targetGraphDock->graphView->offset_y = recty /curScale + overview_offset_y;
|
||||
targetGraphDock->graphView->viewport()->update();
|
||||
}
|
||||
|
||||
void MainWindow::updateTasksIndicator()
|
||||
{
|
||||
bool running = core->getAsyncTaskManager()->getTasksRunning();
|
||||
|
@ -105,7 +105,10 @@ public:
|
||||
|
||||
void updateDockActionChecked(QAction * action);
|
||||
|
||||
OverviewWidget *overviewDock = nullptr;
|
||||
QString getFilename() const
|
||||
{
|
||||
return filename;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void finalizeOpen();
|
||||
@ -129,6 +132,10 @@ public slots:
|
||||
|
||||
void openNewFileFailed();
|
||||
|
||||
void toggleOverview(bool visibility, GraphWidget *targetGraph);
|
||||
void adjustOverview();
|
||||
void adjustGraph();
|
||||
|
||||
private slots:
|
||||
void on_actionAbout_triggered();
|
||||
void on_actionIssue_triggered();
|
||||
@ -204,6 +211,8 @@ private:
|
||||
HexdumpWidget *hexdumpDock = nullptr;
|
||||
PseudocodeWidget *pseudocodeDock = nullptr;
|
||||
GraphWidget *graphDock = nullptr;
|
||||
GraphWidget *targetGraphDock = nullptr;
|
||||
OverviewWidget *overviewDock = nullptr;
|
||||
EntrypointWidget *entrypointDock = nullptr;
|
||||
FunctionsWidget *functionsDock = nullptr;
|
||||
ImportsWidget *importsDock = nullptr;
|
||||
@ -255,12 +264,7 @@ private:
|
||||
void toggleDockWidget(QDockWidget *dock_widget, bool show);
|
||||
|
||||
void updateDockActionsChecked();
|
||||
|
||||
public:
|
||||
QString getFilename() const
|
||||
{
|
||||
return filename;
|
||||
}
|
||||
void setOverviewData();
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
@ -31,6 +31,7 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent)
|
||||
seekable(new CutterSeekable(this))
|
||||
{
|
||||
highlight_token = nullptr;
|
||||
auto *layout = new QVBoxLayout(this);
|
||||
// Signals that require a refresh all
|
||||
connect(Core(), SIGNAL(refreshAll()), this, SLOT(refreshView()));
|
||||
connect(Core(), SIGNAL(commentsChanged()), this, SLOT(refreshView()));
|
||||
@ -124,9 +125,11 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent)
|
||||
header->setLineWrapMode(QTextEdit::NoWrap);
|
||||
|
||||
// Add header as widget to layout so it stretches to the layout width
|
||||
layout()->setContentsMargins(0, 0, 0, 0);
|
||||
layout()->setAlignment(Qt::AlignTop);
|
||||
layout()->addWidget(header);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setAlignment(Qt::AlignTop);
|
||||
layout->addWidget(header);
|
||||
|
||||
prepareHeader();
|
||||
|
||||
highlighter = new SyntaxHighlighter(header->document());
|
||||
}
|
||||
@ -194,12 +197,11 @@ void DisassemblerGraphView::loadCurrentGraph()
|
||||
if (emptyGraph) {
|
||||
// If there's no function to print, just add a message
|
||||
if (!emptyText) {
|
||||
auto *layout = new QVBoxLayout(this);
|
||||
emptyText = new QLabel(this);
|
||||
emptyText->setText(tr("No function detected. Cannot display graph."));
|
||||
emptyText->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||
layout->addWidget(emptyText);
|
||||
layout->setAlignment(emptyText, Qt::AlignHCenter);
|
||||
layout()->addWidget(emptyText);
|
||||
layout()->setAlignment(emptyText, Qt::AlignHCenter);
|
||||
}
|
||||
emptyText->setVisible(true);
|
||||
} else if (emptyText) {
|
||||
@ -962,6 +964,18 @@ void DisassemblerGraphView::on_actionExportGraph_triggered()
|
||||
fileOut << Core()->cmd("agfd $FB");
|
||||
}
|
||||
|
||||
void DisassemblerGraphView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
GraphView::mousePressEvent(event);
|
||||
emit graphMoved();
|
||||
}
|
||||
|
||||
void DisassemblerGraphView::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
GraphView::mouseMoveEvent(event);
|
||||
emit graphMoved();
|
||||
}
|
||||
|
||||
void DisassemblerGraphView::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
// when CTRL is pressed, we zoom in/out with mouse wheel
|
||||
@ -981,4 +995,5 @@ void DisassemblerGraphView::wheelEvent(QWheelEvent *event)
|
||||
// use mouse wheel for scrolling when CTRL is not pressed
|
||||
GraphView::wheelEvent(event);
|
||||
}
|
||||
emit graphMoved();
|
||||
}
|
||||
|
@ -152,7 +152,9 @@ public slots:
|
||||
void copySelection();
|
||||
|
||||
protected:
|
||||
virtual void wheelEvent(QWheelEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void wheelEvent(QWheelEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void on_actionExportGraph_triggered();
|
||||
@ -219,6 +221,7 @@ private:
|
||||
signals:
|
||||
void viewRefreshed();
|
||||
void viewZoomed();
|
||||
void graphMoved();
|
||||
};
|
||||
|
||||
#endif // DISASSEMBLERGRAPHVIEW_H
|
||||
|
@ -2,16 +2,14 @@
|
||||
#include "GraphWidget.h"
|
||||
#include "DisassemblerGraphView.h"
|
||||
#include "WidgetShortcuts.h"
|
||||
#include "OverviewView.h"
|
||||
|
||||
GraphWidget::GraphWidget(MainWindow *main, OverviewWidget *overview, QAction *action) :
|
||||
GraphWidget::GraphWidget(MainWindow *main, QAction *action) :
|
||||
CutterDockWidget(main, action)
|
||||
{
|
||||
this->setObjectName("Graph");
|
||||
this->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
this->graphView = new DisassemblerGraphView(this);
|
||||
this->setWidget(graphView);
|
||||
this->overviewWidget = overview;
|
||||
|
||||
// getting the name of the class is implementation defined, and cannot be
|
||||
// used reliably across different compilers.
|
||||
@ -23,15 +21,15 @@ GraphWidget::GraphWidget(MainWindow *main, OverviewWidget *overview, QAction *ac
|
||||
});
|
||||
|
||||
connect(this, &QDockWidget::visibilityChanged, this, [ = ](bool visibility) {
|
||||
toggleOverview(visibility);
|
||||
main->toggleOverview(visibility, this);
|
||||
if (visibility) {
|
||||
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Graph);
|
||||
this->graphView->refreshView();
|
||||
}
|
||||
});
|
||||
|
||||
connect(graphView, &DisassemblerGraphView::viewRefreshed, this, [ = ]() {
|
||||
overviewWidget->graphView->setData(graphView->getWidth(), graphView->getHeight(), graphView->getBlocks());
|
||||
connect(graphView, &DisassemblerGraphView::graphMoved, this, [ = ]() {
|
||||
main->toggleOverview(true, this);
|
||||
});
|
||||
|
||||
connect(Core(), &CutterCore::raisePrioritizedMemoryWidget,
|
||||
@ -45,68 +43,3 @@ GraphWidget::GraphWidget(MainWindow *main, OverviewWidget *overview, QAction *ac
|
||||
}
|
||||
|
||||
GraphWidget::~GraphWidget() {}
|
||||
|
||||
void GraphWidget::toggleOverview(bool visibility)
|
||||
{
|
||||
if (!overviewWidget) {
|
||||
return;
|
||||
}
|
||||
if (visibility) {
|
||||
connect(graphView, SIGNAL(refreshBlock()), this, SLOT(adjustOverview()));
|
||||
connect(graphView, SIGNAL(viewZoomed()), this, SLOT(adjustOverview()));
|
||||
connect(overviewWidget->graphView, SIGNAL(mouseMoved()), this, SLOT(adjustGraph()));
|
||||
connect(overviewWidget, &QDockWidget::dockLocationChanged, this, &GraphWidget::adjustOverview);
|
||||
connect(overviewWidget, &OverviewWidget::resized, this, &GraphWidget::adjustOverview);
|
||||
} else {
|
||||
disconnect(graphView, SIGNAL(refreshBlock()), this, SLOT(adjustOverview()));
|
||||
disconnect(graphView, SIGNAL(viewZoomed()), this, SLOT(adjustOverview()));
|
||||
disconnect(overviewWidget->graphView, SIGNAL(mouseMoved()), this, SLOT(adjustGraph()));
|
||||
disconnect(overviewWidget, &QDockWidget::dockLocationChanged, this, &GraphWidget::adjustOverview);
|
||||
disconnect(overviewWidget, &OverviewWidget::resized, this, &GraphWidget::adjustOverview);
|
||||
disableOverviewRect();
|
||||
}
|
||||
}
|
||||
|
||||
void GraphWidget::disableOverviewRect()
|
||||
{
|
||||
if (!overviewWidget) {
|
||||
return;
|
||||
}
|
||||
overviewWidget->graphView->rangeRect = QRectF(0, 0, 0, 0);
|
||||
overviewWidget->graphView->viewport()->update();
|
||||
}
|
||||
|
||||
void GraphWidget::adjustOverview()
|
||||
{
|
||||
if (!overviewWidget) {
|
||||
return;
|
||||
}
|
||||
qreal curScale = overviewWidget->graphView->current_scale;
|
||||
qreal baseScale = graphView->current_scale;
|
||||
qreal w = graphView->viewport()->width() * curScale / baseScale;
|
||||
qreal h = graphView->viewport()->height() * curScale / baseScale;
|
||||
int graph_offset_x = graphView->offset_x;
|
||||
int graph_offset_y = graphView->offset_y;
|
||||
int overview_offset_x = overviewWidget->graphView->offset_x;
|
||||
int overview_offset_y = overviewWidget->graphView->offset_y;
|
||||
int rangeRectX = graph_offset_x * curScale - overview_offset_x * curScale;
|
||||
int rangeRectY = graph_offset_y * curScale - overview_offset_y * curScale;
|
||||
|
||||
overviewWidget->graphView->rangeRect = QRectF(rangeRectX, rangeRectY, w, h);
|
||||
overviewWidget->graphView->viewport()->update();
|
||||
}
|
||||
|
||||
void GraphWidget::adjustGraph()
|
||||
{
|
||||
if (!overviewWidget) {
|
||||
return;
|
||||
}
|
||||
qreal curScale = overviewWidget->graphView->current_scale;
|
||||
int rectx = overviewWidget->graphView->rangeRect.x();
|
||||
int recty = overviewWidget->graphView->rangeRect.y();
|
||||
int overview_offset_x = overviewWidget->graphView->offset_x;
|
||||
int overview_offset_y = overviewWidget->graphView->offset_y;
|
||||
graphView->offset_x = rectx /curScale + overview_offset_x;
|
||||
graphView->offset_y = recty /curScale + overview_offset_y;
|
||||
graphView->viewport()->update();
|
||||
}
|
||||
|
@ -5,24 +5,15 @@
|
||||
|
||||
class MainWindow;
|
||||
class DisassemblerGraphView;
|
||||
class OverviewWidget;
|
||||
|
||||
class GraphWidget : public CutterDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GraphWidget(MainWindow *main, OverviewWidget *overview, QAction *action = nullptr);
|
||||
explicit GraphWidget(MainWindow *main, QAction *action = nullptr);
|
||||
~GraphWidget();
|
||||
private:
|
||||
DisassemblerGraphView *graphView;
|
||||
OverviewWidget *overviewWidget;
|
||||
|
||||
void toggleOverview(bool visibility);
|
||||
void disableOverviewRect();
|
||||
private slots:
|
||||
void adjustOverview();
|
||||
void adjustGraph();
|
||||
};
|
||||
|
||||
#endif // GRAPHWIDGET_H
|
||||
|
@ -26,7 +26,7 @@ OverviewView::~OverviewView()
|
||||
{
|
||||
}
|
||||
|
||||
void OverviewView::adjustScale()
|
||||
void OverviewView::refreshView()
|
||||
{
|
||||
current_scale = (qreal)viewport()->width() / width;
|
||||
qreal h_scale = (qreal)viewport()->height() / height;
|
||||
@ -37,13 +37,6 @@ void OverviewView::adjustScale()
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
void OverviewView::refreshView()
|
||||
{
|
||||
current_scale = 1.0;
|
||||
viewport()->update();
|
||||
adjustScale();
|
||||
}
|
||||
|
||||
void OverviewView::drawBlock(QPainter &p, GraphView::GraphBlock &block)
|
||||
{
|
||||
int blockX = block.x - offset_x;
|
||||
|
@ -97,11 +97,6 @@ private:
|
||||
*/
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
/*
|
||||
* \brief apply scale properly on the view
|
||||
*/
|
||||
void adjustScale();
|
||||
|
||||
/*
|
||||
* \brief if the mouse is in the rect in Overview.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user