File indexing completed on 2024-04-28 15:34:19

0001 /*
0002  * SPDX-FileCopyrightText: 2007 Zack Rusin <zack@kde.org>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-or-later
0005  */
0006 #include "speller.h"
0007 
0008 #include "loader_p.h"
0009 #include "settingsimpl_p.h"
0010 #include "spellerplugin_p.h"
0011 
0012 #include "core_debug.h"
0013 
0014 #include <QCache>
0015 
0016 namespace Sonnet
0017 {
0018 class SpellerPrivate
0019 {
0020 public:
0021     SpellerPrivate()
0022     {
0023     }
0024 
0025     ~SpellerPrivate()
0026     {
0027     }
0028 
0029     void init(const QString &lang)
0030     {
0031         Loader *loader = Loader::openLoader();
0032         settings = loader->settings();
0033 
0034         language = lang;
0035         updateDict();
0036     }
0037 
0038     void updateDict()
0039     {
0040         dict = Loader::openLoader()->cachedSpeller(language);
0041     }
0042 
0043     bool isValid()
0044     {
0045         if (settings->modified()) {
0046             recreateDict();
0047             settings->setModified(false);
0048         }
0049         return !dict.isNull();
0050     }
0051 
0052     void recreateDict()
0053     {
0054         Loader::openLoader()->clearSpellerCache();
0055         updateDict();
0056     }
0057 
0058     QSharedPointer<SpellerPlugin> dict;
0059     SettingsImpl *settings = nullptr;
0060     QString language;
0061 };
0062 
0063 Speller::Speller(const QString &lang)
0064     : d(new SpellerPrivate)
0065 {
0066     d->init(lang);
0067 }
0068 
0069 Speller::~Speller()
0070 {
0071     qCDebug(SONNET_LOG_CORE) << "deleting" << this << "for" << d->language;
0072     delete d;
0073 }
0074 
0075 Speller::Speller(const Speller &speller)
0076     : d(new SpellerPrivate)
0077 {
0078     d->language = speller.language();
0079     d->init(d->language);
0080 }
0081 
0082 Speller &Speller::operator=(const Speller &speller)
0083 {
0084     d->language = speller.language();
0085     d->updateDict();
0086     return *this;
0087 }
0088 
0089 bool Speller::isCorrect(const QString &word) const
0090 {
0091     if (!d->isValid()) {
0092         return true;
0093     }
0094     return d->dict->isCorrect(word);
0095 }
0096 
0097 bool Speller::isMisspelled(const QString &word) const
0098 {
0099     if (!d->isValid()) {
0100         return false;
0101     }
0102     return d->dict->isMisspelled(word);
0103 }
0104 
0105 QStringList Speller::suggest(const QString &word) const
0106 {
0107     if (!d->isValid()) {
0108         return QStringList();
0109     }
0110     return d->dict->suggest(word);
0111 }
0112 
0113 bool Speller::checkAndSuggest(const QString &word, QStringList &suggestions) const
0114 {
0115     if (!d->isValid()) {
0116         return true;
0117     }
0118     return d->dict->checkAndSuggest(word, suggestions);
0119 }
0120 
0121 bool Speller::storeReplacement(const QString &bad, const QString &good)
0122 {
0123     if (!d->isValid()) {
0124         return false;
0125     }
0126     return d->dict->storeReplacement(bad, good);
0127 }
0128 
0129 bool Speller::addToPersonal(const QString &word)
0130 {
0131     if (!d->isValid()) {
0132         return false;
0133     }
0134     return d->dict->addToPersonal(word);
0135 }
0136 
0137 bool Speller::addToSession(const QString &word)
0138 {
0139     if (!d->isValid()) {
0140         return false;
0141     }
0142     return d->dict->addToSession(word);
0143 }
0144 
0145 QString Speller::language() const
0146 {
0147     if (!d->isValid()) {
0148         return QString();
0149     }
0150     return d->dict->language();
0151 }
0152 
0153 void Speller::save()
0154 {
0155     if (d->settings) {
0156         d->settings->save();
0157     }
0158 }
0159 
0160 void Speller::restore()
0161 {
0162     if (d->settings) {
0163         d->settings->restore();
0164         d->recreateDict();
0165     }
0166 }
0167 
0168 QStringList Speller::availableBackends() const
0169 {
0170     Loader *l = Loader::openLoader();
0171     return l->clients();
0172 }
0173 
0174 QStringList Speller::availableLanguages() const
0175 {
0176     Loader *l = Loader::openLoader();
0177     return l->languages();
0178 }
0179 
0180 QStringList Speller::availableLanguageNames() const
0181 {
0182     Loader *l = Loader::openLoader();
0183     return l->languageNames();
0184 }
0185 
0186 void Speller::setDefaultLanguage(const QString &lang)
0187 {
0188     if (d->settings->setDefaultLanguage(lang)) {
0189         d->settings->save();
0190     }
0191 }
0192 
0193 QString Speller::defaultLanguage() const
0194 {
0195     return d->settings->defaultLanguage();
0196 }
0197 
0198 void Speller::setDefaultClient(const QString &client)
0199 {
0200     if (d->settings->setDefaultClient(client)) {
0201         d->settings->save();
0202     }
0203 }
0204 
0205 QString Speller::defaultClient() const
0206 {
0207     return d->settings->defaultClient();
0208 }
0209 
0210 void Speller::setAttribute(Attribute attr, bool b)
0211 {
0212     switch (attr) {
0213     case CheckUppercase:
0214         d->settings->setCheckUppercase(b);
0215         break;
0216     case SkipRunTogether:
0217         d->settings->setSkipRunTogether(b);
0218         break;
0219     case AutoDetectLanguage:
0220         d->settings->setAutodetectLanguage(b);
0221         break;
0222     }
0223     d->settings->save();
0224 }
0225 
0226 bool Speller::testAttribute(Attribute attr) const
0227 {
0228     switch (attr) {
0229     case CheckUppercase:
0230         return d->settings->checkUppercase();
0231     case SkipRunTogether:
0232         return d->settings->skipRunTogether();
0233     case AutoDetectLanguage:
0234         return d->settings->autodetectLanguage();
0235     }
0236     return false;
0237 }
0238 
0239 bool Speller::isValid() const
0240 {
0241     return !d->dict.isNull();
0242 }
0243 
0244 void Speller::setLanguage(const QString &lang)
0245 {
0246     d->language = lang;
0247     d->updateDict();
0248 }
0249 
0250 QMap<QString, QString> Sonnet::Speller::availableDictionaries() const
0251 {
0252     Loader *l = Loader::openLoader();
0253     const QStringList lst = l->languages();
0254     QMap<QString, QString> langs;
0255 
0256     for (const QString &tag : lst) {
0257         langs.insert(l->languageNameForCode(tag), tag);
0258     }
0259 
0260     return langs;
0261 }
0262 
0263 QMap<QString, QString> Speller::preferredDictionaries() const
0264 {
0265     Loader *l = Loader::openLoader();
0266     QMap<QString, QString> langs;
0267 
0268     for (const QString &tag : l->settings()->preferredLanguages()) {
0269         langs.insert(l->languageNameForCode(tag), tag);
0270     }
0271 
0272     return langs;
0273 }
0274 
0275 } // namespace Sonnet