Skip to content

Commit

Permalink
refactor:
Browse files Browse the repository at this point in the history
The plugin directory is relative to the executable file.
Uninstall the plug-in using the selection method.
  • Loading branch information
zmoth committed Jan 4, 2023
1 parent c60e4d4 commit 8792708
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 59 deletions.
107 changes: 63 additions & 44 deletions examples/plugins_load/PluginsManagerDlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <QDir>
#include <QFileDialog>
#include <QDesktopServices>
#include <QCoreApplication>

#include <QtNodes/NodeDelegateModelRegistry>
#include <QtNodes/PluginInterface>
Expand All @@ -17,8 +18,11 @@ using QtNodes::PluginInterface;
PluginsManagerDlg::
PluginsManagerDlg(QWidget* parent)
: QDialog(parent)
, _pluginsFolderPath(R"(./nodes)")
{
setMinimumSize(300, 250);

_pluginsFolder.setPath(QDir::cleanPath(QCoreApplication::applicationDirPath() + QDir::separator() + R"(./nodes)"));

QGridLayout *layout = new QGridLayout();
setLayout(layout);

Expand All @@ -31,12 +35,14 @@ PluginsManagerDlg(QWidget* parent)
_model = new QStandardItemModel(pluginTable);

_model->setColumnCount(2);
_model->setHeaderData(0, Qt::Horizontal, "name");
_model->setHeaderData(1, Qt::Horizontal, "version");
_model->setHeaderData(0, Qt::Horizontal, "Name");
_model->setHeaderData(1, Qt::Horizontal, "Version");
pluginTable->setModel(_model);

loadPluginsFromFolder();

pluginTable->selectRow(0);

// add button
QPushButton *addButton = new QPushButton("+");
layout->addWidget(addButton, 1, 0);
Expand All @@ -47,60 +53,75 @@ PluginsManagerDlg(QWidget* parent)
QString fileName =
QFileDialog::getOpenFileName(this,
tr("Load Plugin"),
QDir::currentPath(),
QCoreApplication::applicationDirPath(),
tr("*.dll;*.so;*.dylib"));

if (!QFileInfo::exists(fileName))
return;

// Copy to the plug-in directory
QFileInfo f(fileName);
QString newPath = _pluginsFolderPath + "/" + f.fileName();
QFile::copy(fileName, newPath);

QFileInfo newFile(
QDir::cleanPath(_pluginsFolder.absolutePath() + QDir::separator() + f.fileName()));
QString const newPath = newFile.absoluteFilePath();

if (f.absoluteFilePath() == newPath)
return;

// Copy to the plug-in directory
if (!QFile::copy(f.absoluteFilePath(), newPath))
return;

PluginsManager* pluginsManager = PluginsManager::instance();
auto plugin = pluginsManager->loadPluginFromPath(newPath);
if (plugin == nullptr)
if (!plugin)
{
QFile::remove(newPath);
return;
}

QStandardItem *item = new QStandardItem(plugin->name());
item->setCheckable(true);
item->setCheckState(Qt::Unchecked);
_model->appendRow(item);

item->setData(newPath);
_model->appendRow(item);

std::shared_ptr<NodeDelegateModelRegistry> reg = pluginsManager->registry();
plugin->registerDataModels(reg);
});

// // delete button
// QPushButton *deleteButton = new QPushButton("-", this);
// layout->addWidget(deleteButton, 1, 1);
// connect(deleteButton, &QPushButton::clicked, this,
// [this]()
// {
// for (int i = 0; i < _model->rowCount(); ++i)
// {
// QStandardItem* item = _model->item(i);
// if(item->checkState() == Qt::Checked)
// {
// PluginsManager* pluginsManager = PluginsManager::instance();

// if (pluginsManager->unloadPluginFromName(item->text()))
// {
// qDebug() << item->data().toString();
// if (QFile::remove(item->data().toString()))
// {
// _model->removeRow(i);
// }
// }
// }
// }
// });
// delete button
QPushButton *deleteButton = new QPushButton("-", this);
layout->addWidget(deleteButton, 1, 1);
connect(deleteButton,
&QPushButton::clicked,
this,
[this, pluginTable]()
{
QItemSelectionModel *selectionModel = pluginTable->selectionModel();

int row = selectionModel->currentIndex().row();

while (selectionModel->selectedRows().count() > 0)
{
auto rowIdx = selectionModel->selectedRows().first();
row = std::min(row, rowIdx.row());

QStandardItem *item = _model->itemFromIndex(rowIdx);

PluginsManager *pluginsManager = PluginsManager::instance();

// FIXME: Unload plugin successfully, but cannot delete the plugin file
if (!pluginsManager->unloadPluginFromName(item->text()) ||
!QFile::remove(item->data().toString()))
{
selectionModel->select(rowIdx, QItemSelectionModel::Deselect);
continue;
}

_model->removeRow(rowIdx.row());
}

pluginTable->selectRow(row);
});
}

PluginsManagerDlg::
Expand All @@ -113,14 +134,15 @@ void
PluginsManagerDlg::
openPluginsFolder()
{
QDesktopServices::openUrl(QUrl::fromLocalFile(_pluginsFolderPath));
// QDesktopServices::openUrl(QUrl::fromLocalFile(_pluginsFolderPath));
QDesktopServices::openUrl(QUrl(_pluginsFolder.absolutePath()));
}

QString
PluginsManagerDlg::
pluginsFolderPath() const
{
return _pluginsFolderPath;
return _pluginsFolder.absolutePath();
}

void
Expand All @@ -129,20 +151,17 @@ loadPluginsFromFolder()
{
PluginsManager* pluginsManager = PluginsManager::instance();
std::shared_ptr<NodeDelegateModelRegistry> registry = pluginsManager->registry();
pluginsManager->loadPlugins(_pluginsFolderPath);
pluginsManager->loadPlugins(_pluginsFolder.absolutePath());

for(auto l : pluginsManager->loaders())
{
PluginInterface* plugin = qobject_cast<PluginInterface*>(l.second->instance());
if (plugin == nullptr)
if (!plugin)
continue;

QStandardItem *item = new QStandardItem(plugin->name());
item->setCheckable(true);
item->setCheckState(Qt::Unchecked);
_model->appendRow(item);

item->setData(l.second->fileName());
_model->appendRow(item);

plugin->registerDataModels(registry);
}
Expand Down
3 changes: 2 additions & 1 deletion examples/plugins_load/PluginsManagerDlg.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <QDir>
#include <QDialog>
#include <QStandardItemModel>

Expand Down Expand Up @@ -27,7 +28,7 @@ class PluginsManagerDlg : public QDialog
loadPluginsFromFolder();

private:
QString _pluginsFolderPath;
QDir _pluginsFolder;

QStandardItemModel* _model = nullptr;
};
37 changes: 23 additions & 14 deletions src/PluginsManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,28 +100,36 @@ loadPluginFromPath(const QString & filePath)
return nullptr;

QPluginLoader* loader = new QPluginLoader(filePath);
if (loader->load())

qDebug()<< loader->metaData();

if (loader->isLoaded())
{
PluginInterface* plugin = qobject_cast<PluginInterface*>(loader->instance());
if (plugin)
{
const QString name = plugin->name();
qDebug() << "add plugin: " << name << loader->fileName();

_loaders[name] = loader;
QPluginLoader* l = _loaders.find(plugin->name())->second;
plugin = qobject_cast<PluginInterface*>(l->instance());

return plugin;
}
else
{
delete loader;
loader = nullptr;
}
loader->unload();
delete loader;

return plugin;
}

PluginInterface* plugin = qobject_cast<PluginInterface*>(loader->instance());
if (plugin)
{
_loaders[plugin->name()] = loader;

return plugin;
}
else
{
qCritical() << "loadPlugin:" << filePath << loader->errorString();
qWarning() << loader->errorString();

delete loader;
}

return nullptr;
}

Expand Down Expand Up @@ -177,4 +185,5 @@ unloadPluginFromName(const QString &pluginName)
return false;
}


} // namespace QtNodes

0 comments on commit 8792708

Please sign in to comment.