Compare commits

...

4 Commits

91 changed files with 5499 additions and 3322 deletions

View File

@ -7,8 +7,8 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Run clang-format style check for C/C++/Protobuf programs. - name: Run clang-format style check for C/C++/Protobuf programs.
uses: jidicula/clang-format-action@v4.14.0 uses: jidicula/clang-format-action@v4.15.0
with: with:
clang-format-version: '19' clang-format-version: '20'
exclude-regex: '(qt-template|mkinstaller|grammar)' exclude-regex: '(qt-template|mkinstaller|grammar)'
fallback-style: 'LLVM' # optional fallback-style: 'LLVM' # optional

View File

@ -51,8 +51,8 @@ add_library(
document/commands/bookmark/bookmarkremovecommand.h document/commands/bookmark/bookmarkremovecommand.h
document/commands/bookmark/bookmarkreplacecommand.cpp document/commands/bookmark/bookmarkreplacecommand.cpp
document/commands/bookmark/bookmarkreplacecommand.h document/commands/bookmark/bookmarkreplacecommand.h
document/commands/baseaddrcommand.cpp document/commands/undocommandbase.h
document/commands/baseaddrcommand.h document/commands/undocommandbase.cpp
document/qhexcursor.cpp document/qhexcursor.cpp
document/qhexcursor.h document/qhexcursor.h
document/qhexdocument.cpp document/qhexdocument.cpp

View File

@ -23,8 +23,22 @@
BookMarkAddCommand::BookMarkAddCommand(QHexDocument *doc, qsizetype pos, BookMarkAddCommand::BookMarkAddCommand(QHexDocument *doc, qsizetype pos,
QString comment, QUndoCommand *parent) 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); } 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); } void BookMarkAddCommand::undo() { m_doc->removeBookMark(m_pos); }

View File

@ -24,13 +24,22 @@
#include "bookmarkcommand.h" #include "bookmarkcommand.h"
class BookMarkAddCommand : public BookMarkCommand { #include <QCoreApplication>
public:
BookMarkAddCommand(QHexDocument *doc, qsizetype pos, QString comment,
QUndoCommand *parent = nullptr);
void undo() override; class BookMarkAddCommand : public BookMarkCommand {
void redo() override; 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 #endif // BOOKMARKADDCOMMAND_H

View File

@ -24,8 +24,16 @@
BookMarkClearCommand::BookMarkClearCommand( BookMarkClearCommand::BookMarkClearCommand(
QHexDocument *doc, const QMap<qsizetype, QString> &bookmarks, QHexDocument *doc, const QMap<qsizetype, QString> &bookmarks,
QUndoCommand *parent) 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(); } 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); } void BookMarkClearCommand::undo() { m_doc->applyBookMarks(m_bookmarks); }

View File

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

View File

@ -21,6 +21,8 @@
#include "bookmarkcommand.h" #include "bookmarkcommand.h"
BookMarkCommand::BookMarkCommand(QHexDocument *doc, qsizetype pos, BookMarkCommand::BookMarkCommand(const QString &text, QHexDocument *doc,
QString comment, QUndoCommand *parent) qsizetype pos, QString comment,
: QUndoCommand(parent), m_doc(doc), m_comment(comment), m_pos(pos) {} QUndoCommand *parent)
: UndoCommandBase(text, parent), m_doc(doc), m_comment(comment),
m_pos(pos) {}

View File

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

View File

@ -24,8 +24,21 @@
BookMarkRemoveCommand::BookMarkRemoveCommand(QHexDocument *doc, qsizetype pos, BookMarkRemoveCommand::BookMarkRemoveCommand(QHexDocument *doc, qsizetype pos,
QString comment, QString comment,
QUndoCommand *parent) 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); } 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); } void BookMarkRemoveCommand::undo() { m_doc->addBookMark(m_pos, m_comment); }

View File

@ -24,13 +24,23 @@
#include "bookmarkcommand.h" #include "bookmarkcommand.h"
class BookMarkRemoveCommand : public BookMarkCommand { #include <QCoreApplication>
public:
BookMarkRemoveCommand(QHexDocument *doc, qsizetype pos, QString comment,
QUndoCommand *parent = nullptr);
void undo() override; class BookMarkRemoveCommand : public BookMarkCommand {
void redo() override; 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 #endif // BOOKMARKREMOVECOMMAND_H

View File

@ -25,8 +25,23 @@ BookMarkReplaceCommand::BookMarkReplaceCommand(QHexDocument *doc, qsizetype pos,
QString comment, QString comment,
QString oldcomment, QString oldcomment,
QUndoCommand *parent) 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); } 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); } void BookMarkReplaceCommand::undo() { m_doc->modBookMark(m_pos, m_oldcomment); }

View File

@ -24,13 +24,22 @@
#include "bookmarkcommand.h" #include "bookmarkcommand.h"
class BookMarkReplaceCommand : public BookMarkCommand { #include <QCoreApplication>
public:
BookMarkReplaceCommand(QHexDocument *doc, qsizetype pos, QString comment,
QString oldcomment, QUndoCommand *parent = nullptr);
void undo() override; class BookMarkReplaceCommand : public BookMarkCommand {
void redo() override; 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: protected:
QString m_oldcomment; QString m_oldcomment;

View File

@ -24,7 +24,7 @@
AppendCommand::AppendCommand(QHexDocument *doc, QHexCursor *cursor, AppendCommand::AppendCommand(QHexDocument *doc, QHexCursor *cursor,
const QByteArray &data, int nibbleindex, const QByteArray &data, int nibbleindex,
QUndoCommand *parent) QUndoCommand *parent)
: HexCommand(doc, cursor, nibbleindex, parent) { : HexCommand(tr("[HexAppend]"), doc, cursor, nibbleindex, parent) {
m_offset = -1; m_offset = -1;
m_data = data; m_data = data;
m_length = data.length(); m_length = data.length();
@ -36,7 +36,6 @@ void AppendCommand::undo() {
m_doc->insertBookMarkAdjustRevert(offset, m_length); m_doc->insertBookMarkAdjustRevert(offset, m_length);
m_doc->metadata()->insertAdjustRevert(offset, m_length); m_doc->metadata()->insertAdjustRevert(offset, m_length);
m_cursor->setPos(offset, m_nibbleindex); m_cursor->setPos(offset, m_nibbleindex);
HexCommand::undo();
} }
void AppendCommand::redo() { void AppendCommand::redo() {
@ -49,5 +48,15 @@ void AppendCommand::redo() {
} else { } else {
m_cursor->setPos(offset + m_length, m_nibbleindex); 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 "hexcommand.h"
#include <QCoreApplication>
class AppendCommand : public HexCommand { class AppendCommand : public HexCommand {
Q_DECLARE_TR_FUNCTIONS(AppendCommand)
public: public:
AppendCommand(QHexDocument *doc, QHexCursor *cursor, const QByteArray &data, explicit AppendCommand(QHexDocument *doc, QHexCursor *cursor,
int nibbleindex, QUndoCommand *parent = nullptr); const QByteArray &data, int nibbleindex,
void undo() override; QUndoCommand *parent = nullptr);
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 // APPENDCOMMAND_H #endif // APPENDCOMMAND_H

View File

@ -21,14 +21,8 @@
#include "hexcommand.h" #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)
: 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) {} 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,15 +25,13 @@
#include "document/qhexcursor.h" #include "document/qhexcursor.h"
#include "document/qhexdocument.h" #include "document/qhexdocument.h"
#include <QUndoCommand> #include "document/commands/undocommandbase.h"
class HexCommand : public QUndoCommand { class HexCommand : public UndoCommandBase {
public: public:
HexCommand(QHexDocument *doc, QHexCursor *cursor, int nibbleindex, explicit HexCommand(const QString &text, QHexDocument *doc,
QUndoCommand *parent = nullptr); QHexCursor *cursor, int nibbleindex,
QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
protected: protected:
QHexDocument *m_doc; QHexDocument *m_doc;

View File

@ -21,10 +21,13 @@
#include "insertcommand.h" #include "insertcommand.h"
#include "document/commands/hex/replacecommand.h"
InsertCommand::InsertCommand(QHexDocument *doc, QHexCursor *cursor, InsertCommand::InsertCommand(QHexDocument *doc, QHexCursor *cursor,
qsizetype offset, const QByteArray &data, qsizetype offset, const QByteArray &data,
int nibbleindex, QUndoCommand *parent) int nibbleindex, QUndoCommand *parent)
: HexCommand(doc, cursor, nibbleindex, parent) { : HexCommand(tr("[HexInsert] pos: %1").arg(offset), doc, cursor,
nibbleindex, parent) {
m_offset = offset; m_offset = offset;
m_data = data; m_data = data;
m_length = data.length(); m_length = data.length();
@ -35,7 +38,6 @@ void InsertCommand::undo() {
m_doc->insertBookMarkAdjustRevert(m_offset, m_length); m_doc->insertBookMarkAdjustRevert(m_offset, m_length);
m_doc->metadata()->insertAdjustRevert(m_offset, m_length); m_doc->metadata()->insertAdjustRevert(m_offset, m_length);
m_cursor->setPos(m_offset, m_nibbleindex); m_cursor->setPos(m_offset, m_nibbleindex);
HexCommand::undo();
} }
void InsertCommand::redo() { void InsertCommand::redo() {
m_doc->_insert(m_offset, m_data); m_doc->_insert(m_offset, m_data);
@ -46,5 +48,28 @@ void InsertCommand::redo() {
} else { } else {
m_cursor->setPos(m_offset + m_length, m_nibbleindex); 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 "hexcommand.h"
#include <QCoreApplication>
class InsertCommand : public HexCommand { class InsertCommand : public HexCommand {
Q_DECLARE_TR_FUNCTIONS(InsertCommand)
public: public:
InsertCommand(QHexDocument *doc, QHexCursor *cursor, qsizetype offset, explicit InsertCommand(QHexDocument *doc, QHexCursor *cursor,
const QByteArray &data, int nibbleindex, qsizetype offset, const QByteArray &data,
QUndoCommand *parent = nullptr); int nibbleindex, 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 // INSERTCOMMAND_H #endif // INSERTCOMMAND_H

View File

@ -24,7 +24,8 @@
RemoveCommand::RemoveCommand(QHexDocument *doc, qsizetype offset, RemoveCommand::RemoveCommand(QHexDocument *doc, qsizetype offset,
qsizetype length, QHexCursor *cursor, qsizetype length, QHexCursor *cursor,
int nibbleindex, QUndoCommand *parent) int nibbleindex, QUndoCommand *parent)
: HexCommand(doc, cursor, nibbleindex, parent) { : HexCommand(tr("[HexRemove] pos: %1").arg(offset), doc, cursor,
nibbleindex, parent) {
m_offset = offset; m_offset = offset;
m_length = length; m_length = length;
m_data = doc->read(m_offset, m_length); m_data = doc->read(m_offset, m_length);
@ -43,7 +44,6 @@ void RemoveCommand::undo() {
m_cursor->setPos(m_offset, 0); m_cursor->setPos(m_offset, 0);
} }
} }
HexCommand::undo();
} }
void RemoveCommand::redo() { void RemoveCommand::redo() {
@ -51,5 +51,28 @@ void RemoveCommand::redo() {
m_doc->_remove(m_offset, m_length); m_doc->_remove(m_offset, m_length);
_rmbms = m_doc->removeBookMarkAdjust(m_offset, m_length); _rmbms = m_doc->removeBookMarkAdjust(m_offset, m_length);
_rmMetas = m_doc->metadata()->removeAdjust(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 "hexcommand.h"
#include <QCoreApplication>
class RemoveCommand : public HexCommand { class RemoveCommand : public HexCommand {
Q_DECLARE_TR_FUNCTIONS(RemoveCommand)
public: public:
RemoveCommand(QHexDocument *doc, qsizetype offset, qsizetype length, explicit RemoveCommand(QHexDocument *doc, qsizetype offset,
QHexCursor *cursor, int nibbleindex, qsizetype length, QHexCursor *cursor,
QUndoCommand *parent = nullptr); int nibbleindex, QUndoCommand *parent = nullptr);
void undo() override; // QUndoCommand interface
void redo() override; public:
virtual void undo() override;
virtual void redo() override;
virtual int id() const override;
virtual bool mergeWith(const QUndoCommand *other) override;
private: private:
QVector<QHexMetadataItem> _rmMetas; QVector<QHexMetadataItem> _rmMetas;

View File

@ -25,7 +25,8 @@
ReplaceCommand::ReplaceCommand(QHexDocument *doc, qsizetype offset, ReplaceCommand::ReplaceCommand(QHexDocument *doc, qsizetype offset,
const QByteArray &data, QHexCursor *cursor, const QByteArray &data, QHexCursor *cursor,
int nibbleindex, QUndoCommand *parent) int nibbleindex, QUndoCommand *parent)
: HexCommand(doc, cursor, nibbleindex, parent) { : HexCommand(tr("[HexReplace] pos: %1").arg(offset), doc, cursor,
nibbleindex, parent) {
m_offset = offset; m_offset = offset;
m_data = data; m_data = data;
m_length = data.length(); m_length = data.length();
@ -35,7 +36,6 @@ ReplaceCommand::ReplaceCommand(QHexDocument *doc, qsizetype offset,
void ReplaceCommand::undo() { void ReplaceCommand::undo() {
m_doc->_replace(m_offset, m_olddata); m_doc->_replace(m_offset, m_olddata);
m_cursor->setPos(m_offset, m_nibbleindex); m_cursor->setPos(m_offset, m_nibbleindex);
HexCommand::undo();
} }
void ReplaceCommand::redo() { void ReplaceCommand::redo() {
@ -45,5 +45,48 @@ void ReplaceCommand::redo() {
} else { } else {
m_cursor->setPos(m_offset + m_length, !m_nibbleindex); 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 "hexcommand.h"
#include <QCoreApplication>
class ReplaceCommand : public HexCommand { class ReplaceCommand : public HexCommand {
Q_DECLARE_TR_FUNCTIONS(ReplaceCommand)
friend class InsertCommand;
public: public:
ReplaceCommand(QHexDocument *doc, qsizetype offset, const QByteArray &data, explicit ReplaceCommand(QHexDocument *doc, qsizetype offset,
QHexCursor *cursor, int nibbleindex, const QByteArray &data, QHexCursor *cursor,
QUndoCommand *parent = nullptr); int nibbleindex, QUndoCommand *parent = nullptr);
void undo() override; // QUndoCommand interface
void redo() override; public:
virtual void undo() override;
virtual void redo() override;
virtual int id() const override;
virtual bool mergeWith(const QUndoCommand *other) override;
private: private:
QByteArray m_olddata; QByteArray m_olddata;

View File

@ -24,7 +24,7 @@
MetaAddCommand::MetaAddCommand(QHexMetadata *hexmeta, MetaAddCommand::MetaAddCommand(QHexMetadata *hexmeta,
const QHexMetadataItem &meta, const QHexMetadataItem &meta,
QUndoCommand *parent) QUndoCommand *parent)
: MetaCommand(hexmeta, meta, parent) { : MetaCommand(tr("[MetaAdd]"), hexmeta, meta, parent) {
_brokenMetas = m_hexmeta->mayBrokenMetaData(meta.begin, meta.end); _brokenMetas = m_hexmeta->mayBrokenMetaData(meta.begin, meta.end);
} }
@ -33,6 +33,20 @@ void MetaAddCommand::redo() {
m_meta.background, m_meta.comment); 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() { void MetaAddCommand::undo() {
m_hexmeta->removeMetadata(m_meta.begin, m_meta.end); m_hexmeta->removeMetadata(m_meta.begin, m_meta.end);
for (auto &meta : _brokenMetas) { for (auto &meta : _brokenMetas) {

View File

@ -23,14 +23,22 @@
#define METAADDCOMMAND_H #define METAADDCOMMAND_H
#include "metacommand.h" #include "metacommand.h"
#include <QCoreApplication>
#include <QObject> #include <QObject>
class MetaAddCommand : public MetaCommand { class MetaAddCommand : public MetaCommand {
Q_DECLARE_TR_FUNCTIONS(MetaAddCommand)
public: public:
MetaAddCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta, explicit MetaAddCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta,
QUndoCommand *parent = nullptr); 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: private:
QVector<QHexMetadataItem> _brokenMetas; QVector<QHexMetadataItem> _brokenMetas;

View File

@ -24,8 +24,16 @@
MetaClearCommand::MetaClearCommand(QHexMetadata *hexmeta, MetaClearCommand::MetaClearCommand(QHexMetadata *hexmeta,
const QVector<QHexMetadataItem> &metas, const QVector<QHexMetadataItem> &metas,
QUndoCommand *parent) 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(); } 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); } void MetaClearCommand::undo() { m_hexmeta->applyMetas(m_metas); }

View File

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

View File

@ -21,6 +21,6 @@
#include "metacommand.h" #include "metacommand.h"
MetaCommand::MetaCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta, MetaCommand::MetaCommand(const QString &text, QHexMetadata *hexmeta,
QUndoCommand *parent) const QHexMetadataItem &meta, QUndoCommand *parent)
: QUndoCommand(parent), m_hexmeta(hexmeta), m_meta(meta) {} : UndoCommandBase(text, parent), m_hexmeta(hexmeta), m_meta(meta) {}

View File

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

View File

@ -24,10 +24,20 @@
MetaRemoveCommand::MetaRemoveCommand(QHexMetadata *hexmeta, MetaRemoveCommand::MetaRemoveCommand(QHexMetadata *hexmeta,
const QHexMetadataItem &meta, const QHexMetadataItem &meta,
QUndoCommand *parent) QUndoCommand *parent)
: MetaCommand(hexmeta, meta, parent) {} : MetaCommand(tr("[MetaRemove]"), hexmeta, meta, parent) {}
void MetaRemoveCommand::redo() { m_hexmeta->removeMetadata(m_meta); } 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() { void MetaRemoveCommand::undo() {
m_hexmeta->metadata(m_meta.begin, m_meta.end, m_meta.foreground, m_hexmeta->metadata(m_meta.begin, m_meta.end, m_meta.foreground,
m_meta.background, m_meta.comment); m_meta.background, m_meta.comment);

View File

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

View File

@ -23,16 +23,28 @@
MetaRemovePosCommand::MetaRemovePosCommand(QHexMetadata *hexmeta, qsizetype pos, MetaRemovePosCommand::MetaRemovePosCommand(QHexMetadata *hexmeta, qsizetype pos,
QUndoCommand *parent) QUndoCommand *parent)
: QUndoCommand(parent), m_hexmeta(hexmeta), m_pos(pos) { : MetaCommand(tr("[MetaRemovePos]"), hexmeta, {}, parent), m_pos(pos) {
auto po = m_hexmeta->get(pos); auto po = m_hexmeta->get(pos);
if (po.has_value()) { if (po.has_value()) {
oldmeta = po.value(); m_meta = po.value();
} }
} }
void MetaRemovePosCommand::redo() { m_hexmeta->removeMetadata(m_pos); } void MetaRemovePosCommand::redo() { m_hexmeta->removeMetadata(m_pos); }
void MetaRemovePosCommand::undo() { int MetaRemovePosCommand::id() const { return UndoID_MetaRemovePos; }
m_hexmeta->metadata(oldmeta.begin, oldmeta.end, oldmeta.foreground,
oldmeta.background, oldmeta.comment); 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 #ifndef METAREMOVEPOSCOMMAND_H
#define METAREMOVEPOSCOMMAND_H #define METAREMOVEPOSCOMMAND_H
#include "../../qhexmetadata.h" #include "metacommand.h"
#include <QList>
#include <QObject>
#include <QUndoCommand>
#include <QUndoStack>
class MetaRemovePosCommand : public QUndoCommand { #include <QCoreApplication>
class MetaRemovePosCommand : public MetaCommand {
Q_DECLARE_TR_FUNCTIONS(MetaRemovePosCommand)
public: public:
MetaRemovePosCommand(QHexMetadata *hexmeta, qsizetype pos, explicit MetaRemovePosCommand(QHexMetadata *hexmeta, qsizetype pos,
QUndoCommand *parent = nullptr); QUndoCommand *parent = nullptr);
void undo() override; // QUndoCommand interface
void redo() override; public:
virtual void undo() override;
virtual void redo() override;
virtual int id() const override;
virtual bool mergeWith(const QUndoCommand *other) override;
protected: protected:
QHexMetadata *m_hexmeta;
qsizetype m_pos; qsizetype m_pos;
QHexMetadataItem oldmeta;
}; };
#endif // METAREMOVEPOSCOMMAND_H #endif // METAREMOVEPOSCOMMAND_H

View File

@ -25,8 +25,21 @@ MetaReplaceCommand::MetaReplaceCommand(QHexMetadata *hexmeta,
const QHexMetadataItem &meta, const QHexMetadataItem &meta,
const QHexMetadataItem &oldmeta, const QHexMetadataItem &oldmeta,
QUndoCommand *parent) 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::undo() { m_hexmeta->modifyMetadata(m_old, m_meta); }
void MetaReplaceCommand::redo() { m_hexmeta->modifyMetadata(m_meta, m_old); } 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 #define METAREPLACECOMMAND_H
#include "metacommand.h" #include "metacommand.h"
#include <QCoreApplication>
#include <QObject> #include <QObject>
class MetaReplaceCommand : public MetaCommand { class MetaReplaceCommand : public MetaCommand {
Q_DECLARE_TR_FUNCTIONS(MetaReplaceCommand)
public: public:
MetaReplaceCommand(QHexMetadata *hexmeta, const QHexMetadataItem &meta, explicit MetaReplaceCommand(QHexMetadata *hexmeta,
const QHexMetadataItem &oldmeta, const QHexMetadataItem &meta,
QUndoCommand *parent = nullptr); const QHexMetadataItem &oldmeta,
void undo() override; QUndoCommand *parent = nullptr);
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: private:
QHexMetadataItem m_old; QHexMetadataItem m_old;

View File

@ -19,12 +19,7 @@
** ============================================================================= ** =============================================================================
*/ */
#include "baseaddrcommand.h" #include "undocommandbase.h"
BaseAddrCommand::BaseAddrCommand(QHexDocument *doc, quint64 oldaddr, UndoCommandBase::UndoCommandBase(const QString &text, QUndoCommand *parent)
quint64 newaddr, QUndoCommand *parent) : QUndoCommand(text, 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); }

View File

@ -19,23 +19,31 @@
** ============================================================================= ** =============================================================================
*/ */
#ifndef BASEADDRCOMMAND_H #ifndef UNDOCOMMANDBASE_H
#define BASEADDRCOMMAND_H #define UNDOCOMMANDBASE_H
#include "document/qhexdocument.h"
#include <QUndoCommand> #include <QUndoCommand>
class BaseAddrCommand : public QUndoCommand { class UndoCommandBase : public QUndoCommand {
public: public:
BaseAddrCommand(QHexDocument *doc, quint64 oldaddr, quint64 newaddr, enum UndoCommandID {
QUndoCommand *parent = nullptr); 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; public:
void undo() override; explicit UndoCommandBase(const QString &text,
QUndoCommand *parent = nullptr);
private:
QHexDocument *m_doc;
quint64 m_old, m_new;
}; };
#endif // BASEADDRCOMMAND_H #endif // UNDOCOMMANDBASE_H

View File

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

View File

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

View File

@ -32,37 +32,7 @@
#include <QUndoStack> #include <QUndoStack>
#include <QVector> #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; using qhash_result_t = size_t;
#endif
struct QHexMetadataItem : QHexRegionObject<qsizetype, QHexMetadataItem> { struct QHexMetadataItem : QHexRegionObject<qsizetype, QHexMetadataItem> {
QColor foreground, background; QColor foreground, background;
@ -96,24 +66,7 @@ public:
if (sel.foreground == this->foreground && if (sel.foreground == this->foreground &&
sel.background == this->background && sel.background == this->background &&
sel.comment == this->comment) { sel.comment == this->comment) {
if (canMerge(sel)) { if (mergeRegionWithoutMetaCheck(sel, locker)) {
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();
}
return std::nullopt; return std::nullopt;
} }
return false; 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, 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(); } quintptr QHexView::addressBase() { return m_document->baseAddress(); }
void QHexView::setAddressBase(quintptr base) { void QHexView::setAddressBase(quintptr base) {
m_document->SetBaseAddress(base); m_document->setBaseAddress(base);
} }
bool QHexView::isSaved() { return m_document->isDocSaved(); } bool QHexView::isSaved() { return m_document->isDocSaved(); }
@ -109,7 +109,7 @@ bool QHexView::isSaved() { return m_document->isDocSaved(); }
QFont QHexView::getHexeditorFont() { QFont QHexView::getHexeditorFont() {
QFont f = QFontDatabase::systemFont(QFontDatabase::FixedFont); QFont f = QFontDatabase::systemFont(QFontDatabase::FixedFont);
if (f.styleHint() != QFont::TypeWriter) { if (f.styleHint() != QFont::TypeWriter) {
f.setFamily("Monospace"); // Force Monospaced font f.setFamily(QStringLiteral("Monospace")); // Force Monospaced font
f.setStyleHint(QFont::TypeWriter); f.setStyleHint(QFont::TypeWriter);
} }
return f; return f;

View File

@ -28,6 +28,7 @@ add_definitions(-DAS_NO_THREADS)
if(BUILD_TEST_PLUGIN) if(BUILD_TEST_PLUGIN)
add_subdirectory(TestPlugin) add_subdirectory(TestPlugin)
add_subdirectory(TestManager)
endif() endif()
if(BUILD_SHARED_MEM_EXT) if(BUILD_SHARED_MEM_EXT)
@ -297,7 +298,11 @@ set(CLASS_SRC
src/class/asconsolecompletion.h src/class/asconsolecompletion.h
src/class/asconsolecompletion.cpp src/class/asconsolecompletion.cpp
src/class/scriptsettings.h src/class/scriptsettings.h
src/class/scriptsettings.cpp) src/class/scriptsettings.cpp
src/class/wingangel.h
src/class/wingangel.cpp
src/class/winggeneric.h
src/class/winggeneric.cpp)
set(INTERNAL_PLG_SRC set(INTERNAL_PLG_SRC
src/class/wingangelapi.h src/class/wingangelapi.cpp src/class/wingangelapi.h src/class/wingangelapi.cpp

View File

@ -1,5 +1,6 @@
{ {
"Id" : "shmem", "Id" : "shmem",
"SDK": 18,
"Version" : "0.0.1", "Version" : "0.0.1",
"Vendor" : "WingCloudStudio", "Vendor" : "WingCloudStudio",
"Author" : "wingsummer", "Author" : "wingsummer",

View File

@ -4,27 +4,27 @@
<context> <context>
<name>SharedMemoryDriver</name> <name>SharedMemoryDriver</name>
<message> <message>
<location filename="../sharememorydrv.cpp" line="38"/> <location filename="../sharememorydrv.cpp" line="36"/>
<source>SharedMemoryDriver</source> <source>SharedMemoryDriver</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../sharememorydrv.cpp" line="42"/> <location filename="../sharememorydrv.cpp" line="40"/>
<source>An extension for opening sshared memory in WingHexExplorer2.</source> <source>An extension for opening sshared memory in WingHexExplorer2.</source>
<translation>2</translation> <translation>2</translation>
</message> </message>
<message> <message>
<location filename="../sharememorydrv.cpp" line="62"/> <location filename="../sharememorydrv.cpp" line="56"/>
<source>ShareMemory</source> <source>ShareMemory</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../sharememorydrv.cpp" line="71"/> <location filename="../sharememorydrv.cpp" line="65"/>
<source>SharedMemory</source> <source>SharedMemory</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../sharememorydrv.cpp" line="71"/> <location filename="../sharememorydrv.cpp" line="65"/>
<source>PleaseInputID:</source> <source>PleaseInputID:</source>
<translation></translation> <translation></translation>
</message> </message>

View File

@ -23,8 +23,6 @@ SharedMemoryDriver::SharedMemoryDriver() : WingHex::IWingDevice() {}
SharedMemoryDriver::~SharedMemoryDriver() {} SharedMemoryDriver::~SharedMemoryDriver() {}
int SharedMemoryDriver::sdkVersion() const { return WingHex::SDKVERSION; }
bool SharedMemoryDriver::init(const std::unique_ptr<QSettings> &set) { bool SharedMemoryDriver::init(const std::unique_ptr<QSettings> &set) {
Q_UNUSED(set); Q_UNUSED(set);
return true; return true;
@ -42,10 +40,6 @@ const QString SharedMemoryDriver::pluginComment() const {
return tr("An extension for opening sshared memory in WingHexExplorer2."); return tr("An extension for opening sshared memory in WingHexExplorer2.");
} }
QList<WingHex::PluginPage *> SharedMemoryDriver::registeredPages() const {
return _plgps;
}
WingHex::WingIODevice *SharedMemoryDriver::onOpenFile(const QString &path) { WingHex::WingIODevice *SharedMemoryDriver::onOpenFile(const QString &path) {
return new SharedMemory(path, SharedMemory::ReadWrite, this); return new SharedMemory(path, SharedMemory::ReadWrite, this);
} }

View File

@ -34,15 +34,11 @@ public:
// IWingPlugin interface // IWingPlugin interface
public: public:
virtual int sdkVersion() const override;
virtual bool init(const std::unique_ptr<QSettings> &set) override; virtual bool init(const std::unique_ptr<QSettings> &set) override;
virtual void unload(std::unique_ptr<QSettings> &set) override; virtual void unload(std::unique_ptr<QSettings> &set) override;
virtual const QString pluginName() const override; virtual const QString pluginName() const override;
virtual const QString pluginComment() const override; virtual const QString pluginComment() const override;
public:
virtual QList<WingHex::PluginPage *> registeredPages() const override;
// IWingDevice interface // IWingDevice interface
public: public:
virtual QString onOpenFileBegin() override; virtual QString onOpenFileBegin() override;
@ -50,9 +46,6 @@ public:
virtual QIcon supportedFileIcon() const override; virtual QIcon supportedFileIcon() const override;
virtual WingHex::WingIODevice *onOpenFile(const QString &path) override; virtual WingHex::WingIODevice *onOpenFile(const QString &path) override;
virtual bool onCloseFile(WingHex::WingIODevice *dev) override; virtual bool onCloseFile(WingHex::WingIODevice *dev) override;
private:
QList<WingHex::PluginPage *> _plgps;
}; };
#endif // SHAREDMEMORYDRIVER_H #endif // SHAREDMEMORYDRIVER_H

View File

@ -0,0 +1,50 @@
cmake_minimum_required(VERSION 3.16)
project(TestManager)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
# Test mode, please configure the main program directory to facilitate debugging
# 便
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
option(TEST_MODE TRUE)
# For Qt
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(
Qt${QT_VERSION_MAJOR}
COMPONENTS Widgets
REQUIRED)
add_library(TestManager SHARED testmanager.h testmanager.cpp TestManager.json)
set_target_properties(TestManager PROPERTIES SUFFIX ".wingman")
if(TEST_MODE)
# If you want to be able to debug easily every time you compile, please set
# this variable. Because this test plugin is a subproject of the main
# project, use CMAKE_BINARY_DIR
# 便 CMAKE_BINARY_DIR
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
set(WINGHEX_PATH "${CMAKE_BINARY_DIR}")
add_custom_command(
TARGET TestManager
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:TestManager> ${WINGHEX_PATH})
endif()
target_link_libraries(TestManager PRIVATE Qt${QT_VERSION_MAJOR}::Widgets
WingPlugin)

View File

@ -0,0 +1,9 @@
{
"Id": "TestManager",
"SDK": 18,
"Version": "0.0.1",
"Vendor": "WingCloudStudio",
"Author": "wingsummer",
"License": "AGPL-3.0",
"Url": "https://github.com/Wing-summer/WingHexExplorer2"
}

View File

@ -18,21 +18,40 @@
** ============================================================================= ** =============================================================================
*/ */
#include "testpluginpage.h" #include "testmanager.h"
#include <QVBoxLayout> TestManager::TestManager() : WingHex::IWingManager() { content = new TestPage; }
TestPluginPage::TestPluginPage(QWidget *parent) : WingHex::PluginPage(parent) { TestManager::~TestManager() {
auto layout = new QVBoxLayout(this); // no need to manual delete content
_lbl = new QLabel(QStringLiteral("TestPluginPage"), this); // the host will take the ownership
_lbl->setAlignment(Qt::AlignCenter);
layout->addWidget(_lbl);
} }
QIcon TestPluginPage::categoryIcon() const { bool TestManager::init(const std::unique_ptr<QSettings> &set) {
return QIcon(QStringLiteral(":/images/TestPlugin/images/btn.png")); Q_UNUSED(set);
return true;
} }
QString TestPluginPage::name() const { return tr("TestPluginPage"); } void TestManager::unload(std::unique_ptr<QSettings> &set) { Q_UNUSED(set); }
QString TestPluginPage::id() const { return QStringLiteral("TestPluginPage"); } const QString TestManager::comment() const {
return QStringLiteral("Hello world!");
}
QList<WingHex::SettingPage *> TestManager::registeredSettingPages() const {
return {content};
}
bool TestManager::enterGuard(const QMetaObject *sender, const QString &sig,
const QVariantList &params) {
if (content->isDisableMsg()) {
if (sig.startsWith("msg")) {
// block all msg-prefix function
logWarn(QStringLiteral("Blocking: (%1) {%2}")
.arg(sender->className(), sig));
return false;
}
}
return true;
}

98
TestManager/testmanager.h Normal file
View File

@ -0,0 +1,98 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is
** furnished to do so.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
** THE SOFTWARE.
** =============================================================================
*/
#ifndef TESTMANAGER_H
#define TESTMANAGER_H
#include "WingPlugin/iwingmanager.h"
#include <QCheckBox>
#include <QVBoxLayout>
class TestManager : public WingHex::IWingManager {
Q_OBJECT
// 这两行是必须,只有后面的 "TestManager.json" 你根据需要修改,
// 具体可见 QT 文档,剩下直接 CV 大法
Q_PLUGIN_METADATA(IID "com.wingsummer.iwingmanager" FILE "TestManager.json")
Q_INTERFACES(WingHex::IWingManager)
public:
explicit TestManager();
virtual ~TestManager();
// IWingPluginCoreBase interface
public:
virtual bool init(const std::unique_ptr<QSettings> &set) override;
virtual void unload(std::unique_ptr<QSettings> &set) override;
public:
virtual const QString comment() const override;
virtual QList<WingHex::SettingPage *>
registeredSettingPages() const override;
private:
class TestPage : public WingHex::SettingPage {
public:
TestPage() {
auto layout = new QVBoxLayout(this);
_cbblk = new QCheckBox(QStringLiteral("Disable msg*"), this);
_cbblk->setChecked(false);
layout->addWidget(_cbblk);
layout->addStretch();
}
// PageBase interface
public:
virtual QIcon categoryIcon() const override {
return QIcon(WingHex::HOSTRESPIMG("monitor"));
}
virtual QString name() const override {
return QStringLiteral("TestManager");
}
virtual QString id() const override {
return QStringLiteral("TestManager");
}
// SettingInterface interface
public:
virtual void apply() override { _isDisabled = _cbblk->isChecked(); }
virtual void reset() override {
_isDisabled = false;
_cbblk->setChecked(false);
}
virtual void cancel() override { _cbblk->setChecked(_isDisabled); }
public:
bool isDisableMsg() const { return _isDisabled; }
private:
QCheckBox *_cbblk;
bool _isDisabled = false;
};
public slots:
virtual bool enterGuard(const QMetaObject *sender, const QString &sig,
const QVariantList &params) override;
private:
TestPage *content;
};
#endif // TESTMANAGER_H

View File

@ -64,9 +64,7 @@ add_library(
testsettingpage.h testsettingpage.h
testsettingpage.cpp testsettingpage.cpp
testwingeditorviewwidget.h testwingeditorviewwidget.h
testwingeditorviewwidget.cpp testwingeditorviewwidget.cpp)
testpluginpage.h
testpluginpage.cpp)
set_target_properties(TestPlugin PROPERTIES SUFFIX ".wingplg") set_target_properties(TestPlugin PROPERTIES SUFFIX ".wingplg")

View File

@ -1,5 +1,6 @@
{ {
"Id": "TestPlugin", "Id": "TestPlugin",
"SDK": 18,
"Version": "0.0.1", "Version": "0.0.1",
"Vendor": "WingCloudStudio", "Vendor": "WingCloudStudio",
"Dependencies": [ "Dependencies": [

View File

@ -269,72 +269,64 @@
<context> <context>
<name>TestPlugin</name> <name>TestPlugin</name>
<message> <message>
<location filename="../testplugin.cpp" line="207"/> <location filename="../testplugin.cpp" line="69"/>
<source>Test</source> <source>Test</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../testplugin.cpp" line="219"/> <location filename="../testplugin.cpp" line="81"/>
<location filename="../testplugin.cpp" line="228"/> <location filename="../testplugin.cpp" line="90"/>
<location filename="../testplugin.cpp" line="233"/> <location filename="../testplugin.cpp" line="95"/>
<location filename="../testplugin.cpp" line="314"/> <location filename="../testplugin.cpp" line="164"/>
<source>TestPlugin</source> <source>TestPlugin</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../testplugin.cpp" line="237"/> <location filename="../testplugin.cpp" line="99"/>
<source>Button - </source> <source>Button - </source>
<translation> - </translation> <translation> - </translation>
</message> </message>
<message> <message>
<location filename="../testplugin.cpp" line="241"/> <location filename="../testplugin.cpp" line="103"/>
<source>Click</source> <source>Click</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../testplugin.cpp" line="317"/> <location filename="../testplugin.cpp" line="167"/>
<source>A Test Plugin for WingHexExplorer2.</source> <source>A Test Plugin for WingHexExplorer2.</source>
<translation>2</translation> <translation>2</translation>
</message> </message>
<message> <message>
<location filename="../testplugin.cpp" line="355"/> <location filename="../testplugin.cpp" line="196"/>
<location filename="../testplugin.cpp" line="363"/> <location filename="../testplugin.cpp" line="204"/>
<location filename="../testplugin.cpp" line="372"/> <location filename="../testplugin.cpp" line="213"/>
<location filename="../testplugin.cpp" line="393"/> <location filename="../testplugin.cpp" line="234"/>
<location filename="../testplugin.cpp" line="409"/> <location filename="../testplugin.cpp" line="250"/>
<location filename="../testplugin.cpp" line="416"/> <location filename="../testplugin.cpp" line="257"/>
<location filename="../testplugin.cpp" line="423"/> <location filename="../testplugin.cpp" line="264"/>
<location filename="../testplugin.cpp" line="430"/> <location filename="../testplugin.cpp" line="271"/>
<location filename="../testplugin.cpp" line="438"/> <location filename="../testplugin.cpp" line="278"/>
<location filename="../testplugin.cpp" line="469"/> <location filename="../testplugin.cpp" line="307"/>
<location filename="../testplugin.cpp" line="477"/> <location filename="../testplugin.cpp" line="315"/>
<location filename="../testplugin.cpp" line="485"/> <location filename="../testplugin.cpp" line="323"/>
<location filename="../testplugin.cpp" line="493"/> <location filename="../testplugin.cpp" line="331"/>
<location filename="../testplugin.cpp" line="502"/> <location filename="../testplugin.cpp" line="340"/>
<location filename="../testplugin.cpp" line="509"/> <location filename="../testplugin.cpp" line="347"/>
<source>InvalidParamsCount</source> <source>InvalidParamsCount</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../testplugin.cpp" line="386"/> <location filename="../testplugin.cpp" line="227"/>
<location filename="../testplugin.cpp" line="402"/> <location filename="../testplugin.cpp" line="243"/>
<source>InvalidParam</source> <source>InvalidParam</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../testplugin.cpp" line="460"/> <location filename="../testplugin.cpp" line="298"/>
<source>AllocArrayFailed</source> <source>AllocArrayFailed</source>
<translation></translation> <translation></translation>
</message> </message>
</context> </context>
<context>
<name>TestPluginPage</name>
<message>
<location filename="../testpluginpage.cpp" line="36"/>
<source>TestPluginPage</source>
<translation></translation>
</message>
</context>
<context> <context>
<name>TestWingEditorViewWidget</name> <name>TestWingEditorViewWidget</name>
<message> <message>

View File

@ -19,14 +19,16 @@
*/ */
#include "testplugin.h" #include "testplugin.h"
#include "WingPlugin/iwingangel.h"
#include "testform.h" #include "testform.h"
#include "testpluginpage.h"
#include "testsettingpage.h" #include "testsettingpage.h"
#include "testwingeditorviewwidget.h" #include "testwingeditorviewwidget.h"
#include <QApplication> #include <QApplication>
#include <QMenu> #include <QMenu>
WING_DECLARE_STATIC_API;
// 注意:所有提供的脚本接口函数都不是线程安全的,只是测试 // 注意:所有提供的脚本接口函数都不是线程安全的,只是测试
TestPlugin::TestPlugin() : WingHex::IWingPlugin() { TestPlugin::TestPlugin() : WingHex::IWingPlugin() {
@ -37,151 +39,11 @@ TestPlugin::TestPlugin() : WingHex::IWingPlugin() {
// 初始化会传递一个配置类,插件系统会统一管理放到统一的地方,使用 INI 保存 // 初始化会传递一个配置类,插件系统会统一管理放到统一的地方,使用 INI 保存
// 你可以自行管理,但不建议,统一管理方便使用者备份和转移插件配置 // 你可以自行管理,但不建议,统一管理方便使用者备份和转移插件配置
{ WING_INIT_STATIC_API;
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn =
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_a),
this, std::placeholders::_1);
info.ret = MetaType::Void;
_scriptInfo.insert(QStringLiteral("test_a"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn =
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_b),
this, std::placeholders::_1);
info.ret = MetaType::Void;
info.params.append(qMakePair(MetaType::String, QStringLiteral("info")));
_scriptInfo.insert(QStringLiteral("test_b"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn =
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_c),
this, std::placeholders::_1);
info.ret = MetaType::Void;
info.params.append(
qMakePair(MetaType::Int | MetaType::Array, QStringLiteral("c")));
_scriptInfo.insert(QStringLiteral("test_c"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn =
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_d),
this, std::placeholders::_1);
info.ret = MetaType::Void;
info.params.append(qMakePair(MetaType::Hash, QStringLiteral("d")));
_scriptInfo.insert(QStringLiteral("test_d"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn =
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_e),
this, std::placeholders::_1);
info.ret = MetaType::Bool;
_scriptInfo.insert(QStringLiteral("test_e"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn =
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_f),
this, std::placeholders::_1);
info.ret = MetaType::Byte | MetaType::Array;
_scriptInfo.insert(QStringLiteral("test_f"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn =
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_g),
this, std::placeholders::_1);
info.ret = MetaType::String;
_scriptInfo.insert(QStringLiteral("test_g"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn =
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_h),
this, std::placeholders::_1);
info.ret = MetaType::Hash;
_scriptInfo.insert(QStringLiteral("test_h"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(QOverload<const QVariantList &>::of(
&TestPlugin::createTestShareMem),
this, std::placeholders::_1);
info.ret = MetaType::Bool;
info.params.append(
qMakePair(MetaType::String, QStringLiteral("nameID")));
_scriptInfo.insert(QStringLiteral("createTestShareMem"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(QOverload<const QVariantList &>::of(
&TestPlugin::destoryTestShareMem),
this, std::placeholders::_1);
info.ret = MetaType::Void;
_scriptInfo.insert(QStringLiteral("destoryTestShareMem"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(QOverload<const QVariantList &>::of(
&TestPlugin::printLogTestSharedMemData),
this, std::placeholders::_1);
info.ret = MetaType::Void;
_scriptInfo.insert(QStringLiteral("printLogTestSharedMemData"), info);
}
{
_scriptUnsafe.insert(QStringLiteral("array<color>@ colorTable()"),
std::bind(QOverload<const QList<void *> &>::of(
&TestPlugin::colorTable),
this, std::placeholders::_1));
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(QOverload<const QVariantList &>::of(
&TestPlugin::setPluginMetaTestEnabled),
this, std::placeholders::_1);
info.ret = MetaType::Void;
info.params.append(qMakePair(MetaType::Bool, QStringLiteral("b")));
_scriptInfo.insert(QStringLiteral("setPluginMetaTestEnabled"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(QOverload<const QVariantList &>::of(
&TestPlugin::pluginMetaTestEnabled),
this, std::placeholders::_1);
info.ret = MetaType::Bool;
_scriptInfo.insert(QStringLiteral("pluginMetaTestEnabled"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(
QOverload<const QVariantList &>::of(&TestPlugin::testCrash), this,
std::placeholders::_1);
info.ret = MetaType::Void;
_scriptInfo.insert(QStringLiteral("testCrash"), info);
}
} }
TestPlugin::~TestPlugin() { destoryTestShareMem(); } TestPlugin::~TestPlugin() { destoryTestShareMem(); }
int TestPlugin::sdkVersion() const { return WingHex::SDKVERSION; }
bool TestPlugin::init(const std::unique_ptr<QSettings> &set) { bool TestPlugin::init(const std::unique_ptr<QSettings> &set) {
auto v = set->value("Test", 0).toInt(); auto v = set->value("Test", 0).toInt();
// 如果你之前启动过且正常推出,这个值一定是 5 // 如果你之前启动过且正常推出,这个值一定是 5
@ -247,17 +109,11 @@ bool TestPlugin::init(const std::unique_ptr<QSettings> &set) {
_rtbinfo.append(rtinfo); _rtbinfo.append(rtinfo);
} }
{ _setpages.append(new TestSettingPage(
auto sp = new TestSettingPage(QStringLiteral("Test1"), QStringLiteral("Test1"), QStringLiteral("This is a Test1"), true));
QStringLiteral("This is a Test1"));
_setpages.insert(sp, true);
}
{ _setpages.append(new TestSettingPage(
auto sp = new TestSettingPage(QStringLiteral("Test2"), QStringLiteral("Test2"), QStringLiteral("This is a Test2"), false));
QStringLiteral("This is a Test2"));
_setpages.insert(sp, false);
}
{ {
WingHex::WingDockWidgetInfo info; WingHex::WingDockWidgetInfo info;
@ -274,11 +130,6 @@ bool TestPlugin::init(const std::unique_ptr<QSettings> &set) {
_evws.append(ev); _evws.append(ev);
} }
{
auto pp = new TestPluginPage;
_plgps.append(pp);
}
_tmenu = new QMenu(QStringLiteral("TestPlugin")); _tmenu = new QMenu(QStringLiteral("TestPlugin"));
auto micon = QIcon(QStringLiteral(":/images/TestPlugin/images/btn.png")); auto micon = QIcon(QStringLiteral(":/images/TestPlugin/images/btn.png"));
_tmenu->setIcon(micon); _tmenu->setIcon(micon);
@ -298,9 +149,8 @@ void TestPlugin::unload(std::unique_ptr<QSettings> &set) {
// 设个数字,那就是 5 测试一下配置是否正常工作 // 设个数字,那就是 5 测试一下配置是否正常工作
set->setValue("Test", 5); set->setValue("Test", 5);
for (auto p = _setpages.constKeyValueBegin(); for (auto &p : _setpages) {
p != _setpages.constKeyValueEnd(); ++p) { p->deleteLater();
p->first->deleteLater();
} }
for (auto &item : _winfo) { for (auto &item : _winfo) {
@ -332,24 +182,15 @@ TestPlugin::registeredRibbonTools() const {
return _rtbinfo; return _rtbinfo;
} }
QHash<WingHex::SettingPage *, bool> TestPlugin::registeredSettingPages() const { QList<WingHex::SettingPage *> TestPlugin::registeredSettingPages() const {
return _setpages; return _setpages;
} }
QList<WingHex::PluginPage *> TestPlugin::registeredPages() const {
return _plgps;
}
QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>> QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>>
TestPlugin::registeredEditorViewWidgets() const { TestPlugin::registeredEditorViewWidgets() const {
return _evws; return _evws;
} }
QHash<QString, WingHex::IWingPlugin::UNSAFE_SCFNPTR>
TestPlugin::registeredScriptUnsafeFns() const {
return _scriptUnsafe;
}
QVariant TestPlugin::test_a(const QVariantList &params) { QVariant TestPlugin::test_a(const QVariantList &params) {
if (!params.isEmpty()) { if (!params.isEmpty()) {
return getScriptCallError(-1, tr("InvalidParamsCount")); return getScriptCallError(-1, tr("InvalidParamsCount"));
@ -432,29 +273,26 @@ QVariant TestPlugin::test_h(const QVariantList &params) {
return test_h(); return test_h();
} }
WingHex::IWingPlugin::UNSAFE_RET WingHex::UNSAFE_RET TestPlugin::colorTable(const QList<void *> &params) {
TestPlugin::colorTable(const QList<void *> &params) {
if (!params.isEmpty()) { if (!params.isEmpty()) {
return generateScriptCallError(-1, tr("InvalidParamsCount")); return generateScriptCallError(-1, tr("InvalidParamsCount"));
} }
void *array; void *array = nullptr;
QVector<void *> colors; QVector<void *> colors;
for (auto &c : colorTable()) { for (auto &c : colorTable()) {
colors.append(new QColor(c)); colors.append(new QColor(c));
} }
// TODO auto invoked =
// auto invoked = invokeService(QStringLiteral("WingAngelAPI"), "vector2AsArray",
// invokeService(QStringLiteral("WingAngelAPI"), "vector2AsArray", qReturnArg(array), WingHex::MetaType::Meta_Color, colors);
// WINGAPI_RETURN_ARG(array), if (invoked) {
// WINGAPI_ARG(MetaType::Color), WINGAPI_ARG(colors)); if (array) {
// if (invoked) { qDeleteAll(colors);
// if (array) { return array;
// qDeleteAll(colors); }
// return array; }
// }
// }
qDeleteAll(colors); qDeleteAll(colors);
return generateScriptCallError(-2, tr("AllocArrayFailed")); return generateScriptCallError(-2, tr("AllocArrayFailed"));
@ -512,6 +350,19 @@ QVariant TestPlugin::testCrash(const QVariantList &params) {
return {}; return {};
} }
void TestPlugin::testGenericAdd(WingHex::asIWingGeneric *param) {
auto g = QScopedPointer<WingHex::IWingGeneric>(createParamContext(param));
auto arg0 = g->argDWord(0);
auto arg1 = g->argDWord(1);
g->setReturnDWord(arg0 + arg1);
}
void TestPlugin::testRaiseScriptException(WingHex::asIWingGeneric *) {
raiseContextException(__func__, true);
}
void TestPlugin::test_a() { logDebug(__FUNCTION__); } void TestPlugin::test_a() { logDebug(__FUNCTION__); }
void TestPlugin::test_b(const QString &b) { void TestPlugin::test_b(const QString &b) {
@ -629,15 +480,9 @@ void TestPlugin::testCrash() {
abort(); abort();
} }
QHash<QString, WingHex::IWingPlugin::ScriptFnInfo>
TestPlugin::registeredScriptFns() const {
return _scriptInfo;
}
WingHex::IWingPlugin::RegisteredEvents TestPlugin::registeredEvents() const { WingHex::IWingPlugin::RegisteredEvents TestPlugin::registeredEvents() const {
RegisteredEvents evs; RegisteredEvents evs;
evs.setFlag(RegisteredEvent::AppReady); evs.setFlag(RegisteredEvent::AppReady);
evs.setFlag(RegisteredEvent::ScriptUnSafeFnRegistering);
return evs; return evs;
} }
@ -647,3 +492,113 @@ void TestPlugin::eventReady() {
Qt::AutoConnection, qReturnArg(ret), Qt::AutoConnection, qReturnArg(ret),
QStringLiteral(R"(print("Hello, this is TestPlugin!");)")); QStringLiteral(R"(print("Hello, this is TestPlugin!");)"));
} }
void TestPlugin::onRegisterScriptObj(WingHex::IWingAngel *o) {
o->registerGlobalFunction(
WingHex::MetaType::Meta_Void,
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_a),
this, std::placeholders::_1),
QStringLiteral("test_a"));
o->registerGlobalFunction(
WingHex::MetaType::Meta_Void,
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_b),
this, std::placeholders::_1),
QStringLiteral("test_b"),
{qMakePair(WingHex::MetaType::Meta_String, QStringLiteral("info"))});
o->registerGlobalFunction(
WingHex::MetaType::Meta_Void,
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_c),
this, std::placeholders::_1),
QStringLiteral("test_c"),
{qMakePair(WingHex::MetaType::Meta_Int | WingHex::MetaType::Meta_Array,
QStringLiteral("c"))});
o->registerGlobalFunction(
WingHex::MetaType::Meta_Void,
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_d),
this, std::placeholders::_1),
QStringLiteral("test_d"),
{qMakePair(WingHex::MetaType::Meta_Hash, QStringLiteral("d"))});
o->registerGlobalFunction(
WingHex::MetaType::Meta_Bool,
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_e),
this, std::placeholders::_1),
QStringLiteral("test_e"));
o->registerGlobalFunction(
WingHex::MetaType::Meta_Byte | WingHex::MetaType::Meta_Array,
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_f),
this, std::placeholders::_1),
QStringLiteral("test_f"));
o->registerGlobalFunction(
WingHex::MetaType::Meta_String,
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_g),
this, std::placeholders::_1),
QStringLiteral("test_g"));
o->registerGlobalFunction(
WingHex::MetaType::Meta_Hash,
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::test_h),
this, std::placeholders::_1),
QStringLiteral("test_h"));
o->registerGlobalFunction(
WingHex::MetaType::Meta_Bool,
std::bind(QOverload<const QVariantList &>::of(
&TestPlugin::createTestShareMem),
this, std::placeholders::_1),
QStringLiteral("createTestShareMem"),
{qMakePair(WingHex::MetaType::Meta_String, QStringLiteral("nameID"))});
o->registerGlobalFunction(WingHex::MetaType::Meta_Void,
std::bind(QOverload<const QVariantList &>::of(
&TestPlugin::destoryTestShareMem),
this, std::placeholders::_1),
QStringLiteral("destoryTestShareMem"));
o->registerGlobalFunction(
WingHex::MetaType::Meta_Void,
std::bind(QOverload<const QVariantList &>::of(
&TestPlugin::printLogTestSharedMemData),
this, std::placeholders::_1),
QStringLiteral("printLogTestSharedMemData"));
o->registerGlobalFunction(
QStringLiteral("array<color>@ colorTable()"),
std::bind(QOverload<const QList<void *> &>::of(&TestPlugin::colorTable),
this, std::placeholders::_1));
o->registerGlobalFunction(
WingHex::MetaType::Meta_Void,
std::bind(QOverload<const QVariantList &>::of(
&TestPlugin::setPluginMetaTestEnabled),
this, std::placeholders::_1),
QStringLiteral("setPluginMetaTestEnabled"),
{qMakePair(WingHex::MetaType::Meta_Bool, QStringLiteral("b"))});
o->registerGlobalFunction(WingHex::MetaType::Meta_Bool,
std::bind(QOverload<const QVariantList &>::of(
&TestPlugin::pluginMetaTestEnabled),
this, std::placeholders::_1),
QStringLiteral("pluginMetaTestEnabled"));
o->registerGlobalFunction(
WingHex::MetaType::Meta_Void,
std::bind(QOverload<const QVariantList &>::of(&TestPlugin::testCrash),
this, std::placeholders::_1),
QStringLiteral("testCrash"));
o->registerGlobalFunction(
"int testAdd(int a,int b)", asWINGFUNCTION(TestPlugin::testGenericAdd),
WingHex::IWingAngel::asCallConvTypes::asCALL_GENERIC);
o->registerGlobalFunction(
"void raiseScriptException()",
asWINGFUNCTION(TestPlugin::testRaiseScriptException),
WingHex::IWingAngel::asCallConvTypes::asCALL_GENERIC);
}

View File

@ -40,7 +40,6 @@ public:
// IWingPlugin interface (必须) // IWingPlugin interface (必须)
public: public:
virtual int sdkVersion() const override;
virtual bool init(const std::unique_ptr<QSettings> &set) override; virtual bool init(const std::unique_ptr<QSettings> &set) override;
virtual void unload(std::unique_ptr<QSettings> &set) override; virtual void unload(std::unique_ptr<QSettings> &set) override;
virtual const QString pluginName() const override; virtual const QString pluginName() const override;
@ -57,19 +56,18 @@ public:
virtual QMenu *registeredHexContextMenu() const override; virtual QMenu *registeredHexContextMenu() const override;
virtual QList<WingHex::WingRibbonToolBoxInfo> virtual QList<WingHex::WingRibbonToolBoxInfo>
registeredRibbonTools() const override; registeredRibbonTools() const override;
virtual QHash<WingHex::SettingPage *, bool> virtual QList<WingHex::SettingPage *>
registeredSettingPages() const override; registeredSettingPages() const override;
virtual QList<WingHex::PluginPage *> registeredPages() const override;
virtual QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>> virtual QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>>
registeredEditorViewWidgets() const override; registeredEditorViewWidgets() const override;
virtual QHash<QString, ScriptFnInfo> registeredScriptFns() const override;
virtual QHash<QString, UNSAFE_SCFNPTR>
registeredScriptUnsafeFns() const override;
virtual RegisteredEvents registeredEvents() const override; virtual RegisteredEvents registeredEvents() const override;
virtual void eventReady() override; virtual void eventReady() override;
// IWingPluginCoreBase interface
public:
virtual void onRegisterScriptObj(WingHex::IWingAngel *o) override;
private: private:
QVariant test_a(const QVariantList &params); QVariant test_a(const QVariantList &params);
QVariant test_b(const QVariantList &params); QVariant test_b(const QVariantList &params);
@ -81,7 +79,7 @@ private:
QVariant test_g(const QVariantList &params); QVariant test_g(const QVariantList &params);
QVariant test_h(const QVariantList &params); QVariant test_h(const QVariantList &params);
UNSAFE_RET colorTable(const QList<void *> &params); WingHex::UNSAFE_RET colorTable(const QList<void *> &params);
QVariant createTestShareMem(const QVariantList &params); QVariant createTestShareMem(const QVariantList &params);
QVariant destoryTestShareMem(const QVariantList &params); QVariant destoryTestShareMem(const QVariantList &params);
@ -92,6 +90,10 @@ private:
QVariant testCrash(const QVariantList &params); QVariant testCrash(const QVariantList &params);
static void testGenericAdd(WingHex::asIWingGeneric *param);
static void testRaiseScriptException(WingHex::asIWingGeneric *);
private: private:
void test_a(); void test_a();
void test_b(const QString &b); void test_b(const QString &b);
@ -121,14 +123,10 @@ private:
bool ENABLE_META = false; bool ENABLE_META = false;
QHash<QString, WingHex::IWingPlugin::ScriptFnInfo> _scriptInfo;
QList<WingHex::WingDockWidgetInfo> _winfo; QList<WingHex::WingDockWidgetInfo> _winfo;
QList<WingHex::WingRibbonToolBoxInfo> _rtbinfo; QList<WingHex::WingRibbonToolBoxInfo> _rtbinfo;
QHash<WingHex::SettingPage *, bool> _setpages; QList<WingHex::SettingPage *> _setpages;
QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>> _evws; QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>> _evws;
QList<WingHex::PluginPage *> _plgps;
QHash<QString, WingHex::IWingPlugin::UNSAFE_SCFNPTR> _scriptUnsafe;
}; };
#endif // TESTPLUGIN_H #endif // TESTPLUGIN_H

View File

@ -1,43 +0,0 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is
** furnished to do so.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
** THE SOFTWARE.
** =============================================================================
*/
#ifndef TESTPLUGINPAGE_H
#define TESTPLUGINPAGE_H
#include "WingPlugin/settingpage.h"
#include <QLabel>
class TestPluginPage : public WingHex::PluginPage {
Q_OBJECT
public:
explicit TestPluginPage(QWidget *parent = nullptr);
// PageBase interface
public:
virtual QIcon categoryIcon() const override;
virtual QString name() const override;
virtual QString id() const override;
private:
QLabel *_lbl = nullptr;
};
#endif // TESTPLUGINPAGE_H

View File

@ -23,8 +23,8 @@
#include <QVBoxLayout> #include <QVBoxLayout>
TestSettingPage::TestSettingPage(const QString &id, const QString &content, TestSettingPage::TestSettingPage(const QString &id, const QString &content,
QWidget *parent) bool isShowInRibbon, QWidget *parent)
: WingHex::SettingPage(parent), _id(id) { : WingHex::SettingPage(parent), _id(id), _isShownInRibbton(isShowInRibbon) {
auto layout = new QVBoxLayout(this); auto layout = new QVBoxLayout(this);
_lbl = new QLabel(content, this); _lbl = new QLabel(content, this);
_lbl->setAlignment(Qt::AlignCenter); _lbl->setAlignment(Qt::AlignCenter);
@ -39,6 +39,8 @@ QString TestSettingPage::name() const { return _id; }
QString TestSettingPage::id() const { return _id; } QString TestSettingPage::id() const { return _id; }
bool TestSettingPage::showInRibbon() const { return _isShownInRibbton; }
void TestSettingPage::apply() {} void TestSettingPage::apply() {}
void TestSettingPage::reset() {} void TestSettingPage::reset() {}

View File

@ -29,7 +29,7 @@ class TestSettingPage : public WingHex::SettingPage {
Q_OBJECT Q_OBJECT
public: public:
explicit TestSettingPage(const QString &id, const QString &content, explicit TestSettingPage(const QString &id, const QString &content,
QWidget *parent = nullptr); bool isShowInRibbon, QWidget *parent = nullptr);
// PageBase interface // PageBase interface
public: public:
@ -37,6 +37,8 @@ public:
virtual QString name() const override; virtual QString name() const override;
virtual QString id() const override; virtual QString id() const override;
virtual bool showInRibbon() const override;
// SettingPage interface // SettingPage interface
public: public:
virtual void apply() override; virtual void apply() override;
@ -45,7 +47,7 @@ public:
private: private:
QLabel *_lbl = nullptr; QLabel *_lbl = nullptr;
bool _isShownInRibbton;
QString _id; QString _id;
}; };

@ -1 +1 @@
Subproject commit 8541087abd410facd5559038f67949a58a39aa50 Subproject commit 3fa9d2ba9d7dd78f719c43b482a5e7f49f135f1c

View File

@ -68,7 +68,7 @@ BEGIN
BLOCK "080404b0" BLOCK "080404b0"
BEGIN BEGIN
VALUE "CompanyName", "ÓðÔÆ¹¤×÷ÊÒ£¨WingCloudStudio£©" VALUE "CompanyName", "ÓðÔÆ¹¤×÷ÊÒ£¨WingCloudStudio£©"
VALUE "FileDescription", "一个自由强大跨平台的十六进制编辑器" VALUE "FileDescription", "羽云十六进制编辑器"
VALUE "FileVersion", "1.0.0" VALUE "FileVersion", "1.0.0"
VALUE "InternalName", "WingHexExplorer2.exe" VALUE "InternalName", "WingHexExplorer2.exe"
VALUE "LegalCopyright", "AGPL-3.0" VALUE "LegalCopyright", "AGPL-3.0"

BIN
images/monitor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -61,6 +61,7 @@
<file>images/metadatah.png</file> <file>images/metadatah.png</file>
<file>images/metahide.png</file> <file>images/metahide.png</file>
<file>images/metashow.png</file> <file>images/metashow.png</file>
<file>images/monitor.png</file>
<file>images/new.png</file> <file>images/new.png</file>
<file>images/open.png</file> <file>images/open.png</file>
<file>images/openapp.png</file> <file>images/openapp.png</file>

View File

@ -1,5 +1,6 @@
{ {
"Id": "WingAngelAPI", "Id": "WingAngelAPI",
"SDK": 18,
"Author": "wingsummer", "Author": "wingsummer",
"Version": "2.2.2", "Version": "2.2.2",
"Vendor": "WingCloudStudio", "Vendor": "WingCloudStudio",

View File

@ -1,5 +1,6 @@
{ {
"Id" : "WingCStruct", "Id" : "WingCStruct",
"SDK": 18,
"Version" : "0.0.2", "Version" : "0.0.2",
"Vendor" : "WingCloudStudio", "Vendor" : "WingCloudStudio",
"Author" : "wingsummer", "Author" : "wingsummer",

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 "crashhandler.h"
#include "angelscript.h" #include "angelscript.h"
#include "class/pluginsystem.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 "dockcomponentsfactory.h"
#include "DockWidget.h" #include "DockWidget.h"

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,7 @@
#include <QVariant> #include <QVariant>
#include "WingPlugin/iwingdevice.h" #include "WingPlugin/iwingdevice.h"
#include "WingPlugin/iwingmanager.h"
#include "class/wingangelapi.h" #include "class/wingangelapi.h"
#include "control/editorview.h" #include "control/editorview.h"
@ -102,18 +103,9 @@ private:
QExplicitlySharedDataPointer<UniqueIdGenerator::UniqueId>; QExplicitlySharedDataPointer<UniqueIdGenerator::UniqueId>;
public: public:
struct PluginInfo {
QString id;
QVersionNumber version;
QString vendor;
QList<WingDependency> dependencies;
QString author;
QString license;
QString url;
};
enum class PluginStatus { enum class PluginStatus {
Valid, Valid,
SDKVersion,
BrokenVersion, BrokenVersion,
InvalidID, InvalidID,
DupID, DupID,
@ -126,12 +118,22 @@ private:
SharedUniqueId fid; SharedUniqueId fid;
EditorView *view = nullptr; EditorView *view = nullptr;
IWingPlugin *linkedplg = nullptr; IWingPlugin *linkedplg = nullptr;
QUndoCommand *cmd = nullptr; };
~PluginFileContext() { struct PluginFile {
if (cmd) { QVector<QSharedPointer<PluginFileContext>> contexts;
delete cmd; int currentFID = -1;
};
struct ViewBind {
QList<IWingPlugin *> linkedplg;
QList<QPair<QUndoCommand *, IWingPlugin *>> undoStackPlg;
~ViewBind() {
if (!undoStackPlg.isEmpty()) {
delete undoStackPlg.first().first;
} }
undoStackPlg.clear();
} }
}; };
@ -144,6 +146,8 @@ public:
void loadAllPlugin(); void loadAllPlugin();
void unloadAllPlugin(); void unloadAllPlugin();
void doneRegisterScriptObj();
void destory(); void destory();
const QList<IWingPlugin *> &plugins() const; const QList<IWingPlugin *> &plugins() const;
@ -175,9 +179,6 @@ public:
static QString getPUID(IWingPluginBase *p); static QString getPUID(IWingPluginBase *p);
static QString type2AngelScriptString(uint type, bool isArg,
bool noModifier = false);
private: private:
void loadExtPlugin(); void loadExtPlugin();
@ -185,6 +186,8 @@ private:
void checkDirRootSafe(const QDir &dir); void checkDirRootSafe(const QDir &dir);
void try2LoadManagerPlugin();
template <typename T> template <typename T>
std::optional<PluginInfo> loadPlugin(const QFileInfo &filename, std::optional<PluginInfo> loadPlugin(const QFileInfo &filename,
const QDir &setdir); const QDir &setdir);
@ -201,8 +204,7 @@ private:
EditorView *handle2EditorView(IWingPlugin *plg, int handle); EditorView *handle2EditorView(IWingPlugin *plg, int handle);
SharedUniqueId assginHandleForPluginView(IWingPlugin *plg, int assginHandleForOpenPluginView(IWingPlugin *plg, EditorView *view);
EditorView *view);
static bool equalCompareHandle(const SharedUniqueId &id, int handle); static bool equalCompareHandle(const SharedUniqueId &id, int handle);
@ -213,21 +215,12 @@ private:
PluginStatus checkPluginMetadata(const PluginInfo &meta, bool isPlg); PluginStatus checkPluginMetadata(const PluginInfo &meta, bool isPlg);
static bool isValidIdentifier(const QString &str);
void retranslateMetadata(IWingPluginBase *plg, PluginInfo &meta); void retranslateMetadata(IWingPluginBase *plg, PluginInfo &meta);
private: private:
void registerFns(IWingPlugin *plg);
void registerUnSafeFns(IWingPlugin *plg);
void registerEnums(IWingPlugin *plg);
void registerMarcos(IWingPlugin *plg);
void registerEvents(IWingPlugin *plg); void registerEvents(IWingPlugin *plg);
void applyFunctionTables(IWingPluginBase *plg, const CallTable &fns); void applyFunctionTables(QObject *plg, const CallTable &fns);
static QString getScriptFnSig(const QString &fnName,
const IWingPlugin::ScriptFnInfo &fninfo);
bool isPluginLoaded(const WingDependency &d); bool isPluginLoaded(const WingDependency &d);
@ -242,7 +235,7 @@ private:
QSharedPointer<PluginFileContext> pluginContextById(IWingPlugin *plg, QSharedPointer<PluginFileContext> pluginContextById(IWingPlugin *plg,
int fid) const; int fid) const;
QUndoCommand *pluginCurrentUndoCmd(IWingPlugin *plg) const; QUndoCommand *currentUndoCmd(EditorView *view);
private: private:
void loadPlugin(IWingPlugin *p, PluginInfo &meta, void loadPlugin(IWingPlugin *p, PluginInfo &meta,
@ -251,16 +244,22 @@ private:
const std::optional<QDir> &setdir); const std::optional<QDir> &setdir);
private: private:
void registerMarcoDevice(IWingDevice *plg); void registerPluginDetectMarco(const QString &id);
private: private:
void registerRibbonTools(const QList<WingRibbonToolBoxInfo> &tools);
void registeredSettingPages(const QVariant &itptr,
const QList<SettingPage *> &pages);
void registerPluginDockWidgets(IWingPluginBase *p); void registerPluginDockWidgets(IWingPluginBase *p);
void registerPluginPages(IWingPluginBase *p);
public: public:
// fpr crash checking // fpr crash checking
QString currentLoadingPlugin() const; QString currentLoadingPlugin() const;
IWingManager *monitorManager() const;
const std::optional<PluginInfo> &monitorManagerInfo() const;
private: private:
template <typename T> template <typename T>
T readBasicTypeContent(IWingPlugin *plg, qsizetype offset) { T readBasicTypeContent(IWingPlugin *plg, qsizetype offset) {
@ -284,7 +283,7 @@ private:
auto e = getCurrentPluginView(plg); auto e = getCurrentPluginView(plg);
if (e) { if (e) {
return EditorView::insertBasicTypeContent<T>( return EditorView::insertBasicTypeContent<T>(
e, offset, value, pluginCurrentUndoCmd(plg), _rwlock); e, offset, value, currentUndoCmd(e), _rwlock);
} }
return false; return false;
} }
@ -296,7 +295,7 @@ private:
auto e = getCurrentPluginView(plg); auto e = getCurrentPluginView(plg);
if (e) { if (e) {
return EditorView::writeBasicTypeContent<T>( return EditorView::writeBasicTypeContent<T>(
e, offset, value, pluginCurrentUndoCmd(plg), _rwlock); e, offset, value, currentUndoCmd(e), _rwlock);
} }
return false; return false;
} }
@ -307,7 +306,7 @@ private:
auto e = getCurrentPluginView(plg); auto e = getCurrentPluginView(plg);
if (e) { if (e) {
return EditorView::appendBasicTypeContent<T>( return EditorView::appendBasicTypeContent<T>(
e, value, pluginCurrentUndoCmd(plg), _rwlock); e, value, currentUndoCmd(e), _rwlock);
} }
return false; return false;
} }
@ -319,10 +318,6 @@ private:
PluginSystem(QObject *parent = nullptr); PluginSystem(QObject *parent = nullptr);
~PluginSystem(); ~PluginSystem();
void initCheckingEngine();
void finalizeCheckingEngine();
// IWingPluginBase API // IWingPluginBase API
public slots: public slots:
WING_API void toast(const QObject *sender, const QPixmap &icon, WING_API void toast(const QObject *sender, const QPixmap &icon,
@ -532,6 +527,10 @@ public slots:
WING_API bool endMarco(const QObject *sender); 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, WING_API bool writeInt8(const QObject *sender, qsizetype offset,
qint8 value); qint8 value);
@ -641,7 +640,7 @@ public slots:
bool clearSelection); bool clearSelection);
WING_API bool select(const QObject *sender, qsizetype offset, WING_API bool select(const QObject *sender, qsizetype offset,
qsizetype length, SelectionMode mode); qsizetype length, WingHex::SelectionMode mode);
WING_API bool setInsertionMode(const QObject *sender, bool isinsert); WING_API bool setInsertionMode(const QObject *sender, bool isinsert);
@ -662,16 +661,14 @@ public slots:
WING_API bool setMetaCommentVisible(const QObject *sender, bool b); WING_API bool setMetaCommentVisible(const QObject *sender, bool b);
// mainwindow // mainwindow
WING_API WingHex::ErrFile newFile(const QObject *sender); WING_API int newFile(const QObject *sender);
WING_API WingHex::ErrFile openFile(const QObject *sender, WING_API int openFile(const QObject *sender, const QString &filename);
const QString &filename);
WING_API WingHex::ErrFile WING_API int openExtFile(const QObject *sender, const QString &ext,
openExtFile(const QObject *sender, const QString &ext, const QString &file); const QString &file);
WING_API WingHex::ErrFile openWorkSpace(const QObject *sender, WING_API int openWorkSpace(const QObject *sender, const QString &filename);
const QString &filename);
WING_API WingHex::ErrFile closeHandle(const QObject *sender, int handle); WING_API WingHex::ErrFile closeHandle(const QObject *sender, int handle);
@ -686,7 +683,7 @@ public slots:
WING_API WingHex::ErrFile saveAsFile(const QObject *sender, int handle, WING_API WingHex::ErrFile saveAsFile(const QObject *sender, int handle,
const QString &savename); 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); WING_API WingHex::ErrFile closeCurrent(const QObject *sender, bool force);
@ -712,12 +709,20 @@ public slots:
// extension // extension
WING_API bool closeAllFiles(const QObject *sender); WING_API bool closeAllFiles(const QObject *sender);
// generic call support
WING_API WingHex::IWingGeneric *__createParamContext(const QObject *sender,
void *ctx);
WING_API void __raiseContextException(const QObject *sender,
const QString &exception,
bool allowCatch = true);
private: private:
WingHex::IWingPlugin *checkPluginAndReport(const QObject *sender, WingHex::IWingPlugin *checkPluginAndReport(const QObject *sender,
const char *func); const char *func);
WingHex::IWingDevice *checkBaseAndReport(const QObject *sender, bool passByFailedGuard(const QObject *sender, const char *func,
const char *func); const QVariantList &params);
bool checkErrAllAllowAndReport(const QObject *sender, const char *func); bool checkErrAllAllowAndReport(const QObject *sender, const char *func);
@ -735,17 +740,15 @@ private:
QMap<IWingPlugin::RegisteredEvent, QList<IWingPlugin *>> _evplgs; QMap<IWingPlugin::RegisteredEvent, QList<IWingPlugin *>> _evplgs;
QHash<IWingPlugin *, QVector<QSharedPointer<PluginFileContext>>> QHash<IWingPlugin *, PluginFile> m_plgviewMap;
m_plgviewMap; QHash<EditorView *, ViewBind> m_viewBindings;
QHash<IWingPlugin *, int> m_plgCurrentfid; // fid
QHash<EditorView *, QList<IWingPlugin *>> m_viewBindings;
UniqueIdGenerator m_idGen; UniqueIdGenerator m_idGen;
QHash<QString, QHash<QString, WingAngelAPI::ScriptFnInfo>> _scfns; IWingManager *_manager = nullptr;
std::optional<PluginInfo> _manInfo;
WingAngelAPI *_angelplg = nullptr; WingAngelAPI *_angelplg = nullptr;
asCScriptEngine *_engine = nullptr;
QStringList _scriptMarcos; QStringList _scriptMarcos;
QList<IWingPlugin *> _pragmaedPlg; QList<IWingPlugin *> _pragmaedPlg;

View File

@ -27,6 +27,7 @@
#include "AngelScript/sdk/add_on/scriptmath/scriptmath.h" #include "AngelScript/sdk/add_on/scriptmath/scriptmath.h"
#include "AngelScript/sdk/add_on/scriptmath/scriptmathcomplex.h" #include "AngelScript/sdk/add_on/scriptmath/scriptmathcomplex.h"
#include "AngelScript/sdk/add_on/weakref/weakref.h" #include "AngelScript/sdk/add_on/weakref/weakref.h"
#include "AngelScript/sdk/angelscript/source/as_scriptengine.h"
#include "angelobjstring.h" #include "angelobjstring.h"
#include "class/appmanager.h" #include "class/appmanager.h"
@ -145,6 +146,16 @@ bool ScriptMachine::isRunning(ConsoleMode mode) const {
return _ctx.value(mode) != nullptr; return _ctx.value(mode) != nullptr;
} }
bool ScriptMachine::isEngineConfigError() const {
if (_engine) {
auto e = dynamic_cast<asCScriptEngine *>(_engine);
if (e) {
return e->configFailed;
}
}
return true;
}
#define INS_1 "const ?&in = null" #define INS_1 "const ?&in = null"
#define INS_2 INS_1 ", " INS_1 #define INS_2 INS_1 ", " INS_1
#define INS_4 INS_2 ", " INS_2 #define INS_4 INS_2 ", " INS_2

View File

@ -116,6 +116,7 @@ public:
bool init(); bool init();
bool isInited() const; bool isInited() const;
bool isRunning(ConsoleMode mode) const; bool isRunning(ConsoleMode mode) const;
bool isEngineConfigError() const;
static void registerEngineAddon(asIScriptEngine *engine); static void registerEngineAddon(asIScriptEngine *engine);
static void registerEngineAssert(asIScriptEngine *engine); static void registerEngineAssert(asIScriptEngine *engine);
@ -150,15 +151,15 @@ public:
bool isDebugMode(ConsoleMode mode = Scripting); bool isDebugMode(ConsoleMode mode = Scripting);
public slots: public slots:
bool executeCode(ConsoleMode mode, const QString &code); bool executeCode(ScriptMachine::ConsoleMode mode, const QString &code);
// only scripting mode can be debugged // only scripting mode can be debugged
bool executeScript(ConsoleMode mode, const QString &script, bool executeScript(ScriptMachine::ConsoleMode mode, const QString &script,
bool isInDebug = false, int *retCode = nullptr); bool isInDebug = false, int *retCode = nullptr);
int evaluateDefine(const QString &code, bool &result); int evaluateDefine(const QString &code, bool &result);
void abortDbgScript(); void abortDbgScript();
void abortScript(ConsoleMode mode); void abortScript(ScriptMachine::ConsoleMode mode);
void abortScript(); void abortScript();
protected: protected:

View File

@ -59,18 +59,35 @@ SkinManager &SkinManager::instance() {
return instance; return instance;
} }
void SkinManager::setTheme(SkinManager::Theme theme) { m_theme = theme; } void SkinManager::setTheme(SkinManager::Theme theme) {
if (m_theme != theme) {
m_theme = theme;
m_cache.clear();
}
}
QIcon SkinManager::themeIcon(const QString &name) { QIcon SkinManager::themeIcon(const QString &name) {
switch (m_theme) { auto picon = m_cache.find(name);
case Theme::Dark: if (picon == m_cache.end()) {
return QIcon(QStringLiteral("://dark/") + name + switch (m_theme) {
QStringLiteral(".svg")); case Theme::Dark: {
case Theme::Light: QIcon icon(QStringLiteral("://dark/") + name +
return QIcon(QStringLiteral("://light/") + name + QStringLiteral(".svg"));
QStringLiteral(".svg")); m_cache.insert(name, icon);
return icon;
}
case Theme::Light: {
QIcon icon(QStringLiteral("://light/") + name +
QStringLiteral(".svg"));
m_cache.insert(name, icon);
return icon;
}
default:
return {};
}
} else {
return *picon;
} }
return {};
} }
SkinManager::Theme SkinManager::currentTheme() const { return m_theme; } SkinManager::Theme SkinManager::currentTheme() const { return m_theme; }

View File

@ -19,6 +19,7 @@
#define SKINMANAGER_H #define SKINMANAGER_H
#include <QCoreApplication> #include <QCoreApplication>
#include <QHash>
#include <QObject> #include <QObject>
class SkinManager { class SkinManager {
@ -48,6 +49,8 @@ private:
private: private:
Theme m_theme; Theme m_theme;
QHash<QString, QIcon> m_cache;
explicit SkinManager(); explicit SkinManager();
Q_DISABLE_COPY_MOVE(SkinManager) Q_DISABLE_COPY_MOVE(SkinManager)

597
src/class/wingangel.cpp Normal file
View File

@ -0,0 +1,597 @@
/*==============================================================================
** 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 "wingangel.h"
#include "define.h"
#include "wingangelapi.h"
#include "logger.h"
#include "scriptmachine.h"
#include "utilities.h"
inline asSFuncPtr asCSFuncPtr(const WingHex::asFuncPtr &ptr) {
// some checks
static_assert(std::is_standard_layout_v<asSFuncPtr>,
"asSFuncPtr must be standard layout");
static_assert(std::is_standard_layout_v<WingHex::asFuncPtr>,
"WingHex::asFuncPtr must be standard layout");
static_assert(sizeof(asSFuncPtr) == sizeof(WingHex::asFuncPtr),
"asSFuncPtr is not same as WingHex::asFuncPtr");
static_assert(alignof(asSFuncPtr) == alignof(WingHex::asFuncPtr),
"asSFuncPtr is not same as WingHex::asFuncPtr");
static_assert(offsetof(asSFuncPtr, ptr) ==
offsetof(WingHex::asFuncPtr, ptr),
"asSFuncPtr is not same as WingHex::asFuncPtr");
static_assert(offsetof(asSFuncPtr, flag) ==
offsetof(WingHex::asFuncPtr, flag),
"asSFuncPtr is not same as WingHex::asFuncPtr");
static_assert(sizeof(asSFuncPtr::ptr) == sizeof(WingHex::asFuncPtr::ptr),
"asSFuncPtr is not same as WingHex::asFuncPtr");
static_assert(std::is_same_v<decltype(asSFuncPtr::flag),
decltype(WingHex::asFuncPtr::flag)>,
"asSFuncPtr is not same as WingHex::asFuncPtr");
static_assert(offsetof(asSFuncPtr, flag) ==
offsetof(WingHex::asFuncPtr, flag),
"asSFuncPtr is not same as WingHex::asFuncPtr");
using StructM = decltype(std::declval<asSFuncPtr>().ptr.m);
using StructF = decltype(std::declval<asSFuncPtr>().ptr.f);
using wStructM = decltype(std::declval<WingHex::asFuncPtr>().ptr.m);
using wStructF = decltype(std::declval<WingHex::asFuncPtr>().ptr.f);
static_assert(offsetof(StructM, mthd) == offsetof(wStructM, mthd),
"asSFuncPtr is not same as WingHex::asFuncPtr");
static_assert(offsetof(StructF, func) == offsetof(wStructF, func),
"asSFuncPtr is not same as WingHex::asFuncPtr");
static_assert(offsetof(StructM, dummy) == offsetof(wStructM, dummy),
"asSFuncPtr is not same as WingHex::asFuncPtr");
static_assert(offsetof(StructF, dummy) == offsetof(wStructF, dummy),
"asSFuncPtr is not same as WingHex::asFuncPtr");
static_assert(sizeof(StructM::mthd) == sizeof(wStructM::mthd),
"asSFuncPtr is not same as WingHex::asFuncPtr");
static_assert(sizeof(StructF::func) == sizeof(wStructF::func),
"asSFuncPtr is not same as WingHex::asFuncPtr");
static_assert(sizeof(StructM::dummy) == sizeof(wStructM::dummy),
"asSFuncPtr is not same as WingHex::asFuncPtr");
static_assert(sizeof(StructF::dummy) == sizeof(wStructF::dummy),
"asSFuncPtr is not same as WingHex::asFuncPtr");
// just so simple
asSFuncPtr ret;
std::memcpy(&ret, &ptr, sizeof(ret));
return ret;
}
// some checks
static_assert(asEBehaviours::asBEHAVE_CONSTRUCT ==
int(WingHex::IWingAngel::asBEHAVE_CONSTRUCT),
"asEBehaviours check failed");
static_assert(asEBehaviours::asBEHAVE_LIST_CONSTRUCT ==
int(WingHex::IWingAngel::asBEHAVE_LIST_CONSTRUCT),
"asEBehaviours check failed");
static_assert(asEBehaviours::asBEHAVE_DESTRUCT ==
int(WingHex::IWingAngel::asBEHAVE_DESTRUCT),
"asEBehaviours check failed");
static_assert(asEBehaviours::asBEHAVE_FACTORY ==
int(WingHex::IWingAngel::asBEHAVE_FACTORY),
"asEBehaviours check failed");
static_assert(asEBehaviours::asBEHAVE_LIST_FACTORY ==
int(WingHex::IWingAngel::asBEHAVE_LIST_FACTORY),
"asEBehaviours check failed");
static_assert(asEBehaviours::asBEHAVE_ADDREF ==
int(WingHex::IWingAngel::asBEHAVE_ADDREF),
"asEBehaviours check failed");
static_assert(asEBehaviours::asBEHAVE_RELEASE ==
int(WingHex::IWingAngel::asBEHAVE_RELEASE),
"asEBehaviours check failed");
static_assert(asEBehaviours::asBEHAVE_GET_WEAKREF_FLAG ==
int(WingHex::IWingAngel::asBEHAVE_GET_WEAKREF_FLAG),
"asEBehaviours check failed");
static_assert(asEBehaviours::asBEHAVE_TEMPLATE_CALLBACK ==
int(WingHex::IWingAngel::asBEHAVE_TEMPLATE_CALLBACK),
"asEBehaviours check failed");
static_assert(asEBehaviours::asBEHAVE_FIRST_GC ==
int(WingHex::IWingAngel::asBEHAVE_FIRST_GC),
"asEBehaviours check failed");
static_assert(asEBehaviours::asBEHAVE_GETREFCOUNT ==
int(WingHex::IWingAngel::asBEHAVE_GETREFCOUNT),
"asEBehaviours check failed");
static_assert(asEBehaviours::asBEHAVE_SETGCFLAG ==
int(WingHex::IWingAngel::asBEHAVE_SETGCFLAG),
"asEBehaviours check failed");
static_assert(asEBehaviours::asBEHAVE_GETGCFLAG ==
int(WingHex::IWingAngel::asBEHAVE_GETGCFLAG),
"asEBehaviours check failed");
static_assert(asEBehaviours::asBEHAVE_ENUMREFS ==
int(WingHex::IWingAngel::asBEHAVE_ENUMREFS),
"asEBehaviours check failed");
static_assert(asEBehaviours::asBEHAVE_RELEASEREFS ==
int(WingHex::IWingAngel::asBEHAVE_RELEASEREFS),
"asEBehaviours check failed");
static_assert(asEBehaviours::asBEHAVE_LAST_GC ==
int(WingHex::IWingAngel::asBEHAVE_LAST_GC),
"asEBehaviours check failed");
static_assert(asEBehaviours::asBEHAVE_RELEASEREFS ==
int(WingHex::IWingAngel::asBEHAVE_RELEASEREFS),
"asEBehaviours check failed");
static_assert(asERetCodes::asSUCCESS == int(WingHex::asRetCodes::asSUCCESS),
"asERetCodes check failed");
static_assert(asERetCodes::asERROR == int(WingHex::asRetCodes::asERROR),
"asERetCodes check failed");
static_assert(asERetCodes::asCONTEXT_ACTIVE ==
int(WingHex::asRetCodes::asCONTEXT_ACTIVE),
"asERetCodes check failed");
static_assert(asERetCodes::asCONTEXT_NOT_FINISHED ==
int(WingHex::asRetCodes::asCONTEXT_NOT_FINISHED),
"asERetCodes check failed");
static_assert(asERetCodes::asCONTEXT_NOT_PREPARED ==
int(WingHex::asRetCodes::asCONTEXT_NOT_PREPARED),
"asERetCodes check failed");
static_assert(asERetCodes::asINVALID_ARG ==
int(WingHex::asRetCodes::asINVALID_ARG),
"asERetCodes check failed");
static_assert(asERetCodes::asNO_FUNCTION ==
int(WingHex::asRetCodes::asNO_FUNCTION),
"asERetCodes check failed");
static_assert(asERetCodes::asNOT_SUPPORTED ==
int(WingHex::asRetCodes::asNOT_SUPPORTED),
"asERetCodes check failed");
static_assert(asERetCodes::asINVALID_NAME ==
int(WingHex::asRetCodes::asINVALID_NAME),
"asERetCodes check failed");
static_assert(asERetCodes::asNAME_TAKEN ==
int(WingHex::asRetCodes::asNAME_TAKEN),
"asERetCodes check failed");
static_assert(asERetCodes::asINVALID_DECLARATION ==
int(WingHex::asRetCodes::asINVALID_DECLARATION),
"asERetCodes check failed");
static_assert(asERetCodes::asINVALID_OBJECT ==
int(WingHex::asRetCodes::asINVALID_OBJECT),
"asERetCodes check failed");
static_assert(asERetCodes::asINVALID_TYPE ==
int(WingHex::asRetCodes::asINVALID_TYPE),
"asERetCodes check failed");
static_assert(asERetCodes::asALREADY_REGISTERED ==
int(WingHex::asRetCodes::asALREADY_REGISTERED),
"asERetCodes check failed");
static_assert(asERetCodes::asMULTIPLE_FUNCTIONS ==
int(WingHex::asRetCodes::asMULTIPLE_FUNCTIONS),
"asERetCodes check failed");
static_assert(asERetCodes::asNO_MODULE == int(WingHex::asRetCodes::asNO_MODULE),
"asERetCodes check failed");
static_assert(asERetCodes::asNO_GLOBAL_VAR ==
int(WingHex::asRetCodes::asNO_GLOBAL_VAR),
"asERetCodes check failed");
static_assert(asERetCodes::asINVALID_CONFIGURATION ==
int(WingHex::asRetCodes::asINVALID_CONFIGURATION),
"asERetCodes check failed");
static_assert(asERetCodes::asINVALID_INTERFACE ==
int(WingHex::asRetCodes::asINVALID_INTERFACE),
"asERetCodes check failed");
static_assert(asERetCodes::asCANT_BIND_ALL_FUNCTIONS ==
int(WingHex::asRetCodes::asCANT_BIND_ALL_FUNCTIONS),
"asERetCodes check failed");
static_assert(
asERetCodes::asLOWER_ARRAY_DIMENSION_NOT_REGISTERED ==
int(WingHex::asRetCodes::asLOWER_ARRAY_DIMENSION_NOT_REGISTERED),
"asERetCodes check failed");
static_assert(asERetCodes::asWRONG_CONFIG_GROUP ==
int(WingHex::asRetCodes::asWRONG_CONFIG_GROUP),
"asERetCodes check failed");
static_assert(asERetCodes::asCONFIG_GROUP_IS_IN_USE ==
int(WingHex::asRetCodes::asCONFIG_GROUP_IS_IN_USE),
"asERetCodes check failed");
static_assert(asERetCodes::asILLEGAL_BEHAVIOUR_FOR_TYPE ==
int(WingHex::asRetCodes::asILLEGAL_BEHAVIOUR_FOR_TYPE),
"asERetCodes check failed");
static_assert(asERetCodes::asWRONG_CALLING_CONV ==
int(WingHex::asRetCodes::asWRONG_CALLING_CONV),
"asERetCodes check failed");
static_assert(asERetCodes::asBUILD_IN_PROGRESS ==
int(WingHex::asRetCodes::asBUILD_IN_PROGRESS),
"asERetCodes check failed");
static_assert(asERetCodes::asINIT_GLOBAL_VARS_FAILED ==
int(WingHex::asRetCodes::asINIT_GLOBAL_VARS_FAILED),
"asERetCodes check failed");
static_assert(asERetCodes::asOUT_OF_MEMORY ==
int(WingHex::asRetCodes::asOUT_OF_MEMORY),
"asERetCodes check failed");
static_assert(asERetCodes::asMODULE_IS_IN_USE ==
int(WingHex::asRetCodes::asMODULE_IS_IN_USE),
"asERetCodes check failed");
WingAngel::WingAngel(WingAngelAPI *api, QStringList &marcos)
: _api(api), _scriptMarcos(marcos) {
Q_ASSERT(api);
}
bool WingAngel::setCurrentPluginSession(const QByteArray &ns) {
if (ns != _plgsess) {
auto engine = ScriptMachine::instance().engine();
auto ret = engine->SetDefaultNamespace(ns.data());
if (ret != asSUCCESS) {
return false;
}
_plgsess = ns;
}
return true;
}
WingHex::asRetCodes
WingAngel::registerGlobalFunction(uint retMetaType, const ScriptFn &fn,
const QString &fnName,
const QVector<QPair<uint, QString>> &params) {
auto sig = getScriptFnSig(retMetaType, fn, fnName, params);
if (sig.isEmpty()) {
Logger::critical(tr("RegisterScriptFnUnSupportedTypes:") + _plgsess +
QStringLiteral("::") + fnName);
return WingHex::asRetCodes::asINVALID_ARG;
}
auto engine = ScriptMachine::instance().engine();
auto ret = engine->RegisterGlobalFunction(
sig.toUtf8(), asFUNCTION(WingAngelAPI::script_call),
asECallConvTypes::asCALL_GENERIC);
if (ret < 0) {
// TODO
return returnValue(ret);
}
auto &sfns = _api->_sfns;
auto id = sfns.size();
auto f = engine->GetFunctionById(ret);
if (f) {
f->SetUserData(_api, AsUserDataType::UserData_API);
f->SetUserData(reinterpret_cast<void *>(id),
AsUserDataType::UserData_PluginFn);
} else {
return WingHex::asRetCodes::asINVALID_ARG;
}
WingScriptInternal::ScriptFnInfo info;
info.ret = retMetaType;
info.fn = fn;
info.params = params;
sfns.append(info);
return WingHex::asRetCodes::asSUCCESS;
}
WingHex::asRetCodes
WingAngel::registerGlobalFunction(const QString &decl,
const WingHex::UNSAFE_SCFNPTR &fn) {
if (decl.isEmpty()) {
Logger::critical(tr("RegisterScriptFnUnSupportedTypes:") + _plgsess +
QStringLiteral("::") + decl);
return WingHex::asRetCodes::asINVALID_ARG;
}
auto engine = ScriptMachine::instance().engine();
auto ret = engine->RegisterGlobalFunction(
decl.toUtf8(), asFUNCTION(WingAngelAPI::script_unsafe_call),
asECallConvTypes::asCALL_GENERIC);
if (ret < 0) {
// TODO
return returnValue(ret);
}
auto &sfns = _api->_usfns;
auto id = sfns.size();
auto f = engine->GetFunctionById(ret);
if (f) {
f->SetUserData(_api, AsUserDataType::UserData_API);
f->SetUserData(reinterpret_cast<void *>(id),
AsUserDataType::UserData_PluginFn);
} else {
return WingHex::asRetCodes::asINVALID_ARG;
}
sfns.append(fn);
return WingHex::asRetCodes::asSUCCESS;
}
void WingAngel::registerScriptMarco(const QString &marco) {
if (Utilities::isValidIdentifier(marco)) {
static auto sep = QStringLiteral("_");
_scriptMarcos.append(sep + _plgsess + sep + marco + sep);
} else {
// TODO
}
}
void WingAngel::registerScriptMarcos(const QStringList &marcos) {
for (auto &m : marcos) {
registerScriptMarco(m);
}
}
WingHex::asRetCodes
WingAngel::registerGlobalFunction(const char *declaration,
const WingHex::asFuncPtr &funcPointer,
asCallConvTypes callConv, void *auxiliary) {
auto engine = ScriptMachine::instance().engine();
auto ret = engine->RegisterGlobalFunction(
declaration, asCSFuncPtr(funcPointer), asDWORD(callConv), auxiliary);
return returnValue(ret);
}
WingHex::asRetCodes
WingAngel::registerInterfaceMethod(const char *intf, const char *declaration) {
auto engine = ScriptMachine::instance().engine();
auto ret = engine->RegisterInterfaceMethod(intf, declaration);
return returnValue(ret);
}
WingHex::asRetCodes WingAngel::registerInterface(const char *name) {
auto engine = ScriptMachine::instance().engine();
auto ret = engine->RegisterInterface(name);
return returnValue(ret);
}
WingHex::asRetCodes WingAngel::registerObjectBehaviour(
const char *obj, asBehaviours behaviour, const char *declaration,
const WingHex::asFuncPtr &funcPointer, asCallConvTypes callConv,
void *auxiliary, int compositeOffset, bool isCompositeIndirect) {
auto engine = ScriptMachine::instance().engine();
auto ret = engine->RegisterObjectBehaviour(
obj, asEBehaviours(behaviour), declaration, asCSFuncPtr(funcPointer),
asECallConvTypes(callConv), auxiliary, compositeOffset,
isCompositeIndirect);
return returnValue(ret);
}
WingHex::asRetCodes
WingAngel::registerObjectMethod(const char *obj, const char *declaration,
const WingHex::asFuncPtr &funcPointer,
asCallConvTypes callConv, void *auxiliary,
int compositeOffset, bool isCompositeIndirect) {
auto engine = ScriptMachine::instance().engine();
auto ret = engine->RegisterObjectMethod(
obj, declaration, asCSFuncPtr(funcPointer), asECallConvTypes(callConv),
auxiliary, compositeOffset, isCompositeIndirect);
return returnValue(ret);
}
WingHex::asRetCodes
WingAngel::registerObjectProperty(const char *obj, const char *declaration,
int byteOffset, int compositeOffset,
bool isCompositeIndirect) {
auto engine = ScriptMachine::instance().engine();
auto ret = engine->RegisterObjectProperty(
obj, declaration, byteOffset, compositeOffset, isCompositeIndirect);
return returnValue(ret);
}
WingHex::asRetCodes WingAngel::registerObjectType(const char *obj, int byteSize,
quint64 flags) {
auto engine = ScriptMachine::instance().engine();
auto ret = engine->RegisterObjectType(obj, byteSize, flags);
return returnValue(ret);
}
WingHex::asRetCodes WingAngel::registerGlobalProperty(const char *declaration,
void *pointer) {
auto engine = ScriptMachine::instance().engine();
auto ret = engine->RegisterGlobalProperty(declaration, pointer);
return returnValue(ret);
}
WingHex::asRetCodes WingAngel::registerTypedef(const char *type,
const char *decl) {
auto engine = ScriptMachine::instance().engine();
auto ret = engine->RegisterTypedef(type, decl);
return returnValue(ret);
}
WingHex::asRetCodes WingAngel::registerFuncdef(const char *decl) {
auto engine = ScriptMachine::instance().engine();
auto ret = engine->RegisterFuncdef(decl);
return returnValue(ret);
}
WingHex::asRetCodes WingAngel::registerEnumValue(const char *type,
const char *name, int value) {
auto engine = ScriptMachine::instance().engine();
auto ret = engine->RegisterEnumValue(type, name, value);
return returnValue(ret);
}
WingHex::asRetCodes WingAngel::registerEnum(const char *type) {
auto engine = ScriptMachine::instance().engine();
auto ret = engine->RegisterEnum(type);
return returnValue(ret);
}
WingHex::asRetCodes WingAngel::restoreDefaultNamespace() {
auto engine = ScriptMachine::instance().engine();
auto ret = engine->SetDefaultNamespace(_plgsess);
return returnValue(ret);
}
WingHex::asRetCodes WingAngel::setDefaultNamespace(const char *nameSpace) {
auto engine = ScriptMachine::instance().engine();
if (nameSpace) {
if (qstrlen(nameSpace) > 1024) {
return WingHex::asRetCodes::asINVALID_NAME;
}
auto ns = _plgsess.append(QByteArrayLiteral("::")).append(nameSpace);
auto ret = engine->SetDefaultNamespace(ns.data());
return returnValue(ret);
} else {
return restoreDefaultNamespace();
}
}
QString WingAngel::getScriptFnSig(uint retMetaType, const ScriptFn &fn,
const QString &fnName,
const QVector<QPair<uint, QString>> &params) {
if (fnName.isEmpty()) {
return {};
}
QString sig;
auto ret = type2AngelScriptString(retMetaType, false);
if (ret.isEmpty()) {
return {};
}
sig += ret + QStringLiteral(" ") + fnName + QStringLiteral("(");
QStringList _params;
for (auto &param : params) {
auto ret = type2AngelScriptString(param.first, true);
if (ret.isEmpty()) {
return {};
}
_params << ret + QStringLiteral(" ") + param.second;
}
return sig + _params.join(',') + QStringLiteral(")");
}
QString WingAngel::type2AngelScriptString(uint type, bool isArg,
bool noModifier) {
auto isArray = !!(type & WingHex::Meta_Array);
auto isList = !!(type & WingHex::Meta_List);
auto isContainer = isArray || isList;
if (isContainer) {
if (isArray && isList) {
return {};
}
}
QString retype;
bool complexType = false;
type = WingHex::MetaType(type & WingHex::MetaTypeMask);
switch (type) {
case WingHex::Meta_Void:
retype = QStringLiteral("void");
break;
case WingHex::Meta_Bool:
retype = QStringLiteral("bool");
break;
case WingHex::Meta_Int:
retype = QStringLiteral("int");
break;
case WingHex::Meta_UInt:
retype = QStringLiteral("uint");
break;
case WingHex::Meta_Int8:
retype = QStringLiteral("int8");
break;
case WingHex::Meta_UInt8:
retype = QStringLiteral("uint8");
break;
case WingHex::Meta_Int16:
retype = QStringLiteral("int16");
break;
case WingHex::Meta_UInt16:
retype = QStringLiteral("uint16");
break;
case WingHex::Meta_Int64:
retype = QStringLiteral("int64");
break;
case WingHex::Meta_UInt64:
retype = QStringLiteral("uint64");
break;
case WingHex::Meta_Float:
retype = QStringLiteral("float");
break;
case WingHex::Meta_Double:
retype = QStringLiteral("double");
break;
case WingHex::Meta_String:
retype = QStringLiteral("string");
break;
case WingHex::Meta_Char:
retype = QStringLiteral("char");
break;
case WingHex::Meta_Byte:
retype = QStringLiteral("byte");
break;
case WingHex::Meta_Color:
retype = QStringLiteral("color");
complexType = true;
break;
case WingHex::Meta_Map:
case WingHex::Meta_Hash:
retype = QStringLiteral("dictionary");
complexType = true;
break;
default:
return {};
}
if (isArray || isList) {
retype.append(QStringLiteral("[]"));
}
if (isArg) {
if (!noModifier && (isContainer || complexType)) {
retype.append(QStringLiteral(" &in"))
.prepend(QStringLiteral("const "));
}
} else {
if (!noModifier) {
// if it's a return type, only array<byte> and array<string> are
// supported in AngelScript
// ( array<byte> -> QByteArray , array<string> -> QStringList ),
// other array types are not suported. PRs are welcomed !!!
// IT'S TOO COMPLEX TO SUPPORT QVARIANTLIST !!!
// You can use unsafe registering to support
// extensive scripting system.
// It will be faster and flexible but not easy to implement.
if (isContainer) {
if (type != WingHex::Meta_Byte &&
type != WingHex::Meta_String) {
return {};
}
retype.append(QStringLiteral("@"));
}
if (complexType) {
retype.append(QStringLiteral("@"));
}
}
}
return retype.trimmed();
}
WingHex::asRetCodes WingAngel::returnValue(int ret) {
if (ret < 0) {
return WingHex::asRetCodes(ret);
} else {
return WingHex::asRetCodes::asSUCCESS;
}
}

107
src/class/wingangel.h Normal file
View File

@ -0,0 +1,107 @@
/*==============================================================================
** 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/>.
** =============================================================================
*/
#ifndef WINGANGEL_H
#define WINGANGEL_H
#include "WingPlugin/iwingangel.h"
#include <QCoreApplication>
class WingAngelAPI;
class WingAngel : public WingHex::IWingAngel {
Q_DECLARE_TR_FUNCTIONS(WingAngel)
public:
WingAngel(WingAngelAPI *api, QStringList &marcos);
public:
bool setCurrentPluginSession(const QByteArray &ns);
// IWingAngel interface
public:
virtual WingHex::asRetCodes registerGlobalFunction(
uint retMetaType, const ScriptFn &fn, const QString &fnName,
const QVector<QPair<uint, QString>> &params) override;
virtual WingHex::asRetCodes
registerGlobalFunction(const QString &decl,
const WingHex::UNSAFE_SCFNPTR &fn) override;
virtual void registerScriptMarco(const QString &marco) override;
virtual void registerScriptMarcos(const QStringList &marcos) override;
virtual WingHex::asRetCodes
setDefaultNamespace(const char *nameSpace) override;
virtual WingHex::asRetCodes restoreDefaultNamespace() override;
virtual WingHex::asRetCodes registerEnum(const char *type) override;
virtual WingHex::asRetCodes
registerEnumValue(const char *type, const char *name, int value) override;
virtual WingHex::asRetCodes registerFuncdef(const char *decl) override;
virtual WingHex::asRetCodes registerTypedef(const char *type,
const char *decl) override;
virtual WingHex::asRetCodes registerGlobalProperty(const char *declaration,
void *pointer) override;
virtual WingHex::asRetCodes
registerObjectType(const char *obj, int byteSize, quint64 flags) override;
virtual WingHex::asRetCodes
registerObjectProperty(const char *obj, const char *declaration,
int byteOffset, int compositeOffset,
bool isCompositeIndirect) override;
virtual WingHex::asRetCodes
registerObjectMethod(const char *obj, const char *declaration,
const WingHex::asFuncPtr &funcPointer,
asCallConvTypes callConv, void *auxiliary,
int compositeOffset,
bool isCompositeIndirect) override;
virtual WingHex::asRetCodes registerObjectBehaviour(
const char *obj, asBehaviours behaviour, const char *declaration,
const WingHex::asFuncPtr &funcPointer, asCallConvTypes callConv,
void *auxiliary, int compositeOffset,
bool isCompositeIndirect) override;
virtual WingHex::asRetCodes registerInterface(const char *name) override;
virtual WingHex::asRetCodes
registerInterfaceMethod(const char *intf, const char *declaration) override;
virtual WingHex::asRetCodes
registerGlobalFunction(const char *declaration,
const WingHex::asFuncPtr &funcPointer,
asCallConvTypes callConv, void *auxiliary) override;
private:
static QString getScriptFnSig(uint retMetaType, const ScriptFn &fn,
const QString &fnName,
const QVector<QPair<uint, QString>> &params);
static QString type2AngelScriptString(uint type, bool isArg,
bool noModifier = false);
private:
WingHex::asRetCodes returnValue(int ret);
private:
WingAngelAPI *_api;
QByteArray _plgsess;
QStringList &_scriptMarcos;
};
#endif // WINGANGEL_H

View File

@ -18,9 +18,9 @@
#include "wingangelapi.h" #include "wingangelapi.h"
#include "AngelScript/sdk/angelscript/include/angelscript.h" #include "AngelScript/sdk/angelscript/include/angelscript.h"
#include "WingPlugin/iwingangel.h"
#include "class/angelscripthelper.h" #include "class/angelscripthelper.h"
#include "class/logger.h" #include "class/logger.h"
#include "class/pluginsystem.h"
#include "class/scriptmachine.h" #include "class/scriptmachine.h"
#include "class/wingfiledialog.h" #include "class/wingfiledialog.h"
#include "class/winginputdialog.h" #include "class/winginputdialog.h"
@ -31,6 +31,7 @@
#include <QJsonDocument> #include <QJsonDocument>
#include <QMessageBox> #include <QMessageBox>
#include <QTemporaryFile> #include <QTemporaryFile>
#include <QThread>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#undef MessageBox #undef MessageBox
@ -44,8 +45,6 @@ WingAngelAPI::WingAngelAPI() {
WingAngelAPI::~WingAngelAPI() {} WingAngelAPI::~WingAngelAPI() {}
int WingAngelAPI::sdkVersion() const { return WingHex::SDKVERSION; }
bool WingAngelAPI::init(const std::unique_ptr<QSettings> &set) { bool WingAngelAPI::init(const std::unique_ptr<QSettings> &set) {
Q_UNUSED(set); Q_UNUSED(set);
return true; return true;
@ -69,8 +68,8 @@ QString WingAngelAPI::retranslate(const QString &str) {
return QApplication::tr(str.toLatin1()); return QApplication::tr(str.toLatin1());
} }
QStringList WingAngelAPI::registerScriptMarcos() const { void WingAngelAPI::onRegisterScriptObj(WingHex::IWingAngel *o) {
return {"EXEC_BASE", "AS_ARRAY_EXT", "AS_DICTIONARY_EXT"}; o->registerScriptMarcos({"EXEC_BASE", "AS_ARRAY_EXT", "AS_DICTIONARY_EXT"});
} }
WingHex::IWingPlugin::RegisteredEvents WingAngelAPI::registeredEvents() const { WingHex::IWingPlugin::RegisteredEvents WingAngelAPI::registeredEvents() const {
@ -93,48 +92,6 @@ void WingAngelAPI::eventPluginFile(PluginFileEvent e, FileType type,
} }
} }
void WingAngelAPI::registerUnSafeScriptFns(
const QString &ns, const QHash<QString, UNSAFE_SCFNPTR> &rfns) {
Q_ASSERT(!ns.isEmpty());
if (rfns.isEmpty()) {
return;
}
auto id = _usfns.size();
for (auto p = rfns.constKeyValueBegin(); p != rfns.constKeyValueEnd();
p++) {
_urfns[ns][p->first] = id;
id++;
_usfns.append(p->second);
}
}
void WingAngelAPI::registerScriptEnums(
const QString &ns, const QHash<QString, QList<QPair<QString, int>>> &objs) {
Q_ASSERT(!ns.isEmpty());
if (objs.isEmpty()) {
return;
}
_objs.insert(ns, objs);
}
void WingAngelAPI::registerScriptFns(const QString &ns,
const QHash<QString, ScriptFnInfo> &rfns) {
Q_ASSERT(!ns.isEmpty());
if (rfns.isEmpty()) {
return;
}
auto id = _sfns.size();
for (auto p = rfns.constKeyValueBegin(); p != rfns.constKeyValueEnd();
p++) {
_rfns[ns][p->first] = id;
id++;
_sfns.append(p->second);
}
}
void WingAngelAPI::installAPI(ScriptMachine *machine) { void WingAngelAPI::installAPI(ScriptMachine *machine) {
Q_ASSERT(machine); Q_ASSERT(machine);
auto engine = machine->engine(); auto engine = machine->engine();
@ -150,9 +107,7 @@ void WingAngelAPI::installAPI(ScriptMachine *machine) {
installHexReaderAPI(engine); installHexReaderAPI(engine);
installHexControllerAPI(engine); installHexControllerAPI(engine);
installScriptEnums(engine); // plugin script objects will be install later
installScriptFns(engine);
installScriptUnSafeFns(engine);
} }
void WingAngelAPI::installBasicTypes(asIScriptEngine *engine) { void WingAngelAPI::installBasicTypes(asIScriptEngine *engine) {
@ -767,6 +722,12 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
registerAPI(engine, registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, endMarco, (void), bool), asMETHODPR(WingHex::IWingPlugin, endMarco, (void), bool),
"bool endMarco()"); "bool endMarco()");
registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, isMacroEmpty, (void), bool),
"bool isMacroEmpty()");
registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, resetMarco, (void), bool),
"bool resetMarco()");
registerAPI( registerAPI(
engine, engine,
@ -993,20 +954,18 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
asMETHODPR(WingHex::IWingPlugin, setMetaCommentVisible, (bool), bool), asMETHODPR(WingHex::IWingPlugin, setMetaCommentVisible, (bool), bool),
"bool setMetaCommentVisible(bool b)"); "bool setMetaCommentVisible(bool b)");
registerAPI(engine, registerAPI(engine, asMETHODPR(WingHex::IWingPlugin, newFile, (), int),
asMETHODPR(WingHex::IWingPlugin, newFile, (), WingHex::ErrFile), "int newFile()");
"ErrFile newFile()");
registerAPI(engine, registerAPI(
asMETHODPR(WingHex::IWingPlugin, openFile, (const QString &), engine,
WingHex::ErrFile), asMETHODPR(WingHex::IWingPlugin, openFile, (const QString &), int),
"ErrFile openFile(string &in filename)"); "int openFile(string &in filename)");
registerAPI(engine, registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, openExtFile, asMETHODPR(WingHex::IWingPlugin, openExtFile,
(const QString &, const QString &), (const QString &, const QString &), int),
WingHex::ErrFile), "int openExtFile(string &in ext, string &in file)");
"ErrFile openExtFile(string &in ext, string &in file)");
registerAPI(engine, registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, closeFile, (int, bool), asMETHODPR(WingHex::IWingPlugin, closeFile, (int, bool),
@ -1033,10 +992,8 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
(int, const QString &), WingHex::ErrFile), (int, const QString &), WingHex::ErrFile),
"ErrFile saveAsFile(int handle, string &in savename)"); "ErrFile saveAsFile(int handle, string &in savename)");
registerAPI( registerAPI(engine, asMETHODPR(WingHex::IWingPlugin, openCurrent, (), int),
engine, "int openCurrent()");
asMETHODPR(WingHex::IWingPlugin, openCurrent, (), WingHex::ErrFile),
"ErrFile openCurrent()");
registerAPI(engine, registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, closeCurrent, (bool), asMETHODPR(WingHex::IWingPlugin, closeCurrent, (bool),
@ -1072,10 +1029,10 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
asMETHODPR(WingHex::IWingPlugin, clearBookMark, (), bool), asMETHODPR(WingHex::IWingPlugin, clearBookMark, (), bool),
"bool clearBookMark()"); "bool clearBookMark()");
registerAPI(engine, registerAPI(
asMETHODPR(WingHex::IWingPlugin, openWorkSpace, engine,
(const QString &), WingHex::ErrFile), asMETHODPR(WingHex::IWingPlugin, openWorkSpace, (const QString &), int),
"ErrFile openWorkSpace(string &in filename)"); "int openWorkSpace(string &in filename)");
registerAPI(engine, registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, closeAllFiles, (), bool), asMETHODPR(WingHex::IWingPlugin, closeAllFiles, (), bool),
@ -1084,89 +1041,6 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
engine->SetDefaultNamespace(""); engine->SetDefaultNamespace("");
} }
void WingAngelAPI::installScriptFns(asIScriptEngine *engine) {
for (auto pfns = _rfns.constKeyValueBegin();
pfns != _rfns.constKeyValueEnd(); pfns++) {
auto ns = pfns->first;
int r = engine->SetDefaultNamespace(ns.toUtf8());
Q_ASSERT(r >= 0);
Q_UNUSED(r);
auto &pfn = pfns->second;
for (auto p = pfn.constKeyValueBegin(); p != pfn.constKeyValueEnd();
p++) {
auto sig = p->first;
auto id = p->second;
auto r = engine->RegisterGlobalFunction(
sig.toUtf8(), asFUNCTION(script_call), asCALL_GENERIC);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
// r is the AngelScript function ID
auto fn = engine->GetFunctionById(r);
fn->SetUserData(this, AsUserDataType::UserData_API);
fn->SetUserData(reinterpret_cast<void *>(id),
AsUserDataType::UserData_PluginFn);
}
engine->SetDefaultNamespace("");
}
}
void WingAngelAPI::installScriptUnSafeFns(asIScriptEngine *engine) {
for (auto pfns = _urfns.constKeyValueBegin();
pfns != _urfns.constKeyValueEnd(); pfns++) {
auto ns = pfns->first;
int r = engine->SetDefaultNamespace(ns.toUtf8());
Q_ASSERT(r >= 0);
Q_UNUSED(r);
auto &pfn = pfns->second;
for (auto p = pfn.constKeyValueBegin(); p != pfn.constKeyValueEnd();
p++) {
auto sig = p->first;
auto id = p->second;
auto r = engine->RegisterGlobalFunction(
sig.toUtf8(), asFUNCTION(script_unsafe_call), asCALL_GENERIC);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
// r is the AngelScript function ID
auto fn = engine->GetFunctionById(r);
fn->SetUserData(this, AsUserDataType::UserData_API);
fn->SetUserData(reinterpret_cast<void *>(id),
AsUserDataType::UserData_PluginFn);
}
engine->SetDefaultNamespace("");
}
}
void WingAngelAPI::installScriptEnums(asIScriptEngine *engine) {
for (auto pobjs = _objs.constKeyValueBegin();
pobjs != _objs.constKeyValueEnd(); ++pobjs) {
auto ns = pobjs->first;
int r = engine->SetDefaultNamespace(ns.toUtf8());
Q_ASSERT(r >= 0);
Q_UNUSED(r);
auto &pobj = pobjs->second;
for (auto p = pobj.constKeyValueBegin(); p != pobj.constKeyValueEnd();
p++) {
auto en = p->first.toUtf8();
r = engine->RegisterEnum(en.data());
Q_ASSERT(r >= 0);
Q_UNUSED(r);
for (auto &e : p->second) {
auto ev = e.first.toUtf8();
r = engine->RegisterEnumValue(en.data(), ev.data(), e.second);
Q_ASSERT(r >= 0);
Q_UNUSED(r);
}
}
engine->SetDefaultNamespace("");
}
}
void WingAngelAPI::registerAPI(asIScriptEngine *engine, const asSFuncPtr &fn, void WingAngelAPI::registerAPI(asIScriptEngine *engine, const asSFuncPtr &fn,
const char *sig) { const char *sig) {
auto r = auto r =
@ -1565,12 +1439,13 @@ QVariant WingAngelAPI::qvariantGet(asIScriptEngine *engine, const void *raw,
return {}; return {};
} }
bool WingAngelAPI::getQVariantGetFlag(const ScriptFnInfo &info, int index) { bool WingAngelAPI::getQVariantGetFlag(
const WingScriptInternal::ScriptFnInfo &info, int index) {
auto &params = info.params; auto &params = info.params;
Q_ASSERT(index >= 0 && index < params.size()); Q_ASSERT(index >= 0 && index < params.size());
auto minfo = params.at(index).first; auto minfo = params.at(index).first;
return !!(minfo & MetaType::List) || !!(minfo & MetaType::Hash); return !!(minfo & WingHex::Meta_List) || !!(minfo & WingHex::Meta_Hash);
} }
int WingAngelAPI::qvariantCastASID(asIScriptEngine *engine, int WingAngelAPI::qvariantCastASID(asIScriptEngine *engine,
@ -1698,6 +1573,118 @@ bool WingAngelAPI::isTempBuffered(QMetaType::Type type) {
} }
} }
QString WingAngelAPI::type2AngelScriptString(uint type, bool isArg,
bool noModifier) {
auto isArray = !!(type & WingHex::Meta_Array);
auto isList = !!(type & WingHex::Meta_List);
auto isContainer = isArray || isList;
if (isContainer) {
if (isArray && isList) {
return {};
}
}
QString retype;
bool complexType = false;
type = WingHex::MetaType(type & WingHex::MetaTypeMask);
switch (type) {
case WingHex::Meta_Void:
retype = QStringLiteral("void");
break;
case WingHex::Meta_Bool:
retype = QStringLiteral("bool");
break;
case WingHex::Meta_Int:
retype = QStringLiteral("int");
break;
case WingHex::Meta_UInt:
retype = QStringLiteral("uint");
break;
case WingHex::Meta_Int8:
retype = QStringLiteral("int8");
break;
case WingHex::Meta_UInt8:
retype = QStringLiteral("uint8");
break;
case WingHex::Meta_Int16:
retype = QStringLiteral("int16");
break;
case WingHex::Meta_UInt16:
retype = QStringLiteral("uint16");
break;
case WingHex::Meta_Int64:
retype = QStringLiteral("int64");
break;
case WingHex::Meta_UInt64:
retype = QStringLiteral("uint64");
break;
case WingHex::Meta_Float:
retype = QStringLiteral("float");
break;
case WingHex::Meta_Double:
retype = QStringLiteral("double");
break;
case WingHex::Meta_String:
retype = QStringLiteral("string");
break;
case WingHex::Meta_Char:
retype = QStringLiteral("char");
break;
case WingHex::Meta_Byte:
retype = QStringLiteral("byte");
break;
case WingHex::Meta_Color:
retype = QStringLiteral("color");
complexType = true;
break;
case WingHex::Meta_Map:
case WingHex::Meta_Hash:
retype = QStringLiteral("dictionary");
complexType = true;
break;
default:
return {};
}
if (isArray || isList) {
retype.append(QStringLiteral("[]"));
}
if (isArg) {
if (!noModifier && (isContainer || complexType)) {
retype.append(QStringLiteral(" &in"))
.prepend(QStringLiteral("const "));
}
} else {
if (!noModifier) {
// if it's a return type, only array<byte> and array<string> are
// supported in AngelScript
// ( array<byte> -> QByteArray , array<string> -> QStringList ),
// other array types are not suported. PRs are welcomed !!!
// IT'S TOO COMPLEX TO SUPPORT QVARIANTLIST !!!
// You can use unsafe registering to support
// extensive scripting system.
// It will be faster and flexible but not easy to implement.
if (isContainer) {
if (type != WingHex::Meta_Byte &&
type != WingHex::Meta_String) {
return {};
}
retype.append(QStringLiteral("@"));
}
if (complexType) {
retype.append(QStringLiteral("@"));
}
}
}
return retype.trimmed();
}
void WingAngelAPI::script_call(asIScriptGeneric *gen) { void WingAngelAPI::script_call(asIScriptGeneric *gen) {
auto fn = gen->GetFunction(); auto fn = gen->GetFunction();
@ -1782,7 +1769,7 @@ void WingAngelAPI::script_call(asIScriptGeneric *gen) {
} }
auto rettype = fns.ret; auto rettype = fns.ret;
auto r = PluginSystem::type2AngelScriptString(rettype, false, true); auto r = type2AngelScriptString(rettype, false, true);
if (r == QStringLiteral("int")) { if (r == QStringLiteral("int")) {
r = QStringLiteral("int32"); r = QStringLiteral("int32");
} else if (r == QStringLiteral("uint")) { } else if (r == QStringLiteral("uint")) {
@ -1831,7 +1818,7 @@ void WingAngelAPI::script_unsafe_call(asIScriptGeneric *gen) {
QList<void *> params; QList<void *> params;
auto total = gen->GetArgCount(); auto total = gen->GetArgCount();
WingHex::IWingPlugin::UNSAFE_RET ret; WingHex::UNSAFE_RET ret;
for (decltype(total) i = 0; i < total; ++i) { for (decltype(total) i = 0; i < total; ++i) {
auto raw = gen->GetAddressOfArg(i); auto raw = gen->GetAddressOfArg(i);
params.append(raw); params.append(raw);
@ -1999,11 +1986,11 @@ WingAngelAPI::retriveAsDictionary(const WingHex::SenderInfo &sender,
} }
void *WingAngelAPI::vector2AsArray(const WingHex::SenderInfo &sender, void *WingAngelAPI::vector2AsArray(const WingHex::SenderInfo &sender,
MetaType type, WingHex::MetaType type,
const QVector<void *> &content) { const QVector<void *> &content) {
Q_UNUSED(sender); Q_UNUSED(sender);
auto typeStr = PluginSystem::type2AngelScriptString( auto typeStr = type2AngelScriptString(
MetaType(type | MetaType::Array), false, true); WingHex::MetaType(type | WingHex::MetaType::Meta_Array), false, true);
if (typeStr.isEmpty()) { if (typeStr.isEmpty()) {
return nullptr; return nullptr;
} }
@ -2020,14 +2007,15 @@ void *WingAngelAPI::vector2AsArray(const WingHex::SenderInfo &sender,
} }
void *WingAngelAPI::list2AsArray(const WingHex::SenderInfo &sender, void *WingAngelAPI::list2AsArray(const WingHex::SenderInfo &sender,
MetaType type, const QList<void *> &content) { WingHex::MetaType type,
const QList<void *> &content) {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
static_assert(std::is_same_v<QList<int>, QVector<int>>); static_assert(std::is_same_v<QList<int>, QVector<int>>);
return vector2AsArray(sender, type, content); return vector2AsArray(sender, type, content);
#else #else
Q_UNUSED(sender); Q_UNUSED(sender);
auto typeStr = PluginSystem::type2AngelScriptString( auto typeStr = type2AngelScriptString(MetaType(type | MetaType::Meta_Array),
MetaType(type | MetaType::Array), false, true); false, true);
if (typeStr.isEmpty()) { if (typeStr.isEmpty()) {
return nullptr; return nullptr;
} }
@ -2056,7 +2044,7 @@ void WingAngelAPI::deleteAsArray(const WingHex::SenderInfo &sender,
void *WingAngelAPI::newAsDictionary( void *WingAngelAPI::newAsDictionary(
const WingHex::SenderInfo &sender, const WingHex::SenderInfo &sender,
const QHash<QString, QPair<MetaType, void *>> &content) { const QHash<QString, QPair<WingHex::MetaType, void *>> &content) {
Q_UNUSED(sender); Q_UNUSED(sender);
auto engine = ScriptMachine::instance().engine(); auto engine = ScriptMachine::instance().engine();
auto dic = CScriptDictionary::Create(engine); auto dic = CScriptDictionary::Create(engine);
@ -2064,8 +2052,7 @@ void *WingAngelAPI::newAsDictionary(
for (auto p = content.constKeyValueBegin(); p != content.constKeyValueEnd(); for (auto p = content.constKeyValueBegin(); p != content.constKeyValueEnd();
++p) { ++p) {
auto key = p->first; auto key = p->first;
auto typeStr = auto typeStr = type2AngelScriptString(p->second.first, false, true);
PluginSystem::type2AngelScriptString(p->second.first, false, true);
auto id = engine->GetTypeIdByDecl(typeStr.toUtf8()); auto id = engine->GetTypeIdByDecl(typeStr.toUtf8());
if (id < 0) { if (id < 0) {
continue; continue;

View File

@ -29,17 +29,28 @@ class asIScriptEngine;
class ScriptMachine; class ScriptMachine;
class ScriptingConsole; class ScriptingConsole;
namespace WingScriptInternal {
struct ScriptFnInfo {
uint ret; // MetaType
QVector<QPair<uint, QString>> params;
std::function<QVariant(const QVariantList &)> fn;
};
} // namespace WingScriptInternal
class WingAngelAPI : public WingHex::IWingPlugin { class WingAngelAPI : public WingHex::IWingPlugin {
Q_OBJECT Q_OBJECT
Q_INTERFACES(WingHex::IWingPlugin) Q_INTERFACES(WingHex::IWingPlugin)
friend class WingAngel;
public: public:
WingAngelAPI(); WingAngelAPI();
virtual ~WingAngelAPI(); virtual ~WingAngelAPI();
// IWingPlugin interface // IWingPlugin interface
public: public:
virtual int sdkVersion() const override;
virtual bool init(const std::unique_ptr<QSettings> &set) override; virtual bool init(const std::unique_ptr<QSettings> &set) override;
virtual void unload(std::unique_ptr<QSettings> &set) override; virtual void unload(std::unique_ptr<QSettings> &set) override;
virtual const QString pluginName() const override; virtual const QString pluginName() const override;
@ -49,25 +60,14 @@ public:
virtual QString retranslate(const QString &str) override; virtual QString retranslate(const QString &str) override;
virtual QStringList registerScriptMarcos() const override;
private: private:
virtual void onRegisterScriptObj(WingHex::IWingAngel *o) override;
virtual void eventPluginFile(PluginFileEvent e, FileType type, virtual void eventPluginFile(PluginFileEvent e, FileType type,
const QString &newfileName, int handle, const QString &newfileName, int handle,
const QString &oldfileName) override; const QString &oldfileName) override;
public: public:
void
registerScriptFns(const QString &ns,
const QHash<QString, IWingPlugin::ScriptFnInfo> &rfns);
void registerUnSafeScriptFns(
const QString &ns,
const QHash<QString, IWingPlugin::UNSAFE_SCFNPTR> &rfns);
void
registerScriptEnums(const QString &ns,
const QHash<QString, QList<QPair<QString, int>>> &objs);
void installAPI(ScriptMachine *machine); void installAPI(ScriptMachine *machine);
void installBasicTypes(asIScriptEngine *engine); void installBasicTypes(asIScriptEngine *engine);
@ -85,6 +85,10 @@ public:
*reinterpret_cast<T *>(&buffer) = v; *reinterpret_cast<T *>(&buffer) = v;
} }
public:
static QString type2AngelScriptString(uint type, bool isArg,
bool noModifier);
private: private:
void installLogAPI(asIScriptEngine *engine); void installLogAPI(asIScriptEngine *engine);
void installExtAPI(asIScriptEngine *engine); void installExtAPI(asIScriptEngine *engine);
@ -95,9 +99,6 @@ private:
void installHexBaseType(asIScriptEngine *engine); void installHexBaseType(asIScriptEngine *engine);
void installHexReaderAPI(asIScriptEngine *engine); void installHexReaderAPI(asIScriptEngine *engine);
void installHexControllerAPI(asIScriptEngine *engine); void installHexControllerAPI(asIScriptEngine *engine);
void installScriptFns(asIScriptEngine *engine);
void installScriptUnSafeFns(asIScriptEngine *engine);
void installScriptEnums(asIScriptEngine *engine);
private: private:
void registerAPI(asIScriptEngine *engine, const asSFuncPtr &fn, void registerAPI(asIScriptEngine *engine, const asSFuncPtr &fn,
@ -126,9 +127,8 @@ private:
static QVariant qvariantGet(asIScriptEngine *engine, const void *raw, static QVariant qvariantGet(asIScriptEngine *engine, const void *raw,
int typeID, bool flag); int typeID, bool flag);
static bool static bool getQVariantGetFlag(const WingScriptInternal::ScriptFnInfo &info,
getQVariantGetFlag(const WingHex::IWingPlugin::ScriptFnInfo &info, int index);
int index);
template <typename T> template <typename T>
static const T *getDereferencePointer(const void *value, bool isHandle) { static const T *getDereferencePointer(const void *value, bool isHandle) {
@ -170,17 +170,17 @@ private:
retriveAsDictionary(const WingHex::SenderInfo &sender, void *dic); retriveAsDictionary(const WingHex::SenderInfo &sender, void *dic);
WING_SERVICE void *vector2AsArray(const WingHex::SenderInfo &sender, WING_SERVICE void *vector2AsArray(const WingHex::SenderInfo &sender,
MetaType type, WingHex::MetaType type,
const QVector<void *> &content); const QVector<void *> &content);
WING_SERVICE void *list2AsArray(const WingHex::SenderInfo &sender, WING_SERVICE void *list2AsArray(const WingHex::SenderInfo &sender,
MetaType type, WingHex::MetaType type,
const QList<void *> &content); const QList<void *> &content);
WING_SERVICE void deleteAsArray(const WingHex::SenderInfo &sender, WING_SERVICE void deleteAsArray(const WingHex::SenderInfo &sender,
void *array); void *array);
WING_SERVICE void * WING_SERVICE void *newAsDictionary(
newAsDictionary(const WingHex::SenderInfo &sender, const WingHex::SenderInfo &sender,
const QHash<QString, QPair<MetaType, void *>> &content); const QHash<QString, QPair<WingHex::MetaType, void *>> &content);
WING_SERVICE void deleteAsDictionary(const WingHex::SenderInfo &sender, WING_SERVICE void deleteAsDictionary(const WingHex::SenderInfo &sender,
void *dic); void *dic);
@ -285,13 +285,8 @@ private:
QFileDialog::Options options); QFileDialog::Options options);
private: private:
QVector<IWingPlugin::ScriptFnInfo> _sfns; QVector<WingScriptInternal::ScriptFnInfo> _sfns;
QHash<QString, QHash<QString, qsizetype>> _rfns; QVector<WingHex::UNSAFE_SCFNPTR> _usfns;
QVector<IWingPlugin::UNSAFE_SCFNPTR> _usfns;
QHash<QString, QHash<QString, qsizetype>> _urfns;
QHash<QString, QHash<QString, QList<QPair<QString, int>>>> _objs;
QVector<int> _handles; QVector<int> _handles;
}; };

View File

@ -17,169 +17,15 @@
#include "wingcstruct.h" #include "wingcstruct.h"
#include "WingPlugin/iwingangel.h"
#include "scriptaddon/scriptqdictionary.h" #include "scriptaddon/scriptqdictionary.h"
#include "utilities.h" #include "utilities.h"
#include "wingangelapi.h" #include "wingangelapi.h"
WingCStruct::WingCStruct() : WingHex::IWingPlugin() { WingCStruct::WingCStruct() : WingHex::IWingPlugin() {}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::addStruct), this,
std::placeholders::_1);
info.ret = MetaType::Bool;
info.params.append(
qMakePair(MetaType::String, QStringLiteral("header")));
_scriptInfo.insert(QStringLiteral("addStruct"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(QOverload<const QVariantList &>::of(
&WingCStruct::addStructFromFile),
this, std::placeholders::_1);
info.ret = MetaType::Bool;
info.params.append(
qMakePair(MetaType::String, QStringLiteral("fileName")));
_scriptInfo.insert(QStringLiteral("addStructFromFile"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::resetEnv), this,
std::placeholders::_1);
info.ret = MetaType::Void;
_scriptInfo.insert(QStringLiteral("resetEnv"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::setStructPadding),
this, std::placeholders::_1);
info.ret = MetaType::Bool;
info.params.append(qMakePair(MetaType::Int, QStringLiteral("padding")));
_scriptInfo.insert(QStringLiteral("setStructPadding"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::structPadding),
this, std::placeholders::_1);
info.ret = MetaType::Int;
_scriptInfo.insert(QStringLiteral("structPadding"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::structPadding),
this, std::placeholders::_1);
info.ret = MetaType::Int;
_scriptInfo.insert(QStringLiteral("structPadding"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::structTypes),
this, std::placeholders::_1);
info.ret = MetaType::String | MetaType::Array;
_scriptInfo.insert(QStringLiteral("structTypes"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::sizeofStruct),
this, std::placeholders::_1);
info.ret = getqsizetypeMetaType();
info.params.append(qMakePair(MetaType::String, QStringLiteral("type")));
_scriptInfo.insert(QStringLiteral("sizeofStruct"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::existStruct),
this, std::placeholders::_1);
info.ret = MetaType::Bool;
info.params.append(qMakePair(MetaType::String, QStringLiteral("type")));
_scriptInfo.insert(QStringLiteral("existStruct"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::constDefines),
this, std::placeholders::_1);
info.ret = MetaType::String | MetaType::Array;
_scriptInfo.insert(QStringLiteral("constDefines"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::existDefineValue),
this, std::placeholders::_1);
info.ret = MetaType::Bool;
info.params.append(qMakePair(MetaType::String, QStringLiteral("type")));
_scriptInfo.insert(QStringLiteral("existDefineValue"), info);
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::defineValue),
this, std::placeholders::_1);
info.ret = MetaType::Int;
info.params.append(qMakePair(MetaType::String, QStringLiteral("type")));
_scriptInfo.insert(QStringLiteral("defineValue"), info);
}
// nested dictionary is not supported, so unsafe registering will help
{
_scriptUnsafe.insert(
QStringLiteral("dictionary@ read(") + getqsizeTypeAsString() +
(" offset, const string &in type)"),
std::bind(QOverload<const QList<void *> &>::of(&WingCStruct::read),
this, std::placeholders::_1));
}
{
WingHex::IWingPlugin::ScriptFnInfo info;
info.fn = std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::readRaw), this,
std::placeholders::_1);
info.ret = MetaType::Byte | MetaType::Array;
info.params.append(
qMakePair(getqsizetypeMetaType(), QStringLiteral("offset")));
info.params.append(qMakePair(MetaType::String, QStringLiteral("type")));
_scriptInfo.insert(QStringLiteral("readRaw"), info);
}
}
WingCStruct::~WingCStruct() {} WingCStruct::~WingCStruct() {}
int WingCStruct::sdkVersion() const { return WingHex::SDKVERSION; }
bool WingCStruct::init(const std::unique_ptr<QSettings> &set) { bool WingCStruct::init(const std::unique_ptr<QSettings> &set) {
Q_UNUSED(set); Q_UNUSED(set);
resetEnv(); resetEnv();
@ -205,22 +51,15 @@ QString WingCStruct::retranslate(const QString &str) {
WingCStruct::RegisteredEvents WingCStruct::registeredEvents() const { WingCStruct::RegisteredEvents WingCStruct::registeredEvents() const {
RegisteredEvents evs; RegisteredEvents evs;
evs.setFlag(RegisteredEvent::ScriptUnSafeFnRegistering);
evs.setFlag(RegisteredEvent::ScriptPragma); evs.setFlag(RegisteredEvent::ScriptPragma);
evs.setFlag(RegisteredEvent::ScriptPragmaInit); evs.setFlag(RegisteredEvent::ScriptPragmaInit);
return evs; return evs;
} }
QHash<WingHex::SettingPage *, bool> QList<WingHex::SettingPage *> WingCStruct::registeredSettingPages() const {
WingCStruct::registeredSettingPages() const {
return _setpgs; return _setpgs;
} }
QHash<QString, WingCStruct::ScriptFnInfo>
WingCStruct::registeredScriptFns() const {
return _scriptInfo;
}
bool WingCStruct::eventOnScriptPragma(const QString &script, bool WingCStruct::eventOnScriptPragma(const QString &script,
const QStringList &comments) { const QStringList &comments) {
// #pragma WingCStruct Arch [32 | 64] // #pragma WingCStruct Arch [32 | 64]
@ -291,9 +130,99 @@ bool WingCStruct::eventOnScriptPragma(const QString &script,
void WingCStruct::eventOnScriptPragmaInit() { resetEnv(); } void WingCStruct::eventOnScriptPragmaInit() { resetEnv(); }
QHash<QString, WingHex::IWingPlugin::UNSAFE_SCFNPTR> void WingCStruct::onRegisterScriptObj(WingHex::IWingAngel *o) {
WingCStruct::registeredScriptUnsafeFns() const { o->registerGlobalFunction(
return _scriptUnsafe; WingHex::Meta_Bool,
std::bind(QOverload<const QVariantList &>::of(&WingCStruct::addStruct),
this, std::placeholders::_1),
QStringLiteral("addStruct"),
{qMakePair(WingHex::Meta_String, QStringLiteral("header"))});
o->registerGlobalFunction(
WingHex::Meta_Bool,
std::bind(QOverload<const QVariantList &>::of(
&WingCStruct::addStructFromFile),
this, std::placeholders::_1),
QStringLiteral("addStructFromFile"),
{qMakePair(WingHex::Meta_String, QStringLiteral("fileName"))});
o->registerGlobalFunction(
WingHex::Meta_Void,
std::bind(QOverload<const QVariantList &>::of(&WingCStruct::resetEnv),
this, std::placeholders::_1),
QStringLiteral("resetEnv"));
o->registerGlobalFunction(
WingHex::Meta_Bool,
std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::setStructPadding),
this, std::placeholders::_1),
QStringLiteral("setStructPadding"),
{qMakePair(WingHex::Meta_Int, QStringLiteral("padding"))});
o->registerGlobalFunction(WingHex::Meta_Int,
std::bind(QOverload<const QVariantList &>::of(
&WingCStruct::structPadding),
this, std::placeholders::_1),
QStringLiteral("structPadding"));
o->registerGlobalFunction(WingHex::Meta_String | WingHex::Meta_Array,
std::bind(QOverload<const QVariantList &>::of(
&WingCStruct::structTypes),
this, std::placeholders::_1),
QStringLiteral("structTypes"));
o->registerGlobalFunction(
getqsizetypeMetaType(),
std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::sizeofStruct),
this, std::placeholders::_1),
QStringLiteral("sizeofStruct"),
{qMakePair(WingHex::Meta_String, QStringLiteral("type"))});
o->registerGlobalFunction(
WingHex::Meta_Bool,
std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::existStruct),
this, std::placeholders::_1),
QStringLiteral("existStruct"),
{qMakePair(WingHex::Meta_String, QStringLiteral("type"))});
o->registerGlobalFunction(WingHex::Meta_String | WingHex::Meta_Array,
std::bind(QOverload<const QVariantList &>::of(
&WingCStruct::constDefines),
this, std::placeholders::_1),
QStringLiteral("constDefines"));
o->registerGlobalFunction(
WingHex::Meta_Bool,
std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::existDefineValue),
this, std::placeholders::_1),
QStringLiteral("existDefineValue"),
{qMakePair(WingHex::Meta_String, QStringLiteral("type"))});
o->registerGlobalFunction(
WingHex::Meta_Int,
std::bind(
QOverload<const QVariantList &>::of(&WingCStruct::defineValue),
this, std::placeholders::_1),
QStringLiteral("defineValue"),
{qMakePair(WingHex::Meta_String, QStringLiteral("type"))});
// nested dictionary is not supported, so unsafe registering will help
o->registerGlobalFunction(
QStringLiteral("dictionary@ read(") + getqsizeTypeAsString() +
(" offset, const string &in type)"),
std::bind(QOverload<const QList<void *> &>::of(&WingCStruct::read),
this, std::placeholders::_1));
o->registerGlobalFunction(
WingHex::Meta_Byte | WingHex::Meta_Array,
std::bind(QOverload<const QVariantList &>::of(&WingCStruct::readRaw),
this, std::placeholders::_1),
QStringLiteral("readRaw"),
{qMakePair(WingHex::Meta_String, QStringLiteral("type"))});
} }
bool WingCStruct::addStruct(const QString &header) { bool WingCStruct::addStruct(const QString &header) {
@ -716,9 +645,9 @@ CScriptArray *WingCStruct::convert2AsArray(const QVariantList &array,
return arr; return arr;
} }
WingHex::IWingPlugin::MetaType WingCStruct::getqsizetypeMetaType() const { WingHex::MetaType WingCStruct::getqsizetypeMetaType() const {
return sizeof(qsizetype) == sizeof(quint64) ? MetaType::Int64 return sizeof(qsizetype) == sizeof(quint64) ? WingHex::MetaType::Meta_Int64
: MetaType::Int32; : WingHex::MetaType::Meta_Int32;
} }
QVariant WingCStruct::addStruct(const QVariantList &params) { QVariant WingCStruct::addStruct(const QVariantList &params) {
@ -837,8 +766,7 @@ QVariant WingCStruct::defineValue(const QVariantList &params) {
return defineValue(type); return defineValue(type);
} }
WingHex::IWingPlugin::UNSAFE_RET WingHex::UNSAFE_RET WingCStruct::read(const QList<void *> &params) {
WingCStruct::read(const QList<void *> &params) {
if (params.size() != 2) { if (params.size() != 2) {
return generateScriptCallError(-1, tr("InvalidParamsCount")); return generateScriptCallError(-1, tr("InvalidParamsCount"));
} }

View File

@ -35,7 +35,6 @@ public:
// IWingPluginBase interface // IWingPluginBase interface
public: public:
virtual int sdkVersion() const override;
virtual bool init(const std::unique_ptr<QSettings> &set) override; virtual bool init(const std::unique_ptr<QSettings> &set) override;
virtual void unload(std::unique_ptr<QSettings> &set) override; virtual void unload(std::unique_ptr<QSettings> &set) override;
virtual const QString pluginName() const override; virtual const QString pluginName() const override;
@ -47,14 +46,15 @@ public:
// IWingPlugin interface // IWingPlugin interface
public: public:
virtual RegisteredEvents registeredEvents() const override; virtual RegisteredEvents registeredEvents() const override;
virtual QHash<WingHex::SettingPage *, bool> virtual QList<WingHex::SettingPage *>
registeredSettingPages() const override; registeredSettingPages() const override;
virtual QHash<QString, ScriptFnInfo> registeredScriptFns() const override;
virtual bool eventOnScriptPragma(const QString &script, virtual bool eventOnScriptPragma(const QString &script,
const QStringList &comments) override; const QStringList &comments) override;
virtual void eventOnScriptPragmaInit() override; virtual void eventOnScriptPragmaInit() override;
virtual QHash<QString, UNSAFE_SCFNPTR>
registeredScriptUnsafeFns() const override; // IWingPluginCoreBase interface
public:
virtual void onRegisterScriptObj(WingHex::IWingAngel *o) override;
private: private:
// basic // basic
@ -79,7 +79,7 @@ private:
WING_SERVICE QByteArray readRaw(qsizetype offset, const QString &type); WING_SERVICE QByteArray readRaw(qsizetype offset, const QString &type);
private: private:
MetaType getqsizetypeMetaType() const; WingHex::MetaType getqsizetypeMetaType() const;
QString getqsizeTypeAsString() const; QString getqsizeTypeAsString() const;
@ -112,15 +112,13 @@ private:
QVariant existDefineValue(const QVariantList &params); QVariant existDefineValue(const QVariantList &params);
QVariant defineValue(const QVariantList &params); QVariant defineValue(const QVariantList &params);
UNSAFE_RET read(const QList<void *> &params); WingHex::UNSAFE_RET read(const QList<void *> &params);
QVariant readRaw(const QVariantList &params); QVariant readRaw(const QVariantList &params);
private: private:
CTypeParser _parser; CTypeParser _parser;
QHash<WingHex::SettingPage *, bool> _setpgs; QList<WingHex::SettingPage *> _setpgs;
QHash<QString, WingCStruct::ScriptFnInfo> _scriptInfo;
QHash<QString, WingHex::IWingPlugin::UNSAFE_SCFNPTR> _scriptUnsafe;
}; };
#endif // WINGCSTRUCT_H #endif // WINGCSTRUCT_H

100
src/class/winggeneric.cpp Normal file
View File

@ -0,0 +1,100 @@
/*==============================================================================
** 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 "winggeneric.h"
#include "angelscript.h"
WingGeneric::WingGeneric(asIScriptGeneric *gen) : _gen(gen) {}
int WingGeneric::argCount() const { return _gen->GetArgCount(); }
int WingGeneric::argTypeId(uint arg, quint32 *flags) const {
static_assert(sizeof(quint32) == sizeof(asDWORD),
"asDWORD is same with quint32");
return _gen->GetArgTypeId(arg, reinterpret_cast<asDWORD *>(flags));
}
QString WingGeneric::argTypeName(uint arg, quint32 *flags) {
auto e = _gen->GetEngine();
auto str = e->GetTypeDeclaration(argTypeId(arg, flags));
if (str) {
return str;
} else {
return {};
}
}
uchar WingGeneric::argByte(uint arg) { return _gen->GetArgByte(arg); }
quint16 WingGeneric::argWord(uint arg) { return _gen->GetArgWord(arg); }
quint32 WingGeneric::argDWord(uint arg) { return _gen->GetArgDWord(arg); }
quint64 WingGeneric::argQWord(uint arg) { return _gen->GetArgQWord(arg); }
float WingGeneric::argFloat(uint arg) { return _gen->GetArgFloat(arg); }
double WingGeneric::argDouble(uint arg) { return _gen->GetArgDouble(arg); }
void *WingGeneric::argAddress(uint arg) { return _gen->GetArgAddress(arg); }
void *WingGeneric::argObject(uint arg) { return _gen->GetArgObject(arg); }
void *WingGeneric::addressOfArg(uint arg) { return _gen->GetAddressOfArg(arg); }
int WingGeneric::returnTypeId(quint32 *flags) const {
static_assert(sizeof(quint32) == sizeof(asDWORD),
"asDWORD is same with quint32");
return _gen->GetReturnTypeId(reinterpret_cast<asDWORD *>(flags));
}
WingHex::asRetCodes WingGeneric::setReturnByte(uchar val) {
return WingHex::asRetCodes(_gen->SetReturnByte(val));
}
WingHex::asRetCodes WingGeneric::setReturnWord(quint16 val) {
return WingHex::asRetCodes(_gen->SetReturnWord(val));
}
WingHex::asRetCodes WingGeneric::setReturnDWord(quint32 val) {
return WingHex::asRetCodes(_gen->SetReturnDWord(val));
}
WingHex::asRetCodes WingGeneric::setReturnQWord(quint64 val) {
return WingHex::asRetCodes(_gen->SetReturnQWord(val));
}
WingHex::asRetCodes WingGeneric::setReturnFloat(float val) {
return WingHex::asRetCodes(_gen->SetReturnFloat(val));
}
WingHex::asRetCodes WingGeneric::setReturnDouble(double val) {
return WingHex::asRetCodes(_gen->SetReturnDouble(val));
}
WingHex::asRetCodes WingGeneric::setReturnAddress(void *addr) {
return WingHex::asRetCodes(_gen->SetReturnAddress(addr));
}
WingHex::asRetCodes WingGeneric::setReturnObject(void *obj) {
return WingHex::asRetCodes(_gen->SetReturnObject(obj));
}
void *WingGeneric::addressOfReturnLocation() {
return _gen->GetAddressOfReturnLocation();
}

58
src/class/winggeneric.h Normal file
View File

@ -0,0 +1,58 @@
/*==============================================================================
** 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/>.
** =============================================================================
*/
#ifndef WINGGENERIC_H
#define WINGGENERIC_H
#include "WingPlugin/iwingangel.h"
class asIScriptGeneric;
class WingGeneric : public WingHex::IWingGeneric {
public:
explicit WingGeneric(asIScriptGeneric *gen);
// IWingGeneric interface
public:
int argCount() const override;
int argTypeId(uint arg, quint32 *flags) const override;
QString argTypeName(uint arg, quint32 *flags) override;
uchar argByte(uint arg) override;
quint16 argWord(uint arg) override;
quint32 argDWord(uint arg) override;
quint64 argQWord(uint arg) override;
float argFloat(uint arg) override;
double argDouble(uint arg) override;
void *argAddress(uint arg) override;
void *argObject(uint arg) override;
void *addressOfArg(uint arg) override;
int returnTypeId(quint32 *flags) const override;
WingHex::asRetCodes setReturnByte(uchar val) override;
WingHex::asRetCodes setReturnWord(quint16 val) override;
WingHex::asRetCodes setReturnDWord(quint32 val) override;
WingHex::asRetCodes setReturnQWord(quint64 val) override;
WingHex::asRetCodes setReturnFloat(float val) override;
WingHex::asRetCodes setReturnDouble(double val) override;
WingHex::asRetCodes setReturnAddress(void *addr) override;
WingHex::asRetCodes setReturnObject(void *obj) override;
void *addressOfReturnLocation() override;
private:
asIScriptGeneric *_gen;
};
#endif // WINGGENERIC_H

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 (m_docType == DocumentType::Extension) {
if (_dev->isOpen()) { if (_dev->isOpen()) {
_dev->close(); _dev->close();

View File

@ -238,7 +238,7 @@ private slots:
WING_API bool existsServiceHost(QObject *caller, const QString &puid); WING_API bool existsServiceHost(QObject *caller, const QString &puid);
WING_API bool invokeServiceImpl(const QObject *sender, const QString &puid, WING_API bool invokeServiceImpl(const QObject *sender, const QString &puid,
const MetaCallInfo &infos); const WingHex::MetaCallInfo &infos);
private slots: private slots:
WING_API QString currentDocFilename(QObject *caller); WING_API QString currentDocFilename(QObject *caller);
@ -544,6 +544,7 @@ private:
GotoWidget *m_goto = nullptr; GotoWidget *m_goto = nullptr;
QWidget *m_hexContainer = nullptr; QWidget *m_hexContainer = nullptr;
bool _hasRegistered = false; bool _hasRegistered = false;
quintptr _oldbase = 0;
QHexView *m_hex = nullptr; QHexView *m_hex = nullptr;
QMenu *m_menu = nullptr; QMenu *m_menu = nullptr;

View File

@ -198,7 +198,6 @@ MainWindow::MainWindow(SplashDialog *splash) : FramelessMainWindow() {
m_toolBtneditors.value(ToolButtonIndex::EDITOR_VIEWS)->setEnabled(false); m_toolBtneditors.value(ToolButtonIndex::EDITOR_VIEWS)->setEnabled(false);
// ok, preparing for starting... // ok, preparing for starting...
this->setWindowTitle(tr("WingHexExplorer"));
this->setWindowIcon(Utilities::isRoot() this->setWindowIcon(Utilities::isRoot()
? ICONRES(QStringLiteral("iconroot")) ? ICONRES(QStringLiteral("iconroot"))
: ICONRES(QStringLiteral("icon"))); : ICONRES(QStringLiteral("icon")));
@ -234,26 +233,62 @@ MainWindow::MainWindow(SplashDialog *splash) : FramelessMainWindow() {
auto &sm = ScriptMachine::instance(); auto &sm = ScriptMachine::instance();
auto smr = sm.init(); auto smr = sm.init();
if (smr) { if (smr) {
ScriptMachine::RegCallBacks callbacks; plg.doneRegisterScriptObj();
callbacks.getInputFn = [this]() -> QString { auto cfgerr = sm.isEngineConfigError();
return m_scriptConsole->getInput();
};
callbacks.clearFn = [this]() { m_scriptConsole->clearConsole(); };
callbacks.printMsgFn =
[this](const ScriptMachine::MessageInfo &message) {
m_scriptConsole->onOutput(message);
};
sm.registerCallBack(ScriptMachine::Interactive, callbacks);
callbacks.getInputFn = [this]() -> QString { // At this time, AngelScript service plugin has started
return WingInputDialog::getText(this, tr("InputRequest"), if (cfgerr) {
tr("PleaseInput")); m_scriptConsole->initOutput();
}; m_scriptConsole->setMode(QConsoleWidget::Output);
callbacks.clearFn = [this]() { m_bgScriptOutput->clear(); }; m_scriptConsole->stdErr(tr("EngineConfigError"));
callbacks.printMsgFn =
std::bind(&MainWindow::onOutputBgScriptOutput, this, m_scriptConsole->setEnabled(false);
std::placeholders::_1);
sm.registerCallBack(ScriptMachine::Background, callbacks); // configure error, so disable all script feature
WingHex::WingRibbonToolBoxInfo::RibbonCatagories catagories;
m_ribbonMaps[catagories.SCRIPT]->setEnabled(false);
} else {
ScriptMachine::RegCallBacks callbacks;
callbacks.getInputFn = [this]() -> QString {
return m_scriptConsole->getInput();
};
callbacks.clearFn = [this]() {
m_scriptConsole->clearConsole();
};
callbacks.printMsgFn =
[this](const ScriptMachine::MessageInfo &message) {
m_scriptConsole->onOutput(message);
};
sm.registerCallBack(ScriptMachine::Interactive, callbacks);
callbacks.getInputFn = [this]() -> QString {
return WingInputDialog::getText(this, tr("InputRequest"),
tr("PleaseInput"));
};
callbacks.clearFn = [this]() { m_bgScriptOutput->clear(); };
callbacks.printMsgFn =
std::bind(&MainWindow::onOutputBgScriptOutput, this,
std::placeholders::_1);
sm.registerCallBack(ScriptMachine::Background, callbacks);
if (splash)
splash->setInfoText(tr("SetupConsole"));
m_scriptConsole->init();
if (splash)
splash->setInfoText(tr("SetupScriptManager"));
if (splash)
splash->setInfoText(tr("SetupScriptService"));
m_scriptConsole->initOutput();
m_scriptConsole->setMode(QConsoleWidget::Input);
if (splash)
splash->setInfoText(tr("SetupScriptEditor"));
m_scriptDialog = new ScriptingDialog(this);
m_scriptDialog->initConsole();
}
} else { } else {
QMessageBox::critical(this, qAppName(), QMessageBox::critical(this, qAppName(),
tr("ScriptEngineInitFailed")); tr("ScriptEngineInitFailed"));
@ -261,25 +296,6 @@ MainWindow::MainWindow(SplashDialog *splash) : FramelessMainWindow() {
set.save(SettingManager::SCRIPT); set.save(SettingManager::SCRIPT);
throw CrashCode::ScriptInitFailed; throw CrashCode::ScriptInitFailed;
} }
// At this time, AngelScript service plugin has started
if (splash)
splash->setInfoText(tr("SetupConsole"));
m_scriptConsole->init();
if (splash)
splash->setInfoText(tr("SetupScriptManager"));
if (splash)
splash->setInfoText(tr("SetupScriptService"));
m_scriptConsole->initOutput();
m_scriptConsole->setMode(QConsoleWidget::Input);
if (splash)
splash->setInfoText(tr("SetupScriptEditor"));
m_scriptDialog = new ScriptingDialog(this);
m_scriptDialog->initConsole();
} }
// connect settings signals // connect settings signals
@ -450,6 +466,7 @@ void MainWindow::buildUpDockSystem(QWidget *container) {
m_metadatas->setModel(_metadataEmpty); m_metadatas->setModel(_metadataEmpty);
m_aDelBookMark->setEnabled(false); m_aDelBookMark->setEnabled(false);
m_aDelMetaData->setEnabled(false); m_aDelMetaData->setEnabled(false);
_undoView->setStack(nullptr);
} }
updateEditModeEnabled(); updateEditModeEnabled();
}); });
@ -553,6 +570,8 @@ void MainWindow::buildUpDockSystem(QWidget *container) {
qApp->processEvents(); qApp->processEvents();
buildUpDecodingStrShowDock(m_dock, ads::CenterDockWidgetArea, rightArea); buildUpDecodingStrShowDock(m_dock, ads::CenterDockWidgetArea, rightArea);
qApp->processEvents(); qApp->processEvents();
buildUpUndoStackDock(m_dock, ads::CenterDockWidgetArea, rightArea);
qApp->processEvents();
ads::CDockAreaWidget *bottomRightArea; ads::CDockAreaWidget *bottomRightArea;
if (SettingManager::instance().scriptEnabled()) { if (SettingManager::instance().scriptEnabled()) {
@ -1096,6 +1115,16 @@ MainWindow::buildUpScriptBgOutputDock(ads::CDockManager *dock,
return dock->addDockWidget(area, dw, areaw); 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) { RibbonTabContent *MainWindow::buildFilePage(RibbonTabContent *tab) {
auto shortcuts = QKeySequences::instance(); auto shortcuts = QKeySequences::instance();
{ {
@ -1637,7 +1666,6 @@ void MainWindow::buildUpSettingDialog() {
auto plgPage = new PluginSettingDialog(m_setdialog); auto plgPage = new PluginSettingDialog(m_setdialog);
connect(plgPage, &SettingPage::optionNeedRestartChanged, m_setdialog, connect(plgPage, &SettingPage::optionNeedRestartChanged, m_setdialog,
&SettingDialog::toastTakeEffectReboot); &SettingDialog::toastTakeEffectReboot);
plgPage->buildUp(m_plgPages);
m_setdialog->addPage(plgPage); m_setdialog->addPage(plgPage);
id = plgPage->id(); id = plgPage->id();
Q_ASSERT(!id.isEmpty()); Q_ASSERT(!id.isEmpty());
@ -1662,9 +1690,7 @@ void MainWindow::buildUpSettingDialog() {
usedIDs.append(id); usedIDs.append(id);
qApp->processEvents(); qApp->processEvents();
for (auto page_p = m_settingPages.constKeyValueBegin(); for (auto &page : m_settingPages) {
page_p != m_settingPages.constKeyValueEnd(); ++page_p) {
auto page = page_p->first;
auto name = page->name(); auto name = page->name();
auto id = page->id(); auto id = page->id();
@ -1690,7 +1716,7 @@ void MainWindow::buildUpSettingDialog() {
connect(page, &SettingPage::optionNeedRestartChanged, m_setdialog, connect(page, &SettingPage::optionNeedRestartChanged, m_setdialog,
&SettingDialog::toastTakeEffectReboot); &SettingDialog::toastTakeEffectReboot);
m_setdialog->addPage(page); m_setdialog->addPage(page);
if (page_p->second) { if (page->showInRibbon()) {
auto icon = page->categoryIcon(); auto icon = page->categoryIcon();
addPannelAction(m_pluginSettingsGroup, icon, name, addPannelAction(m_pluginSettingsGroup, icon, name,
[=] { m_setdialog->showConfig(id); }); [=] { m_setdialog->showConfig(id); });
@ -3204,7 +3230,7 @@ void MainWindow::connectEditorView(EditorView *editor) {
auto total = hexeditor->selectionCount(); auto total = hexeditor->selectionCount();
if (m.exec()) { if (m.exec()) {
auto meta = doc->metadata(); auto meta = doc->metadata();
meta->beginMarco(QStringLiteral("OnMetaData")); meta->beginMarco(tr("[MetaAdd]"));
for (int i = 0; i < total; ++i) { for (int i = 0; i < total; ++i) {
auto begin = cur->selectionStart(i).offset(); auto begin = cur->selectionStart(i).offset();
auto end = cur->selectionEnd(i).offset(); auto end = cur->selectionEnd(i).offset();
@ -3331,6 +3357,15 @@ void MainWindow::swapEditor(EditorView *old, EditorView *cur) {
connect(hexeditor, &QHexView::documentSaved, this, [this](bool b) { connect(hexeditor, &QHexView::documentSaved, this, [this](bool b) {
m_iSaved->setIcon(b ? _infoSaved : _infoUnsaved); m_iSaved->setIcon(b ? _infoSaved : _infoUnsaved);
m_sSaved->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) { connect(hexeditor, &QHexView::documentKeepSize, this, [this](bool b) {
m_iCanOver->setIcon(b ? _infoCannotOver : _infoCanOver); m_iCanOver->setIcon(b ? _infoCannotOver : _infoCanOver);
@ -3395,6 +3430,8 @@ void MainWindow::swapEditor(EditorView *old, EditorView *cur) {
m_metadatas->selectionModel()->hasSelection()); m_metadatas->selectionModel()->hasSelection());
}); });
_undoView->setStack(doc->undoStack());
m_curEditor = cur; m_curEditor = cur;
hexeditor->getStatus(); hexeditor->getStatus();
@ -3403,6 +3440,17 @@ void MainWindow::swapEditor(EditorView *old, EditorView *cur) {
{cur->fileName(), (old ? old->fileName() : QString())}); {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) { void MainWindow::loadFindResult(EditorView *view) {
auto result = view->findResultModel(); auto result = view->findResultModel();
m_findresult->setModel(result); m_findresult->setModel(result);
@ -3658,11 +3706,15 @@ void MainWindow::updateEditModeEnabled() {
doc->canRedo()); doc->canRedo());
m_toolBtneditors[ToolButtonIndex::UNDO_ACTION]->setEnabled( m_toolBtneditors[ToolButtonIndex::UNDO_ACTION]->setEnabled(
doc->canUndo()); doc->canUndo());
setWindowFilePath(editor->fileName());
} else { } else {
m_lblloc->setText(QStringLiteral("(0,0)")); m_lblloc->setText(QStringLiteral("(0,0)"));
m_lblsellen->setText(QStringLiteral("0 - 0x0")); m_lblsellen->setText(QStringLiteral("0 - 0x0"));
_numsitem->clear(); _numsitem->clear();
setWindowFilePath({});
} }
updateWindowTitle();
} }
void MainWindow::setCurrentHexEditorScale(qreal rate) { void MainWindow::setCurrentHexEditorScale(qreal rate) {

View File

@ -34,6 +34,7 @@
#include <QTextBrowser> #include <QTextBrowser>
#include <QToolButton> #include <QToolButton>
#include <QTreeView> #include <QTreeView>
#include <QUndoView>
#include <QtConcurrent/QtConcurrentRun> #include <QtConcurrent/QtConcurrentRun>
#include <QtEndian> #include <QtEndian>
@ -44,7 +45,6 @@
#include "Qt-Advanced-Docking-System/src/DockWidget.h" #include "Qt-Advanced-Docking-System/src/DockWidget.h"
#include "WingPlugin/iwingplugin.h" #include "WingPlugin/iwingplugin.h"
#include "class/recentfilemanager.h" #include "class/recentfilemanager.h"
#include "class/scriptmanager.h"
#include "control/editorview.h" #include "control/editorview.h"
#include "control/qtableviewext.h" #include "control/qtableviewext.h"
#include "control/scriptingconsole.h" #include "control/scriptingconsole.h"
@ -122,6 +122,10 @@ private:
buildUpScriptBgOutputDock(ads::CDockManager *dock, ads::DockWidgetArea area, buildUpScriptBgOutputDock(ads::CDockManager *dock, ads::DockWidgetArea area,
ads::CDockAreaWidget *areaw = nullptr); ads::CDockAreaWidget *areaw = nullptr);
ads::CDockAreaWidget *
buildUpUndoStackDock(ads::CDockManager *dock, ads::DockWidgetArea area,
ads::CDockAreaWidget *areaw = nullptr);
RibbonTabContent *buildFilePage(RibbonTabContent *tab); RibbonTabContent *buildFilePage(RibbonTabContent *tab);
RibbonTabContent *buildEditPage(RibbonTabContent *tab); RibbonTabContent *buildEditPage(RibbonTabContent *tab);
RibbonTabContent *buildViewPage(RibbonTabContent *tab); RibbonTabContent *buildViewPage(RibbonTabContent *tab);
@ -243,6 +247,7 @@ private:
void connectEditorView(EditorView *editor); void connectEditorView(EditorView *editor);
void swapEditor(EditorView *old, EditorView *cur); void swapEditor(EditorView *old, EditorView *cur);
void updateWindowTitle();
void loadFindResult(EditorView *view); void loadFindResult(EditorView *view);
@ -496,6 +501,8 @@ private:
QTableViewExt *m_metadatas = nullptr; QTableViewExt *m_metadatas = nullptr;
MetaDataModel *_metadataEmpty = nullptr; MetaDataModel *_metadataEmpty = nullptr;
QUndoView *_undoView = nullptr;
QMap<ToolButtonIndex, QToolButton *> m_toolBtneditors; QMap<ToolButtonIndex, QToolButton *> m_toolBtneditors;
QAction *m_aDelBookMark = nullptr; QAction *m_aDelBookMark = nullptr;
@ -564,8 +571,7 @@ private:
QList<QMenu *> m_hexContextMenu; QList<QMenu *> m_hexContextMenu;
QHash<IWingPlugin *, QList<QSharedPointer<WingEditorViewWidget::Creator>>> QHash<IWingPlugin *, QList<QSharedPointer<WingEditorViewWidget::Creator>>>
m_editorViewWidgets; m_editorViewWidgets;
QHash<SettingPage *, bool> m_settingPages; QList<SettingPage *> m_settingPages;
QList<PluginPage *> m_plgPages;
// these variables will be invalid after restoring state // these variables will be invalid after restoring state
ads::CDockAreaWidget *m_leftViewArea = nullptr; ads::CDockAreaWidget *m_leftViewArea = nullptr;

View File

@ -86,7 +86,7 @@ ScriptingDialog::ScriptingDialog(QWidget *parent)
m_Tbtneditors.value(ToolButtonIndex::EDITOR_VIEWS)->setEnabled(false); m_Tbtneditors.value(ToolButtonIndex::EDITOR_VIEWS)->setEnabled(false);
// ok, preparing for starting... // ok, preparing for starting...
this->setWindowTitle(tr("ScriptEditor")); updateWindowTitle();
this->setWindowIcon(ICONRES(QStringLiteral("script"))); this->setWindowIcon(ICONRES(QStringLiteral("script")));
this->setMinimumSize(800, 600); this->setMinimumSize(800, 600);
@ -833,6 +833,16 @@ void ScriptingDialog::updateEditModeEnabled() {
item->setEnabled(b); 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(); 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) { void ScriptingDialog::updateRunDebugMode(bool disable) {
auto &runner = ScriptMachine::instance(); auto &runner = ScriptMachine::instance();
auto enable = !disable; auto enable = !disable;
@ -1239,6 +1260,8 @@ void ScriptingDialog::on_save() {
auto res = editor->save(); auto res = editor->save();
if (res) { if (res) {
setWindowFilePath(editor->fileName());
updateWindowTitle();
Toast::toast(this, NAMEICONRES(QStringLiteral("save")), Toast::toast(this, NAMEICONRES(QStringLiteral("save")),
tr("SaveSuccessfully")); tr("SaveSuccessfully"));
} else { } else {
@ -1267,6 +1290,8 @@ void ScriptingDialog::on_saveas() {
auto res = editor->save(filename); auto res = editor->save(filename);
if (res) { if (res) {
setWindowFilePath(editor->fileName());
updateWindowTitle();
Toast::toast(this, NAMEICONRES(QStringLiteral("saveas")), Toast::toast(this, NAMEICONRES(QStringLiteral("saveas")),
tr("SaveSuccessfully")); tr("SaveSuccessfully"));
} else { } else {

View File

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

View File

@ -18,7 +18,6 @@
#include "pluginsettingdialog.h" #include "pluginsettingdialog.h"
#include "class/pluginsystem.h" #include "class/pluginsystem.h"
#include "class/settingmanager.h" #include "class/settingmanager.h"
#include "dbghelper.h"
#include "ui_pluginsettingdialog.h" #include "ui_pluginsettingdialog.h"
#include "utilities.h" #include "utilities.h"
@ -48,6 +47,7 @@ PluginSettingDialog::PluginSettingDialog(QWidget *parent)
auto &plgsys = PluginSystem::instance(); auto &plgsys = PluginSystem::instance();
auto pico = ICONRES("plugin"); auto pico = ICONRES("plugin");
ui->plglist->clear(); ui->plglist->clear();
for (auto &p : plgsys.plugins()) { for (auto &p : plgsys.plugins()) {
auto pco = p->pluginIcon(); auto pco = p->pluginIcon();
ui->plglist->addItem( ui->plglist->addItem(
@ -63,17 +63,32 @@ PluginSettingDialog::PluginSettingDialog(QWidget *parent)
new QListWidgetItem(pco.isNull() ? pico : pco, d->pluginName())); new QListWidgetItem(pco.isNull() ? pico : pco, d->pluginName()));
} }
ui->txtd->clear(); ui->txtd->clear();
auto minfo = plgsys.monitorManagerInfo();
if (minfo) {
auto sep = QStringLiteral(" : ");
ui->txtm->append(getWrappedText(tr("ID") + sep + minfo->id));
ui->txtm->append(getWrappedText(tr("License") + sep + minfo->license));
ui->txtm->append(getWrappedText(tr("Author") + sep + minfo->author));
ui->txtm->append(getWrappedText(tr("Vendor") + sep + minfo->vendor));
ui->txtm->append(
getWrappedText(tr("Version") + sep + minfo->version.toString()));
ui->txtm->append(getWrappedText(
tr("URL") + sep + QStringLiteral("<a href=\"") + minfo->url +
QStringLiteral("\">") + minfo->url + QStringLiteral("</a>")));
ui->txtm->append(getWrappedText(tr("Comment") + sep));
auto p = plgsys.monitorManager();
if (p) {
ui->txtm->append(getWrappedText(p->comment()));
}
} else {
ui->txtm->setText(tr("NoMonitorPlugin"));
}
} }
PluginSettingDialog::~PluginSettingDialog() { delete ui; } PluginSettingDialog::~PluginSettingDialog() { delete ui; }
void PluginSettingDialog::buildUp(const QList<PluginPage *> &pages) {
ASSERT_SINGLETON;
for (auto &page : pages) {
ui->tabWidget->addTab(page, page->categoryIcon(), page->name());
}
}
void PluginSettingDialog::reload() { void PluginSettingDialog::reload() {
this->blockSignals(true); this->blockSignals(true);
auto &set = SettingManager::instance(); auto &set = SettingManager::instance();
@ -112,17 +127,18 @@ void PluginSettingDialog::on_devlist_currentRowChanged(int currentRow) {
auto info = plgsys.getPluginInfo(plg); auto info = plgsys.getPluginInfo(plg);
ui->txtd->clear(); ui->txtd->clear();
ui->txtd->append(getWrappedText(tr("ID") + " : " + info.id)); static auto sep = QStringLiteral(" : ");
ui->txtd->append(getWrappedText(tr("Name") + " : " + plg->pluginName())); ui->txtd->append(getWrappedText(tr("ID") + sep + info.id));
ui->txtd->append(getWrappedText(tr("License") + " : " + info.license)); ui->txtd->append(getWrappedText(tr("Name") + sep + plg->pluginName()));
ui->txtd->append(getWrappedText(tr("Author") + " : " + info.author)); ui->txtd->append(getWrappedText(tr("License") + sep + info.license));
ui->txtd->append(getWrappedText(tr("Vendor") + " : " + info.vendor)); ui->txtd->append(getWrappedText(tr("Author") + sep + info.author));
ui->txtd->append(getWrappedText(tr("Vendor") + sep + info.vendor));
ui->txtd->append( ui->txtd->append(
getWrappedText(tr("Version") + " : " + info.version.toString())); getWrappedText(tr("Version") + sep + info.version.toString()));
ui->txtd->append( ui->txtd->append(
getWrappedText(tr("Comment") + " : " + plg->pluginComment())); getWrappedText(tr("Comment") + sep + plg->pluginComment()));
ui->txtd->append(getWrappedText( ui->txtd->append(getWrappedText(
tr("URL") + " : " + QStringLiteral("<a href=\"") + info.url + tr("URL") + sep + QStringLiteral("<a href=\"") + info.url +
QStringLiteral("\">") + info.url + QStringLiteral("</a>"))); QStringLiteral("\">") + info.url + QStringLiteral("</a>")));
} }
@ -136,16 +152,16 @@ void PluginSettingDialog::on_plglist_currentRowChanged(int currentRow) {
auto info = plgsys.getPluginInfo(plg); auto info = plgsys.getPluginInfo(plg);
ui->txtc->clear(); ui->txtc->clear();
static auto sep = QStringLiteral(" : ");
ui->txtc->append(getWrappedText(tr("ID") + " : " + info.id)); ui->txtc->append(getWrappedText(tr("ID") + sep + info.id));
ui->txtc->append(getWrappedText(tr("Name") + " : " + plg->pluginName())); ui->txtc->append(getWrappedText(tr("Name") + sep + plg->pluginName()));
ui->txtc->append(getWrappedText(tr("License") + " : " + info.license)); ui->txtc->append(getWrappedText(tr("License") + sep + info.license));
ui->txtc->append(getWrappedText(tr("Author") + " : " + info.author)); ui->txtc->append(getWrappedText(tr("Author") + sep + info.author));
ui->txtc->append(getWrappedText(tr("Vendor") + " : " + info.vendor)); ui->txtc->append(getWrappedText(tr("Vendor") + sep + info.vendor));
ui->txtc->append( ui->txtc->append(
getWrappedText(tr("Version") + " : " + info.version.toString())); getWrappedText(tr("Version") + sep + info.version.toString()));
ui->txtc->append( ui->txtc->append(
getWrappedText(tr("Comment") + " : " + plg->pluginComment())); getWrappedText(tr("Comment") + sep + plg->pluginComment()));
if (!info.dependencies.isEmpty()) { if (!info.dependencies.isEmpty()) {
ui->txtc->append(getWrappedText(tr("pluginDependencies:"))); ui->txtc->append(getWrappedText(tr("pluginDependencies:")));
for (auto &d : info.dependencies) { for (auto &d : info.dependencies) {
@ -156,7 +172,7 @@ void PluginSettingDialog::on_plglist_currentRowChanged(int currentRow) {
} }
} }
ui->txtc->append(getWrappedText( ui->txtc->append(getWrappedText(
tr("URL") + " : " + QStringLiteral("<a href=\"") + info.url + tr("URL") + sep + QStringLiteral("<a href=\"") + info.url +
QStringLiteral("\">") + info.url + QStringLiteral("</a> "))); QStringLiteral("\">") + info.url + QStringLiteral("</a> ")));
} }

View File

@ -32,8 +32,6 @@ public:
explicit PluginSettingDialog(QWidget *parent = nullptr); explicit PluginSettingDialog(QWidget *parent = nullptr);
~PluginSettingDialog(); ~PluginSettingDialog();
void buildUp(const QList<WingHex::PluginPage *> &pages);
private: private:
Ui::PluginSettingDialog *ui; Ui::PluginSettingDialog *ui;

View File

@ -167,6 +167,24 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab_2">
<attribute name="icon">
<iconset resource="../../resources.qrc">
<normaloff>:/com.wingsummer.winghex/images/monitor.png</normaloff>:/com.wingsummer.winghex/images/monitor.png</iconset>
</attribute>
<attribute name="title">
<string>APIMonitor</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QTextBrowser" name="txtm">
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget> </widget>
</item> </item>
</layout> </layout>

View File

@ -57,7 +57,15 @@ Q_DECL_UNUSED static inline QString NAMEICONRES(const QString &name) {
} }
Q_DECL_UNUSED static inline QIcon ICONRES(const QString &name) { Q_DECL_UNUSED static inline QIcon ICONRES(const QString &name) {
return QIcon(NAMEICONRES(name)); static QHash<QString, QIcon> cache;
auto picon = cache.find(name);
if (picon == cache.end()) {
QIcon icon(NAMEICONRES(name));
cache.insert(name, icon);
return icon;
} else {
return *picon;
}
} }
class Utilities { class Utilities {
@ -305,6 +313,23 @@ public:
return dec->toUnicode(buffer); return dec->toUnicode(buffer);
#endif #endif
} }
static bool isValidIdentifier(const QString &str) {
if (str.isEmpty()) {
return false;
}
auto pch = str.cbegin();
if (pch->isDigit()) {
return false;
}
pch++;
for (; pch != str.cend(); pch++) {
if (!pch->isLetterOrNumber() && *pch != '_') {
return false;
}
}
return true;
}
}; };
#endif // UTILITIES_H #endif // UTILITIES_H