diff --git a/examples/plugins_load/PluginsManagerDlg.cpp b/examples/plugins_load/PluginsManagerDlg.cpp index 2d35a902f..e48323a0d 100644 --- a/examples/plugins_load/PluginsManagerDlg.cpp +++ b/examples/plugins_load/PluginsManagerDlg.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -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); @@ -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); @@ -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 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:: @@ -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 @@ -129,20 +151,17 @@ loadPluginsFromFolder() { PluginsManager* pluginsManager = PluginsManager::instance(); std::shared_ptr registry = pluginsManager->registry(); - pluginsManager->loadPlugins(_pluginsFolderPath); + pluginsManager->loadPlugins(_pluginsFolder.absolutePath()); for(auto l : pluginsManager->loaders()) { PluginInterface* plugin = qobject_cast(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); } diff --git a/examples/plugins_load/PluginsManagerDlg.hpp b/examples/plugins_load/PluginsManagerDlg.hpp index c5ed81a0e..d0ead0019 100644 --- a/examples/plugins_load/PluginsManagerDlg.hpp +++ b/examples/plugins_load/PluginsManagerDlg.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -27,7 +28,7 @@ class PluginsManagerDlg : public QDialog loadPluginsFromFolder(); private: - QString _pluginsFolderPath; + QDir _pluginsFolder; QStandardItemModel* _model = nullptr; }; diff --git a/src/PluginsManager.cpp b/src/PluginsManager.cpp index 09063a3b8..a0329228d 100644 --- a/src/PluginsManager.cpp +++ b/src/PluginsManager.cpp @@ -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(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(l->instance()); - return plugin; - } - else - { - delete loader; - loader = nullptr; - } + loader->unload(); + delete loader; + + return plugin; + } + + PluginInterface* plugin = qobject_cast(loader->instance()); + if (plugin) + { + _loaders[plugin->name()] = loader; + + return plugin; } else { - qCritical() << "loadPlugin:" << filePath << loader->errorString(); + qWarning() << loader->errorString(); + + delete loader; } + return nullptr; } @@ -177,4 +185,5 @@ unloadPluginFromName(const QString &pluginName) return false; } + } // namespace QtNodes