From 552021c38d73567a737fda828cefeafc24b73c0c Mon Sep 17 00:00:00 2001 From: karliss Date: Sat, 29 Jun 2019 09:28:35 +0300 Subject: [PATCH] Move graph header to GraphWidget. (#1628) * prevents layout problems * fix header change when doubleclicking in unsynchronized function --- src/widgets/DisassemblerGraphView.cpp | 24 --------------------- src/widgets/DisassemblerGraphView.h | 4 ---- src/widgets/GraphView.cpp | 10 ++++++--- src/widgets/GraphWidget.cpp | 30 +++++++++++++++++++++++++-- src/widgets/GraphWidget.h | 3 +++ 5 files changed, 38 insertions(+), 33 deletions(-) diff --git a/src/widgets/DisassemblerGraphView.cpp b/src/widgets/DisassemblerGraphView.cpp index 89bd3057..0caa856c 100644 --- a/src/widgets/DisassemblerGraphView.cpp +++ b/src/widgets/DisassemblerGraphView.cpp @@ -157,19 +157,9 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent, CutterSeekable* se connect(blockMenu, &DisassemblyContextMenu::copy, this, &DisassemblerGraphView::copySelection); - header = new QTextEdit(); - header->setFixedHeight(30); - header->setReadOnly(true); - 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); - - prepareHeader(); - - highlighter = new SyntaxHighlighter(header->document()); } void DisassemblerGraphView::connectSeekChanged(bool disconn) @@ -395,17 +385,6 @@ void DisassemblerGraphView::cleanupEdges() } } -void DisassemblerGraphView::prepareHeader() -{ - QString afcf = Core()->cmd("afcf").trimmed(); - if (afcf.isEmpty()) { - header->hide(); - return; - } - header->show(); - header->setPlainText(afcf); -} - void DisassemblerGraphView::initFont() { setFont(Config()->getFont()); @@ -783,9 +762,6 @@ void DisassemblerGraphView::onSeekChanged(RVA addr) transition_dont_seek = true; showBlock(&blocks[db->entry], !switchFunction); showInstruction(blocks[db->entry], addr); - prepareHeader(); - } else { - header->hide(); } } diff --git a/src/widgets/DisassemblerGraphView.h b/src/widgets/DisassemblerGraphView.h index dee2ab43..b196ac4e 100644 --- a/src/widgets/DisassemblerGraphView.h +++ b/src/widgets/DisassemblerGraphView.h @@ -102,7 +102,6 @@ public: void loadCurrentGraph(); QString windowTitle; - QTextEdit *header = nullptr; int getWidth() { return width; } int getHeight() { return height; } @@ -157,7 +156,6 @@ private: void initFont(); void prepareGraphNode(GraphBlock &block); void cleanupEdges(); - void prepareHeader(); Token *getToken(Instr *instr, int x); QPoint getTextOffset(int line) const; QPoint getInstructionOffset(const DisassemblyBlock &block, int line) const; @@ -206,8 +204,6 @@ private: QAction actionSyncOffset; QLabel *emptyText = nullptr; - SyntaxHighlighter *highlighter = nullptr; - signals: void viewRefreshed(); void viewZoomed(); diff --git a/src/widgets/GraphView.cpp b/src/widgets/GraphView.cpp index 32b62a21..0602f53f 100644 --- a/src/widgets/GraphView.cpp +++ b/src/widgets/GraphView.cpp @@ -424,10 +424,14 @@ void GraphView::showRectangle(const QRect &block, bool anywhere) if (height * current_scale <= viewport()->height()) { centerY(false); } else { - static const int HEADER_HEIGHT = 35; // this could be handled better - if (!anywhere || block.y() < offset.y() + HEADER_HEIGHT + if (!anywhere || block.y() < offset.y() || block.bottom() > offset.y() + renderSize.height()) { - offset.ry() = block.y() - HEADER_HEIGHT / current_scale; + offset.ry() = block.y(); + // Leave some space at top if possible + const qreal topPadding = 10 / current_scale; + if (block.height() + topPadding < renderSize.height()) { + offset.ry() -= topPadding; + } } } clampViewOffset(); diff --git a/src/widgets/GraphWidget.cpp b/src/widgets/GraphWidget.cpp index 9073bacf..ec80f5cd 100644 --- a/src/widgets/GraphWidget.cpp +++ b/src/widgets/GraphWidget.cpp @@ -2,6 +2,7 @@ #include "GraphWidget.h" #include "DisassemblerGraphView.h" #include "WidgetShortcuts.h" +#include GraphWidget::GraphWidget(MainWindow *main, QAction *action) : MemoryDockWidget(CutterCore::MemoryWidgetType::Graph, main, action) @@ -11,8 +12,19 @@ GraphWidget::GraphWidget(MainWindow *main, QAction *action) : : getWidgetType()); setAllowedAreas(Qt::AllDockWidgetAreas); - graphView = new DisassemblerGraphView(this, seekable); - setWidget(graphView); + + auto *layoutWidget = new QWidget(this); + setWidget(layoutWidget); + auto *layout = new QVBoxLayout(layoutWidget); + layout->setContentsMargins(0, 0, 0, 0); + layoutWidget->setLayout(layout); + + header = new QLineEdit(this); + header->setReadOnly(true); + layout->addWidget(header); + + graphView = new DisassemblerGraphView(layoutWidget, seekable); + layout->addWidget(graphView); // getting the name of the class is implementation defined, and cannot be // used reliably across different compilers. @@ -36,6 +48,8 @@ GraphWidget::GraphWidget(MainWindow *main, QAction *action) : connect(graphView, &DisassemblerGraphView::graphMoved, this, [ = ]() { main->toggleOverview(true, this); }); + connect(seekable, &CutterSeekable::seekableSeekChanged, this, &GraphWidget::prepareHeader); + connect(Core(), &CutterCore::functionRenamed, this, &GraphWidget::prepareHeader); } QWidget *GraphWidget::widgetToFocusOnRaise() @@ -63,3 +77,15 @@ QString GraphWidget::getWidgetType() { return "Graph"; } + +void GraphWidget::prepareHeader() +{ + QString afcf = Core()->cmd(QString("afcf @%1").arg(seekable->getOffset())).trimmed(); + if (afcf.isEmpty()) { + header->hide(); + return; + } + header->show(); + header->setText(afcf); +} + diff --git a/src/widgets/GraphWidget.h b/src/widgets/GraphWidget.h index bc48b99d..542ea3e7 100644 --- a/src/widgets/GraphWidget.h +++ b/src/widgets/GraphWidget.h @@ -2,6 +2,7 @@ #define GRAPHWIDGET_H #include "MemoryDockWidget.h" +#include class MainWindow; class DisassemblerGraphView; @@ -28,8 +29,10 @@ private: void closeEvent(QCloseEvent *event) override; QString getWindowTitle() const override; + void prepareHeader(); DisassemblerGraphView *graphView; + QLineEdit *header = nullptr; }; #endif // GRAPHWIDGET_H