00001
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
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(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 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
00114
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,
00136 lISOName,
00137 cISOName,
00138 variantName,
00139 localizedLang,
00140 localizedCountry;
00141 QByteArray variantEnglish;
00142
00143 int underscorePos,
00144 minusPos,
00145 variantCount = 0;
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") },
00155 { "60", I18N_NOOP2("dictionary variant", "60") },
00156 { "80", I18N_NOOP2("dictionary variant", "80") },
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("-");
00179 underscorePos = currentDictionary.indexOf("_");
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 (variantList[ variantCount ].variantShortName ==
00207 variantName)
00208 break;
00209 else
00210 variantCount++;
00211 if (variantList[variantCount].variantShortName != 0)
00212 variantEnglish = variantList[variantCount].variantEnglishName;
00213 else
00214 variantEnglish = variantName.toLatin1();
00215 }
00216 if (!cISOName.isEmpty() && !variantName.isEmpty())
00217 return i18nc(
00218 "dictionary name. %1-language, %2-country and %3 variant name",
00219 "%1 (%2) [%3]", localizedLang, localizedCountry,
00220 i18nc( "dictionary variant", variantEnglish));
00221 else if (!cISOName.isEmpty())
00222 return i18nc(
00223 "dictionary name. %1-language and %2-country name",
00224 "%1 (%2)", localizedLang, localizedCountry);
00225 else if (!variantName.isEmpty())
00226 return i18nc(
00227 "dictionary name. %1-language and %2-variant name",
00228 "%1 [%2]", localizedLang,
00229 i18nc("dictionary variant", variantEnglish));
00230 else
00231 return localizedLang;
00232 }
00233
00234 QStringList Loader::languageNames() const
00235 {
00236
00237
00238
00239 if (d->languagesNameCache.count() == languages().count() )
00240 return d->languagesNameCache;
00241
00242 QStringList allLocalizedDictionaries;
00243 const QStringList allDictionaries = languages();
00244
00245 for (QStringList::ConstIterator it = allDictionaries.begin();
00246 it != allDictionaries.end(); ++it) {
00247 allLocalizedDictionaries.append(languageNameForCode(*it));
00248 }
00249
00250 d->languagesNameCache = allLocalizedDictionaries;
00251 return allLocalizedDictionaries;
00252 }
00253
00254 Settings* Loader::settings() const
00255 {
00256 return d->settings;
00257 }
00258
00259 void Loader::loadPlugins()
00260 {
00261 d->plugins = KServiceTypeTrader::self()->query("Sonnet/SpellClient");
00262
00263 for (KService::List::const_iterator itr = d->plugins.constBegin();
00264 itr != d->plugins.constEnd(); ++itr ) {
00265 loadPlugin((*itr));
00266 }
00267 }
00268
00269 void Loader::loadPlugin(const KSharedPtr<KService> &service)
00270 {
00271 QString error;
00272
00273 Client *client = service->createInstance<Client>(this,
00274 QVariantList(),
00275 &error);
00276
00277 if (client) {
00278 const QStringList languages = client->languages();
00279 d->clients.append(client->name());
00280
00281 for (QStringList::const_iterator itr = languages.begin();
00282 itr != languages.end(); ++itr) {
00283 if (!d->languageClients[*itr].isEmpty() &&
00284 client->reliability() <
00285 d->languageClients[*itr].first()->reliability())
00286 d->languageClients[*itr].append(client);
00287 else
00288 d->languageClients[*itr].prepend(client);
00289 }
00290
00291 kDebug() << "Successfully loaded plugin:" << service->entryPath();
00292 } else {
00293 kDebug() << error;
00294 }
00295 }
00296
00297 void Loader::changed()
00298 {
00299 emit configurationChanged();
00300 }
00301
00302 }
00303
00304 #include "loader_p.moc"