diff --git a/class/appmanager.cpp b/class/appmanager.cpp index 7697613..32e34d7 100644 --- a/class/appmanager.cpp +++ b/class/appmanager.cpp @@ -1,11 +1,11 @@ #include "appmanager.h" #include #include +#include AppManager *AppManager::m_instance = nullptr; AppManager::AppManager(QObject *parent) : QObject(parent) { - // 初始化选词监控 auto clipboard = qApp->clipboard(); connect(clipboard, &QClipboard::selectionChanged, this, [=] { @@ -24,8 +24,8 @@ AppManager::AppManager(QObject *parent) : QObject(parent) { CONNECT(mouseMove); connect(&monitor, &EventMonitor::buttonPress, - [=](EventMonitor::MouseButton btn, int x, int y) { - if (btn == EventMonitor::MouseButton::MiddleButton) { + [=](Qt::MouseButton btn, int x, int y) { + if (this->checkToolShow(btn)) { toolwin.popup(QCursor::pos()); } emit this->buttonPress(btn, x, y); @@ -37,7 +37,7 @@ AppManager::AppManager(QObject *parent) : QObject(parent) { emit this->mouseDrag(x, y); }); connect(&monitor, &EventMonitor::buttonRelease, - [=](EventMonitor::MouseButton btn, int x, int y) { + [=](Qt::MouseButton btn, int x, int y) { toolwin.hide(); ignoremsg = true; emit this->buttonRelease(btn, x, y); @@ -45,8 +45,6 @@ AppManager::AppManager(QObject *parent) : QObject(parent) { monitor.start(); - // 初始化热键存储 - // 存单实例 m_instance = this; } @@ -107,3 +105,7 @@ void AppManager::clearHotkey() { registeredSeq.clear(); hotkeys.clear(); } + +Qt::KeyboardModifier AppManager::getKeyModifier() const { + return monitor.getKeyModifier(); +} diff --git a/class/appmanager.h b/class/appmanager.h index 81ab75a..ccd357a 100644 --- a/class/appmanager.h +++ b/class/appmanager.h @@ -4,8 +4,7 @@ #include "class/eventmonitor.h" #include "class/hotkey.h" #include "dialog/toolwindow.h" -#undef Bool -#undef Unsorted +#include "utilities.h" #include #include #include @@ -25,9 +24,11 @@ public: bool editHotkey(Hotkey *hotkey, QKeySequence &keyseq); void clearHotkey(); + Qt::KeyboardModifier getKeyModifier() const; + signals: - void buttonPress(EventMonitor::MouseButton btn, int x, int y); - void buttonRelease(EventMonitor::MouseButton btn, int x, int y); + void buttonPress(Qt::MouseButton btn, int x, int y); + void buttonRelease(Qt::MouseButton btn, int x, int y); void clicked(int x, int y); void doubleClicked(int x, int y); void mouseWheel(EventMonitor::MouseWheel direction); @@ -39,11 +40,11 @@ signals: void hotkeyEnableChanged(bool value, const Hotkey *hotkey); void selectionTextChanged(const QString &selectedText); + bool checkToolShow(Qt::MouseButton btn); private: EventMonitor monitor; QList hotkeys; - QStringList execs; bool ignoremsg = false; diff --git a/class/eventmonitor.cpp b/class/eventmonitor.cpp index 2c8876c..2f090f3 100644 --- a/class/eventmonitor.cpp +++ b/class/eventmonitor.cpp @@ -1,6 +1,5 @@ #include "eventmonitor.h" #include -#include EventMonitor::EventMonitor(QObject *parent) : QThread(parent) { isPress = false; @@ -34,7 +33,7 @@ void EventMonitor::run() { // Receive ButtonPress, ButtonRelease and MotionNotify // events. memset(range, 0, sizeof(XRecordRange)); - range->device_events.first = ButtonPress; + range->device_events.first = KeyPress; range->device_events.last = MotionNotify; // And create the XRECORD context. @@ -66,6 +65,10 @@ void EventMonitor::run() { isClicked = false; } +Qt::KeyboardModifier EventMonitor::getKeyModifier() const { + return keyModifier; +} + void EventMonitor::callback(XPointer ptr, XRecordInterceptData *data) { (reinterpret_cast(ptr))->handleRecordEvent(data); } @@ -78,10 +81,10 @@ void EventMonitor::handleRecordEvent(XRecordInterceptData *data) { case ButtonPress: if (handleWheelEvent(event->u.u.detail)) { isPress = true; - MouseButton btn = MouseButton::NoneButton; + Qt::MouseButton btn = Qt::MouseButton::NoButton; switch (event->u.u.detail) { case Button1: { - btn = MouseButton::LeftButton; + btn = Qt::MouseButton::LeftButton; auto clicknow = std::chrono::system_clock::now(); double diff_ms = @@ -100,16 +103,16 @@ void EventMonitor::handleRecordEvent(XRecordInterceptData *data) { } break; case Button2: - btn = MouseButton::MiddleButton; + btn = Qt::MouseButton::MiddleButton; break; case Button3: - btn = MouseButton::RightButton; + btn = Qt::MouseButton::RightButton; break; - case XButton1: - btn = MouseButton::XButton_1; + case XButton_1: + btn = Qt::MouseButton::XButton1; break; - case XButton2: - btn = MouseButton::XButton_2; + case XButton_2: + btn = Qt::MouseButton::XButton2; break; } @@ -130,28 +133,53 @@ void EventMonitor::handleRecordEvent(XRecordInterceptData *data) { if (handleWheelEvent(event->u.u.detail)) { isPress = false; - MouseButton btn = MouseButton::NoneButton; + Qt::MouseButton btn = Qt::MouseButton::NoButton; switch (event->u.u.detail) { case Button1: - btn = MouseButton::LeftButton; + btn = Qt::MouseButton::LeftButton; break; case Button2: - btn = MouseButton::MiddleButton; + btn = Qt::MouseButton::MiddleButton; break; case Button3: - btn = MouseButton::RightButton; + btn = Qt::MouseButton::RightButton; break; - case XButton1: - btn = MouseButton::XButton_1; + case XButton_1: + btn = Qt::MouseButton::XButton1; break; - case XButton2: - btn = MouseButton::XButton_2; + case XButton_2: + btn = Qt::MouseButton::XButton2; break; } emit buttonRelease(btn, event->u.keyButtonPointer.rootX, event->u.keyButtonPointer.rootY); } break; + case KeyPress: { + auto code = data->data[1]; + switch (code) { + case 50: + case 62: + keyModifier = Qt::ShiftModifier; + break; + case 37: + case 105: + keyModifier = Qt::ControlModifier; + break; + case 64: + case 108: + keyModifier = Qt::AltModifier; + break; + case 133: + keyModifier = Qt::MetaModifier; + break; + default: + break; + } + } break; + case KeyRelease: + keyModifier = Qt::NoModifier; + break; default: break; } diff --git a/class/eventmonitor.h b/class/eventmonitor.h index a2a0751..5a5b0eb 100644 --- a/class/eventmonitor.h +++ b/class/eventmonitor.h @@ -12,9 +12,17 @@ #include #include #include + +/*== X11 头文件有和 QT 头文件冲突的地方 ==*/ +// 所以 undef 使其编译通过 #include -#undef None +#include #include +#undef Unsorted +#undef None +#undef Bool +#undef Data +/*==================================*/ // Virtual button codes that are not defined by X11. #define Button1 1 @@ -24,23 +32,13 @@ #define WheelDown 5 #define WheelLeft 6 #define WheelRight 7 -#define XButton1 8 -#define XButton2 9 +#define XButton_1 8 +#define XButton_2 9 class EventMonitor : public QThread { Q_OBJECT public: - enum class MouseButton { - NoneButton, - LeftButton, - RightButton, - MiddleButton, - XButton_1, - XButton_2 - }; - Q_ENUM(MouseButton) - enum class MouseWheel { None, Up, Down, Left, Right }; Q_ENUM(MouseWheel) @@ -48,9 +46,11 @@ public: EventMonitor(QObject *parent = nullptr); ~EventMonitor() override; + Qt::KeyboardModifier getKeyModifier() const; + signals: - void buttonPress(MouseButton btn, int x, int y); // 当鼠标按键被按下时 - void buttonRelease(MouseButton btn, int x, int y); // 当鼠标按键被释放时 + void buttonPress(Qt::MouseButton btn, int x, int y); // 当鼠标按键被按下时 + void buttonRelease(Qt::MouseButton btn, int x, int y); // 当鼠标按键被释放时 void clicked(int x, int y); // 当鼠标进行单击操作时 void doubleClicked(int x, int y); // 当鼠标进行双击操作时 void mouseWheel(MouseWheel direction); // 当鼠标滚轮滚动时 @@ -69,6 +69,8 @@ private: Display *display_datalink; std::chrono::system_clock::time_point clickbefore; + + Qt::KeyboardModifier keyModifier; }; #endif diff --git a/class/settingmanager.cpp b/class/settingmanager.cpp index 62c7289..2c4fd69 100644 --- a/class/settingmanager.cpp +++ b/class/settingmanager.cpp @@ -1,11 +1,17 @@ #include "settingmanager.h" +#include "plugin/pluginsystem.h" #include #include #include SettingManager *SettingManager::m_instance = nullptr; -SettingManager::SettingManager(QObject *parent) : QObject(parent) { +SettingManager::SettingManager(QObject *parent) + : QObject(parent), m_toolGridSize(TOOLGRIDSIZE), + m_toolBox( + QKeySequence(Qt::KeyboardModifier::ShiftModifier | Qt::Key_Space)), + m_toolwinMod(Qt::KeyboardModifier::ControlModifier), + m_toolMouse(Qt::MouseButton::MidButton) { m_instance = this; } @@ -19,8 +25,132 @@ bool SettingManager::loadSettings() { .arg(qApp->applicationName()); QFile f(strConfigPath); + QDataStream stream(&f); if (f.open(QFile::ReadOnly)) { - emit this->loadingFinish(); + // 开始读配置文件咯 + static char header[] = "WINGTOOL"; + char buffer[8]; + stream.readRawData(buffer, 8); + if (memcmp(header, buffer, 8)) { + // 如果文件头不对劲,就视为非法配置 + return false; + } + + auto plgsys = PluginSystem::instance(); + + // General + stream >> m_toolGridSize >> m_toolBox >> m_toolwinMod >> m_toolMouse; + + // 读取结束,提示可以加载基础配置内容了 + emit this->loadedGeneral(); + + // 读取 Hotkey 的相关信息 + int len; + stream >> len; // 先读取一下有几个 + for (auto i = 0; i < len; i++) { + ToolStructInfo buf; + stream >> buf.enabled >> buf.isPlugin >> buf.seq; + if (buf.isPlugin) { + stream >> buf.serviceID; + QByteArray arr; + stream >> arr; + buf.provider = QString::fromUtf8(arr); + stream >> arr; + buf.params = QString::fromUtf8(arr); + stream >> arr; + + auto pi = plgsys->pluginIndexByProvider(buf.provider); + // 找不到了,插件丢失或者不兼容 + if (pi < 0) + continue; + // 检查兼容性,不兼容出门左拐 + if (!Utilities::isPluginCompatible(plgsys->plugin(pi), arr)) { + continue; + } + // 经历过重重检验,合格入库 + + emit addHotKeyInfo(buf); + } else { + // 如果是打开文件就没这么多事情了 + QByteArray arr; + stream >> arr; + buf.process = QString::fromUtf8(arr); + stream >> arr; + buf.params = QString::fromUtf8(arr); + emit addHotKeyInfo(buf); + } + } + + // 下面继续读取 ToolWin 相关信息,只有8条 + for (auto i = 0; i < 8; i++) { + ToolStructInfo buf{true}; + + // 对于 ToolWin 来说,这个成员是决定性的 + // 只有这个标志位有效,这个工具才有意义 + + stream >> buf.isPlugin; + if (buf.isPlugin) { + stream >> buf.serviceID; + QByteArray arr; + stream >> arr; + buf.provider = QString::fromUtf8(arr); + stream >> arr; + buf.params = QString::fromUtf8(arr); + auto pi = plgsys->pluginIndexByProvider(buf.provider); + // 找不到了,插件丢失或者不兼容 + if (pi < 0) + continue; + // 检查兼容性,不兼容出门左拐 + if (!Utilities::isPluginCompatible(plgsys->plugin(pi), arr)) { + continue; + } + // 经历过重重检验,合格入库 + emit setToolWinInfo(i, buf); + } else { // 如果是打开文件就没这么多事情了 + QByteArray arr; + stream >> arr; + buf.process = QString::fromUtf8(arr); + stream >> arr; + buf.params = QString::fromUtf8(arr); + emit setToolWinInfo(i, buf); + } + } + + // 下面读取 WinTool 相关信息 + + stream >> len; // 先读一下有几个 + for (auto i = 0; i < len; i++) { + ToolStructInfo buf; + + // 对于 WinTool 来说, enabled 就没用了 + // 只存储相关基础信息就可以了 + stream >> buf.isPlugin; + if (buf.isPlugin) { + stream >> buf.serviceID; + QByteArray arr; + stream >> arr; + buf.provider = QString::fromUtf8(arr); + stream >> arr; + buf.params = QString::fromUtf8(arr); + auto pi = plgsys->pluginIndexByProvider(buf.provider); + // 找不到了,插件丢失或者不兼容 + if (pi < 0) + continue; + // 检查兼容性,不兼容出门左拐 + if (!Utilities::isPluginCompatible(plgsys->plugin(pi), arr)) { + continue; + } + // 经历过重重检验,合格入库 + emit addWinToolInfo(buf); + } else { + QByteArray arr; + stream >> arr; + buf.process = QString::fromUtf8(arr); + stream >> arr; + buf.params = QString::fromUtf8(arr); + emit addWinToolInfo(buf); + } + } } return true; } @@ -38,24 +168,44 @@ bool SettingManager::exportSettings(QString filename) { QFile f(filename); QDataStream stream(&f); if (f.open(QFile::WriteOnly)) { - + // 写文件头 + static char header[] = "WINGTOOL"; + stream.writeRawData(header, 8); + // General + stream << m_toolGridSize << m_toolBox << m_toolwinMod << m_toolMouse; + // 有些配置直接保存到 CenterWindow 里面了,为了减少内存占用 + emit sigSaveConfig(stream); + // 至此,保存完毕 + f.close(); return true; } return false; } -int SettingManager::toolGridSize() { return m_toolGridSize; } +int SettingManager::toolGridSize() const { return m_toolGridSize; } -void SettingManager::setToolGridSize(int v) { +void SettingManager::setToolGridSize(const int v) { if (v > 0) { m_toolGridSize = v; emit sigToolGridSizeChanged(v); } } -void SettingManager::getHokeysBuffer(QList &hotkeysBuf, - QMap &buffer) {} +QKeySequence SettingManager::toolBoxHotkey() const { return m_toolBox; } -void SettingManager::getToolLeftBuffer(ToolStructInfo buffer[]) {} +void SettingManager::setToolBoxHotkey(const QKeySequence seq) { + m_toolBox = seq; + emit sigToolBoxHotkeyChanged(seq); +} -void SettingManager::getToolRightBuffer(QList &buffer) {} +Qt::KeyboardModifier SettingManager::toolwinMod() const { return m_toolwinMod; } + +void SettingManager::setToolwinMod(const Qt::KeyboardModifier &toolwinMod) { + m_toolwinMod = toolwinMod; +} + +Qt::MouseButton SettingManager::toolwinMouseBtn() const { return m_toolMouse; } + +void SettingManager::setToolMouseBtn(const Qt::MouseButton &toolMouse) { + m_toolMouse = toolMouse; +} diff --git a/class/settingmanager.h b/class/settingmanager.h index 007d7a5..76d341c 100644 --- a/class/settingmanager.h +++ b/class/settingmanager.h @@ -3,6 +3,7 @@ #include "class/hotkey.h" #include "utilities.h" +#include #include #define TOOLGRIDSIZE 40 @@ -21,23 +22,41 @@ public: void resetSettings(); public: - int toolGridSize(); - void setToolGridSize(int v); + int toolGridSize() const; + void setToolGridSize(const int v); + + QKeySequence toolBoxHotkey() const; + void setToolBoxHotkey(const QKeySequence seq); + + Qt::KeyboardModifier toolwinMod() const; + void setToolwinMod(const Qt::KeyboardModifier &toolwinMod); + + Qt::MouseButton toolwinMouseBtn() const; + void setToolMouseBtn(const Qt::MouseButton &toolwinMouseBtn); signals: void sigToolGridSizeChanged(int v); - void loadingFinish(); + void loadedGeneral(); + void sigToolBoxHotkeyChanged(const QKeySequence seq); + void sigToolWinShortCutChanged(const Qt::KeyboardModifier mod, + const Qt::MouseButton btn); -public slots: - void getHokeysBuffer(QList &hotkeysBuf, - QMap &buffer); - void getToolLeftBuffer(ToolStructInfo buffer[]); - void getToolRightBuffer(QList &buffer); + void sigSaveConfig(QDataStream &stream); + + // 配置添加信号 + void addHotKeyInfo(ToolStructInfo &info); + void setToolWinInfo(int index, ToolStructInfo &info); + void addWinToolInfo(ToolStructInfo &info); private: static SettingManager *m_instance; - int m_toolGridSize = TOOLGRIDSIZE; + int m_toolGridSize; + + QKeySequence m_toolBox; + + Qt::KeyboardModifier m_toolwinMod; + Qt::MouseButton m_toolMouse; }; #endif // SETTINGMANAGER_H diff --git a/dialog/centerwindow.cpp b/dialog/centerwindow.cpp index d859ea2..fb4adb3 100644 --- a/dialog/centerwindow.cpp +++ b/dialog/centerwindow.cpp @@ -53,13 +53,26 @@ CenterWindow::CenterWindow(DMainWindow *parent) : DMainWindow(parent) { }); vlayout->addWidget(cbauto, Qt::AlignTop); + auto gw = new QWidget(w); + vlayout->addWidget(gw); + auto hlayout = new QHBoxLayout(gw); + hlayout->addWidget(new DLabel(tr("ToolWinGridSize"), this)); + hlayout->addSpacing(5); + sbGridsize = new DSpinBox(w); + sbGridsize->setRange(30, 60); + sbGridsize->setValue(40); // 默认 40 先 + connect(sbGridsize, QOverload::of(&DSpinBox::valueChanged), this, + [=](int v) { + + }); + hlayout->addWidget(sbGridsize); vlayout->addSpacing(10); l = new DLabel(tr("Shortcut"), this); l->setFont(font); vlayout->addWidget(l); vlayout->addSpacing(5); - auto gw = new QWidget(w); + gw = new QWidget(w); vlayout->addWidget(gw); auto flayout = new QFormLayout(gw); kseqTool = new DKeySequenceEdit(gw); @@ -68,7 +81,7 @@ CenterWindow::CenterWindow(DMainWindow *parent) : DMainWindow(parent) { }); flayout->addRow(tr("ToolBox:"), kseqTool); - auto hlayout = new QHBoxLayout(gw); + hlayout = new QHBoxLayout(gw); cbMod = new DComboBox(gw); cbMod->addItems({"Ctrl", "Shift", "Alt", "Super"}); cbMod->setCurrentIndex(0); @@ -113,7 +126,8 @@ CenterWindow::CenterWindow(DMainWindow *parent) : DMainWindow(parent) { vlayout->addWidget(new DLabel(QString(tr("%1 , Ver %2 , by WingSummer.")) .arg(qApp->applicationName()) - .arg(qApp->applicationVersion()))); + .arg(qApp->applicationVersion()), + this)); vlayout->addStretch(); tabs->addTab(w, tr("General")); @@ -650,17 +664,93 @@ void CenterWindow::on_upToolWin() {} void CenterWindow::on_downToolWin() {} -void CenterWindow::initSettings() { +void CenterWindow::addHotKeyInfo(ToolStructInfo &info) { + // 添加 UI 项目 + auto index = tbhotkeys->rowCount(); + tbhotkeys->setRowCount(index + 1); + auto wt = new QTableWidgetItem; + wt->setCheckState(info.enabled ? Qt::Checked : Qt::Unchecked); + tbhotkeys->setItem(index, 0, wt); + tbhotkeys->setItem(index, 1, new QTableWidgetItem(info.seq.toString())); + wt = new QTableWidgetItem(info.process); + wt->setToolTip(info.process); + tbhotkeys->setItem(index, 2, wt); + wt = new QTableWidgetItem(info.params); + wt->setToolTip(info.params); + tbhotkeys->setItem(index, 3, wt); + + // 注册热键 + auto hk = manager->registerHotkey(info.seq, true); + hotkeys << hk; + scinfos.insert(hk, info); + + // 修正热键状态 + manager->enableHotKey(hk, info.enabled); +} + +void CenterWindow::setoolWinInfo(int index, ToolStructInfo &info) { + if (index >= 4) + index++; + toolinfos[index] = info; + + // 更新 UI + // TODO +} + +void CenterWindow::addWinToolInfo(ToolStructInfo &info) { + wintoolinfos << info; + auto item = new QListWidgetItem( + Utilities::trimIconFromInfo(plgsys->plugin(info.pluginIndex), info), + info.isPlugin ? info.process : QFileInfo(info.process).fileName()); + item->setToolTip(info.process); + lstoolwin->addItem(item); +} + +void CenterWindow::initGeneralSettings() { sm = SettingManager::instance(); auto gridsize = sm->toolGridSize(); for (auto i = 0; i < 9; i++) { lbls[i]->setFixedSize(QSize(gridsize, gridsize)); } - emit this->getHokeysBuffer(hotkeys, scinfos); - emit this->getToolLeftBuffer(toolinfos); - emit this->getToolRightBuffer(wintoolinfos); - // 获取完数据后,开始初始化程序配置 + Qt::KeyboardModifier mod = sm->toolwinMod(); + Qt::MouseButton btn = sm->toolwinMouseBtn(); + switch (mod) { + case Qt::KeyboardModifier::AltModifier: + cbMod->setCurrentIndex(2); + break; + case Qt::KeyboardModifier::MetaModifier: + cbMod->setCurrentIndex(3); + break; + case Qt::KeyboardModifier::ShiftModifier: + cbMod->setCurrentIndex(1); + break; + default: + cbMod->setCurrentIndex(0); + break; + } + + switch (btn) { + case Qt::MouseButton::RightButton: + cbMouseBtn->setCurrentIndex(1); + break; + case Qt::MouseButton::MidButton: + cbMouseBtn->setCurrentIndex(2); + break; + case Qt::MouseButton::XButton1: + cbMouseBtn->setCurrentIndex(3); + break; + case Qt::MouseButton::XButton2: + cbMouseBtn->setCurrentIndex(4); + break; + default: + cbMouseBtn->setCurrentIndex(0); + break; + } + + auto seq = sm->toolBoxHotkey(); + kseqTool->setKeySequence(seq); + manager->registerHotkey(seq, true); } void CenterWindow::initPluginSys() { @@ -694,6 +784,60 @@ void CenterWindow::initAppManger() { }); } +void CenterWindow::getConfig(QDataStream &f) { + // 先保存 Hotkey 的相关信息 + f << hotkeys.count(); // 先存一下有几个 + for (auto &p : scinfos) { + f << p.enabled << p.isPlugin << p.seq; + if (p.isPlugin) { + f << p.serviceID << p.provider.toUtf8() << p.params.toUtf8() + << plgsys->pluginHash(p.pluginIndex); //最后存储 MD5 表示一条信息结束了 + } else { + f << p.process.toUtf8() + << p.params.toUtf8(); // 如果是打开文件就没这么多事情了 + } + } + + // 下面继续存储 ToolWin 相关信息,只有8条 + for (auto i = 0; i < 9; i++) { + if (i == 4) // 抛掉空的 + continue; + + auto &p = toolinfos[i]; + // 对于 ToolWin 来说,enabled 是决定性的 + // 只有这个标志位有效,这个工具才有意义 + // 只存有意义的即可 + if (p.enabled) { + f << p.isPlugin; + if (p.isPlugin) { + f << p.serviceID << p.provider.toUtf8() << p.params.toUtf8() + << plgsys->pluginHash( + p.pluginIndex); //最后存储 MD5 表示一条信息结束了 + } else { + f << p.process.toUtf8() + << p.params.toUtf8(); // 如果是打开文件就没这么多事情了 + } + } + } + + // 下面存取 WinTool 相关信息 + f << wintoolinfos.count(); // 先存一下有几个 + for (auto &p : wintoolinfos) { + // 对于 WinTool 来说, enabled 就没用了 + // 只存储相关基础信息就可以了 + f << p.isPlugin; + if (p.isPlugin) { + f << p.serviceID << p.provider.toUtf8() << p.params.toUtf8() + << plgsys->pluginHash(p.pluginIndex); //最后存储 MD5 表示一条信息结束了 + } else { + f << p.process.toUtf8() + << p.params.toUtf8(); // 如果是打开文件就没这么多事情了 + } + } + + // 保存完毕,可以返回了 +} + void CenterWindow::closeEvent(QCloseEvent *event) { event->ignore(); hide(); diff --git a/dialog/centerwindow.h b/dialog/centerwindow.h index c0e365a..9af9fba 100644 --- a/dialog/centerwindow.h +++ b/dialog/centerwindow.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -57,16 +58,15 @@ private: void on_upToolWin(); void on_downToolWin(); -signals: - void getHokeysBuffer(QList &hotkeysBuf, - QMap &buffer); - void getToolLeftBuffer(ToolStructInfo buffer[]); - void getToolRightBuffer(QList &buffer); - public slots: - void initSettings(); + void addHotKeyInfo(ToolStructInfo &info); + void setoolWinInfo(int index, ToolStructInfo &info); + void addWinToolInfo(ToolStructInfo &info); + + void initGeneralSettings(); void initPluginSys(); void initAppManger(); + void getConfig(QDataStream &f); protected: void closeEvent(QCloseEvent *event) override; @@ -96,6 +96,8 @@ private: DKeySequenceEdit *kseqTool; DComboBox *cbMod, *cbMouseBtn; + DSpinBox *sbGridsize; + private: QMap scinfos; // 用于 Hotkeys QList hotkeys; // Hotkeys 方便进行检索 diff --git a/dialog/toolwindow.cpp b/dialog/toolwindow.cpp index e96ef7a..5f64f1c 100644 --- a/dialog/toolwindow.cpp +++ b/dialog/toolwindow.cpp @@ -9,8 +9,7 @@ ToolWindow::ToolWindow(DDialog *parent) : DDialog(parent) { Qt::X11BypassWindowManagerHint); setWindowFlag(Qt::FramelessWindowHint); - auto sm = SettingManager::instance(); - auto gridsize = sm->toolGridSize(); + auto gridsize = 40; // 默认 40 先 gridtotal = gridsize * 3; setFixedSize(gridtotal, gridtotal); delete layout(); @@ -29,6 +28,10 @@ ToolWindow::ToolWindow(DDialog *parent) : DDialog(parent) { } lbls[4]->setIcon(ICONRES("close")); +} + +void ToolWindow::loadSettings() { + auto sm = SettingManager::instance(); // 当设置修改时,响应调整大小 connect(sm, &SettingManager::sigToolGridSizeChanged, this, [=](int v) { diff --git a/dialog/toolwindow.h b/dialog/toolwindow.h index e187d87..4976a02 100644 --- a/dialog/toolwindow.h +++ b/dialog/toolwindow.h @@ -14,6 +14,8 @@ public: ToolWindow(DDialog *parent = nullptr); public slots: + void loadSettings(); + void setIcons(QVector icons); void setIcon(int index, QIcon icon); diff --git a/main.cpp b/main.cpp index 1d76fab..a0c44e1 100644 --- a/main.cpp +++ b/main.cpp @@ -15,6 +15,8 @@ DWIDGET_USE_NAMESPACE +Q_DECLARE_METATYPE(Qt::MouseButton) + int main(int argc, char *argv[]) { //解决 root/ubuntu 主题样式走形 qputenv("XDG_CURRENT_DESKTOP", "Deepin"); @@ -80,18 +82,7 @@ int main(int argc, char *argv[]) { /*== 以下在主函数初始化确保单例 ==*/ /* 之后不得使用构造函数的方式使用 */ - // 初始化软件配置 - SettingManager sm; - - QObject::connect(&sm, &SettingManager::loadingFinish, &w, - &CenterWindow::initSettings); - QObject::connect(&w, &CenterWindow::getHokeysBuffer, &sm, - &SettingManager::getHokeysBuffer); - QObject::connect(&w, &CenterWindow::getToolLeftBuffer, &sm, - &SettingManager::getToolLeftBuffer); - QObject::connect(&w, &CenterWindow::getToolRightBuffer, &sm, - &SettingManager::getToolRightBuffer); - sm.loadSettings(); + qRegisterMetaType(); // 初始化程序基础驱动 AppManager manager; @@ -101,6 +92,28 @@ int main(int argc, char *argv[]) { PluginSystem plgsys; w.initPluginSys(); + // 初始化软件配置 + SettingManager sm; + + QObject::connect(&sm, &SettingManager::loadedGeneral, &w, + &CenterWindow::initGeneralSettings); + QObject::connect(&sm, &SettingManager::addHotKeyInfo, &w, + &CenterWindow::addHotKeyInfo); + QObject::connect(&sm, &SettingManager::setToolWinInfo, &w, + &CenterWindow::setoolWinInfo); + QObject::connect(&sm, &SettingManager::addWinToolInfo, &w, + &CenterWindow::addWinToolInfo); + QObject::connect(&sm, &SettingManager::sigSaveConfig, &w, + &CenterWindow::getConfig); + sm.loadSettings(); + + QObject::connect(&manager, &AppManager::checkToolShow, + [&sm, &manager](Qt::MouseButton btn) { + auto mod = manager.getKeyModifier(); + return mod == sm.toolwinMod() && + sm.toolwinMouseBtn() == btn; + }); + /*===========================*/ // 初始化托盘 diff --git a/plugin/iwingtoolplg.h b/plugin/iwingtoolplg.h index 8f70b06..10c63d3 100644 --- a/plugin/iwingtoolplg.h +++ b/plugin/iwingtoolplg.h @@ -38,16 +38,6 @@ struct WingPluginInfo { QString pluginComment; }; -enum class MouseButtonEvent { - NoneButton, - LeftButton, - RightButton, - MiddleButton, - XButton_1, - XButton_2 -}; -Q_DECLARE_METATYPE(MouseButtonEvent) - enum class MouseWheelEvent { None, Up, Down, Left, Right }; Q_DECLARE_METATYPE(MouseWheelEvent) @@ -135,14 +125,14 @@ public slots: virtual QVariant pluginServicePipe(int serviceID, QList params) = 0; // 当鼠标任何一个键被按下就会触发该函数,如果想处理重载 - virtual void buttonPress(MouseButtonEvent btn, int x, int y) { + virtual void buttonPress(Qt::MouseButton btn, int x, int y) { Q_UNUSED(btn); Q_UNUSED(x); Q_UNUSED(y); } // 当鼠标任何一个键从被按下的状态释放就会触发该函数,如果想处理重载 - virtual void buttonRelease(MouseButtonEvent btn, int x, int y) { + virtual void buttonRelease(Qt::MouseButton btn, int x, int y) { Q_UNUSED(btn); Q_UNUSED(x); Q_UNUSED(y); diff --git a/plugin/pluginsystem.cpp b/plugin/pluginsystem.cpp index 40796de..149ad9a 100644 --- a/plugin/pluginsystem.cpp +++ b/plugin/pluginsystem.cpp @@ -1,4 +1,5 @@ #include "pluginsystem.h" +#include "utilities.h" #include #include #include @@ -32,15 +33,15 @@ PluginSystem::PluginSystem(QObject *parent) // 初始化插件基础服务 connect(manager, &AppManager::buttonPress, this, - [=](EventMonitor::MouseButton btn, int x, int y) { + [=](Qt::MouseButton btn, int x, int y) { for (auto item : dispatcher[HookIndex::ButtonPress]) { - item->buttonPress(MouseButtonEvent(btn), x, y); + item->buttonPress(btn, x, y); } }); connect(manager, &AppManager::buttonRelease, this, - [=](EventMonitor::MouseButton btn, int x, int y) { + [=](Qt::MouseButton btn, int x, int y) { for (auto item : dispatcher[HookIndex::ButtonRelease]) { - item->buttonRelease(MouseButtonEvent(btn), x, y); + item->buttonRelease(btn, x, y); } }); connect(manager, &AppManager::mouseMove, this, [=](int x, int y) { @@ -216,9 +217,10 @@ void PluginSystem::loadPlugin(QFileInfo fileinfo) { info.pluginComment = p->pluginComment(); info.pluginVersion = p->pluginVersion(); - loadedplginfos.push_back(info); - m_plgs.push_back(p); + loadedplginfos << info; + m_plgs << p; loadedProvider << p->provider(); + m_plgsMD5s << Utilities::getPUID(p); dWarning(tr("PluginInitRegister")); @@ -248,7 +250,7 @@ void PluginSystem::loadPlugin(QFileInfo fileinfo) { auto hk = this->manager->registerHotkey(keyseq, false); if (hk) { auto uuid = QUuid::createUuid(); - m_plghk[sender].append(uuid); + m_plghk[sender] << uuid; uhmap.insert(uuid, hk); return uuid; } else { @@ -350,7 +352,7 @@ QList PluginSystem::pluginRegisteredHotkey(IWingToolPlg *plg) { auto plist = m_plghk[plg]; for (auto &item : plist) { auto hk = uhmap[item]; - keys.append(hk->shortcut()); + keys << hk->shortcut(); } return keys; } @@ -368,6 +370,12 @@ bool PluginSystem::pluginCall(QString provider, int serviceID, return true; } +QByteArray PluginSystem::pluginHash(int index) { return m_plgsMD5s[index]; } + +int PluginSystem::pluginIndexByProvider(QString provider) { + return loadedProvider.indexOf(provider); +} + IWingToolPlg *PluginSystem::loopUpHotkey(QUuid uuid, int &index) { for (auto plg : m_plgs) { auto res = m_plghk[plg].indexOf(uuid); diff --git a/plugin/pluginsystem.h b/plugin/pluginsystem.h index ffd6ec5..393b124 100644 --- a/plugin/pluginsystem.h +++ b/plugin/pluginsystem.h @@ -46,6 +46,10 @@ public: bool pluginCall(QString provider, int serviceID, QList params); + QByteArray pluginHash(int index); + + int pluginIndexByProvider(QString provider); + private: IWingToolPlg *loopUpHotkey(QUuid uuid, int &index); @@ -53,14 +57,16 @@ private: static PluginSystem *m_instance; AppManager *manager; - QStringList loadedProvider; // 已加载的插件 PUID - QList m_plgs; // 已加载的插件集合 + QStringList loadedProvider; // 已加载的插件 provider ,需要唯一 + QList m_plgs; // 已加载的插件集合 QMap> m_plghk; // 注册的热键句柄集合 QMap uhmap; // UUID 和 QHotkey 的对应图 QMap> m_catplgs; // 对应类别的插件集合 - QMap> dispatcher; + QMap> dispatcher; // Hook 消息订阅 + + QList m_plgsMD5s; // 已加载的插件 HASH }; #endif // PLUGINSYSTEM_H diff --git a/utilities.h b/utilities.h index f8894fb..a7e3ed4 100644 --- a/utilities.h +++ b/utilities.h @@ -30,8 +30,6 @@ struct ToolStructInfo { Q_DECLARE_METATYPE(ToolStructInfo) -class PluginSystem; - class Utilities { public: static bool activeWindowFromDock(quintptr winId) { @@ -55,6 +53,54 @@ public: return plg->pluginIcon(); } + // 虽然 provider 是插件的唯一标识,需要进行校验 + // 但是,检查兼容性的时候第一关就是看看有没有它 + // 所以:没必要! + static QByteArray getPUID(IWingToolPlg *plg) { + if (!plg) + return QByteArray(); + // 这个 PUID 似乎不那么高大上,仅仅就是拼凑 + // 但这几个是影响插件兼容的必要因素 + + QByteArray buffer; + QBuffer b(&buffer); + QDataStream f(&b); + + f << plg->isTool() << plg->pluginServices(); + return buffer; + } + + static bool isPluginCompatible(IWingToolPlg *plg, QByteArray &old) { + if (!plg) + return false; + + QBuffer b(&old); + QDataStream f(&b); + + bool isTool; + f >> isTool; + if (isTool != plg->isTool()) // 以前你是工具项目之一,后面不是了,肯定不兼容 + return false; + + QStringList services; + f >> services; + + auto srv = plg->pluginServices(); + auto len = services.count(); + + // 服务比原来的都少了,肯定不兼容 + if (srv.count() < len) + return false; + + // 开始评判函数,函数名不一致会导致错误的函数调用 + for (auto i = 0; i < len; i++) { + if (srv[i] != services[i]) + return false; + } + + return true; + } + static QIcon trimIconFromInfo(IWingToolPlg *plg, ToolStructInfo &info) { if (info.isPlugin) { if (plg == nullptr)