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