1 /***************************************************************************
3 copyright : (C) Mark Kretschmann
5 ***************************************************************************/
7 /***************************************************************************
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
14 ***************************************************************************/
16 #define DEBUG_PREFIX "PluginManager"
18 #include "pluginmanager.h"
25 #include <KMessageBox>
33 vector
<PluginManager::StoreItem
>
34 PluginManager::m_store
;
37 /////////////////////////////////////////////////////////////////////////////////////
39 /////////////////////////////////////////////////////////////////////////////////////
42 PluginManager::query( const QString
& constraint
)
44 // Add versioning constraint
46 str
= "[X-KDE-Amarok-framework-version] == ";
47 str
+= QString::number( FrameworkVersion
);
48 if ( !constraint
.trimmed().isEmpty() )
49 str
+= " and " + constraint
;
51 str
+= "[X-KDE-Amarok-rank] > 0";
53 debug() << "Plugin trader constraint: " << str
;
55 return KServiceTypeTrader::self()->query( "Amarok/Plugin", str
);
60 PluginManager::createFromQuery( const QString
&constraint
)
62 Debug::Block
block( __PRETTY_FUNCTION__
);
64 KService::List offers
= query( constraint
);
66 if ( offers
.isEmpty() ) {
67 warning() << "No matching plugin found.\n";
71 // Select plugin with highest rank
74 for ( int i
= 0; i
< offers
.count(); i
++ ) {
75 if ( offers
[i
]->property( "X-KDE-Amarok-rank" ).toInt() > rank
)
79 return createFromService( offers
[current
] );
84 PluginManager::createFromService( const KService::Ptr service
)
86 debug() << "Trying to load: " << service
->library();
88 //get the library loader instance
89 KLibLoader
*loader
= KLibLoader::self();
90 //try to load the specified library
91 KLibrary
*lib
= loader
->library( QFile::encodeName( service
->library() ), QLibrary::ExportExternalSymbolsHint
);
94 KMessageBox::error( 0, i18n( "<p>KLibLoader could not load the plugin:<br/><i>%1</i></p>"
95 "<p>Error message:<br/><i>%2</i></p>" )
96 .arg( service
->library() )
97 .arg( loader
->lastErrorMessage() ) );
100 //look up address of init function and cast it to pointer-to-function
101 Plugin
* (*create_plugin
)() = ( Plugin
* (*)() ) lib
->resolveSymbol( "create_plugin" );
103 if ( !create_plugin
) {
104 warning() << "create_plugin == NULL\n";
107 //create plugin on the heap
108 Plugin
* plugin
= create_plugin();
110 //put plugin into store
112 item
.plugin
= plugin
;
114 item
.service
= service
;
115 m_store
.push_back( item
);
123 PluginManager::unload( Plugin
* plugin
)
127 vector
<StoreItem
>::iterator iter
= lookupPlugin( plugin
);
129 if ( iter
!= m_store
.end() ) {
130 delete (*iter
).plugin
;
131 debug() << "Unloading library: "<< (*iter
).service
->library();
132 (*iter
).library
->unload();
134 m_store
.erase( iter
);
137 warning() << "Could not unload plugin (not found in store).\n";
142 PluginManager::getService( const Plugin
* plugin
)
145 warning() << "pointer == NULL\n";
146 return KService::Ptr(0);
149 //search plugin in store
150 vector
<StoreItem
>::const_iterator iter
= lookupPlugin( plugin
);
152 if ( iter
== m_store
.end() ) {
153 warning() << "Plugin not found in store.\n";
154 return KService::Ptr(0);
157 return (*iter
).service
;
162 PluginManager::showAbout( const QString
&constraint
)
164 KService::List offers
= query( constraint
);
166 if ( offers
.isEmpty() )
169 KService::Ptr s
= offers
.front();
171 const QString body
= "<tr><td>%1</td><td>%2</td></tr>";
173 QString str
= "<html><body><table width=\"100%\" border=\"1\">";
175 str
+= body
.arg( i18n( "Name" ), s
->name() );
176 str
+= body
.arg( i18n( "Library" ), s
->library() );
177 str
+= body
.arg( i18n( "Authors" ), s
->property( "X-KDE-Amarok-authors" ).toStringList().join( "\n" ) );
178 str
+= body
.arg( i18n( "Email" ), s
->property( "X-KDE-Amarok-email" ).toStringList().join( "\n" ) );
179 str
+= body
.arg( i18n( "Version" ), s
->property( "X-KDE-Amarok-version" ).toString() );
180 str
+= body
.arg( i18n( "Framework Version" ), s
->property( "X-KDE-Amarok-framework-version" ).toString() );
182 str
+= "</table></body></html>";
184 KMessageBox::information( 0, str
, i18n( "Plugin Information" ) );
189 PluginManager::dump( const KService::Ptr service
)
191 #define ENDLI endl << Debug::indent()
195 << "PluginManager Service Info:" << ENDLI
196 << "---------------------------" << ENDLI
197 << "name :" << service
->name() << ENDLI
198 << "library :" << service
->library() << ENDLI
199 << "desktopEntryPath :" << service
->desktopEntryPath() << ENDLI
200 << "X-KDE-Amarok-plugintype :" << service
->property( "X-KDE-Amarok-plugintype" ).toString() << ENDLI
201 << "X-KDE-Amarok-name :" << service
->property( "X-KDE-Amarok-name" ).toString() << ENDLI
202 << "X-KDE-Amarok-authors :" << service
->property( "X-KDE-Amarok-authors" ).toStringList() << ENDLI
203 << "X-KDE-Amarok-rank :" << service
->property( "X-KDE-Amarok-rank" ).toString() << ENDLI
204 << "X-KDE-Amarok-version :" << service
->property( "X-KDE-Amarok-version" ).toString() << ENDLI
205 << "X-KDE-Amarok-framework-version:" << service
->property( "X-KDE-Amarok-framework-version" ).toString()
213 /////////////////////////////////////////////////////////////////////////////////////
215 /////////////////////////////////////////////////////////////////////////////////////
217 vector
<PluginManager::StoreItem
>::iterator
218 PluginManager::lookupPlugin( const Plugin
* plugin
)
220 vector
<StoreItem
>::iterator iter
;
222 //search plugin pointer in store
223 vector
<StoreItem
>::iterator
iterEnd(m_store
.end() );
224 for ( iter
= m_store
.begin(); iter
!= iterEnd
; ++iter
) {
225 if ( (*iter
).plugin
== plugin
)