2 * Copyright 2022-2023 Soren Stoutner <soren@stoutner.com>.
4 * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
6 * Privacy Browser PC is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * Privacy Browser PC is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
20 // Application headers.
21 #include "BrowserWindow.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/AddFolderDialog.h"
29 #include "dialogs/BookmarksDialog.h"
30 #include "dialogs/CookiesDialog.h"
31 #include "dialogs/DomainSettingsDialog.h"
32 #include "dialogs/EditBookmarkDialog.h"
33 #include "dialogs/EditFolderDialog.h"
34 #include "helpers/SearchEngineHelper.h"
35 #include "helpers/UserAgentHelper.h"
36 #include "structs/BookmarkStruct.h"
38 // KDE Frameworks headers.
39 #include <KActionCollection>
40 #include <KColorScheme>
41 #include <KXMLGUIFactory>
43 // Qt toolkit headers.
45 #include <QContextMenuEvent>
46 #include <QDBusConnection>
47 #include <QDBusConnectionInterface>
48 #include <QDBusMessage>
49 #include <QFileDialog>
50 #include <QInputDialog>
51 #include <QNetworkCookie>
53 #include <QMessageBox>
56 #include <QWebEngineFindTextResult>
58 // Construct the class.
59 BrowserWindow::BrowserWindow(bool firstWindow, QString *initialUrlStringPointer) : KXmlGuiWindow()
61 // Initialize the variables.
62 javaScriptEnabled = false;
63 localStorageEnabled = false;
65 // Instantiate the privacy tab widget pointer.
66 tabWidgetPointer = new TabWidget(this);
68 // Set the privacy tab widget as the central widget.
69 setCentralWidget(tabWidgetPointer);
71 // Get a handle for the action collection.
72 actionCollectionPointer = this->actionCollection();
74 // Add the standard actions.
75 KStandardAction::print(tabWidgetPointer, SLOT(print()), actionCollectionPointer);
76 QAction *printPreviewActionPointer = KStandardAction::printPreview(tabWidgetPointer, SLOT(printPreview()), actionCollectionPointer);
77 KStandardAction::quit(qApp, SLOT(closeAllWindows()), actionCollectionPointer);
78 zoomInActionPointer = KStandardAction::zoomIn(this, SLOT(incrementZoom()), actionCollectionPointer);
79 zoomOutActionPointer = KStandardAction::zoomOut(this, SLOT(decrementZoom()), actionCollectionPointer);
80 refreshActionPointer = KStandardAction::redisplay(this, SLOT(refresh()), actionCollectionPointer);
81 fullScreenActionPointer = KStandardAction::fullScreen(this, SLOT(toggleFullScreen()), this, actionCollectionPointer);
82 QAction *backActionPointer = KStandardAction::back(this, SLOT(back()), actionCollectionPointer);
83 QAction *forwardActionPointer = KStandardAction::forward(this, SLOT(forward()), actionCollectionPointer);
84 KStandardAction::home(this, SLOT(home()), actionCollectionPointer);
85 QAction *editBookmarksActionPointer = KStandardAction::editBookmarks(this, SLOT(editBookmarks()), actionCollectionPointer);
86 KStandardAction::preferences(this, SLOT(showSettingsDialog()), actionCollectionPointer);
87 KStandardAction::find(this, SLOT(showFindTextActions()), actionCollectionPointer);
88 findNextActionPointer = KStandardAction::findNext(this, SLOT(findNext()), actionCollectionPointer);
89 findPreviousActionPointer = KStandardAction::findPrev(this, SLOT(findPrevious()), actionCollectionPointer);
91 // Add the custom actions.
92 QAction *newTabActionPointer = actionCollectionPointer->addAction(QLatin1String("new_tab"));
93 QAction *newWindowActionPointer = actionCollectionPointer->addAction(QLatin1String("new_window"));
94 QAction *saveArchiveActionPointer = actionCollectionPointer->addAction(QLatin1String("save_archive"));
95 zoomDefaultActionPointer = actionCollectionPointer->addAction(QLatin1String("zoom_default"));
96 QAction *reloadAndBypassCacheActionPointer = actionCollectionPointer->addAction(QLatin1String("reload_and_bypass_cache"));
97 stopActionPointer = actionCollectionPointer->addAction(QLatin1String("stop"));
98 viewSourceActionPointer = actionCollectionPointer->addAction(QLatin1String("view_source"));
99 viewSourceInNewTabActionPointer = actionCollectionPointer->addAction(QLatin1String("view_source_in_new_tab"));
100 developerToolsActionPointer = actionCollectionPointer->addAction(QLatin1String("developer_tools"));
101 javaScriptActionPointer = actionCollectionPointer->addAction(QLatin1String("javascript"));
102 localStorageActionPointer = actionCollectionPointer->addAction(QLatin1String("local_storage"));
103 domStorageActionPointer = actionCollectionPointer->addAction(QLatin1String("dom_storage"));
104 userAgentPrivacyBrowserActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_privacy_browser"));
105 userAgentWebEngineDefaultActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_webengine_default"));
106 userAgentFirefoxLinuxActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_firefox_linux"));
107 userAgentChromiumLinuxActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_chromium_linux"));
108 userAgentFirefoxWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_firefox_windows"));
109 userAgentChromeWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_chrome_windows"));
110 userAgentEdgeWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_edge_windows"));
111 userAgentSafariMacosActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_safari_macos"));
112 userAgentCustomActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_custom"));
113 zoomFactorActionPointer = actionCollectionPointer->addAction(QLatin1String("zoom_factor"));
114 searchEngineMojeekActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_mojeek"));
115 searchEngineMonoclesActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_monocles"));
116 searchEngineMetagerActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_metager"));
117 searchEngineGoogleActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_google"));
118 searchEngineBingActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_bing"));
119 searchEngineYahooActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_yahoo"));
120 searchEngineCustomActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_custom"));
121 viewBookmarksToolBarActionPointer = actionCollectionPointer->addAction(QLatin1String("view_bookmarks_toolbar"));
122 QAction *domainSettingsActionPointer = actionCollectionPointer->addAction(QLatin1String("domain_settings"));
123 cookiesActionPointer = actionCollectionPointer->addAction(QLatin1String("cookies"));
124 findCaseSensitiveActionPointer = actionCollectionPointer->addAction(QLatin1String("find_case_sensitive"));
125 hideFindTextActionPointer = actionCollectionPointer->addAction(QLatin1String("hide_find_actions"));
127 // Create the action groups
128 QActionGroup *userAgentActionGroupPointer = new QActionGroup(this);
129 QActionGroup *searchEngineActionGroupPointer = new QActionGroup(this);
131 // Add the actions to the groups.
132 userAgentActionGroupPointer->addAction(userAgentPrivacyBrowserActionPointer);
133 userAgentActionGroupPointer->addAction(userAgentWebEngineDefaultActionPointer);
134 userAgentActionGroupPointer->addAction(userAgentFirefoxLinuxActionPointer);
135 userAgentActionGroupPointer->addAction(userAgentChromiumLinuxActionPointer);
136 userAgentActionGroupPointer->addAction(userAgentFirefoxWindowsActionPointer);
137 userAgentActionGroupPointer->addAction(userAgentChromeWindowsActionPointer);
138 userAgentActionGroupPointer->addAction(userAgentEdgeWindowsActionPointer);
139 userAgentActionGroupPointer->addAction(userAgentSafariMacosActionPointer);
140 userAgentActionGroupPointer->addAction(userAgentCustomActionPointer);
141 searchEngineActionGroupPointer->addAction(searchEngineMojeekActionPointer);
142 searchEngineActionGroupPointer->addAction(searchEngineMonoclesActionPointer);
143 searchEngineActionGroupPointer->addAction(searchEngineMetagerActionPointer);
144 searchEngineActionGroupPointer->addAction(searchEngineGoogleActionPointer);
145 searchEngineActionGroupPointer->addAction(searchEngineBingActionPointer);
146 searchEngineActionGroupPointer->addAction(searchEngineYahooActionPointer);
147 searchEngineActionGroupPointer->addAction(searchEngineCustomActionPointer);
149 // Set some actions to be checkable.
150 javaScriptActionPointer->setCheckable(true);
151 localStorageActionPointer->setCheckable(true);
152 domStorageActionPointer->setCheckable(true);
153 findCaseSensitiveActionPointer->setCheckable(true);
154 viewSourceActionPointer->setCheckable(true);
155 developerToolsActionPointer->setCheckable(true);
156 userAgentPrivacyBrowserActionPointer->setCheckable(true);
157 userAgentWebEngineDefaultActionPointer->setCheckable(true);
158 userAgentFirefoxLinuxActionPointer->setCheckable(true);
159 userAgentChromiumLinuxActionPointer->setCheckable(true);
160 userAgentFirefoxWindowsActionPointer->setCheckable(true);
161 userAgentChromeWindowsActionPointer->setCheckable(true);
162 userAgentEdgeWindowsActionPointer->setCheckable(true);
163 userAgentSafariMacosActionPointer->setCheckable(true);
164 userAgentCustomActionPointer->setCheckable(true);
165 searchEngineMojeekActionPointer->setCheckable(true);
166 searchEngineMonoclesActionPointer->setCheckable(true);
167 searchEngineMetagerActionPointer->setCheckable(true);
168 searchEngineGoogleActionPointer->setCheckable(true);
169 searchEngineBingActionPointer->setCheckable(true);
170 searchEngineYahooActionPointer->setCheckable(true);
171 searchEngineCustomActionPointer->setCheckable(true);
172 viewBookmarksToolBarActionPointer->setCheckable(true);
174 // Instantiate the user agent helper.
175 UserAgentHelper *userAgentHelperPointer = new UserAgentHelper();
177 // Set the action text.
178 newTabActionPointer->setText(i18nc("New tab action", "New Tab"));
179 newWindowActionPointer->setText(i18nc("New window action", "New Window"));
180 saveArchiveActionPointer->setText(i18nc("Save archive action", "Save Archive"));
181 zoomDefaultActionPointer->setText(i18nc("Zoom default action", "Zoom Default"));
182 reloadAndBypassCacheActionPointer->setText(i18nc("Reload and bypass cache action", "Reload and Bypass Cache"));
183 stopActionPointer->setText(i18nc("Stop action", "Stop"));
184 viewSourceActionPointer->setText(i18nc("View source action", "View Source"));
185 viewSourceInNewTabActionPointer->setText(i18nc("View source in new tab action", "View Source in New Tab"));
186 developerToolsActionPointer->setText(i18nc("Developer tools action", "Developer Tools"));
187 javaScriptActionPointer->setText(i18nc("JavaScript action", "JavaScript"));
188 localStorageActionPointer->setText(i18nc("The Local Storage action", "Local Storage"));
189 domStorageActionPointer->setText(i18nc("DOM Storage action", "DOM Storage"));
190 userAgentPrivacyBrowserActionPointer->setText(userAgentHelperPointer->PRIVACY_BROWSER_TRANSLATED);
191 userAgentWebEngineDefaultActionPointer->setText(userAgentHelperPointer->WEB_ENGINE_DEFAULT_TRANSLATED);
192 userAgentFirefoxLinuxActionPointer->setText(userAgentHelperPointer->FIREFOX_LINUX_TRANSLATED);
193 userAgentChromiumLinuxActionPointer->setText(userAgentHelperPointer->CHROMIUM_LINUX_TRANSLATED);
194 userAgentFirefoxWindowsActionPointer->setText(userAgentHelperPointer->FIREFOX_WINDOWS_TRANSLATED);
195 userAgentChromeWindowsActionPointer->setText(userAgentHelperPointer->CHROME_WINDOWS_TRANSLATED);
196 userAgentEdgeWindowsActionPointer->setText(userAgentHelperPointer->EDGE_WINDOWS_TRANSLATED);
197 userAgentSafariMacosActionPointer->setText(userAgentHelperPointer->SAFARI_MACOS_TRANSLATED);
198 searchEngineMojeekActionPointer->setText(i18nc("Search engine", "Mojeek"));
199 searchEngineMonoclesActionPointer->setText(i18nc("Search engine", "Monocles"));
200 searchEngineMetagerActionPointer->setText(i18nc("Search engine", "MetaGer"));
201 searchEngineGoogleActionPointer->setText(i18nc("Search engine", "Google"));
202 searchEngineBingActionPointer->setText(i18nc("Search engine", "Bing"));
203 searchEngineYahooActionPointer->setText(i18nc("Search engine", "Yahoo"));
204 viewBookmarksToolBarActionPointer->setText(i18nc("View bookmarks toolbar", "View Bookmarks Toolbar"));
205 domainSettingsActionPointer->setText(i18nc("Domain Settings action", "Domain Settings"));
206 cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", 0));
207 findCaseSensitiveActionPointer->setText(i18nc("Find Case Sensitive action", "Find Case Sensitive"));
208 hideFindTextActionPointer->setText(i18nc("Hide Find Text action (the text should include the language-specific escape keyboard shortcut).", "Hide Find Text (Esc)"));
210 // Set the action icons. Gnome doesn't contain some of the icons that KDE has.
211 // The toolbar icons don't pick up unless the size is explicit, probably because the toolbar ends up being an intermediate size.
212 newTabActionPointer->setIcon(QIcon::fromTheme(QLatin1String("tab-new")));
213 newWindowActionPointer->setIcon(QIcon::fromTheme(QLatin1String("window-new")));
214 saveArchiveActionPointer->setIcon(QIcon::fromTheme(QLatin1String("document-save")));
215 zoomDefaultActionPointer->setIcon(QIcon::fromTheme(QLatin1String("zoom-fit-best")));
216 reloadAndBypassCacheActionPointer->setIcon(QIcon::fromTheme(QLatin1String("view-refresh")));
217 stopActionPointer->setIcon(QIcon::fromTheme(QLatin1String("process-stop")));
218 viewSourceActionPointer->setIcon(QIcon::fromTheme(QLatin1String("view-choose"), QIcon::fromTheme(QLatin1String("accessories-text-editor"))));
219 viewSourceInNewTabActionPointer->setIcon(QIcon::fromTheme(QLatin1String("view-choose"), QIcon::fromTheme(QLatin1String("accessories-text-editor"))));
220 developerToolsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("add-subtitle"), QIcon::fromTheme("system-run")));
221 domStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("code-class"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/actions/gtk-unindent-ltr.png"))));
222 userAgentPrivacyBrowserActionPointer->setIcon(QIcon(QLatin1String(":/icons/privacy-mode.svg")));
223 userAgentWebEngineDefaultActionPointer->setIcon(QIcon::fromTheme(QLatin1String("qtlogo"), QIcon::fromTheme(QLatin1String("user-group-properties"),
224 QIcon::fromTheme(QLatin1String("contact-new")))));
225 userAgentFirefoxLinuxActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"),
226 QIcon::fromTheme(QLatin1String("contact-new")))));
227 userAgentChromiumLinuxActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
228 userAgentFirefoxWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"),
229 QIcon::fromTheme(QLatin1String("contact-new")))));
230 userAgentChromeWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
231 userAgentEdgeWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
232 userAgentSafariMacosActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
233 userAgentCustomActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
234 searchEngineMojeekActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
235 searchEngineMonoclesActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
236 searchEngineMetagerActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
237 searchEngineGoogleActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-google"), QIcon::fromTheme(QLatin1String("edit-find"))));
238 searchEngineBingActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
239 searchEngineYahooActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-yahoo"), QIcon::fromTheme(QLatin1String("edit-find"))));
240 searchEngineCustomActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
241 zoomFactorActionPointer->setIcon(QIcon::fromTheme(QLatin1String("zoom-fit-best")));
242 editBookmarksActionPointer->setIcon(QIcon::fromTheme(QLatin1String("bookmark-edit"), QIcon::fromTheme(QLatin1String("bookmark-new"))));
243 viewBookmarksToolBarActionPointer->setIcon(QIcon::fromTheme(QLatin1String("bookmarks"), QIcon::fromTheme(QLatin1String("bookmark-new"))));
244 domainSettingsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("settings-configure"), QIcon::fromTheme(QLatin1String("preferences-desktop"))));
245 cookiesActionPointer->setIcon(QIcon::fromTheme(QLatin1String("preferences-web-browser-cookies"), QIcon::fromTheme(QLatin1String("appointment-new"))));
246 findCaseSensitiveActionPointer->setIcon(QIcon::fromTheme(QLatin1String("format-text-lowercase"), QIcon::fromTheme(QLatin1String("/usr/share/icons/gnome/32x32/apps/fonts.png"))));
247 hideFindTextActionPointer->setIcon(QIcon::fromTheme(QLatin1String("window-close-symbolic")));
249 // Create the key sequences.
250 QKeySequence ctrlTKeySequence = QKeySequence(i18nc("The open new tab key sequence.", "Ctrl+T"));
251 QKeySequence ctrlNKeySequence = QKeySequence(i18nc("The open new window key sequence.", "Ctrl+N"));
252 QKeySequence ctrlAKeySequence = QKeySequence(i18nc("The save archive key sequence.", "Ctrl+A"));
253 QKeySequence ctrl0KeySequence = QKeySequence(i18nc("The zoom default key sequence.", "Ctrl+0"));
254 QKeySequence ctrlF5KeySequence = QKeySequence(i18nc("The reload and bypass cache key sequence.", "Ctrl+F5"));
255 QKeySequence ctrlShiftXKeySequence = QKeySequence(i18nc("The stop key sequence.", "Ctrl+Shift+X"));
256 QKeySequence ctrlUKeySequence = QKeySequence(i18nc("The view source key sequence.", "Ctrl+U"));
257 QKeySequence ctrlShiftUKeySequence = QKeySequence(i18nc("The view source in new tab key sequence.", "Ctrl+Shift+U"));
258 QKeySequence f12KeySequence = QKeySequence(i18nc("The developer tools key sequence.", "F12"));
259 QKeySequence ctrlShiftPKeySequence = QKeySequence(i18nc("The print preview key sequence.", "Ctrl+Shift+P"));
260 QKeySequence ctrlJKeySequence = QKeySequence(i18nc("The JavaScript key sequence.", "Ctrl+J"));
261 QKeySequence ctrlLKeySequence = QKeySequence(i18nc("The local storage key sequence.", "Ctrl+L"));
262 QKeySequence ctrlDKeySequence = QKeySequence(i18nc("The DOM storage key sequence.", "Ctrl+D"));
263 QKeySequence ctrlSKeySequence = QKeySequence(i18nc("The find case sensitive key sequence.", "Ctrl+S"));
264 QKeySequence ctrlAltPKeySequence = QKeySequence(i18nc("The Privacy Browser user agent key sequence.", "Ctrl+Alt+P"));
265 QKeySequence ctrlAltWKeySequence = QKeySequence(i18nc("The WebEngine Default user agent key sequence.", "Ctrl+Alt+W"));
266 QKeySequence ctrlAltFKeySequence = QKeySequence(i18nc("The Firefox on Linux user agent key sequence.", "Ctrl+Alt+F"));
267 QKeySequence ctrlAltCKeySequence = QKeySequence(i18nc("The Chromium on Linux user agent key sequence.", "Ctrl+Alt+C"));
268 QKeySequence ctrlAltShiftFKeySequence = QKeySequence(i18nc("The Firefox on Windows user agent key sequence.", "Ctrl+Alt+Shift+F"));
269 QKeySequence ctrlAltShiftCKeySequence = QKeySequence(i18nc("The Chrome on Windows user agent key sequence.", "Ctrl+Alt+Shift+C"));
270 QKeySequence ctrlAltEKeySequence = QKeySequence(i18nc("The Edge on Windows user agent key sequence.", "Ctrl+Alt+E"));
271 QKeySequence ctrlAltSKeySequence = QKeySequence(i18nc("The Safari on macOS user agent key sequence.", "Ctrl+Alt+S"));
272 QKeySequence altShiftCKeySequence = QKeySequence(i18nc("The custom user agent key sequence.", "Alt+Shift+C"));
273 QKeySequence ctrlAltZKeySequence = QKeySequence(i18nc("The zoom factor key sequence.", "Ctrl+Alt+Z"));
274 QKeySequence ctrlShiftMKeySequence = QKeySequence(i18nc("The Mojeek search engine key sequence.", "Ctrl+Shift+M"));
275 QKeySequence ctrlShiftOKeySequence = QKeySequence(i18nc("The Monocles search engine key sequence.", "Ctrl+Shift+O"));
276 QKeySequence ctrlShiftEKeySequence = QKeySequence(i18nc("The MetaGer search engine key sequence.", "Ctrl+Shift+E"));
277 QKeySequence ctrlShiftGKeySequence = QKeySequence(i18nc("The Google search engine key sequence.", "Ctrl+Shift+G"));
278 QKeySequence ctrlShiftBKeySequence = QKeySequence(i18nc("The Bing search engine key sequence.", "Ctrl+Shift+B"));
279 QKeySequence ctrlShiftYKeySequence = QKeySequence(i18nc("The Yahoo search engine key sequence.", "Ctrl+Shift+Y"));
280 QKeySequence ctrlShiftCKeySequence = QKeySequence(i18nc("The custom search engine key sequence.", "Ctrl+Shift+C"));
281 QKeySequence ctrlAltShiftBKeySequence = QKeySequence(i18nc("The edit bookmarks key sequence.", "Ctrl+Alt+Shift+B"));
282 QKeySequence ctrlAltBKeySequence = QKeySequence(i18nc("The view bookmarks toolbar key sequence.", "Ctrl+Alt+B"));
283 QKeySequence ctrlShiftDKeySequence = QKeySequence(i18nc("The domain settings key sequence.", "Ctrl+Shift+D"));
284 QKeySequence ctrlSemicolonKeySequence = QKeySequence(i18nc("The cookies dialog key sequence.", "Ctrl+;"));
286 // Set the action key sequences.
287 actionCollectionPointer->setDefaultShortcut(newTabActionPointer, ctrlTKeySequence);
288 actionCollectionPointer->setDefaultShortcut(newWindowActionPointer, ctrlNKeySequence);
289 actionCollectionPointer->setDefaultShortcut(saveArchiveActionPointer, ctrlAKeySequence);
290 actionCollectionPointer->setDefaultShortcut(zoomDefaultActionPointer, ctrl0KeySequence);
291 actionCollectionPointer->setDefaultShortcut(reloadAndBypassCacheActionPointer, ctrlF5KeySequence);
292 actionCollectionPointer->setDefaultShortcut(stopActionPointer, ctrlShiftXKeySequence);
293 actionCollectionPointer->setDefaultShortcut(viewSourceActionPointer, ctrlUKeySequence);
294 actionCollectionPointer->setDefaultShortcut(viewSourceInNewTabActionPointer, ctrlShiftUKeySequence);
295 actionCollectionPointer->setDefaultShortcut(developerToolsActionPointer, f12KeySequence);
296 actionCollectionPointer->setDefaultShortcut(printPreviewActionPointer, ctrlShiftPKeySequence);
297 actionCollectionPointer->setDefaultShortcut(javaScriptActionPointer, ctrlJKeySequence);
298 actionCollectionPointer->setDefaultShortcut(localStorageActionPointer, ctrlLKeySequence);
299 actionCollectionPointer->setDefaultShortcut(domStorageActionPointer, ctrlDKeySequence);
300 actionCollectionPointer->setDefaultShortcut(findCaseSensitiveActionPointer, ctrlSKeySequence);
301 actionCollectionPointer->setDefaultShortcut(userAgentPrivacyBrowserActionPointer, ctrlAltPKeySequence);
302 actionCollectionPointer->setDefaultShortcut(userAgentWebEngineDefaultActionPointer, ctrlAltWKeySequence);
303 actionCollectionPointer->setDefaultShortcut(userAgentFirefoxLinuxActionPointer, ctrlAltFKeySequence);
304 actionCollectionPointer->setDefaultShortcut(userAgentChromiumLinuxActionPointer, ctrlAltCKeySequence);
305 actionCollectionPointer->setDefaultShortcut(userAgentFirefoxWindowsActionPointer, ctrlAltShiftFKeySequence);
306 actionCollectionPointer->setDefaultShortcut(userAgentChromeWindowsActionPointer, ctrlAltShiftCKeySequence);
307 actionCollectionPointer->setDefaultShortcut(userAgentEdgeWindowsActionPointer, ctrlAltEKeySequence);
308 actionCollectionPointer->setDefaultShortcut(userAgentSafariMacosActionPointer, ctrlAltSKeySequence);
309 actionCollectionPointer->setDefaultShortcut(userAgentCustomActionPointer, altShiftCKeySequence);
310 actionCollectionPointer->setDefaultShortcut(zoomFactorActionPointer, ctrlAltZKeySequence);
311 actionCollectionPointer->setDefaultShortcut(searchEngineMojeekActionPointer, ctrlShiftMKeySequence);
312 actionCollectionPointer->setDefaultShortcut(searchEngineMonoclesActionPointer, ctrlShiftOKeySequence);
313 actionCollectionPointer->setDefaultShortcut(searchEngineMetagerActionPointer, ctrlShiftEKeySequence);
314 actionCollectionPointer->setDefaultShortcut(searchEngineGoogleActionPointer, ctrlShiftGKeySequence);
315 actionCollectionPointer->setDefaultShortcut(searchEngineBingActionPointer, ctrlShiftBKeySequence);
316 actionCollectionPointer->setDefaultShortcut(searchEngineYahooActionPointer, ctrlShiftYKeySequence);
317 actionCollectionPointer->setDefaultShortcut(searchEngineCustomActionPointer, ctrlShiftCKeySequence);
318 actionCollectionPointer->setDefaultShortcut(editBookmarksActionPointer, ctrlAltShiftBKeySequence);
319 actionCollectionPointer->setDefaultShortcut(viewBookmarksToolBarActionPointer, ctrlAltBKeySequence);
320 actionCollectionPointer->setDefaultShortcut(domainSettingsActionPointer, ctrlShiftDKeySequence);
321 actionCollectionPointer->setDefaultShortcut(cookiesActionPointer, ctrlSemicolonKeySequence);
323 // Execute the actions.
324 connect(newTabActionPointer, SIGNAL(triggered()), tabWidgetPointer, SLOT(addTab()));
325 connect(newWindowActionPointer, SIGNAL(triggered()), this, SLOT(newWindow()));
326 connect(saveArchiveActionPointer, SIGNAL(triggered()), tabWidgetPointer, SLOT(saveArchive()));
327 connect(zoomDefaultActionPointer, SIGNAL(triggered()), this, SLOT(zoomDefault()));
328 connect(reloadAndBypassCacheActionPointer, SIGNAL(triggered()), this, SLOT(reloadAndBypassCache()));
329 connect(stopActionPointer, SIGNAL(triggered()), tabWidgetPointer, SLOT(stop()));
330 connect(viewSourceActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewSource()));
331 connect(viewSourceInNewTabActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewSourceInNewTab()));
332 connect(developerToolsActionPointer, SIGNAL(triggered()), this, SLOT(toggleDeveloperTools()));
333 connect(zoomFactorActionPointer, SIGNAL(triggered()), this, SLOT(getZoomFactorFromUser()));
334 connect(viewBookmarksToolBarActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewBookmarksToolBar()));
335 connect(cookiesActionPointer, SIGNAL(triggered()), this, SLOT(showCookiesDialog()));
336 connect(domainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(showDomainSettingsDialog()));
338 // Update the on-the-fly menus.
339 connect(tabWidgetPointer, SIGNAL(updateUserAgentActions(QString, bool)), this, SLOT(updateUserAgentActions(QString, bool)));
340 connect(tabWidgetPointer, SIGNAL(updateZoomActions(double)), this, SLOT(updateZoomActions(double)));
341 connect(tabWidgetPointer, SIGNAL(updateSearchEngineActions(QString, bool)), this, SLOT(updateSearchEngineActions(QString, bool)));
343 // Apply the on-the-fly settings when selected.
344 connect(userAgentActionGroupPointer, SIGNAL(triggered(QAction*)), tabWidgetPointer, SLOT(applyOnTheFlyUserAgent(QAction*)));
345 connect(searchEngineActionGroupPointer, SIGNAL(triggered(QAction*)), tabWidgetPointer, SLOT(applyOnTheFlySearchEngine(QAction*)));
347 // Process cookie changes.
348 connect(tabWidgetPointer, SIGNAL(updateCookiesAction(int)), this, SLOT(updateCookiesAction(int)));
350 // Store the default zoom factor.
351 connect(tabWidgetPointer, SIGNAL(updateDefaultZoomFactor(double)), this, SLOT(updateDefaultZoomFactor(double)));
353 // Connect the URL toolbar actions.
354 connect(javaScriptActionPointer, SIGNAL(triggered()), this, SLOT(toggleJavaScript()));
355 connect(localStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleLocalStorage()));
356 connect(domStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleDomStorage()));
358 // Update the actions from the tab widget.
359 connect(tabWidgetPointer, SIGNAL(updateDeveloperToolsAction(bool)), developerToolsActionPointer, SLOT(setChecked(bool)));
360 connect(tabWidgetPointer, SIGNAL(updateBackAction(bool)), backActionPointer, SLOT(setEnabled(bool)));
361 connect(tabWidgetPointer, SIGNAL(updateForwardAction(bool)), forwardActionPointer, SLOT(setEnabled(bool)));
362 connect(tabWidgetPointer, SIGNAL(updateJavaScriptAction(bool)), this, SLOT(updateJavaScriptAction(bool)));
363 connect(tabWidgetPointer, SIGNAL(updateLocalStorageAction(bool)), this, SLOT(updateLocalStorageAction(bool)));
364 connect(tabWidgetPointer, SIGNAL(updateDomStorageAction(bool)), this, SLOT(updateDomStorageAction(bool)));
366 // Connect the find text actions.
367 connect(findCaseSensitiveActionPointer, SIGNAL(triggered()), this, SLOT(toggleFindCaseSensitive()));
368 connect(hideFindTextActionPointer, SIGNAL(triggered()), this, SLOT(hideFindTextActions()));
372 // Setup the GUI based on the browserwindowui.rc file.
373 setupGUI(StandardWindowOption::Default, ("browserwindowui.rc"));
375 // Get lists of the actions' associated widgets.
376 QList<QWidget*> userAgentAssociatedWidgetsPointerList = userAgentPrivacyBrowserActionPointer->associatedWidgets();
377 QList<QWidget*> searchEngineAssociatedWidgetsPointerList = searchEngineMojeekActionPointer->associatedWidgets();
379 // Get the menu widget pointers. It is the second entry, after the main window.
380 QWidget *userAgentMenuWidgetPointer = userAgentAssociatedWidgetsPointerList[1];
381 QWidget *searchEngineMenuWidgetPointer = searchEngineAssociatedWidgetsPointerList[1];
383 // Get the menu pointers.
384 QMenu *userAgentMenuPointer = qobject_cast<QMenu*>(userAgentMenuWidgetPointer);
385 QMenu *searchEngineMenuPointer = qobject_cast<QMenu*>(searchEngineMenuWidgetPointer);
387 // Get the menu actions.
388 userAgentMenuActionPointer = userAgentMenuPointer->menuAction();
389 searchEngineMenuActionPointer = searchEngineMenuPointer->menuAction();
391 // Get handles for the toolbars.
392 navigationToolBarPointer = toolBar(QLatin1String("navigation_toolbar"));
393 urlToolBarPointer = toolBar(QLatin1String("url_toolbar"));
394 bookmarksToolBarPointer = toolBar(QLatin1String("bookmarks_toolbar"));
396 // Populate the view bookmarks toolbar checkbox.
397 connect(bookmarksToolBarPointer, SIGNAL(visibilityChanged(bool)), this, SLOT(updateViewBookmarksToolBarCheckbox(bool)));
399 // Create the line edits.
400 urlLineEditPointer = new KLineEdit();
401 findTextLineEditPointer = new KLineEdit();
403 // Get the line edit size policies.
404 QSizePolicy urlLineEditSizePolicy = urlLineEditPointer->sizePolicy();
405 QSizePolicy findTextLineEditSizePolicy = findTextLineEditPointer->sizePolicy();
407 // Set the URL line edit horizontal stretch to be five times the find text line edit stretch.
408 urlLineEditSizePolicy.setHorizontalStretch(5);
409 findTextLineEditSizePolicy.setHorizontalStretch(1);
412 urlLineEditPointer->setSizePolicy(urlLineEditSizePolicy);
413 findTextLineEditPointer->setSizePolicy(findTextLineEditSizePolicy);
416 urlLineEditPointer->setMinimumWidth(350);
417 findTextLineEditPointer->setMinimumWidth(200);
418 findTextLineEditPointer->setMaximumWidth(350);
420 // Set the place holder text.
421 urlLineEditPointer->setPlaceholderText(i18nc("The URL line edit placeholder text", "URL or Search Terms"));
422 findTextLineEditPointer->setPlaceholderText(i18nc("The find line edit placeholder text", "Find Text"));
424 // Show the clear button on the find line edit.
425 findTextLineEditPointer->setClearButtonEnabled(true);
427 // Add the actions to the URL line edit.
428 bookmarkedActionPointer = urlLineEditPointer->addAction(QIcon::fromTheme("non-starred-symbolic"), QLineEdit::LeadingPosition);
429 QAction *addOrEditDomainSettingsActionPointer = urlLineEditPointer->addAction(QIcon::fromTheme("settings-configure", QIcon::fromTheme(QLatin1String("preferences-desktop"))),
430 QLineEdit::TrailingPosition);
432 // Set the bookmarked action pointer to be checkable.
433 bookmarkedActionPointer->setCheckable(true);
435 // Connect the URL line edit actions.
436 connect(bookmarkedActionPointer, SIGNAL(triggered()), this, SLOT(toggleBookmark()));
437 connect(addOrEditDomainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(addOrEditDomainSettings()));
439 // Create a find text label pointer.
440 findTextLabelPointer = new QLabel();
442 // Set the default label text.
443 findTextLabelPointer->setText(QLatin1String(" ") + i18nc("Default find results.", "0/0") + QLatin1String(" "));
445 // Insert the widgets into the toolbars.
446 urlToolBarPointer->insertWidget(javaScriptActionPointer, urlLineEditPointer);
447 findTextLineEditActionPointer = urlToolBarPointer->insertWidget(findNextActionPointer, findTextLineEditPointer);
448 findTextLabelActionPointer = urlToolBarPointer->insertWidget(findNextActionPointer, findTextLabelPointer);
450 // Initially hide the find text actions.
451 hideFindTextActions();
453 // Load a new URL from the URL line edit.
454 connect(urlLineEditPointer, SIGNAL(returnKeyPressed(const QString)), this, SLOT(loadUrlFromLineEdit(const QString)));
456 // Find text as it is typed.
457 connect(findTextLineEditPointer, SIGNAL(textEdited(const QString &)), tabWidgetPointer, SLOT(findText(const QString &)));
459 // Find next if the enter key is pressed.
460 connect(findTextLineEditPointer, SIGNAL(returnKeyPressed(const QString &)), tabWidgetPointer, SLOT(findText(const QString &)));
462 // Update find text when switching tabs.
463 connect(tabWidgetPointer, SIGNAL(updateFindText(const QString &, const bool)), this, SLOT(updateFindText(const QString &, const bool)));
465 // Update the find text results.
466 connect(tabWidgetPointer, SIGNAL(updateFindTextResults(const QWebEngineFindTextResult &)), this, SLOT(updateFindTextResults(const QWebEngineFindTextResult &)));
468 // Update the URL line edit on page loads.
469 connect(tabWidgetPointer, SIGNAL(updateUrlLineEdit(QUrl)), this, SLOT(updateUrlLineEdit(QUrl)));
471 // Update the window title.
472 connect(tabWidgetPointer, SIGNAL(updateWindowTitle(const QString)), this, SLOT(updateWindowTitle(const QString)));
474 // Get a handle for the status bar.
475 QStatusBar *statusBarPointer = statusBar();
477 // Create the status bar widgets.
478 progressBarPointer = new QProgressBar();
479 zoomMinusButtonPointer = new QPushButton();
480 currentZoomButtonPointer = new QPushButton();
481 zoomPlusButtonPointer = new QPushButton();
483 // Set the button icons.
484 zoomMinusButtonPointer->setIcon(QIcon::fromTheme(QStringLiteral("list-remove-symbolic")));
485 zoomPlusButtonPointer->setIcon(QIcon::fromTheme(QStringLiteral("list-add-symbolic")));
487 // Set the button icons to be flat (no borders).
488 zoomMinusButtonPointer->setFlat(true);
489 currentZoomButtonPointer->setFlat(true);
490 zoomPlusButtonPointer->setFlat(true);
492 // Handle clicks on the zoom buttons.
493 connect(zoomMinusButtonPointer, SIGNAL(clicked()), this, SLOT(decrementZoom()));
494 connect(currentZoomButtonPointer, SIGNAL(clicked()), this, SLOT(getZoomFactorFromUser()));
495 connect(zoomPlusButtonPointer, SIGNAL(clicked()), this, SLOT(incrementZoom()));
497 // Remove the padding around the current zoom button text.
498 currentZoomButtonPointer->setStyleSheet("padding: 0px;");
500 // Add the widgets to the far right of the status bar.
501 statusBarPointer->addPermanentWidget(progressBarPointer);
502 statusBarPointer->addPermanentWidget(zoomMinusButtonPointer);
503 statusBarPointer->addPermanentWidget(currentZoomButtonPointer);
504 statusBarPointer->addPermanentWidget(zoomPlusButtonPointer);
506 // Update the status bar with the URL when a link is hovered.
507 connect(tabWidgetPointer, SIGNAL(linkHovered(QString)), statusBarPointer, SLOT(showMessage(QString)));
509 // Update the progress bar.
510 connect(tabWidgetPointer, SIGNAL(showProgressBar(const int)), this, SLOT(showProgressBar(const int)));
511 connect(tabWidgetPointer, SIGNAL(hideProgressBar()), this, SLOT(hideProgressBar()));
513 // Update the URL line edit focus.
514 connect(tabWidgetPointer, SIGNAL(clearUrlLineEditFocus()), this, SLOT(clearUrlLineEditFocus()));
516 // Get the URL line edit palettes.
517 normalBackgroundPalette = urlLineEditPointer->palette();
518 negativeBackgroundPalette = normalBackgroundPalette;
519 positiveBackgroundPalette = normalBackgroundPalette;
521 // Modify the palettes.
522 KColorScheme::adjustBackground(negativeBackgroundPalette, KColorScheme::NegativeBackground);
523 KColorScheme::adjustBackground(positiveBackgroundPalette, KColorScheme::PositiveBackground);
525 // Update the applied palette.
526 connect(tabWidgetPointer, SIGNAL(updateDomainSettingsIndicator(const bool)), this, SLOT(updateDomainSettingsIndicator(const bool)));
528 // Process full screen requests.
529 connect(tabWidgetPointer, SIGNAL(fullScreenRequested(bool)), this, SLOT(fullScreenRequested(bool)));
531 // Create keyboard shortcuts.
532 QShortcut *f11ShortcutPointer = new QShortcut(QKeySequence(i18nc("The toggle full screen shortcut.", "F11")), this);
533 QShortcut *escapeShortcutPointer = new QShortcut(QKeySequence::Cancel, this);
535 // Connect the keyboard shortcuts.
536 connect(f11ShortcutPointer, SIGNAL(activated()), fullScreenActionPointer, SLOT(trigger()));
537 connect(escapeShortcutPointer, SIGNAL(activated()), this, SLOT(escape()));
539 // Get a handle for the Bookmarks menu.
540 bookmarksMenuPointer = qobject_cast<QMenu*>(guiFactory()->container("bookmarks", this));
542 // Add a separator to the bookmarks menu.
543 bookmarksMenuPointer->addSeparator();
545 // Initialize the current bookmarks lists.
546 finalBookmarkFolderMenuActionList = QList<QPair<QMenu *, QAction *> *>();
547 bookmarksMenuActionList = QList<QPair<QMenu *, QAction *> *>();
548 bookmarksMenuSubmenuList = QList<QPair<QMenu *, QMenu *> *>();
549 bookmarksToolBarActionList = QList<QAction*>();
550 bookmarksToolBarSubfolderActionList = QList<QPair<QMenu *, QAction * > *>();
552 // Set the bookmarks toolbar context menu policy.
553 bookmarksToolBarPointer->setContextMenuPolicy(Qt::CustomContextMenu);
555 // Show the custom bookmark context menu when requested.
556 connect(bookmarksToolBarPointer, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showBookmarkContextMenu(const QPoint&)));
558 // Populate the bookmarks in this window.
559 populateBookmarksInThisWindow();
562 // 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.
563 updateJavaScriptAction(Settings::javaScriptEnabled());
564 updateLocalStorageAction(Settings::localStorageEnabled());
565 updateDomStorageAction(Settings::domStorageEnabled());
566 updateUserAgentActions(UserAgentHelper::getUserAgentFromDatabaseName(Settings::userAgent()), true);
567 updateZoomActions(Settings::zoomFactor());
569 // Populate the first tab.
570 if (firstWindow) // This is the first window.
572 // Load the initial website.
573 tabWidgetPointer->loadInitialWebsite();
575 else if (initialUrlStringPointer) // An initial URL was specified.
577 // Load the initial URL.
578 tabWidgetPointer->loadUrlFromLineEdit(*initialUrlStringPointer);
582 void BrowserWindow::addFinalBookmarkFolderMenuActions(QMenu *menuPointer, double folderId)
584 // Get the database ID.
585 int folderDatabaseId = BookmarksDatabase::getFolderDatabaseId(folderId);
588 menuPointer->addSeparator();
590 // Add the add bookmark action to the menu.
591 QAction *addBookmarkActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("bookmark-new")), i18nc("The add bookmark action", "Add Bookmark"), [=]
593 // Instantiate an add bookmark dialog.
594 AddBookmarkDialog *addBookmarkDialogPointer = new AddBookmarkDialog(tabWidgetPointer->getCurrentTabTitle(), tabWidgetPointer->getCurrentTabUrl(),
595 tabWidgetPointer->getCurrentTabFavoritIcon(), folderId);
597 // Update the displayed bookmarks when a new one is added.
598 connect(addBookmarkDialogPointer, SIGNAL(bookmarkAdded()), this, SLOT(populateBookmarksInAllWindows()));
601 addBookmarkDialogPointer->show();
605 // Add the add folder action to the menu.
606 QAction *addFolderActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("folder-add")), i18nc("The add folder action", "Add Folder"), [=]
608 // Instantiate an add folder dialog.
609 AddFolderDialog *addFolderDialogPointer = new AddFolderDialog(tabWidgetPointer->getCurrentTabFavoritIcon(), folderId);
611 // Update the displayed bookmarks when a folder is added.
612 connect(addFolderDialogPointer, SIGNAL(folderAdded()), this, SLOT(populateBookmarksInAllWindows()));
615 addFolderDialogPointer->show();
620 menuPointer->addSeparator();
622 // Add the open folder in new tabs action to the menu.
623 QAction *openFolderInNewTabsActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("The open folder in new tabs action", "Open Folder in New Tabs"), [=]
625 // Get all the folder URLs.
626 QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(folderId);
628 // Open the URLs in new tabs. `true` removes the URL line edit focus, `false` does not load a background tab.
629 for (QString url : *folderUrlsListPointer)
630 tabWidgetPointer->addTab(true, false, url);
634 // Add the open folder in background tabs action to the menu.
635 QAction *openFolderInBackgroundTabsActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")),
636 i18nc("The open folder in background tabs action", "Open Folder in Background Tabs"), [=]
638 // Get all the folder URLs.
639 QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(folderId);
641 // Open the URLs in new tabs. `true` removes the URL line edit focus, `true` loads a background tab.
642 for (QString url : *folderUrlsListPointer)
643 tabWidgetPointer->addTab(true, true, url);
647 // Add the open folder in new window action to the menu.
648 QAction *openFolderInNewWindowActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("window-new")), i18nc("The open folder in new window action", "Open Folder in New Window"), [=]
650 // Get all the folder URLs.
651 QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(folderId);
653 // Create a new browser window.
654 BrowserWindow *browserWindowPointer = new BrowserWindow(false, &folderUrlsListPointer->first());
656 // Get a count of the folder URLs.
657 const int folderUrls = folderUrlsListPointer->count();
659 // Load all the other URLs. `true` removes the URL line edit focus, `true` loads a background tab.
660 for (int i = 1; i < folderUrls; ++i)
661 browserWindowPointer->tabWidgetPointer->addTab(true, true, folderUrlsListPointer->value(i));
663 // Show the new browser window.
664 browserWindowPointer->show();
669 menuPointer->addSeparator();
671 // Add the edit folder action to the menu if this is not the root bookmark menu.
674 QAction *editFolderActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("document-edit")), i18nc("The edit folder action", "Edit Folder"), [=]
676 // Get the current tab favorite icon.
677 QIcon currentTabFavoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
679 // Instantiate an edit folder dialog.
680 QDialog *editFolderDialogPointer = new EditFolderDialog(folderDatabaseId, currentTabFavoriteIcon);
683 editFolderDialogPointer->show();
685 // Process bookmark events.
686 connect(editFolderDialogPointer, SIGNAL(folderSaved()), this, SLOT(populateBookmarksInAllWindows()));
690 // Add the action to the beginning of the final bookmark folder menu action list.
691 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, editFolderActionPointer));
694 // Add the delete folder action to the menu.
695 QAction *deleteFolderActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-delete")), i18nc("Delete folder context menu entry", "Delete Folder"), [=]
697 // Create an items to delete list.
698 QList<int>* itemsToDeleteListPointer = new QList<int>;
700 // Add the folder to the list of items to delete if it is not the root folder.
702 itemsToDeleteListPointer->append(folderDatabaseId);
704 // Add the folder contents to the list of items to delete.
705 itemsToDeleteListPointer->append(*BookmarksDatabase::getFolderContentsDatabaseIdsRecursively(folderId));
707 // Instantiate a delete dialog message box.
708 QMessageBox deleteDialogMessageBox;
711 deleteDialogMessageBox.setIcon(QMessageBox::Warning);
713 // Set the window title.
714 deleteDialogMessageBox.setWindowTitle(i18nc("Delete bookmarks dialog title", "Delete Bookmarks"));
717 deleteDialogMessageBox.setText(i18ncp("Delete bookmarks dialog main message", "Delete %1 bookmark item?", "Delete %1 bookmark items?", itemsToDeleteListPointer->count()));
719 // Set the informative text.
720 deleteDialogMessageBox.setInformativeText(i18nc("Delete bookmarks dialog secondary message", "This cannot be undone."));
722 // Set the standard buttons.
723 deleteDialogMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
725 // Set the default button.
726 deleteDialogMessageBox.setDefaultButton(QMessageBox::No);
728 // Display the dialog and capture the return value.
729 int returnValue = deleteDialogMessageBox.exec();
731 // Delete the domain if instructed.
732 if (returnValue == QMessageBox::Yes)
734 // Get the parent folder ID.
735 double parentFolderId = BookmarksDatabase::getParentFolderId(folderDatabaseId);
737 // Delete the folder and its contents.
738 for (const int databaseId : *itemsToDeleteListPointer)
739 BookmarksDatabase::deleteBookmark(databaseId);
741 // Update the display order of the bookmarks in the parent folder.
742 BookmarksDatabase::updateFolderContentsDisplayOrder(parentFolderId);
744 // Repopulate the bookmarks.
745 populateBookmarksInAllWindows();
750 // Add the key sequences if this is the root bookmarks menu.
753 // Create the key sequences.
754 QKeySequence ctrlBKeySequence = QKeySequence(i18nc("The add bookmark key sequence.", "Ctrl+B"));
755 QKeySequence metaFKeySequence = QKeySequence(i18nc("The add folder key sequence.", "Meta+F"));
757 // Set the action key sequences.
758 actionCollectionPointer->setDefaultShortcut(addBookmarkActionPointer, ctrlBKeySequence);
759 actionCollectionPointer->setDefaultShortcut(addFolderActionPointer, metaFKeySequence);
762 // Add the actions to the beginning of the final bookmark folder menu action list.
763 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, addBookmarkActionPointer));
764 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, addFolderActionPointer));
765 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, openFolderInNewTabsActionPointer));
766 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, openFolderInBackgroundTabsActionPointer));
767 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, openFolderInNewWindowActionPointer));
768 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, deleteFolderActionPointer));
771 void BrowserWindow::addOrEditDomainSettings() const
773 // Remove the focus from the URL line edit.
774 urlLineEditPointer->clearFocus();
776 // Create the domain settings dialog pointer.
777 DomainSettingsDialog *domainSettingsDialogPointer;
779 // Get the current domain settings name.
780 QString ¤tDomainSettingsName = tabWidgetPointer->getDomainSettingsName();
782 // Run the commands according to the current domain settings status.
783 if (currentDomainSettingsName == QStringLiteral("")) // Domain settings are not currently applied.
785 // Instruct the domain settings dialog to add a new domain.
786 domainSettingsDialogPointer = new DomainSettingsDialog(DomainSettingsDialog::ADD_DOMAIN, currentUrl.host());
788 else // Domain settings are currently applied.
790 // Instruct the domain settings dialog to edit the current domain.
791 domainSettingsDialogPointer = new DomainSettingsDialog(DomainSettingsDialog::EDIT_DOMAIN, currentDomainSettingsName);
794 // Reload the tabs when domain settings are updated.
795 connect(domainSettingsDialogPointer, SIGNAL(domainSettingsUpdated()), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
798 domainSettingsDialogPointer->show();
801 void BrowserWindow::back() const
803 // Remove the focus from the URL line edit.
804 urlLineEditPointer->clearFocus();
807 tabWidgetPointer->back();
810 void BrowserWindow::clearUrlLineEditFocus() const
812 // Remove the focus from the URL line edit.
813 urlLineEditPointer->clearFocus();
816 void BrowserWindow::decrementZoom()
818 // Update the current zoom factor.
819 currentZoomFactor = currentZoomFactor - 0.25;
821 // Check to make sure the zoom factor is in the valid range (0.25 to 5.00).
822 if (currentZoomFactor < 0.25)
823 currentZoomFactor = 0.25;
825 // Set the new zoom factor.
826 tabWidgetPointer->applyOnTheFlyZoomFactor(currentZoomFactor);
828 // Update the on-the-fly action text.
829 updateZoomActions(currentZoomFactor);
832 void BrowserWindow::editBookmarks() const
834 // Instantiate an edit bookmarks dialog.
835 BookmarksDialog *bookmarksDialogPointer = new BookmarksDialog(tabWidgetPointer->getCurrentTabTitle(), tabWidgetPointer->getCurrentTabUrl(), tabWidgetPointer->getCurrentTabFavoritIcon());
837 // Update the displayed bookmarks when edited.
838 connect(bookmarksDialogPointer, SIGNAL(bookmarkUpdated()), this, SLOT(populateBookmarksInAllWindows()));
841 bookmarksDialogPointer->show();
844 void BrowserWindow::escape() const
846 // Process the escape according to the status of the browser.
847 if (fullScreenActionPointer->isChecked()) // Full screen browsing is enabled.
849 // Exit full screen browsing.
850 fullScreenActionPointer->trigger();
852 else if (!findTextLineEditPointer->text().isEmpty()) // Find text is populated.
854 // Clear the find text line edit.
855 findTextLineEditPointer->clear();
857 // Clear the search in the WebEngine.
858 tabWidgetPointer->findText(QStringLiteral(""));
860 else if (findTextLineEditActionPointer->isVisible()) // Find text actions are visible.
862 // Hide the find text actions.
863 hideFindTextActions();
867 void BrowserWindow::findNext() const
869 // Get the find string.
870 const QString findString = findTextLineEditPointer->text();
872 // Search for the text if it is not empty.
873 if (!findString.isEmpty())
874 tabWidgetPointer->findText(findString);
877 void BrowserWindow::findPrevious() const
879 // Get the find string.
880 const QString findString = findTextLineEditPointer->text();
882 // Search for the text if it is not empty.
883 if (!findString.isEmpty())
884 tabWidgetPointer->findPrevious(findString);
887 void BrowserWindow::forward() const
889 // Remove the focus from the URL line edit.
890 urlLineEditPointer->clearFocus();
893 tabWidgetPointer->forward();
896 void BrowserWindow::fullScreenRequested(const bool toggleOn)
898 // Toggle full screen mode.
899 if (toggleOn) // Turn full screen mode on.
901 // Enable full screen mode.
902 fullScreenActionPointer->setFullScreen(window(), true);
904 // Hide the menu bar if specified.
905 if (Settings::fullScreenHideMenuBar())
906 menuBar()->setVisible(false);
908 // Hide the toolbars if specified.
909 if (Settings::fullScreenHideToolBars())
911 navigationToolBarPointer->setVisible(false);
912 urlToolBarPointer->setVisible(false);
913 bookmarksToolBarPointer->setVisible(false);
916 // Hide the tab bar if specified.
917 if (Settings::fullScreenHideTabBar())
918 tabWidgetPointer->setTabBarVisible(false);
920 // Hide the status bar if specified.
921 if (Settings::fullScreenHideStatusBar())
922 statusBar()->setVisible(false);
924 else // Disable full screen browsing mode.
926 // Disable full screen mode.
927 fullScreenActionPointer->setFullScreen(window(), false);
929 // Show the menu bar.
930 menuBar()->setVisible(true);
932 // Show the toolbars.
933 navigationToolBarPointer->setVisible(true);
934 urlToolBarPointer->setVisible(true);
936 // Only show the bookmarks toolbar if it was previously visible.
937 if (bookmarksToolBarIsVisible)
938 bookmarksToolBarPointer->setVisible(true);
941 tabWidgetPointer->setTabBarVisible(true);
943 // Show the status bar.
944 statusBar()->setVisible(true);
948 void BrowserWindow::getZoomFactorFromUser()
950 // Create an OK flag.
953 // 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.
954 double newZoomFactor = QInputDialog::getDouble(this, i18nc("The on-the-fly zoom factor dialog title", "On-The-Fly Zoom Factor"),
955 i18nc("The instruction text of the on-the-fly zoom factor dialog", "Enter a zoom factor between 0.25 and 5.00"),
956 currentZoomFactor, .025, 5.00, 2, &okClicked, Qt::WindowFlags(), 0.25);
958 // Update the zoom factor if the user clicked OK.
961 // Set the new zoom factor.
962 tabWidgetPointer->applyOnTheFlyZoomFactor(newZoomFactor);
964 // Update the on-the-fly action text.
965 updateZoomActions(newZoomFactor);
969 void BrowserWindow::hideFindTextActions() const
971 // Hide the find text actions.
972 findTextLineEditActionPointer->setVisible(false);
973 findTextLabelActionPointer->setVisible(false);
974 findNextActionPointer->setVisible(false);
975 findPreviousActionPointer->setVisible(false);
976 findCaseSensitiveActionPointer->setVisible(false);
977 hideFindTextActionPointer->setVisible(false);
980 void BrowserWindow::home() const
982 // Remove the focus from the URL line edit.
983 urlLineEditPointer->clearFocus();
986 tabWidgetPointer->home();
989 void BrowserWindow::hideProgressBar() const
991 // Hide the progress bar.
992 progressBarPointer->hide();
994 // Disable and hide the stop action.
995 stopActionPointer->setEnabled(false);
996 stopActionPointer->setVisible(false);
998 // Enable and show the refresh action.
999 refreshActionPointer->setEnabled(true);
1000 refreshActionPointer->setVisible(true);
1003 void BrowserWindow::incrementZoom()
1005 // Update the current zoom factor.
1006 currentZoomFactor = currentZoomFactor + 0.25;
1008 // Check to make sure the zoom factor is in the valid range (0.25 to 5.00).
1009 if (currentZoomFactor > 5.0)
1010 currentZoomFactor = 5.0;
1012 // Set the new zoom factor.
1013 tabWidgetPointer->applyOnTheFlyZoomFactor(currentZoomFactor);
1015 // Update the on-the-fly action text.
1016 updateZoomActions(currentZoomFactor);
1019 void BrowserWindow::loadUrlFromLineEdit(const QString &url) const
1021 // Remove the focus from the URL line edit.
1022 urlLineEditPointer->clearFocus();
1025 tabWidgetPointer->loadUrlFromLineEdit(url);
1028 void BrowserWindow::newWindow() const
1030 // Create a new browser window.
1031 BrowserWindow *browserWindowPointer = new BrowserWindow();
1033 // Show the new browser window.
1034 browserWindowPointer->show();
1037 void BrowserWindow::populateBookmarksInAllWindows() const
1039 // Get a list of all the registered service names.
1040 QStringList registeredServiceNames = QDBusConnection::sessionBus().interface()->registeredServiceNames().value();
1042 // Get a list of all the Privacy Browser windows, which will be `com.stoutner.privacybrowser-` with the PID appended.
1043 QStringList privacyBrowserServiceNames = registeredServiceNames.filter("com.stoutner.privacybrowser");
1045 // Repopulate the bookmarks in each window.
1046 for (QString privacyBrowserServiceName : privacyBrowserServiceNames)
1048 // Prepare the D-Bus message.
1049 QDBusMessage dBusMessage = QDBusMessage::createMethodCall(privacyBrowserServiceName, "/privacybrowser/MainWindow_1", "com.stoutner.privacybrowser.BrowserWindow", "populateBookmarksInThisWindow");
1052 QDBusConnection::sessionBus().send(dBusMessage);
1056 void BrowserWindow::populateBookmarksInThisWindow()
1058 // Remove all the final bookmark folder menu actions.
1059 for (QPair<QMenu *, QAction *> *finalBookmarkFolderMenuActionPair : finalBookmarkFolderMenuActionList)
1061 // Remove the action.
1062 finalBookmarkFolderMenuActionPair->first->removeAction(finalBookmarkFolderMenuActionPair->second);
1065 // Remove all the current menu bookmarks.
1066 for (QPair<QMenu *, QAction *> *bookmarkMenuActionPairPointer : bookmarksMenuActionList)
1068 // Remove the bookmark.
1069 bookmarkMenuActionPairPointer->first->removeAction(bookmarkMenuActionPairPointer->second);
1072 // Remove all the current menu subfolders.
1073 for (QPair<QMenu *, QMenu *> *submenuPairPointer : bookmarksMenuSubmenuList)
1075 // Remove the submenu from the parent menu.
1076 submenuPairPointer->first->removeAction(submenuPairPointer->second->menuAction());
1079 // Remove all the current toolbar subfolders.
1080 for (QPair<QMenu *, QAction *> *subfolderActionPairPointer : bookmarksToolBarSubfolderActionList)
1082 // Remove the action from the subfolder.
1083 subfolderActionPairPointer->first->removeAction(subfolderActionPairPointer->second);
1086 // Remove all the current toolbar bookmarks.
1087 for (QAction *bookmarkAction : bookmarksToolBarActionList)
1089 // Remove the bookmark.
1090 bookmarksToolBarPointer->removeAction(bookmarkAction);
1093 // Clear the current bookmark lists.
1094 bookmarksMenuActionList.clear();
1095 bookmarksMenuSubmenuList.clear();
1096 bookmarksToolBarActionList.clear();
1097 bookmarksToolBarSubfolderActionList.clear();
1099 // Populate the bookmarks subfolders, beginning with the root folder (`0`);
1100 populateBookmarksMenuSubfolders(0, bookmarksMenuPointer);
1102 // Populate the bookmarks toolbar.
1103 populateBookmarksToolBar();
1105 // Get a handle for the bookmark toolbar layout.
1106 QLayout *bookmarksToolBarLayoutPointer = bookmarksToolBarPointer->layout();
1108 // Get the count of the bookmarks.
1109 int bookmarkCount = bookmarksToolBarLayoutPointer->count();
1111 // Set the layout of each bookmark to be left aligned.
1112 for(int i = 0; i < bookmarkCount; ++i)
1113 bookmarksToolBarLayoutPointer->itemAt(i)->setAlignment(Qt::AlignLeft);
1115 // Update the bookmarked action.
1116 updateBookmarkedAction();
1119 void BrowserWindow::populateBookmarksMenuSubfolders(const double folderId, QMenu *menuPointer)
1121 // Get the folder contents.
1122 QList<BookmarkStruct> *folderContentsListPointer = BookmarksDatabase::getFolderContents(folderId);
1124 // Populate the bookmarks menu and toolbar.
1125 for (BookmarkStruct bookmarkStruct : *folderContentsListPointer)
1127 // Process the item according to the type.
1128 if (bookmarkStruct.isFolder) // This item is a folder.
1130 // Add a submenu to the menu.
1131 QMenu *submenuPointer = menuPointer->addMenu(bookmarkStruct.favoriteIcon, bookmarkStruct.name);
1133 // Add the submenu to the beginning of the list of menus to be deleted on repopulate.
1134 bookmarksMenuSubmenuList.prepend(new QPair<QMenu *, QMenu *>(menuPointer, submenuPointer));
1136 // Populate any subfolders.
1137 populateBookmarksMenuSubfolders(bookmarkStruct.folderId, submenuPointer);
1139 else // This item is a bookmark.
1141 // Add the bookmark to the menu.
1142 QAction *menuBookmarkActionPointer = menuPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name, [=]
1144 // Remove the focus from the URL line edit.
1145 urlLineEditPointer->clearFocus();
1148 tabWidgetPointer->loadUrlFromLineEdit(bookmarkStruct.url);
1152 // Add the actions to the beginning of the list of bookmarks to be deleted on repopulate.
1153 bookmarksMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, menuBookmarkActionPointer));
1157 // Add the extra items at the bottom of the menu.
1158 addFinalBookmarkFolderMenuActions(menuPointer, folderId);
1161 void BrowserWindow::populateBookmarksToolBar()
1163 // Get the root folder contents (which has a folder ID of `0`).
1164 QList<BookmarkStruct> *folderContentsListPointer = BookmarksDatabase::getFolderContents(0);
1166 // Populate the bookmarks toolbar.
1167 for (BookmarkStruct bookmarkStruct : *folderContentsListPointer)
1169 // Process the item according to the type.
1170 if (bookmarkStruct.isFolder) // This item is a folder.
1172 // Add the subfolder action.
1173 QAction *toolBarSubfolderActionPointer = bookmarksToolBarPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name);
1175 // Add the bookmark database ID to the toolbar action.
1176 toolBarSubfolderActionPointer->setData(bookmarkStruct.databaseId);
1178 // Add the action to the beginning of the list of actions to be deleted on repopulate.
1179 bookmarksToolBarActionList.prepend(toolBarSubfolderActionPointer);
1181 // Create a subfolder menu.
1182 QMenu *subfolderMenuPointer = new QMenu();
1184 // Add the menu to the action.
1185 toolBarSubfolderActionPointer->setMenu(subfolderMenuPointer);
1187 // Add the submenu to the toolbar menu list.
1188 bookmarksToolBarMenuList.append(new QPair<QMenu *, const double>(subfolderMenuPointer, bookmarkStruct.folderId));
1190 // Set the popup mode for the menu.
1191 dynamic_cast<QToolButton *>(bookmarksToolBarPointer->widgetForAction(toolBarSubfolderActionPointer))->setPopupMode(QToolButton::InstantPopup);
1193 // Populate the subfolder.
1194 populateBookmarksToolBarSubfolders(bookmarkStruct.folderId, subfolderMenuPointer);
1196 else // This item is a bookmark.
1198 // Add the bookmark to the toolbar.
1199 QAction *toolBarBookmarkActionPointer = bookmarksToolBarPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name, [=]
1201 // Remove the focus from the URL line edit.
1202 urlLineEditPointer->clearFocus();
1205 tabWidgetPointer->loadUrlFromLineEdit(bookmarkStruct.url);
1209 // Add the bookmark database ID to the toolbar action.
1210 toolBarBookmarkActionPointer->setData(bookmarkStruct.databaseId);
1212 // Add the actions to the beginning of the current bookmarks lists.
1213 bookmarksToolBarActionList.prepend(toolBarBookmarkActionPointer);
1217 // Add the extra items to the toolbar folder menus. The first item in the pair is the menu pointer. The second is the folder ID.
1218 for (QPair<QMenu *, const double> *menuAndFolderIdPairPointer : bookmarksToolBarMenuList)
1220 // Populate the final bookmarks menu entries.
1221 addFinalBookmarkFolderMenuActions(menuAndFolderIdPairPointer->first, menuAndFolderIdPairPointer->second);
1225 void BrowserWindow::populateBookmarksToolBarSubfolders(const double folderId, QMenu *menuPointer)
1227 // Get the folder contents.
1228 QList<BookmarkStruct> *folderContentsListPointer = BookmarksDatabase::getFolderContents(folderId);
1230 // Populate the bookmarks folder.
1231 for (BookmarkStruct bookmarkStruct : *folderContentsListPointer)
1233 // Get the bookmark URL.
1234 QString bookmarkUrl = bookmarkStruct.url;
1236 // Process the item according to the type.
1237 if (bookmarkStruct.isFolder) // This item is a folder.
1239 // Add the subfolder action.
1240 QAction *toolBarSubfolderActionPointer = menuPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name);
1242 // Add the action to the beginning of the list of actions to be deleted on repopulate.
1243 bookmarksToolBarSubfolderActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, toolBarSubfolderActionPointer));
1245 // Create a subfolder menu.
1246 QMenu *subfolderMenuPointer = new QMenu();
1248 // Add the submenu to the action.
1249 toolBarSubfolderActionPointer->setMenu(subfolderMenuPointer);
1251 // Add the submenu to the toolbar menu list.
1252 bookmarksToolBarMenuList.append(new QPair<QMenu *, const double>(subfolderMenuPointer, bookmarkStruct.folderId));
1254 // Populate the subfolder menu.
1255 populateBookmarksToolBarSubfolders(bookmarkStruct.folderId, subfolderMenuPointer);
1257 else // This item is a bookmark.
1259 // Add the bookmark to the folder.
1260 QAction *toolBarBookmarkActionPointer = menuPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name, [=]
1262 // Remove the focus from the URL line edit.
1263 urlLineEditPointer->clearFocus();
1266 tabWidgetPointer->loadUrlFromLineEdit(bookmarkUrl);
1270 // Add the bookmark database ID to the toolbar action.
1271 toolBarBookmarkActionPointer->setData(bookmarkStruct.databaseId);
1273 // Add the action to the beginning of the list of actions to be deleted on repopulate.
1274 bookmarksToolBarSubfolderActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, toolBarBookmarkActionPointer));
1279 void BrowserWindow::refresh() const
1281 // Remove the focus from the URL line edit.
1282 urlLineEditPointer->clearFocus();
1284 // Refresh the web page.
1285 tabWidgetPointer->refresh();
1288 void BrowserWindow::reloadAndBypassCache() const
1290 // Remove the focus from the URL line edit.
1291 urlLineEditPointer->clearFocus();
1293 // Refresh the web page.
1294 tabWidgetPointer->refresh();
1297 void BrowserWindow::showBookmarkContextMenu(const QPoint &point)
1299 // Get the bookmark action.
1300 QAction *bookmarkActionPointer = bookmarksToolBarPointer->actionAt(point);
1302 // Check to see if an action was clicked.
1303 if (bookmarkActionPointer) // An action was clicked.
1305 // Create a bookmark context menu.
1306 QMenu *bookmarkContextMenuPointer = new QMenu();
1308 // Get the database ID from the action.
1309 int databaseId = bookmarkActionPointer->data().toInt();
1311 // Create the menu according to the type.
1312 if (BookmarksDatabase::isFolder(databaseId)) // A folder was clicked.
1314 // Populate the final bookmarks menu entries.
1315 addFinalBookmarkFolderMenuActions(bookmarkContextMenuPointer, BookmarksDatabase::getFolderId(databaseId));
1317 else // A bookmark was clicked.
1319 // Add the open in new tab action to the menu.
1320 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("Open bookmark in new tab context menu entry", "Open in New Tab"), [=]
1322 // Get the bookmark.
1323 BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
1325 // Open the bookmark in a new tab. `true` removes the URL line edit focus, `false` does not load a background tab.
1326 tabWidgetPointer->addTab(true, false, bookmarkStructPointer->url);
1330 // Add the open in background tab action to the menu.
1331 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("Open bookmark in background tab context menu entry", "Open in Background Tab"), [=]
1333 // Get the bookmark.
1334 BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
1336 // Open the bookmark in a new tab. `true` removes the URL line edit focus, `true` loads a background tab.
1337 tabWidgetPointer->addTab(true, true, bookmarkStructPointer->url);
1341 // Add the open in new window action to the menu.
1342 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("window-new")), i18nc("Open bookmark in new window context menu entry", "Open in New Window"), [=]
1344 // Get the bookmark.
1345 BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
1347 // Create a new browser window and load the first URL. `false` indicates it is not the first browser window.
1348 BrowserWindow *browserWindowPointer = new BrowserWindow(false, &bookmarkStructPointer->url);
1350 // Show the new browser window.
1351 browserWindowPointer->show();
1356 bookmarkContextMenuPointer->addSeparator();
1358 // Add the edit action to the menu.
1359 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("document-edit")), i18nc("Edit bookmark context menu entry", "Edit"), [=]
1361 // Get the current tab favorite icon.
1362 QIcon currentTabFavoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
1364 // Instantiate an edit bookmark dialog.
1365 QDialog *editBookmarkDialogPointer = new EditBookmarkDialog(databaseId, currentTabFavoriteIcon);
1368 editBookmarkDialogPointer->show();
1370 // Process bookmark events.
1371 connect(editBookmarkDialogPointer, SIGNAL(bookmarkSaved()), this, SLOT(populateBookmarksInAllWindows()));
1375 // Add the copy URL action to the menu.
1376 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-copy")), i18nc("Copy bookmark URL context menu entry", "Copy URL"), [=]
1378 // Get the bookmark.
1379 BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
1381 // Get a handle for the clipboard.
1382 QClipboard *clipboard = QGuiApplication::clipboard();
1384 // Place the URL on the keyboard.
1385 clipboard->setText(bookmarkStructPointer->url);
1390 bookmarkContextMenuPointer->addSeparator();
1392 // Add the delete action to the menu.
1393 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-delete")), i18nc("Delete bookmark context menu entry", "Delete"), [=]
1395 // Get the parent folder ID.
1396 double parentFolderId = BookmarksDatabase::getParentFolderId(databaseId);
1398 // Delete the bookmark.
1399 BookmarksDatabase::deleteBookmark(databaseId);
1401 // Update the display order of the bookmarks in the parent folder.
1402 BookmarksDatabase::updateFolderContentsDisplayOrder(parentFolderId);
1404 // Repopulate the bookmarks.
1405 populateBookmarksInAllWindows();
1410 // Delete the menu from memory when it is closed.
1411 bookmarkContextMenuPointer->setAttribute(Qt::WA_DeleteOnClose);
1413 // Display the context menu.
1414 bookmarkContextMenuPointer->popup(bookmarksToolBarPointer->mapToGlobal(point));
1416 else // The toolbar background was clicked.
1418 // Temporarily set the context menu policy to the default.
1419 bookmarksToolBarPointer->setContextMenuPolicy(Qt::DefaultContextMenu);
1421 // Create a context menu event with the same position.
1422 QContextMenuEvent *contextMenuEventPointer = new QContextMenuEvent(QContextMenuEvent::Mouse, point);
1424 // Send the context menu event to the toolbar.
1425 QCoreApplication::sendEvent(bookmarksToolBarPointer, contextMenuEventPointer);
1427 // Reset the context menu policy.
1428 bookmarksToolBarPointer->setContextMenuPolicy(Qt::CustomContextMenu);
1432 void BrowserWindow::showCookiesDialog()
1434 // Remove the focus from the URL line edit.
1435 urlLineEditPointer->clearFocus();
1437 // Instantiate the cookie settings dialog.
1438 CookiesDialog *cookiesDialogPointer = new CookiesDialog(tabWidgetPointer->getCookieList());
1441 cookiesDialogPointer->show();
1443 // Connect the dialog signals.
1444 connect(cookiesDialogPointer, SIGNAL(addCookie(QNetworkCookie)), tabWidgetPointer, SLOT(addCookieToStore(QNetworkCookie)));
1445 connect(cookiesDialogPointer, SIGNAL(deleteAllCookies()), tabWidgetPointer, SLOT(deleteAllCookies()));
1446 connect(cookiesDialogPointer, SIGNAL(deleteCookie(QNetworkCookie)), tabWidgetPointer, SLOT(deleteCookieFromStore(QNetworkCookie)));
1449 void BrowserWindow::showDownloadLocationBrowseDialog() const
1451 // Get the current download location.
1452 QString currentDownloadLocation = downloadLocationComboBoxPointer->currentText();
1454 // Resolve the system download directory if specified.
1455 if (currentDownloadLocation == QStringLiteral("System Download Directory"))
1456 currentDownloadLocation = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
1458 // Get the new download location.
1459 QString newDownloadLocation = QFileDialog::getExistingDirectory(configDialogPointer, i18nc("Select download location dialog caption", "Select Download Location"), currentDownloadLocation);
1461 // Populate the download location combo box according to the new download location.
1462 if (newDownloadLocation == QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)) // The default download location was selected.
1464 // Populate the download location with the default text.
1465 downloadLocationComboBoxPointer->setCurrentText("System Download Directory");
1467 else if (newDownloadLocation != QStringLiteral("")) // A different directory was selected.
1469 // Populate the download location.
1470 downloadLocationComboBoxPointer->setCurrentText(newDownloadLocation);
1474 void BrowserWindow::showDomainSettingsDialog() const
1476 // Remove the focus from the URL line edit.
1477 urlLineEditPointer->clearFocus();
1479 // Instantiate the domain settings dialog.
1480 DomainSettingsDialog *domainSettingsDialogPointer = new DomainSettingsDialog();
1482 // Reload the tabs when domain settings are updated.
1483 connect(domainSettingsDialogPointer, SIGNAL(domainSettingsUpdated()), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
1486 domainSettingsDialogPointer->show();
1489 void BrowserWindow::showFindTextActions() const
1491 // Show the find text actions.
1492 findTextLineEditActionPointer->setVisible(true);
1493 findTextLabelActionPointer->setVisible(true);
1494 findNextActionPointer->setVisible(true);
1495 findPreviousActionPointer->setVisible(true);
1496 findCaseSensitiveActionPointer->setVisible(true);
1497 hideFindTextActionPointer->setVisible(true);
1499 // Set the focus on the find line edit.
1500 findTextLineEditPointer->setFocus();
1502 // Select all the text in the find line edit.
1503 findTextLineEditPointer->selectAll();
1506 void BrowserWindow::showProgressBar(const int &progress) const
1508 // Set the progress bar value.
1509 progressBarPointer->setValue(progress);
1511 // Show the progress bar.
1512 progressBarPointer->show();
1514 // Disable and hide the refresh action.
1515 refreshActionPointer->setEnabled(false);
1516 refreshActionPointer->setVisible(false);
1518 // Enable and show the stop action.
1519 stopActionPointer->setEnabled(true);
1520 stopActionPointer->setVisible(true);
1523 void BrowserWindow::showSettingsDialog()
1525 // Create the settings widgets.
1526 QWidget *privacySettingsWidgetPointer = new QWidget;
1527 QWidget *generalSettingsWidgetPointer = new QWidget;
1528 QWidget *spellCheckSettingsWidgetPointer = new QWidget;
1530 // Instantiate the settings UI.
1531 Ui::PrivacySettings privacySettingsUi;
1532 Ui::GeneralSettings generalSettingsUi;
1533 Ui::SpellCheckSettings spellCheckSettingsUi;
1535 // Setup the UI to display the settings widgets.
1536 privacySettingsUi.setupUi(privacySettingsWidgetPointer);
1537 generalSettingsUi.setupUi(generalSettingsWidgetPointer);
1538 spellCheckSettingsUi.setupUi(spellCheckSettingsWidgetPointer);
1540 // Get handles for the widgets.
1541 QComboBox *userAgentComboBoxPointer = privacySettingsUi.kcfg_userAgent;
1542 userAgentLabelPointer = privacySettingsUi.userAgentLabel;
1543 QComboBox *searchEngineComboBoxPointer = generalSettingsUi.kcfg_searchEngine;
1544 searchEngineLabelPointer = generalSettingsUi.searchEngineLabel;
1545 downloadLocationComboBoxPointer = generalSettingsUi.kcfg_downloadLocation;
1546 QPushButton *browseButtonPointer = generalSettingsUi.browseButton;
1547 QListWidget *spellCheckListWidgetPointer = spellCheckSettingsUi.spellCheckListWidget;
1549 // Populate the combo box labels.
1550 updateUserAgentLabel(userAgentComboBoxPointer->currentText());
1551 updateSearchEngineLabel(searchEngineComboBoxPointer->currentText());
1553 // Update the labels when the combo boxes change.
1554 connect(userAgentComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateUserAgentLabel(const QString)));
1555 connect(searchEngineComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateSearchEngineLabel(const QString)));
1557 // Connect the download location directory browse button.
1558 connect(browseButtonPointer, SIGNAL(clicked()), this, SLOT(showDownloadLocationBrowseDialog()));
1560 // Create a dictionaries QDir from the `QTWEBENGINE_DICTIONARIES_PATH` environment variable.
1561 QDir dictionariesDir = QDir(qEnvironmentVariable("QTWEBENGINE_DICTIONARIES_PATH"));
1563 // Get a dictionaries string list.
1564 QStringList dictionariesStringList = dictionariesDir.entryList(QStringList(QLatin1String("*.bdic")), QDir::Files | QDir::NoSymLinks);
1566 // Remove the `.bdic` file extensions from the dictionaries list.
1567 dictionariesStringList.replaceInStrings(QLatin1String(".bdic"), QLatin1String(""));
1569 // Get a list of the enabled spell check languages.
1570 QStringList enabledSpellCheckLanguagesList = Settings::spellCheckLanguages();
1572 // Add each dictionary to the spell check list widget.
1573 foreach(QString dictionaryString, dictionariesStringList)
1575 // Create a new list widget item pointer.
1576 QListWidgetItem *listWidgetItemPointer = new QListWidgetItem();
1578 // Create a dictionary check box widget with the name of the dictionary string.
1579 QCheckBox *dictionaryCheckBoxWidget = new QCheckBox(dictionaryString);
1581 // Check the language if it is currently enabled.
1582 if (enabledSpellCheckLanguagesList.contains(dictionaryString))
1583 dictionaryCheckBoxWidget->setCheckState(Qt::Checked);
1585 dictionaryCheckBoxWidget->setCheckState(Qt::Unchecked);
1587 // Add the list widget item to the spell check list widget.
1588 spellCheckListWidgetPointer->addItem(listWidgetItemPointer);
1590 // Set the list widget item check box widget.
1591 spellCheckListWidgetPointer->setItemWidget(listWidgetItemPointer, dictionaryCheckBoxWidget);
1594 // Get a handle for the KConfig skeleton.
1595 KConfigSkeleton *kConfigSkeletonPointer = Settings::self();
1597 // Instantiate a settings config dialog from the settings.kcfg file.
1598 configDialogPointer = new KConfigDialog(this, QLatin1String("settings"), kConfigSkeletonPointer);
1600 // Create a settings icon string.
1601 QString settingsIconString;
1603 // Get a settings icon that matches the theme.
1604 if (QIcon::hasThemeIcon("breeze-settings"))
1606 // KDE uses breeze-settings.
1607 settingsIconString = QLatin1String("breeze-settings");
1611 // Gnome uses preferences-desktop.
1612 settingsIconString = QLatin1String("preferences-desktop");
1615 // Add the settings widgets as config dialog pages.
1616 configDialogPointer->addPage(privacySettingsWidgetPointer, i18nc("Settings tab title", "Privacy"), QLatin1String("privacybrowser"));
1617 configDialogPointer->addPage(generalSettingsWidgetPointer, i18nc("Settings tab title", "General"), settingsIconString);
1618 configDialogPointer->addPage(spellCheckSettingsWidgetPointer, i18nc("Settings tab title", "Spell Check"), QLatin1String("tools-check-spelling"));
1620 // Get handles for the buttons.
1621 QPushButton *applyButtonPointer = configDialogPointer->button(QDialogButtonBox::Apply);
1622 QPushButton *okButtonPointer = configDialogPointer->button(QDialogButtonBox::Ok);
1624 // Prevent interaction with the parent window while the dialog is open.
1625 configDialogPointer->setWindowModality(Qt::WindowModal);
1628 configDialogPointer->show();
1630 // TODO. KConfigDialog does not respect expanding size policies. <https://redmine.stoutner.com/issues/823>
1631 //configDialogPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1632 //privacySettingsWidgetPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1633 //generalSettingsWidgetPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1634 //configDialogPointer->adjustSize();
1636 // Expand the config dialog.
1637 configDialogPointer->resize(1000, 500);
1639 // Create a save spell check languages lambda.
1640 auto saveSpellCheckLanguages = [spellCheckListWidgetPointer, kConfigSkeletonPointer, this] ()
1642 // Create a list of enabled languages.
1643 QStringList newSpellCheckLanguages = QStringList();
1645 // Get a count of all the languages.
1646 int allLanguagesCount = spellCheckListWidgetPointer->count();
1648 // Get a list of all the checked languages.
1649 for (int i = 0; i < allLanguagesCount; ++i) {
1650 // Get the language item.
1651 QListWidgetItem *languageItemPointer = spellCheckListWidgetPointer->item(i);
1653 // Get the language check box.
1654 QCheckBox *languageCheckBoxPointer = qobject_cast<QCheckBox*>(spellCheckListWidgetPointer->itemWidget(languageItemPointer));
1656 // Add the item to the enabled languages if it is checked.
1657 if (languageCheckBoxPointer->checkState() == Qt::Checked)
1660 QString languageString = languageCheckBoxPointer->text();
1662 // Remove all instances of `&`, which may have been added automatically when creating the check box text.
1663 languageString.remove(QChar('&'));
1665 // Add the language string to the list.
1666 newSpellCheckLanguages.append(languageString);
1670 // Update the spell check languages.
1671 if (Settings::spellCheckLanguages() != newSpellCheckLanguages)
1673 // Update the spell check languages.
1674 Settings::setSpellCheckLanguages(newSpellCheckLanguages);
1676 // Write the settings to disk.
1677 kConfigSkeletonPointer->save();
1680 // Apply the spell check languages.
1681 tabWidgetPointer->applySpellCheckLanguages();
1685 connect(applyButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages);
1686 connect(okButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages);
1688 // Apply the settings handled by KConfig.
1689 connect(configDialogPointer, SIGNAL(settingsChanged(QString)), tabWidgetPointer, SLOT(applyApplicationSettings()));
1690 connect(configDialogPointer, SIGNAL(settingsChanged(QString)), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
1693 QSize BrowserWindow::sizeHint() const
1695 // Return the default window size.
1696 return QSize(1500, 1200);
1699 void BrowserWindow::toggleBookmark()
1701 // Remove the focus from the URL line edit, which will have been focused when the user clicked on the bookmarked icon.
1702 urlLineEditPointer->clearFocus();
1704 // Create or delete the bookmark
1705 if (bookmarkedActionPointer->isChecked()) // The user checked the toggle. Create a bookmark.
1707 // Create a bookmark struct.
1708 BookmarkStruct *bookmarkStructPointer = new BookmarkStruct;
1710 // Populate the bookmark struct.
1711 bookmarkStructPointer->name = tabWidgetPointer->getCurrentTabTitle();
1712 bookmarkStructPointer->url = tabWidgetPointer->getCurrentTabUrl();
1713 bookmarkStructPointer->parentFolderId = 0;
1714 bookmarkStructPointer->favoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
1716 // Add the bookmark.
1717 BookmarksDatabase::addBookmark(bookmarkStructPointer);
1719 else // The user unchecked the toggle. Delete all related bookmarks.
1721 // Delete the bookmarks.
1722 BookmarksDatabase::deleteBookmarks(urlLineEditPointer->text());
1727 // Repopulate the bookmarks.
1728 populateBookmarksInAllWindows();
1731 void BrowserWindow::toggleDeveloperTools() const
1733 // Toggle the developer tools.
1734 tabWidgetPointer->toggleDeveloperTools(developerToolsActionPointer->isChecked());
1737 void BrowserWindow::toggleDomStorage() const
1739 // Remove the focus from the URL line edit.
1740 urlLineEditPointer->clearFocus();
1742 // Toggle DOM storage.
1743 tabWidgetPointer->toggleDomStorage();
1746 void BrowserWindow::toggleFindCaseSensitive() const
1748 // Get the current find string.
1749 const QString findString = findTextLineEditPointer->text();
1751 // Toggle find case sensitive.
1752 tabWidgetPointer->toggleFindCaseSensitive(findString);
1755 void BrowserWindow::toggleJavaScript() const
1757 // Remove the focus from the URL line edit.
1758 urlLineEditPointer->clearFocus();
1760 // Toggle JavaScript.
1761 tabWidgetPointer->toggleJavaScript();
1764 void BrowserWindow::toggleLocalStorage() const
1766 // Remove the focus from the URL line edit.
1767 urlLineEditPointer->clearFocus();
1769 // Toggle local storage.
1770 tabWidgetPointer->toggleLocalStorage();
1773 void BrowserWindow::toggleFullScreen()
1775 // Toggle the full screen status.
1776 fullScreenRequested(fullScreenActionPointer->isChecked());
1779 void BrowserWindow::toggleViewSource() const
1781 // Get the current URL.
1782 QString url = urlLineEditPointer->text();
1785 if (url.startsWith(QLatin1String("view-source:"))) // The source is currently being viewed.
1787 // Remove `view-source:` from the URL.
1788 url = url.remove(0, 12);
1790 else // The source is not currently being viewed.
1792 // Prepend `view-source:` from the URL.
1793 url = url.prepend(QLatin1String("view-source:"));
1797 loadUrlFromLineEdit(url);
1800 void BrowserWindow::toggleViewBookmarksToolBar()
1802 // Store the current status of the bookmarks toolbar, which is used when exiting full screen browsing.
1803 bookmarksToolBarIsVisible = viewBookmarksToolBarActionPointer->isChecked();
1805 // Update the visibility of the bookmarks toolbar.
1806 bookmarksToolBarPointer->setVisible(bookmarksToolBarIsVisible);
1809 void BrowserWindow::toggleViewSourceInNewTab() const
1811 // Get the current URL.
1812 QString url = urlLineEditPointer->text();
1815 if (url.startsWith(QLatin1String("view-source:"))) // The source is currently being viewed.
1817 // Remove `view-source:` from the URL.
1818 url = url.remove(0, 12);
1820 else // The source is not currently being viewed.
1822 // Prepend `view-source:` from the URL.
1823 url = url.prepend(QLatin1String("view-source:"));
1826 // Add the new tab. `true` removes the URL line edit focus, `false` does not open a background tab.
1827 tabWidgetPointer->addTab(true, false, url);
1830 void BrowserWindow::updateBookmarkedAction() const
1832 // Update the bookmarked action to reflect the current state.
1833 if (bookmarkedActionPointer->isChecked())
1834 bookmarkedActionPointer->setIcon(QIcon::fromTheme("starred-symbolic"));
1836 bookmarkedActionPointer->setIcon(QIcon::fromTheme("non-starred-symbolic"));
1839 void BrowserWindow::updateCookiesAction(const int numberOfCookies) const
1841 // Update the action text.
1842 cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", numberOfCookies));
1845 void BrowserWindow::updateDefaultZoomFactor(const double newDefaultZoomFactor)
1847 // Store the new default zoom factor.
1848 defaultZoomFactor = newDefaultZoomFactor;
1851 void BrowserWindow::updateDomStorageAction(const bool &isEnabled) const
1853 // Set the action checked status.
1854 domStorageActionPointer->setChecked(isEnabled);
1857 void BrowserWindow::updateDomainSettingsIndicator(const bool status)
1859 // Set the domain palette according to the status.
1861 urlLineEditPointer->setPalette(positiveBackgroundPalette);
1863 urlLineEditPointer->setPalette(normalBackgroundPalette);
1866 void BrowserWindow::updateFindText(const QString &text, const bool findCaseSensitive) const
1869 findTextLineEditPointer->setText(text);
1871 // Set the find case sensitive action checked status.
1872 findCaseSensitiveActionPointer->setChecked(findCaseSensitive);
1875 void BrowserWindow::updateFindTextResults(const QWebEngineFindTextResult &findTextResult) const
1877 // Update the find text label.
1878 findTextLabelPointer->setText(QStringLiteral(" %1/%2 ").arg(findTextResult.activeMatch()).arg(findTextResult.numberOfMatches()));
1880 // Set the background color according to the find status.
1881 if (findTextLineEditPointer->text().isEmpty())
1882 findTextLineEditPointer->setPalette(normalBackgroundPalette);
1883 else if (findTextResult.numberOfMatches() == 0)
1884 findTextLineEditPointer->setPalette(negativeBackgroundPalette);
1886 findTextLineEditPointer->setPalette(positiveBackgroundPalette);
1889 void BrowserWindow::updateJavaScriptAction(const bool &isEnabled)
1891 // Update the JavaScript status.
1892 javaScriptEnabled = isEnabled;
1894 // Set the icon according to the status.
1895 if (javaScriptEnabled)
1896 javaScriptActionPointer->setIcon(QIcon(QLatin1String(":/icons/javascript-warning.svg")));
1898 javaScriptActionPointer->setIcon(QIcon(QLatin1String(":/icons/privacy-mode.svg")));
1900 // Set the action checked status.
1901 javaScriptActionPointer->setChecked(javaScriptEnabled);
1903 // Update the status of the DOM storage action.
1904 domStorageActionPointer->setEnabled(javaScriptEnabled & localStorageEnabled);
1907 void BrowserWindow::updateLocalStorageAction(const bool &isEnabled)
1909 // Update the local storage status.
1910 localStorageEnabled = isEnabled;
1912 // 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.
1913 if (localStorageEnabled)
1914 localStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("disk-quota-high"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/actions/document-save-as.png"))));
1916 localStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("disk-quota"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/apps/kfm.png"))));
1918 // Set the action checked status.
1919 localStorageActionPointer->setChecked(localStorageEnabled);
1921 // Update the status of the DOM storage action.
1922 domStorageActionPointer->setEnabled(localStorageEnabled & javaScriptEnabled);
1925 void BrowserWindow::updateSearchEngineActions(const QString &searchEngine, const bool &updateCustomSearchEngineStatus)
1927 // Initialize the custom search engine flag.
1928 bool customSearchEngine = false;
1930 if (searchEngine == "Mojeek") // Mojeek.
1932 // Check the Mojeek user agent action.
1933 searchEngineMojeekActionPointer->setChecked(true);
1935 // Update the search engine menu action icon.
1936 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1938 // Update the search engine menu action text.
1939 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Mojeek"));
1941 else if (searchEngine == "Monocles") // Monocles.
1943 // Check the Monocles user agent action.
1944 searchEngineMonoclesActionPointer->setChecked(true);
1946 // Update the search engine menu action icon.
1947 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1949 // Update the search engine menu action text.
1950 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Monocles"));
1952 else if (searchEngine == "MetaGer") // MetaGer.
1954 // Check the MetaGer user agent action.
1955 searchEngineMetagerActionPointer->setChecked(true);
1957 // Update the search engine menu action icon.
1958 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1960 // Update the search engine menu action text.
1961 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - MetaGer"));
1963 else if (searchEngine == "Google") // Google.
1965 // Check the Google user agent action.
1966 searchEngineGoogleActionPointer->setChecked(true);
1968 // Update the search engine menu action icon.
1969 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-google"), QIcon::fromTheme(QLatin1String("edit-find"))));
1971 // Update the search engine menu action text.
1972 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Google"));
1974 else if (searchEngine == "Bing") // Bing.
1976 // Check the Bing user agent action.
1977 searchEngineBingActionPointer->setChecked(true);
1979 // Update the search engine menu action icon.
1980 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1982 // Update the search engine menu action text.
1983 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Bing"));
1985 else if (searchEngine == "Yahoo") // Yahoo.
1987 // Check the Yahoo user agent action.
1988 searchEngineYahooActionPointer->setChecked(true);
1990 // Update the search engine menu action icon.
1991 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-yahoo"), QIcon::fromTheme(QLatin1String("edit-find"))));
1993 // Update the search engine menu action text.
1994 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Yahoo"));
1996 else // Custom search engine.
1998 // Check the user agent.
1999 searchEngineCustomActionPointer->setChecked(true);
2001 // Update the search engine menu action icon.
2002 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
2004 // Update the search engine menu action text.
2005 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Custom"));
2007 // Set the custom search engine text.
2008 searchEngineCustomActionPointer->setText(searchEngine);
2010 // Set the custom search engine flag.
2011 customSearchEngine = true;
2014 // Update the custom search engine enabled boolean.
2015 if (updateCustomSearchEngineStatus)
2016 customSearchEngineEnabled = customSearchEngine;
2018 // Format the custom search engine.
2019 if (customSearchEngineEnabled)
2021 // Enable the custom search engine.
2022 searchEngineCustomActionPointer->setEnabled(true);
2026 // Disable the custom search engine.
2027 searchEngineCustomActionPointer->setEnabled(false);
2029 // Reset the custom search engine text.
2030 searchEngineCustomActionPointer->setText(i18nc("@action", "Custom"));
2034 void BrowserWindow::updateSearchEngineLabel(const QString &searchEngineString) const
2036 // Update the search engine label.
2037 searchEngineLabelPointer->setText(SearchEngineHelper::getSearchUrl(searchEngineString));
2040 void BrowserWindow::updateUrlLineEdit(const QUrl &newUrl)
2042 // Get the new URL string in encoded form, which displays punycode.
2043 QString newUrlString = newUrl.toEncoded();
2045 // Update the view source actions.
2046 if (newUrlString.startsWith(QLatin1String("view-source:"))) // The source is currently being viewed.
2048 // Mark the view source checkbox.
2049 viewSourceActionPointer->setChecked(true);
2051 // Update the view in new tab action text.
2052 viewSourceInNewTabActionPointer->setText(i18nc("View rendered website in new tab action", "View Rendered Website in New Tab"));
2054 else // The source is not currently being viewed.
2056 // Unmark the view source checkbox.
2057 viewSourceActionPointer->setChecked(false);
2059 // Update the view in new tab action text.
2060 viewSourceInNewTabActionPointer->setText(i18nc("View source in new tab action", "View Source in New Tab"));
2063 // Update the URL line edit if it does not have focus.
2064 if (!urlLineEditPointer->hasFocus())
2066 // Update the URL line edit.
2067 urlLineEditPointer->setText(newUrlString);
2069 // Set the bookmarked action status.
2070 bookmarkedActionPointer->setChecked(BookmarksDatabase::isBookmarked(newUrlString));
2072 // Update the bookmarked action.
2073 updateBookmarkedAction();
2075 // Set the focus if the new URL is blank.
2076 if (newUrlString == QStringLiteral(""))
2077 urlLineEditPointer->setFocus();
2080 // Store the current URL.
2081 currentUrl = newUrl;
2084 void BrowserWindow::updateUserAgentActions(const QString &userAgent, const bool &updateCustomUserAgentStatus)
2086 // Initialize the custom user agent flag.
2087 bool customUserAgent = false;
2089 // Check the indicated on-the-fly user agent.
2090 if (userAgent == UserAgentHelper::PRIVACY_BROWSER_USER_AGENT) // Privacy Browser.
2092 // Check the Privacy Browser user agent action.
2093 userAgentPrivacyBrowserActionPointer->setChecked(true);
2095 // Update the user agent menu action icon.
2096 userAgentMenuActionPointer->setIcon(QIcon(":/icons/privacy-mode.svg"));
2098 // Update the user agent menu action text.
2099 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Privacy Browser"));
2101 else if (userAgent == TabWidget::webEngineDefaultUserAgent) // WebEngine default.
2103 // check the WebEngine default user agent action.
2104 userAgentWebEngineDefaultActionPointer->setChecked(true);
2106 // Update the user agent menu action icon.
2107 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("qtlogo"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2109 // Update the user agent menu action text.
2110 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - WebEngine default"));
2112 else if (userAgent == UserAgentHelper::FIREFOX_LINUX_USER_AGENT) // Firefox on Linux.
2114 // Check the Firefox on Linux user agent action.
2115 userAgentFirefoxLinuxActionPointer->setChecked(true);
2117 // Update the user agent menu action icon.
2118 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2120 // Update the user agent menu action text.
2121 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Firefox on Linux"));
2123 else if (userAgent == UserAgentHelper::CHROMIUM_LINUX_USER_AGENT) // Chromium on Linux.
2125 // Check the Chromium on Linux user agent action.
2126 userAgentChromiumLinuxActionPointer->setChecked(true);
2128 // Update the user agent menu action icon.
2129 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2131 // Update the user agent menu action text.
2132 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Chromium on Linux"));
2134 else if (userAgent == UserAgentHelper::FIREFOX_WINDOWS_USER_AGENT) // Firefox on Windows.
2136 // Check the Firefox on Windows user agent action.
2137 userAgentFirefoxWindowsActionPointer->setChecked(true);
2139 // Update the user agent menu action icon.
2140 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2142 // Update the user agent menu action text.
2143 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Firefox on Windows"));
2145 else if (userAgent == UserAgentHelper::CHROME_WINDOWS_USER_AGENT) // Chrome on Windows.
2147 // Check the Chrome on Windows user agent action.
2148 userAgentChromeWindowsActionPointer->setChecked(true);
2150 // Update the user agent menu action icon.
2151 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2153 // Update the user agent menu action text.
2154 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Chrome on Windows"));
2156 else if (userAgent == UserAgentHelper::EDGE_WINDOWS_USER_AGENT) // Edge on Windows.
2158 // Check the Edge on Windows user agent action.
2159 userAgentEdgeWindowsActionPointer->setChecked(true);
2161 // Update the user agent menu action icon.
2162 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
2164 // Update the user agent menu action text.
2165 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Edge on Windows"));
2167 else if (userAgent == UserAgentHelper::SAFARI_MACOS_USER_AGENT) // Safari on macOS.
2169 // Check the Safari on macOS user agent action.
2170 userAgentSafariMacosActionPointer->setChecked(true);
2172 // Update the user agent menu action icon.
2173 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
2175 // Update the user agent menu action text.
2176 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Safari on macOS"));
2178 else // Custom user agent.
2180 // Check the user agent.
2181 userAgentCustomActionPointer->setChecked(true);
2183 // Update the user agent menu action icon.
2184 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
2186 // Update the user agent menu action text.
2187 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Custom"));
2189 // Set the custom user agent text.
2190 userAgentCustomActionPointer->setText(userAgent);
2192 // Set the custom user agent flag.
2193 customUserAgent = true;
2196 // Update the custom user agent enabled boolean.
2197 // 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.
2198 if (updateCustomUserAgentStatus)
2199 customUserAgentEnabled = customUserAgent;
2202 // Format the custom user agent.
2203 if (customUserAgentEnabled)
2205 // Enable the custom user agent.
2206 userAgentCustomActionPointer->setEnabled(true);
2210 // Disable the custom user agent.
2211 userAgentCustomActionPointer->setEnabled(false);
2213 // Reset the custom user agent text.
2214 userAgentCustomActionPointer->setText(i18nc("@action", "Custom"));
2218 void BrowserWindow::updateUserAgentLabel(const QString &userAgentDatabaseName) const
2220 // Update the user agent label.
2221 userAgentLabelPointer->setText(UserAgentHelper::getUserAgentFromDatabaseName(userAgentDatabaseName));
2224 void BrowserWindow::updateViewBookmarksToolBarCheckbox(const bool visible)
2226 // Update the view bookmarks toolbar checkbox.
2227 viewBookmarksToolBarActionPointer->setChecked(visible);
2229 // Initialize the bookmarks toolbar visibility tracker if Privacy Browser has just launched.
2230 if (bookmarksToolBarUninitialized)
2232 // Set the initialization flag.
2233 bookmarksToolBarUninitialized = false;
2235 // Store the current status of the bookmarks toolbar, which is used when exiting full screen browsing.
2236 bookmarksToolBarIsVisible = visible;
2240 void BrowserWindow::updateWindowTitle(const QString &title)
2242 // Update the window title.
2243 setWindowTitle(title);
2246 void BrowserWindow::updateZoomActions(const double &zoomFactor)
2248 // Set the current zoom factor.
2249 currentZoomFactor = zoomFactor;
2251 // Set the status of the default zoom action.
2252 zoomDefaultActionPointer->setEnabled(currentZoomFactor != defaultZoomFactor);
2254 // Set the status of the zoom in action and button.
2255 zoomInActionPointer->setEnabled(currentZoomFactor <= 4.99);
2256 zoomPlusButtonPointer->setEnabled(currentZoomFactor <= 4.99);
2258 // Set the status of the zoom out action and button.
2259 zoomMinusButtonPointer->setEnabled(currentZoomFactor > 0.25);
2260 zoomOutActionPointer->setEnabled(currentZoomFactor > 0.25);
2263 // 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.
2264 zoomFactorActionPointer->setText(ki18nc("The zoom factor action", "Zoom Factor - %1").subs(zoomFactor, 0, '0', 2).toString());
2266 // Update the status bar zoom factor label.
2267 currentZoomButtonPointer->setText(ki18nc("The status bar zoom, which is just the formatted zoom factor", "%1").subs(zoomFactor, 0, '0', 2).toString());
2270 void BrowserWindow::zoomDefault()
2272 // Set the new zoom factor.
2273 tabWidgetPointer->applyOnTheFlyZoomFactor(defaultZoomFactor);
2275 // Update the on-the-fly action text.
2276 updateZoomActions(defaultZoomFactor);