1
/*****************************************************************
3
Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
5
Permission is hereby granted, free of charge, to any person obtaining a copy
6
of this software and associated documentation files (the "Software"), to deal
7
in the Software without restriction, including without limitation the rights
8
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
copies of the Software, and to permit persons to whom the Software is
10
furnished to do so, subject to the following conditions:
12
The above copyright notice and this permission notice shall be included in
13
all copies or substantial portions of the Software.
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
******************************************************************/
26
#include <Qt3Support/q3tl.h>
30
#include <k3staticdeleter.h>
32
#include <kapplication.h>
35
#include <klibloader.h>
36
#include <kpanelapplet.h>
37
#include <kpanelextension.h>
38
#include <kstandarddirs.h>
40
#include "appletinfo.h"
41
#include "container_applet.h"
42
#include "container_extension.h"
43
#include "panelextension.h"
44
#include "pluginmanager.h"
45
#include <kconfiggroup.h>
47
static K3StaticDeleter<PluginManager> pluginManagerDeleter;
48
PluginManager* PluginManager::m_self = 0;
50
PluginManager* PluginManager::self()
54
pluginManagerDeleter.setObject(m_self, new PluginManager());
60
AppletInfo::List PluginManager::applets(bool sort, AppletInfo::List* list)
63
KGlobal::dirs()->findAllResources("applets", "*.desktop", KStandardDirs::NoDuplicates, rel);
64
return plugins(rel, AppletInfo::Applet, sort, list);
67
AppletInfo::List PluginManager::extensions(bool sort, AppletInfo::List* list)
70
KGlobal::dirs()->findAllResources("extensions", "*.desktop", KStandardDirs::NoDuplicates, rel);
71
return plugins(rel, AppletInfo::Extension, sort, list);
74
AppletInfo::List PluginManager::builtinButtons(bool sort, AppletInfo::List* list)
77
KGlobal::dirs()->findAllResources("builtinbuttons", "*.desktop", KStandardDirs::NoDuplicates, rel);
78
return plugins(rel, AppletInfo::BuiltinButton, sort, list);
81
AppletInfo::List PluginManager::specialButtons(bool sort, AppletInfo::List* list)
84
KGlobal::dirs()->findAllResources("specialbuttons", "*.desktop", KStandardDirs::NoDuplicates, rel);
85
return plugins(rel, AppletInfo::SpecialButton, sort, list);
88
AppletInfo::List PluginManager::plugins(const QStringList& desktopFiles,
89
AppletInfo::AppletType type,
91
AppletInfo::List* list)
93
AppletInfo::List plugins;
100
for (QStringList::ConstIterator it = desktopFiles.constBegin();
101
it != desktopFiles.constEnd(); ++it)
103
AppletInfo info(*it, QString(), type);
105
if (!info.isHidden())
107
plugins.append(info);
113
qHeapSort(plugins.begin(), plugins.end());
119
PluginManager::PluginManager()
121
KConfigGroup generalGroup(KGlobal::config(), "General");
122
m_untrustedApplets = generalGroup.readEntry("UntrustedApplets", QStringList() );
123
m_untrustedExtensions = generalGroup.readEntry("UntrustedExtensions", QStringList() );
126
PluginManager::~PluginManager()
128
AppletInfo::Dict::const_iterator it = m_appletDict.constBegin();
129
for (; it != m_appletDict.constEnd(); ++it)
131
disconnect(it.key(), SIGNAL(destroyed( QObject*)),
132
this, SLOT(slotPluginDestroyed(QObject*)));
136
// clear the untrusted lists
137
clearUntrustedLists();
140
KPanelApplet* PluginManager::loadApplet(const AppletInfo& info,
143
KLibLoader* loader = KLibLoader::self();
144
KLibrary* lib = loader->library( info.library() );
148
kWarning() << "cannot open applet: " << info.library()
149
<< " because of " << loader->lastErrorMessage() << endl;
153
KPanelApplet* (*init_ptr)(QWidget *, const QString&);
154
init_ptr = (KPanelApplet* (*)(QWidget *, const QString&))lib->resolveFunction( "init" );
158
kWarning() << info.library() << " is not a kicker extension!" ;
159
loader->unloadLibrary( info.library() );
163
KPanelApplet* applet = init_ptr( parent, info.configFile() );
167
m_appletDict.insert( applet, new AppletInfo( info ) );
168
connect( applet, SIGNAL( destroyed( QObject* ) ),
169
SLOT( slotPluginDestroyed( QObject* ) ) );
175
KPanelExtension* PluginManager::loadExtension(const AppletInfo& info, QWidget* parent )
177
if (info.library() == QLatin1String("childpanel_panelextension")
178
/* KDE4? || info.library() == "panel" */)
180
return new PanelExtension(info.configFile(), parent);
183
KLibLoader* loader = KLibLoader::self();
184
KLibrary* lib = loader->library( info.library() );
187
kWarning() << "cannot open extension: " << info.library()
188
<< " because of " << loader->lastErrorMessage() << endl;
192
KPanelExtension* (*init_ptr)(QWidget *, const QString&);
193
init_ptr = (KPanelExtension* (*)(QWidget *, const QString&))lib->resolveFunction( "init" );
196
kWarning() << info.library() << " is not a kicker extension!" ;
197
loader->unloadLibrary( info.library() );
201
KPanelExtension* extension = init_ptr( parent, info.configFile() );
204
m_appletDict.insert( extension, new AppletInfo( info ) );
205
connect( extension, SIGNAL( destroyed( QObject* ) ),
206
SLOT( slotPluginDestroyed( QObject* ) ) );
212
bool PluginManager::hasInstance( const AppletInfo& info ) const
214
AppletInfo::Dict::const_iterator it = m_appletDict.constBegin();
215
for (; it != m_appletDict.constEnd(); ++it)
217
if (it.value()->library() == info.library())
226
void PluginManager::slotPluginDestroyed(QObject* object)
228
AppletInfo* info = 0;
229
AppletInfo::Dict::iterator it = m_appletDict.begin();
230
for (; it != m_appletDict.end(); ++it)
232
if (it.key() == object)
234
info = dynamic_cast<AppletInfo*>(it.value());
235
m_appletDict.erase(it);
245
LibUnloader::unload(info->library());
248
emit pluginDestroyed();
251
AppletContainer* PluginManager::createAppletContainer(
252
const QString& desktopFile,
254
const QString& configFile,
259
QString desktopPath = KGlobal::dirs()->findResource( "applets", desktopFile );
261
if (desktopPath.isEmpty())
266
AppletInfo info( desktopPath, configFile, AppletInfo::Applet );
268
bool instanceFound = hasInstance(info);
269
if (info.isUniqueApplet() && instanceFound)
274
bool untrusted = m_untrustedApplets.indexOf(desktopFile) != -1;
275
if (isStartup && untrusted)
277
// don't load extensions that bombed on us previously!
280
else if (!isStartup && !instanceFound && !untrusted)
282
// we haven't loaded this puppy before and we're not in the untrusted list
283
m_untrustedApplets.append(desktopFile);
284
KConfigGroup generalGroup(KGlobal::config(), "General");
285
generalGroup.writeEntry("UntrustedApplets", m_untrustedApplets);
289
AppletContainer* container = new AppletContainer(info, opMenu, isImmutable, parent);
291
if (!container->isValid())
300
ExtensionContainer* PluginManager::createExtensionContainer(const QString& desktopFile,
302
const QString& configFile,
303
const QString& extensionId)
305
if (desktopFile.isEmpty())
310
QString desktopPath = KGlobal::dirs()->findResource("extensions", desktopFile);
311
if (desktopPath.isEmpty())
316
AppletInfo info(desktopPath, configFile, AppletInfo::Extension);
318
bool internal = (info.library() == "childpanel_panelextension");
319
bool instance = !internal && hasInstance(info);
320
if (instance && info.isUniqueApplet())
327
bool untrusted = m_untrustedExtensions.indexOf(desktopFile) != -1;
328
if (isStartup && untrusted)
330
// don't load extensions that bombed on us previously!
333
else if (!isStartup && !instance && !untrusted)
335
// we don't have an instance around and we're not in the untrusted list!
336
m_untrustedExtensions.append(desktopFile);
337
KConfigGroup generalGroup(KGlobal::config(), "General");
338
generalGroup.writeEntry("UntrustedExtensions", m_untrustedExtensions);
343
return new ExtensionContainer(info, extensionId);
346
void PluginManager::clearUntrustedLists()
348
m_untrustedExtensions.clear();
349
m_untrustedApplets.clear();
351
KConfigGroup generalGroup(KGlobal::config(), "General");
352
generalGroup.writeEntry("UntrustedApplets", m_untrustedApplets);
353
generalGroup.writeEntry("UntrustedExtensions", m_untrustedExtensions);
357
LibUnloader::LibUnloader( const QString &libName, QObject *parent )
358
: QObject( parent ), _libName( libName )
360
// NOTE: this doesn't work on kicker shutdown because the timer never gets
362
QTimer::singleShot( 0, this, SLOT( unload() ) );
365
void LibUnloader::unload( const QString &libName )
367
(void)new LibUnloader( libName, kapp );
370
void LibUnloader::unload()
372
KLibLoader::self()->unloadLibrary( _libName );
376
#include "pluginmanager.moc"