diff --git a/autotests/test_settings.cpp b/autotests/test_settings.cpp --- a/autotests/test_settings.cpp +++ b/autotests/test_settings.cpp @@ -9,7 +9,7 @@ #include "test_settings.h" #include "speller.h" -#include "settings_p.h" +#include "settingsimpl_p.h" #include #include diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -5,6 +5,7 @@ client.cpp spellerplugin.cpp speller.cpp + settingsimpl.cpp settings.cpp backgroundchecker.cpp guesslanguage.cpp @@ -51,6 +52,7 @@ BackgroundChecker Speller GuessLanguage + Settings PREFIX Sonnet REQUIRED_HEADERS SonnetCore_HEADERS ) diff --git a/src/core/languagefilter.cpp b/src/core/languagefilter.cpp --- a/src/core/languagefilter.cpp +++ b/src/core/languagefilter.cpp @@ -11,7 +11,7 @@ #include "guesslanguage.h" #include "speller.h" #include "loader_p.h" -#include "settings_p.h" +#include "settingsimpl_p.h" namespace Sonnet { #define MIN_RELIABILITY 0.1 diff --git a/src/core/loader.cpp b/src/core/loader.cpp --- a/src/core/loader.cpp +++ b/src/core/loader.cpp @@ -5,7 +5,7 @@ * SPDX-License-Identifier: LGPL-2.1-or-later */ #include "loader_p.h" -#include "settings_p.h" +#include "settingsimpl_p.h" #include "client_p.h" #include "spellerplugin_p.h" @@ -30,7 +30,7 @@ class LoaderPrivate { public: - Settings *settings; + SettingsImpl *settings; // QMap > languageClients; @@ -54,7 +54,7 @@ Loader::Loader() : d(new LoaderPrivate) { - d->settings = new Settings(this); + d->settings = new SettingsImpl(this); d->settings->restore(); loadPlugins(); } @@ -267,7 +267,7 @@ return allLocalizedDictionaries; } -Settings *Loader::settings() const +SettingsImpl *Loader::settings() const { return d->settings; } diff --git a/src/core/loader_p.h b/src/core/loader_p.h --- a/src/core/loader_p.h +++ b/src/core/loader_p.h @@ -14,7 +14,7 @@ #include namespace Sonnet { -class Settings; +class SettingsImpl; class SpellerPlugin; class LoaderPrivate; /** @@ -103,12 +103,12 @@ QString languageNameForCode(const QString &langCode) const; /** - * Returns the Settings object used by the loader. + * Returns the SettingsImpl object used by the loader. */ - Settings *settings() const; + SettingsImpl *settings() const; Q_SIGNALS: /** - * Signal is emitted whenever the Settings object + * Signal is emitted whenever the SettingsImpl object * associated with this Loader changes. */ void configurationChanged(); @@ -123,7 +123,7 @@ void loadingDictionaryFailed(const QString &language) const; protected: - friend class Settings; + friend class SettingsImpl; void changed(); private: void loadPlugins(); diff --git a/src/core/settings.h b/src/core/settings.h new file mode 100644 --- /dev/null +++ b/src/core/settings.h @@ -0,0 +1,85 @@ +/* + * SPDX-FileCopyrightText: 2020 Benjamin Port + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ +#ifndef SONNET_SETTINGS_H +#define SONNET_SETTINGS_H + +#include +#include +#include + +#include "sonnetcore_export.h" + +namespace Sonnet { +class Loader; +class SettingsImpl; +class SettingsPrivate; + +class SONNETCORE_EXPORT Settings : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool skipUppercase READ skipUppercase WRITE setSkipUppercase) + Q_PROPERTY(bool autodetectLanguage READ autodetectLanguage WRITE setAutodetectLanguage) + Q_PROPERTY(bool backgroundCheckerEnabled READ backgroundCheckerEnabled WRITE setBackgroundCheckerEnabled) + Q_PROPERTY(bool checkerEnabledByDefault READ checkerEnabledByDefault WRITE setCheckerEnabledByDefault) + Q_PROPERTY(bool skipRunTogether READ skipRunTogether WRITE setSkipRunTogether) + Q_PROPERTY(QStringList currentIgnoreList READ currentIgnoreList WRITE setCurrentIgnoreList) + Q_PROPERTY(QStringList preferredLanguages READ preferredLanguages WRITE setPreferredLanguages) + Q_PROPERTY(QString defaultLanguage READ defaultLanguage WRITE setDefaultLanguage) + +public: + explicit Settings(QObject *parent = nullptr); + ~Settings() override; + + void setDefaultLanguage(const QString &lang); + QString defaultLanguage() const; + + void setPreferredLanguages(const QStringList &lang); + QStringList preferredLanguages() const; + + void setDefaultClient(const QString &client); + QString defaultClient() const; + + void setSkipUppercase(bool); + bool skipUppercase() const; + + void setAutodetectLanguage(bool); + bool autodetectLanguage() const; + + void setSkipRunTogether(bool); + bool skipRunTogether() const; + + void setBackgroundCheckerEnabled(bool); + bool backgroundCheckerEnabled() const; + + void setCheckerEnabledByDefault(bool); + bool checkerEnabledByDefault() const; + + void setCurrentIgnoreList(const QStringList &ignores); + bool addWordToIgnore(const QString &word); + QStringList currentIgnoreList() const; + bool ignore(const QString &word); + + QStringList clients() const; + bool modified() const; + + void save(); + + static QStringList defaultIgnoreList(); + static bool defaultSkipUppercase(); + static bool defaultAutodetectLanguage(); + static bool defaultBackgroundCheckerEnabled(); + static bool defaultCheckerEnabledByDefault(); + static bool defauktSkipRunTogether(); + static QString defaultDefaultLanguage(); + static QStringList defaultPreferredLanguages(); + +private: + friend class Loader; + SettingsPrivate *const d; +}; +} + +#endif //SONNET_SETTINGS_H diff --git a/src/core/settings.cpp b/src/core/settings.cpp --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -1,254 +1,142 @@ /* - * SPDX-FileCopyrightText: 2003 Zack Rusin - * SPDX-FileCopyrightText: 2006 Laurent Montel - * SPDX-FileCopyrightText: 2013 Martin Sandsmark + * SPDX-FileCopyrightText: 2020 Benjamin Port * * SPDX-License-Identifier: LGPL-2.1-or-later */ -#include "settings_p.h" +#include "settingsimpl_p.h" -#include "loader_p.h" - -#include #include -#include + +#include "loader_p.h" +#include "settings.h" namespace Sonnet { class SettingsPrivate { public: - Loader *loader = nullptr; //can't be a Ptr since we don't want to hold a ref on it - bool modified = false; - - QString defaultLanguage; - QStringList preferredLanguages; - QString defaultClient; - - bool checkUppercase = false; - bool skipRunTogether = false; - bool backgroundCheckerEnabled = false; - bool checkerEnabledByDefault = false; - bool autodetectLanguage = false; - - int disablePercentage; - int disableWordCount; - - QMap ignore; + Loader *loader; }; -Settings::Settings(Loader *loader) - : d(new SettingsPrivate) +Settings::Settings(QObject *parent) + : QObject(parent) + , d(new SettingsPrivate) { - d->loader = loader; - - d->modified = false; - d->checkerEnabledByDefault = false; - restore(); + d->loader = Loader::openLoader(); } Settings::~Settings() { delete d; } -bool Settings::setDefaultLanguage(const QString &lang) +void Settings::setDefaultLanguage(const QString &lang) { - const QStringList cs = d->loader->languages(); - if (cs.indexOf(lang) != -1 - && d->defaultLanguage != lang) { - d->defaultLanguage = lang; - d->modified = true; - d->loader->changed(); - return true; - } - return false; + d->loader->settings()->setDefaultLanguage(lang); } QString Settings::defaultLanguage() const { - return d->defaultLanguage; + return d->loader->settings()->defaultLanguage(); } -bool Settings::setPreferredLanguages(const QStringList &lang) +void Settings::setPreferredLanguages(const QStringList &lang) { - if (d->preferredLanguages != lang) { - d->modified = true; - d->preferredLanguages = lang; - return true; - } - - return false; + d->loader->settings()->setPreferredLanguages(lang); } QStringList Settings::preferredLanguages() const { - return d->preferredLanguages; + return d->loader->settings()->preferredLanguages(); } -bool Settings::setDefaultClient(const QString &client) +void Settings::setDefaultClient(const QString &client) { - //Different from setDefaultLanguage because - //the number of clients can't be even close - //as big as the number of languages - if (d->loader->clients().contains(client)) { - d->defaultClient = client; - d->modified = true; - d->loader->changed(); - return true; - } - return false; + d->loader->settings()->setDefaultClient(client); } QString Settings::defaultClient() const { - return d->defaultClient; + return d->loader->settings()->defaultClient(); } -bool Settings::setCheckUppercase(bool check) +void Settings::setSkipUppercase(bool skip) { - if (d->checkUppercase != check) { - d->modified = true; - d->checkUppercase = check; - return true; - } - return false; + d->loader->settings()->setCheckUppercase(!skip); } -bool Settings::checkUppercase() const +bool Settings::skipUppercase() const { - return d->checkUppercase; + return !d->loader->settings()->checkUppercase(); } -bool Settings::setAutodetectLanguage(bool detect) +void Settings::setAutodetectLanguage(bool detect) { - if (d->autodetectLanguage != detect) { - d->modified = true; - d->autodetectLanguage = detect; - return true; - } - return false; + d->loader->settings()->setAutodetectLanguage(detect); } bool Settings::autodetectLanguage() const { - return d->autodetectLanguage; + return d->loader->settings()->autodetectLanguage(); } -bool Settings::setSkipRunTogether(bool skip) +void Settings::setSkipRunTogether(bool skip) { - if (d->skipRunTogether != skip) { - d->modified = true; - d->skipRunTogether = skip; - return true; - } - return false; + d->loader->settings()->setSkipRunTogether(skip); } bool Settings::skipRunTogether() const { - return d->skipRunTogether; + return d->loader->settings()->skipRunTogether(); } -bool Settings::setCheckerEnabledByDefault(bool check) +void Settings::setCheckerEnabledByDefault(bool check) { - if (d->checkerEnabledByDefault != check) { - d->modified = true; - d->checkerEnabledByDefault = check; - return true; - } - return false; + d->loader->settings()->setCheckerEnabledByDefault(check); } bool Settings::checkerEnabledByDefault() const { - return d->checkerEnabledByDefault; + return d->loader->settings()->checkerEnabledByDefault(); } -bool Settings::setBackgroundCheckerEnabled(bool enable) +void Settings::setBackgroundCheckerEnabled(bool enable) { - if (d->backgroundCheckerEnabled != enable) { - d->modified = true; - d->backgroundCheckerEnabled = enable; - return true; - } - return false; + d->loader->settings()->setBackgroundCheckerEnabled(enable); } bool Settings::backgroundCheckerEnabled() const { - return d->backgroundCheckerEnabled; + return d->loader->settings()->backgroundCheckerEnabled(); } -bool Settings::setCurrentIgnoreList(const QStringList &ignores) +void Settings::setCurrentIgnoreList(const QStringList &ignores) { - bool changed = setQuietIgnoreList(ignores); - d->modified = true; - return changed; -} - -bool Settings::setQuietIgnoreList(const QStringList &ignores) -{ - bool changed = false; - d->ignore = QMap();//clear out - for (QStringList::const_iterator itr = ignores.begin(); - itr != ignores.end(); ++itr) { - d->ignore.insert(*itr, true); - changed = true; - } - return changed; + d->loader->settings()->setCurrentIgnoreList(ignores); } QStringList Settings::currentIgnoreList() const { - return d->ignore.keys(); -} - -bool Settings::addWordToIgnore(const QString &word) -{ - if (!d->ignore.contains(word)) { - d->modified = true; - d->ignore.insert(word, true); - return true; - } - return false; -} - -bool Settings::ignore(const QString &word) -{ - return d->ignore.contains(word); + return d->loader->settings()->currentIgnoreList(); } -int Settings::disablePercentageWordError() const +QStringList Settings::clients() const { - return d->disablePercentage; + return d->loader->clients(); } -int Settings::disableWordErrorCount() const +void Settings::save() { - return d->disableWordCount; + d->loader->settings()->save(); } -void Settings::save() +bool Settings::modified() const { - QSettings settings(QStringLiteral("KDE"), QStringLiteral("Sonnet")); - settings.setValue(QStringLiteral("defaultClient"), d->defaultClient); - settings.setValue(QStringLiteral("defaultLanguage"), d->defaultLanguage); - settings.setValue(QStringLiteral("preferredLanguages"), d->preferredLanguages); - settings.setValue(QStringLiteral("checkUppercase"), d->checkUppercase); - settings.setValue(QStringLiteral("skipRunTogether"), d->skipRunTogether); - settings.setValue(QStringLiteral("backgroundCheckerEnabled"), d->backgroundCheckerEnabled); - settings.setValue(QStringLiteral("checkerEnabledByDefault"), d->checkerEnabledByDefault); - settings.setValue(QStringLiteral("autodetectLanguage"), d->autodetectLanguage); - QString defaultLanguage = QStringLiteral("ignore_%1").arg(d->defaultLanguage); - if (settings.contains(defaultLanguage) && d->ignore.isEmpty()) { - settings.remove(defaultLanguage); - } else if (!d->ignore.isEmpty()) { - settings.setValue(defaultLanguage, QStringList(d->ignore.keys())); - } + return d->loader->settings()->modified(); } +// default values // A static list of KDE specific words that we want to recognize -static QStringList kdeWords() +QStringList Settings::defaultIgnoreList() { QStringList l; l.append(QStringLiteral("KMail")); @@ -269,40 +157,38 @@ return l; } -void Settings::restore() +bool Settings::defaultSkipUppercase() +{ + return false; +} + +bool Settings::defaultAutodetectLanguage() { - QSettings settings(QStringLiteral("KDE"), QStringLiteral("Sonnet")); - d->defaultClient = settings.value(QStringLiteral("defaultClient"), QString()).toString(); - d->defaultLanguage = settings.value(QStringLiteral("defaultLanguage"), - QLocale::system().name()).toString(); - d->preferredLanguages = settings.value(QStringLiteral("preferredLanguages")).toStringList(); + return true; +} - //same defaults are in the default filter (filter.cpp) - d->checkUppercase = settings.value(QStringLiteral("checkUppercase"), true).toBool(); - d->skipRunTogether = settings.value(QStringLiteral("skipRunTogether"), true).toBool(); - d->backgroundCheckerEnabled - = settings.value(QStringLiteral("backgroundCheckerEnabled"), true).toBool(); - d->checkerEnabledByDefault - = settings.value(QStringLiteral("checkerEnabledByDefault"), false).toBool(); - d->disablePercentage - = settings.value(QStringLiteral("Sonnet_AsYouTypeDisablePercentage"), 90).toInt(); - d->disableWordCount - = settings.value(QStringLiteral("Sonnet_AsYouTypeDisableWordCount"), 100).toInt(); - d->autodetectLanguage = settings.value(QStringLiteral("autodetectLanguage"), true).toBool(); +bool Settings::defaultBackgroundCheckerEnabled() +{ + return true; +} - const QString ignoreEntry = QStringLiteral("ignore_%1").arg(d->defaultLanguage); - const QStringList ignores = settings.value(ignoreEntry, kdeWords()).toStringList(); - setQuietIgnoreList(ignores); +bool Settings::defaultCheckerEnabledByDefault() +{ + return false; } -bool Settings::modified() const +bool Settings::defauktSkipRunTogether() { - return d->modified; + return true; } -void Settings::setModified(bool modified) +QString Settings::defaultDefaultLanguage() { - d->modified = modified; + return QLocale::system().name(); } -} // namespace Sonnet +QStringList Settings::defaultPreferredLanguages() +{ + return QStringList(); +} +} diff --git a/src/core/settings.cpp b/src/core/settingsimpl.cpp copy from src/core/settings.cpp copy to src/core/settingsimpl.cpp --- a/src/core/settings.cpp +++ b/src/core/settingsimpl.cpp @@ -5,16 +5,17 @@ * * SPDX-License-Identifier: LGPL-2.1-or-later */ -#include "settings_p.h" +#include "settingsimpl_p.h" #include "loader_p.h" #include -#include #include +#include "settings.h" + namespace Sonnet { -class SettingsPrivate +class SettingsImplPrivate { public: Loader *loader = nullptr; //can't be a Ptr since we don't want to hold a ref on it @@ -36,22 +37,22 @@ QMap ignore; }; -Settings::Settings(Loader *loader) - : d(new SettingsPrivate) +SettingsImpl::SettingsImpl(Loader *loader) + : d(new SettingsImplPrivate) { d->loader = loader; d->modified = false; d->checkerEnabledByDefault = false; restore(); } -Settings::~Settings() +SettingsImpl::~SettingsImpl() { delete d; } -bool Settings::setDefaultLanguage(const QString &lang) +bool SettingsImpl::setDefaultLanguage(const QString &lang) { const QStringList cs = d->loader->languages(); if (cs.indexOf(lang) != -1 @@ -64,12 +65,12 @@ return false; } -QString Settings::defaultLanguage() const +QString SettingsImpl::defaultLanguage() const { return d->defaultLanguage; } -bool Settings::setPreferredLanguages(const QStringList &lang) +bool SettingsImpl::setPreferredLanguages(const QStringList &lang) { if (d->preferredLanguages != lang) { d->modified = true; @@ -80,12 +81,12 @@ return false; } -QStringList Settings::preferredLanguages() const +QStringList SettingsImpl::preferredLanguages() const { return d->preferredLanguages; } -bool Settings::setDefaultClient(const QString &client) +bool SettingsImpl::setDefaultClient(const QString &client) { //Different from setDefaultLanguage because //the number of clients can't be even close @@ -99,12 +100,12 @@ return false; } -QString Settings::defaultClient() const +QString SettingsImpl::defaultClient() const { return d->defaultClient; } -bool Settings::setCheckUppercase(bool check) +bool SettingsImpl::setCheckUppercase(bool check) { if (d->checkUppercase != check) { d->modified = true; @@ -114,12 +115,12 @@ return false; } -bool Settings::checkUppercase() const +bool SettingsImpl::checkUppercase() const { return d->checkUppercase; } -bool Settings::setAutodetectLanguage(bool detect) +bool SettingsImpl::setAutodetectLanguage(bool detect) { if (d->autodetectLanguage != detect) { d->modified = true; @@ -129,12 +130,12 @@ return false; } -bool Settings::autodetectLanguage() const +bool SettingsImpl::autodetectLanguage() const { return d->autodetectLanguage; } -bool Settings::setSkipRunTogether(bool skip) +bool SettingsImpl::setSkipRunTogether(bool skip) { if (d->skipRunTogether != skip) { d->modified = true; @@ -144,12 +145,12 @@ return false; } -bool Settings::skipRunTogether() const +bool SettingsImpl::skipRunTogether() const { return d->skipRunTogether; } -bool Settings::setCheckerEnabledByDefault(bool check) +bool SettingsImpl::setCheckerEnabledByDefault(bool check) { if (d->checkerEnabledByDefault != check) { d->modified = true; @@ -159,12 +160,12 @@ return false; } -bool Settings::checkerEnabledByDefault() const +bool SettingsImpl::checkerEnabledByDefault() const { return d->checkerEnabledByDefault; } -bool Settings::setBackgroundCheckerEnabled(bool enable) +bool SettingsImpl::setBackgroundCheckerEnabled(bool enable) { if (d->backgroundCheckerEnabled != enable) { d->modified = true; @@ -174,19 +175,19 @@ return false; } -bool Settings::backgroundCheckerEnabled() const +bool SettingsImpl::backgroundCheckerEnabled() const { return d->backgroundCheckerEnabled; } -bool Settings::setCurrentIgnoreList(const QStringList &ignores) +bool SettingsImpl::setCurrentIgnoreList(const QStringList &ignores) { bool changed = setQuietIgnoreList(ignores); d->modified = true; return changed; } -bool Settings::setQuietIgnoreList(const QStringList &ignores) +bool SettingsImpl::setQuietIgnoreList(const QStringList &ignores) { bool changed = false; d->ignore = QMap();//clear out @@ -198,12 +199,12 @@ return changed; } -QStringList Settings::currentIgnoreList() const +QStringList SettingsImpl::currentIgnoreList() const { return d->ignore.keys(); } -bool Settings::addWordToIgnore(const QString &word) +bool SettingsImpl::addWordToIgnore(const QString &word) { if (!d->ignore.contains(word)) { d->modified = true; @@ -213,22 +214,22 @@ return false; } -bool Settings::ignore(const QString &word) +bool SettingsImpl::ignore(const QString &word) { return d->ignore.contains(word); } -int Settings::disablePercentageWordError() const +int SettingsImpl::disablePercentageWordError() const { return d->disablePercentage; } -int Settings::disableWordErrorCount() const +int SettingsImpl::disableWordErrorCount() const { return d->disableWordCount; } -void Settings::save() +void SettingsImpl::save() { QSettings settings(QStringLiteral("KDE"), QStringLiteral("Sonnet")); settings.setValue(QStringLiteral("defaultClient"), d->defaultClient); @@ -247,62 +248,39 @@ } } -// A static list of KDE specific words that we want to recognize -static QStringList kdeWords() -{ - QStringList l; - l.append(QStringLiteral("KMail")); - l.append(QStringLiteral("KOrganizer")); - l.append(QStringLiteral("KAddressBook")); - l.append(QStringLiteral("KHTML")); - l.append(QStringLiteral("KIO")); - l.append(QStringLiteral("KJS")); - l.append(QStringLiteral("Konqueror")); - l.append(QStringLiteral("Sonnet")); - l.append(QStringLiteral("Kontact")); - l.append(QStringLiteral("Qt")); - l.append(QStringLiteral("Okular")); - l.append(QStringLiteral("KMix")); - l.append(QStringLiteral("Amarok")); - l.append(QStringLiteral("KDevelop")); - l.append(QStringLiteral("Nepomuk")); - return l; -} - -void Settings::restore() +void SettingsImpl::restore() { QSettings settings(QStringLiteral("KDE"), QStringLiteral("Sonnet")); d->defaultClient = settings.value(QStringLiteral("defaultClient"), QString()).toString(); d->defaultLanguage = settings.value(QStringLiteral("defaultLanguage"), - QLocale::system().name()).toString(); - d->preferredLanguages = settings.value(QStringLiteral("preferredLanguages")).toStringList(); + Settings::defaultDefaultLanguage()).toString(); + d->preferredLanguages = settings.value(QStringLiteral("preferredLanguages"), Settings::defaultPreferredLanguages()).toStringList(); //same defaults are in the default filter (filter.cpp) - d->checkUppercase = settings.value(QStringLiteral("checkUppercase"), true).toBool(); - d->skipRunTogether = settings.value(QStringLiteral("skipRunTogether"), true).toBool(); + d->checkUppercase = settings.value(QStringLiteral("checkUppercase"), !Settings::defaultSkipUppercase()).toBool(); + d->skipRunTogether = settings.value(QStringLiteral("skipRunTogether"), Settings::defauktSkipRunTogether()).toBool(); d->backgroundCheckerEnabled - = settings.value(QStringLiteral("backgroundCheckerEnabled"), true).toBool(); + = settings.value(QStringLiteral("backgroundCheckerEnabled"), Settings::defaultBackgroundCheckerEnabled()).toBool(); d->checkerEnabledByDefault - = settings.value(QStringLiteral("checkerEnabledByDefault"), false).toBool(); + = settings.value(QStringLiteral("checkerEnabledByDefault"), Settings::defaultCheckerEnabledByDefault()).toBool(); d->disablePercentage = settings.value(QStringLiteral("Sonnet_AsYouTypeDisablePercentage"), 90).toInt(); d->disableWordCount = settings.value(QStringLiteral("Sonnet_AsYouTypeDisableWordCount"), 100).toInt(); - d->autodetectLanguage = settings.value(QStringLiteral("autodetectLanguage"), true).toBool(); + d->autodetectLanguage = settings.value(QStringLiteral("autodetectLanguage"), Settings::defaultAutodetectLanguage()).toBool(); const QString ignoreEntry = QStringLiteral("ignore_%1").arg(d->defaultLanguage); - const QStringList ignores = settings.value(ignoreEntry, kdeWords()).toStringList(); + const QStringList ignores = settings.value(ignoreEntry, Settings::defaultIgnoreList()).toStringList(); setQuietIgnoreList(ignores); } -bool Settings::modified() const +bool SettingsImpl::modified() const { return d->modified; } -void Settings::setModified(bool modified) +void SettingsImpl::setModified(bool modified) { d->modified = modified; } - } // namespace Sonnet diff --git a/src/core/settings_p.h b/src/core/settingsimpl_p.h rename from src/core/settings_p.h rename to src/core/settingsimpl_p.h --- a/src/core/settings_p.h +++ b/src/core/settingsimpl_p.h @@ -3,26 +3,27 @@ * * SPDX-License-Identifier: LGPL-2.1-or-later */ -#ifndef SONNET_SETTINGS_P_H -#define SONNET_SETTINGS_P_H +#ifndef SONNET_SETTINGS_IMPL_P_H +#define SONNET_SETTINGS_IMPL_P_H + +#include "sonnetcore_export.h" #include #include -#include "sonnetcore_export.h" namespace Sonnet { class Loader; -class SettingsPrivate; +class SettingsImplPrivate; /** - * Settings class + * SettingsImpl class */ -class SONNETCORE_EXPORT Settings +class SONNETCORE_EXPORT SettingsImpl { public: - ~Settings(); + ~SettingsImpl(); - Settings(const Settings &) = delete; - Settings &operator=(const Settings &) = delete; + SettingsImpl(const SettingsImpl &) = delete; + SettingsImpl &operator=(const SettingsImpl &) = delete; bool modified() const; void setModified(bool modified); @@ -63,15 +64,14 @@ int disableWordErrorCount() const; private: - void readIgnoreList(); bool setQuietIgnoreList(const QStringList &ignores); private: friend class Loader; - explicit Settings(Loader *loader); + explicit SettingsImpl(Loader *loader); private: - SettingsPrivate *const d; + SettingsImplPrivate *const d; }; } -#endif // SONNET_SETTINGS_P_H +#endif // SONNET_SETTINGS_IMPL_P_H diff --git a/src/core/speller.cpp b/src/core/speller.cpp --- a/src/core/speller.cpp +++ b/src/core/speller.cpp @@ -6,7 +6,7 @@ #include "speller.h" #include "loader_p.h" -#include "settings_p.h" +#include "settingsimpl_p.h" #include "spellerplugin_p.h" #include @@ -58,7 +58,7 @@ } QSharedPointer dict; - Settings *settings = nullptr; + SettingsImpl *settings = nullptr; QString language; }; diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -4,6 +4,7 @@ set(sonnetui_SRCS configdialog.cpp + configview.cpp configwidget.cpp dialog.cpp dictionarycombobox.cpp @@ -30,6 +31,7 @@ Dialog Highlighter ConfigDialog + ConfigView ConfigWidget DictionaryComboBox SpellCheckDecorator diff --git a/src/ui/configui.ui b/src/ui/configui.ui --- a/src/ui/configui.ui +++ b/src/ui/configui.ui @@ -72,35 +72,35 @@ - + Enable autodetection of &language - + Enable &background spellchecking - + &Automatic spell checking enabled by default - + Skip all &uppercase words - + S&kip run-together words diff --git a/src/ui/configview.h b/src/ui/configview.h new file mode 100644 --- /dev/null +++ b/src/ui/configview.h @@ -0,0 +1,52 @@ +/* + * + * SPDX-FileCopyrightText: 2004 Zack Rusin + * SPDX-FileCopyrightText: 2020 Benjamin Port + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ +#ifndef SONNET_CONFIGVIEW_H +#define SONNET_CONFIGVIEW_H + +#include + +#include "sonnetui_export.h" + +class ConfigViewPrivate; + +namespace Sonnet { + +class SONNETUI_EXPORT ConfigView : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QString language READ language WRITE setLanguage) + Q_PROPERTY(QStringList ignoreList READ ignoreList WRITE setIgnoreList) + Q_PROPERTY(QStringList preferredLanguages READ preferredLanguages WRITE setPreferredLanguages) + Q_PROPERTY(bool backgroundCheckingButtonShown READ backgroundCheckingButtonShown WRITE setBackgroundCheckingButtonShown) + Q_PROPERTY(bool showNoBackendFound READ noBackendFoundVisible WRITE setNoBackendFoundVisible) +public: + explicit ConfigView(QWidget *parent = nullptr); + ~ConfigView() override; + + bool backgroundCheckingButtonShown() const; + bool noBackendFoundVisible() const; + QStringList preferredLanguages() const; + QString language() const; + QStringList ignoreList() const; + +public Q_SLOTS: + void setNoBackendFoundVisible(bool show); + void setBackgroundCheckingButtonShown(bool); + void setPreferredLanguages(const QStringList &ignoreList); + void setLanguage(const QString &language); + void setIgnoreList(const QStringList &ignoreList); + +Q_SIGNALS: + void configChanged(); + +private: + ConfigViewPrivate *const d; +}; +} + +#endif diff --git a/src/ui/configview.cpp b/src/ui/configview.cpp new file mode 100644 --- /dev/null +++ b/src/ui/configview.cpp @@ -0,0 +1,198 @@ +/* + * configwidget.cpp + * + * SPDX-FileCopyrightText: 2004 Zack Rusin + * SPDX-FileCopyrightText: 2020 Benjamin Port + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ +#include "configview.h" +#include "ui_configui.h" + +#include +#include +#include +#include "ui_debug.h" + +using namespace Sonnet; + +class ConfigViewPrivate +{ +public: + explicit ConfigViewPrivate(ConfigView *v); + Ui_SonnetConfigUI ui; + QWidget *wdg = nullptr; + QStringList ignoreList; + ConfigView *q; + void slotUpdateButton(const QString &text); + void slotSelectionChanged(); + void slotIgnoreWordAdded(); + void slotIgnoreWordRemoved(); +}; + +ConfigViewPrivate::ConfigViewPrivate(ConfigView *v) +{ + q = v; +} + +void ConfigViewPrivate::slotUpdateButton(const QString &text) +{ + ui.addButton->setEnabled(!text.isEmpty()); +} + +void ConfigViewPrivate::slotSelectionChanged() +{ + ui.removeButton->setEnabled(!ui.ignoreListWidget->selectedItems().isEmpty()); +} + +void ConfigViewPrivate::slotIgnoreWordAdded() +{ + QString newWord = ui.newIgnoreEdit->text(); + ui.newIgnoreEdit->clear(); + if (newWord.isEmpty() || ignoreList.contains(newWord)) { + return; + } + ignoreList.append(newWord); + + ui.ignoreListWidget->clear(); + ui.ignoreListWidget->addItems(ignoreList); + + emit q->configChanged(); +} + +void ConfigViewPrivate::slotIgnoreWordRemoved() +{ + const QList selectedItems = ui.ignoreListWidget->selectedItems(); + for (const QListWidgetItem *item : selectedItems) { + ignoreList.removeAll(item->text()); + } + + ui.ignoreListWidget->clear(); + ui.ignoreListWidget->addItems(ignoreList); + + emit q->configChanged(); +} + +ConfigView::ConfigView(QWidget *parent) + : QWidget(parent) + , d(new ConfigViewPrivate(this)) +{ + auto *layout = new QVBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->setObjectName(QStringLiteral("SonnetConfigUILayout")); + d->wdg = new QWidget(this); + d->ui.setupUi(d->wdg); + + for (int i = 0; i < d->ui.m_langCombo->count(); i++) { + const QString tag = d->ui.m_langCombo->itemData(i).toString(); + if (tag.isEmpty()) { // skip separator + continue; + } + auto *item = new QListWidgetItem(d->ui.m_langCombo->itemText(i), d->ui.languageList); + item->setData(Qt::UserRole, tag); + } + + d->ui.kcfg_backgroundCheckerEnabled->hide();//hidden by default + + connect(d->ui.addButton, &QAbstractButton::clicked, this, [this]{ d->slotIgnoreWordAdded(); }); + connect(d->ui.removeButton, &QAbstractButton::clicked, this, [this]{ d->slotIgnoreWordRemoved(); }); + + layout->addWidget(d->wdg); + connect(d->ui.newIgnoreEdit, &QLineEdit::textChanged, this, [this](const QString &text){ d->slotUpdateButton(text); }); + connect(d->ui.ignoreListWidget, &QListWidget::itemSelectionChanged, this, [this]{ d->slotSelectionChanged(); }); + d->ui.addButton->setEnabled(false); + d->ui.removeButton->setEnabled(false); + + connect(d->ui.m_langCombo, &DictionaryComboBox::dictionaryChanged, this, + &ConfigView::configChanged); + connect(d->ui.languageList, &QListWidget::itemChanged, this, &ConfigView::configChanged); + + connect(d->ui.kcfg_backgroundCheckerEnabled, &QAbstractButton::clicked, this, &ConfigView::configChanged); + connect(d->ui.kcfg_skipUppercase, &QAbstractButton::clicked, this, &ConfigView::configChanged); + connect(d->ui.kcfg_skipRunTogether, &QAbstractButton::clicked, this, + &ConfigView::configChanged); + connect(d->ui.kcfg_checkerEnabledByDefault, &QAbstractButton::clicked, this, + &ConfigView::configChanged); + connect(d->ui.kcfg_autodetectLanguage, &QAbstractButton::clicked, this, &ConfigView::configChanged); +} + +ConfigView::~ConfigView() +{ + delete d; +} + +void ConfigView::setNoBackendFoundVisible(bool show) +{ + d->ui.nobackendfound->setVisible(show); +} + + +bool ConfigView::noBackendFoundVisible() const +{ + return d->ui.nobackendfound->isVisible(); +} + +void ConfigView::setBackgroundCheckingButtonShown(bool b) +{ + d->ui.kcfg_backgroundCheckerEnabled->setVisible(b); +} + +bool ConfigView::backgroundCheckingButtonShown() const +{ + return !d->ui.kcfg_backgroundCheckerEnabled->isHidden(); +} + +void ConfigView::setLanguage(const QString &language) +{ + d->ui.m_langCombo->setCurrentByDictionary(language); +} + +QString ConfigView::language() const +{ + if (d->ui.m_langCombo->count()) { + return d->ui.m_langCombo->currentDictionary(); + } else { + return QString(); + } +} + +void ConfigView::setPreferredLanguages(const QStringList& preferredLanguages) +{ + for(int i = 0; i < d->ui.languageList->count(); ++i) { + QListWidgetItem* item = d->ui.languageList->item(i); + QString tag = item->data(Qt::UserRole).toString(); + if (preferredLanguages.contains(tag)) { + item->setCheckState(Qt::Checked); + } else { + item->setCheckState(Qt::Unchecked); + } + } + emit configChanged(); +} + + +QStringList ConfigView::preferredLanguages() const +{ + QStringList preferredLanguages; + for (int i = 0; i < d->ui.languageList->count(); i++) { + if (d->ui.languageList->item(i)->checkState() == Qt::Unchecked) { + continue; + } + preferredLanguages << d->ui.languageList->item(i)->data(Qt::UserRole).toString(); + } + return preferredLanguages; +} + +void ConfigView::setIgnoreList(const QStringList& ignoreList) +{ + d->ignoreList = ignoreList; + d->ignoreList.sort(); + d->ui.ignoreListWidget->clear(); + d->ui.ignoreListWidget->addItems(d->ignoreList); + emit configChanged(); +} + +QStringList ConfigView::ignoreList() const +{ + return d->ignoreList; +} diff --git a/src/ui/configwidget.cpp b/src/ui/configwidget.cpp --- a/src/ui/configwidget.cpp +++ b/src/ui/configwidget.cpp @@ -9,7 +9,8 @@ #include "ui_configui.h" #include "loader_p.h" -#include "settings_p.h" +#include "settingsimpl_p.h" +#include "settings.h" #include #include @@ -23,24 +24,24 @@ { public: Ui_SonnetConfigUI ui; - Loader *loader = nullptr; + Settings *settings = nullptr; QWidget *wdg = nullptr; }; ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) , d(new ConfigWidgetPrivate) { - d->loader = Loader::openLoader(); + d->settings = new Settings(this); QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setObjectName(QStringLiteral("SonnetConfigUILayout")); d->wdg = new QWidget(this); d->ui.setupUi(d->wdg); - d->ui.m_langCombo->setCurrentByDictionary(d->loader->settings()->defaultLanguage()); + d->ui.m_langCombo->setCurrentByDictionary(d->settings->defaultLanguage()); - QStringList preferredLanguages = d->loader->settings()->preferredLanguages(); + QStringList preferredLanguages = d->settings->preferredLanguages(); for (int i = 0; i < d->ui.m_langCombo->count(); i++) { const QString tag = d->ui.m_langCombo->itemData(i).toString(); if (tag.isEmpty()) { // skip separator @@ -56,15 +57,15 @@ } } - d->ui.m_skipUpperCB->setChecked(!d->loader->settings()->checkUppercase()); - d->ui.m_skipRunTogetherCB->setChecked(d->loader->settings()->skipRunTogether()); - d->ui.m_checkerEnabledByDefaultCB->setChecked(d->loader->settings()->checkerEnabledByDefault()); - d->ui.m_autodetectCB->setChecked(d->loader->settings()->autodetectLanguage()); - QStringList ignoreList = d->loader->settings()->currentIgnoreList(); + d->ui.kcfg_skipUppercase->setChecked(d->settings->skipUppercase()); + d->ui.kcfg_skipRunTogether->setChecked(d->settings->skipRunTogether()); + d->ui.kcfg_checkerEnabledByDefault->setChecked(d->settings->checkerEnabledByDefault()); + d->ui.kcfg_autodetectLanguage->setChecked(d->settings->autodetectLanguage()); + QStringList ignoreList = d->settings->currentIgnoreList(); ignoreList.sort(); d->ui.ignoreListWidget->addItems(ignoreList); - d->ui.m_bgSpellCB->setChecked(d->loader->settings()->backgroundCheckerEnabled()); - d->ui.m_bgSpellCB->hide();//hidden by default + d->ui.kcfg_backgroundCheckerEnabled->setChecked(d->settings->backgroundCheckerEnabled()); + d->ui.kcfg_backgroundCheckerEnabled->hide();//hidden by default connect(d->ui.addButton, &QAbstractButton::clicked, this, &ConfigWidget::slotIgnoreWordAdded); connect(d->ui.removeButton, &QAbstractButton::clicked, this, &ConfigWidget::slotIgnoreWordRemoved); @@ -74,16 +75,16 @@ &ConfigWidget::configChanged); connect(d->ui.languageList, &QListWidget::itemChanged, this, &ConfigWidget::configChanged); - connect(d->ui.m_bgSpellCB, &QAbstractButton::clicked, this, &ConfigWidget::configChanged); - connect(d->ui.m_skipUpperCB, &QAbstractButton::clicked, this, &ConfigWidget::configChanged); - connect(d->ui.m_skipRunTogetherCB, &QAbstractButton::clicked, this, + connect(d->ui.kcfg_backgroundCheckerEnabled, &QAbstractButton::clicked, this, &ConfigWidget::configChanged); + connect(d->ui.kcfg_skipUppercase, &QAbstractButton::clicked, this, &ConfigWidget::configChanged); + connect(d->ui.kcfg_skipRunTogether, &QAbstractButton::clicked, this, &ConfigWidget::configChanged); - connect(d->ui.m_checkerEnabledByDefaultCB, &QAbstractButton::clicked, this, + connect(d->ui.kcfg_checkerEnabledByDefault, &QAbstractButton::clicked, this, &ConfigWidget::configChanged); - connect(d->ui.m_autodetectCB, &QAbstractButton::clicked, this, &ConfigWidget::configChanged); + connect(d->ui.kcfg_autodetectLanguage, &QAbstractButton::clicked, this, &ConfigWidget::configChanged); connect(d->ui.newIgnoreEdit, &QLineEdit::textChanged, this, &ConfigWidget::slotUpdateButton); connect(d->ui.ignoreListWidget, &QListWidget::itemSelectionChanged, this, &ConfigWidget::slotSelectionChanged); - d->ui.nobackendfound->setVisible(d->loader->clients().isEmpty()); + d->ui.nobackendfound->setVisible(d->settings->clients().isEmpty()); d->ui.addButton->setEnabled(false); d->ui.removeButton->setEnabled(false); } @@ -110,10 +111,8 @@ void ConfigWidget::setFromGui() { - Settings *settings = d->loader->settings(); - if (d->ui.m_langCombo->count()) { - settings->setDefaultLanguage(d->ui.m_langCombo->currentDictionary()); + d->settings->setDefaultLanguage(d->ui.m_langCombo->currentDictionary()); } QStringList preferredLanguages; @@ -123,29 +122,29 @@ } preferredLanguages << d->ui.languageList->item(i)->data(Qt::UserRole).toString(); } - settings->setPreferredLanguages(preferredLanguages); + d->settings->setPreferredLanguages(preferredLanguages); - settings->setCheckUppercase(!d->ui.m_skipUpperCB->isChecked()); - settings->setSkipRunTogether(d->ui.m_skipRunTogetherCB->isChecked()); - settings->setBackgroundCheckerEnabled(d->ui.m_bgSpellCB->isChecked()); - settings->setCheckerEnabledByDefault(d->ui.m_checkerEnabledByDefaultCB->isChecked()); - settings->setAutodetectLanguage(d->ui.m_autodetectCB->isChecked()); + d->settings->setSkipUppercase(d->ui.kcfg_skipUppercase->isChecked()); + d->settings->setSkipRunTogether(d->ui.kcfg_skipRunTogether->isChecked()); + d->settings->setBackgroundCheckerEnabled(d->ui.kcfg_backgroundCheckerEnabled->isChecked()); + d->settings->setCheckerEnabledByDefault(d->ui.kcfg_checkerEnabledByDefault->isChecked()); + d->settings->setAutodetectLanguage(d->ui.kcfg_autodetectLanguage->isChecked()); - if (settings->modified()) { - settings->save(); + if (d->settings->modified()) { + d->settings->save(); } } void ConfigWidget::slotIgnoreWordAdded() { - QStringList ignoreList = d->loader->settings()->currentIgnoreList(); + QStringList ignoreList = d->settings->currentIgnoreList(); QString newWord = d->ui.newIgnoreEdit->text(); d->ui.newIgnoreEdit->clear(); if (newWord.isEmpty() || ignoreList.contains(newWord)) { return; } ignoreList.append(newWord); - d->loader->settings()->setCurrentIgnoreList(ignoreList); + d->settings->setCurrentIgnoreList(ignoreList); d->ui.ignoreListWidget->clear(); d->ui.ignoreListWidget->addItems(ignoreList); @@ -155,12 +154,12 @@ void ConfigWidget::slotIgnoreWordRemoved() { - QStringList ignoreList = d->loader->settings()->currentIgnoreList(); + QStringList ignoreList = d->settings->currentIgnoreList(); const QList selectedItems = d->ui.ignoreListWidget->selectedItems(); for (const QListWidgetItem *item : selectedItems) { ignoreList.removeAll(item->text()); } - d->loader->settings()->setCurrentIgnoreList(ignoreList); + d->settings->setCurrentIgnoreList(ignoreList); d->ui.ignoreListWidget->clear(); d->ui.ignoreListWidget->addItems(ignoreList); @@ -170,23 +169,23 @@ void ConfigWidget::setBackgroundCheckingButtonShown(bool b) { - d->ui.m_bgSpellCB->setVisible(b); + d->ui.kcfg_backgroundCheckerEnabled->setVisible(b); } bool ConfigWidget::backgroundCheckingButtonShown() const { - return !d->ui.m_bgSpellCB->isHidden(); + return !d->ui.kcfg_backgroundCheckerEnabled->isHidden(); } void ConfigWidget::slotDefault() { - d->ui.m_autodetectCB->setChecked(true); - d->ui.m_skipUpperCB->setChecked(false); - d->ui.m_skipRunTogetherCB->setChecked(false); - d->ui.m_checkerEnabledByDefaultCB->setChecked(false); - d->ui.m_bgSpellCB->setChecked(true); + d->ui.kcfg_autodetectLanguage->setChecked(Settings::defaultAutodetectLanguage()); + d->ui.kcfg_skipUppercase->setChecked(Settings::defaultSkipUppercase()); + d->ui.kcfg_skipRunTogether->setChecked(Settings::defauktSkipRunTogether()); + d->ui.kcfg_checkerEnabledByDefault->setChecked(Settings::defaultCheckerEnabledByDefault()); + d->ui.kcfg_backgroundCheckerEnabled->setChecked(Settings::defaultBackgroundCheckerEnabled()); d->ui.ignoreListWidget->clear(); - d->ui.m_langCombo->setCurrentByDictionary(d->loader->settings()->defaultLanguage()); + d->ui.m_langCombo->setCurrentByDictionary(d->settings->defaultLanguage()); } void ConfigWidget::setLanguage(const QString &language) diff --git a/src/ui/dialog.cpp b/src/ui/dialog.cpp --- a/src/ui/dialog.cpp +++ b/src/ui/dialog.cpp @@ -11,7 +11,7 @@ #include "backgroundchecker.h" #include "speller.h" -#include "settings_p.h" +#include "settingsimpl_p.h" #include diff --git a/src/ui/highlighter.cpp b/src/ui/highlighter.cpp --- a/src/ui/highlighter.cpp +++ b/src/ui/highlighter.cpp @@ -13,7 +13,7 @@ #include "speller.h" #include "loader_p.h" #include "tokenizer_p.h" -#include "settings_p.h" +#include "settingsimpl_p.h" #include "languagefilter_p.h" #include "ui_debug.h"