2 * Copyright 2024 Soren Stoutner <soren@stoutner.com>.
4 * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
6 * Privacy Browser PC is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * Privacy Browser PC is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
20 // Application headers.
22 #include "SettingsDialog.h"
23 #include "helpers/SearchEngineHelper.h"
24 #include "helpers/UserAgentHelper.h"
25 #include "ui_SettingsGeneral.h"
26 #include "ui_SettingsPrivacy.h"
27 #include "ui_SettingsSpellCheck.h"
29 // Qt toolkit headers.
31 #include <QFileDialog>
33 SettingsDialog::SettingsDialog(QWidget *parentWidgetPointer, KCoreConfigSkeleton *coreConfigSkeletonPointer) :
34 KConfigDialog(parentWidgetPointer, QLatin1String("settings"), coreConfigSkeletonPointer)
36 // Instantiate the settings UI.
37 Ui::PrivacySettings privacySettingsUi;
38 Ui::GeneralSettings generalSettingsUi;
39 Ui::SpellCheckSettings spellCheckSettingsUi;
41 // Create the settings widgets.
42 QWidget *privacySettingsWidgetPointer = new QWidget;
43 QWidget *generalSettingsWidgetPointer = new QWidget;
44 QWidget *spellCheckSettingsWidgetPointer = new QWidget;
46 // Setup the UI to display the settings widgets.
47 privacySettingsUi.setupUi(privacySettingsWidgetPointer);
48 generalSettingsUi.setupUi(generalSettingsWidgetPointer);
49 spellCheckSettingsUi.setupUi(spellCheckSettingsWidgetPointer);
51 // Get handles for the widgets.
52 QCheckBox *javaScriptCheckBoxPointer = privacySettingsUi.kcfg_javaScriptEnabled;
53 QCheckBox *localStorageCheckBoxPointer = privacySettingsUi.kcfg_localStorageEnabled;
54 QCheckBox *domStorageCheckBoxPointer = privacySettingsUi.kcfg_domStorageEnabled;
55 QComboBox *userAgentComboBoxPointer = privacySettingsUi.kcfg_userAgent;
56 userAgentLabelPointer = privacySettingsUi.userAgentLabel;
57 QComboBox *searchEngineComboBoxPointer = generalSettingsUi.kcfg_searchEngine;
58 searchEngineLabelPointer = generalSettingsUi.searchEngineLabel;
59 downloadDirectoryComboBoxPointer = generalSettingsUi.kcfg_downloadDirectory;
60 QPushButton *browseButtonPointer = generalSettingsUi.browseButton;
61 QListWidget *spellCheckListWidgetPointer = spellCheckSettingsUi.spellCheckListWidget;
63 // Create a save spell check languages lambda.
64 auto updateCheckBoxes = [javaScriptCheckBoxPointer, localStorageCheckBoxPointer, domStorageCheckBoxPointer] ()
66 // Only enable the DOM storage check box if both JavaScript and local storage are checked.
67 domStorageCheckBoxPointer->setEnabled(javaScriptCheckBoxPointer->isChecked() && localStorageCheckBoxPointer->isChecked());
70 // Update the status of the DOM storage check box when either JavaScript or local storage are changed.
71 connect(javaScriptCheckBoxPointer, &QCheckBox::stateChanged, this, updateCheckBoxes);
72 connect(localStorageCheckBoxPointer, &QCheckBox::stateChanged, this, updateCheckBoxes);
74 // Populate the combo box labels.
75 updateUserAgentLabel(userAgentComboBoxPointer->currentText());
76 updateSearchEngineLabel(searchEngineComboBoxPointer->currentText());
78 // Update the labels when the combo boxes change.
79 connect(userAgentComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateUserAgentLabel(const QString)));
80 connect(searchEngineComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateSearchEngineLabel(const QString)));
82 // Connect the download directory directory browse button.
83 connect(browseButtonPointer, SIGNAL(clicked()), this, SLOT(showDownloadDirectoryBrowseDialog()));
85 // Create a dictionaries QDir from the `QTWEBENGINE_DICTIONARIES_PATH` environment variable.
86 QDir dictionariesDir = QDir(qEnvironmentVariable("QTWEBENGINE_DICTIONARIES_PATH"));
88 // Get a dictionaries string list.
89 QStringList dictionariesStringList = dictionariesDir.entryList(QStringList(QLatin1String("*.bdic")), QDir::Files | QDir::NoSymLinks);
91 // Remove the `.bdic` file extensions from the dictionaries list.
92 dictionariesStringList.replaceInStrings(QLatin1String(".bdic"), QLatin1String(""));
94 // Get a list of the enabled spell check languages.
95 QStringList enabledSpellCheckLanguagesList = Settings::spellCheckLanguages();
97 // Add each dictionary to the spell check list widget.
98 foreach(QString dictionaryString, dictionariesStringList)
100 // Create a new list widget item pointer.
101 QListWidgetItem *listWidgetItemPointer = new QListWidgetItem();
103 // Create a dictionary check box widget with the name of the dictionary string.
104 QCheckBox *dictionaryCheckBoxWidget = new QCheckBox(dictionaryString);
106 // Check the language if it is currently enabled.
107 if (enabledSpellCheckLanguagesList.contains(dictionaryString))
108 dictionaryCheckBoxWidget->setCheckState(Qt::Checked);
110 dictionaryCheckBoxWidget->setCheckState(Qt::Unchecked);
112 // Add the list widget item to the spell check list widget.
113 spellCheckListWidgetPointer->addItem(listWidgetItemPointer);
115 // Set the list widget item check box widget.
116 spellCheckListWidgetPointer->setItemWidget(listWidgetItemPointer, dictionaryCheckBoxWidget);
119 // Create a settings icon string.
120 QString settingsIconString;
122 // Get a settings icon that matches the theme.
123 if (QIcon::hasThemeIcon("breeze-settings"))
125 // KDE uses breeze-settings.
126 settingsIconString = QLatin1String("breeze-settings");
130 // Gnome uses preferences-desktop.
131 settingsIconString = QLatin1String("preferences-desktop");
134 // Add the settings widgets as config dialog pages.
135 addPage(privacySettingsWidgetPointer, i18nc("Settings tab title", "Privacy"), QLatin1String("privacybrowser"));
136 addPage(generalSettingsWidgetPointer, i18nc("Settings tab title", "General"), settingsIconString);
137 addPage(spellCheckSettingsWidgetPointer, i18nc("Settings tab title", "Spell Check"), QLatin1String("tools-check-spelling"));
139 // Get handles for the buttons.
140 QPushButton *applyButtonPointer = button(QDialogButtonBox::Apply);
141 QPushButton *okButtonPointer = button(QDialogButtonBox::Ok);
143 // Prevent interaction with the parent window while the dialog is open.
144 setWindowModality(Qt::WindowModal);
146 // Create a save spell check languages lambda.
147 auto saveSpellCheckLanguages = [spellCheckListWidgetPointer, coreConfigSkeletonPointer, this] ()
149 // Create a list of enabled languages.
150 QStringList newSpellCheckLanguages = QStringList();
152 // Get a count of all the languages.
153 int allLanguagesCount = spellCheckListWidgetPointer->count();
155 // Get a list of all the checked languages.
156 for (int i = 0; i < allLanguagesCount; ++i) {
157 // Get the language item.
158 QListWidgetItem *languageItemPointer = spellCheckListWidgetPointer->item(i);
160 // Get the language check box.
161 QCheckBox *languageCheckBoxPointer = qobject_cast<QCheckBox*>(spellCheckListWidgetPointer->itemWidget(languageItemPointer));
163 // Add the item to the enabled languages if it is checked.
164 if (languageCheckBoxPointer->checkState() == Qt::Checked)
167 QString languageString = languageCheckBoxPointer->text();
169 // Remove all instances of `&`, which may have been added automatically when creating the check box text.
170 languageString.remove(QChar('&'));
172 // Add the language string to the list.
173 newSpellCheckLanguages.append(languageString);
177 // Update the spell check languages.
178 if (Settings::spellCheckLanguages() != newSpellCheckLanguages)
180 // Update the spell check languages.
181 Settings::setSpellCheckLanguages(newSpellCheckLanguages);
183 // Write the settings to disk.
184 coreConfigSkeletonPointer->save();
186 // Emit the spell check languages updated signal.
187 emit spellCheckLanguagesUpdated();
191 // Process clicks on the buttons.
192 connect(applyButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages);
193 connect(okButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages);
196 void SettingsDialog::showDownloadDirectoryBrowseDialog()
198 // Get the current download directory.
199 QString currentDownloadDirectory = downloadDirectoryComboBoxPointer->currentText();
201 // Resolve the system download directory if specified.
202 if (currentDownloadDirectory == QStringLiteral("System Download Directory"))
203 currentDownloadDirectory = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
205 // Get the new download directory.
206 QString newDownloadDirectory = QFileDialog::getExistingDirectory(this, i18nc("Select download directory dialog caption", "Select Download Directory"), currentDownloadDirectory);
208 // Populate the download directory combo box according to the new download location.
209 if (newDownloadDirectory == QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)) // The default download location was selected.
211 // Populate the download location with the default text.
212 downloadDirectoryComboBoxPointer->setCurrentText("System Download Directory");
214 else if (newDownloadDirectory != QStringLiteral("")) // A different directory was selected.
216 // Populate the download location.
217 downloadDirectoryComboBoxPointer->setCurrentText(newDownloadDirectory);
221 void SettingsDialog::updateSearchEngineLabel(const QString &searchEngineString) const
223 // Update the search engine label.
224 searchEngineLabelPointer->setText(SearchEngineHelper::getSearchUrl(searchEngineString));
227 void SettingsDialog::updateUserAgentLabel(const QString &userAgentDatabaseName) const
229 // Update the user agent label.
230 userAgentLabelPointer->setText(UserAgentHelper::getUserAgentFromDatabaseName(userAgentDatabaseName));