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

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()
0125 {
0126     delete d;
0127 }
0128 
0129 void Settings::setDefaultLanguage(const QString &lang)
0130 {
0131     if (defaultLanguage() == lang) {
0132         return;
0133     }
0134     d->loader->settings()->setDefaultLanguage(lang);
0135     Q_EMIT defaultLanguageChanged();
0136     Q_EMIT modifiedChanged();
0137 
0138     if (d->dictionaryModel) {
0139         d->dictionaryModel->setDefaultLanguage(lang);
0140     }
0141 }
0142 
0143 QString Settings::defaultLanguage() const
0144 {
0145     return d->loader->settings()->defaultLanguage();
0146 }
0147 
0148 void Settings::setPreferredLanguages(const QStringList &lang)
0149 {
0150     if (!d->loader->settings()->setPreferredLanguages(lang)) {
0151         return;
0152     }
0153     Q_EMIT modifiedChanged();
0154     Q_EMIT preferredLanguagesChanged();
0155 }
0156 
0157 QStringList Settings::preferredLanguages() const
0158 {
0159     return d->loader->settings()->preferredLanguages();
0160 }
0161 
0162 void Settings::setDefaultClient(const QString &client)
0163 {
0164     if (!d->loader->settings()->setDefaultClient(client)) {
0165         return;
0166     }
0167     Q_EMIT defaultClientChanged();
0168     Q_EMIT modifiedChanged();
0169 }
0170 
0171 QString Settings::defaultClient() const
0172 {
0173     return d->loader->settings()->defaultClient();
0174 }
0175 
0176 void Settings::setSkipUppercase(bool skip)
0177 {
0178     if (!d->loader->settings()->setCheckUppercase(!skip)) {
0179         return;
0180     }
0181     Q_EMIT skipUppercaseChanged();
0182     Q_EMIT modifiedChanged();
0183 }
0184 
0185 bool Settings::skipUppercase() const
0186 {
0187     return !d->loader->settings()->checkUppercase();
0188 }
0189 
0190 void Settings::setAutodetectLanguage(bool detect)
0191 {
0192     if (!d->loader->settings()->setAutodetectLanguage(detect)) {
0193         return;
0194     }
0195     Q_EMIT autodetectLanguageChanged();
0196     Q_EMIT modifiedChanged();
0197 }
0198 
0199 bool Settings::autodetectLanguage() const
0200 {
0201     return d->loader->settings()->autodetectLanguage();
0202 }
0203 
0204 void Settings::setSkipRunTogether(bool skip)
0205 {
0206     if (skipRunTogether() == skip) {
0207         return;
0208     }
0209     d->loader->settings()->setSkipRunTogether(skip);
0210     Q_EMIT skipRunTogetherChanged();
0211     Q_EMIT modifiedChanged();
0212 }
0213 
0214 bool Settings::skipRunTogether() const
0215 {
0216     return d->loader->settings()->skipRunTogether();
0217 }
0218 
0219 void Settings::setCheckerEnabledByDefault(bool check)
0220 {
0221     if (checkerEnabledByDefault() == check) {
0222         return;
0223     }
0224     d->loader->settings()->setCheckerEnabledByDefault(check);
0225     Q_EMIT checkerEnabledByDefaultChanged();
0226     Q_EMIT modifiedChanged();
0227 }
0228 
0229 bool Settings::checkerEnabledByDefault() const
0230 {
0231     return d->loader->settings()->checkerEnabledByDefault();
0232 }
0233 
0234 void Settings::setBackgroundCheckerEnabled(bool enable)
0235 {
0236     if (backgroundCheckerEnabled() == enable) {
0237         return;
0238     }
0239     d->loader->settings()->setBackgroundCheckerEnabled(enable);
0240     Q_EMIT backgroundCheckerEnabledChanged();
0241     Q_EMIT modifiedChanged();
0242 }
0243 
0244 bool Settings::backgroundCheckerEnabled() const
0245 {
0246     return d->loader->settings()->backgroundCheckerEnabled();
0247 }
0248 
0249 void Settings::setCurrentIgnoreList(const QStringList &ignores)
0250 {
0251     if (currentIgnoreList() == ignores) {
0252         return;
0253     }
0254     d->loader->settings()->setCurrentIgnoreList(ignores);
0255     Q_EMIT currentIgnoreListChanged();
0256     Q_EMIT modifiedChanged();
0257 }
0258 
0259 QStringList Settings::currentIgnoreList() const
0260 {
0261     return d->loader->settings()->currentIgnoreList();
0262 }
0263 
0264 QStringList Settings::clients() const
0265 {
0266     return d->loader->clients();
0267 }
0268 
0269 void Settings::save()
0270 {
0271     d->loader->settings()->save();
0272     Q_EMIT modifiedChanged();
0273 }
0274 
0275 bool Settings::modified() const
0276 {
0277     return d->loader->settings()->modified();
0278 }
0279 
0280 // default values
0281 // A static list of KDE specific words that we want to recognize
0282 QStringList Settings::defaultIgnoreList()
0283 {
0284     QStringList l;
0285     l.append(QStringLiteral("KMail"));
0286     l.append(QStringLiteral("KOrganizer"));
0287     l.append(QStringLiteral("KAddressBook"));
0288     l.append(QStringLiteral("KHTML"));
0289     l.append(QStringLiteral("KIO"));
0290     l.append(QStringLiteral("KJS"));
0291     l.append(QStringLiteral("Konqueror"));
0292     l.append(QStringLiteral("Sonnet"));
0293     l.append(QStringLiteral("Kontact"));
0294     l.append(QStringLiteral("Qt"));
0295     l.append(QStringLiteral("Okular"));
0296     l.append(QStringLiteral("KMix"));
0297     l.append(QStringLiteral("Amarok"));
0298     l.append(QStringLiteral("KDevelop"));
0299     l.append(QStringLiteral("Nepomuk"));
0300     return l;
0301 }
0302 
0303 bool Settings::defaultSkipUppercase()
0304 {
0305     return false;
0306 }
0307 
0308 bool Settings::defaultAutodetectLanguage()
0309 {
0310     return true;
0311 }
0312 
0313 bool Settings::defaultBackgroundCheckerEnabled()
0314 {
0315     return true;
0316 }
0317 
0318 bool Settings::defaultCheckerEnabledByDefault()
0319 {
0320     return false;
0321 }
0322 
0323 bool Settings::defauktSkipRunTogether()
0324 {
0325     return true;
0326 }
0327 
0328 QString Settings::defaultDefaultLanguage()
0329 {
0330     return QLocale::system().name();
0331 }
0332 
0333 QStringList Settings::defaultPreferredLanguages()
0334 {
0335     return QStringList();
0336 }
0337 
0338 QAbstractListModel *Settings::dictionaryModel()
0339 {
0340     // Lazy loading
0341     if (d->dictionaryModel) {
0342         return d->dictionaryModel;
0343     }
0344 
0345     d->dictionaryModel = new DictionaryModel(this);
0346     d->dictionaryModel->setDefaultLanguage(defaultLanguage());
0347     return d->dictionaryModel;
0348 }
0349 }
0350 
0351 #include "moc_settings.cpp"
0352 #include "settings.moc"