mirror of
https://github.com/rizinorg/cutter.git
synced 2025-02-20 13:46:06 +00:00
ToolTip for cropped lines in Graph, Fix #227
This commit is contained in:
parent
41430d2826
commit
2522e6a378
@ -102,7 +102,7 @@ void RichTextPainter::htmlRichText(const List & richText, QString & textHtml, QS
|
||||
}
|
||||
}
|
||||
|
||||
RichTextPainter::List RichTextPainter::cropped(const RichTextPainter::List &richText, int maxCols, const QString &indicator)
|
||||
RichTextPainter::List RichTextPainter::cropped(const RichTextPainter::List &richText, int maxCols, const QString &indicator, bool *croppedOut)
|
||||
{
|
||||
List r;
|
||||
r.reserve(richText.size());
|
||||
@ -154,5 +154,9 @@ RichTextPainter::List RichTextPainter::cropped(const RichTextPainter::List &rich
|
||||
}
|
||||
}
|
||||
|
||||
if(croppedOut)
|
||||
{
|
||||
*croppedOut = cropped;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
static void paintRichText(QPainter* painter, int x, int y, int w, int h, int xinc, const List & richText, CachedFontMetrics* fontMetrics);
|
||||
static void htmlRichText(const List & richText, QString & textHtml, QString & textPlain);
|
||||
|
||||
static List cropped(const List &richText, int maxCols, const QString &indicator = nullptr);
|
||||
static List cropped(const List &richText, int maxCols, const QString &indicator = nullptr, bool *croppedOut = nullptr);
|
||||
};
|
||||
|
||||
#endif // RICHTEXTPAINTER_H
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <QMouseEvent>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QShortcut>
|
||||
#include <QToolTip>
|
||||
|
||||
#include "cutter.h"
|
||||
#include "utils/Colors.h"
|
||||
@ -166,7 +167,16 @@ void DisassemblerGraphView::loadCurrentGraph()
|
||||
comment.flags = RichTextPainter::FlagColor;
|
||||
richText.insert(richText.end(), comment);
|
||||
}
|
||||
i.text = Text(RichTextPainter::cropped(richText, Config()->getGraphBlockMaxChars(), "..."));
|
||||
bool cropped;
|
||||
i.text = Text(RichTextPainter::cropped(richText, Config()->getGraphBlockMaxChars(), "...", &cropped));
|
||||
if(cropped)
|
||||
{
|
||||
i.fullText = richText;
|
||||
}
|
||||
else
|
||||
{
|
||||
i.fullText = Text();
|
||||
}
|
||||
db.instrs.push_back(i);
|
||||
}
|
||||
disassembly_blocks[db.entry] = db;
|
||||
@ -377,7 +387,7 @@ GraphView::EdgeConfiguration DisassemblerGraphView::edgeConfiguration(GraphView:
|
||||
return ec;
|
||||
}
|
||||
|
||||
RVA DisassemblerGraphView::getInstrForMouseEvent(GraphBlock &block, QPoint* point)
|
||||
RVA DisassemblerGraphView::getAddrForMouseEvent(GraphBlock &block, QPoint *point)
|
||||
{
|
||||
DisassemblyBlock &db = disassembly_blocks[block.entry];
|
||||
|
||||
@ -393,17 +403,39 @@ RVA DisassemblerGraphView::getInstrForMouseEvent(GraphBlock &block, QPoint* poin
|
||||
return db.entry;
|
||||
}
|
||||
|
||||
Instr *instr = getInstrForMouseEvent(block, point);
|
||||
if(instr)
|
||||
{
|
||||
return instr->addr;
|
||||
}
|
||||
|
||||
return RVA_INVALID;
|
||||
}
|
||||
|
||||
|
||||
DisassemblerGraphView::Instr *DisassemblerGraphView::getInstrForMouseEvent(GraphView::GraphBlock &block, QPoint *point)
|
||||
{
|
||||
DisassemblyBlock &db = disassembly_blocks[block.entry];
|
||||
|
||||
// Remove header and margin
|
||||
int off_y = (2 * charWidth) + (db.header_text.lines.size() * charHeight);
|
||||
// Get mouse coordinate over the actual text
|
||||
int text_point_y = point->y() - off_y;
|
||||
int mouse_row = text_point_y / charHeight;
|
||||
|
||||
int cur_row = db.header_text.lines.size();
|
||||
|
||||
for(Instr & instr : db.instrs)
|
||||
{
|
||||
if(mouse_row < cur_row + (int)instr.text.lines.size())
|
||||
{
|
||||
return instr.addr;
|
||||
return &instr;
|
||||
}
|
||||
cur_row += instr.text.lines.size();
|
||||
}
|
||||
return RVA_INVALID;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Public Slots
|
||||
|
||||
@ -582,7 +614,7 @@ void DisassemblerGraphView::seekPrev()
|
||||
|
||||
void DisassemblerGraphView::blockClicked(GraphView::GraphBlock &block, QMouseEvent *event, QPoint pos)
|
||||
{
|
||||
RVA instr = getInstrForMouseEvent(block, &pos);
|
||||
RVA instr = getAddrForMouseEvent(block, &pos);
|
||||
if(instr == RVA_INVALID)
|
||||
{
|
||||
return;
|
||||
@ -600,7 +632,7 @@ void DisassemblerGraphView::blockClicked(GraphView::GraphBlock &block, QMouseEve
|
||||
void DisassemblerGraphView::blockDoubleClicked(GraphView::GraphBlock &block, QMouseEvent *event, QPoint pos)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
RVA instr = getInstrForMouseEvent(block, &pos);
|
||||
RVA instr = getAddrForMouseEvent(block, &pos);
|
||||
if(instr == RVA_INVALID)
|
||||
{
|
||||
return;
|
||||
@ -615,6 +647,30 @@ void DisassemblerGraphView::blockDoubleClicked(GraphView::GraphBlock &block, QMo
|
||||
}
|
||||
}
|
||||
|
||||
void DisassemblerGraphView::blockHelpEvent(GraphView::GraphBlock &block, QHelpEvent *event, QPoint pos)
|
||||
{
|
||||
Instr *instr = getInstrForMouseEvent(block, &pos);
|
||||
if(!instr || instr->fullText.lines.empty())
|
||||
{
|
||||
QToolTip::hideText();
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
QToolTip::showText(event->globalPos(), instr->fullText.ToQString());
|
||||
}
|
||||
|
||||
bool DisassemblerGraphView::helpEvent(QHelpEvent *event)
|
||||
{
|
||||
if(!GraphView::helpEvent(event))
|
||||
{
|
||||
QToolTip::hideText();
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DisassemblerGraphView::blockTransitionedTo(GraphView::GraphBlock *to)
|
||||
{
|
||||
if(transition_dont_seek)
|
||||
|
@ -92,6 +92,7 @@ class DisassemblerGraphView : public GraphView
|
||||
ut64 addr = 0;
|
||||
ut64 size = 0;
|
||||
Text text;
|
||||
Text fullText;
|
||||
std::vector<unsigned char> opcode; //instruction bytes
|
||||
};
|
||||
|
||||
@ -142,6 +143,8 @@ public:
|
||||
virtual void drawBlock(QPainter & p, GraphView::GraphBlock &block) override;
|
||||
virtual void blockClicked(GraphView::GraphBlock &block, QMouseEvent *event, QPoint pos) override;
|
||||
virtual void blockDoubleClicked(GraphView::GraphBlock &block, QMouseEvent *event, QPoint pos) override;
|
||||
virtual bool helpEvent(QHelpEvent *event) override;
|
||||
virtual void blockHelpEvent(GraphView::GraphBlock &block, QHelpEvent *event, QPoint pos) override;
|
||||
virtual GraphView::EdgeConfiguration edgeConfiguration(GraphView::GraphBlock &from, GraphView::GraphBlock *to) override;
|
||||
virtual void blockTransitionedTo(GraphView::GraphBlock *to) override;
|
||||
|
||||
@ -183,7 +186,8 @@ private:
|
||||
|
||||
void initFont();
|
||||
void prepareGraphNode(GraphBlock &block);
|
||||
RVA getInstrForMouseEvent(GraphBlock &block, QPoint* point);
|
||||
RVA getAddrForMouseEvent(GraphBlock &block, QPoint *point);
|
||||
Instr *getInstrForMouseEvent(GraphBlock &block, QPoint *point);
|
||||
DisassemblyBlock *blockForAddress(RVA addr);
|
||||
void seek(RVA addr, bool update_viewport=true);
|
||||
void seekInstruction(bool previous_instr);
|
||||
|
@ -61,6 +61,34 @@ void GraphView::blockDoubleClicked(GraphView::GraphBlock &block, QMouseEvent *ev
|
||||
qWarning() << "Block double clicked not overridden!";
|
||||
}
|
||||
|
||||
void GraphView::blockHelpEvent(GraphView::GraphBlock &block, QHelpEvent *event, QPoint pos)
|
||||
{
|
||||
Q_UNUSED(block);
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(pos);
|
||||
}
|
||||
|
||||
bool GraphView::helpEvent(QHelpEvent *event)
|
||||
{
|
||||
int x = ((event->pos().x() - unscrolled_render_offset_x) / current_scale) + horizontalScrollBar()->value();
|
||||
int y = ((event->pos().y() - unscrolled_render_offset_y) / current_scale) + verticalScrollBar()->value();
|
||||
|
||||
for(auto & blockIt : blocks)
|
||||
{
|
||||
GraphBlock &block = blockIt.second;
|
||||
|
||||
if((block.x <= x) && (block.y <= y) &&
|
||||
(x <= block.x + block.width) & (y <= block.y + block.height))
|
||||
{
|
||||
QPoint pos = QPoint(x - block.x, y - block.y);
|
||||
blockHelpEvent(block, event, pos);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GraphView::blockTransitionedTo(GraphView::GraphBlock *to)
|
||||
{
|
||||
Q_UNUSED(to);
|
||||
@ -98,6 +126,19 @@ void GraphView::adjustSize(int new_width, int new_height)
|
||||
verticalScrollBar()->setValue((int)((double)verticalScrollBar()->maximum() * vfactor));
|
||||
}
|
||||
|
||||
bool GraphView::event(QEvent *event)
|
||||
{
|
||||
if(event->type() == QEvent::ToolTip)
|
||||
{
|
||||
if(helpEvent(static_cast<QHelpEvent *>(event)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return QAbstractScrollArea::event(event);
|
||||
}
|
||||
|
||||
// This calculates the full graph starting at block entry.
|
||||
void GraphView::computeGraph(ut64 entry)
|
||||
{
|
||||
@ -698,6 +739,7 @@ GraphView::GraphEdge GraphView::routeEdge(EdgesVector & horiz_edges, EdgesVector
|
||||
return edge;
|
||||
}
|
||||
|
||||
|
||||
int GraphView::findHorizEdgeIndex(EdgesVector & edges, int row, int min_col, int max_col)
|
||||
{
|
||||
//Find a valid index
|
||||
@ -746,7 +788,6 @@ int GraphView::findVertEdgeIndex(EdgesVector & edges, int col, int min_row, int
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
void GraphView::showBlock(GraphBlock &block, bool animated)
|
||||
{
|
||||
showBlock(&block, animated);
|
||||
@ -806,6 +847,7 @@ void GraphView::addBlock(GraphView::GraphBlock block)
|
||||
blocks[block.entry] = block;
|
||||
}
|
||||
|
||||
|
||||
void GraphView::setEntry(ut64 e)
|
||||
{
|
||||
entry = e;
|
||||
@ -824,7 +866,6 @@ bool GraphView::checkPointClicked(QPointF &point, int x, int y, bool above_y)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void GraphView::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
adjustSize(event->size().width(), event->size().height());
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <QAbstractScrollArea>
|
||||
#include <QScrollBar>
|
||||
#include <QElapsedTimer>
|
||||
#include <QHelpEvent>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
@ -121,10 +122,14 @@ protected:
|
||||
virtual void drawBlock(QPainter & p, GraphView::GraphBlock &block);
|
||||
virtual void blockClicked(GraphView::GraphBlock &block, QMouseEvent *event, QPoint pos);
|
||||
virtual void blockDoubleClicked(GraphView::GraphBlock &block, QMouseEvent *event, QPoint pos);
|
||||
virtual void blockHelpEvent(GraphView::GraphBlock &block, QHelpEvent *event, QPoint pos);
|
||||
virtual bool helpEvent(QHelpEvent *event);
|
||||
virtual void blockTransitionedTo(GraphView::GraphBlock *to);
|
||||
virtual EdgeConfiguration edgeConfiguration(GraphView::GraphBlock &from, GraphView::GraphBlock *to);
|
||||
|
||||
void adjustSize(int new_width, int new_height);
|
||||
|
||||
bool event(QEvent *event);
|
||||
private:
|
||||
bool checkPointClicked(QPointF &point, int x, int y, bool above_y=false);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user