2016-02-11 23:46:10 +00:00
|
|
|
#include "hexdumpviewer.h"
|
|
|
|
#include "ui_hexdumpviewer.h"
|
|
|
|
|
2016-07-05 13:35:38 +00:00
|
|
|
#include <QDebug>
|
2016-06-30 00:37:09 +00:00
|
|
|
#include <QScrollBar>
|
2016-10-15 22:48:26 +00:00
|
|
|
#include <QSettings>
|
|
|
|
#include <QAction>
|
|
|
|
#include <QMenu>
|
2016-06-30 00:37:09 +00:00
|
|
|
|
2016-02-11 23:46:10 +00:00
|
|
|
HexDumpViewer::HexDumpViewer(QWidget *parent) :
|
2016-10-14 22:27:28 +00:00
|
|
|
FileViewerInterface(parent),
|
2016-02-11 23:46:10 +00:00
|
|
|
ui(new Ui::HexDumpViewer)
|
|
|
|
{
|
|
|
|
ui->setupUi(this);
|
|
|
|
m_offset = 0;
|
|
|
|
|
|
|
|
QString title = QString("Hex Viewer");
|
|
|
|
setWindowTitle(title);
|
2016-10-15 22:48:26 +00:00
|
|
|
|
|
|
|
QSettings settings;
|
|
|
|
toggleWordWrap(settings.value("HexViewer.WordWrap",true).toBool());
|
2016-02-11 23:46:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
HexDumpViewer::~HexDumpViewer()
|
|
|
|
{
|
|
|
|
delete ui;
|
|
|
|
}
|
|
|
|
|
2016-10-15 22:48:26 +00:00
|
|
|
void HexDumpViewer::toggleWordWrap(bool enabled)
|
|
|
|
{
|
|
|
|
if (enabled)
|
|
|
|
{
|
|
|
|
ui->textArea->setWordWrapMode(QTextOption::WordWrap);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ui->textArea->setWordWrapMode(QTextOption::NoWrap);
|
|
|
|
}
|
|
|
|
QSettings settings;
|
|
|
|
settings.setValue("HexViewer.WordWrap",enabled);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-07-05 13:35:38 +00:00
|
|
|
void HexDumpViewer::showHexAndAsciiValues()
|
2016-02-11 23:46:10 +00:00
|
|
|
{
|
2016-06-30 00:37:09 +00:00
|
|
|
int offset = ui->textArea->verticalScrollBar()->value();
|
2016-02-11 23:46:10 +00:00
|
|
|
|
|
|
|
QStringList lines;
|
|
|
|
|
|
|
|
//TODO: Align text from x00 to xFF. Currently it will start with whatever the offset is.
|
|
|
|
|
|
|
|
quint16 addr = m_offset;
|
2016-06-30 00:37:09 +00:00
|
|
|
for (int idx = 0; idx <= m_data.count()/16; idx++) {
|
2016-07-05 13:35:38 +00:00
|
|
|
QString line = QString("(%1) %2: ")
|
|
|
|
.arg(m_offset+(idx*16),4,10,QChar('0'))
|
|
|
|
.arg(m_offset+(idx*16),4,16,QChar('0'));
|
|
|
|
QString asciiline;
|
|
|
|
|
2016-02-11 23:46:10 +00:00
|
|
|
for (int jdx = (idx*16); jdx < (idx*16)+16; jdx++) {
|
|
|
|
addr++;
|
2016-06-30 00:37:09 +00:00
|
|
|
if (jdx < m_data.count()) {
|
2016-07-05 13:35:38 +00:00
|
|
|
asciiline += valToAppleAscii(m_data[jdx]);
|
|
|
|
|
2016-06-30 00:37:09 +00:00
|
|
|
line += QString(" %1").arg((quint8) m_data[jdx],2,16,QChar('0'));
|
2016-02-11 23:46:10 +00:00
|
|
|
}
|
|
|
|
}
|
2016-07-05 13:35:38 +00:00
|
|
|
|
|
|
|
if (line.length() > 14) {
|
|
|
|
int diff = (62 - line.length());
|
|
|
|
if (diff < 0) { diff = 0; }
|
|
|
|
if (diff>0) {
|
|
|
|
for (int pdx = 0; pdx < diff; pdx++)
|
|
|
|
{
|
|
|
|
line.append(" ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lines.append(line + "  " + asciiline);
|
2016-02-11 23:46:10 +00:00
|
|
|
}
|
|
|
|
}
|
2016-06-30 00:37:09 +00:00
|
|
|
setText(qPrintable(lines.join("<br>").toUpper()));
|
|
|
|
ui->textArea->verticalScrollBar()->setValue(offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
QString HexDumpViewer::valToAppleAscii(quint8 val)
|
|
|
|
{
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
Inverse,
|
|
|
|
Flash,
|
|
|
|
Normal,
|
|
|
|
AltUC
|
|
|
|
} Zone;
|
|
|
|
|
|
|
|
Zone zone;
|
|
|
|
|
|
|
|
QString charval;
|
|
|
|
if (val <= 0x1F) { val += 0x40; charval = QString("%1").arg(QChar(val)); zone = Inverse; } //INV UC
|
|
|
|
else if (val <= 0x3F) { val = val; charval = QString("%1").arg(QChar(val)); zone = Inverse; } // INV SP
|
|
|
|
else if (val <= 0x5F) { val = val; charval = QString("%1").arg(QChar(val)); zone = Flash; } // FL UC
|
|
|
|
else if (val <= 0x7F) { val -= 0x40; charval = QString("%1").arg(QChar(val)); zone = Flash; } // FL SP
|
|
|
|
else if (val <= 0x9F) { val -= 0x40; charval = QString("%1").arg(QChar(val)); zone = AltUC; } // NORMx UC
|
|
|
|
else if (val <= 0xBF) { val -= 0x40; charval = QString("%1").arg(QChar(val)); zone = Normal; } // NORM SP
|
|
|
|
else if (val <= 0xDF) { val -= 0x80; charval = QString("%1").arg(QChar(val)); zone = Normal; } // NORM UC
|
|
|
|
else if (val < 0xFF) { val -= 0x80; charval = QString("%1").arg(QChar(val)); zone = Normal; } // NORM LC
|
|
|
|
else if (val == 0xFF) { val = val; charval = QString("\u25a0"); zone = Normal; }
|
|
|
|
|
|
|
|
QString htmlstr = charval.toHtmlEscaped();
|
|
|
|
|
|
|
|
QString retval;
|
2016-07-05 13:35:38 +00:00
|
|
|
if (zone == Inverse) { retval = QString("<font color=\"blue\"><b>%1</b></font>").arg(htmlstr); }
|
|
|
|
else if (zone == Flash) { retval = QString("<font color=\"green\"><b><i>%1</i></b></font>").arg(htmlstr);}
|
|
|
|
else if (zone == AltUC) { retval = QString("<font color=\"red\"><i>%1</i></font>").arg(htmlstr);}
|
2016-06-30 00:37:09 +00:00
|
|
|
else /* zone == Normal */ { retval = QString("%1").arg(htmlstr);}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HexDumpViewer::setFile(GenericFile *file, quint16 offset)
|
|
|
|
{
|
|
|
|
QString title = QString("Hex Viewer: %1").arg(file->filename());
|
|
|
|
setWindowTitle(title);
|
|
|
|
|
|
|
|
m_offset = offset;
|
|
|
|
|
|
|
|
m_data = file->data();
|
|
|
|
|
2016-07-05 13:35:38 +00:00
|
|
|
showHexAndAsciiValues();
|
2016-06-30 00:37:09 +00:00
|
|
|
|
2016-02-11 23:46:10 +00:00
|
|
|
}
|
|
|
|
|
2016-10-15 22:48:26 +00:00
|
|
|
bool HexDumpViewer::optionsMenuItems(QMenu *menu)
|
|
|
|
{
|
|
|
|
QSettings settings;
|
|
|
|
|
|
|
|
QAction *action = new QAction("&Word Wrap");
|
|
|
|
action->setCheckable(true);
|
|
|
|
action->setChecked(settings.value("HexViewer.WordWrap",true).toBool());
|
|
|
|
connect(action, SIGNAL(toggled(bool)), SLOT(toggleWordWrap(bool)));
|
|
|
|
menu->addAction(action);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-02-11 23:46:10 +00:00
|
|
|
void HexDumpViewer::setData(QByteArray data)
|
|
|
|
{
|
2016-06-30 00:37:09 +00:00
|
|
|
ui->textArea->setHtml(data);
|
2016-02-11 23:46:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void HexDumpViewer::setText(QString text)
|
|
|
|
{
|
|
|
|
ui->textArea->setHtml(text);
|
|
|
|
}
|