9#include "settingsimpl_p.h"
10#include "spellerplugin_p.h"
12#include "core_debug.h"
14#include <QCoreApplication>
20#include <QPluginLoader>
29 SettingsImpl *settings;
32 QMap<QString, QList<Client *>> languageClients;
35 QSet<QString> loadedPlugins;
37 QStringList languagesNameCache;
38 QHash<QString, QSharedPointer<SpellerPlugin>> spellerCache;
41Q_GLOBAL_STATIC(Loader, s_loader)
43Loader *Loader::openLoader()
45 if (s_loader.isDestroyed()) {
53 : d(new LoaderPrivate)
55 d->settings =
new SettingsImpl(
this);
56 d->settings->restore();
62 qCDebug(SONNET_LOG_CORE) <<
"Removing loader: " <<
this;
64 d->settings =
nullptr;
67SpellerPlugin *Loader::createSpeller(
const QString &language,
const QString &clientName)
const
73 plang = d->settings->defaultLanguage();
76 auto clientsItr = d->languageClients.constFind(plang);
77 if (clientsItr == d->languageClients.constEnd()) {
78 if (language.
isEmpty() || language == QStringLiteral(
"C")) {
79 qCDebug(SONNET_LOG_CORE) <<
"No language dictionaries for the language:" << plang <<
"trying to load en_US as default";
80 return createSpeller(QStringLiteral(
"en_US"), clientName);
82 qCDebug(SONNET_LOG_CORE) <<
"No language dictionaries for the language:" << plang;
83 Q_EMIT loadingDictionaryFailed(plang);
90 backend = d->settings->defaultClient();
94 bool unknown = !std::any_of(lClients.
constBegin(), lClients.
constEnd(), [backend](
const Client *client) {
95 return client->name() == backend;
98 qCWarning(SONNET_LOG_CORE) <<
"Default client" << backend <<
"doesn't support language:" << plang;
105 while (itr.hasNext()) {
106 Client *item = itr.next();
108 if (backend == item->name()) {
109 SpellerPlugin *dict = item->createSpeller(plang);
110 qCDebug(SONNET_LOG_CORE) <<
"Using the" << item->name() <<
"plugin for language" << plang;
116 SpellerPlugin *dict = item->createSpeller(plang);
117 qCDebug(SONNET_LOG_CORE) <<
"Using the" << item->name() <<
"plugin for language" << plang;
122 qCWarning(SONNET_LOG_CORE) <<
"The default client" << backend <<
"has no language dictionaries for the language:" << plang;
128 auto &speller = d->spellerCache[language];
130 speller.reset(createSpeller(language));
135void Loader::clearSpellerCache()
137 d->spellerCache.clear();
147 return d->languageClients.keys();
152 QString currentDictionary = langCode;
161 int variantCount = 0;
163 struct variantListType {
164 const char *variantShortName;
165 const char *variantEnglishName;
174#undef QT_TRANSLATE_NOOP3
175#define QT_TRANSLATE_NOOP3(a, b, c) b
177 const variantListType variantList[] = {{
"40", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"40",
"dictionary variant")},
178 {
"60", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"60",
"dictionary variant")},
179 {
"80", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"80",
"dictionary variant")},
180 {
"ise", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"-ise suffixes",
"dictionary variant")},
181 {
"ize", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"-ize suffixes",
"dictionary variant")},
182 {
"ise-w_accents", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"-ise suffixes and with accents",
"dictionary variant")},
183 {
"ise-wo_accents", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"-ise suffixes and without accents",
"dictionary variant")},
184 {
"ize-w_accents", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"-ize suffixes and with accents",
"dictionary variant")},
185 {
"ize-wo_accents", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"-ize suffixes and without accents",
"dictionary variant")},
186 {
"lrg", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"large",
"dictionary variant")},
187 {
"med", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"medium",
"dictionary variant")},
188 {
"sml", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"small",
"dictionary variant")},
189 {
"variant_0", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"variant 0",
"dictionary variant")},
190 {
"variant_1", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"variant 1",
"dictionary variant")},
191 {
"variant_2", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"variant 2",
"dictionary variant")},
192 {
"wo_accents", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"without accents",
"dictionary variant")},
193 {
"w_accents", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"with accents",
"dictionary variant")},
194 {
"ye", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"with ye, modern russian",
"dictionary variant")},
195 {
"yeyo", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"with yeyo, modern and old russian",
"dictionary variant")},
196 {
"yo", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"with yo, old russian",
"dictionary variant")},
197 {
"extended", QT_TRANSLATE_NOOP3(
"Sonnet::Loader",
"extended",
"dictionary variant")},
201 if (minusPos != -1) {
202 variantName = currentDictionary.
right(currentDictionary.
length() - minusPos - 1);
203 while (variantList[variantCount].variantShortName !=
nullptr) {
204 if (
QLatin1String(variantList[variantCount].variantShortName) == variantName) {
210 if (variantList[variantCount].variantShortName !=
nullptr) {
211 variantEnglish = variantList[variantCount].variantEnglishName;
213 variantEnglish = variantName.
toLatin1();
216 localizedVariant = tr(variantEnglish.
constData(),
"dictionary variant");
217 isoCode = currentDictionary.
left(minusPos);
219 isoCode = currentDictionary;
223 localizedCountry = locale.nativeTerritoryName();
224 localizedLang = locale.nativeLanguageName();
231 return tr(
"%1 (%2) [%3]",
"dictionary name; %1 = language name, %2 = country name and %3 = language variant name")
232 .arg(localizedLang, localizedCountry, localizedVariant);
233 }
else if (!localizedCountry.
isEmpty()) {
234 return tr(
"%1 (%2)",
"dictionary name; %1 = language name, %2 = country name").arg(localizedLang, localizedCountry);
236 return localizedLang;
245 if (d->languagesNameCache.count() ==
languages().count()) {
246 return d->languagesNameCache;
251 allLocalizedDictionaries.
append(languageNameForCode(langCode));
254 d->languagesNameCache = allLocalizedDictionaries;
255 return allLocalizedDictionaries;
258SettingsImpl *Loader::settings()
const
263void Loader::loadPlugins()
267 const QString pathSuffix(QStringLiteral(
"/kf6/sonnet/"));
268 for (
const QString &libPath : libPaths) {
269 QDir dir(libPath + pathSuffix);
274 loadPlugin(
dir.absoluteFilePath(fileName));
278 if (d->loadedPlugins.isEmpty()) {
279 qCWarning(SONNET_LOG_CORE) <<
"Sonnet: No speller backends available!";
292 Client *client = qobject_cast<Client *>(plugin.instance());
294 qCWarning(SONNET_LOG_CORE) <<
"Sonnet: Invalid static plugin loaded" << plugin.
metaData();
301void Loader::loadPlugin(
const QString &pluginPath)
306 if (d->loadedPlugins.contains(pluginId)) {
307 qCDebug(SONNET_LOG_CORE) <<
"Skipping already loaded" << pluginPath;
311 d->loadedPlugins.
insert(pluginId);
313 if (!plugin.load()) {
314 qCDebug(SONNET_LOG_CORE) <<
"Sonnet: Unable to load plugin" << pluginPath <<
"Error:" << plugin.errorString();
315 d->loadedPlugins.remove(pluginId);
319 Client *client = qobject_cast<Client *>(plugin.instance());
322 qCWarning(SONNET_LOG_CORE) <<
"Sonnet: Invalid plugin loaded" << pluginPath;
330void Loader::addClient(Client *client)
333 d->clients.
append(client->name());
335 for (
const QString &language : languages) {
339 || client->reliability() < languageClients.
first()->reliability()) {
340 languageClients.
append(client);
342 languageClients.
prepend(client);
347void Loader::changed()
349 Q_EMIT configurationChanged();
353#include "moc_loader_p.cpp"
char * toString(const EngineQuery &query)
KIOCORE_EXPORT QString dir(const QString &fileClass)
KEDUVOCDOCUMENT_EXPORT QStringList languages()
const char * constData() const const
QStringList libraryPaths()
QString completeBaseName() const const
void append(QList< T > &&value)
const_iterator constBegin() const const
const_iterator constEnd() const const
bool isEmpty() const const
void prepend(parameter_type value)
QList< QStaticPlugin > staticPlugins()
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
QString & insert(qsizetype position, QChar ch)
bool isEmpty() const const
QString left(qsizetype n) const const
qsizetype length() const const
QString right(qsizetype n) const const
QByteArray toLatin1() const const