feat: 引入文档撤销堆栈可视化;插件不再具有独立的撤销堆栈;
This commit is contained in:
parent
fb4f439e50
commit
a3b465534c
|
@ -51,8 +51,8 @@ add_library(
|
|||
document/commands/bookmark/bookmarkremovecommand.h
|
||||
document/commands/bookmark/bookmarkreplacecommand.cpp
|
||||
document/commands/bookmark/bookmarkreplacecommand.h
|
||||
document/commands/baseaddrcommand.cpp
|
||||
document/commands/baseaddrcommand.h
|
||||
document/commands/undocommandbase.h
|
||||
document/commands/undocommandbase.cpp
|
||||
document/qhexcursor.cpp
|
||||
document/qhexcursor.h
|
||||
document/qhexdocument.cpp
|
||||
|
|
|
@ -23,8 +23,22 @@
|
|||
|
||||
BookMarkAddCommand::BookMarkAddCommand(QHexDocument *doc, qsizetype pos,
|
||||
QString comment, QUndoCommand *parent)
|
||||
: BookMarkCommand(doc, pos, comment, parent) {}
|
||||
: BookMarkCommand(tr("[AddBookMark] pos: %1").arg(pos), doc, pos, comment,
|
||||
parent) {}
|
||||
|
||||
void BookMarkAddCommand::redo() { m_doc->addBookMark(m_pos, m_comment); }
|
||||
|
||||
int BookMarkAddCommand::id() const { return UndoID_BookMarkAdd; }
|
||||
|
||||
bool BookMarkAddCommand::mergeWith(const QUndoCommand *other) {
|
||||
auto ucmd = static_cast<const BookMarkAddCommand *>(other);
|
||||
if (ucmd) {
|
||||
if (this->m_pos == ucmd->m_pos) {
|
||||
this->m_comment = m_comment;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BookMarkAddCommand::undo() { m_doc->removeBookMark(m_pos); }
|
||||
|
|
|
@ -24,13 +24,22 @@
|
|||
|
||||
#include "bookmarkcommand.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
class BookMarkAddCommand : public BookMarkCommand {
|
||||
Q_DECLARE_TR_FUNCTIONS(BookMarkAddCommand)
|
||||
public:
|
||||
BookMarkAddCommand(QHexDocument *doc, qsizetype pos, QString comment,
|
||||
explicit BookMarkAddCommand(QHexDocument *doc, qsizetype pos,
|
||||
QString comment,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
// QUndoCommand interface
|
||||
public:
|
||||
virtual void undo() override;
|
||||
virtual void redo() override;
|
||||
|
||||
virtual int id() const override;
|
||||
virtual bool mergeWith(const QUndoCommand *other) override;
|
||||
};
|
||||
|
||||
#endif // BOOKMARKADDCOMMAND_H
|
||||
|
|
|
@ -24,8 +24,16 @@
|
|||
BookMarkClearCommand::BookMarkClearCommand(
|
||||
QHexDocument *doc, const QMap<qsizetype, QString> &bookmarks,
|
||||
QUndoCommand *parent)
|
||||
: QUndoCommand(parent), m_doc(doc), m_bookmarks(bookmarks) {}
|
||||
: UndoCommandBase(tr("[ClearBookMark]"), parent), m_doc(doc),
|
||||
m_bookmarks(bookmarks) {}
|
||||
|
||||
void BookMarkClearCommand::redo() { m_doc->clearBookMark(); }
|
||||
|
||||
int BookMarkClearCommand::id() const { return UndoID_BookMarkClear; }
|
||||
|
||||
bool BookMarkClearCommand::mergeWith(const QUndoCommand *other) {
|
||||
Q_UNUSED(other);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BookMarkClearCommand::undo() { m_doc->applyBookMarks(m_bookmarks); }
|
||||
|
|
|
@ -22,19 +22,26 @@
|
|||
#ifndef BOOKMARKCLEARCOMMAND_H
|
||||
#define BOOKMARKCLEARCOMMAND_H
|
||||
|
||||
#include "../undocommandbase.h"
|
||||
#include "document/qhexdocument.h"
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
#include <QUndoCommand>
|
||||
|
||||
class BookMarkClearCommand : public QUndoCommand {
|
||||
#include <QCoreApplication>
|
||||
#include <QMap>
|
||||
|
||||
class BookMarkClearCommand : public UndoCommandBase {
|
||||
Q_DECLARE_TR_FUNCTIONS(BookMarkClearCommand)
|
||||
public:
|
||||
BookMarkClearCommand(QHexDocument *doc,
|
||||
explicit BookMarkClearCommand(QHexDocument *doc,
|
||||
const QMap<qsizetype, QString> &bookmarks,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
// QUndoCommand interface
|
||||
public:
|
||||
virtual void undo() override;
|
||||
virtual void redo() override;
|
||||
|
||||
virtual int id() const override;
|
||||
virtual bool mergeWith(const QUndoCommand *other) override;
|
||||
|
||||
protected:
|
||||
QHexDocument *m_doc;
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include "bookmarkcommand.h"
|
||||
|
||||
BookMarkCommand::BookMarkCommand(QHexDocument *doc, qsizetype pos,
|
||||
QString comment, QUndoCommand *parent)
|
||||
: QUndoCommand(parent), m_doc(doc), m_comment(comment), m_pos(pos) {}
|
||||
BookMarkCommand::BookMarkCommand(const QString &text, QHexDocument *doc,
|
||||
qsizetype pos, QString comment,
|
||||
QUndoCommand *parent)
|
||||
: UndoCommandBase(text, parent), m_doc(doc), m_comment(comment),
|
||||
m_pos(pos) {}
|
||||
|
|
|
@ -22,13 +22,13 @@
|
|||
#ifndef BOOKMARKCOMMAND_H
|
||||
#define BOOKMARKCOMMAND_H
|
||||
|
||||
#include "../undocommandbase.h"
|
||||
#include "document/qhexdocument.h"
|
||||
#include <QObject>
|
||||
#include <QUndoCommand>
|
||||
|
||||
class BookMarkCommand : public QUndoCommand {
|
||||
class BookMarkCommand : public UndoCommandBase {
|
||||
public:
|
||||
BookMarkCommand(QHexDocument *doc, qsizetype pos, QString comment,
|
||||
explicit BookMarkCommand(const QString &text, QHexDocument *doc,
|
||||
qsizetype pos, QString comment,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -24,8 +24,21 @@
|
|||
BookMarkRemoveCommand::BookMarkRemoveCommand(QHexDocument *doc, qsizetype pos,
|
||||
QString comment,
|
||||
QUndoCommand *parent)
|
||||
: BookMarkCommand(doc, pos, comment, parent) {}
|
||||
: BookMarkCommand(tr("[RemoveBookMark] pos: %1").arg(pos), doc, pos,
|
||||
comment, parent) {}
|
||||
|
||||
void BookMarkRemoveCommand::redo() { m_doc->removeBookMark(m_pos); }
|
||||
|
||||
int BookMarkRemoveCommand::id() const { return UndoID_BookMarkRemove; }
|
||||
|
||||
bool BookMarkRemoveCommand::mergeWith(const QUndoCommand *other) {
|
||||
auto ucmd = static_cast<const BookMarkRemoveCommand *>(other);
|
||||
if (ucmd) {
|
||||
if (this->m_pos == ucmd->m_pos) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BookMarkRemoveCommand::undo() { m_doc->addBookMark(m_pos, m_comment); }
|
||||
|
|
|
@ -24,13 +24,23 @@
|
|||
|
||||
#include "bookmarkcommand.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
class BookMarkRemoveCommand : public BookMarkCommand {
|
||||
Q_DECLARE_TR_FUNCTIONS(BookMarkRemoveCommand)
|
||||
|
||||
public:
|
||||
BookMarkRemoveCommand(QHexDocument *doc, qsizetype pos, QString comment,
|
||||
explicit BookMarkRemoveCommand(QHexDocument *doc, qsizetype pos,
|
||||
QString comment,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
// QUndoCommand interface
|
||||
public:
|
||||
virtual void undo() override;
|
||||
virtual void redo() override;
|
||||
|
||||
virtual int id() const override;
|
||||
virtual bool mergeWith(const QUndoCommand *other) override;
|
||||
};
|
||||
|
||||
#endif // BOOKMARKREMOVECOMMAND_H
|
||||
|
|
|
@ -25,8 +25,23 @@ BookMarkReplaceCommand::BookMarkReplaceCommand(QHexDocument *doc, qsizetype pos,
|
|||
QString comment,
|
||||
QString oldcomment,
|
||||
QUndoCommand *parent)
|
||||
: BookMarkCommand(doc, pos, comment, parent), m_oldcomment(oldcomment) {}
|
||||
: BookMarkCommand(tr("[ReplaceBookMark] pos: %1").arg(pos), doc, pos,
|
||||
comment, parent),
|
||||
m_oldcomment(oldcomment) {}
|
||||
|
||||
void BookMarkReplaceCommand::redo() { m_doc->modBookMark(m_pos, m_comment); }
|
||||
|
||||
int BookMarkReplaceCommand::id() const { return UndoID_BookMarkReplace; }
|
||||
|
||||
bool BookMarkReplaceCommand::mergeWith(const QUndoCommand *other) {
|
||||
auto ucmd = static_cast<const BookMarkReplaceCommand *>(other);
|
||||
if (ucmd) {
|
||||
if (this->m_pos == ucmd->m_pos) {
|
||||
this->m_comment = m_comment;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BookMarkReplaceCommand::undo() { m_doc->modBookMark(m_pos, m_oldcomment); }
|
||||
|
|
|
@ -24,13 +24,22 @@
|
|||
|
||||
#include "bookmarkcommand.h"
|
||||
|
||||
class BookMarkReplaceCommand : public BookMarkCommand {
|
||||
public:
|
||||
BookMarkReplaceCommand(QHexDocument *doc, qsizetype pos, QString comment,
|
||||
QString oldcomment, QUndoCommand *parent = nullptr);
|
||||
#include <QCoreApplication>
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
class BookMarkReplaceCommand : public BookMarkCommand {
|
||||
Q_DECLARE_TR_FUNCTIONS(BookMarkReplaceCommand)
|
||||
public:
|
||||
explicit BookMarkReplaceCommand(QHexDocument *doc, qsizetype pos,
|
||||
QString comment, QString oldcomment,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
// QUndoCommand interface
|
||||
public:
|
||||
virtual void undo() override;
|
||||
virtual void redo() override;
|
||||
|
||||
virtual int id() const override;
|
||||
virtual bool mergeWith(const QUndoCommand *other) override;
|
||||
|
||||
protected:
|
||||
QString m_oldcomment;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
AppendCommand::AppendCommand(QHexDocument *doc, QHexCursor *cursor,
|
||||
const QByteArray &data, int nibbleindex,
|
||||
QUndoCommand *parent)
|
||||
: HexCommand(doc, cursor, nibbleindex, parent) {
|
||||
: HexCommand(tr("[HexAppend]"), doc, cursor, nibbleindex, parent) {
|
||||
m_offset = -1;
|
||||
m_data = data;
|
||||
m_length = data.length();
|
||||
|
@ -36,7 +36,6 @@ void AppendCommand::undo() {
|
|||
m_doc->insertBookMarkAdjustRevert(offset, m_length);
|
||||
m_doc->metadata()->insertAdjustRevert(offset, m_length);
|
||||
m_cursor->setPos(offset, m_nibbleindex);
|
||||
HexCommand::undo();
|
||||
}
|
||||
|
||||
void AppendCommand::redo() {
|
||||
|
@ -49,5 +48,15 @@ void AppendCommand::redo() {
|
|||
} else {
|
||||
m_cursor->setPos(offset + m_length, m_nibbleindex);
|
||||
}
|
||||
HexCommand::redo();
|
||||
}
|
||||
|
||||
int AppendCommand::id() const { return UndoID_HexAppend; }
|
||||
|
||||
bool AppendCommand::mergeWith(const QUndoCommand *other) {
|
||||
auto ucmd = static_cast<const AppendCommand *>(other);
|
||||
if (ucmd) {
|
||||
this->m_data.append(ucmd->m_data);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -24,12 +24,22 @@
|
|||
|
||||
#include "hexcommand.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
class AppendCommand : public HexCommand {
|
||||
Q_DECLARE_TR_FUNCTIONS(AppendCommand)
|
||||
public:
|
||||
AppendCommand(QHexDocument *doc, QHexCursor *cursor, const QByteArray &data,
|
||||
int nibbleindex, QUndoCommand *parent = nullptr);
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
explicit AppendCommand(QHexDocument *doc, QHexCursor *cursor,
|
||||
const QByteArray &data, int nibbleindex,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
// QUndoCommand interface
|
||||
public:
|
||||
virtual void undo() override;
|
||||
virtual void redo() override;
|
||||
|
||||
virtual int id() const override;
|
||||
virtual bool mergeWith(const QUndoCommand *other) override;
|
||||
};
|
||||
|
||||
#endif // APPENDCOMMAND_H
|
||||
|
|
|
@ -21,14 +21,8 @@
|
|||
|
||||
#include "hexcommand.h"
|
||||
|
||||
HexCommand::HexCommand(QHexDocument *doc, QHexCursor *cursor, int nibbleindex,
|
||||
HexCommand::HexCommand(const QString &text, QHexDocument *doc,
|
||||
QHexCursor *cursor, int nibbleindex,
|
||||
QUndoCommand *parent)
|
||||
: QUndoCommand(parent), m_doc(doc), m_cursor(cursor), m_offset(0),
|
||||
: UndoCommandBase(text, parent), m_doc(doc), m_cursor(cursor), m_offset(0),
|
||||
m_length(0), m_nibbleindex(nibbleindex) {}
|
||||
|
||||
void HexCommand::undo() {
|
||||
Q_ASSERT(m_doc->m_bytesModFlag > 0);
|
||||
m_doc->m_bytesModFlag--;
|
||||
}
|
||||
|
||||
void HexCommand::redo() { m_doc->m_bytesModFlag++; }
|
||||
|
|
|
@ -25,16 +25,14 @@
|
|||
#include "document/qhexcursor.h"
|
||||
#include "document/qhexdocument.h"
|
||||
|
||||
#include <QUndoCommand>
|
||||
#include "document/commands/undocommandbase.h"
|
||||
|
||||
class HexCommand : public QUndoCommand {
|
||||
class HexCommand : public UndoCommandBase {
|
||||
public:
|
||||
HexCommand(QHexDocument *doc, QHexCursor *cursor, int nibbleindex,
|
||||
explicit HexCommand(const QString &text, QHexDocument *doc,
|
||||
QHexCursor *cursor, int nibbleindex,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
protected:
|
||||
QHexDocument *m_doc;
|
||||
QHexCursor *m_cursor;
|
||||
|
|
|
@ -21,10 +21,13 @@
|
|||
|
||||
#include "insertcommand.h"
|
||||
|
||||
#include "document/commands/hex/replacecommand.h"
|
||||
|
||||
InsertCommand::InsertCommand(QHexDocument *doc, QHexCursor *cursor,
|
||||
qsizetype offset, const QByteArray &data,
|
||||
int nibbleindex, QUndoCommand *parent)
|
||||
: HexCommand(doc, cursor, nibbleindex, parent) {
|
||||
: HexCommand(tr("[HexInsert] pos: %1").arg(offset), doc, cursor,
|
||||
nibbleindex, parent) {
|
||||
m_offset = offset;
|
||||
m_data = data;
|
||||
m_length = data.length();
|
||||
|
@ -35,7 +38,6 @@ void InsertCommand::undo() {
|
|||
m_doc->insertBookMarkAdjustRevert(m_offset, m_length);
|
||||
m_doc->metadata()->insertAdjustRevert(m_offset, m_length);
|
||||
m_cursor->setPos(m_offset, m_nibbleindex);
|
||||
HexCommand::undo();
|
||||
}
|
||||
void InsertCommand::redo() {
|
||||
m_doc->_insert(m_offset, m_data);
|
||||
|
@ -46,5 +48,28 @@ void InsertCommand::redo() {
|
|||
} else {
|
||||
m_cursor->setPos(m_offset + m_length, m_nibbleindex);
|
||||
}
|
||||
HexCommand::redo();
|
||||
}
|
||||
|
||||
int InsertCommand::id() const { return UndoID_HexReplaceInsert; }
|
||||
|
||||
bool InsertCommand::mergeWith(const QUndoCommand *other) {
|
||||
auto ucmd = dynamic_cast<const InsertCommand *>(other);
|
||||
if (ucmd) {
|
||||
if (this->m_offset + this->m_length == ucmd->m_offset) {
|
||||
this->m_length += ucmd->m_length;
|
||||
this->m_data.append(ucmd->m_data);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
auto ucmd = dynamic_cast<const ReplaceCommand *>(other);
|
||||
if (ucmd) {
|
||||
if (this->m_offset + this->m_length - 1 == ucmd->m_offset &&
|
||||
ucmd->m_length == 1 && this->m_nibbleindex == 1 &&
|
||||
ucmd->m_nibbleindex == 0) {
|
||||
this->m_data.back() = ucmd->m_data.at(0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -24,13 +24,23 @@
|
|||
|
||||
#include "hexcommand.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
class InsertCommand : public HexCommand {
|
||||
Q_DECLARE_TR_FUNCTIONS(InsertCommand)
|
||||
|
||||
public:
|
||||
InsertCommand(QHexDocument *doc, QHexCursor *cursor, qsizetype offset,
|
||||
const QByteArray &data, int nibbleindex,
|
||||
QUndoCommand *parent = nullptr);
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
explicit InsertCommand(QHexDocument *doc, QHexCursor *cursor,
|
||||
qsizetype offset, const QByteArray &data,
|
||||
int nibbleindex, QUndoCommand *parent = nullptr);
|
||||
|
||||
// QUndoCommand interface
|
||||
public:
|
||||
virtual void undo() override;
|
||||
virtual void redo() override;
|
||||
|
||||
virtual int id() const override;
|
||||
virtual bool mergeWith(const QUndoCommand *other) override;
|
||||
};
|
||||
|
||||
#endif // INSERTCOMMAND_H
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
RemoveCommand::RemoveCommand(QHexDocument *doc, qsizetype offset,
|
||||
qsizetype length, QHexCursor *cursor,
|
||||
int nibbleindex, QUndoCommand *parent)
|
||||
: HexCommand(doc, cursor, nibbleindex, parent) {
|
||||
: HexCommand(tr("[HexRemove] pos: %1").arg(offset), doc, cursor,
|
||||
nibbleindex, parent) {
|
||||
m_offset = offset;
|
||||
m_length = length;
|
||||
m_data = doc->read(m_offset, m_length);
|
||||
|
@ -43,7 +44,6 @@ void RemoveCommand::undo() {
|
|||
m_cursor->setPos(m_offset, 0);
|
||||
}
|
||||
}
|
||||
HexCommand::undo();
|
||||
}
|
||||
|
||||
void RemoveCommand::redo() {
|
||||
|
@ -51,5 +51,28 @@ void RemoveCommand::redo() {
|
|||
m_doc->_remove(m_offset, m_length);
|
||||
_rmbms = m_doc->removeBookMarkAdjust(m_offset, m_length);
|
||||
_rmMetas = m_doc->metadata()->removeAdjust(m_offset, m_length);
|
||||
HexCommand::redo();
|
||||
}
|
||||
|
||||
int RemoveCommand::id() const { return UndoID_HexRemove; }
|
||||
|
||||
bool RemoveCommand::mergeWith(const QUndoCommand *other) {
|
||||
auto ucmd = static_cast<const RemoveCommand *>(other);
|
||||
if (ucmd) {
|
||||
if (this->m_offset == ucmd->m_offset) {
|
||||
this->m_data.append(ucmd->m_data);
|
||||
auto bms = ucmd->_rmbms;
|
||||
for (auto &&b : bms.asKeyValueRange()) {
|
||||
this->_rmbms.insert(b.first + this->m_length, b.second);
|
||||
}
|
||||
auto metas = ucmd->_rmMetas;
|
||||
for (auto &m : metas) {
|
||||
m.begin += this->m_length;
|
||||
m.end += this->m_length;
|
||||
}
|
||||
this->_rmMetas.append(ucmd->_rmMetas);
|
||||
this->m_length += ucmd->m_length;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -24,13 +24,21 @@
|
|||
|
||||
#include "hexcommand.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
class RemoveCommand : public HexCommand {
|
||||
Q_DECLARE_TR_FUNCTIONS(RemoveCommand)
|
||||
public:
|
||||
RemoveCommand(QHexDocument *doc, qsizetype offset, qsizetype length,
|
||||
QHexCursor *cursor, int nibbleindex,
|
||||
QUndoCommand *parent = nullptr);
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
explicit RemoveCommand(QHexDocument *doc, qsizetype offset,
|
||||
qsizetype length, QHexCursor *cursor,
|
||||
int nibbleindex, QUndoCommand *parent = nullptr);
|
||||
// QUndoCommand interface
|
||||
public:
|
||||
virtual void undo() override;
|
||||
virtual void redo() override;
|
||||
|
||||
virtual int id() const override;
|
||||
virtual bool mergeWith(const QUndoCommand *other) override;
|
||||
|
||||
private:
|
||||
QVector<QHexMetadataItem> _rmMetas;
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
ReplaceCommand::ReplaceCommand(QHexDocument *doc, qsizetype offset,
|
||||
const QByteArray &data, QHexCursor *cursor,
|
||||
int nibbleindex, QUndoCommand *parent)
|
||||
: HexCommand(doc, cursor, nibbleindex, parent) {
|
||||
: HexCommand(tr("[HexReplace] pos: %1").arg(offset), doc, cursor,
|
||||
nibbleindex, parent) {
|
||||
m_offset = offset;
|
||||
m_data = data;
|
||||
m_length = data.length();
|
||||
|
@ -35,7 +36,6 @@ ReplaceCommand::ReplaceCommand(QHexDocument *doc, qsizetype offset,
|
|||
void ReplaceCommand::undo() {
|
||||
m_doc->_replace(m_offset, m_olddata);
|
||||
m_cursor->setPos(m_offset, m_nibbleindex);
|
||||
HexCommand::undo();
|
||||
}
|
||||
|
||||
void ReplaceCommand::redo() {
|
||||
|
@ -45,5 +45,48 @@ void ReplaceCommand::redo() {
|
|||
} else {
|
||||
m_cursor->setPos(m_offset + m_length, !m_nibbleindex);
|
||||
}
|
||||
HexCommand::redo();
|
||||
}
|
||||
|
||||
int ReplaceCommand::id() const { return UndoID_HexReplaceInsert; }
|
||||
|
||||
bool ReplaceCommand::mergeWith(const QUndoCommand *other) {
|
||||
auto ucmd = dynamic_cast<const ReplaceCommand *>(other);
|
||||
if (ucmd) {
|
||||
if (this->m_offset == ucmd->m_offset) {
|
||||
if (this->m_length <= ucmd->m_length) {
|
||||
this->m_olddata = ucmd->m_olddata;
|
||||
this->m_data = ucmd->m_data;
|
||||
this->m_length = ucmd->m_length;
|
||||
} else {
|
||||
this->m_data.replace(0, ucmd->m_length, ucmd->m_data);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this->m_offset + this->m_length == ucmd->m_offset) {
|
||||
this->m_length += ucmd->m_offset;
|
||||
this->m_data.append(ucmd->m_data);
|
||||
this->m_olddata.append(ucmd->m_olddata);
|
||||
this->m_nibbleindex = ucmd->m_nibbleindex;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this->m_offset <= ucmd->m_offset &&
|
||||
this->m_offset + m_length >= ucmd->m_offset + ucmd->m_length) {
|
||||
auto dis = ucmd->m_offset - this->m_offset;
|
||||
this->m_data.replace(dis, ucmd->m_length, ucmd->m_data);
|
||||
return true;
|
||||
}
|
||||
if (this->m_offset >= ucmd->m_offset &&
|
||||
this->m_offset + m_length <= ucmd->m_offset + ucmd->m_length) {
|
||||
this->m_offset = ucmd->m_offset;
|
||||
this->m_data = ucmd->m_data;
|
||||
this->m_length = ucmd->m_length;
|
||||
this->m_olddata = ucmd->m_olddata;
|
||||
this->m_nibbleindex = ucmd->m_nibbleindex;
|
||||
setText(tr("[HexReplace] pos: %1").arg(this->m_offset));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -24,13 +24,23 @@
|
|||
|
||||
#include "hexcommand.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
class ReplaceCommand : public HexCommand {
|
||||
Q_DECLARE_TR_FUNCTIONS(ReplaceCommand)
|
||||
friend class InsertCommand;
|
||||
|
||||
public:
|
||||
ReplaceCommand(QHexDocument *doc, qsizetype offset, const QByteArray &data,
|
||||
QHexCursor *cursor, int nibbleindex,
|
||||
QUndoCommand *parent = nullptr);
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
explicit ReplaceCommand(QHexDocument *doc, qsizetype offset,
|
||||
const QByteArray &data, QHexCursor *cursor,
|
||||
int nibbleindex, QUndoCommand *parent = nullptr);
|
||||
// QUndoCommand interface
|
||||
public:
|
||||
virtual void undo() override;
|
||||
virtual void redo() override;
|
||||
|
||||
virtual int id() const override;
|
||||
virtual bool mergeWith(const QUndoCommand *other) override;
|
||||
|
||||
private:
|
||||
QByteArray m_olddata;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
MetaAddCommand::MetaAddCommand(QHexMetadata *hexmeta,
|
||||
const QHexMetadataItem &meta,
|
||||
QUndoCommand *parent)
|
||||
: MetaCommand(hexmeta, meta, parent) {
|
||||
: MetaCommand(tr("[MetaAdd]"), hexmeta, meta, parent) {
|
||||
_brokenMetas = m_hexmeta->mayBrokenMetaData(meta.begin, meta.end);
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,20 @@ void MetaAddCommand::redo() {
|
|||
m_meta.background, m_meta.comment);
|
||||
}
|
||||
|
||||
int MetaAddCommand::id() const { return UndoID_MetaAdd; }
|
||||
|
||||
bool MetaAddCommand::mergeWith(const QUndoCommand *other) {
|
||||
auto ucmd = static_cast<const MetaAddCommand *>(other);
|
||||
if (ucmd) {
|
||||
if (this->m_meta.foreground == ucmd->m_meta.foreground &&
|
||||
this->m_meta.background == ucmd->m_meta.background &&
|
||||
this->m_meta.comment == ucmd->m_meta.comment) {
|
||||
return this->m_meta.mergeRegionWithoutMetaCheck(ucmd->m_meta);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MetaAddCommand::undo() {
|
||||
m_hexmeta->removeMetadata(m_meta.begin, m_meta.end);
|
||||
for (auto &meta : _brokenMetas) {
|
||||
|
|
|
@ -23,14 +23,22 @@
|
|||
#define METAADDCOMMAND_H
|
||||
|
||||
#include "metacommand.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QObject>
|
||||
|
||||
class MetaAddCommand : public MetaCommand {
|
||||
Q_DECLARE_TR_FUNCTIONS(MetaAddCommand)
|
||||
public:
|
||||
MetaAddCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
|
||||
explicit MetaAddCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
|
||||
QUndoCommand *parent = nullptr);
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
// QUndoCommand interface
|
||||
public:
|
||||
virtual void undo() override;
|
||||
virtual void redo() override;
|
||||
|
||||
virtual int id() const override;
|
||||
virtual bool mergeWith(const QUndoCommand *other) override;
|
||||
|
||||
private:
|
||||
QVector<QHexMetadataItem> _brokenMetas;
|
||||
|
|
|
@ -24,8 +24,16 @@
|
|||
MetaClearCommand::MetaClearCommand(QHexMetadata *hexmeta,
|
||||
const QVector<QHexMetadataItem> &metas,
|
||||
QUndoCommand *parent)
|
||||
: QUndoCommand(parent), m_hexmeta(hexmeta), m_metas(metas) {}
|
||||
: UndoCommandBase(tr("[MetaClear]"), parent), m_hexmeta(hexmeta),
|
||||
m_metas(metas) {}
|
||||
|
||||
void MetaClearCommand::redo() { m_hexmeta->clear(); }
|
||||
|
||||
int MetaClearCommand::id() const { return UndoID_MetaClear; }
|
||||
|
||||
bool MetaClearCommand::mergeWith(const QUndoCommand *other) {
|
||||
Q_UNUSED(other);
|
||||
return true;
|
||||
}
|
||||
|
||||
void MetaClearCommand::undo() { m_hexmeta->applyMetas(m_metas); }
|
||||
|
|
|
@ -23,21 +23,27 @@
|
|||
#define METACLEARCOMMAND_H
|
||||
|
||||
#include "../../qhexmetadata.h"
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
#include <QUndoCommand>
|
||||
#include <QUndoStack>
|
||||
#include "../undocommandbase.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QVector>
|
||||
|
||||
// this class is newed by wingsummer
|
||||
|
||||
class MetaClearCommand : public QUndoCommand {
|
||||
class MetaClearCommand : public UndoCommandBase {
|
||||
Q_DECLARE_TR_FUNCTIONS(MetaClearCommand)
|
||||
public:
|
||||
MetaClearCommand(QHexMetadata *hexmeta,
|
||||
explicit MetaClearCommand(QHexMetadata *hexmeta,
|
||||
const QVector<QHexMetadataItem> &metas,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
// QUndoCommand interface
|
||||
public:
|
||||
virtual void undo() override;
|
||||
virtual void redo() override;
|
||||
|
||||
virtual int id() const override;
|
||||
virtual bool mergeWith(const QUndoCommand *other) override;
|
||||
|
||||
protected:
|
||||
QHexMetadata *m_hexmeta;
|
||||
|
|
|
@ -21,6 +21,6 @@
|
|||
|
||||
#include "metacommand.h"
|
||||
|
||||
MetaCommand::MetaCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
|
||||
QUndoCommand *parent)
|
||||
: QUndoCommand(parent), m_hexmeta(hexmeta), m_meta(meta) {}
|
||||
MetaCommand::MetaCommand(const QString &text, QHexMetadata *hexmeta,
|
||||
const QHexMetadataItem &meta, QUndoCommand *parent)
|
||||
: UndoCommandBase(text, parent), m_hexmeta(hexmeta), m_meta(meta) {}
|
||||
|
|
|
@ -22,16 +22,15 @@
|
|||
#ifndef METACOMMAND_H
|
||||
#define METACOMMAND_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QUndoCommand>
|
||||
|
||||
#include "../../qhexmetadata.h"
|
||||
#include "../undocommandbase.h"
|
||||
|
||||
// this class is newed by wingsummer
|
||||
|
||||
class MetaCommand : public QUndoCommand {
|
||||
class MetaCommand : public UndoCommandBase {
|
||||
public:
|
||||
MetaCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
|
||||
explicit MetaCommand(const QString &text, QHexMetadata *hexmeta,
|
||||
const QHexMetadataItem &meta,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -24,10 +24,20 @@
|
|||
MetaRemoveCommand::MetaRemoveCommand(QHexMetadata *hexmeta,
|
||||
const QHexMetadataItem &meta,
|
||||
QUndoCommand *parent)
|
||||
: MetaCommand(hexmeta, meta, parent) {}
|
||||
: MetaCommand(tr("[MetaRemove]"), hexmeta, meta, parent) {}
|
||||
|
||||
void MetaRemoveCommand::redo() { m_hexmeta->removeMetadata(m_meta); }
|
||||
|
||||
int MetaRemoveCommand::id() const { return UndoID_MetaRemove; }
|
||||
|
||||
bool MetaRemoveCommand::mergeWith(const QUndoCommand *other) {
|
||||
auto ucmd = static_cast<const MetaRemoveCommand *>(other);
|
||||
if (ucmd) {
|
||||
return this->m_meta == ucmd->m_meta;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MetaRemoveCommand::undo() {
|
||||
m_hexmeta->metadata(m_meta.begin, m_meta.end, m_meta.foreground,
|
||||
m_meta.background, m_meta.comment);
|
||||
|
|
|
@ -23,18 +23,26 @@
|
|||
#define METAREMOVECOMMAND_H
|
||||
|
||||
#include "metacommand.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
|
||||
// this class is newed by wingsummer
|
||||
|
||||
class MetaRemoveCommand : public MetaCommand {
|
||||
Q_DECLARE_TR_FUNCTIONS(MetaRemoveCommand)
|
||||
public:
|
||||
MetaRemoveCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
|
||||
explicit MetaRemoveCommand(QHexMetadata *hexmeta,
|
||||
const QHexMetadataItem &meta,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
// QUndoCommand interface
|
||||
public:
|
||||
virtual void undo() override;
|
||||
virtual void redo() override;
|
||||
|
||||
virtual int id() const override;
|
||||
virtual bool mergeWith(const QUndoCommand *other) override;
|
||||
};
|
||||
|
||||
#endif // METAREMOVECOMMAND_H
|
||||
|
|
|
@ -23,16 +23,28 @@
|
|||
|
||||
MetaRemovePosCommand::MetaRemovePosCommand(QHexMetadata *hexmeta, qsizetype pos,
|
||||
QUndoCommand *parent)
|
||||
: QUndoCommand(parent), m_hexmeta(hexmeta), m_pos(pos) {
|
||||
: MetaCommand(tr("[MetaRemovePos]"), hexmeta, {}, parent), m_pos(pos) {
|
||||
auto po = m_hexmeta->get(pos);
|
||||
if (po.has_value()) {
|
||||
oldmeta = po.value();
|
||||
m_meta = po.value();
|
||||
}
|
||||
}
|
||||
|
||||
void MetaRemovePosCommand::redo() { m_hexmeta->removeMetadata(m_pos); }
|
||||
|
||||
void MetaRemovePosCommand::undo() {
|
||||
m_hexmeta->metadata(oldmeta.begin, oldmeta.end, oldmeta.foreground,
|
||||
oldmeta.background, oldmeta.comment);
|
||||
int MetaRemovePosCommand::id() const { return UndoID_MetaRemovePos; }
|
||||
|
||||
bool MetaRemovePosCommand::mergeWith(const QUndoCommand *other) {
|
||||
auto ucmd = static_cast<const MetaRemovePosCommand *>(other);
|
||||
if (ucmd) {
|
||||
if (this->m_pos == ucmd->m_pos) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MetaRemovePosCommand::undo() {
|
||||
m_hexmeta->metadata(m_meta.begin, m_meta.end, m_meta.foreground,
|
||||
m_meta.background, m_meta.comment);
|
||||
}
|
||||
|
|
|
@ -22,24 +22,26 @@
|
|||
#ifndef METAREMOVEPOSCOMMAND_H
|
||||
#define METAREMOVEPOSCOMMAND_H
|
||||
|
||||
#include "../../qhexmetadata.h"
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
#include <QUndoCommand>
|
||||
#include <QUndoStack>
|
||||
#include "metacommand.h"
|
||||
|
||||
class MetaRemovePosCommand : public QUndoCommand {
|
||||
#include <QCoreApplication>
|
||||
|
||||
class MetaRemovePosCommand : public MetaCommand {
|
||||
Q_DECLARE_TR_FUNCTIONS(MetaRemovePosCommand)
|
||||
public:
|
||||
MetaRemovePosCommand(QHexMetadata *hexmeta, qsizetype pos,
|
||||
explicit MetaRemovePosCommand(QHexMetadata *hexmeta, qsizetype pos,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
// QUndoCommand interface
|
||||
public:
|
||||
virtual void undo() override;
|
||||
virtual void redo() override;
|
||||
|
||||
virtual int id() const override;
|
||||
virtual bool mergeWith(const QUndoCommand *other) override;
|
||||
|
||||
protected:
|
||||
QHexMetadata *m_hexmeta;
|
||||
qsizetype m_pos;
|
||||
QHexMetadataItem oldmeta;
|
||||
};
|
||||
|
||||
#endif // METAREMOVEPOSCOMMAND_H
|
||||
|
|
|
@ -25,8 +25,21 @@ MetaReplaceCommand::MetaReplaceCommand(QHexMetadata *hexmeta,
|
|||
const QHexMetadataItem &meta,
|
||||
const QHexMetadataItem &oldmeta,
|
||||
QUndoCommand *parent)
|
||||
: MetaCommand(hexmeta, meta, parent), m_old(oldmeta) {}
|
||||
: MetaCommand(tr("[MetaReplace]"), hexmeta, meta, parent), m_old(oldmeta) {}
|
||||
|
||||
void MetaReplaceCommand::undo() { m_hexmeta->modifyMetadata(m_old, m_meta); }
|
||||
|
||||
void MetaReplaceCommand::redo() { m_hexmeta->modifyMetadata(m_meta, m_old); }
|
||||
|
||||
int MetaReplaceCommand::id() const { return UndoID_MetaReplace; }
|
||||
|
||||
bool MetaReplaceCommand::mergeWith(const QUndoCommand *other) {
|
||||
auto ucmd = static_cast<const MetaReplaceCommand *>(other);
|
||||
if (ucmd) {
|
||||
if (this->m_old == ucmd->m_old) {
|
||||
this->m_meta = ucmd->m_meta;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -23,15 +23,24 @@
|
|||
#define METAREPLACECOMMAND_H
|
||||
|
||||
#include "metacommand.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QObject>
|
||||
|
||||
class MetaReplaceCommand : public MetaCommand {
|
||||
Q_DECLARE_TR_FUNCTIONS(MetaReplaceCommand)
|
||||
public:
|
||||
MetaReplaceCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
|
||||
explicit MetaReplaceCommand(QHexMetadata *hexmeta,
|
||||
const QHexMetadataItem &meta,
|
||||
const QHexMetadataItem &oldmeta,
|
||||
QUndoCommand *parent = nullptr);
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
// QUndoCommand interface
|
||||
public:
|
||||
virtual void undo() override;
|
||||
virtual void redo() override;
|
||||
|
||||
virtual int id() const override;
|
||||
virtual bool mergeWith(const QUndoCommand *other) override;
|
||||
|
||||
private:
|
||||
QHexMetadataItem m_old;
|
||||
|
|
|
@ -19,12 +19,7 @@
|
|||
** =============================================================================
|
||||
*/
|
||||
|
||||
#include "baseaddrcommand.h"
|
||||
#include "undocommandbase.h"
|
||||
|
||||
BaseAddrCommand::BaseAddrCommand(QHexDocument *doc, quint64 oldaddr,
|
||||
quint64 newaddr, QUndoCommand *parent)
|
||||
: QUndoCommand(parent), m_doc(doc), m_old(oldaddr), m_new(newaddr) {}
|
||||
|
||||
void BaseAddrCommand::redo() { m_doc->setBaseAddress(m_new); }
|
||||
|
||||
void BaseAddrCommand::undo() { m_doc->setBaseAddress(m_old); }
|
||||
UndoCommandBase::UndoCommandBase(const QString &text, QUndoCommand *parent)
|
||||
: QUndoCommand(text, parent) {}
|
|
@ -19,23 +19,31 @@
|
|||
** =============================================================================
|
||||
*/
|
||||
|
||||
#ifndef BASEADDRCOMMAND_H
|
||||
#define BASEADDRCOMMAND_H
|
||||
#ifndef UNDOCOMMANDBASE_H
|
||||
#define UNDOCOMMANDBASE_H
|
||||
|
||||
#include "document/qhexdocument.h"
|
||||
#include <QUndoCommand>
|
||||
|
||||
class BaseAddrCommand : public QUndoCommand {
|
||||
class UndoCommandBase : public QUndoCommand {
|
||||
public:
|
||||
BaseAddrCommand(QHexDocument *doc, quint64 oldaddr, quint64 newaddr,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
void redo() override;
|
||||
void undo() override;
|
||||
|
||||
private:
|
||||
QHexDocument *m_doc;
|
||||
quint64 m_old, m_new;
|
||||
enum UndoCommandID {
|
||||
UndoID_BookMarkAdd,
|
||||
UndoID_BookMarkClear,
|
||||
UndoID_BookMarkRemove,
|
||||
UndoID_BookMarkReplace,
|
||||
UndoID_HexAppend,
|
||||
UndoID_HexReplaceInsert,
|
||||
UndoID_HexRemove,
|
||||
UndoID_MetaAdd,
|
||||
UndoID_MetaClear,
|
||||
UndoID_MetaRemove,
|
||||
UndoID_MetaRemovePos,
|
||||
UndoID_MetaReplace
|
||||
};
|
||||
|
||||
#endif // BASEADDRCOMMAND_H
|
||||
public:
|
||||
explicit UndoCommandBase(const QString &text,
|
||||
QUndoCommand *parent = nullptr);
|
||||
};
|
||||
|
||||
#endif // UNDOCOMMANDBASE_H
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
#include "qhexdocument.h"
|
||||
#include "buffer/qfilebuffer.h"
|
||||
#include "commands/baseaddrcommand.h"
|
||||
#include "commands/bookmark/bookmarkaddcommand.h"
|
||||
#include "commands/bookmark/bookmarkclearcommand.h"
|
||||
#include "commands/bookmark/bookmarkremovecommand.h"
|
||||
|
@ -221,8 +220,6 @@ void QHexDocument::removeBookMarkAdjustRevert(
|
|||
|
||||
bool QHexDocument::isDocSaved() { return m_undostack->isClean(); }
|
||||
|
||||
bool QHexDocument::isUndoByteModified() { return m_bytesModFlag > 0; }
|
||||
|
||||
void QHexDocument::setDocSaved(bool b) {
|
||||
if (b) {
|
||||
m_undostack->setClean();
|
||||
|
@ -677,20 +674,16 @@ char QHexDocument::at(qsizetype offset) const {
|
|||
return char(m_buffer->at(offset));
|
||||
}
|
||||
|
||||
void QHexDocument::SetBaseAddress(quint64 baseaddress) {
|
||||
m_undostack->push(new BaseAddrCommand(this, m_baseaddress, baseaddress));
|
||||
bool QHexDocument::setBaseAddress(quint64 baseaddress) {
|
||||
if (m_baseaddress == baseaddress) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void QHexDocument::setBaseAddress(quint64 baseaddress) {
|
||||
if (m_baseaddress == baseaddress)
|
||||
return;
|
||||
|
||||
m_baseaddress = baseaddress;
|
||||
Q_EMIT documentChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
void QHexDocument::sync() { Q_EMIT documentChanged(); }
|
||||
|
||||
void QHexDocument::undo() {
|
||||
m_undostack->undo();
|
||||
Q_EMIT documentChanged();
|
||||
|
@ -904,3 +897,5 @@ QHexDocument *QHexDocument::fromLargeFile(const QString &filename,
|
|||
}
|
||||
|
||||
QHexBuffer *QHexDocument::buffer() const { return m_buffer; }
|
||||
|
||||
QUndoStack *QHexDocument::undoStack() const { return m_undostack; }
|
||||
|
|
|
@ -32,8 +32,6 @@
|
|||
class QHexDocument : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
friend class HexCommand;
|
||||
|
||||
private:
|
||||
explicit QHexDocument(QHexBuffer *buffer,
|
||||
bool readonly = false); // modified by wingsummer
|
||||
|
@ -113,7 +111,6 @@ public:
|
|||
const std::function<bool()> &pred = [] { return true; });
|
||||
|
||||
bool isDocSaved();
|
||||
bool isUndoByteModified();
|
||||
void setDocSaved(bool b = true);
|
||||
|
||||
void setMetafgVisible(bool b);
|
||||
|
@ -137,9 +134,7 @@ public:
|
|||
QByteArray read(qsizetype offset, qsizetype len = -1) const;
|
||||
|
||||
char at(qsizetype offset) const;
|
||||
void SetBaseAddress(quintptr baseaddress);
|
||||
void setBaseAddress(quintptr baseaddress);
|
||||
void sync();
|
||||
bool setBaseAddress(quintptr baseaddress);
|
||||
|
||||
public slots:
|
||||
void undo();
|
||||
|
@ -247,6 +242,8 @@ public:
|
|||
|
||||
QHexBuffer *buffer() const;
|
||||
|
||||
QUndoStack *undoStack() const;
|
||||
|
||||
signals:
|
||||
|
||||
/*================================*/
|
||||
|
@ -277,7 +274,6 @@ private:
|
|||
QHexMetadata *m_metadata;
|
||||
|
||||
QUndoStack *m_undostack;
|
||||
size_t m_bytesModFlag = 0;
|
||||
|
||||
quintptr m_baseaddress;
|
||||
quint8 m_areaindent;
|
||||
|
|
|
@ -32,37 +32,7 @@
|
|||
#include <QUndoStack>
|
||||
#include <QVector>
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
using qhash_result_t = uint;
|
||||
|
||||
// copying from QT6 source code for supporting QT5's qHashMulti
|
||||
namespace QtPrivate {
|
||||
template <typename T>
|
||||
inline constexpr bool QNothrowHashableHelper_v =
|
||||
noexcept(qHash(std::declval<const T &>()));
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct QNothrowHashable : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct QNothrowHashable<T, std::enable_if_t<QNothrowHashableHelper_v<T>>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
constexpr inline bool QNothrowHashable_v = QNothrowHashable<T>::value;
|
||||
|
||||
} // namespace QtPrivate
|
||||
|
||||
template <typename... T>
|
||||
constexpr qhash_result_t
|
||||
qHashMulti(qhash_result_t seed, const T &...args) noexcept(
|
||||
std::conjunction_v<QtPrivate::QNothrowHashable<T>...>) {
|
||||
QtPrivate::QHashCombine hash;
|
||||
return ((seed = hash(seed, args)), ...), seed;
|
||||
}
|
||||
#else
|
||||
using qhash_result_t = size_t;
|
||||
#endif
|
||||
|
||||
struct QHexMetadataItem : QHexRegionObject<qsizetype, QHexMetadataItem> {
|
||||
QColor foreground, background;
|
||||
|
@ -96,24 +66,7 @@ public:
|
|||
if (sel.foreground == this->foreground &&
|
||||
sel.background == this->background &&
|
||||
sel.comment == this->comment) {
|
||||
if (canMerge(sel)) {
|
||||
if (locker) {
|
||||
locker->lock();
|
||||
}
|
||||
|
||||
if (!this->contains(sel)) {
|
||||
if (this->begin < sel.end) {
|
||||
this->begin = qMin(this->begin, next(sel.begin));
|
||||
this->end = qMax(next(this->end), sel.end);
|
||||
} else {
|
||||
this->begin = qMin(next(this->begin), sel.begin);
|
||||
this->end = qMax(this->end, next(sel.end));
|
||||
}
|
||||
}
|
||||
|
||||
if (locker) {
|
||||
locker->unlock();
|
||||
}
|
||||
if (mergeRegionWithoutMetaCheck(sel, locker)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return false;
|
||||
|
@ -130,6 +83,18 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool mergeRegionWithoutMetaCheck(const QHexMetadataItem &sel,
|
||||
QMutex *locker = nullptr) {
|
||||
Q_ASSERT(sel.foreground == this->foreground &&
|
||||
sel.background == this->background &&
|
||||
sel.comment == this->comment);
|
||||
auto ret = Super::mergeRegion(sel, locker);
|
||||
if (std::holds_alternative<bool>(ret)) {
|
||||
return std::get<bool>(ret);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
inline qhash_result_t qHash(const QHexMetadataItem &c,
|
||||
|
|
|
@ -101,7 +101,7 @@ void QHexView::setHeaderVisible(bool b) {
|
|||
quintptr QHexView::addressBase() { return m_document->baseAddress(); }
|
||||
|
||||
void QHexView::setAddressBase(quintptr base) {
|
||||
m_document->SetBaseAddress(base);
|
||||
m_document->setBaseAddress(base);
|
||||
}
|
||||
|
||||
bool QHexView::isSaved() { return m_document->isDocSaved(); }
|
||||
|
@ -109,7 +109,7 @@ bool QHexView::isSaved() { return m_document->isDocSaved(); }
|
|||
QFont QHexView::getHexeditorFont() {
|
||||
QFont f = QFontDatabase::systemFont(QFontDatabase::FixedFont);
|
||||
if (f.styleHint() != QFont::TypeWriter) {
|
||||
f.setFamily("Monospace"); // Force Monospaced font
|
||||
f.setFamily(QStringLiteral("Monospace")); // Force Monospaced font
|
||||
f.setStyleHint(QFont::TypeWriter);
|
||||
}
|
||||
return f;
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit cdaf256c8a44e724cc295e5b23cc291ac2414c02
|
||||
Subproject commit 3fa9d2ba9d7dd78f719c43b482a5e7f49f135f1c
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +1,20 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify it under
|
||||
** the terms of the GNU Affero General Public License as published by the Free
|
||||
** Software Foundation, version 3.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
** details.
|
||||
**
|
||||
** You should have received a copy of the GNU Affero General Public License
|
||||
** along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#include "crashhandler.h"
|
||||
#include "angelscript.h"
|
||||
#include "class/pluginsystem.h"
|
||||
|
|
|
@ -1,3 +1,20 @@
|
|||
/*==============================================================================
|
||||
** Copyright (C) 2024-2027 WingSummer
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify it under
|
||||
** the terms of the GNU Affero General Public License as published by the Free
|
||||
** Software Foundation, version 3.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
** details.
|
||||
**
|
||||
** You should have received a copy of the GNU Affero General Public License
|
||||
** along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
** =============================================================================
|
||||
*/
|
||||
|
||||
#include "dockcomponentsfactory.h"
|
||||
|
||||
#include "DockWidget.h"
|
||||
|
|
|
@ -1241,11 +1241,11 @@ bool PluginSystem::switchDocument(const QObject *sender, int handle) {
|
|||
}
|
||||
|
||||
if (handle < 0) {
|
||||
m_plgCurrentfid[plg] = -1;
|
||||
m_plgviewMap[plg].currentFID = -1;
|
||||
} else {
|
||||
auto ctx = pluginContextById(plg, handle);
|
||||
if (ctx) {
|
||||
m_plgCurrentfid[plg] = handle;
|
||||
m_plgviewMap[plg].currentFID = handle;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -1421,14 +1421,26 @@ bool PluginSystem::beginMarco(const QObject *sender, const QString &txt) {
|
|||
return false;
|
||||
}
|
||||
|
||||
auto fid = m_plgCurrentfid[plg];
|
||||
auto fid = m_plgviewMap[plg].currentFID;
|
||||
if (fid < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto r = pluginContextById(plg, fid);
|
||||
if (r) {
|
||||
r->cmd = new QUndoCommand(txt);
|
||||
auto &u = m_viewBindings[r->view];
|
||||
|
||||
auto rtxt = txt.trimmed();
|
||||
if (rtxt.isEmpty()) {
|
||||
rtxt = _pinfos.value(plg).id;
|
||||
}
|
||||
|
||||
if (u.undoStackPlg.isEmpty()) {
|
||||
u.undoStackPlg.append(qMakePair(new QUndoCommand(rtxt), plg));
|
||||
} else {
|
||||
u.undoStackPlg.append(qMakePair(
|
||||
new QUndoCommand(rtxt, u.undoStackPlg.last().first), plg));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1443,22 +1455,104 @@ bool PluginSystem::endMarco(const QObject *sender) {
|
|||
return false;
|
||||
}
|
||||
|
||||
auto fid = m_plgCurrentfid[plg];
|
||||
auto fid = m_plgviewMap[plg].currentFID;
|
||||
if (fid < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto r = pluginContextById(plg, fid);
|
||||
if (r) {
|
||||
if (r->cmd) {
|
||||
auto &u = m_viewBindings[r->view];
|
||||
auto &undo = u.undoStackPlg;
|
||||
|
||||
if (undo.isEmpty()) {
|
||||
return false;
|
||||
} else {
|
||||
auto &l = undo.last();
|
||||
if (l.second != plg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto r = std::find_if(
|
||||
undo.rbegin(), undo.rend(),
|
||||
[plg](const QPair<QUndoCommand *, IWingPlugin *> &ctx) {
|
||||
return ctx.second == plg;
|
||||
});
|
||||
|
||||
if (r == undo.rend()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (r != undo.rbegin()) {
|
||||
Logger::warning(tr("UnexpectedUndoCmdPushDetected"));
|
||||
undo.erase(r.base(), undo.end());
|
||||
}
|
||||
|
||||
auto cmdl = undo.takeLast();
|
||||
if (undo.isEmpty()) {
|
||||
auto e = pluginCurrentEditor(plg);
|
||||
if (e) {
|
||||
if (e == nullptr) {
|
||||
return false;
|
||||
}
|
||||
auto doc = e->hexEditor()->document();
|
||||
doc->pushMakeUndo(r->cmd);
|
||||
r->cmd = nullptr;
|
||||
doc->pushMakeUndo(cmdl.first);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PluginSystem::isMacroEmpty(const QObject *sender) {
|
||||
auto plg = checkPluginAndReport(sender, __func__);
|
||||
if (plg == nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (passByFailedGuard(sender, __func__, {})) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto fid = m_plgviewMap[plg].currentFID;
|
||||
if (fid < 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto r = pluginContextById(plg, fid);
|
||||
if (r) {
|
||||
auto &u = m_viewBindings[r->view];
|
||||
auto &undo = u.undoStackPlg;
|
||||
return undo.isEmpty();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PluginSystem::resetMarco(const QObject *sender) {
|
||||
auto plg = checkPluginAndReport(sender, __func__);
|
||||
if (plg == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (passByFailedGuard(sender, __func__, {})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto fid = m_plgviewMap[plg].currentFID;
|
||||
if (fid < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto r = pluginContextById(plg, fid);
|
||||
if (r) {
|
||||
auto &u = m_viewBindings[r->view];
|
||||
auto &undo = u.undoStackPlg;
|
||||
if (!undo.isEmpty()) {
|
||||
delete undo.first().first;
|
||||
undo.clear();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1620,7 +1714,7 @@ bool PluginSystem::writeString(const QObject *sender, qsizetype offset,
|
|||
auto doc = editor->document();
|
||||
|
||||
auto unicode = Utilities::encodingString(value, encoding);
|
||||
auto uc = pluginCurrentUndoCmd(plg);
|
||||
auto uc = currentUndoCmd(e);
|
||||
auto cmd = doc->MakeReplace(uc, editor->cursor(), offset, unicode);
|
||||
if (uc == nullptr && cmd) {
|
||||
_rwlock.lockForWrite();
|
||||
|
@ -1647,7 +1741,7 @@ bool PluginSystem::writeBytes(const QObject *sender, qsizetype offset,
|
|||
if (e) {
|
||||
auto editor = e->hexEditor();
|
||||
auto doc = editor->document();
|
||||
auto uc = pluginCurrentUndoCmd(plg);
|
||||
auto uc = currentUndoCmd(e);
|
||||
auto cmd = doc->MakeReplace(uc, editor->cursor(), offset, data);
|
||||
if (uc == nullptr && cmd) {
|
||||
_rwlock.lockForWrite();
|
||||
|
@ -1816,7 +1910,7 @@ bool PluginSystem::insertString(const QObject *sender, qsizetype offset,
|
|||
auto doc = editor->document();
|
||||
|
||||
auto unicode = Utilities::encodingString(value, encoding);
|
||||
auto uc = pluginCurrentUndoCmd(plg);
|
||||
auto uc = currentUndoCmd(e);
|
||||
auto cmd = doc->MakeInsert(uc, editor->cursor(), offset, unicode);
|
||||
if (uc == nullptr && cmd) {
|
||||
_rwlock.lockForWrite();
|
||||
|
@ -1843,7 +1937,7 @@ bool PluginSystem::insertBytes(const QObject *sender, qsizetype offset,
|
|||
if (e) {
|
||||
auto editor = e->hexEditor();
|
||||
auto doc = editor->document();
|
||||
auto uc = pluginCurrentUndoCmd(plg);
|
||||
auto uc = currentUndoCmd(e);
|
||||
auto cmd = doc->MakeInsert(uc, editor->cursor(), offset, data);
|
||||
if (uc == nullptr && cmd) {
|
||||
_rwlock.lockForWrite();
|
||||
|
@ -1998,7 +2092,7 @@ bool PluginSystem::appendString(const QObject *sender, const QString &value,
|
|||
auto offset = doc->length();
|
||||
|
||||
auto unicode = Utilities::encodingString(value, encoding);
|
||||
auto uc = pluginCurrentUndoCmd(plg);
|
||||
auto uc = currentUndoCmd(e);
|
||||
auto cmd = doc->MakeInsert(uc, editor->cursor(), offset, unicode);
|
||||
if (uc == nullptr && cmd) {
|
||||
_rwlock.lockForWrite();
|
||||
|
@ -2024,7 +2118,7 @@ bool PluginSystem::appendBytes(const QObject *sender, const QByteArray &data) {
|
|||
if (e) {
|
||||
auto editor = e->hexEditor();
|
||||
auto doc = editor->document();
|
||||
auto uc = pluginCurrentUndoCmd(plg);
|
||||
auto uc = currentUndoCmd(e);
|
||||
auto cmd = doc->MakeAppend(uc, editor->cursor(), data);
|
||||
if (uc == nullptr && cmd) {
|
||||
_rwlock.lockForWrite();
|
||||
|
@ -2052,7 +2146,7 @@ bool PluginSystem::removeBytes(const QObject *sender, qsizetype offset,
|
|||
auto editor = e->hexEditor();
|
||||
auto doc = editor->document();
|
||||
|
||||
auto uc = pluginCurrentUndoCmd(plg);
|
||||
auto uc = currentUndoCmd(e);
|
||||
auto cmd = doc->MakeRemove(uc, editor->cursor(), offset, len);
|
||||
if (uc == nullptr && cmd) {
|
||||
_rwlock.lockForWrite();
|
||||
|
@ -2195,7 +2289,7 @@ bool PluginSystem::metadata(const QObject *sender, qsizetype begin,
|
|||
if (e) {
|
||||
auto doc = e->hexEditor()->document();
|
||||
|
||||
auto uc = pluginCurrentUndoCmd(plg);
|
||||
auto uc = currentUndoCmd(e);
|
||||
auto cmd = doc->metadata()->MakeMetadata(uc, begin, begin + length - 1,
|
||||
fgcolor, bgcolor, comment);
|
||||
if (uc == nullptr && cmd) {
|
||||
|
@ -2223,7 +2317,7 @@ bool PluginSystem::removeMetadata(const QObject *sender, qsizetype offset) {
|
|||
auto e = pluginCurrentEditor(plg);
|
||||
if (e) {
|
||||
auto doc = e->hexEditor()->document();
|
||||
auto uc = pluginCurrentUndoCmd(plg);
|
||||
auto uc = currentUndoCmd(e);
|
||||
auto cmd = doc->metadata()->MakeRemoveMetadata(uc, offset);
|
||||
if (uc == nullptr && cmd) {
|
||||
doc->pushMakeUndo(cmd);
|
||||
|
@ -2250,7 +2344,7 @@ bool PluginSystem::clearMetadata(const QObject *sender) {
|
|||
auto e = pluginCurrentEditor(plg);
|
||||
if (e) {
|
||||
auto doc = e->hexEditor()->document();
|
||||
auto uc = pluginCurrentUndoCmd(plg);
|
||||
auto uc = currentUndoCmd(e);
|
||||
auto cmd = doc->metadata()->MakeClear(uc);
|
||||
if (uc == nullptr && cmd) {
|
||||
doc->pushMakeUndo(cmd);
|
||||
|
@ -2372,7 +2466,7 @@ bool PluginSystem::addBookMark(const QObject *sender, qsizetype pos,
|
|||
auto e = pluginCurrentEditor(plg);
|
||||
if (e) {
|
||||
auto doc = e->hexEditor()->document();
|
||||
auto uc = pluginCurrentUndoCmd(plg);
|
||||
auto uc = currentUndoCmd(e);
|
||||
auto cmd = doc->MakeAddBookMark(uc, pos, comment);
|
||||
if (uc == nullptr && cmd) {
|
||||
doc->pushMakeUndo(cmd);
|
||||
|
@ -2400,7 +2494,7 @@ bool PluginSystem::modBookMark(const QObject *sender, qsizetype pos,
|
|||
auto e = pluginCurrentEditor(plg);
|
||||
if (e) {
|
||||
auto doc = e->hexEditor()->document();
|
||||
auto uc = pluginCurrentUndoCmd(plg);
|
||||
auto uc = currentUndoCmd(e);
|
||||
auto cmd = doc->MakeModBookMark(uc, pos, comment);
|
||||
if (uc == nullptr && cmd) {
|
||||
doc->pushMakeUndo(cmd);
|
||||
|
@ -2427,7 +2521,7 @@ bool PluginSystem::removeBookMark(const QObject *sender, qsizetype pos) {
|
|||
auto e = pluginCurrentEditor(plg);
|
||||
if (e) {
|
||||
auto doc = e->hexEditor()->document();
|
||||
auto uc = pluginCurrentUndoCmd(plg);
|
||||
auto uc = currentUndoCmd(e);
|
||||
auto cmd = doc->MakeRemoveBookMark(uc, pos);
|
||||
if (uc == nullptr && cmd) {
|
||||
doc->pushMakeUndo(cmd);
|
||||
|
@ -2454,7 +2548,7 @@ bool PluginSystem::clearBookMark(const QObject *sender) {
|
|||
auto e = pluginCurrentEditor(plg);
|
||||
if (e) {
|
||||
auto doc = e->hexEditor()->document();
|
||||
auto uc = pluginCurrentUndoCmd(plg);
|
||||
auto uc = currentUndoCmd(e);
|
||||
auto cmd = doc->MakeClearBookMark(uc);
|
||||
if (uc == nullptr && cmd) {
|
||||
doc->pushMakeUndo(cmd);
|
||||
|
@ -2478,11 +2572,12 @@ bool PluginSystem::closeAllFiles(const QObject *sender) {
|
|||
return false;
|
||||
}
|
||||
|
||||
auto &maps = m_plgviewMap[plg];
|
||||
auto &map = m_plgviewMap[plg];
|
||||
auto &maps = map.contexts;
|
||||
for (auto &item : maps) {
|
||||
closeEditor(plg, getUIDHandle(item->fid), true);
|
||||
}
|
||||
m_plgCurrentfid[plg] = -1;
|
||||
map.currentFID = -1;
|
||||
maps.clear();
|
||||
return true;
|
||||
}
|
||||
|
@ -2690,7 +2785,7 @@ ErrFile PluginSystem::closeCurrent(const QObject *sender, bool force) {
|
|||
return _win->closeEditor(view, force);
|
||||
}
|
||||
|
||||
ErrFile PluginSystem::openCurrent(const QObject *sender) {
|
||||
int PluginSystem::openCurrent(const QObject *sender) {
|
||||
if (!checkThreadAff()) {
|
||||
return ErrFile::NotAllowedInNoneGUIThread;
|
||||
}
|
||||
|
@ -2710,16 +2805,14 @@ ErrFile PluginSystem::openCurrent(const QObject *sender) {
|
|||
return ErrFile::AlreadyOpened;
|
||||
}
|
||||
|
||||
auto id = assginHandleForPluginView(plg, view);
|
||||
auto handle = getUIDHandle(id);
|
||||
m_plgCurrentfid[plg] = handle;
|
||||
auto id = assginHandleForOpenPluginView(plg, view);
|
||||
|
||||
PluginSystem::instance().dispatchEvent(
|
||||
IWingPlugin::RegisteredEvent::PluginFileOpened,
|
||||
{quintptr(plg), view->fileName(), handle,
|
||||
{quintptr(plg), view->fileName(), id,
|
||||
QVariant::fromValue(_win->getEditorViewFileType(view))});
|
||||
|
||||
return ErrFile(handle);
|
||||
return id;
|
||||
}
|
||||
return ErrFile::Error;
|
||||
}
|
||||
|
@ -2778,7 +2871,7 @@ ErrFile PluginSystem::exportFile(const QObject *sender, int handle,
|
|||
return ErrFile::NotExist;
|
||||
}
|
||||
|
||||
ErrFile PluginSystem::openWorkSpace(const QObject *sender,
|
||||
int PluginSystem::openWorkSpace(const QObject *sender,
|
||||
const QString &filename) {
|
||||
if (!checkThreadAff()) {
|
||||
return ErrFile::NotAllowedInNoneGUIThread;
|
||||
|
@ -2803,16 +2896,14 @@ ErrFile PluginSystem::openWorkSpace(const QObject *sender,
|
|||
checkPluginHasAlreadyOpened(plg, view)) {
|
||||
return ErrFile::AlreadyOpened;
|
||||
}
|
||||
auto id = assginHandleForPluginView(plg, view);
|
||||
auto handle = getUIDHandle(id);
|
||||
m_plgCurrentfid[plg] = handle;
|
||||
auto id = assginHandleForOpenPluginView(plg, view);
|
||||
|
||||
PluginSystem::instance().dispatchEvent(
|
||||
IWingPlugin::RegisteredEvent::PluginFileOpened,
|
||||
{quintptr(plg), filename, handle,
|
||||
{quintptr(plg), filename, id,
|
||||
QVariant::fromValue(_win->getEditorViewFileType(view))});
|
||||
|
||||
return ErrFile(handle);
|
||||
return id;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
|
@ -2884,7 +2975,7 @@ ErrFile PluginSystem::closeHandle(const QObject *sender, int handle) {
|
|||
return WingHex::ErrFile::NotExist;
|
||||
}
|
||||
|
||||
ErrFile PluginSystem::openExtFile(const QObject *sender, const QString &ext,
|
||||
int PluginSystem::openExtFile(const QObject *sender, const QString &ext,
|
||||
const QString &file) {
|
||||
if (!checkThreadAff()) {
|
||||
return ErrFile::NotAllowedInNoneGUIThread;
|
||||
|
@ -2909,22 +3000,20 @@ ErrFile PluginSystem::openExtFile(const QObject *sender, const QString &ext,
|
|||
checkPluginHasAlreadyOpened(plg, view)) {
|
||||
return ErrFile::AlreadyOpened;
|
||||
}
|
||||
auto id = assginHandleForPluginView(plg, view);
|
||||
auto handle = getUIDHandle(id);
|
||||
m_plgCurrentfid[plg] = handle;
|
||||
auto id = assginHandleForOpenPluginView(plg, view);
|
||||
|
||||
PluginSystem::instance().dispatchEvent(
|
||||
IWingPlugin::RegisteredEvent::PluginFileOpened,
|
||||
{quintptr(plg), file, handle,
|
||||
{quintptr(plg), file, id,
|
||||
QVariant::fromValue(_win->getEditorViewFileType(view))});
|
||||
|
||||
return ErrFile(handle);
|
||||
return id;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ErrFile PluginSystem::openFile(const QObject *sender, const QString &filename) {
|
||||
int PluginSystem::openFile(const QObject *sender, const QString &filename) {
|
||||
if (!checkThreadAff()) {
|
||||
return ErrFile::NotAllowedInNoneGUIThread;
|
||||
}
|
||||
|
@ -2948,21 +3037,19 @@ ErrFile PluginSystem::openFile(const QObject *sender, const QString &filename) {
|
|||
checkPluginHasAlreadyOpened(plg, view)) {
|
||||
return ErrFile::AlreadyOpened;
|
||||
}
|
||||
auto id = assginHandleForPluginView(plg, view);
|
||||
auto handle = getUIDHandle(id);
|
||||
m_plgCurrentfid[plg] = handle;
|
||||
auto id = assginHandleForOpenPluginView(plg, view);
|
||||
PluginSystem::instance().dispatchEvent(
|
||||
IWingPlugin::RegisteredEvent::PluginFileOpened,
|
||||
{quintptr(plg), filename, handle,
|
||||
{quintptr(plg), filename, id,
|
||||
QVariant::fromValue(_win->getEditorViewFileType(view))});
|
||||
|
||||
return ErrFile(handle);
|
||||
return id;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ErrFile PluginSystem::newFile(const QObject *sender) {
|
||||
int PluginSystem::newFile(const QObject *sender) {
|
||||
if (!checkThreadAff()) {
|
||||
return ErrFile::NotAllowedInNoneGUIThread;
|
||||
}
|
||||
|
@ -2981,18 +3068,17 @@ ErrFile PluginSystem::newFile(const QObject *sender) {
|
|||
}
|
||||
auto view = _win->newfileGUI();
|
||||
if (view) {
|
||||
auto id = assginHandleForPluginView(plg, view);
|
||||
auto handle = getUIDHandle(id);
|
||||
m_plgCurrentfid[plg] = handle;
|
||||
auto id = assginHandleForOpenPluginView(plg, view);
|
||||
m_plgviewMap[plg].currentFID = id;
|
||||
|
||||
PluginSystem::instance().dispatchEvent(
|
||||
IWingPlugin::RegisteredEvent::PluginFileOpened,
|
||||
{quintptr(plg),
|
||||
{},
|
||||
handle,
|
||||
id,
|
||||
QVariant::fromValue(_win->getEditorViewFileType(view))});
|
||||
|
||||
return ErrFile(handle);
|
||||
return id;
|
||||
} else {
|
||||
return ErrFile::Error;
|
||||
}
|
||||
|
@ -3196,11 +3282,8 @@ EditorView *PluginSystem::getCurrentPluginView(IWingPlugin *plg) {
|
|||
if (plg == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!m_plgCurrentfid.contains(plg)) {
|
||||
m_plgCurrentfid.insert(plg, -1);
|
||||
}
|
||||
|
||||
auto fid = m_plgCurrentfid[plg];
|
||||
auto fid = m_plgviewMap[plg].currentFID;
|
||||
auto ctx = pluginContextById(plg, fid);
|
||||
if (ctx) {
|
||||
return ctx->view;
|
||||
|
@ -3236,8 +3319,8 @@ void PluginSystem::retranslateMetadata(IWingPluginBase *plg, PluginInfo &meta) {
|
|||
meta.license = plg->retranslate(meta.license);
|
||||
}
|
||||
|
||||
PluginSystem::SharedUniqueId
|
||||
PluginSystem::assginHandleForPluginView(IWingPlugin *plg, EditorView *view) {
|
||||
int PluginSystem::assginHandleForOpenPluginView(IWingPlugin *plg,
|
||||
EditorView *view) {
|
||||
if (plg == nullptr || view == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
@ -3249,9 +3332,13 @@ PluginSystem::assginHandleForPluginView(IWingPlugin *plg, EditorView *view) {
|
|||
context->linkedplg = plg;
|
||||
context->view = view;
|
||||
|
||||
m_plgviewMap[plg].append(context);
|
||||
m_viewBindings[view].append(plg);
|
||||
return id;
|
||||
auto handle = getUIDHandle(id);
|
||||
|
||||
m_plgviewMap[plg].currentFID = handle;
|
||||
m_plgviewMap[plg].contexts.append(context);
|
||||
m_viewBindings[view].linkedplg.append(plg);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
PluginInfo PluginSystem::parsePluginMetadata(const QJsonObject &meta) {
|
||||
|
@ -3329,12 +3416,12 @@ bool PluginSystem::checkPluginCanOpenedFile(IWingPlugin *plg) {
|
|||
if (plg == nullptr) {
|
||||
return false;
|
||||
}
|
||||
return m_plgviewMap[plg].size() <= UCHAR_MAX;
|
||||
return m_plgviewMap[plg].contexts.size() <= UCHAR_MAX;
|
||||
}
|
||||
|
||||
bool PluginSystem::checkPluginHasAlreadyOpened(IWingPlugin *plg,
|
||||
EditorView *view) {
|
||||
auto &maps = m_plgviewMap[plg];
|
||||
auto &maps = m_plgviewMap[plg].contexts;
|
||||
auto ret =
|
||||
std::find_if(maps.begin(), maps.end(),
|
||||
[view](const QSharedPointer<PluginFileContext> &content) {
|
||||
|
@ -3348,35 +3435,15 @@ void PluginSystem::cleanUpEditorViewHandle(EditorView *view) {
|
|||
auto v = m_viewBindings[view];
|
||||
|
||||
// clean up
|
||||
for (auto &plg : v) {
|
||||
for (auto &plg : v.linkedplg) {
|
||||
auto &handles = m_plgviewMap[plg];
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
handles.erase(std::remove_if(
|
||||
handles.begin(), handles.end(),
|
||||
[view, this](const QSharedPointer<PluginFileContext> &v) {
|
||||
auto id = handles.currentFID;
|
||||
handles.contexts.removeIf(
|
||||
[view, this, id,
|
||||
plg](const QSharedPointer<PluginFileContext> &v) {
|
||||
if (v->view == view) {
|
||||
if (equalCompareHandle(v->fid,
|
||||
m_plgCurrentfid[v->linkedplg])) {
|
||||
m_plgCurrentfid[v->linkedplg] = -1;
|
||||
}
|
||||
dispatchEvent(
|
||||
IWingPlugin::RegisteredEvent::PluginFileClosed,
|
||||
{quintptr(v->linkedplg), v->view->fileName(),
|
||||
getUIDHandle(v->fid),
|
||||
QVariant::fromValue(
|
||||
_win->getEditorViewFileType(view))});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
|
||||
#else
|
||||
handles.removeIf(
|
||||
[view, this](const QSharedPointer<PluginFileContext> &v) {
|
||||
if (v->view == view) {
|
||||
if (equalCompareHandle(v->fid,
|
||||
m_plgCurrentfid[v->linkedplg])) {
|
||||
m_plgCurrentfid[v->linkedplg] = -1;
|
||||
if (equalCompareHandle(v->fid, id)) {
|
||||
m_plgviewMap[plg].currentFID = -1;
|
||||
}
|
||||
dispatchEvent(
|
||||
IWingPlugin::RegisteredEvent::PluginFileClosed,
|
||||
|
@ -3388,7 +3455,6 @@ void PluginSystem::cleanUpEditorViewHandle(EditorView *view) {
|
|||
}
|
||||
return false;
|
||||
});
|
||||
#endif
|
||||
}
|
||||
m_viewBindings.remove(view);
|
||||
}
|
||||
|
@ -3396,7 +3462,8 @@ void PluginSystem::cleanUpEditorViewHandle(EditorView *view) {
|
|||
|
||||
bool PluginSystem::closeEditor(IWingPlugin *plg, int handle, bool force) {
|
||||
if (handle >= 0) {
|
||||
auto &handles = m_plgviewMap[plg];
|
||||
auto &vm = m_plgviewMap[plg];
|
||||
auto &handles = vm.contexts;
|
||||
auto r = std::find_if(
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
handles.cbegin(), handles.cend(),
|
||||
|
@ -3411,15 +3478,16 @@ bool PluginSystem::closeEditor(IWingPlugin *plg, int handle, bool force) {
|
|||
}
|
||||
auto sharedc = *r;
|
||||
|
||||
auto &bind = m_viewBindings[sharedc->view];
|
||||
auto &vb = m_viewBindings[sharedc->view];
|
||||
auto &bind = vb.linkedplg;
|
||||
bind.removeOne(plg);
|
||||
if (bind.isEmpty()) {
|
||||
_win->closeEditor(sharedc->view, force);
|
||||
m_viewBindings.remove(sharedc->view);
|
||||
}
|
||||
|
||||
if (m_plgCurrentfid[plg] == handle) {
|
||||
m_plgCurrentfid[plg] = -1;
|
||||
if (vm.currentFID == handle) {
|
||||
vm.currentFID = -1;
|
||||
}
|
||||
|
||||
handles.erase(r);
|
||||
|
@ -3434,7 +3502,8 @@ bool PluginSystem::closeHandle(IWingPlugin *plg, int handle) {
|
|||
if (handle < 0) {
|
||||
return false;
|
||||
}
|
||||
auto &handles = m_plgviewMap[plg];
|
||||
auto &vm = m_plgviewMap[plg];
|
||||
auto &handles = vm.contexts;
|
||||
auto r = std::find_if(
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
handles.cbegin(), handles.cend(),
|
||||
|
@ -3449,14 +3518,14 @@ bool PluginSystem::closeHandle(IWingPlugin *plg, int handle) {
|
|||
}
|
||||
auto sharedc = *r;
|
||||
|
||||
auto &bind = m_viewBindings[sharedc->view];
|
||||
auto &bind = m_viewBindings[sharedc->view].linkedplg;
|
||||
bind.removeOne(plg);
|
||||
if (bind.isEmpty()) {
|
||||
m_viewBindings.remove(sharedc->view);
|
||||
}
|
||||
|
||||
if (m_plgCurrentfid[plg] == handle) {
|
||||
m_plgCurrentfid[plg] = -1;
|
||||
if (vm.currentFID == handle) {
|
||||
vm.currentFID = -1;
|
||||
}
|
||||
handles.erase(r);
|
||||
return true;
|
||||
|
@ -3949,7 +4018,6 @@ void PluginSystem::loadPlugin(IWingPlugin *p, PluginInfo &meta,
|
|||
|
||||
// prepare for file contenxt
|
||||
m_plgviewMap.insert(p, {});
|
||||
m_plgCurrentfid.insert(p, -1);
|
||||
} catch (const QString &error) {
|
||||
Logger::critical(error);
|
||||
if (p_tr) {
|
||||
|
@ -4323,7 +4391,7 @@ void PluginSystem::destory() {
|
|||
|
||||
EditorView *PluginSystem::pluginCurrentEditor(IWingPlugin *plg) const {
|
||||
if (plg) {
|
||||
auto fid = m_plgCurrentfid[plg];
|
||||
auto fid = m_plgviewMap[plg].currentFID;
|
||||
if (fid < 0) {
|
||||
return _win->currentEditor();
|
||||
}
|
||||
|
@ -4336,12 +4404,23 @@ EditorView *PluginSystem::pluginCurrentEditor(IWingPlugin *plg) const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
QUndoCommand *PluginSystem::currentUndoCmd(EditorView *view) {
|
||||
if (m_viewBindings.contains(view)) {
|
||||
auto &vb = m_viewBindings[view];
|
||||
auto &undo = vb.undoStackPlg;
|
||||
if (!undo.isEmpty()) {
|
||||
return undo.last().first;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QSharedPointer<PluginSystem::PluginFileContext>
|
||||
PluginSystem::pluginContextById(IWingPlugin *plg, int fid) const {
|
||||
if (fid < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
auto &handles = m_plgviewMap[plg];
|
||||
auto &handles = m_plgviewMap[plg].contexts;
|
||||
auto r = std::find_if(handles.begin(), handles.end(),
|
||||
[fid](const QSharedPointer<PluginFileContext> &d) {
|
||||
return equalCompareHandle(d->fid, fid);
|
||||
|
@ -4351,18 +4430,3 @@ PluginSystem::pluginContextById(IWingPlugin *plg, int fid) const {
|
|||
}
|
||||
return *r;
|
||||
}
|
||||
|
||||
QUndoCommand *PluginSystem::pluginCurrentUndoCmd(IWingPlugin *plg) const {
|
||||
if (plg) {
|
||||
auto fid = m_plgCurrentfid[plg];
|
||||
if (fid < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto ctx = pluginContextById(plg, fid);
|
||||
if (ctx) {
|
||||
return ctx->cmd;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -118,12 +118,22 @@ private:
|
|||
SharedUniqueId fid;
|
||||
EditorView *view = nullptr;
|
||||
IWingPlugin *linkedplg = nullptr;
|
||||
QUndoCommand *cmd = nullptr;
|
||||
};
|
||||
|
||||
~PluginFileContext() {
|
||||
if (cmd) {
|
||||
delete cmd;
|
||||
struct PluginFile {
|
||||
QVector<QSharedPointer<PluginFileContext>> contexts;
|
||||
int currentFID = -1;
|
||||
};
|
||||
|
||||
struct ViewBind {
|
||||
QList<IWingPlugin *> linkedplg;
|
||||
QList<QPair<QUndoCommand *, IWingPlugin *>> undoStackPlg;
|
||||
|
||||
~ViewBind() {
|
||||
if (!undoStackPlg.isEmpty()) {
|
||||
delete undoStackPlg.first().first;
|
||||
}
|
||||
undoStackPlg.clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -194,8 +204,7 @@ private:
|
|||
|
||||
EditorView *handle2EditorView(IWingPlugin *plg, int handle);
|
||||
|
||||
SharedUniqueId assginHandleForPluginView(IWingPlugin *plg,
|
||||
EditorView *view);
|
||||
int assginHandleForOpenPluginView(IWingPlugin *plg, EditorView *view);
|
||||
|
||||
static bool equalCompareHandle(const SharedUniqueId &id, int handle);
|
||||
|
||||
|
@ -226,7 +235,7 @@ private:
|
|||
QSharedPointer<PluginFileContext> pluginContextById(IWingPlugin *plg,
|
||||
int fid) const;
|
||||
|
||||
QUndoCommand *pluginCurrentUndoCmd(IWingPlugin *plg) const;
|
||||
QUndoCommand *currentUndoCmd(EditorView *view);
|
||||
|
||||
private:
|
||||
void loadPlugin(IWingPlugin *p, PluginInfo &meta,
|
||||
|
@ -274,7 +283,7 @@ private:
|
|||
auto e = getCurrentPluginView(plg);
|
||||
if (e) {
|
||||
return EditorView::insertBasicTypeContent<T>(
|
||||
e, offset, value, pluginCurrentUndoCmd(plg), _rwlock);
|
||||
e, offset, value, currentUndoCmd(e), _rwlock);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -286,7 +295,7 @@ private:
|
|||
auto e = getCurrentPluginView(plg);
|
||||
if (e) {
|
||||
return EditorView::writeBasicTypeContent<T>(
|
||||
e, offset, value, pluginCurrentUndoCmd(plg), _rwlock);
|
||||
e, offset, value, currentUndoCmd(e), _rwlock);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -297,7 +306,7 @@ private:
|
|||
auto e = getCurrentPluginView(plg);
|
||||
if (e) {
|
||||
return EditorView::appendBasicTypeContent<T>(
|
||||
e, value, pluginCurrentUndoCmd(plg), _rwlock);
|
||||
e, value, currentUndoCmd(e), _rwlock);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -518,6 +527,10 @@ public slots:
|
|||
|
||||
WING_API bool endMarco(const QObject *sender);
|
||||
|
||||
WING_API bool isMacroEmpty(const QObject *sender);
|
||||
|
||||
WING_API bool resetMarco(const QObject *sender);
|
||||
|
||||
WING_API bool writeInt8(const QObject *sender, qsizetype offset,
|
||||
qint8 value);
|
||||
|
||||
|
@ -648,16 +661,14 @@ public slots:
|
|||
WING_API bool setMetaCommentVisible(const QObject *sender, bool b);
|
||||
|
||||
// mainwindow
|
||||
WING_API WingHex::ErrFile newFile(const QObject *sender);
|
||||
WING_API int newFile(const QObject *sender);
|
||||
|
||||
WING_API WingHex::ErrFile openFile(const QObject *sender,
|
||||
const QString &filename);
|
||||
WING_API int openFile(const QObject *sender, const QString &filename);
|
||||
|
||||
WING_API WingHex::ErrFile
|
||||
openExtFile(const QObject *sender, const QString &ext, const QString &file);
|
||||
WING_API int openExtFile(const QObject *sender, const QString &ext,
|
||||
const QString &file);
|
||||
|
||||
WING_API WingHex::ErrFile openWorkSpace(const QObject *sender,
|
||||
const QString &filename);
|
||||
WING_API int openWorkSpace(const QObject *sender, const QString &filename);
|
||||
|
||||
WING_API WingHex::ErrFile closeHandle(const QObject *sender, int handle);
|
||||
|
||||
|
@ -672,7 +683,7 @@ public slots:
|
|||
WING_API WingHex::ErrFile saveAsFile(const QObject *sender, int handle,
|
||||
const QString &savename);
|
||||
|
||||
WING_API WingHex::ErrFile openCurrent(const QObject *sender);
|
||||
WING_API int openCurrent(const QObject *sender);
|
||||
|
||||
WING_API WingHex::ErrFile closeCurrent(const QObject *sender, bool force);
|
||||
|
||||
|
@ -729,10 +740,8 @@ private:
|
|||
|
||||
QMap<IWingPlugin::RegisteredEvent, QList<IWingPlugin *>> _evplgs;
|
||||
|
||||
QHash<IWingPlugin *, QVector<QSharedPointer<PluginFileContext>>>
|
||||
m_plgviewMap;
|
||||
QHash<IWingPlugin *, int> m_plgCurrentfid; // fid
|
||||
QHash<EditorView *, QList<IWingPlugin *>> m_viewBindings;
|
||||
QHash<IWingPlugin *, PluginFile> m_plgviewMap;
|
||||
QHash<EditorView *, ViewBind> m_viewBindings;
|
||||
|
||||
UniqueIdGenerator m_idGen;
|
||||
|
||||
|
|
|
@ -722,6 +722,12 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
|
|||
registerAPI(engine,
|
||||
asMETHODPR(WingHex::IWingPlugin, endMarco, (void), bool),
|
||||
"bool endMarco()");
|
||||
registerAPI(engine,
|
||||
asMETHODPR(WingHex::IWingPlugin, isMacroEmpty, (void), bool),
|
||||
"bool isMacroEmpty()");
|
||||
registerAPI(engine,
|
||||
asMETHODPR(WingHex::IWingPlugin, resetMarco, (void), bool),
|
||||
"bool resetMarco()");
|
||||
|
||||
registerAPI(
|
||||
engine,
|
||||
|
@ -948,20 +954,18 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
|
|||
asMETHODPR(WingHex::IWingPlugin, setMetaCommentVisible, (bool), bool),
|
||||
"bool setMetaCommentVisible(bool b)");
|
||||
|
||||
registerAPI(engine,
|
||||
asMETHODPR(WingHex::IWingPlugin, newFile, (), WingHex::ErrFile),
|
||||
"ErrFile newFile()");
|
||||
registerAPI(engine, asMETHODPR(WingHex::IWingPlugin, newFile, (), int),
|
||||
"int newFile()");
|
||||
|
||||
registerAPI(engine,
|
||||
asMETHODPR(WingHex::IWingPlugin, openFile, (const QString &),
|
||||
WingHex::ErrFile),
|
||||
"ErrFile openFile(string &in filename)");
|
||||
registerAPI(
|
||||
engine,
|
||||
asMETHODPR(WingHex::IWingPlugin, openFile, (const QString &), int),
|
||||
"int openFile(string &in filename)");
|
||||
|
||||
registerAPI(engine,
|
||||
asMETHODPR(WingHex::IWingPlugin, openExtFile,
|
||||
(const QString &, const QString &),
|
||||
WingHex::ErrFile),
|
||||
"ErrFile openExtFile(string &in ext, string &in file)");
|
||||
(const QString &, const QString &), int),
|
||||
"int openExtFile(string &in ext, string &in file)");
|
||||
|
||||
registerAPI(engine,
|
||||
asMETHODPR(WingHex::IWingPlugin, closeFile, (int, bool),
|
||||
|
@ -988,10 +992,8 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
|
|||
(int, const QString &), WingHex::ErrFile),
|
||||
"ErrFile saveAsFile(int handle, string &in savename)");
|
||||
|
||||
registerAPI(
|
||||
engine,
|
||||
asMETHODPR(WingHex::IWingPlugin, openCurrent, (), WingHex::ErrFile),
|
||||
"ErrFile openCurrent()");
|
||||
registerAPI(engine, asMETHODPR(WingHex::IWingPlugin, openCurrent, (), int),
|
||||
"int openCurrent()");
|
||||
|
||||
registerAPI(engine,
|
||||
asMETHODPR(WingHex::IWingPlugin, closeCurrent, (bool),
|
||||
|
@ -1027,10 +1029,10 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
|
|||
asMETHODPR(WingHex::IWingPlugin, clearBookMark, (), bool),
|
||||
"bool clearBookMark()");
|
||||
|
||||
registerAPI(engine,
|
||||
asMETHODPR(WingHex::IWingPlugin, openWorkSpace,
|
||||
(const QString &), WingHex::ErrFile),
|
||||
"ErrFile openWorkSpace(string &in filename)");
|
||||
registerAPI(
|
||||
engine,
|
||||
asMETHODPR(WingHex::IWingPlugin, openWorkSpace, (const QString &), int),
|
||||
"int openWorkSpace(string &in filename)");
|
||||
|
||||
registerAPI(engine,
|
||||
asMETHODPR(WingHex::IWingPlugin, closeAllFiles, (), bool),
|
||||
|
|
|
@ -559,7 +559,7 @@ ErrFile EditorView::save(const QString &workSpaceName, const QString &path,
|
|||
}
|
||||
}
|
||||
|
||||
if (doc->isUndoByteModified() || m_fileName != fileName || isNewFile()) {
|
||||
if (!doc->isDocSaved() || m_fileName != fileName || isNewFile()) {
|
||||
if (m_docType == DocumentType::Extension) {
|
||||
if (_dev->isOpen()) {
|
||||
_dev->close();
|
||||
|
|
|
@ -238,7 +238,7 @@ private slots:
|
|||
WING_API bool existsServiceHost(QObject *caller, const QString &puid);
|
||||
|
||||
WING_API bool invokeServiceImpl(const QObject *sender, const QString &puid,
|
||||
const MetaCallInfo &infos);
|
||||
const WingHex::MetaCallInfo &infos);
|
||||
|
||||
private slots:
|
||||
WING_API QString currentDocFilename(QObject *caller);
|
||||
|
@ -544,6 +544,7 @@ private:
|
|||
GotoWidget *m_goto = nullptr;
|
||||
QWidget *m_hexContainer = nullptr;
|
||||
bool _hasRegistered = false;
|
||||
quintptr _oldbase = 0;
|
||||
|
||||
QHexView *m_hex = nullptr;
|
||||
QMenu *m_menu = nullptr;
|
||||
|
|
|
@ -198,7 +198,6 @@ MainWindow::MainWindow(SplashDialog *splash) : FramelessMainWindow() {
|
|||
m_toolBtneditors.value(ToolButtonIndex::EDITOR_VIEWS)->setEnabled(false);
|
||||
|
||||
// ok, preparing for starting...
|
||||
this->setWindowTitle(tr("WingHexExplorer"));
|
||||
this->setWindowIcon(Utilities::isRoot()
|
||||
? ICONRES(QStringLiteral("iconroot"))
|
||||
: ICONRES(QStringLiteral("icon")));
|
||||
|
@ -467,6 +466,7 @@ void MainWindow::buildUpDockSystem(QWidget *container) {
|
|||
m_metadatas->setModel(_metadataEmpty);
|
||||
m_aDelBookMark->setEnabled(false);
|
||||
m_aDelMetaData->setEnabled(false);
|
||||
_undoView->setStack(nullptr);
|
||||
}
|
||||
updateEditModeEnabled();
|
||||
});
|
||||
|
@ -570,6 +570,8 @@ void MainWindow::buildUpDockSystem(QWidget *container) {
|
|||
qApp->processEvents();
|
||||
buildUpDecodingStrShowDock(m_dock, ads::CenterDockWidgetArea, rightArea);
|
||||
qApp->processEvents();
|
||||
buildUpUndoStackDock(m_dock, ads::CenterDockWidgetArea, rightArea);
|
||||
qApp->processEvents();
|
||||
|
||||
ads::CDockAreaWidget *bottomRightArea;
|
||||
if (SettingManager::instance().scriptEnabled()) {
|
||||
|
@ -1113,6 +1115,16 @@ MainWindow::buildUpScriptBgOutputDock(ads::CDockManager *dock,
|
|||
return dock->addDockWidget(area, dw, areaw);
|
||||
}
|
||||
|
||||
ads::CDockAreaWidget *
|
||||
MainWindow::buildUpUndoStackDock(ads::CDockManager *dock,
|
||||
ads::DockWidgetArea area,
|
||||
ads::CDockAreaWidget *areaw) {
|
||||
_undoView = new QUndoView(this);
|
||||
auto dw = buildDockWidget(dock, QStringLiteral("UndoStack"),
|
||||
tr("UndoStack"), _undoView);
|
||||
return dock->addDockWidget(area, dw, areaw);
|
||||
}
|
||||
|
||||
RibbonTabContent *MainWindow::buildFilePage(RibbonTabContent *tab) {
|
||||
auto shortcuts = QKeySequences::instance();
|
||||
{
|
||||
|
@ -3218,7 +3230,7 @@ void MainWindow::connectEditorView(EditorView *editor) {
|
|||
auto total = hexeditor->selectionCount();
|
||||
if (m.exec()) {
|
||||
auto meta = doc->metadata();
|
||||
meta->beginMarco(QStringLiteral("OnMetaData"));
|
||||
meta->beginMarco(tr("[MetaAdd]"));
|
||||
for (int i = 0; i < total; ++i) {
|
||||
auto begin = cur->selectionStart(i).offset();
|
||||
auto end = cur->selectionEnd(i).offset();
|
||||
|
@ -3345,6 +3357,15 @@ void MainWindow::swapEditor(EditorView *old, EditorView *cur) {
|
|||
connect(hexeditor, &QHexView::documentSaved, this, [this](bool b) {
|
||||
m_iSaved->setIcon(b ? _infoSaved : _infoUnsaved);
|
||||
m_sSaved->setIcon(b ? _infoSaved : _infoUnsaved);
|
||||
if (b) {
|
||||
auto cur = currentEditor();
|
||||
auto fn = cur->fileName();
|
||||
if (cur) {
|
||||
m_sSaved->setToolTip(fn);
|
||||
setWindowFilePath(QFileInfo(fn).fileName());
|
||||
updateWindowTitle();
|
||||
}
|
||||
}
|
||||
});
|
||||
connect(hexeditor, &QHexView::documentKeepSize, this, [this](bool b) {
|
||||
m_iCanOver->setIcon(b ? _infoCannotOver : _infoCanOver);
|
||||
|
@ -3409,6 +3430,8 @@ void MainWindow::swapEditor(EditorView *old, EditorView *cur) {
|
|||
m_metadatas->selectionModel()->hasSelection());
|
||||
});
|
||||
|
||||
_undoView->setStack(doc->undoStack());
|
||||
|
||||
m_curEditor = cur;
|
||||
hexeditor->getStatus();
|
||||
|
||||
|
@ -3417,6 +3440,17 @@ void MainWindow::swapEditor(EditorView *old, EditorView *cur) {
|
|||
{cur->fileName(), (old ? old->fileName() : QString())});
|
||||
}
|
||||
|
||||
void MainWindow::updateWindowTitle() {
|
||||
static auto title = tr("WingHexExplorer");
|
||||
auto fp = windowFilePath();
|
||||
if (fp.isEmpty()) {
|
||||
this->setWindowTitle(title);
|
||||
} else {
|
||||
QFileInfo info(fp);
|
||||
this->setWindowTitle(title + QStringLiteral(" - ") + info.fileName());
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::loadFindResult(EditorView *view) {
|
||||
auto result = view->findResultModel();
|
||||
m_findresult->setModel(result);
|
||||
|
@ -3672,11 +3706,15 @@ void MainWindow::updateEditModeEnabled() {
|
|||
doc->canRedo());
|
||||
m_toolBtneditors[ToolButtonIndex::UNDO_ACTION]->setEnabled(
|
||||
doc->canUndo());
|
||||
setWindowFilePath(editor->fileName());
|
||||
} else {
|
||||
m_lblloc->setText(QStringLiteral("(0,0)"));
|
||||
m_lblsellen->setText(QStringLiteral("0 - 0x0"));
|
||||
_numsitem->clear();
|
||||
setWindowFilePath({});
|
||||
}
|
||||
|
||||
updateWindowTitle();
|
||||
}
|
||||
|
||||
void MainWindow::setCurrentHexEditorScale(qreal rate) {
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <QTextBrowser>
|
||||
#include <QToolButton>
|
||||
#include <QTreeView>
|
||||
#include <QUndoView>
|
||||
#include <QtConcurrent/QtConcurrentRun>
|
||||
#include <QtEndian>
|
||||
|
||||
|
@ -44,7 +45,6 @@
|
|||
#include "Qt-Advanced-Docking-System/src/DockWidget.h"
|
||||
#include "WingPlugin/iwingplugin.h"
|
||||
#include "class/recentfilemanager.h"
|
||||
#include "class/scriptmanager.h"
|
||||
#include "control/editorview.h"
|
||||
#include "control/qtableviewext.h"
|
||||
#include "control/scriptingconsole.h"
|
||||
|
@ -122,6 +122,10 @@ private:
|
|||
buildUpScriptBgOutputDock(ads::CDockManager *dock, ads::DockWidgetArea area,
|
||||
ads::CDockAreaWidget *areaw = nullptr);
|
||||
|
||||
ads::CDockAreaWidget *
|
||||
buildUpUndoStackDock(ads::CDockManager *dock, ads::DockWidgetArea area,
|
||||
ads::CDockAreaWidget *areaw = nullptr);
|
||||
|
||||
RibbonTabContent *buildFilePage(RibbonTabContent *tab);
|
||||
RibbonTabContent *buildEditPage(RibbonTabContent *tab);
|
||||
RibbonTabContent *buildViewPage(RibbonTabContent *tab);
|
||||
|
@ -243,6 +247,7 @@ private:
|
|||
|
||||
void connectEditorView(EditorView *editor);
|
||||
void swapEditor(EditorView *old, EditorView *cur);
|
||||
void updateWindowTitle();
|
||||
|
||||
void loadFindResult(EditorView *view);
|
||||
|
||||
|
@ -496,6 +501,8 @@ private:
|
|||
QTableViewExt *m_metadatas = nullptr;
|
||||
MetaDataModel *_metadataEmpty = nullptr;
|
||||
|
||||
QUndoView *_undoView = nullptr;
|
||||
|
||||
QMap<ToolButtonIndex, QToolButton *> m_toolBtneditors;
|
||||
|
||||
QAction *m_aDelBookMark = nullptr;
|
||||
|
|
|
@ -86,7 +86,7 @@ ScriptingDialog::ScriptingDialog(QWidget *parent)
|
|||
m_Tbtneditors.value(ToolButtonIndex::EDITOR_VIEWS)->setEnabled(false);
|
||||
|
||||
// ok, preparing for starting...
|
||||
this->setWindowTitle(tr("ScriptEditor"));
|
||||
updateWindowTitle();
|
||||
this->setWindowIcon(ICONRES(QStringLiteral("script")));
|
||||
this->setMinimumSize(800, 600);
|
||||
|
||||
|
@ -833,6 +833,16 @@ void ScriptingDialog::updateEditModeEnabled() {
|
|||
item->setEnabled(b);
|
||||
}
|
||||
|
||||
if (b) {
|
||||
auto fn = editor->fileName();
|
||||
setWindowFilePath(fn);
|
||||
m_status->setToolTip(fn);
|
||||
} else {
|
||||
setWindowFilePath({});
|
||||
m_status->setToolTip({});
|
||||
m_status->clearMessage();
|
||||
}
|
||||
updateWindowTitle();
|
||||
updateRunDebugMode();
|
||||
}
|
||||
|
||||
|
@ -895,6 +905,17 @@ void ScriptingDialog::swapEditor(ScriptEditor *old, ScriptEditor *cur) {
|
|||
}
|
||||
}
|
||||
|
||||
void ScriptingDialog::updateWindowTitle() {
|
||||
auto title = tr("ScriptEditor");
|
||||
auto fp = windowFilePath();
|
||||
if (fp.isEmpty()) {
|
||||
this->setWindowTitle(title);
|
||||
} else {
|
||||
QFileInfo info(fp);
|
||||
this->setWindowTitle(title + QStringLiteral(" - ") + info.fileName());
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptingDialog::updateRunDebugMode(bool disable) {
|
||||
auto &runner = ScriptMachine::instance();
|
||||
auto enable = !disable;
|
||||
|
@ -1239,6 +1260,8 @@ void ScriptingDialog::on_save() {
|
|||
|
||||
auto res = editor->save();
|
||||
if (res) {
|
||||
setWindowFilePath(editor->fileName());
|
||||
updateWindowTitle();
|
||||
Toast::toast(this, NAMEICONRES(QStringLiteral("save")),
|
||||
tr("SaveSuccessfully"));
|
||||
} else {
|
||||
|
@ -1267,6 +1290,8 @@ void ScriptingDialog::on_saveas() {
|
|||
|
||||
auto res = editor->save(filename);
|
||||
if (res) {
|
||||
setWindowFilePath(editor->fileName());
|
||||
updateWindowTitle();
|
||||
Toast::toast(this, NAMEICONRES(QStringLiteral("saveas")),
|
||||
tr("SaveSuccessfully"));
|
||||
} else {
|
||||
|
|
|
@ -202,6 +202,7 @@ private:
|
|||
void updateEditModeEnabled();
|
||||
ScriptEditor *currentEditor() const;
|
||||
void swapEditor(ScriptEditor *old, ScriptEditor *cur);
|
||||
void updateWindowTitle();
|
||||
|
||||
void updateRunDebugMode(bool disable = false);
|
||||
|
||||
|
|
Loading…
Reference in New Issue