diff --git a/src/SeerAsmWidget.cpp b/src/SeerAsmWidget.cpp index 0a53b67..86e27c4 100644 --- a/src/SeerAsmWidget.cpp +++ b/src/SeerAsmWidget.cpp @@ -1,6 +1,7 @@ #include "SeerAsmWidget.h" #include "SeerUtl.h" #include +#include SeerAsmWidget::SeerAsmWidget(QWidget* parent) : QWidget(parent) { @@ -13,8 +14,9 @@ SeerAsmWidget::SeerAsmWidget(QWidget* parent) : QWidget(parent) { font.setFixedPitch(true); font.setStyleHint(QFont::TypeWriter); - treeWidget->setFont(font); - treeWidget->setRootIsDecorated(false); + plainTextEdit->setFont(font); + plainTextEdit->setFocusPolicy(Qt::StrongFocus); + plainTextEdit->setTextInteractionFlags(Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse); // Connect things. } @@ -22,6 +24,16 @@ SeerAsmWidget::SeerAsmWidget(QWidget* parent) : QWidget(parent) { SeerAsmWidget::~SeerAsmWidget() { } +QTextDocument* SeerAsmWidget::document () { + + return plainTextEdit->document(); +} + +QString SeerAsmWidget::toPlainText () { + + return plainTextEdit->toPlainText(); +} + void SeerAsmWidget::setData (const QString& data) { @@ -31,30 +43,72 @@ void SeerAsmWidget::setData (const QString& data) { // {address="0x0000000000400946",func-name="main()",offset="372",inst="mov -0x30(%rbp),%rax"} // ] - treeWidget->clear(); + // Clear the document. + plainTextEdit->clear(); + // Set text formats. + QTextCharFormat defaultFormat = plainTextEdit->currentCharFormat(); + QTextCharFormat grayFormat = defaultFormat; + grayFormat.setBackground(QBrush(Qt::lightGray)); + + // Get a cursor + QTextCursor cursor(plainTextEdit->textCursor()); + + cursor.movePosition(QTextCursor::Start); + + // Prepare the 'data' for parsing. QString asm_insns_text = Seer::parseFirst(data, "asm_insns=", '[', ']', false); QStringList asm_list = Seer::parse(asm_insns_text, "", '{', '}', false); - // Loop through the asm list. + // Loop through the asm list to get maximum field widths. + int address_width = QString("Address").length(); + int opcode_width = QString("Opcode").length(); + int inst_width = QString("Assembly").length(); + for ( const auto& asm_text : asm_list ) { QString address_text = Seer::parseFirst(asm_text, "address=", '"', '"', false); QString opcodes_text = Seer::parseFirst(asm_text, "opcodes=", '"', '"', false); QString inst_text = Seer::parseFirst(asm_text, "inst=", '"', '"', false); - // Add the file to the tree. - QTreeWidgetItem* item = new QTreeWidgetItem; - item->setText(0, address_text); - item->setText(1, opcodes_text); - item->setText(2, inst_text); - - treeWidget->addTopLevelItem(item); + address_width = std::max(address_width,address_text.length()); + opcode_width = std::max(opcode_width, opcodes_text.length()); + inst_width = std::max(inst_width, inst_text.length()); } - treeWidget->resizeColumnToContents(0); - treeWidget->resizeColumnToContents(1); - treeWidget->resizeColumnToContents(2); + // Write header. + cursor.insertText (QString("Address").leftJustified(address_width, ' ', true), grayFormat); + cursor.insertText (QString(" "), defaultFormat); + cursor.insertText (QString("Opcodes").leftJustified(opcode_width, ' ', true), defaultFormat); + cursor.insertText (QString(" | "), defaultFormat); + cursor.insertText (QString("Assembly"), defaultFormat); + cursor.insertText (QString("\n"), defaultFormat); + + // Loop through the asm list and print each line. + for ( const auto& asm_text : asm_list ) { + + // Get the strings, with padding. + QString address_text = Seer::parseFirst(asm_text, "address=", '"', '"', false).leftJustified(address_width, ' ', true); + QString opcodes_text = Seer::parseFirst(asm_text, "opcodes=", '"', '"', false).leftJustified(opcode_width, ' ', true); + QString inst_text = Seer::parseFirst(asm_text, "inst=", '"', '"', false).leftJustified(inst_width, ' ', true); + + // Write the text, with spacers. + cursor.insertText (address_text, grayFormat); + cursor.insertText (QString(" "), defaultFormat); + + cursor.insertText (opcodes_text, defaultFormat); + cursor.insertText (QString(" | "), defaultFormat); + + cursor.insertText (inst_text, defaultFormat); + + // Write eol to document. + cursor.insertText (QString("\n"), defaultFormat); + } + + // Move to the start of the document. + cursor.movePosition(QTextCursor::Start); + + plainTextEdit->setTextCursor(cursor); } diff --git a/src/SeerAsmWidget.h b/src/SeerAsmWidget.h index 355f29f..5e3c7cb 100644 --- a/src/SeerAsmWidget.h +++ b/src/SeerAsmWidget.h @@ -11,6 +11,9 @@ class SeerAsmWidget: public QWidget, protected Ui::SeerAsmWidgetForm { SeerAsmWidget(QWidget* parent = 0); ~SeerAsmWidget(); + QTextDocument* document (); + QString toPlainText (); + signals: public slots: diff --git a/src/SeerAsmWidget.ui b/src/SeerAsmWidget.ui index 46b18ac..496bda3 100644 --- a/src/SeerAsmWidget.ui +++ b/src/SeerAsmWidget.ui @@ -15,25 +15,19 @@ - - - 3 + + + + 0 + 100 + + + + true + + + Qt::NoTextInteraction - - - Address - - - - - Op Codes - - - - - Instructions - - diff --git a/src/SeerHexWidget.cpp b/src/SeerHexWidget.cpp index fac2734..cc8c49d 100644 --- a/src/SeerHexWidget.cpp +++ b/src/SeerHexWidget.cpp @@ -571,13 +571,12 @@ void SeerHexWidget::create () { if (i % bytesPerLine() == 0) { QString address = QString("0x%1").arg(i + addressOffset(), SeerHexWidget::HexFieldWidth-2, 16, QChar('0')); // -2 to allow '0x'. - QString spacer(" "); // Write adress to document. cursor.insertText (address, grayFormat); // Write spacer to document. - cursor.insertText (spacer, defaultFormat); + cursor.insertText (QString(" "), defaultFormat); } // Print N bytes in their datatype value. @@ -601,11 +600,10 @@ void SeerHexWidget::create () { val = "??"; } - QString spacer(" "); cursor.insertText (val, defaultFormat); // Write spacer to document. - cursor.insertText (spacer, defaultFormat); + cursor.insertText (QString(" "), defaultFormat); } // Print N odd remainder bytes. @@ -625,20 +623,16 @@ void SeerHexWidget::create () { val = "??"; } - QString spacer(" "); - // Write memory value to document cursor.insertText (val, defaultFormat); // Write spacer to document. - cursor.insertText (spacer, defaultFormat); + cursor.insertText (QString(" "), defaultFormat); } // Print vertical line. - QString spacer("| "); - // Write spacer to document. - cursor.insertText (spacer, defaultFormat); + cursor.insertText (QString("| "), defaultFormat); // Print N bytes in their char value. if (charMode() == SeerHexWidget::AsciiCharMode) { diff --git a/src/SeerMemoryVisualizerWidget.cpp b/src/SeerMemoryVisualizerWidget.cpp index 898dd60..e755b54 100644 --- a/src/SeerMemoryVisualizerWidget.cpp +++ b/src/SeerMemoryVisualizerWidget.cpp @@ -306,7 +306,15 @@ void SeerMemoryVisualizerWidget::handlePrintButton () { // Make a copy so we can temporarily add a header. - QTextDocument* clone = memoryHexEditor->document()->clone(this); + QTextDocument* clone = 0; + + if (tabWidget->currentWidget()->objectName() == "hex_tab") { + clone = memoryHexEditor->document()->clone(this); + }else if (tabWidget->currentWidget()->objectName() == "asm_tab") { + clone = memoryAsmEditor->document()->clone(this); + }else{ + clone = new QTextDocument("NO TAB SELECTED!!!\n"); + } QTextCursor cursor(clone); QTextCharFormat format = cursor.charFormat(); @@ -352,7 +360,13 @@ void SeerMemoryVisualizerWidget::handleSaveButton () { stream << "\n"; stream << "name=" << variableName() << " address=" << variableAddress() << " bytesPerLine=" << memoryHexEditor->bytesPerLine() << " bytes=" << memoryHexEditor->size() << " memory=" << memoryHexEditor->memoryModeString() << " char=" << memoryHexEditor->charModeString() << "\n"; stream << "\n"; - stream << memoryHexEditor->toPlainText(); + if (tabWidget->currentWidget()->objectName() == "hex_tab") { + stream << memoryHexEditor->toPlainText(); + }else if (tabWidget->currentWidget()->objectName() == "asm_tab") { + stream << memoryAsmEditor->toPlainText(); + }else{ + stream << "NO TAB SELECTED!!!\n"; + } stream << "\n"; file.flush(); diff --git a/src/SeerMemoryVisualizerWidget.ui b/src/SeerMemoryVisualizerWidget.ui index 6d778b4..fef9b43 100644 --- a/src/SeerMemoryVisualizerWidget.ui +++ b/src/SeerMemoryVisualizerWidget.ui @@ -177,7 +177,7 @@ 0 - + Memory @@ -194,7 +194,7 @@ - + Disassembly