libKipi
pluginloader.cpp
Go to the documentation of this file.
1/* ============================================================
2 *
3 * This file is a part of kipi-plugins project
4 * http://www.kipi-plugins.org
5 *
6 * Date : 2004-02-01
7 * Description : plugin loader
8 *
9 * Copyright (C) 2004-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
10 * Copyright (C) 2004-2005 by Renchi Raju <renchi.raju at kdemail.net>
11 *
12 * This program is free software; you can redistribute it
13 * and/or modify it under the terms of the GNU General
14 * Public License as published by the Free Software Foundation;
15 * either version 2, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * ============================================================ */
23
26// Qt include.
27
28#include <qstringlist.h>
29#include <qcheckbox.h>
30#include <qlayout.h>
31
32// KDE includes.
33
34#include <ktrader.h>
35#include <kparts/componentfactory.h>
36#include <kdebug.h>
37#include <kdialog.h>
38#include <kconfig.h>
39
40// Local includes.
41
42#include "plugin.h"
43#include "interface.h"
44#include "pluginloader.h"
45#include "pluginloader.moc"
46
116namespace KIPI
117{
118
119//---------------------------------------------------------------------
120//
121// PluginLoader::Info
122//
123//---------------------------------------------------------------------
132
133PluginLoader::Info::Info(const QString& name, const QString& comment, const QString& library, bool shouldLoad)
134{
135 d=new Private;
136 d->m_name=name;
139 d->m_plugin=0;
141}
142
144{
145 delete d;
146}
147
149{
150 return d->m_name;
151}
152
154{
155 return d->m_comment;
156}
157
159{
160 return d->m_library;
161}
162
164{
165 return d->m_plugin;
166}
167
169{
170 d->m_plugin=plugin;
171}
172
174{
175 return d->m_shouldLoad;
176}
177
179{
180 d->m_shouldLoad=value;
181}
182
183//---------------------------------------------------------------------
184//
185// PluginLoader
186//
187//---------------------------------------------------------------------
188
189static PluginLoader* s_instance = 0;
190
197
198PluginLoader::PluginLoader( const QStringList& ignores, Interface* interface )
199{
200 Q_ASSERT( s_instance == 0 );
201 s_instance = this;
202
203 d=new Private;
204 d->m_interface = interface;
205 d->m_ignores = ignores;
206
207 KTrader::OfferList offers = KTrader::self()->query("KIPI/Plugin");
208 KConfig* config = KGlobal::config();
209 config->setGroup( QString::fromLatin1( "KIPI/EnabledPlugin" ) );
210
211 KTrader::OfferList::ConstIterator iter;
212 for(iter = offers.begin(); iter != offers.end(); ++iter)
213 {
214 KService::Ptr service = *iter;
215 QString name = service->name();
216 QString comment = service->comment();
217 QString library = service->library();
218 QStringList reqFeatures = service->property( QString::fromLatin1( "X-KIPI-ReqFeatures" ) ).toStringList();
219
220 if (library.isEmpty() || name.isEmpty() )
221 {
222 kdWarning( 51001 ) << "KIPI::PluginLoader: Plugin had an empty name or library file - this should not happen." << endl;
223 continue;
224 }
225
226 if ( d->m_ignores.contains( name ) )
227 {
228 kdDebug( 51001 ) << "KIPI::PluginLoader: plugin " << name << " is in the ignore list for host application" << endl;
229 continue;
230 }
231
232 bool appHasAllReqFeatures=true;
233 for( QStringList::Iterator featureIt = reqFeatures.begin(); featureIt != reqFeatures.end(); ++featureIt )
234 {
235 if ( !d->m_interface->hasFeature( *featureIt ) )
236 {
237 kdDebug( 51001 ) << "Plugin " << name << " was not loaded because the host application is missing\n"
238 << "the feature " << *featureIt << endl;
239 appHasAllReqFeatures=false;
240 break;
241 }
242 }
243
244 bool load = config->readBoolEntry( name, true );
245
246 if (!appHasAllReqFeatures)
247 continue;
248
249 Info* info = new Info( name, comment, library, load );
250 d->m_pluginList.append( info );
251 }
252}
253
255{
256 delete d;
257}
258
260{
261 for( PluginList::Iterator it = d->m_pluginList.begin(); it != d->m_pluginList.end(); ++it )
262 {
263 loadPlugin( *it );
264 }
265 emit replug();
266}
267
269{
270 if ( info->plugin() == 0 && info->shouldLoad() )
271 {
272 Plugin *plugin = 0;
273 int error;
274 plugin = KParts::ComponentFactory
275 ::createInstanceFromLibrary<Plugin>(info->library().local8Bit().data(),
276 d->m_interface, 0, QStringList(), &error);
277
278 if (plugin)
279 kdDebug( 51001 ) << "KIPI::PluginLoader: Loaded plugin " << plugin->name() << endl;
280 else
281 {
282 kdWarning( 51001 ) << "KIPI::PluginLoader:: createInstanceFromLibrary returned 0 for "
283 << info->name()
284 << " (" << info->library() << ")"
285 << " with error number "
286 << error << endl;
287 if (error == KParts::ComponentFactory::ErrNoLibrary)
288 kdWarning( 51001 ) << "KLibLoader says: "
289 << KLibLoader::self()->lastErrorMessage() << endl;
290 }
291 info->setPlugin(plugin);
292 }
293 if ( info->plugin() ) // Do not emit if we had trouble loading the plugin.
294 emit PluginLoader::instance()->plug( info );
295}
296
301
303{
304 Q_ASSERT( s_instance != 0);
305 return s_instance;
306}
307
308//---------------------------------------------------------------------
309//
310// ConfigWidget
311//
312//---------------------------------------------------------------------
314{
315 return new ConfigWidget( parent );
316}
317
318
319class PluginCheckBox :public QCheckBox
320{
321public:
322
323 PluginCheckBox( PluginLoader::Info* info, QWidget* parent )
324 : QCheckBox( info->comment(), parent ), info( info )
325 {
326 setChecked( info->shouldLoad() );
327 }
329};
330
332{
333 QValueList< PluginCheckBox* > _boxes;
334};
335
337 : QScrollView( parent, "KIPI::PluginLoader::ConfigWidget" )
338{
339 d=new Private;
340 QWidget* top = new QWidget( viewport() );
341 addChild( top );
342 setResizePolicy( AutoOneFit );
343
344 QVBoxLayout* lay = new QVBoxLayout( top, KDialog::marginHint(), KDialog::spacingHint() );
345
346 PluginLoader::PluginList list = PluginLoader::instance()->d->m_pluginList;
347 for( PluginLoader::PluginList::Iterator it = list.begin(); it != list.end(); ++it )
348 {
349 PluginCheckBox* cb = new PluginCheckBox( *it, top );
350 lay->addWidget( cb );
351 d->_boxes.append( cb );
352 }
353
354 lay->addStretch(10);
355}
356
358{
359 delete d;
360}
361
363{
364 KConfig* config = KGlobal::config();
365 config->setGroup( QString::fromLatin1( "KIPI/EnabledPlugin" ) );
366 bool changes = false;
367
368 for( QValueList<PluginCheckBox*>::Iterator it = d->_boxes.begin(); it != d->_boxes.end(); ++it )
369 {
370 bool orig = (*it)->info->shouldLoad();
371 bool load = (*it)->isChecked();
372 if ( orig != load )
373 {
374 changes = true;
375 config->writeEntry( (*it)->info->name(), load );
376 (*it)->info->setShouldLoad(load);
377 if ( load )
378 {
379 PluginLoader::instance()->loadPlugin( (*it)->info);
380 }
381 else
382 {
383 if ( (*it)->info->plugin() ) // Do not emit if we had trouble loading plugin.
384 emit PluginLoader::instance()->unplug( (*it)->info);
385 }
386 }
387 }
389}
390
391} // namespace
392
KDStream & endl(KDStream &stream)
Definition KDStream.cpp:264
Definition pluginloader.h:103
ConfigWidget(QWidget *parent)
Definition pluginloader.cpp:336
~ConfigWidget()
Definition pluginloader.cpp:357
void apply()
Definition pluginloader.cpp:362
Definition interface.h:64
bool hasFeature(KIPI::Features feature)
Definition interface.cpp:129
Definition pluginloader.cpp:320
PluginLoader::Info * info
Definition pluginloader.cpp:328
PluginCheckBox(PluginLoader::Info *info, QWidget *parent)
Definition pluginloader.cpp:323
Definition pluginloader.h:50
Plugin * plugin() const
Definition pluginloader.cpp:163
void setShouldLoad(bool)
Definition pluginloader.cpp:178
bool shouldLoad() const
Definition pluginloader.cpp:173
void setPlugin(Plugin *)
Definition pluginloader.cpp:168
QString comment() const
Definition pluginloader.cpp:153
Info(const QString &name, const QString &comment, const QString &library, bool shouldLoad)
Definition pluginloader.cpp:133
QString name() const
Definition pluginloader.cpp:148
QString library() const
Definition pluginloader.cpp:158
~Info()
Definition pluginloader.cpp:143
Definition pluginloader.h:44
QValueList< Info * > PluginList
Definition pluginloader.h:81
virtual ~PluginLoader()
Definition pluginloader.cpp:254
PluginLoader(const QStringList &ignores, Interface *interface)
Definition pluginloader.cpp:198
void loadPlugins()
Definition pluginloader.cpp:259
ConfigWidget * configWidget(QWidget *parent)
Definition pluginloader.cpp:313
static PluginLoader * instance()
Definition pluginloader.cpp:302
void loadPlugin(Info *)
Definition pluginloader.cpp:268
void unplug(KIPI::PluginLoader::Info *)
const PluginList & pluginList()
Definition pluginloader.cpp:297
friend class ConfigWidget
Definition pluginloader.h:95
void plug(KIPI::PluginLoader::Info *)
Definition plugin.h:59
Definition batchprogressdialog.cpp:70
Definition pluginloader.cpp:332
QValueList< PluginCheckBox * > _boxes
Definition pluginloader.cpp:333
Definition pluginloader.cpp:125
QString m_comment
Definition pluginloader.cpp:127
QString m_name
Definition pluginloader.cpp:126
bool m_shouldLoad
Definition pluginloader.cpp:130
QString m_library
Definition pluginloader.cpp:128
Plugin * m_plugin
Definition pluginloader.cpp:129
Definition pluginloader.cpp:192
PluginList m_pluginList
Definition pluginloader.cpp:193
QStringList m_ignores
Definition pluginloader.cpp:195
Interface * m_interface
Definition pluginloader.cpp:194