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 <tqptrdict.h> 00038 #include <tqmap.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 TQMap<TQString, TQPtrList<Client> > languageClients; 00053 TQStringList clients; 00054 DefaultDictionary *defaultDictionary; 00055 }; 00056 00057 TQPtrDict<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 TQPtrDict<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 TQString& language, const TQString& clientName ) const 00115 { 00116 TQString pclient = clientName; 00117 TQString 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 TQPtrList<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 TQPtrListIterator<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 TQStringList Broker::clients() const 00160 { 00161 return d->clients; 00162 } 00163 00164 TQStringList 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 TQString& pluginId ) 00186 { 00187 int error = 0; 00188 00189 kdDebug()<<"Loading plugin " << pluginId << endl; 00190 00191 Client *client = KParts::ComponentFactory::createInstanceFromQuery<Client>( 00192 TQString::fromLatin1( "KSpell/Client" ), 00193 TQString::fromLatin1( "[X-KDE-PluginInfo-Name]=='%1'" ).arg( pluginId ), 00194 this, 0, TQStringList(), &error ); 00195 00196 if ( client ) 00197 { 00198 TQStringList languages = client->languages(); 00199 d->clients.append( client->name() ); 00200 00201 for ( TQStringList::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"