From 047aaf9be66baee435c13b8e61ea6bc924c5b451 Mon Sep 17 00:00:00 2001
From: wingsummer <1326224942@qq.com>
Date: Tue, 27 Sep 2022 16:27:13 +0800
Subject: [PATCH] add testplugin
---
TestPlugin/TestPlugin.json | 3 ++
TestPlugin/TestPlugin.pro | 36 ++++++++++++++++
TestPlugin/logo.svg | 1 +
TestPlugin/resources.qrc | 5 +++
TestPlugin/testplugin.cpp | 78 +++++++++++++++++++++++++++++++++++
TestPlugin/testplugin.h | 43 +++++++++++++++++++
control/pluginselector.cpp | 3 +-
control/pluginselector.h | 4 ++
dialog/centerwindow.cpp | 14 ++++---
dialog/pluginseldialog.cpp | 12 +++++-
dialog/pluginseldialog.h | 1 +
dialog/shortcuteditdialog.cpp | 22 +++++++++-
dialog/shortcuteditdialog.h | 6 +++
plugin/iwingtoolplg.h | 21 ++++++++--
plugin/pluginsystem.cpp | 49 ++++++++++++++++++++--
plugin/pluginsystem.h | 3 ++
utilities.h | 6 +--
17 files changed, 287 insertions(+), 20 deletions(-)
create mode 100644 TestPlugin/TestPlugin.json
create mode 100644 TestPlugin/TestPlugin.pro
create mode 100644 TestPlugin/logo.svg
create mode 100644 TestPlugin/resources.qrc
create mode 100644 TestPlugin/testplugin.cpp
create mode 100644 TestPlugin/testplugin.h
diff --git a/TestPlugin/TestPlugin.json b/TestPlugin/TestPlugin.json
new file mode 100644
index 0000000..1e81138
--- /dev/null
+++ b/TestPlugin/TestPlugin.json
@@ -0,0 +1,3 @@
+{
+ "Keys" : [ ]
+}
diff --git a/TestPlugin/TestPlugin.pro b/TestPlugin/TestPlugin.pro
new file mode 100644
index 0000000..9b19988
--- /dev/null
+++ b/TestPlugin/TestPlugin.pro
@@ -0,0 +1,36 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2022-09-27T14:57:42
+#
+#-------------------------------------------------
+
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = TestPlugin
+TEMPLATE = lib
+CONFIG += plugin
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+ testplugin.cpp
+
+HEADERS += \
+ ../plugin/iwingtoolplg.h \
+ testplugin.h
+DISTFILES += TestPlugin.json
+
+RESOURCES += \
+ resources.qrc
+
diff --git a/TestPlugin/logo.svg b/TestPlugin/logo.svg
new file mode 100644
index 0000000..4db8539
--- /dev/null
+++ b/TestPlugin/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/TestPlugin/resources.qrc b/TestPlugin/resources.qrc
new file mode 100644
index 0000000..95ac425
--- /dev/null
+++ b/TestPlugin/resources.qrc
@@ -0,0 +1,5 @@
+
+
+ logo.svg
+
+
diff --git a/TestPlugin/testplugin.cpp b/TestPlugin/testplugin.cpp
new file mode 100644
index 0000000..c03aadf
--- /dev/null
+++ b/TestPlugin/testplugin.cpp
@@ -0,0 +1,78 @@
+#include "testplugin.h"
+
+TestPlugin::TestPlugin(QObject *parent) { Q_UNUSED(parent) }
+
+int TestPlugin::sdkVersion() { return SDKVERSION; }
+
+QString TestPlugin::signature() { return WINGSUMMER; }
+
+TestPlugin::~TestPlugin() {}
+
+bool TestPlugin::init(QList loadedplugin) {
+ Q_UNUSED(loadedplugin);
+ dialog = new QDialog;
+ dialog->setFixedSize(400, 400);
+ dialog->setWindowTitle("TestPluginConsole");
+ dialog->setWindowFlags(Qt::CustomizeWindowHint |
+ Qt::WindowMinimizeButtonHint |
+ Qt::WindowMaximizeButtonHint);
+ tbinfo = new QTextBrowser(dialog);
+ tbinfo->setFixedSize(dialog->size());
+ tbinfo->setUndoRedoEnabled(false);
+ dialog->show();
+ return true;
+}
+
+void TestPlugin::unload() {
+ dialog->close();
+ delete dialog;
+}
+
+QString TestPlugin::pluginName() { return "TestPlugin"; }
+
+QByteArray TestPlugin::provider() { return "testpro"; }
+
+QString TestPlugin::pluginAuthor() { return WINGSUMMER; }
+
+IWingToolPlg::Catagorys TestPlugin::pluginCatagory() {
+ return IWingToolPlg::Catagorys::Explor;
+}
+
+uint TestPlugin::pluginVersion() { return 1; }
+
+QString TestPlugin::pluginComment() { return "This is a test plugin !"; }
+
+QIcon TestPlugin::pluginIcon() { return QIcon(":/TestPlugin/logo.svg"); }
+
+QStringList TestPlugin::pluginServices() { return {"func1", "func2", "func3"}; }
+
+HookIndex TestPlugin::getHookSubscribe() { return HookIndex::None; }
+
+QVariant TestPlugin::pluginServicePipe(int serviceID, QList params) {
+ switch (serviceID) {
+ case HostService:
+ if (params.first() == LoadedPluginMsg) {
+ testhotkey = registerHotkey(
+ QKeySequence(Qt::KeyboardModifier::ControlModifier |
+ Qt::KeyboardModifier::AltModifier | Qt::Key_Q));
+ }
+ break;
+ case RemoteCallRes:
+ break;
+ case HotKeyTriggered:
+ tbinfo->append(QString("HotKeyTriggered : %1")
+ .arg(params.first().value().toString()));
+ break;
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ break;
+ }
+ return QVariant();
+}
+
+#if QT_VERSION < 0x050000
+Q_EXPORT_PLUGIN2(TestPlugin, IWingToolPlg)
+#endif // QT_VERSION < 0x050000
diff --git a/TestPlugin/testplugin.h b/TestPlugin/testplugin.h
new file mode 100644
index 0000000..09a20df
--- /dev/null
+++ b/TestPlugin/testplugin.h
@@ -0,0 +1,43 @@
+#ifndef GENERICPLUGIN_H
+#define GENERICPLUGIN_H
+
+#include "../plugin/iwingtoolplg.h"
+#include
+#include
+
+class TestPlugin : public IWingToolPlg {
+ Q_OBJECT
+#if QT_VERSION >= 0x050000
+ Q_PLUGIN_METADATA(IID IWINGPLUGIN_INTERFACE_IID FILE "TestPlugin.json")
+#endif // QT_VERSION >= 0x050000
+
+ Q_INTERFACES(IWingToolPlg)
+
+public:
+ TestPlugin(QObject *parent = nullptr);
+ int sdkVersion() override;
+ QString signature() override;
+ ~TestPlugin() override;
+
+ bool init(QList loadedplugin) override;
+ void unload() override;
+ QString pluginName() override;
+ QByteArray provider() override;
+ QString pluginAuthor() override;
+ Catagorys pluginCatagory() override;
+ uint pluginVersion() override;
+ QString pluginComment() override;
+ QIcon pluginIcon() override;
+ QStringList pluginServices() override;
+ HookIndex getHookSubscribe() override;
+
+public slots:
+ QVariant pluginServicePipe(int serviceID, QList params) override;
+
+private:
+ QUuid testhotkey;
+ QDialog *dialog;
+ QTextBrowser *tbinfo;
+};
+
+#endif // GENERICPLUGIN_H
diff --git a/control/pluginselector.cpp b/control/pluginselector.cpp
index dfa5a5e..ef973bc 100644
--- a/control/pluginselector.cpp
+++ b/control/pluginselector.cpp
@@ -19,12 +19,13 @@ void PluginSelector::selectPlugin() {
if (index >= 0) {
auto plg = plgsys->plugin(index);
setIcon(Utilities::processPluginIcon(plg));
- selplgindex = index;
setText(plg->pluginName());
} else {
setText("/");
setIcon(ICONRES("plugin"));
}
+ selplgindex = index;
+ emit finished();
}
int PluginSelector::getSelectedIndex() { return selplgindex; }
diff --git a/control/pluginselector.h b/control/pluginselector.h
index 0361cd6..408f896 100644
--- a/control/pluginselector.h
+++ b/control/pluginselector.h
@@ -8,6 +8,7 @@
DWIDGET_USE_NAMESPACE
class PluginSelector : public DPushButton {
+ Q_OBJECT
public:
explicit PluginSelector(QWidget *parent = nullptr);
@@ -18,6 +19,9 @@ public:
int getSelectedIndex();
IWingToolPlg *getSelectedPlg();
+signals:
+ void finished();
+
private:
PluginSystem *plgsys;
diff --git a/dialog/centerwindow.cpp b/dialog/centerwindow.cpp
index 4a6e495..387ae10 100644
--- a/dialog/centerwindow.cpp
+++ b/dialog/centerwindow.cpp
@@ -213,7 +213,7 @@ CenterWindow::CenterWindow(DMainWindow *parent)
tbplginfo->append(QObject::tr("Catagory:") +
QObject::tr(e.valueToKey(int(plg->pluginCatagory()))));
- tbplginfo->append(QObject::tr("Version") +
+ tbplginfo->append(QObject::tr("Version:") +
QString::number(plg->pluginVersion()));
tbplginfo->append(QObject::tr("Author:") + plg->pluginAuthor());
tbplginfo->append(QObject::tr("Comment:") + plg->pluginComment());
@@ -268,8 +268,10 @@ CenterWindow::CenterWindow(DMainWindow *parent)
//初始化热键事件处理函数
QObject::connect(manager, &AppManager::hotkeyTirggered, this,
[=](const QHotkey *hotkey) {
- auto &task = scinfos[const_cast(hotkey)];
- this->runTask(task.process, task.params);
+ if (hotkeys.contains(const_cast(hotkey))) {
+ auto &task = scinfos[const_cast(hotkey)];
+ this->runTask(task.process, task.params);
+ }
});
QObject::connect(manager, &AppManager::hotkeyReleased, this,
[=](const QHotkey *) {
@@ -278,8 +280,10 @@ CenterWindow::CenterWindow(DMainWindow *parent)
QObject::connect(
manager, &AppManager::hotkeyEnableChanged, this,
[=](bool value, const QHotkey *hotkey) {
- tbhotkeys->item(hotkeys.indexOf(const_cast(hotkey)), 0)
- ->setCheckState(value ? Qt::Checked : Qt::Unchecked);
+ if (hotkeys.contains(const_cast(hotkey))) {
+ tbhotkeys->item(hotkeys.indexOf(const_cast(hotkey)), 0)
+ ->setCheckState(value ? Qt::Checked : Qt::Unchecked);
+ }
});
}
diff --git a/dialog/pluginseldialog.cpp b/dialog/pluginseldialog.cpp
index 85b6ae2..0cd18a9 100644
--- a/dialog/pluginseldialog.cpp
+++ b/dialog/pluginseldialog.cpp
@@ -2,6 +2,7 @@
#include "plugin/pluginsystem.h"
#include "utilities.h"
#include
+#include
#include
#include
@@ -52,8 +53,15 @@ PluginSelDialog::PluginSelDialog(DDialog *parent) : DDialog(parent) {
auto group = new DButtonBox(this);
QList blist;
auto b = new DButtonBoxButton(tr("Select"), this);
- connect(b, &DButtonBoxButton::clicked, this,
- [=] { this->done(lsplgs->currentRow()); });
+ connect(b, &DButtonBoxButton::clicked, this, [=] {
+ auto sel = lsplgs->currentRow();
+ if (sel < 0) {
+ DMessageManager::instance()->sendMessage(this, ProgramIcon,
+ tr("NoSelection"));
+ return;
+ }
+ this->done(sel);
+ });
blist.append(b);
b = new DButtonBoxButton(tr("NoPlugin"), this);
connect(b, &DButtonBoxButton::clicked, this, [=] { this->done(-1); });
diff --git a/dialog/pluginseldialog.h b/dialog/pluginseldialog.h
index 4bcfd99..7e70177 100644
--- a/dialog/pluginseldialog.h
+++ b/dialog/pluginseldialog.h
@@ -9,6 +9,7 @@
DWIDGET_USE_NAMESPACE
class PluginSelDialog : public DDialog {
+ Q_OBJECT
public:
PluginSelDialog(DDialog *parent = nullptr);
diff --git a/dialog/shortcuteditdialog.cpp b/dialog/shortcuteditdialog.cpp
index 970d3a2..47976ad 100644
--- a/dialog/shortcuteditdialog.cpp
+++ b/dialog/shortcuteditdialog.cpp
@@ -29,15 +29,35 @@ ShortCutEditDialog::ShortCutEditDialog(bool enabled, QKeySequence seq,
addContent(new DLabel(tr("Plugin"), this));
addSpacing(5);
ps = new PluginSelector(this);
+ connect(ps, &PluginSelector::finished, this, [=] {
+ auto plg = ps->getSelectedPlg();
+ if (plg) {
+ lblp->setText(tr("Service"));
+ fcedit->setVisible(false);
+ cbService->clear();
+ cbService->addItems(plg->pluginServices());
+ cbService->setVisible(true);
+ } else {
+ lblp->setText(tr("FilePath"));
+ fcedit->setVisible(true);
+ cbService->setVisible(false);
+ }
+ });
addContent(ps);
addSpacing(10);
- addContent(new DLabel(tr("FilePath"), this));
+ lblp = new DLabel(tr("FilePath"), this);
+ addContent(lblp);
addSpacing(5);
fcedit = new DFileChooserEdit(this);
fcedit->initDialog();
fcedit->setText(process);
addContent(fcedit);
+
+ cbService = new DComboBox(this);
+ cbService->setVisible(false);
+ addContent(cbService);
+
addSpacing(10);
addContent(new DLabel(tr("Param"), this));
diff --git a/dialog/shortcuteditdialog.h b/dialog/shortcuteditdialog.h
index da79c27..2463ec4 100644
--- a/dialog/shortcuteditdialog.h
+++ b/dialog/shortcuteditdialog.h
@@ -6,15 +6,18 @@
#include "class/appmanager.h"
#include "control/pluginselector.h"
#include
+#include
#include
#include
#include
+#include
#include
#include
DWIDGET_USE_NAMESPACE
class ShortCutEditDialog : public DDialog {
+ Q_OBJECT
public:
ShortCutEditDialog(bool enabled = true, QKeySequence seq = QKeySequence(),
QString process = QString(), QString params = QString(),
@@ -37,6 +40,9 @@ private:
DFileChooserEdit *fcedit;
DLineEdit *dledit;
DKeySequenceEdit *ksedit;
+
+ DLabel *lblp;
+ DComboBox *cbService;
};
#endif // SHORTCUTEDITDIALOG_H
diff --git a/plugin/iwingtoolplg.h b/plugin/iwingtoolplg.h
index b59c95a..519e96c 100644
--- a/plugin/iwingtoolplg.h
+++ b/plugin/iwingtoolplg.h
@@ -1,6 +1,8 @@
#ifndef IWINGTOOLPLG_H
#define IWINGTOOLPLG_H
+#include
+#include
#include
#include
#include
@@ -14,8 +16,19 @@
#define LoadingPluginMsg QVariant::fromValue('l')
#define LoadedPluginMsg QVariant::fromValue('L')
-#define HostService -1
-#define RemoteCallRes -2
+
+/*=================================*/
+
+// 插件系统预定义服务号,全部为负数
+// 如果服务号为非负数,则表示为插件服务
+
+#define HostService -1 // 插件加载消息服务
+#define RemoteCallRes -2 // 远程调用结果服务
+#define HotKeyTriggered -3 // 热键触发服务
+#define HotKeyReleased -4 //热键释放服务
+#define HotkeyEnableChanged -5 // 热键状态更改服务
+
+/*=================================*/
struct WingPluginInfo {
QString pluginName;
@@ -100,13 +113,13 @@ public:
signals:
// 注册热键,如果被占用则返回 -1 表示失败(通常是重复),
// 大于等于 0 则表示成功,返回句柄
- QUuid registerHotkey(QKeySequence &keyseq);
+ QUuid registerHotkey(QKeySequence keyseq);
// 修改热键状态,其中 id 为注册热键句柄,enable 为热键的新状态
bool enableHotKey(const QUuid id, bool enabled = true);
// 修改热键
- bool editHotkey(const QUuid id, QKeySequence &seq);
+ bool editHotkey(const QUuid id, QKeySequence seq);
// 注销热键,其中 id 为注册热键句柄
bool unregisterHotkey(const QUuid id);
diff --git a/plugin/pluginsystem.cpp b/plugin/pluginsystem.cpp
index ff6f4ce..cfad2a0 100644
--- a/plugin/pluginsystem.cpp
+++ b/plugin/pluginsystem.cpp
@@ -70,7 +70,33 @@ PluginSystem::PluginSystem(QObject *parent)
});
connect(manager, &AppManager::hotkeyTirggered, this,
[=](const QHotkey *hotkey) {
-
+ auto uuid = uhmap.key(const_cast(hotkey), QUuid());
+ if (uuid.isNull())
+ return;
+ int id;
+ auto plg = this->loopUpHotkey(uuid, id);
+ if (plg)
+ plg->pluginServicePipe(HotKeyTriggered, {uuid});
+ });
+ connect(manager, &AppManager::hotkeyReleased, this,
+ [=](const QHotkey *hotkey) {
+ auto uuid = uhmap.key(const_cast(hotkey), QUuid());
+ if (uuid.isNull())
+ return;
+ int id;
+ auto plg = this->loopUpHotkey(uuid, id);
+ if (plg)
+ plg->pluginServicePipe(HotKeyReleased, {uuid});
+ });
+ connect(manager, &AppManager::hotkeyEnableChanged, this,
+ [=](bool value, const QHotkey *hotkey) {
+ auto uuid = uhmap.key(const_cast(hotkey), QUuid());
+ if (uuid.isNull())
+ return;
+ int id;
+ auto plg = this->loopUpHotkey(uuid, id);
+ if (plg)
+ plg->pluginServicePipe(HotkeyEnableChanged, {value, uuid});
});
LoadPlugin();
@@ -85,8 +111,12 @@ PluginSystem::~PluginSystem() {
bool PluginSystem::LoadPlugin() {
QDir plugindir(QCoreApplication::applicationDirPath() + "/plugin");
+#ifdef QT_DEBUG
+ plugindir.setNameFilters(QStringList("*.so"));
+#else
plugindir.setNameFilters(QStringList("*.wingplg"));
- auto plgs = plugindir.entryInfoList();
+#endif
+ auto plgs = plugindir.entryInfoList(QDir::Files);
for (auto item : plgs) {
loadPlugin(item);
}
@@ -194,7 +224,7 @@ void PluginSystem::loadPlugin(QFileInfo fileinfo) {
// 连接信号
connect(p, &IWingToolPlg::registerHotkey, this,
- [=](QKeySequence &keyseq) {
+ [=](QKeySequence keyseq) {
auto sender = qobject_cast(QObject::sender());
if (sender == nullptr)
return QUuid();
@@ -234,7 +264,7 @@ void PluginSystem::loadPlugin(QFileInfo fileinfo) {
return false;
});
connect(p, &IWingToolPlg::editHotkey, this,
- [=](const QUuid id, QKeySequence &seq) {
+ [=](const QUuid id, QKeySequence seq) {
auto sender = qobject_cast(QObject::sender());
if (sender == nullptr)
return false;
@@ -305,3 +335,14 @@ QList PluginSystem::pluginRegisteredHotkey(IWingToolPlg *plg) {
}
return keys;
}
+
+IWingToolPlg *PluginSystem::loopUpHotkey(QUuid uuid, int &index) {
+ for (auto plg : m_plgs) {
+ auto res = m_plghk[plg].indexOf(uuid);
+ if (res >= 0) {
+ index = res;
+ return plg;
+ }
+ }
+ return nullptr;
+}
diff --git a/plugin/pluginsystem.h b/plugin/pluginsystem.h
index 5ae87a0..e66da4d 100644
--- a/plugin/pluginsystem.h
+++ b/plugin/pluginsystem.h
@@ -42,6 +42,9 @@ public:
QList pluginRegisteredHotkey(IWingToolPlg *plg);
+private:
+ IWingToolPlg *loopUpHotkey(QUuid uuid, int &index);
+
private:
static PluginSystem *m_instance;
AppManager *manager;
diff --git a/utilities.h b/utilities.h
index 9afa291..1efd61b 100644
--- a/utilities.h
+++ b/utilities.h
@@ -19,10 +19,10 @@ struct ShortCutEditRes {
class Utilities {
public:
static QIcon processPluginIcon(IWingToolPlg *plg) {
- if (plg->pluginIcon().availableSizes().count()) {
- return plg->pluginIcon();
+ if (plg->pluginIcon().isNull()) {
+ return ICONRES("plugin");
}
- return ICONRES("plugin");
+ return plg->pluginIcon();
}
};