KDECore
loader.cpp
Go to the documentation of this file.
00001 // -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- 00021 #include "loader_p.h" 00022 #include "settings_p.h" 00023 #include "client_p.h" 00024 #include "spellerplugin_p.h" 00025 00026 #include <klocale.h> 00027 #include <kservicetypetrader.h> 00028 00029 #include <kconfig.h> 00030 #include <kdebug.h> 00031 00032 #include <QtCore/QHash> 00033 #include <QtCore/QMap> 00034 00035 #define DEFAULT_CONFIG_FILE "sonnetrc" 00036 00037 namespace Sonnet 00038 { 00039 00040 class Loader::Private 00041 { 00042 public: 00043 KService::List plugins; 00044 Settings *settings; 00045 00046 // <language, Clients with that language > 00047 QMap<QString, QList<Client*> > languageClients; 00048 QStringList clients; 00049 00050 QStringList languagesNameCache; 00051 }; 00052 00053 K_GLOBAL_STATIC(Loader, s_loader) 00054 00055 Loader *Loader::openLoader() 00056 { 00057 if (s_loader.isDestroyed()) { 00058 return 0; 00059 } 00060 00061 return s_loader; 00062 } 00063 00064 Loader::Loader() 00065 :d(new Private) 00066 { 00067 d->settings = new Settings(this); 00068 KConfig config(QString::fromLatin1(DEFAULT_CONFIG_FILE)); 00069 d->settings->restore(&config); 00070 loadPlugins(); 00071 } 00072 00073 Loader::~Loader() 00074 { 00075 //kDebug()<<"Removing loader : "<< this; 00076 d->plugins.clear(); 00077 delete d->settings; d->settings = 0; 00078 delete d; 00079 } 00080 00081 SpellerPlugin *Loader::createSpeller(const QString& language, 00082 const QString& clientName) const 00083 { 00084 QString pclient = clientName; 00085 QString plang = language; 00086 bool ddefault = false; 00087 00088 if (plang.isEmpty()) { 00089 plang = d->settings->defaultLanguage(); 00090 } 00091 if (clientName == d->settings->defaultClient() && 00092 plang == d->settings->defaultLanguage()) { 00093 ddefault = true; 00094 } 00095 00096 const QList<Client*> lClients = d->languageClients[plang]; 00097 00098 if (lClients.isEmpty()) { 00099 kError()<<"No language dictionaries for the language : " 00100 << plang <<endl; 00101 return 0; 00102 } 00103 00104 QListIterator<Client*> itr(lClients); 00105 while (itr.hasNext()) { 00106 Client* item = itr.next(); 00107 if (!pclient.isEmpty()) { 00108 if (pclient == item->name()) { 00109 SpellerPlugin *dict = item->createSpeller(plang); 00110 return dict; 00111 } 00112 } else { 00113 //the first one is the one with the highest 00114 //reliability 00115 SpellerPlugin *dict = item->createSpeller(plang); 00116 return dict; 00117 } 00118 } 00119 00120 return 0; 00121 } 00122 00123 QStringList Loader::clients() const 00124 { 00125 return d->clients; 00126 } 00127 00128 QStringList Loader::languages() const 00129 { 00130 return d->languageClients.keys(); 00131 } 00132 00133 QString Loader::languageNameForCode(const QString &langCode) const 00134 { 00135 QString currentDictionary = langCode, // e.g. en_GB-ize-wo_accents 00136 lISOName, // language ISO name 00137 cISOName, // country ISO name 00138 variantName, // dictionary variant name e.g. w_accents 00139 localizedLang, // localized language 00140 localizedCountry; // localized country 00141 QByteArray variantEnglish; // dictionary variant in English 00142 00143 int underscorePos, // position of "_" char 00144 minusPos, // position of "-" char 00145 variantCount = 0; // used to iterate over variantList 00146 00147 struct variantListType 00148 { 00149 const char* variantShortName; 00150 const char* variantEnglishName; 00151 }; 00152 00153 const variantListType variantList[] = { 00154 { "40", I18N_NOOP2("dictionary variant", "40") }, // what does 40 mean? 00155 { "60", I18N_NOOP2("dictionary variant", "60") }, // what does 60 mean? 00156 { "80", I18N_NOOP2("dictionary variant", "80") }, // what does 80 mean? 00157 { "ise", I18N_NOOP2("dictionary variant", "-ise suffixes") }, 00158 { "ize", I18N_NOOP2("dictionary variant", "-ize suffixes") }, 00159 { "ise-w_accents", I18N_NOOP2("dictionary variant", "-ise suffixes and with accents") }, 00160 { "ise-wo_accents", I18N_NOOP2("dictionary variant", "-ise suffixes and without accents") }, 00161 { "ize-w_accents", I18N_NOOP2("dictionary variant", "-ize suffixes and with accents") }, 00162 { "ize-wo_accents", I18N_NOOP2("dictionary variant", "-ize suffixes and without accents") }, 00163 { "lrg", I18N_NOOP2("dictionary variant", "large") }, 00164 { "med", I18N_NOOP2("dictionary variant", "medium") }, 00165 { "sml", I18N_NOOP2("dictionary variant", "small") }, 00166 { "variant_0", I18N_NOOP2("dictionary variant", "variant 0") }, 00167 { "variant_1", I18N_NOOP2("dictionary variant", "variant 1") }, 00168 { "variant_2", I18N_NOOP2("dictionary variant", "variant 2") }, 00169 { "wo_accents", I18N_NOOP2("dictionary variant", "without accents") }, 00170 { "w_accents", I18N_NOOP2("dictionary variant", "with accents") }, 00171 { "ye", I18N_NOOP2("dictionary variant", "with ye") }, 00172 { "yeyo", I18N_NOOP2("dictionary variant", "with yeyo") }, 00173 { "yo", I18N_NOOP2("dictionary variant", "with yo") }, 00174 { "extended", I18N_NOOP2("dictionary variant", "extended") }, 00175 { 0, 0 } 00176 }; 00177 00178 minusPos = currentDictionary.indexOf(QLatin1Char('-')); 00179 underscorePos = currentDictionary.indexOf(QLatin1Char('_')); 00180 if (underscorePos != -1 && underscorePos <= 3) { 00181 cISOName = currentDictionary.mid(underscorePos + 1, 2); 00182 lISOName = currentDictionary.left(underscorePos); 00183 if ( minusPos != -1 ) 00184 variantName = currentDictionary.right( 00185 currentDictionary.length() - minusPos - 1); 00186 } else { 00187 if ( minusPos != -1 ) { 00188 variantName = currentDictionary.right( 00189 currentDictionary.length() - minusPos - 1); 00190 lISOName = currentDictionary.left(minusPos); 00191 } 00192 else 00193 lISOName = currentDictionary; 00194 } 00195 localizedLang = KGlobal::locale()->languageCodeToName(lISOName); 00196 if (localizedLang.isEmpty()) 00197 localizedLang = lISOName; 00198 if (!cISOName.isEmpty()) { 00199 if (!KGlobal::locale()->countryCodeToName(cISOName).isEmpty()) 00200 localizedCountry = KGlobal::locale()->countryCodeToName(cISOName); 00201 else 00202 localizedCountry = cISOName; 00203 } 00204 if (!variantName.isEmpty()) { 00205 while (variantList[variantCount].variantShortName != 0) 00206 if (QLatin1String(variantList[variantCount].variantShortName) == variantName) 00207 break; 00208 else 00209 variantCount++; 00210 if (variantList[variantCount].variantShortName != 0) 00211 variantEnglish = variantList[variantCount].variantEnglishName; 00212 else 00213 variantEnglish = variantName.toLatin1(); 00214 } 00215 if (!cISOName.isEmpty() && !variantName.isEmpty()) 00216 return i18nc( 00217 "dictionary name. %1-language, %2-country and %3 variant name", 00218 "%1 (%2) [%3]", localizedLang, localizedCountry, 00219 i18nc( "dictionary variant", variantEnglish)); 00220 else if (!cISOName.isEmpty()) 00221 return i18nc( 00222 "dictionary name. %1-language and %2-country name", 00223 "%1 (%2)", localizedLang, localizedCountry); 00224 else if (!variantName.isEmpty()) 00225 return i18nc( 00226 "dictionary name. %1-language and %2-variant name", 00227 "%1 [%2]", localizedLang, 00228 i18nc("dictionary variant", variantEnglish)); 00229 else 00230 return localizedLang; 00231 } 00232 00233 QStringList Loader::languageNames() const 00234 { 00235 /* For whatever reason languages() might change. So, 00236 * to be in sync with it let's do the following check. 00237 */ 00238 if (d->languagesNameCache.count() == languages().count() ) 00239 return d->languagesNameCache; 00240 00241 QStringList allLocalizedDictionaries; 00242 const QStringList allDictionaries = languages(); 00243 00244 for (QStringList::ConstIterator it = allDictionaries.begin(); 00245 it != allDictionaries.end(); ++it) { 00246 allLocalizedDictionaries.append(languageNameForCode(*it)); 00247 } 00248 // cache the list 00249 d->languagesNameCache = allLocalizedDictionaries; 00250 return allLocalizedDictionaries; 00251 } 00252 00253 Settings* Loader::settings() const 00254 { 00255 return d->settings; 00256 } 00257 00258 void Loader::loadPlugins() 00259 { 00260 d->plugins = KServiceTypeTrader::self()->query(QString::fromLatin1("Sonnet/SpellClient")); 00261 00262 for (KService::List::const_iterator itr = d->plugins.constBegin(); 00263 itr != d->plugins.constEnd(); ++itr ) { 00264 loadPlugin((*itr)); 00265 } 00266 } 00267 00268 void Loader::loadPlugin(const KSharedPtr<KService> &service) 00269 { 00270 QString error; 00271 00272 Client *client = service->createInstance<Client>(this, 00273 QVariantList(), 00274 &error); 00275 00276 if (client) { 00277 const QStringList languages = client->languages(); 00278 d->clients.append(client->name()); 00279 00280 for (QStringList::const_iterator itr = languages.begin(); 00281 itr != languages.end(); ++itr) { 00282 if (!d->languageClients[*itr].isEmpty() && 00283 client->reliability() < 00284 d->languageClients[*itr].first()->reliability()) 00285 d->languageClients[*itr].append(client); 00286 else 00287 d->languageClients[*itr].prepend(client); 00288 } 00289 00290 //kDebug() << "Successfully loaded plugin:" << service->entryPath(); 00291 } else { 00292 kDebug() << error; 00293 } 00294 } 00295 00296 void Loader::changed() 00297 { 00298 emit configurationChanged(); 00299 } 00300 00301 } 00302 00303 #include "loader_p.moc"
KDE 4.6 API Reference