Merge pull request #2466 from Kloen/we-dont-need-this
Removed unused and outdated external qhexeditmaster
commit
291ded52ac
@ -1,21 +0,0 @@
|
|||||||
set(CMAKE_AUTOMOC ON)
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
|
||||||
|
|
||||||
set(SRCS
|
|
||||||
commands.cpp
|
|
||||||
qhexedit.cpp
|
|
||||||
qhexedit_p.cpp
|
|
||||||
xbytearray.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set(HEADERS
|
|
||||||
commands.h
|
|
||||||
qhexedit.h
|
|
||||||
qhexedit_p.h
|
|
||||||
xbytearray.h
|
|
||||||
)
|
|
||||||
|
|
||||||
create_directory_groups(${SRCS} ${HEADERS})
|
|
||||||
|
|
||||||
add_library(qhexedit STATIC ${SRCS} ${HEADERS})
|
|
||||||
target_link_libraries(qhexedit ${CITRA_QT_LIBS})
|
|
@ -1,115 +0,0 @@
|
|||||||
#include "commands.h"
|
|
||||||
|
|
||||||
CharCommand::CharCommand(XByteArray * xData, Cmd cmd, int charPos, char newChar, QUndoCommand *parent)
|
|
||||||
: QUndoCommand(parent)
|
|
||||||
{
|
|
||||||
_xData = xData;
|
|
||||||
_charPos = charPos;
|
|
||||||
_newChar = newChar;
|
|
||||||
_cmd = cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CharCommand::mergeWith(const QUndoCommand *command)
|
|
||||||
{
|
|
||||||
const CharCommand *nextCommand = static_cast<const CharCommand *>(command);
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (_cmd != remove)
|
|
||||||
{
|
|
||||||
if (nextCommand->_cmd == replace)
|
|
||||||
if (nextCommand->_charPos == _charPos)
|
|
||||||
{
|
|
||||||
_newChar = nextCommand->_newChar;
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CharCommand::undo()
|
|
||||||
{
|
|
||||||
switch (_cmd)
|
|
||||||
{
|
|
||||||
case insert:
|
|
||||||
_xData->remove(_charPos, 1);
|
|
||||||
break;
|
|
||||||
case replace:
|
|
||||||
_xData->replace(_charPos, _oldChar);
|
|
||||||
_xData->setDataChanged(_charPos, _wasChanged);
|
|
||||||
break;
|
|
||||||
case remove:
|
|
||||||
_xData->insert(_charPos, _oldChar);
|
|
||||||
_xData->setDataChanged(_charPos, _wasChanged);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CharCommand::redo()
|
|
||||||
{
|
|
||||||
switch (_cmd)
|
|
||||||
{
|
|
||||||
case insert:
|
|
||||||
_xData->insert(_charPos, _newChar);
|
|
||||||
break;
|
|
||||||
case replace:
|
|
||||||
_oldChar = _xData->data()[_charPos];
|
|
||||||
_wasChanged = _xData->dataChanged(_charPos);
|
|
||||||
_xData->replace(_charPos, _newChar);
|
|
||||||
break;
|
|
||||||
case remove:
|
|
||||||
_oldChar = _xData->data()[_charPos];
|
|
||||||
_wasChanged = _xData->dataChanged(_charPos);
|
|
||||||
_xData->remove(_charPos, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ArrayCommand::ArrayCommand(XByteArray * xData, Cmd cmd, int baPos, QByteArray newBa, int len, QUndoCommand *parent)
|
|
||||||
: QUndoCommand(parent)
|
|
||||||
{
|
|
||||||
_cmd = cmd;
|
|
||||||
_xData = xData;
|
|
||||||
_baPos = baPos;
|
|
||||||
_newBa = newBa;
|
|
||||||
_len = len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayCommand::undo()
|
|
||||||
{
|
|
||||||
switch (_cmd)
|
|
||||||
{
|
|
||||||
case insert:
|
|
||||||
_xData->remove(_baPos, _newBa.length());
|
|
||||||
break;
|
|
||||||
case replace:
|
|
||||||
_xData->replace(_baPos, _oldBa);
|
|
||||||
_xData->setDataChanged(_baPos, _wasChanged);
|
|
||||||
break;
|
|
||||||
case remove:
|
|
||||||
_xData->insert(_baPos, _oldBa);
|
|
||||||
_xData->setDataChanged(_baPos, _wasChanged);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArrayCommand::redo()
|
|
||||||
{
|
|
||||||
switch (_cmd)
|
|
||||||
{
|
|
||||||
case insert:
|
|
||||||
_xData->insert(_baPos, _newBa);
|
|
||||||
break;
|
|
||||||
case replace:
|
|
||||||
_oldBa = _xData->data().mid(_baPos, _len);
|
|
||||||
_wasChanged = _xData->dataChanged(_baPos, _len);
|
|
||||||
_xData->replace(_baPos, _newBa);
|
|
||||||
break;
|
|
||||||
case remove:
|
|
||||||
_oldBa = _xData->data().mid(_baPos, _len);
|
|
||||||
_wasChanged = _xData->dataChanged(_baPos, _len);
|
|
||||||
_xData->remove(_baPos, _len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
#ifndef COMMANDS_H
|
|
||||||
#define COMMANDS_H
|
|
||||||
|
|
||||||
/** \cond docNever */
|
|
||||||
|
|
||||||
#include <QUndoCommand>
|
|
||||||
|
|
||||||
#include "xbytearray.h"
|
|
||||||
|
|
||||||
/*! CharCommand is a class to prived undo/redo functionality in QHexEdit.
|
|
||||||
A QUndoCommand represents a single editing action on a document. CharCommand
|
|
||||||
is responsable for manipulations on single chars. It can insert. replace and
|
|
||||||
remove characters. A manipulation stores allways to actions
|
|
||||||
1. redo (or do) action
|
|
||||||
2. undo action.
|
|
||||||
|
|
||||||
CharCommand also supports command compression via mergeWidht(). This allows
|
|
||||||
the user to execute a undo command contation e.g. 3 steps in a single command.
|
|
||||||
If you for example insert a new byt "34" this means for the editor doing 3
|
|
||||||
steps: insert a "00", replace it with "03" and the replace it with "34". These
|
|
||||||
3 steps are combined into a single step, insert a "34".
|
|
||||||
*/
|
|
||||||
class CharCommand : public QUndoCommand
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum { Id = 1234 };
|
|
||||||
enum Cmd {insert, remove, replace};
|
|
||||||
|
|
||||||
CharCommand(XByteArray * xData, Cmd cmd, int charPos, char newChar,
|
|
||||||
QUndoCommand *parent=0);
|
|
||||||
|
|
||||||
void undo();
|
|
||||||
void redo();
|
|
||||||
bool mergeWith(const QUndoCommand *command);
|
|
||||||
int id() const { return Id; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
XByteArray * _xData;
|
|
||||||
int _charPos;
|
|
||||||
bool _wasChanged;
|
|
||||||
char _newChar;
|
|
||||||
char _oldChar;
|
|
||||||
Cmd _cmd;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! ArrayCommand provides undo/redo functionality for handling binary strings. It
|
|
||||||
can undo/redo insert, replace and remove binary strins (QByteArrays).
|
|
||||||
*/
|
|
||||||
class ArrayCommand : public QUndoCommand
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum Cmd {insert, remove, replace};
|
|
||||||
ArrayCommand(XByteArray * xData, Cmd cmd, int baPos, QByteArray newBa=QByteArray(), int len=0,
|
|
||||||
QUndoCommand *parent=0);
|
|
||||||
void undo();
|
|
||||||
void redo();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Cmd _cmd;
|
|
||||||
XByteArray * _xData;
|
|
||||||
int _baPos;
|
|
||||||
int _len;
|
|
||||||
QByteArray _wasChanged;
|
|
||||||
QByteArray _newBa;
|
|
||||||
QByteArray _oldBa;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \endcond docNever */
|
|
||||||
|
|
||||||
#endif // COMMANDS_H
|
|
@ -1,180 +0,0 @@
|
|||||||
#include <QtGui>
|
|
||||||
|
|
||||||
#include "qhexedit.h"
|
|
||||||
|
|
||||||
|
|
||||||
QHexEdit::QHexEdit(QWidget *parent) : QScrollArea(parent)
|
|
||||||
{
|
|
||||||
qHexEdit_p = new QHexEditPrivate(this);
|
|
||||||
setWidget(qHexEdit_p);
|
|
||||||
setWidgetResizable(true);
|
|
||||||
|
|
||||||
connect(qHexEdit_p, SIGNAL(currentAddressChanged(int)), this, SIGNAL(currentAddressChanged(int)));
|
|
||||||
connect(qHexEdit_p, SIGNAL(currentSizeChanged(int)), this, SIGNAL(currentSizeChanged(int)));
|
|
||||||
connect(qHexEdit_p, SIGNAL(dataChanged()), this, SIGNAL(dataChanged()));
|
|
||||||
connect(qHexEdit_p, SIGNAL(overwriteModeChanged(bool)), this, SIGNAL(overwriteModeChanged(bool)));
|
|
||||||
setFocusPolicy(Qt::NoFocus);
|
|
||||||
}
|
|
||||||
|
|
||||||
int QHexEdit::indexOf(const QByteArray & ba, int from) const
|
|
||||||
{
|
|
||||||
return qHexEdit_p->indexOf(ba, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::insert(int i, const QByteArray & ba)
|
|
||||||
{
|
|
||||||
qHexEdit_p->insert(i, ba);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::insert(int i, char ch)
|
|
||||||
{
|
|
||||||
qHexEdit_p->insert(i, ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
int QHexEdit::lastIndexOf(const QByteArray & ba, int from) const
|
|
||||||
{
|
|
||||||
return qHexEdit_p->lastIndexOf(ba, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::remove(int pos, int len)
|
|
||||||
{
|
|
||||||
qHexEdit_p->remove(pos, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::replace( int pos, int len, const QByteArray & after)
|
|
||||||
{
|
|
||||||
qHexEdit_p->replace(pos, len, after);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QHexEdit::toReadableString()
|
|
||||||
{
|
|
||||||
return qHexEdit_p->toRedableString();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QHexEdit::selectionToReadableString()
|
|
||||||
{
|
|
||||||
return qHexEdit_p->selectionToReadableString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::setAddressArea(bool addressArea)
|
|
||||||
{
|
|
||||||
qHexEdit_p->setAddressArea(addressArea);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::redo()
|
|
||||||
{
|
|
||||||
qHexEdit_p->redo();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::undo()
|
|
||||||
{
|
|
||||||
qHexEdit_p->undo();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::setAddressWidth(int addressWidth)
|
|
||||||
{
|
|
||||||
qHexEdit_p->setAddressWidth(addressWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::setAsciiArea(bool asciiArea)
|
|
||||||
{
|
|
||||||
qHexEdit_p->setAsciiArea(asciiArea);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::setHighlighting(bool mode)
|
|
||||||
{
|
|
||||||
qHexEdit_p->setHighlighting(mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::setAddressOffset(int offset)
|
|
||||||
{
|
|
||||||
qHexEdit_p->setAddressOffset(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
int QHexEdit::addressOffset()
|
|
||||||
{
|
|
||||||
return qHexEdit_p->addressOffset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::setCursorPosition(int cursorPos)
|
|
||||||
{
|
|
||||||
// cursorPos in QHexEditPrivate is the position of the textcoursor without
|
|
||||||
// blanks, means bytePos*2
|
|
||||||
qHexEdit_p->setCursorPos(cursorPos*2);
|
|
||||||
}
|
|
||||||
|
|
||||||
int QHexEdit::cursorPosition()
|
|
||||||
{
|
|
||||||
return qHexEdit_p->cursorPos() / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QHexEdit::setData(const QByteArray &data)
|
|
||||||
{
|
|
||||||
qHexEdit_p->setData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray QHexEdit::data()
|
|
||||||
{
|
|
||||||
return qHexEdit_p->data();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::setAddressAreaColor(const QColor &color)
|
|
||||||
{
|
|
||||||
qHexEdit_p->setAddressAreaColor(color);
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor QHexEdit::addressAreaColor()
|
|
||||||
{
|
|
||||||
return qHexEdit_p->addressAreaColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::setHighlightingColor(const QColor &color)
|
|
||||||
{
|
|
||||||
qHexEdit_p->setHighlightingColor(color);
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor QHexEdit::highlightingColor()
|
|
||||||
{
|
|
||||||
return qHexEdit_p->highlightingColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::setSelectionColor(const QColor &color)
|
|
||||||
{
|
|
||||||
qHexEdit_p->setSelectionColor(color);
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor QHexEdit::selectionColor()
|
|
||||||
{
|
|
||||||
return qHexEdit_p->selectionColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::setOverwriteMode(bool overwriteMode)
|
|
||||||
{
|
|
||||||
qHexEdit_p->setOverwriteMode(overwriteMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QHexEdit::overwriteMode()
|
|
||||||
{
|
|
||||||
return qHexEdit_p->overwriteMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::setReadOnly(bool readOnly)
|
|
||||||
{
|
|
||||||
qHexEdit_p->setReadOnly(readOnly);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QHexEdit::isReadOnly()
|
|
||||||
{
|
|
||||||
return qHexEdit_p->isReadOnly();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEdit::setFont(const QFont &font)
|
|
||||||
{
|
|
||||||
qHexEdit_p->setFont(font);
|
|
||||||
}
|
|
||||||
|
|
||||||
const QFont & QHexEdit::font() const
|
|
||||||
{
|
|
||||||
return qHexEdit_p->font();
|
|
||||||
}
|
|
@ -1,240 +0,0 @@
|
|||||||
// Original author: Winfried Simon
|
|
||||||
// See http://code.google.com/p/qhexedit2/
|
|
||||||
// Huge thanks!
|
|
||||||
|
|
||||||
#ifndef QHEXEDIT_H
|
|
||||||
#define QHEXEDIT_H
|
|
||||||
|
|
||||||
#include <QtGui>
|
|
||||||
#include "qhexedit_p.h"
|
|
||||||
|
|
||||||
/** \mainpage
|
|
||||||
QHexEdit is a binary editor widget for Qt.
|
|
||||||
|
|
||||||
\version Version 0.6.3
|
|
||||||
\image html hexedit.png
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*! QHexEdit is a hex editor widget written in C++ for the Qt (Qt4) framework.
|
|
||||||
It is a simple editor for binary data, just like QPlainTextEdit is for text
|
|
||||||
data. There are sip configuration files included, so it is easy to create
|
|
||||||
bindings for PyQt and you can use this widget also in python.
|
|
||||||
|
|
||||||
QHexEdit takes the data of a QByteArray (setData()) and shows it. You can use
|
|
||||||
the mouse or the keyboard to navigate inside the widget. If you hit the keys
|
|
||||||
(0..9, a..f) you will change the data. Changed data is highlighted and can be
|
|
||||||
accessed via data().
|
|
||||||
|
|
||||||
Normaly QHexEdit works in the overwrite Mode. You can set overwriteMode(false)
|
|
||||||
and insert data. In this case the size of data() increases. It is also possible
|
|
||||||
to delete bytes (del or backspace), here the size of data decreases.
|
|
||||||
|
|
||||||
You can select data with keyboard hits or mouse movements. The copy-key will
|
|
||||||
copy the selected data into the clipboard. The cut-key copies also but delets
|
|
||||||
it afterwards. In overwrite mode, the paste function overwrites the content of
|
|
||||||
the (does not change the length) data. In insert mode, clipboard data will be
|
|
||||||
inserted. The clipboard content is expected in ASCII Hex notation. Unknown
|
|
||||||
characters will be ignored.
|
|
||||||
|
|
||||||
QHexEdit comes with undo/redo functionality. All changes can be undone, by
|
|
||||||
pressing the undo-key (usually ctr-z). They can also be redone afterwards.
|
|
||||||
The undo/redo framework is cleared, when setData() sets up a new
|
|
||||||
content for the editor. You can search data inside the content with indexOf()
|
|
||||||
and lastIndexOf(). The replace() function is to change located subdata. This
|
|
||||||
'replaced' data can also be undone by the undo/redo framework.
|
|
||||||
|
|
||||||
This widget can only handle small amounts of data. The size has to be below 10
|
|
||||||
megabytes, otherwise the scroll sliders ard not shown and you can't scroll any
|
|
||||||
more.
|
|
||||||
*/
|
|
||||||
class QHexEdit : public QScrollArea
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
/*! Property data holds the content of QHexEdit. Call setData() to set the
|
|
||||||
content of QHexEdit, data() returns the actual content.
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(QByteArray data READ data WRITE setData)
|
|
||||||
|
|
||||||
/*! Property addressOffset is added to the Numbers of the Address Area.
|
|
||||||
A offset in the address area (left side) is sometimes usefull, whe you show
|
|
||||||
only a segment of a complete memory picture. With setAddressOffset() you set
|
|
||||||
this property - with addressOffset() you get the actual value.
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(int addressOffset READ addressOffset WRITE setAddressOffset)
|
|
||||||
|
|
||||||
/*! Property address area color sets (setAddressAreaColor()) the backgorund
|
|
||||||
color of address areas. You can also read the color (addressaAreaColor()).
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(QColor addressAreaColor READ addressAreaColor WRITE setAddressAreaColor)
|
|
||||||
|
|
||||||
/*! Porperty cursorPosition sets or gets the position of the editor cursor
|
|
||||||
in QHexEdit.
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition)
|
|
||||||
|
|
||||||
/*! Property highlighting color sets (setHighlightingColor()) the backgorund
|
|
||||||
color of highlighted text areas. You can also read the color
|
|
||||||
(highlightingColor()).
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(QColor highlightingColor READ highlightingColor WRITE setHighlightingColor)
|
|
||||||
|
|
||||||
/*! Property selection color sets (setSelectionColor()) the backgorund
|
|
||||||
color of selected text areas. You can also read the color
|
|
||||||
(selectionColor()).
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(QColor selectionColor READ selectionColor WRITE setSelectionColor)
|
|
||||||
|
|
||||||
/*! Porperty overwrite mode sets (setOverwriteMode()) or gets (overwriteMode()) the mode
|
|
||||||
in which the editor works. In overwrite mode the user will overwrite existing data. The
|
|
||||||
size of data will be constant. In insert mode the size will grow, when inserting
|
|
||||||
new data.
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode)
|
|
||||||
|
|
||||||
/*! Porperty readOnly sets (setReadOnly()) or gets (isReadOnly) the mode
|
|
||||||
in which the editor works. In readonly mode the the user can only navigate
|
|
||||||
through the data and select data; modifying is not possible. This
|
|
||||||
property's default is false.
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
|
|
||||||
|
|
||||||
/*! Set the font of the widget. Please use fixed width fonts like Mono or Courier.*/
|
|
||||||
Q_PROPERTY(QFont font READ font WRITE setFont)
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
/*! Creates an instance of QHexEdit.
|
|
||||||
\param parent Parent widget of QHexEdit.
|
|
||||||
*/
|
|
||||||
QHexEdit(QWidget *parent = 0);
|
|
||||||
|
|
||||||
/*! Returns the index position of the first occurrence
|
|
||||||
of the byte array ba in this byte array, searching forward from index position
|
|
||||||
from. Returns -1 if ba could not be found. In addition to this functionality
|
|
||||||
of QByteArray the cursorposition is set to the end of found bytearray and
|
|
||||||
it will be selected.
|
|
||||||
|
|
||||||
*/
|
|
||||||
int indexOf(const QByteArray & ba, int from = 0) const;
|
|
||||||
|
|
||||||
/*! Inserts a byte array.
|
|
||||||
\param i Index position, where to insert
|
|
||||||
\param ba byte array, which is to insert
|
|
||||||
In overwrite mode, the existing data will be overwritten, in insertmode ba will be
|
|
||||||
inserted and size of data grows.
|
|
||||||
*/
|
|
||||||
void insert(int i, const QByteArray & ba);
|
|
||||||
|
|
||||||
/*! Inserts a char.
|
|
||||||
\param i Index position, where to insert
|
|
||||||
\param ch Char, which is to insert
|
|
||||||
In overwrite mode, the existing data will be overwritten, in insertmode ba will be
|
|
||||||
inserted and size of data grows.
|
|
||||||
*/
|
|
||||||
void insert(int i, char ch);
|
|
||||||
|
|
||||||
/*! Returns the index position of the last occurrence
|
|
||||||
of the byte array ba in this byte array, searching backwards from index position
|
|
||||||
from. Returns -1 if ba could not be found. In addition to this functionality
|
|
||||||
of QByteArray the cursorposition is set to the beginning of found bytearray and
|
|
||||||
it will be selected.
|
|
||||||
|
|
||||||
*/
|
|
||||||
int lastIndexOf(const QByteArray & ba, int from = 0) const;
|
|
||||||
|
|
||||||
/*! Removes len bytes from the content.
|
|
||||||
\param pos Index position, where to remove
|
|
||||||
\param len Amount of bytes to remove
|
|
||||||
In overwrite mode, the existing bytes will be overwriten with 0x00.
|
|
||||||
*/
|
|
||||||
void remove(int pos, int len=1);
|
|
||||||
|
|
||||||
/*! Replaces len bytes from index position pos with the byte array after.
|
|
||||||
*/
|
|
||||||
void replace( int pos, int len, const QByteArray & after);
|
|
||||||
|
|
||||||
/*! Gives back a formatted image of the content of QHexEdit
|
|
||||||
*/
|
|
||||||
QString toReadableString();
|
|
||||||
|
|
||||||
/*! Gives back a formatted image of the selected content of QHexEdit
|
|
||||||
*/
|
|
||||||
QString selectionToReadableString();
|
|
||||||
|
|
||||||
/*! \cond docNever */
|
|
||||||
void setAddressOffset(int offset);
|
|
||||||
int addressOffset();
|
|
||||||
void setCursorPosition(int cusorPos);
|
|
||||||
int cursorPosition();
|
|
||||||
void setData(QByteArray const &data);
|
|
||||||
QByteArray data();
|
|
||||||
void setAddressAreaColor(QColor const &color);
|
|
||||||
QColor addressAreaColor();
|
|
||||||
void setHighlightingColor(QColor const &color);
|
|
||||||
QColor highlightingColor();
|
|
||||||
void setSelectionColor(QColor const &color);
|
|
||||||
QColor selectionColor();
|
|
||||||
void setOverwriteMode(bool);
|
|
||||||
bool overwriteMode();
|
|
||||||
void setReadOnly(bool);
|
|
||||||
bool isReadOnly();
|
|
||||||
const QFont &font() const;
|
|
||||||
void setFont(const QFont &);
|
|
||||||
/*! \endcond docNever */
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
/*! Redoes the last operation. If there is no operation to redo, i.e.
|
|
||||||
there is no redo step in the undo/redo history, nothing happens.
|
|
||||||
*/
|
|
||||||
void redo();
|
|
||||||
|
|
||||||
/*! Set the minimum width of the address area.
|
|
||||||
\param addressWidth Width in characters.
|
|
||||||
*/
|
|
||||||
void setAddressWidth(int addressWidth);
|
|
||||||
|
|
||||||
/*! Switch the address area on or off.
|
|
||||||
\param addressArea true (show it), false (hide it).
|
|
||||||
*/
|
|
||||||
void setAddressArea(bool addressArea);
|
|
||||||
|
|
||||||
/*! Switch the ascii area on or off.
|
|
||||||
\param asciiArea true (show it), false (hide it).
|
|
||||||
*/
|
|
||||||
void setAsciiArea(bool asciiArea);
|
|
||||||
|
|
||||||
/*! Switch the highlighting feature on or of.
|
|
||||||
\param mode true (show it), false (hide it).
|
|
||||||
*/
|
|
||||||
void setHighlighting(bool mode);
|
|
||||||
|
|
||||||
/*! Undoes the last operation. If there is no operation to undo, i.e.
|
|
||||||
there is no undo step in the undo/redo history, nothing happens.
|
|
||||||
*/
|
|
||||||
void undo();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
|
|
||||||
/*! Contains the address, where the cursor is located. */
|
|
||||||
void currentAddressChanged(int address);
|
|
||||||
|
|
||||||
/*! Contains the size of the data to edit. */
|
|
||||||
void currentSizeChanged(int size);
|
|
||||||
|
|
||||||
/*! The signal is emited every time, the data is changed. */
|
|
||||||
void dataChanged();
|
|
||||||
|
|
||||||
/*! The signal is emited every time, the overwrite mode is changed. */
|
|
||||||
void overwriteModeChanged(bool state);
|
|
||||||
|
|
||||||
private:
|
|
||||||
/*! \cond docNever */
|
|
||||||
QHexEditPrivate *qHexEdit_p;
|
|
||||||
QHBoxLayout *layout;
|
|
||||||
QScrollArea *scrollArea;
|
|
||||||
/*! \endcond docNever */
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,857 +0,0 @@
|
|||||||
#include "qhexedit_p.h"
|
|
||||||
#include "commands.h"
|
|
||||||
|
|
||||||
const int HEXCHARS_IN_LINE = 47;
|
|
||||||
const int GAP_ADR_HEX = 10;
|
|
||||||
const int GAP_HEX_ASCII = 16;
|
|
||||||
const int BYTES_PER_LINE = 16;
|
|
||||||
|
|
||||||
QHexEditPrivate::QHexEditPrivate(QScrollArea *parent) : QWidget(parent)
|
|
||||||
{
|
|
||||||
_undoStack = new QUndoStack(this);
|
|
||||||
|
|
||||||
_scrollArea = parent;
|
|
||||||
setAddressWidth(4);
|
|
||||||
setAddressOffset(0);
|
|
||||||
setAddressArea(true);
|
|
||||||
setAsciiArea(true);
|
|
||||||
setHighlighting(true);
|
|
||||||
setOverwriteMode(true);
|
|
||||||
setReadOnly(false);
|
|
||||||
setAddressAreaColor(QColor(0xd4, 0xd4, 0xd4, 0xff));
|
|
||||||
setHighlightingColor(QColor(0xff, 0xff, 0x99, 0xff));
|
|
||||||
setSelectionColor(QColor(0x6d, 0x9e, 0xff, 0xff));
|
|
||||||
setFont(QFont("Courier", 10));
|
|
||||||
|
|
||||||
_size = 0;
|
|
||||||
resetSelection(0);
|
|
||||||
|
|
||||||
setFocusPolicy(Qt::StrongFocus);
|
|
||||||
|
|
||||||
connect(&_cursorTimer, SIGNAL(timeout()), this, SLOT(updateCursor()));
|
|
||||||
_cursorTimer.setInterval(500);
|
|
||||||
_cursorTimer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::setAddressOffset(int offset)
|
|
||||||
{
|
|
||||||
_xData.setAddressOffset(offset);
|
|
||||||
adjust();
|
|
||||||
}
|
|
||||||
|
|
||||||
int QHexEditPrivate::addressOffset()
|
|
||||||
{
|
|
||||||
return _xData.addressOffset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::setData(const QByteArray &data)
|
|
||||||
{
|
|
||||||
_xData.setData(data);
|
|
||||||
_undoStack->clear();
|
|
||||||
adjust();
|
|
||||||
setCursorPos(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray QHexEditPrivate::data()
|
|
||||||
{
|
|
||||||
return _xData.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::setAddressAreaColor(const QColor &color)
|
|
||||||
{
|
|
||||||
_addressAreaColor = color;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor QHexEditPrivate::addressAreaColor()
|
|
||||||
{
|
|
||||||
return _addressAreaColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::setHighlightingColor(const QColor &color)
|
|
||||||
{
|
|
||||||
_highlightingColor = color;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor QHexEditPrivate::highlightingColor()
|
|
||||||
{
|
|
||||||
return _highlightingColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::setSelectionColor(const QColor &color)
|
|
||||||
{
|
|
||||||
_selectionColor = color;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor QHexEditPrivate::selectionColor()
|
|
||||||
{
|
|
||||||
return _selectionColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::setReadOnly(bool readOnly)
|
|
||||||
{
|
|
||||||
_readOnly = readOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QHexEditPrivate::isReadOnly()
|
|
||||||
{
|
|
||||||
return _readOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
XByteArray & QHexEditPrivate::xData()
|
|
||||||
{
|
|
||||||
return _xData;
|
|
||||||
}
|
|
||||||
|
|
||||||
int QHexEditPrivate::indexOf(const QByteArray & ba, int from)
|
|
||||||
{
|
|
||||||
if (from > (_xData.data().length() - 1))
|
|
||||||
from = _xData.data().length() - 1;
|
|
||||||
int idx = _xData.data().indexOf(ba, from);
|
|
||||||
if (idx > -1)
|
|
||||||
{
|
|
||||||
int curPos = idx*2;
|
|
||||||
setCursorPos(curPos + ba.length()*2);
|
|
||||||
resetSelection(curPos);
|
|
||||||
setSelection(curPos + ba.length()*2);
|
|
||||||
ensureVisible();
|
|
||||||
}
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::insert(int index, const QByteArray & ba)
|
|
||||||
{
|
|
||||||
if (ba.length() > 0)
|
|
||||||
{
|
|
||||||
if (_overwriteMode)
|
|
||||||
{
|
|
||||||
QUndoCommand *arrayCommand= new ArrayCommand(&_xData, ArrayCommand::replace, index, ba, ba.length());
|
|
||||||
_undoStack->push(arrayCommand);
|
|
||||||
emit dataChanged();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QUndoCommand *arrayCommand= new ArrayCommand(&_xData, ArrayCommand::insert, index, ba, ba.length());
|
|
||||||
_undoStack->push(arrayCommand);
|
|
||||||
emit dataChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::insert(int index, char ch)
|
|
||||||
{
|
|
||||||
QUndoCommand *charCommand = new CharCommand(&_xData, CharCommand::insert, index, ch);
|
|
||||||
_undoStack->push(charCommand);
|
|
||||||
emit dataChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
int QHexEditPrivate::lastIndexOf(const QByteArray & ba, int from)
|
|
||||||
{
|
|
||||||
from -= ba.length();
|
|
||||||
if (from < 0)
|
|
||||||
from = 0;
|
|
||||||
int idx = _xData.data().lastIndexOf(ba, from);
|
|
||||||
if (idx > -1)
|
|
||||||
{
|
|
||||||
int curPos = idx*2;
|
|
||||||
setCursorPos(curPos);
|
|
||||||
resetSelection(curPos);
|
|
||||||
setSelection(curPos + ba.length()*2);
|
|
||||||
ensureVisible();
|
|
||||||
}
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::remove(int index, int len)
|
|
||||||
{
|
|
||||||
if (len > 0)
|
|
||||||
{
|
|
||||||
if (len == 1)
|
|
||||||
{
|
|
||||||
if (_overwriteMode)
|
|
||||||
{
|
|
||||||
QUndoCommand *charCommand = new CharCommand(&_xData, CharCommand::replace, index, char(0));
|
|
||||||
_undoStack->push(charCommand);
|
|
||||||
emit dataChanged();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QUndoCommand *charCommand = new CharCommand(&_xData, CharCommand::remove, index, char(0));
|
|
||||||
_undoStack->push(charCommand);
|
|
||||||
emit dataChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QByteArray ba = QByteArray(len, char(0));
|
|
||||||
if (_overwriteMode)
|
|
||||||
{
|
|
||||||
QUndoCommand *arrayCommand = new ArrayCommand(&_xData, ArrayCommand::replace, index, ba, ba.length());
|
|
||||||
_undoStack->push(arrayCommand);
|
|
||||||
emit dataChanged();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QUndoCommand *arrayCommand= new ArrayCommand(&_xData, ArrayCommand::remove, index, ba, len);
|
|
||||||
_undoStack->push(arrayCommand);
|
|
||||||
emit dataChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::replace(int index, char ch)
|
|
||||||
{
|
|
||||||
QUndoCommand *charCommand = new CharCommand(&_xData, CharCommand::replace, index, ch);
|
|
||||||
_undoStack->push(charCommand);
|
|
||||||
resetSelection();
|
|
||||||
emit dataChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::replace(int index, const QByteArray & ba)
|
|
||||||
{
|
|
||||||
QUndoCommand *arrayCommand= new ArrayCommand(&_xData, ArrayCommand::replace, index, ba, ba.length());
|
|
||||||
_undoStack->push(arrayCommand);
|
|
||||||
resetSelection();
|
|
||||||
emit dataChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::replace(int pos, int len, const QByteArray &after)
|
|
||||||
{
|
|
||||||
QUndoCommand *arrayCommand= new ArrayCommand(&_xData, ArrayCommand::replace, pos, after, len);
|
|
||||||
_undoStack->push(arrayCommand);
|
|
||||||
resetSelection();
|
|
||||||
emit dataChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::setAddressArea(bool addressArea)
|
|
||||||
{
|
|
||||||
_addressArea = addressArea;
|
|
||||||
adjust();
|
|
||||||
|
|
||||||
setCursorPos(_cursorPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::setAddressWidth(int addressWidth)
|
|
||||||
{
|
|
||||||
_xData.setAddressWidth(addressWidth);
|
|
||||||
|
|
||||||
setCursorPos(_cursorPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::setAsciiArea(bool asciiArea)
|
|
||||||
{
|
|
||||||
_asciiArea = asciiArea;
|
|
||||||
adjust();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::setFont(const QFont &font)
|
|
||||||
{
|
|
||||||
QWidget::setFont(font);
|
|
||||||
adjust();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::setHighlighting(bool mode)
|
|
||||||
{
|
|
||||||
_highlighting = mode;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::setOverwriteMode(bool overwriteMode)
|
|
||||||
{
|
|
||||||
_overwriteMode = overwriteMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QHexEditPrivate::overwriteMode()
|
|
||||||
{
|
|
||||||
return _overwriteMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::redo()
|
|
||||||
{
|
|
||||||
_undoStack->redo();
|
|
||||||
emit dataChanged();
|
|
||||||
setCursorPos(_cursorPosition);
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::undo()
|
|
||||||
{
|
|
||||||
_undoStack->undo();
|
|
||||||
emit dataChanged();
|
|
||||||
setCursorPos(_cursorPosition);
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QHexEditPrivate::toRedableString()
|
|
||||||
{
|
|
||||||
return _xData.toRedableString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QString QHexEditPrivate::selectionToReadableString()
|
|
||||||
{
|
|
||||||
return _xData.toRedableString(getSelectionBegin(), getSelectionEnd());
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::keyPressEvent(QKeyEvent *event)
|
|
||||||
{
|
|
||||||
int charX = (_cursorX - _xPosHex) / _charWidth;
|
|
||||||
int posX = (charX / 3) * 2 + (charX % 3);
|
|
||||||
int posBa = (_cursorY / _charHeight) * BYTES_PER_LINE + posX / 2;
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* Cursor movements */
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
if (event->matches(QKeySequence::MoveToNextChar))
|
|
||||||
{
|
|
||||||
setCursorPos(_cursorPosition + 1);
|
|
||||||
resetSelection(_cursorPosition);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::MoveToPreviousChar))
|
|
||||||
{
|
|
||||||
setCursorPos(_cursorPosition - 1);
|
|
||||||
resetSelection(_cursorPosition);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::MoveToEndOfLine))
|
|
||||||
{
|
|
||||||
setCursorPos(_cursorPosition | (2 * BYTES_PER_LINE -1));
|
|
||||||
resetSelection(_cursorPosition);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::MoveToStartOfLine))
|
|
||||||
{
|
|
||||||
setCursorPos(_cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)));
|
|
||||||
resetSelection(_cursorPosition);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::MoveToPreviousLine))
|
|
||||||
{
|
|
||||||
setCursorPos(_cursorPosition - (2 * BYTES_PER_LINE));
|
|
||||||
resetSelection(_cursorPosition);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::MoveToNextLine))
|
|
||||||
{
|
|
||||||
setCursorPos(_cursorPosition + (2 * BYTES_PER_LINE));
|
|
||||||
resetSelection(_cursorPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event->matches(QKeySequence::MoveToNextPage))
|
|
||||||
{
|
|
||||||
setCursorPos(_cursorPosition + (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE));
|
|
||||||
resetSelection(_cursorPosition);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::MoveToPreviousPage))
|
|
||||||
{
|
|
||||||
setCursorPos(_cursorPosition - (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE));
|
|
||||||
resetSelection(_cursorPosition);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::MoveToEndOfDocument))
|
|
||||||
{
|
|
||||||
setCursorPos(_xData.size() * 2);
|
|
||||||
resetSelection(_cursorPosition);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::MoveToStartOfDocument))
|
|
||||||
{
|
|
||||||
setCursorPos(0);
|
|
||||||
resetSelection(_cursorPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* Select commands */
|
|
||||||
/*****************************************************************************/
|
|
||||||
if (event->matches(QKeySequence::SelectAll))
|
|
||||||
{
|
|
||||||
resetSelection(0);
|
|
||||||
setSelection(2*_xData.size() + 1);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::SelectNextChar))
|
|
||||||
{
|
|
||||||
int pos = _cursorPosition + 1;
|
|
||||||
setCursorPos(pos);
|
|
||||||
setSelection(pos);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::SelectPreviousChar))
|
|
||||||
{
|
|
||||||
int pos = _cursorPosition - 1;
|
|
||||||
setSelection(pos);
|
|
||||||
setCursorPos(pos);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::SelectEndOfLine))
|
|
||||||
{
|
|
||||||
int pos = _cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)) + (2 * BYTES_PER_LINE);
|
|
||||||
setCursorPos(pos);
|
|
||||||
setSelection(pos);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::SelectStartOfLine))
|
|
||||||
{
|
|
||||||
int pos = _cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE));
|
|
||||||
setCursorPos(pos);
|
|
||||||
setSelection(pos);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::SelectPreviousLine))
|
|
||||||
{
|
|
||||||
int pos = _cursorPosition - (2 * BYTES_PER_LINE);
|
|
||||||
setCursorPos(pos);
|
|
||||||
setSelection(pos);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::SelectNextLine))
|
|
||||||
{
|
|
||||||
int pos = _cursorPosition + (2 * BYTES_PER_LINE);
|
|
||||||
setCursorPos(pos);
|
|
||||||
setSelection(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event->matches(QKeySequence::SelectNextPage))
|
|
||||||
{
|
|
||||||
int pos = _cursorPosition + (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE);
|
|
||||||
setCursorPos(pos);
|
|
||||||
setSelection(pos);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::SelectPreviousPage))
|
|
||||||
{
|
|
||||||
int pos = _cursorPosition - (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE);
|
|
||||||
setCursorPos(pos);
|
|
||||||
setSelection(pos);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::SelectEndOfDocument))
|
|
||||||
{
|
|
||||||
int pos = _xData.size() * 2;
|
|
||||||
setCursorPos(pos);
|
|
||||||
setSelection(pos);
|
|
||||||
}
|
|
||||||
if (event->matches(QKeySequence::SelectStartOfDocument))
|
|
||||||
{
|
|
||||||
int pos = 0;
|
|
||||||
setCursorPos(pos);
|
|
||||||
setSelection(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* Edit Commands */
|
|
||||||
/*****************************************************************************/
|
|
||||||
if (!_readOnly)
|
|
||||||
{
|
|
||||||
/* Hex input */
|
|
||||||
int key = int(event->text()[0].toLatin1());
|
|
||||||
if ((key>='0' && key<='9') || (key>='a' && key <= 'f'))
|
|
||||||
{
|
|
||||||
if (getSelectionBegin() != getSelectionEnd())
|
|
||||||
{
|
|
||||||
posBa = getSelectionBegin();
|
|
||||||
remove(posBa, getSelectionEnd() - posBa);
|
|
||||||
setCursorPos(2*posBa);
|
|
||||||
resetSelection(2*posBa);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If insert mode, then insert a byte
|
|
||||||
if (_overwriteMode == false)
|
|
||||||
if ((charX % 3) == 0)
|
|
||||||
{
|
|
||||||
insert(posBa, char(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change content
|
|
||||||
if (_xData.size() > 0)
|
|
||||||
{
|
|
||||||
QByteArray hexValue = _xData.data().mid(posBa, 1).toHex();
|
|
||||||
if ((charX % 3) == 0)
|
|
||||||
hexValue[0] = key;
|
|
||||||
else
|
|
||||||
hexValue[1] = key;
|
|
||||||
|
|
||||||
replace(posBa, QByteArray().fromHex(hexValue)[0]);
|
|
||||||
|
|
||||||
setCursorPos(_cursorPosition + 1);
|
|
||||||
resetSelection(_cursorPosition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cut & Paste */
|
|
||||||
if (event->matches(QKeySequence::Cut))
|
|
||||||
{
|
|
||||||
QString result = QString();
|
|
||||||
for (int idx = getSelectionBegin(); idx < getSelectionEnd(); idx++)
|
|
||||||
{
|
|
||||||
result += _xData.data().mid(idx, 1).toHex() + " ";
|
|
||||||
if ((idx % 16) == 15)
|
|
||||||
result.append("\n");
|
|
||||||
}
|
|
||||||
remove(getSelectionBegin(), getSelectionEnd() - getSelectionBegin());
|
|
||||||
QClipboard *clipboard = QApplication::clipboard();
|
|
||||||
clipboard->setText(result);
|
|
||||||
setCursorPos(getSelectionBegin());
|
|
||||||
resetSelection(getSelectionBegin());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event->matches(QKeySequence::Paste))
|
|
||||||
{
|
|
||||||
QClipboard *clipboard = QApplication::clipboard();
|
|
||||||
QByteArray ba = QByteArray().fromHex(clipboard->text().toLatin1());
|
|
||||||
insert(_cursorPosition / 2, ba);
|
|
||||||
setCursorPos(_cursorPosition + 2 * ba.length());
|
|
||||||
resetSelection(getSelectionBegin());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Delete char */
|
|
||||||
if (event->matches(QKeySequence::Delete))
|
|
||||||
{
|
|
||||||
if (getSelectionBegin() != getSelectionEnd())
|
|
||||||
{
|
|
||||||
posBa = getSelectionBegin();
|
|
||||||
remove(posBa, getSelectionEnd() - posBa);
|
|
||||||
setCursorPos(2*posBa);
|
|
||||||
resetSelection(2*posBa);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_overwriteMode)
|
|
||||||
replace(posBa, char(0));
|
|
||||||
else
|
|
||||||
remove(posBa, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Backspace */
|
|
||||||
if ((event->key() == Qt::Key_Backspace) && (event->modifiers() == Qt::NoModifier))
|
|
||||||
{
|
|
||||||
if (getSelectionBegin() != getSelectionEnd())
|
|
||||||
{
|
|
||||||
posBa = getSelectionBegin();
|
|
||||||
remove(posBa, getSelectionEnd() - posBa);
|
|
||||||
setCursorPos(2*posBa);
|
|
||||||
resetSelection(2*posBa);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (posBa > 0)
|
|
||||||
{
|
|
||||||
if (_overwriteMode)
|
|
||||||
replace(posBa - 1, char(0));
|
|
||||||
else
|
|
||||||
remove(posBa - 1, 1);
|
|
||||||
setCursorPos(_cursorPosition - 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* undo */
|
|
||||||
if (event->matches(QKeySequence::Undo))
|
|
||||||
{
|
|
||||||
undo();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* redo */
|
|
||||||
if (event->matches(QKeySequence::Redo))
|
|
||||||
{
|
|
||||||
redo();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event->matches(QKeySequence::Copy))
|
|
||||||
{
|
|
||||||
QString result = QString();
|
|
||||||
for (int idx = getSelectionBegin(); idx < getSelectionEnd(); idx++)
|
|
||||||
{
|
|
||||||
result += _xData.data().mid(idx, 1).toHex() + " ";
|
|
||||||
if ((idx % 16) == 15)
|
|
||||||
result.append('\n');
|
|
||||||
}
|
|
||||||
QClipboard *clipboard = QApplication::clipboard();
|
|
||||||
clipboard->setText(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Switch between insert/overwrite mode
|
|
||||||
if ((event->key() == Qt::Key_Insert) && (event->modifiers() == Qt::NoModifier))
|
|
||||||
{
|
|
||||||
_overwriteMode = !_overwriteMode;
|
|
||||||
setCursorPos(_cursorPosition);
|
|
||||||
overwriteModeChanged(_overwriteMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
ensureVisible();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::mouseMoveEvent(QMouseEvent * event)
|
|
||||||
{
|
|
||||||
_blink = false;
|
|
||||||
update();
|
|
||||||
int actPos = cursorPos(event->pos());
|
|
||||||
setCursorPos(actPos);
|
|
||||||
setSelection(actPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::mousePressEvent(QMouseEvent * event)
|
|
||||||
{
|
|
||||||
_blink = false;
|
|
||||||
update();
|
|
||||||
int cPos = cursorPos(event->pos());
|
|
||||||
resetSelection(cPos);
|
|
||||||
setCursorPos(cPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::paintEvent(QPaintEvent *event)
|
|
||||||
{
|
|
||||||
QPainter painter(this);
|
|
||||||
|
|
||||||
// draw some patterns if needed
|
|
||||||
painter.fillRect(event->rect(), this->palette().color(QPalette::Base));
|
|
||||||
if (_addressArea)
|
|
||||||
painter.fillRect(QRect(_xPosAdr, event->rect().top(), _xPosHex - GAP_ADR_HEX + 2, height()), _addressAreaColor);
|
|
||||||
if (_asciiArea)
|
|
||||||
{
|
|
||||||
int linePos = _xPosAscii - (GAP_HEX_ASCII / 2);
|
|
||||||
painter.setPen(Qt::gray);
|
|
||||||
painter.drawLine(linePos, event->rect().top(), linePos, height());
|
|
||||||
}
|
|
||||||
|
|
||||||
painter.setPen(this->palette().color(QPalette::WindowText));
|
|
||||||
|
|
||||||
// calc position
|
|
||||||
int firstLineIdx = ((event->rect().top()/ _charHeight) - _charHeight) * BYTES_PER_LINE;
|
|
||||||
if (firstLineIdx < 0)
|
|
||||||
firstLineIdx = 0;
|
|
||||||
int lastLineIdx = ((event->rect().bottom() / _charHeight) + _charHeight) * BYTES_PER_LINE;
|
|
||||||
if (lastLineIdx > _xData.size())
|
|
||||||
lastLineIdx = _xData.size();
|
|
||||||
int yPosStart = ((firstLineIdx) / BYTES_PER_LINE) * _charHeight + _charHeight;
|
|
||||||
|
|
||||||
// paint address area
|
|
||||||
if (_addressArea)
|
|
||||||
{
|
|
||||||
for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight)
|
|
||||||
{
|
|
||||||
QString address = QString("%1")
|
|
||||||
.arg(lineIdx + _xData.addressOffset(), _xData.realAddressNumbers(), 16, QChar('0'));
|
|
||||||
painter.drawText(_xPosAdr, yPos, address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// paint hex area
|
|
||||||
QByteArray hexBa(_xData.data().mid(firstLineIdx, lastLineIdx - firstLineIdx + 1).toHex());
|
|
||||||
QBrush highLighted = QBrush(_highlightingColor);
|
|
||||||
QPen colHighlighted = QPen(this->palette().color(QPalette::WindowText));
|
|
||||||
QBrush selected = QBrush(_selectionColor);
|
|
||||||
QPen colSelected = QPen(Qt::white);
|
|
||||||
QPen colStandard = QPen(this->palette().color(QPalette::WindowText));
|
|
||||||
|
|
||||||
painter.setBackgroundMode(Qt::TransparentMode);
|
|
||||||
|
|
||||||
for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight)
|
|
||||||
{
|
|
||||||
QByteArray hex;
|
|
||||||
int xPos = _xPosHex;
|
|
||||||
for (int colIdx = 0; ((lineIdx + colIdx) < _xData.size() && (colIdx < BYTES_PER_LINE)); colIdx++)
|
|
||||||
{
|
|
||||||
int posBa = lineIdx + colIdx;
|
|
||||||
if ((getSelectionBegin() <= posBa) && (getSelectionEnd() > posBa))
|
|
||||||
{
|
|
||||||
painter.setBackground(selected);
|
|
||||||
painter.setBackgroundMode(Qt::OpaqueMode);
|
|
||||||
painter.setPen(colSelected);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_highlighting)
|
|
||||||
{
|
|
||||||
// hilight diff bytes
|
|
||||||
painter.setBackground(highLighted);
|
|
||||||
if (_xData.dataChanged(posBa))
|
|
||||||
{
|
|
||||||
painter.setPen(colHighlighted);
|
|
||||||
painter.setBackgroundMode(Qt::OpaqueMode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
painter.setPen(colStandard);
|
|
||||||
painter.setBackgroundMode(Qt::TransparentMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// render hex value
|
|
||||||
if (colIdx == 0)
|
|
||||||
{
|
|
||||||
hex = hexBa.mid((lineIdx - firstLineIdx) * 2, 2);
|
|
||||||
painter.drawText(xPos, yPos, hex);
|
|
||||||
xPos += 2 * _charWidth;
|
|
||||||
} else {
|
|
||||||
hex = hexBa.mid((lineIdx + colIdx - firstLineIdx) * 2, 2).prepend(" ");
|
|
||||||
painter.drawText(xPos, yPos, hex);
|
|
||||||
xPos += 3 * _charWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
painter.setBackgroundMode(Qt::TransparentMode);
|
|
||||||
painter.setPen(this->palette().color(QPalette::WindowText));
|
|
||||||
|
|
||||||
// paint ascii area
|
|
||||||
if (_asciiArea)
|
|
||||||
{
|
|
||||||
for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight)
|
|
||||||
{
|
|
||||||
int xPosAscii = _xPosAscii;
|
|
||||||
for (int colIdx = 0; ((lineIdx + colIdx) < _xData.size() && (colIdx < BYTES_PER_LINE)); colIdx++)
|
|
||||||
{
|
|
||||||
painter.drawText(xPosAscii, yPos, _xData.asciiChar(lineIdx + colIdx));
|
|
||||||
xPosAscii += _charWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// paint cursor
|
|
||||||
if (_blink && !_readOnly && hasFocus())
|
|
||||||
{
|
|
||||||
if (_overwriteMode)
|
|
||||||
painter.fillRect(_cursorX, _cursorY + _charHeight - 2, _charWidth, 2, this->palette().color(QPalette::WindowText));
|
|
||||||
else
|
|
||||||
painter.fillRect(_cursorX, _cursorY, 2, _charHeight, this->palette().color(QPalette::WindowText));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_size != _xData.size())
|
|
||||||
{
|
|
||||||
_size = _xData.size();
|
|
||||||
emit currentSizeChanged(_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::setCursorPos(int position)
|
|
||||||
{
|
|
||||||
// delete cursor
|
|
||||||
_blink = false;
|
|
||||||
update();
|
|
||||||
|
|
||||||
// cursor in range?
|
|
||||||
if (_overwriteMode)
|
|
||||||
{
|
|
||||||
if (position > (_xData.size() * 2 - 1))
|
|
||||||
position = _xData.size() * 2 - 1;
|
|
||||||
} else {
|
|
||||||
if (position > (_xData.size() * 2))
|
|
||||||
position = _xData.size() * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (position < 0)
|
|
||||||
position = 0;
|
|
||||||
|
|
||||||
// calc position
|
|
||||||
_cursorPosition = position;
|
|
||||||
_cursorY = (position / (2 * BYTES_PER_LINE)) * _charHeight + 4;
|
|
||||||
int x = (position % (2 * BYTES_PER_LINE));
|
|
||||||
_cursorX = (((x / 2) * 3) + (x % 2)) * _charWidth + _xPosHex;
|
|
||||||
|
|
||||||
// immiadately draw cursor
|
|
||||||
_blink = true;
|
|
||||||
update();
|
|
||||||
emit currentAddressChanged(_cursorPosition/2);
|
|
||||||
}
|
|
||||||
|
|
||||||
int QHexEditPrivate::cursorPos(QPoint pos)
|
|
||||||
{
|
|
||||||
int result = -1;
|
|
||||||
// find char under cursor
|
|
||||||
if ((pos.x() >= _xPosHex) && (pos.x() < (_xPosHex + HEXCHARS_IN_LINE * _charWidth)))
|
|
||||||
{
|
|
||||||
int x = (pos.x() - _xPosHex) / _charWidth;
|
|
||||||
if ((x % 3) == 0)
|
|
||||||
x = (x / 3) * 2;
|
|
||||||
else
|
|
||||||
x = ((x / 3) * 2) + 1;
|
|
||||||
int y = ((pos.y() - 3) / _charHeight) * 2 * BYTES_PER_LINE;
|
|
||||||
result = x + y;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int QHexEditPrivate::cursorPos()
|
|
||||||
{
|
|
||||||
return _cursorPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::resetSelection()
|
|
||||||
{
|
|
||||||
_selectionBegin = _selectionInit;
|
|
||||||
_selectionEnd = _selectionInit;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::resetSelection(int pos)
|
|
||||||
{
|
|
||||||
if (pos < 0)
|
|
||||||
pos = 0;
|
|
||||||
pos = pos / 2;
|
|
||||||
_selectionInit = pos;
|
|
||||||
_selectionBegin = pos;
|
|
||||||
_selectionEnd = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::setSelection(int pos)
|
|
||||||
{
|
|
||||||
if (pos < 0)
|
|
||||||
pos = 0;
|
|
||||||
pos = pos / 2;
|
|
||||||
if (pos >= _selectionInit)
|
|
||||||
{
|
|
||||||
_selectionEnd = pos;
|
|
||||||
_selectionBegin = _selectionInit;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_selectionBegin = pos;
|
|
||||||
_selectionEnd = _selectionInit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int QHexEditPrivate::getSelectionBegin()
|
|
||||||
{
|
|
||||||
return _selectionBegin;
|
|
||||||
}
|
|
||||||
|
|
||||||
int QHexEditPrivate::getSelectionEnd()
|
|
||||||
{
|
|
||||||
return _selectionEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QHexEditPrivate::updateCursor()
|
|
||||||
{
|
|
||||||
if (_blink)
|
|
||||||
_blink = false;
|
|
||||||
else
|
|
||||||
_blink = true;
|
|
||||||
update(_cursorX, _cursorY, _charWidth, _charHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::adjust()
|
|
||||||
{
|
|
||||||
_charWidth = fontMetrics().width(QLatin1Char('9'));
|
|
||||||
_charHeight = fontMetrics().height();
|
|
||||||
|
|
||||||
_xPosAdr = 0;
|
|
||||||
if (_addressArea)
|
|
||||||
_xPosHex = _xData.realAddressNumbers()*_charWidth + GAP_ADR_HEX;
|
|
||||||
else
|
|
||||||
_xPosHex = 0;
|
|
||||||
_xPosAscii = _xPosHex + HEXCHARS_IN_LINE * _charWidth + GAP_HEX_ASCII;
|
|
||||||
|
|
||||||
// tell QAbstractScollbar, how big we are
|
|
||||||
setMinimumHeight(((_xData.size()/16 + 1) * _charHeight) + 5);
|
|
||||||
if(_asciiArea)
|
|
||||||
setMinimumWidth(_xPosAscii + (BYTES_PER_LINE * _charWidth));
|
|
||||||
else
|
|
||||||
setMinimumWidth(_xPosHex + HEXCHARS_IN_LINE * _charWidth);
|
|
||||||
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexEditPrivate::ensureVisible()
|
|
||||||
{
|
|
||||||
// scrolls to cursorx, cusory (which are set by setCursorPos)
|
|
||||||
// x-margin is 3 pixels, y-margin is half of charHeight
|
|
||||||
_scrollArea->ensureVisible(_cursorX, _cursorY + _charHeight/2, 3, _charHeight/2 + 2);
|
|
||||||
}
|
|
@ -1,128 +0,0 @@
|
|||||||
#ifndef QHEXEDIT_P_H
|
|
||||||
#define QHEXEDIT_P_H
|
|
||||||
|
|
||||||
/** \cond docNever */
|
|
||||||
|
|
||||||
|
|
||||||
#include <QtGui>
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
|
||||||
#include <QtWidgets>
|
|
||||||
#endif
|
|
||||||
#include "xbytearray.h"
|
|
||||||
|
|
||||||
class QHexEditPrivate : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
QHexEditPrivate(QScrollArea *parent);
|
|
||||||
|
|
||||||
void setAddressAreaColor(QColor const &color);
|
|
||||||
QColor addressAreaColor();
|
|
||||||
|
|
||||||
void setAddressOffset(int offset);
|
|
||||||
int addressOffset();
|
|
||||||
|
|
||||||
void setCursorPos(int position);
|
|
||||||
int cursorPos();
|
|
||||||
|
|
||||||
void setData(QByteArray const &data);
|
|
||||||
QByteArray data();
|
|
||||||
|
|
||||||
void setHighlightingColor(QColor const &color);
|
|
||||||
QColor highlightingColor();
|
|
||||||
|
|
||||||
void setOverwriteMode(bool overwriteMode);
|
|
||||||
bool overwriteMode();
|
|
||||||
|
|
||||||
void setReadOnly(bool readOnly);
|
|
||||||
bool isReadOnly();
|
|
||||||
|
|
||||||
void setSelectionColor(QColor const &color);
|
|
||||||
QColor selectionColor();
|
|
||||||
|
|
||||||
XByteArray & xData();
|
|
||||||
|
|
||||||
int indexOf(const QByteArray & ba, int from = 0);
|
|
||||||
void insert(int index, const QByteArray & ba);
|
|
||||||
void insert(int index, char ch);
|
|
||||||
int lastIndexOf(const QByteArray & ba, int from = 0);
|
|
||||||
void remove(int index, int len=1);
|
|
||||||
void replace(int index, char ch);
|
|
||||||
void replace(int index, const QByteArray & ba);
|
|
||||||
void replace(int pos, int len, const QByteArray & after);
|
|
||||||
|
|
||||||
void setAddressArea(bool addressArea);
|
|
||||||
void setAddressWidth(int addressWidth);
|
|
||||||
void setAsciiArea(bool asciiArea);
|
|
||||||
void setHighlighting(bool mode);
|
|
||||||
virtual void setFont(const QFont &font);
|
|
||||||
|
|
||||||
void undo();
|
|
||||||
void redo();
|
|
||||||
|
|
||||||
QString toRedableString();
|
|
||||||
QString selectionToReadableString();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void currentAddressChanged(int address);
|
|
||||||
void currentSizeChanged(int size);
|
|
||||||
void dataChanged();
|
|
||||||
void overwriteModeChanged(bool state);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void keyPressEvent(QKeyEvent * event);
|
|
||||||
void mouseMoveEvent(QMouseEvent * event);
|
|
||||||
void mousePressEvent(QMouseEvent * event);
|
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *event);
|
|
||||||
|
|
||||||
int cursorPos(QPoint pos); // calc cursorpos from graphics position. DOES NOT STORE POSITION
|
|
||||||
|
|
||||||
void resetSelection(int pos); // set selectionStart and selectionEnd to pos
|
|
||||||
void resetSelection(); // set selectionEnd to selectionStart
|
|
||||||
void setSelection(int pos); // set min (if below init) or max (if greater init)
|
|
||||||
int getSelectionBegin();
|
|
||||||
int getSelectionEnd();
|
|
||||||
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void updateCursor();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void adjust();
|
|
||||||
void ensureVisible();
|
|
||||||
|
|
||||||
QColor _addressAreaColor;
|
|
||||||
QColor _highlightingColor;
|
|
||||||
QColor _selectionColor;
|
|
||||||
QScrollArea *_scrollArea;
|
|
||||||
QTimer _cursorTimer;
|
|
||||||
QUndoStack *_undoStack;
|
|
||||||
|
|
||||||
XByteArray _xData; // Hält den Inhalt des Hex Editors
|
|
||||||
|
|
||||||
bool _blink; // true: then cursor blinks
|
|
||||||
bool _renderingRequired; // Flag to store that rendering is necessary
|
|
||||||
bool _addressArea; // left area of QHexEdit
|
|
||||||
bool _asciiArea; // medium area
|
|
||||||
bool _highlighting; // highlighting of changed bytes
|
|
||||||
bool _overwriteMode;
|
|
||||||
bool _readOnly; // true: the user can only look and navigate
|
|
||||||
|
|
||||||
int _charWidth, _charHeight; // char dimensions (dpendend on font)
|
|
||||||
int _cursorX, _cursorY; // graphics position of the cursor
|
|
||||||
int _cursorPosition; // character positioin in stream (on byte ends in to steps)
|
|
||||||
int _xPosAdr, _xPosHex, _xPosAscii; // graphics x-position of the areas
|
|
||||||
|
|
||||||
int _selectionBegin; // First selected char
|
|
||||||
int _selectionEnd; // Last selected char
|
|
||||||
int _selectionInit; // That's, where we pressed the mouse button
|
|
||||||
|
|
||||||
int _size;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \endcond docNever */
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,167 +0,0 @@
|
|||||||
#include "xbytearray.h"
|
|
||||||
|
|
||||||
XByteArray::XByteArray()
|
|
||||||
{
|
|
||||||
_oldSize = -99;
|
|
||||||
_addressNumbers = 4;
|
|
||||||
_addressOffset = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int XByteArray::addressOffset()
|
|
||||||
{
|
|
||||||
return _addressOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void XByteArray::setAddressOffset(int offset)
|
|
||||||
{
|
|
||||||
_addressOffset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
int XByteArray::addressWidth()
|
|
||||||
{
|
|
||||||
return _addressNumbers;
|
|
||||||
}
|
|
||||||
|
|
||||||
void XByteArray::setAddressWidth(int width)
|
|
||||||
{
|
|
||||||
if ((width >= 0) && (width<=6))
|
|
||||||
{
|
|
||||||
_addressNumbers = width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray & XByteArray::data()
|
|
||||||
{
|
|
||||||
return _data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void XByteArray::setData(QByteArray data)
|
|
||||||
{
|
|
||||||
_data = data;
|
|
||||||
_changedData = QByteArray(data.length(), char(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool XByteArray::dataChanged(int i)
|
|
||||||
{
|
|
||||||
return bool(_changedData[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray XByteArray::dataChanged(int i, int len)
|
|
||||||
{
|
|
||||||
return _changedData.mid(i, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XByteArray::setDataChanged(int i, bool state)
|
|
||||||
{
|
|
||||||
_changedData[i] = char(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XByteArray::setDataChanged(int i, const QByteArray & state)
|
|
||||||
{
|
|
||||||
int length = state.length();
|
|
||||||
int len;
|
|
||||||
if ((i + length) > _changedData.length())
|
|
||||||
len = _changedData.length() - i;
|
|
||||||
else
|
|
||||||
len = length;
|
|
||||||
_changedData.replace(i, len, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
int XByteArray::realAddressNumbers()
|
|
||||||
{
|
|
||||||
if (_oldSize != _data.size())
|
|
||||||
{
|
|
||||||
// is addressNumbers wide enought?
|
|
||||||
QString test = QString("%1")
|
|
||||||
.arg(_data.size() + _addressOffset, _addressNumbers, 16, QChar('0'));
|
|
||||||
_realAddressNumbers = test.size();
|
|
||||||
}
|
|
||||||
return _realAddressNumbers;
|
|
||||||
}
|
|
||||||
|
|
||||||
int XByteArray::size()
|
|
||||||
{
|
|
||||||
return _data.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray & XByteArray::insert(int i, char ch)
|
|
||||||
{
|
|
||||||
_data.insert(i, ch);
|
|
||||||
_changedData.insert(i, char(1));
|
|
||||||
return _data;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray & XByteArray::insert(int i, const QByteArray & ba)
|
|
||||||
{
|
|
||||||
_data.insert(i, ba);
|
|
||||||
_changedData.insert(i, QByteArray(ba.length(), char(1)));
|
|
||||||
return _data;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray & XByteArray::remove(int i, int len)
|
|
||||||
{
|
|
||||||
_data.remove(i, len);
|
|
||||||
_changedData.remove(i, len);
|
|
||||||
return _data;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray & XByteArray::replace(int index, char ch)
|
|
||||||
{
|
|
||||||
_data[index] = ch;
|
|
||||||
_changedData[index] = char(1);
|
|
||||||
return _data;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray & XByteArray::replace(int index, const QByteArray & ba)
|
|
||||||
{
|
|
||||||
int len = ba.length();
|
|
||||||
return replace(index, len, ba);
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray & XByteArray::replace(int index, int length, const QByteArray & ba)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
if ((index + length) > _data.length())
|
|
||||||
len = _data.length() - index;
|
|
||||||
else
|
|
||||||
len = length;
|
|
||||||
_data.replace(index, len, ba.mid(0, len));
|
|
||||||
_changedData.replace(index, len, QByteArray(len, char(1)));
|
|
||||||
return _data;
|
|
||||||
}
|
|
||||||
|
|
||||||
QChar XByteArray::asciiChar(int index)
|
|
||||||
{
|
|
||||||
char ch = _data[index];
|
|
||||||
if ((ch < 0x20) || (ch > 0x7e))
|
|
||||||
ch = '.';
|
|
||||||
return QChar(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString XByteArray::toRedableString(int start, int end)
|
|
||||||
{
|
|
||||||
int adrWidth = realAddressNumbers();
|
|
||||||
if (_addressNumbers > adrWidth)
|
|
||||||
adrWidth = _addressNumbers;
|
|
||||||
if (end < 0)
|
|
||||||
end = _data.size();
|
|
||||||
|
|
||||||
QString result;
|
|
||||||
for (int i=start; i < end; i += 16)
|
|
||||||
{
|
|
||||||
QString adrStr = QString("%1").arg(_addressOffset + i, adrWidth, 16, QChar('0'));
|
|
||||||
QString hexStr;
|
|
||||||
QString ascStr;
|
|
||||||
for (int j=0; j<16; j++)
|
|
||||||
{
|
|
||||||
if ((i + j) < _data.size())
|
|
||||||
{
|
|
||||||
hexStr.append(" ").append(_data.mid(i+j, 1).toHex());
|
|
||||||
ascStr.append(asciiChar(i+j));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result += adrStr + " " + QString("%1").arg(hexStr, -48) + " " + QString("%1").arg(ascStr, -17) + "\n";
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
#ifndef XBYTEARRAY_H
|
|
||||||
#define XBYTEARRAY_H
|
|
||||||
|
|
||||||
/** \cond docNever */
|
|
||||||
|
|
||||||
#include <QtCore>
|
|
||||||
|
|
||||||
/*! XByteArray represents the content of QHexEcit.
|
|
||||||
XByteArray comprehend the data itself and informations to store if it was
|
|
||||||
changed. The QHexEdit component uses these informations to perform nice
|
|
||||||
rendering of the data
|
|
||||||
|
|
||||||
XByteArray also provides some functionality to insert, replace and remove
|
|
||||||
single chars and QByteArras. Additionally some functions support rendering
|
|
||||||
and converting to readable strings.
|
|
||||||
*/
|
|
||||||
class XByteArray
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit XByteArray();
|
|
||||||
|
|
||||||
int addressOffset();
|
|
||||||
void setAddressOffset(int offset);
|
|
||||||
|
|
||||||
int addressWidth();
|
|
||||||
void setAddressWidth(int width);
|
|
||||||
|
|
||||||
QByteArray & data();
|
|
||||||
void setData(QByteArray data);
|
|
||||||
|
|
||||||
bool dataChanged(int i);
|
|
||||||
QByteArray dataChanged(int i, int len);
|
|
||||||
void setDataChanged(int i, bool state);
|
|
||||||
void setDataChanged(int i, const QByteArray & state);
|
|
||||||
|
|
||||||
int realAddressNumbers();
|
|
||||||
int size();
|
|
||||||
|
|
||||||
QByteArray & insert(int i, char ch);
|
|
||||||
QByteArray & insert(int i, const QByteArray & ba);
|
|
||||||
|
|
||||||
QByteArray & remove(int pos, int len);
|
|
||||||
|
|
||||||
QByteArray & replace(int index, char ch);
|
|
||||||
QByteArray & replace(int index, const QByteArray & ba);
|
|
||||||
QByteArray & replace(int index, int length, const QByteArray & ba);
|
|
||||||
|
|
||||||
QChar asciiChar(int index);
|
|
||||||
QString toRedableString(int start=0, int end=-1);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
|
|
||||||
private:
|
|
||||||
QByteArray _data;
|
|
||||||
QByteArray _changedData;
|
|
||||||
|
|
||||||
int _addressNumbers; // wanted width of address area
|
|
||||||
int _addressOffset; // will be added to the real addres inside bytearray
|
|
||||||
int _realAddressNumbers; // real width of address area (can be greater then wanted width)
|
|
||||||
int _oldSize; // size of data
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \endcond docNever */
|
|
||||||
#endif // XBYTEARRAY_H
|
|
@ -1,12 +0,0 @@
|
|||||||
// Copyright 2014 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include "citra_qt/debugger/ramview.h"
|
|
||||||
|
|
||||||
GRamView::GRamView(QWidget* parent) : QHexEdit(parent) {}
|
|
||||||
|
|
||||||
void GRamView::OnCPUStepped() {
|
|
||||||
// TODO: QHexEdit doesn't show vertical scroll bars for > 10MB data streams...
|
|
||||||
// setData(QByteArray((const char*)Mem_RAM,sizeof(Mem_RAM)/8));
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
// Copyright 2014 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "qhexedit.h"
|
|
||||||
|
|
||||||
class GRamView : public QHexEdit {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit GRamView(QWidget* parent = nullptr);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void OnCPUStepped();
|
|
||||||
};
|
|
Loading…
Reference in New Issue