some more work on collabsible albums. I think I will need to optimize the playlist...
[amarok.git] / src / pluginmanager.cpp
blobb63b04eda0b8d0c1f9b8ae3cd2ac04422dd264c1
1 /***************************************************************************
2 begin : 2004/03/12
3 copyright : (C) Mark Kretschmann
4 email : markey@web.de
5 ***************************************************************************/
7 /***************************************************************************
8 * *
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. *
13 * *
14 ***************************************************************************/
16 #define DEBUG_PREFIX "PluginManager"
18 #include "pluginmanager.h"
20 #include "debug.h"
21 #include "plugin.h"
23 #include <KLibLoader>
24 #include <KLocale>
25 #include <KMessageBox>
27 #include <QFile>
29 using std::vector;
30 using Amarok::Plugin;
33 vector<PluginManager::StoreItem>
34 PluginManager::m_store;
37 /////////////////////////////////////////////////////////////////////////////////////
38 // PUBLIC INTERFACE
39 /////////////////////////////////////////////////////////////////////////////////////
41 KService::List
42 PluginManager::query( const QString& constraint )
44 // Add versioning constraint
45 QString
46 str = "[X-KDE-Amarok-framework-version] == ";
47 str += QString::number( FrameworkVersion );
48 if ( !constraint.trimmed().isEmpty() )
49 str += " and " + constraint;
50 str += " and ";
51 str += "[X-KDE-Amarok-rank] > 0";
53 debug() << "Plugin trader constraint: " << str;
55 return KServiceTypeTrader::self()->query( "Amarok/Plugin", str );
59 Plugin*
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";
68 return 0;
71 // Select plugin with highest rank
72 int rank = 0;
73 uint current = 0;
74 for ( int i = 0; i < offers.count(); i++ ) {
75 if ( offers[i]->property( "X-KDE-Amarok-rank" ).toInt() > rank )
76 current = i;
79 return createFromService( offers[current] );
83 Plugin*
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 );
93 if ( !lib ) {
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() ) );
98 return 0;
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";
105 return 0;
107 //create plugin on the heap
108 Plugin* plugin = create_plugin();
110 //put plugin into store
111 StoreItem item;
112 item.plugin = plugin;
113 item.library = lib;
114 item.service = service;
115 m_store.push_back( item );
117 dump( service );
118 return plugin;
122 void
123 PluginManager::unload( Plugin* plugin )
125 DEBUG_FUNC_INFO
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 );
136 else
137 warning() << "Could not unload plugin (not found in store).\n";
141 KService::Ptr
142 PluginManager::getService( const Plugin* plugin )
144 if ( !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;
161 void
162 PluginManager::showAbout( const QString &constraint )
164 KService::List offers = query( constraint );
166 if ( offers.isEmpty() )
167 return;
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" ) );
188 void
189 PluginManager::dump( const KService::Ptr service )
191 #define ENDLI endl << Debug::indent()
193 debug()
194 << ENDLI
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()
206 << endl
209 #undef ENDLI
213 /////////////////////////////////////////////////////////////////////////////////////
214 // PRIVATE INTERFACE
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 )
226 break;
229 return iter;