From 22e1626444752f99e32b8c85b27c7b9e2054a96e Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Tue, 7 Feb 2023 18:14:07 -0700 Subject: [PATCH] Enable spell checking. https://redmine.stoutner.com/issues/840 --- src/CMakeLists.txt | 3 +- src/settings/Settings.kcfg | 14 ++++-- src/settings/Settings.kcfgc | 8 ++- src/uis/SettingsGeneral.ui | 2 +- src/uis/SettingsPrivacy.ui | 2 +- src/uis/SettingsSpellCheck.ui | 53 ++++++++++++++++++++ src/widgets/TabWidget.cpp | 28 +++++++++-- src/widgets/TabWidget.h | 1 + src/windows/BrowserWindow.cpp | 93 ++++++++++++++++++++++++++++++++--- 9 files changed, 188 insertions(+), 16 deletions(-) create mode 100644 src/uis/SettingsSpellCheck.ui diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8278a21..2d1340b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2022 Soren Stoutner . +# Copyright 2022-2023 Soren Stoutner . # # This file is part of Privacy Browser PC . # @@ -43,6 +43,7 @@ ki18n_wrap_ui(privacy-browser uis/SaveDialog.ui uis/SettingsGeneral.ui uis/SettingsPrivacy.ui + uis/SettingsSpellCheck.ui uis/TabWidget.ui ) diff --git a/src/settings/Settings.kcfg b/src/settings/Settings.kcfg index 9b46d73..9f8a87d 100644 --- a/src/settings/Settings.kcfg +++ b/src/settings/Settings.kcfg @@ -1,7 +1,7 @@ - + - + @@ -82,4 +84,10 @@ true + + + + en_US + + diff --git a/src/settings/Settings.kcfgc b/src/settings/Settings.kcfgc index 42940f7..dce7cb8 100644 --- a/src/settings/Settings.kcfgc +++ b/src/settings/Settings.kcfgc @@ -1,4 +1,4 @@ -# Copyright © 2022 Soren Stoutner . +# Copyright 2022-2023 Soren Stoutner . # # This file is part of Privacy Browser PC . # @@ -15,6 +15,9 @@ # You should have received a copy of the GNU General Public License # along with Privacy Browser PC. If not, see . +# The options for this file are partially specified at the following URLs: +# +# # Specify the KConfig file. File=Settings.kcfg @@ -24,3 +27,6 @@ ClassName=Settings # Make the generated class a singleton. Singleton=true + +# List of variables that can be manually changed. +Mutators=spellCheckLanguages diff --git a/src/uis/SettingsGeneral.ui b/src/uis/SettingsGeneral.ui index 38fcfd4..d2911fa 100644 --- a/src/uis/SettingsGeneral.ui +++ b/src/uis/SettingsGeneral.ui @@ -1,7 +1,7 @@ + + + + SpellCheckSettings + + + + + + + + Spell checking languages can be added by installing the Hunspell language packages. One or more languages can be selected. All selected languages will be applied simultaneously. + + + + true + + + + + + + + + + 0 + 0 + + + + + + + diff --git a/src/widgets/TabWidget.cpp b/src/widgets/TabWidget.cpp index aee71d7..a5ecefc 100644 --- a/src/widgets/TabWidget.cpp +++ b/src/widgets/TabWidget.cpp @@ -341,7 +341,7 @@ PrivacyWebEngineView* TabWidget::addTab(const bool removeUrlLineEditFocus, const webEngineProfilePointer->setSpellCheckEnabled(true); // Set the spell check language. - webEngineProfilePointer->setSpellCheckLanguages({QLatin1String("en_US")}); + webEngineProfilePointer->setSpellCheckLanguages(Settings::spellCheckLanguages()); // Populate the zoom factor. This is necessary if a URL is being loaded, like a local URL, that does not trigger `applyDomainSettings()`. privacyWebEngineViewPointer->setZoomFactor(Settings::zoomFactor()); @@ -554,7 +554,7 @@ void TabWidget::applyOnTheFlySearchEngine(QAction *searchEngineActionPointer) // Store the search engine string. searchEngineUrl = SearchEngineHelper::getSearchUrl(searchEngineName); - // Update the search engine actionas. + // Update the search engine actions. emit updateSearchEngineActions(searchEngineName, false); } @@ -586,6 +586,28 @@ void TabWidget::applyOnTheFlyZoomFactor(const double &zoomFactor) currentPrivacyWebEngineViewPointer->setZoomFactor(zoomFactor); } +void TabWidget::applySpellCheckLanguages() const +{ + // Get the number of tab. + int numberOfTabs = tabWidgetPointer->count(); + + // Set the spell check languages for each tab. + for (int i = 0; i < numberOfTabs; ++i) + { + // Get the WebEngine view pointer. + PrivacyWebEngineView *webEngineViewPointer = qobject_cast(tabWidgetPointer->currentWidget()); + + // Get the WebEngine page pointer. + QWebEnginePage *webEnginePagePointer = webEngineViewPointer->page(); + + // Get the WebEngine profile pointer. + QWebEngineProfile *webEngineProfilePointer = webEnginePagePointer->profile(); + + // Set the spell check languages. + webEngineProfilePointer->setSpellCheckLanguages(Settings::spellCheckLanguages()); + } +} + void TabWidget::back() const { // Go back. @@ -1058,7 +1080,7 @@ void TabWidget::toggleJavaScript() const void TabWidget::toggleLocalStorage() { - // Toggle local storeage. + // Toggle local storage. currentPrivacyWebEngineViewPointer->localStorageEnabled = !currentPrivacyWebEngineViewPointer->localStorageEnabled; // Update the local storage action. diff --git a/src/widgets/TabWidget.h b/src/widgets/TabWidget.h index 4b247f7..72a50a0 100644 --- a/src/widgets/TabWidget.h +++ b/src/widgets/TabWidget.h @@ -51,6 +51,7 @@ public: // The public functions. void applyOnTheFlyZoomFactor(const double &zoomFactor); + void applySpellCheckLanguages() const; PrivacyWebEngineView* loadBlankInitialWebsite(); void loadInitialWebsite(); void findPrevious(const QString &text) const; diff --git a/src/windows/BrowserWindow.cpp b/src/windows/BrowserWindow.cpp index 5960393..efa87ab 100644 --- a/src/windows/BrowserWindow.cpp +++ b/src/windows/BrowserWindow.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2022 Soren Stoutner . + * Copyright 2022-2023 Soren Stoutner . * * This file is part of Privacy Browser PC . * @@ -20,8 +20,9 @@ // Application headers. #include "BrowserWindow.h" #include "Settings.h" -#include "ui_SettingsPrivacy.h" #include "ui_SettingsGeneral.h" +#include "ui_SettingsPrivacy.h" +#include "ui_SettingsSpellCheck.h" #include "dialogs/CookiesDialog.h" #include "dialogs/DomainSettingsDialog.h" #include "helpers/SearchEngineHelper.h" @@ -631,14 +632,17 @@ void BrowserWindow::showSettingsDialog() // Create the settings widgets. QWidget *privacySettingsWidgetPointer = new QWidget; QWidget *generalSettingsWidgetPointer = new QWidget; + QWidget *spellCheckSettingsWidgetPointer = new QWidget; // Instantiate the settings UI. Ui::PrivacySettings privacySettingsUi; Ui::GeneralSettings generalSettingsUi; + Ui::SpellCheckSettings spellCheckSettingsUi; // Setup the UI to display the settings widgets. privacySettingsUi.setupUi(privacySettingsWidgetPointer); generalSettingsUi.setupUi(generalSettingsWidgetPointer); + spellCheckSettingsUi.setupUi(spellCheckSettingsWidgetPointer); // Get handles for the widgets. QComboBox *userAgentComboBoxPointer = privacySettingsUi.kcfg_userAgent; @@ -647,6 +651,7 @@ void BrowserWindow::showSettingsDialog() searchEngineLabelPointer = generalSettingsUi.searchEngineLabel; downloadLocationComboBoxPointer = generalSettingsUi.kcfg_downloadLocation; QPushButton *browseButtonPointer = generalSettingsUi.browseButton; + QListWidget *spellCheckListWidgetPointer = spellCheckSettingsUi.spellCheckListWidget; // Populate the combo box labels. updateUserAgentLabel(userAgentComboBoxPointer->currentText()); @@ -659,12 +664,51 @@ void BrowserWindow::showSettingsDialog() // Connect the download location directory browse button. connect(browseButtonPointer, SIGNAL(clicked()), this, SLOT(showDownloadLocationBrowseDialog())); + // Create a dictionaries QDir from the `QTWEBENGINE_DICTIONARIES_PATH` environment variable. + QDir dictionariesDir = QDir(qEnvironmentVariable("QTWEBENGINE_DICTIONARIES_PATH")); + + // Get a dictionaries string list. + QStringList dictionariesStringList = dictionariesDir.entryList(QStringList(QLatin1String("*.bdic")), QDir::Files | QDir::NoSymLinks); + + // Remove the `.bdic` file extensions from the dictionaries list. + dictionariesStringList.replaceInStrings(QLatin1String(".bdic"), QLatin1String("")); + + // Get a list of the enabled spell check languages. + QStringList enabledSpellCheckLanguagesList = Settings::spellCheckLanguages(); + + // Add each dictionary to the spell check list widget. + foreach(QString dictionaryString, dictionariesStringList) + { + // Create a new list widget item pointer named after the dictionary string. + QListWidgetItem *listWidgetItemPointer = new QListWidgetItem(dictionaryString, spellCheckListWidgetPointer); + + // Set the list widget item pointer to be checkable. + listWidgetItemPointer->setFlags(listWidgetItemPointer->flags() | Qt::ItemIsUserCheckable); + + // Check the language if it is currently enabled. + if (enabledSpellCheckLanguagesList.contains(dictionaryString)) + listWidgetItemPointer->setCheckState(Qt::Checked); + else + listWidgetItemPointer->setCheckState(Qt::Unchecked); + + // Add the list widget item to the widget. + spellCheckListWidgetPointer->addItem(listWidgetItemPointer); + } + + // Get a handle for the KConfig skeleton. + KConfigSkeleton *kConfigSkeletonPointer = Settings::self(); + // Instantiate a settings config dialog from the settings.kcfg file. - configDialogPointer = new KConfigDialog(this, QStringLiteral("settings"), Settings::self()); + configDialogPointer = new KConfigDialog(this, QLatin1String("settings"), kConfigSkeletonPointer); // Add the settings widgets as config dialog pages. - configDialogPointer->addPage(privacySettingsWidgetPointer, i18nc("@title:tab", "Privacy"), QStringLiteral("privacy-browser")); - configDialogPointer->addPage(generalSettingsWidgetPointer, i18nc("@title:tab", "General"), QStringLiteral("breeze-settings")); + configDialogPointer->addPage(privacySettingsWidgetPointer, i18nc("Settings tab title", "Privacy"), QLatin1String("privacy-browser")); + configDialogPointer->addPage(generalSettingsWidgetPointer, i18nc("Settings tab title", "General"), QLatin1String("breeze-settings")); + configDialogPointer->addPage(spellCheckSettingsWidgetPointer, i18nc("Settings tab title", "Spell Check"), QLatin1String("tools-check-spelling")); + + // Get handles for the buttons. + QPushButton *applyButtonPointer = configDialogPointer->button(QDialogButtonBox::Apply); + QPushButton *okButtonPointer = configDialogPointer->button(QDialogButtonBox::Ok); // Prevent interaction with the parent window while the dialog is open. configDialogPointer->setWindowModality(Qt::WindowModal); @@ -681,7 +725,44 @@ void BrowserWindow::showSettingsDialog() // Expand the config dialog. configDialogPointer->resize(1000, 500); - // Apply the settings when they are updated. + // Create a save spell check languages lambda. + auto saveSpellCheckLanguages = [spellCheckListWidgetPointer, kConfigSkeletonPointer, this] () + { + // Create a list of enabled languages. + QStringList newSpellCheckLanguages = QStringList(); + + // Get a count of all the languages. + int allLanguagesCount = spellCheckListWidgetPointer->count(); + + // Get a list of all the checked languages. + for (int i = 0; i < allLanguagesCount; ++i) { + // Get the language item. + QListWidgetItem *languageItemPointer = spellCheckListWidgetPointer->item(i); + + // Add the item to the enabled languages if it is checked. + if (languageItemPointer->checkState() == Qt::Checked) + newSpellCheckLanguages.append(languageItemPointer->text()); + } + + // Update the spell check languages. + if (Settings::spellCheckLanguages() != newSpellCheckLanguages) + { + // Update the spell check languages. + Settings::setSpellCheckLanguages(newSpellCheckLanguages); + + // Write the settings to disk. + kConfigSkeletonPointer->save(); + } + + // Apply the spell check languages. + tabWidgetPointer->applySpellCheckLanguages(); + }; + + // Process + connect(applyButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages); + connect(okButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages); + + // Apply the settings handled by KConfig. connect(configDialogPointer, SIGNAL(settingsChanged(QString)), tabWidgetPointer, SLOT(applyApplicationSettings())); connect(configDialogPointer, SIGNAL(settingsChanged(QString)), tabWidgetPointer, SLOT(applyDomainSettingsAndReload())); } -- 2.45.2