File indexing completed on 2024-04-14 03:58:20

0001 /*
0002  * SPDX-FileCopyrightText: 2020 Benjamin Port <benjamin.port@enioka.com>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-or-later
0005  */
0006 #include "settingsimpl_p.h"
0007 
0008 #include <QLocale>
0009 
0010 #include "loader_p.h"
0011 #include "settings.h"
0012 #include <QDebug>
0013 #include <speller.h>
0014 
0015 namespace Sonnet
0016 {
0017 class DictionaryModel : public QAbstractListModel
0018 {
0019     Q_OBJECT
0020 public:
0021     explicit DictionaryModel(QObject *parent = nullptr)
0022         : QAbstractListModel(parent)
0023     {
0024         reload();
0025     }
0026 
0027     ~DictionaryModel() override
0028     {
0029     }
0030 
0031     void reload()
0032     {
0033         beginResetModel();
0034         Sonnet::Speller speller;
0035         m_preferredDictionaries = speller.preferredDictionaries();
0036         m_availableDictionaries = speller.availableDictionaries();
0037         endResetModel();
0038     }
0039 
0040     void setDefaultLanguage(const QString &language)
0041     {
0042         m_defaultDictionary = language;
0043         Q_EMIT dataChanged(index(0, 0), index(rowCount(QModelIndex()) - 1, 0), {Settings::DefaultRole});
0044     }
0045 
0046     bool setData(const QModelIndex &idx, const QVariant &value, int role = Qt::EditRole) override
0047     {
0048         Q_UNUSED(value)
0049 
0050         if (!checkIndex(idx) || role != Qt::CheckStateRole) {
0051             return false;
0052         }
0053         const int row = idx.row();
0054         const auto language = m_availableDictionaries.keys().at(row);
0055         const auto inPreferredDictionaries = m_preferredDictionaries.contains(m_availableDictionaries.keys().at(row));
0056 
0057         if (inPreferredDictionaries) {
0058             m_preferredDictionaries.remove(language);
0059         } else {
0060             m_preferredDictionaries[language] = m_availableDictionaries.values().at(row);
0061         }
0062         qobject_cast<Settings *>(parent())->setPreferredLanguages(m_preferredDictionaries.values());
0063         Q_EMIT dataChanged(index(row, 0), index(row, 0), {Qt::CheckStateRole});
0064         return true;
0065     }
0066 
0067     QVariant data(const QModelIndex &index, int role) const override
0068     {
0069         if (!checkIndex(index)) {
0070             return {};
0071         }
0072         const int row = index.row();
0073 
0074         switch (role) {
0075         case Qt::DisplayRole:
0076             return m_availableDictionaries.keys().at(row);
0077         case Settings::LanguageCodeRole:
0078             return m_availableDictionaries.values().at(row);
0079         case Qt::CheckStateRole:
0080             return m_preferredDictionaries.contains(m_availableDictionaries.keys().at(row));
0081         case Settings::DefaultRole:
0082             return data(index, Settings::LanguageCodeRole) == m_defaultDictionary;
0083         }
0084         return {};
0085     }
0086 
0087     int rowCount(const QModelIndex &parent) const override
0088     {
0089         Q_UNUSED(parent)
0090         return m_availableDictionaries.count();
0091     }
0092 
0093     QHash<int, QByteArray> roleNames() const override
0094     {
0095         return {
0096             {Qt::DisplayRole, QByteArrayLiteral("display")},
0097             {Qt::CheckStateRole, QByteArrayLiteral("checked")},
0098             {Settings::PreferredRole, QByteArrayLiteral("isPreferred")},
0099             {Settings::LanguageCodeRole, QByteArrayLiteral("languageCode")},
0100             {Settings::DefaultRole, QByteArrayLiteral("isDefault")},
0101         };
0102     }
0103 
0104 private:
0105     QMap<QString, QString> m_preferredDictionaries;
0106     QMap<QString, QString> m_availableDictionaries;
0107     QString m_defaultDictionary;
0108 };
0109 
0110 class SettingsPrivate
0111 {
0112 public:
0113     Loader *loader = nullptr;
0114     DictionaryModel *dictionaryModel = nullptr;
0115 };
0116 
0117 Settings::Settings(QObject *parent)
0118     : QObject(parent)
0119     , d(new SettingsPrivate)
0120 {
0121     d->loader = Loader::openLoader();
0122 }
0123 
0124 Settings::~Settings() = default;
0125 
0126 void Settings::setDefaultLanguage(const QString &lang)
0127 {
0128     if (defaultLanguage() == lang) {
0129         return;
0130     }
0131     d->loader->settings()->setDefaultLanguage(lang);
0132     Q_EMIT defaultLanguageChanged();
0133     Q_EMIT modifiedChanged();
0134 
0135     if (d->dictionaryModel) {
0136         d->dictionaryModel->setDefaultLanguage(lang);
0137     }
0138 }
0139 
0140 QString Settings::defaultLanguage() const
0141 {
0142     return d->loader->settings()->defaultLanguage();
0143 }
0144 
0145 void Settings::setPreferredLanguages(const QStringList &lang)
0146 {
0147     if (!d->loader->settings()->setPreferredLanguages(lang)) {
0148         return;
0149     }
0150     Q_EMIT modifiedChanged();
0151     Q_EMIT preferredLanguagesChanged();
0152 }
0153 
0154 QStringList Settings::preferredLanguages() const
0155 {
0156     return d->loader->settings()->preferredLanguages();
0157 }
0158 
0159 void Settings::setDefaultClient(const QString &client)
0160 {
0161     if (!d->loader->settings()->setDefaultClient(client)) {
0162         return;
0163     }
0164     Q_EMIT defaultClientChanged();
0165     Q_EMIT modifiedChanged();
0166 }
0167 
0168 QString Settings::defaultClient() const
0169 {
0170     return d->loader->settings()->defaultClient();
0171 }
0172 
0173 void Settings::setSkipUppercase(bool skip)
0174 {
0175     if (!d->loader->settings()->setCheckUppercase(!skip)) {
0176         return;
0177     }
0178     Q_EMIT skipUppercaseChanged();
0179     Q_EMIT modifiedChanged();
0180 }
0181 
0182 bool Settings::skipUppercase() const
0183 {
0184     return !d->loader->settings()->checkUppercase();
0185 }
0186 
0187 void Settings::setAutodetectLanguage(bool detect)
0188 {
0189     if (!d->loader->settings()->setAutodetectLanguage(detect)) {
0190         return;
0191     }
0192     Q_EMIT autodetectLanguageChanged();
0193     Q_EMIT modifiedChanged();
0194 }
0195 
0196 bool Settings::autodetectLanguage() const
0197 {
0198     return d->loader->settings()->autodetectLanguage();
0199 }
0200 
0201 void Settings::setSkipRunTogether(bool skip)
0202 {
0203     if (skipRunTogether() == skip) {
0204         return;
0205     }
0206     d->loader->settings()->setSkipRunTogether(skip);
0207     Q_EMIT skipRunTogetherChanged();
0208     Q_EMIT modifiedChanged();
0209 }
0210 
0211 bool Settings::skipRunTogether() const
0212 {
0213     return d->loader->settings()->skipRunTogether();
0214 }
0215 
0216 void Settings::setCheckerEnabledByDefault(bool check)
0217 {
0218     if (checkerEnabledByDefault() == check) {
0219         return;
0220     }
0221     d->loader->settings()->setCheckerEnabledByDefault(check);
0222     Q_EMIT checkerEnabledByDefaultChanged();
0223     Q_EMIT modifiedChanged();
0224 }
0225 
0226 bool Settings::checkerEnabledByDefault() const
0227 {
0228     return d->loader->settings()->checkerEnabledByDefault();
0229 }
0230 
0231 void Settings::setBackgroundCheckerEnabled(bool enable)
0232 {
0233     if (backgroundCheckerEnabled() == enable) {
0234         return;
0235     }
0236     d->loader->settings()->setBackgroundCheckerEnabled(enable);
0237     Q_EMIT backgroundCheckerEnabledChanged();
0238     Q_EMIT modifiedChanged();
0239 }
0240 
0241 bool Settings::backgroundCheckerEnabled() const
0242 {
0243     return d->loader->settings()->backgroundCheckerEnabled();
0244 }
0245 
0246 void Settings::setCurrentIgnoreList(const QStringList &ignores)
0247 {
0248     if (currentIgnoreList() == ignores) {
0249         return;
0250     }
0251     d->loader->settings()->setCurrentIgnoreList(ignores);
0252     Q_EMIT currentIgnoreListChanged();
0253     Q_EMIT modifiedChanged();
0254 }
0255 
0256 QStringList Settings::currentIgnoreList() const
0257 {
0258     return d->loader->settings()->currentIgnoreList();
0259 }
0260 
0261 QStringList Settings::clients() const
0262 {
0263     return d->loader->clients();
0264 }
0265 
0266 void Settings::save()
0267 {
0268     d->loader->settings()->save();
0269     Q_EMIT modifiedChanged();
0270 }
0271 
0272 bool Settings::modified() const
0273 {
0274     return d->loader->settings()->modified();
0275 }
0276 
0277 // default values
0278 // A static list of KDE specific words that we want to recognize
0279 QStringList Settings::defaultIgnoreList()
0280 {
0281     QStringList l;
0282     l.append(QStringLiteral("KMail"));
0283     l.append(QStringLiteral("KOrganizer"));
0284     l.append(QStringLiteral("KAddressBook"));
0285     l.append(QStringLiteral("KHTML"));
0286     l.append(QStringLiteral("KIO"));
0287     l.append(QStringLiteral("KJS"));
0288     l.append(QStringLiteral("Konqueror"));
0289     l.append(QStringLiteral("Sonnet"));
0290     l.append(QStringLiteral("Kontact"));
0291     l.append(QStringLiteral("Qt"));
0292     l.append(QStringLiteral("Okular"));
0293     l.append(QStringLiteral("KMix"));
0294     l.append(QStringLiteral("Amarok"));
0295     l.append(QStringLiteral("KDevelop"));
0296     l.append(QStringLiteral("Nepomuk"));
0297     return l;
0298 }
0299 
0300 bool Settings::defaultSkipUppercase()
0301 {
0302     return false;
0303 }
0304 
0305 bool Settings::defaultAutodetectLanguage()
0306 {
0307     return true;
0308 }
0309 
0310 bool Settings::defaultBackgroundCheckerEnabled()
0311 {
0312     return true;
0313 }
0314 
0315 bool Settings::defaultCheckerEnabledByDefault()
0316 {
0317     return false;
0318 }
0319 
0320 bool Settings::defauktSkipRunTogether()
0321 {
0322     return true;
0323 }
0324 
0325 QString Settings::defaultDefaultLanguage()
0326 {
0327     return QLocale::system().name();
0328 }
0329 
0330 QStringList Settings::defaultPreferredLanguages()
0331 {
0332     return QStringList();
0333 }
0334 
0335 QAbstractListModel *Settings::dictionaryModel()
0336 {
0337     // Lazy loading
0338     if (d->dictionaryModel) {
0339         return d->dictionaryModel;
0340     }
0341 
0342     d->dictionaryModel = new DictionaryModel(this);
0343     d->dictionaryModel->setDefaultLanguage(defaultLanguage());
0344     return d->dictionaryModel;
0345 }
0346 }
0347 
0348 #include "moc_settings.cpp"
0349 #include "settings.moc"