]> gitweb.stoutner.com Git - PrivacyBrowserPC.git/blob - src/windows/BrowserWindow.cpp
Add a File > New Tab action.
[PrivacyBrowserPC.git] / src / windows / BrowserWindow.cpp
1 /*
2  * Copyright 2022-2023 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 // Application headers.
21 #include "BrowserWindow.h"
22 #include "Settings.h"
23 #include "ui_SettingsGeneral.h"
24 #include "ui_SettingsPrivacy.h"
25 #include "ui_SettingsSpellCheck.h"
26 #include "dialogs/CookiesDialog.h"
27 #include "dialogs/DomainSettingsDialog.h"
28 #include "helpers/SearchEngineHelper.h"
29 #include "helpers/UserAgentHelper.h"
30
31 // KDE Frameworks headers.
32 #include <KActionCollection>
33 #include <KColorScheme>
34 #include <KToolBar>
35
36 // Qt toolkit headers.
37 #include <QFileDialog>
38 #include <QInputDialog>
39 #include <QNetworkCookie>
40 #include <QMenuBar>
41 #include <QShortcut>
42 #include <QStatusBar>
43 #include <QWebEngineFindTextResult>
44
45 // Construct the class.
46 BrowserWindow::BrowserWindow(bool firstWindow) : KXmlGuiWindow()
47 {
48     // Initialize the variables.
49     javaScriptEnabled = false;
50     localStorageEnabled = false;
51
52     // Instantiate the privacy tab widget pointer.
53     tabWidgetPointer = new TabWidget(this);
54
55     // Set the privacy tab widget as the central widget.
56     setCentralWidget(tabWidgetPointer);
57
58     // Get a handle for the action collection.
59     KActionCollection *actionCollectionPointer = this->actionCollection();
60
61     // Add the standard actions.
62     KStandardAction::print(tabWidgetPointer, SLOT(print()), actionCollectionPointer);
63     KStandardAction::printPreview(tabWidgetPointer, SLOT(printPreview()), actionCollectionPointer);
64     KStandardAction::quit(qApp, SLOT(closeAllWindows()), actionCollectionPointer);
65     KStandardAction::redisplay(this, SLOT(refresh()), actionCollectionPointer);
66     fullScreenActionPointer = KStandardAction::fullScreen(this, SLOT(toggleFullScreen()), this, actionCollectionPointer);
67     QAction *backActionPointer = KStandardAction::back(this, SLOT(back()), actionCollectionPointer);
68     QAction *forwardActionPointer = KStandardAction::forward(this, SLOT(forward()), actionCollectionPointer);
69     KStandardAction::home(this, SLOT(home()), actionCollectionPointer);
70     KStandardAction::preferences(this, SLOT(showSettingsDialog()), actionCollectionPointer);
71     KStandardAction::find(this, SLOT(showFindTextActions()), actionCollectionPointer);
72     findNextActionPointer = KStandardAction::findNext(this, SLOT(findNext()), actionCollectionPointer);
73     findPreviousActionPointer = KStandardAction::findPrev(this, SLOT(findPrevious()), actionCollectionPointer);
74
75     // Add the custom actions.
76     QAction *newTabActionPointer = actionCollectionPointer->addAction(QLatin1String("new_tab"));
77     QAction *newWindowActionPointer = actionCollectionPointer->addAction(QLatin1String("new_window"));
78     userAgentPrivacyBrowserActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_privacy_browser"));
79     userAgentWebEngineDefaultActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_webengine_default"));
80     userAgentFirefoxLinuxActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_firefox_linux"));
81     userAgentChromiumLinuxActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_chromium_linux"));
82     userAgentFirefoxWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_firefox_windows"));
83     userAgentChromeWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_chrome_windows"));
84     userAgentEdgeWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_edge_windows"));
85     userAgentSafariMacosActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_safari_macos"));
86     userAgentCustomActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_custom"));
87     zoomFactorActionPointer = actionCollectionPointer->addAction(QLatin1String("zoom_factor"));
88     searchEngineMojeekActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_mojeek"));
89     searchEngineMonoclesActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_monocles"));
90     searchEngineMetagerActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_metager"));
91     searchEngineGoogleActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_google"));
92     searchEngineBingActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_bing"));
93     searchEngineYahooActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_yahoo"));
94     searchEngineCustomActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_custom"));
95     QAction *domainSettingsActionPointer = actionCollectionPointer->addAction(QLatin1String("domain_settings"));
96     cookiesActionPointer = actionCollectionPointer->addAction(QLatin1String("cookies"));
97     javaScriptActionPointer = actionCollectionPointer->addAction(QLatin1String("javascript"));
98     localStorageActionPointer = actionCollectionPointer->addAction(QLatin1String("local_storage"));
99     domStorageActionPointer = actionCollectionPointer->addAction(QLatin1String("dom_storage"));
100     findCaseSensitiveActionPointer = actionCollectionPointer->addAction(QLatin1String("find_case_sensitive"));
101     hideFindTextActionPointer = actionCollectionPointer->addAction(QLatin1String("hide_find_actions"));
102
103     // Create the action groups
104     QActionGroup *userAgentActionGroupPointer = new QActionGroup(this);
105     QActionGroup *searchEngineActionGroupPointer = new QActionGroup(this);
106
107     // Add the actions to the groups.
108     userAgentActionGroupPointer->addAction(userAgentPrivacyBrowserActionPointer);
109     userAgentActionGroupPointer->addAction(userAgentWebEngineDefaultActionPointer);
110     userAgentActionGroupPointer->addAction(userAgentFirefoxLinuxActionPointer);
111     userAgentActionGroupPointer->addAction(userAgentChromiumLinuxActionPointer);
112     userAgentActionGroupPointer->addAction(userAgentFirefoxWindowsActionPointer);
113     userAgentActionGroupPointer->addAction(userAgentChromeWindowsActionPointer);
114     userAgentActionGroupPointer->addAction(userAgentEdgeWindowsActionPointer);
115     userAgentActionGroupPointer->addAction(userAgentSafariMacosActionPointer);
116     userAgentActionGroupPointer->addAction(userAgentCustomActionPointer);
117     searchEngineActionGroupPointer->addAction(searchEngineMojeekActionPointer);
118     searchEngineActionGroupPointer->addAction(searchEngineMonoclesActionPointer);
119     searchEngineActionGroupPointer->addAction(searchEngineMetagerActionPointer);
120     searchEngineActionGroupPointer->addAction(searchEngineGoogleActionPointer);
121     searchEngineActionGroupPointer->addAction(searchEngineBingActionPointer);
122     searchEngineActionGroupPointer->addAction(searchEngineYahooActionPointer);
123     searchEngineActionGroupPointer->addAction(searchEngineCustomActionPointer);
124
125     // Set some actions to be checkable.
126     javaScriptActionPointer->setCheckable(true);
127     localStorageActionPointer->setCheckable(true);
128     domStorageActionPointer->setCheckable(true);
129     findCaseSensitiveActionPointer->setCheckable(true);
130     userAgentPrivacyBrowserActionPointer->setCheckable(true);
131     userAgentWebEngineDefaultActionPointer->setCheckable(true);
132     userAgentFirefoxLinuxActionPointer->setCheckable(true);
133     userAgentChromiumLinuxActionPointer->setCheckable(true);
134     userAgentFirefoxWindowsActionPointer->setCheckable(true);
135     userAgentChromeWindowsActionPointer->setCheckable(true);
136     userAgentEdgeWindowsActionPointer->setCheckable(true);
137     userAgentSafariMacosActionPointer->setCheckable(true);
138     userAgentCustomActionPointer->setCheckable(true);
139     searchEngineMojeekActionPointer->setCheckable(true);
140     searchEngineMonoclesActionPointer->setCheckable(true);
141     searchEngineMetagerActionPointer->setCheckable(true);
142     searchEngineGoogleActionPointer->setCheckable(true);
143     searchEngineBingActionPointer->setCheckable(true);
144     searchEngineYahooActionPointer->setCheckable(true);
145     searchEngineCustomActionPointer->setCheckable(true);
146
147     // Instantiate the user agent helper.
148     UserAgentHelper *userAgentHelperPointer = new UserAgentHelper();
149
150     // Set the action text.
151     newTabActionPointer->setText(i18nc("New tab action", "New Tab"));
152     newWindowActionPointer->setText(i18nc("New window action", "New Window"));
153     userAgentPrivacyBrowserActionPointer->setText(userAgentHelperPointer->PRIVACY_BROWSER_TRANSLATED);
154     userAgentWebEngineDefaultActionPointer->setText(userAgentHelperPointer->WEB_ENGINE_DEFAULT_TRANSLATED);
155     userAgentFirefoxLinuxActionPointer->setText(userAgentHelperPointer->FIREFOX_LINUX_TRANSLATED);
156     userAgentChromiumLinuxActionPointer->setText(userAgentHelperPointer->CHROMIUM_LINUX_TRANSLATED);
157     userAgentFirefoxWindowsActionPointer->setText(userAgentHelperPointer->FIREFOX_WINDOWS_TRANSLATED);
158     userAgentChromeWindowsActionPointer->setText(userAgentHelperPointer->CHROME_WINDOWS_TRANSLATED);
159     userAgentEdgeWindowsActionPointer->setText(userAgentHelperPointer->EDGE_WINDOWS_TRANSLATED);
160     userAgentSafariMacosActionPointer->setText(userAgentHelperPointer->SAFARI_MACOS_TRANSLATED);
161     searchEngineMojeekActionPointer->setText(i18nc("Search engine", "Mojeek"));
162     searchEngineMonoclesActionPointer->setText(i18nc("Search engine", "Monocles"));
163     searchEngineMetagerActionPointer->setText(i18nc("Search engine", "MetaGer"));
164     searchEngineGoogleActionPointer->setText(i18nc("Search engine", "Google"));
165     searchEngineBingActionPointer->setText(i18nc("Search engine", "Bing"));
166     searchEngineYahooActionPointer->setText(i18nc("Search engine", "Yahoo"));
167     domainSettingsActionPointer->setText(i18nc("Domain Settings action", "Domain Settings"));
168     cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", 0));
169     javaScriptActionPointer->setText(i18nc("JavaScript action", "JavaScript"));
170     localStorageActionPointer->setText(i18nc("The Local Storage action", "Local Storage"));
171     domStorageActionPointer->setText(i18nc("DOM Storage action", "DOM Storage"));
172     findCaseSensitiveActionPointer->setText(i18nc("Find Case Sensitive action", "Find Case Sensitive"));
173     hideFindTextActionPointer->setText(i18nc("Hide Find Text action", "Hide Find Text"));
174
175     // Set the action icons.
176     newTabActionPointer->setIcon(QIcon::fromTheme(QLatin1String("tab-new")));
177     newWindowActionPointer->setIcon(QIcon::fromTheme(QLatin1String("window-new")));
178     userAgentPrivacyBrowserActionPointer->setIcon(QIcon(":/icons/privacy-mode"));
179     userAgentWebEngineDefaultActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties")));
180     userAgentFirefoxLinuxActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr")));
181     userAgentChromiumLinuxActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium")));
182     userAgentFirefoxWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr")));
183     userAgentChromeWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium")));
184     userAgentEdgeWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties")));
185     userAgentSafariMacosActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties")));
186     userAgentCustomActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties")));
187     searchEngineMojeekActionPointer->setIcon(QIcon::fromTheme(QLatin1String("search")));
188     searchEngineMonoclesActionPointer->setIcon(QIcon::fromTheme(QLatin1String("search")));
189     searchEngineMetagerActionPointer->setIcon(QIcon::fromTheme(QLatin1String("search")));
190     searchEngineGoogleActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-google")));
191     searchEngineBingActionPointer->setIcon(QIcon::fromTheme(QLatin1String("search")));
192     searchEngineYahooActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-yahoo")));
193     searchEngineCustomActionPointer->setIcon(QIcon::fromTheme(QLatin1String("search")));
194     zoomFactorActionPointer->setIcon(QIcon::fromTheme(QLatin1String("zoom")));
195     domainSettingsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("settings-configure")));
196     cookiesActionPointer->setIcon(QIcon::fromTheme(QLatin1String("preferences-web-browser-cookies")));
197     domStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("code-class")));
198     findCaseSensitiveActionPointer->setIcon(QIcon::fromTheme(QLatin1String("format-text-lowercase")));
199     hideFindTextActionPointer->setIcon(QIcon::fromTheme(QLatin1String("window-close-symbolic")));
200
201     // Create the key sequences.
202     QKeySequence ctrlTKeySequence = QKeySequence(i18nc("The open new tab key sequence.", "Ctrl+T"));
203     QKeySequence ctrlNKeySequence = QKeySequence(i18nc("The open new window key sequence.", "Ctrl+N"));
204
205     // Set the action key sequences.
206     newTabActionPointer->setShortcut(ctrlTKeySequence);
207     newWindowActionPointer->setShortcut(ctrlNKeySequence);
208
209     // Execute the actions.
210     connect(newTabActionPointer, SIGNAL(triggered()), tabWidgetPointer, SLOT(addTab()));
211     connect(newWindowActionPointer, SIGNAL(triggered()), this, SLOT(newWindow()));
212     connect(zoomFactorActionPointer, SIGNAL(triggered()), this, SLOT(getZoomFactorFromUser()));
213     connect(cookiesActionPointer, SIGNAL(triggered()), this, SLOT(showCookiesDialog()));
214     connect(domainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(showDomainSettingsDialog()));
215
216     // Update the on-the-fly menus.
217     connect(tabWidgetPointer, SIGNAL(updateUserAgentActions(QString, bool)), this, SLOT(updateUserAgentActions(QString, bool)));
218     connect(tabWidgetPointer, SIGNAL(updateZoomFactorAction(double)), this, SLOT(updateZoomFactorAction(double)));
219     connect(tabWidgetPointer, SIGNAL(updateSearchEngineActions(QString, bool)), this, SLOT(updateSearchEngineActions(QString, bool)));
220
221     // Apply the on-the-fly settings when selected.
222     connect(userAgentActionGroupPointer, SIGNAL(triggered(QAction*)), tabWidgetPointer, SLOT(applyOnTheFlyUserAgent(QAction*)));
223     connect(searchEngineActionGroupPointer, SIGNAL(triggered(QAction*)), tabWidgetPointer, SLOT(applyOnTheFlySearchEngine(QAction*)));
224
225     // Process cookie changes.
226     connect(tabWidgetPointer, SIGNAL(updateCookiesAction(int)), this, SLOT(updateCookiesAction(int)));
227
228     // Connect the URL toolbar actions.
229     connect(javaScriptActionPointer, SIGNAL(triggered()), this, SLOT(toggleJavaScript()));
230     connect(localStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleLocalStorage()));
231     connect(domStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleDomStorage()));
232
233     // Update the URL toolbar actions.
234     connect(tabWidgetPointer, SIGNAL(updateBackAction(bool)), backActionPointer, SLOT(setEnabled(bool)));
235     connect(tabWidgetPointer, SIGNAL(updateForwardAction(bool)), forwardActionPointer, SLOT(setEnabled(bool)));
236     connect(tabWidgetPointer, SIGNAL(updateJavaScriptAction(bool)), this, SLOT(updateJavaScriptAction(bool)));
237     connect(tabWidgetPointer, SIGNAL(updateLocalStorageAction(bool)), this, SLOT(updateLocalStorageAction(bool)));
238     connect(tabWidgetPointer, SIGNAL(updateDomStorageAction(bool)), this, SLOT(updateDomStorageAction(bool)));
239
240     // Connect the find text actions.
241     connect(findCaseSensitiveActionPointer, SIGNAL(triggered()), this, SLOT(toggleFindCaseSensitive()));
242     connect(hideFindTextActionPointer, SIGNAL(triggered()), this, SLOT(hideFindTextActions()));
243
244     // Setup the GUI based on the browserwindowui.rc file.
245     setupGUI(StandardWindowOption::Default, ("browserwindowui.rc"));
246
247     // Get lists of the actions' associated widgets.
248     QList<QWidget*> userAgentAssociatedWidgetsPointerList = userAgentPrivacyBrowserActionPointer->associatedWidgets();
249     QList<QWidget*> searchEngineAssociatedWidgetsPointerList = searchEngineMojeekActionPointer->associatedWidgets();
250
251     // Get the menu widget pointers.  It is the second entry, after the main window.
252     QWidget *userAgentMenuWidgetPointer = userAgentAssociatedWidgetsPointerList[1];
253     QWidget *searchEngineMenuWidgetPointer = searchEngineAssociatedWidgetsPointerList[1];
254
255     // Get the menu pointers.
256     QMenu *userAgentMenuPointer = qobject_cast<QMenu*>(userAgentMenuWidgetPointer);
257     QMenu *searchEngineMenuPointer = qobject_cast<QMenu*>(searchEngineMenuWidgetPointer);
258
259     // Get the menu actions.
260     userAgentMenuActionPointer = userAgentMenuPointer->menuAction();
261     searchEngineMenuActionPointer = searchEngineMenuPointer->menuAction();
262
263     // Get handles for the toolbars.
264     navigationToolBarPointer = toolBar(QLatin1String("navigation_toolbar"));
265     urlToolBarPointer = toolBar(QLatin1String("url_toolbar"));
266
267     // Create the line edits.
268     urlLineEditPointer = new KLineEdit();
269     findTextLineEditPointer = new KLineEdit();
270
271     // Get the line edit size policies.
272     QSizePolicy urlLineEditSizePolicy = urlLineEditPointer->sizePolicy();
273     QSizePolicy findTextLineEditSizePolicy = findTextLineEditPointer->sizePolicy();
274
275     // Set the URL line edit horizontal stretch to be five times the find text line edit stretch.
276     urlLineEditSizePolicy.setHorizontalStretch(5);
277     findTextLineEditSizePolicy.setHorizontalStretch(1);
278
279     // Set the policies.
280     urlLineEditPointer->setSizePolicy(urlLineEditSizePolicy);
281     findTextLineEditPointer->setSizePolicy(findTextLineEditSizePolicy);
282
283     // Set the widths.
284     urlLineEditPointer->setMinimumWidth(350);
285     findTextLineEditPointer->setMinimumWidth(200);
286     findTextLineEditPointer->setMaximumWidth(350);
287
288     // Set the place holder text.
289     urlLineEditPointer->setPlaceholderText(i18nc("The URL line edit placeholder text", "URL or Search Terms"));
290     findTextLineEditPointer->setPlaceholderText(i18nc("The find line edit placeholder text", "Find Text"));
291
292     // Show the clear button on the find line edit.
293     findTextLineEditPointer->setClearButtonEnabled(true);
294
295     // Add an edit or add domain settings action to the URL line edit.
296     QAction *addOrEditDomainSettingsActionPointer = urlLineEditPointer->addAction(QIcon::fromTheme("settings-configure"), QLineEdit::TrailingPosition);
297
298     // Add or edit the current domain settings.
299     connect(addOrEditDomainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(addOrEditDomainSettings()));
300
301     // Create a find text label pointer.
302     findTextLabelPointer = new QLabel();
303
304     // Set the default label text.
305     findTextLabelPointer->setText(QLatin1String("  ") + i18nc("Default find results.", "0/0") + QLatin1String("  "));
306
307     // Insert the widgets into the toolbars.
308     urlToolBarPointer->insertWidget(javaScriptActionPointer, urlLineEditPointer);
309     findTextLineEditActionPointer = urlToolBarPointer->insertWidget(findNextActionPointer, findTextLineEditPointer);
310     findTextLabelActionPointer = urlToolBarPointer->insertWidget(findNextActionPointer, findTextLabelPointer);
311
312     // Initially hide the find text actions.
313     hideFindTextActions();
314
315     // Load a new URL from the URL line edit.
316     connect(urlLineEditPointer, SIGNAL(returnKeyPressed(const QString)), this, SLOT(loadUrlFromLineEdit(const QString)));
317
318     // Find text as it is typed.
319     connect(findTextLineEditPointer, SIGNAL(textEdited(const QString &)), tabWidgetPointer, SLOT(findText(const QString &)));
320
321     // Find next if the enter key is pressed.
322     connect(findTextLineEditPointer, SIGNAL(returnKeyPressed(const QString &)), tabWidgetPointer, SLOT(findText(const QString &)));
323
324     // Update find text when switching tabs.
325     connect(tabWidgetPointer, SIGNAL(updateFindText(const QString &, const bool)), this, SLOT(updateFindText(const QString &, const bool)));
326
327     // Update the find text results.
328     connect(tabWidgetPointer, SIGNAL(updateFindTextResults(const QWebEngineFindTextResult &)), this, SLOT(updateFindTextResults(const QWebEngineFindTextResult &)));
329
330     // Update the URL line edit on page loads.
331     connect(tabWidgetPointer, SIGNAL(updateUrlLineEdit(QUrl)), this, SLOT(updateUrlLineEdit(QUrl)));
332
333     // Update the window title.
334     connect(tabWidgetPointer, SIGNAL(updateWindowTitle(const QString)), this, SLOT(updateWindowTitle(const QString)));
335
336     // Get a handle for the status bar.
337     QStatusBar *statusBarPointer = statusBar();
338
339     // Create a progress bar.
340     progressBarPointer = new QProgressBar();
341
342     // Add the progress bar to to the status bar.
343     statusBarPointer->addPermanentWidget(progressBarPointer);
344
345     // Update the status bar with the URL when a link is hovered.
346     connect(tabWidgetPointer, SIGNAL(linkHovered(QString)), statusBarPointer, SLOT(showMessage(QString)));
347
348     // Update the progress bar.
349     connect(tabWidgetPointer, SIGNAL(showProgressBar(const int)), this, SLOT(showProgressBar(const int)));
350     connect(tabWidgetPointer, SIGNAL(hideProgressBar()), progressBarPointer, SLOT(hide()));
351
352     // Update the URL line edit focus.
353     connect(tabWidgetPointer, SIGNAL(clearUrlLineEditFocus()), this, SLOT(clearUrlLineEditFocus()));
354
355     // Get the URL line edit palettes.
356     normalBackgroundPalette = urlLineEditPointer->palette();
357     negativeBackgroundPalette = normalBackgroundPalette;
358     positiveBackgroundPalette = normalBackgroundPalette;
359
360     // Modify the palettes.
361     KColorScheme::adjustBackground(negativeBackgroundPalette, KColorScheme::NegativeBackground);
362     KColorScheme::adjustBackground(positiveBackgroundPalette, KColorScheme::PositiveBackground);
363
364     // Update the applied palette.
365     connect(tabWidgetPointer, SIGNAL(updateDomainSettingsIndicator(const bool)), this, SLOT(updateDomainSettingsIndicator(const bool)));
366
367     // Process full screen requests.
368     connect(tabWidgetPointer, SIGNAL(fullScreenRequested(bool)), this, SLOT(fullScreenRequested(bool)));
369
370     // Create keyboard shortcuts.
371     QShortcut *f11ShortcutPointer = new QShortcut(QKeySequence(i18nc("The toggle full screen shortcut.", "F11")), this);
372     QShortcut *escapeShortcutPointer = new QShortcut(QKeySequence::Cancel, this);
373
374     // Connect the keyboard shortcuts.
375     connect(f11ShortcutPointer, SIGNAL(activated()), fullScreenActionPointer, SLOT(trigger()));
376     connect(escapeShortcutPointer, SIGNAL(activated()), this, SLOT(escape()));
377
378     // Populate the UI.
379     // This must be done here, because otherwise, if a URL is loaded, like a local file, that does not trigger a call to TabWidget::applyDomainSettings, the UI will not be fully populated.
380     updateJavaScriptAction(Settings::javaScriptEnabled());
381     updateLocalStorageAction(Settings::localStorageEnabled());
382     updateDomStorageAction(Settings::domStorageEnabled());
383     updateUserAgentActions(UserAgentHelper::getUserAgentFromDatabaseName(Settings::userAgent()), true);
384     updateZoomFactorAction(Settings::zoomFactor());
385
386     // Load the initial website if this is the first window.
387     if (firstWindow)
388         tabWidgetPointer->loadInitialWebsite();
389 }
390
391 void BrowserWindow::addOrEditDomainSettings() const
392 {
393     // Remove the focus from the URL line edit.
394     urlLineEditPointer->clearFocus();
395
396     // Create the domain settings dialog pointer.
397     DomainSettingsDialog *domainSettingsDialogPointer;
398
399     // Get the current domain settings name.
400     QString &currentDomainSettingsName = tabWidgetPointer->getDomainSettingsName();
401
402     // Run the commands according to the current domain settings status.
403     if (currentDomainSettingsName == QStringLiteral(""))  // Domain settings are not currently applied.
404     {
405         // Instruct the domain settings dialog to add a new domain.
406         domainSettingsDialogPointer = new DomainSettingsDialog(DomainSettingsDialog::ADD_DOMAIN, currentUrl.host());
407     }
408     else  // Domain settings are currently applied.
409     {
410         // Instruct the domain settings dialog to edit the current domain.
411         domainSettingsDialogPointer = new DomainSettingsDialog(DomainSettingsDialog::EDIT_DOMAIN, currentDomainSettingsName);
412     }
413
414     // Set the dialog window title.
415     domainSettingsDialogPointer->setWindowTitle(i18nc("The domain settings dialog title", "Domain Settings"));
416
417     // Set the modality.
418     domainSettingsDialogPointer->setWindowModality(Qt::WindowModality::WindowModal);;
419
420     // Show the dialog.
421     domainSettingsDialogPointer->show();
422
423     // Reload the tabs when domain settings are updated.
424     connect(domainSettingsDialogPointer, SIGNAL(domainSettingsUpdated()), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
425 }
426
427 void BrowserWindow::back() const
428 {
429     // Remove the focus from the URL line edit.
430     urlLineEditPointer->clearFocus();
431
432     // Go back.
433     tabWidgetPointer->back();
434 }
435
436 void BrowserWindow::clearUrlLineEditFocus() const
437 {
438     // Remove the focus from the URL line edit.
439     urlLineEditPointer->clearFocus();
440 }
441
442 void BrowserWindow::escape() const
443 {
444     // Process the escape according to the status of the browser.
445     if (fullScreenActionPointer->isChecked())  // Full screen browsing is enabled.
446     {
447         // Exit full screen browsing.
448         fullScreenActionPointer->trigger();
449     }
450     else if (!findTextLineEditPointer->text().isEmpty())  // Find text is populated.
451     {
452         // Clear the text in the line edit.
453         findTextLineEditPointer->clear();
454
455         // Clear the search in the WebEngine.
456         tabWidgetPointer->findText(QStringLiteral(""));
457     }
458     else if (findTextLineEditActionPointer->isVisible())  // Find text actions are visible.
459     {
460         // Hide the find text actions.
461         hideFindTextActions();
462     }
463 }
464
465 void BrowserWindow::findNext() const
466 {
467     // Get the find string.
468     const QString findString = findTextLineEditPointer->text();
469
470     // Search for the text if it is not empty.
471     if (!findString.isEmpty())
472         tabWidgetPointer->findText(findString);
473 }
474
475 void BrowserWindow::findPrevious() const
476 {
477     // Get the find string.
478     const QString findString = findTextLineEditPointer->text();
479
480     // Search for the text if it is not empty.
481     if (!findString.isEmpty())
482         tabWidgetPointer->findPrevious(findString);
483 }
484
485 void BrowserWindow::forward() const
486 {
487     // Remove the focus from the URL line edit.
488     urlLineEditPointer->clearFocus();
489
490     // Go forward.
491     tabWidgetPointer->forward();
492 }
493
494 void BrowserWindow::fullScreenRequested(const bool toggleOn)
495 {
496     // Toggle full screen mode.
497     if (toggleOn)  // Turn full screen mode on.
498     {
499         // Set the window to be full screen.
500         fullScreenActionPointer->setFullScreen(window(), true);
501
502         // Hide all the bars.
503         menuBar()->setVisible(false);
504         navigationToolBarPointer->setVisible(false);
505         urlToolBarPointer->setVisible(false);
506         tabWidgetPointer->setTabBarVisible(false);
507         statusBar()->setVisible(false);
508     }
509     else  // Turn full screen mode off.
510     {
511         // Set the window to not be full screen.
512         fullScreenActionPointer->setFullScreen(window(), false);
513
514         // Show all the bars.
515         menuBar()->setVisible(true);
516         navigationToolBarPointer->setVisible(true);
517         urlToolBarPointer->setVisible(true);
518         tabWidgetPointer->setTabBarVisible(true);
519         statusBar()->setVisible(true);
520     }
521 }
522
523 void BrowserWindow::getZoomFactorFromUser()
524 {
525     // Create an OK flag.
526     bool okClicked;
527
528     // Display a dialog to get the new zoom factor from the user.  Format the double to display two decimals and have a 0.25 step.
529     double newZoomFactor = QInputDialog::getDouble(this, i18nc("The on-the-fly zoom factor dialog title", "On-The-Fly Zoom Factor"),
530                                                    i18nc("The instruction text of the on-the-fly zoom factor dialog", "Enter a zoom factor between 0.25 and 5.00"),
531                                                    currentZoomFactor, .025, 5.00, 2, &okClicked, Qt::WindowFlags(), 0.25);
532
533     // Update the zoom factor if the user clicked OK.
534     if (okClicked)
535     {
536         // Update the current zoom factor.
537         currentZoomFactor = newZoomFactor;
538
539         // Set the new zoom factor.
540         tabWidgetPointer->applyOnTheFlyZoomFactor(newZoomFactor);
541
542         // Update the on-the-fly action text.
543         updateZoomFactorAction(newZoomFactor);
544     }
545 }
546
547 void BrowserWindow::hideFindTextActions() const
548 {
549     // Hide the find text actions.
550     findTextLineEditActionPointer->setVisible(false);
551     findTextLabelActionPointer->setVisible(false);
552     findNextActionPointer->setVisible(false);
553     findPreviousActionPointer->setVisible(false);
554     findCaseSensitiveActionPointer->setVisible(false);
555     hideFindTextActionPointer->setVisible(false);
556 }
557
558 void BrowserWindow::home() const
559 {
560     // Remove the focus from the URL line edit.
561     urlLineEditPointer->clearFocus();
562
563     // Go home.
564     tabWidgetPointer->home();
565 }
566
567 void BrowserWindow::loadUrlFromLineEdit(const QString &url) const
568 {
569     // Remove the focus from the URL line edit.
570     urlLineEditPointer->clearFocus();
571
572     // Load the URL.
573     tabWidgetPointer->loadUrlFromLineEdit(url);
574 }
575
576 void BrowserWindow::newWindow() const
577 {
578     // Display a new instance of Privacy Browser.
579     (new BrowserWindow)->show();
580 }
581
582 void BrowserWindow::refresh() const
583 {
584     // Remove the focus from the URL line edit.
585     urlLineEditPointer->clearFocus();
586
587     // Refresh the web page.
588     tabWidgetPointer->refresh();
589 }
590
591 void BrowserWindow::showCookiesDialog()
592 {
593     // Remove the focus from the URL line edit.
594     urlLineEditPointer->clearFocus();
595
596     // Instantiate the cookie settings dialog.
597     CookiesDialog *cookiesDialogPointer = new CookiesDialog(tabWidgetPointer->getCookieList());
598
599     // Show the dialog.
600     cookiesDialogPointer->show();
601
602     // Connect the dialog signals.
603     connect(cookiesDialogPointer, SIGNAL(addCookie(QNetworkCookie)), tabWidgetPointer, SLOT(addCookieToStore(QNetworkCookie)));
604     connect(cookiesDialogPointer, SIGNAL(deleteAllCookies()), tabWidgetPointer, SLOT(deleteAllCookies()));
605     connect(cookiesDialogPointer, SIGNAL(deleteCookie(QNetworkCookie)), tabWidgetPointer, SLOT(deleteCookieFromStore(QNetworkCookie)));
606 }
607
608 void BrowserWindow::showDownloadLocationBrowseDialog() const
609 {
610     // Get the current download location.
611     QString currentDownloadLocation = downloadLocationComboBoxPointer->currentText();
612
613     // Resolve the system download directory if specified.
614     if (currentDownloadLocation == QStringLiteral("System Download Directory"))
615         currentDownloadLocation = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
616
617     // Get the new download location.
618     QString newDownloadLocation = QFileDialog::getExistingDirectory(configDialogPointer, i18nc("Select download location dialog caption", "Select Download Location"), currentDownloadLocation);
619
620     // Populate the download location combo box according to the new download location.
621     if (newDownloadLocation == QStandardPaths::writableLocation(QStandardPaths::DownloadLocation))  // The default download location was selected.
622     {
623         // Populate the download location with the default text.
624         downloadLocationComboBoxPointer->setCurrentText("System Download Directory");
625     }
626     else if (newDownloadLocation != QStringLiteral(""))  // A different directory was selected.
627     {
628         // Populate the download location.
629         downloadLocationComboBoxPointer->setCurrentText(newDownloadLocation);
630     }
631 }
632
633 void BrowserWindow::showDomainSettingsDialog() const
634 {
635     // Remove the focus from the URL line edit.
636     urlLineEditPointer->clearFocus();
637
638     // Instantiate the domain settings dialog.
639     DomainSettingsDialog *domainSettingsDialogPointer = new DomainSettingsDialog();
640
641     // Show the dialog.
642     domainSettingsDialogPointer->show();
643
644     // Reload the tabs when domain settings are updated.
645     connect(domainSettingsDialogPointer, SIGNAL(domainSettingsUpdated()), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
646 }
647
648 void BrowserWindow::showFindTextActions() const
649 {
650     // Show the find text actions.
651     findTextLineEditActionPointer->setVisible(true);
652     findTextLabelActionPointer->setVisible(true);
653     findNextActionPointer->setVisible(true);
654     findPreviousActionPointer->setVisible(true);
655     findCaseSensitiveActionPointer->setVisible(true);
656     hideFindTextActionPointer->setVisible(true);
657
658     // Set the focus on the find line edit.
659     findTextLineEditPointer->setFocus();
660
661     // Select all the text in the find line edit.
662     findTextLineEditPointer->selectAll();
663 }
664
665 void BrowserWindow::showProgressBar(const int &progress) const
666 {
667     // Set the progress bar value.
668     progressBarPointer->setValue(progress);
669
670     // Show the progress bar.
671     progressBarPointer->show();
672 }
673
674 void BrowserWindow::showSettingsDialog()
675 {
676     // Create the settings widgets.
677     QWidget *privacySettingsWidgetPointer = new QWidget;
678     QWidget *generalSettingsWidgetPointer = new QWidget;
679     QWidget *spellCheckSettingsWidgetPointer = new QWidget;
680
681     // Instantiate the settings UI.
682     Ui::PrivacySettings privacySettingsUi;
683     Ui::GeneralSettings generalSettingsUi;
684     Ui::SpellCheckSettings spellCheckSettingsUi;
685
686     // Setup the UI to display the settings widgets.
687     privacySettingsUi.setupUi(privacySettingsWidgetPointer);
688     generalSettingsUi.setupUi(generalSettingsWidgetPointer);
689     spellCheckSettingsUi.setupUi(spellCheckSettingsWidgetPointer);
690
691     // Get handles for the widgets.
692     QComboBox *userAgentComboBoxPointer = privacySettingsUi.kcfg_userAgent;
693     userAgentLabelPointer = privacySettingsUi.userAgentLabel;
694     QComboBox *searchEngineComboBoxPointer = generalSettingsUi.kcfg_searchEngine;
695     searchEngineLabelPointer = generalSettingsUi.searchEngineLabel;
696     downloadLocationComboBoxPointer = generalSettingsUi.kcfg_downloadLocation;
697     QPushButton *browseButtonPointer = generalSettingsUi.browseButton;
698     QListWidget *spellCheckListWidgetPointer = spellCheckSettingsUi.spellCheckListWidget;
699
700     // Populate the combo box labels.
701     updateUserAgentLabel(userAgentComboBoxPointer->currentText());
702     updateSearchEngineLabel(searchEngineComboBoxPointer->currentText());
703
704     // Update the labels when the combo boxes change.
705     connect(userAgentComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateUserAgentLabel(const QString)));
706     connect(searchEngineComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateSearchEngineLabel(const QString)));
707
708     // Connect the download location directory browse button.
709     connect(browseButtonPointer, SIGNAL(clicked()), this, SLOT(showDownloadLocationBrowseDialog()));
710
711     // Create a dictionaries QDir from the `QTWEBENGINE_DICTIONARIES_PATH` environment variable.
712     QDir dictionariesDir = QDir(qEnvironmentVariable("QTWEBENGINE_DICTIONARIES_PATH"));
713
714     // Get a dictionaries string list.
715     QStringList dictionariesStringList = dictionariesDir.entryList(QStringList(QLatin1String("*.bdic")), QDir::Files | QDir::NoSymLinks);
716
717     // Remove the `.bdic` file extensions from the dictionaries list.
718     dictionariesStringList.replaceInStrings(QLatin1String(".bdic"), QLatin1String(""));
719
720     // Get a list of the enabled spell check languages.
721     QStringList enabledSpellCheckLanguagesList = Settings::spellCheckLanguages();
722
723     // Add each dictionary to the spell check list widget.
724     foreach(QString dictionaryString, dictionariesStringList)
725     {
726         // Create a new list widget item pointer named after the dictionary string.
727         QListWidgetItem *listWidgetItemPointer = new QListWidgetItem(dictionaryString, spellCheckListWidgetPointer);
728
729         // Set the list widget item pointer to be checkable.
730         listWidgetItemPointer->setFlags(listWidgetItemPointer->flags() | Qt::ItemIsUserCheckable);
731
732         // Check the language if it is currently enabled.
733         if (enabledSpellCheckLanguagesList.contains(dictionaryString))
734             listWidgetItemPointer->setCheckState(Qt::Checked);
735         else
736             listWidgetItemPointer->setCheckState(Qt::Unchecked);
737
738         // Add the list widget item to the widget.
739         spellCheckListWidgetPointer->addItem(listWidgetItemPointer);
740     }
741
742     // Get a handle for the KConfig skeleton.
743     KConfigSkeleton *kConfigSkeletonPointer = Settings::self();
744
745     // Instantiate a settings config dialog from the settings.kcfg file.
746     configDialogPointer = new KConfigDialog(this, QLatin1String("settings"), kConfigSkeletonPointer);
747
748     // Add the settings widgets as config dialog pages.
749     configDialogPointer->addPage(privacySettingsWidgetPointer, i18nc("Settings tab title", "Privacy"), QLatin1String("privacy-browser"));
750     configDialogPointer->addPage(generalSettingsWidgetPointer, i18nc("Settings tab title", "General"), QLatin1String("breeze-settings"));
751     configDialogPointer->addPage(spellCheckSettingsWidgetPointer, i18nc("Settings tab title", "Spell Check"), QLatin1String("tools-check-spelling"));
752
753     // Get handles for the buttons.
754     QPushButton *applyButtonPointer = configDialogPointer->button(QDialogButtonBox::Apply);
755     QPushButton *okButtonPointer = configDialogPointer->button(QDialogButtonBox::Ok);
756
757     // Prevent interaction with the parent window while the dialog is open.
758     configDialogPointer->setWindowModality(Qt::WindowModal);
759
760     // Make it so.
761     configDialogPointer->show();
762
763     // TODO.  KConfigDialog does not respect expanding size policies.  <https://redmine.stoutner.com/issues/823>
764     //configDialogPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
765     //privacySettingsWidgetPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
766     //generalSettingsWidgetPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
767     //configDialogPointer->adjustSize();
768
769     // Expand the config dialog.
770     configDialogPointer->resize(1000, 500);
771
772     // Create a save spell check languages lambda.
773     auto saveSpellCheckLanguages = [spellCheckListWidgetPointer, kConfigSkeletonPointer, this] ()
774     {
775         // Create a list of enabled languages.
776         QStringList newSpellCheckLanguages = QStringList();
777
778         // Get a count of all the languages.
779         int allLanguagesCount = spellCheckListWidgetPointer->count();
780
781         // Get a list of all the checked languages.
782         for (int i = 0; i < allLanguagesCount; ++i) {
783             // Get the language item.
784             QListWidgetItem *languageItemPointer = spellCheckListWidgetPointer->item(i);
785
786             // Add the item to the enabled languages if it is checked.
787             if (languageItemPointer->checkState() == Qt::Checked)
788                 newSpellCheckLanguages.append(languageItemPointer->text());
789         }
790
791         // Update the spell check languages.
792         if (Settings::spellCheckLanguages() != newSpellCheckLanguages)
793         {
794             // Update the spell check languages.
795             Settings::setSpellCheckLanguages(newSpellCheckLanguages);
796
797             // Write the settings to disk.
798             kConfigSkeletonPointer->save();
799         }
800
801         // Apply the spell check languages.
802         tabWidgetPointer->applySpellCheckLanguages();
803     };
804
805     // Process
806     connect(applyButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages);
807     connect(okButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages);
808
809     // Apply the settings handled by KConfig.
810     connect(configDialogPointer, SIGNAL(settingsChanged(QString)), tabWidgetPointer, SLOT(applyApplicationSettings()));
811     connect(configDialogPointer, SIGNAL(settingsChanged(QString)), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
812 }
813
814 QSize BrowserWindow::sizeHint() const
815 {
816     // Return the default window size.
817     return QSize(1500, 1200);
818 }
819
820 void BrowserWindow::toggleDomStorage() const
821 {
822     // Remove the focus from the URL line edit.
823     urlLineEditPointer->clearFocus();
824
825     // Toggle DOM storage.
826     tabWidgetPointer->toggleDomStorage();
827 }
828
829 void BrowserWindow::toggleFindCaseSensitive() const
830 {
831     // Get the current find string.
832     const QString findString = findTextLineEditPointer->text();
833
834     // Toggle find case sensitive.
835     tabWidgetPointer->toggleFindCaseSensitive(findString);
836 }
837
838 void BrowserWindow::toggleJavaScript() const
839 {
840     // Remove the focus from the URL line edit.
841     urlLineEditPointer->clearFocus();
842
843     // Toggle JavaScript.
844     tabWidgetPointer->toggleJavaScript();
845 }
846
847 void BrowserWindow::toggleLocalStorage() const
848 {
849     // Remove the focus from the URL line edit.
850     urlLineEditPointer->clearFocus();
851
852     // Toggle local storage.
853     tabWidgetPointer->toggleLocalStorage();
854 }
855
856 void BrowserWindow::toggleFullScreen()
857 {
858     // Toggle the full screen status.
859     if (fullScreenActionPointer->isChecked())  // Enable full screen browsing mode.
860     {
861         // Enable full screen mode.
862         fullScreenActionPointer->setFullScreen(window(), true);
863
864         // Hide the menu bar if specified.
865         if (Settings::fullScreenHideMenuBar())
866             menuBar()->setVisible(false);
867
868         // Hide the toolbars if specified.
869         if (Settings::fullScreenHideToolBars())
870         {
871             navigationToolBarPointer->setVisible(false);
872             urlToolBarPointer->setVisible(false);
873         }
874
875         // Hide the tab bar if specified.
876         if (Settings::fullScreenHideTabBar())
877             tabWidgetPointer->setTabBarVisible(false);
878
879         // Hide the status bar if specified.
880         if (Settings::fullScreenHideStatusBar())
881             statusBar()->setVisible(false);
882     }
883     else  // Disable full screen browsing mode.
884     {
885         // Disable full screen mode.
886         fullScreenActionPointer->setFullScreen(window(), false);
887
888         // Show the menu bar.
889         menuBar()->setVisible(true);
890
891         // Show the toolbars.
892         navigationToolBarPointer->setVisible(true);
893         urlToolBarPointer->setVisible(true);
894
895         // Show the tab bar.
896         tabWidgetPointer->setTabBarVisible(true);
897
898         // Show the status bar.
899         statusBar()->setVisible(true);
900     }
901 }
902
903 void BrowserWindow::updateCookiesAction(const int numberOfCookies) const
904 {
905     // Update the action text.
906     cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", numberOfCookies));
907 }
908
909 void BrowserWindow::updateDomStorageAction(const bool &isEnabled) const
910 {
911     // Set the action checked status.
912     domStorageActionPointer->setChecked(isEnabled);
913 }
914
915 void BrowserWindow::updateDomainSettingsIndicator(const bool status)
916 {
917     // Set the domain palette according to the status.
918     if (status)
919         urlLineEditPointer->setPalette(positiveBackgroundPalette);
920     else
921         urlLineEditPointer->setPalette(normalBackgroundPalette);
922 }
923
924 void BrowserWindow::updateFindText(const QString &text, const bool findCaseSensitive) const
925 {
926     // Set the text.
927     findTextLineEditPointer->setText(text);
928
929     // Set the find case sensitive action checked status.
930     findCaseSensitiveActionPointer->setChecked(findCaseSensitive);
931 }
932
933 void BrowserWindow::updateFindTextResults(const QWebEngineFindTextResult &findTextResult) const
934 {
935     // Update the find text label.
936     findTextLabelPointer->setText(QStringLiteral("  %1/%2  ").arg(findTextResult.activeMatch()).arg(findTextResult.numberOfMatches()));
937
938     // Set the background color according to the find status.
939     if (findTextLineEditPointer->text().isEmpty())
940         findTextLineEditPointer->setPalette(normalBackgroundPalette);
941     else if (findTextResult.numberOfMatches() == 0)
942         findTextLineEditPointer->setPalette(negativeBackgroundPalette);
943     else
944         findTextLineEditPointer->setPalette(positiveBackgroundPalette);
945 }
946
947 void BrowserWindow::updateJavaScriptAction(const bool &isEnabled)
948 {
949     // Update the JavaScript status.
950     javaScriptEnabled = isEnabled;
951
952     // Set the icon according to the status.
953     if (javaScriptEnabled)
954         javaScriptActionPointer->setIcon(QIcon(QStringLiteral(":/icons/javascript-warning")));
955     else
956         javaScriptActionPointer->setIcon(QIcon(QStringLiteral(":/icons/privacy-mode")));
957
958     // Set the action checked status.
959     javaScriptActionPointer->setChecked(javaScriptEnabled);
960
961     // Update the status of the DOM storage action.
962     domStorageActionPointer->setEnabled(javaScriptEnabled & localStorageEnabled);
963 }
964
965 void BrowserWindow::updateLocalStorageAction(const bool &isEnabled)
966 {
967     // Update the local storage status.
968     localStorageEnabled = isEnabled;
969
970     // Update the icon.
971     if (localStorageEnabled)
972         localStorageActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("disk-quota-high")));
973     else
974         localStorageActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("disk-quota")));
975
976     // Set the action checked status.
977     localStorageActionPointer->setChecked(localStorageEnabled);
978
979     // Update the status of the DOM storage action.
980     domStorageActionPointer->setEnabled(localStorageEnabled & javaScriptEnabled);
981 }
982
983 void BrowserWindow::updateSearchEngineActions(const QString &searchEngine, const bool &updateCustomSearchEngineStatus)
984 {
985     // Initialize the custom search engine flag.
986     bool customSearchEngine = false;
987
988     if (searchEngine == "Mojeek")  // Mojeek.
989     {
990         // Check the Mojeek user agent action.
991         searchEngineMojeekActionPointer->setChecked(true);
992
993         // Update the search engine menu action text.
994         searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Mojeek"));
995     }
996     else if (searchEngine == "Monocles")  // Monocles.
997     {
998         // Check the Monocles user agent action.
999         searchEngineMonoclesActionPointer->setChecked(true);
1000
1001         // Update the search engine menu action text.
1002         searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Monocles"));
1003     }
1004     else if (searchEngine == "MetaGer")  // MetaGer.
1005     {
1006         // Check the MetaGer user agent action.
1007         searchEngineMetagerActionPointer->setChecked(true);
1008
1009         // Update the search engine menu action text.
1010         searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - MetaGer"));
1011     }
1012     else if (searchEngine == "Google")  // Google.
1013     {
1014         // Check the Google user agent action.
1015         searchEngineGoogleActionPointer->setChecked(true);
1016
1017         // Update the search engine menu action text.
1018         searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Google"));
1019     }
1020     else if (searchEngine == "Bing")  // Bing.
1021     {
1022         // Check the Bing user agent action.
1023         searchEngineBingActionPointer->setChecked(true);
1024
1025         // Update the search engine menu action text.
1026         searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Bing"));
1027     }
1028     else if (searchEngine == "Yahoo")  // Yahoo.
1029     {
1030         // Check the Yahoo user agent action.
1031         searchEngineYahooActionPointer->setChecked(true);
1032
1033         // Update the search engine menu action text.
1034         searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Yahoo"));
1035     }
1036     else  // Custom search engine.
1037     {
1038         // Check the user agent.
1039         searchEngineCustomActionPointer->setChecked(true);
1040
1041         // Update the search engine menu action text.
1042         searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Custom"));
1043
1044         // Set the custom search engine text.
1045         searchEngineCustomActionPointer->setText(searchEngine);
1046
1047         // Set the custom search engine flag.
1048         customSearchEngine = true;
1049     }
1050
1051     // Update the custom search engine enabled boolean.
1052     if (updateCustomSearchEngineStatus)
1053         customSearchEngineEnabled = customSearchEngine;
1054
1055     // Format the custom search engine.
1056     if (customSearchEngineEnabled)
1057     {
1058         // Enable the custom search engine.
1059         searchEngineCustomActionPointer->setEnabled(true);
1060     }
1061     else
1062     {
1063         // Disable the custom search engine.
1064         searchEngineCustomActionPointer->setEnabled(false);
1065
1066         // Reset the custom search engine text.
1067         searchEngineCustomActionPointer->setText(i18nc("@action", "Custom"));
1068     }
1069 }
1070
1071 void BrowserWindow::updateUserAgentActions(const QString &userAgent, const bool &updateCustomUserAgentStatus)
1072 {
1073     // Initialize the custom user agent flag.
1074     bool customUserAgent = false;
1075
1076     // Check the indicated on-the-fly user agent.
1077     if (userAgent == UserAgentHelper::PRIVACY_BROWSER_USER_AGENT)  // Privacy Browser.
1078     {
1079         // Check the Privacy Browser user agent action.
1080         userAgentPrivacyBrowserActionPointer->setChecked(true);
1081
1082         // Update the user agent menu action text.
1083         userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Privacy Browser"));
1084     }
1085     else if (userAgent == TabWidget::webEngineDefaultUserAgent)  // WebEngine default.
1086     {
1087         // check the WebEngine default user agent action.
1088         userAgentWebEngineDefaultActionPointer->setChecked(true);
1089
1090         // Update the user agent menu action text.
1091         userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - WebEngine default"));
1092     }
1093     else if (userAgent == UserAgentHelper::FIREFOX_LINUX_USER_AGENT)  // Firefox on Linux.
1094     {
1095         // Check the Firefox on Linux user agent action.
1096         userAgentFirefoxLinuxActionPointer->setChecked(true);
1097
1098         // Update the user agent menu action text.
1099         userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Firefox on Linux"));
1100     }
1101     else if (userAgent == UserAgentHelper::CHROMIUM_LINUX_USER_AGENT)  // Chromium on Linux.
1102     {
1103         // Check the Chromium on Linux user agent action.
1104         userAgentChromiumLinuxActionPointer->setChecked(true);
1105
1106         // Update the user agent menu action text.
1107         userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Chromium on Linux"));
1108     }
1109     else if (userAgent == UserAgentHelper::FIREFOX_WINDOWS_USER_AGENT)  // Firefox on Windows.
1110     {
1111         // Check the Firefox on Windows user agent action.
1112         userAgentFirefoxWindowsActionPointer->setChecked(true);
1113
1114         // Update the user agent menu action text.
1115         userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Firefox on Windows"));
1116     }
1117     else if (userAgent == UserAgentHelper::CHROME_WINDOWS_USER_AGENT)  // Chrome on Windows.
1118     {
1119         // Check the Chrome on Windows user agent action.
1120         userAgentChromeWindowsActionPointer->setChecked(true);
1121
1122         // Update the user agent menu action text.
1123         userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Chrome on Windows"));
1124     }
1125     else if (userAgent == UserAgentHelper::EDGE_WINDOWS_USER_AGENT)  // Edge on Windows.
1126     {
1127         // Check the Edge on Windows user agent action.
1128         userAgentEdgeWindowsActionPointer->setChecked(true);
1129
1130         // Update the user agent menu action text.
1131         userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Edge on Windows"));
1132     }
1133     else if (userAgent == UserAgentHelper::SAFARI_MACOS_USER_AGENT)  // Safari on macOS.
1134     {
1135         // Check the Safari on macOS user agent action.
1136         userAgentSafariMacosActionPointer->setChecked(true);
1137
1138         // Update the user agent menu action text.
1139         userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Safari on macOS"));
1140     }
1141     else  // Custom user agent.
1142     {
1143         // Check the user agent.
1144         userAgentCustomActionPointer->setChecked(true);
1145
1146         // Update the user agent menu action text.
1147         userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Custom"));
1148
1149         // Set the custom user agent text.
1150         userAgentCustomActionPointer->setText(userAgent);
1151
1152         // Set the custom user agent flag.
1153         customUserAgent = true;
1154     }
1155
1156     // Update the custom user agent enabled boolean.
1157     // This is not done when the current user agent is a custom one but it is temporarially being changed via on-the-fly settings so that the user can switch back to the custom user agent.
1158     if (updateCustomUserAgentStatus)
1159         customUserAgentEnabled = customUserAgent;
1160
1161
1162     // Format the custom user agent.
1163     if (customUserAgentEnabled)
1164     {
1165         // Enable the custom user agent.
1166         userAgentCustomActionPointer->setEnabled(true);
1167     }
1168     else
1169     {
1170         // Disable the custom user agent.
1171         userAgentCustomActionPointer->setEnabled(false);
1172
1173         // Reset the custom user agent text.
1174         userAgentCustomActionPointer->setText(i18nc("@action", "Custom"));
1175     }
1176 }
1177
1178 void BrowserWindow::updateZoomFactorAction(const double &zoomFactor)
1179 {
1180     // Set the current zoom factor.
1181     currentZoomFactor = zoomFactor;
1182
1183     // Update the zoom factor action text, formatting the double with 2 decimal places.
1184     zoomFactorActionPointer->setText(ki18nc("@action", "Zoom Factor - %1").subs(zoomFactor, 0, '0', 2).toString());
1185 }
1186
1187 void BrowserWindow::updateSearchEngineLabel(const QString &searchEngineString) const
1188 {
1189     // Update the search engine label.
1190     searchEngineLabelPointer->setText(SearchEngineHelper::getSearchUrl(searchEngineString));
1191 }
1192
1193 void BrowserWindow::updateUrlLineEdit(const QUrl &newUrl)
1194 {
1195     // Update the URL line edit if it does not have focus.
1196     if (!urlLineEditPointer->hasFocus())
1197     {
1198         // Get the new URL string.
1199         QString newUrlString = newUrl.toString();
1200
1201         // Update the URL line edit.
1202         urlLineEditPointer->setText(newUrlString);
1203
1204         // Set the focus if the new URL is blank.
1205         if (newUrlString == QStringLiteral(""))
1206             urlLineEditPointer->setFocus();
1207     }
1208
1209     // Store the current URL.
1210     currentUrl = newUrl;
1211 }
1212
1213 void BrowserWindow::updateUserAgentLabel(const QString &userAgentDatabaseName) const
1214 {
1215     // Update the user agent label.
1216     userAgentLabelPointer->setText(UserAgentHelper::getUserAgentFromDatabaseName(userAgentDatabaseName));
1217 }
1218
1219 void BrowserWindow::updateWindowTitle(const QString &title)
1220 {
1221     // Update the window title.
1222     setWindowTitle(title);
1223 }