From a3b465534ced9eef43b10e7ad72d9bdffef424e8 Mon Sep 17 00:00:00 2001 From: wingsummer <1326224942@qq.com> Date: Sat, 5 Jul 2025 21:04:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=BC=95=E5=85=A5=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E6=92=A4=E9=94=80=E5=A0=86=E6=A0=88=E5=8F=AF=E8=A7=86=E5=8C=96?= =?UTF-8?q?=EF=BC=9B=E6=8F=92=E4=BB=B6=E4=B8=8D=E5=86=8D=E5=85=B7=E6=9C=89?= =?UTF-8?q?=E7=8B=AC=E7=AB=8B=E7=9A=84=E6=92=A4=E9=94=80=E5=A0=86=E6=A0=88?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3rdparty/QHexView/CMakeLists.txt | 4 +- .../commands/bookmark/bookmarkaddcommand.cpp | 16 +- .../commands/bookmark/bookmarkaddcommand.h | 21 +- .../bookmark/bookmarkclearcommand.cpp | 10 +- .../commands/bookmark/bookmarkclearcommand.h | 23 +- .../commands/bookmark/bookmarkcommand.cpp | 8 +- .../commands/bookmark/bookmarkcommand.h | 10 +- .../bookmark/bookmarkremovecommand.cpp | 15 +- .../commands/bookmark/bookmarkremovecommand.h | 22 +- .../bookmark/bookmarkreplacecommand.cpp | 17 +- .../bookmark/bookmarkreplacecommand.h | 21 +- .../document/commands/hex/appendcommand.cpp | 15 +- .../document/commands/hex/appendcommand.h | 18 +- .../document/commands/hex/hexcommand.cpp | 12 +- .../document/commands/hex/hexcommand.h | 12 +- .../document/commands/hex/insertcommand.cpp | 31 +- .../document/commands/hex/insertcommand.h | 20 +- .../document/commands/hex/removecommand.cpp | 29 +- .../document/commands/hex/removecommand.h | 18 +- .../document/commands/hex/replacecommand.cpp | 49 +- .../document/commands/hex/replacecommand.h | 20 +- .../document/commands/meta/metaaddcommand.cpp | 16 +- .../document/commands/meta/metaaddcommand.h | 16 +- .../commands/meta/metaclearcommand.cpp | 10 +- .../document/commands/meta/metaclearcommand.h | 26 +- .../document/commands/meta/metacommand.cpp | 6 +- .../document/commands/meta/metacommand.h | 11 +- .../commands/meta/metaremovecommand.cpp | 12 +- .../commands/meta/metaremovecommand.h | 16 +- .../commands/meta/metaremoveposcommand.cpp | 22 +- .../commands/meta/metaremoveposcommand.h | 26 +- .../commands/meta/metareplacecommand.cpp | 15 +- .../commands/meta/metareplacecommand.h | 19 +- ...aseaddrcommand.cpp => undocommandbase.cpp} | 11 +- .../{baseaddrcommand.h => undocommandbase.h} | 34 +- 3rdparty/QHexView/document/qhexdocument.cpp | 19 +- 3rdparty/QHexView/document/qhexdocument.h | 10 +- 3rdparty/QHexView/document/qhexmetadata.h | 61 +- 3rdparty/QHexView/qhexview.cpp | 4 +- WingPlugin | 2 +- lang/zh_CN/winghex_zh_CN.ts | 918 ++++++++++-------- lang/zh_TW/winghex_zh_TW.ts | 918 ++++++++++-------- src/class/crashhandler.cpp | 17 + src/class/dockcomponentsfactory.cpp | 17 + src/class/pluginsystem.cpp | 310 +++--- src/class/pluginsystem.h | 53 +- src/class/wingangelapi.cpp | 38 +- src/control/editorview.cpp | 2 +- src/control/editorview.h | 3 +- src/dialog/mainwindow.cpp | 42 +- src/dialog/mainwindow.h | 9 +- src/dialog/scriptingdialog.cpp | 27 +- src/dialog/scriptingdialog.h | 1 + 53 files changed, 1884 insertions(+), 1198 deletions(-) rename 3rdparty/QHexView/document/commands/{baseaddrcommand.cpp => undocommandbase.cpp} (73%) rename 3rdparty/QHexView/document/commands/{baseaddrcommand.h => undocommandbase.h} (62%) diff --git a/3rdparty/QHexView/CMakeLists.txt b/3rdparty/QHexView/CMakeLists.txt index a8b33f8..96fb4c0 100644 --- a/3rdparty/QHexView/CMakeLists.txt +++ b/3rdparty/QHexView/CMakeLists.txt @@ -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 diff --git a/3rdparty/QHexView/document/commands/bookmark/bookmarkaddcommand.cpp b/3rdparty/QHexView/document/commands/bookmark/bookmarkaddcommand.cpp index 0fa2bcf..e2443cf 100644 --- a/3rdparty/QHexView/document/commands/bookmark/bookmarkaddcommand.cpp +++ b/3rdparty/QHexView/document/commands/bookmark/bookmarkaddcommand.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(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); } diff --git a/3rdparty/QHexView/document/commands/bookmark/bookmarkaddcommand.h b/3rdparty/QHexView/document/commands/bookmark/bookmarkaddcommand.h index 2636376..fd769bc 100644 --- a/3rdparty/QHexView/document/commands/bookmark/bookmarkaddcommand.h +++ b/3rdparty/QHexView/document/commands/bookmark/bookmarkaddcommand.h @@ -24,13 +24,22 @@ #include "bookmarkcommand.h" -class BookMarkAddCommand : public BookMarkCommand { -public: - BookMarkAddCommand(QHexDocument *doc, qsizetype pos, QString comment, - QUndoCommand *parent = nullptr); +#include - void undo() override; - void redo() override; +class BookMarkAddCommand : public BookMarkCommand { + Q_DECLARE_TR_FUNCTIONS(BookMarkAddCommand) +public: + explicit BookMarkAddCommand(QHexDocument *doc, qsizetype pos, + QString comment, + 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 // BOOKMARKADDCOMMAND_H diff --git a/3rdparty/QHexView/document/commands/bookmark/bookmarkclearcommand.cpp b/3rdparty/QHexView/document/commands/bookmark/bookmarkclearcommand.cpp index 2716734..260f40a 100644 --- a/3rdparty/QHexView/document/commands/bookmark/bookmarkclearcommand.cpp +++ b/3rdparty/QHexView/document/commands/bookmark/bookmarkclearcommand.cpp @@ -24,8 +24,16 @@ BookMarkClearCommand::BookMarkClearCommand( QHexDocument *doc, const QMap &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); } diff --git a/3rdparty/QHexView/document/commands/bookmark/bookmarkclearcommand.h b/3rdparty/QHexView/document/commands/bookmark/bookmarkclearcommand.h index 8a65ec2..664ae49 100644 --- a/3rdparty/QHexView/document/commands/bookmark/bookmarkclearcommand.h +++ b/3rdparty/QHexView/document/commands/bookmark/bookmarkclearcommand.h @@ -22,19 +22,26 @@ #ifndef BOOKMARKCLEARCOMMAND_H #define BOOKMARKCLEARCOMMAND_H +#include "../undocommandbase.h" #include "document/qhexdocument.h" + +#include #include -#include -#include -class BookMarkClearCommand : public QUndoCommand { +class BookMarkClearCommand : public UndoCommandBase { + Q_DECLARE_TR_FUNCTIONS(BookMarkClearCommand) public: - BookMarkClearCommand(QHexDocument *doc, - const QMap &bookmarks, - QUndoCommand *parent = nullptr); + explicit BookMarkClearCommand(QHexDocument *doc, + const QMap &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; diff --git a/3rdparty/QHexView/document/commands/bookmark/bookmarkcommand.cpp b/3rdparty/QHexView/document/commands/bookmark/bookmarkcommand.cpp index 70dd068..42c2e50 100644 --- a/3rdparty/QHexView/document/commands/bookmark/bookmarkcommand.cpp +++ b/3rdparty/QHexView/document/commands/bookmark/bookmarkcommand.cpp @@ -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) {} diff --git a/3rdparty/QHexView/document/commands/bookmark/bookmarkcommand.h b/3rdparty/QHexView/document/commands/bookmark/bookmarkcommand.h index aee4456..7efbbd6 100644 --- a/3rdparty/QHexView/document/commands/bookmark/bookmarkcommand.h +++ b/3rdparty/QHexView/document/commands/bookmark/bookmarkcommand.h @@ -22,14 +22,14 @@ #ifndef BOOKMARKCOMMAND_H #define BOOKMARKCOMMAND_H +#include "../undocommandbase.h" #include "document/qhexdocument.h" -#include -#include -class BookMarkCommand : public QUndoCommand { +class BookMarkCommand : public UndoCommandBase { public: - BookMarkCommand(QHexDocument *doc, qsizetype pos, QString comment, - QUndoCommand *parent = nullptr); + explicit BookMarkCommand(const QString &text, QHexDocument *doc, + qsizetype pos, QString comment, + QUndoCommand *parent = nullptr); protected: QHexDocument *m_doc; diff --git a/3rdparty/QHexView/document/commands/bookmark/bookmarkremovecommand.cpp b/3rdparty/QHexView/document/commands/bookmark/bookmarkremovecommand.cpp index 4f0218f..ac04bb4 100644 --- a/3rdparty/QHexView/document/commands/bookmark/bookmarkremovecommand.cpp +++ b/3rdparty/QHexView/document/commands/bookmark/bookmarkremovecommand.cpp @@ -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(other); + if (ucmd) { + if (this->m_pos == ucmd->m_pos) { + return true; + } + } + return false; +} + void BookMarkRemoveCommand::undo() { m_doc->addBookMark(m_pos, m_comment); } diff --git a/3rdparty/QHexView/document/commands/bookmark/bookmarkremovecommand.h b/3rdparty/QHexView/document/commands/bookmark/bookmarkremovecommand.h index 3cd5874..fff8a50 100644 --- a/3rdparty/QHexView/document/commands/bookmark/bookmarkremovecommand.h +++ b/3rdparty/QHexView/document/commands/bookmark/bookmarkremovecommand.h @@ -24,13 +24,23 @@ #include "bookmarkcommand.h" -class BookMarkRemoveCommand : public BookMarkCommand { -public: - BookMarkRemoveCommand(QHexDocument *doc, qsizetype pos, QString comment, - QUndoCommand *parent = nullptr); +#include - void undo() override; - void redo() override; +class BookMarkRemoveCommand : public BookMarkCommand { + Q_DECLARE_TR_FUNCTIONS(BookMarkRemoveCommand) + +public: + explicit BookMarkRemoveCommand(QHexDocument *doc, qsizetype pos, + QString comment, + 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 // BOOKMARKREMOVECOMMAND_H diff --git a/3rdparty/QHexView/document/commands/bookmark/bookmarkreplacecommand.cpp b/3rdparty/QHexView/document/commands/bookmark/bookmarkreplacecommand.cpp index 69f8bd3..a0b6ee2 100644 --- a/3rdparty/QHexView/document/commands/bookmark/bookmarkreplacecommand.cpp +++ b/3rdparty/QHexView/document/commands/bookmark/bookmarkreplacecommand.cpp @@ -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(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); } diff --git a/3rdparty/QHexView/document/commands/bookmark/bookmarkreplacecommand.h b/3rdparty/QHexView/document/commands/bookmark/bookmarkreplacecommand.h index 7b88b69..2077428 100644 --- a/3rdparty/QHexView/document/commands/bookmark/bookmarkreplacecommand.h +++ b/3rdparty/QHexView/document/commands/bookmark/bookmarkreplacecommand.h @@ -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 - 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; diff --git a/3rdparty/QHexView/document/commands/hex/appendcommand.cpp b/3rdparty/QHexView/document/commands/hex/appendcommand.cpp index d147297..6074ac2 100644 --- a/3rdparty/QHexView/document/commands/hex/appendcommand.cpp +++ b/3rdparty/QHexView/document/commands/hex/appendcommand.cpp @@ -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(other); + if (ucmd) { + this->m_data.append(ucmd->m_data); + return true; + } + return false; } diff --git a/3rdparty/QHexView/document/commands/hex/appendcommand.h b/3rdparty/QHexView/document/commands/hex/appendcommand.h index dc6346d..6c5e5cc 100644 --- a/3rdparty/QHexView/document/commands/hex/appendcommand.h +++ b/3rdparty/QHexView/document/commands/hex/appendcommand.h @@ -24,12 +24,22 @@ #include "hexcommand.h" +#include + 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 diff --git a/3rdparty/QHexView/document/commands/hex/hexcommand.cpp b/3rdparty/QHexView/document/commands/hex/hexcommand.cpp index 514fe96..9c4f8a8 100644 --- a/3rdparty/QHexView/document/commands/hex/hexcommand.cpp +++ b/3rdparty/QHexView/document/commands/hex/hexcommand.cpp @@ -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++; } diff --git a/3rdparty/QHexView/document/commands/hex/hexcommand.h b/3rdparty/QHexView/document/commands/hex/hexcommand.h index aa32697..24b9256 100644 --- a/3rdparty/QHexView/document/commands/hex/hexcommand.h +++ b/3rdparty/QHexView/document/commands/hex/hexcommand.h @@ -25,15 +25,13 @@ #include "document/qhexcursor.h" #include "document/qhexdocument.h" -#include +#include "document/commands/undocommandbase.h" -class HexCommand : public QUndoCommand { +class HexCommand : public UndoCommandBase { public: - HexCommand(QHexDocument *doc, QHexCursor *cursor, int nibbleindex, - QUndoCommand *parent = nullptr); - - void undo() override; - void redo() override; + explicit HexCommand(const QString &text, QHexDocument *doc, + QHexCursor *cursor, int nibbleindex, + QUndoCommand *parent = nullptr); protected: QHexDocument *m_doc; diff --git a/3rdparty/QHexView/document/commands/hex/insertcommand.cpp b/3rdparty/QHexView/document/commands/hex/insertcommand.cpp index b495788..9b279b7 100644 --- a/3rdparty/QHexView/document/commands/hex/insertcommand.cpp +++ b/3rdparty/QHexView/document/commands/hex/insertcommand.cpp @@ -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(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(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; } diff --git a/3rdparty/QHexView/document/commands/hex/insertcommand.h b/3rdparty/QHexView/document/commands/hex/insertcommand.h index 04b15b1..df62c53 100644 --- a/3rdparty/QHexView/document/commands/hex/insertcommand.h +++ b/3rdparty/QHexView/document/commands/hex/insertcommand.h @@ -24,13 +24,23 @@ #include "hexcommand.h" +#include + 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 diff --git a/3rdparty/QHexView/document/commands/hex/removecommand.cpp b/3rdparty/QHexView/document/commands/hex/removecommand.cpp index 3aa869f..bc241f1 100644 --- a/3rdparty/QHexView/document/commands/hex/removecommand.cpp +++ b/3rdparty/QHexView/document/commands/hex/removecommand.cpp @@ -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(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; } diff --git a/3rdparty/QHexView/document/commands/hex/removecommand.h b/3rdparty/QHexView/document/commands/hex/removecommand.h index 55a0520..6548280 100644 --- a/3rdparty/QHexView/document/commands/hex/removecommand.h +++ b/3rdparty/QHexView/document/commands/hex/removecommand.h @@ -24,13 +24,21 @@ #include "hexcommand.h" +#include + 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 _rmMetas; diff --git a/3rdparty/QHexView/document/commands/hex/replacecommand.cpp b/3rdparty/QHexView/document/commands/hex/replacecommand.cpp index 67e1593..b931d8f 100644 --- a/3rdparty/QHexView/document/commands/hex/replacecommand.cpp +++ b/3rdparty/QHexView/document/commands/hex/replacecommand.cpp @@ -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(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; } diff --git a/3rdparty/QHexView/document/commands/hex/replacecommand.h b/3rdparty/QHexView/document/commands/hex/replacecommand.h index 3652969..4306a7c 100644 --- a/3rdparty/QHexView/document/commands/hex/replacecommand.h +++ b/3rdparty/QHexView/document/commands/hex/replacecommand.h @@ -24,13 +24,23 @@ #include "hexcommand.h" +#include + 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; diff --git a/3rdparty/QHexView/document/commands/meta/metaaddcommand.cpp b/3rdparty/QHexView/document/commands/meta/metaaddcommand.cpp index 179ee70..b4cbc40 100644 --- a/3rdparty/QHexView/document/commands/meta/metaaddcommand.cpp +++ b/3rdparty/QHexView/document/commands/meta/metaaddcommand.cpp @@ -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(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) { diff --git a/3rdparty/QHexView/document/commands/meta/metaaddcommand.h b/3rdparty/QHexView/document/commands/meta/metaaddcommand.h index 1e23ae3..458b5a0 100644 --- a/3rdparty/QHexView/document/commands/meta/metaaddcommand.h +++ b/3rdparty/QHexView/document/commands/meta/metaaddcommand.h @@ -23,14 +23,22 @@ #define METAADDCOMMAND_H #include "metacommand.h" +#include #include class MetaAddCommand : public MetaCommand { + Q_DECLARE_TR_FUNCTIONS(MetaAddCommand) public: - MetaAddCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta, - QUndoCommand *parent = nullptr); - void undo() override; - void redo() override; + explicit MetaAddCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta, + 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 _brokenMetas; diff --git a/3rdparty/QHexView/document/commands/meta/metaclearcommand.cpp b/3rdparty/QHexView/document/commands/meta/metaclearcommand.cpp index d543ba5..088a2a4 100644 --- a/3rdparty/QHexView/document/commands/meta/metaclearcommand.cpp +++ b/3rdparty/QHexView/document/commands/meta/metaclearcommand.cpp @@ -24,8 +24,16 @@ MetaClearCommand::MetaClearCommand(QHexMetadata *hexmeta, const QVector &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); } diff --git a/3rdparty/QHexView/document/commands/meta/metaclearcommand.h b/3rdparty/QHexView/document/commands/meta/metaclearcommand.h index 1bd89cb..895f889 100644 --- a/3rdparty/QHexView/document/commands/meta/metaclearcommand.h +++ b/3rdparty/QHexView/document/commands/meta/metaclearcommand.h @@ -23,21 +23,27 @@ #define METACLEARCOMMAND_H #include "../../qhexmetadata.h" -#include -#include -#include -#include +#include "../undocommandbase.h" + +#include +#include // this class is newed by wingsummer -class MetaClearCommand : public QUndoCommand { +class MetaClearCommand : public UndoCommandBase { + Q_DECLARE_TR_FUNCTIONS(MetaClearCommand) public: - MetaClearCommand(QHexMetadata *hexmeta, - const QVector &metas, - QUndoCommand *parent = nullptr); + explicit MetaClearCommand(QHexMetadata *hexmeta, + const QVector &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; diff --git a/3rdparty/QHexView/document/commands/meta/metacommand.cpp b/3rdparty/QHexView/document/commands/meta/metacommand.cpp index 7af09b8..c9c0924 100644 --- a/3rdparty/QHexView/document/commands/meta/metacommand.cpp +++ b/3rdparty/QHexView/document/commands/meta/metacommand.cpp @@ -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) {} diff --git a/3rdparty/QHexView/document/commands/meta/metacommand.h b/3rdparty/QHexView/document/commands/meta/metacommand.h index cd10ece..9cc5d3a 100644 --- a/3rdparty/QHexView/document/commands/meta/metacommand.h +++ b/3rdparty/QHexView/document/commands/meta/metacommand.h @@ -22,17 +22,16 @@ #ifndef METACOMMAND_H #define METACOMMAND_H -#include -#include - #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, - QUndoCommand *parent = nullptr); + explicit MetaCommand(const QString &text, QHexMetadata *hexmeta, + const QHexMetadataItem &meta, + QUndoCommand *parent = nullptr); protected: QHexMetadata *m_hexmeta; diff --git a/3rdparty/QHexView/document/commands/meta/metaremovecommand.cpp b/3rdparty/QHexView/document/commands/meta/metaremovecommand.cpp index 41631b9..ac11dd9 100644 --- a/3rdparty/QHexView/document/commands/meta/metaremovecommand.cpp +++ b/3rdparty/QHexView/document/commands/meta/metaremovecommand.cpp @@ -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(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); diff --git a/3rdparty/QHexView/document/commands/meta/metaremovecommand.h b/3rdparty/QHexView/document/commands/meta/metaremovecommand.h index 79b72ed..7c84110 100644 --- a/3rdparty/QHexView/document/commands/meta/metaremovecommand.h +++ b/3rdparty/QHexView/document/commands/meta/metaremovecommand.h @@ -23,18 +23,26 @@ #define METAREMOVECOMMAND_H #include "metacommand.h" +#include #include #include // this class is newed by wingsummer class MetaRemoveCommand : public MetaCommand { + Q_DECLARE_TR_FUNCTIONS(MetaRemoveCommand) public: - MetaRemoveCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta, - QUndoCommand *parent = nullptr); + 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 diff --git a/3rdparty/QHexView/document/commands/meta/metaremoveposcommand.cpp b/3rdparty/QHexView/document/commands/meta/metaremoveposcommand.cpp index cc1f8c5..c33ac44 100644 --- a/3rdparty/QHexView/document/commands/meta/metaremoveposcommand.cpp +++ b/3rdparty/QHexView/document/commands/meta/metaremoveposcommand.cpp @@ -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(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); } diff --git a/3rdparty/QHexView/document/commands/meta/metaremoveposcommand.h b/3rdparty/QHexView/document/commands/meta/metaremoveposcommand.h index 122e38d..a5a2dff 100644 --- a/3rdparty/QHexView/document/commands/meta/metaremoveposcommand.h +++ b/3rdparty/QHexView/document/commands/meta/metaremoveposcommand.h @@ -22,24 +22,26 @@ #ifndef METAREMOVEPOSCOMMAND_H #define METAREMOVEPOSCOMMAND_H -#include "../../qhexmetadata.h" -#include -#include -#include -#include +#include "metacommand.h" -class MetaRemovePosCommand : public QUndoCommand { +#include + +class MetaRemovePosCommand : public MetaCommand { + Q_DECLARE_TR_FUNCTIONS(MetaRemovePosCommand) public: - MetaRemovePosCommand(QHexMetadata *hexmeta, qsizetype pos, - QUndoCommand *parent = nullptr); + 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 diff --git a/3rdparty/QHexView/document/commands/meta/metareplacecommand.cpp b/3rdparty/QHexView/document/commands/meta/metareplacecommand.cpp index b93d01e..e73e037 100644 --- a/3rdparty/QHexView/document/commands/meta/metareplacecommand.cpp +++ b/3rdparty/QHexView/document/commands/meta/metareplacecommand.cpp @@ -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(other); + if (ucmd) { + if (this->m_old == ucmd->m_old) { + this->m_meta = ucmd->m_meta; + return true; + } + } + return false; +} diff --git a/3rdparty/QHexView/document/commands/meta/metareplacecommand.h b/3rdparty/QHexView/document/commands/meta/metareplacecommand.h index 3600d55..a82682f 100644 --- a/3rdparty/QHexView/document/commands/meta/metareplacecommand.h +++ b/3rdparty/QHexView/document/commands/meta/metareplacecommand.h @@ -23,15 +23,24 @@ #define METAREPLACECOMMAND_H #include "metacommand.h" +#include #include class MetaReplaceCommand : public MetaCommand { + Q_DECLARE_TR_FUNCTIONS(MetaReplaceCommand) public: - MetaReplaceCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta, - const QHexMetadataItem &oldmeta, - QUndoCommand *parent = nullptr); - void undo() override; - void redo() override; + explicit MetaReplaceCommand(QHexMetadata *hexmeta, + const QHexMetadataItem &meta, + const QHexMetadataItem &oldmeta, + 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: QHexMetadataItem m_old; diff --git a/3rdparty/QHexView/document/commands/baseaddrcommand.cpp b/3rdparty/QHexView/document/commands/undocommandbase.cpp similarity index 73% rename from 3rdparty/QHexView/document/commands/baseaddrcommand.cpp rename to 3rdparty/QHexView/document/commands/undocommandbase.cpp index c368079..a09139b 100644 --- a/3rdparty/QHexView/document/commands/baseaddrcommand.cpp +++ b/3rdparty/QHexView/document/commands/undocommandbase.cpp @@ -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) {} diff --git a/3rdparty/QHexView/document/commands/baseaddrcommand.h b/3rdparty/QHexView/document/commands/undocommandbase.h similarity index 62% rename from 3rdparty/QHexView/document/commands/baseaddrcommand.h rename to 3rdparty/QHexView/document/commands/undocommandbase.h index f660693..c405032 100644 --- a/3rdparty/QHexView/document/commands/baseaddrcommand.h +++ b/3rdparty/QHexView/document/commands/undocommandbase.h @@ -19,23 +19,31 @@ ** ============================================================================= */ -#ifndef BASEADDRCOMMAND_H -#define BASEADDRCOMMAND_H +#ifndef UNDOCOMMANDBASE_H +#define UNDOCOMMANDBASE_H -#include "document/qhexdocument.h" #include -class BaseAddrCommand : public QUndoCommand { +class UndoCommandBase : public QUndoCommand { public: - BaseAddrCommand(QHexDocument *doc, quint64 oldaddr, quint64 newaddr, - QUndoCommand *parent = nullptr); + 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 + }; - void redo() override; - void undo() override; - -private: - QHexDocument *m_doc; - quint64 m_old, m_new; +public: + explicit UndoCommandBase(const QString &text, + QUndoCommand *parent = nullptr); }; -#endif // BASEADDRCOMMAND_H +#endif // UNDOCOMMANDBASE_H diff --git a/3rdparty/QHexView/document/qhexdocument.cpp b/3rdparty/QHexView/document/qhexdocument.cpp index 60aa451..0df0683 100644 --- a/3rdparty/QHexView/document/qhexdocument.cpp +++ b/3rdparty/QHexView/document/qhexdocument.cpp @@ -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)); -} - -void QHexDocument::setBaseAddress(quint64 baseaddress) { - if (m_baseaddress == baseaddress) - return; +bool QHexDocument::setBaseAddress(quint64 baseaddress) { + if (m_baseaddress == baseaddress) { + return false; + } 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; } diff --git a/3rdparty/QHexView/document/qhexdocument.h b/3rdparty/QHexView/document/qhexdocument.h index 0b9f02f..cee23d0 100644 --- a/3rdparty/QHexView/document/qhexdocument.h +++ b/3rdparty/QHexView/document/qhexdocument.h @@ -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 &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; diff --git a/3rdparty/QHexView/document/qhexmetadata.h b/3rdparty/QHexView/document/qhexmetadata.h index e400fcd..9d0c7a7 100644 --- a/3rdparty/QHexView/document/qhexmetadata.h +++ b/3rdparty/QHexView/document/qhexmetadata.h @@ -32,37 +32,7 @@ #include #include -#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 -inline constexpr bool QNothrowHashableHelper_v = - noexcept(qHash(std::declval())); - -template -struct QNothrowHashable : std::false_type {}; - -template -struct QNothrowHashable>> - : std::true_type {}; - -template -constexpr inline bool QNothrowHashable_v = QNothrowHashable::value; - -} // namespace QtPrivate - -template -constexpr qhash_result_t -qHashMulti(qhash_result_t seed, const T &...args) noexcept( - std::conjunction_v...>) { - QtPrivate::QHashCombine hash; - return ((seed = hash(seed, args)), ...), seed; -} -#else using qhash_result_t = size_t; -#endif struct QHexMetadataItem : QHexRegionObject { 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(ret)) { + return std::get(ret); + } + return false; + } }; inline qhash_result_t qHash(const QHexMetadataItem &c, diff --git a/3rdparty/QHexView/qhexview.cpp b/3rdparty/QHexView/qhexview.cpp index 2c58a96..295b1b8 100644 --- a/3rdparty/QHexView/qhexview.cpp +++ b/3rdparty/QHexView/qhexview.cpp @@ -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; diff --git a/WingPlugin b/WingPlugin index cdaf256..3fa9d2b 160000 --- a/WingPlugin +++ b/WingPlugin @@ -1 +1 @@ -Subproject commit cdaf256c8a44e724cc295e5b23cc291ac2414c02 +Subproject commit 3fa9d2ba9d7dd78f719c43b482a5e7f49f135f1c diff --git a/lang/zh_CN/winghex_zh_CN.ts b/lang/zh_CN/winghex_zh_CN.ts index 2ee3284..bc37fa7 100644 --- a/lang/zh_CN/winghex_zh_CN.ts +++ b/lang/zh_CN/winghex_zh_CN.ts @@ -89,6 +89,46 @@ 文件已被打开 + + AppendCommand + + + [HexAppend] + + + + + BookMarkAddCommand + + + [AddBookMark] pos: %1 + + + + + BookMarkClearCommand + + + [ClearBookMark] + + + + + BookMarkRemoveCommand + + + [RemoveBookMark] pos: %1 + + + + + BookMarkReplaceCommand + + + [ReplaceBookMark] pos: %1 + + + BookMarksModel @@ -768,6 +808,14 @@ 选择颜色 + + InsertCommand + + + [HexInsert] pos: %1 + + + InspectQtLogHelper @@ -847,24 +895,24 @@ MainWindow - + File 文件 - - + + View 视图 - + About 关于 - + WingHexExplorer 羽云十六进制编辑器 @@ -879,322 +927,322 @@ 选长: - + Edit 编辑 - + Script 脚本 - - - + + + Plugin 插件 - + Setting 设置 - - + + Log 日志 - + ExportFindResult 导出搜索结果 - + ClearFindResult 清空记录 - - + + FindResult 搜索结果 - - - - - - - + + + + + + + Copy 复制 - - - - - + + + + + CopyToClipBoard 数据已拷贝到粘贴板 - + LittleEndian 小端 - + BigEndian 大端 - + Number 数值 - - + + CheckSum 校验和 - - + + DeleteBookMark 删除书签 - - + + ClearBookMark 清空书签 - - - - + + + + BookMark 书签 - + DecodeText 解码字符串 - + ScriptConsole 脚本控制台 - - + + Basic 基础 - + New 新建 - + OpenF 打开文件 - + OpenWorkSpace 打开工作区 - + RecentFiles 最近打开 - - - + + + Reload 重新加载 - - + + Save 保存 - + SaveAs 另存为 - + ConvertWS 转为工作区 - + Export 导出 - + SaveSel 保存选区字节 - - - - + + + + General 基本 - + Undo 撤销 - + Redo 恢复 - + Cut 剪切 - + Paste 粘贴 - + Delete 删除 - + Clone 克隆 - + Lookup 查询 - + Find 查找 - + Goto 跳转 - - + + Encoding 编码 - + FileInfo 文件信息 - - + + Hex 十六进制 - + CutHex 剪切(十六进制) - + CopyHex 复制(十六进制) - + PasteHex 粘贴(十六进制) - - + + Fill 填充 - + FillZero 填充零 - - - - - + + + + + MetaData 标注 - + DeleteMetadata 删除标注 - + ClearMetadata 清空标注 - + MetaDataEdit 编辑标注 - + DeleteMetaData 删除标注 - + ClearMetaData 清空标注 - + Display 显示 - + ViewText 文本预览 - + Scale 缩放 @@ -1214,856 +1262,882 @@ 启动 Dock 服务 - + LaunchingLog 启动日志系统 - + SetupPluginSystem 启动插件系统 - + LoadingPlg: 加载插件中: - + SetupConsole 启动脚本控制台 - + SetupScriptManager 启动脚本管理器 - + SetupScriptService 启动脚本服务 - + SetupScriptEditor 构建脚本编辑器 - + SetupSetDialog 构建设置窗体 - + SetupPlgWidgets 启动插件组件 - + SetupDockingLayout 恢复 Dock 布局 - + SetupWaiting 启动即将完成 - + SetupFinished 启动完毕 - + NoExtension 无扩展 - - + + ExportResult 导出结果 - + NothingToSave 没有保存的数据 - + OpenExt 打开 - 拓展 - + ResetScale 重置缩放 - + ShowMetafg 标注前景色 - + ShowMetabg 标注背景色 - + ShowMetaComment 批注 - + MetaShowAll 显示所有标注 - + MetaHideAll 隐藏所有标注 - + FileStatus 文件状态 - + InfoSave 是否保存 - + ReadOnly 可读写 - + SetLocked 启用/禁用锁定编辑 - + ErrUnLock 锁定编辑失败 - + SetOver 启用/禁用改变大小 - + InputRequest 输入请求 - + ScriptEngineInitFailed 脚本引擎启动失败,将自动禁用该功能。 - + UnsignedHex 无符号 Hex - + BgScriptOutputHere 后台脚本执行将会在这里输出 - + SelectAll 全选 - - + + Clear 清空 - + AbortScript 终止脚本 - + BgScriptOutput 后台脚本输出 - + ErrUnOver 锁定文件大小失败 - + Window 窗体 - + Editor 编辑器 - + Tools 工具 - + HexEditorLayout 编辑器布局 - + SetBaseAddr 设置基址 - + addressBase 基址 - + inputAddressBase 请输入基址 - + WarnBigBaseAddress 基址过大,你得到的地址将会不正确! - + ErrBaseAddress 非法基址输入 - + SetColInfo 显示/隐藏地址栏 - + SetHeaderInfo 显示/隐藏表头 - + SetAsciiString 显示/隐藏解码字符串 - + Layout 布局 - + Fullscreen 全屏 - + Default 默认 - - - + + + LayoutRestoring... 恢复布局中... - + RestoreLayout 恢复布局 - - + + SaveLayout 保存布局 - - + + ExportLog 导出日志 - - + + ClearLog 清空日志 - + InsepctQt 监视 Qt - + ScriptEditor 脚本编辑器 - + Scripts 脚本仓库 - + PluginFunctions 插件功能 - + ScriptSetting 脚本设置 - + PluginSettings 插件设置 - + Info 信息 - + Software 软件 - + Sponsor 赞助 - + CheckUpdate 检查更新 - + Wiki 网页 Wiki - + EngineConfigError - + + UndoStack + + + + AboutQT 关于 QT - + SetPageIDEmptyTryUseName 设置页 ID 为空,尝试使用名称作为 ID - + SetPageDupNameIgnored 设置页重复的 ID 名称,已忽略加载 - + Plugin %1 contains a duplicate ID (%2) that is already registered by plugin %3 插件 %1 包含重复 ID (%2),该 ID 已被插件 %3 注册 - - + + ChooseFile 选择文件 - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + Error 错误 - - + + FileNotExist 文件不存在! - - - - - + + + + + FilePermission 因文件权限无法继续! - + ProjectFile (*.wingpro) 项目文件 (*.wingpro) - + ReloadSuccessfully 文件重新加载成功! - + ReloadUnSuccessfully 文件重新加载失败! - - - - + + + + ChooseSaveFile 请选择保存文件路径: - + PasteFailedNote 粘贴失败,请注意权限或者内容长度 - + NoMoreClone 克隆已到上限,无法继续操作! - + FindFininishBusy 查找任务繁忙,请勿重复查找! - + MayTooMuchFindResult 搜索数量已到达上限,结果可能不全,建议请按区段搜索。 - + SaveLayoutSuccess 保存布局成功 - + SaveLayoutError 保存布局失败 - + HasClonedView 该编辑页已被克隆编辑,如果关闭,相关联的页也会被关闭,你确认继续吗? - + + [MetaAdd] + + + + FileCloseBigFile 大文件读取模式下目标文件被关闭,该标签将会被关闭。 - - + + ReloadNeededYesOrNo 目标文件被修改,是否重新加载? - + SaveWorkSpace 保存工作区 - + WingHexWorkSpace (*.wingpro) 羽云十六进制工作区 (*.wingpro) - + ConfirmSave 正在关闭未保存的文件或工作区,你确定保存吗? - + [Info] 【信息】 - + [Warn] 【警告】 - + [Error] 【错误】 - + ConfirmAPPSave 你尝试关闭程序,但仍存在未保存的文件或工作区,你确定保存这些更改吗? - - - + + + SaveSuccessfully 保存成功! - - + + SaveWSError 保存工作区错误! - - + + Warn 警告 - + Opening... 打开文件中... - + WorkSpaceOpening... 打开工作区中... - + Reloading... 重载文件中... - + Saving... 保存中... - + SaveNewFirst 请首先保存新建的文件 - + AlreadyWorkSpace 已经是工作区,无需转化 - + ConvWorkSpaceFailed 转化为工作区失败 - + ConvWorkSpaceSuccess 转化为工作区成功 - + SavingAs... 另存为中... - + SaveUnSuccessfully 保存失败! - + Exporting... 导出中... - + ChooseExportFile 请选择导出文件路径: - + ExportSuccessfully 导出成功! - + ExportUnSuccessfully 导出失败! - + SavingSel... 保存选中字节中... - + SaveSelSuccess 保存选区字节成功! - + SaveSelError 保存选区字节失败,因文件不具有可写权限! - - + + CutToClipBoard 数据已剪切到粘贴板! - - + + UnCutToClipBoard 由于保持大小限制,数据剪切到粘贴板失败! - - + + UnCopyToClipBoard 由于保持大小限制,数据剪切到复制板失败! - - + + Finding... 查找中... - + DeleteSuccess 删除成功 - + DeleteFailed 删除失败 - + FindFininish 查找结果完毕! - + PleaseInputFill 请输入填充字节值 - + FillInputTruncWarn 填充输入数值过大,将会被截断填充 - + FillInputError 填充字节输入错误 - - + + InputComment 请输入批注: - - + + BookmarkDelSuccess 删除书签成功 - + BookmarkDelNoItem 无书签可删除 - + BookmarkClearSuccess 书签清空完毕 - - - + + + NoSelection 没有选区,无法继续的操作! - + NoMetaData 无可编辑标记 - + PleaseClearSel 请清空选择 - + MetaDelSuccess 元数据删除成功 - + MetaDelNoItem 无元数据可删除 - + MetaClearSuccess 元数据清空完毕 - + FindResultExporting... 查找结果导出中... - - + + EmptyFindResult 没有可导出的搜索结果! - + SaveFindResult 导出搜索结果成功! - + SaveFindResultError 导出结果失败! - + TooManyBytesDecode 超出解码字节限制…… - + NoTextFileMayInvalid 该文件不是文本文件,以文本方式预览并不是一个好的方式,你确认继续吗? - + LayoutSaving... 布局保存中... - - + + PleaseInput 请输入 - + LogExporting... 日志导出中... - + ExportLogError 导出日志失败! - + ExportLogSuccess 导出日志成功,路径: - + ClearLogSuccess 清空日志成功! - + BadNetwork 无法与远程服务器的更新检查建立连接,请检查网络。 - + NewestVersion 当前软件为最新版本 - - + + OlderVersion 你使用的软件为老版本,建议到 Github 和 Gitee 的仓库发行版下载更新。 - + CheckingUpdate 检查更新中…… - + Too much opened files 打开的文件过多,无法继续操作! - + FilePermissionSure2Quit 因文件权限无法保存,你确认要退出吗? - + UnknownErrorSure2Quit 因未知错误无法保存,你确认要退出吗? - + WorkSpaceUnSavedSure2Quit 工作区文件无法保存,你确认要退出吗? - + CopyLimit 拷贝字节超出限制 - + ErrOpenFileBelow 打开文件出现错误(由于权限不足),如下为打开错误的文件: + + MetaAddCommand + + + [MetaAdd] + + + + + MetaClearCommand + + + [MetaClear] + + + MetaDataModel @@ -2120,6 +2194,30 @@ 开启选项但未设置,如不想设置请关闭! + + MetaRemoveCommand + + + [MetaRemove] + + + + + MetaRemovePosCommand + + + [MetaRemovePos] + + + + + MetaReplaceCommand + + + [MetaReplace] + + + NumShowModel @@ -2307,173 +2405,178 @@ PluginSystem - + LoadingPlugin 加载插件中: - - + + InvalidPluginBrokenInfo 加载插件失败:损坏的插件数据 - - + + PluginBlockByManager - + AppClosingCanceled: 程序关闭被取消: - + - PluginID: - 插件 ID: - + FoundDrvPluginCount 总计发现设备拓展插件数目: - + PluginManagerNeedSingleton - - + + ErrLoadPluginSDKVersion 插件加载失败:非法插件 SDK 版本! - + ErrLoadPluginNoName 插件加载失败:非法插件名称! - - + + ErrLoadInitPlugin 插件加载失败:初始化插件失败! - + PluginName : 插件名: - + PluginAuthor : 插件作者: - + PluginWidgetRegister 注册插件对象中…… - + ExtPluginAuthor : 设备拓展插件作者: - + ExtPluginWidgetRegister 设备拓展注册插件对象中…… - + ErrLoadInitExtPlugin 设备拓展插件加载失败:初始化插件失败! - + ChooseFile 选择文件 - - + + Error 错误 - + FileNotExist 文件不存在! - + FilePermission 因文件权限无法继续! - + EmptyNameDockWidget: 空的贴边组件名: - + InvalidNameDockWidget: 无效贴边组件名: - + InvalidNullDockWidget: 无效空贴边组件: - + Not allowed operation in non-UI thread 该操作在非 UI 线程非法 - + + UnexpectedUndoCmdPushDetected + + + + UnsafePluginDir 不安全的插件目录,请将插件目录设置为仅管理员账户可写 - - + + InvalidPluginID 加载插件失败:非法插件标识符 - + InvalidDupPlugin 加载插件失败:重复的插件标识符 - + FoundPluginCount 总计发现插件数目: - + PluginLoadingFailedSummary 有依赖插件加载失败总结 - + - Dependencies: - 依赖: - + PUID: 插件唯一标志符: - + Version: 版本: - + PluginLoadingFinished 加载插件完毕! @@ -2797,6 +2900,23 @@ 打开历史记录完成! + + RemoveCommand + + + [HexRemove] pos: %1 + + + + + ReplaceCommand + + + + [HexReplace] pos: %1 + + + RibbonButtonGroup @@ -4592,7 +4712,7 @@ ScriptingDialog - + ScriptEditor 脚本编辑器 @@ -4653,7 +4773,7 @@ - + Reload 重新加载 @@ -4826,11 +4946,11 @@ - - - - - + + + + + Error 错误 @@ -4850,83 +4970,83 @@ 脚本保存失败,你仍确认关闭吗? - + ReloadNeededYesOrNo 目标文件被修改,是否重新加载? - + Debuging... 调试中... - + Running... 运行中... - + Line %1, Col %2 行 %1, 列 %2 - + (Selected: %1) (选中: %1) - - + + ChooseFile 选择文件 - - - + + + FilePermission 因文件权限无法继续! - + ReloadSuccessfully 文件重新加载成功! - + ReloadUnSuccessfully 文件重新加载失败! - + ChooseSaveFile 请选择保存文件路径: - - + + SaveSuccessfully 保存成功! - + SaveUnSuccessfully 保存失败! - + FormatCodeFailed 代码格式化失败 - - + + CannotSave2RunScript 无法保存,故无法继续运行脚本。 - + ScriptStillRunning 脚本仍在运行,你确定要退出吗? @@ -5256,18 +5376,18 @@ 为 AngelScript 脚本提供调用主机 API 能力的内部插件。 - + NotSupportedQMetaType: 不支持的 QT 数据元类型: - - + + Get Exception While ScriptCall: (%1) %2 脚本调用发生异常:(%1)%2 - + InvalidRetType: need 无效返回值:需要 @@ -5275,41 +5395,41 @@ WingCStruct - + WingCStruct 羽云文件结构分析器 - + Providing basic support for analyzing file structures 提供基础的文件结构分析支持 - - - - - - - - - - - - - + + + + + + + + + + + + + InvalidParamsCount 非法参数个数 - - - - - - - - + + + + + + + + InvalidParam 非法参数 diff --git a/lang/zh_TW/winghex_zh_TW.ts b/lang/zh_TW/winghex_zh_TW.ts index e31687d..28a901c 100644 --- a/lang/zh_TW/winghex_zh_TW.ts +++ b/lang/zh_TW/winghex_zh_TW.ts @@ -89,6 +89,46 @@ 檔已被打開 + + AppendCommand + + + [HexAppend] + + + + + BookMarkAddCommand + + + [AddBookMark] pos: %1 + + + + + BookMarkClearCommand + + + [ClearBookMark] + + + + + BookMarkRemoveCommand + + + [RemoveBookMark] pos: %1 + + + + + BookMarkReplaceCommand + + + [ReplaceBookMark] pos: %1 + + + BookMarksModel @@ -768,6 +808,14 @@ 選擇顏色 + + InsertCommand + + + [HexInsert] pos: %1 + + + InspectQtLogHelper @@ -847,24 +895,24 @@ MainWindow - + File - - + + View 視圖 - + About 關於 - + WingHexExplorer 羽雲十六進制編輯器 @@ -879,322 +927,322 @@ 選長: - + Edit 編輯 - + Script 腳本 - - - + + + Plugin 插件 - + Setting 設置 - - + + Log 日誌 - + ExportFindResult 導出搜索結果 - + ClearFindResult 清空記錄 - - + + FindResult 搜索結果 - - - - - - - + + + + + + + Copy 複製 - - - - - + + + + + CopyToClipBoard 數據已拷貝到粘貼板 - + LittleEndian 小端 - + BigEndian 大端 - + Number 數值 - - + + CheckSum 校驗和 - - + + DeleteBookMark 刪除書簽 - - + + ClearBookMark 清空書簽 - - - - + + + + BookMark 書簽 - + DecodeText 解碼字串 - + ScriptConsole 腳本控制臺 - - + + Basic 基礎 - + New 新建 - + OpenF 打開檔 - + OpenWorkSpace 打開工作區 - + RecentFiles 最近打開 - - - + + + Reload 重新加載 - - + + Save 保存 - + SaveAs 另存為 - + ConvertWS 轉為工作區 - + Export 導出 - + SaveSel 保存選區位元組 - - - - + + + + General 基本 - + Undo 撤銷 - + Redo 恢復 - + Cut 剪切 - + Paste 粘貼 - + Delete 刪除 - + Clone 克隆 - + Lookup 查詢 - + Find 查找 - + Goto 跳轉 - - + + Encoding 編碼 - + FileInfo 檔資訊 - - + + Hex 十六進制 - + CutHex 剪切(十六進制) - + CopyHex 複製(十六進制) - + PasteHex 粘貼(十六進制) - - + + Fill 填充 - + FillZero 填充零 - - - - - + + + + + MetaData 標注 - + DeleteMetadata 刪除標注 - + ClearMetadata 清空標注 - + MetaDataEdit 編輯標注 - + DeleteMetaData 刪除標注 - + ClearMetaData 清空標注 - + Display 顯示 - + ViewText 文本預覽 - + Scale 縮放 @@ -1214,856 +1262,882 @@ 啟動 Dock 服務 - + LaunchingLog 啟動日誌系統 - + SetupPluginSystem 啟動插件系統 - + LoadingPlg: 加載插件中: - + SetupConsole 啟動腳本控制臺 - + SetupScriptManager 啟動腳本管理器 - + SetupScriptService 啟動腳本服務 - + SetupScriptEditor 構建腳本編輯器 - + SetupSetDialog 構建設置窗體 - + SetupPlgWidgets 啟動插件組件 - + SetupDockingLayout 恢復 Dock 佈局 - + SetupWaiting 啟動即將完成 - + SetupFinished 啟動完畢 - + NoExtension 無擴展 - - + + ExportResult 導出結果 - + NothingToSave 沒有保存的數據 - + OpenExt 打開 - 拓展 - + ResetScale 重置縮放 - + ShowMetafg 標注前景色 - + ShowMetabg 標注背景色 - + ShowMetaComment 批註 - + MetaShowAll 顯示所有標注 - + MetaHideAll 隱藏所有標注 - + FileStatus 檔狀態 - + InfoSave 是否保存 - + ReadOnly 可讀寫 - + SetLocked 啟用/禁用鎖定編輯 - + ErrUnLock 鎖定編輯失敗 - + SetOver 啟用/禁用改變大小 - + InputRequest 輸入請求 - + ScriptEngineInitFailed 腳本引擎啟動失敗,將自動禁用該功能。 - + UnsignedHex 無符號 Hex - + BgScriptOutputHere 後臺腳本執行將會在這裏輸出 - + SelectAll 全選 - - + + Clear 清空 - + AbortScript 終止腳本 - + BgScriptOutput 後臺腳本輸出 - + ErrUnOver 鎖定檔大小失敗 - + Window 窗體 - + Editor 編輯器 - + Tools 工具 - + HexEditorLayout 編輯器佈局 - + SetBaseAddr 設置基址 - + addressBase 基址 - + inputAddressBase 請輸入基址 - + WarnBigBaseAddress 基址過大,你得到的地址將會不正確! - + ErrBaseAddress 非法基址輸入 - + SetColInfo 顯示/隱藏地址欄 - + SetHeaderInfo 顯示/隱藏表頭 - + SetAsciiString 顯示/隱藏解碼字串 - + Layout 佈局 - + Fullscreen 全屏 - + Default 默認 - - - + + + LayoutRestoring... 恢復佈局中... - + RestoreLayout 恢復佈局 - - + + SaveLayout 保存佈局 - - + + ExportLog 導出日誌 - - + + ClearLog 清空日誌 - + InsepctQt 監視 Qt - + ScriptEditor 腳本編輯器 - + Scripts 腳本倉庫 - + PluginFunctions 插件功能 - + ScriptSetting 腳本設置 - + PluginSettings 插件設置 - + Info 資訊 - + Software 軟體 - + Sponsor 贊助 - + CheckUpdate 檢查更新 - + Wiki 網頁 Wiki - + EngineConfigError - + + UndoStack + + + + AboutQT 關於 QT - + SetPageIDEmptyTryUseName 設置頁 ID 為空,嘗試使用名稱作為 ID - + SetPageDupNameIgnored 設置頁重複的 ID 名稱,已忽略加載 - + Plugin %1 contains a duplicate ID (%2) that is already registered by plugin %3 插件 %1 包含重複 ID (%2),該 ID 已被插件 %3 註冊 - - + + ChooseFile 選擇檔 - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + Error 錯誤 - - + + FileNotExist 檔不存在! - - - - - + + + + + FilePermission 因檔許可權無法繼續! - + ProjectFile (*.wingpro) 專案檔 (*.wingpro) - + ReloadSuccessfully 檔重新加載成功! - + ReloadUnSuccessfully 檔重新加載失敗! - - - - + + + + ChooseSaveFile 請選擇保存檔路徑: - + PasteFailedNote 粘貼失敗,請注意許可權或者內容長度 - + NoMoreClone 克隆已到上限,無法繼續操作! - + FindFininishBusy 查找任務繁忙,請勿重複查找! - + MayTooMuchFindResult 搜索數量已到達上限,結果可能不全,建議請按區段搜索。 - + SaveLayoutSuccess 保存佈局成功 - + SaveLayoutError 保存佈局失敗 - + HasClonedView 該編輯頁已被克隆編輯,如果關閉,相關聯的頁也會被關閉,你確認繼續嗎? - + + [MetaAdd] + + + + FileCloseBigFile 大檔讀取模式下目的檔案被關閉,該標籤將會被關閉。 - - + + ReloadNeededYesOrNo 目的檔案被修改,是否重新載入? - + SaveWorkSpace 保存工作區 - + WingHexWorkSpace (*.wingpro) 羽雲十六進制工作區 (*.wingpro) - + ConfirmSave 正在關閉未保存的檔或工作區,你確定保存嗎? - + [Info] 【資訊】 - + [Warn] 【警告】 - + [Error] 【錯誤】 - + ConfirmAPPSave 你嘗試關閉程式,但仍存在未保存的檔或工作區,你確定保存這些更改嗎? - - - + + + SaveSuccessfully 保存成功! - - + + SaveWSError 保存工作區錯誤! - - + + Warn 警告 - + Opening... 打開檔中... - + WorkSpaceOpening... 打開工作區中... - + Reloading... 重載檔中... - + Saving... 保存中... - + SaveNewFirst 請首先保存新建的檔 - + AlreadyWorkSpace 已經是工作區,無需轉化 - + ConvWorkSpaceFailed 轉化為工作區失敗 - + ConvWorkSpaceSuccess 轉化為工作區成功 - + SavingAs... 另存為中... - + SaveUnSuccessfully 保存失敗! - + Exporting... 導出中... - + ChooseExportFile 請選擇導出檔路徑: - + ExportSuccessfully 導出成功! - + ExportUnSuccessfully 導出失敗! - + SavingSel... 保存選中位元組中... - + SaveSelSuccess 保存選區位元組成功! - + SaveSelError 保存選區位元組失敗,因檔不具有可寫許可權! - - + + CutToClipBoard 數據已剪切到粘貼板! - - + + UnCutToClipBoard 由於保持大小限制,數據剪切到粘貼板失敗! - - + + UnCopyToClipBoard 由於保持大小限制,數據剪切到複製板失敗! - - + + Finding... 查找中... - + DeleteSuccess 刪除成功 - + DeleteFailed 刪除失敗 - + FindFininish 查找結果完畢! - + PleaseInputFill 請輸入填充位元組值 - + FillInputTruncWarn 填充輸入數值過大,將會被截斷填充 - + FillInputError 填充位元組輸入錯誤 - - + + InputComment 請輸入批註: - - + + BookmarkDelSuccess 刪除書簽成功 - + BookmarkDelNoItem 無書簽可刪除 - + BookmarkClearSuccess 書簽清空完畢 - - - + + + NoSelection 沒有選區,無法繼續的操作! - + NoMetaData 無可編輯標記 - + PleaseClearSel 請清空選擇 - + MetaDelSuccess 元數據刪除成功 - + MetaDelNoItem 無元數據可刪除 - + MetaClearSuccess 元數據清空完畢 - + FindResultExporting... 查找結果導出中... - - + + EmptyFindResult 沒有可導出的搜索結果! - + SaveFindResult 導出搜索結果成功! - + SaveFindResultError 導出結果失敗! - + TooManyBytesDecode 超出解碼位元組限制…… - + NoTextFileMayInvalid 該檔不是文本檔,以文本方式預覽並不是一個好的方式,你確認繼續嗎? - + LayoutSaving... 佈局保存中... - - + + PleaseInput 請輸入 - + LogExporting... 日誌導出中... - + ExportLogError 導出日誌失敗! - + ExportLogSuccess 導出日誌成功,路徑: - + ClearLogSuccess 清空日誌成功! - + BadNetwork 無法與遠程伺服器的更新檢查建立連接,請檢查網路。 - + NewestVersion 當前軟體為最新版本 - - + + OlderVersion 你使用的軟體為老版本,建議到 Github 和 Gitee 的倉庫發行版下載更新。 - + CheckingUpdate 檢查更新中…… - + Too much opened files 打開的檔過多,無法繼續操作! - + FilePermissionSure2Quit 因檔許可權無法保存,你確認要退出嗎? - + UnknownErrorSure2Quit 因未知錯誤無法保存,你確認要退出嗎? - + WorkSpaceUnSavedSure2Quit 工作區檔無法保存,你確認要退出嗎? - + CopyLimit 拷貝位元組超出限制 - + ErrOpenFileBelow 打開檔出現錯誤(由於許可權不足),如下為打開錯誤的檔: + + MetaAddCommand + + + [MetaAdd] + + + + + MetaClearCommand + + + [MetaClear] + + + MetaDataModel @@ -2120,6 +2194,30 @@ 開啟選項但未設置,如不想設置請關閉! + + MetaRemoveCommand + + + [MetaRemove] + + + + + MetaRemovePosCommand + + + [MetaRemovePos] + + + + + MetaReplaceCommand + + + [MetaReplace] + + + NumShowModel @@ -2307,173 +2405,178 @@ PluginSystem - + LoadingPlugin 加載插件中: - - + + InvalidPluginBrokenInfo 加載插件失敗:損壞的插件數據 - - + + PluginBlockByManager - + AppClosingCanceled: 程式關閉被取消: - + - PluginID: - 插件 ID: - + FoundDrvPluginCount 總計發現設備拓展插件數目: - + PluginManagerNeedSingleton - - + + ErrLoadPluginSDKVersion 插件加載失敗:非法插件 SDK 版本! - + ErrLoadPluginNoName 插件加載失敗:非法插件名稱! - - + + ErrLoadInitPlugin 插件加載失敗:初始化插件失敗! - + PluginName : 插件名: - + PluginAuthor : 插件作者: - + PluginWidgetRegister 註冊插件對象中…… - + ExtPluginAuthor : 設備拓展插件作者: - + ExtPluginWidgetRegister 設備拓展註冊插件對象中…… - + ErrLoadInitExtPlugin 設備拓展插件加載失敗:初始化插件失敗! - + ChooseFile 選擇檔 - - + + Error 錯誤 - + FileNotExist 檔不存在! - + FilePermission 因檔許可權無法繼續! - + EmptyNameDockWidget: 空的貼邊組件名: - + InvalidNameDockWidget: 無效貼邊組件名: - + InvalidNullDockWidget: 無效空貼邊組件: - + Not allowed operation in non-UI thread 該操作在非 UI 線程非法 - + + UnexpectedUndoCmdPushDetected + + + + UnsafePluginDir 不安全的插件目錄,請將插件目錄設置為僅管理員帳戶可寫 - - + + InvalidPluginID 加載插件失敗:非法插件識別字 - + InvalidDupPlugin 加載插件失敗:重複的插件識別字 - + FoundPluginCount 總計發現插件數目: - + PluginLoadingFailedSummary 有依賴插件加載失敗總結 - + - Dependencies: - 依賴: - + PUID: 插件唯一標誌符: - + Version: 版本: - + PluginLoadingFinished 加載插件完畢! @@ -2797,6 +2900,23 @@ 打開歷史記錄完成! + + RemoveCommand + + + [HexRemove] pos: %1 + + + + + ReplaceCommand + + + + [HexReplace] pos: %1 + + + RibbonButtonGroup @@ -4592,7 +4712,7 @@ ScriptingDialog - + ScriptEditor 腳本編輯器 @@ -4653,7 +4773,7 @@ - + Reload 重新加載 @@ -4826,11 +4946,11 @@ - - - - - + + + + + Error 錯誤 @@ -4850,83 +4970,83 @@ 腳本保存失敗,你仍確認關閉嗎? - + ReloadNeededYesOrNo 目的檔案被修改,是否重新載入? - + Debuging... 調試中... - + Running... 運行中... - + Line %1, Col %2 行 %1, 列 %2 - + (Selected: %1) (選中: %1) - - + + ChooseFile 選擇檔 - - - + + + FilePermission 因檔許可權無法繼續! - + ReloadSuccessfully 檔重新加載成功! - + ReloadUnSuccessfully 檔重新加載失敗! - + ChooseSaveFile 請選擇保存檔路徑: - - + + SaveSuccessfully 保存成功! - + SaveUnSuccessfully 保存失敗! - + FormatCodeFailed 代碼格式化失敗 - - + + CannotSave2RunScript 無法保存,故無法繼續運行腳本。 - + ScriptStillRunning 腳本仍在運行,你確定要退出嗎? @@ -5256,18 +5376,18 @@ 為 AngelScript 腳本提供調用主機 API 能力的內部插件。 - + NotSupportedQMetaType: 不支持的 QT 數據元類型: - - + + Get Exception While ScriptCall: (%1) %2 腳本調用發生異常:(%1)%2 - + InvalidRetType: need 無效返回值:需要 @@ -5275,41 +5395,41 @@ WingCStruct - + WingCStruct 羽雲檔結構分析器 - + Providing basic support for analyzing file structures 提供基礎的檔結構分析支持 - - - - - - - - - - - - - + + + + + + + + + + + + + InvalidParamsCount 非法參數個數 - - - - - - - - + + + + + + + + InvalidParam 非法參數 diff --git a/src/class/crashhandler.cpp b/src/class/crashhandler.cpp index 0301fbd..26a23f6 100644 --- a/src/class/crashhandler.cpp +++ b/src/class/crashhandler.cpp @@ -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 . +** ============================================================================= +*/ + #include "crashhandler.h" #include "angelscript.h" #include "class/pluginsystem.h" diff --git a/src/class/dockcomponentsfactory.cpp b/src/class/dockcomponentsfactory.cpp index 0b2e845..52e2999 100644 --- a/src/class/dockcomponentsfactory.cpp +++ b/src/class/dockcomponentsfactory.cpp @@ -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 . +** ============================================================================= +*/ + #include "dockcomponentsfactory.h" #include "DockWidget.h" diff --git a/src/class/pluginsystem.cpp b/src/class/pluginsystem.cpp index 27a252a..eabe6c9 100644 --- a/src/class/pluginsystem.cpp +++ b/src/class/pluginsystem.cpp @@ -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,26 +1455,108 @@ 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 e = pluginCurrentEditor(plg); - if (e) { + 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 &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 == 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; +} + bool PluginSystem::writeInt8(const QObject *sender, qsizetype offset, qint8 value) { auto plg = checkPluginAndReport(sender, __func__); @@ -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,8 +2871,8 @@ ErrFile PluginSystem::exportFile(const QObject *sender, int handle, return ErrFile::NotExist; } -ErrFile PluginSystem::openWorkSpace(const QObject *sender, - const QString &filename) { +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,8 +2975,8 @@ ErrFile PluginSystem::closeHandle(const QObject *sender, int handle) { return WingHex::ErrFile::NotExist; } -ErrFile PluginSystem::openExtFile(const QObject *sender, const QString &ext, - const QString &file) { +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 &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 &v) { + auto id = handles.currentFID; + handles.contexts.removeIf( + [view, this, id, + plg](const QSharedPointer &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 &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::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 &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; -} diff --git a/src/class/pluginsystem.h b/src/class/pluginsystem.h index ee6da57..165ca38 100644 --- a/src/class/pluginsystem.h +++ b/src/class/pluginsystem.h @@ -118,12 +118,22 @@ private: SharedUniqueId fid; EditorView *view = nullptr; IWingPlugin *linkedplg = nullptr; - QUndoCommand *cmd = nullptr; + }; - ~PluginFileContext() { - if (cmd) { - delete cmd; + struct PluginFile { + QVector> contexts; + int currentFID = -1; + }; + + struct ViewBind { + QList linkedplg; + QList> 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 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( - 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( - 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( - 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> _evplgs; - QHash>> - m_plgviewMap; - QHash m_plgCurrentfid; // fid - QHash> m_viewBindings; + QHash m_plgviewMap; + QHash m_viewBindings; UniqueIdGenerator m_idGen; diff --git a/src/class/wingangelapi.cpp b/src/class/wingangelapi.cpp index ffb6850..fd1c6fa 100644 --- a/src/class/wingangelapi.cpp +++ b/src/class/wingangelapi.cpp @@ -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), diff --git a/src/control/editorview.cpp b/src/control/editorview.cpp index 683f063..3555d3b 100644 --- a/src/control/editorview.cpp +++ b/src/control/editorview.cpp @@ -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(); diff --git a/src/control/editorview.h b/src/control/editorview.h index 023d513..9bdaeb0 100644 --- a/src/control/editorview.h +++ b/src/control/editorview.h @@ -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; diff --git a/src/dialog/mainwindow.cpp b/src/dialog/mainwindow.cpp index 284013c..b309e84 100644 --- a/src/dialog/mainwindow.cpp +++ b/src/dialog/mainwindow.cpp @@ -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) { diff --git a/src/dialog/mainwindow.h b/src/dialog/mainwindow.h index cee8132..b4934db 100644 --- a/src/dialog/mainwindow.h +++ b/src/dialog/mainwindow.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -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 m_toolBtneditors; QAction *m_aDelBookMark = nullptr; diff --git a/src/dialog/scriptingdialog.cpp b/src/dialog/scriptingdialog.cpp index 9d4afbb..13230c6 100644 --- a/src/dialog/scriptingdialog.cpp +++ b/src/dialog/scriptingdialog.cpp @@ -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 { diff --git a/src/dialog/scriptingdialog.h b/src/dialog/scriptingdialog.h index 394c45a..868af91 100644 --- a/src/dialog/scriptingdialog.h +++ b/src/dialog/scriptingdialog.h @@ -202,6 +202,7 @@ private: void updateEditModeEnabled(); ScriptEditor *currentEditor() const; void swapEditor(ScriptEditor *old, ScriptEditor *cur); + void updateWindowTitle(); void updateRunDebugMode(bool disable = false);