mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-24 05:45:27 +00:00
* Fixed #807 - Function summary displaying has bad disasm preview formatting (-monospace font) * FunctionsWidget: tooltip has made less transparent, hardcoded constants utilization refactored, replaced raw command with json'ed one, added some space between paragraphs in tooltip (thanks to @ITAYC0HEN's advice)
This commit is contained in:
parent
3dc71c90d2
commit
9118deebf3
@ -7,6 +7,7 @@
|
||||
#include "dialogs/RenameDialog.h"
|
||||
#include "dialogs/XrefsDialog.h"
|
||||
#include "utils/FunctionsTask.h"
|
||||
#include "utils/TempConfig.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <QMenu>
|
||||
@ -14,8 +15,17 @@
|
||||
#include <QString>
|
||||
#include <QResource>
|
||||
#include <QShortcut>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
namespace {
|
||||
|
||||
static const int kMaxTooltipWidth = 400;
|
||||
static const int kMaxTooltipDisasmPreviewLines = 10;
|
||||
static const int kMaxTooltipHighlightsLines = 5;
|
||||
|
||||
}
|
||||
|
||||
FunctionModel::FunctionModel(QList<FunctionDescription> *functions, QSet<RVA> *importAddresses,
|
||||
ut64 *mainAdress, bool nested, QFont default_font, QFont highlight_font, QObject *parent)
|
||||
: QAbstractItemModel(parent),
|
||||
@ -186,16 +196,79 @@ QVariant FunctionModel::data(const QModelIndex &index, int role) const
|
||||
return static_cast<int>(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
|
||||
case Qt::ToolTipRole: {
|
||||
QList<QString> info = Core()->cmd("afi @ " + function.name).split("\n");
|
||||
if (info.length() > 2) {
|
||||
QString size = info[4].split(" ")[1];
|
||||
QString complex = info[8].split(" ")[1];
|
||||
QString bb = info[11].split(" ")[1];
|
||||
return QString("Summary:\n\n Size: " + size +
|
||||
"\n Cyclomatic complexity: " + complex +
|
||||
"\n Basic blocks: " + bb +
|
||||
"\n\nDisasm preview:\n\n" + Core()->cmd("pdi 10 @ " + function.name) +
|
||||
"\nStrings:\n\n" + Core()->cmd("pdsf @ " + function.name));
|
||||
const QJsonArray &info = Core()->cmdj("afij @ " + function.name).array();
|
||||
if (!info.isEmpty()) {
|
||||
const QJsonObject &funcInfo = info[0].toObject();
|
||||
|
||||
static const QStringList kRequiredFields{ "size", "cc", "nbbs" };
|
||||
for (const auto& key : kRequiredFields) {
|
||||
if (!funcInfo.contains(key)) {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
const int size = funcInfo["size"].toInt();
|
||||
const int complex = funcInfo["cc"].toInt();
|
||||
const int bb = funcInfo["nbbs"].toInt();
|
||||
QStringList disasmPreview;
|
||||
|
||||
QJsonArray jDisasmEntries;
|
||||
{
|
||||
// temporarily simplify the disasm output to get it colorful and simple to read
|
||||
TempConfig tempConfig;
|
||||
tempConfig.set("scr.html", true)
|
||||
.set("scr.color", COLOR_MODE_16M)
|
||||
.set("asm.lines", false)
|
||||
.set("asm.var", false)
|
||||
.set("asm.comments", false)
|
||||
.set("asm.bytes", false)
|
||||
.set("asm.lines.fcn", false)
|
||||
.set("asm.lines.out", false)
|
||||
.set("asm.lines.bb", false)
|
||||
.set("asm.bbline", false);
|
||||
|
||||
jDisasmEntries = Core()->cmdj(QString("pDJ %1 @ %2").arg(function.size).arg(function.offset)).array();
|
||||
}
|
||||
for (const QJsonValue &value : jDisasmEntries) {
|
||||
const QJsonObject &object = value.toObject();
|
||||
|
||||
disasmPreview << object["text"].toString();
|
||||
if (disasmPreview.length() >= kMaxTooltipDisasmPreviewLines) {
|
||||
disasmPreview << "...";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const QStringList &summary = Core()->cmd("pdsf @ " + function.name).split("\n", QString::SkipEmptyParts);
|
||||
|
||||
const QFont &fnt = Config()->getFont();
|
||||
QFontMetrics fm{ fnt };
|
||||
|
||||
// elide long strings using current didsam font metrics
|
||||
QStringList highlights;
|
||||
for (const QString &s : summary) {
|
||||
highlights << fm.elidedText(s, Qt::ElideRight, kMaxTooltipWidth);
|
||||
if (highlights.length() > kMaxTooltipHighlightsLines) {
|
||||
highlights << "...";
|
||||
break;
|
||||
}
|
||||
}
|
||||
QString toolTipContent = QString("<html><div style=\"font-family: %1; font-size: %2pt; white-space: nowrap;\">")
|
||||
.arg(fnt.family())
|
||||
.arg(qMax(6, fnt.pointSize() - 1)) // slightly decrease font size, to keep more text in the same
|
||||
+ tr("<div><strong>Summary</strong>:<br>")
|
||||
+ tr("Size: %1, Cyclomatic complexity: %2, Basic blocks: %3")
|
||||
.arg(size)
|
||||
.arg(complex)
|
||||
.arg(bb)
|
||||
+ tr("</div><div style=\"margin-top: 10px;\"><strong>Disassembly preview</strong>:<br>%1</div>")
|
||||
.arg(disasmPreview.join("<br>"));
|
||||
|
||||
if (!highlights.isEmpty()) {
|
||||
toolTipContent += tr("<div style=\"margin-top: 10px;\"><strong>Highlights</strong>:<br>%1</div>")
|
||||
.arg(highlights.join("\n").toHtmlEscaped().replace("\n", "<br>"));
|
||||
}
|
||||
toolTipContent += "</div></html>";
|
||||
return toolTipContent;
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
@ -422,6 +495,8 @@ FunctionsWidget::FunctionsWidget(MainWindow *main, QAction *action) :
|
||||
// Radare core found in:
|
||||
this->main = main;
|
||||
|
||||
setStyleSheet(QString("QToolTip { max-width: %2px; opacity: 230; }").arg(kMaxTooltipWidth));
|
||||
|
||||
// leave the filter visible by default so users know it exists
|
||||
//ui->filterLineEdit->setVisible(false);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user