add testplugin

This commit is contained in:
寂静的羽夏 2022-09-27 16:27:13 +08:00
parent 726bf42ce4
commit 047aaf9be6
17 changed files with 287 additions and 20 deletions

View File

@ -0,0 +1,3 @@
{
"Keys" : [ ]
}

36
TestPlugin/TestPlugin.pro Normal file
View File

@ -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

1
TestPlugin/logo.svg Normal file
View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1664265123673" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1957" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M916.968 797.124l-277-455.782V42.688h-256v298.656L107.032 797.124c-13.812 22.594-21.688 49.156-21.688 77.562 0 82.468 66.812 149.312 149.312 149.312h554.688c82.438 0 149.312-66.844 149.312-149.312 0-28.404-7.938-54.968-21.688-77.562z" fill="#E6E9ED" p-id="1958"></path><path d="M682.656 64c0 35.344-28.688 64-64 64H405.344c-35.376 0-64-28.656-64-64s28.624-64 64-64h213.312c35.312 0 64 28.656 64 64z" fill="#CCD1D9" p-id="1959"></path><path d="M829.094 652.532c-17.938 20.312-38.938 38.906-62.75 55.032-41.688 28.25-82.376 43-122.438 47.218-88.75 9.344-174.812-32.968-263.876-95.25-45.062-31.468-93.124-59.376-142.938-76.468l-130.06 214.06c-13.812 22.594-21.688 49.156-21.688 77.562 0 82.468 66.812 149.312 149.312 149.312h554.688c82.438 0 149.312-66.844 149.312-149.312 0-28.406-7.938-54.968-21.688-77.562l-87.874-144.592z" fill="#48CFAD" p-id="1960"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

5
TestPlugin/resources.qrc Normal file
View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/TestPlugin">
<file>logo.svg</file>
</qresource>
</RCC>

78
TestPlugin/testplugin.cpp Normal file
View File

@ -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<WingPluginInfo> 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<QVariant> 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<QUuid>().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

43
TestPlugin/testplugin.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef GENERICPLUGIN_H
#define GENERICPLUGIN_H
#include "../plugin/iwingtoolplg.h"
#include <QDialog>
#include <QTextBrowser>
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<WingPluginInfo> 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<QVariant> params) override;
private:
QUuid testhotkey;
QDialog *dialog;
QTextBrowser *tbinfo;
};
#endif // GENERICPLUGIN_H

View File

@ -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; }

View File

@ -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;

View File

@ -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<QHotkey *>(hotkey)];
this->runTask(task.process, task.params);
if (hotkeys.contains(const_cast<QHotkey *>(hotkey))) {
auto &task = scinfos[const_cast<QHotkey *>(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<QHotkey *>(hotkey)), 0)
->setCheckState(value ? Qt::Checked : Qt::Unchecked);
if (hotkeys.contains(const_cast<QHotkey *>(hotkey))) {
tbhotkeys->item(hotkeys.indexOf(const_cast<QHotkey *>(hotkey)), 0)
->setCheckState(value ? Qt::Checked : Qt::Unchecked);
}
});
}

View File

@ -2,6 +2,7 @@
#include "plugin/pluginsystem.h"
#include "utilities.h"
#include <DButtonBox>
#include <DMessageManager>
#include <QHBoxLayout>
#include <QMetaEnum>
@ -52,8 +53,15 @@ PluginSelDialog::PluginSelDialog(DDialog *parent) : DDialog(parent) {
auto group = new DButtonBox(this);
QList<DButtonBoxButton *> 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); });

View File

@ -9,6 +9,7 @@
DWIDGET_USE_NAMESPACE
class PluginSelDialog : public DDialog {
Q_OBJECT
public:
PluginSelDialog(DDialog *parent = nullptr);

View File

@ -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));

View File

@ -6,15 +6,18 @@
#include "class/appmanager.h"
#include "control/pluginselector.h"
#include <DCheckBox>
#include <DComboBox>
#include <DDialog>
#include <DFileChooserEdit>
#include <DKeySequenceEdit>
#include <DLabel>
#include <DLineEdit>
#include <DMainWindow>
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

View File

@ -1,6 +1,8 @@
#ifndef IWINGTOOLPLG_H
#define IWINGTOOLPLG_H
#include <QIcon>
#include <QKeySequence>
#include <QObject>
#include <QUuid>
#include <QVariant>
@ -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);

View File

@ -70,7 +70,33 @@ PluginSystem::PluginSystem(QObject *parent)
});
connect(manager, &AppManager::hotkeyTirggered, this,
[=](const QHotkey *hotkey) {
auto uuid = uhmap.key(const_cast<QHotkey *>(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<QHotkey *>(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<QHotkey *>(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<IWingToolPlg *>(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<IWingToolPlg *>(QObject::sender());
if (sender == nullptr)
return false;
@ -305,3 +335,14 @@ QList<QKeySequence> 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;
}

View File

@ -42,6 +42,9 @@ public:
QList<QKeySequence> pluginRegisteredHotkey(IWingToolPlg *plg);
private:
IWingToolPlg *loopUpHotkey(QUuid uuid, int &index);
private:
static PluginSystem *m_instance;
AppManager *manager;

View File

@ -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();
}
};