akregator/src

pluginmanager.cpp

00001 /***************************************************************************
00002 begin                : 2004/03/12
00003 copyright            : (C) Mark Kretschmann
00004 email                : markey@web.de
00005 ***************************************************************************/
00006 
00007 /***************************************************************************
00008  *                                                                         *
00009  *   This program is free software; you can redistribute it and/or modify  *
00010  *   it under the terms of the GNU General Public License as published by  *
00011  *   the Free Software Foundation; either version 2 of the License, or     *
00012  *   (at your option) any later version.                                   *
00013  *                                                                         *
00014  ***************************************************************************/
00015 
00016 #include "plugin.h"
00017 #include "pluginmanager.h"
00018 
00019 #include <vector>
00020 
00021 #include <qfile.h>
00022 #include <qstring.h>
00023 
00024 #include <klibloader.h>
00025 #include <kdebug.h>
00026 #include <klocale.h>
00027 #include <kmessagebox.h>
00028 
00029 using std::vector;
00030 using Akregator::Plugin;
00031 
00032 namespace Akregator {
00033 
00034 vector<PluginManager::StoreItem>
00035 PluginManager::m_store;
00036 
00037 
00039 // PUBLIC INTERFACE
00041 
00042 KTrader::OfferList
00043 PluginManager::query( const QString& constraint )
00044 {
00045     // Add versioning constraint
00046     QString
00047     str  = "[X-KDE-akregator-framework-version] == ";
00048     str += QString::number( FrameworkVersion );
00049     str += " and ";
00050     if (!constraint.stripWhiteSpace().isEmpty())
00051         str += constraint + " and ";
00052     str += "[X-KDE-akregator-rank] > 0";
00053 
00054     kdDebug() << "Plugin trader constraint: " << str << endl;
00055 
00056     return KTrader::self()->query( "Akregator/Plugin", str );
00057 }
00058 
00059 
00060 Plugin*
00061 PluginManager::createFromQuery( const QString &constraint )
00062 {
00063     KTrader::OfferList offers = query( constraint );
00064 
00065     if ( offers.isEmpty() ) {
00066         kdWarning() << k_funcinfo << "No matching plugin found.\n";
00067         return 0;
00068     }
00069 
00070     // Select plugin with highest rank
00071     int rank = 0;
00072     uint current = 0;
00073     for ( uint i = 0; i < offers.count(); i++ ) {
00074         if ( offers[i]->property( "X-KDE-akregator-rank" ).toInt() > rank )
00075             current = i;
00076     }
00077 
00078     return createFromService( offers[current] );
00079 }
00080 
00081 
00082 Plugin*
00083 PluginManager::createFromService( const KService::Ptr service )
00084 {
00085     kdDebug() << "Trying to load: " << service->library() << endl;
00086 
00087     //get the library loader instance
00088     KLibLoader *loader = KLibLoader::self();
00089     //try to load the specified library
00090     KLibrary *lib = loader->globalLibrary( QFile::encodeName( service->library() ) );
00091 
00092     if ( !lib ) {
00093         KMessageBox::error( 0, i18n( "<p>KLibLoader could not load the plugin:<br/><i>%1</i></p>"
00094                                      "<p>Error message:<br/><i>%2</i></p>" )
00095                                .arg( service->library() )
00096                                .arg( loader->lastErrorMessage() ) );
00097         return 0;
00098     }
00099     //look up address of init function and cast it to pointer-to-function
00100     Plugin* (*create_plugin)() = ( Plugin* (*)() ) lib->symbol( "create_plugin" );
00101 
00102     if ( !create_plugin ) {
00103         kdWarning() << k_funcinfo << "create_plugin == NULL\n";
00104         return 0;
00105     }
00106     //create plugin on the heap
00107     Plugin* plugin = create_plugin();
00108 
00109     //put plugin into store
00110     StoreItem item;
00111     item.plugin = plugin;
00112     item.library = lib;
00113     item.service = service;
00114     m_store.push_back( item );
00115 
00116     dump( service );
00117     return plugin;
00118 }
00119 
00120 
00121 void
00122 PluginManager::unload( Plugin* plugin )
00123 {
00124     vector<StoreItem>::iterator iter = lookupPlugin( plugin );
00125 
00126     if ( iter != m_store.end() ) {
00127         delete (*iter).plugin;
00128         kdDebug() << "Unloading library: "<< (*iter).service->library() << endl;
00129         (*iter).library->unload();
00130 
00131         m_store.erase( iter );
00132     }
00133     else
00134         kdWarning() << k_funcinfo << "Could not unload plugin (not found in store).\n";
00135 }
00136 
00137 
00138 KService::Ptr
00139 PluginManager::getService( const Plugin* plugin )
00140 {
00141     if ( !plugin ) {
00142         kdWarning() << k_funcinfo << "pointer == NULL\n";
00143         return 0;
00144     }
00145 
00146     //search plugin in store
00147     vector<StoreItem>::const_iterator iter = lookupPlugin( plugin );
00148 
00149     if ( iter == m_store.end() )
00150         kdWarning() << k_funcinfo << "Plugin not found in store.\n";
00151 
00152     return (*iter).service;
00153 }
00154 
00155 
00156 void
00157 PluginManager::showAbout( const QString &constraint )
00158 {
00159     KTrader::OfferList offers = query( constraint );
00160 
00161     if ( offers.isEmpty() )
00162         return;
00163 
00164     KService::Ptr s = offers.front();
00165 
00166     const QString body = "<tr><td>%1</td><td>%2</td></tr>";
00167 
00168     QString str  = "<html><body><table width=\"100%\" border=\"1\">";
00169 
00170     str += body.arg( i18n( "Name" ),                s->name() );
00171     str += body.arg( i18n( "Library" ),             s->library() );
00172     str += body.arg( i18n( "Authors" ),             s->property( "X-KDE-akregator-authors" ).toStringList().join( "\n" ) );
00173     str += body.arg( i18n( "Email" ),               s->property( "X-KDE-akregator-email" ).toStringList().join( "\n" ) );
00174     str += body.arg( i18n( "Version" ),             s->property( "X-KDE-akregator-version" ).toString() );
00175     str += body.arg( i18n( "Framework Version" ),   s->property( "X-KDE-akregator-framework-version" ).toString() );
00176 
00177     str += "</table></body></html>";
00178 
00179     KMessageBox::information( 0, str, i18n( "Plugin Information" ) );
00180 }
00181 
00182 
00183 void
00184 PluginManager::dump( const KService::Ptr service )
00185 {
00186     kdDebug()
00187       << "PluginManager Service Info:" << endl
00188       << "---------------------------" << endl
00189       << "name                          : " << service->name() << endl
00190       << "library                       : " << service->library() << endl
00191       << "desktopEntryPath              : " << service->desktopEntryPath() << endl
00192       << "X-KDE-akregator-plugintype       : " << service->property( "X-KDE-akregator-plugintype" ).toString() << endl
00193       << "X-KDE-akregator-name             : " << service->property( "X-KDE-akregator-name" ).toString() << endl
00194       << "X-KDE-akregator-authors          : " << service->property( "X-KDE-akregator-authors" ).toStringList() << endl
00195       << "X-KDE-akregator-rank             : " << service->property( "X-KDE-akregator-rank" ).toString() << endl
00196       << "X-KDE-akregator-version          : " << service->property( "X-KDE-akregator-version" ).toString() << endl
00197       << "X-KDE-akregator-framework-version: " << service->property( "X-KDE-akregator-framework-version" ).toString()
00198       << endl;
00199 
00200 }
00201 
00202 
00204 // PRIVATE INTERFACE
00206 
00207 vector<PluginManager::StoreItem>::iterator
00208 PluginManager::lookupPlugin( const Plugin* plugin )
00209 {
00210     vector<StoreItem>::iterator iter;
00211 
00212     //search plugin pointer in store
00213     vector<StoreItem>::const_iterator end;
00214     for ( iter = m_store.begin(); iter != end; ++iter ) {
00215         if ( (*iter).plugin == plugin )
00216             break;
00217     }
00218 
00219     return iter;
00220 }
00221 
00222 } // namespace Akregator
KDE Home | KDE Accessibility Home | Description of Access Keys