LAMPCAE/src/PluginManager/PluginManager.cpp

228 lines
5.0 KiB
C++
Raw Normal View History

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