X-Git-Url: https://git.siccegge.de//index.cgi?p=frida%2Ffrida.git;a=blobdiff_plain;f=src%2Fgui%2Fwidgets%2FBasicBlockWidget.cxx;h=de97c51d521c92b6cfc36d1871102a0b31cd221e;hp=bdddd520f429c925fb4a446a3209867e2a13e1de;hb=7e983f239ca96faf5c8ba92cd4de54eba5235f75;hpb=9fd091260777a95432902173a35e15a475f6f9f9 diff --git a/src/gui/widgets/BasicBlockWidget.cxx b/src/gui/widgets/BasicBlockWidget.cxx index bdddd52..de97c51 100644 --- a/src/gui/widgets/BasicBlockWidget.cxx +++ b/src/gui/widgets/BasicBlockWidget.cxx @@ -1,4 +1,5 @@ #include "BasicBlockWidget.hxx" +#include "CFGScene.hxx" #include "gui/Mainwindow.hxx" #include "gui/dialogs/SimpleStringDialog.hxx" #include "core/BasicBlock.hxx" @@ -15,6 +16,8 @@ public: CustomQGraphicsTextItem(const QString& text, BasicBlockWidget* parent) : QGraphicsTextItem(text, parent), parent(parent) {} void contextMenuEvent(QGraphicsSceneContextMenuEvent*); + + void adjustSize(); private: void addComment(int row, bool global); @@ -30,12 +33,15 @@ void CustomQGraphicsTextItem::addComment(int row, bool global) { if (global) { comment = parent->block->getManager()->newGlobalComment(address); } else { - comment = parent->block->getManager()->newLocalComment(address, NULL); + /* TODO: 0x23 as we currently don't have the function here + * and setting it to null will make the comment appear + * global. Also means local comments are largely still + * broken. + */ + comment = parent->block->getManager()->newLocalComment(address, (Function*)0x23); } comment->setText(dialog.result().toStdString()); parent->block->getManager()->finishComment(comment); - -// cell.firstCursorPosition().insertHtml(QString(";; ") + dialog.result()); } else { LOG4CXX_DEBUG(parent->logger, "addComment aborted"); } @@ -70,10 +76,35 @@ void CustomQGraphicsTextItem::contextMenuEvent(QGraphicsSceneContextMenuEvent* e menu.exec(event->screenPos()); } +/* QGraphicsTextItem has an adjustSize() function that is supposed to + * resize the widget to it's "ideal" size. However it totally ignores + * all directives to not wrap lines and "ideal" is actually just a + * bunch of heuristics. + * + * We are starting with a hopefully absurdly large startingwidth and + * reduce it untill a line is broken (detected by a change in + * height). As long as the width (1000 here) is sufficiently large, + * this should give us a widget without any line-wrapping. + * + * One needs to call this on a Pointer of tye CustomQGraphicsTextItem + * as the adjustSize() function is not polymorphic (vurtual). + */ +void CustomQGraphicsTextItem::adjustSize() { + int width = 1000; + setTextWidth(width); + int height = boundingRect().height(); + while (width > 250 && height == boundingRect().height()) { + setTextWidth(width -= 10); + } + width += 10; + if (width < 250) width = 250; + setTextWidth(width); +} + BasicBlockWidget::BasicBlockWidget(const QString& name, BasicBlock * block, Mainwindow * mainwindow) - : width(270), height(45), name(name) - , _table(NULL) + : width(200), height(45), name(name) + , currentColor(defaultColor), _table(NULL) , block(block), mainwindow(mainwindow) , logger(log4cxx::Logger::getLogger("gui.BasicBlockWidget." + name.toStdString())) { next[0] = NULL; next[1] = NULL; @@ -92,6 +123,21 @@ BasicBlockWidget::BasicBlockWidget(const QString& name, BasicBlock * block, if (str.startsWith("function:")) { QString address = str.remove("function:"); mainwindow->switchMainPlaneToAddress(address.toInt(NULL, 16)); + } else if (str.startsWith("block:")) { + QString address = str.remove("block:"); + + /* next[0] is always the jumptarget. On a + * conditional jump, next[1] also + * contains the following instruction + * + * TODO: Verify we're switching to the + * right block -- the target + * address matches the next blocks + * start address + */ + LOG4CXX_TRACE(logger, "Highlighting block at Address " << address.toStdString() + << " BasicBlockWidget " << std::hex << next[0]); + ((CFGScene*)this->scene())->highlightBlock(next[0]); } }); instructions = block->getInstructions(); @@ -110,13 +156,24 @@ void BasicBlockWidget::updateFunctionName(RenameFunctionEvent *event) { if (isLink) { if (search == format.anchorHref()) { - LOG4CXX_DEBUG(logger, i.fragment().text().toStdString() << " ---> " << format.anchorHref().toStdString()); + LOG4CXX_DEBUG(logger, i.fragment().text().toStdString() << " ---> " + << format.anchorHref().toStdString()); + + /* This should select the function name. It stars + * by selecting the whole link fragment from back + * to front and then moves one word to the back + * again deselecting whatever mnemonic is used for + * the call instruction. + */ QTextCursor c(b); c.setPosition(i.fragment().position()); c.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, i.fragment().length()); c.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor, i.fragment().length()); c.movePosition(QTextCursor::WordRight, QTextCursor::KeepAnchor); c.insertText(event->new_name.c_str()); + + QGraphicsTextItem* item = _widget.get(); + ((CustomQGraphicsTextItem*)item)->adjustSize(); } } } @@ -144,6 +201,8 @@ void BasicBlockWidget::changeCommentHandler(ChangeCommentEvent* event) { } cursor.removeSelectedText(); cursor.insertHtml(formatComments(&*inst_it)); + QGraphicsTextItem* item = _widget.get(); + ((CustomQGraphicsTextItem*)item)->adjustSize(); } } @@ -168,7 +227,7 @@ void BasicBlockWidget::populateWidget() { bytestring += hexdigits[byte & 0xF]; bytestring += ' '; } - _table->cellAt(row, 0).firstCursorPosition().insertText(bytestring); + _table->cellAt(row, 0).firstCursorPosition().insertHtml("" + bytestring + ""); QString line = inst.getText().c_str(); line = line.replace('\t', ' ').toHtmlEscaped(); @@ -186,28 +245,29 @@ void BasicBlockWidget::populateWidget() { } line = "" + line + ""; } - _table->cellAt(row, 1).firstCursorPosition().insertHtml(line); + _table->cellAt(row, 1).firstCursorPosition().insertHtml("" + line + ""); _table->cellAt(row, 2).firstCursorPosition().insertHtml(formatComments(&inst)); } + QGraphicsTextItem* item = _widget.get(); + ((CustomQGraphicsTextItem*)item)->adjustSize(); } QString BasicBlockWidget::formatComments(Instruction* inst) { QString comments; for (Comment* c: inst->comments()) { comments += "
"; - comments += c->getText().c_str(); + comments += QString(c->getText().c_str()).toHtmlEscaped(); } return (comments == "" ? "" : ";; ") + comments.trimmed(); } void BasicBlockWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*) { - _widget->adjustSize(); width = 10 + _widget->boundingRect().width(); height = 25 + _widget->boundingRect().height(); if (width < 250) width = 250; - painter->fillRect(0, 0, width, height, QColor(0xcc, 0xcc, 0xff, 0xff)); + painter->fillRect(0, 0, width, height, currentColor); painter->setPen(QColor(0x00, 0x00, 0xff, 0xff)); painter->drawRect(0, 0, width, height); painter->drawText(5, 15, name);