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 Q_ASSERT(dict);
00117 return dict;
00118 }
00119 }
00120
00121 return 0;
00122 }
00123
00124 QStringList Loader::clients() const
00125 {
00126 return d->clients;
00127 }
00128
00129 QStringList Loader::languages() const
00130 {
00131 return d->languageClients.keys();
00132 }
00133
00134 QStringList Loader::languageNames() const
00135 {
00136
00137
00138
00139 if (d->languagesNameCache.count() == languages().count() )
00140 return d->languagesNameCache;
00141
00142 QStringList allLocalizedDictionaries;
00143 const QStringList allDictionaries = languages();
00144 QString currentDictionary,
00145 lISOName,
00146 cISOName,
00147 variantName,
00148 localizedLang,
00149 localizedCountry;
00150 QByteArray variantEnglish;
00151
00152 int underscorePos,
00153 minusPos,
00154 variantCount = 0;
00155
00156 struct variantListType
00157 {
00158 const char* variantShortName;
00159 const char* variantEnglishName;
00160 };
00161 const variantListType variantList[] = {
00162 { "40", I18N_NOOP2("dictionary variant", "40") },
00163 { "60", I18N_NOOP2("dictionary variant", "60") },
00164 { "80", I18N_NOOP2("dictionary variant", "80") },
00165 { "ise", I18N_NOOP2("dictionary variant", "-ise suffixes") },
00166 { "ize", I18N_NOOP2("dictionary variant", "-ize suffixes") },
00167 { "ise-w_accents", I18N_NOOP2("dictionary variant", "-ise suffixes and with accents") },
00168 { "ise-wo_accents", I18N_NOOP2("dictionary variant", "-ise suffixes and without accents") },
00169 { "ize-w_accents", I18N_NOOP2("dictionary variant", "-ize suffixes and with accents") },
00170 { "ize-wo_accents", I18N_NOOP2("dictionary variant", "-ize suffixes and without accents") },
00171 { "lrg", I18N_NOOP2("dictionary variant", "large") },
00172 { "med", I18N_NOOP2("dictionary variant", "medium") },
00173 { "sml", I18N_NOOP2("dictionary variant", "small") },
00174 { "variant_0", I18N_NOOP2("dictionary variant", "variant 0") },
00175 { "variant_1", I18N_NOOP2("dictionary variant", "variant 1") },
00176 { "variant_2", I18N_NOOP2("dictionary variant", "variant 2") },
00177 { "wo_accents", I18N_NOOP2("dictionary variant", "without accents") },
00178 { "w_accents", I18N_NOOP2("dictionary variant", "with accents") },
00179 { "ye", I18N_NOOP2("dictionary variant", "with ye") },
00180 { "yeyo", I18N_NOOP2("dictionary variant", "with yeyo") },
00181 { "yo", I18N_NOOP2("dictionary variant", "with yo") },
00182 { "extended", I18N_NOOP2("dictionary variant", "extended") },
00183 { 0, 0 }
00184 };
00185
00186 for (QStringList::ConstIterator it = allDictionaries.begin();
00187 it != allDictionaries.end(); ++it) {
00188 currentDictionary = *it;
00189 minusPos = currentDictionary.indexOf("-");
00190 underscorePos = currentDictionary.indexOf("_");
00191 if (underscorePos != -1 && underscorePos <= 3) {
00192 cISOName = currentDictionary.mid(underscorePos + 1, 2);
00193 lISOName = currentDictionary.left(underscorePos);
00194 if ( minusPos != -1 )
00195 variantName = currentDictionary.right(
00196 currentDictionary.length() - minusPos - 1);
00197 } else {
00198 if ( minusPos != -1 ) {
00199 variantName = currentDictionary.right(
00200 currentDictionary.length() - minusPos - 1);
00201 lISOName = currentDictionary.left(minusPos);
00202 }
00203 else
00204 lISOName = currentDictionary;
00205 }
00206 localizedLang = KGlobal::locale()->languageCodeToName(lISOName);
00207 if (localizedLang.isEmpty())
00208 localizedLang = lISOName;
00209 if (!cISOName.isEmpty())
00210 if (!KGlobal::locale()->countryCodeToName(cISOName).isEmpty())
00211 localizedCountry = KGlobal::locale()->countryCodeToName(
00212 cISOName);
00213 else
00214 localizedCountry = cISOName;
00215 if (!variantName.isEmpty()) {
00216 while (variantList[variantCount].variantShortName != 0)
00217 if (variantList[ variantCount ].variantShortName ==
00218 variantName)
00219 break;
00220 else
00221 variantCount++;
00222 if (variantList[variantCount].variantShortName != 0)
00223 variantEnglish = variantList[variantCount].variantEnglishName;
00224 else
00225 variantEnglish = variantName.toLatin1();
00226 }
00227 if (!cISOName.isEmpty() && !variantName.isEmpty())
00228 allLocalizedDictionaries.append(
00229 i18nc(
00230 "dictionary name. %1-language, %2-country and %3 variant name",
00231 "%1 (%2) [%3]", localizedLang, localizedCountry,
00232 i18nc( "dictionary variant", variantEnglish)));
00233 else
00234 if (!cISOName.isEmpty())
00235 allLocalizedDictionaries.append(
00236 i18nc(
00237 "dictionary name. %1-language and %2-country name",
00238 "%1 (%2)", localizedLang, localizedCountry));
00239 else
00240 if (!variantName.isEmpty())
00241 allLocalizedDictionaries.append(
00242 i18nc(
00243 "dictionary name. %1-language and %2-variant name",
00244 "%1 [%2]", localizedLang,
00245 i18nc("dictionary variant", variantEnglish)));
00246 else
00247 allLocalizedDictionaries.append(localizedLang);
00248 lISOName = cISOName = variantName = "";
00249 variantCount = 0;
00250 }
00251
00252 d->languagesNameCache = allLocalizedDictionaries;
00253 return allLocalizedDictionaries;
00254 }
00255
00256 Settings* Loader::settings() const
00257 {
00258 return d->settings;
00259 }
00260
00261 void Loader::loadPlugins()
00262 {
00263 d->plugins = KServiceTypeTrader::self()->query("Sonnet/SpellClient");
00264
00265 for (KService::List::const_iterator itr = d->plugins.begin();
00266 itr != d->plugins.end(); ++itr ) {
00267 loadPlugin((*itr));
00268 }
00269 }
00270
00271 void Loader::loadPlugin(const KSharedPtr<KService> &service)
00272 {
00273 QString error;
00274
00275 Client *client = service->createInstance<Client>(this,
00276 QVariantList(),
00277 &error);
00278
00279 if (client) {
00280 const QStringList languages = client->languages();
00281 d->clients.append(client->name());
00282
00283 for (QStringList::const_iterator itr = languages.begin();
00284 itr != languages.end(); ++itr) {
00285 if (!d->languageClients[*itr].isEmpty() &&
00286 client->reliability() <
00287 d->languageClients[*itr].first()->reliability())
00288 d->languageClients[*itr].append(client);
00289 else
00290 d->languageClients[*itr].prepend(client);
00291 }
00292
00293 kDebug() << "Successfully loaded plugin:" << service->entryPath();
00294 } else {
00295 kDebug() << error;
00296 }
00297 }
00298
00299 void Loader::changed()
00300 {
00301 emit configurationChanged();
00302 }
00303
00304 }
00305
00306 #include "loader_p.moc"