From daacd01a7e34d54231a3708365c1d5cc9333c63e Mon Sep 17 00:00:00 2001 From: Joseph Mirabel <jmirabel@laas.fr> Date: Wed, 16 May 2018 10:38:13 +0200 Subject: [PATCH] Improve plugin manager dialog. --- .../gepetto/gui/dialog/pluginmanagerdialog.hh | 11 +- include/gepetto/gui/settings.hh | 2 +- include/gepetto/gui/ui/pluginmanagerdialog.ui | 51 ++++++-- src/gui/dialog/pluginmanagerdialog.cc | 118 ++++++++++++------ src/gui/settings.cc | 6 +- 5 files changed, 137 insertions(+), 51 deletions(-) diff --git a/include/gepetto/gui/dialog/pluginmanagerdialog.hh b/include/gepetto/gui/dialog/pluginmanagerdialog.hh index 0047454..fb5cf22 100644 --- a/include/gepetto/gui/dialog/pluginmanagerdialog.hh +++ b/include/gepetto/gui/dialog/pluginmanagerdialog.hh @@ -45,8 +45,6 @@ namespace gepetto { return plugins_; } - bool add (const QString& name, QWidget* parent = NULL, bool load = false); - template <typename Interface> Interface* getFirstOf (); template <typename Interface> QList <Interface*> get (); @@ -57,6 +55,12 @@ namespace gepetto { static void addPluginDir (const QString& path); + void declareAllPlugins (QWidget* parent = NULL); + + bool declarePlugin (const QString& name, QWidget* parent = NULL); + + bool loadPlugin (const QString& name); + bool initPlugin (const QString& name); bool unloadPlugin (const QString& name); @@ -83,8 +87,10 @@ namespace gepetto { void onItemChanged (QTableWidgetItem* current, QTableWidgetItem* previous); void contextMenu(const QPoint& pos); + void declareAll (); void load (const QString& name); void unload (const QString& name); + void save (); private: static const int P_NAME; @@ -97,7 +103,6 @@ namespace gepetto { ::Ui::PluginManagerDialog *ui_; PluginManager* pm_; - QSignalMapper signalMapper_; }; template <typename Interface> diff --git a/include/gepetto/gui/settings.hh b/include/gepetto/gui/settings.hh index ac69ec2..8b9d0e4 100644 --- a/include/gepetto/gui/settings.hh +++ b/include/gepetto/gui/settings.hh @@ -116,11 +116,11 @@ namespace gepetto { void restoreState () const; void restoreDockWidgetsState () const; - private: void writeRobotFile (); void writeEnvFile (); void writeSettingFile (); + private: void addRobotFromString (const std::string& rbtStr); void addEnvFromString (const std::string& envStr); void addPlugin (const QString& plg, bool init); diff --git a/include/gepetto/gui/ui/pluginmanagerdialog.ui b/include/gepetto/gui/ui/pluginmanagerdialog.ui index 028091d..a768dbc 100644 --- a/include/gepetto/gui/ui/pluginmanagerdialog.ui +++ b/include/gepetto/gui/ui/pluginmanagerdialog.ui @@ -46,6 +46,47 @@ </column> </widget> </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QPushButton" name="declareAllPluginsButton"> + <property name="text"> + <string>Find &all plugins</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="saveButton"> + <property name="text"> + <string>&Save</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QDialogButtonBox" name="pluginManagerButtonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </item> <item> <widget class="QLabel" name="pluginMessage"> <property name="text"> @@ -53,16 +94,6 @@ </property> </widget> </item> - <item> - <widget class="QDialogButtonBox" name="pluginManagerButtonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> </layout> </widget> <resources/> diff --git a/src/gui/dialog/pluginmanagerdialog.cc b/src/gui/dialog/pluginmanagerdialog.cc index db5c688..9d9d688 100644 --- a/src/gui/dialog/pluginmanagerdialog.cc +++ b/src/gui/dialog/pluginmanagerdialog.cc @@ -21,6 +21,7 @@ #include <QMenu> #include "gepetto/gui/plugin-interface.hh" +#include "gepetto/gui/mainwindow.hh" #include <iostream> @@ -28,28 +29,6 @@ namespace gepetto { namespace gui { QList <QDir> PluginManager::pluginDirs_; - bool PluginManager::add(const QString &name, QWidget *parent, bool init) - { - if (!plugins_.contains(name)) { - QString filename = name; - if (!QDir::isAbsolutePath(name)) { - foreach (QDir dir, pluginDirs_) { - if (dir.exists(name)) { - filename = dir.absoluteFilePath(name); - break; - } - } - } - plugins_[name] = new QPluginLoader (filename, parent); - } - if (!plugins_[name]->load()) { - qDebug() << name << ": " << plugins_[name]->errorString(); - return false; - } - if (init) return initPlugin(name); - return false; - } - QIcon PluginManager::icon(const QPluginLoader *pl) { if (pl->isLoaded()) { @@ -57,6 +36,7 @@ namespace gepetto { if (pi && pi->isInit ()) { return QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation); } + return QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning); } return QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical); } @@ -86,18 +66,69 @@ namespace gepetto { } } - bool PluginManager::initPlugin(const QString &name) + void PluginManager::declareAllPlugins (QWidget *parent) { - if (!plugins_[name]->isLoaded()) { + foreach (const QDir& dir, pluginDirs_) { + qDebug() << "Looking for plugins into" << dir.absolutePath(); + QStringList soFiles = dir.entryList(QStringList() << "*.so", QDir::Files); + foreach (const QString& soFile, soFiles) { + qDebug() << "Found" << soFile; + if (!plugins_.contains(soFile)) { + plugins_[soFile] = new QPluginLoader (dir.absoluteFilePath(soFile), parent); + } + } + } + } + + bool PluginManager::declarePlugin(const QString &name, QWidget *parent) + { + if (!plugins_.contains(name)) { + QString filename = name; + if (!QDir::isAbsolutePath(name)) { + foreach (QDir dir, pluginDirs_) { + if (dir.exists(name)) { + filename = dir.absoluteFilePath(name); + break; + } + } + } + plugins_[name] = new QPluginLoader (filename, parent); + return true; + } + qDebug () << "Plugin" << name << "already declared."; + return false; + } + + bool PluginManager::loadPlugin(const QString &name) + { + if (!plugins_.contains(name)) { + qDebug () << "Plugin" << name << "not declared."; + return false; + } + if (!plugins_[name]->load()) { qDebug() << name << ": " << plugins_[name]->errorString(); return false; } - PluginInterface* pi = qobject_cast <PluginInterface*> (plugins_[name]->instance()); + return true; + } + + bool PluginManager::initPlugin(const QString &name) + { + if (!plugins_.contains(name)) { + qDebug () << "Plugin" << name << "not declared."; + return false; + } + QPluginLoader* p = plugins_[name]; + if (!p->isLoaded()) { + qDebug () << "Plugin" << name << "not loaded:" << p->errorString(); + return false; + } + PluginInterface* pi = qobject_cast <PluginInterface*> (p->instance()); if (!pi) { qDebug() << name << ": Wrong interface."; return false; } - pi->doInit(); + if (!pi->isInit()) pi->doInit(); return pi->isInit (); } @@ -125,9 +156,13 @@ namespace gepetto { ui_->pluginList->setColumnHidden(P_FILE, true); connect(ui_->pluginList, SIGNAL (currentItemChanged (QTableWidgetItem*,QTableWidgetItem*)), - this, SLOT (onItemChanged(QTableWidgetItem*,QTableWidgetItem*))); + SLOT (onItemChanged(QTableWidgetItem*,QTableWidgetItem*))); connect(ui_->pluginList, SIGNAL(customContextMenuRequested(QPoint)), - this, SLOT(contextMenu(QPoint))); + SLOT(contextMenu(QPoint))); + connect(ui_->declareAllPluginsButton, SIGNAL(clicked()), + SLOT(declareAll())); + connect(ui_->saveButton, SIGNAL(clicked()), + SLOT(save())); } PluginManagerDialog::~PluginManagerDialog() @@ -150,21 +185,29 @@ namespace gepetto { if (row == -1) return; QString key = ui_->pluginList->item(row, P_FILE)->text(); QMenu contextMenu (tr("Plugin"), ui_->pluginList); + QSignalMapper sm; if (pm_->plugins()[key]->isLoaded()) { - QAction* unload = contextMenu.addAction("&Unload", &signalMapper_, SLOT(map())); - signalMapper_.setMapping (unload, key); - connect(&signalMapper_, SIGNAL (mapped(QString)), this, SLOT(unload(QString))); + QAction* unload = contextMenu.addAction("&Unload", &sm, SLOT(map())); + sm.setMapping (unload, key); + connect(&sm, SIGNAL (mapped(QString)), this, SLOT(unload(QString))); contextMenu.exec(ui_->pluginList->mapToGlobal(pos)); } else { - QAction* load = contextMenu.addAction("&Load", &signalMapper_, SLOT(map())); - signalMapper_.setMapping (load, key); - connect(&signalMapper_, SIGNAL (mapped(QString)), this, SLOT(load(QString))); + QAction* load = contextMenu.addAction("&Load", &sm, SLOT(map())); + sm.setMapping (load, key); + connect(&sm, SIGNAL (mapped(QString)), this, SLOT(load(QString))); contextMenu.exec(ui_->pluginList->mapToGlobal(pos)); } } + void PluginManagerDialog::declareAll() + { + pm_->declareAllPlugins(); + updateList(); + } + void PluginManagerDialog::load(const QString &name) { + pm_->loadPlugin(name); pm_->initPlugin(name); updateList (); } @@ -175,6 +218,11 @@ namespace gepetto { updateList (); } + void PluginManagerDialog::save () + { + MainWindow::instance()->settings_->writeSettingFile(); + } + const int PluginManagerDialog::P_NAME = 0; const int PluginManagerDialog::P_FILE = 1; const int PluginManagerDialog::P_VERSION = 2; @@ -186,7 +234,7 @@ namespace gepetto { ui_->pluginList->removeRow(0); for (PluginManager::Map::const_iterator p = pm_->plugins ().constBegin(); p != pm_->plugins().constEnd(); p++) { - QString name = p.value()->fileName(), + QString name = p.key(), filename = p.key(), fullpath = p.value()->fileName(), version = ""; diff --git a/src/gui/settings.cc b/src/gui/settings.cc index 0a752bd..6ccec95 100644 --- a/src/gui/settings.cc +++ b/src/gui/settings.cc @@ -175,8 +175,10 @@ namespace gepetto { void Settings::initPlugins() { - foreach (QString name, pluginsToInit_) + foreach (QString name, pluginsToInit_) { + pluginManager_.loadPlugin (name); pluginManager_.initPlugin (name); + } #if GEPETTO_GUI_HAS_PYTHONQT PythonWidget* pw = mw->pythonWidget(); foreach (QString name, pyplugins_) { @@ -471,7 +473,7 @@ namespace gepetto { void Settings::addPlugin (const QString& plg, bool init) { if (init) pluginsToInit_.append (plg); - pluginManager_.add(plg, 0, false); + pluginManager_.declarePlugin (plg); } void Settings::addPyPlugin (const QString& plg, bool init) -- GitLab