1
/***************************************************************************
2
pluginmanager.cpp - description
4
begin : Mon Apr 28 2003
5
copyright : (C) 2003 by Martin Witte
6
email : witte@kawo1.rwth-aachen.de
7
***************************************************************************/
9
/***************************************************************************
11
* This program is free software; you can redistribute it and/or modify *
12
* it under the terms of the GNU General Public License as published by *
13
* the Free Software Foundation; either version 2 of the License, or *
14
* (at your option) any later version. *
16
***************************************************************************/
19
#include "pluginmanager.h"
20
#include "pluginmanager-configuration.h"
21
#include "plugin_configuration_dialog.h"
22
#include "kradioapp.h"
24
#include <kiconloader.h>
25
#include <kdialogbase.h>
28
#include <kprogress.h>
32
#include <qmenudata.h>
34
#include "debug-profiler.h"
36
PluginManager::PluginManager(
39
const QString &configDialogTitle,
40
const QString &aboutDialogTitle)
43
m_showProgressBar(true),
44
m_configDialog (NULL),
45
m_pluginManagerConfiguration(NULL),
47
m_configDialogTitle(configDialogTitle),
48
m_aboutDialogTitle (aboutDialogTitle)
53
PluginManager::~PluginManager()
55
delete m_pluginManagerConfiguration;
56
m_pluginManagerConfiguration = NULL;
58
// config Dialog must be deleted first, so we can clear m_configPages
59
// without problems (this is the only place where our config dialog is deleted)
60
// Without clearing this list, those pages would be deleted, but
61
// we would try to delete them another time when the associated plugin is
62
// deleted, because m_configPages is out of date.
64
m_configDialog->cancel();
65
delete m_configDialog;
67
m_configPages.clear();
68
m_configPageFrames.clear();
69
m_configDialog = NULL;
74
m_aboutPageFrames.clear();
77
while (PluginBase *p = m_plugins.getFirst()) {
83
void PluginManager::noticeLibrariesChanged()
85
if (m_pluginManagerConfiguration)
86
m_pluginManagerConfiguration->noticePluginLibrariesChanged();
90
void PluginManager::unloadPlugins(const QString &class_name)
92
PluginList plugins = m_plugins;
93
for (PluginIterator it(plugins); it.current(); ++it) {
94
PluginBase *p = it.current();
95
if (p->pluginClassName() == class_name) {
102
void PluginManager::addWidgetPluginMenuItems(QMenuData *menu, QMap<WidgetPluginBase *,int> &map) const
106
for (PluginIterator it(m_plugins); it.current(); ++it) {
107
WidgetPluginBase *b = dynamic_cast<WidgetPluginBase*>(it.current());
110
int id = menu->insertItem("dummy", b->getWidget(), SLOT(toggleShown()));
112
updateWidgetPluginMenuItem(b, menu, map, b->isReallyVisible());
117
void PluginManager::updateWidgetPluginMenuItem(WidgetPluginBase *b, QMenuData *menu, QMap<WidgetPluginBase *,int> &map, bool shown) const
119
if (!b || !map.contains(b))
122
const QString &name = b->description();
123
QString text = (shown ? i18n("Hide %1") : i18n("Show %1")).arg(name);
125
menu->changeItem(map[b],
126
QIconSet(SmallIconSet(!shown ? "kradio_show" : "kradio_hide")),
131
void PluginManager::noticeWidgetPluginShown(WidgetPluginBase *p, bool shown)
133
for (PluginIterator it(m_plugins); it.current(); ++it) {
134
it.current()->noticeWidgetPluginShown(p, shown);
139
PluginBase *PluginManager::getPluginByName(const QString &name) const
141
for (PluginIterator it(m_plugins); it.current(); ++it) {
142
if (it.current()->name() == name)
149
void PluginManager::insertPlugin(PluginBase *p)
151
BlockProfiler profiler("PluginManager::insertPlugin");
154
BlockProfiler profiler_cfg("PluginManager::insertPlugin - about/config");
156
/*kdDebug() << QDateTime::currentDateTime().toString(Qt::ISODate)
157
<< " Debug: Adding Plugin: " << p->name() << "\n";*/
160
createConfigDialog(m_configDialogTitle);
162
createAboutDialog(m_aboutDialogTitle);
167
addConfigurationPage (p, p->createConfigurationPage());
168
addAboutPage (p, p->createAboutPage());
171
BlockProfiler profiler_connect("PluginManager::insertPlugin - connect");
173
// connect plugins with each other
174
for (PluginIterator it(m_plugins); it.current(); ++it) {
175
if (it.current() != p) {
176
/*kdDebug() << QDateTime::currentDateTime().toString(Qt::ISODate)
177
<< " Debug: connecting with " << it.current()->name() << "\n";*/
178
p->connectI(it.current());
182
// perhaps some existing config pages will profit from new plugin
183
// example: timecontrol profits from radio plugin
184
for (QWidgetDictIterator it(m_configPages); it.current(); ++it) {
185
Interface *i = dynamic_cast<Interface *>(it.current());
190
profiler_connect.stop();
191
BlockProfiler profiler_widget("PluginManager::insertPlugin - notifywidgets");
193
WidgetPluginBase *w1 = dynamic_cast<WidgetPluginBase*>(p);
194
for (PluginIterator it(m_plugins); it.current(); ++it) {
195
it.current()->noticePluginsChanged(m_plugins);
197
it.current()->noticeWidgetPluginShown(w1, w1->isReallyVisible());
199
WidgetPluginBase *w2 = dynamic_cast<WidgetPluginBase*>(it.current());
201
p->noticeWidgetPluginShown(w2, w2->isReallyVisible());
204
if (m_pluginManagerConfiguration)
205
m_pluginManagerConfiguration->noticePluginsChanged();
207
profiler_widget.stop();
212
void PluginManager::deletePlugin(PluginBase *p)
214
if (p && m_plugins.contains(p)) {
221
void PluginManager::removePlugin(PluginBase *p)
223
if (p && m_plugins.contains(p)) {
225
for (PluginIterator it(m_plugins); it.current(); ++it) {
226
if (it.current() != p) {
227
// workaround for buggy compilers/libstdc++
228
if (p->destructorCalled()) {
229
p->PluginBase::disconnectI(it.current());
231
p->disconnectI(it.current());
236
// remove config page from config dialog, only chance is to delete it
237
// plugin will be notified automatically (mechanism implemented by
239
while (QFrame *f = m_configPageFrames.find(p)) {
240
m_configPageFrames.remove(p);
241
m_configPages.remove(p);
244
while (QFrame *f = m_aboutPageFrames.find(p)) {
245
m_aboutPageFrames.remove(p);
246
m_aboutPages.remove(p);
250
// remove bindings between me and plugin
254
p->noticePluginsChanged(PluginList());
255
for (PluginIterator it(m_plugins); it.current(); ++it) {
256
it.current()->noticePluginsChanged(m_plugins);
259
if (m_pluginManagerConfiguration)
260
m_pluginManagerConfiguration->noticePluginsChanged();
265
void PluginManager::addConfigurationPage (PluginBase *forWhom,
266
const ConfigPageInfo &info)
268
if (!forWhom || !m_plugins.containsRef(forWhom) || !info.page)
270
QFrame *f = addConfigurationPage(info);
272
// register this frame and config page
273
m_configPageFrames.insert(forWhom, f);
274
m_configPages.insert(forWhom, info.page);
276
// perhaps new config page profits from existing plugins
277
// example: timecontrol profits from radio plugin
278
Interface *i = dynamic_cast<Interface *>(info.page);
280
for (PluginIterator it(m_plugins); it.current(); ++it)
281
i->connectI(it.current());
286
QFrame *PluginManager::addConfigurationPage (const ConfigPageInfo &info)
289
createConfigDialog(i18n(m_configDialogTitle.ascii()));
291
// create empty config frame
292
QFrame *f = m_configDialog->addPage(
295
KGlobal::instance()->iconLoader()->loadIcon( info.iconName, KIcon::NoGroup, KIcon::SizeMedium )
298
// fill config frame with layout ...
299
QGridLayout *l = new QGridLayout(f);
303
// ... and externally created config page
304
info.page->reparent (f, QPoint(0,0), true);
305
l->addWidget( info.page, 0, 0 );
307
// make sure, that config page receives ok, apply and cancel signals
308
QObject::connect(this, SIGNAL(sigConfigOK()), info.page, SLOT(slotOK()));
309
QObject::connect(m_configDialog, SIGNAL(cancelClicked()), info.page, SLOT(slotCancel()));
315
void PluginManager::createConfigDialog(const QString &title)
317
if (m_configDialog) delete m_configDialog;
318
m_configDialog = NULL;
320
PluginConfigurationDialog *cfg = new PluginConfigurationDialog(
321
KDialogBase::IconList,
323
KDialogBase::Apply|KDialogBase::Ok|KDialogBase::Cancel,
330
m_configDialog = cfg;
332
QObject::connect(m_configDialog, SIGNAL(okClicked()), this, SLOT(slotConfigOK()));
333
QObject::connect(m_configDialog, SIGNAL(applyClicked()), this, SLOT(slotConfigOK()));
337
addConfigurationPage(createOwnConfigurationPage());
339
for (PluginIterator i(m_plugins); m_configDialog && i.current(); ++i) {
340
addConfigurationPage(i.current(),
341
i.current()->createConfigurationPage());
346
ConfigPageInfo PluginManager::createOwnConfigurationPage()
348
m_pluginManagerConfiguration = new PluginManagerConfiguration(NULL, m_Application, this);
349
return ConfigPageInfo (m_pluginManagerConfiguration,
351
i18n("Plugin Library Configuration"),
359
void PluginManager::addAboutPage (PluginBase *forWhom,
360
const AboutPageInfo &info)
363
createAboutDialog(i18n(m_aboutDialogTitle.ascii()));
365
if ( !forWhom || !m_plugins.containsRef(forWhom)
366
|| !m_aboutDialog || !info.page)
370
// create empty about frame
371
QFrame *f = m_aboutDialog->addPage(
374
KGlobal::instance()->iconLoader()->loadIcon( info.iconName, KIcon::NoGroup, KIcon::SizeMedium )
377
// register this frame and config page
378
m_aboutPageFrames.insert(forWhom, f);
379
m_aboutPages.insert(forWhom, info.page);
381
// fill config frame with layout ...
382
QGridLayout *l = new QGridLayout(f);
386
// ... and externally created config page
387
info.page->reparent (f, QPoint(0,0), true);
388
l->addWidget( info.page, 0, 0 );
392
void PluginManager::createAboutDialog(const QString &title)
394
if (m_aboutDialog) delete m_aboutDialog;
395
m_aboutDialog = NULL;
397
m_aboutDialog = new KDialogBase(KDialogBase::IconList,
406
for (PluginIterator i(m_plugins); m_aboutDialog && i.current(); ++i) {
407
addAboutPage(i.current(),
408
i.current()->createAboutPage());
413
void PluginManager::saveState (KConfig *c) const
415
c->setGroup("PluginManager-" + m_Name);
416
c->writeEntry("show-progress-bar", m_showProgressBar);
418
for (PluginIterator it(m_plugins); it.current(); ++it) {
419
QString class_name = it.current()->pluginClassName();
420
QString object_name = it.current()->name();
421
if (class_name.length() && object_name.length() &&
422
m_Application->getPluginClasses().contains(class_name))
425
c->writeEntry("plugin_class_" + QString::number(n), class_name);
426
c->writeEntry("plugin_name_" + QString::number(n), object_name);
429
c->writeEntry("plugins", n);
431
for (PluginIterator i(m_plugins); i.current(); ++i) {
432
i.current()->saveState(c);
437
void PluginManager::restoreState (KConfig *c)
439
BlockProfiler profile_all("PluginManager::restoreState");
440
c->setGroup("PluginManager-" + m_Name);
441
m_showProgressBar = c->readBoolEntry("show-progress-bar", true);
442
int n = c->readNumEntry("plugins", 0);
444
KProgressDialog *progress = NULL;
445
if (m_showProgressBar) {
446
progress = new KProgressDialog(NULL, NULL, i18n("Starting Plugins"));
447
progress->setMinimumWidth(400);
448
progress->setAllowCancel(false);
450
progress->progressBar()->setTotalSteps(2*n);
453
for (int i = 1; i <= n; ++i) {
454
c->setGroup("PluginManager-" + m_Name);
455
QString class_name = c->readEntry("plugin_class_" + QString::number(i));
456
QString object_name = c->readEntry("plugin_name_" + QString::number(i));
458
if (m_showProgressBar)
459
progress->QWidget::setCaption(i18n("Creating Plugin ") + class_name);
460
if (class_name.length() && object_name.length())
461
m_Application->CreatePlugin(this, class_name, object_name);
462
if (m_showProgressBar)
463
progress->progressBar()->setProgress(i);
466
if (m_Application && n == 0) {
467
const QMap<QString, PluginClassInfo> &classes = m_Application->getPluginClasses();
468
QMapConstIterator<QString, PluginClassInfo> end = classes.end();
470
if (m_showProgressBar)
471
progress->progressBar()->setTotalSteps(2*n);
473
for (QMapConstIterator<QString, PluginClassInfo> it=classes.begin(); it != end; ++it, ++idx) {
474
const PluginClassInfo &cls = *it;
475
if (m_showProgressBar)
476
progress->QWidget::setCaption(i18n("Creating Plugin ") + cls.class_name);
477
m_Application->CreatePlugin(this, cls.class_name, m_Name + "-" + cls.class_name);
478
if (m_showProgressBar)
479
progress->progressBar()->setProgress(idx);
481
m_configDialog->show();
484
BlockProfiler profile_plugins("PluginManager::restoreState - plugins");
487
for (PluginIterator i(m_plugins); i.current(); ++i, ++idx) {
488
BlockProfiler profile_plugin("PluginManager::restoreState - " + i.current()->pluginClassName());
489
if (m_showProgressBar)
490
progress->QWidget::setCaption("Initializing Plugin " + i.current()->pluginClassName());
491
i.current()->restoreState(c);
492
if (m_showProgressBar)
493
progress->progressBar()->setProgress(idx+1);
495
if (m_showProgressBar)
499
PluginConfigurationDialog *PluginManager::getConfigDialog()
502
createConfigDialog(m_configDialogTitle);
503
return m_configDialog;
506
KDialogBase *PluginManager::getAboutDialog()
510
return m_aboutDialog;
515
void PluginManager::slotConfigOK()
519
m_Application->saveState(KGlobal::config());
523
void PluginManager::startPlugins()
525
for (PluginIterator i(m_plugins); i.current(); ++i) {
526
i.current()->startPlugin();
530
void PluginManager::aboutToQuit()
532
for (PluginIterator i(m_plugins); i.current(); ++i) {
533
i.current()->aboutToQuit();
538
#include "pluginmanager.moc"