#include "PluginManager.h" #include "pluginBase.h" #include "PluginManageDialog.h" #include "Settings/BusAPI.h" #include "MainWindow/MainWindow.h" #include #include #include #include #include #include #include #ifdef Q_OS_WIN #include #include #endif #ifdef Q_OS_UNIX #include #endif namespace Plugins { PluginManager *PluginManager::_instance = nullptr; PluginManager *PluginManager::getInstance() { if (_instance == nullptr) _instance = new PluginManager; return _instance; } int PluginManager::getPluginsCount() { return _pluginList.size(); } void PluginManager::releasePlugs() { int nplug = _pluginList.size(); for (int i = 0; i < nplug; ++i) { Plugins::PluginBase *p = _pluginList.at(i); bool ok = p->uninstall(); if (!ok) continue; delete p; } _pluginList.clear(); } void PluginManager::loadPlugs(GUI::MainWindow *m) { _mainWindow = m; if (m != nullptr) connect(this, SIGNAL(updateActionStates()), m, SIGNAL(updateActionStatesSig())); QStringList plugins = Setting::BusAPI::instance()->getPlugins(); const QString plugdir = QApplication::applicationDirPath() + "/plugins/"; QDir dir(plugdir); if (!dir.exists()) { plugins.clear(); Setting::BusAPI::instance()->setPlugins(plugins); return; } for (int i = 0; i < plugins.size(); ++i) { QString pluginname = plugins.at(i); bool ok = loadPlugin(pluginname); if (!ok) plugins.removeOne(pluginname); } Setting::BusAPI::instance()->setPlugins(plugins); } bool PluginManager::loadPlugin(QString pluginname) { if (isFileLoaded(pluginname)) return false; QString lang = Setting::BusAPI::instance()->getLanguage(); const QString plugdir = QApplication::applicationDirPath() + "/plugins/"; QString plugpath = plugdir + pluginname; qDebug() << pluginname; typedef void (*Reg)(GUI::MainWindow *, QList *); Reg fun = nullptr; #ifdef Q_OS_WIN if (!pluginname.toLower().startsWith("plugin")) return false; if (!pluginname.toLower().endsWith(".dll")) return false; HMODULE hmodel = LoadLibrary(LPCWSTR(plugpath.utf16())); if (hmodel) { fun = (Reg)GetProcAddress(hmodel, "Register"); if (fun) { fun(_mainWindow, &_pluginList); Plugins::PluginBase *pls = _pluginList.last(); qDebug() << "Plugin: " << pls->getDescribe(); pls->install(); pls->setFileName(pluginname); pls->setWinModule(hmodel); pls->reTranslate(lang); } else { FreeLibrary(hmodel); return false; } } #endif #ifdef Q_OS_LINUX if (!pluginname.toLower().startsWith("libplugin")) return false; if (!pluginname.toLower().endsWith(".so")) return false; void *pHandle = dlopen(plugpath.toLatin1().data(), RTLD_NOW); if (!pHandle) return false; fun = (Reg)dlsym(pHandle, "Register"); if (fun) { fun(_mainWindow, &_pluginList); Plugins::PluginBase *pls = _pluginList.last(); qDebug() << "Plugin: " << pls->getDescribe(); pls->install(); pls->setFileName(pluginname); pls->setLinuxModule(pHandle); pls->reTranslate(lang); } else { // plugins.removeOne(pluginname); dlclose(pHandle); return false; } #endif emit updateActionStates(); return true; } void PluginManager::reTranslate(QString lang) { const int n = _pluginList.size(); for (int i = 0; i < n; ++i) { auto p = _pluginList.at(i); p->reTranslate(lang); } } PluginBase *PluginManager::getPluginByDescribe(QString des) { for (auto p : _pluginList) { if (des.toLower() == p->getDescribe().toLower()) return p; } return nullptr; } void PluginManager::manage() { PluginManageDialog dlg(_mainWindow, this); dlg.exec(); } bool PluginManager::releasePlugin(QString name) { for (auto p : _pluginList) { if (name == p->getFileName()) { bool ok = p->uninstall(); if (!ok) return false; delete p; _pluginList.removeOne(p); break; } } emit updateActionStates(); return true; } QList PluginManager::getPluginsByType(PluginType t) { QList ps; for (PluginBase *p : _pluginList) { if (p->getType() == t) ps.append(p); } return ps; } QDomElement &PluginManager::writeToProjectFile(QDomDocument *doc, QDomElement *parent) { static QDomElement pgsele = doc->createElement("Plugins"); for (auto p : _pluginList) p->writeToProjectFile(doc, &pgsele); parent->appendChild(pgsele); return pgsele; } void PluginManager::readDataFromProjectFile(QDomElement *e) { for (auto p : _pluginList) p->readFromProjectFile(e); } bool PluginManager::hasInfoToSave() { for (auto p : _pluginList) if (p->hasInfoToSave()) return true; return false; } bool PluginManager::isFileLoaded(const QString fileName) { for (auto p : _pluginList) { QString name = p->getFileName(); if (name.toLower() == fileName.toLower()) return true; } return false; } }