mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-02 02:05:26 +00:00
Seperate Widget showing grid of bytes from rest of the hexdump panel. (#1504)
* Seperate Widget showing grid of bytes from rest of the hexdump panel.
This commit is contained in:
parent
37cb9b5278
commit
cda24bfc53
@ -272,6 +272,7 @@ SOURCES += \
|
|||||||
menus/DisassemblyContextMenu.cpp \
|
menus/DisassemblyContextMenu.cpp \
|
||||||
widgets/DisassemblyWidget.cpp \
|
widgets/DisassemblyWidget.cpp \
|
||||||
widgets/HexdumpWidget.cpp \
|
widgets/HexdumpWidget.cpp \
|
||||||
|
widgets/HexTextView.cpp \
|
||||||
common/Configuration.cpp \
|
common/Configuration.cpp \
|
||||||
common/Colors.cpp \
|
common/Colors.cpp \
|
||||||
dialogs/SaveProjectDialog.cpp \
|
dialogs/SaveProjectDialog.cpp \
|
||||||
@ -391,6 +392,7 @@ HEADERS += \
|
|||||||
menus/DisassemblyContextMenu.h \
|
menus/DisassemblyContextMenu.h \
|
||||||
widgets/DisassemblyWidget.h \
|
widgets/DisassemblyWidget.h \
|
||||||
widgets/HexdumpWidget.h \
|
widgets/HexdumpWidget.h \
|
||||||
|
widgets/HexTextView.h \
|
||||||
common/Configuration.h \
|
common/Configuration.h \
|
||||||
common/Colors.h \
|
common/Colors.h \
|
||||||
dialogs/SaveProjectDialog.h \
|
dialogs/SaveProjectDialog.h \
|
||||||
@ -499,6 +501,7 @@ FORMS += \
|
|||||||
widgets/StringsWidget.ui \
|
widgets/StringsWidget.ui \
|
||||||
widgets/SymbolsWidget.ui \
|
widgets/SymbolsWidget.ui \
|
||||||
widgets/HexdumpWidget.ui \
|
widgets/HexdumpWidget.ui \
|
||||||
|
widgets/HexTextView.ui \
|
||||||
dialogs/SaveProjectDialog.ui \
|
dialogs/SaveProjectDialog.ui \
|
||||||
dialogs/preferences/PreferencesDialog.ui \
|
dialogs/preferences/PreferencesDialog.ui \
|
||||||
dialogs/preferences/AppearanceOptionsWidget.ui \
|
dialogs/preferences/AppearanceOptionsWidget.ui \
|
||||||
|
@ -2,11 +2,14 @@
|
|||||||
#include "ui_HexdumpRangeDialog.h"
|
#include "ui_HexdumpRangeDialog.h"
|
||||||
|
|
||||||
#include <QRegExpValidator>
|
#include <QRegExpValidator>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <cstdint>
|
||||||
#include "core/Cutter.h"
|
#include "core/Cutter.h"
|
||||||
|
|
||||||
HexdumpRangeDialog::HexdumpRangeDialog(QWidget *parent) :
|
HexdumpRangeDialog::HexdumpRangeDialog(QWidget *parent, bool allowEmpty) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
ui(new Ui::HexdumpRangeDialog)
|
ui(new Ui::HexdumpRangeDialog),
|
||||||
|
allowEmpty(allowEmpty)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
QRegExpValidator *v = new QRegExpValidator(QRegExp("(?:0[xX])?[0-9a-fA-F]+"), this);
|
QRegExpValidator *v = new QRegExpValidator(QRegExp("(?:0[xX])?[0-9a-fA-F]+"), this);
|
||||||
@ -15,6 +18,7 @@ HexdumpRangeDialog::HexdumpRangeDialog(QWidget *parent) :
|
|||||||
ui->endAddressLineEdit->setValidator(v);
|
ui->endAddressLineEdit->setValidator(v);
|
||||||
|
|
||||||
//subscribe to a text change slot
|
//subscribe to a text change slot
|
||||||
|
connect(ui->startAddressLineEdit, &QLineEdit::textEdited, this, &HexdumpRangeDialog::textEdited);
|
||||||
connect(ui->endAddressLineEdit, &QLineEdit::textEdited, this, &HexdumpRangeDialog::textEdited);
|
connect(ui->endAddressLineEdit, &QLineEdit::textEdited, this, &HexdumpRangeDialog::textEdited);
|
||||||
connect(ui->lengthLineEdit, &QLineEdit::textEdited, this, &HexdumpRangeDialog::textEdited);
|
connect(ui->lengthLineEdit, &QLineEdit::textEdited, this, &HexdumpRangeDialog::textEdited);
|
||||||
connect(ui->endAddressRadioButton, &QRadioButton::clicked, this,
|
connect(ui->endAddressRadioButton, &QRadioButton::clicked, this,
|
||||||
@ -29,19 +33,19 @@ HexdumpRangeDialog::~HexdumpRangeDialog()
|
|||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString HexdumpRangeDialog::getStartAddress() const
|
bool HexdumpRangeDialog::empty()
|
||||||
{
|
{
|
||||||
return ui->startAddressLineEdit->text();
|
return emptyRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString HexdumpRangeDialog::getEndAddress() const
|
unsigned long long HexdumpRangeDialog::getStartAddress() const
|
||||||
{
|
{
|
||||||
return ui->endAddressLineEdit->text();
|
return startAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString HexdumpRangeDialog::getLength() const
|
unsigned long long HexdumpRangeDialog::getEndAddress() const
|
||||||
{
|
{
|
||||||
return ui->lengthLineEdit->text();
|
return endAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HexdumpRangeDialog::getEndAddressRadioButtonChecked() const
|
bool HexdumpRangeDialog::getEndAddressRadioButtonChecked() const
|
||||||
@ -60,44 +64,76 @@ void HexdumpRangeDialog::setStartAddress(ut64 start)
|
|||||||
QString("0x%1").arg(start, 0, 16));
|
QString("0x%1").arg(start, 0, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HexdumpRangeDialog::textEdited()
|
void HexdumpRangeDialog::open(ut64 start)
|
||||||
|
{
|
||||||
|
setStartAddress(start);
|
||||||
|
setModal(false);
|
||||||
|
show();
|
||||||
|
activateWindow();
|
||||||
|
raise();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HexdumpRangeDialog::validate()
|
||||||
{
|
{
|
||||||
bool warningVisibile = false;
|
bool warningVisibile = false;
|
||||||
ut64 startAddress = Core()->math(ui->startAddressLineEdit->text());
|
startAddress = Core()->math(ui->startAddressLineEdit->text());
|
||||||
ut64 endAddress = 0;
|
endAddress = 0;
|
||||||
ut64 length = 0;
|
ut64 length = 0;
|
||||||
if (sender() == ui->endAddressLineEdit) {
|
emptyRange = true;
|
||||||
endAddress = Core()->math(getEndAddress());
|
if (ui->endAddressRadioButton->isChecked()) {
|
||||||
|
endAddress = Core()->math(ui->endAddressLineEdit->text());
|
||||||
if (endAddress > startAddress) {
|
if (endAddress > startAddress) {
|
||||||
length = endAddress - startAddress;
|
length = endAddress - startAddress;
|
||||||
ui->lengthLineEdit->setText(
|
ui->lengthLineEdit->setText(
|
||||||
QString("0x%1").arg(length, 0, 16));
|
QString("0x%1").arg(length, 0, 16));
|
||||||
}
|
this->endAddress = endAddress - 1;
|
||||||
else {
|
emptyRange = false;
|
||||||
|
} else if (endAddress == startAddress) {
|
||||||
|
ui->lengthLineEdit->setText("0");
|
||||||
|
return allowEmpty;
|
||||||
|
} else {
|
||||||
ui->lengthLineEdit->setText("Invalid");
|
ui->lengthLineEdit->setText("Invalid");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} else if ( sender() == ui->lengthLineEdit) {
|
} else {
|
||||||
//we edited the length, so update the end address to be start address + length
|
//we edited the length, so update the end address to be start address + length
|
||||||
length = Core()->math(getLength());
|
length = Core()->math(ui->lengthLineEdit->text());
|
||||||
endAddress = startAddress + length;
|
if (length == 0) {
|
||||||
ui->endAddressLineEdit->setText(
|
ui->endAddressLineEdit->setText("Empty");
|
||||||
QString("0x%1").arg(endAddress, 0, 16));
|
return allowEmpty;
|
||||||
|
} else if (UINT64_MAX - startAddress < length - 1) {
|
||||||
|
ui->endAddressLineEdit->setText("Invalid");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
endAddress = startAddress + length - 1;
|
||||||
|
emptyRange = false;
|
||||||
|
if (endAddress == UINT64_MAX) {
|
||||||
|
ui->endAddressLineEdit->setText(
|
||||||
|
QString("2^64"));
|
||||||
|
} else {
|
||||||
|
ui->endAddressLineEdit->setText(
|
||||||
|
QString("0x%1").arg(endAddress + 1, 0, 16));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
length = Core()->math(getLength());
|
|
||||||
|
|
||||||
// Warn the user for potentially heavy operation
|
// Warn the user for potentially heavy operation
|
||||||
if (length > 0x25000) {
|
if (length > 0x25000) {
|
||||||
warningVisibile = true;
|
warningVisibile = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->selectionWarningLabel->setVisible(warningVisibile);
|
ui->selectionWarningLabel->setVisible(warningVisibile);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexdumpRangeDialog::textEdited()
|
||||||
|
{
|
||||||
|
bool valid = validate();
|
||||||
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HexdumpRangeDialog::on_radioButtonClicked(bool checked)
|
void HexdumpRangeDialog::on_radioButtonClicked(bool checked)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (sender() == ui->endAddressRadioButton && checked == true) {
|
if (sender() == ui->endAddressRadioButton && checked == true) {
|
||||||
ui->lengthLineEdit->setEnabled(false);
|
ui->lengthLineEdit->setEnabled(false);
|
||||||
ui->endAddressLineEdit->setEnabled(true);
|
ui->endAddressLineEdit->setEnabled(true);
|
||||||
@ -107,5 +143,4 @@ void HexdumpRangeDialog::on_radioButtonClicked(bool checked)
|
|||||||
ui->endAddressLineEdit->setEnabled(false);
|
ui->endAddressLineEdit->setEnabled(false);
|
||||||
ui->lengthLineEdit->setFocus();
|
ui->lengthLineEdit->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,20 +14,28 @@ class HexdumpRangeDialog : public QDialog
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit HexdumpRangeDialog(QWidget *parent = nullptr);
|
explicit HexdumpRangeDialog(QWidget *parent = nullptr, bool allowEmpty = false);
|
||||||
~HexdumpRangeDialog();
|
~HexdumpRangeDialog();
|
||||||
QString getStartAddress() const;
|
bool empty();
|
||||||
QString getEndAddress() const;
|
ut64 getStartAddress() const;
|
||||||
QString getLength() const;
|
ut64 getEndAddress() const;
|
||||||
bool getEndAddressRadioButtonChecked() const;
|
|
||||||
bool getLengthRadioButtonChecked() const;
|
|
||||||
void setStartAddress(ut64 start);
|
void setStartAddress(ut64 start);
|
||||||
|
void open(ut64 start);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void textEdited();
|
void textEdited();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool getEndAddressRadioButtonChecked() const;
|
||||||
|
bool getLengthRadioButtonChecked() const;
|
||||||
|
bool validate();
|
||||||
|
|
||||||
Ui::HexdumpRangeDialog *ui;
|
Ui::HexdumpRangeDialog *ui;
|
||||||
|
bool emptyRange = true;
|
||||||
|
ut64 startAddress;
|
||||||
|
ut64 endAddress;
|
||||||
|
bool allowEmpty = false;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_radioButtonClicked(bool checked);
|
void on_radioButtonClicked(bool checked);
|
||||||
|
@ -43,6 +43,9 @@
|
|||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QRadioButton" name="endAddressRadioButton">
|
<widget class="QRadioButton" name="endAddressRadioButton">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Exclusive end address</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>End Address:</string>
|
<string>End Address:</string>
|
||||||
</property>
|
</property>
|
||||||
@ -72,6 +75,9 @@
|
|||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QLineEdit" name="endAddressLineEdit">
|
<widget class="QLineEdit" name="endAddressLineEdit">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Exclusive end address</string>
|
||||||
|
</property>
|
||||||
<property name="maxLength">
|
<property name="maxLength">
|
||||||
<number>18</number>
|
<number>18</number>
|
||||||
</property>
|
</property>
|
||||||
|
999
src/widgets/HexTextView.cpp
Normal file
999
src/widgets/HexTextView.cpp
Normal file
@ -0,0 +1,999 @@
|
|||||||
|
#include "HexTextView.h"
|
||||||
|
#include "ui_HexTextView.h"
|
||||||
|
|
||||||
|
#include "common/Helpers.h"
|
||||||
|
#include "common/Configuration.h"
|
||||||
|
#include "common/TempConfig.h"
|
||||||
|
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QElapsedTimer>
|
||||||
|
#include <QTextDocumentFragment>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QScrollBar>
|
||||||
|
#include <QInputDialog>
|
||||||
|
#include <QShortcut>
|
||||||
|
|
||||||
|
HexTextView::HexTextView(QWidget *parent) :
|
||||||
|
QScrollArea(parent),
|
||||||
|
ui(new Ui::HexTextView)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
// Setup hex highlight
|
||||||
|
//connect(ui->hexHexText, SIGNAL(cursorPositionChanged()), this, SLOT(highlightHexCurrentLine()));
|
||||||
|
//highlightHexCurrentLine();
|
||||||
|
|
||||||
|
int margin = static_cast<int>(ui->hexOffsetText->document()->documentMargin());
|
||||||
|
ui->offsetHeaderLabel->setContentsMargins(margin, 0, margin, 0);
|
||||||
|
|
||||||
|
margin = static_cast<int>(ui->hexHexText->document()->documentMargin());
|
||||||
|
ui->hexHeaderLabel->setContentsMargins(margin, 0, margin, 0);
|
||||||
|
|
||||||
|
margin = static_cast<int>(ui->hexASCIIText->document()->documentMargin());
|
||||||
|
ui->asciiHeaderLabel->setContentsMargins(margin, 0, margin, 0);
|
||||||
|
|
||||||
|
setupFonts();
|
||||||
|
|
||||||
|
updateHeaders();
|
||||||
|
|
||||||
|
// Set hexdump context menu
|
||||||
|
ui->hexHexText->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(ui->hexHexText, SIGNAL(customContextMenuRequested(const QPoint &)),
|
||||||
|
this, SLOT(showHexdumpContextMenu(const QPoint &)));
|
||||||
|
ui->hexASCIIText->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(ui->hexASCIIText, SIGNAL(customContextMenuRequested(const QPoint &)),
|
||||||
|
this, SLOT(showHexASCIIContextMenu(const QPoint &)));
|
||||||
|
|
||||||
|
setupScrollSync();
|
||||||
|
|
||||||
|
// Control Disasm and Hex scroll to add more contents
|
||||||
|
connectScroll(false);
|
||||||
|
|
||||||
|
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdated()));
|
||||||
|
|
||||||
|
connect(ui->hexHexText, &QTextEdit::selectionChanged, this, &HexTextView::onSelectionChanged);
|
||||||
|
connect(ui->hexASCIIText, &QTextEdit::selectionChanged, this, &HexTextView::onSelectionChanged);
|
||||||
|
connect(ui->hexHexText, &QTextEdit::cursorPositionChanged, this, &HexTextView::onSelectionChanged);
|
||||||
|
connect(ui->hexASCIIText, &QTextEdit::cursorPositionChanged, this,
|
||||||
|
&HexTextView::onSelectionChanged);
|
||||||
|
connect(&rangeDialog, &QDialog::accepted, this, &HexTextView::on_rangeDialogAccepted);
|
||||||
|
|
||||||
|
addAction(ui->actionResetZoom);
|
||||||
|
connect(ui->actionResetZoom, &QAction::triggered, this, &HexTextView::zoomReset);
|
||||||
|
defaultFontSize = ui->hexHexText->font().pointSizeF();
|
||||||
|
|
||||||
|
addAction(ui->actionCopyAddressAtCursor);
|
||||||
|
ui->actionCopyAddressAtCursor->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_C);
|
||||||
|
|
||||||
|
format = Format::Hex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::setupScrollSync()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* For some reason, QScrollBar::valueChanged is not emitted when
|
||||||
|
* the scrolling happened from moving the cursor beyond the visible content,
|
||||||
|
* so QTextEdit::cursorPositionChanged has to be connected as well.
|
||||||
|
*/
|
||||||
|
|
||||||
|
auto offsetHexFunc = [this]() {
|
||||||
|
if (!scroll_disabled) {
|
||||||
|
scroll_disabled = true;
|
||||||
|
ui->hexHexText->verticalScrollBar()->setValue(ui->hexOffsetText->verticalScrollBar()->value());
|
||||||
|
scroll_disabled = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto offsetASCIIFunc = [this]() {
|
||||||
|
if (!scroll_disabled) {
|
||||||
|
scroll_disabled = true;
|
||||||
|
ui->hexASCIIText->verticalScrollBar()->setValue(ui->hexOffsetText->verticalScrollBar()->value());
|
||||||
|
scroll_disabled = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
connect(ui->hexOffsetText->verticalScrollBar(), &QScrollBar::valueChanged,
|
||||||
|
ui->hexHexText->verticalScrollBar(), offsetHexFunc);
|
||||||
|
connect(ui->hexOffsetText, &QTextEdit::cursorPositionChanged, ui->hexHexText->verticalScrollBar(),
|
||||||
|
offsetHexFunc);
|
||||||
|
connect(ui->hexOffsetText->verticalScrollBar(), &QScrollBar::valueChanged,
|
||||||
|
ui->hexASCIIText->verticalScrollBar(), offsetASCIIFunc);
|
||||||
|
connect(ui->hexOffsetText, &QTextEdit::cursorPositionChanged, ui->hexASCIIText->verticalScrollBar(),
|
||||||
|
offsetASCIIFunc);
|
||||||
|
|
||||||
|
auto hexOffsetFunc = [this]() {
|
||||||
|
if (!scroll_disabled) {
|
||||||
|
scroll_disabled = true;
|
||||||
|
ui->hexOffsetText->verticalScrollBar()->setValue(ui->hexHexText->verticalScrollBar()->value());
|
||||||
|
scroll_disabled = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto hexASCIIFunc = [this]() {
|
||||||
|
if (!scroll_disabled) {
|
||||||
|
scroll_disabled = true;
|
||||||
|
ui->hexASCIIText->verticalScrollBar()->setValue(ui->hexHexText->verticalScrollBar()->value());
|
||||||
|
scroll_disabled = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
connect(ui->hexHexText->verticalScrollBar(), &QScrollBar::valueChanged,
|
||||||
|
ui->hexOffsetText->verticalScrollBar(), hexOffsetFunc);
|
||||||
|
connect(ui->hexHexText, &QTextEdit::cursorPositionChanged, ui->hexOffsetText->verticalScrollBar(),
|
||||||
|
hexOffsetFunc);
|
||||||
|
connect(ui->hexHexText->verticalScrollBar(), &QScrollBar::valueChanged,
|
||||||
|
ui->hexASCIIText->verticalScrollBar(), hexASCIIFunc);
|
||||||
|
connect(ui->hexHexText, &QTextEdit::cursorPositionChanged, ui->hexASCIIText->verticalScrollBar(),
|
||||||
|
hexASCIIFunc);
|
||||||
|
|
||||||
|
auto asciiOffsetFunc = [this]() {
|
||||||
|
if (!scroll_disabled) {
|
||||||
|
scroll_disabled = true;
|
||||||
|
ui->hexOffsetText->verticalScrollBar()->setValue(ui->hexASCIIText->verticalScrollBar()->value());
|
||||||
|
scroll_disabled = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto asciiHexFunc = [this]() {
|
||||||
|
if (!scroll_disabled) {
|
||||||
|
scroll_disabled = true;
|
||||||
|
ui->hexHexText->verticalScrollBar()->setValue(ui->hexASCIIText->verticalScrollBar()->value());
|
||||||
|
scroll_disabled = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
connect(ui->hexASCIIText->verticalScrollBar(), &QScrollBar::valueChanged,
|
||||||
|
ui->hexOffsetText->verticalScrollBar(), asciiOffsetFunc);
|
||||||
|
connect(ui->hexASCIIText, &QTextEdit::cursorPositionChanged, ui->hexOffsetText->verticalScrollBar(),
|
||||||
|
asciiOffsetFunc);
|
||||||
|
connect(ui->hexASCIIText->verticalScrollBar(), &QScrollBar::valueChanged,
|
||||||
|
ui->hexHexText->verticalScrollBar(), asciiHexFunc);
|
||||||
|
connect(ui->hexASCIIText, &QTextEdit::cursorPositionChanged, ui->hexHexText->verticalScrollBar(),
|
||||||
|
asciiHexFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::connectScroll(bool disconnect_)
|
||||||
|
{
|
||||||
|
scroll_disabled = disconnect_;
|
||||||
|
if (disconnect_) {
|
||||||
|
disconnect(ui->hexHexText->verticalScrollBar(), &QScrollBar::valueChanged, this,
|
||||||
|
&HexTextView::scrollChanged);
|
||||||
|
disconnect(ui->hexHexText, &QTextEdit::cursorPositionChanged, this, &HexTextView::scrollChanged);
|
||||||
|
} else {
|
||||||
|
connect(ui->hexHexText->verticalScrollBar(), &QScrollBar::valueChanged, this,
|
||||||
|
&HexTextView::scrollChanged);
|
||||||
|
connect(ui->hexHexText, &QTextEdit::cursorPositionChanged, this, &HexTextView::scrollChanged);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HexTextView::~HexTextView() {}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Text highlight functions
|
||||||
|
* Currently unused
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
void HexTextView::highlightHexCurrentLine()
|
||||||
|
{
|
||||||
|
QList<QTextEdit::ExtraSelection> extraSelections;
|
||||||
|
|
||||||
|
if (!ui->hexHexText->isReadOnly())
|
||||||
|
{
|
||||||
|
QTextEdit::ExtraSelection selection;
|
||||||
|
|
||||||
|
QColor lineColor = QColor(190, 144, 212);
|
||||||
|
|
||||||
|
selection.format.setBackground(lineColor);
|
||||||
|
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
|
||||||
|
selection.cursor = ui->hexHexText->textCursor();
|
||||||
|
selection.cursor.clearSelection();
|
||||||
|
extraSelections.append(selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextCursor cursor = ui->hexHexText->textCursor();
|
||||||
|
cursor.select(QTextCursor::WordUnderCursor);
|
||||||
|
|
||||||
|
QTextEdit::ExtraSelection currentWord;
|
||||||
|
|
||||||
|
QColor blueColor = QColor(Qt::blue).lighter(160);
|
||||||
|
currentWord.format.setBackground(blueColor);
|
||||||
|
|
||||||
|
currentWord.cursor = cursor;
|
||||||
|
extraSelections.append(currentWord);
|
||||||
|
|
||||||
|
ui->hexHexText->setExtraSelections(extraSelections);
|
||||||
|
|
||||||
|
highlightHexWords(cursor.selectedText());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HexTextView::highlightHexWords(const QString &str)
|
||||||
|
{
|
||||||
|
QString searchString = str;
|
||||||
|
QTextDocument *document = ui->hexHexText->document();
|
||||||
|
|
||||||
|
document->undo();
|
||||||
|
|
||||||
|
QTextCursor highlightCursor(document);
|
||||||
|
QTextCursor cursor(document);
|
||||||
|
|
||||||
|
cursor.beginEditBlock();
|
||||||
|
|
||||||
|
QColor blueColor = QColor(Qt::blue).lighter(160);
|
||||||
|
|
||||||
|
QTextCharFormat plainFormat(highlightCursor.charFormat());
|
||||||
|
QTextCharFormat colorFormat = plainFormat;
|
||||||
|
colorFormat.setBackground(blueColor);
|
||||||
|
|
||||||
|
while (!highlightCursor.isNull() && !highlightCursor.atEnd())
|
||||||
|
{
|
||||||
|
highlightCursor = document->find(searchString, highlightCursor, QTextDocument::FindWholeWords);
|
||||||
|
|
||||||
|
if (!highlightCursor.isNull())
|
||||||
|
{
|
||||||
|
highlightCursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
|
||||||
|
highlightCursor.mergeCharFormat(colorFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cursor.endEditBlock();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void HexTextView::refresh(RVA addr)
|
||||||
|
{
|
||||||
|
if (addr == RVA_INVALID) {
|
||||||
|
addr = currentPos;
|
||||||
|
} else {
|
||||||
|
currentPos = addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ut64 loadLines = 0;
|
||||||
|
ut64 curAddrLineOffset = 0;
|
||||||
|
connectScroll(true);
|
||||||
|
|
||||||
|
updateHeaders();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cols = Core()->getConfigi("hex.cols");
|
||||||
|
// Avoid divison by 0
|
||||||
|
if (cols == 0)
|
||||||
|
cols = 16;
|
||||||
|
|
||||||
|
// TODO: Figure out how to calculate a sane value for this
|
||||||
|
bufferLines = qhelpers::getMaxFullyDisplayedLines(ui->hexHexText) * 10;
|
||||||
|
|
||||||
|
if (requestedSelectionEndAddress != 0 && requestedSelectionStartAddress != 0
|
||||||
|
&& requestedSelectionEndAddress > requestedSelectionStartAddress) {
|
||||||
|
loadLines = ((requestedSelectionEndAddress - requestedSelectionStartAddress) / cols) +
|
||||||
|
(bufferLines * 2);
|
||||||
|
curAddrLineOffset = bufferLines;
|
||||||
|
} else {
|
||||||
|
loadLines = bufferLines * 3; // total lines to load
|
||||||
|
curAddrLineOffset = bufferLines; // line number where seek should be
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addr < curAddrLineOffset * cols) {
|
||||||
|
curAddrLineOffset = static_cast<int>(addr / cols);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addr > RVA_MAX - curAddrLineOffset * cols) {
|
||||||
|
curAddrLineOffset = static_cast<int>(loadLines - (RVA_MAX - addr) / cols);
|
||||||
|
}
|
||||||
|
|
||||||
|
first_loaded_address = addr - curAddrLineOffset * cols;
|
||||||
|
last_loaded_address = addr + (loadLines - curAddrLineOffset) * cols;
|
||||||
|
|
||||||
|
auto hexdump = fetchHexdump(first_loaded_address, loadLines);
|
||||||
|
|
||||||
|
ui->hexOffsetText->setText(hexdump[0]);
|
||||||
|
ui->hexHexText->setText(hexdump[1]);
|
||||||
|
ui->hexASCIIText->setPlainText(hexdump[2]);
|
||||||
|
|
||||||
|
QTextCursor cursor(ui->hexHexText->document()->findBlockByLineNumber(curAddrLineOffset));
|
||||||
|
ui->hexHexText->moveCursor(QTextCursor::End);
|
||||||
|
ui->hexHexText->ensureCursorVisible();
|
||||||
|
ui->hexHexText->setTextCursor(cursor);
|
||||||
|
ui->hexHexText->ensureCursorVisible();
|
||||||
|
|
||||||
|
// Set the backgorund color of the current seek
|
||||||
|
QTextCursor offsetCursor(ui->hexOffsetText->document()->findBlockByLineNumber(curAddrLineOffset));
|
||||||
|
QTextBlockFormat formatTmp = offsetCursor.blockFormat();
|
||||||
|
formatTmp.setBackground(QColor(64, 129, 160));
|
||||||
|
offsetCursor.setBlockFormat(formatTmp);
|
||||||
|
|
||||||
|
updateWidths();
|
||||||
|
|
||||||
|
// Update other text areas scroll
|
||||||
|
ui->hexOffsetText->verticalScrollBar()->setValue(ui->hexHexText->verticalScrollBar()->value());
|
||||||
|
ui->hexASCIIText->verticalScrollBar()->setValue(ui->hexHexText->verticalScrollBar()->value());
|
||||||
|
|
||||||
|
connectScroll(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::updateHeaders()
|
||||||
|
{
|
||||||
|
int cols = Core()->getConfigi("hex.cols");
|
||||||
|
int ascii_cols = cols;
|
||||||
|
bool pairs = Core()->getConfigb("hex.pairs");
|
||||||
|
|
||||||
|
QString hexHeaderString;
|
||||||
|
QString asciiHeaderString;
|
||||||
|
|
||||||
|
QTextStream hexHeader(&hexHeaderString);
|
||||||
|
QTextStream asciiHeader(&asciiHeaderString);
|
||||||
|
|
||||||
|
hexHeader.setIntegerBase(16);
|
||||||
|
hexHeader.setNumberFlags(QTextStream::UppercaseDigits);
|
||||||
|
asciiHeader.setIntegerBase(16);
|
||||||
|
asciiHeader.setNumberFlags(QTextStream::UppercaseDigits);
|
||||||
|
|
||||||
|
// Custom spacing for the header
|
||||||
|
QString space = " ";
|
||||||
|
switch (format) {
|
||||||
|
case Hex:
|
||||||
|
space = space.repeated(1);
|
||||||
|
break;
|
||||||
|
case Octal:
|
||||||
|
space = space.repeated(2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qWarning() << "Unknown format in hexdump!";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < cols; i++) {
|
||||||
|
if (i > 0 && ((pairs && !(i & 1)) || !pairs)) {
|
||||||
|
hexHeader << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
hexHeader << space << (i & 0xF);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < ascii_cols; i++) {
|
||||||
|
asciiHeader << (i & 0xF);
|
||||||
|
}
|
||||||
|
|
||||||
|
hexHeader.flush();
|
||||||
|
asciiHeader.flush();
|
||||||
|
|
||||||
|
ui->hexHeaderLabel->setText(hexHeaderString);
|
||||||
|
ui->asciiHeaderLabel->setText(asciiHeaderString);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::array<QString, 3> HexTextView::fetchHexdump(RVA addr, int lines)
|
||||||
|
{
|
||||||
|
// Main bytes to fetch:
|
||||||
|
int bytes = cols * lines;
|
||||||
|
|
||||||
|
QString command = QString("pxj %1 @%2").arg(
|
||||||
|
QString::number(bytes),
|
||||||
|
RAddressString(addr));
|
||||||
|
QJsonArray byte_array = Core()->cmdj(command).array();
|
||||||
|
|
||||||
|
QString hexText = "";
|
||||||
|
QString offsetText = "";
|
||||||
|
QString asciiText = "";
|
||||||
|
RVA cur_addr = addr;
|
||||||
|
for (int i = 0; i < lines; i++) {
|
||||||
|
for (int j = 0; j < cols; j++) {
|
||||||
|
int b = byte_array[(i * cols) + j].toInt();
|
||||||
|
if ((j > 0) && (j < cols)) {
|
||||||
|
hexText += " ";
|
||||||
|
}
|
||||||
|
// Non printable
|
||||||
|
if ((b < 0x20) || (b > 0x7E)) {
|
||||||
|
asciiText += ".";
|
||||||
|
} else {
|
||||||
|
asciiText += (char)b;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case Octal:
|
||||||
|
hexText += QString::number(b, 8).rightJustified(3, '0');
|
||||||
|
break;
|
||||||
|
case Hex:
|
||||||
|
default:
|
||||||
|
hexText += QString::number(b, 16).rightJustified(2, '0');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offsetText += RAddressString(cur_addr) + "\n";
|
||||||
|
hexText += "\n";
|
||||||
|
asciiText += "\n";
|
||||||
|
cur_addr += cols;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {{offsetText, hexText, asciiText}};
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::onSelectionChanged()
|
||||||
|
{
|
||||||
|
if (scroll_disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
connectScroll(true);
|
||||||
|
|
||||||
|
if (sender() == ui->hexHexText) {
|
||||||
|
QTextCursor textCursor = ui->hexHexText->textCursor();
|
||||||
|
if (!textCursor.hasSelection()) {
|
||||||
|
RVA adr = hexPositionToAddress(textCursor.position());
|
||||||
|
int pos = asciiAddressToPosition(adr);
|
||||||
|
setTextEditPosition(ui->hexASCIIText, pos);
|
||||||
|
|
||||||
|
selection = {true, 0, 0};
|
||||||
|
emit selectionChanged(selection);
|
||||||
|
currentPos = adr;
|
||||||
|
emit positionChanged(adr);
|
||||||
|
connectScroll(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int selectionStart = textCursor.selectionStart();
|
||||||
|
int selectionEnd = textCursor.selectionEnd();
|
||||||
|
|
||||||
|
QChar start = ui->hexHexText->document()->characterAt(selectionStart);
|
||||||
|
QChar end = ui->hexHexText->document()->characterAt(selectionEnd);
|
||||||
|
|
||||||
|
// This adjusts the selection to make sense with the chosen format
|
||||||
|
switch (format) {
|
||||||
|
case Hex:
|
||||||
|
// Handle the spaces/newlines (if it's at the start, move forward,
|
||||||
|
// if it's at the end, move back)
|
||||||
|
|
||||||
|
if (!start.isLetterOrNumber()) {
|
||||||
|
selectionStart += 1;
|
||||||
|
} else if (ui->hexHexText->document()->characterAt(selectionStart - 1).isLetterOrNumber()) {
|
||||||
|
selectionStart += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!end.isLetterOrNumber()) {
|
||||||
|
selectionEnd += 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Octal:
|
||||||
|
if (!start.isLetterOrNumber()) {
|
||||||
|
selectionStart += 1;
|
||||||
|
}
|
||||||
|
if (!end.isLetterOrNumber()) {
|
||||||
|
selectionEnd += 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In hextext we have the spaces that we need to somehow handle.
|
||||||
|
RVA startAddress = hexPositionToAddress(selectionStart);
|
||||||
|
RVA endAddress = hexPositionToAddress(selectionEnd);
|
||||||
|
|
||||||
|
int startPosition = asciiAddressToPosition(startAddress);
|
||||||
|
int endPosition = asciiAddressToPosition(endAddress);
|
||||||
|
QTextCursor targetTextCursor = ui->hexASCIIText->textCursor();
|
||||||
|
targetTextCursor.setPosition(startPosition);
|
||||||
|
targetTextCursor.setPosition(endPosition, QTextCursor::KeepAnchor);
|
||||||
|
ui->hexASCIIText->setTextCursor(targetTextCursor);
|
||||||
|
|
||||||
|
selection = {false, startAddress, endAddress > startAddress ? endAddress - 1 : endAddress};
|
||||||
|
emit selectionChanged(selection);
|
||||||
|
currentPos = startAddress;
|
||||||
|
emit positionChanged(startAddress);
|
||||||
|
} else {
|
||||||
|
QTextCursor textCursor = ui->hexASCIIText->textCursor();
|
||||||
|
if (!textCursor.hasSelection()) {
|
||||||
|
RVA adr = asciiPositionToAddress(textCursor.position());
|
||||||
|
int pos = hexAddressToPosition(adr);
|
||||||
|
setTextEditPosition(ui->hexHexText, pos);
|
||||||
|
connectScroll(false);
|
||||||
|
selection = {false, 0, 0};
|
||||||
|
emit selectionChanged(selection);
|
||||||
|
currentPos = adr;
|
||||||
|
emit positionChanged(adr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RVA startAddress = asciiPositionToAddress(textCursor.selectionStart());
|
||||||
|
RVA endAddress = asciiPositionToAddress(textCursor.selectionEnd());
|
||||||
|
|
||||||
|
int startPosition = hexAddressToPosition(startAddress);
|
||||||
|
int endPosition = hexAddressToPosition(endAddress);
|
||||||
|
|
||||||
|
// End position -1 because the position we get above is for the next
|
||||||
|
// entry, so including the space/newline
|
||||||
|
endPosition -= 1;
|
||||||
|
QTextCursor targetTextCursor = ui->hexHexText->textCursor();
|
||||||
|
targetTextCursor.setPosition(startPosition);
|
||||||
|
targetTextCursor.setPosition(endPosition, QTextCursor::KeepAnchor);
|
||||||
|
ui->hexHexText->setTextCursor(targetTextCursor);
|
||||||
|
|
||||||
|
selection = {false, startAddress, endAddress > startAddress ? endAddress - 1 : endAddress};
|
||||||
|
emit selectionChanged(selection);
|
||||||
|
currentPos = startAddress;
|
||||||
|
emit positionChanged(startAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
connectScroll(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void HexTextView::showHexdumpContextMenu(const QPoint &pt)
|
||||||
|
{
|
||||||
|
// Set Hexdump popup menu
|
||||||
|
QMenu *menu = ui->hexHexText->createStandardContextMenu();
|
||||||
|
menu->clear();
|
||||||
|
|
||||||
|
/*menu->addAction(ui->actionHexCopy_Hexpair);
|
||||||
|
menu->addAction(ui->actionHexCopy_ASCII);
|
||||||
|
menu->addAction(ui->actionHexCopy_Text);
|
||||||
|
menu->addSeparator();*/
|
||||||
|
QMenu *colSubmenu = menu->addMenu(tr("Columns"));
|
||||||
|
colSubmenu->addAction(ui->action4columns);
|
||||||
|
colSubmenu->addAction(ui->action8columns);
|
||||||
|
colSubmenu->addAction(ui->action16columns);
|
||||||
|
colSubmenu->addAction(ui->action32columns);
|
||||||
|
|
||||||
|
QMenu *formatSubmenu = menu->addMenu(tr("Format"));
|
||||||
|
formatSubmenu->addAction(ui->actionFormatHex);
|
||||||
|
formatSubmenu->addAction(ui->actionFormatOctal);
|
||||||
|
|
||||||
|
menu->addAction(ui->actionSelect_Block);
|
||||||
|
|
||||||
|
menu->addSeparator();
|
||||||
|
menu->addActions(this->actions());
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// formatSubmenu->addAction(ui->actionFormatHalfWord);
|
||||||
|
// formatSubmenu->addAction(ui->actionFormatWord);
|
||||||
|
// formatSubmenu->addAction(ui->actionFormatQuadWord);
|
||||||
|
// formatSubmenu->addAction(ui->actionFormatEmoji);
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// QMenu *signedIntFormatSubmenu = formatSubmenu->addMenu(tr("Signed integer"));
|
||||||
|
// signedIntFormatSubmenu->addAction(ui->actionFormatSignedInt1);
|
||||||
|
// signedIntFormatSubmenu->addAction(ui->actionFormatSignedInt2);
|
||||||
|
// signedIntFormatSubmenu->addAction(ui->actionFormatSignedInt4);
|
||||||
|
|
||||||
|
/*menu->addSeparator();
|
||||||
|
menu->addAction(ui->actionHexEdit);
|
||||||
|
menu->addAction(ui->actionHexPaste);
|
||||||
|
menu->addSeparator();
|
||||||
|
menu->addAction(ui->actionHexInsert_Hex);
|
||||||
|
menu->addAction(ui->actionHexInsert_String);*/
|
||||||
|
|
||||||
|
ui->hexHexText->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
|
||||||
|
menu->exec(ui->hexHexText->mapToGlobal(pt));
|
||||||
|
delete menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::showHexASCIIContextMenu(const QPoint &pt)
|
||||||
|
{
|
||||||
|
// Set Hex ASCII popup menu
|
||||||
|
QMenu *menu = ui->hexASCIIText->createStandardContextMenu();
|
||||||
|
menu->clear();
|
||||||
|
/*menu->addAction(ui->actionHexCopy_Hexpair);
|
||||||
|
menu->addAction(ui->actionHexCopy_ASCII);
|
||||||
|
menu->addAction(ui->actionHexCopy_Text);
|
||||||
|
menu->addSeparator();*/
|
||||||
|
QMenu *colSubmenu = menu->addMenu("Columns");
|
||||||
|
colSubmenu->addAction(ui->action4columns);
|
||||||
|
colSubmenu->addAction(ui->action8columns);
|
||||||
|
colSubmenu->addAction(ui->action16columns);
|
||||||
|
colSubmenu->addAction(ui->action32columns);
|
||||||
|
/*menu->addSeparator();
|
||||||
|
menu->addAction(ui->actionHexEdit);
|
||||||
|
menu->addAction(ui->actionHexPaste);
|
||||||
|
menu->addSeparator();
|
||||||
|
menu->addAction(ui->actionHexInsert_Hex);
|
||||||
|
menu->addAction(ui->actionHexInsert_String);*/
|
||||||
|
|
||||||
|
ui->hexASCIIText->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
|
||||||
|
menu->exec(ui->hexASCIIText->mapToGlobal(pt));
|
||||||
|
delete menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::setupFonts()
|
||||||
|
{
|
||||||
|
QFont font = Config()->getFont();
|
||||||
|
|
||||||
|
ui->hexOffsetText->setFont(font);
|
||||||
|
ui->hexHexText->setFont(font);
|
||||||
|
ui->hexASCIIText->setFont(font);
|
||||||
|
|
||||||
|
ui->offsetHeaderLabel->setFont(font);
|
||||||
|
ui->hexHeaderLabel->setFont(font);
|
||||||
|
ui->asciiHeaderLabel->setFont(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
HexTextView::Selection HexTextView::getSelection()
|
||||||
|
{
|
||||||
|
return selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
RVA HexTextView::position()
|
||||||
|
{
|
||||||
|
return currentPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::fontsUpdated()
|
||||||
|
{
|
||||||
|
setupFonts();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RVA HexTextView::hexPositionToAddress(int position)
|
||||||
|
{
|
||||||
|
switch (format) {
|
||||||
|
|
||||||
|
case Octal:
|
||||||
|
return first_loaded_address + (position / 4);
|
||||||
|
case Hex:
|
||||||
|
default:
|
||||||
|
return first_loaded_address + (position / 3);
|
||||||
|
}
|
||||||
|
return RVA_INVALID;
|
||||||
|
// In hex each byte takes up 2 characters + 1 spacer (including newline as spacer)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
RVA HexTextView::asciiPositionToAddress(int position)
|
||||||
|
{
|
||||||
|
// Each row adds one byte (because of the newline), so cols + 1 gets rid of that offset
|
||||||
|
return first_loaded_address + (position - (position / (cols + 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int HexTextView::hexAddressToPosition(RVA address)
|
||||||
|
{
|
||||||
|
// This strictly assumes that the address is actually loaded.
|
||||||
|
switch (format) {
|
||||||
|
|
||||||
|
case Octal:
|
||||||
|
return (address - first_loaded_address) * 4;
|
||||||
|
case Hex:
|
||||||
|
default:
|
||||||
|
return (address - first_loaded_address) * 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int HexTextView::asciiAddressToPosition(RVA address)
|
||||||
|
{
|
||||||
|
RVA local_address = address - first_loaded_address;
|
||||||
|
int position = local_address + (local_address / cols);
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::setTextEditPosition(QTextEdit *textEdit, int position)
|
||||||
|
{
|
||||||
|
QTextCursor textCursor = textEdit->textCursor();
|
||||||
|
textCursor.setPosition(position);
|
||||||
|
textEdit->setTextCursor(textCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
int HexTextView::getDisplayedLined(QTextEdit *textEdit, bool bottom)
|
||||||
|
{
|
||||||
|
//int start_pos = textEdit->cursorForPosition(QPoint(0, 0)).position();
|
||||||
|
QPoint top_right(textEdit->viewport()->x(), textEdit->viewport()->y());
|
||||||
|
QPoint bottom_right(textEdit->viewport()->width(), textEdit->viewport()->height() - 1);
|
||||||
|
QPoint point = top_right;
|
||||||
|
if (bottom) {
|
||||||
|
point = bottom_right;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextCursor textCursor = textEdit->cursorForPosition(point);
|
||||||
|
//QTextBlock textBlock = textCursor.block();
|
||||||
|
//QTextLayout *textLayout = textBlock.layout();
|
||||||
|
//const int relativePos = textCursor.position() - textBlock.position();
|
||||||
|
//int end_pos = textEdit->cursorForPosition(bottom_right).position();
|
||||||
|
return textCursor.blockNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::removeTopLinesWithoutScroll(QTextEdit *textEdit, int lines)
|
||||||
|
{
|
||||||
|
int scroll_val_before = textEdit->verticalScrollBar()->value();
|
||||||
|
int height_before = textEdit->document()->size().height();
|
||||||
|
|
||||||
|
QTextBlock block = textEdit->document()->firstBlock();
|
||||||
|
for (int i = 0; i < lines; i++) {
|
||||||
|
QTextCursor cursor(block);
|
||||||
|
block = block.next();
|
||||||
|
cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor);
|
||||||
|
cursor.removeSelectedText();
|
||||||
|
}
|
||||||
|
|
||||||
|
int height_after = textEdit->document()->size().height();
|
||||||
|
textEdit->verticalScrollBar()->setValue(scroll_val_before + (height_after - height_before));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::removeBottomLinesWithoutScroll(QTextEdit *textEdit, int lines)
|
||||||
|
{
|
||||||
|
QTextBlock block = textEdit->document()->lastBlock().previous();
|
||||||
|
QTextCursor textCursor = textEdit->textCursor();
|
||||||
|
for (int i = 0; i < lines; i++) {
|
||||||
|
QTextCursor cursor(block);
|
||||||
|
block = block.previous();
|
||||||
|
cursor.select(QTextCursor::BlockUnderCursor);
|
||||||
|
cursor.removeSelectedText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::prependWithoutScroll(QTextEdit *textEdit, QString text)
|
||||||
|
{
|
||||||
|
// TODO: Keep selection (already works for append)
|
||||||
|
QTextCursor textCursor = textEdit->textCursor();
|
||||||
|
int current_positon = textCursor.position();
|
||||||
|
|
||||||
|
//int scroll_max_before = textEdit->verticalScrollBar()->maximum();
|
||||||
|
int scroll_val_before = textEdit->verticalScrollBar()->value();
|
||||||
|
int height_before = textEdit->document()->size().height();
|
||||||
|
textEdit->moveCursor(QTextCursor::Start);
|
||||||
|
textEdit->insertPlainText(text);
|
||||||
|
textCursor.setPosition(text.length() + current_positon);
|
||||||
|
textEdit->setTextCursor(textCursor);
|
||||||
|
int height_after = textEdit->document()->size().height();
|
||||||
|
//int scroll_max_after = textEdit->verticalScrollBar()->maximum();
|
||||||
|
//int scroll_val_after = textEdit->verticalScrollBar()->maximum();
|
||||||
|
textEdit->verticalScrollBar()->setValue(scroll_val_before + (height_after - height_before));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::appendWithoutScroll(QTextEdit *textEdit, QString text)
|
||||||
|
{
|
||||||
|
int scroll_val_before = textEdit->verticalScrollBar()->value();
|
||||||
|
QTextCursor textCursor = textEdit->textCursor();
|
||||||
|
textEdit->moveCursor(QTextCursor::End);
|
||||||
|
textEdit->insertPlainText(text);
|
||||||
|
textEdit->setTextCursor(textCursor);
|
||||||
|
textEdit->verticalScrollBar()->setValue(scroll_val_before);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::scrollChanged()
|
||||||
|
{
|
||||||
|
connectScroll(true);
|
||||||
|
|
||||||
|
int firstLine = getDisplayedLined(ui->hexHexText);
|
||||||
|
if (firstLine < (bufferLines / 2)) {
|
||||||
|
int loadLines = bufferLines;
|
||||||
|
RVA shift = static_cast<RVA>(loadLines * cols);
|
||||||
|
if (shift > first_loaded_address) {
|
||||||
|
loadLines = static_cast<int>(first_loaded_address / cols);
|
||||||
|
shift = first_loaded_address;
|
||||||
|
}
|
||||||
|
first_loaded_address -= shift;
|
||||||
|
last_loaded_address -= shift;
|
||||||
|
|
||||||
|
if (loadLines > 0) {
|
||||||
|
auto hexdump = fetchHexdump(first_loaded_address, loadLines);
|
||||||
|
prependWithoutScroll(ui->hexOffsetText, hexdump[0]);
|
||||||
|
prependWithoutScroll(ui->hexHexText, hexdump[1]);
|
||||||
|
prependWithoutScroll(ui->hexASCIIText, hexdump[2]);
|
||||||
|
|
||||||
|
removeBottomLinesWithoutScroll(ui->hexOffsetText, loadLines);
|
||||||
|
removeBottomLinesWithoutScroll(ui->hexHexText, loadLines);
|
||||||
|
removeBottomLinesWithoutScroll(ui->hexASCIIText, loadLines);
|
||||||
|
|
||||||
|
ui->hexOffsetText->verticalScrollBar()->setValue(ui->hexHexText->verticalScrollBar()->value());
|
||||||
|
ui->hexASCIIText->verticalScrollBar()->setValue(ui->hexHexText->verticalScrollBar()->value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int blocks = ui->hexHexText->document()->blockCount();
|
||||||
|
int lastLine = getDisplayedLined(ui->hexHexText, true);
|
||||||
|
if (blocks - lastLine < (bufferLines / 2)) {
|
||||||
|
int loadLines = bufferLines;
|
||||||
|
RVA shift = static_cast<RVA>(loadLines * cols);
|
||||||
|
if (last_loaded_address > RVA_MAX - shift) {
|
||||||
|
shift = RVA_MAX - last_loaded_address;
|
||||||
|
loadLines = static_cast<int>(shift / cols);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loadLines > 0) {
|
||||||
|
auto hexdump = fetchHexdump(last_loaded_address, loadLines);
|
||||||
|
last_loaded_address += shift;
|
||||||
|
first_loaded_address += shift;
|
||||||
|
|
||||||
|
removeTopLinesWithoutScroll(ui->hexOffsetText, loadLines);
|
||||||
|
removeTopLinesWithoutScroll(ui->hexHexText, loadLines);
|
||||||
|
removeTopLinesWithoutScroll(ui->hexASCIIText, loadLines);
|
||||||
|
appendWithoutScroll(ui->hexOffsetText, hexdump[0]);
|
||||||
|
appendWithoutScroll(ui->hexHexText, hexdump[1]);
|
||||||
|
appendWithoutScroll(ui->hexASCIIText, hexdump[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connectScroll(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Actions callback functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
void HexTextView::on_actionCopyAddressAtCursor_triggered()
|
||||||
|
{
|
||||||
|
auto addr = hexPositionToAddress(ui->hexHexText->textCursor().position());
|
||||||
|
|
||||||
|
QClipboard *clipboard = QApplication::clipboard();
|
||||||
|
clipboard->setText(RAddressString(addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HexTextView::on_action8columns_triggered()
|
||||||
|
{
|
||||||
|
Core()->setConfig("hex.cols", 8);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::on_action16columns_triggered()
|
||||||
|
{
|
||||||
|
Core()->setConfig("hex.cols", 16);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::on_action4columns_triggered()
|
||||||
|
{
|
||||||
|
Core()->setConfig("hex.cols", 4);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::on_action32columns_triggered()
|
||||||
|
{
|
||||||
|
Core()->setConfig("hex.cols", 32);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::on_action64columns_triggered()
|
||||||
|
{
|
||||||
|
Core()->setConfig("hex.cols", 64);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::on_action2columns_triggered()
|
||||||
|
{
|
||||||
|
Core()->setConfig("hex.cols", 2);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::on_action1column_triggered()
|
||||||
|
{
|
||||||
|
Core()->setConfig("hex.cols", 1);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::on_actionFormatHex_triggered()
|
||||||
|
{
|
||||||
|
format = Format::Hex;
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::on_actionFormatOctal_triggered()
|
||||||
|
{
|
||||||
|
format = Format::Octal;
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::on_actionSelect_Block_triggered()
|
||||||
|
{
|
||||||
|
rangeDialog.open(hexPositionToAddress(ui->hexHexText->textCursor().position()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void HexTextView::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
QScrollArea::resizeEvent(event);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::wheelEvent(QWheelEvent *event)
|
||||||
|
{
|
||||||
|
if ( Qt::ControlModifier == event->modifiers() ) {
|
||||||
|
const QPoint numDegrees = event->angleDelta() / 8;
|
||||||
|
if (!numDegrees.isNull()) {
|
||||||
|
const QPoint numSteps = numDegrees / 15;
|
||||||
|
if ( 0 != numSteps.y() ) {
|
||||||
|
zoomIn(numSteps.y() > 0 ? 1 : -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
event->accept();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event->ignore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::selectRange(RVA start, RVA end)
|
||||||
|
{
|
||||||
|
int startPosition;
|
||||||
|
int endPosition;
|
||||||
|
QTextCursor targetTextCursor;
|
||||||
|
|
||||||
|
requestedSelectionStartAddress = start;
|
||||||
|
requestedSelectionEndAddress = end;
|
||||||
|
|
||||||
|
//not sure what the accepted user feedback mechanism is, output to console or a QMessageBox alert
|
||||||
|
if (requestedSelectionEndAddress < requestedSelectionStartAddress) {
|
||||||
|
Core()->message(tr("Error: Could not select range, end address is less then start address"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//seek to the start address and create a text cursor to highlight the desired range
|
||||||
|
refresh(requestedSelectionStartAddress);
|
||||||
|
|
||||||
|
//for large selections, won't be able to calculate the endPosition because hexAddressToPosition assumes the address is loaded?
|
||||||
|
startPosition = hexAddressToPosition(requestedSelectionStartAddress);
|
||||||
|
endPosition = hexAddressToPosition(requestedSelectionEndAddress + 1);
|
||||||
|
|
||||||
|
targetTextCursor = ui->hexHexText->textCursor();
|
||||||
|
|
||||||
|
targetTextCursor.setPosition(startPosition);
|
||||||
|
targetTextCursor.setPosition(endPosition, QTextCursor::KeepAnchor);
|
||||||
|
|
||||||
|
ui->hexHexText->setTextCursor(targetTextCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::on_rangeDialogAccepted()
|
||||||
|
{
|
||||||
|
if (rangeDialog.empty()) {
|
||||||
|
refresh(rangeDialog.getStartAddress());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
requestedSelectionStartAddress = rangeDialog.getStartAddress();
|
||||||
|
requestedSelectionEndAddress = rangeDialog.getEndAddress();
|
||||||
|
|
||||||
|
selectRange(requestedSelectionStartAddress, requestedSelectionEndAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::showOffsets(bool show)
|
||||||
|
{
|
||||||
|
if (show) {
|
||||||
|
ui->hexOffsetText->show();
|
||||||
|
Core()->setConfig("asm.offset", 1);
|
||||||
|
} else {
|
||||||
|
ui->hexOffsetText->hide();
|
||||||
|
Core()->setConfig("asm.offset", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::zoomIn(int range)
|
||||||
|
{
|
||||||
|
ui->hexHexText->zoomIn(range);
|
||||||
|
syncScale();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::zoomOut(int range)
|
||||||
|
{
|
||||||
|
zoomIn(-range);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::zoomReset()
|
||||||
|
{
|
||||||
|
QFont font(ui->hexHexText->font());
|
||||||
|
font.setPointSizeF(defaultFontSize);
|
||||||
|
ui->hexHexText->setFont(font);
|
||||||
|
syncScale();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::updateWidths()
|
||||||
|
{
|
||||||
|
// Update width
|
||||||
|
auto idealWidth = ui->hexHexText->document()->idealWidth();
|
||||||
|
ui->hexHexText->document()->setTextWidth(idealWidth);
|
||||||
|
|
||||||
|
ui->hexOffsetText->document()->adjustSize();
|
||||||
|
ui->hexOffsetText->setFixedWidth(ui->hexOffsetText->document()->size().width() + 1);
|
||||||
|
|
||||||
|
ui->hexASCIIText->document()->adjustSize();
|
||||||
|
ui->hexASCIIText->setMinimumWidth(ui->hexASCIIText->document()->size().width());
|
||||||
|
}
|
||||||
|
|
||||||
|
void HexTextView::syncScale()
|
||||||
|
{
|
||||||
|
ui->hexOffsetText->setFont(ui->hexHexText->font());
|
||||||
|
ui->hexASCIIText->setFont(ui->hexHexText->font());
|
||||||
|
ui->offsetHeaderLabel->setFont(ui->hexHexText->font());
|
||||||
|
ui->hexHeaderLabel->setFont(ui->hexHexText->font());
|
||||||
|
ui->asciiHeaderLabel->setFont(ui->hexHexText->font());
|
||||||
|
updateWidths();
|
||||||
|
}
|
158
src/widgets/HexTextView.h
Normal file
158
src/widgets/HexTextView.h
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#ifndef HexTextView_H
|
||||||
|
#define HexTextView_H
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QTextEdit>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QScrollArea>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "core/Cutter.h"
|
||||||
|
#include "MemoryDockWidget.h"
|
||||||
|
#include "common/CutterSeekable.h"
|
||||||
|
#include "dialogs/HexdumpRangeDialog.h"
|
||||||
|
#include "common/Highlighter.h"
|
||||||
|
#include "common/HexAsciiHighlighter.h"
|
||||||
|
#include "common/HexHighlighter.h"
|
||||||
|
#include "common/SvgIconEngine.h"
|
||||||
|
|
||||||
|
#include "Dashboard.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class HexTextView;
|
||||||
|
}
|
||||||
|
|
||||||
|
class RefreshDeferrer;
|
||||||
|
|
||||||
|
class HexTextView : public QScrollArea
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit HexTextView(QWidget *parent);
|
||||||
|
~HexTextView();
|
||||||
|
Highlighter *highlighter;
|
||||||
|
enum Format {
|
||||||
|
Hex,
|
||||||
|
Octal,
|
||||||
|
// TODO:
|
||||||
|
// HalfWord,
|
||||||
|
// Word,
|
||||||
|
// QuadWord,
|
||||||
|
// Emoji,
|
||||||
|
// SignedInt1,
|
||||||
|
// SignedInt2,
|
||||||
|
// SignedInt4,
|
||||||
|
};
|
||||||
|
void refresh(RVA addr = RVA_INVALID);
|
||||||
|
/**
|
||||||
|
* @brief Select non empty inclusive range [start; end]
|
||||||
|
* @param start
|
||||||
|
* @param end
|
||||||
|
*/
|
||||||
|
void selectRange(RVA start, RVA end);
|
||||||
|
void setupFonts();
|
||||||
|
|
||||||
|
struct Selection {
|
||||||
|
bool empty;
|
||||||
|
RVA startAddress;
|
||||||
|
RVA endAddress;
|
||||||
|
};
|
||||||
|
|
||||||
|
Selection getSelection();
|
||||||
|
RVA position();
|
||||||
|
public slots:
|
||||||
|
void on_rangeDialogAccepted();
|
||||||
|
void showOffsets(bool show);
|
||||||
|
|
||||||
|
void zoomIn(int range = 1);
|
||||||
|
void zoomOut(int range = 1);
|
||||||
|
void zoomReset();
|
||||||
|
signals:
|
||||||
|
void selectionChanged(Selection selection);
|
||||||
|
void positionChanged(RVA start);
|
||||||
|
protected:
|
||||||
|
virtual void resizeEvent(QResizeEvent *event) override;
|
||||||
|
virtual void wheelEvent(QWheelEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum Format format = Format::Hex;
|
||||||
|
|
||||||
|
std::unique_ptr<Ui::HexTextView> ui;
|
||||||
|
|
||||||
|
bool sent_seek = false;
|
||||||
|
bool scroll_disabled = false;
|
||||||
|
|
||||||
|
RVA first_loaded_address = RVA_INVALID;
|
||||||
|
RVA last_loaded_address = RVA_INVALID;
|
||||||
|
|
||||||
|
void updateHeaders();
|
||||||
|
|
||||||
|
std::array<QString, 3> fetchHexdump(RVA addr, int lines);
|
||||||
|
|
||||||
|
void connectScroll(bool disconnect_);
|
||||||
|
void setupScrollSync();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// If bottom = false gets the FIRST displayed line, otherwise the LAST displayed
|
||||||
|
// line.
|
||||||
|
int getDisplayedLined(QTextEdit *textEdit, bool bottom = false);
|
||||||
|
|
||||||
|
static void removeTopLinesWithoutScroll(QTextEdit *textEdit, int lines);
|
||||||
|
static void removeBottomLinesWithoutScroll(QTextEdit *textEdit, int lines);
|
||||||
|
static void prependWithoutScroll(QTextEdit *textEdit, QString text);
|
||||||
|
static void appendWithoutScroll(QTextEdit *textEdit, QString text);
|
||||||
|
static void setTextEditPosition(QTextEdit *textEdit, int position);
|
||||||
|
|
||||||
|
RVA hexPositionToAddress(int position);
|
||||||
|
RVA asciiPositionToAddress(int position);
|
||||||
|
int hexAddressToPosition(RVA address);
|
||||||
|
int asciiAddressToPosition(RVA address);
|
||||||
|
void updateWidths();
|
||||||
|
void syncScale();
|
||||||
|
|
||||||
|
void updateParseWindow(RVA start_address, int size);
|
||||||
|
void clearParseWindow();
|
||||||
|
|
||||||
|
int bufferLines = 0;
|
||||||
|
int cols = 0;
|
||||||
|
ut64 requestedSelectionStartAddress=0;
|
||||||
|
ut64 requestedSelectionEndAddress=0;
|
||||||
|
HexdumpRangeDialog rangeDialog;
|
||||||
|
RVA currentPos = 0;
|
||||||
|
qreal defaultFontSize;
|
||||||
|
Selection selection;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
// Currently unused/untested
|
||||||
|
// void highlightHexCurrentLine();
|
||||||
|
// void highlightHexWords(const QString &str);
|
||||||
|
|
||||||
|
void showHexdumpContextMenu(const QPoint &pt);
|
||||||
|
void showHexASCIIContextMenu(const QPoint &pt);
|
||||||
|
|
||||||
|
void onSelectionChanged();
|
||||||
|
void scrollChanged();
|
||||||
|
|
||||||
|
void on_actionCopyAddressAtCursor_triggered();
|
||||||
|
|
||||||
|
void on_action1column_triggered();
|
||||||
|
void on_action2columns_triggered();
|
||||||
|
void on_action4columns_triggered();
|
||||||
|
void on_action8columns_triggered();
|
||||||
|
void on_action16columns_triggered();
|
||||||
|
void on_action32columns_triggered();
|
||||||
|
void on_action64columns_triggered();
|
||||||
|
|
||||||
|
void on_actionFormatHex_triggered();
|
||||||
|
void on_actionFormatOctal_triggered();
|
||||||
|
|
||||||
|
void on_actionSelect_Block_triggered();
|
||||||
|
|
||||||
|
void fontsUpdated();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HexTextView_H
|
418
src/widgets/HexTextView.ui
Normal file
418
src/widgets/HexTextView.ui
Normal file
@ -0,0 +1,418 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>HexTextView</class>
|
||||||
|
<widget class="QScrollArea" name="HexTextView">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="widgetResizable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>515</width>
|
||||||
|
<height>770</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,0,0,0,1">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item row="1" column="3">
|
||||||
|
<widget class="Line" name="line_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QLabel" name="hexHeaderLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0 1 2 3 ...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QTextEdit" name="hexOffsetText">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="acceptDrops">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="lineWidth">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="verticalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="4">
|
||||||
|
<widget class="QLabel" name="asciiHeaderLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Ignored" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0123...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="offsetHeaderLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Offset</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="4">
|
||||||
|
<widget class="QTextEdit" name="hexASCIIText">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Anonymous Pro</family>
|
||||||
|
<pointsize>13</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="acceptDrops">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="lineWidth">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="verticalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||||
|
</property>
|
||||||
|
<property name="lineWrapMode">
|
||||||
|
<enum>QTextEdit::NoWrap</enum>
|
||||||
|
</property>
|
||||||
|
<property name="cursorWidth">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QTextEdit" name="hexHexText">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="acceptDrops">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="lineWidth">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="verticalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<action name="actionFunctionsUndefine">
|
||||||
|
<property name="text">
|
||||||
|
<string>Undefine</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Undefine</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDisasCopy_All">
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy all</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Copy all</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDisasCopy_Bytes">
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy bytes</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Copy bytes</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDisasCopy_Disasm">
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy disasm</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Copy disasm</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionHexCopy_Hexpair">
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy Hexpair</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Copy Hexpair</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionHexCopy_ASCII">
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy ASCII</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Copy ASCII</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionHexCopy_Text">
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy Text</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Copy Text</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCopyAddressAtCursor">
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy Address</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Copy Address at Cursor</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="action1column">
|
||||||
|
<property name="text">
|
||||||
|
<string>1</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>1</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="action2columns">
|
||||||
|
<property name="text">
|
||||||
|
<string>2</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>2</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="action4columns">
|
||||||
|
<property name="text">
|
||||||
|
<string>4</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>4</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="action8columns">
|
||||||
|
<property name="text">
|
||||||
|
<string>8</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>8</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="action16columns">
|
||||||
|
<property name="text">
|
||||||
|
<string>16</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>16</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="action32columns">
|
||||||
|
<property name="text">
|
||||||
|
<string>32</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>32</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="action64columns">
|
||||||
|
<property name="text">
|
||||||
|
<string>64</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>64</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionHexEdit">
|
||||||
|
<property name="text">
|
||||||
|
<string>Edit</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Edit</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionHexPaste">
|
||||||
|
<property name="text">
|
||||||
|
<string>Paste</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Paste</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionHexInsert_Hex">
|
||||||
|
<property name="text">
|
||||||
|
<string>Insert Hex</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Insert Hex</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionHexInsert_String">
|
||||||
|
<property name="text">
|
||||||
|
<string>Insert String</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Insert String</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionFormatHex">
|
||||||
|
<property name="text">
|
||||||
|
<string>Hex</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionFormatOctal">
|
||||||
|
<property name="text">
|
||||||
|
<string>Octal</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionFormatHalfWord">
|
||||||
|
<property name="text">
|
||||||
|
<string>Half-word</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionFormatWord">
|
||||||
|
<property name="text">
|
||||||
|
<string>Word</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionFormatQuadWord">
|
||||||
|
<property name="text">
|
||||||
|
<string>Quad-word</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionFormatEmoji">
|
||||||
|
<property name="text">
|
||||||
|
<string>Emoji</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionFormatSignedInt1">
|
||||||
|
<property name="text">
|
||||||
|
<string>1 byte</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>1 byte</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionFormatSignedInt2">
|
||||||
|
<property name="text">
|
||||||
|
<string>2 bytes</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>2 bytes</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionFormatSignedInt4">
|
||||||
|
<property name="text">
|
||||||
|
<string>4 bytes</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>4 bytes</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSelect_Block">
|
||||||
|
<property name="text">
|
||||||
|
<string>Select Block...</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionResetZoom">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Reset zoom</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+0</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcutContext">
|
||||||
|
<enum>Qt::WindowShortcut</enum>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<resources />
|
||||||
|
<connections />
|
||||||
|
</ui>
|
File diff suppressed because it is too large
Load Diff
@ -12,11 +12,11 @@
|
|||||||
#include "core/Cutter.h"
|
#include "core/Cutter.h"
|
||||||
#include "MemoryDockWidget.h"
|
#include "MemoryDockWidget.h"
|
||||||
#include "common/CutterSeekable.h"
|
#include "common/CutterSeekable.h"
|
||||||
#include "dialogs/HexdumpRangeDialog.h"
|
|
||||||
#include "common/Highlighter.h"
|
#include "common/Highlighter.h"
|
||||||
#include "common/HexAsciiHighlighter.h"
|
#include "common/HexAsciiHighlighter.h"
|
||||||
#include "common/HexHighlighter.h"
|
#include "common/HexHighlighter.h"
|
||||||
#include "common/SvgIconEngine.h"
|
#include "common/SvgIconEngine.h"
|
||||||
|
#include "HexTextView.h"
|
||||||
|
|
||||||
#include "Dashboard.h"
|
#include "Dashboard.h"
|
||||||
|
|
||||||
@ -33,127 +33,46 @@ public:
|
|||||||
explicit HexdumpWidget(MainWindow *main, QAction *action = nullptr);
|
explicit HexdumpWidget(MainWindow *main, QAction *action = nullptr);
|
||||||
~HexdumpWidget();
|
~HexdumpWidget();
|
||||||
Highlighter *highlighter;
|
Highlighter *highlighter;
|
||||||
enum Format {
|
|
||||||
Hex,
|
|
||||||
Octal,
|
|
||||||
// TODO:
|
|
||||||
// HalfWord,
|
|
||||||
// Word,
|
|
||||||
// QuadWord,
|
|
||||||
// Emoji,
|
|
||||||
// SignedInt1,
|
|
||||||
// SignedInt2,
|
|
||||||
// SignedInt4,
|
|
||||||
};
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void initParsing();
|
void initParsing();
|
||||||
void on_rangeDialogAccepted();
|
|
||||||
void showOffsets(bool show);
|
|
||||||
|
|
||||||
void zoomIn(int range = 1);
|
|
||||||
void zoomOut(int range = 1);
|
|
||||||
void zoomReset();
|
|
||||||
void toggleSync();
|
void toggleSync();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void resizeEvent(QResizeEvent *event) override;
|
virtual void resizeEvent(QResizeEvent *event) override;
|
||||||
virtual void wheelEvent(QWheelEvent *event) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int linesMarginMin = 32;
|
|
||||||
static const int linesMarginDefault = 48;
|
|
||||||
static const int linesMarginMax = 64;
|
|
||||||
|
|
||||||
enum Format format = Format::Hex;
|
|
||||||
|
|
||||||
std::unique_ptr<Ui::HexdumpWidget> ui;
|
std::unique_ptr<Ui::HexdumpWidget> ui;
|
||||||
|
|
||||||
bool sent_seek = false;
|
bool sent_seek = false;
|
||||||
bool scroll_disabled = false;
|
|
||||||
|
|
||||||
RVA first_loaded_address = RVA_INVALID;
|
|
||||||
RVA last_loaded_address = RVA_INVALID;
|
|
||||||
|
|
||||||
RefreshDeferrer *refreshDeferrer;
|
RefreshDeferrer *refreshDeferrer;
|
||||||
|
|
||||||
void refresh(RVA addr = RVA_INVALID);
|
void refresh(RVA addr = RVA_INVALID);
|
||||||
void selectHexPreview();
|
void selectHexPreview();
|
||||||
void updateHeaders();
|
|
||||||
|
|
||||||
std::array<QString, 3> fetchHexdump(RVA addr, int lines);
|
|
||||||
|
|
||||||
void connectScroll(bool disconnect_);
|
|
||||||
void setupScrollSync();
|
|
||||||
|
|
||||||
void setupFonts();
|
void setupFonts();
|
||||||
|
|
||||||
// If bottom = false gets the FIRST displayed line, otherwise the LAST displayed
|
void refreshSelectionInfo();
|
||||||
// line.
|
|
||||||
int getDisplayedLined(QTextEdit *textEdit, bool bottom = false);
|
|
||||||
|
|
||||||
static void removeTopLinesWithoutScroll(QTextEdit *textEdit, int lines);
|
|
||||||
static void removeBottomLinesWithoutScroll(QTextEdit *textEdit, int lines);
|
|
||||||
static void prependWithoutScroll(QTextEdit *textEdit, QString text);
|
|
||||||
static void appendWithoutScroll(QTextEdit *textEdit, QString text);
|
|
||||||
static void setTextEditPosition(QTextEdit *textEdit, int position);
|
|
||||||
|
|
||||||
RVA hexPositionToAddress(int position);
|
|
||||||
RVA asciiPositionToAddress(int position);
|
|
||||||
int hexAddressToPosition(RVA address);
|
|
||||||
int asciiAddressToPosition(RVA address);
|
|
||||||
void updateWidths();
|
|
||||||
void syncScale();
|
|
||||||
|
|
||||||
void updateParseWindow(RVA start_address, int size);
|
void updateParseWindow(RVA start_address, int size);
|
||||||
void clearParseWindow();
|
void clearParseWindow();
|
||||||
|
|
||||||
int bufferLines = 0;
|
|
||||||
int cols = 0;
|
|
||||||
ut64 requestedSelectionStartAddress=0;
|
|
||||||
ut64 requestedSelectionEndAddress=0;
|
|
||||||
HexdumpRangeDialog rangeDialog;
|
|
||||||
QAction syncAction;
|
QAction syncAction;
|
||||||
CutterSeekable *seekable;
|
CutterSeekable *seekable;
|
||||||
qreal defaultFontSize;
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onSeekChanged(RVA addr);
|
void onSeekChanged(RVA addr);
|
||||||
|
|
||||||
// Currently unused/untested
|
|
||||||
// void highlightHexCurrentLine();
|
|
||||||
// void highlightHexWords(const QString &str);
|
|
||||||
|
|
||||||
void on_actionHideHexdump_side_panel_triggered();
|
void on_actionHideHexdump_side_panel_triggered();
|
||||||
|
|
||||||
void showHexdumpContextMenu(const QPoint &pt);
|
void selectionChanged(HexTextView::Selection selection);
|
||||||
void showHexASCIIContextMenu(const QPoint &pt);
|
|
||||||
|
|
||||||
void selectionChanged();
|
|
||||||
void scrollChanged();
|
|
||||||
|
|
||||||
void on_parseArchComboBox_currentTextChanged(const QString &arg1);
|
void on_parseArchComboBox_currentTextChanged(const QString &arg1);
|
||||||
void on_parseBitsComboBox_currentTextChanged(const QString &arg1);
|
void on_parseBitsComboBox_currentTextChanged(const QString &arg1);
|
||||||
void on_parseTypeComboBox_currentTextChanged(const QString &arg1);
|
void on_parseTypeComboBox_currentTextChanged(const QString &arg1);
|
||||||
void on_parseEndianComboBox_currentTextChanged(const QString &arg1);
|
void on_parseEndianComboBox_currentTextChanged(const QString &arg1);
|
||||||
|
|
||||||
void on_actionCopyAddressAtCursor_triggered();
|
|
||||||
|
|
||||||
void on_action1column_triggered();
|
|
||||||
void on_action2columns_triggered();
|
|
||||||
void on_action4columns_triggered();
|
|
||||||
void on_action8columns_triggered();
|
|
||||||
void on_action16columns_triggered();
|
|
||||||
void on_action32columns_triggered();
|
|
||||||
void on_action64columns_triggered();
|
|
||||||
|
|
||||||
void on_actionFormatHex_triggered();
|
|
||||||
void on_actionFormatOctal_triggered();
|
|
||||||
|
|
||||||
void on_actionSelect_Block_triggered();
|
|
||||||
|
|
||||||
void fontsUpdated();
|
void fontsUpdated();
|
||||||
void colorsUpdatedSlot();
|
|
||||||
|
|
||||||
void on_hexSideTab_2_currentChanged(int index);
|
void on_hexSideTab_2_currentChanged(int index);
|
||||||
void on_copyMD5_clicked();
|
void on_copyMD5_clicked();
|
||||||
|
@ -32,192 +32,13 @@
|
|||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QScrollArea" name="scrollArea">
|
<widget class="HexTextView" name="hexTextView">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::NoFrame</enum>
|
<enum>QFrame::NoFrame</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="widgetResizable">
|
<property name="widgetResizable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>515</width>
|
|
||||||
<height>770</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,0,0,0,1">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item row="1" column="3">
|
|
||||||
<widget class="Line" name="line_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QLabel" name="hexHeaderLabel">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>0 1 2 3 ...</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QTextEdit" name="hexOffsetText">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="acceptDrops">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="lineWidth">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="verticalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="horizontalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeAdjustPolicy">
|
|
||||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="4">
|
|
||||||
<widget class="QLabel" name="asciiHeaderLabel">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Ignored" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>0123...</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="offsetHeaderLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Offset</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="4">
|
|
||||||
<widget class="QTextEdit" name="hexASCIIText">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<family>Anonymous Pro</family>
|
|
||||||
<pointsize>13</pointsize>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="acceptDrops">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="lineWidth">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="verticalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="horizontalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeAdjustPolicy">
|
|
||||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
|
||||||
</property>
|
|
||||||
<property name="lineWrapMode">
|
|
||||||
<enum>QTextEdit::NoWrap</enum>
|
|
||||||
</property>
|
|
||||||
<property name="cursorWidth">
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="Line" name="line">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="2">
|
|
||||||
<widget class="QTextEdit" name="hexHexText">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="acceptDrops">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="lineWidth">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="verticalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="horizontalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeAdjustPolicy">
|
|
||||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QTabWidget" name="hexSideTab_2">
|
<widget class="QTabWidget" name="hexSideTab_2">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -764,70 +585,6 @@
|
|||||||
<string>Copy Text</string>
|
<string>Copy Text</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionCopyAddressAtCursor">
|
|
||||||
<property name="text">
|
|
||||||
<string>Copy Address</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Copy Address at Cursor</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="action1column">
|
|
||||||
<property name="text">
|
|
||||||
<string>1</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>1</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="action2columns">
|
|
||||||
<property name="text">
|
|
||||||
<string>2</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>2</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="action4columns">
|
|
||||||
<property name="text">
|
|
||||||
<string>4</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>4</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="action8columns">
|
|
||||||
<property name="text">
|
|
||||||
<string>8</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>8</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="action16columns">
|
|
||||||
<property name="text">
|
|
||||||
<string>16</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>16</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="action32columns">
|
|
||||||
<property name="text">
|
|
||||||
<string>32</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>32</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="action64columns">
|
|
||||||
<property name="text">
|
|
||||||
<string>64</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>64</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionHexEdit">
|
<action name="actionHexEdit">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Edit</string>
|
<string>Edit</string>
|
||||||
@ -914,26 +671,15 @@
|
|||||||
<string>4 bytes</string>
|
<string>4 bytes</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionSelect_Block">
|
|
||||||
<property name="text">
|
|
||||||
<string>Select Block...</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionResetZoom">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Reset zoom</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+0</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcutContext">
|
|
||||||
<enum>Qt::WindowShortcut</enum>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
</widget>
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>HexTextView</class>
|
||||||
|
<extends>QScrollArea</extends>
|
||||||
|
<header>HexTextView.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../resources.qrc"/>
|
<include location="../resources.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user