feat: 增加插件管理者插件支持以及引入相关破坏性更新;

This commit is contained in:
寂静的羽夏 2025-06-26 19:45:55 +08:00
parent 08d5969070
commit b42880aa7e
39 changed files with 1042 additions and 795 deletions

View File

@ -28,6 +28,7 @@ add_definitions(-DAS_NO_THREADS)
if(BUILD_TEST_PLUGIN) if(BUILD_TEST_PLUGIN)
add_subdirectory(TestPlugin) add_subdirectory(TestPlugin)
add_subdirectory(TestManager)
endif() endif()
if(BUILD_SHARED_MEM_EXT) if(BUILD_SHARED_MEM_EXT)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

98
TestManager/testmanager.h Normal file
View File

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

View File

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

View File

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

View File

@ -269,72 +269,64 @@
<context> <context>
<name>TestPlugin</name> <name>TestPlugin</name>
<message> <message>
<location filename="../testplugin.cpp" line="207"/> <location filename="../testplugin.cpp" line="204"/>
<source>Test</source> <source>Test</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../testplugin.cpp" line="219"/> <location filename="../testplugin.cpp" line="216"/>
<location filename="../testplugin.cpp" line="228"/> <location filename="../testplugin.cpp" line="225"/>
<location filename="../testplugin.cpp" line="233"/> <location filename="../testplugin.cpp" line="230"/>
<location filename="../testplugin.cpp" line="314"/> <location filename="../testplugin.cpp" line="299"/>
<source>TestPlugin</source> <source>TestPlugin</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../testplugin.cpp" line="237"/> <location filename="../testplugin.cpp" line="234"/>
<source>Button - </source> <source>Button - </source>
<translation> - </translation> <translation> - </translation>
</message> </message>
<message> <message>
<location filename="../testplugin.cpp" line="241"/> <location filename="../testplugin.cpp" line="238"/>
<source>Click</source> <source>Click</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../testplugin.cpp" line="317"/> <location filename="../testplugin.cpp" line="302"/>
<source>A Test Plugin for WingHexExplorer2.</source> <source>A Test Plugin for WingHexExplorer2.</source>
<translation>2</translation> <translation>2</translation>
</message> </message>
<message> <message>
<location filename="../testplugin.cpp" line="355"/> <location filename="../testplugin.cpp" line="336"/>
<location filename="../testplugin.cpp" line="363"/> <location filename="../testplugin.cpp" line="344"/>
<location filename="../testplugin.cpp" line="372"/> <location filename="../testplugin.cpp" line="353"/>
<location filename="../testplugin.cpp" line="393"/> <location filename="../testplugin.cpp" line="374"/>
<location filename="../testplugin.cpp" line="409"/> <location filename="../testplugin.cpp" line="390"/>
<location filename="../testplugin.cpp" line="416"/> <location filename="../testplugin.cpp" line="397"/>
<location filename="../testplugin.cpp" line="423"/> <location filename="../testplugin.cpp" line="404"/>
<location filename="../testplugin.cpp" line="430"/> <location filename="../testplugin.cpp" line="411"/>
<location filename="../testplugin.cpp" line="438"/> <location filename="../testplugin.cpp" line="419"/>
<location filename="../testplugin.cpp" line="467"/> <location filename="../testplugin.cpp" line="448"/>
<location filename="../testplugin.cpp" line="475"/> <location filename="../testplugin.cpp" line="456"/>
<location filename="../testplugin.cpp" line="483"/> <location filename="../testplugin.cpp" line="464"/>
<location filename="../testplugin.cpp" line="491"/> <location filename="../testplugin.cpp" line="472"/>
<location filename="../testplugin.cpp" line="500"/> <location filename="../testplugin.cpp" line="481"/>
<location filename="../testplugin.cpp" line="507"/> <location filename="../testplugin.cpp" line="488"/>
<source>InvalidParamsCount</source> <source>InvalidParamsCount</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../testplugin.cpp" line="386"/> <location filename="../testplugin.cpp" line="367"/>
<location filename="../testplugin.cpp" line="402"/> <location filename="../testplugin.cpp" line="383"/>
<source>InvalidParam</source> <source>InvalidParam</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../testplugin.cpp" line="458"/> <location filename="../testplugin.cpp" line="439"/>
<source>AllocArrayFailed</source> <source>AllocArrayFailed</source>
<translation></translation> <translation></translation>
</message> </message>
</context> </context>
<context>
<name>TestPluginPage</name>
<message>
<location filename="../testpluginpage.cpp" line="36"/>
<source>TestPluginPage</source>
<translation></translation>
</message>
</context>
<context> <context>
<name>TestWingEditorViewWidget</name> <name>TestWingEditorViewWidget</name>
<message> <message>

View File

@ -20,7 +20,6 @@
#include "testplugin.h" #include "testplugin.h"
#include "testform.h" #include "testform.h"
#include "testpluginpage.h"
#include "testsettingpage.h" #include "testsettingpage.h"
#include "testwingeditorviewwidget.h" #include "testwingeditorviewwidget.h"
@ -180,8 +179,6 @@ TestPlugin::TestPlugin() : WingHex::IWingPlugin() {
TestPlugin::~TestPlugin() { destoryTestShareMem(); } TestPlugin::~TestPlugin() { destoryTestShareMem(); }
int TestPlugin::sdkVersion() const { return WingHex::SDKVERSION; }
bool TestPlugin::init(const std::unique_ptr<QSettings> &set) { bool TestPlugin::init(const std::unique_ptr<QSettings> &set) {
auto v = set->value("Test", 0).toInt(); auto v = set->value("Test", 0).toInt();
// 如果你之前启动过且正常推出,这个值一定是 5 // 如果你之前启动过且正常推出,这个值一定是 5
@ -247,17 +244,11 @@ bool TestPlugin::init(const std::unique_ptr<QSettings> &set) {
_rtbinfo.append(rtinfo); _rtbinfo.append(rtinfo);
} }
{ _setpages.append(new TestSettingPage(
auto sp = new TestSettingPage(QStringLiteral("Test1"), QStringLiteral("Test1"), QStringLiteral("This is a Test1"), true));
QStringLiteral("This is a Test1"));
_setpages.insert(sp, true);
}
{ _setpages.append(new TestSettingPage(
auto sp = new TestSettingPage(QStringLiteral("Test2"), QStringLiteral("Test2"), QStringLiteral("This is a Test2"), false));
QStringLiteral("This is a Test2"));
_setpages.insert(sp, false);
}
{ {
WingHex::WingDockWidgetInfo info; WingHex::WingDockWidgetInfo info;
@ -274,11 +265,6 @@ bool TestPlugin::init(const std::unique_ptr<QSettings> &set) {
_evws.append(ev); _evws.append(ev);
} }
{
auto pp = new TestPluginPage;
_plgps.append(pp);
}
_tmenu = new QMenu(QStringLiteral("TestPlugin")); _tmenu = new QMenu(QStringLiteral("TestPlugin"));
auto micon = QIcon(QStringLiteral(":/images/TestPlugin/images/btn.png")); auto micon = QIcon(QStringLiteral(":/images/TestPlugin/images/btn.png"));
_tmenu->setIcon(micon); _tmenu->setIcon(micon);
@ -298,9 +284,8 @@ void TestPlugin::unload(std::unique_ptr<QSettings> &set) {
// 设个数字,那就是 5 测试一下配置是否正常工作 // 设个数字,那就是 5 测试一下配置是否正常工作
set->setValue("Test", 5); set->setValue("Test", 5);
for (auto p = _setpages.constKeyValueBegin(); for (auto &p : _setpages) {
p != _setpages.constKeyValueEnd(); ++p) { p->deleteLater();
p->first->deleteLater();
} }
for (auto &item : _winfo) { for (auto &item : _winfo) {
@ -332,14 +317,10 @@ TestPlugin::registeredRibbonTools() const {
return _rtbinfo; return _rtbinfo;
} }
QHash<WingHex::SettingPage *, bool> TestPlugin::registeredSettingPages() const { QList<WingHex::SettingPage *> TestPlugin::registeredSettingPages() const {
return _setpages; return _setpages;
} }
QList<WingHex::PluginPage *> TestPlugin::registeredPages() const {
return _plgps;
}
QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>> QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>>
TestPlugin::registeredEditorViewWidgets() const { TestPlugin::registeredEditorViewWidgets() const {
return _evws; return _evws;

View File

@ -40,7 +40,6 @@ public:
// IWingPlugin interface (必须) // IWingPlugin interface (必须)
public: public:
virtual int sdkVersion() const override;
virtual bool init(const std::unique_ptr<QSettings> &set) override; virtual bool init(const std::unique_ptr<QSettings> &set) override;
virtual void unload(std::unique_ptr<QSettings> &set) override; virtual void unload(std::unique_ptr<QSettings> &set) override;
virtual const QString pluginName() const override; virtual const QString pluginName() const override;
@ -57,9 +56,8 @@ public:
virtual QMenu *registeredHexContextMenu() const override; virtual QMenu *registeredHexContextMenu() const override;
virtual QList<WingHex::WingRibbonToolBoxInfo> virtual QList<WingHex::WingRibbonToolBoxInfo>
registeredRibbonTools() const override; registeredRibbonTools() const override;
virtual QHash<WingHex::SettingPage *, bool> virtual QList<WingHex::SettingPage *>
registeredSettingPages() const override; registeredSettingPages() const override;
virtual QList<WingHex::PluginPage *> registeredPages() const override;
virtual QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>> virtual QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>>
registeredEditorViewWidgets() const override; registeredEditorViewWidgets() const override;
virtual QHash<QString, ScriptFnInfo> registeredScriptFns() const override; virtual QHash<QString, ScriptFnInfo> registeredScriptFns() const override;
@ -124,9 +122,8 @@ private:
QHash<QString, WingHex::IWingPlugin::ScriptFnInfo> _scriptInfo; QHash<QString, WingHex::IWingPlugin::ScriptFnInfo> _scriptInfo;
QList<WingHex::WingDockWidgetInfo> _winfo; QList<WingHex::WingDockWidgetInfo> _winfo;
QList<WingHex::WingRibbonToolBoxInfo> _rtbinfo; QList<WingHex::WingRibbonToolBoxInfo> _rtbinfo;
QHash<WingHex::SettingPage *, bool> _setpages; QList<WingHex::SettingPage *> _setpages;
QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>> _evws; QList<QSharedPointer<WingHex::WingEditorViewWidget::Creator>> _evws;
QList<WingHex::PluginPage *> _plgps;
QHash<QString, WingHex::IWingPlugin::UNSAFE_SCFNPTR> _scriptUnsafe; QHash<QString, WingHex::IWingPlugin::UNSAFE_SCFNPTR> _scriptUnsafe;
}; };

View File

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

View File

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

View File

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

@ -1 +1 @@
Subproject commit ad5654088ab1da66ad93713ef5933a603fb8e2a3 Subproject commit ec5bcd41309e175aa262f367011c1ad9fe7e9b31

View File

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

BIN
images/monitor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

@ -2520,6 +2520,12 @@ bool PluginSystem::checkErrAllAllowAndReport(const QObject *sender,
return false; return false;
} }
const std::optional<PluginInfo> &PluginSystem::monitorManagerInfo() const {
return _manInfo;
}
IWingManager *PluginSystem::monitorManager() const { return _manager; }
IWingPlugin *PluginSystem::checkPluginAndReport(const QObject *sender, IWingPlugin *PluginSystem::checkPluginAndReport(const QObject *sender,
const char *func) { const char *func) {
Q_ASSERT(func); Q_ASSERT(func);
@ -3075,8 +3081,8 @@ IWingDevice *PluginSystem::device(qsizetype index) const {
} }
template <typename T> template <typename T>
std::optional<PluginSystem::PluginInfo> std::optional<PluginInfo> PluginSystem::loadPlugin(const QFileInfo &fileinfo,
PluginSystem::loadPlugin(const QFileInfo &fileinfo, const QDir &setdir) { const QDir &setdir) {
Q_ASSERT(_win); Q_ASSERT(_win);
if (fileinfo.exists()) { if (fileinfo.exists()) {
@ -3090,7 +3096,7 @@ PluginSystem::loadPlugin(const QFileInfo &fileinfo, const QDir &setdir) {
auto lmeta = loader.metaData(); auto lmeta = loader.metaData();
PluginStatus cret; PluginStatus cret;
std::optional<PluginSystem::PluginInfo> meta; std::optional<PluginInfo> meta;
if (lmeta.contains("MetaData")) { if (lmeta.contains("MetaData")) {
auto m = parsePluginMetadata(lmeta["MetaData"].toObject()); auto m = parsePluginMetadata(lmeta["MetaData"].toObject());
cret = checkPluginMetadata(m, std::is_same_v<T, IWingPlugin>); cret = checkPluginMetadata(m, std::is_same_v<T, IWingPlugin>);
@ -3116,13 +3122,25 @@ PluginSystem::loadPlugin(const QFileInfo &fileinfo, const QDir &setdir) {
case PluginStatus::DupID: case PluginStatus::DupID:
Logger::critical(tr("InvalidDupPlugin")); Logger::critical(tr("InvalidDupPlugin"));
return std::nullopt; return std::nullopt;
case PluginStatus::SDKVersion:
Logger::critical(tr("ErrLoadPluginSDKVersion"));
return std::nullopt;
}
auto m = meta.value();
if (_manager) {
if (!_manager->onLoadingPlugin(fileName, m)) {
Logger::critical(QStringLiteral("{ ") + m.id +
QStringLiteral("} ") +
tr("PluginBlockByManager"));
return std::nullopt;
}
} }
auto p = qobject_cast<T *>(loader.instance()); auto p = qobject_cast<T *>(loader.instance());
if (Q_UNLIKELY(p == nullptr)) { if (Q_UNLIKELY(p == nullptr)) {
Logger::critical(loader.errorString()); Logger::critical(loader.errorString());
} else { } else {
auto m = meta.value();
retranslateMetadata(p, m); retranslateMetadata(p, m);
loadPlugin(p, m, setdir); loadPlugin(p, m, setdir);
} }
@ -3196,11 +3214,11 @@ PluginSystem::assginHandleForPluginView(IWingPlugin *plg, EditorView *view) {
return id; return id;
} }
PluginSystem::PluginInfo PluginInfo PluginSystem::parsePluginMetadata(const QJsonObject &meta) {
PluginSystem::parsePluginMetadata(const QJsonObject &meta) { PluginInfo info;
PluginSystem::PluginInfo info;
info.id = meta["Id"].toString().trimmed(); info.id = meta["Id"].toString().trimmed();
info.SDKVersion = meta["SDK"].toInt();
info.version = info.version =
QVersionNumber::fromString(meta["Version"].toString().trimmed()); QVersionNumber::fromString(meta["Version"].toString().trimmed());
@ -3238,6 +3256,10 @@ PluginSystem::PluginStatus
PluginSystem::checkPluginMetadata(const PluginInfo &meta, bool isPlg) { PluginSystem::checkPluginMetadata(const PluginInfo &meta, bool isPlg) {
constexpr auto puid_limit = 36; // same as uuid length, so enough constexpr auto puid_limit = 36; // same as uuid length, so enough
if (meta.SDKVersion != SDKVERSION) {
return PluginStatus::SDKVersion;
}
if (meta.id.length() > puid_limit) { if (meta.id.length() > puid_limit) {
return PluginStatus::InvalidID; return PluginStatus::InvalidID;
} }
@ -3560,8 +3582,7 @@ IWingDevice *PluginSystem::ext2Device(const QString &ext) {
return *r; return *r;
} }
PluginSystem::PluginInfo PluginInfo PluginSystem::getPluginInfo(IWingPluginBase *plg) const {
PluginSystem::getPluginInfo(IWingPluginBase *plg) const {
Q_ASSERT(plg); Q_ASSERT(plg);
return _pinfos.value(plg); return _pinfos.value(plg);
} }
@ -3596,7 +3617,7 @@ void PluginSystem::loadExtPlugin() {
loadPlugin<IWingPlugin>(item, udir); loadPlugin<IWingPlugin>(item, udir);
} }
QList<PluginSystem::PluginInfo> errorplg; QList<PluginInfo> errorplg;
if (!_lazyplgs.isEmpty()) { if (!_lazyplgs.isEmpty()) {
QStringList lazyplgs; QStringList lazyplgs;
lazyplgs.swap(_lazyplgs); lazyplgs.swap(_lazyplgs);
@ -3687,18 +3708,59 @@ void PluginSystem::try2LoadManagerPlugin() {
auto lmeta = loader.metaData(); auto lmeta = loader.metaData();
auto m = parsePluginMetadata(lmeta["MetaData"].toObject()); auto m = parsePluginMetadata(lmeta["MetaData"].toObject());
// ID should not be empty auto cret = checkPluginMetadata(m, false);
if (m.id.isEmpty()) {
switch (cret) {
case PluginStatus::Valid:
break;
case PluginStatus::SDKVersion:
Logger::critical(tr("ErrLoadPluginSDKVersion"));
return;
case PluginStatus::InvalidID:
Logger::critical(tr("InvalidPluginID"));
return;
case PluginStatus::BrokenVersion:
Logger::critical(tr("InvalidPluginBrokenInfo"));
return;
case PluginStatus::DupID:
case PluginStatus::LackDependencies:
// monitor is the first plugin to load and
// should not have any dependency
Q_ASSERT(false);
return; return;
} }
auto p = qobject_cast<IWingManager *>(loader.instance()); auto p = qobject_cast<IWingManager *>(loader.instance());
if (p) { if (p) {
QDir udir(Utilities::getAppDataPath());
auto plgset = QStringLiteral("plgset");
udir.mkdir(plgset);
if (!udir.cd(plgset)) {
throw CrashCode::PluginSetting;
}
auto setp = std::make_unique<QSettings>(udir.absoluteFilePath(m.id),
QSettings::Format::IniFormat);
if (!p->init(setp)) {
setp->deleteLater();
Logger::critical(tr("ErrLoadInitPlugin"));
return;
}
applyFunctionTables(p, _plgFns); applyFunctionTables(p, _plgFns);
_manager = p; _manager = p;
// translate the meta-data
m.author = p->retranslate(m.author);
m.vendor = p->retranslate(m.vendor);
m.license = p->retranslate(m.license);
_manInfo = m; _manInfo = m;
// TODO registerRibbonTools(p->registeredRibbonTools());
registeredSettingPages(QVariant::fromValue(p),
p->registeredSettingPages());
} }
} }
@ -4160,10 +4222,6 @@ void PluginSystem::loadPlugin(IWingPlugin *p, PluginInfo &meta,
QTranslator *p_tr = nullptr; QTranslator *p_tr = nullptr;
try { try {
if (p->sdkVersion() != SDKVERSION) {
throw tr("ErrLoadPluginSDKVersion");
}
if (!p->pluginName().trimmed().length()) { if (!p->pluginName().trimmed().length()) {
throw tr("ErrLoadPluginNoName"); throw tr("ErrLoadPluginNoName");
} }
@ -4193,61 +4251,12 @@ void PluginSystem::loadPlugin(IWingPlugin *p, PluginInfo &meta,
_loadedplgs.append(p); _loadedplgs.append(p);
_pinfos.insert(p, meta); _pinfos.insert(p, meta);
Logger::warning(tr("PluginName :") + p->pluginName()); Logger::info(tr("PluginName :") + p->pluginName());
Logger::warning(tr("PluginAuthor :") + meta.author); Logger::debug(tr("PluginAuthor :") + meta.author);
Logger::warning(tr("PluginWidgetRegister")); Logger::debug(tr("PluginWidgetRegister"));
// ensure call only once // ensure call only once
auto ribbonToolboxInfos = p->registeredRibbonTools(); registerRibbonTools(p->registeredRibbonTools());
if (!ribbonToolboxInfos.isEmpty()) {
for (auto &item : ribbonToolboxInfos) {
if (_win->m_ribbonMaps.contains(item.catagory)) {
if (!item.toolboxs.isEmpty()) {
auto &cat = _win->m_ribbonMaps[item.catagory];
for (auto &group : item.toolboxs) {
if (group.tools.isEmpty()) {
continue;
}
auto g = cat->addGroup(group.name);
for (auto &tool : group.tools) {
g->addButton(tool);
}
}
}
} else {
if (!item.toolboxs.isEmpty()) {
bool isSys = false;
RibbonTabContent *cat;
if (_win->m_ribbonMaps.contains(item.catagory)) {
isSys = true;
cat = _win->m_ribbonMaps.value(item.catagory);
} else {
cat = new RibbonTabContent;
}
bool hasAdded = false;
for (auto &group : item.toolboxs) {
if (group.tools.isEmpty()) {
continue;
}
auto g = cat->addGroup(group.name);
for (auto &tool : group.tools) {
g->addButton(tool);
}
hasAdded = true;
}
if (!isSys) {
if (hasAdded) {
_win->m_ribbon->addTab(cat, item.displayName);
_win->m_ribbonMaps[item.catagory] = cat;
} else {
delete cat;
}
}
}
}
}
}
registerPluginDockWidgets(p); registerPluginDockWidgets(p);
{ {
@ -4264,18 +4273,8 @@ void PluginSystem::loadPlugin(IWingPlugin *p, PluginInfo &meta,
} }
} }
{ registeredSettingPages(QVariant::fromValue(p),
auto sp = p->registeredSettingPages(); p->registeredSettingPages());
if (!sp.isEmpty()) {
for (auto page = sp.keyBegin(); page != sp.keyEnd(); ++page) {
auto pp = *page;
pp->setProperty("__plg__", QVariant::fromValue(p));
}
_win->m_settingPages.insert(sp);
}
}
registerPluginPages(p);
registerFns(p); registerFns(p);
registerEnums(p); registerEnums(p);
@ -4298,12 +4297,8 @@ void PluginSystem::loadPlugin(IWingDevice *p, PluginInfo &meta,
QTranslator *p_tr = nullptr; QTranslator *p_tr = nullptr;
try { try {
if (p->sdkVersion() != SDKVERSION) { Logger::debug(tr("ExtPluginAuthor :") + meta.author);
throw tr("ErrLoadExtPluginSDKVersion"); Logger::debug(tr("ExtPluginWidgetRegister"));
}
Logger::warning(tr("ExtPluginAuthor :") + meta.author);
Logger::warning(tr("ExtPluginWidgetRegister"));
p_tr = LanguageManager::instance().try2LoadPluginLang(meta.id); p_tr = LanguageManager::instance().try2LoadPluginLang(meta.id);
@ -4326,7 +4321,6 @@ void PluginSystem::loadPlugin(IWingDevice *p, PluginInfo &meta,
_loadeddevs.append(p); _loadeddevs.append(p);
_pinfos.insert(p, meta); _pinfos.insert(p, meta);
registerPluginPages(p);
registerMarcoDevice(p); registerMarcoDevice(p);
// ok register into menu open // ok register into menu open
@ -4454,22 +4448,74 @@ void PluginSystem::registerPluginDockWidgets(IWingPluginBase *p) {
} }
} }
void PluginSystem::registerPluginPages(IWingPluginBase *p) {
auto rp = p->registeredPages();
if (!rp.isEmpty()) {
for (auto &page : rp) {
page->setProperty("__plg__", QVariant::fromValue(p));
}
_win->m_plgPages.append(rp);
}
}
void PluginSystem::registerMarcoDevice(IWingDevice *plg) { void PluginSystem::registerMarcoDevice(IWingDevice *plg) {
auto id = getPUID(plg).toUpper(); auto id = getPUID(plg).toUpper();
auto sep = QStringLiteral("_"); auto sep = QStringLiteral("_");
_scriptMarcos.append(sep + id + sep); _scriptMarcos.append(sep + id + sep);
} }
void PluginSystem::registerRibbonTools(
const QList<WingRibbonToolBoxInfo> &tools) {
if (!tools.isEmpty()) {
for (auto &item : tools) {
if (_win->m_ribbonMaps.contains(item.catagory)) {
if (!item.toolboxs.isEmpty()) {
auto &cat = _win->m_ribbonMaps[item.catagory];
for (auto &group : item.toolboxs) {
if (group.tools.isEmpty()) {
continue;
}
auto g = cat->addGroup(group.name);
for (auto &tool : group.tools) {
g->addButton(tool);
}
}
}
} else {
if (!item.toolboxs.isEmpty()) {
bool isSys = false;
RibbonTabContent *cat;
if (_win->m_ribbonMaps.contains(item.catagory)) {
isSys = true;
cat = _win->m_ribbonMaps.value(item.catagory);
} else {
cat = new RibbonTabContent;
}
bool hasAdded = false;
for (auto &group : item.toolboxs) {
if (group.tools.isEmpty()) {
continue;
}
auto g = cat->addGroup(group.name);
for (auto &tool : group.tools) {
g->addButton(tool);
}
hasAdded = true;
}
if (!isSys) {
if (hasAdded) {
_win->m_ribbon->addTab(cat, item.displayName);
_win->m_ribbonMaps[item.catagory] = cat;
} else {
delete cat;
}
}
}
}
}
}
}
void PluginSystem::registeredSettingPages(const QVariant &itptr,
const QList<SettingPage *> &pages) {
if (!pages.isEmpty()) {
for (auto &page : pages) {
page->setProperty("__plg__", itptr);
}
_win->m_settingPages.append(pages);
}
}
bool PluginSystem::checkThreadAff() { bool PluginSystem::checkThreadAff() {
if (QThread::currentThread() != qApp->thread()) { if (QThread::currentThread() != qApp->thread()) {
Logger::warning(tr("Not allowed operation in non-UI thread")); Logger::warning(tr("Not allowed operation in non-UI thread"));
@ -4497,6 +4543,7 @@ void PluginSystem::loadAllPlugin() {
try2LoadManagerPlugin(); try2LoadManagerPlugin();
auto &set = SettingManager::instance(); auto &set = SettingManager::instance();
// manager plugin can not block WingAngelAPI, only settings
if (set.scriptEnabled()) { if (set.scriptEnabled()) {
_angelplg = new WingAngelAPI; _angelplg = new WingAngelAPI;
@ -4520,7 +4567,6 @@ void PluginSystem::loadAllPlugin() {
initCheckingEngine(); initCheckingEngine();
{ {
auto cstructplg = new WingCStruct;
QFile cstructjson(QStringLiteral( QFile cstructjson(QStringLiteral(
":/com.wingsummer.winghex/src/class/WingCStruct.json")); ":/com.wingsummer.winghex/src/class/WingCStruct.json"));
auto ret = cstructjson.open(QFile::ReadOnly); auto ret = cstructjson.open(QFile::ReadOnly);
@ -4532,16 +4578,23 @@ void PluginSystem::loadAllPlugin() {
QJsonDocument doc = QJsonDocument::fromJson(cstruct); QJsonDocument doc = QJsonDocument::fromJson(cstruct);
auto meta = parsePluginMetadata(doc.object()); auto meta = parsePluginMetadata(doc.object());
QDir setd(Utilities::getAppDataPath()); // internal plugin has no filename
auto plgset = QStringLiteral("plgset"); if (_manager->onLoadingPlugin({}, meta)) {
setd.mkdir(plgset); auto cstructplg = new WingCStruct;
retranslateMetadata(cstructplg, meta); QDir setd(Utilities::getAppDataPath());
loadPlugin(cstructplg, meta, setd); auto plgset = QStringLiteral("plgset");
setd.mkdir(plgset);
retranslateMetadata(cstructplg, meta);
loadPlugin(cstructplg, meta, setd);
} else {
Logger::critical(QStringLiteral("{ ") + meta.id +
QStringLiteral("} ") + tr("PluginBlockByManager"));
}
} }
Logger::newLine(); Logger::newLine();
bool ok; bool ok = false;
auto disAll = auto disAll =
qEnvironmentVariableIntValue("WING_DISABLE_PLUGIN_SYSTEM", &ok); qEnvironmentVariableIntValue("WING_DISABLE_PLUGIN_SYSTEM", &ok);
@ -4603,6 +4656,13 @@ void PluginSystem::destory() {
delete item; delete item;
} }
_loadeddevs.clear(); _loadeddevs.clear();
if (_manager && _manInfo) {
auto set = std::make_unique<QSettings>(
udir.absoluteFilePath(_manInfo->id), QSettings::Format::IniFormat);
_manager->unload(set);
delete _manager;
}
} }
EditorView *PluginSystem::pluginCurrentEditor(IWingPlugin *plg) const { EditorView *PluginSystem::pluginCurrentEditor(IWingPlugin *plg) const {

View File

@ -103,18 +103,9 @@ private:
QExplicitlySharedDataPointer<UniqueIdGenerator::UniqueId>; QExplicitlySharedDataPointer<UniqueIdGenerator::UniqueId>;
public: public:
struct PluginInfo {
QString id;
QVersionNumber version;
QString vendor;
QList<WingDependency> dependencies;
QString author;
QString license;
QString url;
};
enum class PluginStatus { enum class PluginStatus {
Valid, Valid,
SDKVersion,
BrokenVersion, BrokenVersion,
InvalidID, InvalidID,
DupID, DupID,
@ -257,13 +248,19 @@ private:
void registerMarcoDevice(IWingDevice *plg); void registerMarcoDevice(IWingDevice *plg);
private: private:
void registerRibbonTools(const QList<WingRibbonToolBoxInfo> &tools);
void registeredSettingPages(const QVariant &itptr,
const QList<SettingPage *> &pages);
void registerPluginDockWidgets(IWingPluginBase *p); void registerPluginDockWidgets(IWingPluginBase *p);
void registerPluginPages(IWingPluginBase *p);
public: public:
// fpr crash checking // fpr crash checking
QString currentLoadingPlugin() const; QString currentLoadingPlugin() const;
IWingManager *monitorManager() const;
const std::optional<PluginInfo> &monitorManagerInfo() const;
private: private:
template <typename T> template <typename T>
T readBasicTypeContent(IWingPlugin *plg, qsizetype offset) { T readBasicTypeContent(IWingPlugin *plg, qsizetype offset) {

View File

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

View File

@ -48,6 +48,8 @@ private:
private: private:
Theme m_theme; Theme m_theme;
QHash<QString, QIcon> m_cache;
explicit SkinManager(); explicit SkinManager();
Q_DISABLE_COPY_MOVE(SkinManager) Q_DISABLE_COPY_MOVE(SkinManager)

View File

@ -44,8 +44,6 @@ WingAngelAPI::WingAngelAPI() {
WingAngelAPI::~WingAngelAPI() {} WingAngelAPI::~WingAngelAPI() {}
int WingAngelAPI::sdkVersion() const { return WingHex::SDKVERSION; }
bool WingAngelAPI::init(const std::unique_ptr<QSettings> &set) { bool WingAngelAPI::init(const std::unique_ptr<QSettings> &set) {
Q_UNUSED(set); Q_UNUSED(set);
return true; return true;

View File

@ -39,7 +39,6 @@ public:
// IWingPlugin interface // IWingPlugin interface
public: public:
virtual int sdkVersion() const override;
virtual bool init(const std::unique_ptr<QSettings> &set) override; virtual bool init(const std::unique_ptr<QSettings> &set) override;
virtual void unload(std::unique_ptr<QSettings> &set) override; virtual void unload(std::unique_ptr<QSettings> &set) override;
virtual const QString pluginName() const override; virtual const QString pluginName() const override;

View File

@ -178,8 +178,6 @@ WingCStruct::WingCStruct() : WingHex::IWingPlugin() {
WingCStruct::~WingCStruct() {} WingCStruct::~WingCStruct() {}
int WingCStruct::sdkVersion() const { return WingHex::SDKVERSION; }
bool WingCStruct::init(const std::unique_ptr<QSettings> &set) { bool WingCStruct::init(const std::unique_ptr<QSettings> &set) {
Q_UNUSED(set); Q_UNUSED(set);
resetEnv(); resetEnv();
@ -211,8 +209,7 @@ WingCStruct::RegisteredEvents WingCStruct::registeredEvents() const {
return evs; return evs;
} }
QHash<WingHex::SettingPage *, bool> QList<WingHex::SettingPage *> WingCStruct::registeredSettingPages() const {
WingCStruct::registeredSettingPages() const {
return _setpgs; return _setpgs;
} }

View File

@ -35,7 +35,6 @@ public:
// IWingPluginBase interface // IWingPluginBase interface
public: public:
virtual int sdkVersion() const override;
virtual bool init(const std::unique_ptr<QSettings> &set) override; virtual bool init(const std::unique_ptr<QSettings> &set) override;
virtual void unload(std::unique_ptr<QSettings> &set) override; virtual void unload(std::unique_ptr<QSettings> &set) override;
virtual const QString pluginName() const override; virtual const QString pluginName() const override;
@ -47,7 +46,7 @@ public:
// IWingPlugin interface // IWingPlugin interface
public: public:
virtual RegisteredEvents registeredEvents() const override; virtual RegisteredEvents registeredEvents() const override;
virtual QHash<WingHex::SettingPage *, bool> virtual QList<WingHex::SettingPage *>
registeredSettingPages() const override; registeredSettingPages() const override;
virtual QHash<QString, ScriptFnInfo> registeredScriptFns() const override; virtual QHash<QString, ScriptFnInfo> registeredScriptFns() const override;
virtual bool eventOnScriptPragma(const QString &script, virtual bool eventOnScriptPragma(const QString &script,
@ -118,7 +117,7 @@ private:
private: private:
CTypeParser _parser; CTypeParser _parser;
QHash<WingHex::SettingPage *, bool> _setpgs; QList<WingHex::SettingPage *> _setpgs;
QHash<QString, WingCStruct::ScriptFnInfo> _scriptInfo; QHash<QString, WingCStruct::ScriptFnInfo> _scriptInfo;
QHash<QString, WingHex::IWingPlugin::UNSAFE_SCFNPTR> _scriptUnsafe; QHash<QString, WingHex::IWingPlugin::UNSAFE_SCFNPTR> _scriptUnsafe;
}; };

View File

@ -1637,7 +1637,6 @@ void MainWindow::buildUpSettingDialog() {
auto plgPage = new PluginSettingDialog(m_setdialog); auto plgPage = new PluginSettingDialog(m_setdialog);
connect(plgPage, &SettingPage::optionNeedRestartChanged, m_setdialog, connect(plgPage, &SettingPage::optionNeedRestartChanged, m_setdialog,
&SettingDialog::toastTakeEffectReboot); &SettingDialog::toastTakeEffectReboot);
plgPage->buildUp(m_plgPages);
m_setdialog->addPage(plgPage); m_setdialog->addPage(plgPage);
id = plgPage->id(); id = plgPage->id();
Q_ASSERT(!id.isEmpty()); Q_ASSERT(!id.isEmpty());
@ -1662,9 +1661,7 @@ void MainWindow::buildUpSettingDialog() {
usedIDs.append(id); usedIDs.append(id);
qApp->processEvents(); qApp->processEvents();
for (auto page_p = m_settingPages.constKeyValueBegin(); for (auto &page : m_settingPages) {
page_p != m_settingPages.constKeyValueEnd(); ++page_p) {
auto page = page_p->first;
auto name = page->name(); auto name = page->name();
auto id = page->id(); auto id = page->id();
@ -1690,7 +1687,7 @@ void MainWindow::buildUpSettingDialog() {
connect(page, &SettingPage::optionNeedRestartChanged, m_setdialog, connect(page, &SettingPage::optionNeedRestartChanged, m_setdialog,
&SettingDialog::toastTakeEffectReboot); &SettingDialog::toastTakeEffectReboot);
m_setdialog->addPage(page); m_setdialog->addPage(page);
if (page_p->second) { if (page->showInRibbon()) {
auto icon = page->categoryIcon(); auto icon = page->categoryIcon();
addPannelAction(m_pluginSettingsGroup, icon, name, addPannelAction(m_pluginSettingsGroup, icon, name,
[=] { m_setdialog->showConfig(id); }); [=] { m_setdialog->showConfig(id); });

View File

@ -564,8 +564,7 @@ private:
QList<QMenu *> m_hexContextMenu; QList<QMenu *> m_hexContextMenu;
QHash<IWingPlugin *, QList<QSharedPointer<WingEditorViewWidget::Creator>>> QHash<IWingPlugin *, QList<QSharedPointer<WingEditorViewWidget::Creator>>>
m_editorViewWidgets; m_editorViewWidgets;
QHash<SettingPage *, bool> m_settingPages; QList<SettingPage *> m_settingPages;
QList<PluginPage *> m_plgPages;
// these variables will be invalid after restoring state // these variables will be invalid after restoring state
ads::CDockAreaWidget *m_leftViewArea = nullptr; ads::CDockAreaWidget *m_leftViewArea = nullptr;

View File

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

View File

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

View File

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

View File

@ -57,7 +57,15 @@ Q_DECL_UNUSED static inline QString NAMEICONRES(const QString &name) {
} }
Q_DECL_UNUSED static inline QIcon ICONRES(const QString &name) { Q_DECL_UNUSED static inline QIcon ICONRES(const QString &name) {
return QIcon(NAMEICONRES(name)); static QHash<QString, QIcon> cache;
auto picon = cache.find(name);
if (picon == cache.end()) {
QIcon icon(NAMEICONRES(name));
cache.insert(name, icon);
return icon;
} else {
return *picon;
}
} }
class Utilities { class Utilities {