Changed: #1193 Added the feature of enable/disable plugins on startup program.

This commit is contained in:
dnk-88 2011-09-14 01:47:27 +03:00
parent ac60393862
commit 4af62dfa63
13 changed files with 171 additions and 66 deletions

View file

@ -105,6 +105,6 @@ public:
}; //namespace ExtensionSystem }; //namespace ExtensionSystem
Q_DECLARE_INTERFACE(ExtensionSystem::IPlugin, "dev.ryzom.com.ObjectViewerQt.IPlugin/0.9.1") Q_DECLARE_INTERFACE(ExtensionSystem::IPlugin, "dev.ryzom.com.ObjectViewerQt.IPlugin/0.9.2")
#endif // IPLUGIN_H #endif // IPLUGIN_H

View file

@ -98,7 +98,7 @@ public:
{ {
QList<QObject *> all = allObjects(); QList<QObject *> all = allObjects();
QObject *result = 0; QObject *result = 0;
Q_FOREACH (QObject *qobj, all) Q_FOREACH(QObject *qobj, all)
{ {
if (qobj->objectName() == name) if (qobj->objectName() == name)
{ {

View file

@ -71,9 +71,13 @@ public:
virtual IPlugin *plugin() const = 0; virtual IPlugin *plugin() const = 0;
// state // state
virtual int getState() const = 0; virtual int state() const = 0;
virtual bool hasError() const = 0; virtual bool hasError() const = 0;
virtual QString errorString() const = 0; virtual QString errorString() const = 0;
/// Enables/disables load this plugin after restart the program
virtual void setEnabled(bool enabled) = 0;
virtual bool isEnabled() const = 0;
}; };
} // namespace ExtensionSystem } // namespace ExtensionSystem

View file

@ -34,6 +34,7 @@ CPluginManager::CPluginManager(QObject *parent)
CPluginManager::~CPluginManager() CPluginManager::~CPluginManager()
{ {
writeSettings();
stopAll(); stopAll();
deleteAll(); deleteAll();
qDeleteAll(m_pluginSpecs); qDeleteAll(m_pluginSpecs);
@ -114,6 +115,7 @@ void CPluginManager::setPluginPaths(const QStringList &paths)
{ {
m_pluginPaths = paths; m_pluginPaths = paths;
readPluginPaths(); readPluginPaths();
readSettings();
} }
QList<IPluginSpec *> CPluginManager::plugins() const QList<IPluginSpec *> CPluginManager::plugins() const
@ -133,10 +135,41 @@ QSettings *CPluginManager::settings() const
void CPluginManager::readSettings() void CPluginManager::readSettings()
{ {
if (m_settings)
{
QStringList blackList;
m_settings->beginGroup("PluginManager");
blackList = m_settings->value("BlackList").toStringList();
m_settings->endGroup();
Q_FOREACH (CPluginSpec *spec, m_pluginSpecs)
{
QString pluginName = spec->fileName();
if (blackList.contains(pluginName))
{
spec->setEnabled(false);
spec->setEnabledStartup(false);
}
}
}
} }
void CPluginManager::writeSettings() void CPluginManager::writeSettings()
{ {
if (m_settings)
{
QStringList blackList;
Q_FOREACH(CPluginSpec *spec, m_pluginSpecs)
{
nlinfo(spec->fileName().toStdString().c_str());
if (!spec->isEnabled())
blackList.push_back(spec->fileName());
}
m_settings->beginGroup("PluginManager");
m_settings->setValue("BlackList", blackList);
m_settings->endGroup();
m_settings->sync();
}
} }
void CPluginManager::readPluginPaths() void CPluginManager::readPluginPaths()
@ -176,7 +209,11 @@ void CPluginManager::readPluginPaths()
void CPluginManager::setPluginState(CPluginSpec *spec, int destState) void CPluginManager::setPluginState(CPluginSpec *spec, int destState)
{ {
if (spec->hasError() || spec->getState() != destState-1) if (spec->hasError() || spec->state() != destState-1)
return;
// plugin in black list
if (!spec->isEnabledStartup())
return; return;
switch (destState) switch (destState)
@ -198,7 +235,7 @@ void CPluginManager::setPluginState(CPluginSpec *spec, int destState)
} }
Q_FOREACH (const CPluginSpec *depSpec, spec->dependencySpecs()) Q_FOREACH (const CPluginSpec *depSpec, spec->dependencySpecs())
{ {
if (depSpec->getState() != destState) if (depSpec->state() != destState)
{ {
spec->m_hasError = true; spec->m_hasError = true;
spec->m_errorString = tr("Cannot initializing plugin because dependency failed to load: %1\nReason: %2") spec->m_errorString = tr("Cannot initializing plugin because dependency failed to load: %1\nReason: %2")
@ -251,7 +288,7 @@ bool CPluginManager::loadQueue(CPluginSpec *spec, QList<CPluginSpec *> &queue,
} }
circularityCheckQueue.append(spec); circularityCheckQueue.append(spec);
// check if we have the dependencies // check if we have the dependencies
if (spec->getState() == State::Invalid || spec->getState() == State::Read) if (spec->state() == State::Invalid || spec->state() == State::Read)
{ {
queue.append(spec); queue.append(spec);
return false; return false;

View file

@ -40,6 +40,8 @@ CPluginSpec::CPluginSpec()
m_vendor(""), m_vendor(""),
m_description(""), m_description(""),
m_state(State::Invalid), m_state(State::Invalid),
m_enabled(true),
m_enabledStartup(true),
m_hasError(false), m_hasError(false),
m_errorString(""), m_errorString(""),
m_plugin(0), m_plugin(0),
@ -82,12 +84,12 @@ QString CPluginSpec::fileName() const
return m_fileName; return m_fileName;
} }
IPlugin* CPluginSpec::plugin() const IPlugin *CPluginSpec::plugin() const
{ {
return m_plugin; return m_plugin;
} }
int CPluginSpec::getState() const int CPluginSpec::state() const
{ {
return m_state; return m_state;
} }
@ -124,6 +126,16 @@ bool CPluginSpec::setFileName(const QString &fileName)
return true; return true;
} }
void CPluginSpec::setEnabled(bool enabled)
{
m_enabled = enabled;
}
bool CPluginSpec::isEnabled() const
{
return m_enabled;
}
bool CPluginSpec::loadLibrary() bool CPluginSpec::loadLibrary()
{ {
if (m_hasError) if (m_hasError)
@ -259,6 +271,16 @@ void CPluginSpec::kill()
m_state = State::Deleted; m_state = State::Deleted;
} }
void CPluginSpec::setEnabledStartup(bool enabled)
{
m_enabledStartup = enabled;
}
bool CPluginSpec::isEnabledStartup() const
{
return m_enabledStartup;
}
bool CPluginSpec::reportError(const QString &err) bool CPluginSpec::reportError(const QString &err)
{ {
m_errorString = err; m_errorString = err;

View file

@ -41,11 +41,15 @@ public:
virtual IPlugin *plugin() const; virtual IPlugin *plugin() const;
// state // state
virtual int getState() const; virtual int state() const;
virtual bool hasError() const; virtual bool hasError() const;
virtual QString errorString() const; virtual QString errorString() const;
QList<CPluginSpec *> dependencySpecs() const; QList<CPluginSpec *> dependencySpecs() const;
/// Enables/disables load this plugin after restart the program
virtual void setEnabled(bool enabled);
virtual bool isEnabled() const;
private: private:
CPluginSpec(); CPluginSpec();
@ -57,6 +61,11 @@ private:
void stop(); void stop();
void kill(); void kill();
/// Enables/disables load this plugin on startup the program
/// Method is used for disabling startup plugin by pluginmanager
void setEnabledStartup(bool enabled);
bool isEnabledStartup() const;
bool reportError(const QString &err); bool reportError(const QString &err);
QString m_location; QString m_location;
@ -69,6 +78,7 @@ private:
QString m_description; QString m_description;
int m_state; int m_state;
bool m_enabled, m_enabledStartup;
bool m_hasError; bool m_hasError;
QString m_errorString; QString m_errorString;

View file

@ -132,7 +132,7 @@ sint main(int argc, char **argv)
QSettings::setDefaultFormat(QSettings::IniFormat); QSettings::setDefaultFormat(QSettings::IniFormat);
QSettings *settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, QSettings *settings = new QSettings(QSettings::IniFormat, QSettings::UserScope,
QLatin1String("RyzomCore"), QLatin1String(appNameC)); QLatin1String("RyzomCore"), QLatin1String(appNameC));
QTranslator translator; QTranslator translator;
QTranslator qtTranslator; QTranslator qtTranslator;
@ -162,17 +162,8 @@ sint main(int argc, char **argv)
splash->hide(); splash->hide();
const QList<ExtensionSystem::IPluginSpec *> plugins = pluginManager.plugins(); ExtensionSystem::IPluginSpec *corePlugin = pluginManager.pluginByName("Core");
ExtensionSystem::IPluginSpec *corePlugin = 0;
Q_FOREACH(ExtensionSystem::IPluginSpec *spec, plugins)
{
if (spec->name() == QLatin1String("Core"))
{
corePlugin = spec;
break;
}
}
if (!corePlugin) if (!corePlugin)
{ {
QDir absolutePluginPaths(pluginPaths.join(QLatin1String(","))); QDir absolutePluginPaths(pluginPaths.join(QLatin1String(",")));
@ -183,8 +174,8 @@ sint main(int argc, char **argv)
QString newPath = QFileDialog::getExistingDirectory(0, QCoreApplication::translate("Application", "Change the plugins path"), QDir::homePath()); QString newPath = QFileDialog::getExistingDirectory(0, QCoreApplication::translate("Application", "Change the plugins path"), QDir::homePath());
bool ok; bool ok;
QString text = QInputDialog::getText(0, QCoreApplication::translate("Application", "Enter the plugins path"), QString text = QInputDialog::getText(0, QCoreApplication::translate("Application", "Enter the plugins path"),
QCoreApplication::translate("Application", "Plugin path:"), QLineEdit::Normal, QCoreApplication::translate("Application", "Plugin path:"), QLineEdit::Normal,
newPath, &ok); newPath, &ok);
if (ok && !text.isEmpty()) if (ok && !text.isEmpty())
settings->setValue("PluginPath", text); settings->setValue("PluginPath", text);
settings->sync(); settings->sync();
@ -203,7 +194,7 @@ sint main(int argc, char **argv)
if (!errors.isEmpty()) if (!errors.isEmpty())
QMessageBox::warning(0, QCoreApplication::translate("Application", "Object Viewer Qt - Plugin loader messages"), QMessageBox::warning(0, QCoreApplication::translate("Application", "Object Viewer Qt - Plugin loader messages"),
errors.join(QString::fromLatin1("\n\n"))); errors.join(QString::fromLatin1("\n\n")));
int result = app.exec(); int result = app.exec();
return result; return result;

View file

@ -37,6 +37,8 @@
using namespace Core; using namespace Core;
CorePlugin::CorePlugin() CorePlugin::CorePlugin()
: m_plugMan(0),
m_mainWindow(0)
{ {
} }
@ -49,7 +51,8 @@ CorePlugin::~CorePlugin()
qDeleteAll(m_autoReleaseObjects); qDeleteAll(m_autoReleaseObjects);
m_autoReleaseObjects.clear(); m_autoReleaseObjects.clear();
delete m_mainWindow; if (m_mainWindow)
delete m_mainWindow;
} }
bool CorePlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) bool CorePlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString)

View file

@ -107,8 +107,8 @@ bool MainWindow::initialize(QString *errorString)
void MainWindow::extensionsInitialized() void MainWindow::extensionsInitialized()
{ {
readSettings(); readSettings();
connect(m_contextManager, SIGNAL(currentContextChanged(Core::IContext*)), connect(m_contextManager, SIGNAL(currentContextChanged(Core::IContext *)),
this, SLOT(updateContext(Core::IContext*))); this, SLOT(updateContext(Core::IContext *)));
if (m_contextManager->currentContext() != NULL) if (m_contextManager->currentContext() != NULL)
updateContext(m_contextManager->currentContext()); updateContext(m_contextManager->currentContext());
show(); show();
@ -437,7 +437,7 @@ void MainWindow::createStatusBar()
void MainWindow::createDialogs() void MainWindow::createDialogs()
{ {
m_pluginView = new ExtensionSystem::CPluginView(m_pluginManager, this); m_pluginView = new PluginView(m_pluginManager, this);
// Create undo/redo command list // Create undo/redo command list
m_dockWidget = new QDockWidget("Command List", this); m_dockWidget = new QDockWidget("Command List", this);

View file

@ -93,7 +93,7 @@ private:
void writeSettings(); void writeSettings();
ExtensionSystem::IPluginManager *m_pluginManager; ExtensionSystem::IPluginManager *m_pluginManager;
ExtensionSystem::CPluginView *m_pluginView; PluginView *m_pluginView;
MenuManager *m_menuManager; MenuManager *m_menuManager;
ContextManager *m_contextManager; ContextManager *m_contextManager;
CoreImpl *m_coreImpl; CoreImpl *m_coreImpl;

View file

@ -16,11 +16,12 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "plugin_view_dialog.h" #include "plugin_view_dialog.h"
#include "core_constants.h"
#include "nel/misc/debug.h"
// Qt includes // Qt includes
#include <QtCore/QDir> #include <QtCore/QDir>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtGui/QIcon> #include <QtGui/QIcon>
#include <QtGui/QStyle> #include <QtGui/QStyle>
#include <QtGui/QTreeWidgetItem> #include <QtGui/QTreeWidgetItem>
@ -29,45 +30,79 @@
#include "../../extension_system/iplugin_spec.h" #include "../../extension_system/iplugin_spec.h"
#include "../../extension_system/iplugin_manager.h" #include "../../extension_system/iplugin_manager.h"
namespace ExtensionSystem namespace Core
{ {
CPluginView::CPluginView(IPluginManager *pluginManager, QWidget *parent) PluginView::PluginView(ExtensionSystem::IPluginManager *pluginManager, QWidget *parent)
: QDialog(parent) : QDialog(parent),
m_checkStateColumn(0)
{ {
_ui.setupUi(this); m_ui.setupUi(this);
_pluginManager = pluginManager; m_pluginManager = pluginManager;
connect(_pluginManager, SIGNAL(pluginsChanged()), this, SLOT(updateList())); connect(m_pluginManager, SIGNAL(pluginsChanged()), this, SLOT(updateList()));
connect(this, SIGNAL(accepted()), this, SLOT(updateSettings()));
// WhiteList is list of plugins which can not disable.
m_whiteList << Constants::OVQT_CORE_PLUGIN;
updateList(); updateList();
} }
CPluginView::~CPluginView() PluginView::~PluginView()
{ {
} }
void CPluginView::updateList() void PluginView::updateList()
{ {
static QIcon okIcon = QApplication::style()->standardIcon(QStyle::SP_DialogApplyButton); static QIcon okIcon = QApplication::style()->standardIcon(QStyle::SP_DialogApplyButton);
static QIcon errorIcon = QApplication::style()->standardIcon(QStyle::SP_DialogCancelButton); static QIcon errorIcon = QApplication::style()->standardIcon(QStyle::SP_DialogCancelButton);
static QIcon notLoadedIcon = QApplication::style()->standardIcon(QStyle::SP_DialogResetButton);
m_specToItem.clear();
QList<QTreeWidgetItem *> items; QList<QTreeWidgetItem *> items;
Q_FOREACH (IPluginSpec *spec, _pluginManager->plugins()) Q_FOREACH (ExtensionSystem::IPluginSpec *spec, m_pluginManager->plugins())
{ {
QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() QTreeWidgetItem *item = new QTreeWidgetItem(QStringList()
<< ""
<< spec->name() << spec->name()
<< QString("%1").arg(spec->version()) << QString("%1").arg(spec->version())
<< spec->vendor() << spec->vendor()
<< QDir::toNativeSeparators(spec->filePath())); << QDir::toNativeSeparators(spec->filePath()));
item->setIcon(0, spec->hasError() ? errorIcon : okIcon);
bool ok = !spec->hasError();
QIcon icon = ok ? okIcon : errorIcon;
if (ok && (spec->state() != ExtensionSystem::State::Running))
icon = notLoadedIcon;
item->setIcon(m_checkStateColumn, icon);
if (!m_whiteList.contains(spec->name()))
item->setCheckState(m_checkStateColumn, spec->isEnabled() ? Qt::Checked : Qt::Unchecked);
items.append(item); items.append(item);
m_specToItem.insert(spec, item);
} }
_ui.pluginTreeWidget->clear(); m_ui.pluginTreeWidget->clear();
if (!items.isEmpty()) if (!items.isEmpty())
_ui.pluginTreeWidget->addTopLevelItems(items); m_ui.pluginTreeWidget->addTopLevelItems(items);
m_ui.pluginTreeWidget->resizeColumnToContents(m_checkStateColumn);
} }
} /* namespace NLQT */ void PluginView::updateSettings()
{
Q_FOREACH (ExtensionSystem::IPluginSpec *spec, m_pluginManager->plugins())
{
if (m_specToItem.contains(spec) && (!m_whiteList.contains(spec->name())))
{
QTreeWidgetItem *item = m_specToItem.value(spec);
if (item->checkState(m_checkStateColumn) == Qt::Checked)
spec->setEnabled(true);
else
spec->setEnabled(false);
}
}
}
} /* namespace Core */

View file

@ -20,28 +20,39 @@
#include "ui_plugin_view_dialog.h" #include "ui_plugin_view_dialog.h"
#include <QtCore/QMap>
#include <QtCore/QStringList>
namespace ExtensionSystem namespace ExtensionSystem
{ {
class IPluginManager; class IPluginManager;
class IPluginSpec;
}
class CPluginView: public QDialog namespace Core
{
class PluginView: public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
CPluginView(IPluginManager *pluginManager, QWidget *parent = 0); PluginView(ExtensionSystem::IPluginManager *pluginManager, QWidget *parent = 0);
~CPluginView(); ~PluginView();
private Q_SLOTS: private Q_SLOTS:
void updateList(); void updateList();
void updateSettings();
private: private:
IPluginManager *_pluginManager; const int m_checkStateColumn;
Ui::CPluginView _ui; QMap<ExtensionSystem::IPluginSpec *, QTreeWidgetItem *> m_specToItem;
}; /* class CPluginView */ QStringList m_whiteList;
ExtensionSystem::IPluginManager *m_pluginManager;
Ui::PluginView m_ui;
}; /* class PluginView */
} /* namespace NLQT */ } /* namespace Core */
#endif // PLUGIN_VIEW_H #endif // PLUGIN_VIEW_H

View file

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>CPluginView</class> <class>PluginView</class>
<widget class="QDialog" name="CPluginView"> <widget class="QDialog" name="PluginView">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>691</width> <width>756</width>
<height>249</height> <height>296</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -37,14 +37,6 @@
<property name="sortingEnabled"> <property name="sortingEnabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
<attribute name="headerDefaultSectionSize">
<number>100</number>
</attribute>
<column>
<property name="text">
<string>State</string>
</property>
</column>
<column> <column>
<property name="text"> <property name="text">
<string>Name</string> <string>Name</string>
@ -126,7 +118,7 @@
<connection> <connection>
<sender>closePushButton</sender> <sender>closePushButton</sender>
<signal>clicked()</signal> <signal>clicked()</signal>
<receiver>CPluginView</receiver> <receiver>PluginView</receiver>
<slot>accept()</slot> <slot>accept()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">