23 #include "pluginmanager.h" 27 #include <tqapplication.h> 31 #include <tqvaluestack.h> 33 #include <tdeapplication.h> 35 #include <tdeparts/componentfactory.h> 36 #include <kplugininfo.h> 37 #include <ksettings/dispatcher.h> 38 #include <ksimpleconfig.h> 39 #include <kstandarddirs.h> 40 #include <kstaticdeleter.h> 47 class PluginManager::Private
51 TQValueList<KPluginInfo*> plugins;
55 TQMap<KPluginInfo*, Plugin*> loadedPlugins;
61 enum ShutdownMode { StartingUp, Running, ShuttingDown, DoneShutdown };
62 ShutdownMode shutdownMode;
64 TDESharedConfig::Ptr config;
66 TQValueStack<TQString> pluginsToLoad;
69 PluginManager::PluginManager( TQObject *parent )
79 d->shutdownMode = Private::StartingUp;
81 KSettings::Dispatcher::self()->registerInstance( TDEGlobal::instance(),
82 this, TQT_SLOT( loadAllPlugins() ) );
84 d->plugins = KPluginInfo::fromServices(
85 TDETrader::self()->query( TQString::fromLatin1(
"Komposer/Plugin" ),
86 TQString::fromLatin1(
"[X-Komposer-Version] == 1" ) ) );
89 PluginManager::~PluginManager()
91 if ( d->shutdownMode != Private::DoneShutdown ) {
92 slotShutdownTimeout();
94 kdWarning() << k_funcinfo
95 <<
"Destructing plugin manager without going through " 96 <<
"the shutdown process!" 98 << kdBacktrace(10) << endl;
103 TQMap<KPluginInfo*, Plugin*>::ConstIterator it;
104 for ( it = d->loadedPlugins.begin(); it != d->loadedPlugins.end(); )
107 TQMap<KPluginInfo*, Plugin*>::ConstIterator nextIt( it );
109 kdWarning() << k_funcinfo <<
"Deleting stale plugin '" 110 << it.data()->name() <<
"'" << endl;
118 TQValueList<KPluginInfo*>
119 PluginManager::availablePlugins(
const TQString &category )
const 121 if ( category.isEmpty() )
124 TQValueList<KPluginInfo*> result;
125 TQValueList<KPluginInfo*>::ConstIterator it;
126 for ( it = d->plugins.begin(); it != d->plugins.end(); ++it )
128 if ( ( *it )->category() == category )
129 result.append( *it );
135 TQMap<KPluginInfo*, Plugin*>
136 PluginManager::loadedPlugins(
const TQString &category )
const 138 TQMap<KPluginInfo*, Plugin*> result;
139 TQMap<KPluginInfo*, Plugin*>::ConstIterator it;
140 for ( it = d->loadedPlugins.begin(); it != d->loadedPlugins.end(); ++it )
142 if ( category.isEmpty() || it.key()->category() == category )
143 result.insert( it.key(), it.data() );
150 PluginManager::shutdown()
152 d->shutdownMode = Private::ShuttingDown;
155 d->pluginsToLoad.clear();
158 if ( d->loadedPlugins.empty() ) {
159 d->shutdownMode = Private::DoneShutdown;
161 TQMap<KPluginInfo*, Plugin*>::ConstIterator it;
162 for ( it = d->loadedPlugins.begin(); it != d->loadedPlugins.end(); )
165 TQMap<KPluginInfo*, Plugin*>::ConstIterator nextIt( it );
167 it.data()->aboutToUnload();
172 TQTimer::singleShot( 3000,
this, TQT_SLOT(slotShutdownTimeout()) );
176 PluginManager::slotPluginReadyForUnload()
181 Plugin* plugin =
dynamic_cast<Plugin*
>(
const_cast<TQObject*
>( sender() ) );
184 kdWarning() << k_funcinfo <<
"Calling object is not a plugin!" << endl;
188 kdDebug()<<
"manager unloading"<<endl;
189 plugin->deleteLater();
193 PluginManager::slotShutdownTimeout()
197 if ( d->shutdownMode == Private::DoneShutdown )
201 TQStringList remaining;
202 for ( TQMap<KPluginInfo*, Plugin*>::ConstIterator it = d->loadedPlugins.begin();
203 it != d->loadedPlugins.end(); ++it )
204 remaining.append( it.key()->pluginName() );
206 kdWarning() << k_funcinfo <<
"Some plugins didn't shutdown in time!" << endl
207 <<
"Remaining plugins: " 208 << remaining.join( TQString::fromLatin1(
", " ) ) << endl
209 <<
"Forcing Komposer shutdown now." << endl;
216 PluginManager::slotShutdownDone()
218 d->shutdownMode = Private::DoneShutdown;
224 PluginManager::loadAllPlugins()
229 d->config = TDESharedConfig::openConfig(
"komposerrc" );
231 TQMap<TQString, TQString> entries = d->config->entryMap(
232 TQString::fromLatin1(
"Plugins" ) );
234 TQMap<TQString, TQString>::Iterator it;
235 for ( it = entries.begin(); it != entries.end(); ++it )
237 TQString key = it.key();
238 if ( key.endsWith( TQString::fromLatin1(
"Enabled" ) ) )
240 key.setLength( key.length() - 7 );
243 if ( it.data() == TQString::fromLatin1(
"true" ) )
245 if ( !plugin( key ) )
246 d->pluginsToLoad.push( key );
260 TQTimer::singleShot( 0,
this, TQT_SLOT( slotLoadNextPlugin() ) );
263 void PluginManager::slotLoadNextPlugin()
265 if ( d->pluginsToLoad.isEmpty() )
267 if ( d->shutdownMode == Private::StartingUp )
269 d->shutdownMode = Private::Running;
270 emit allPluginsLoaded();
275 TQString key = d->pluginsToLoad.pop();
276 loadPluginInternal( key );
282 TQTimer::singleShot( 0,
this, TQT_SLOT( slotLoadNextPlugin() ) );
286 PluginManager::loadPlugin(
const TQString &pluginId,
287 PluginLoadMode mode )
289 if ( mode == LoadSync ) {
290 return loadPluginInternal( pluginId );
292 d->pluginsToLoad.push( pluginId );
293 TQTimer::singleShot( 0,
this, TQT_SLOT( slotLoadNextPlugin() ) );
299 PluginManager::loadPluginInternal(
const TQString &pluginId )
301 KPluginInfo* info = infoForPluginId( pluginId );
303 kdWarning() << k_funcinfo <<
"Unable to find a plugin named '" 304 << pluginId <<
"'!" << endl;
308 if ( d->loadedPlugins.contains( info ) )
309 return d->loadedPlugins[ info ];
312 Plugin *plugin = KParts::ComponentFactory::createInstanceFromQuery<Komposer::Plugin>(
313 TQString::fromLatin1(
"Komposer/Plugin" ),
314 TQString::fromLatin1(
"[X-TDE-PluginInfo-Name]=='%1'" ).arg( pluginId ),
315 this, 0, TQStringList(), &error );
318 d->loadedPlugins.insert( info, plugin );
319 info->setPluginEnabled(
true );
321 connect( plugin, TQT_SIGNAL(destroyed(TQObject*)),
322 this, TQT_SLOT(slotPluginDestroyed(TQObject*)) );
323 connect( plugin, TQT_SIGNAL(readyForUnload()),
324 this, TQT_SLOT(slotPluginReadyForUnload()) );
326 kdDebug() << k_funcinfo <<
"Successfully loaded plugin '" 327 << pluginId <<
"'" << endl;
329 emit pluginLoaded( plugin );
332 case KParts::ComponentFactory::ErrNoServiceFound:
333 kdDebug() << k_funcinfo <<
"No service implementing the given mimetype " 334 <<
"and fullfilling the given constraint expression can be found." 338 case KParts::ComponentFactory::ErrServiceProvidesNoLibrary:
339 kdDebug() <<
"the specified service provides no shared library." << endl;
342 case KParts::ComponentFactory::ErrNoLibrary:
343 kdDebug() <<
"the specified library could not be loaded." << endl;
346 case KParts::ComponentFactory::ErrNoFactory:
347 kdDebug() <<
"the library does not export a factory for creating components." 351 case KParts::ComponentFactory::ErrNoComponent:
352 kdDebug() <<
"the factory does not support creating components " 353 <<
"of the specified type." 358 kdDebug() << k_funcinfo <<
"Loading plugin '" << pluginId
359 <<
"' failed, KLibLoader reported error: '" 360 << KLibLoader::self()->lastErrorMessage()
368 PluginManager::unloadPlugin(
const TQString &spec )
370 TQMap<KPluginInfo*, Plugin*>::ConstIterator it;
371 for ( it = d->loadedPlugins.begin(); it != d->loadedPlugins.end(); ++it )
373 if ( it.key()->pluginName() == spec )
375 it.data()->aboutToUnload();
384 PluginManager::slotPluginDestroyed( TQObject *plugin )
386 TQMap<KPluginInfo*, Plugin*>::Iterator it;
387 for ( it = d->loadedPlugins.begin(); it != d->loadedPlugins.end(); ++it )
389 if ( it.data() == plugin )
391 d->loadedPlugins.erase( it );
396 if ( d->shutdownMode == Private::ShuttingDown && d->loadedPlugins.isEmpty() )
400 TQTimer::singleShot( 0,
this, TQT_SLOT(slotShutdownDone()) );
405 PluginManager::plugin(
const TQString &pluginId )
const 407 KPluginInfo *info = infoForPluginId( pluginId );
411 if ( d->loadedPlugins.contains( info ) )
412 return d->loadedPlugins[ info ];
418 PluginManager::pluginName(
const Plugin *plugin )
const 420 TQMap<KPluginInfo*, Plugin*>::ConstIterator it;
421 for ( it = d->loadedPlugins.begin(); it != d->loadedPlugins.end(); ++it )
423 if ( it.data() == plugin )
424 return it.key()->name();
427 return TQString::fromLatin1(
"Unknown" );
431 PluginManager::pluginId(
const Plugin *plugin )
const 433 TQMap<KPluginInfo*, Plugin*>::ConstIterator it;
434 for ( it = d->loadedPlugins.begin(); it != d->loadedPlugins.end(); ++it )
436 if ( it.data() == plugin )
437 return it.key()->pluginName();
440 return TQString::fromLatin1(
"unknown" );
444 PluginManager::pluginIcon(
const Plugin *plugin )
const 446 TQMap<KPluginInfo*, Plugin*>::ConstIterator it;
447 for ( it = d->loadedPlugins.begin(); it != d->loadedPlugins.end(); ++it )
449 if ( it.data() == plugin )
450 return it.key()->icon();
453 return TQString::fromLatin1(
"Unknown" );
457 PluginManager::infoForPluginId(
const TQString &pluginId )
const 459 TQValueList<KPluginInfo*>::ConstIterator it;
460 for ( it = d->plugins.begin(); it != d->plugins.end(); ++it )
462 if ( ( *it )->pluginName() == pluginId )
470 PluginManager::setPluginEnabled(
const TQString &pluginId,
bool enabled )
473 d->config = TDESharedConfig::openConfig(
"komposerrc" );
475 d->config->setGroup(
"Plugins" );
478 if ( !infoForPluginId( pluginId ) )
481 d->config->writeEntry( pluginId + TQString::fromLatin1(
"Enabled" ), enabled );
489 #include "pluginmanager.moc"