feat: 引入文档撤销堆栈可视化;插件不再具有独立的撤销堆栈;

This commit is contained in:
寂静的羽夏 2025-07-05 21:04:30 +08:00
parent fb4f439e50
commit a3b465534c
53 changed files with 1884 additions and 1198 deletions

View File

@ -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

View File

@ -23,8 +23,22 @@
BookMarkAddCommand::BookMarkAddCommand(QHexDocument *doc, qsizetype pos,
QString comment, QUndoCommand *parent)
: BookMarkCommand(doc, pos, comment, parent) {}
: BookMarkCommand(tr("[AddBookMark] pos: %1").arg(pos), doc, pos, comment,
parent) {}
void BookMarkAddCommand::redo() { m_doc->addBookMark(m_pos, m_comment); }
int BookMarkAddCommand::id() const { return UndoID_BookMarkAdd; }
bool BookMarkAddCommand::mergeWith(const QUndoCommand *other) {
auto ucmd = static_cast<const BookMarkAddCommand *>(other);
if (ucmd) {
if (this->m_pos == ucmd->m_pos) {
this->m_comment = m_comment;
return true;
}
}
return false;
}
void BookMarkAddCommand::undo() { m_doc->removeBookMark(m_pos); }

View File

@ -24,13 +24,22 @@
#include "bookmarkcommand.h"
#include <QCoreApplication>
class BookMarkAddCommand : public BookMarkCommand {
Q_DECLARE_TR_FUNCTIONS(BookMarkAddCommand)
public:
BookMarkAddCommand(QHexDocument *doc, qsizetype pos, QString comment,
explicit BookMarkAddCommand(QHexDocument *doc, qsizetype pos,
QString comment,
QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
// QUndoCommand interface
public:
virtual void undo() override;
virtual void redo() override;
virtual int id() const override;
virtual bool mergeWith(const QUndoCommand *other) override;
};
#endif // BOOKMARKADDCOMMAND_H

View File

@ -24,8 +24,16 @@
BookMarkClearCommand::BookMarkClearCommand(
QHexDocument *doc, const QMap<qsizetype, QString> &bookmarks,
QUndoCommand *parent)
: QUndoCommand(parent), m_doc(doc), m_bookmarks(bookmarks) {}
: UndoCommandBase(tr("[ClearBookMark]"), parent), m_doc(doc),
m_bookmarks(bookmarks) {}
void BookMarkClearCommand::redo() { m_doc->clearBookMark(); }
int BookMarkClearCommand::id() const { return UndoID_BookMarkClear; }
bool BookMarkClearCommand::mergeWith(const QUndoCommand *other) {
Q_UNUSED(other);
return true;
}
void BookMarkClearCommand::undo() { m_doc->applyBookMarks(m_bookmarks); }

View File

@ -22,19 +22,26 @@
#ifndef BOOKMARKCLEARCOMMAND_H
#define BOOKMARKCLEARCOMMAND_H
#include "../undocommandbase.h"
#include "document/qhexdocument.h"
#include <QMap>
#include <QObject>
#include <QUndoCommand>
class BookMarkClearCommand : public QUndoCommand {
#include <QCoreApplication>
#include <QMap>
class BookMarkClearCommand : public UndoCommandBase {
Q_DECLARE_TR_FUNCTIONS(BookMarkClearCommand)
public:
BookMarkClearCommand(QHexDocument *doc,
explicit BookMarkClearCommand(QHexDocument *doc,
const QMap<qsizetype, QString> &bookmarks,
QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
// QUndoCommand interface
public:
virtual void undo() override;
virtual void redo() override;
virtual int id() const override;
virtual bool mergeWith(const QUndoCommand *other) override;
protected:
QHexDocument *m_doc;

View File

@ -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) {}

View File

@ -22,13 +22,13 @@
#ifndef BOOKMARKCOMMAND_H
#define BOOKMARKCOMMAND_H
#include "../undocommandbase.h"
#include "document/qhexdocument.h"
#include <QObject>
#include <QUndoCommand>
class BookMarkCommand : public QUndoCommand {
class BookMarkCommand : public UndoCommandBase {
public:
BookMarkCommand(QHexDocument *doc, qsizetype pos, QString comment,
explicit BookMarkCommand(const QString &text, QHexDocument *doc,
qsizetype pos, QString comment,
QUndoCommand *parent = nullptr);
protected:

View File

@ -24,8 +24,21 @@
BookMarkRemoveCommand::BookMarkRemoveCommand(QHexDocument *doc, qsizetype pos,
QString comment,
QUndoCommand *parent)
: BookMarkCommand(doc, pos, comment, parent) {}
: BookMarkCommand(tr("[RemoveBookMark] pos: %1").arg(pos), doc, pos,
comment, parent) {}
void BookMarkRemoveCommand::redo() { m_doc->removeBookMark(m_pos); }
int BookMarkRemoveCommand::id() const { return UndoID_BookMarkRemove; }
bool BookMarkRemoveCommand::mergeWith(const QUndoCommand *other) {
auto ucmd = static_cast<const BookMarkRemoveCommand *>(other);
if (ucmd) {
if (this->m_pos == ucmd->m_pos) {
return true;
}
}
return false;
}
void BookMarkRemoveCommand::undo() { m_doc->addBookMark(m_pos, m_comment); }

View File

@ -24,13 +24,23 @@
#include "bookmarkcommand.h"
#include <QCoreApplication>
class BookMarkRemoveCommand : public BookMarkCommand {
Q_DECLARE_TR_FUNCTIONS(BookMarkRemoveCommand)
public:
BookMarkRemoveCommand(QHexDocument *doc, qsizetype pos, QString comment,
explicit BookMarkRemoveCommand(QHexDocument *doc, qsizetype pos,
QString comment,
QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
// QUndoCommand interface
public:
virtual void undo() override;
virtual void redo() override;
virtual int id() const override;
virtual bool mergeWith(const QUndoCommand *other) override;
};
#endif // BOOKMARKREMOVECOMMAND_H

View File

@ -25,8 +25,23 @@ BookMarkReplaceCommand::BookMarkReplaceCommand(QHexDocument *doc, qsizetype pos,
QString comment,
QString oldcomment,
QUndoCommand *parent)
: BookMarkCommand(doc, pos, comment, parent), m_oldcomment(oldcomment) {}
: BookMarkCommand(tr("[ReplaceBookMark] pos: %1").arg(pos), doc, pos,
comment, parent),
m_oldcomment(oldcomment) {}
void BookMarkReplaceCommand::redo() { m_doc->modBookMark(m_pos, m_comment); }
int BookMarkReplaceCommand::id() const { return UndoID_BookMarkReplace; }
bool BookMarkReplaceCommand::mergeWith(const QUndoCommand *other) {
auto ucmd = static_cast<const BookMarkReplaceCommand *>(other);
if (ucmd) {
if (this->m_pos == ucmd->m_pos) {
this->m_comment = m_comment;
return true;
}
}
return false;
}
void BookMarkReplaceCommand::undo() { m_doc->modBookMark(m_pos, m_oldcomment); }

View File

@ -24,13 +24,22 @@
#include "bookmarkcommand.h"
class BookMarkReplaceCommand : public BookMarkCommand {
public:
BookMarkReplaceCommand(QHexDocument *doc, qsizetype pos, QString comment,
QString oldcomment, QUndoCommand *parent = nullptr);
#include <QCoreApplication>
void undo() override;
void redo() override;
class BookMarkReplaceCommand : public BookMarkCommand {
Q_DECLARE_TR_FUNCTIONS(BookMarkReplaceCommand)
public:
explicit BookMarkReplaceCommand(QHexDocument *doc, qsizetype pos,
QString comment, QString oldcomment,
QUndoCommand *parent = nullptr);
// QUndoCommand interface
public:
virtual void undo() override;
virtual void redo() override;
virtual int id() const override;
virtual bool mergeWith(const QUndoCommand *other) override;
protected:
QString m_oldcomment;

View File

@ -24,7 +24,7 @@
AppendCommand::AppendCommand(QHexDocument *doc, QHexCursor *cursor,
const QByteArray &data, int nibbleindex,
QUndoCommand *parent)
: HexCommand(doc, cursor, nibbleindex, parent) {
: HexCommand(tr("[HexAppend]"), doc, cursor, nibbleindex, parent) {
m_offset = -1;
m_data = data;
m_length = data.length();
@ -36,7 +36,6 @@ void AppendCommand::undo() {
m_doc->insertBookMarkAdjustRevert(offset, m_length);
m_doc->metadata()->insertAdjustRevert(offset, m_length);
m_cursor->setPos(offset, m_nibbleindex);
HexCommand::undo();
}
void AppendCommand::redo() {
@ -49,5 +48,15 @@ void AppendCommand::redo() {
} else {
m_cursor->setPos(offset + m_length, m_nibbleindex);
}
HexCommand::redo();
}
int AppendCommand::id() const { return UndoID_HexAppend; }
bool AppendCommand::mergeWith(const QUndoCommand *other) {
auto ucmd = static_cast<const AppendCommand *>(other);
if (ucmd) {
this->m_data.append(ucmd->m_data);
return true;
}
return false;
}

View File

@ -24,12 +24,22 @@
#include "hexcommand.h"
#include <QCoreApplication>
class AppendCommand : public HexCommand {
Q_DECLARE_TR_FUNCTIONS(AppendCommand)
public:
AppendCommand(QHexDocument *doc, QHexCursor *cursor, const QByteArray &data,
int nibbleindex, QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
explicit AppendCommand(QHexDocument *doc, QHexCursor *cursor,
const QByteArray &data, int nibbleindex,
QUndoCommand *parent = nullptr);
// QUndoCommand interface
public:
virtual void undo() override;
virtual void redo() override;
virtual int id() const override;
virtual bool mergeWith(const QUndoCommand *other) override;
};
#endif // APPENDCOMMAND_H

View File

@ -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++; }

View File

@ -25,16 +25,14 @@
#include "document/qhexcursor.h"
#include "document/qhexdocument.h"
#include <QUndoCommand>
#include "document/commands/undocommandbase.h"
class HexCommand : public QUndoCommand {
class HexCommand : public UndoCommandBase {
public:
HexCommand(QHexDocument *doc, QHexCursor *cursor, int nibbleindex,
explicit HexCommand(const QString &text, QHexDocument *doc,
QHexCursor *cursor, int nibbleindex,
QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
protected:
QHexDocument *m_doc;
QHexCursor *m_cursor;

View File

@ -21,10 +21,13 @@
#include "insertcommand.h"
#include "document/commands/hex/replacecommand.h"
InsertCommand::InsertCommand(QHexDocument *doc, QHexCursor *cursor,
qsizetype offset, const QByteArray &data,
int nibbleindex, QUndoCommand *parent)
: HexCommand(doc, cursor, nibbleindex, parent) {
: HexCommand(tr("[HexInsert] pos: %1").arg(offset), doc, cursor,
nibbleindex, parent) {
m_offset = offset;
m_data = data;
m_length = data.length();
@ -35,7 +38,6 @@ void InsertCommand::undo() {
m_doc->insertBookMarkAdjustRevert(m_offset, m_length);
m_doc->metadata()->insertAdjustRevert(m_offset, m_length);
m_cursor->setPos(m_offset, m_nibbleindex);
HexCommand::undo();
}
void InsertCommand::redo() {
m_doc->_insert(m_offset, m_data);
@ -46,5 +48,28 @@ void InsertCommand::redo() {
} else {
m_cursor->setPos(m_offset + m_length, m_nibbleindex);
}
HexCommand::redo();
}
int InsertCommand::id() const { return UndoID_HexReplaceInsert; }
bool InsertCommand::mergeWith(const QUndoCommand *other) {
auto ucmd = dynamic_cast<const InsertCommand *>(other);
if (ucmd) {
if (this->m_offset + this->m_length == ucmd->m_offset) {
this->m_length += ucmd->m_length;
this->m_data.append(ucmd->m_data);
return true;
}
} else {
auto ucmd = dynamic_cast<const ReplaceCommand *>(other);
if (ucmd) {
if (this->m_offset + this->m_length - 1 == ucmd->m_offset &&
ucmd->m_length == 1 && this->m_nibbleindex == 1 &&
ucmd->m_nibbleindex == 0) {
this->m_data.back() = ucmd->m_data.at(0);
return true;
}
}
}
return false;
}

View File

@ -24,13 +24,23 @@
#include "hexcommand.h"
#include <QCoreApplication>
class InsertCommand : public HexCommand {
Q_DECLARE_TR_FUNCTIONS(InsertCommand)
public:
InsertCommand(QHexDocument *doc, QHexCursor *cursor, qsizetype offset,
const QByteArray &data, int nibbleindex,
QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
explicit InsertCommand(QHexDocument *doc, QHexCursor *cursor,
qsizetype offset, const QByteArray &data,
int nibbleindex, QUndoCommand *parent = nullptr);
// QUndoCommand interface
public:
virtual void undo() override;
virtual void redo() override;
virtual int id() const override;
virtual bool mergeWith(const QUndoCommand *other) override;
};
#endif // INSERTCOMMAND_H

View File

@ -24,7 +24,8 @@
RemoveCommand::RemoveCommand(QHexDocument *doc, qsizetype offset,
qsizetype length, QHexCursor *cursor,
int nibbleindex, QUndoCommand *parent)
: HexCommand(doc, cursor, nibbleindex, parent) {
: HexCommand(tr("[HexRemove] pos: %1").arg(offset), doc, cursor,
nibbleindex, parent) {
m_offset = offset;
m_length = length;
m_data = doc->read(m_offset, m_length);
@ -43,7 +44,6 @@ void RemoveCommand::undo() {
m_cursor->setPos(m_offset, 0);
}
}
HexCommand::undo();
}
void RemoveCommand::redo() {
@ -51,5 +51,28 @@ void RemoveCommand::redo() {
m_doc->_remove(m_offset, m_length);
_rmbms = m_doc->removeBookMarkAdjust(m_offset, m_length);
_rmMetas = m_doc->metadata()->removeAdjust(m_offset, m_length);
HexCommand::redo();
}
int RemoveCommand::id() const { return UndoID_HexRemove; }
bool RemoveCommand::mergeWith(const QUndoCommand *other) {
auto ucmd = static_cast<const RemoveCommand *>(other);
if (ucmd) {
if (this->m_offset == ucmd->m_offset) {
this->m_data.append(ucmd->m_data);
auto bms = ucmd->_rmbms;
for (auto &&b : bms.asKeyValueRange()) {
this->_rmbms.insert(b.first + this->m_length, b.second);
}
auto metas = ucmd->_rmMetas;
for (auto &m : metas) {
m.begin += this->m_length;
m.end += this->m_length;
}
this->_rmMetas.append(ucmd->_rmMetas);
this->m_length += ucmd->m_length;
return true;
}
}
return false;
}

View File

@ -24,13 +24,21 @@
#include "hexcommand.h"
#include <QCoreApplication>
class RemoveCommand : public HexCommand {
Q_DECLARE_TR_FUNCTIONS(RemoveCommand)
public:
RemoveCommand(QHexDocument *doc, qsizetype offset, qsizetype length,
QHexCursor *cursor, int nibbleindex,
QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
explicit RemoveCommand(QHexDocument *doc, qsizetype offset,
qsizetype length, QHexCursor *cursor,
int nibbleindex, QUndoCommand *parent = nullptr);
// QUndoCommand interface
public:
virtual void undo() override;
virtual void redo() override;
virtual int id() const override;
virtual bool mergeWith(const QUndoCommand *other) override;
private:
QVector<QHexMetadataItem> _rmMetas;

View File

@ -25,7 +25,8 @@
ReplaceCommand::ReplaceCommand(QHexDocument *doc, qsizetype offset,
const QByteArray &data, QHexCursor *cursor,
int nibbleindex, QUndoCommand *parent)
: HexCommand(doc, cursor, nibbleindex, parent) {
: HexCommand(tr("[HexReplace] pos: %1").arg(offset), doc, cursor,
nibbleindex, parent) {
m_offset = offset;
m_data = data;
m_length = data.length();
@ -35,7 +36,6 @@ ReplaceCommand::ReplaceCommand(QHexDocument *doc, qsizetype offset,
void ReplaceCommand::undo() {
m_doc->_replace(m_offset, m_olddata);
m_cursor->setPos(m_offset, m_nibbleindex);
HexCommand::undo();
}
void ReplaceCommand::redo() {
@ -45,5 +45,48 @@ void ReplaceCommand::redo() {
} else {
m_cursor->setPos(m_offset + m_length, !m_nibbleindex);
}
HexCommand::redo();
}
int ReplaceCommand::id() const { return UndoID_HexReplaceInsert; }
bool ReplaceCommand::mergeWith(const QUndoCommand *other) {
auto ucmd = dynamic_cast<const ReplaceCommand *>(other);
if (ucmd) {
if (this->m_offset == ucmd->m_offset) {
if (this->m_length <= ucmd->m_length) {
this->m_olddata = ucmd->m_olddata;
this->m_data = ucmd->m_data;
this->m_length = ucmd->m_length;
} else {
this->m_data.replace(0, ucmd->m_length, ucmd->m_data);
}
return true;
}
if (this->m_offset + this->m_length == ucmd->m_offset) {
this->m_length += ucmd->m_offset;
this->m_data.append(ucmd->m_data);
this->m_olddata.append(ucmd->m_olddata);
this->m_nibbleindex = ucmd->m_nibbleindex;
return true;
}
if (this->m_offset <= ucmd->m_offset &&
this->m_offset + m_length >= ucmd->m_offset + ucmd->m_length) {
auto dis = ucmd->m_offset - this->m_offset;
this->m_data.replace(dis, ucmd->m_length, ucmd->m_data);
return true;
}
if (this->m_offset >= ucmd->m_offset &&
this->m_offset + m_length <= ucmd->m_offset + ucmd->m_length) {
this->m_offset = ucmd->m_offset;
this->m_data = ucmd->m_data;
this->m_length = ucmd->m_length;
this->m_olddata = ucmd->m_olddata;
this->m_nibbleindex = ucmd->m_nibbleindex;
setText(tr("[HexReplace] pos: %1").arg(this->m_offset));
return true;
}
}
return false;
}

View File

@ -24,13 +24,23 @@
#include "hexcommand.h"
#include <QCoreApplication>
class ReplaceCommand : public HexCommand {
Q_DECLARE_TR_FUNCTIONS(ReplaceCommand)
friend class InsertCommand;
public:
ReplaceCommand(QHexDocument *doc, qsizetype offset, const QByteArray &data,
QHexCursor *cursor, int nibbleindex,
QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
explicit ReplaceCommand(QHexDocument *doc, qsizetype offset,
const QByteArray &data, QHexCursor *cursor,
int nibbleindex, QUndoCommand *parent = nullptr);
// QUndoCommand interface
public:
virtual void undo() override;
virtual void redo() override;
virtual int id() const override;
virtual bool mergeWith(const QUndoCommand *other) override;
private:
QByteArray m_olddata;

View File

@ -24,7 +24,7 @@
MetaAddCommand::MetaAddCommand(QHexMetadata *hexmeta,
const QHexMetadataItem &meta,
QUndoCommand *parent)
: MetaCommand(hexmeta, meta, parent) {
: MetaCommand(tr("[MetaAdd]"), hexmeta, meta, parent) {
_brokenMetas = m_hexmeta->mayBrokenMetaData(meta.begin, meta.end);
}
@ -33,6 +33,20 @@ void MetaAddCommand::redo() {
m_meta.background, m_meta.comment);
}
int MetaAddCommand::id() const { return UndoID_MetaAdd; }
bool MetaAddCommand::mergeWith(const QUndoCommand *other) {
auto ucmd = static_cast<const MetaAddCommand *>(other);
if (ucmd) {
if (this->m_meta.foreground == ucmd->m_meta.foreground &&
this->m_meta.background == ucmd->m_meta.background &&
this->m_meta.comment == ucmd->m_meta.comment) {
return this->m_meta.mergeRegionWithoutMetaCheck(ucmd->m_meta);
}
}
return false;
}
void MetaAddCommand::undo() {
m_hexmeta->removeMetadata(m_meta.begin, m_meta.end);
for (auto &meta : _brokenMetas) {

View File

@ -23,14 +23,22 @@
#define METAADDCOMMAND_H
#include "metacommand.h"
#include <QCoreApplication>
#include <QObject>
class MetaAddCommand : public MetaCommand {
Q_DECLARE_TR_FUNCTIONS(MetaAddCommand)
public:
MetaAddCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
explicit MetaAddCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
// QUndoCommand interface
public:
virtual void undo() override;
virtual void redo() override;
virtual int id() const override;
virtual bool mergeWith(const QUndoCommand *other) override;
private:
QVector<QHexMetadataItem> _brokenMetas;

View File

@ -24,8 +24,16 @@
MetaClearCommand::MetaClearCommand(QHexMetadata *hexmeta,
const QVector<QHexMetadataItem> &metas,
QUndoCommand *parent)
: QUndoCommand(parent), m_hexmeta(hexmeta), m_metas(metas) {}
: UndoCommandBase(tr("[MetaClear]"), parent), m_hexmeta(hexmeta),
m_metas(metas) {}
void MetaClearCommand::redo() { m_hexmeta->clear(); }
int MetaClearCommand::id() const { return UndoID_MetaClear; }
bool MetaClearCommand::mergeWith(const QUndoCommand *other) {
Q_UNUSED(other);
return true;
}
void MetaClearCommand::undo() { m_hexmeta->applyMetas(m_metas); }

View File

@ -23,21 +23,27 @@
#define METACLEARCOMMAND_H
#include "../../qhexmetadata.h"
#include <QList>
#include <QObject>
#include <QUndoCommand>
#include <QUndoStack>
#include "../undocommandbase.h"
#include <QCoreApplication>
#include <QVector>
// this class is newed by wingsummer
class MetaClearCommand : public QUndoCommand {
class MetaClearCommand : public UndoCommandBase {
Q_DECLARE_TR_FUNCTIONS(MetaClearCommand)
public:
MetaClearCommand(QHexMetadata *hexmeta,
explicit MetaClearCommand(QHexMetadata *hexmeta,
const QVector<QHexMetadataItem> &metas,
QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
// QUndoCommand interface
public:
virtual void undo() override;
virtual void redo() override;
virtual int id() const override;
virtual bool mergeWith(const QUndoCommand *other) override;
protected:
QHexMetadata *m_hexmeta;

View File

@ -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) {}

View File

@ -22,16 +22,15 @@
#ifndef METACOMMAND_H
#define METACOMMAND_H
#include <QObject>
#include <QUndoCommand>
#include "../../qhexmetadata.h"
#include "../undocommandbase.h"
// this class is newed by wingsummer
class MetaCommand : public QUndoCommand {
class MetaCommand : public UndoCommandBase {
public:
MetaCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
explicit MetaCommand(const QString &text, QHexMetadata *hexmeta,
const QHexMetadataItem &meta,
QUndoCommand *parent = nullptr);
protected:

View File

@ -24,10 +24,20 @@
MetaRemoveCommand::MetaRemoveCommand(QHexMetadata *hexmeta,
const QHexMetadataItem &meta,
QUndoCommand *parent)
: MetaCommand(hexmeta, meta, parent) {}
: MetaCommand(tr("[MetaRemove]"), hexmeta, meta, parent) {}
void MetaRemoveCommand::redo() { m_hexmeta->removeMetadata(m_meta); }
int MetaRemoveCommand::id() const { return UndoID_MetaRemove; }
bool MetaRemoveCommand::mergeWith(const QUndoCommand *other) {
auto ucmd = static_cast<const MetaRemoveCommand *>(other);
if (ucmd) {
return this->m_meta == ucmd->m_meta;
}
return false;
}
void MetaRemoveCommand::undo() {
m_hexmeta->metadata(m_meta.begin, m_meta.end, m_meta.foreground,
m_meta.background, m_meta.comment);

View File

@ -23,18 +23,26 @@
#define METAREMOVECOMMAND_H
#include "metacommand.h"
#include <QCoreApplication>
#include <QList>
#include <QObject>
// this class is newed by wingsummer
class MetaRemoveCommand : public MetaCommand {
Q_DECLARE_TR_FUNCTIONS(MetaRemoveCommand)
public:
MetaRemoveCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
explicit MetaRemoveCommand(QHexMetadata *hexmeta,
const QHexMetadataItem &meta,
QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
// QUndoCommand interface
public:
virtual void undo() override;
virtual void redo() override;
virtual int id() const override;
virtual bool mergeWith(const QUndoCommand *other) override;
};
#endif // METAREMOVECOMMAND_H

View File

@ -23,16 +23,28 @@
MetaRemovePosCommand::MetaRemovePosCommand(QHexMetadata *hexmeta, qsizetype pos,
QUndoCommand *parent)
: QUndoCommand(parent), m_hexmeta(hexmeta), m_pos(pos) {
: MetaCommand(tr("[MetaRemovePos]"), hexmeta, {}, parent), m_pos(pos) {
auto po = m_hexmeta->get(pos);
if (po.has_value()) {
oldmeta = po.value();
m_meta = po.value();
}
}
void MetaRemovePosCommand::redo() { m_hexmeta->removeMetadata(m_pos); }
void MetaRemovePosCommand::undo() {
m_hexmeta->metadata(oldmeta.begin, oldmeta.end, oldmeta.foreground,
oldmeta.background, oldmeta.comment);
int MetaRemovePosCommand::id() const { return UndoID_MetaRemovePos; }
bool MetaRemovePosCommand::mergeWith(const QUndoCommand *other) {
auto ucmd = static_cast<const MetaRemovePosCommand *>(other);
if (ucmd) {
if (this->m_pos == ucmd->m_pos) {
return true;
}
}
return false;
}
void MetaRemovePosCommand::undo() {
m_hexmeta->metadata(m_meta.begin, m_meta.end, m_meta.foreground,
m_meta.background, m_meta.comment);
}

View File

@ -22,24 +22,26 @@
#ifndef METAREMOVEPOSCOMMAND_H
#define METAREMOVEPOSCOMMAND_H
#include "../../qhexmetadata.h"
#include <QList>
#include <QObject>
#include <QUndoCommand>
#include <QUndoStack>
#include "metacommand.h"
class MetaRemovePosCommand : public QUndoCommand {
#include <QCoreApplication>
class MetaRemovePosCommand : public MetaCommand {
Q_DECLARE_TR_FUNCTIONS(MetaRemovePosCommand)
public:
MetaRemovePosCommand(QHexMetadata *hexmeta, qsizetype pos,
explicit MetaRemovePosCommand(QHexMetadata *hexmeta, qsizetype pos,
QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
// QUndoCommand interface
public:
virtual void undo() override;
virtual void redo() override;
virtual int id() const override;
virtual bool mergeWith(const QUndoCommand *other) override;
protected:
QHexMetadata *m_hexmeta;
qsizetype m_pos;
QHexMetadataItem oldmeta;
};
#endif // METAREMOVEPOSCOMMAND_H

View File

@ -25,8 +25,21 @@ MetaReplaceCommand::MetaReplaceCommand(QHexMetadata *hexmeta,
const QHexMetadataItem &meta,
const QHexMetadataItem &oldmeta,
QUndoCommand *parent)
: MetaCommand(hexmeta, meta, parent), m_old(oldmeta) {}
: MetaCommand(tr("[MetaReplace]"), hexmeta, meta, parent), m_old(oldmeta) {}
void MetaReplaceCommand::undo() { m_hexmeta->modifyMetadata(m_old, m_meta); }
void MetaReplaceCommand::redo() { m_hexmeta->modifyMetadata(m_meta, m_old); }
int MetaReplaceCommand::id() const { return UndoID_MetaReplace; }
bool MetaReplaceCommand::mergeWith(const QUndoCommand *other) {
auto ucmd = static_cast<const MetaReplaceCommand *>(other);
if (ucmd) {
if (this->m_old == ucmd->m_old) {
this->m_meta = ucmd->m_meta;
return true;
}
}
return false;
}

View File

@ -23,15 +23,24 @@
#define METAREPLACECOMMAND_H
#include "metacommand.h"
#include <QCoreApplication>
#include <QObject>
class MetaReplaceCommand : public MetaCommand {
Q_DECLARE_TR_FUNCTIONS(MetaReplaceCommand)
public:
MetaReplaceCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
explicit MetaReplaceCommand(QHexMetadata *hexmeta,
const QHexMetadataItem &meta,
const QHexMetadataItem &oldmeta,
QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
// QUndoCommand interface
public:
virtual void undo() override;
virtual void redo() override;
virtual int id() const override;
virtual bool mergeWith(const QUndoCommand *other) override;
private:
QHexMetadataItem m_old;

View File

@ -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) {}

View File

@ -19,23 +19,31 @@
** =============================================================================
*/
#ifndef BASEADDRCOMMAND_H
#define BASEADDRCOMMAND_H
#ifndef UNDOCOMMANDBASE_H
#define UNDOCOMMANDBASE_H
#include "document/qhexdocument.h"
#include <QUndoCommand>
class BaseAddrCommand : public QUndoCommand {
class UndoCommandBase : public QUndoCommand {
public:
BaseAddrCommand(QHexDocument *doc, quint64 oldaddr, quint64 newaddr,
QUndoCommand *parent = nullptr);
void redo() override;
void undo() override;
private:
QHexDocument *m_doc;
quint64 m_old, m_new;
enum UndoCommandID {
UndoID_BookMarkAdd,
UndoID_BookMarkClear,
UndoID_BookMarkRemove,
UndoID_BookMarkReplace,
UndoID_HexAppend,
UndoID_HexReplaceInsert,
UndoID_HexRemove,
UndoID_MetaAdd,
UndoID_MetaClear,
UndoID_MetaRemove,
UndoID_MetaRemovePos,
UndoID_MetaReplace
};
#endif // BASEADDRCOMMAND_H
public:
explicit UndoCommandBase(const QString &text,
QUndoCommand *parent = nullptr);
};
#endif // UNDOCOMMANDBASE_H

View File

@ -21,7 +21,6 @@
#include "qhexdocument.h"
#include "buffer/qfilebuffer.h"
#include "commands/baseaddrcommand.h"
#include "commands/bookmark/bookmarkaddcommand.h"
#include "commands/bookmark/bookmarkclearcommand.h"
#include "commands/bookmark/bookmarkremovecommand.h"
@ -221,8 +220,6 @@ void QHexDocument::removeBookMarkAdjustRevert(
bool QHexDocument::isDocSaved() { return m_undostack->isClean(); }
bool QHexDocument::isUndoByteModified() { return m_bytesModFlag > 0; }
void QHexDocument::setDocSaved(bool b) {
if (b) {
m_undostack->setClean();
@ -677,20 +674,16 @@ char QHexDocument::at(qsizetype offset) const {
return char(m_buffer->at(offset));
}
void QHexDocument::SetBaseAddress(quint64 baseaddress) {
m_undostack->push(new BaseAddrCommand(this, m_baseaddress, baseaddress));
bool QHexDocument::setBaseAddress(quint64 baseaddress) {
if (m_baseaddress == baseaddress) {
return false;
}
void QHexDocument::setBaseAddress(quint64 baseaddress) {
if (m_baseaddress == baseaddress)
return;
m_baseaddress = baseaddress;
Q_EMIT documentChanged();
return true;
}
void QHexDocument::sync() { Q_EMIT documentChanged(); }
void QHexDocument::undo() {
m_undostack->undo();
Q_EMIT documentChanged();
@ -904,3 +897,5 @@ QHexDocument *QHexDocument::fromLargeFile(const QString &filename,
}
QHexBuffer *QHexDocument::buffer() const { return m_buffer; }
QUndoStack *QHexDocument::undoStack() const { return m_undostack; }

View File

@ -32,8 +32,6 @@
class QHexDocument : public QObject {
Q_OBJECT
friend class HexCommand;
private:
explicit QHexDocument(QHexBuffer *buffer,
bool readonly = false); // modified by wingsummer
@ -113,7 +111,6 @@ public:
const std::function<bool()> &pred = [] { return true; });
bool isDocSaved();
bool isUndoByteModified();
void setDocSaved(bool b = true);
void setMetafgVisible(bool b);
@ -137,9 +134,7 @@ public:
QByteArray read(qsizetype offset, qsizetype len = -1) const;
char at(qsizetype offset) const;
void SetBaseAddress(quintptr baseaddress);
void setBaseAddress(quintptr baseaddress);
void sync();
bool setBaseAddress(quintptr baseaddress);
public slots:
void undo();
@ -247,6 +242,8 @@ public:
QHexBuffer *buffer() const;
QUndoStack *undoStack() const;
signals:
/*================================*/
@ -277,7 +274,6 @@ private:
QHexMetadata *m_metadata;
QUndoStack *m_undostack;
size_t m_bytesModFlag = 0;
quintptr m_baseaddress;
quint8 m_areaindent;

View File

@ -32,37 +32,7 @@
#include <QUndoStack>
#include <QVector>
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
using qhash_result_t = uint;
// copying from QT6 source code for supporting QT5's qHashMulti
namespace QtPrivate {
template <typename T>
inline constexpr bool QNothrowHashableHelper_v =
noexcept(qHash(std::declval<const T &>()));
template <typename T, typename Enable = void>
struct QNothrowHashable : std::false_type {};
template <typename T>
struct QNothrowHashable<T, std::enable_if_t<QNothrowHashableHelper_v<T>>>
: std::true_type {};
template <typename T>
constexpr inline bool QNothrowHashable_v = QNothrowHashable<T>::value;
} // namespace QtPrivate
template <typename... T>
constexpr qhash_result_t
qHashMulti(qhash_result_t seed, const T &...args) noexcept(
std::conjunction_v<QtPrivate::QNothrowHashable<T>...>) {
QtPrivate::QHashCombine hash;
return ((seed = hash(seed, args)), ...), seed;
}
#else
using qhash_result_t = size_t;
#endif
struct QHexMetadataItem : QHexRegionObject<qsizetype, QHexMetadataItem> {
QColor foreground, background;
@ -96,24 +66,7 @@ public:
if (sel.foreground == this->foreground &&
sel.background == this->background &&
sel.comment == this->comment) {
if (canMerge(sel)) {
if (locker) {
locker->lock();
}
if (!this->contains(sel)) {
if (this->begin < sel.end) {
this->begin = qMin(this->begin, next(sel.begin));
this->end = qMax(next(this->end), sel.end);
} else {
this->begin = qMin(next(this->begin), sel.begin);
this->end = qMax(this->end, next(sel.end));
}
}
if (locker) {
locker->unlock();
}
if (mergeRegionWithoutMetaCheck(sel, locker)) {
return std::nullopt;
}
return false;
@ -130,6 +83,18 @@ public:
}
}
}
bool mergeRegionWithoutMetaCheck(const QHexMetadataItem &sel,
QMutex *locker = nullptr) {
Q_ASSERT(sel.foreground == this->foreground &&
sel.background == this->background &&
sel.comment == this->comment);
auto ret = Super::mergeRegion(sel, locker);
if (std::holds_alternative<bool>(ret)) {
return std::get<bool>(ret);
}
return false;
}
};
inline qhash_result_t qHash(const QHexMetadataItem &c,

View File

@ -101,7 +101,7 @@ void QHexView::setHeaderVisible(bool b) {
quintptr QHexView::addressBase() { return m_document->baseAddress(); }
void QHexView::setAddressBase(quintptr base) {
m_document->SetBaseAddress(base);
m_document->setBaseAddress(base);
}
bool QHexView::isSaved() { return m_document->isDocSaved(); }
@ -109,7 +109,7 @@ bool QHexView::isSaved() { return m_document->isDocSaved(); }
QFont QHexView::getHexeditorFont() {
QFont f = QFontDatabase::systemFont(QFontDatabase::FixedFont);
if (f.styleHint() != QFont::TypeWriter) {
f.setFamily("Monospace"); // Force Monospaced font
f.setFamily(QStringLiteral("Monospace")); // Force Monospaced font
f.setStyleHint(QFont::TypeWriter);
}
return f;

@ -1 +1 @@
Subproject commit cdaf256c8a44e724cc295e5b23cc291ac2414c02
Subproject commit 3fa9d2ba9d7dd78f719c43b482a5e7f49f135f1c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,20 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** This program is free software: you can redistribute it and/or modify it under
** the terms of the GNU Affero General Public License as published by the Free
** Software Foundation, version 3.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
** details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <https://www.gnu.org/licenses/>.
** =============================================================================
*/
#include "crashhandler.h"
#include "angelscript.h"
#include "class/pluginsystem.h"

View File

@ -1,3 +1,20 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** This program is free software: you can redistribute it and/or modify it under
** the terms of the GNU Affero General Public License as published by the Free
** Software Foundation, version 3.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
** details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <https://www.gnu.org/licenses/>.
** =============================================================================
*/
#include "dockcomponentsfactory.h"
#include "DockWidget.h"

View File

@ -1241,11 +1241,11 @@ bool PluginSystem::switchDocument(const QObject *sender, int handle) {
}
if (handle < 0) {
m_plgCurrentfid[plg] = -1;
m_plgviewMap[plg].currentFID = -1;
} else {
auto ctx = pluginContextById(plg, handle);
if (ctx) {
m_plgCurrentfid[plg] = handle;
m_plgviewMap[plg].currentFID = handle;
}
}
return true;
@ -1421,14 +1421,26 @@ bool PluginSystem::beginMarco(const QObject *sender, const QString &txt) {
return false;
}
auto fid = m_plgCurrentfid[plg];
auto fid = m_plgviewMap[plg].currentFID;
if (fid < 0) {
return false;
}
auto r = pluginContextById(plg, fid);
if (r) {
r->cmd = new QUndoCommand(txt);
auto &u = m_viewBindings[r->view];
auto rtxt = txt.trimmed();
if (rtxt.isEmpty()) {
rtxt = _pinfos.value(plg).id;
}
if (u.undoStackPlg.isEmpty()) {
u.undoStackPlg.append(qMakePair(new QUndoCommand(rtxt), plg));
} else {
u.undoStackPlg.append(qMakePair(
new QUndoCommand(rtxt, u.undoStackPlg.last().first), plg));
}
}
return true;
}
@ -1443,22 +1455,104 @@ bool PluginSystem::endMarco(const QObject *sender) {
return false;
}
auto fid = m_plgCurrentfid[plg];
auto fid = m_plgviewMap[plg].currentFID;
if (fid < 0) {
return false;
}
auto r = pluginContextById(plg, fid);
if (r) {
if (r->cmd) {
auto &u = m_viewBindings[r->view];
auto &undo = u.undoStackPlg;
if (undo.isEmpty()) {
return false;
} else {
auto &l = undo.last();
if (l.second != plg) {
return false;
}
auto r = std::find_if(
undo.rbegin(), undo.rend(),
[plg](const QPair<QUndoCommand *, IWingPlugin *> &ctx) {
return ctx.second == plg;
});
if (r == undo.rend()) {
return false;
}
if (r != undo.rbegin()) {
Logger::warning(tr("UnexpectedUndoCmdPushDetected"));
undo.erase(r.base(), undo.end());
}
auto cmdl = undo.takeLast();
if (undo.isEmpty()) {
auto e = pluginCurrentEditor(plg);
if (e) {
if (e == nullptr) {
return false;
}
auto doc = e->hexEditor()->document();
doc->pushMakeUndo(r->cmd);
r->cmd = nullptr;
doc->pushMakeUndo(cmdl.first);
return true;
}
return true;
}
}
return false;
}
bool PluginSystem::isMacroEmpty(const QObject *sender) {
auto plg = checkPluginAndReport(sender, __func__);
if (plg == nullptr) {
return true;
}
if (passByFailedGuard(sender, __func__, {})) {
return true;
}
auto fid = m_plgviewMap[plg].currentFID;
if (fid < 0) {
return true;
}
auto r = pluginContextById(plg, fid);
if (r) {
auto &u = m_viewBindings[r->view];
auto &undo = u.undoStackPlg;
return undo.isEmpty();
}
return true;
}
bool PluginSystem::resetMarco(const QObject *sender) {
auto plg = checkPluginAndReport(sender, __func__);
if (plg == nullptr) {
return false;
}
if (passByFailedGuard(sender, __func__, {})) {
return false;
}
auto fid = m_plgviewMap[plg].currentFID;
if (fid < 0) {
return false;
}
auto r = pluginContextById(plg, fid);
if (r) {
auto &u = m_viewBindings[r->view];
auto &undo = u.undoStackPlg;
if (!undo.isEmpty()) {
delete undo.first().first;
undo.clear();
}
return true;
}
return false;
}
@ -1620,7 +1714,7 @@ bool PluginSystem::writeString(const QObject *sender, qsizetype offset,
auto doc = editor->document();
auto unicode = Utilities::encodingString(value, encoding);
auto uc = pluginCurrentUndoCmd(plg);
auto uc = currentUndoCmd(e);
auto cmd = doc->MakeReplace(uc, editor->cursor(), offset, unicode);
if (uc == nullptr && cmd) {
_rwlock.lockForWrite();
@ -1647,7 +1741,7 @@ bool PluginSystem::writeBytes(const QObject *sender, qsizetype offset,
if (e) {
auto editor = e->hexEditor();
auto doc = editor->document();
auto uc = pluginCurrentUndoCmd(plg);
auto uc = currentUndoCmd(e);
auto cmd = doc->MakeReplace(uc, editor->cursor(), offset, data);
if (uc == nullptr && cmd) {
_rwlock.lockForWrite();
@ -1816,7 +1910,7 @@ bool PluginSystem::insertString(const QObject *sender, qsizetype offset,
auto doc = editor->document();
auto unicode = Utilities::encodingString(value, encoding);
auto uc = pluginCurrentUndoCmd(plg);
auto uc = currentUndoCmd(e);
auto cmd = doc->MakeInsert(uc, editor->cursor(), offset, unicode);
if (uc == nullptr && cmd) {
_rwlock.lockForWrite();
@ -1843,7 +1937,7 @@ bool PluginSystem::insertBytes(const QObject *sender, qsizetype offset,
if (e) {
auto editor = e->hexEditor();
auto doc = editor->document();
auto uc = pluginCurrentUndoCmd(plg);
auto uc = currentUndoCmd(e);
auto cmd = doc->MakeInsert(uc, editor->cursor(), offset, data);
if (uc == nullptr && cmd) {
_rwlock.lockForWrite();
@ -1998,7 +2092,7 @@ bool PluginSystem::appendString(const QObject *sender, const QString &value,
auto offset = doc->length();
auto unicode = Utilities::encodingString(value, encoding);
auto uc = pluginCurrentUndoCmd(plg);
auto uc = currentUndoCmd(e);
auto cmd = doc->MakeInsert(uc, editor->cursor(), offset, unicode);
if (uc == nullptr && cmd) {
_rwlock.lockForWrite();
@ -2024,7 +2118,7 @@ bool PluginSystem::appendBytes(const QObject *sender, const QByteArray &data) {
if (e) {
auto editor = e->hexEditor();
auto doc = editor->document();
auto uc = pluginCurrentUndoCmd(plg);
auto uc = currentUndoCmd(e);
auto cmd = doc->MakeAppend(uc, editor->cursor(), data);
if (uc == nullptr && cmd) {
_rwlock.lockForWrite();
@ -2052,7 +2146,7 @@ bool PluginSystem::removeBytes(const QObject *sender, qsizetype offset,
auto editor = e->hexEditor();
auto doc = editor->document();
auto uc = pluginCurrentUndoCmd(plg);
auto uc = currentUndoCmd(e);
auto cmd = doc->MakeRemove(uc, editor->cursor(), offset, len);
if (uc == nullptr && cmd) {
_rwlock.lockForWrite();
@ -2195,7 +2289,7 @@ bool PluginSystem::metadata(const QObject *sender, qsizetype begin,
if (e) {
auto doc = e->hexEditor()->document();
auto uc = pluginCurrentUndoCmd(plg);
auto uc = currentUndoCmd(e);
auto cmd = doc->metadata()->MakeMetadata(uc, begin, begin + length - 1,
fgcolor, bgcolor, comment);
if (uc == nullptr && cmd) {
@ -2223,7 +2317,7 @@ bool PluginSystem::removeMetadata(const QObject *sender, qsizetype offset) {
auto e = pluginCurrentEditor(plg);
if (e) {
auto doc = e->hexEditor()->document();
auto uc = pluginCurrentUndoCmd(plg);
auto uc = currentUndoCmd(e);
auto cmd = doc->metadata()->MakeRemoveMetadata(uc, offset);
if (uc == nullptr && cmd) {
doc->pushMakeUndo(cmd);
@ -2250,7 +2344,7 @@ bool PluginSystem::clearMetadata(const QObject *sender) {
auto e = pluginCurrentEditor(plg);
if (e) {
auto doc = e->hexEditor()->document();
auto uc = pluginCurrentUndoCmd(plg);
auto uc = currentUndoCmd(e);
auto cmd = doc->metadata()->MakeClear(uc);
if (uc == nullptr && cmd) {
doc->pushMakeUndo(cmd);
@ -2372,7 +2466,7 @@ bool PluginSystem::addBookMark(const QObject *sender, qsizetype pos,
auto e = pluginCurrentEditor(plg);
if (e) {
auto doc = e->hexEditor()->document();
auto uc = pluginCurrentUndoCmd(plg);
auto uc = currentUndoCmd(e);
auto cmd = doc->MakeAddBookMark(uc, pos, comment);
if (uc == nullptr && cmd) {
doc->pushMakeUndo(cmd);
@ -2400,7 +2494,7 @@ bool PluginSystem::modBookMark(const QObject *sender, qsizetype pos,
auto e = pluginCurrentEditor(plg);
if (e) {
auto doc = e->hexEditor()->document();
auto uc = pluginCurrentUndoCmd(plg);
auto uc = currentUndoCmd(e);
auto cmd = doc->MakeModBookMark(uc, pos, comment);
if (uc == nullptr && cmd) {
doc->pushMakeUndo(cmd);
@ -2427,7 +2521,7 @@ bool PluginSystem::removeBookMark(const QObject *sender, qsizetype pos) {
auto e = pluginCurrentEditor(plg);
if (e) {
auto doc = e->hexEditor()->document();
auto uc = pluginCurrentUndoCmd(plg);
auto uc = currentUndoCmd(e);
auto cmd = doc->MakeRemoveBookMark(uc, pos);
if (uc == nullptr && cmd) {
doc->pushMakeUndo(cmd);
@ -2454,7 +2548,7 @@ bool PluginSystem::clearBookMark(const QObject *sender) {
auto e = pluginCurrentEditor(plg);
if (e) {
auto doc = e->hexEditor()->document();
auto uc = pluginCurrentUndoCmd(plg);
auto uc = currentUndoCmd(e);
auto cmd = doc->MakeClearBookMark(uc);
if (uc == nullptr && cmd) {
doc->pushMakeUndo(cmd);
@ -2478,11 +2572,12 @@ bool PluginSystem::closeAllFiles(const QObject *sender) {
return false;
}
auto &maps = m_plgviewMap[plg];
auto &map = m_plgviewMap[plg];
auto &maps = map.contexts;
for (auto &item : maps) {
closeEditor(plg, getUIDHandle(item->fid), true);
}
m_plgCurrentfid[plg] = -1;
map.currentFID = -1;
maps.clear();
return true;
}
@ -2690,7 +2785,7 @@ ErrFile PluginSystem::closeCurrent(const QObject *sender, bool force) {
return _win->closeEditor(view, force);
}
ErrFile PluginSystem::openCurrent(const QObject *sender) {
int PluginSystem::openCurrent(const QObject *sender) {
if (!checkThreadAff()) {
return ErrFile::NotAllowedInNoneGUIThread;
}
@ -2710,16 +2805,14 @@ ErrFile PluginSystem::openCurrent(const QObject *sender) {
return ErrFile::AlreadyOpened;
}
auto id = assginHandleForPluginView(plg, view);
auto handle = getUIDHandle(id);
m_plgCurrentfid[plg] = handle;
auto id = assginHandleForOpenPluginView(plg, view);
PluginSystem::instance().dispatchEvent(
IWingPlugin::RegisteredEvent::PluginFileOpened,
{quintptr(plg), view->fileName(), handle,
{quintptr(plg), view->fileName(), id,
QVariant::fromValue(_win->getEditorViewFileType(view))});
return ErrFile(handle);
return id;
}
return ErrFile::Error;
}
@ -2778,7 +2871,7 @@ ErrFile PluginSystem::exportFile(const QObject *sender, int handle,
return ErrFile::NotExist;
}
ErrFile PluginSystem::openWorkSpace(const QObject *sender,
int PluginSystem::openWorkSpace(const QObject *sender,
const QString &filename) {
if (!checkThreadAff()) {
return ErrFile::NotAllowedInNoneGUIThread;
@ -2803,16 +2896,14 @@ ErrFile PluginSystem::openWorkSpace(const QObject *sender,
checkPluginHasAlreadyOpened(plg, view)) {
return ErrFile::AlreadyOpened;
}
auto id = assginHandleForPluginView(plg, view);
auto handle = getUIDHandle(id);
m_plgCurrentfid[plg] = handle;
auto id = assginHandleForOpenPluginView(plg, view);
PluginSystem::instance().dispatchEvent(
IWingPlugin::RegisteredEvent::PluginFileOpened,
{quintptr(plg), filename, handle,
{quintptr(plg), filename, id,
QVariant::fromValue(_win->getEditorViewFileType(view))});
return ErrFile(handle);
return id;
} else {
return ret;
}
@ -2884,7 +2975,7 @@ ErrFile PluginSystem::closeHandle(const QObject *sender, int handle) {
return WingHex::ErrFile::NotExist;
}
ErrFile PluginSystem::openExtFile(const QObject *sender, const QString &ext,
int PluginSystem::openExtFile(const QObject *sender, const QString &ext,
const QString &file) {
if (!checkThreadAff()) {
return ErrFile::NotAllowedInNoneGUIThread;
@ -2909,22 +3000,20 @@ ErrFile PluginSystem::openExtFile(const QObject *sender, const QString &ext,
checkPluginHasAlreadyOpened(plg, view)) {
return ErrFile::AlreadyOpened;
}
auto id = assginHandleForPluginView(plg, view);
auto handle = getUIDHandle(id);
m_plgCurrentfid[plg] = handle;
auto id = assginHandleForOpenPluginView(plg, view);
PluginSystem::instance().dispatchEvent(
IWingPlugin::RegisteredEvent::PluginFileOpened,
{quintptr(plg), file, handle,
{quintptr(plg), file, id,
QVariant::fromValue(_win->getEditorViewFileType(view))});
return ErrFile(handle);
return id;
} else {
return ret;
}
}
ErrFile PluginSystem::openFile(const QObject *sender, const QString &filename) {
int PluginSystem::openFile(const QObject *sender, const QString &filename) {
if (!checkThreadAff()) {
return ErrFile::NotAllowedInNoneGUIThread;
}
@ -2948,21 +3037,19 @@ ErrFile PluginSystem::openFile(const QObject *sender, const QString &filename) {
checkPluginHasAlreadyOpened(plg, view)) {
return ErrFile::AlreadyOpened;
}
auto id = assginHandleForPluginView(plg, view);
auto handle = getUIDHandle(id);
m_plgCurrentfid[plg] = handle;
auto id = assginHandleForOpenPluginView(plg, view);
PluginSystem::instance().dispatchEvent(
IWingPlugin::RegisteredEvent::PluginFileOpened,
{quintptr(plg), filename, handle,
{quintptr(plg), filename, id,
QVariant::fromValue(_win->getEditorViewFileType(view))});
return ErrFile(handle);
return id;
} else {
return ret;
}
}
ErrFile PluginSystem::newFile(const QObject *sender) {
int PluginSystem::newFile(const QObject *sender) {
if (!checkThreadAff()) {
return ErrFile::NotAllowedInNoneGUIThread;
}
@ -2981,18 +3068,17 @@ ErrFile PluginSystem::newFile(const QObject *sender) {
}
auto view = _win->newfileGUI();
if (view) {
auto id = assginHandleForPluginView(plg, view);
auto handle = getUIDHandle(id);
m_plgCurrentfid[plg] = handle;
auto id = assginHandleForOpenPluginView(plg, view);
m_plgviewMap[plg].currentFID = id;
PluginSystem::instance().dispatchEvent(
IWingPlugin::RegisteredEvent::PluginFileOpened,
{quintptr(plg),
{},
handle,
id,
QVariant::fromValue(_win->getEditorViewFileType(view))});
return ErrFile(handle);
return id;
} else {
return ErrFile::Error;
}
@ -3196,11 +3282,8 @@ EditorView *PluginSystem::getCurrentPluginView(IWingPlugin *plg) {
if (plg == nullptr) {
return nullptr;
}
if (!m_plgCurrentfid.contains(plg)) {
m_plgCurrentfid.insert(plg, -1);
}
auto fid = m_plgCurrentfid[plg];
auto fid = m_plgviewMap[plg].currentFID;
auto ctx = pluginContextById(plg, fid);
if (ctx) {
return ctx->view;
@ -3236,8 +3319,8 @@ void PluginSystem::retranslateMetadata(IWingPluginBase *plg, PluginInfo &meta) {
meta.license = plg->retranslate(meta.license);
}
PluginSystem::SharedUniqueId
PluginSystem::assginHandleForPluginView(IWingPlugin *plg, EditorView *view) {
int PluginSystem::assginHandleForOpenPluginView(IWingPlugin *plg,
EditorView *view) {
if (plg == nullptr || view == nullptr) {
return {};
}
@ -3249,9 +3332,13 @@ PluginSystem::assginHandleForPluginView(IWingPlugin *plg, EditorView *view) {
context->linkedplg = plg;
context->view = view;
m_plgviewMap[plg].append(context);
m_viewBindings[view].append(plg);
return id;
auto handle = getUIDHandle(id);
m_plgviewMap[plg].currentFID = handle;
m_plgviewMap[plg].contexts.append(context);
m_viewBindings[view].linkedplg.append(plg);
return handle;
}
PluginInfo PluginSystem::parsePluginMetadata(const QJsonObject &meta) {
@ -3329,12 +3416,12 @@ bool PluginSystem::checkPluginCanOpenedFile(IWingPlugin *plg) {
if (plg == nullptr) {
return false;
}
return m_plgviewMap[plg].size() <= UCHAR_MAX;
return m_plgviewMap[plg].contexts.size() <= UCHAR_MAX;
}
bool PluginSystem::checkPluginHasAlreadyOpened(IWingPlugin *plg,
EditorView *view) {
auto &maps = m_plgviewMap[plg];
auto &maps = m_plgviewMap[plg].contexts;
auto ret =
std::find_if(maps.begin(), maps.end(),
[view](const QSharedPointer<PluginFileContext> &content) {
@ -3348,35 +3435,15 @@ void PluginSystem::cleanUpEditorViewHandle(EditorView *view) {
auto v = m_viewBindings[view];
// clean up
for (auto &plg : v) {
for (auto &plg : v.linkedplg) {
auto &handles = m_plgviewMap[plg];
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
handles.erase(std::remove_if(
handles.begin(), handles.end(),
[view, this](const QSharedPointer<PluginFileContext> &v) {
auto id = handles.currentFID;
handles.contexts.removeIf(
[view, this, id,
plg](const QSharedPointer<PluginFileContext> &v) {
if (v->view == view) {
if (equalCompareHandle(v->fid,
m_plgCurrentfid[v->linkedplg])) {
m_plgCurrentfid[v->linkedplg] = -1;
}
dispatchEvent(
IWingPlugin::RegisteredEvent::PluginFileClosed,
{quintptr(v->linkedplg), v->view->fileName(),
getUIDHandle(v->fid),
QVariant::fromValue(
_win->getEditorViewFileType(view))});
return true;
}
return false;
}));
#else
handles.removeIf(
[view, this](const QSharedPointer<PluginFileContext> &v) {
if (v->view == view) {
if (equalCompareHandle(v->fid,
m_plgCurrentfid[v->linkedplg])) {
m_plgCurrentfid[v->linkedplg] = -1;
if (equalCompareHandle(v->fid, id)) {
m_plgviewMap[plg].currentFID = -1;
}
dispatchEvent(
IWingPlugin::RegisteredEvent::PluginFileClosed,
@ -3388,7 +3455,6 @@ void PluginSystem::cleanUpEditorViewHandle(EditorView *view) {
}
return false;
});
#endif
}
m_viewBindings.remove(view);
}
@ -3396,7 +3462,8 @@ void PluginSystem::cleanUpEditorViewHandle(EditorView *view) {
bool PluginSystem::closeEditor(IWingPlugin *plg, int handle, bool force) {
if (handle >= 0) {
auto &handles = m_plgviewMap[plg];
auto &vm = m_plgviewMap[plg];
auto &handles = vm.contexts;
auto r = std::find_if(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
handles.cbegin(), handles.cend(),
@ -3411,15 +3478,16 @@ bool PluginSystem::closeEditor(IWingPlugin *plg, int handle, bool force) {
}
auto sharedc = *r;
auto &bind = m_viewBindings[sharedc->view];
auto &vb = m_viewBindings[sharedc->view];
auto &bind = vb.linkedplg;
bind.removeOne(plg);
if (bind.isEmpty()) {
_win->closeEditor(sharedc->view, force);
m_viewBindings.remove(sharedc->view);
}
if (m_plgCurrentfid[plg] == handle) {
m_plgCurrentfid[plg] = -1;
if (vm.currentFID == handle) {
vm.currentFID = -1;
}
handles.erase(r);
@ -3434,7 +3502,8 @@ bool PluginSystem::closeHandle(IWingPlugin *plg, int handle) {
if (handle < 0) {
return false;
}
auto &handles = m_plgviewMap[plg];
auto &vm = m_plgviewMap[plg];
auto &handles = vm.contexts;
auto r = std::find_if(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
handles.cbegin(), handles.cend(),
@ -3449,14 +3518,14 @@ bool PluginSystem::closeHandle(IWingPlugin *plg, int handle) {
}
auto sharedc = *r;
auto &bind = m_viewBindings[sharedc->view];
auto &bind = m_viewBindings[sharedc->view].linkedplg;
bind.removeOne(plg);
if (bind.isEmpty()) {
m_viewBindings.remove(sharedc->view);
}
if (m_plgCurrentfid[plg] == handle) {
m_plgCurrentfid[plg] = -1;
if (vm.currentFID == handle) {
vm.currentFID = -1;
}
handles.erase(r);
return true;
@ -3949,7 +4018,6 @@ void PluginSystem::loadPlugin(IWingPlugin *p, PluginInfo &meta,
// prepare for file contenxt
m_plgviewMap.insert(p, {});
m_plgCurrentfid.insert(p, -1);
} catch (const QString &error) {
Logger::critical(error);
if (p_tr) {
@ -4323,7 +4391,7 @@ void PluginSystem::destory() {
EditorView *PluginSystem::pluginCurrentEditor(IWingPlugin *plg) const {
if (plg) {
auto fid = m_plgCurrentfid[plg];
auto fid = m_plgviewMap[plg].currentFID;
if (fid < 0) {
return _win->currentEditor();
}
@ -4336,12 +4404,23 @@ EditorView *PluginSystem::pluginCurrentEditor(IWingPlugin *plg) const {
return nullptr;
}
QUndoCommand *PluginSystem::currentUndoCmd(EditorView *view) {
if (m_viewBindings.contains(view)) {
auto &vb = m_viewBindings[view];
auto &undo = vb.undoStackPlg;
if (!undo.isEmpty()) {
return undo.last().first;
}
}
return nullptr;
}
QSharedPointer<PluginSystem::PluginFileContext>
PluginSystem::pluginContextById(IWingPlugin *plg, int fid) const {
if (fid < 0) {
return nullptr;
}
auto &handles = m_plgviewMap[plg];
auto &handles = m_plgviewMap[plg].contexts;
auto r = std::find_if(handles.begin(), handles.end(),
[fid](const QSharedPointer<PluginFileContext> &d) {
return equalCompareHandle(d->fid, fid);
@ -4351,18 +4430,3 @@ PluginSystem::pluginContextById(IWingPlugin *plg, int fid) const {
}
return *r;
}
QUndoCommand *PluginSystem::pluginCurrentUndoCmd(IWingPlugin *plg) const {
if (plg) {
auto fid = m_plgCurrentfid[plg];
if (fid < 0) {
return nullptr;
}
auto ctx = pluginContextById(plg, fid);
if (ctx) {
return ctx->cmd;
}
}
return nullptr;
}

View File

@ -118,12 +118,22 @@ private:
SharedUniqueId fid;
EditorView *view = nullptr;
IWingPlugin *linkedplg = nullptr;
QUndoCommand *cmd = nullptr;
};
~PluginFileContext() {
if (cmd) {
delete cmd;
struct PluginFile {
QVector<QSharedPointer<PluginFileContext>> contexts;
int currentFID = -1;
};
struct ViewBind {
QList<IWingPlugin *> linkedplg;
QList<QPair<QUndoCommand *, IWingPlugin *>> undoStackPlg;
~ViewBind() {
if (!undoStackPlg.isEmpty()) {
delete undoStackPlg.first().first;
}
undoStackPlg.clear();
}
};
@ -194,8 +204,7 @@ private:
EditorView *handle2EditorView(IWingPlugin *plg, int handle);
SharedUniqueId assginHandleForPluginView(IWingPlugin *plg,
EditorView *view);
int assginHandleForOpenPluginView(IWingPlugin *plg, EditorView *view);
static bool equalCompareHandle(const SharedUniqueId &id, int handle);
@ -226,7 +235,7 @@ private:
QSharedPointer<PluginFileContext> pluginContextById(IWingPlugin *plg,
int fid) const;
QUndoCommand *pluginCurrentUndoCmd(IWingPlugin *plg) const;
QUndoCommand *currentUndoCmd(EditorView *view);
private:
void loadPlugin(IWingPlugin *p, PluginInfo &meta,
@ -274,7 +283,7 @@ private:
auto e = getCurrentPluginView(plg);
if (e) {
return EditorView::insertBasicTypeContent<T>(
e, offset, value, pluginCurrentUndoCmd(plg), _rwlock);
e, offset, value, currentUndoCmd(e), _rwlock);
}
return false;
}
@ -286,7 +295,7 @@ private:
auto e = getCurrentPluginView(plg);
if (e) {
return EditorView::writeBasicTypeContent<T>(
e, offset, value, pluginCurrentUndoCmd(plg), _rwlock);
e, offset, value, currentUndoCmd(e), _rwlock);
}
return false;
}
@ -297,7 +306,7 @@ private:
auto e = getCurrentPluginView(plg);
if (e) {
return EditorView::appendBasicTypeContent<T>(
e, value, pluginCurrentUndoCmd(plg), _rwlock);
e, value, currentUndoCmd(e), _rwlock);
}
return false;
}
@ -518,6 +527,10 @@ public slots:
WING_API bool endMarco(const QObject *sender);
WING_API bool isMacroEmpty(const QObject *sender);
WING_API bool resetMarco(const QObject *sender);
WING_API bool writeInt8(const QObject *sender, qsizetype offset,
qint8 value);
@ -648,16 +661,14 @@ public slots:
WING_API bool setMetaCommentVisible(const QObject *sender, bool b);
// mainwindow
WING_API WingHex::ErrFile newFile(const QObject *sender);
WING_API int newFile(const QObject *sender);
WING_API WingHex::ErrFile openFile(const QObject *sender,
const QString &filename);
WING_API int openFile(const QObject *sender, const QString &filename);
WING_API WingHex::ErrFile
openExtFile(const QObject *sender, const QString &ext, const QString &file);
WING_API int openExtFile(const QObject *sender, const QString &ext,
const QString &file);
WING_API WingHex::ErrFile openWorkSpace(const QObject *sender,
const QString &filename);
WING_API int openWorkSpace(const QObject *sender, const QString &filename);
WING_API WingHex::ErrFile closeHandle(const QObject *sender, int handle);
@ -672,7 +683,7 @@ public slots:
WING_API WingHex::ErrFile saveAsFile(const QObject *sender, int handle,
const QString &savename);
WING_API WingHex::ErrFile openCurrent(const QObject *sender);
WING_API int openCurrent(const QObject *sender);
WING_API WingHex::ErrFile closeCurrent(const QObject *sender, bool force);
@ -729,10 +740,8 @@ private:
QMap<IWingPlugin::RegisteredEvent, QList<IWingPlugin *>> _evplgs;
QHash<IWingPlugin *, QVector<QSharedPointer<PluginFileContext>>>
m_plgviewMap;
QHash<IWingPlugin *, int> m_plgCurrentfid; // fid
QHash<EditorView *, QList<IWingPlugin *>> m_viewBindings;
QHash<IWingPlugin *, PluginFile> m_plgviewMap;
QHash<EditorView *, ViewBind> m_viewBindings;
UniqueIdGenerator m_idGen;

View File

@ -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),

View File

@ -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();

View File

@ -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;

View File

@ -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) {

View File

@ -34,6 +34,7 @@
#include <QTextBrowser>
#include <QToolButton>
#include <QTreeView>
#include <QUndoView>
#include <QtConcurrent/QtConcurrentRun>
#include <QtEndian>
@ -44,7 +45,6 @@
#include "Qt-Advanced-Docking-System/src/DockWidget.h"
#include "WingPlugin/iwingplugin.h"
#include "class/recentfilemanager.h"
#include "class/scriptmanager.h"
#include "control/editorview.h"
#include "control/qtableviewext.h"
#include "control/scriptingconsole.h"
@ -122,6 +122,10 @@ private:
buildUpScriptBgOutputDock(ads::CDockManager *dock, ads::DockWidgetArea area,
ads::CDockAreaWidget *areaw = nullptr);
ads::CDockAreaWidget *
buildUpUndoStackDock(ads::CDockManager *dock, ads::DockWidgetArea area,
ads::CDockAreaWidget *areaw = nullptr);
RibbonTabContent *buildFilePage(RibbonTabContent *tab);
RibbonTabContent *buildEditPage(RibbonTabContent *tab);
RibbonTabContent *buildViewPage(RibbonTabContent *tab);
@ -243,6 +247,7 @@ private:
void connectEditorView(EditorView *editor);
void swapEditor(EditorView *old, EditorView *cur);
void updateWindowTitle();
void loadFindResult(EditorView *view);
@ -496,6 +501,8 @@ private:
QTableViewExt *m_metadatas = nullptr;
MetaDataModel *_metadataEmpty = nullptr;
QUndoView *_undoView = nullptr;
QMap<ToolButtonIndex, QToolButton *> m_toolBtneditors;
QAction *m_aDelBookMark = nullptr;

View File

@ -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 {

View File

@ -202,6 +202,7 @@ private:
void updateEditModeEnabled();
ScriptEditor *currentEditor() const;
void swapEditor(ScriptEditor *old, ScriptEditor *cur);
void updateWindowTitle();
void updateRunDebugMode(bool disable = false);