Adding a header to the DisassemblyWidget to show the function prototype (#771)

* Adding a header to the DisassemblyWidget to show the function prototype

* Moving the afcf headerLabel functionality to the GraphWidget

* In middle of implementation

* In middle

* syntax highlighter added

* Implementation done.

* Fixed the changes that were not necessary.
This commit is contained in:
Vanellope 2018-10-16 23:49:26 +09:00 committed by Itay Cohen
parent 4b454e086e
commit 842dda45bd
3 changed files with 61 additions and 6 deletions

View File

@ -8,6 +8,7 @@
#include <QShortcut> #include <QShortcut>
#include <QToolTip> #include <QToolTip>
#include <QTextDocument> #include <QTextDocument>
#include <QTextEdit>
#include <QFileDialog> #include <QFileDialog>
#include <QFile> #include <QFile>
#include <QVBoxLayout> #include <QVBoxLayout>
@ -19,6 +20,7 @@
#include "utils/Configuration.h" #include "utils/Configuration.h"
#include "utils/CachedFontMetrics.h" #include "utils/CachedFontMetrics.h"
#include "utils/TempConfig.h" #include "utils/TempConfig.h"
#include "utils/SyntaxHighlighter.h"
DisassemblerGraphView::DisassemblerGraphView(QWidget *parent) DisassemblerGraphView::DisassemblerGraphView(QWidget *parent)
: GraphView(parent), : GraphView(parent),
@ -111,6 +113,12 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent)
connect(&actionSyncOffset, SIGNAL(triggered(bool)), this, SLOT(toggleSync())); connect(&actionSyncOffset, SIGNAL(triggered(bool)), this, SLOT(toggleSync()));
initFont(); initFont();
colorsUpdatedSlot(); colorsUpdatedSlot();
header = new QTextEdit(viewport());
header->setFixedHeight(30);
header->setReadOnly(true);
header->setLineWrapMode(QTextEdit::NoWrap);
highlighter = new SyntaxHighlighter(header->document());
} }
void DisassemblerGraphView::connectSeekChanged(bool disconn) void DisassemblerGraphView::connectSeekChanged(bool disconn)
@ -336,6 +344,44 @@ void DisassemblerGraphView::prepareGraphNode(GraphBlock &block)
block.height = (height * charHeight) + extra; block.height = (height * charHeight) + extra;
} }
void DisassemblerGraphView::prepareHeader()
{
QString afcf = Core()->cmd("afcf").trimmed();
if (afcf.length() > 0) {
header->setPlainText(afcf);
header->show();
return;
}
QJsonArray func = Core()->cmdj("afij").array();
QJsonValue value = func.first();
QJsonObject obj = value.toObject();
QString name = obj["name"].toString().trimmed();
if (name.isEmpty()) {
header->hide();
return;
}
QString ret = obj["calltype"].toString().trimmed();
ret += (" ") + name + ("(");
QJsonArray args = obj["bpvars"].toArray();
QString argNames = QString();
for (QJsonValue value : args) {
QJsonObject obj = value.toObject();
QString kind = obj["kind"].toString();
if (kind == "arg") {
QString typeName = obj["type"].toString().trimmed();
QString argName = obj["name"].toString().trimmed();
if (argNames.isEmpty()) {
argNames += typeName + (" ") + argName;
} else {
argNames += (", ") + typeName + (" ") + argName;
}
}
}
ret += argNames + (")");
header->setPlainText(ret);
header->show();
}
void DisassemblerGraphView::initFont() void DisassemblerGraphView::initFont()
{ {
setFont(Config()->getFont()); setFont(Config()->getFont());
@ -629,14 +675,16 @@ void DisassemblerGraphView::onSeekChanged(RVA addr)
// This is a local address! We animated to it. // This is a local address! We animated to it.
transition_dont_seek = true; transition_dont_seek = true;
showBlock(&blocks[db->entry], true); showBlock(&blocks[db->entry], true);
prepareHeader();
return; return;
} else { } else {
refreshView(); refreshView();
DisassemblyBlock *db = blockForAddress(addr); db = blockForAddress(addr);
if (db) { if (db) {
// This is a local address! We animated to it. // This is a local address! We animated to it.
transition_dont_seek = true; transition_dont_seek = true;
showBlock(&blocks[db->entry], false); showBlock(&blocks[db->entry], true);
prepareHeader();
return; return;
} }
} }

View File

@ -13,6 +13,9 @@
#include "utils/RichTextPainter.h" #include "utils/RichTextPainter.h"
#include "CutterSeekableWidget.h" #include "CutterSeekableWidget.h"
class QTextEdit;
class SyntaxHighlighter;
class DisassemblerGraphView : public GraphView class DisassemblerGraphView : public GraphView
{ {
Q_OBJECT Q_OBJECT
@ -123,6 +126,7 @@ public:
void loadCurrentGraph(); void loadCurrentGraph();
QString windowTitle; QString windowTitle;
bool isGraphEmpty(); bool isGraphEmpty();
QTextEdit *header = nullptr;
public slots: public slots:
void refreshView(); void refreshView();
@ -168,6 +172,7 @@ private:
void initFont(); void initFont();
void prepareGraphNode(GraphBlock &block); void prepareGraphNode(GraphBlock &block);
void prepareHeader();
Token *getToken(Instr *instr, int x); Token *getToken(Instr *instr, int x);
RVA getAddrForMouseEvent(GraphBlock &block, QPoint *point); RVA getAddrForMouseEvent(GraphBlock &block, QPoint *point);
Instr *getInstrForMouseEvent(GraphBlock &block, QPoint *point); Instr *getInstrForMouseEvent(GraphBlock &block, QPoint *point);
@ -206,6 +211,7 @@ private:
QAction actionSyncOffset; QAction actionSyncOffset;
QLabel *emptyText = nullptr; QLabel *emptyText = nullptr;
SyntaxHighlighter *highlighter = nullptr;
}; };
#endif // DISASSEMBLERGRAPHVIEW_H #endif // DISASSEMBLERGRAPHVIEW_H

View File

@ -14,16 +14,16 @@ GraphWidget::GraphWidget(MainWindow *main, QAction *action) :
// getting the name of the class is implementation defined, and cannot be // getting the name of the class is implementation defined, and cannot be
// used reliably across different compilers. // used reliably across different compilers.
//QShortcut *toggle_shortcut = new QShortcut(widgetShortcuts[typeid(this).name()], main); //QShortcut *toggle_shortcut = new QShortcut(widgetShortcuts[typeid(this).name()], main);
QShortcut *toggle_shortcut = new QShortcut(widgetShortcuts["GraphWidget"], main); QShortcut *toggle_shortcut = new QShortcut(widgetShortcuts["GraphWidget"], main);
connect(toggle_shortcut, &QShortcut::activated, this, [ = ]() { connect(toggle_shortcut, &QShortcut::activated, this, [ = ]() {
toggleDockWidget(true); toggleDockWidget(true);
main->updateDockActionChecked(action); main->updateDockActionChecked(action);
}); });
connect(this, &QDockWidget::visibilityChanged, this, [](bool visibility) { connect(this, &QDockWidget::visibilityChanged, this, [ = ](bool visibility) {
if (visibility) { if (visibility) {
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Graph); Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Graph);
this->graphView->header->setFixedWidth(width());
} }
}); });
@ -33,6 +33,7 @@ GraphWidget::GraphWidget(MainWindow *main, QAction *action) :
if (type == CutterCore::MemoryWidgetType::Graph && !emptyGraph) { if (type == CutterCore::MemoryWidgetType::Graph && !emptyGraph) {
this->raise(); this->raise();
this->graphView->setFocus(); this->graphView->setFocus();
this->graphView->header->setFixedWidth(width());
} }
}); });
} }