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