broker.cpp

00001 // -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*-
00022 #include "broker.h"
00023 #include "settings.h"
00024 #include "client.h"
00025 #include "defaultdictionary.h"
00026 #include "dictionary.h"
00027 
00028 #include <kparts/plugin.h>
00029 #include <kparts/componentfactory.h>
00030 
00031 #include <kplugininfo.h>
00032 #include <ktrader.h>
00033 #include <kconfig.h>
00034 
00035 #include <kdebug.h>
00036 
00037 #include <qptrdict.h>
00038 #include <qmap.h>
00039 
00040 #define DEFAULT_CONFIG_FILE   "kspellrc"
00041 
00042 namespace KSpell2
00043 {
00044 
00045 class Broker::Private
00046 {
00047 public:
00048     KPluginInfo::List plugins;
00049     Settings *settings;
00050 
00051     // <language, Clients with that language >
00052     QMap<QString, QPtrList<Client> > languageClients;
00053     QStringList clients;
00054     DefaultDictionary *defaultDictionary;
00055 };
00056 
00057 QPtrDict<Broker> *Broker::s_brokers = 0;
00058 
00059 Broker *Broker::openBroker( KSharedConfig *config )
00060 {
00061     KSharedConfig::Ptr preventDeletion;
00062     if ( !config ) {
00063         preventDeletion = KSharedConfig::openConfig( DEFAULT_CONFIG_FILE );
00064     } else
00065         preventDeletion = config;
00066 
00067     if ( s_brokers ) {
00068         Broker *broker = s_brokers->find( preventDeletion );
00069         if ( broker )
00070             return broker;
00071     }
00072 
00073     Broker *broker = new Broker( preventDeletion );
00074     return broker;
00075 }
00076 
00077 Broker::Broker( KSharedConfig *config )
00078 {
00079     KSharedConfig::Ptr preventDeletion( config );
00080     Q_UNUSED( preventDeletion );
00081 
00082     if ( !s_brokers )
00083         s_brokers = new QPtrDict<Broker>;
00084     s_brokers->insert( config, this );
00085 
00086     d = new Private;
00087     d->settings = new Settings( this, config );
00088     loadPlugins();
00089 
00090     d->defaultDictionary = new DefaultDictionary( d->settings->defaultLanguage(),
00091                                                   this );
00092 }
00093 
00094 Broker::~Broker()
00095 {
00096     kdDebug()<<"Removing broker : "<< this << endl;
00097     s_brokers->remove( d->settings->sharedConfig() );
00098     KPluginInfo::List::iterator it = d->plugins.begin();
00099     while ( it != d->plugins.end() ) {
00100         KPluginInfo *pluginInfo = *it;
00101         it = d->plugins.remove( it );
00102         delete pluginInfo;
00103     }
00104 
00105     delete d->settings; d->settings = 0;
00106     delete d; d = 0;
00107 }
00108 
00109 DefaultDictionary* Broker::defaultDictionary() const
00110 {
00111     return d->defaultDictionary;
00112 }
00113 
00114 Dictionary* Broker::dictionary( const QString& language, const QString& clientName ) const
00115 {
00116     QString pclient = clientName;
00117     QString plang   = language;
00118     bool ddefault = false;
00119 
00120     if ( plang.isEmpty() ) {
00121         plang = d->settings->defaultLanguage();
00122     }
00123     if ( clientName == d->settings->defaultClient() &&
00124         plang == d->settings->defaultLanguage() ) {
00125         ddefault = true;
00126     }
00127 
00128     QPtrList<Client> lClients = d->languageClients[ plang ];
00129 
00130     if ( lClients.isEmpty() ) {
00131         kdError()<<"No language dictionaries for the language : "<< plang <<endl;
00132         return 0;
00133     }
00134 
00135     QPtrListIterator<Client> itr( lClients );
00136     while ( itr.current() ) {
00137         if ( !pclient.isEmpty() ) {
00138             if ( pclient == itr.current()->name() ) {
00139                 Dictionary *dict = itr.current()->dictionary( plang );
00140                 if ( dict ) //remove the if if the assert proves ok
00141                     dict->m_default = ddefault;
00142                 return dict;
00143             }
00144         } else {
00145             //the first one is the one with the highest
00146             //reliability
00147             Dictionary *dict = itr.current()->dictionary( plang );
00148             Q_ASSERT( dict );
00149             if ( dict ) //remove the if if the assert proves ok
00150                 dict->m_default = ddefault;
00151             return dict;
00152         }
00153         ++itr;
00154     }
00155 
00156     return 0;
00157 }
00158 
00159 QStringList Broker::clients() const
00160 {
00161     return d->clients;
00162 }
00163 
00164 QStringList Broker::languages() const
00165 {
00166     return d->languageClients.keys();
00167 }
00168 
00169 Settings* Broker::settings() const
00170 {
00171     return d->settings;
00172 }
00173 
00174 void Broker::loadPlugins()
00175 {
00176     d->plugins = KPluginInfo::fromServices(
00177         KTrader::self()->query( "KSpell/Client" ) );
00178 
00179     for ( KPluginInfo::List::Iterator itr = d->plugins.begin();
00180           itr != d->plugins.end(); ++itr ) {
00181         loadPlugin( ( *itr )->pluginName() );
00182     }
00183 }
00184 
00185 void Broker::loadPlugin( const QString& pluginId )
00186 {
00187     int error = 0;
00188 
00189     kdDebug()<<"Loading plugin " << pluginId << endl;
00190 
00191     Client *client = KParts::ComponentFactory::createInstanceFromQuery<Client>(
00192         QString::fromLatin1( "KSpell/Client" ),
00193         QString::fromLatin1( "[X-KDE-PluginInfo-Name]=='%1'" ).arg( pluginId ),
00194         this, 0, QStringList(), &error );
00195 
00196     if ( client )
00197     {
00198         QStringList languages = client->languages();
00199         d->clients.append( client->name() );
00200 
00201         for ( QStringList::Iterator itr = languages.begin();
00202               itr != languages.end(); ++itr ) {
00203             if ( !d->languageClients[ *itr ].isEmpty() &&
00204                  client->reliability() < d->languageClients[ *itr ].first()->reliability() )
00205                 d->languageClients[ *itr ].append( client );
00206             else
00207                 d->languageClients[ *itr ].prepend( client );
00208         }
00209 
00210         kdDebug() << k_funcinfo << "Successfully loaded plugin '"
00211                   << pluginId << "'" << endl;
00212     }
00213     else
00214     {
00215         switch( error )
00216         {
00217         case KParts::ComponentFactory::ErrNoServiceFound:
00218             kdDebug() << k_funcinfo << "No service implementing the given mimetype "
00219                       << "and fullfilling the given constraint expression can be found."
00220                       << endl;
00221             break;
00222         case KParts::ComponentFactory::ErrServiceProvidesNoLibrary:
00223             kdDebug() << "the specified service provides no shared library." << endl;
00224             break;
00225         case KParts::ComponentFactory::ErrNoLibrary:
00226             kdDebug() << "the specified library could not be loaded." << endl;
00227             break;
00228         case KParts::ComponentFactory::ErrNoFactory:
00229             kdDebug() << "the library does not export a factory for creating components."
00230                       << endl;
00231             break;
00232         case KParts::ComponentFactory::ErrNoComponent:
00233             kdDebug() << "the factory does not support creating "
00234                       << "components of the specified type."
00235                       << endl;
00236             break;
00237         }
00238 
00239         kdDebug() << k_funcinfo << "Loading plugin '" << pluginId
00240                   << "' failed, KLibLoader reported error: '" << endl
00241                   << KLibLoader::self()->lastErrorMessage() << "'" << endl;
00242     }
00243 }
00244 
00245 void Broker::changed()
00246 {
00247     emit configurationChanged();
00248 }
00249 
00250 }
00251 
00252 #include "broker.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys