update
This commit is contained in:
parent
7e5542e7aa
commit
10a1316509
|
@ -166,6 +166,7 @@ QHexEdit is released under MIT license
|
|||
10. 增加一些接口适应工作区支持需要
|
||||
11. 修复标记背景色第一行有超出部分的 Bug
|
||||
12. 修复复制中字节含有零字节会截断的 Bug
|
||||
13. 撤销恢复支持光标跟随
|
||||
|
||||
### 有关 QHexEdit2
|
||||
|
||||
|
|
|
@ -162,6 +162,7 @@ My improvements on the modified components are as follows:
|
|||
10. Add some interfaces to meet the needs of workspace support
|
||||
11. Fix the bug with excessive part in the first line of the background color of the mark
|
||||
12. Fix the bug that the bytes in the copy contain zero bytes and will be truncated
|
||||
13. Undo recovery supports cursor following
|
||||
|
||||
### About QHexEdit2
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include "hexcommand.h"
|
||||
|
||||
HexCommand::HexCommand(QHexBuffer *buffer, QUndoCommand *parent)
|
||||
: QUndoCommand(parent), m_buffer(buffer), m_offset(0), m_length(0) {}
|
||||
HexCommand::HexCommand(QHexBuffer *buffer, QHexCursor *cursor, int nibbleindex,
|
||||
QUndoCommand *parent)
|
||||
: QUndoCommand(parent), m_buffer(buffer), m_offset(0), m_length(0),
|
||||
m_cursor(cursor), m_nibbleindex(nibbleindex) {}
|
||||
|
|
|
@ -2,17 +2,22 @@
|
|||
#define HEXCOMMAND_H
|
||||
|
||||
#include "../../buffer/qhexbuffer.h"
|
||||
#include "QHexView/document/qhexcursor.h"
|
||||
#include <QUndoCommand>
|
||||
|
||||
class HexCommand : public QUndoCommand {
|
||||
public:
|
||||
HexCommand(QHexBuffer *buffer, QUndoCommand *parent = nullptr);
|
||||
HexCommand(QHexBuffer *buffer, QHexCursor *cursor, int nibbleindex,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
protected:
|
||||
QHexBuffer *m_buffer;
|
||||
qint64 m_offset;
|
||||
int m_length;
|
||||
QByteArray m_data;
|
||||
|
||||
QHexCursor *m_cursor;
|
||||
int m_nibbleindex;
|
||||
};
|
||||
|
||||
#endif // HEXCOMMAND_H
|
||||
|
|
|
@ -1,11 +1,23 @@
|
|||
#include "insertcommand.h"
|
||||
|
||||
InsertCommand::InsertCommand(QHexBuffer *buffer, qint64 offset,
|
||||
const QByteArray &data, QUndoCommand *parent)
|
||||
: HexCommand(buffer, parent) {
|
||||
const QByteArray &data, QHexCursor *cursor,
|
||||
int nibbleindex, QUndoCommand *parent)
|
||||
: HexCommand(buffer, cursor, nibbleindex, parent) {
|
||||
m_offset = offset;
|
||||
m_data = data;
|
||||
m_length = data.length();
|
||||
}
|
||||
|
||||
void InsertCommand::undo() { m_buffer->remove(m_offset, m_data.length()); }
|
||||
void InsertCommand::redo() { m_buffer->insert(m_offset, m_data); }
|
||||
void InsertCommand::undo() {
|
||||
m_buffer->remove(m_offset, m_data.length());
|
||||
m_cursor->setPos(m_offset, m_nibbleindex);
|
||||
}
|
||||
void InsertCommand::redo() {
|
||||
m_buffer->insert(m_offset, m_data);
|
||||
if (m_data.length() == 1 && m_nibbleindex) {
|
||||
m_cursor->setPos(m_offset, 0);
|
||||
} else {
|
||||
m_cursor->setPos(m_offset + m_length, m_nibbleindex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,13 @@
|
|||
|
||||
#include "hexcommand.h"
|
||||
|
||||
class InsertCommand: public HexCommand
|
||||
{
|
||||
public:
|
||||
InsertCommand(QHexBuffer* buffer, qint64 offset, const QByteArray& data, QUndoCommand* parent = nullptr);
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
class InsertCommand : public HexCommand {
|
||||
public:
|
||||
InsertCommand(QHexBuffer *buffer, qint64 offset, const QByteArray &data,
|
||||
QHexCursor *cursor, int nibbleindex,
|
||||
QUndoCommand *parent = nullptr);
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
};
|
||||
|
||||
#endif // INSERTCOMMAND_H
|
||||
|
|
|
@ -1,15 +1,28 @@
|
|||
#include "removecommand.h"
|
||||
|
||||
RemoveCommand::RemoveCommand(QHexBuffer *buffer, qint64 offset, int length,
|
||||
QHexCursor *cursor, int nibbleindex,
|
||||
QUndoCommand *parent)
|
||||
: HexCommand(buffer, parent) {
|
||||
: HexCommand(buffer, cursor, nibbleindex, parent) {
|
||||
m_offset = offset;
|
||||
m_length = length;
|
||||
m_data = m_buffer->read(m_offset, m_length);
|
||||
}
|
||||
|
||||
void RemoveCommand::undo() { m_buffer->insert(m_offset, m_data); }
|
||||
void RemoveCommand::undo() {
|
||||
m_buffer->insert(m_offset, m_data);
|
||||
if (m_length > 1) {
|
||||
m_cursor->setPos(m_offset + m_length - 1, 1);
|
||||
} else {
|
||||
if (m_nibbleindex) {
|
||||
m_cursor->setPos(m_offset + 1, 1);
|
||||
} else {
|
||||
m_cursor->setPos(m_offset, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveCommand::redo() {
|
||||
m_data = m_buffer->read(m_offset, m_length); // Backup data
|
||||
m_cursor->setPos(m_offset, m_nibbleindex);
|
||||
m_buffer->remove(m_offset, m_length);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
class RemoveCommand : public HexCommand {
|
||||
public:
|
||||
RemoveCommand(QHexBuffer *buffer, qint64 offset, int length,
|
||||
QHexCursor *cursor, int nibbleindex,
|
||||
QUndoCommand *parent = nullptr);
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
|
|
@ -1,15 +1,25 @@
|
|||
#include "replacecommand.h"
|
||||
|
||||
ReplaceCommand::ReplaceCommand(QHexBuffer *buffer, qint64 offset,
|
||||
const QByteArray &data, QUndoCommand *parent)
|
||||
: HexCommand(buffer, parent) {
|
||||
const QByteArray &data, QHexCursor *cursor,
|
||||
int nibbleindex, QUndoCommand *parent)
|
||||
: HexCommand(buffer, cursor, nibbleindex, parent) {
|
||||
m_offset = offset;
|
||||
m_data = data;
|
||||
m_length = data.length();
|
||||
m_olddata = m_buffer->read(m_offset, m_length);
|
||||
}
|
||||
|
||||
void ReplaceCommand::undo() { m_buffer->replace(m_offset, m_olddata); }
|
||||
void ReplaceCommand::undo() {
|
||||
m_buffer->replace(m_offset, m_olddata);
|
||||
m_cursor->setPos(m_offset, m_nibbleindex);
|
||||
}
|
||||
|
||||
void ReplaceCommand::redo() {
|
||||
m_olddata = m_buffer->read(m_offset, m_data.length());
|
||||
m_buffer->replace(m_offset, m_data);
|
||||
if (m_data.length() == 1 && m_nibbleindex) {
|
||||
m_cursor->setPos(m_offset, 0);
|
||||
} else {
|
||||
m_cursor->setPos(m_offset + m_length, !m_nibbleindex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
class ReplaceCommand : public HexCommand {
|
||||
public:
|
||||
ReplaceCommand(QHexBuffer *buffer, qint64 offset, const QByteArray &data,
|
||||
QHexCursor *cursor, int nibbleindex,
|
||||
QUndoCommand *parent = nullptr);
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
|
|
@ -109,6 +109,11 @@ void QHexCursor::moveTo(qint64 offset) {
|
|||
this->moveTo(quint64(line), int(offset - (line * m_lineWidth)));
|
||||
}
|
||||
|
||||
void QHexCursor::setPos(qint64 offset, int nibbleindex) {
|
||||
qint64 line = offset / m_lineWidth;
|
||||
this->moveTo(quint64(line), int(offset - (line * m_lineWidth)), nibbleindex);
|
||||
}
|
||||
|
||||
void QHexCursor::select(int length) {
|
||||
this->select(m_position.line,
|
||||
std::min(m_lineWidth - 1, m_position.column + length - 1));
|
||||
|
|
|
@ -60,6 +60,8 @@ public:
|
|||
void moveTo(const QHexPosition &pos);
|
||||
void moveTo(quint64 line, int column, int nibbleindex = 1);
|
||||
void moveTo(qint64 offset);
|
||||
void setPos(qint64 offset, int nibbleindex);
|
||||
// 和 moveTo 其实一样,只是为了不冲突
|
||||
void select(const QHexPosition &pos);
|
||||
void select(quint64 line, int column, int nibbleindex = 1);
|
||||
void select(int length);
|
||||
|
|
|
@ -508,12 +508,12 @@ QByteArray QHexDocument::read(qint64 offset, int len) {
|
|||
return m_buffer->read(offset, len);
|
||||
}
|
||||
|
||||
bool QHexDocument::RemoveSelection() {
|
||||
bool QHexDocument::RemoveSelection(int nibbleindex) {
|
||||
if (!m_cursor->hasSelection())
|
||||
return false;
|
||||
|
||||
auto res = this->Remove(m_cursor->selectionStart().offset(),
|
||||
m_cursor->selectionLength());
|
||||
m_cursor->selectionLength(), nibbleindex);
|
||||
if (res)
|
||||
m_cursor->clearSelection();
|
||||
return res;
|
||||
|
@ -553,7 +553,7 @@ void QHexDocument::redo() {
|
|||
emit documentChanged();
|
||||
}
|
||||
|
||||
bool QHexDocument::Cut(bool hex) {
|
||||
bool QHexDocument::Cut(int nibbleindex, bool hex) {
|
||||
if (!m_cursor->hasSelection())
|
||||
return true;
|
||||
|
||||
|
@ -562,7 +562,7 @@ bool QHexDocument::Cut(bool hex) {
|
|||
|
||||
auto res = this->copy(hex);
|
||||
if (res) {
|
||||
return this->RemoveSelection();
|
||||
return this->RemoveSelection(nibbleindex);
|
||||
} else {
|
||||
emit copyLimitRaised();
|
||||
return res;
|
||||
|
@ -597,7 +597,7 @@ bool QHexDocument::copy(bool hex) {
|
|||
}
|
||||
|
||||
// modified by wingsummer
|
||||
void QHexDocument::Paste(bool hex) {
|
||||
void QHexDocument::Paste(int nibbleindex, bool hex) {
|
||||
Q_UNUSED(hex)
|
||||
|
||||
QClipboard *c = qApp->clipboard();
|
||||
|
@ -607,53 +607,58 @@ void QHexDocument::Paste(bool hex) {
|
|||
if (data.isEmpty())
|
||||
return;
|
||||
|
||||
this->RemoveSelection();
|
||||
this->RemoveSelection(nibbleindex);
|
||||
|
||||
if (hex)
|
||||
data = QByteArray::fromHex(data);
|
||||
|
||||
auto pos = m_cursor->position().offset();
|
||||
if (!m_keepsize) {
|
||||
this->Insert(pos, data);
|
||||
this->Insert(pos, data, nibbleindex);
|
||||
m_cursor->moveTo(pos + data.length()); // added by wingsummer
|
||||
} else
|
||||
this->Replace(pos, data);
|
||||
this->Replace(pos, data, nibbleindex);
|
||||
}
|
||||
|
||||
void QHexDocument::Insert(qint64 offset, uchar b) {
|
||||
void QHexDocument::Insert(qint64 offset, uchar b, int nibbleindex) {
|
||||
if (m_keepsize || m_readonly || m_islocked)
|
||||
return;
|
||||
this->Insert(offset, QByteArray(1, char(b)));
|
||||
this->Insert(offset, QByteArray(1, char(b)), nibbleindex);
|
||||
}
|
||||
|
||||
void QHexDocument::Replace(qint64 offset, uchar b) {
|
||||
void QHexDocument::Replace(qint64 offset, uchar b, int nibbleindex) {
|
||||
if (m_readonly || m_islocked)
|
||||
return;
|
||||
this->Replace(offset, QByteArray(1, char(b)));
|
||||
this->Replace(offset, QByteArray(1, char(b)), nibbleindex);
|
||||
}
|
||||
|
||||
void QHexDocument::Insert(qint64 offset, const QByteArray &data) {
|
||||
void QHexDocument::Insert(qint64 offset, const QByteArray &data,
|
||||
int nibbleindex) {
|
||||
if (m_keepsize || m_readonly || m_islocked ||
|
||||
(offset < m_buffer->length() && m_metadata->hasMetadata()))
|
||||
return;
|
||||
if (!m_metadata->hasMetadata())
|
||||
m_undostack.push(new InsertCommand(m_buffer, offset, data));
|
||||
m_undostack.push(
|
||||
new InsertCommand(m_buffer, offset, data, m_cursor, nibbleindex));
|
||||
else
|
||||
m_buffer->insert(offset, data);
|
||||
emit documentChanged();
|
||||
}
|
||||
|
||||
void QHexDocument::Replace(qint64 offset, const QByteArray &data) {
|
||||
void QHexDocument::Replace(qint64 offset, const QByteArray &data,
|
||||
int nibbleindex) {
|
||||
if (m_readonly || m_islocked)
|
||||
return;
|
||||
m_undostack.push(new ReplaceCommand(m_buffer, offset, data));
|
||||
m_undostack.push(
|
||||
new ReplaceCommand(m_buffer, offset, data, m_cursor, nibbleindex));
|
||||
emit documentChanged();
|
||||
}
|
||||
|
||||
bool QHexDocument::Remove(qint64 offset, int len) {
|
||||
bool QHexDocument::Remove(qint64 offset, int len, int nibbleindex) {
|
||||
if (m_keepsize || m_readonly || m_islocked || m_metadata->hasMetadata())
|
||||
return false;
|
||||
m_undostack.push(new RemoveCommand(m_buffer, offset, len));
|
||||
m_undostack.push(
|
||||
new RemoveCommand(m_buffer, offset, len, m_cursor, nibbleindex));
|
||||
emit documentChanged();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ public:
|
|||
/*======================*/
|
||||
|
||||
public:
|
||||
bool RemoveSelection();
|
||||
bool RemoveSelection(int nibbleindex = 1);
|
||||
QByteArray read(qint64 offset, int len = 0);
|
||||
QByteArray selectedBytes() const;
|
||||
char at(int offset) const;
|
||||
|
@ -118,14 +118,14 @@ public:
|
|||
public slots:
|
||||
void undo();
|
||||
void redo();
|
||||
bool Cut(bool hex = false);
|
||||
bool Cut(int nibbleindex = 0, bool hex = false);
|
||||
bool copy(bool hex = false);
|
||||
void Paste(bool hex = false);
|
||||
void Insert(qint64 offset, uchar b);
|
||||
void Insert(qint64 offset, const QByteArray &data);
|
||||
void Replace(qint64 offset, uchar b);
|
||||
void Replace(qint64 offset, const QByteArray &data);
|
||||
bool Remove(qint64 offset, int len);
|
||||
void Paste(int nibbleindex = 0, bool hex = false);
|
||||
void Insert(qint64 offset, uchar b, int nibbleindex);
|
||||
void Insert(qint64 offset, const QByteArray &data, int nibbleindex);
|
||||
void Replace(qint64 offset, uchar b, int nibbleindex);
|
||||
void Replace(qint64 offset, const QByteArray &data, int nibbleindex = 0);
|
||||
bool Remove(qint64 offset, int len, int nibbleindex = 0);
|
||||
QByteArray read(qint64 offset, int len) const;
|
||||
bool saveTo(QIODevice *device, bool cleanUndo);
|
||||
|
||||
|
|
|
@ -547,28 +547,20 @@ bool QHexView::processAction(QHexCursor *cur, QKeyEvent *e) {
|
|||
// modified by wingsummer
|
||||
if (isKeepSize()) {
|
||||
if (e->key() == Qt::Key_Backspace)
|
||||
m_document->Replace(cur->position().offset() - 1, uchar(0));
|
||||
m_document->Replace(cur->position().offset() - 1, uchar(0), 0);
|
||||
else
|
||||
m_document->Replace(cur->position().offset(), uchar(0));
|
||||
m_document->Replace(cur->position().offset(), uchar(0), 0);
|
||||
} else {
|
||||
if (e->key() == Qt::Key_Backspace)
|
||||
m_document->Remove(cur->position().offset() - 1, 1);
|
||||
m_document->Remove(cur->position().offset() - 1, 1, 1);
|
||||
else
|
||||
m_document->Remove(cur->position().offset(), 1);
|
||||
m_document->Remove(cur->position().offset(), 1, 0);
|
||||
}
|
||||
|
||||
} else {
|
||||
QHexPosition oldpos = cur->selectionStart();
|
||||
m_document->RemoveSelection();
|
||||
cur->moveTo(oldpos.line, oldpos.column + 1);
|
||||
}
|
||||
|
||||
if (e->key() == Qt::Key_Backspace) {
|
||||
if (m_renderer->selectedArea() == QHexRenderer::HexArea)
|
||||
this->movePrevious();
|
||||
|
||||
this->movePrevious();
|
||||
}
|
||||
} else if (e->key() == Qt::Key_Insert)
|
||||
cur->switchInsertionMode();
|
||||
else
|
||||
|
@ -692,8 +684,8 @@ bool QHexView::processTextInput(QHexCursor *cur, QKeyEvent *e) {
|
|||
if (m_document->atEnd() ||
|
||||
(cur->currentNibble() && !isKeepSize() &&
|
||||
cur->insertionMode() == QHexCursor::InsertMode)) {
|
||||
m_document->Insert(cur->position().offset(), uchar(val << 4)); // X0 byte
|
||||
this->moveNext();
|
||||
m_document->Insert(cur->position().offset(), uchar(val << 4),
|
||||
1); // X0 byte
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -704,8 +696,7 @@ bool QHexView::processTextInput(QHexCursor *cur, QKeyEvent *e) {
|
|||
else // 0X
|
||||
val = (ch & 0xF0) | val;
|
||||
|
||||
m_document->Replace(cur->position().offset(), val);
|
||||
this->moveNext();
|
||||
m_document->Replace(cur->position().offset(), val, cur->currentNibble());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -717,9 +708,9 @@ bool QHexView::processTextInput(QHexCursor *cur, QKeyEvent *e) {
|
|||
|
||||
if (!m_document->atEnd() &&
|
||||
(cur->insertionMode() == QHexCursor::OverwriteMode))
|
||||
m_document->Replace(cur->position().offset(), key);
|
||||
m_document->Replace(cur->position().offset(), key, 1);
|
||||
else
|
||||
m_document->Insert(cur->position().offset(), key);
|
||||
m_document->Insert(cur->position().offset(), key, 1);
|
||||
|
||||
QKeyEvent keyevent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier);
|
||||
qApp->sendEvent(this, &keyevent);
|
||||
|
|
|
@ -28,7 +28,10 @@ void Logger::messageHandler(QtMsgType type, const QMessageLogContext &,
|
|||
emit instance->log(INFOLOG(tr("[Info]") + output));
|
||||
break;
|
||||
case QtMsgType::QtWarningMsg:
|
||||
emit instance->log(WARNLOG(tr("[Warn]") + output));
|
||||
// QXcbConnection WarningMsg
|
||||
// It's Qt noise on Linux I can't do nothing to avoid it.
|
||||
if (!output.startsWith("QXcbConnection"))
|
||||
emit instance->log(WARNLOG(tr("[Warn]") + output));
|
||||
break;
|
||||
case QtMsgType::QtCriticalMsg:
|
||||
emit instance->log(ERRLOG(tr("[Error]") + output));
|
||||
|
|
|
@ -857,6 +857,10 @@ MainWindow::MainWindow(DMainWindow *parent) {
|
|||
|
||||
logger = new Logger(this);
|
||||
connect(logger, &Logger::log, [=](QString msg) {
|
||||
QMutexLocker locker(&logmutex);
|
||||
auto cur = pluginInfo->textCursor();
|
||||
cur.movePosition(QTextCursor::End);
|
||||
pluginInfo->setTextCursor(cur);
|
||||
pluginInfo->insertHtml(msg);
|
||||
pluginInfo->append("");
|
||||
});
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <QFile>
|
||||
#include <QList>
|
||||
#include <QMutex>
|
||||
#include <QMutexLocker>
|
||||
#include <QObject>
|
||||
#include <QPixmap>
|
||||
#include <QPoint>
|
||||
|
@ -350,6 +351,7 @@ private:
|
|||
bool islittle = true;
|
||||
|
||||
QString lastusedpath;
|
||||
QMutex logmutex;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
|
|
@ -53,7 +53,7 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
a.setOrganizationName("WingCloud");
|
||||
a.setApplicationName(QObject::tr("WingHexExplorer"));
|
||||
a.setApplicationVersion("1.5.2");
|
||||
a.setApplicationVersion("1.5.3");
|
||||
a.setApplicationLicense("AGPL-3.0");
|
||||
a.setProductIcon(QIcon(":/images/icon.png"));
|
||||
a.setProductName(QObject::tr("WingHexExplorer"));
|
||||
|
|
BIN
screenshot.png
BIN
screenshot.png
Binary file not shown.
Before Width: | Height: | Size: 348 KiB After Width: | Height: | Size: 345 KiB |
Loading…
Reference in New Issue