~ubuntu-branches/ubuntu/utopic/kradio/utopic

« back to all changes in this revision

Viewing changes to kradio3/src/libkradio/pluginmanager.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Marc 'HE' Brockschmidt
  • Date: 2008-03-16 19:00:02 UTC
  • mfrom: (3.1.2 gutsy)
  • Revision ID: james.westby@ubuntu.com-20080316190002-sdjqu8cahhx7c6tk
Tags: 0.1.1.1~20061112-3.1
* Non-maintainer upload.
* Fix gcc-4.3 FTBFS, patch by Kibi (Closes: #455390)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
                          pluginmanager.cpp  -  description
3
 
                             -------------------
4
 
    begin                : Mon Apr 28 2003
5
 
    copyright            : (C) 2003 by Martin Witte
6
 
    email                : witte@kawo1.rwth-aachen.de
7
 
 ***************************************************************************/
8
 
 
9
 
/***************************************************************************
10
 
 *                                                                         *
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.                                   *
15
 
 *                                                                         *
16
 
 ***************************************************************************/
17
 
 
18
 
#include "plugins.h"
19
 
#include "pluginmanager.h"
20
 
#include "pluginmanager-configuration.h"
21
 
#include "plugin_configuration_dialog.h"
22
 
#include "kradioapp.h"
23
 
 
24
 
#include <kiconloader.h>
25
 
#include <kdialogbase.h>
26
 
#include <klocale.h>
27
 
#include <kconfig.h>
28
 
#include <kprogress.h>
29
 
 
30
 
#include <qlayout.h>
31
 
#include <qframe.h>
32
 
#include <qmenudata.h>
33
 
 
34
 
#include "debug-profiler.h"
35
 
 
36
 
PluginManager::PluginManager(
37
 
    const QString &name,
38
 
    KRadioApp     *app,
39
 
    const QString &configDialogTitle,
40
 
    const QString &aboutDialogTitle)
41
 
 : m_Name(name),
42
 
   m_Application(app),
43
 
   m_showProgressBar(true),
44
 
   m_configDialog (NULL),
45
 
   m_pluginManagerConfiguration(NULL),
46
 
   m_aboutDialog(NULL),
47
 
   m_configDialogTitle(configDialogTitle),
48
 
   m_aboutDialogTitle (aboutDialogTitle)
49
 
{
50
 
}
51
 
 
52
 
 
53
 
PluginManager::~PluginManager()
54
 
{
55
 
    delete m_pluginManagerConfiguration;
56
 
    m_pluginManagerConfiguration = NULL;
57
 
 
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.
63
 
    if (m_configDialog) {
64
 
        m_configDialog->cancel();
65
 
        delete m_configDialog;
66
 
    }
67
 
    m_configPages.clear();
68
 
    m_configPageFrames.clear();
69
 
    m_configDialog = NULL;
70
 
 
71
 
    if (m_aboutDialog)
72
 
        delete m_aboutDialog;
73
 
    m_aboutPages.clear();
74
 
    m_aboutPageFrames.clear();
75
 
    m_aboutDialog = NULL;
76
 
 
77
 
    while (PluginBase *p = m_plugins.getFirst()) {
78
 
        deletePlugin(p);
79
 
    }
80
 
}
81
 
 
82
 
 
83
 
void PluginManager::noticeLibrariesChanged()
84
 
{
85
 
    if (m_pluginManagerConfiguration)
86
 
        m_pluginManagerConfiguration->noticePluginLibrariesChanged();
87
 
}
88
 
 
89
 
 
90
 
void PluginManager::unloadPlugins(const QString &class_name)
91
 
{
92
 
    PluginList plugins = m_plugins;
93
 
    for (PluginIterator it(plugins); it.current(); ++it) {
94
 
        PluginBase *p = it.current();
95
 
        if (p->pluginClassName() == class_name) {
96
 
            deletePlugin(p);
97
 
        }
98
 
    }
99
 
}
100
 
 
101
 
 
102
 
void PluginManager::addWidgetPluginMenuItems(QMenuData *menu, QMap<WidgetPluginBase *,int> &map) const
103
 
{
104
 
    map.clear();
105
 
 
106
 
    for (PluginIterator it(m_plugins); it.current(); ++it) {
107
 
        WidgetPluginBase *b = dynamic_cast<WidgetPluginBase*>(it.current());
108
 
        if (!b) continue;
109
 
 
110
 
        int id = menu->insertItem("dummy", b->getWidget(), SLOT(toggleShown()));
111
 
        map.insert(b, id);
112
 
        updateWidgetPluginMenuItem(b, menu, map, b->isReallyVisible());
113
 
    }
114
 
}
115
 
 
116
 
 
117
 
void PluginManager::updateWidgetPluginMenuItem(WidgetPluginBase *b, QMenuData *menu, QMap<WidgetPluginBase *,int> &map, bool shown) const
118
 
{
119
 
    if (!b || !map.contains(b))
120
 
        return;
121
 
 
122
 
    const QString &name = b->description();
123
 
    QString text = (shown ? i18n("Hide %1") : i18n("Show %1")).arg(name);
124
 
 
125
 
    menu->changeItem(map[b],
126
 
                     QIconSet(SmallIconSet(!shown ? "kradio_show" : "kradio_hide")),
127
 
                     text);
128
 
}
129
 
 
130
 
 
131
 
void PluginManager::noticeWidgetPluginShown(WidgetPluginBase *p, bool shown)
132
 
{
133
 
    for (PluginIterator it(m_plugins); it.current(); ++it) {
134
 
        it.current()->noticeWidgetPluginShown(p, shown);
135
 
    }
136
 
}
137
 
 
138
 
 
139
 
PluginBase *PluginManager::getPluginByName(const QString &name) const
140
 
{
141
 
    for (PluginIterator it(m_plugins); it.current(); ++it) {
142
 
        if (it.current()->name() == name)
143
 
            return it.current();
144
 
    }
145
 
    return NULL;
146
 
}
147
 
 
148
 
 
149
 
void PluginManager::insertPlugin(PluginBase *p)
150
 
{
151
 
    BlockProfiler profiler("PluginManager::insertPlugin");
152
 
 
153
 
    if (p) {
154
 
        BlockProfiler profiler_cfg("PluginManager::insertPlugin - about/config");
155
 
 
156
 
        /*kdDebug() << QDateTime::currentDateTime().toString(Qt::ISODate)
157
 
                  << " Debug: Adding Plugin: " << p->name() << "\n";*/
158
 
 
159
 
        if (!m_configDialog)
160
 
            createConfigDialog(m_configDialogTitle);
161
 
        if (!m_aboutDialog)
162
 
            createAboutDialog(m_aboutDialogTitle);
163
 
 
164
 
        m_plugins.append(p);
165
 
        p->setManager(this);
166
 
 
167
 
        addConfigurationPage (p, p->createConfigurationPage());
168
 
        addAboutPage         (p, p->createAboutPage());
169
 
 
170
 
        profiler_cfg.stop();
171
 
        BlockProfiler profiler_connect("PluginManager::insertPlugin - connect");
172
 
 
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());
179
 
            }
180
 
        }
181
 
 
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());
186
 
            if (i)
187
 
                i->connectI(p);
188
 
        }
189
 
 
190
 
        profiler_connect.stop();
191
 
        BlockProfiler profiler_widget("PluginManager::insertPlugin - notifywidgets");
192
 
 
193
 
        WidgetPluginBase *w1 = dynamic_cast<WidgetPluginBase*>(p);
194
 
        for (PluginIterator it(m_plugins); it.current(); ++it) {
195
 
            it.current()->noticePluginsChanged(m_plugins);
196
 
            if (w1)
197
 
                it.current()->noticeWidgetPluginShown(w1, w1->isReallyVisible());
198
 
 
199
 
            WidgetPluginBase *w2 = dynamic_cast<WidgetPluginBase*>(it.current());
200
 
            if (w2)
201
 
                p->noticeWidgetPluginShown(w2, w2->isReallyVisible());
202
 
        }
203
 
 
204
 
        if (m_pluginManagerConfiguration)
205
 
            m_pluginManagerConfiguration->noticePluginsChanged();
206
 
 
207
 
        profiler_widget.stop();
208
 
    }
209
 
}
210
 
 
211
 
 
212
 
void PluginManager::deletePlugin(PluginBase *p)
213
 
{
214
 
    if (p && m_plugins.contains(p)) {
215
 
        removePlugin(p);
216
 
        delete p;
217
 
    }
218
 
}
219
 
 
220
 
 
221
 
void PluginManager::removePlugin(PluginBase *p)
222
 
{
223
 
    if (p && m_plugins.contains(p)) {
224
 
 
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());
230
 
                } else {
231
 
                    p->disconnectI(it.current());
232
 
                }
233
 
            }
234
 
        }
235
 
 
236
 
        // remove config page from config dialog, only chance is to delete it
237
 
        // plugin will be notified automatically (mechanism implemented by
238
 
        // PluginBase)
239
 
        while (QFrame *f = m_configPageFrames.find(p)) {
240
 
            m_configPageFrames.remove(p);
241
 
            m_configPages.remove(p);
242
 
            delete f;
243
 
        }
244
 
        while (QFrame *f = m_aboutPageFrames.find(p)) {
245
 
            m_aboutPageFrames.remove(p);
246
 
            m_aboutPages.remove(p);
247
 
            delete f;
248
 
        }
249
 
 
250
 
        // remove bindings between me and plugin
251
 
        m_plugins.remove(p);
252
 
        p->unsetManager();
253
 
 
254
 
        p->noticePluginsChanged(PluginList());
255
 
        for (PluginIterator it(m_plugins); it.current(); ++it) {
256
 
            it.current()->noticePluginsChanged(m_plugins);
257
 
        }
258
 
 
259
 
        if (m_pluginManagerConfiguration)
260
 
            m_pluginManagerConfiguration->noticePluginsChanged();
261
 
    }
262
 
}
263
 
 
264
 
 
265
 
void PluginManager::addConfigurationPage (PluginBase *forWhom,
266
 
                                          const ConfigPageInfo &info)
267
 
{
268
 
    if (!forWhom || !m_plugins.containsRef(forWhom) || !info.page)
269
 
        return;
270
 
    QFrame *f = addConfigurationPage(info);
271
 
 
272
 
    // register this frame and config page
273
 
    m_configPageFrames.insert(forWhom, f);
274
 
    m_configPages.insert(forWhom, info.page);
275
 
 
276
 
    // perhaps new config page profits from existing plugins
277
 
    // example: timecontrol profits from radio plugin
278
 
    Interface *i = dynamic_cast<Interface *>(info.page);
279
 
    if (i) {
280
 
        for (PluginIterator it(m_plugins); it.current(); ++it)
281
 
            i->connectI(it.current());
282
 
    }
283
 
}
284
 
 
285
 
 
286
 
QFrame *PluginManager::addConfigurationPage (const ConfigPageInfo &info)
287
 
{
288
 
    if (!m_configDialog)
289
 
        createConfigDialog(i18n(m_configDialogTitle.ascii()));
290
 
 
291
 
    // create empty config frame
292
 
    QFrame *f = m_configDialog->addPage(
293
 
      info.itemName,
294
 
      info.pageHeader,
295
 
      KGlobal::instance()->iconLoader()->loadIcon( info.iconName, KIcon::NoGroup, KIcon::SizeMedium )
296
 
    );
297
 
 
298
 
    // fill config frame with layout ...
299
 
    QGridLayout *l = new QGridLayout(f);
300
 
    l->setSpacing( 0 );
301
 
    l->setMargin( 0 );
302
 
 
303
 
    // ... and externally created config page
304
 
    info.page->reparent (f, QPoint(0,0), true);
305
 
    l->addWidget( info.page, 0, 0 );
306
 
 
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()));
310
 
 
311
 
    return f;
312
 
}
313
 
 
314
 
 
315
 
void PluginManager::createConfigDialog(const QString &title)
316
 
{
317
 
    if (m_configDialog) delete m_configDialog;
318
 
    m_configDialog = NULL;
319
 
 
320
 
    PluginConfigurationDialog *cfg = new PluginConfigurationDialog(
321
 
        KDialogBase::IconList,
322
 
        title,
323
 
        KDialogBase::Apply|KDialogBase::Ok|KDialogBase::Cancel,
324
 
        KDialogBase::Ok,
325
 
        /*parent = */ NULL,
326
 
        title.ascii(),
327
 
        /*modal = */ false,
328
 
        true);
329
 
 
330
 
    m_configDialog = cfg;
331
 
 
332
 
    QObject::connect(m_configDialog, SIGNAL(okClicked()),     this, SLOT(slotConfigOK()));
333
 
    QObject::connect(m_configDialog, SIGNAL(applyClicked()),  this, SLOT(slotConfigOK()));
334
 
 
335
 
    insertPlugin(cfg);
336
 
 
337
 
    addConfigurationPage(createOwnConfigurationPage());
338
 
 
339
 
    for (PluginIterator i(m_plugins); m_configDialog && i.current(); ++i) {
340
 
        addConfigurationPage(i.current(),
341
 
                             i.current()->createConfigurationPage());
342
 
    }
343
 
}
344
 
 
345
 
 
346
 
ConfigPageInfo PluginManager::createOwnConfigurationPage()
347
 
{
348
 
    m_pluginManagerConfiguration = new PluginManagerConfiguration(NULL, m_Application, this);
349
 
    return ConfigPageInfo (m_pluginManagerConfiguration,
350
 
                           i18n("Plugins"),
351
 
                           i18n("Plugin Library Configuration"),
352
 
                           "kdf");
353
 
}
354
 
 
355
 
 
356
 
 
357
 
 
358
 
 
359
 
void PluginManager::addAboutPage (PluginBase *forWhom,
360
 
                                  const AboutPageInfo &info)
361
 
{
362
 
    if (!m_aboutDialog)
363
 
        createAboutDialog(i18n(m_aboutDialogTitle.ascii()));
364
 
 
365
 
    if (   !forWhom || !m_plugins.containsRef(forWhom)
366
 
        || !m_aboutDialog || !info.page)
367
 
        return;
368
 
 
369
 
 
370
 
    // create empty about frame
371
 
    QFrame *f = m_aboutDialog->addPage(
372
 
      info.itemName,
373
 
      info.pageHeader,
374
 
      KGlobal::instance()->iconLoader()->loadIcon( info.iconName, KIcon::NoGroup, KIcon::SizeMedium )
375
 
    );
376
 
 
377
 
    // register this frame and config page
378
 
    m_aboutPageFrames.insert(forWhom, f);
379
 
    m_aboutPages.insert(forWhom, info.page);
380
 
 
381
 
    // fill config frame with layout ...
382
 
    QGridLayout *l = new QGridLayout(f);
383
 
    l->setSpacing( 0 );
384
 
    l->setMargin( 0 );
385
 
 
386
 
    // ... and externally created config page
387
 
    info.page->reparent (f, QPoint(0,0), true);
388
 
    l->addWidget( info.page, 0, 0 );
389
 
}
390
 
 
391
 
 
392
 
void PluginManager::createAboutDialog(const QString &title)
393
 
{
394
 
    if (m_aboutDialog) delete m_aboutDialog;
395
 
    m_aboutDialog = NULL;
396
 
 
397
 
    m_aboutDialog = new KDialogBase(KDialogBase::IconList,
398
 
                                    title,
399
 
                                    KDialogBase::Close,
400
 
                                    KDialogBase::Close,
401
 
                                    /*parent = */ NULL,
402
 
                                    title.ascii(),
403
 
                                    /*modal = */ false,
404
 
                                    true);
405
 
 
406
 
    for (PluginIterator i(m_plugins); m_aboutDialog && i.current(); ++i) {
407
 
        addAboutPage(i.current(),
408
 
                     i.current()->createAboutPage());
409
 
    }
410
 
}
411
 
 
412
 
 
413
 
void PluginManager::saveState (KConfig *c) const
414
 
{
415
 
    c->setGroup("PluginManager-" + m_Name);
416
 
    c->writeEntry("show-progress-bar", m_showProgressBar);
417
 
    int n = 0;
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))
423
 
        {
424
 
            ++n;
425
 
            c->writeEntry("plugin_class_" + QString::number(n), class_name);
426
 
            c->writeEntry("plugin_name_"  + QString::number(n), object_name);
427
 
        }
428
 
    }
429
 
    c->writeEntry("plugins", n);
430
 
 
431
 
    for (PluginIterator i(m_plugins); i.current(); ++i) {
432
 
        i.current()->saveState(c);
433
 
    }
434
 
}
435
 
 
436
 
 
437
 
void PluginManager::restoreState (KConfig *c)
438
 
{
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);
443
 
 
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);
449
 
        progress->show();
450
 
        progress->progressBar()->setTotalSteps(2*n);
451
 
    }
452
 
 
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));
457
 
 
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);
464
 
    }
465
 
 
466
 
    if (m_Application && n == 0) {
467
 
        const QMap<QString, PluginClassInfo> &classes = m_Application->getPluginClasses();
468
 
        QMapConstIterator<QString, PluginClassInfo> end = classes.end();
469
 
        n = classes.count();
470
 
        if (m_showProgressBar)
471
 
            progress->progressBar()->setTotalSteps(2*n);
472
 
        int idx = 1;
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);
480
 
        }
481
 
        m_configDialog->show();
482
 
    }
483
 
 
484
 
    BlockProfiler  profile_plugins("PluginManager::restoreState -  plugins");
485
 
 
486
 
    int idx = n;
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);
494
 
    }
495
 
    if (m_showProgressBar)
496
 
        delete progress;
497
 
}
498
 
 
499
 
PluginConfigurationDialog *PluginManager::getConfigDialog()
500
 
{
501
 
    if (!m_configDialog)
502
 
        createConfigDialog(m_configDialogTitle);
503
 
    return m_configDialog;
504
 
}
505
 
 
506
 
KDialogBase               *PluginManager::getAboutDialog()
507
 
{
508
 
    if (!m_aboutDialog)
509
 
        createAboutDialog();
510
 
    return m_aboutDialog;
511
 
}
512
 
 
513
 
 
514
 
 
515
 
void PluginManager::slotConfigOK()
516
 
{
517
 
    emit sigConfigOK();
518
 
    if (m_Application)
519
 
        m_Application->saveState(KGlobal::config());
520
 
}
521
 
 
522
 
 
523
 
void  PluginManager::startPlugins()
524
 
{
525
 
    for (PluginIterator i(m_plugins); i.current(); ++i) {
526
 
        i.current()->startPlugin();
527
 
    }
528
 
}
529
 
 
530
 
void  PluginManager::aboutToQuit()
531
 
{
532
 
    for (PluginIterator i(m_plugins); i.current(); ++i) {
533
 
        i.current()->aboutToQuit();
534
 
    }
535
 
}
536
 
 
537
 
 
538
 
#include "pluginmanager.moc"