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