feat: 重构插件系统和相关插件开发

This commit is contained in:
寂静的羽夏 2025-02-28 21:25:46 +08:00
parent 90241e89ff
commit fc4d28f681
74 changed files with 8448 additions and 6327 deletions

View File

@ -104,29 +104,6 @@ void QHexMetadata::Clear() {
}
}
QUndoCommand *QHexMetadata::MakeColor(QUndoCommand *parent, qsizetype begin,
qsizetype end, const QColor &fgcolor,
const QColor &bgcolor) {
return MakeMetadata(parent, begin, end, fgcolor, bgcolor, QString());
}
QUndoCommand *QHexMetadata::MakeForeground(QUndoCommand *parent,
qsizetype begin, qsizetype end,
const QColor &fgcolor) {
return MakeMetadata(parent, begin, end, fgcolor, QColor(), QString());
}
QUndoCommand *QHexMetadata::MakeBackground(QUndoCommand *parent,
qsizetype begin, qsizetype end,
const QColor &bgcolor) {
return MakeMetadata(parent, begin, end, QColor(), bgcolor, QString());
}
QUndoCommand *QHexMetadata::MakeComment(QUndoCommand *parent, qsizetype begin,
qsizetype end, const QString &comment) {
return MakeMetadata(parent, begin, end, QColor(), QColor(), comment);
}
QUndoCommand *
QHexMetadata::MakeModifyMetadata(QUndoCommand *parent,
const QHexMetadataItem &newmeta,

View File

@ -197,16 +197,6 @@ public:
const QColor &bgcolor, const QString &comment);
void Clear();
QUndoCommand *MakeColor(QUndoCommand *parent, qsizetype begin,
qsizetype end, const QColor &fgcolor,
const QColor &bgcolor);
QUndoCommand *MakeForeground(QUndoCommand *parent, qsizetype begin,
qsizetype end, const QColor &fgcolor);
QUndoCommand *MakeBackground(QUndoCommand *parent, qsizetype begin,
qsizetype end, const QColor &bgcolor);
QUndoCommand *MakeComment(QUndoCommand *parent, qsizetype begin,
qsizetype end, const QString &comment);
QUndoCommand *MakeModifyMetadata(QUndoCommand *parent,
const QHexMetadataItem &newmeta,
const QHexMetadataItem &oldmeta);

2
3rdparty/cpptrace vendored

@ -1 +1 @@
Subproject commit 1940dc607aa09fd9014c650aa305f363284919fa
Subproject commit c37b5ed7364f4fc1c58e92d13399cd04656e6572

View File

@ -208,7 +208,8 @@ set(CONTROL_SRC
src/control/qtlonglongspinbox.h
src/control/dockwidgettab.h
src/control/dockwidgettab.cpp
src/control/qhextextedit.h src/control/qhextextedit.cpp)
src/control/qhextextedit.h
src/control/qhextextedit.cpp)
set(CLASS_SRC
src/class/logger.cpp
@ -283,7 +284,9 @@ set(CLASS_SRC
src/class/diffutil.cpp
src/class/clickcallback.h
src/class/crashhandler.h
src/class/crashhandler.cpp)
src/class/crashhandler.cpp
src/class/pluginsystem.h
src/class/pluginsystem.cpp)
set(INTERNAL_PLG_SRC
src/class/wingangelapi.h src/class/wingangelapi.cpp
@ -374,11 +377,6 @@ set(CODEEDIT_WIDGET
src/qcodeeditwidget/formatconfigmodel.h
src/qcodeeditwidget/formatconfigmodel.cpp)
set(PLUGIN_SRC
src/plugin/iwingplugin.h src/plugin/iwingpluginbase.h
src/plugin/iwingdevice.h src/plugin/pluginsystem.cpp
src/plugin/pluginsystem.h src/plugin/settingpage.h)
# localization support
file(
GLOB_RECURSE TS_FILES
@ -471,7 +469,6 @@ set(PROJECT_SOURCES
${INTERNAL_PLG_SRC}
${MODEL_SRC}
${DIALOG_SRC}
${PLUGIN_SRC}
${CONTROL_SRC}
${SETTING_SRC}
${SCRIPT_ADDON_SRC}
@ -523,6 +520,7 @@ target_link_libraries(
Qt${QT_VERSION_MAJOR}::Xml
cpptrace::cpptrace
QtSingleApplication::QtSingleApplication
WingPlugin
QHexView
QCodeEditor2
QJsonModel
@ -577,3 +575,4 @@ if(${QT_VERSION_MAJOR} EQUAL 6)
install(SCRIPT ${deploy_script})
endif()
endif()
add_subdirectory(WingPlugin)

View File

@ -18,39 +18,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
option(TEST_MODE TRUE)
# Set the location where the SDK is stored. Only iwingplugin.h and settingpage.h
# are required.
# SDK iwingplugin.h settingpage.h
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
set(WINGHEX_SDK "${CMAKE_CURRENT_SOURCE_DIR}/../src/plugin")
set(PLUGIN_INTERFACE_BASE_FOUND FALSE)
set(PLUGIN_INTERFACE_FOUND FALSE)
set(PLUGIN_SETPAGE_FOUND FALSE)
if(EXISTS "${WINGHEX_SDK}/iwingpluginbase.h")
set(PLUGIN_INTERFACE_BASE_FOUND TRUE)
endif()
if(EXISTS "${WINGHEX_SDK}/iwingplugin.h")
set(PLUGIN_INTERFACE_FOUND TRUE)
endif()
if(EXISTS "${WINGHEX_SDK}/settingpage.h")
set(PLUGIN_SETPAGE_FOUND TRUE)
endif()
if(PLUGIN_INTERFACE_FOUND
AND PLUGIN_INTERFACE_BASE_FOUND
AND PLUGIN_SETPAGE_FOUND)
message(STATUS "${WINGHEX_SDK} is valid SDK path")
else()
message(FATAL_ERROR "Invalid SDK path!")
endif()
set(WINGHEX_SDK_HEADER
"${WINGHEX_SDK}/iwingplugin.h" "${WINGHEX_SDK}/iwingpluginbase.h"
"${WINGHEX_SDK}/settingpage.h")
include_directories(${WINGHEX_SDK})
# For Qt
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets LinguistTools)
find_package(
@ -125,4 +92,4 @@ if(TEST_MODE)
${WINGHEX_PLUGIN_PATH})
endif()
target_link_libraries(TestPlugin PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
target_link_libraries(TestPlugin PRIVATE Qt${QT_VERSION_MAJOR}::Widgets WingPlugin)

View File

@ -23,7 +23,8 @@
CtlTestForm::CtlTestForm(WingHex::IWingPlugin *plg, QTextBrowser *br,
QWidget *parent)
: QWidget(parent), ui(new Ui::CtlTestForm), _plg(plg), _br(br) {
: QWidget(parent), WingHex::IWingPluginAPICalls(plg),
ui(new Ui::CtlTestForm), _plg(plg), _br(br) {
ui->setupUi(this);
}
@ -31,9 +32,8 @@ CtlTestForm::~CtlTestForm() { delete ui; }
void CtlTestForm::on_btnInt8_clicked() {
bool ok;
auto ret = emit _plg->inputbox.getInt(this, QStringLiteral("Test"),
tr("PleaseInputInt8"), 0, INT8_MIN,
UINT8_MAX, 1, &ok);
auto ret = getInt(this, QStringLiteral("Test"), tr("PleaseInputInt8"), 0,
INT8_MIN, UINT8_MAX, 1, &ok);
if (ok) {
auto buffer = qint8(ret);
if (ui->rbInsert->isChecked()) {
@ -56,9 +56,8 @@ void CtlTestForm::on_btnInt8_clicked() {
void CtlTestForm::on_btnInt16_clicked() {
bool ok;
auto ret = emit _plg->inputbox.getInt(this, QStringLiteral("Test"),
tr("PleaseInputInt16"), 0, INT16_MIN,
UINT16_MAX, 1, &ok);
auto ret = getInt(this, QStringLiteral("Test"), tr("PleaseInputInt16"), 0,
INT16_MIN, UINT16_MAX, 1, &ok);
if (ok) {
auto buffer = qint16(ret);
if (ui->rbInsert->isChecked()) {
@ -81,9 +80,8 @@ void CtlTestForm::on_btnInt16_clicked() {
void CtlTestForm::on_btnInt32_clicked() {
bool ok;
auto ret = emit _plg->inputbox.getInt(this, QStringLiteral("Test"),
tr("PleaseInputInt32"), 0, INT32_MIN,
UINT32_MAX, 1, &ok);
auto ret = getInt(this, QStringLiteral("Test"), tr("PleaseInputInt32"), 0,
INT32_MIN, INT32_MAX, 1, &ok);
if (ok) {
auto buffer = qint32(ret);
if (ui->rbInsert->isChecked()) {
@ -106,9 +104,8 @@ void CtlTestForm::on_btnInt32_clicked() {
void CtlTestForm::on_btnInt64_clicked() {
bool ok;
auto ret = emit _plg->inputbox.getText(
this, QStringLiteral("Test"), tr("PleaseInputInt64"), QLineEdit::Normal,
QStringLiteral("0"), &ok);
auto ret = getText(this, QStringLiteral("Test"), tr("PleaseInputInt64"),
QLineEdit::Normal, QStringLiteral("0"), &ok);
if (ok) {
auto buffer = qint64(ret.toULongLong(&ok));
if (ok) {
@ -134,9 +131,8 @@ void CtlTestForm::on_btnInt64_clicked() {
void CtlTestForm::on_btnFloat_clicked() {
bool ok;
auto limit = std::numeric_limits<float>();
auto ret = emit _plg->inputbox.getDouble(
this, QStringLiteral("Test"), tr("PleaseInputFloat"), 0, limit.min(),
limit.max(), 0.0, &ok);
auto ret = getDouble(this, QStringLiteral("Test"), tr("PleaseInputFloat"),
0, limit.min(), limit.max(), 0.0, &ok);
if (ok) {
auto buffer = float(ret);
if (ui->rbInsert->isChecked()) {
@ -160,9 +156,8 @@ void CtlTestForm::on_btnFloat_clicked() {
void CtlTestForm::on_btnDouble_clicked() {
bool ok;
auto limit = std::numeric_limits<double>();
auto ret = emit _plg->inputbox.getDouble(
this, QStringLiteral("Test"), tr("PleaseInputFloat"), 0, limit.min(),
limit.max(), 0.0, &ok);
auto ret = getDouble(this, QStringLiteral("Test"), tr("PleaseInputFloat"),
0, limit.min(), limit.max(), 0.0, &ok);
if (ok) {
auto buffer = double(ret);
if (ui->rbInsert->isChecked()) {
@ -185,9 +180,8 @@ void CtlTestForm::on_btnDouble_clicked() {
void CtlTestForm::on_btnString_clicked() {
bool ok;
auto buffer = emit _plg->inputbox.getText(
this, QStringLiteral("Test"), tr("PleaseInputString"),
QLineEdit::Normal, WingHex::WINGSUMMER, &ok);
auto buffer = getText(this, QStringLiteral("Test"), tr("PleaseInputString"),
QLineEdit::Normal, "wingsummer", &ok);
if (ok) {
if (ui->rbInsert->isChecked()) {
ok = insertContent(ui->sbOffset->value(), buffer);
@ -201,9 +195,9 @@ void CtlTestForm::on_btnString_clicked() {
void CtlTestForm::on_btnByteArray_clicked() {
bool ok;
auto ret = emit _plg->inputbox.getText(
this, QStringLiteral("Test"), tr("PleaseInputByteArray(00 23 5A)"),
QLineEdit::Normal, QStringLiteral("00"), &ok);
auto ret = getText(this, QStringLiteral("Test"),
tr("PleaseInputByteArray(00 23 5A)"), QLineEdit::Normal,
QStringLiteral("00"), &ok);
if (ok) {
auto buffer = QByteArray::fromHex(ret.toUtf8());
if (buffer.isEmpty()) {

View File

@ -24,13 +24,13 @@
#include <QTextBrowser>
#include <QWidget>
#include "iwingplugin.h"
#include "WingPlugin/iwingplugin.h"
namespace Ui {
class CtlTestForm;
}
class CtlTestForm : public QWidget {
class CtlTestForm : public QWidget, public WingHex::IWingPluginAPICalls {
Q_OBJECT
public:
@ -61,27 +61,27 @@ private:
Q_ASSERT(_plg);
if constexpr (std::is_integral_v<T>) {
if constexpr (sizeof(T) == sizeof(qint8)) {
return emit _plg->controller.writeInt8(offset, value);
return writeInt8(offset, value);
} else if constexpr (sizeof(T) == sizeof(qint16)) {
return emit _plg->controller.writeInt16(offset, value);
return writeInt16(offset, value);
} else if constexpr (sizeof(T) == sizeof(qint32)) {
return emit _plg->controller.writeInt32(offset, value);
return writeInt32(offset, value);
} else if constexpr (sizeof(T) == sizeof(qint64)) {
return emit _plg->controller.writeInt64(offset, value);
return writeInt64(offset, value);
} else {
static_assert(false, "unsupported writeContent");
return false;
}
} else if constexpr (std::is_floating_point_v<T>) {
if constexpr (std::is_same_v<T, float>) {
return emit _plg->controller.writeFloat(offset, value);
return writeFloat(offset, value);
} else {
return emit _plg->controller.writeDouble(offset, value);
return writeDouble(offset, value);
}
} else if constexpr (std::is_same_v<T, QString>) {
return emit _plg->controller.writeString(offset, value);
return writeString(offset, value);
} else if constexpr (std::is_same_v<T, QByteArray>) {
return emit _plg->controller.writeBytes(offset, value);
return writeBytes(offset, value);
} else {
static_assert(false, "unsupported writeContent");
return false;
@ -93,27 +93,27 @@ private:
Q_ASSERT(_plg);
if constexpr (std::is_integral_v<T>) {
if constexpr (sizeof(T) == sizeof(qint8)) {
return emit _plg->controller.insertInt8(offset, value);
return insertInt8(offset, value);
} else if constexpr (sizeof(T) == sizeof(qint16)) {
return emit _plg->controller.insertInt16(offset, value);
return insertInt16(offset, value);
} else if constexpr (sizeof(T) == sizeof(qint32)) {
return emit _plg->controller.insertInt32(offset, value);
return insertInt32(offset, value);
} else if constexpr (sizeof(T) == sizeof(qint64)) {
return emit _plg->controller.insertInt64(offset, value);
return insertInt64(offset, value);
} else {
static_assert(false, "unsupported insertContent");
return false;
}
} else if constexpr (std::is_floating_point_v<T>) {
if constexpr (std::is_same_v<T, float>) {
return emit _plg->controller.insertFloat(offset, value);
return insertFloat(offset, value);
} else {
return emit _plg->controller.insertDouble(offset, value);
return insertDouble(offset, value);
}
} else if constexpr (std::is_same_v<T, QString>) {
return emit _plg->controller.insertString(offset, value);
return insertString(offset, value);
} else if constexpr (std::is_same_v<T, QByteArray>) {
return emit _plg->controller.insertBytes(offset, value);
return insertBytes(offset, value);
} else {
static_assert(false, "unsupported insertContent");
return false;
@ -125,27 +125,27 @@ private:
Q_ASSERT(_plg);
if constexpr (std::is_integral_v<T>) {
if constexpr (sizeof(T) == sizeof(qint8)) {
return emit _plg->controller.appendInt8(value);
return appendInt8(value);
} else if constexpr (sizeof(T) == sizeof(qint16)) {
return emit _plg->controller.appendInt16(value);
return appendInt16(value);
} else if constexpr (sizeof(T) == sizeof(qint32)) {
return emit _plg->controller.appendInt32(value);
return appendInt32(value);
} else if constexpr (sizeof(T) == sizeof(qint64)) {
return emit _plg->controller.appendInt64(value);
return appendInt64(value);
} else {
static_assert(false, "unsupported appendContent");
return false;
}
} else if constexpr (std::is_floating_point_v<T>) {
if constexpr (std::is_same_v<T, float>) {
return emit _plg->controller.appendFloat(value);
return appendFloat(value);
} else {
return emit _plg->controller.appendDouble(value);
return appendDouble(value);
}
} else if constexpr (std::is_same_v<T, QString>) {
return emit _plg->controller.appendString(value);
return appendString(value);
} else if constexpr (std::is_same_v<T, QByteArray>) {
return emit _plg->controller.appendBytes(value);
return appendBytes(value);
} else {
static_assert(false, "unsupported appendContent");
return false;

View File

@ -39,33 +39,33 @@
<translation>8</translation>
</message>
<message>
<location filename="../ctltestform.cpp" line="60"/>
<location filename="../ctltestform.cpp" line="59"/>
<source>PleaseInputInt16</source>
<translation>16</translation>
</message>
<message>
<location filename="../ctltestform.cpp" line="85"/>
<location filename="../ctltestform.cpp" line="83"/>
<source>PleaseInputInt32</source>
<translation>32</translation>
</message>
<message>
<location filename="../ctltestform.cpp" line="110"/>
<location filename="../ctltestform.cpp" line="107"/>
<source>PleaseInputInt64</source>
<translation>64</translation>
</message>
<message>
<location filename="../ctltestform.cpp" line="138"/>
<location filename="../ctltestform.cpp" line="164"/>
<location filename="../ctltestform.cpp" line="134"/>
<location filename="../ctltestform.cpp" line="159"/>
<source>PleaseInputFloat</source>
<translation></translation>
</message>
<message>
<location filename="../ctltestform.cpp" line="189"/>
<location filename="../ctltestform.cpp" line="183"/>
<source>PleaseInputString</source>
<translation></translation>
</message>
<message>
<location filename="../ctltestform.cpp" line="205"/>
<location filename="../ctltestform.cpp" line="199"/>
<source>PleaseInputByteArray(00 23 5A)</source>
<translation>00 23 5A</translation>
</message>
@ -272,23 +272,23 @@
<translation></translation>
</message>
<message>
<location filename="../testform.cpp" line="344"/>
<location filename="../testform.cpp" line="355"/>
<location filename="../testform.cpp" line="336"/>
<location filename="../testform.cpp" line="345"/>
<source>UpdateTextTreeError</source>
<translation></translation>
</message>
<message>
<location filename="../testform.cpp" line="370"/>
<location filename="../testform.cpp" line="360"/>
<source>UpdateTextListByModelError</source>
<translation></translation>
</message>
<message>
<location filename="../testform.cpp" line="380"/>
<location filename="../testform.cpp" line="370"/>
<source>UpdateTextTableByModelError</source>
<translation></translation>
</message>
<message>
<location filename="../testform.cpp" line="391"/>
<location filename="../testform.cpp" line="381"/>
<source>UpdateTextTreeByModelError</source>
<translation></translation>
</message>
@ -296,60 +296,60 @@
<context>
<name>TestPlugin</name>
<message>
<location filename="../testplugin.cpp" line="208"/>
<location filename="../testplugin.cpp" line="207"/>
<source>Test</source>
<translation></translation>
</message>
<message>
<location filename="../testplugin.cpp" line="220"/>
<location filename="../testplugin.cpp" line="229"/>
<location filename="../testplugin.cpp" line="234"/>
<location filename="../testplugin.cpp" line="315"/>
<location filename="../testplugin.cpp" line="219"/>
<location filename="../testplugin.cpp" line="228"/>
<location filename="../testplugin.cpp" line="233"/>
<location filename="../testplugin.cpp" line="314"/>
<source>TestPlugin</source>
<translation></translation>
</message>
<message>
<location filename="../testplugin.cpp" line="238"/>
<location filename="../testplugin.cpp" line="237"/>
<source>Button - </source>
<translation> - </translation>
</message>
<message>
<location filename="../testplugin.cpp" line="242"/>
<location filename="../testplugin.cpp" line="241"/>
<source>Click</source>
<translation></translation>
</message>
<message>
<location filename="../testplugin.cpp" line="318"/>
<location filename="../testplugin.cpp" line="317"/>
<source>A Test Plugin for WingHexExplorer2.</source>
<translation>2</translation>
</message>
<message>
<location filename="../testplugin.cpp" line="356"/>
<location filename="../testplugin.cpp" line="364"/>
<location filename="../testplugin.cpp" line="373"/>
<location filename="../testplugin.cpp" line="394"/>
<location filename="../testplugin.cpp" line="410"/>
<location filename="../testplugin.cpp" line="417"/>
<location filename="../testplugin.cpp" line="424"/>
<location filename="../testplugin.cpp" line="431"/>
<location filename="../testplugin.cpp" line="439"/>
<location filename="../testplugin.cpp" line="470"/>
<location filename="../testplugin.cpp" line="478"/>
<location filename="../testplugin.cpp" line="486"/>
<location filename="../testplugin.cpp" line="494"/>
<location filename="../testplugin.cpp" line="503"/>
<location filename="../testplugin.cpp" line="510"/>
<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="468"/>
<location filename="../testplugin.cpp" line="476"/>
<location filename="../testplugin.cpp" line="484"/>
<location filename="../testplugin.cpp" line="492"/>
<location filename="../testplugin.cpp" line="501"/>
<location filename="../testplugin.cpp" line="508"/>
<source>InvalidParamsCount</source>
<translation></translation>
</message>
<message>
<location filename="../testplugin.cpp" line="387"/>
<location filename="../testplugin.cpp" line="403"/>
<location filename="../testplugin.cpp" line="386"/>
<location filename="../testplugin.cpp" line="402"/>
<source>InvalidParam</source>
<translation></translation>
</message>
<message>
<location filename="../testplugin.cpp" line="461"/>
<location filename="../testplugin.cpp" line="459"/>
<source>AllocArrayFailed</source>
<translation></translation>
</message>

View File

@ -25,7 +25,8 @@
ReaderTestForm::ReaderTestForm(WingHex::IWingPlugin *plg, QTextBrowser *br,
QWidget *parent)
: QWidget(parent), ui(new Ui::ReaderTestForm), _plg(plg), _br(br) {
: QWidget(parent), WingHex::IWingPluginCalls(plg),
ui(new Ui::ReaderTestForm), _plg(plg), _br(br) {
ui->setupUi(this);
ui->sbOffset->setRange(0, INT_MAX);
}
@ -33,43 +34,42 @@ ReaderTestForm::ReaderTestForm(WingHex::IWingPlugin *plg, QTextBrowser *br,
ReaderTestForm::~ReaderTestForm() { delete ui; }
void ReaderTestForm::on_btnReadInt8_clicked() {
auto v = emit _plg->reader.readInt8(ui->sbOffset->value());
auto v = readInt8(ui->sbOffset->value());
_br->append(QStringLiteral("[ReadInt8] ") + QString::number(v));
}
void ReaderTestForm::on_btnReadInt16_clicked() {
auto v = emit _plg->reader.readInt16(ui->sbOffset->value());
auto v = readInt16(ui->sbOffset->value());
_br->append(QStringLiteral("[ReadInt16] ") + QString::number(v));
}
void ReaderTestForm::on_btnReadInt32_clicked() {
auto v = emit _plg->reader.readInt32(ui->sbOffset->value());
auto v = readInt32(ui->sbOffset->value());
_br->append(QStringLiteral("[ReadInt32] ") + QString::number(v));
}
void ReaderTestForm::on_btnReadInt64_clicked() {
auto v = emit _plg->reader.readInt64(ui->sbOffset->value());
auto v = readInt64(ui->sbOffset->value());
_br->append(QStringLiteral("[ReadInt64] ") + QString::number(v));
}
void ReaderTestForm::on_btnReadFloat_clicked() {
auto v = emit _plg->reader.readFloat(ui->sbOffset->value());
auto v = readFloat(ui->sbOffset->value());
_br->append(QStringLiteral("[ReadFloat] ") + QString::number(v));
}
void ReaderTestForm::on_btnReadDouble_clicked() {
auto v = emit _plg->reader.readDouble(ui->sbOffset->value());
auto v = readDouble(ui->sbOffset->value());
_br->append(QStringLiteral("[ReadDouble] ") + QString::number(v));
}
void ReaderTestForm::on_btnReadString_clicked() {
auto v = emit _plg->reader.readString(ui->sbOffset->value());
auto v = readString(ui->sbOffset->value());
_br->append(QStringLiteral("[ReadString] ") + v);
}
void ReaderTestForm::on_btnReadByteArray_clicked() {
auto v =
emit _plg->reader.readBytes(ui->sbOffset->value(), ui->sbLen->value());
auto v = readBytes(ui->sbOffset->value(), ui->sbLen->value());
_br->append(QStringLiteral("[ReadByteArray] ") + v.toHex(' '));
}
@ -78,63 +78,49 @@ void ReaderTestForm::on_btnStatus_clicked() {
static auto strue = QStringLiteral("true");
static auto sfalse = QStringLiteral("false");
_br->clear();
_br->append(QStringLiteral("[Status]") % lf %
QStringLiteral("getSupportedEncodings: ") %
(emit _plg->reader.getSupportedEncodings().join(';')) % lf %
QStringLiteral("isCurrentDocEditing: ") %
(emit _plg->reader.isCurrentDocEditing() ? strue : sfalse) %
lf % QStringLiteral("currentDocFilename: ") %
emit _plg->reader.currentDocFilename() % lf %
QStringLiteral("isReadOnly: ") %
(emit _plg->reader.isReadOnly() ? strue : sfalse) % lf %
QStringLiteral("isKeepSize: ") %
(emit _plg->reader.isKeepSize() ? strue : sfalse) % lf %
QStringLiteral("isLocked: ") %
(emit _plg->reader.isLocked() ? strue : sfalse) % lf %
QStringLiteral("isModified: ") %
(emit _plg->reader.isModified() ? strue : sfalse) % lf %
QStringLiteral("stringVisible: ") %
(emit _plg->reader.stringVisible() ? strue : sfalse) % lf %
QStringLiteral("addressVisible: ") %
(emit _plg->reader.addressVisible() ? strue : sfalse) % lf %
QStringLiteral("headerVisible: ") %
(emit _plg->reader.headerVisible() ? strue : sfalse) % lf %
QStringLiteral("addressBase: ") % QStringLiteral("0x") %
QString::number(emit _plg->reader.addressBase(), 16).toUpper() %
lf % QStringLiteral("documentLines: ") %
QString::number(emit _plg->reader.documentLines()) % lf %
QStringLiteral("documentBytes: ") %
QString::number(emit _plg->reader.documentBytes()) % lf %
QStringLiteral("currentPos: ") %
getPrintableHexPosition(emit _plg->reader.currentPos()) % lf %
QStringLiteral("currentRow: ") %
QString::number(emit _plg->reader.currentRow()) % lf %
QStringLiteral("currentColumn: ") %
QString::number(emit _plg->reader.currentColumn()) % lf %
QStringLiteral("currentOffset: ") %
QString::number(emit _plg->reader.currentOffset()) % lf %
QStringLiteral("selectedLength: ") %
QString::number(emit _plg->reader.selectedLength()));
_br->append(
QStringLiteral("[Status]") % lf %
QStringLiteral("isCurrentDocEditing: ") %
(isCurrentDocEditing() ? strue : sfalse) % lf %
QStringLiteral("currentDocFilename: ") % currentDocFilename() % lf %
QStringLiteral("isReadOnly: ") % (isReadOnly() ? strue : sfalse) % lf %
QStringLiteral("isKeepSize: ") % (isKeepSize() ? strue : sfalse) % lf %
QStringLiteral("isLocked: ") % (isLocked() ? strue : sfalse) % lf %
QStringLiteral("isModified: ") % (isModified() ? strue : sfalse) % lf %
QStringLiteral("stringVisible: ") % (stringVisible() ? strue : sfalse) %
lf % QStringLiteral("addressVisible: ") %
(addressVisible() ? strue : sfalse) % lf %
QStringLiteral("headerVisible: ") % (headerVisible() ? strue : sfalse) %
lf % QStringLiteral("addressBase: ") % QStringLiteral("0x") %
QString::number(addressBase(), 16).toUpper() % lf %
QStringLiteral("documentLines: ") % QString::number(documentLines()) %
lf % QStringLiteral("documentBytes: ") %
QString::number(documentBytes()) % lf % QStringLiteral("currentPos: ") %
getPrintableHexPosition(currentPos()) % lf %
QStringLiteral("currentRow: ") % QString::number(currentRow()) % lf %
QStringLiteral("currentColumn: ") % QString::number(currentColumn()) %
lf % QStringLiteral("currentOffset: ") %
QString::number(currentOffset()) % lf %
QStringLiteral("selectedLength: ") % QString::number(selectedLength()));
_br->append(QStringLiteral("[Selection]"));
auto total = emit _plg->reader.selectionCount();
auto total = selectionCount();
_br->append(QStringLiteral("selectionCount: ") % QString::number(total));
for (decltype(total) i = 0; i < total; ++i) {
_br->append(QStringLiteral("{ ") % QString::number(i) %
QStringLiteral(" }"));
_br->append(
QStringLiteral("selectionStart: ") %
getPrintableHexPosition(emit _plg->reader.selectionStart(i)) % lf %
QStringLiteral("selectionEnd: ") %
getPrintableHexPosition(emit _plg->reader.selectionEnd(i)) % lf %
QStringLiteral("selectionLength: ") %
QString::number(emit _plg->reader.selectionLength(i)) % lf %
QStringLiteral("selectedBytes: ") %
(emit _plg->reader.selectedBytes(i)).toHex(' '));
_br->append(QStringLiteral("selectionStart: ") %
getPrintableHexPosition(selectionStart(i)) % lf %
QStringLiteral("selectionEnd: ") %
getPrintableHexPosition(selectionEnd(i)) % lf %
QStringLiteral("selectionLength: ") %
QString::number(selectionLength(i)) % lf %
QStringLiteral("selectedBytes: ") %
(selectedBytes(i)).toHex(' '));
}
_br->append(QStringLiteral("[Selections]"));
_br->append((emit _plg->reader.selectionBytes()).join('\n').toHex(' '));
_br->append((selectionBytes()).join('\n').toHex(' '));
}
QString

View File

@ -24,13 +24,13 @@
#include <QTextBrowser>
#include <QWidget>
#include "iwingplugin.h"
#include "WingPlugin/iwingplugin.h"
namespace Ui {
class ReaderTestForm;
}
class ReaderTestForm : public QWidget {
class ReaderTestForm : public QWidget, public WingHex::IWingPluginCalls {
Q_OBJECT
public:

View File

@ -30,17 +30,18 @@
#include <QMetaEnum>
#include <QScrollArea>
#include <QStandardItemModel>
#include <QStringListModel>
TestForm::TestForm(WingHex::IWingPlugin *plg, QWidget *parent)
: QWidget(parent), ui(new Ui::TestForm), _plg(plg) {
: QWidget(parent), WingHex::IWingPluginAPICalls(plg), ui(new Ui::TestForm) {
ui->setupUi(this);
ui->teDataVisual->setAcceptRichText(false);
ui->saReader->widget()->layout()->addWidget(
new ReaderTestForm(_plg, ui->tbReaderLogger, this));
new ReaderTestForm(plg, ui->tbReaderLogger, this));
ui->saCtl->widget()->layout()->addWidget(
new CtlTestForm(_plg, ui->tbCtlLogger, this));
new CtlTestForm(plg, ui->tbCtlLogger, this));
ui->spltReader->setSizes({300, 150});
ui->spltCtl->setSizes({300, 150});
@ -152,32 +153,32 @@ QFileDialog::Options TestForm::getFileDialogOptions() const {
}
void TestForm::onDVClicked(const QModelIndex &index) {
emit _plg->warn(QStringLiteral("[Test - Click] ") +
index.model()->data(index).toString());
warn(QStringLiteral("[Test - Click] ") +
index.model()->data(index).toString());
}
void TestForm::onDVDoubleClicked(const QModelIndex &index) {
emit _plg->msgbox.warning(this, QStringLiteral("Test - DoubleClick"),
index.model()->data(index).toString());
warning(this, QStringLiteral("Test - DoubleClick"),
index.model()->data(index).toString());
}
void TestForm::on_btnSendLog_clicked() {
auto txt = ui->leLogText->text();
switch (Level(ui->cbLogLevel->currentIndex())) {
case q1ERROR:
emit _plg->error(txt);
error(txt);
break;
case q2WARN:
emit _plg->warn(txt);
warn(txt);
break;
case q3INFO:
emit _plg->info(txt);
info(txt);
break;
case q4DEBUG:
emit _plg->debug(txt);
debug(txt);
break;
case q5TRACE:
emit _plg->trace(txt);
trace(txt);
break;
default:
break;
@ -188,38 +189,37 @@ void TestForm::on_btnSendToast_clicked() {
auto idx = ui->cbToastIcon->currentIndex();
Q_ASSERT(idx >= 0);
auto icon = ui->cbToastIcon->itemData(idx).value<QPixmap>();
emit _plg->toast(icon, ui->leToastText->text());
toast(icon, ui->leToastText->text());
}
void TestForm::on_btnAboutQt_clicked() {
emit _plg->msgbox.aboutQt(this, ui->leAboutTitle->text());
aboutQt(this, ui->leAboutTitle->text());
}
void TestForm::on_btnQuestion_clicked() {
emit _plg->msgbox.question(
question(
this, ui->leMsgTitle->text(), ui->leMsgText->text(), getMsgButtons(),
QMessageBox::StandardButton(ui->cbMsgDefButton->currentData().toInt()));
}
void TestForm::on_btnWarning_clicked() {
emit _plg->msgbox.warning(
warning(
this, ui->leMsgTitle->text(), ui->leMsgText->text(), getMsgButtons(),
QMessageBox::StandardButton(ui->cbMsgDefButton->currentData().toInt()));
}
void TestForm::on_btnCritical_clicked() {
emit _plg->msgbox.critical(
critical(
this, ui->leMsgTitle->text(), ui->leMsgText->text(), getMsgButtons(),
QMessageBox::StandardButton(ui->cbMsgDefButton->currentData().toInt()));
}
void TestForm::on_btnAbout_clicked() {
emit _plg->msgbox.about(this, ui->leMsgTitle->text(),
ui->leMsgText->text());
about(this, ui->leMsgTitle->text(), ui->leMsgText->text());
}
void TestForm::on_btnMsgBox_clicked() {
emit _plg->msgbox.msgbox(
msgbox(
this, ui->cbMsgIcon->currentData().value<QMessageBox::Icon>(),
ui->leMsgTitle->text(), ui->leMsgText->text(), getMsgButtons(),
QMessageBox::StandardButton(ui->cbMsgDefButton->currentData().toInt()));
@ -227,9 +227,8 @@ void TestForm::on_btnMsgBox_clicked() {
void TestForm::on_btnText_clicked() {
bool ok = false;
auto ret = emit _plg->inputbox.getText(
this, ui->leInputTitle->text(), ui->leInputLabel->text(),
QLineEdit::Normal, __FUNCTION__, &ok);
auto ret = getText(this, ui->leInputTitle->text(), ui->leInputLabel->text(),
QLineEdit::Normal, __FUNCTION__, &ok);
ui->tbInputLogger->append(
QStringLiteral("[getText] ( ") %
(ok ? QStringLiteral("true") : QStringLiteral("false")) %
@ -238,9 +237,8 @@ void TestForm::on_btnText_clicked() {
void TestForm::on_btnMultiLineText_clicked() {
bool ok = false;
auto ret = emit _plg->inputbox.getMultiLineText(
this, ui->leInputTitle->text(), ui->leInputLabel->text(), __FUNCTION__,
&ok);
auto ret = getMultiLineText(this, ui->leInputTitle->text(),
ui->leInputLabel->text(), __FUNCTION__, &ok);
ui->tbInputLogger->append(
QStringLiteral("[getText] ( ") %
(ok ? QStringLiteral("true") : QStringLiteral("false")) %
@ -253,9 +251,8 @@ void TestForm::on_btnItem_clicked() {
l.append(QStringLiteral("WingSummer WingHex2 - %1").arg(i));
}
bool ok = false;
auto ret =
emit _plg->inputbox.getItem(this, ui->leInputTitle->text(),
ui->leInputLabel->text(), l, 0, true, &ok);
auto ret = getItem(this, ui->leInputTitle->text(), ui->leInputLabel->text(),
l, 0, true, &ok);
ui->tbInputLogger->append(
QStringLiteral("[getItem] ( ") %
(ok ? QStringLiteral("true") : QStringLiteral("false")) %
@ -264,9 +261,8 @@ void TestForm::on_btnItem_clicked() {
void TestForm::on_btnInt_clicked() {
bool ok = false;
auto ret = emit _plg->inputbox.getInt(this, ui->leInputTitle->text(),
ui->leInputLabel->text(), 0, 0,
WingHex::SDKVERSION, 1, &ok);
auto ret = getInt(this, ui->leInputTitle->text(), ui->leInputLabel->text(),
0, 0, WingHex::SDKVERSION, 1, &ok);
ui->tbInputLogger->append(
QStringLiteral("[getInt] ( ") %
(ok ? QStringLiteral("true") : QStringLiteral("false")) %
@ -275,10 +271,10 @@ void TestForm::on_btnInt_clicked() {
void TestForm::on_btnDouble_clicked() {
bool ok = false;
auto ret = emit _plg->inputbox.getDouble(
this, ui->leInputTitle->text(), ui->leInputLabel->text(),
QLineEdit::Normal, -double(WingHex::SDKVERSION), 0.0,
double(WingHex::SDKVERSION), &ok);
auto ret =
getDouble(this, ui->leInputTitle->text(), ui->leInputLabel->text(),
QLineEdit::Normal, -double(WingHex::SDKVERSION), 0.0,
double(WingHex::SDKVERSION), &ok);
ui->tbInputLogger->append(
QStringLiteral("[getDouble] ( ") %
(ok ? QStringLiteral("true") : QStringLiteral("false")) %
@ -286,21 +282,21 @@ void TestForm::on_btnDouble_clicked() {
}
void TestForm::on_btnExistingDirectory_clicked() {
auto ret = emit _plg->filedlg.getExistingDirectory(
this, ui->leFileCaption->text(), qApp->applicationDirPath(),
getFileDialogOptions());
auto ret = getExistingDirectory(this, ui->leFileCaption->text(),
qApp->applicationDirPath(),
getFileDialogOptions());
ui->tbFileLogger->append(QStringLiteral("[getExistingDirectory] ") % ret);
}
void TestForm::on_btnOpenFileName_clicked() {
auto ret = emit _plg->filedlg.getOpenFileName(
auto ret = getOpenFileName(
this, ui->leFileCaption->text(), qApp->applicationDirPath(),
ui->leFileFilter->text(), nullptr, getFileDialogOptions());
ui->tbFileLogger->append(QStringLiteral("[getOpenFileName] ") % ret);
}
void TestForm::on_btnOpenFileNames_clicked() {
auto ret = emit _plg->filedlg.getOpenFileNames(
auto ret = getOpenFileNames(
this, ui->leFileCaption->text(), qApp->applicationDirPath(),
ui->leFileFilter->text(), nullptr, getFileDialogOptions());
ui->tbFileLogger->append(QStringLiteral("[getOpenFileName] ") %
@ -308,14 +304,14 @@ void TestForm::on_btnOpenFileNames_clicked() {
}
void TestForm::on_btnSaveFileName_clicked() {
auto ret = emit _plg->filedlg.getSaveFileName(
auto ret = getSaveFileName(
this, ui->leFileCaption->text(), qApp->applicationDirPath(),
ui->leFileFilter->text(), nullptr, getFileDialogOptions());
ui->tbFileLogger->append(QStringLiteral("[getSaveFileName] ") % ret);
}
void TestForm::on_btnGetColor_clicked() {
auto ret = emit _plg->colordlg.getColor(ui->leColorCaption->text(), this);
auto ret = getColor(ui->leColorCaption->text(), this);
if (ret.isValid()) {
ui->wColor->setStyleSheet(QStringLiteral("background-color:") +
ret.name());
@ -325,34 +321,28 @@ void TestForm::on_btnGetColor_clicked() {
}
void TestForm::on_btnText_2_clicked() {
emit _plg->visual.updateText(ui->teDataVisual->toPlainText(),
QStringLiteral("TestForm"));
updateText(ui->teDataVisual->toPlainText(), QStringLiteral("TestForm"));
}
void TestForm::on_btnTextList_clicked() {
auto txts = ui->teDataVisual->toPlainText().split('\n');
emit _plg->visual.updateTextList(txts, QStringLiteral("TestForm"), _click,
_dblclick);
updateTextList(txts, QStringLiteral("TestForm"), _click, _dblclick);
}
void TestForm::on_btnTextTree_clicked() {
auto ret = emit _plg->visual.updateTextTree(ui->teDataVisual->toPlainText(),
QStringLiteral("TestForm"),
_click, _dblclick);
auto ret = updateTextTree(ui->teDataVisual->toPlainText(),
QStringLiteral("TestForm"), _click, _dblclick);
if (!ret) {
emit _plg->msgbox.critical(this, QStringLiteral("Test"),
tr("UpdateTextTreeError"));
critical(this, QStringLiteral("Test"), tr("UpdateTextTreeError"));
}
}
void TestForm::on_btnTextTable_clicked() {
auto ret = emit _plg->visual.updateTextTable(
ui->teDataVisual->toPlainText(),
{WingHex::WINGSUMMER, WingHex::WINGSUMMER}, {},
QStringLiteral("TestForm"), _click, _dblclick);
auto ret = updateTextTable(ui->teDataVisual->toPlainText(),
{"wingsummer", "wingsummer"}, {},
QStringLiteral("TestForm"), _click, _dblclick);
if (!ret) {
emit _plg->msgbox.critical(this, QStringLiteral("Test"),
tr("UpdateTextTreeError"));
critical(this, QStringLiteral("Test"), tr("UpdateTextTreeError"));
}
}
@ -360,62 +350,62 @@ void TestForm::on_btnTextListByModel_clicked() {
auto model = new QStringListModel;
QStringList buffer;
for (int i = 0; i < WingHex::SDKVERSION; ++i) {
buffer.append(WingHex::WINGSUMMER % QString::number(i));
buffer.append("wingsummer" % QString::number(i));
}
model->setStringList(buffer);
auto ret = emit _plg->visual.updateTextListByModel(
model, QStringLiteral("TestForm"), _click, _dblclick);
auto ret = updateTextListByModel(model, QStringLiteral("TestForm"), _click,
_dblclick);
if (!ret) {
emit _plg->msgbox.critical(this, QStringLiteral("Test"),
tr("UpdateTextListByModelError"));
critical(this, QStringLiteral("Test"),
tr("UpdateTextListByModelError"));
}
}
void TestForm::on_btnTextTableByModel_clicked() {
auto model = new TestTableModel;
auto ret = emit _plg->visual.updateTextTableByModel(
model, QStringLiteral("TestForm"), _click, _dblclick);
auto ret = updateTextTableByModel(model, QStringLiteral("TestForm"), _click,
_dblclick);
if (!ret) {
emit _plg->msgbox.critical(this, QStringLiteral("Test"),
tr("UpdateTextTableByModelError"));
critical(this, QStringLiteral("Test"),
tr("UpdateTextTableByModelError"));
}
}
void TestForm::on_btnTextTreeByModel_clicked() {
auto model = new QFileSystemModel;
model->setRootPath(QDir::currentPath());
auto ret = emit _plg->visual.updateTextTreeByModel(
model, QStringLiteral("TestForm"), _click, _dblclick);
auto ret = updateTextTreeByModel(model, QStringLiteral("TestForm"), _click,
_dblclick);
if (!ret) {
emit _plg->msgbox.critical(this, QStringLiteral("Test"),
tr("UpdateTextTreeByModelError"));
critical(this, QStringLiteral("Test"),
tr("UpdateTextTreeByModelError"));
}
}
void TestForm::on_btnStatusVisible_clicked() {
if (ui->rbLockedFile->isChecked()) {
Q_UNUSED(emit _plg->controller.setLockedFile(true));
Q_UNUSED(setLockedFile(true));
} else if (ui->rbAddressVisible->isChecked()) {
Q_UNUSED(emit _plg->controller.setAddressVisible(true));
Q_UNUSED(setAddressVisible(true));
} else if (ui->rbHeaderVisible->isChecked()) {
Q_UNUSED(emit _plg->controller.setHeaderVisible(true));
Q_UNUSED(setHeaderVisible(true));
} else if (ui->rbKeepSize->isChecked()) {
Q_UNUSED(emit _plg->controller.setKeepSize(true));
Q_UNUSED(setKeepSize(true));
} else if (ui->rbStringVisible->isChecked()) {
Q_UNUSED(emit _plg->controller.setStringVisible(true));
Q_UNUSED(setStringVisible(true));
}
}
void TestForm::on_btnStatusInvisible_clicked() {
if (ui->rbLockedFile->isChecked()) {
Q_UNUSED(emit _plg->controller.setLockedFile(false));
Q_UNUSED(setLockedFile(false));
} else if (ui->rbAddressVisible->isChecked()) {
Q_UNUSED(emit _plg->controller.setAddressVisible(false));
Q_UNUSED(setAddressVisible(false));
} else if (ui->rbHeaderVisible->isChecked()) {
Q_UNUSED(emit _plg->controller.setHeaderVisible(false));
Q_UNUSED(setHeaderVisible(false));
} else if (ui->rbKeepSize->isChecked()) {
Q_UNUSED(emit _plg->controller.setKeepSize(false));
Q_UNUSED(setKeepSize(false));
} else if (ui->rbStringVisible->isChecked()) {
Q_UNUSED(emit _plg->controller.setStringVisible(false));
Q_UNUSED(setStringVisible(false));
}
}

View File

@ -21,7 +21,7 @@
#ifndef TESTFORM_H
#define TESTFORM_H
#include "iwingplugin.h"
#include "WingPlugin/iwingplugin.h"
#include <QWidget>
@ -29,7 +29,7 @@ namespace Ui {
class TestForm;
}
class TestForm : public QWidget {
class TestForm : public QWidget, public WingHex::IWingPluginAPICalls {
Q_OBJECT
public:
@ -130,10 +130,8 @@ private:
private:
Ui::TestForm *ui;
WingHex::WingPlugin::DataVisual::ClickedCallBack _click;
WingHex::WingPlugin::DataVisual::DoubleClickedCallBack _dblclick;
WingHex::IWingPlugin *_plg;
WingHex::ClickedCallBack _click;
WingHex::ClickedCallBack _dblclick;
};
#endif // TESTFORM_H

View File

@ -25,6 +25,7 @@
#include "testwingeditorviewwidget.h"
#include <QApplication>
#include <QMenu>
// 注意:所有提供的脚本接口函数都不是线程安全的,只是测试
@ -181,19 +182,17 @@ TestPlugin::~TestPlugin() { destoryTestShareMem(); }
int TestPlugin::sdkVersion() const { return WingHex::SDKVERSION; }
const QString TestPlugin::signature() const { return WingHex::WINGSUMMER; }
bool TestPlugin::init(const std::unique_ptr<QSettings> &set) {
auto v = set->value("Test", 0).toInt();
// 如果你之前启动过且正常推出,这个值一定是 5
qDebug() << v;
// 和日志与 UI 相关的接口此时可用,剩余的 API 初始化成功才可用
_tform = emit createDialog(new TestForm(this));
_tform = createDialog(new TestForm(this));
if (_tform == nullptr) {
return false;
}
_tform->setWindowFlag(Qt::WindowStaysOnTopHint);
_tform->setMaximumHeight(500);
using TBInfo = WingHex::WingRibbonToolBoxInfo;
@ -239,7 +238,7 @@ bool TestPlugin::init(const std::unique_ptr<QSettings> &set) {
QStringLiteral("(%1, %2)").arg(i).arg(y));
connect(tb, &QToolButton::clicked, this, [this] {
auto tb = qobject_cast<QToolButton *>(sender());
emit msgbox.information(nullptr, tr("Click"), tb->text());
information(nullptr, tr("Click"), tb->text());
});
tbtb.tools.append(tb);
}
@ -287,7 +286,7 @@ bool TestPlugin::init(const std::unique_ptr<QSettings> &set) {
auto a = new QAction(
micon, QStringLiteral("Test - ") + QString::number(i), _tmenu);
connect(a, &QAction::triggered, this, [this, a]() {
emit msgbox.information(nullptr, QStringLiteral("Test"), a->text());
information(nullptr, QStringLiteral("Test"), a->text());
});
_tmenu->addAction(a);
}
@ -447,9 +446,8 @@ TestPlugin::colorTable(const QList<void *> &params) {
auto invoked =
invokeService(QStringLiteral("WingAngelAPI"), "vector2AsArray",
WINGAPI_RETURN_ARG(void *, array),
WINGAPI_ARG(MetaType, MetaType::Color),
WINGAPI_ARG(QVector<void *>, colors));
WINGAPI_RETURN_ARG(array), WINGAPI_ARG(MetaType::Color),
WINGAPI_ARG(colors));
if (invoked) {
if (array) {
qDeleteAll(colors);
@ -513,10 +511,10 @@ QVariant TestPlugin::testCrash(const QVariantList &params) {
return {};
}
void TestPlugin::test_a() { emit debug(__FUNCTION__); }
void TestPlugin::test_a() { debug(__FUNCTION__); }
void TestPlugin::test_b(const QString &b) {
emit warn(__FUNCTION__ + QStringLiteral(" : ") % b);
warn(__FUNCTION__ + QStringLiteral(" : ") % b);
}
void TestPlugin::test_c(const QVector<int> &c) {
@ -531,7 +529,7 @@ void TestPlugin::test_c(const QVector<int> &c) {
content += QStringLiteral(" }");
emit warn(content);
warn(content);
}
void TestPlugin::test_d(const QVariantHash &d) {
@ -546,29 +544,30 @@ void TestPlugin::test_d(const QVariantHash &d) {
content += hash.join(", ");
}
content += QStringLiteral(" }");
emit warn(content);
warn(content);
}
bool TestPlugin::test_e() {
emit warn(__FUNCTION__);
warn(__FUNCTION__);
return true;
}
QByteArray TestPlugin::test_f() {
emit warn(__FUNCTION__);
return WingHex::WINGSUMMER.toLatin1();
warn(__FUNCTION__);
return "wingsummer";
}
QString TestPlugin::test_g() {
emit warn(__FUNCTION__);
return WingHex::WINGSUMMER;
warn(__FUNCTION__);
return "wingsummer";
}
QVariantHash TestPlugin::test_h() {
QVariantHash hash;
auto t = WingHex::WINGSUMMER.length();
constexpr auto str = "wingsummer";
auto t = qstrlen(str);
for (int i = 0; i < t; ++i) {
hash.insert(WingHex::WINGSUMMER.at(i), i);
hash.insert(QChar(str[i]), i);
}
return hash;
}
@ -605,8 +604,8 @@ void TestPlugin::destoryTestShareMem() {
}
void TestPlugin::printLogTestSharedMemData() {
emit warn(QByteArray(reinterpret_cast<const char *>(_tsharemem->data()), 20)
.toHex(' '));
warn(QByteArray(reinterpret_cast<const char *>(_tsharemem->data()), 20)
.toHex(' '));
}
void TestPlugin::setPluginMetaTestEnabled(bool b) {
@ -614,7 +613,7 @@ void TestPlugin::setPluginMetaTestEnabled(bool b) {
ENABLE_META = b;
for (auto &i : TestWingEditorViewWidget::instances()) {
i->setEnableMeta(b);
emit i->docSaved(false);
i->docSaved(false);
}
}
}
@ -644,8 +643,8 @@ WingHex::IWingPlugin::RegisteredEvents TestPlugin::registeredEvents() const {
void TestPlugin::eventReady() {
bool ret;
emit invokeService(
invokeService(
QStringLiteral("WingAngelAPI"), "execCode", Qt::AutoConnection,
WINGAPI_RETURN_ARG(bool, ret),
WINGAPI_ARG(QString, R"(print("Hello, this is TestPlugin!");)"));
WINGAPI_RETURN_ARG(ret),
WINGAPI_ARG(QString(R"(print("Hello, this is TestPlugin!");)")));
}

View File

@ -21,7 +21,7 @@
#ifndef TESTPLUGIN_H
#define TESTPLUGIN_H
#include "iwingplugin.h"
#include "WingPlugin/iwingplugin.h"
#include <QSharedMemory>
@ -41,7 +41,6 @@ public:
// IWingPlugin interface (必须)
public:
virtual int sdkVersion() const override;
virtual const QString signature() 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;

View File

@ -1,7 +1,7 @@
#ifndef TESTPLUGINPAGE_H
#define TESTPLUGINPAGE_H
#include "settingpage.h"
#include "WingPlugin/settingpage.h"
#include <QLabel>

View File

@ -1,7 +1,7 @@
#ifndef TESTSETTINGPAGE_H
#define TESTSETTINGPAGE_H
#include "settingpage.h"
#include "WingPlugin/settingpage.h"
#include <QLabel>

View File

@ -1,6 +1,5 @@
#include "testtablemodel.h"
#include "iwingplugin.h"
#include "WingPlugin/iwingpluginbase.h"
TestTableModel::TestTableModel(QObject *parent) : QAbstractTableModel(parent) {}

View File

@ -33,9 +33,8 @@ QString TestWingEditorViewWidget::Creator::id() const {
}
void TestWingEditorViewWidget::toggled(bool isVisible) {
plugin()->emit warn(
__FUNCTION__ + QStringLiteral(": ") +
(isVisible ? QStringLiteral("true") : QStringLiteral("false")));
warn(__FUNCTION__ + QStringLiteral(": ") +
(isVisible ? QStringLiteral("true") : QStringLiteral("false")));
}
WingHex::WingEditorViewWidget *TestWingEditorViewWidget::clone() {
@ -43,20 +42,16 @@ WingHex::WingEditorViewWidget *TestWingEditorViewWidget::clone() {
}
void TestWingEditorViewWidget::loadState(const QByteArray &state) {
plugin()->emit warn(__FUNCTION__ + QStringLiteral(": ") +
QString::fromUtf8(state));
warn(__FUNCTION__ + QStringLiteral(": ") + QString::fromUtf8(state));
}
bool TestWingEditorViewWidget::hasUnsavedState() { return m_unSaved; }
QByteArray TestWingEditorViewWidget::saveState() {
return WingHex::WINGSUMMER.toUtf8();
}
QByteArray TestWingEditorViewWidget::saveState() { return "wingsummer"; }
void TestWingEditorViewWidget::onWorkSpaceNotify(bool isWorkSpace) {
plugin()->emit warn(
__FUNCTION__ + QStringLiteral(": ") +
(isWorkSpace ? QStringLiteral("true") : QStringLiteral("false")));
warn(__FUNCTION__ + QStringLiteral(": ") +
(isWorkSpace ? QStringLiteral("true") : QStringLiteral("false")));
}
QList<TestWingEditorViewWidget *> TestWingEditorViewWidget::instances() {

View File

@ -1,7 +1,7 @@
#ifndef TESTWINGEDITORVIEWWIDGET_H
#define TESTWINGEDITORVIEWWIDGET_H
#include "iwingplugin.h"
#include "WingPlugin/iwingplugin.h"
#include <QLabel>

41
WingPlugin/CMakeLists.txt Normal file
View File

@ -0,0 +1,41 @@
cmake_minimum_required(VERSION 3.16)
project(WingPlugin LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
add_library(
WingPlugin SHARED
iwingplugin.cpp
iwingplugin.h
iwingpluginbase.h
iwingpluginbase.cpp
wingplugin_global.h
wingcore.h
wingplugincalls.h
wingplugincalls.cpp
wingplugincalls_p.h
wingeditorviewwidget.h
wingeditorviewwidget.cpp
settingpage.h
iwingdevice.h
iwingdevice.cpp
settingpage.cpp
iwingpluginbasecalls.h
iwingpluginbasecalls.cpp
iwingplugincalls.h
iwingplugincalls.cpp
wingplugincallconvertor.h wingplugincallconvertor.cpp)
target_link_libraries(WingPlugin PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
target_include_directories(WingPlugin PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
target_compile_definitions(WingPlugin PRIVATE WINGPLUGIN_LIBRARY)

View File

@ -0,0 +1,33 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** You can redistribute this file and/or modify it under the terms of the
** BSD 3-Clause.
**
** THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** =============================================================================
*/
#include "iwingdevice.h"
using namespace WingHex;
IWingDevice::IWingDevice(QObject *parent) : IWingPluginBase() {}
QIcon IWingDevice::supportedFileIcon() const { return {}; }
QString IWingDevice::onOpenFileBegin() { return {}; }
WingIODevice::WingIODevice(QObject *parent) : QIODevice(parent) {}
bool WingIODevice::keepSize() const { return false; }

View File

@ -23,29 +23,32 @@
#include "iwingpluginbase.h"
#include <optional>
#include <QIODevice>
namespace WingHex {
class WingIODevice : public QIODevice {
class WINGPLUGIN_EXPORT WingIODevice : public QIODevice {
Q_OBJECT
public:
WingIODevice(QObject *parent = nullptr) : QIODevice(parent) {}
WingIODevice(QObject *parent = nullptr);
// can not change size during editing (default: changing-abled)
virtual bool keepSize() const { return false; };
virtual bool keepSize() const;
};
class IWingDevice : public IWingPluginBase {
class WINGPLUGIN_EXPORT IWingDevice : public IWingPluginBase {
Q_OBJECT
public:
explicit IWingDevice(QObject *parent = nullptr);
public:
virtual QString supportedFileExtDisplayName() const = 0;
virtual QIcon supportedFileIcon() const { return {}; };
virtual QIcon supportedFileIcon() const;
public:
virtual QString onOpenFileBegin() { return {}; }
virtual QString onOpenFileBegin();
virtual WingIODevice *onOpenFile(const QString &path) = 0;

113
WingPlugin/iwingplugin.cpp Normal file
View File

@ -0,0 +1,113 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** You can redistribute this file and/or modify it under the terms of the
** BSD 3-Clause.
**
** THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** =============================================================================
*/
#include "iwingplugin.h"
using namespace WingHex;
IWingPlugin::IWingPlugin() : IWingPluginBase(), IWingPluginCalls(this) {}
QVariant IWingPlugin::getScriptCallError(int errCode, const QString &msg) {
ScriptCallError err;
err.errorCode = errCode;
err.errmsg = msg;
return QVariant::fromValue(err);
}
IWingPlugin::RegisteredEvents IWingPlugin::registeredEvents() const {
return RegisteredEvent::None;
}
QMenu *IWingPlugin::registeredHexContextMenu() const { return nullptr; }
QList<WingRibbonToolBoxInfo> IWingPlugin::registeredRibbonTools() const {
return {};
}
QHash<SettingPage *, bool> IWingPlugin::registeredSettingPages() const {
return {};
}
QList<QSharedPointer<WingEditorViewWidget::Creator>>
IWingPlugin::registeredEditorViewWidgets() const {
return {};
}
QHash<QString, QList<QPair<QString, int>>>
IWingPlugin::registeredScriptEnums() const {
return {};
}
QStringList IWingPlugin::registerScriptMarcos() const { return {}; }
void IWingPlugin::eventSelectionChanged(const QByteArrayList &selections,
bool isPreview) {
Q_UNUSED(selections);
Q_UNUSED(isPreview);
}
void IWingPlugin::eventCursorPositionChanged(const HexPosition &pos) {
Q_UNUSED(pos);
}
void IWingPlugin::eventPluginFile(PluginFileEvent e, FileType type,
const QString &newfileName, int handle,
const QString &oldfileName) {
Q_UNUSED(e);
Q_UNUSED(newfileName);
Q_UNUSED(oldfileName);
Q_UNUSED(handle);
Q_UNUSED(type);
}
void IWingPlugin::eventReady() {}
bool IWingPlugin::eventClosing() { return true; }
bool IWingPlugin::eventOnScriptPragma(const QString &script,
const QStringList &comments) {
Q_UNUSED(script);
Q_UNUSED(comments);
return false;
}
void IWingPlugin::eventOnScriptPragmaInit() {}
QHash<QString, IWingPlugin::UNSAFE_SCFNPTR>
IWingPlugin::registeredScriptUnsafeFns() const {
return {};
}
QHash<QString, IWingPlugin::ScriptFnInfo>
IWingPlugin::registeredScriptFns() const {
return {};
}
ScriptCallError IWingPlugin::generateScriptCallError(int errCode,
const QString &msg) {
ScriptCallError err;
err.errorCode = errCode;
err.errmsg = msg;
return err;
}

223
WingPlugin/iwingplugin.h Normal file
View File

@ -0,0 +1,223 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** You can redistribute this file and/or modify it under the terms of the
** BSD 3-Clause.
**
** THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** =============================================================================
*/
#ifndef IWINGPLUGIN_H
#define IWINGPLUGIN_H
#include "WingPlugin/iwingplugincalls.h"
#include "iwingpluginbase.h"
#include "wingeditorviewwidget.h"
#include "wingplugin_global.h"
#include <variant>
#include <QToolButton>
namespace WingHex {
class IWingPlugin;
struct WINGPLUGIN_EXPORT SenderInfo {
QString plgcls;
QString puid;
QVariant meta;
};
struct WINGPLUGIN_EXPORT WingRibbonToolBoxInfo {
struct WINGPLUGIN_EXPORT RibbonCatagories {
const QString FILE = QStringLiteral("File");
const QString EDIT = QStringLiteral("Edit");
const QString VIEW = QStringLiteral("View");
const QString SCRIPT = QStringLiteral("Script");
const QString PLUGIN = QStringLiteral("Plugin");
const QString SETTING = QStringLiteral("Setting");
const QString ABOUT = QStringLiteral("About");
};
QString catagory;
QString displayName;
struct WINGPLUGIN_EXPORT Toolbox {
QString name;
QList<QToolButton *> tools;
};
QList<Toolbox> toolboxs;
};
struct WINGPLUGIN_EXPORT ScriptCallError {
int errorCode;
QString errmsg;
};
class SettingPage;
class WINGPLUGIN_EXPORT IWingPlugin : public IWingPluginBase,
public IWingPluginCalls {
Q_OBJECT
public:
IWingPlugin();
public:
using ScriptFn = std::function<QVariant(const QVariantList &)>;
using UNSAFE_RET =
std::variant<std::monostate, bool, quint8, quint16, quint32, quint64,
float, double, void *, ScriptCallError>;
using UNSAFE_SCFNPTR = std::function<UNSAFE_RET(const QList<void *> &)>;
enum MetaType : uint {
Void,
Bool,
Int,
Int32 = Int,
UInt,
UInt32 = UInt,
Int8,
UInt8,
Int16,
UInt16,
Int64,
UInt64,
Float,
Double,
String,
Char,
Byte,
Color,
Map, // QVariantMap -> dictionary
Hash, // QVariantHash -> dictionary
MetaMax, // reserved
MetaTypeMask = 0xFFFFF,
Array = 0x100000, // QVector<?> -> array<?>
List = 0x200000, // QList<?> -> array<?>
};
static_assert(MetaType::MetaMax < MetaType::Array);
struct ScriptFnInfo {
MetaType ret;
QVector<QPair<MetaType, QString>> params;
ScriptFn fn;
};
enum class RegisteredEvent : uint {
None,
AppReady = 1u,
AppClosing = 1u << 1,
SelectionChanged = 1u << 2,
CursorPositionChanged = 1u << 3,
FileOpened = 1u << 4,
FileSaved = 1u << 5,
FileSwitched = 1u << 6,
FileClosed = 1u << 7,
ScriptPragma = 1u << 8,
PluginFileOpened = 1u << 9,
PluginFileClosed = 1u << 10,
ScriptUnSafeFnRegistering = 1u << 11,
ScriptPragmaInit = 1u << 12
};
Q_DECLARE_FLAGS(RegisteredEvents, RegisteredEvent)
enum class PluginFileEvent {
Opened,
Saved,
Exported,
Switched,
Closed,
PluginOpened,
PluginClosed
};
enum class FileType { Invalid, File, Extension };
Q_ENUM(FileType)
public:
ScriptCallError generateScriptCallError(int errCode, const QString &msg);
QVariant getScriptCallError(int errCode, const QString &msg);
public:
virtual ~IWingPlugin() = default;
virtual RegisteredEvents registeredEvents() const;
public:
virtual QMenu *registeredHexContextMenu() const;
virtual QList<WingRibbonToolBoxInfo> registeredRibbonTools() const;
// QMap<page, whether is visible in setting tab>
virtual QHash<SettingPage *, bool> registeredSettingPages() const;
virtual QList<QSharedPointer<WingEditorViewWidget::Creator>>
registeredEditorViewWidgets() const;
public:
// QHash< function-name, fn >
virtual QHash<QString, ScriptFnInfo> registeredScriptFns() const;
// A hacking way to register script function (Generic_Call)
// This registering way is not safe. There is no
// other checking except function's signature.
// You should handle your all the types and pay yourself.
// You should set RegisteredEvent::ScriptFnRegistering ON to enable it.
// QHash< function-name, fn >
virtual QHash<QString, UNSAFE_SCFNPTR> registeredScriptUnsafeFns() const;
// QHash< enum , members >
virtual QHash<QString, QList<QPair<QString, int>>>
registeredScriptEnums() const;
// Note: must be valid identifier
virtual QStringList registerScriptMarcos() const;
public:
virtual void eventSelectionChanged(const QByteArrayList &selections,
bool isPreview);
virtual void eventCursorPositionChanged(const WingHex::HexPosition &pos);
virtual void eventPluginFile(PluginFileEvent e, FileType type,
const QString &newfileName, int handle,
const QString &oldfileName);
virtual void eventReady();
virtual bool eventClosing();
public:
virtual bool eventOnScriptPragma(const QString &script,
const QStringList &comments);
virtual void eventOnScriptPragmaInit();
};
} // namespace WingHex
Q_DECLARE_METATYPE(WingHex::SenderInfo)
Q_DECLARE_METATYPE(WingHex::ScriptCallError)
Q_DECLARE_INTERFACE(WingHex::IWingPlugin, "com.wingsummer.iwingplugin")
#endif // IWINGPLUGIN_H

View File

@ -0,0 +1,47 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** You can redistribute this file and/or modify it under the terms of the
** BSD 3-Clause.
**
** THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** =============================================================================
*/
#include "iwingpluginbase.h"
#include <QCoreApplication>
#include <QDialog>
#include <QMetaMethod>
using namespace WingHex;
IWingPluginBase::IWingPluginBase() : IWingPluginBaseCalls(this) {}
QIcon IWingPluginBase::pluginIcon() const { return {}; }
QString IWingPluginBase::retranslate(const QString &str) { return str; }
QList<WingDockWidgetInfo> IWingPluginBase::registeredDockWidgets() const {
return {};
}
QList<PluginPage *> IWingPluginBase::registeredPages() const { return {}; }
QString WingHex::PLUGINDIR() {
return QCoreApplication::applicationDirPath() + QStringLiteral("/plugin");
}
QString WingHex::HOSTRESPIMG(const QString &name, const QString &suffix) {
return QStringLiteral(":/com.wingsummer.winghex/images/") + name + suffix;
}

View File

@ -0,0 +1,68 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** You can redistribute this file and/or modify it under the terms of the
** BSD 3-Clause.
**
** THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** =============================================================================
*/
#ifndef IWINGPLUGINBASE_H
#define IWINGPLUGINBASE_H
#include "WingPlugin/iwingpluginbasecalls.h"
#include "wingplugin_global.h"
#include <QSettings>
namespace WingHex {
Q_DECL_UNUSED constexpr auto SDKVERSION = 15;
WINGPLUGIN_EXPORT QString PLUGINDIR();
WINGPLUGIN_EXPORT QString HOSTRESPIMG(
const QString &name, const QString &suffix = QStringLiteral(".png"));
class PluginPage;
class WINGPLUGIN_EXPORT IWingPluginBase : public QObject,
public IWingPluginBaseCalls {
Q_OBJECT
public:
IWingPluginBase();
virtual ~IWingPluginBase() = default;
public:
virtual int sdkVersion() const = 0;
virtual bool init(const std::unique_ptr<QSettings> &set) = 0;
virtual void unload(std::unique_ptr<QSettings> &set) = 0;
virtual const QString pluginName() const = 0;
virtual QIcon pluginIcon() const;
virtual const QString pluginComment() const = 0;
virtual QString retranslate(const QString &str);
public:
virtual QList<WingDockWidgetInfo> registeredDockWidgets() const;
virtual QList<PluginPage *> registeredPages() const;
};
} // namespace WingHex
#endif // IWINGPLUGINBASE_H

View File

@ -0,0 +1,281 @@
#include "iwingpluginbasecalls.h"
#include "WingPlugin/wingcore.h"
#include "iwingpluginbase.h"
using namespace WingHex;
IWingPluginBaseCalls::IWingPluginBaseCalls(IWingPluginBase *const caller)
: WingPluginCalls(caller) {}
void IWingPluginBaseCalls::toast(const QPixmap &icon, const QString &message) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::toast);
m.invoke(callReceiver(), Qt::DirectConnection, getSenderObj(),
WINGAPI_ARG(icon), WINGAPI_ARG(message));
}
void IWingPluginBaseCalls::trace(const QString &message) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::trace);
m.invoke(callReceiver(), Qt::DirectConnection, getSenderObj(),
WINGAPI_ARG(message));
}
void IWingPluginBaseCalls::debug(const QString &message) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::debug);
m.invoke(callReceiver(), Qt::DirectConnection, getSenderObj(),
WINGAPI_ARG(message));
}
void IWingPluginBaseCalls::warn(const QString &message) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::warn);
m.invoke(callReceiver(), Qt::DirectConnection, getSenderObj(),
WINGAPI_ARG(message));
}
void IWingPluginBaseCalls::error(const QString &message) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::error);
m.invoke(callReceiver(), Qt::DirectConnection, getSenderObj(),
WINGAPI_ARG(message));
}
void IWingPluginBaseCalls::info(const QString &message) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::info);
m.invoke(callReceiver(), Qt::DirectConnection, getSenderObj(),
WINGAPI_ARG(message));
}
bool IWingPluginBaseCalls::raiseDockWidget(QWidget *w) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::raiseDockWidget);
bool ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(w));
return ret;
}
QDialog *IWingPluginBaseCalls::createDialog(QWidget *content) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::createDialog);
QDialog *ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(content));
return ret;
}
void IWingPluginBaseCalls::aboutQt(QWidget *parent, const QString &title) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::aboutQt);
m.invoke(callReceiver(), Qt::DirectConnection, getSenderObj(),
WINGAPI_ARG(parent), WINGAPI_ARG(title));
}
QMessageBox::StandardButton
IWingPluginBaseCalls::information(QWidget *parent, const QString &title,
const QString &text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::information);
QMessageBox::StandardButton ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(parent), WINGAPI_ARG(title),
WINGAPI_ARG(text), WINGAPI_ARG(buttons),
WINGAPI_ARG(defaultButton));
return ret;
}
QMessageBox::StandardButton
IWingPluginBaseCalls::question(QWidget *parent, const QString &title,
const QString &text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::question);
QMessageBox::StandardButton ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(parent), WINGAPI_ARG(title),
WINGAPI_ARG(text), WINGAPI_ARG(buttons),
WINGAPI_ARG(defaultButton));
return ret;
}
QMessageBox::StandardButton
IWingPluginBaseCalls::warning(QWidget *parent, const QString &title,
const QString &text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::warning);
QMessageBox::StandardButton ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(parent), WINGAPI_ARG(title),
WINGAPI_ARG(text), WINGAPI_ARG(buttons),
WINGAPI_ARG(defaultButton));
return ret;
}
QMessageBox::StandardButton
IWingPluginBaseCalls::critical(QWidget *parent, const QString &title,
const QString &text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::critical);
QMessageBox::StandardButton ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(parent), WINGAPI_ARG(title),
WINGAPI_ARG(text), WINGAPI_ARG(buttons),
WINGAPI_ARG(defaultButton));
return ret;
}
void IWingPluginBaseCalls::about(QWidget *parent, const QString &title,
const QString &text) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::about);
m.invoke(callReceiver(), Qt::DirectConnection, getSenderObj(),
WINGAPI_ARG(parent), WINGAPI_ARG(title), WINGAPI_ARG(text));
}
QMessageBox::StandardButton
IWingPluginBaseCalls::msgbox(QWidget *parent, QMessageBox::Icon icon,
const QString &title, const QString &text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::msgbox);
QMessageBox::StandardButton ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(parent), WINGAPI_ARG(icon),
WINGAPI_ARG(title), WINGAPI_ARG(text), WINGAPI_ARG(buttons),
WINGAPI_ARG(defaultButton));
return ret;
}
QString IWingPluginBaseCalls::getText(QWidget *parent, const QString &title,
const QString &label,
QLineEdit::EchoMode echo,
const QString &text, bool *ok,
Qt::InputMethodHints inputMethodHints) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::getText);
QString ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(parent), WINGAPI_ARG(title),
WINGAPI_ARG(label), WINGAPI_ARG(echo), WINGAPI_ARG(text),
WINGAPI_ARG(ok), WINGAPI_ARG(inputMethodHints));
return ret;
}
QString IWingPluginBaseCalls::getMultiLineText(
QWidget *parent, const QString &title, const QString &label,
const QString &text, bool *ok, Qt::InputMethodHints inputMethodHints) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::getMultiLineText);
QString ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(parent), WINGAPI_ARG(title),
WINGAPI_ARG(label), WINGAPI_ARG(text), WINGAPI_ARG(ok),
WINGAPI_ARG(inputMethodHints));
return ret;
}
QString IWingPluginBaseCalls::getItem(QWidget *parent, const QString &title,
const QString &label,
const QStringList &items, int current,
bool editable, bool *ok,
Qt::InputMethodHints inputMethodHints) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::getItem);
QString ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(parent), WINGAPI_ARG(title),
WINGAPI_ARG(label), WINGAPI_ARG(items), WINGAPI_ARG(current),
WINGAPI_ARG(editable), WINGAPI_ARG(ok),
WINGAPI_ARG(inputMethodHints));
return ret;
}
int IWingPluginBaseCalls::getInt(QWidget *parent, const QString &title,
const QString &label, int value, int minValue,
int maxValue, int step, bool *ok) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::getInt);
int ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(parent), WINGAPI_ARG(title),
WINGAPI_ARG(label), WINGAPI_ARG(value), WINGAPI_ARG(minValue),
WINGAPI_ARG(maxValue), WINGAPI_ARG(step), WINGAPI_ARG(ok));
return ret;
}
double IWingPluginBaseCalls::getDouble(QWidget *parent, const QString &title,
const QString &label, double value,
double minValue, double maxValue,
int decimals, bool *ok, double step) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::getDouble);
double ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(parent), WINGAPI_ARG(title),
WINGAPI_ARG(label), WINGAPI_ARG(value), WINGAPI_ARG(minValue),
WINGAPI_ARG(maxValue), WINGAPI_ARG(decimals), WINGAPI_ARG(ok),
WINGAPI_ARG(step));
return ret;
}
QString IWingPluginBaseCalls::getExistingDirectory(
QWidget *parent, const QString &caption, const QString &dir,
QFileDialog::Options options) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::getExistingDirectory);
QString ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(parent), WINGAPI_ARG(caption),
WINGAPI_ARG(dir), WINGAPI_ARG(options));
return ret;
}
QString IWingPluginBaseCalls::getOpenFileName(QWidget *parent,
const QString &caption,
const QString &dir,
const QString &filter,
QString *selectedFilter,
QFileDialog::Options options) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::getOpenFileName);
QString ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(parent), WINGAPI_ARG(caption),
WINGAPI_ARG(dir), WINGAPI_ARG(filter), WINGAPI_ARG(selectedFilter),
WINGAPI_ARG(options));
return ret;
}
QStringList IWingPluginBaseCalls::getOpenFileNames(
QWidget *parent, const QString &caption, const QString &dir,
const QString &filter, QString *selectedFilter,
QFileDialog::Options options) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::getOpenFileNames);
QStringList ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(parent), WINGAPI_ARG(caption),
WINGAPI_ARG(dir), WINGAPI_ARG(filter), WINGAPI_ARG(selectedFilter),
WINGAPI_ARG(options));
return ret;
}
QString IWingPluginBaseCalls::getSaveFileName(QWidget *parent,
const QString &caption,
const QString &dir,
const QString &filter,
QString *selectedFilter,
QFileDialog::Options options) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::getSaveFileName);
QString ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(parent), WINGAPI_ARG(caption),
WINGAPI_ARG(dir), WINGAPI_ARG(filter), WINGAPI_ARG(selectedFilter),
WINGAPI_ARG(options));
return ret;
}
QColor IWingPluginBaseCalls::getColor(const QString &caption, QWidget *parent) {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::getColor);
QColor ret;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(ret),
getSenderObj(), WINGAPI_ARG(caption), WINGAPI_ARG(parent));
return ret;
}
AppTheme IWingPluginBaseCalls::currentAppTheme() {
SETUP_CALL_CONTEXT(&IWingPluginBaseCalls::currentAppTheme);
WingHex::AppTheme theme;
m.invoke(callReceiver(), Qt::DirectConnection, WINGAPI_RETURN_ARG(theme),
getSenderObj());
return theme;
}

View File

@ -1,58 +1,43 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** You can redistribute this file and/or modify it under the terms of the
** BSD 3-Clause.
**
** THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** =============================================================================
*/
#ifndef IWINGPLUGINBASECALLS_H
#define IWINGPLUGINBASECALLS_H
#ifndef IWINGPLUGINBASE_H
#define IWINGPLUGINBASE_H
#include "WingPlugin/wingplugincallconvertor.h"
#include "wingplugincalls.h"
#include "settingpage.h"
#include <QCoreApplication>
#include <QFileDialog>
#include <QIcon>
#include <QInputDialog>
#include <QLineEdit>
#include <QList>
#include <QMessageBox>
#include <QObject>
#include <QSettings>
#include <QVersionNumber>
namespace WingHex {
using qusizetype = QIntegerForSizeof<std::size_t>::Unsigned;
class IWingPluginBase;
Q_DECL_UNUSED constexpr auto SDKVERSION = 15;
class WINGPLUGIN_EXPORT IWingPluginBaseCalls : public WingPluginCalls {
public:
explicit IWingPluginBaseCalls(IWingPluginBase *const caller);
Q_DECL_UNUSED static QString PLUGINDIR() {
return QCoreApplication::applicationDirPath() + QStringLiteral("/plugin");
}
public:
void toast(const QPixmap &icon, const QString &message);
void trace(const QString &message);
void debug(const QString &message);
void warn(const QString &message);
void error(const QString &message);
void info(const QString &message);
Q_DECL_UNUSED static QString
HOSTRESPIMG(const QString &name,
const QString &suffix = QStringLiteral(".png")) {
return QStringLiteral(":/com.wingsummer.winghex/images/") + name + suffix;
}
bool raiseDockWidget(QWidget *w);
namespace WingPlugin {
// theme
WingHex::AppTheme currentAppTheme();
class MessageBox : public QObject {
Q_OBJECT
signals:
// not available for AngelScript
// only for plugin UI extenstion
QDialog *createDialog(QWidget *content);
public:
void aboutQt(QWidget *parent = nullptr, const QString &title = QString());
QMessageBox::StandardButton information(
@ -83,11 +68,8 @@ signals:
const QString &text,
QMessageBox::StandardButtons buttons = QMessageBox::NoButton,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
};
class InputBox : public QObject {
Q_OBJECT
signals:
public:
Q_REQUIRED_RESULT QString
getText(QWidget *parent, const QString &title, const QString &label,
QLineEdit::EchoMode echo = QLineEdit::Normal,
@ -116,11 +98,8 @@ signals:
double maxValue = 2147483647,
int decimals = 1, bool *ok = nullptr,
double step = 1);
};
class FileDialog : public QObject {
Q_OBJECT
signals:
public:
Q_REQUIRED_RESULT QString getExistingDirectory(
QWidget *parent = nullptr, const QString &caption = QString(),
const QString &dir = QString(),
@ -143,90 +122,17 @@ signals:
const QString &dir = QString(), const QString &filter = QString(),
QString *selectedFilter = nullptr,
QFileDialog::Options options = QFileDialog::Options());
};
class ColorDialog : public QObject {
Q_OBJECT
signals:
public:
Q_REQUIRED_RESULT QColor getColor(const QString &caption,
QWidget *parent = nullptr);
};
} // namespace WingPlugin
struct WingDependency {
QString puid;
QVersionNumber version;
};
struct WingDockWidgetInfo {
QString widgetName;
QString displayName;
QWidget *widget = nullptr;
Qt::DockWidgetArea area = Qt::DockWidgetArea::NoDockWidgetArea;
};
#ifdef WING_SERVICE
#undef WING_SERVICE
#endif
#define WING_SERVICE Q_INVOKABLE
const auto WINGSUMMER = QStringLiteral("wingsummer");
enum class AppTheme { Dark, Light };
class IWingPluginBase : public QObject {
Q_OBJECT
public:
virtual ~IWingPluginBase() = default;
public:
virtual int sdkVersion() const = 0;
virtual const QString signature() const = 0;
virtual bool init(const std::unique_ptr<QSettings> &set) = 0;
virtual void unload(std::unique_ptr<QSettings> &set) = 0;
virtual const QString pluginName() const = 0;
virtual QIcon pluginIcon() const { return {}; }
virtual const QString pluginComment() const = 0;
virtual QString retranslate(const QString &str) { return str; }
public:
virtual QList<WingDockWidgetInfo> registeredDockWidgets() const {
return {};
}
virtual QList<PluginPage *> registeredPages() const { return {}; }
signals:
void toast(const QPixmap &icon, const QString &message);
void trace(const QString &message);
void debug(const QString &message);
void warn(const QString &message);
void error(const QString &message);
void info(const QString &message);
bool raiseDockWidget(QWidget *w);
// theme
WingHex::AppTheme currentAppTheme();
// not available for AngelScript
// only for plugin UI extenstion
QDialog *createDialog(QWidget *content);
public:
WingPlugin::MessageBox msgbox;
WingPlugin::InputBox inputbox;
WingPlugin::FileDialog filedlg;
WingPlugin::ColorDialog colordlg;
};
} // namespace WingHex
#endif // IWINGPLUGINBASE_H
Q_DECLARE_METATYPE(QMessageBox::StandardButtons)
Q_DECLARE_METATYPE(QMessageBox::StandardButton)
Q_DECLARE_METATYPE(bool *)
Q_DECLARE_METATYPE(QString *)
#endif // IWINGPLUGINBASECALLS_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,265 @@
#ifndef IWINGPLUGINCALLS_H
#define IWINGPLUGINCALLS_H
#include "WingPlugin/iwingpluginbasecalls.h"
#include <QAbstractItemModel>
namespace WingHex {
struct WINGPLUGIN_EXPORT HexPosition {
qsizetype line;
int column;
quint8 lineWidth;
int nibbleindex;
Q_REQUIRED_RESULT qsizetype offset() const;
qsizetype operator-(const HexPosition &rhs) const;
bool operator==(const HexPosition &rhs) const;
bool operator!=(const HexPosition &rhs) const;
};
class IWingPlugin;
class WINGPLUGIN_EXPORT IWingPluginCalls : public WingPluginCalls {
public:
explicit IWingPluginCalls(IWingPlugin *const caller);
public:
bool existsServiceHost(const QString &puid);
bool invokeService(const QString &puid, const char *method,
Qt::ConnectionType type, QGenericReturnArgument ret,
QGenericArgument val0 = QGenericArgument(nullptr),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument());
bool invokeService(const QString &puid, const char *member,
QGenericReturnArgument ret,
QGenericArgument val0 = QGenericArgument(nullptr),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument());
bool invokeService(const QString &puid, const char *member,
Qt::ConnectionType type, QGenericArgument val0,
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument());
bool invokeService(const QString &puid, const char *member,
QGenericArgument val0,
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument());
public:
Q_REQUIRED_RESULT bool isCurrentDocEditing();
Q_REQUIRED_RESULT QString currentDocFilename();
// document
Q_REQUIRED_RESULT bool isReadOnly();
Q_REQUIRED_RESULT bool isInsertionMode();
Q_REQUIRED_RESULT bool isKeepSize();
Q_REQUIRED_RESULT bool isLocked();
Q_REQUIRED_RESULT qsizetype documentLines();
Q_REQUIRED_RESULT qsizetype documentBytes();
Q_REQUIRED_RESULT WingHex::HexPosition currentPos();
Q_REQUIRED_RESULT qsizetype currentRow();
Q_REQUIRED_RESULT qsizetype currentColumn();
Q_REQUIRED_RESULT qsizetype currentOffset();
Q_REQUIRED_RESULT qsizetype selectedLength();
Q_REQUIRED_RESULT QByteArray selectedBytes(qsizetype index);
Q_REQUIRED_RESULT QByteArrayList selectionBytes();
Q_REQUIRED_RESULT WingHex::HexPosition selectionStart(qsizetype index);
Q_REQUIRED_RESULT WingHex::HexPosition selectionEnd(qsizetype index);
Q_REQUIRED_RESULT qsizetype selectionLength(qsizetype index);
Q_REQUIRED_RESULT qsizetype selectionCount();
Q_REQUIRED_RESULT bool stringVisible();
Q_REQUIRED_RESULT bool addressVisible();
Q_REQUIRED_RESULT bool headerVisible();
Q_REQUIRED_RESULT quintptr addressBase();
Q_REQUIRED_RESULT bool isModified();
Q_REQUIRED_RESULT qint8 readInt8(qsizetype offset);
Q_REQUIRED_RESULT qint16 readInt16(qsizetype offset);
Q_REQUIRED_RESULT qint32 readInt32(qsizetype offset);
Q_REQUIRED_RESULT qint64 readInt64(qsizetype offset);
Q_REQUIRED_RESULT float readFloat(qsizetype offset);
Q_REQUIRED_RESULT double readDouble(qsizetype offset);
Q_REQUIRED_RESULT QString readString(qsizetype offset,
const QString &encoding = {});
Q_REQUIRED_RESULT QByteArray readBytes(qsizetype offset, qsizetype count);
Q_REQUIRED_RESULT qsizetype findNext(qsizetype begin, const QByteArray &ba);
Q_REQUIRED_RESULT qsizetype findPrevious(qsizetype begin,
const QByteArray &ba);
Q_REQUIRED_RESULT QString bookMarkComment(qsizetype pos);
Q_REQUIRED_RESULT bool existBookMark(qsizetype pos);
public:
// document
Q_REQUIRED_RESULT bool switchDocument(int handle);
Q_REQUIRED_RESULT bool raiseDocument(int handle);
Q_REQUIRED_RESULT bool setLockedFile(bool b);
Q_REQUIRED_RESULT bool setKeepSize(bool b);
Q_REQUIRED_RESULT bool setStringVisible(bool b);
Q_REQUIRED_RESULT bool setAddressVisible(bool b);
Q_REQUIRED_RESULT bool setHeaderVisible(bool b);
Q_REQUIRED_RESULT bool setAddressBase(quintptr base);
Q_REQUIRED_RESULT bool beginMarco(const QString &txt = {});
bool endMarco();
Q_REQUIRED_RESULT bool writeInt8(qsizetype offset, qint8 value);
Q_REQUIRED_RESULT bool writeInt16(qsizetype offset, qint16 value);
Q_REQUIRED_RESULT bool writeInt32(qsizetype offset, qint32 value);
Q_REQUIRED_RESULT bool writeInt64(qsizetype offset, qint64 value);
Q_REQUIRED_RESULT bool writeFloat(qsizetype offset, float value);
Q_REQUIRED_RESULT bool writeDouble(qsizetype offset, double value);
Q_REQUIRED_RESULT bool writeString(qsizetype offset, const QString &value,
const QString &encoding = QString());
Q_REQUIRED_RESULT bool writeBytes(qsizetype offset, const QByteArray &data);
Q_REQUIRED_RESULT bool insertInt8(qsizetype offset, qint8 value);
Q_REQUIRED_RESULT bool insertInt16(qsizetype offset, qint16 value);
Q_REQUIRED_RESULT bool insertInt32(qsizetype offset, qint32 value);
Q_REQUIRED_RESULT bool insertInt64(qsizetype offset, qint64 value);
Q_REQUIRED_RESULT bool insertFloat(qsizetype offset, float value);
Q_REQUIRED_RESULT bool insertDouble(qsizetype offset, double value);
Q_REQUIRED_RESULT bool insertString(qsizetype offset, const QString &value,
const QString &encoding = QString());
Q_REQUIRED_RESULT bool insertBytes(qsizetype offset,
const QByteArray &data);
Q_REQUIRED_RESULT bool appendInt8(qint8 value);
Q_REQUIRED_RESULT bool appendInt16(qint16 value);
Q_REQUIRED_RESULT bool appendInt32(qint32 value);
Q_REQUIRED_RESULT bool appendInt64(qint64 value);
Q_REQUIRED_RESULT bool appendFloat(float value);
Q_REQUIRED_RESULT bool appendDouble(double value);
Q_REQUIRED_RESULT bool appendString(const QString &value,
const QString &encoding = QString());
Q_REQUIRED_RESULT bool appendBytes(const QByteArray &data);
Q_REQUIRED_RESULT bool removeBytes(qsizetype offset, qsizetype len);
// cursor
Q_REQUIRED_RESULT bool moveTo(qsizetype line, qsizetype column,
int nibbleindex = 1,
bool clearSelection = true);
Q_REQUIRED_RESULT bool moveTo(qsizetype offset, bool clearSelection = true);
Q_REQUIRED_RESULT bool select(qsizetype offset, qsizetype length,
SelectionMode mode = SelectionMode::Add);
Q_REQUIRED_RESULT bool setInsertionMode(bool isinsert);
// metadata
Q_REQUIRED_RESULT bool foreground(qsizetype begin, qsizetype length,
const QColor &fgcolor);
Q_REQUIRED_RESULT bool background(qsizetype begin, qsizetype length,
const QColor &bgcolor);
Q_REQUIRED_RESULT bool comment(qsizetype begin, qsizetype length,
const QString &comment);
Q_REQUIRED_RESULT bool metadata(qsizetype begin, qsizetype length,
const QColor &fgcolor,
const QColor &bgcolor,
const QString &comment);
Q_REQUIRED_RESULT bool removeMetadata(qsizetype offset);
Q_REQUIRED_RESULT bool clearMetadata();
Q_REQUIRED_RESULT bool setMetaVisible(bool b);
Q_REQUIRED_RESULT bool setMetafgVisible(bool b);
Q_REQUIRED_RESULT bool setMetabgVisible(bool b);
Q_REQUIRED_RESULT bool setMetaCommentVisible(bool b);
// mainwindow
Q_REQUIRED_RESULT WingHex::ErrFile newFile();
Q_REQUIRED_RESULT WingHex::ErrFile openFile(const QString &filename);
Q_REQUIRED_RESULT WingHex::ErrFile openExtFile(const QString &ext,
const QString &file);
WingHex::ErrFile closeHandle(int handle);
WingHex::ErrFile closeFile(int handle, bool force = false);
Q_REQUIRED_RESULT WingHex::ErrFile saveFile(int handle);
Q_REQUIRED_RESULT WingHex::ErrFile exportFile(int handle,
const QString &savename);
Q_REQUIRED_RESULT WingHex::ErrFile saveAsFile(int handle,
const QString &savename);
Q_REQUIRED_RESULT WingHex::ErrFile openCurrent();
Q_REQUIRED_RESULT WingHex::ErrFile closeCurrent(bool force = false);
Q_REQUIRED_RESULT WingHex::ErrFile saveCurrent();
Q_REQUIRED_RESULT WingHex::ErrFile exportCurrent(const QString &savename);
Q_REQUIRED_RESULT WingHex::ErrFile saveAsCurrent(const QString &savename);
// bookmark
Q_REQUIRED_RESULT bool addBookMark(qsizetype pos, const QString &comment);
Q_REQUIRED_RESULT bool modBookMark(qsizetype pos, const QString &comment);
Q_REQUIRED_RESULT bool removeBookMark(qsizetype pos);
Q_REQUIRED_RESULT bool clearBookMark();
// workspace
Q_REQUIRED_RESULT WingHex::ErrFile openWorkSpace(const QString &filename);
// extension
bool closeAllFiles();
public:
bool updateText(const QString &data, const QString &title = {});
bool updateTextList(const QStringList &data, const QString &title = {},
WingHex::ClickedCallBack clicked = {},
WingHex::ClickedCallBack dblClicked = {});
Q_REQUIRED_RESULT bool
updateTextTree(const QString &json, const QString &title = {},
WingHex::ClickedCallBack clicked = {},
WingHex::ClickedCallBack dblClicked = {});
Q_REQUIRED_RESULT bool
updateTextTable(const QString &json, const QStringList &headers,
const QStringList &headerNames = {},
const QString &title = {},
WingHex::ClickedCallBack clicked = {},
WingHex::ClickedCallBack dblClicked = {});
// API for Qt Plugin Only
Q_REQUIRED_RESULT bool
updateTextListByModel(QAbstractItemModel *model, const QString &title = {},
WingHex::ClickedCallBack clicked = {},
WingHex::ClickedCallBack dblClicked = {});
Q_REQUIRED_RESULT bool
updateTextTableByModel(QAbstractItemModel *model, const QString &title = {},
WingHex::ClickedCallBack clicked = {},
WingHex::ClickedCallBack dblClicked = {});
Q_REQUIRED_RESULT bool
updateTextTreeByModel(QAbstractItemModel *model, const QString &title = {},
WingHex::ClickedCallBack clicked = {},
WingHex::ClickedCallBack dblClicked = {});
};
class WINGPLUGIN_EXPORT IWingPluginAPICalls : public IWingPluginCalls,
public IWingPluginBaseCalls {
public:
explicit IWingPluginAPICalls(IWingPlugin *const caller);
};
} // namespace WingHex
Q_DECLARE_METATYPE(const char *)
Q_DECLARE_METATYPE(QGenericArgument)
Q_DECLARE_METATYPE(QGenericReturnArgument)
Q_DECLARE_METATYPE(QModelIndex)
Q_DECLARE_METATYPE(WingHex::ClickedCallBack)
Q_DECLARE_METATYPE(WingHex::HexPosition)
#endif // IWINGPLUGINCALLS_H

View File

@ -0,0 +1,29 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** You can redistribute this file and/or modify it under the terms of the
** BSD 3-Clause.
**
** THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** =============================================================================
*/
#include "settingpage.h"
using namespace WingHex;
PageBase::PageBase(QWidget *parent) : QWidget(parent) {}
SettingPage::SettingPage(QWidget *parent) : PageBase(parent) {}
PluginPage::PluginPage(QWidget *parent) : PageBase(parent) {}

View File

@ -18,13 +18,14 @@
#ifndef SETTINGPAGE_H
#define SETTINGPAGE_H
#include "wingplugin_global.h"
#include <QWidget>
namespace WingHex {
class PageBase : public QWidget {
class WINGPLUGIN_EXPORT PageBase : public QWidget {
public:
explicit PageBase(QWidget *parent = nullptr) : QWidget(parent) {}
explicit PageBase(QWidget *parent = nullptr);
public:
virtual QIcon categoryIcon() const = 0;
@ -32,10 +33,10 @@ public:
virtual QString id() const = 0;
};
class SettingPage : public PageBase {
class WINGPLUGIN_EXPORT SettingPage : public PageBase {
Q_OBJECT
public:
explicit SettingPage(QWidget *parent = nullptr) : PageBase(parent) {}
explicit SettingPage(QWidget *parent = nullptr);
signals:
void optionNeedRestartChanged();
@ -46,9 +47,9 @@ public:
virtual void cancel() = 0;
};
class PluginPage : public PageBase {
class WINGPLUGIN_EXPORT PluginPage : public PageBase {
public:
explicit PluginPage(QWidget *parent = nullptr) : PageBase(parent) {}
explicit PluginPage(QWidget *parent = nullptr);
};
} // namespace WingHex

72
WingPlugin/wingcore.h Normal file
View File

@ -0,0 +1,72 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** You can redistribute this file and/or modify it under the terms of the
** BSD 3-Clause.
**
** THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** =============================================================================
*/
#ifndef WINGCORE_H
#define WINGCORE_H
#include <QDebug>
#include <QMetaType>
#include <QMutex>
#include <QMutexLocker>
#include <QObject>
#include <QString>
constexpr auto CALL_TABLE_PROPERTY = "__CALL_TABLE__";
constexpr auto CALL_POINTER_PROPERTY = "__CALL_POINTER__";
template <class Func>
inline QByteArray getFunctionSig(Func &&, const char *fn) {
typedef QtPrivate::FunctionPointer<std::decay_t<Func>> FnPointerType;
const int *types =
QtPrivate::ConnectionTypes<typename FnPointerType::Arguments>::types();
if constexpr (FnPointerType::ArgumentCount > 0) {
QStringList args;
Q_ASSERT(types);
for (int i = 0; i < FnPointerType::ArgumentCount; ++i) {
QMetaType type(types[i]);
if (type.isValid()) {
args.append(type.name());
}
}
return QByteArray(fn) + '(' + args.join(',').toLatin1() + ')';
} else {
return QByteArray(fn) + QByteArray("()");
}
}
#define SETUP_CALL_CONTEXT(FN) \
static QMutex __mutex__; \
static QMetaMethod m; \
do { \
QMutexLocker locker(&__mutex__); \
static auto CALLNAME = getFunctionSig(FN, __func__); \
if (!m.isValid()) { \
auto fnMap = callTable(); \
if (fnMap.contains(CALLNAME)) { \
m = fnMap.value(CALLNAME); \
Q_ASSERT(m.isValid()); \
} else { \
qDebug("[InvokeCall] '%s' is not found in call table.", \
CALLNAME.constData()); \
} \
} \
} while (0)
#endif // WINGCORE_H

View File

@ -0,0 +1,47 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** You can redistribute this file and/or modify it under the terms of the
** BSD 3-Clause.
**
** THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** =============================================================================
*/
#include "wingeditorviewwidget.h"
WingHex::WingEditorViewWidget::WingEditorViewWidget(IWingPlugin *plg,
QWidget *parent)
: QWidget(parent), WingHex::IWingPluginAPICalls(plg) {}
void WingHex::WingEditorViewWidget::docSaved(bool saved) {
// TODO
}
void WingHex::WingEditorViewWidget::raiseView() {
// TODO
}
void WingHex::WingEditorViewWidget::loadState(const QByteArray &state) {
Q_UNUSED(state);
}
bool WingHex::WingEditorViewWidget::hasUnsavedState() { return false; }
QByteArray WingHex::WingEditorViewWidget::saveState() { return {}; }
bool WingHex::WingEditorViewWidget::onClosing() { return true; }
void WingHex::WingEditorViewWidget::onWorkSpaceNotify(bool isWorkSpace) {
Q_UNUSED(isWorkSpace);
}

View File

@ -0,0 +1,85 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** You can redistribute this file and/or modify it under the terms of the
** BSD 3-Clause.
**
** THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** =============================================================================
*/
#ifndef WINGEDITORVIEWWIDGET_H
#define WINGEDITORVIEWWIDGET_H
#include "iwingplugincalls.h"
#include "wingplugin_global.h"
#include <QWidget>
namespace WingHex {
class IWingPlugin;
class WINGPLUGIN_EXPORT WingEditorViewWidget
: public QWidget,
protected WingHex::IWingPluginAPICalls {
Q_OBJECT
public:
class Creator {
public:
Creator() = default;
public:
virtual QIcon icon() const = 0;
virtual QString name() const = 0;
virtual QString id() const = 0;
public:
virtual WingEditorViewWidget *create(WingHex::IWingPlugin *plg,
QWidget *parent) const = 0;
};
public:
explicit WingEditorViewWidget(WingHex::IWingPlugin *plg,
QWidget *parent = nullptr);
virtual WingEditorViewWidget *clone() = 0;
public slots:
void docSaved(bool saved);
void raiseView();
public slots:
virtual void toggled(bool isVisible) = 0;
virtual void loadState(const QByteArray &state);
virtual bool hasUnsavedState();
virtual QByteArray saveState();
// return false then stop closing and swith the view
// but you cannot prevent closing the cloned view
virtual bool onClosing();
// cloned view will never call it
virtual void onWorkSpaceNotify(bool isWorkSpace);
};
} // namespace WingHex
#endif // WINGEDITORVIEWWIDGET_H

View File

@ -0,0 +1,130 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** You can redistribute this file and/or modify it under the terms of the
** BSD 3-Clause.
**
** THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** =============================================================================
*/
#ifndef WINGPLUGIN_GLOBAL_H
#define WINGPLUGIN_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(WINGPLUGIN_LIBRARY)
#define WINGPLUGIN_EXPORT Q_DECL_EXPORT
#else
#define WINGPLUGIN_EXPORT Q_DECL_IMPORT
#endif
#include <QFileDialog>
#include <QInputDialog>
#include <QMessageBox>
#include <QMetaMethod>
#include <QString>
#include <QVersionNumber>
#include <QWidget>
#ifdef WING_SERVICE
#undef WING_SERVICE
#endif
#define WING_SERVICE Q_INVOKABLE
#define WINGAPI_ARG_SPEC(Type) \
inline QArgument<Type> WINGAPI_ARG(const Type &t) { \
return QArgument<Type>(#Type, t); \
} \
inline QReturnArgument<Type> WINGAPI_RETURN_ARG(Type &t) { \
return QReturnArgument<Type>(#Type, t); \
}
template <typename T>
inline QArgument<T> WINGAPI_ARG(const T &t) {
static QByteArray name;
if (name.isEmpty()) {
auto m = QMetaType::fromType<std::decay_t<T>>();
name = m.name();
}
return QArgument<std::decay_t<T>>(name, t);
}
template <typename T>
inline QReturnArgument<T> WINGAPI_RETURN_ARG(T &t) {
static QByteArray name;
if (name.isEmpty()) {
auto m = QMetaType::fromType<std::decay_t<T>>();
name = m.name();
}
return QReturnArgument<std::decay_t<T>>(name, t);
}
namespace WingHex {
struct WingDockWidgetInfo {
QString widgetName;
QString displayName;
QWidget *widget = nullptr;
Qt::DockWidgetArea area = Qt::DockWidgetArea::NoDockWidgetArea;
};
struct WingDependency {
QString puid;
QVersionNumber version;
};
enum class AppTheme { Dark, Light };
using CallTable = QHash<QByteArray, QMetaMethod>;
using ClickedCallBack = std::function<void(const QModelIndex &)>;
Q_NAMESPACE_EXPORT(WINGPLUGIN_EXPORT)
enum ErrFile : int {
Success = 0,
Error = -1,
UnSaved = -2,
Permission = -3,
NotExist = -4,
AlreadyOpened = -5,
IsNewFile = -6,
WorkSpaceUnSaved = -7,
ClonedFile = -8,
InvalidFormat = -9,
TooManyOpenedFile = -10,
NotAllowedInNoneGUIThread = -11,
DevNotFound = -12,
};
Q_ENUM_NS(ErrFile)
enum class SelectionMode : int { Add, Remove, Single };
Q_ENUM_NS(SelectionMode)
} // namespace WingHex
Q_DECLARE_METATYPE(WingHex::AppTheme)
Q_DECLARE_METATYPE(WingHex::CallTable)
// Template specialization for typedefs
WINGAPI_ARG_SPEC(QMessageBox::StandardButtons);
WINGAPI_ARG_SPEC(QInputDialog::InputDialogOptions);
WINGAPI_ARG_SPEC(QFileDialog::Options);
WINGAPI_ARG_SPEC(Qt::InputMethodHints);
WINGAPI_ARG_SPEC(qsizetype);
WINGAPI_ARG_SPEC(WingHex::ClickedCallBack);
#endif // WINGPLUGIN_GLOBAL_H

View File

@ -0,0 +1,14 @@
#include "wingplugincallconvertor.h"
#include "WingPlugin/wingplugin_global.h"
#include "iwingpluginbase.h"
WingHex::WingPluginCallConvertor::WingPluginCallConvertor(QObject *caller) {
_caller = reinterpret_cast<WingHex::IWingPluginBase *>(caller);
Q_ASSERT(_caller);
}
QArgument<WingHex::IWingPluginBase *>
WingHex::WingPluginCallConvertor::getSenderObj() {
return WINGAPI_ARG(_caller);
}

View File

@ -0,0 +1,22 @@
#ifndef WINGPLUGINCALLCONVERTOR_H
#define WINGPLUGINCALLCONVERTOR_H
#include <QArgument>
namespace WingHex {
class IWingPluginBase;
class WingPluginCallConvertor {
public:
WingPluginCallConvertor(QObject *caller);
protected:
QArgument<IWingPluginBase *> getSenderObj();
private:
IWingPluginBase *_caller;
};
} // namespace WingHex
#endif // WINGPLUGINCALLCONVERTOR_H

View File

@ -0,0 +1,109 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** You can redistribute this file and/or modify it under the terms of the
** BSD 3-Clause.
**
** THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** =============================================================================
*/
#include "wingplugincalls.h"
#include "wingcore.h"
#include "wingplugincalls_p.h"
#include <QDynamicPropertyChangeEvent>
#include <QEvent>
using namespace WingHex;
Q_DECLARE_METATYPE(QMetaMethod)
WingPluginCalls::WingPluginCalls(QObject *coreobj)
: WingPluginCallConvertor(coreobj), _core(new WingPluginCallsCore) {
Q_ASSERT(coreobj);
coreobj->installEventFilter(_core);
auto var = coreobj->property(CALL_POINTER_PROPERTY);
if (var.canConvert<quintptr>()) {
_core->d_ptr->_fnCaller =
reinterpret_cast<QObject *>(var.value<quintptr>());
}
var = coreobj->property(CALL_TABLE_PROPERTY);
if (var.canConvert<QHash<QByteArray, QMetaMethod>>()) {
_core->d_ptr->_fnTable = var.value<QHash<QByteArray, QMetaMethod>>();
}
}
WingPluginCalls::~WingPluginCalls() { delete _core; }
WingHex::CallTable WingPluginCalls::callTable() const {
if (_core->d_ptr->_fnTable.isEmpty()) {
std::abort();
}
return _core->d_ptr->_fnTable;
}
QObject *WingPluginCalls::callReceiver() const {
if (_core->d_ptr->_fnCaller == nullptr) {
std::abort();
}
return _core->d_ptr->_fnCaller;
}
WingPluginCallsCore *WingPluginCalls::core() const { return _core; }
WingPluginCallsCore::WingPluginCallsCore()
: QObject(), d_ptr(new WingPluginCallsCorePrivate) {}
WingPluginCallsCore::~WingPluginCallsCore() { delete d_ptr; }
bool WingPluginCallsCore::eventFilter(QObject *watched, QEvent *event) {
if (event->type() == QEvent::DynamicPropertyChange) {
auto e = static_cast<QDynamicPropertyChangeEvent *>(event);
if (e) {
auto ppname = e->propertyName();
if (ppname == CALL_POINTER_PROPERTY) {
Q_D(WingPluginCallsCore);
if (d->_fnCaller) {
std::abort();
}
auto var = watched->property(CALL_POINTER_PROPERTY);
if (!var.canConvert<quintptr>()) {
std::abort();
}
d->_fnCaller =
reinterpret_cast<QObject *>(var.value<quintptr>());
}
if (ppname == CALL_TABLE_PROPERTY) {
Q_D(WingPluginCallsCore);
if (!d->_fnTable.isEmpty()) {
std::abort();
}
auto var = watched->property(CALL_TABLE_PROPERTY);
if (!var.canConvert<QHash<QByteArray, QMetaMethod>>()) {
std::abort();
}
d->_fnTable = var.value<QHash<QByteArray, QMetaMethod>>();
}
}
}
return QObject::eventFilter(watched, event);
}

View File

@ -0,0 +1,71 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** You can redistribute this file and/or modify it under the terms of the
** BSD 3-Clause.
**
** THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** =============================================================================
*/
#ifndef WINGPLUGINCALLS_H
#define WINGPLUGINCALLS_H
#include <QMetaMethod>
#include <QObject>
#include "wingplugin_global.h"
#include "wingplugincallconvertor.h"
namespace WingHex {
class WingPluginCallsCorePrivate;
class WingPluginCallsCore : public QObject {
Q_OBJECT
friend class WingPluginCalls;
public:
WingPluginCallsCore();
virtual ~WingPluginCallsCore();
// QObject interface
public:
virtual bool eventFilter(QObject *watched, QEvent *event) override;
private:
WingPluginCallsCorePrivate *d_ptr;
Q_DECLARE_PRIVATE(WingPluginCallsCore)
Q_DISABLE_COPY_MOVE(WingPluginCallsCore)
};
class WINGPLUGIN_EXPORT WingPluginCalls : public WingPluginCallConvertor {
public:
explicit WingPluginCalls(QObject *coreobj);
virtual ~WingPluginCalls();
WingPluginCallsCore *core() const;
protected:
WingHex::CallTable callTable() const;
QObject *callReceiver() const;
private:
WingPluginCallsCore *_core;
Q_DISABLE_COPY_MOVE(WingPluginCalls)
};
} // namespace WingHex
#endif // WINGPLUGINCALLS_H

View File

@ -0,0 +1,40 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** You can redistribute this file and/or modify it under the terms of the
** BSD 3-Clause.
**
** THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** =============================================================================
*/
#ifndef WINGPLUGINCALLS_P_H
#define WINGPLUGINCALLS_P_H
#include <QHash>
#include <QMetaMethod>
#include <QObject>
#include "wingplugin_global.h"
namespace WingHex {
class WingPluginCallsCorePrivate {
public:
WingHex::CallTable _fnTable;
QObject *_fnCaller = nullptr;
};
} // namespace WingHex
#endif // WINGPLUGINCALLS_P_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -27,13 +27,11 @@
#define QPTR_WRAP(decl) "uint " decl
#define QPTR "uint"
#define QSIZETYPE "int"
#define QUSIZETYPE "uint"
#elif Q_PROCESSOR_WORDSIZE == 8
#define QSIZETYPE_WRAP(decl) "int64 " decl
#define QPTR_WRAP(decl) "uint64 " decl
#define QPTR "uint64"
#define QSIZETYPE "int64"
#define QUSIZETYPE "uint64"
#else
#error "Processor with unexpected word size"
#endif

View File

@ -18,15 +18,14 @@
#ifndef CLICKCALLBACK_H
#define CLICKCALLBACK_H
#include "WingPlugin/iwingplugin.h"
#include "angelscript.h"
#include "plugin/iwingplugin.h"
class ClickCallBack {
public:
ClickCallBack() {}
ClickCallBack(const WingHex::WingPlugin::DataVisual::ClickedCallBack &b)
: _call(b) {}
ClickCallBack(const WingHex::ClickedCallBack &b) : _call(b) {}
explicit ClickCallBack(asIScriptEngine *engine, asIScriptFunction *func)
: _engine(engine), _func(func) {
@ -42,14 +41,12 @@ public:
}
public:
ClickCallBack &
operator=(const WingHex::WingPlugin::DataVisual::ClickedCallBack &_Right) {
ClickCallBack &operator=(const WingHex::ClickedCallBack &_Right) {
*this = ClickCallBack(_Right);
return *this;
}
ClickCallBack &
operator=(WingHex::WingPlugin::DataVisual::ClickedCallBack &&_Right) {
ClickCallBack &operator=(WingHex::ClickedCallBack &&_Right) {
*this = ClickCallBack(_Right);
return *this;
}
@ -79,7 +76,7 @@ public:
}
private:
WingHex::WingPlugin::DataVisual::ClickedCallBack _call;
WingHex::ClickedCallBack _call;
asIScriptEngine *_engine = nullptr;
asIScriptFunction *_func = nullptr;
};

View File

@ -1,7 +1,7 @@
#include "crashhandler.h"
#include "angelscript.h"
#include "class/pluginsystem.h"
#include "dialog/crashreport.h"
#include "plugin/pluginsystem.h"
#include <QApplication>
#include <QLibraryInfo>

3491
src/class/pluginsystem.cpp Normal file

File diff suppressed because it is too large Load Diff

853
src/class/pluginsystem.h Normal file
View File

@ -0,0 +1,853 @@
/*==============================================================================
** 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 PLUGINSYSTEM_H
#define PLUGINSYSTEM_H
#include <QDockWidget>
#include <QHash>
#include <QList>
#include <QMenu>
#include <QMutex>
#include <QObject>
#include <QQueue>
#include <QReadWriteLock>
#include <QTimer>
#include <QTimerEvent>
#include <QToolButton>
#include <QVariant>
#include "WingPlugin/iwingdevice.h"
#include "class/clickcallback.h"
#include "class/wingangelapi.h"
#include "control/editorview.h"
using namespace WingHex;
class MainWindow;
class asCScriptEngine;
class PluginSystem : public QObject {
Q_OBJECT
private:
class UniqueIdGenerator {
public:
class UniqueId : public QSharedData {
public:
UniqueId() : _id(-1), _gen(nullptr) {}
UniqueId(UniqueIdGenerator *gen, int id) : _id(id), _gen(gen) {
Q_ASSERT(gen);
Q_ASSERT(id >= 0);
#ifdef QT_DEBUG
qDebug() << "[UniqueId] alloced: " << id;
#endif
}
~UniqueId() {
if (_gen) {
_gen->release(_id);
}
#ifdef QT_DEBUG
qDebug() << "[UniqueId] freed: " << _id;
#endif
}
operator int() { return _id; }
private:
int _id;
UniqueIdGenerator *_gen;
};
public:
UniqueIdGenerator() : currentId(0) {}
QExplicitlySharedDataPointer<UniqueId> get() {
if (!releasedIds.isEmpty()) {
int id = releasedIds.dequeue();
return QExplicitlySharedDataPointer<UniqueId>(
new UniqueId(this, id));
} else {
return QExplicitlySharedDataPointer<UniqueId>(
new UniqueId(this, currentId++));
}
}
void release(int id) {
if (id < currentId && !releasedIds.contains(id)) {
releasedIds.enqueue(id);
}
}
private:
int currentId;
QQueue<int> releasedIds;
};
using SharedUniqueId =
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,
BrokenVersion,
InvalidID,
DupID,
LackDependencies
};
Q_ENUM(PluginStatus)
private:
struct PluginFileContext {
SharedUniqueId fid;
EditorView *view = nullptr;
IWingPlugin *linkedplg = nullptr;
QUndoCommand *cmd = nullptr;
~PluginFileContext() {
if (cmd) {
delete cmd;
}
}
};
public:
static PluginSystem &instance();
void setMainWindow(MainWindow *win);
QWidget *mainWindow() const;
void loadAllPlugin();
void unloadAllPlugin();
void destory();
const QList<IWingPlugin *> &plugins() const;
IWingPlugin *plugin(qsizetype index) const;
const QList<IWingDevice *> &devices() const;
IWingDevice *device(qsizetype index) const;
WingAngelAPI *angelApi() const;
void cleanUpEditorViewHandle(EditorView *view);
bool dispatchEvent(IWingPlugin::RegisteredEvent event,
const QVariantList &params);
IWingDevice *ext2Device(const QString &ext);
QStringList scriptMarcos() const;
public:
void scriptPragmaBegin();
qsizetype pluginAPICount() const;
public:
PluginInfo getPluginInfo(IWingPluginBase *plg) const;
QString getPluginID(IWingPluginBase *plg) const;
static QString getPUID(IWingPluginBase *p);
static QString type2AngelScriptString(IWingPlugin::MetaType type,
bool isArg, bool noModifier = false);
private:
void loadExtPlugin();
void loadDevicePlugin();
void checkDirRootSafe(const QDir &dir);
template <typename T>
std::optional<PluginInfo> loadPlugin(const QFileInfo &filename,
const QDir &setdir);
bool closeEditor(IWingPlugin *plg, int handle, bool force);
bool closeHandle(IWingPlugin *plg, int handle);
bool checkPluginCanOpenedFile(IWingPlugin *plg);
bool checkPluginHasAlreadyOpened(IWingPlugin *plg, EditorView *view);
EditorView *getCurrentPluginView(IWingPlugin *plg);
EditorView *handle2EditorView(IWingPlugin *plg, int handle);
SharedUniqueId assginHandleForPluginView(IWingPlugin *plg,
EditorView *view);
static bool equalCompareHandle(const SharedUniqueId &id, int handle);
static int getUIDHandle(const SharedUniqueId &id);
private:
PluginInfo parsePluginMetadata(const QJsonObject &meta);
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);
bool isPluginLoaded(const WingDependency &d);
bool isPluginLoaded(const QString &id);
bool checkThreadAff();
static QString packLogMessage(const char *header, const QString &msg);
EditorView *pluginCurrentEditor(IWingPlugin *plg) const;
QSharedPointer<PluginFileContext> pluginContextById(IWingPlugin *plg,
int fid) const;
QUndoCommand *pluginCurrentUndoCmd(IWingPlugin *plg) const;
private:
void loadPlugin(IWingPlugin *p, PluginInfo &meta,
const std::optional<QDir> &setdir);
void loadPlugin(IWingDevice *p, PluginInfo &meta,
const std::optional<QDir> &setdir);
private:
void registerMarcoDevice(IWingDevice *plg);
private:
void registerPluginDockWidgets(IWingPluginBase *p);
void registerPluginPages(IWingPluginBase *p);
public:
bool updateTextList_API(const QStringList &data, const QString &title,
const ClickCallBack &click,
const ClickCallBack &dblclick);
bool updateTextTree_API(const QString &json, const QString &title,
const ClickCallBack &click,
const ClickCallBack &dblclick);
bool updateTextTable_API(const QString &json, const QStringList &headers,
const QStringList &headerNames,
const QString &title, const ClickCallBack &click,
const ClickCallBack &dblclick);
public:
// fpr crash checking
QString currentLoadingPlugin() const;
private:
template <typename T>
T readBasicTypeContent(IWingPlugin *plg, qsizetype offset) {
Q_STATIC_ASSERT(std::is_integral_v<T> || std::is_floating_point_v<T>);
auto e = pluginCurrentEditor(plg);
if (e) {
_rwlock.lockForRead();
auto buffer = e->hexEditor()->document()->read(offset, sizeof(T));
if (buffer.size() == sizeof(T)) {
auto pb = reinterpret_cast<const T *>(buffer.constData());
_rwlock.unlock();
return *pb;
}
}
if constexpr (std::is_floating_point_v<T>) {
return qQNaN();
} else {
return T(0);
}
}
template <typename T>
bool insertBasicTypeContent(IWingPlugin *plg, qsizetype offset,
const T &value) {
Q_STATIC_ASSERT(std::is_integral_v<T> || std::is_floating_point_v<T>);
auto e = getCurrentPluginView(plg);
if (e) {
auto editor = e->hexEditor();
auto doc = editor->document();
auto buffer = reinterpret_cast<const char *>(&value);
auto uc = pluginCurrentUndoCmd(plg);
auto cmd = doc->MakeInsert(uc, editor->cursor(), offset,
QByteArray(buffer, sizeof(T)));
if (uc == nullptr && cmd) {
_rwlock.lockForWrite();
doc->pushMakeUndo(cmd);
_rwlock.unlock();
return true;
}
}
return false;
}
template <typename T>
bool writeBasicTypeContent(IWingPlugin *plg, qsizetype offset,
const T &value) {
Q_STATIC_ASSERT(std::is_integral_v<T> || std::is_floating_point_v<T>);
auto e = getCurrentPluginView(plg);
if (e) {
auto editor = e->hexEditor();
auto doc = editor->document();
auto buffer = reinterpret_cast<const char *>(&value);
auto uc = pluginCurrentUndoCmd(plg);
auto cmd = doc->MakeReplace(uc, editor->cursor(), offset,
QByteArray(buffer, sizeof(T)));
if (uc == nullptr && cmd) {
_rwlock.lockForWrite();
doc->pushMakeUndo(cmd);
_rwlock.unlock();
return true;
}
}
return false;
}
template <typename T>
bool appendBasicTypeContent(IWingPlugin *plg, const T &value) {
Q_STATIC_ASSERT(std::is_integral_v<T> || std::is_floating_point_v<T>);
auto e = getCurrentPluginView(plg);
if (e) {
auto editor = e->hexEditor();
auto doc = editor->document();
auto buffer = reinterpret_cast<const char *>(&value);
auto uc = pluginCurrentUndoCmd(plg);
auto cmd = doc->MakeAppend(uc, editor->cursor(),
QByteArray(buffer, sizeof(T)));
if (uc == nullptr && cmd) {
_rwlock.lockForWrite();
doc->pushMakeUndo(cmd);
_rwlock.unlock();
return true;
}
}
return false;
}
signals:
void pluginLoading(const QString &plgName);
private:
PluginSystem(QObject *parent = nullptr);
~PluginSystem();
void initCheckingEngine();
void finalizeCheckingEngine();
// IWingPluginBase API
public:
WING_SERVICE void toast(WingHex::IWingPluginBase *sender,
const QPixmap &icon, const QString &message);
// logging
WING_SERVICE void trace(WingHex::IWingPluginBase *sender,
const QString &message);
WING_SERVICE void debug(WingHex::IWingPluginBase *sender,
const QString &message);
WING_SERVICE void info(WingHex::IWingPluginBase *sender,
const QString &message);
WING_SERVICE void warn(WingHex::IWingPluginBase *sender,
const QString &message);
WING_SERVICE void error(WingHex::IWingPluginBase *sender,
const QString &message);
WING_SERVICE bool raiseDockWidget(WingHex::IWingPluginBase *sender,
QWidget *w);
WING_SERVICE WingHex::AppTheme
currentAppTheme(WingHex::IWingPluginBase *sender);
WING_SERVICE QDialog *createDialog(WingHex::IWingPluginBase *sender,
QWidget *content);
public:
WING_SERVICE void aboutQt(WingHex::IWingPluginBase *sender, QWidget *parent,
const QString &title);
WING_SERVICE QMessageBox::StandardButton
information(WingHex::IWingPluginBase *sender, QWidget *parent,
const QString &title, const QString &text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton);
WING_SERVICE QMessageBox::StandardButton
question(WingHex::IWingPluginBase *sender, QWidget *parent,
const QString &title, const QString &text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton);
WING_SERVICE QMessageBox::StandardButton
warning(WingHex::IWingPluginBase *sender, QWidget *parent,
const QString &title, const QString &text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton);
WING_SERVICE QMessageBox::StandardButton
critical(WingHex::IWingPluginBase *sender, QWidget *parent,
const QString &title, const QString &text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton);
WING_SERVICE void about(WingHex::IWingPluginBase *sender, QWidget *parent,
const QString &title, const QString &text);
WING_SERVICE QMessageBox::StandardButton
msgbox(WingHex::IWingPluginBase *sender, QWidget *parent,
QMessageBox::Icon icon, const QString &title, const QString &text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton);
public:
WING_SERVICE QString getText(WingHex::IWingPluginBase *sender,
QWidget *parent, const QString &title,
const QString &label, QLineEdit::EchoMode echo,
const QString &text, bool *ok,
Qt::InputMethodHints inputMethodHints);
WING_SERVICE QString getMultiLineText(
WingHex::IWingPluginBase *sender, QWidget *parent, const QString &title,
const QString &label, const QString &text, bool *ok,
Qt::InputMethodHints inputMethodHints);
WING_SERVICE QString getItem(WingHex::IWingPluginBase *sender,
QWidget *parent, const QString &title,
const QString &label, const QStringList &items,
int current, bool editable, bool *ok,
Qt::InputMethodHints inputMethodHints);
WING_SERVICE int getInt(WingHex::IWingPluginBase *sender, QWidget *parent,
const QString &title, const QString &label,
int value, int minValue, int maxValue, int step,
bool *ok);
WING_SERVICE double getDouble(WingHex::IWingPluginBase *sender,
QWidget *parent, const QString &title,
const QString &label, double value,
double minValue, double maxValue,
int decimals, bool *ok, double step);
public:
WING_SERVICE QString getExistingDirectory(WingHex::IWingPluginBase *sender,
QWidget *parent,
const QString &caption,
const QString &dir,
QFileDialog::Options options);
WING_SERVICE QString getOpenFileName(
WingHex::IWingPluginBase *sender, QWidget *parent,
const QString &caption, const QString &dir, const QString &filter,
QString *selectedFilter, QFileDialog::Options options);
WING_SERVICE QStringList getOpenFileNames(
WingHex::IWingPluginBase *sender, QWidget *parent,
const QString &caption, const QString &dir, const QString &filter,
QString *selectedFilter, QFileDialog::Options options);
WING_SERVICE QString getSaveFileName(
WingHex::IWingPluginBase *sender, QWidget *parent,
const QString &caption, const QString &dir, const QString &filter,
QString *selectedFilter, QFileDialog::Options options);
WING_SERVICE QColor getColor(WingHex::IWingPluginBase *sender,
const QString &caption, QWidget *parent);
// IWingPlugin API
public:
WING_SERVICE bool existsServiceHost(WingHex::IWingPluginBase *sender,
const QString &puid);
WING_SERVICE bool
invokeService(WingHex::IWingPluginBase *sender, const QString &puid,
const char *method, Qt::ConnectionType type,
QGenericReturnArgument ret, QGenericArgument val0,
QGenericArgument val1, QGenericArgument val2,
QGenericArgument val3, QGenericArgument val4);
WING_SERVICE bool isCurrentDocEditing(WingHex::IWingPluginBase *sender);
WING_SERVICE QString currentDocFilename(WingHex::IWingPluginBase *sender);
// document
WING_SERVICE bool isReadOnly(WingHex::IWingPluginBase *sender);
WING_SERVICE bool isInsertionMode(WingHex::IWingPluginBase *sender);
WING_SERVICE bool isKeepSize(WingHex::IWingPluginBase *sender);
WING_SERVICE bool isLocked(WingHex::IWingPluginBase *sender);
WING_SERVICE qsizetype documentLines(WingHex::IWingPluginBase *sender);
WING_SERVICE qsizetype documentBytes(WingHex::IWingPluginBase *sender);
WING_SERVICE WingHex::HexPosition
currentPos(WingHex::IWingPluginBase *sender);
WING_SERVICE qsizetype currentRow(WingHex::IWingPluginBase *sender);
WING_SERVICE qsizetype currentColumn(WingHex::IWingPluginBase *sender);
WING_SERVICE qsizetype currentOffset(WingHex::IWingPluginBase *sender);
WING_SERVICE qsizetype selectedLength(WingHex::IWingPluginBase *sender);
WING_SERVICE QByteArray selectedBytes(WingHex::IWingPluginBase *sender,
qsizetype index);
WING_SERVICE QByteArrayList
selectionBytes(WingHex::IWingPluginBase *sender);
WING_SERVICE WingHex::HexPosition
selectionStart(WingHex::IWingPluginBase *sender, qsizetype index);
WING_SERVICE WingHex::HexPosition
selectionEnd(WingHex::IWingPluginBase *sender, qsizetype index);
WING_SERVICE qsizetype selectionLength(WingHex::IWingPluginBase *sender,
qsizetype index);
WING_SERVICE qsizetype selectionCount(WingHex::IWingPluginBase *sender);
WING_SERVICE bool stringVisible(WingHex::IWingPluginBase *sender);
WING_SERVICE bool addressVisible(WingHex::IWingPluginBase *sender);
WING_SERVICE bool headerVisible(WingHex::IWingPluginBase *sender);
WING_SERVICE quintptr addressBase(WingHex::IWingPluginBase *sender);
WING_SERVICE bool isModified(WingHex::IWingPluginBase *sender);
WING_SERVICE qint8 readInt8(WingHex::IWingPluginBase *sender,
qsizetype offset);
WING_SERVICE qint16 readInt16(WingHex::IWingPluginBase *sender,
qsizetype offset);
WING_SERVICE qint32 readInt32(WingHex::IWingPluginBase *sender,
qsizetype offset);
WING_SERVICE qint64 readInt64(WingHex::IWingPluginBase *sender,
qsizetype offset);
WING_SERVICE float readFloat(WingHex::IWingPluginBase *sender,
qsizetype offset);
WING_SERVICE double readDouble(WingHex::IWingPluginBase *sender,
qsizetype offset);
WING_SERVICE QString readString(WingHex::IWingPluginBase *sender,
qsizetype offset, const QString &encoding);
WING_SERVICE QByteArray readBytes(WingHex::IWingPluginBase *sender,
qsizetype offset, qsizetype count);
WING_SERVICE qsizetype findNext(WingHex::IWingPluginBase *sender,
qsizetype begin, const QByteArray &ba);
WING_SERVICE qsizetype findPrevious(WingHex::IWingPluginBase *sender,
qsizetype begin, const QByteArray &ba);
WING_SERVICE QString bookMarkComment(WingHex::IWingPluginBase *sender,
qsizetype pos);
WING_SERVICE bool existBookMark(WingHex::IWingPluginBase *sender,
qsizetype pos);
// document
WING_SERVICE bool switchDocument(WingHex::IWingPluginBase *sender,
int handle);
WING_SERVICE bool raiseDocument(WingHex::IWingPluginBase *sender,
int handle);
WING_SERVICE bool setLockedFile(WingHex::IWingPluginBase *sender, bool b);
WING_SERVICE bool setKeepSize(WingHex::IWingPluginBase *sender, bool b);
WING_SERVICE bool setStringVisible(WingHex::IWingPluginBase *sender,
bool b);
WING_SERVICE bool setAddressVisible(WingHex::IWingPluginBase *sender,
bool b);
WING_SERVICE bool setHeaderVisible(WingHex::IWingPluginBase *sender,
bool b);
WING_SERVICE bool setAddressBase(WingHex::IWingPluginBase *sender,
quintptr base);
WING_SERVICE bool beginMarco(WingHex::IWingPluginBase *sender,
const QString &txt);
WING_SERVICE bool endMarco(WingHex::IWingPluginBase *sender);
WING_SERVICE bool writeInt8(WingHex::IWingPluginBase *sender,
qsizetype offset, qint8 value);
WING_SERVICE bool writeInt16(WingHex::IWingPluginBase *sender,
qsizetype offset, qint16 value);
WING_SERVICE bool writeInt32(WingHex::IWingPluginBase *sender,
qsizetype offset, qint32 value);
WING_SERVICE bool writeInt64(WingHex::IWingPluginBase *sender,
qsizetype offset, qint64 value);
WING_SERVICE bool writeFloat(WingHex::IWingPluginBase *sender,
qsizetype offset, float value);
WING_SERVICE bool writeDouble(WingHex::IWingPluginBase *sender,
qsizetype offset, double value);
WING_SERVICE bool writeString(WingHex::IWingPluginBase *sender,
qsizetype offset, const QString &value,
const QString &encoding);
WING_SERVICE bool writeBytes(WingHex::IWingPluginBase *sender,
qsizetype offset, const QByteArray &data);
WING_SERVICE bool insertInt8(WingHex::IWingPluginBase *sender,
qsizetype offset, qint8 value);
WING_SERVICE bool insertInt16(WingHex::IWingPluginBase *sender,
qsizetype offset, qint16 value);
WING_SERVICE bool insertInt32(WingHex::IWingPluginBase *sender,
qsizetype offset, qint32 value);
WING_SERVICE bool insertInt64(WingHex::IWingPluginBase *sender,
qsizetype offset, qint64 value);
WING_SERVICE bool insertFloat(WingHex::IWingPluginBase *sender,
qsizetype offset, float value);
WING_SERVICE bool insertDouble(WingHex::IWingPluginBase *sender,
qsizetype offset, double value);
WING_SERVICE bool insertString(WingHex::IWingPluginBase *sender,
qsizetype offset, const QString &value,
const QString &encoding);
WING_SERVICE bool insertBytes(WingHex::IWingPluginBase *sender,
qsizetype offset, const QByteArray &data);
WING_SERVICE bool appendInt8(WingHex::IWingPluginBase *sender, qint8 value);
WING_SERVICE bool appendInt16(WingHex::IWingPluginBase *sender,
qint16 value);
WING_SERVICE bool appendInt32(WingHex::IWingPluginBase *sender,
qint32 value);
WING_SERVICE bool appendInt64(WingHex::IWingPluginBase *sender,
qint64 value);
WING_SERVICE bool appendFloat(WingHex::IWingPluginBase *sender,
float value);
WING_SERVICE bool appendDouble(WingHex::IWingPluginBase *sender,
double value);
WING_SERVICE bool appendString(WingHex::IWingPluginBase *sender,
const QString &value,
const QString &encoding);
WING_SERVICE bool appendBytes(WingHex::IWingPluginBase *sender,
const QByteArray &data);
WING_SERVICE bool removeBytes(WingHex::IWingPluginBase *sender,
qsizetype offset, qsizetype len);
// cursor
WING_SERVICE bool moveTo(WingHex::IWingPluginBase *sender, qsizetype line,
qsizetype column, int nibbleindex,
bool clearSelection);
WING_SERVICE bool moveTo(WingHex::IWingPluginBase *sender, qsizetype offset,
bool clearSelection);
WING_SERVICE bool select(WingHex::IWingPluginBase *sender, qsizetype offset,
qsizetype length, SelectionMode mode);
WING_SERVICE bool setInsertionMode(WingHex::IWingPluginBase *sender,
bool isinsert);
WING_SERVICE bool metadata(WingHex::IWingPluginBase *sender,
qsizetype begin, qsizetype length,
const QColor &fgcolor, const QColor &bgcolor,
const QString &comment);
WING_SERVICE bool removeMetadata(WingHex::IWingPluginBase *sender,
qsizetype offset);
WING_SERVICE bool clearMetadata(WingHex::IWingPluginBase *sender);
WING_SERVICE bool setMetaVisible(WingHex::IWingPluginBase *sender, bool b);
WING_SERVICE bool setMetafgVisible(WingHex::IWingPluginBase *sender,
bool b);
WING_SERVICE bool setMetabgVisible(WingHex::IWingPluginBase *sender,
bool b);
WING_SERVICE bool setMetaCommentVisible(WingHex::IWingPluginBase *sender,
bool b);
// mainwindow
WING_SERVICE WingHex::ErrFile newFile(WingHex::IWingPluginBase *sender);
WING_SERVICE WingHex::ErrFile openFile(WingHex::IWingPluginBase *sender,
const QString &filename);
WING_SERVICE WingHex::ErrFile openExtFile(WingHex::IWingPluginBase *sender,
const QString &ext,
const QString &file);
WING_SERVICE WingHex::ErrFile
openWorkSpace(WingHex::IWingPluginBase *sender, const QString &filename);
WING_SERVICE WingHex::ErrFile closeHandle(WingHex::IWingPluginBase *sender,
int handle);
WING_SERVICE WingHex::ErrFile closeFile(WingHex::IWingPluginBase *sender,
int handle, bool force);
WING_SERVICE WingHex::ErrFile saveFile(WingHex::IWingPluginBase *sender,
int handle);
WING_SERVICE WingHex::ErrFile exportFile(WingHex::IWingPluginBase *sender,
int handle,
const QString &savename);
WING_SERVICE WingHex::ErrFile saveAsFile(WingHex::IWingPluginBase *sender,
int handle,
const QString &savename);
WING_SERVICE WingHex::ErrFile openCurrent(WingHex::IWingPluginBase *sender);
WING_SERVICE WingHex::ErrFile closeCurrent(WingHex::IWingPluginBase *sender,
bool force);
WING_SERVICE WingHex::ErrFile saveCurrent(WingHex::IWingPluginBase *sender);
WING_SERVICE WingHex::ErrFile
exportCurrent(WingHex::IWingPluginBase *sender, const QString &savename);
WING_SERVICE WingHex::ErrFile
saveAsCurrent(WingHex::IWingPluginBase *sender, const QString &savename);
// bookmark
WING_SERVICE bool addBookMark(WingHex::IWingPluginBase *sender,
qsizetype pos, const QString &comment);
WING_SERVICE bool modBookMark(WingHex::IWingPluginBase *sender,
qsizetype pos, const QString &comment);
WING_SERVICE bool removeBookMark(WingHex::IWingPluginBase *sender,
qsizetype pos);
WING_SERVICE bool clearBookMark(WingHex::IWingPluginBase *sender);
// extension
WING_SERVICE bool closeAllFiles(WingHex::IWingPluginBase *sender);
WING_SERVICE bool updateText(WingHex::IWingPluginBase *sender,
const QString &data, const QString &title);
WING_SERVICE bool updateTextList(WingHex::IWingPluginBase *sender,
const QStringList &data,
const QString &title,
WingHex::ClickedCallBack clicked,
WingHex::ClickedCallBack dblClicked);
WING_SERVICE bool updateTextTree(WingHex::IWingPluginBase *sender,
const QString &json, const QString &title,
WingHex::ClickedCallBack clicked,
WingHex::ClickedCallBack dblClicked);
WING_SERVICE bool
updateTextTable(WingHex::IWingPluginBase *sender, const QString &json,
const QStringList &headers, const QStringList &headerNames,
const QString &title, WingHex::ClickedCallBack clicked,
WingHex::ClickedCallBack dblClicked);
// API for Qt Plugin Only
WING_SERVICE bool
updateTextListByModel(WingHex::IWingPluginBase *sender,
QAbstractItemModel *model, const QString &title,
WingHex::ClickedCallBack clicked,
WingHex::ClickedCallBack dblClicked);
WING_SERVICE bool
updateTextTableByModel(WingHex::IWingPluginBase *sender,
QAbstractItemModel *model, const QString &title,
WingHex::ClickedCallBack clicked,
WingHex::ClickedCallBack dblClicked);
WING_SERVICE bool
updateTextTreeByModel(WingHex::IWingPluginBase *sender,
QAbstractItemModel *model, const QString &title,
WingHex::ClickedCallBack clicked,
WingHex::ClickedCallBack dblClicked);
private:
CallTable _plgFns;
private:
MainWindow *_win = nullptr;
QHash<IWingPluginBase *, PluginInfo> _pinfos;
QList<IWingPlugin *> _loadedplgs;
QHash<QWidget *, ads::CDockWidget *> _raisedw;
QStringList _lazyplgs;
QList<IWingDevice *> _loadeddevs;
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;
UniqueIdGenerator m_idGen;
QHash<QString, QHash<QString, WingAngelAPI::ScriptFnInfo>> _scfns;
WingAngelAPI *_angelplg = nullptr;
asCScriptEngine *_engine = nullptr;
QStringList _scriptMarcos;
QList<IWingPlugin *> _pragmaedPlg;
QReadWriteLock _rwlock;
private:
QString _curLoadingPlg;
Q_DISABLE_COPY_MOVE(PluginSystem)
};
#endif // PLUGINSYSTEM_H

View File

@ -30,9 +30,9 @@
#include "angelobjstring.h"
#include "class/asbuilder.h"
#include "class/pluginsystem.h"
#include "class/qascodeparser.h"
#include "define.h"
#include "plugin/pluginsystem.h"
#include "scriptaddon/scriptcolor.h"
#include "scriptaddon/scriptfile.h"
#include "scriptaddon/scriptjson.h"

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,9 @@
#define WINGANGELAPI_H
#include "AngelScript/sdk/add_on/scriptarray/scriptarray.h"
#include "plugin/iwingplugin.h"
#include "WingPlugin/iwingplugin.h"
#include <QFileDialog>
#include <any>
#include <functional>
@ -31,6 +33,7 @@ class ScriptingConsole;
class WingAngelAPI : public WingHex::IWingPlugin {
Q_OBJECT
Q_INTERFACES(WingHex::IWingPlugin)
public:
WingAngelAPI();
@ -39,7 +42,6 @@ public:
// IWingPlugin interface
public:
virtual int sdkVersion() const override;
virtual const QString signature() 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;
@ -227,15 +229,6 @@ private:
qsizetype _HexReader_findPrevious(qsizetype begin, const CScriptArray &ba);
CScriptArray *_HexReader_findAllBytes(qsizetype begin, qsizetype end,
const CScriptArray &ba);
CScriptArray *_HexReader_getsBookmarkPos(qsizetype line);
CScriptArray *_HexReader_getSupportedEncodings();
CScriptArray *_HexReader_getStorageDrivers();
bool _HexController_writeBytes(qsizetype offset, const CScriptArray &ba);
bool _HexController_insertBytes(qsizetype offset, const CScriptArray &ba);

View File

@ -180,8 +180,6 @@ WingCStruct::~WingCStruct() {}
int WingCStruct::sdkVersion() const { return WingHex::SDKVERSION; }
const QString WingCStruct::signature() const { return WingHex::WINGSUMMER; }
bool WingCStruct::init(const std::unique_ptr<QSettings> &set) {
Q_UNUSED(set);
resetEnv();
@ -348,7 +346,7 @@ QVariantHash WingCStruct::read(qsizetype offset, const QString &type) {
return {};
}
if (!emit reader.isCurrentDocEditing()) {
if (!isCurrentDocEditing()) {
return {};
}
@ -356,13 +354,13 @@ QVariantHash WingCStruct::read(qsizetype offset, const QString &type) {
return {};
}
auto doclen = emit reader.documentBytes();
auto doclen = documentBytes();
if (doclen < 0 || offset + len > doclen) {
return {};
}
// first read all bytes
auto raw = emit reader.readBytes(offset, len);
auto raw = readBytes(offset, len);
// then slice and parse
const auto *pdata = raw.data();
@ -377,11 +375,11 @@ QByteArray WingCStruct::readRaw(qsizetype offset, const QString &type) {
return {};
}
if (!emit reader.isCurrentDocEditing()) {
if (!isCurrentDocEditing()) {
return {};
}
return emit reader.readBytes(offset, len);
return readBytes(offset, len);
}
QString WingCStruct::getqsizeTypeAsString() const {

View File

@ -18,8 +18,8 @@
#ifndef WINGCSTRUCT_H
#define WINGCSTRUCT_H
#include "WingPlugin/iwingplugin.h"
#include "ctypeparser.h"
#include "plugin/iwingplugin.h"
class CScriptDictionary;
class asIScriptEngine;
@ -27,6 +27,7 @@ class CScriptArray;
class WingCStruct : public WingHex::IWingPlugin {
Q_OBJECT
Q_PLUGIN_METADATA(IID "com.wingsummer.iwingplugin")
public:
explicit WingCStruct();
@ -35,7 +36,6 @@ public:
// IWingPluginBase interface
public:
virtual int sdkVersion() const override;
virtual const QString signature() 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;

View File

@ -22,9 +22,9 @@
#include "Qt-Advanced-Docking-System/src/DockWidgetTab.h"
#include "class/qkeysequences.h"
#include "class/pluginsystem.h"
#include "class/settingmanager.h"
#include "class/workspacemanager.h"
#include "plugin/pluginsystem.h"
#include "utilities.h"
#include <QFile>
@ -135,18 +135,13 @@ void EditorView::registerView(const QString &id, WingEditorViewWidget *view) {
}
void EditorView::switchView(const QString &id) {
// Dont use qobject_cast because
// each plugin source code has its own WingEditorViewWidget class
// implement though they should be the same.
auto curWidget = m_stack->currentWidget();
if (id.isEmpty()) {
if (curWidget != m_hexContainer) {
m_stack->setCurrentWidget(m_hexContainer);
if (curWidget->inherits("WingHex::WingEditorViewWidget")) {
auto o = static_cast<WingEditorViewWidget *>(curWidget);
if (o) {
o->toggled(false);
}
auto o = qobject_cast<WingEditorViewWidget *>(curWidget);
if (o) {
o->toggled(false);
}
}
} else {
@ -223,7 +218,7 @@ EditorView::FindError EditorView::find(const FindDialog::Result &result) {
auto lineWidth = m_hex->renderer()->hexLineWidth();
for (auto &ritem : results) {
FindResult r;
FindResultModel::FindResult r;
r.offset = ritem;
r.line = r.offset / lineWidth;
r.col = r.offset % lineWidth;

View File

@ -23,13 +23,13 @@
#include "QHexView/qhexview.h"
#include "Qt-Advanced-Docking-System/src/DockWidget.h"
#include "WingPlugin/iwingdevice.h"
#include "WingPlugin/wingeditorviewwidget.h"
#include "dialog/finddialog.h"
#include "gotowidget.h"
#include "model/bookmarksmodel.h"
#include "model/findresultmodel.h"
#include "model/metadatamodel.h"
#include "plugin/iwingdevice.h"
#include "plugin/iwingplugin.h"
#include "utilities.h"
using namespace WingHex;

View File

@ -30,6 +30,7 @@
#include "class/languagemanager.h"
#include "class/layoutmanager.h"
#include "class/logger.h"
#include "class/pluginsystem.h"
#include "class/qkeysequences.h"
#include "class/richtextitemdelegate.h"
#include "class/scriptconsolemachine.h"
@ -44,7 +45,6 @@
#include "fileinfodialog.h"
#include "finddialog.h"
#include "metadialog.h"
#include "plugin/pluginsystem.h"
#include "settings/editorsettingdialog.h"
#include "settings/generalsettingdialog.h"
#include "settings/othersettingsdialog.h"
@ -57,11 +57,15 @@
#include <QDesktopServices>
#include <QGridLayout>
#include <QHeaderView>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QKeyEvent>
#include <QPainter>
#include <QPicture>
#include <QPushButton>
#include <QRadioButton>
#include <QScopeGuard>
#include <QScrollBar>
#include <QStatusBar>
#include <QTimer>
@ -598,8 +602,6 @@ MainWindow::buildUpFindResultDock(ads::CDockManager *dock,
m_findresult->setProperty("EditorView", quintptr(0));
Utilities::applyTableViewProperty(m_findresult);
auto header = m_findresult->horizontalHeader();
m_findresult->setContextMenuPolicy(
Qt::ContextMenuPolicy::CustomContextMenu);
@ -1022,7 +1024,7 @@ MainWindow::buildUpVisualDataDock(ads::CDockManager *dock,
obj->property("__DOCK__").value<quintptr>());
if (dock) {
if (!title.isEmpty()) {
display += QStringLiteral("(") % title %
display += QStringLiteral("(") + title +
QStringLiteral(")");
}
dock->setWindowTitle(display);

View File

@ -21,6 +21,8 @@
#include "dialog/splashdialog.h"
#include "framelessmainwindow.h"
#include <QBuffer>
#include <QFutureWatcher>
#include <QListView>
#include <QMainWindow>
#include <QMap>
@ -32,12 +34,14 @@
#include <QToolButton>
#include <QTreeView>
#include <QtConcurrent/QtConcurrentRun>
#include <QtEndian>
#include "QWingRibbon/ribbon.h"
#include "QWingRibbon/ribbonbuttongroup.h"
#include "QWingRibbon/ribbontabcontent.h"
#include "Qt-Advanced-Docking-System/src/DockManager.h"
#include "Qt-Advanced-Docking-System/src/DockWidget.h"
#include "WingPlugin/iwingplugin.h"
#include "class/clickcallback.h"
#include "class/recentfilemanager.h"
#include "class/scriptmanager.h"
@ -49,7 +53,6 @@
#include "model/checksummodel.h"
#include "model/metadatamodel.h"
#include "model/numshowmodel.h"
#include "plugin/iwingplugin.h"
#include "scriptingdialog.h"
#include "settingdialog.h"
#include "showtextdialog.h"

View File

@ -22,12 +22,12 @@
#include "aboutsoftwaredialog.h"
#include "class/langservice.h"
#include "class/languagemanager.h"
#include "class/pluginsystem.h"
#include "class/qkeysequences.h"
#include "class/settingmanager.h"
#include "class/wingfiledialog.h"
#include "class/wingmessagebox.h"
#include "control/toast.h"
#include "plugin/pluginsystem.h"
#include "qcodeeditwidget/qeditconfig.h"
#include "qcodeeditwidget/qformatconfig.h"
#include "qdocumentline.h"

View File

@ -18,8 +18,8 @@
#ifndef SETTINGDIALOG_H
#define SETTINGDIALOG_H
#include "WingPlugin/settingpage.h"
#include "framelessdialogbase.h"
#include "plugin/settingpage.h"
#include <QAbstractButton>
namespace Ui {

View File

@ -48,7 +48,7 @@ QVariant FindResultModel::data(const QModelIndex &index, int role) const {
// range
auto data = m_findData.at(row);
QString buffer =
data.cheader.toHex(' ').toUpper() % QStringLiteral(" <b>");
data.cheader.toHex(' ').toUpper() + QStringLiteral(" <b>");
if (!data.hbuffer.isEmpty()) {
buffer += data.hbuffer.toHex(' ').toUpper();
if (!data.tbuffer.isEmpty()) {
@ -56,8 +56,8 @@ QVariant FindResultModel::data(const QModelIndex &index, int role) const {
}
}
buffer += data.tbuffer.toHex(' ').toUpper() %
QStringLiteral("</b> ") %
buffer += data.tbuffer.toHex(' ').toUpper() +
QStringLiteral("</b> ") +
data.ctailer.toHex(' ').toUpper();
return buffer;
@ -65,7 +65,7 @@ QVariant FindResultModel::data(const QModelIndex &index, int role) const {
case 4: { // decoding
auto data = m_findData.at(row);
QString buffer =
Utilities::decodingString(data.cheader, m_encoding) %
Utilities::decodingString(data.cheader, m_encoding) +
QStringLiteral(" <b>");
if (!data.hbuffer.isEmpty()) {
buffer += Utilities::decodingString(data.hbuffer);
@ -74,8 +74,8 @@ QVariant FindResultModel::data(const QModelIndex &index, int role) const {
}
}
buffer += Utilities::decodingString(data.tbuffer) %
QStringLiteral("</b> ") %
buffer += Utilities::decodingString(data.tbuffer) +
QStringLiteral("</b> ") +
Utilities::decodingString(data.ctailer);
return buffer;
@ -127,7 +127,9 @@ void FindResultModel::setEncoding(const QString &newEncoding) {
}
}
QList<WingHex::FindResult> &FindResultModel::results() { return m_results; }
QList<FindResultModel::FindResult> &FindResultModel::results() {
return m_results;
}
QList<FindResultModel::FindInfo> &FindResultModel::findData() {
return m_findData;
@ -139,7 +141,7 @@ void FindResultModel::beginUpdate() { this->beginResetModel(); }
void FindResultModel::endUpdate() { this->endResetModel(); }
WingHex::FindResult FindResultModel::resultAt(qsizetype index) const {
FindResultModel::FindResult FindResultModel::resultAt(qsizetype index) const {
return m_results.at(index);
}
@ -149,7 +151,7 @@ void FindResultModel::clear() {
emit layoutChanged();
}
QList<WingHex::FindResult>::size_type FindResultModel::size() const {
QList<FindResultModel::FindResult>::size_type FindResultModel::size() const {
return m_results.size();
}
@ -176,7 +178,7 @@ QString FindResultModel::copyContent(const QModelIndex &index) const {
}
}
buffer += data.tbuffer.toHex(' ').toUpper() %
buffer += data.tbuffer.toHex(' ').toUpper() +
data.ctailer.toHex(' ').toUpper();
return buffer;
@ -192,7 +194,7 @@ QString FindResultModel::copyContent(const QModelIndex &index) const {
}
}
buffer += Utilities::decodingString(data.tbuffer) %
buffer += Utilities::decodingString(data.tbuffer) +
Utilities::decodingString(data.ctailer);
return buffer;

View File

@ -18,8 +18,6 @@
#ifndef FINDRESULTMODEL_H
#define FINDRESULTMODEL_H
#include "plugin/iwingplugin.h"
#include <QAbstractTableModel>
class FindResultModel : public QAbstractTableModel {
@ -33,19 +31,25 @@ public:
QByteArray ctailer;
};
struct FindResult {
qsizetype offset = -1;
qsizetype line = -1;
qsizetype col = -1;
};
public:
explicit FindResultModel(QObject *parent = nullptr);
QList<WingHex::FindResult> &results();
QList<FindResult> &results();
QList<FindInfo> &findData();
QString &lastFindData();
void beginUpdate();
void endUpdate();
WingHex::FindResult resultAt(qsizetype index) const;
FindResult resultAt(qsizetype index) const;
void clear();
QList<WingHex::FindResult>::size_type size() const;
QList<FindResult>::size_type size() const;
QString copyContent(const QModelIndex &index) const;
@ -61,7 +65,7 @@ public:
void setEncoding(const QString &newEncoding);
private:
QList<WingHex::FindResult> m_results;
QList<FindResult> m_results;
QList<FindInfo> m_findData;
QString m_lastFindData;

View File

@ -1,664 +0,0 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** You can redistribute this file and/or modify it under the terms of the
** BSD 3-Clause.
**
** THIS FILE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** =============================================================================
*/
#ifndef IWINGPLUGIN_H
#define IWINGPLUGIN_H
#include "iwingpluginbase.h"
#include <functional>
#include <variant>
#include <QCryptographicHash>
#include <QDockWidget>
#include <QList>
#include <QMap>
#include <QMenu>
#include <QToolBar>
#include <QToolButton>
#include <QWidget>
#include <QtCore>
#include <QMetaObject>
/**
* Don't try to modify this file, unless you are the dev
*
*/
namespace WingHex {
Q_NAMESPACE
enum ErrFile : int {
Success = 0,
Error = -1,
UnSaved = -2,
Permission = -3,
NotExist = -4,
AlreadyOpened = -5,
IsNewFile = -6,
WorkSpaceUnSaved = -7,
ClonedFile = -8,
InvalidFormat = -9,
TooManyOpenedFile = -10,
NotAllowedInNoneGUIThread = -11,
DevNotFound = -12,
};
Q_ENUM_NS(ErrFile)
Q_NAMESPACE
enum class SelectionMode : int { Add, Remove, Single };
Q_ENUM_NS(SelectionMode)
struct FindResult {
qsizetype offset = -1;
qsizetype line = -1;
qsizetype col = -1;
};
class IWingPlugin;
struct HexPosition {
qsizetype line;
int column;
quint8 lineWidth;
int nibbleindex;
Q_REQUIRED_RESULT inline qsizetype offset() const {
return static_cast<qsizetype>(line * lineWidth) + column;
}
inline qsizetype operator-(const HexPosition &rhs) const {
return qsizetype(this->offset() - rhs.offset());
}
inline bool operator==(const HexPosition &rhs) const {
return (line == rhs.line) && (column == rhs.column) &&
(nibbleindex == rhs.nibbleindex);
}
inline bool operator!=(const HexPosition &rhs) const {
return (line != rhs.line) || (column != rhs.column) ||
(nibbleindex != rhs.nibbleindex);
}
};
namespace WingPlugin {
class Reader : public QObject {
Q_OBJECT
signals:
Q_REQUIRED_RESULT bool isCurrentDocEditing();
Q_REQUIRED_RESULT QString currentDocFilename();
// document
Q_REQUIRED_RESULT bool isReadOnly();
Q_REQUIRED_RESULT bool isInsertionMode();
Q_REQUIRED_RESULT bool isKeepSize();
Q_REQUIRED_RESULT bool isLocked();
Q_REQUIRED_RESULT qsizetype documentLines();
Q_REQUIRED_RESULT qsizetype documentBytes();
Q_REQUIRED_RESULT WingHex::HexPosition currentPos();
Q_REQUIRED_RESULT qsizetype currentRow();
Q_REQUIRED_RESULT qsizetype currentColumn();
Q_REQUIRED_RESULT qsizetype currentOffset();
Q_REQUIRED_RESULT qsizetype selectedLength();
Q_REQUIRED_RESULT QByteArray selectedBytes(qsizetype index);
Q_REQUIRED_RESULT QByteArrayList selectionBytes();
Q_REQUIRED_RESULT WingHex::HexPosition selectionStart(qsizetype index);
Q_REQUIRED_RESULT WingHex::HexPosition selectionEnd(qsizetype index);
Q_REQUIRED_RESULT qsizetype selectionLength(qsizetype index);
Q_REQUIRED_RESULT qsizetype selectionCount();
Q_REQUIRED_RESULT bool stringVisible();
Q_REQUIRED_RESULT bool addressVisible();
Q_REQUIRED_RESULT bool headerVisible();
Q_REQUIRED_RESULT quintptr addressBase();
Q_REQUIRED_RESULT bool isModified();
Q_REQUIRED_RESULT qint8 readInt8(qsizetype offset);
Q_REQUIRED_RESULT qint16 readInt16(qsizetype offset);
Q_REQUIRED_RESULT qint32 readInt32(qsizetype offset);
Q_REQUIRED_RESULT qint64 readInt64(qsizetype offset);
Q_REQUIRED_RESULT float readFloat(qsizetype offset);
Q_REQUIRED_RESULT double readDouble(qsizetype offset);
Q_REQUIRED_RESULT QString readString(qsizetype offset,
const QString &encoding = QString());
Q_REQUIRED_RESULT QByteArray readBytes(qsizetype offset, qsizetype count);
Q_REQUIRED_RESULT qsizetype findNext(qsizetype begin, const QByteArray &ba);
Q_REQUIRED_RESULT qsizetype findPrevious(qsizetype begin,
const QByteArray &ba);
Q_REQUIRED_RESULT QList<qsizetype>
findAllBytes(qsizetype begin, qsizetype end, const QByteArray &b);
// metadata
Q_REQUIRED_RESULT bool lineHasMetadata(qsizetype line);
// bookmark
Q_REQUIRED_RESULT bool lineHasBookMark(qsizetype line);
Q_REQUIRED_RESULT QList<qsizetype> getsBookmarkPos(qsizetype line);
Q_REQUIRED_RESULT QString bookMarkComment(qsizetype pos);
Q_REQUIRED_RESULT bool existBookMark(qsizetype pos);
// extension
Q_REQUIRED_RESULT QStringList getSupportedEncodings();
Q_REQUIRED_RESULT QStringList getStorageDrivers();
};
class Controller : public QObject {
Q_OBJECT
signals:
// document
Q_REQUIRED_RESULT bool switchDocument(int handle);
Q_REQUIRED_RESULT bool raiseDocument(int handle);
Q_REQUIRED_RESULT bool setLockedFile(bool b);
Q_REQUIRED_RESULT bool setKeepSize(bool b);
Q_REQUIRED_RESULT bool setStringVisible(bool b);
Q_REQUIRED_RESULT bool setAddressVisible(bool b);
Q_REQUIRED_RESULT bool setHeaderVisible(bool b);
Q_REQUIRED_RESULT bool setAddressBase(quintptr base);
Q_REQUIRED_RESULT bool beginMarco(const QString &txt = {});
bool endMarco();
Q_REQUIRED_RESULT bool writeInt8(qsizetype offset, qint8 value);
Q_REQUIRED_RESULT bool writeInt16(qsizetype offset, qint16 value);
Q_REQUIRED_RESULT bool writeInt32(qsizetype offset, qint32 value);
Q_REQUIRED_RESULT bool writeInt64(qsizetype offset, qint64 value);
Q_REQUIRED_RESULT bool writeFloat(qsizetype offset, float value);
Q_REQUIRED_RESULT bool writeDouble(qsizetype offset, double value);
Q_REQUIRED_RESULT bool writeString(qsizetype offset, const QString &value,
const QString &encoding = QString());
Q_REQUIRED_RESULT bool writeBytes(qsizetype offset, const QByteArray &data);
Q_REQUIRED_RESULT bool insertInt8(qsizetype offset, qint8 value);
Q_REQUIRED_RESULT bool insertInt16(qsizetype offset, qint16 value);
Q_REQUIRED_RESULT bool insertInt32(qsizetype offset, qint32 value);
Q_REQUIRED_RESULT bool insertInt64(qsizetype offset, qint64 value);
Q_REQUIRED_RESULT bool insertFloat(qsizetype offset, float value);
Q_REQUIRED_RESULT bool insertDouble(qsizetype offset, double value);
Q_REQUIRED_RESULT bool insertString(qsizetype offset, const QString &value,
const QString &encoding = QString());
Q_REQUIRED_RESULT bool insertBytes(qsizetype offset,
const QByteArray &data);
Q_REQUIRED_RESULT bool appendInt8(qint8 value);
Q_REQUIRED_RESULT bool appendInt16(qint16 value);
Q_REQUIRED_RESULT bool appendInt32(qint32 value);
Q_REQUIRED_RESULT bool appendInt64(qint64 value);
Q_REQUIRED_RESULT bool appendFloat(float value);
Q_REQUIRED_RESULT bool appendDouble(double value);
Q_REQUIRED_RESULT bool appendString(const QString &value,
const QString &encoding = QString());
Q_REQUIRED_RESULT bool appendBytes(const QByteArray &data);
Q_REQUIRED_RESULT bool remove(qsizetype offset, qsizetype len);
Q_REQUIRED_RESULT bool removeAllBytes(); // extension
// cursor
Q_REQUIRED_RESULT bool moveTo(qsizetype line, qsizetype column,
int nibbleindex = 1,
bool clearSelection = true);
Q_REQUIRED_RESULT bool moveTo(qsizetype offset, bool clearSelection = true);
Q_REQUIRED_RESULT bool select(qsizetype offset, qsizetype length,
SelectionMode mode = SelectionMode::Add);
Q_REQUIRED_RESULT bool setInsertionMode(bool isinsert);
// metadata
Q_REQUIRED_RESULT bool foreground(qsizetype begin, qusizetype length,
const QColor &fgcolor);
Q_REQUIRED_RESULT bool background(qsizetype begin, qusizetype length,
const QColor &bgcolor);
Q_REQUIRED_RESULT bool comment(qsizetype begin, qusizetype length,
const QString &comment);
Q_REQUIRED_RESULT bool metadata(qsizetype begin, qusizetype length,
const QColor &fgcolor,
const QColor &bgcolor,
const QString &comment);
Q_REQUIRED_RESULT bool removeMetadata(qsizetype offset);
Q_REQUIRED_RESULT bool clearMetadata();
Q_REQUIRED_RESULT bool setMetaVisible(bool b);
Q_REQUIRED_RESULT bool setMetafgVisible(bool b);
Q_REQUIRED_RESULT bool setMetabgVisible(bool b);
Q_REQUIRED_RESULT bool setMetaCommentVisible(bool b);
// mainwindow
Q_REQUIRED_RESULT WingHex::ErrFile newFile();
Q_REQUIRED_RESULT WingHex::ErrFile openFile(const QString &filename);
Q_REQUIRED_RESULT WingHex::ErrFile openExtFile(const QString &ext,
const QString &file);
WingHex::ErrFile closeHandle(int handle);
WingHex::ErrFile closeFile(int handle, bool force = false);
Q_REQUIRED_RESULT WingHex::ErrFile saveFile(int handle);
Q_REQUIRED_RESULT WingHex::ErrFile exportFile(int handle,
const QString &savename);
Q_REQUIRED_RESULT WingHex::ErrFile saveAsFile(int handle,
const QString &savename);
Q_REQUIRED_RESULT WingHex::ErrFile openCurrent();
Q_REQUIRED_RESULT WingHex::ErrFile closeCurrent(bool force = false);
Q_REQUIRED_RESULT WingHex::ErrFile saveCurrent();
Q_REQUIRED_RESULT WingHex::ErrFile exportCurrent(const QString &savename);
Q_REQUIRED_RESULT WingHex::ErrFile saveAsCurrent(const QString &savename);
// bookmark
Q_REQUIRED_RESULT bool addBookMark(qsizetype pos, const QString &comment);
Q_REQUIRED_RESULT bool modBookMark(qsizetype pos, const QString &comment);
Q_REQUIRED_RESULT bool removeBookMark(qsizetype pos);
Q_REQUIRED_RESULT bool clearBookMark();
// workspace
Q_REQUIRED_RESULT WingHex::ErrFile openWorkSpace(const QString &filename);
// extension
bool closeAll();
};
class DataVisual : public QObject {
Q_OBJECT
public:
typedef std::function<void(const QModelIndex &)> ClickedCallBack;
typedef ClickedCallBack DoubleClickedCallBack;
signals:
bool updateText(const QString &data, const QString &title = {});
bool updateTextList(const QStringList &data, const QString &title = {},
ClickedCallBack clicked = {},
DoubleClickedCallBack dblClicked = {});
Q_REQUIRED_RESULT bool
updateTextTree(const QString &json, const QString &title = {},
ClickedCallBack clicked = {},
DoubleClickedCallBack dblClicked = {});
Q_REQUIRED_RESULT bool
updateTextTable(const QString &json, const QStringList &headers,
const QStringList &headerNames = {},
const QString &title = {}, ClickedCallBack clicked = {},
DoubleClickedCallBack dblClicked = {});
// API for Qt Plugin Only
Q_REQUIRED_RESULT bool
updateTextListByModel(QAbstractItemModel *model, const QString &title = {},
ClickedCallBack clicked = {},
DoubleClickedCallBack dblClicked = {});
Q_REQUIRED_RESULT bool
updateTextTableByModel(QAbstractItemModel *model, const QString &title = {},
ClickedCallBack clicked = {},
DoubleClickedCallBack dblClicked = {});
Q_REQUIRED_RESULT bool
updateTextTreeByModel(QAbstractItemModel *model, const QString &title = {},
ClickedCallBack clicked = {},
DoubleClickedCallBack dblClicked = {});
};
} // namespace WingPlugin
struct WingRibbonToolBoxInfo {
struct RibbonCatagories {
const QString FILE = QStringLiteral("File");
const QString EDIT = QStringLiteral("Edit");
const QString VIEW = QStringLiteral("View");
const QString SCRIPT = QStringLiteral("Script");
const QString PLUGIN = QStringLiteral("Plugin");
const QString SETTING = QStringLiteral("Setting");
const QString ABOUT = QStringLiteral("About");
};
QString catagory;
QString displayName;
struct Toolbox {
QString name;
QList<QToolButton *> tools;
};
QList<Toolbox> toolboxs;
};
class WingEditorViewWidget : public QWidget {
Q_OBJECT
public:
class Creator {
public:
Creator() = default;
public:
virtual QIcon icon() const = 0;
virtual QString name() const = 0;
virtual QString id() const = 0;
public:
virtual WingEditorViewWidget *create(WingHex::IWingPlugin *plg,
QWidget *parent) const = 0;
};
public:
explicit WingEditorViewWidget(WingHex::IWingPlugin *plg,
QWidget *parent = nullptr)
: QWidget(parent), _plg(plg) {}
WingHex::IWingPlugin *plugin() const { return _plg; }
signals:
void docSaved(bool saved);
void raiseView();
public slots:
virtual void toggled(bool isVisible) = 0;
virtual void loadState(const QByteArray &state) { Q_UNUSED(state); }
virtual bool hasUnsavedState() { return false; }
virtual QByteArray saveState() { return {}; }
virtual WingEditorViewWidget *clone() = 0;
// return false then stop closing and swith the view
// but you cannot prevent closing the cloned view
virtual bool onClosing() { return true; }
// cloned view will never call it
virtual void onWorkSpaceNotify(bool isWorkSpace) { Q_UNUSED(isWorkSpace); }
private:
WingHex::IWingPlugin *_plg;
};
struct SenderInfo {
QString plgcls;
QString puid;
QVariant meta;
};
// for bad broken Qt API
#define WINGAPI_ARG(type, data) QArgument<type>(#type, data)
#define WINGAPI_RETURN_ARG(type, data) QReturnArgument<type>(#type, data)
class IWingPlugin : public IWingPluginBase {
Q_OBJECT
public:
struct ScriptCallError {
int errorCode;
QString errmsg;
};
using ScriptFn = std::function<QVariant(const QVariantList &)>;
using UNSAFE_RET =
std::variant<std::monostate, bool, quint8, quint16, quint32, quint64,
float, double, void *, ScriptCallError>;
using UNSAFE_SCFNPTR = std::function<UNSAFE_RET(const QList<void *> &)>;
enum MetaType : uint {
Void,
Bool,
Int,
Int32 = Int,
UInt,
UInt32 = UInt,
Int8,
UInt8,
Int16,
UInt16,
Int64,
UInt64,
Float,
Double,
String,
Char,
Byte,
Color,
Map, // QVariantMap -> dictionary
Hash, // QVariantHash -> dictionary
MetaMax, // reserved
MetaTypeMask = 0xFFFFF,
Array = 0x100000, // QVector<?> -> array<?>
List = 0x200000, // QList<?> -> array<?>
};
static_assert(MetaType::MetaMax < MetaType::Array);
struct ScriptFnInfo {
MetaType ret;
QVector<QPair<MetaType, QString>> params;
ScriptFn fn;
};
enum class RegisteredEvent : uint {
None,
AppReady = 1u,
AppClosing = 1u << 1,
SelectionChanged = 1u << 2,
CursorPositionChanged = 1u << 3,
FileOpened = 1u << 4,
FileSaved = 1u << 5,
FileSwitched = 1u << 6,
FileClosed = 1u << 7,
ScriptPragma = 1u << 8,
PluginFileOpened = 1u << 9,
PluginFileClosed = 1u << 10,
ScriptUnSafeFnRegistering = 1u << 11,
ScriptPragmaInit = 1u << 12
};
Q_DECLARE_FLAGS(RegisteredEvents, RegisteredEvent)
enum class PluginFileEvent {
Opened,
Saved,
Exported,
Switched,
Closed,
PluginOpened,
PluginClosed
};
enum class FileType { Invalid, File, Extension };
Q_ENUM(FileType)
public:
ScriptCallError generateScriptCallError(int errCode, const QString &msg) {
ScriptCallError err;
err.errorCode = errCode;
err.errmsg = msg;
return err;
}
QVariant getScriptCallError(int errCode, const QString &msg) {
ScriptCallError err;
err.errorCode = errCode;
err.errmsg = msg;
return QVariant::fromValue(err);
}
public:
virtual ~IWingPlugin() = default;
virtual RegisteredEvents registeredEvents() const {
return RegisteredEvent::None;
}
public:
virtual QMenu *registeredHexContextMenu() const { return nullptr; }
virtual QList<WingRibbonToolBoxInfo> registeredRibbonTools() const {
return {};
}
// QMap<page, whether is visible in setting tab>
virtual QHash<SettingPage *, bool> registeredSettingPages() const {
return {};
}
virtual QList<QSharedPointer<WingEditorViewWidget::Creator>>
registeredEditorViewWidgets() const {
return {};
}
public:
// QHash< function-name, fn >
virtual QHash<QString, ScriptFnInfo> registeredScriptFns() const {
return {};
}
// A hacking way to register script function (Generic_Call)
// This registering way is not safe. There is no
// other checking except function's signature.
// You should handle your all the types and pay yourself.
// You should set RegisteredEvent::ScriptFnRegistering ON to enable it.
// QHash< function-name, fn >
virtual QHash<QString, UNSAFE_SCFNPTR> registeredScriptUnsafeFns() const {
return {};
}
// QHash< enum , members >
virtual QHash<QString, QList<QPair<QString, int>>>
registeredScriptEnums() const {
return {};
}
// Note: must be valid identifier
virtual QStringList registerScriptMarcos() const { return {}; }
public:
virtual void eventSelectionChanged(const QByteArrayList &selections,
bool isPreview) {
Q_UNUSED(selections);
Q_UNUSED(isPreview);
}
virtual void eventCursorPositionChanged(const WingHex::HexPosition &pos) {
Q_UNUSED(pos);
}
virtual void eventPluginFile(PluginFileEvent e, FileType type,
const QString &newfileName, int handle,
const QString &oldfileName) {
Q_UNUSED(e);
Q_UNUSED(newfileName);
Q_UNUSED(oldfileName);
Q_UNUSED(handle);
Q_UNUSED(type);
}
virtual void eventReady() {}
virtual bool eventClosing() { return true; }
public:
virtual bool eventOnScriptPragma(const QString &script,
const QStringList &comments) {
Q_UNUSED(script);
Q_UNUSED(comments);
return false;
}
virtual void eventOnScriptPragmaInit() {}
signals:
bool existsServiceHost(const QString &puid);
bool invokeService(const QString &puid, const char *method,
Qt::ConnectionType type, QGenericReturnArgument ret,
QGenericArgument val0 = QGenericArgument(nullptr),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument());
public:
inline bool invokeService(const QString &puid, const char *member,
QGenericReturnArgument ret,
QGenericArgument val0 = QGenericArgument(nullptr),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument()) {
return emit invokeService(puid, member, Qt::DirectConnection, ret, val0,
val1, val2, val3, val4, val5, val6, val7,
val8);
}
inline bool invokeService(const QString &puid, const char *member,
Qt::ConnectionType type, QGenericArgument val0,
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument()) {
return emit invokeService(puid, member, type, QGenericReturnArgument(),
val0, val1, val2, val3, val4, val5, val6,
val7, val8);
}
inline bool invokeService(const QString &puid, const char *member,
QGenericArgument val0,
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument()) {
return emit invokeService(puid, member, Qt::DirectConnection,
QGenericReturnArgument(), val0, val1, val2,
val3, val4, val5, val6, val7, val8);
}
public:
WingPlugin::Reader reader;
WingPlugin::Controller controller;
WingPlugin::DataVisual visual;
};
} // namespace WingHex
Q_DECLARE_METATYPE(WingHex::SenderInfo)
Q_DECLARE_METATYPE(WingHex::IWingPlugin::ScriptCallError)
Q_DECLARE_INTERFACE(WingHex::IWingPlugin, "com.wingsummer.iwingplugin")
#endif // IWINGPLUGIN_H

File diff suppressed because it is too large Load Diff

View File

@ -1,415 +0,0 @@
/*==============================================================================
** 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 PLUGINSYSTEM_H
#define PLUGINSYSTEM_H
#include <QDockWidget>
#include <QHash>
#include <QList>
#include <QMenu>
#include <QMutex>
#include <QObject>
#include <QTimer>
#include <QTimerEvent>
#include <QToolButton>
#include <QVariant>
#include "class/clickcallback.h"
#include "class/wingangelapi.h"
#include "control/editorview.h"
#include "plugin/iwingdevice.h"
using namespace WingHex;
class MainWindow;
class asCScriptEngine;
class PluginSystem : public QObject {
Q_OBJECT
private:
class UniqueIdGenerator {
public:
class UniqueId : public QSharedData {
public:
UniqueId() : _id(-1), _gen(nullptr) {}
UniqueId(UniqueIdGenerator *gen, int id) : _id(id), _gen(gen) {
Q_ASSERT(gen);
Q_ASSERT(id >= 0);
#ifdef QT_DEBUG
qDebug() << "[UniqueId] alloced: " << id;
#endif
}
~UniqueId() {
if (_gen) {
_gen->release(_id);
}
#ifdef QT_DEBUG
qDebug() << "[UniqueId] freed: " << _id;
#endif
}
operator int() { return _id; }
private:
int _id;
UniqueIdGenerator *_gen;
};
public:
UniqueIdGenerator() : currentId(0) {}
QExplicitlySharedDataPointer<UniqueId> get() {
if (!releasedIds.isEmpty()) {
int id = releasedIds.dequeue();
return QExplicitlySharedDataPointer<UniqueId>(
new UniqueId(this, id));
} else {
return QExplicitlySharedDataPointer<UniqueId>(
new UniqueId(this, currentId++));
}
}
void release(int id) {
if (id < currentId && !releasedIds.contains(id)) {
releasedIds.enqueue(id);
}
}
private:
int currentId;
QQueue<int> releasedIds;
};
using SharedUniqueId =
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,
BrokenVersion,
InvalidID,
DupID,
LackDependencies
};
Q_ENUM(PluginStatus)
private:
struct PluginFileContext {
SharedUniqueId fid;
EditorView *view = nullptr;
IWingPlugin *linkedplg = nullptr;
QUndoCommand *cmd = nullptr;
~PluginFileContext() {
if (cmd) {
delete cmd;
}
}
};
public:
static PluginSystem &instance();
void setMainWindow(MainWindow *win);
QWidget *mainWindow() const;
void loadAllPlugin();
void unloadAllPlugin();
void destory();
const QList<IWingPlugin *> &plugins() const;
IWingPlugin *plugin(qsizetype index) const;
const QList<IWingDevice *> &devices() const;
IWingDevice *device(qsizetype index) const;
WingAngelAPI *angelApi() const;
void cleanUpEditorViewHandle(EditorView *view);
bool dispatchEvent(IWingPlugin::RegisteredEvent event,
const QVariantList &params);
IWingDevice *ext2Device(const QString &ext);
QStringList scriptMarcos() const;
public:
void scriptPragmaBegin();
public:
PluginInfo getPluginInfo(IWingPluginBase *plg) const;
QString getPluginID(IWingPluginBase *plg) const;
static QString getPUID(IWingPluginBase *p);
static QString type2AngelScriptString(IWingPlugin::MetaType type,
bool isArg, bool noModifier = false);
private:
void loadExtPlugin();
void loadDevicePlugin();
void checkDirRootSafe(const QDir &dir);
template <typename T>
std::optional<PluginInfo> loadPlugin(const QFileInfo &filename,
const QDir &setdir);
bool closeEditor(IWingPlugin *plg, int handle, bool force);
bool closeHandle(IWingPlugin *plg, int handle);
bool checkPluginCanOpenedFile(IWingPlugin *plg);
bool checkPluginHasAlreadyOpened(IWingPlugin *plg, EditorView *view);
EditorView *getCurrentPluginView(IWingPlugin *plg);
EditorView *handle2EditorView(IWingPlugin *plg, int handle);
SharedUniqueId assginHandleForPluginView(IWingPlugin *plg,
EditorView *view);
static bool equalCompareHandle(const SharedUniqueId &id, int handle);
static int getUIDHandle(const SharedUniqueId &id);
private:
PluginInfo parsePluginMetadata(const QJsonObject &meta);
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);
static QString getScriptFnSig(const QString &fnName,
const IWingPlugin::ScriptFnInfo &fninfo);
bool isPluginLoaded(const WingDependency &d);
bool isPluginLoaded(const QString &id);
bool checkThreadAff();
static QString packLogMessage(const char *header, const QString &msg);
EditorView *pluginCurrentEditor(IWingPlugin *plg) const;
QSharedPointer<PluginFileContext> pluginContextById(IWingPlugin *plg,
int fid) const;
QUndoCommand *pluginCurrentUndoCmd(IWingPlugin *plg) const;
private:
void loadPlugin(IWingPlugin *p, PluginInfo &meta,
const std::optional<QDir> &setdir);
void loadPlugin(IWingDevice *p, PluginInfo &meta,
const std::optional<QDir> &setdir);
private:
void connectInterface(IWingPlugin *plg);
void connectLoadingInterface(IWingPlugin *plg);
void connectBaseInterface(IWingPlugin *plg);
void connectReaderInterface(IWingPlugin *plg);
void connectControllerInterface(IWingPlugin *plg);
void connectUIInterface(IWingPlugin *plg);
private:
void connectInterface(IWingDevice *plg);
void connectLoadingInterface(IWingDevice *plg);
void registerMarcoDevice(IWingDevice *plg);
private:
void connectBaseInterface(IWingPluginBase *plg);
void connectUIInterface(IWingPluginBase *plg);
void registerPluginDockWidgets(IWingPluginBase *p);
void registerPluginPages(IWingPluginBase *p);
public:
bool updateTextList_API(const QStringList &data, const QString &title,
const ClickCallBack &click,
const ClickCallBack &dblclick);
bool updateTextTree_API(const QString &json, const QString &title,
const ClickCallBack &click,
const ClickCallBack &dblclick);
bool updateTextTable_API(const QString &json, const QStringList &headers,
const QStringList &headerNames,
const QString &title, const ClickCallBack &click,
const ClickCallBack &dblclick);
public:
// fpr crash checking
QString currentLoadingPlugin() const;
private:
template <typename T>
T readBasicTypeContent(IWingPlugin *plg, qsizetype offset) {
Q_STATIC_ASSERT(std::is_integral_v<T> || std::is_floating_point_v<T>);
auto e = pluginCurrentEditor(plg);
if (e) {
_rwlock.lockForRead();
auto buffer = e->hexEditor()->document()->read(offset, sizeof(T));
if (buffer.size() == sizeof(T)) {
auto pb = reinterpret_cast<const T *>(buffer.constData());
_rwlock.unlock();
return *pb;
}
}
if constexpr (std::is_floating_point_v<T>) {
return qQNaN();
} else {
return T(0);
}
}
template <typename T>
bool insertBasicTypeContent(IWingPlugin *plg, qsizetype offset,
const T &value) {
Q_STATIC_ASSERT(std::is_integral_v<T> || std::is_floating_point_v<T>);
auto e = getCurrentPluginView(plg);
if (e) {
auto editor = e->hexEditor();
auto doc = editor->document();
auto buffer = reinterpret_cast<const char *>(&value);
auto uc = pluginCurrentUndoCmd(plg);
auto cmd = doc->MakeInsert(uc, editor->cursor(), offset,
QByteArray(buffer, sizeof(T)));
if (uc == nullptr && cmd) {
_rwlock.lockForWrite();
doc->pushMakeUndo(cmd);
_rwlock.unlock();
return true;
}
}
return false;
}
template <typename T>
bool writeBasicTypeContent(IWingPlugin *plg, qsizetype offset,
const T &value) {
Q_STATIC_ASSERT(std::is_integral_v<T> || std::is_floating_point_v<T>);
auto e = getCurrentPluginView(plg);
if (e) {
auto editor = e->hexEditor();
auto doc = editor->document();
auto buffer = reinterpret_cast<const char *>(&value);
auto uc = pluginCurrentUndoCmd(plg);
auto cmd = doc->MakeReplace(uc, editor->cursor(), offset,
QByteArray(buffer, sizeof(T)));
if (uc == nullptr && cmd) {
_rwlock.lockForWrite();
doc->pushMakeUndo(cmd);
_rwlock.unlock();
return true;
}
}
return false;
}
template <typename T>
bool appendBasicTypeContent(IWingPlugin *plg, const T &value) {
Q_STATIC_ASSERT(std::is_integral_v<T> || std::is_floating_point_v<T>);
auto e = getCurrentPluginView(plg);
if (e) {
auto editor = e->hexEditor();
auto doc = editor->document();
auto buffer = reinterpret_cast<const char *>(&value);
auto uc = pluginCurrentUndoCmd(plg);
auto cmd = doc->MakeAppend(uc, editor->cursor(),
QByteArray(buffer, sizeof(T)));
if (uc == nullptr && cmd) {
_rwlock.lockForWrite();
doc->pushMakeUndo(cmd);
_rwlock.unlock();
return true;
}
}
return false;
}
signals:
void pluginLoading(const QString &plgName);
private:
PluginSystem(QObject *parent = nullptr);
~PluginSystem();
void initCheckingEngine();
void finalizeCheckingEngine();
private:
MainWindow *_win = nullptr;
QHash<IWingPluginBase *, PluginInfo> _pinfos;
QList<IWingPlugin *> _loadedplgs;
QHash<QWidget *, ads::CDockWidget *> _raisedw;
QStringList _lazyplgs;
QList<IWingDevice *> _loadeddevs;
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;
UniqueIdGenerator m_idGen;
QHash<QString, QHash<QString, WingAngelAPI::ScriptFnInfo>> _scfns;
WingAngelAPI *_angelplg = nullptr;
asCScriptEngine *_engine = nullptr;
QStringList _scriptMarcos;
QList<IWingPlugin *> _pragmaedPlg;
QReadWriteLock _rwlock;
private:
QString _curLoadingPlg;
Q_DISABLE_COPY_MOVE(PluginSystem)
};
#endif // PLUGINSYSTEM_H

View File

@ -1,7 +1,7 @@
#ifndef QEDITCONFIG_H
#define QEDITCONFIG_H
#include "plugin/settingpage.h"
#include "WingPlugin/settingpage.h"
#include "qeditor.h"
#include <QWidget>

View File

@ -1,8 +1,8 @@
#ifndef QFORMATCONFIG_H
#define QFORMATCONFIG_H
#include "WingPlugin/settingpage.h"
#include "formatconfigmodel.h"
#include "plugin/settingpage.h"
#include <QWidget>
namespace Ui {

View File

@ -1,7 +1,7 @@
#ifndef CLANGFORMATSETDIALOG_H
#define CLANGFORMATSETDIALOG_H
#include "plugin/settingpage.h"
#include "WingPlugin/settingpage.h"
namespace Ui {
class ClangFormatSetDialog;

View File

@ -18,7 +18,7 @@
#ifndef EDITORSETTINGDIALOG_H
#define EDITORSETTINGDIALOG_H
#include "plugin/settingpage.h"
#include "WingPlugin/settingpage.h"
#include <QWidget>
namespace Ui {

View File

@ -18,7 +18,7 @@
#ifndef GENERALSETTINGDIALOG_H
#define GENERALSETTINGDIALOG_H
#include "plugin/settingpage.h"
#include "WingPlugin/settingpage.h"
#include <QWidget>
namespace Ui {

View File

@ -18,7 +18,7 @@
#ifndef OTHERSETTINGSDIALOG_H
#define OTHERSETTINGSDIALOG_H
#include "plugin/settingpage.h"
#include "WingPlugin/settingpage.h"
#include <QWidget>
namespace Ui {

View File

@ -16,9 +16,9 @@
*/
#include "pluginsettingdialog.h"
#include "class/pluginsystem.h"
#include "class/settingmanager.h"
#include "dbghelper.h"
#include "plugin/pluginsystem.h"
#include "ui_pluginsettingdialog.h"
#include "utilities.h"

View File

@ -18,7 +18,7 @@
#ifndef PLUGINSETTINGDIALOG_H
#define PLUGINSETTINGDIALOG_H
#include "../plugin/settingpage.h"
#include "WingPlugin/settingpage.h"
#include <QWidget>
namespace Ui {

View File

@ -18,8 +18,8 @@
#ifndef SCRIPTSETTINGDIALOG_H
#define SCRIPTSETTINGDIALOG_H
#include "WingPlugin/settingpage.h"
#include "class/scriptmanager.h"
#include "plugin/settingpage.h"
#include <QWidget>
namespace Ui {

View File

@ -242,7 +242,9 @@ public:
QAbstractItemView::SelectionBehavior::SelectRows);
view->setFocusPolicy(Qt::StrongFocus);
view->verticalHeader()->setDefaultAlignment(Qt::AlignCenter);
view->horizontalHeader()->setStretchLastSection(true);
auto hheader = view->horizontalHeader();
hheader->setStretchLastSection(true);
hheader->setHighlightSections(false);
}
template <typename T>