Compare commits

...

4 Commits

91 changed files with 5499 additions and 3322 deletions

View File

@ -7,8 +7,8 @@ jobs:
steps:
- uses: actions/checkout@v4
- 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:
clang-format-version: '19'
clang-format-version: '20'
exclude-regex: '(qt-template|mkinstaller|grammar)'
fallback-style: 'LLVM' # optional

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,14 +21,8 @@
#include "hexcommand.h"
HexCommand::HexCommand(QHexDocument *doc, QHexCursor *cursor, int nibbleindex,
HexCommand::HexCommand(const QString &text, QHexDocument *doc,
QHexCursor *cursor, int nibbleindex,
QUndoCommand *parent)
: QUndoCommand(parent), m_doc(doc), m_cursor(cursor), m_offset(0),
: UndoCommandBase(text, parent), m_doc(doc), m_cursor(cursor), m_offset(0),
m_length(0), m_nibbleindex(nibbleindex) {}
void HexCommand::undo() {
Q_ASSERT(m_doc->m_bytesModFlag > 0);
m_doc->m_bytesModFlag--;
}
void HexCommand::redo() { m_doc->m_bytesModFlag++; }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -19,12 +19,7 @@
** =============================================================================
*/
#include "baseaddrcommand.h"
#include "undocommandbase.h"
BaseAddrCommand::BaseAddrCommand(QHexDocument *doc, quint64 oldaddr,
quint64 newaddr, QUndoCommand *parent)
: QUndoCommand(parent), m_doc(doc), m_old(oldaddr), m_new(newaddr) {}
void BaseAddrCommand::redo() { m_doc->setBaseAddress(m_new); }
void BaseAddrCommand::undo() { m_doc->setBaseAddress(m_old); }
UndoCommandBase::UndoCommandBase(const QString &text, QUndoCommand *parent)
: QUndoCommand(text, parent) {}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -28,6 +28,7 @@ add_definitions(-DAS_NO_THREADS)
if(BUILD_TEST_PLUGIN)
add_subdirectory(TestPlugin)
add_subdirectory(TestManager)
endif()
if(BUILD_SHARED_MEM_EXT)
@ -297,7 +298,11 @@ set(CLASS_SRC
src/class/asconsolecompletion.h
src/class/asconsolecompletion.cpp
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
src/class/wingangelapi.h src/class/wingangelapi.cpp

View File

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

View File

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

View File

@ -23,8 +23,6 @@ SharedMemoryDriver::SharedMemoryDriver() : WingHex::IWingDevice() {}
SharedMemoryDriver::~SharedMemoryDriver() {}
int SharedMemoryDriver::sdkVersion() const { return WingHex::SDKVERSION; }
bool SharedMemoryDriver::init(const std::unique_ptr<QSettings> &set) {
Q_UNUSED(set);
return true;
@ -42,10 +40,6 @@ const QString SharedMemoryDriver::pluginComment() const {
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) {
return new SharedMemory(path, SharedMemory::ReadWrite, this);
}

View File

@ -34,15 +34,11 @@ public:
// IWingPlugin interface
public:
virtual int sdkVersion() const override;
virtual bool init(const std::unique_ptr<QSettings> &set) override;
virtual void unload(std::unique_ptr<QSettings> &set) override;
virtual const QString pluginName() const override;
virtual const QString pluginComment() const override;
public:
virtual QList<WingHex::PluginPage *> registeredPages() const override;
// IWingDevice interface
public:
virtual QString onOpenFileBegin() override;
@ -50,9 +46,6 @@ public:
virtual QIcon supportedFileIcon() const override;
virtual WingHex::WingIODevice *onOpenFile(const QString &path) override;
virtual bool onCloseFile(WingHex::WingIODevice *dev) override;
private:
QList<WingHex::PluginPage *> _plgps;
};
#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) {
auto layout = new QVBoxLayout(this);
_lbl = new QLabel(QStringLiteral("TestPluginPage"), this);
_lbl->setAlignment(Qt::AlignCenter);
layout->addWidget(_lbl);
TestManager::~TestManager() {
// no need to manual delete content
// the host will take the ownership
}
QIcon TestPluginPage::categoryIcon() const {
return QIcon(QStringLiteral(":/images/TestPlugin/images/btn.png"));
bool TestManager::init(const std::unique_ptr<QSettings> &set) {
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.cpp
testwingeditorviewwidget.h
testwingeditorviewwidget.cpp
testpluginpage.h
testpluginpage.cpp)
testwingeditorviewwidget.cpp)
set_target_properties(TestPlugin PROPERTIES SUFFIX ".wingplg")

View File

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

View File

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

View File

@ -19,14 +19,16 @@
*/
#include "testplugin.h"
#include "WingPlugin/iwingangel.h"
#include "testform.h"
#include "testpluginpage.h"
#include "testsettingpage.h"
#include "testwingeditorviewwidget.h"
#include <QApplication>
#include <QMenu>
WING_DECLARE_STATIC_API;
// 注意:所有提供的脚本接口函数都不是线程安全的,只是测试
TestPlugin::TestPlugin() : WingHex::IWingPlugin() {
@ -37,151 +39,11 @@ TestPlugin::TestPlugin() : WingHex::IWingPlugin() {
// 初始化会传递一个配置类,插件系统会统一管理放到统一的地方,使用 INI 保存
// 你可以自行管理,但不建议,统一管理方便使用者备份和转移插件配置
{
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);
}
WING_INIT_STATIC_API;
}
TestPlugin::~TestPlugin() { destoryTestShareMem(); }
int TestPlugin::sdkVersion() const { return WingHex::SDKVERSION; }
bool TestPlugin::init(const std::unique_ptr<QSettings> &set) {
auto v = set->value("Test", 0).toInt();
// 如果你之前启动过且正常推出,这个值一定是 5
@ -247,17 +109,11 @@ bool TestPlugin::init(const std::unique_ptr<QSettings> &set) {
_rtbinfo.append(rtinfo);
}
{
auto sp = new TestSettingPage(QStringLiteral("Test1"),
QStringLiteral("This is a Test1"));
_setpages.insert(sp, true);
}
_setpages.append(new TestSettingPage(
QStringLiteral("Test1"), QStringLiteral("This is a Test1"), true));
{
auto sp = new TestSettingPage(QStringLiteral("Test2"),
QStringLiteral("This is a Test2"));
_setpages.insert(sp, false);
}
_setpages.append(new TestSettingPage(
QStringLiteral("Test2"), QStringLiteral("This is a Test2"), false));
{
WingHex::WingDockWidgetInfo info;
@ -274,11 +130,6 @@ bool TestPlugin::init(const std::unique_ptr<QSettings> &set) {
_evws.append(ev);
}
{
auto pp = new TestPluginPage;
_plgps.append(pp);
}
_tmenu = new QMenu(QStringLiteral("TestPlugin"));
auto micon = QIcon(QStringLiteral(":/images/TestPlugin/images/btn.png"));
_tmenu->setIcon(micon);
@ -298,9 +149,8 @@ void TestPlugin::unload(std::unique_ptr<QSettings> &set) {
// 设个数字,那就是 5 测试一下配置是否正常工作
set->setValue("Test", 5);
for (auto p = _setpages.constKeyValueBegin();
p != _setpages.constKeyValueEnd(); ++p) {
p->first->deleteLater();
for (auto &p : _setpages) {
p->deleteLater();
}
for (auto &item : _winfo) {
@ -332,24 +182,15 @@ TestPlugin::registeredRibbonTools() const {
return _rtbinfo;
}
QHash<WingHex::SettingPage *, bool> TestPlugin::registeredSettingPages() const {
QList<WingHex::SettingPage *> TestPlugin::registeredSettingPages() const {
return _setpages;
}
QList<WingHex::PluginPage *> TestPlugin::registeredPages() const {
return _plgps;
}
QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>>
TestPlugin::registeredEditorViewWidgets() const {
return _evws;
}
QHash<QString, WingHex::IWingPlugin::UNSAFE_SCFNPTR>
TestPlugin::registeredScriptUnsafeFns() const {
return _scriptUnsafe;
}
QVariant TestPlugin::test_a(const QVariantList &params) {
if (!params.isEmpty()) {
return getScriptCallError(-1, tr("InvalidParamsCount"));
@ -432,29 +273,26 @@ QVariant TestPlugin::test_h(const QVariantList &params) {
return test_h();
}
WingHex::IWingPlugin::UNSAFE_RET
TestPlugin::colorTable(const QList<void *> &params) {
WingHex::UNSAFE_RET TestPlugin::colorTable(const QList<void *> &params) {
if (!params.isEmpty()) {
return generateScriptCallError(-1, tr("InvalidParamsCount"));
}
void *array;
void *array = nullptr;
QVector<void *> colors;
for (auto &c : colorTable()) {
colors.append(new QColor(c));
}
// TODO
// auto invoked =
// invokeService(QStringLiteral("WingAngelAPI"), "vector2AsArray",
// WINGAPI_RETURN_ARG(array),
// WINGAPI_ARG(MetaType::Color), WINGAPI_ARG(colors));
// if (invoked) {
// if (array) {
// qDeleteAll(colors);
// return array;
// }
// }
auto invoked =
invokeService(QStringLiteral("WingAngelAPI"), "vector2AsArray",
qReturnArg(array), WingHex::MetaType::Meta_Color, colors);
if (invoked) {
if (array) {
qDeleteAll(colors);
return array;
}
}
qDeleteAll(colors);
return generateScriptCallError(-2, tr("AllocArrayFailed"));
@ -512,6 +350,19 @@ QVariant TestPlugin::testCrash(const QVariantList &params) {
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_b(const QString &b) {
@ -629,15 +480,9 @@ void TestPlugin::testCrash() {
abort();
}
QHash<QString, WingHex::IWingPlugin::ScriptFnInfo>
TestPlugin::registeredScriptFns() const {
return _scriptInfo;
}
WingHex::IWingPlugin::RegisteredEvents TestPlugin::registeredEvents() const {
RegisteredEvents evs;
evs.setFlag(RegisteredEvent::AppReady);
evs.setFlag(RegisteredEvent::ScriptUnSafeFnRegistering);
return evs;
}
@ -647,3 +492,113 @@ void TestPlugin::eventReady() {
Qt::AutoConnection, qReturnArg(ret),
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 (必须)
public:
virtual int sdkVersion() const override;
virtual bool init(const std::unique_ptr<QSettings> &set) override;
virtual void unload(std::unique_ptr<QSettings> &set) override;
virtual const QString pluginName() const override;
@ -57,19 +56,18 @@ public:
virtual QMenu *registeredHexContextMenu() const override;
virtual QList<WingHex::WingRibbonToolBoxInfo>
registeredRibbonTools() const override;
virtual QHash<WingHex::SettingPage *, bool>
virtual QList<WingHex::SettingPage *>
registeredSettingPages() const override;
virtual QList<WingHex::PluginPage *> registeredPages() const override;
virtual QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>>
registeredEditorViewWidgets() const override;
virtual QHash<QString, ScriptFnInfo> registeredScriptFns() const override;
virtual QHash<QString, UNSAFE_SCFNPTR>
registeredScriptUnsafeFns() const override;
virtual RegisteredEvents registeredEvents() const override;
virtual void eventReady() override;
// IWingPluginCoreBase interface
public:
virtual void onRegisterScriptObj(WingHex::IWingAngel *o) override;
private:
QVariant test_a(const QVariantList &params);
QVariant test_b(const QVariantList &params);
@ -81,7 +79,7 @@ private:
QVariant test_g(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 destoryTestShareMem(const QVariantList &params);
@ -92,6 +90,10 @@ private:
QVariant testCrash(const QVariantList &params);
static void testGenericAdd(WingHex::asIWingGeneric *param);
static void testRaiseScriptException(WingHex::asIWingGeneric *);
private:
void test_a();
void test_b(const QString &b);
@ -121,14 +123,10 @@ private:
bool ENABLE_META = false;
QHash<QString, WingHex::IWingPlugin::ScriptFnInfo> _scriptInfo;
QList<WingHex::WingDockWidgetInfo> _winfo;
QList<WingHex::WingRibbonToolBoxInfo> _rtbinfo;
QHash<WingHex::SettingPage *, bool> _setpages;
QList<WingHex::SettingPage *> _setpages;
QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>> _evws;
QList<WingHex::PluginPage *> _plgps;
QHash<QString, WingHex::IWingPlugin::UNSAFE_SCFNPTR> _scriptUnsafe;
};
#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>
TestSettingPage::TestSettingPage(const QString &id, const QString &content,
QWidget *parent)
: WingHex::SettingPage(parent), _id(id) {
bool isShowInRibbon, QWidget *parent)
: WingHex::SettingPage(parent), _id(id), _isShownInRibbton(isShowInRibbon) {
auto layout = new QVBoxLayout(this);
_lbl = new QLabel(content, this);
_lbl->setAlignment(Qt::AlignCenter);
@ -39,6 +39,8 @@ QString TestSettingPage::name() const { return _id; }
QString TestSettingPage::id() const { return _id; }
bool TestSettingPage::showInRibbon() const { return _isShownInRibbton; }
void TestSettingPage::apply() {}
void TestSettingPage::reset() {}

View File

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

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

View File

@ -68,7 +68,7 @@ BEGIN
BLOCK "080404b0"
BEGIN
VALUE "CompanyName", "ÓðÔÆ¹¤×÷ÊÒ£¨WingCloudStudio£©"
VALUE "FileDescription", "一个自由强大跨平台的十六进制编辑器"
VALUE "FileDescription", "羽云十六进制编辑器"
VALUE "FileVersion", "1.0.0"
VALUE "InternalName", "WingHexExplorer2.exe"
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/metahide.png</file>
<file>images/metashow.png</file>
<file>images/monitor.png</file>
<file>images/new.png</file>
<file>images/open.png</file>
<file>images/openapp.png</file>

View File

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

View File

@ -1,5 +1,6 @@
{
"Id" : "WingCStruct",
"SDK": 18,
"Version" : "0.0.2",
"Vendor" : "WingCloudStudio",
"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 "angelscript.h"
#include "class/pluginsystem.h"

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -27,6 +27,7 @@
#include "AngelScript/sdk/add_on/scriptmath/scriptmath.h"
#include "AngelScript/sdk/add_on/scriptmath/scriptmathcomplex.h"
#include "AngelScript/sdk/add_on/weakref/weakref.h"
#include "AngelScript/sdk/angelscript/source/as_scriptengine.h"
#include "angelobjstring.h"
#include "class/appmanager.h"
@ -145,6 +146,16 @@ bool ScriptMachine::isRunning(ConsoleMode mode) const {
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_2 INS_1 ", " INS_1
#define INS_4 INS_2 ", " INS_2

View File

@ -116,6 +116,7 @@ public:
bool init();
bool isInited() const;
bool isRunning(ConsoleMode mode) const;
bool isEngineConfigError() const;
static void registerEngineAddon(asIScriptEngine *engine);
static void registerEngineAssert(asIScriptEngine *engine);
@ -150,15 +151,15 @@ public:
bool isDebugMode(ConsoleMode mode = Scripting);
public slots:
bool executeCode(ConsoleMode mode, const QString &code);
bool executeCode(ScriptMachine::ConsoleMode mode, const QString &code);
// 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);
int evaluateDefine(const QString &code, bool &result);
void abortDbgScript();
void abortScript(ConsoleMode mode);
void abortScript(ScriptMachine::ConsoleMode mode);
void abortScript();
protected:

View File

@ -59,18 +59,35 @@ SkinManager &SkinManager::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) {
switch (m_theme) {
case Theme::Dark:
return QIcon(QStringLiteral("://dark/") + name +
QStringLiteral(".svg"));
case Theme::Light:
return QIcon(QStringLiteral("://light/") + name +
QStringLiteral(".svg"));
auto picon = m_cache.find(name);
if (picon == m_cache.end()) {
switch (m_theme) {
case Theme::Dark: {
QIcon icon(QStringLiteral("://dark/") + name +
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; }

View File

@ -19,6 +19,7 @@
#define SKINMANAGER_H
#include <QCoreApplication>
#include <QHash>
#include <QObject>
class SkinManager {
@ -48,6 +49,8 @@ private:
private:
Theme m_theme;
QHash<QString, QIcon> m_cache;
explicit 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 "AngelScript/sdk/angelscript/include/angelscript.h"
#include "WingPlugin/iwingangel.h"
#include "class/angelscripthelper.h"
#include "class/logger.h"
#include "class/pluginsystem.h"
#include "class/scriptmachine.h"
#include "class/wingfiledialog.h"
#include "class/winginputdialog.h"
@ -31,6 +31,7 @@
#include <QJsonDocument>
#include <QMessageBox>
#include <QTemporaryFile>
#include <QThread>
#ifdef Q_OS_WIN
#undef MessageBox
@ -44,8 +45,6 @@ WingAngelAPI::WingAngelAPI() {
WingAngelAPI::~WingAngelAPI() {}
int WingAngelAPI::sdkVersion() const { return WingHex::SDKVERSION; }
bool WingAngelAPI::init(const std::unique_ptr<QSettings> &set) {
Q_UNUSED(set);
return true;
@ -69,8 +68,8 @@ QString WingAngelAPI::retranslate(const QString &str) {
return QApplication::tr(str.toLatin1());
}
QStringList WingAngelAPI::registerScriptMarcos() const {
return {"EXEC_BASE", "AS_ARRAY_EXT", "AS_DICTIONARY_EXT"};
void WingAngelAPI::onRegisterScriptObj(WingHex::IWingAngel *o) {
o->registerScriptMarcos({"EXEC_BASE", "AS_ARRAY_EXT", "AS_DICTIONARY_EXT"});
}
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) {
Q_ASSERT(machine);
auto engine = machine->engine();
@ -150,9 +107,7 @@ void WingAngelAPI::installAPI(ScriptMachine *machine) {
installHexReaderAPI(engine);
installHexControllerAPI(engine);
installScriptEnums(engine);
installScriptFns(engine);
installScriptUnSafeFns(engine);
// plugin script objects will be install later
}
void WingAngelAPI::installBasicTypes(asIScriptEngine *engine) {
@ -767,6 +722,12 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, endMarco, (void), bool),
"bool endMarco()");
registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, isMacroEmpty, (void), bool),
"bool isMacroEmpty()");
registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, resetMarco, (void), bool),
"bool resetMarco()");
registerAPI(
engine,
@ -993,20 +954,18 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
asMETHODPR(WingHex::IWingPlugin, setMetaCommentVisible, (bool), bool),
"bool setMetaCommentVisible(bool b)");
registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, newFile, (), WingHex::ErrFile),
"ErrFile newFile()");
registerAPI(engine, asMETHODPR(WingHex::IWingPlugin, newFile, (), int),
"int newFile()");
registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, openFile, (const QString &),
WingHex::ErrFile),
"ErrFile openFile(string &in filename)");
registerAPI(
engine,
asMETHODPR(WingHex::IWingPlugin, openFile, (const QString &), int),
"int openFile(string &in filename)");
registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, openExtFile,
(const QString &, const QString &),
WingHex::ErrFile),
"ErrFile openExtFile(string &in ext, string &in file)");
(const QString &, const QString &), int),
"int openExtFile(string &in ext, string &in file)");
registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, closeFile, (int, bool),
@ -1033,10 +992,8 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
(int, const QString &), WingHex::ErrFile),
"ErrFile saveAsFile(int handle, string &in savename)");
registerAPI(
engine,
asMETHODPR(WingHex::IWingPlugin, openCurrent, (), WingHex::ErrFile),
"ErrFile openCurrent()");
registerAPI(engine, asMETHODPR(WingHex::IWingPlugin, openCurrent, (), int),
"int openCurrent()");
registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, closeCurrent, (bool),
@ -1072,10 +1029,10 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
asMETHODPR(WingHex::IWingPlugin, clearBookMark, (), bool),
"bool clearBookMark()");
registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, openWorkSpace,
(const QString &), WingHex::ErrFile),
"ErrFile openWorkSpace(string &in filename)");
registerAPI(
engine,
asMETHODPR(WingHex::IWingPlugin, openWorkSpace, (const QString &), int),
"int openWorkSpace(string &in filename)");
registerAPI(engine,
asMETHODPR(WingHex::IWingPlugin, closeAllFiles, (), bool),
@ -1084,89 +1041,6 @@ void WingAngelAPI::installHexControllerAPI(asIScriptEngine *engine) {
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,
const char *sig) {
auto r =
@ -1565,12 +1439,13 @@ QVariant WingAngelAPI::qvariantGet(asIScriptEngine *engine, const void *raw,
return {};
}
bool WingAngelAPI::getQVariantGetFlag(const ScriptFnInfo &info, int index) {
bool WingAngelAPI::getQVariantGetFlag(
const WingScriptInternal::ScriptFnInfo &info, int index) {
auto &params = info.params;
Q_ASSERT(index >= 0 && index < params.size());
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,
@ -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) {
auto fn = gen->GetFunction();
@ -1782,7 +1769,7 @@ void WingAngelAPI::script_call(asIScriptGeneric *gen) {
}
auto rettype = fns.ret;
auto r = PluginSystem::type2AngelScriptString(rettype, false, true);
auto r = type2AngelScriptString(rettype, false, true);
if (r == QStringLiteral("int")) {
r = QStringLiteral("int32");
} else if (r == QStringLiteral("uint")) {
@ -1831,7 +1818,7 @@ void WingAngelAPI::script_unsafe_call(asIScriptGeneric *gen) {
QList<void *> params;
auto total = gen->GetArgCount();
WingHex::IWingPlugin::UNSAFE_RET ret;
WingHex::UNSAFE_RET ret;
for (decltype(total) i = 0; i < total; ++i) {
auto raw = gen->GetAddressOfArg(i);
params.append(raw);
@ -1999,11 +1986,11 @@ WingAngelAPI::retriveAsDictionary(const WingHex::SenderInfo &sender,
}
void *WingAngelAPI::vector2AsArray(const WingHex::SenderInfo &sender,
MetaType type,
WingHex::MetaType type,
const QVector<void *> &content) {
Q_UNUSED(sender);
auto typeStr = PluginSystem::type2AngelScriptString(
MetaType(type | MetaType::Array), false, true);
auto typeStr = type2AngelScriptString(
WingHex::MetaType(type | WingHex::MetaType::Meta_Array), false, true);
if (typeStr.isEmpty()) {
return nullptr;
}
@ -2020,14 +2007,15 @@ void *WingAngelAPI::vector2AsArray(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)
static_assert(std::is_same_v<QList<int>, QVector<int>>);
return vector2AsArray(sender, type, content);
#else
Q_UNUSED(sender);
auto typeStr = PluginSystem::type2AngelScriptString(
MetaType(type | MetaType::Array), false, true);
auto typeStr = type2AngelScriptString(MetaType(type | MetaType::Meta_Array),
false, true);
if (typeStr.isEmpty()) {
return nullptr;
}
@ -2056,7 +2044,7 @@ void WingAngelAPI::deleteAsArray(const WingHex::SenderInfo &sender,
void *WingAngelAPI::newAsDictionary(
const WingHex::SenderInfo &sender,
const QHash<QString, QPair<MetaType, void *>> &content) {
const QHash<QString, QPair<WingHex::MetaType, void *>> &content) {
Q_UNUSED(sender);
auto engine = ScriptMachine::instance().engine();
auto dic = CScriptDictionary::Create(engine);
@ -2064,8 +2052,7 @@ void *WingAngelAPI::newAsDictionary(
for (auto p = content.constKeyValueBegin(); p != content.constKeyValueEnd();
++p) {
auto key = p->first;
auto typeStr =
PluginSystem::type2AngelScriptString(p->second.first, false, true);
auto typeStr = type2AngelScriptString(p->second.first, false, true);
auto id = engine->GetTypeIdByDecl(typeStr.toUtf8());
if (id < 0) {
continue;

View File

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

View File

@ -17,169 +17,15 @@
#include "wingcstruct.h"
#include "WingPlugin/iwingangel.h"
#include "scriptaddon/scriptqdictionary.h"
#include "utilities.h"
#include "wingangelapi.h"
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() : WingHex::IWingPlugin() {}
WingCStruct::~WingCStruct() {}
int WingCStruct::sdkVersion() const { return WingHex::SDKVERSION; }
bool WingCStruct::init(const std::unique_ptr<QSettings> &set) {
Q_UNUSED(set);
resetEnv();
@ -205,22 +51,15 @@ QString WingCStruct::retranslate(const QString &str) {
WingCStruct::RegisteredEvents WingCStruct::registeredEvents() const {
RegisteredEvents evs;
evs.setFlag(RegisteredEvent::ScriptUnSafeFnRegistering);
evs.setFlag(RegisteredEvent::ScriptPragma);
evs.setFlag(RegisteredEvent::ScriptPragmaInit);
return evs;
}
QHash<WingHex::SettingPage *, bool>
WingCStruct::registeredSettingPages() const {
QList<WingHex::SettingPage *> WingCStruct::registeredSettingPages() const {
return _setpgs;
}
QHash<QString, WingCStruct::ScriptFnInfo>
WingCStruct::registeredScriptFns() const {
return _scriptInfo;
}
bool WingCStruct::eventOnScriptPragma(const QString &script,
const QStringList &comments) {
// #pragma WingCStruct Arch [32 | 64]
@ -291,9 +130,99 @@ bool WingCStruct::eventOnScriptPragma(const QString &script,
void WingCStruct::eventOnScriptPragmaInit() { resetEnv(); }
QHash<QString, WingHex::IWingPlugin::UNSAFE_SCFNPTR>
WingCStruct::registeredScriptUnsafeFns() const {
return _scriptUnsafe;
void WingCStruct::onRegisterScriptObj(WingHex::IWingAngel *o) {
o->registerGlobalFunction(
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) {
@ -716,9 +645,9 @@ CScriptArray *WingCStruct::convert2AsArray(const QVariantList &array,
return arr;
}
WingHex::IWingPlugin::MetaType WingCStruct::getqsizetypeMetaType() const {
return sizeof(qsizetype) == sizeof(quint64) ? MetaType::Int64
: MetaType::Int32;
WingHex::MetaType WingCStruct::getqsizetypeMetaType() const {
return sizeof(qsizetype) == sizeof(quint64) ? WingHex::MetaType::Meta_Int64
: WingHex::MetaType::Meta_Int32;
}
QVariant WingCStruct::addStruct(const QVariantList &params) {
@ -837,8 +766,7 @@ QVariant WingCStruct::defineValue(const QVariantList &params) {
return defineValue(type);
}
WingHex::IWingPlugin::UNSAFE_RET
WingCStruct::read(const QList<void *> &params) {
WingHex::UNSAFE_RET WingCStruct::read(const QList<void *> &params) {
if (params.size() != 2) {
return generateScriptCallError(-1, tr("InvalidParamsCount"));
}

View File

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

View File

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

View File

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

View File

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

View File

@ -86,7 +86,7 @@ ScriptingDialog::ScriptingDialog(QWidget *parent)
m_Tbtneditors.value(ToolButtonIndex::EDITOR_VIEWS)->setEnabled(false);
// ok, preparing for starting...
this->setWindowTitle(tr("ScriptEditor"));
updateWindowTitle();
this->setWindowIcon(ICONRES(QStringLiteral("script")));
this->setMinimumSize(800, 600);
@ -833,6 +833,16 @@ void ScriptingDialog::updateEditModeEnabled() {
item->setEnabled(b);
}
if (b) {
auto fn = editor->fileName();
setWindowFilePath(fn);
m_status->setToolTip(fn);
} else {
setWindowFilePath({});
m_status->setToolTip({});
m_status->clearMessage();
}
updateWindowTitle();
updateRunDebugMode();
}
@ -895,6 +905,17 @@ void ScriptingDialog::swapEditor(ScriptEditor *old, ScriptEditor *cur) {
}
}
void ScriptingDialog::updateWindowTitle() {
auto title = tr("ScriptEditor");
auto fp = windowFilePath();
if (fp.isEmpty()) {
this->setWindowTitle(title);
} else {
QFileInfo info(fp);
this->setWindowTitle(title + QStringLiteral(" - ") + info.fileName());
}
}
void ScriptingDialog::updateRunDebugMode(bool disable) {
auto &runner = ScriptMachine::instance();
auto enable = !disable;
@ -1239,6 +1260,8 @@ void ScriptingDialog::on_save() {
auto res = editor->save();
if (res) {
setWindowFilePath(editor->fileName());
updateWindowTitle();
Toast::toast(this, NAMEICONRES(QStringLiteral("save")),
tr("SaveSuccessfully"));
} else {
@ -1267,6 +1290,8 @@ void ScriptingDialog::on_saveas() {
auto res = editor->save(filename);
if (res) {
setWindowFilePath(editor->fileName());
updateWindowTitle();
Toast::toast(this, NAMEICONRES(QStringLiteral("saveas")),
tr("SaveSuccessfully"));
} else {

View File

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

View File

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

View File

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

View File

@ -167,6 +167,24 @@
</item>
</layout>
</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>
</item>
</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) {
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 {
@ -305,6 +313,23 @@ public:
return dec->toUnicode(buffer);
#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