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, `true` opens the new tabs in an adjacent tab. `false` does not load a background tab.
629 for (QString url : *folderUrlsListPointer)
630 tabWidgetPointer->addTab(true, 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` opens the new tabs in an adjacent tab. `true` loads a background tab.
642 for (QString url : *folderUrlsListPointer)
643 tabWidgetPointer->addTab(true, 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, `false` does not load the new tabs in adjacent tabs. `true` loads a background tab.
660 for (int i = 1; i < folderUrls; ++i)
661 browserWindowPointer->tabWidgetPointer->addTab(true, false, 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, `true` opens the new tab in an adjacent tab. `false` does not load a background tab.
1326 tabWidgetPointer->addTab(true, 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` opens the new tab in an adjacent tab. `true` loads a background tab.
1337 tabWidgetPointer->addTab(true, 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::showDownloadDirectoryBrowseDialog() const
1451 // Get the current download directory.
1452 QString currentDownloadDirectory = downloadDirectoryComboBoxPointer->currentText();
1454 // Resolve the system download directory if specified.
1455 if (currentDownloadDirectory == QStringLiteral("System Download Directory"))
1456 currentDownloadDirectory = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
1458 // Get the new download directory.
1459 QString newDownloadDirectory = QFileDialog::getExistingDirectory(configDialogPointer, i18nc("Select download directory dialog caption", "Select Download Directory"),
1460 currentDownloadDirectory);
1462 // Populate the download directory combo box according to the new download location.
1463 if (newDownloadDirectory == QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)) // The default download location was selected.
1465 // Populate the download location with the default text.
1466 downloadDirectoryComboBoxPointer->setCurrentText("System Download Directory");
1468 else if (newDownloadDirectory != QStringLiteral("")) // A different directory was selected.
1470 // Populate the download location.
1471 downloadDirectoryComboBoxPointer->setCurrentText(newDownloadDirectory);
1475 void BrowserWindow::showDomainSettingsDialog() const
1477 // Remove the focus from the URL line edit.
1478 urlLineEditPointer->clearFocus();
1480 // Instantiate the domain settings dialog.
1481 DomainSettingsDialog *domainSettingsDialogPointer = new DomainSettingsDialog();
1483 // Reload the tabs when domain settings are updated.
1484 connect(domainSettingsDialogPointer, SIGNAL(domainSettingsUpdated()), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
1487 domainSettingsDialogPointer->show();
1490 void BrowserWindow::showFindTextActions() const
1492 // Show the find text actions.
1493 findTextLineEditActionPointer->setVisible(true);
1494 findTextLabelActionPointer->setVisible(true);
1495 findNextActionPointer->setVisible(true);
1496 findPreviousActionPointer->setVisible(true);
1497 findCaseSensitiveActionPointer->setVisible(true);
1498 hideFindTextActionPointer->setVisible(true);
1500 // Set the focus on the find line edit.
1501 findTextLineEditPointer->setFocus();
1503 // Select all the text in the find line edit.
1504 findTextLineEditPointer->selectAll();
1507 void BrowserWindow::showProgressBar(const int &progress) const
1509 // Set the progress bar value.
1510 progressBarPointer->setValue(progress);
1512 // Show the progress bar.
1513 progressBarPointer->show();
1515 // Disable and hide the refresh action.
1516 refreshActionPointer->setEnabled(false);
1517 refreshActionPointer->setVisible(false);
1519 // Enable and show the stop action.
1520 stopActionPointer->setEnabled(true);
1521 stopActionPointer->setVisible(true);
1524 void BrowserWindow::showSettingsDialog()
1526 // Create the settings widgets.
1527 QWidget *privacySettingsWidgetPointer = new QWidget;
1528 QWidget *generalSettingsWidgetPointer = new QWidget;
1529 QWidget *spellCheckSettingsWidgetPointer = new QWidget;
1531 // Instantiate the settings UI.
1532 Ui::PrivacySettings privacySettingsUi;
1533 Ui::GeneralSettings generalSettingsUi;
1534 Ui::SpellCheckSettings spellCheckSettingsUi;
1536 // Setup the UI to display the settings widgets.
1537 privacySettingsUi.setupUi(privacySettingsWidgetPointer);
1538 generalSettingsUi.setupUi(generalSettingsWidgetPointer);
1539 spellCheckSettingsUi.setupUi(spellCheckSettingsWidgetPointer);
1541 // Get handles for the widgets.
1542 QComboBox *userAgentComboBoxPointer = privacySettingsUi.kcfg_userAgent;
1543 userAgentLabelPointer = privacySettingsUi.userAgentLabel;
1544 QComboBox *searchEngineComboBoxPointer = generalSettingsUi.kcfg_searchEngine;
1545 searchEngineLabelPointer = generalSettingsUi.searchEngineLabel;
1546 downloadDirectoryComboBoxPointer = generalSettingsUi.kcfg_downloadDirectory;
1547 QPushButton *browseButtonPointer = generalSettingsUi.browseButton;
1548 QListWidget *spellCheckListWidgetPointer = spellCheckSettingsUi.spellCheckListWidget;
1550 // Populate the combo box labels.
1551 updateUserAgentLabel(userAgentComboBoxPointer->currentText());
1552 updateSearchEngineLabel(searchEngineComboBoxPointer->currentText());
1554 // Update the labels when the combo boxes change.
1555 connect(userAgentComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateUserAgentLabel(const QString)));
1556 connect(searchEngineComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateSearchEngineLabel(const QString)));
1558 // Connect the download directory directory browse button.
1559 connect(browseButtonPointer, SIGNAL(clicked()), this, SLOT(showDownloadDirectoryBrowseDialog()));
1561 // Create a dictionaries QDir from the `QTWEBENGINE_DICTIONARIES_PATH` environment variable.
1562 QDir dictionariesDir = QDir(qEnvironmentVariable("QTWEBENGINE_DICTIONARIES_PATH"));
1564 // Get a dictionaries string list.
1565 QStringList dictionariesStringList = dictionariesDir.entryList(QStringList(QLatin1String("*.bdic")), QDir::Files | QDir::NoSymLinks);
1567 // Remove the `.bdic` file extensions from the dictionaries list.
1568 dictionariesStringList.replaceInStrings(QLatin1String(".bdic"), QLatin1String(""));
1570 // Get a list of the enabled spell check languages.
1571 QStringList enabledSpellCheckLanguagesList = Settings::spellCheckLanguages();
1573 // Add each dictionary to the spell check list widget.
1574 foreach(QString dictionaryString, dictionariesStringList)
1576 // Create a new list widget item pointer.
1577 QListWidgetItem *listWidgetItemPointer = new QListWidgetItem();
1579 // Create a dictionary check box widget with the name of the dictionary string.
1580 QCheckBox *dictionaryCheckBoxWidget = new QCheckBox(dictionaryString);
1582 // Check the language if it is currently enabled.
1583 if (enabledSpellCheckLanguagesList.contains(dictionaryString))
1584 dictionaryCheckBoxWidget->setCheckState(Qt::Checked);
1586 dictionaryCheckBoxWidget->setCheckState(Qt::Unchecked);
1588 // Add the list widget item to the spell check list widget.
1589 spellCheckListWidgetPointer->addItem(listWidgetItemPointer);
1591 // Set the list widget item check box widget.
1592 spellCheckListWidgetPointer->setItemWidget(listWidgetItemPointer, dictionaryCheckBoxWidget);
1595 // Get a handle for the KConfig skeleton.
1596 KConfigSkeleton *kConfigSkeletonPointer = Settings::self();
1598 // Instantiate a settings config dialog from the settings.kcfg file.
1599 configDialogPointer = new KConfigDialog(this, QLatin1String("settings"), kConfigSkeletonPointer);
1601 // Create a settings icon string.
1602 QString settingsIconString;
1604 // Get a settings icon that matches the theme.
1605 if (QIcon::hasThemeIcon("breeze-settings"))
1607 // KDE uses breeze-settings.
1608 settingsIconString = QLatin1String("breeze-settings");
1612 // Gnome uses preferences-desktop.
1613 settingsIconString = QLatin1String("preferences-desktop");
1616 // Add the settings widgets as config dialog pages.
1617 configDialogPointer->addPage(privacySettingsWidgetPointer, i18nc("Settings tab title", "Privacy"), QLatin1String("privacybrowser"));
1618 configDialogPointer->addPage(generalSettingsWidgetPointer, i18nc("Settings tab title", "General"), settingsIconString);
1619 configDialogPointer->addPage(spellCheckSettingsWidgetPointer, i18nc("Settings tab title", "Spell Check"), QLatin1String("tools-check-spelling"));
1621 // Get handles for the buttons.
1622 QPushButton *applyButtonPointer = configDialogPointer->button(QDialogButtonBox::Apply);
1623 QPushButton *okButtonPointer = configDialogPointer->button(QDialogButtonBox::Ok);
1625 // Prevent interaction with the parent window while the dialog is open.
1626 configDialogPointer->setWindowModality(Qt::WindowModal);
1629 configDialogPointer->show();
1631 // TODO. KConfigDialog does not respect expanding size policies. <https://redmine.stoutner.com/issues/823>
1632 //configDialogPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1633 //privacySettingsWidgetPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1634 //generalSettingsWidgetPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1635 //configDialogPointer->adjustSize();
1637 // Expand the config dialog.
1638 configDialogPointer->resize(1000, 500);
1640 // Create a save spell check languages lambda.
1641 auto saveSpellCheckLanguages = [spellCheckListWidgetPointer, kConfigSkeletonPointer, this] ()
1643 // Create a list of enabled languages.
1644 QStringList newSpellCheckLanguages = QStringList();
1646 // Get a count of all the languages.
1647 int allLanguagesCount = spellCheckListWidgetPointer->count();
1649 // Get a list of all the checked languages.
1650 for (int i = 0; i < allLanguagesCount; ++i) {
1651 // Get the language item.
1652 QListWidgetItem *languageItemPointer = spellCheckListWidgetPointer->item(i);
1654 // Get the language check box.
1655 QCheckBox *languageCheckBoxPointer = qobject_cast<QCheckBox*>(spellCheckListWidgetPointer->itemWidget(languageItemPointer));
1657 // Add the item to the enabled languages if it is checked.
1658 if (languageCheckBoxPointer->checkState() == Qt::Checked)
1661 QString languageString = languageCheckBoxPointer->text();
1663 // Remove all instances of `&`, which may have been added automatically when creating the check box text.
1664 languageString.remove(QChar('&'));
1666 // Add the language string to the list.
1667 newSpellCheckLanguages.append(languageString);
1671 // Update the spell check languages.
1672 if (Settings::spellCheckLanguages() != newSpellCheckLanguages)
1674 // Update the spell check languages.
1675 Settings::setSpellCheckLanguages(newSpellCheckLanguages);
1677 // Write the settings to disk.
1678 kConfigSkeletonPointer->save();
1681 // Apply the spell check languages.
1682 tabWidgetPointer->applySpellCheckLanguages();
1686 connect(applyButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages);
1687 connect(okButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages);
1689 // Apply the settings handled by KConfig.
1690 connect(configDialogPointer, SIGNAL(settingsChanged(QString)), tabWidgetPointer, SLOT(applyApplicationSettings()));
1691 connect(configDialogPointer, SIGNAL(settingsChanged(QString)), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
1694 QSize BrowserWindow::sizeHint() const
1696 // Return the default window size.
1697 return QSize(1500, 1200);
1700 void BrowserWindow::toggleBookmark()
1702 // Remove the focus from the URL line edit, which will have been focused when the user clicked on the bookmarked icon.
1703 urlLineEditPointer->clearFocus();
1705 // Create or delete the bookmark
1706 if (bookmarkedActionPointer->isChecked()) // The user checked the toggle. Create a bookmark.
1708 // Create a bookmark struct.
1709 BookmarkStruct *bookmarkStructPointer = new BookmarkStruct;
1711 // Populate the bookmark struct.
1712 bookmarkStructPointer->name = tabWidgetPointer->getCurrentTabTitle();
1713 bookmarkStructPointer->url = tabWidgetPointer->getCurrentTabUrl();
1714 bookmarkStructPointer->parentFolderId = 0;
1715 bookmarkStructPointer->favoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
1717 // Add the bookmark.
1718 BookmarksDatabase::addBookmark(bookmarkStructPointer);
1720 else // The user unchecked the toggle. Delete all related bookmarks.
1722 // Delete the bookmarks.
1723 BookmarksDatabase::deleteBookmarks(urlLineEditPointer->text());
1728 // Repopulate the bookmarks.
1729 populateBookmarksInAllWindows();
1732 void BrowserWindow::toggleDeveloperTools() const
1734 // Toggle the developer tools.
1735 tabWidgetPointer->toggleDeveloperTools(developerToolsActionPointer->isChecked());
1738 void BrowserWindow::toggleDomStorage() const
1740 // Remove the focus from the URL line edit.
1741 urlLineEditPointer->clearFocus();
1743 // Toggle DOM storage.
1744 tabWidgetPointer->toggleDomStorage();
1747 void BrowserWindow::toggleFindCaseSensitive() const
1749 // Get the current find string.
1750 const QString findString = findTextLineEditPointer->text();
1752 // Toggle find case sensitive.
1753 tabWidgetPointer->toggleFindCaseSensitive(findString);
1756 void BrowserWindow::toggleJavaScript() const
1758 // Remove the focus from the URL line edit.
1759 urlLineEditPointer->clearFocus();
1761 // Toggle JavaScript.
1762 tabWidgetPointer->toggleJavaScript();
1765 void BrowserWindow::toggleLocalStorage() const
1767 // Remove the focus from the URL line edit.
1768 urlLineEditPointer->clearFocus();
1770 // Toggle local storage.
1771 tabWidgetPointer->toggleLocalStorage();
1774 void BrowserWindow::toggleFullScreen()
1776 // Toggle the full screen status.
1777 fullScreenRequested(fullScreenActionPointer->isChecked());
1780 void BrowserWindow::toggleViewSource() const
1782 // Get the current URL.
1783 QString url = urlLineEditPointer->text();
1786 if (url.startsWith(QLatin1String("view-source:"))) // The source is currently being viewed.
1788 // Remove `view-source:` from the URL.
1789 url = url.remove(0, 12);
1791 else // The source is not currently being viewed.
1793 // Prepend `view-source:` from the URL.
1794 url = url.prepend(QLatin1String("view-source:"));
1798 loadUrlFromLineEdit(url);
1801 void BrowserWindow::toggleViewBookmarksToolBar()
1803 // Store the current status of the bookmarks toolbar, which is used when exiting full screen browsing.
1804 bookmarksToolBarIsVisible = viewBookmarksToolBarActionPointer->isChecked();
1806 // Update the visibility of the bookmarks toolbar.
1807 bookmarksToolBarPointer->setVisible(bookmarksToolBarIsVisible);
1810 void BrowserWindow::toggleViewSourceInNewTab() const
1812 // Get the current URL.
1813 QString url = urlLineEditPointer->text();
1816 if (url.startsWith(QLatin1String("view-source:"))) // The source is currently being viewed.
1818 // Remove `view-source:` from the URL.
1819 url = url.remove(0, 12);
1821 else // The source is not currently being viewed.
1823 // Prepend `view-source:` from the URL.
1824 url = url.prepend(QLatin1String("view-source:"));
1827 // Add the new tab. `true` removes the URL line edit focus, `true` opens the new tab in an adjacent tab. `false` does not open a background tab.
1828 tabWidgetPointer->addTab(true, true, false, url);
1831 void BrowserWindow::updateBookmarkedAction() const
1833 // Update the bookmarked action to reflect the current state.
1834 if (bookmarkedActionPointer->isChecked())
1835 bookmarkedActionPointer->setIcon(QIcon::fromTheme("starred-symbolic"));
1837 bookmarkedActionPointer->setIcon(QIcon::fromTheme("non-starred-symbolic"));
1840 void BrowserWindow::updateCookiesAction(const int numberOfCookies) const
1842 // Update the action text.
1843 cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", numberOfCookies));
1846 void BrowserWindow::updateDefaultZoomFactor(const double newDefaultZoomFactor)
1848 // Store the new default zoom factor.
1849 defaultZoomFactor = newDefaultZoomFactor;
1852 void BrowserWindow::updateDomStorageAction(const bool &isEnabled) const
1854 // Set the action checked status.
1855 domStorageActionPointer->setChecked(isEnabled);
1858 void BrowserWindow::updateDomainSettingsIndicator(const bool status)
1860 // Set the domain palette according to the status.
1862 urlLineEditPointer->setPalette(positiveBackgroundPalette);
1864 urlLineEditPointer->setPalette(normalBackgroundPalette);
1867 void BrowserWindow::updateFindText(const QString &text, const bool findCaseSensitive) const
1870 findTextLineEditPointer->setText(text);
1872 // Set the find case sensitive action checked status.
1873 findCaseSensitiveActionPointer->setChecked(findCaseSensitive);
1876 void BrowserWindow::updateFindTextResults(const QWebEngineFindTextResult &findTextResult) const
1878 // Update the find text label.
1879 findTextLabelPointer->setText(QStringLiteral(" %1/%2 ").arg(findTextResult.activeMatch()).arg(findTextResult.numberOfMatches()));
1881 // Set the background color according to the find status.
1882 if (findTextLineEditPointer->text().isEmpty())
1883 findTextLineEditPointer->setPalette(normalBackgroundPalette);
1884 else if (findTextResult.numberOfMatches() == 0)
1885 findTextLineEditPointer->setPalette(negativeBackgroundPalette);
1887 findTextLineEditPointer->setPalette(positiveBackgroundPalette);
1890 void BrowserWindow::updateJavaScriptAction(const bool &isEnabled)
1892 // Update the JavaScript status.
1893 javaScriptEnabled = isEnabled;
1895 // Set the icon according to the status.
1896 if (javaScriptEnabled)
1897 javaScriptActionPointer->setIcon(QIcon(QLatin1String(":/icons/javascript-warning.svg")));
1899 javaScriptActionPointer->setIcon(QIcon(QLatin1String(":/icons/privacy-mode.svg")));
1901 // Set the action checked status.
1902 javaScriptActionPointer->setChecked(javaScriptEnabled);
1904 // Update the status of the DOM storage action.
1905 domStorageActionPointer->setEnabled(javaScriptEnabled & localStorageEnabled);
1908 void BrowserWindow::updateLocalStorageAction(const bool &isEnabled)
1910 // Update the local storage status.
1911 localStorageEnabled = isEnabled;
1913 // 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.
1914 if (localStorageEnabled)
1915 localStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("disk-quota-high"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/actions/document-save-as.png"))));
1917 localStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("disk-quota"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/apps/kfm.png"))));
1919 // Set the action checked status.
1920 localStorageActionPointer->setChecked(localStorageEnabled);
1922 // Update the status of the DOM storage action.
1923 domStorageActionPointer->setEnabled(localStorageEnabled & javaScriptEnabled);
1926 void BrowserWindow::updateSearchEngineActions(const QString &searchEngine, const bool &updateCustomSearchEngineStatus)
1928 // Initialize the custom search engine flag.
1929 bool customSearchEngine = false;
1931 if (searchEngine == "Mojeek") // Mojeek.
1933 // Check the Mojeek user agent action.
1934 searchEngineMojeekActionPointer->setChecked(true);
1936 // Update the search engine menu action icon.
1937 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1939 // Update the search engine menu action text.
1940 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Mojeek"));
1942 else if (searchEngine == "Monocles") // Monocles.
1944 // Check the Monocles user agent action.
1945 searchEngineMonoclesActionPointer->setChecked(true);
1947 // Update the search engine menu action icon.
1948 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1950 // Update the search engine menu action text.
1951 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Monocles"));
1953 else if (searchEngine == "MetaGer") // MetaGer.
1955 // Check the MetaGer user agent action.
1956 searchEngineMetagerActionPointer->setChecked(true);
1958 // Update the search engine menu action icon.
1959 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1961 // Update the search engine menu action text.
1962 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - MetaGer"));
1964 else if (searchEngine == "Google") // Google.
1966 // Check the Google user agent action.
1967 searchEngineGoogleActionPointer->setChecked(true);
1969 // Update the search engine menu action icon.
1970 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-google"), QIcon::fromTheme(QLatin1String("edit-find"))));
1972 // Update the search engine menu action text.
1973 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Google"));
1975 else if (searchEngine == "Bing") // Bing.
1977 // Check the Bing user agent action.
1978 searchEngineBingActionPointer->setChecked(true);
1980 // Update the search engine menu action icon.
1981 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1983 // Update the search engine menu action text.
1984 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Bing"));
1986 else if (searchEngine == "Yahoo") // Yahoo.
1988 // Check the Yahoo user agent action.
1989 searchEngineYahooActionPointer->setChecked(true);
1991 // Update the search engine menu action icon.
1992 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-yahoo"), QIcon::fromTheme(QLatin1String("edit-find"))));
1994 // Update the search engine menu action text.
1995 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Yahoo"));
1997 else // Custom search engine.
1999 // Check the user agent.
2000 searchEngineCustomActionPointer->setChecked(true);
2002 // Update the search engine menu action icon.
2003 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
2005 // Update the search engine menu action text.
2006 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Custom"));
2008 // Set the custom search engine text.
2009 searchEngineCustomActionPointer->setText(searchEngine);
2011 // Set the custom search engine flag.
2012 customSearchEngine = true;
2015 // Update the custom search engine enabled boolean.
2016 if (updateCustomSearchEngineStatus)
2017 customSearchEngineEnabled = customSearchEngine;
2019 // Format the custom search engine.
2020 if (customSearchEngineEnabled)
2022 // Enable the custom search engine.
2023 searchEngineCustomActionPointer->setEnabled(true);
2027 // Disable the custom search engine.
2028 searchEngineCustomActionPointer->setEnabled(false);
2030 // Reset the custom search engine text.
2031 searchEngineCustomActionPointer->setText(i18nc("@action", "Custom"));
2035 void BrowserWindow::updateSearchEngineLabel(const QString &searchEngineString) const
2037 // Update the search engine label.
2038 searchEngineLabelPointer->setText(SearchEngineHelper::getSearchUrl(searchEngineString));
2041 void BrowserWindow::updateUrlLineEdit(const QUrl &newUrl)
2043 // Get the new URL string in encoded form, which displays punycode.
2044 QString newUrlString = newUrl.toEncoded();
2046 // Update the view source actions.
2047 if (newUrlString.startsWith(QLatin1String("view-source:"))) // The source is currently being viewed.
2049 // Mark the view source checkbox.
2050 viewSourceActionPointer->setChecked(true);
2052 // Update the view in new tab action text.
2053 viewSourceInNewTabActionPointer->setText(i18nc("View rendered website in new tab action", "View Rendered Website in New Tab"));
2055 else // The source is not currently being viewed.
2057 // Unmark the view source checkbox.
2058 viewSourceActionPointer->setChecked(false);
2060 // Update the view in new tab action text.
2061 viewSourceInNewTabActionPointer->setText(i18nc("View source in new tab action", "View Source in New Tab"));
2064 // Update the URL line edit if it does not have focus.
2065 if (!urlLineEditPointer->hasFocus())
2067 // Update the URL line edit.
2068 urlLineEditPointer->setText(newUrlString);
2070 // Set the bookmarked action status.
2071 bookmarkedActionPointer->setChecked(BookmarksDatabase::isBookmarked(newUrlString));
2073 // Update the bookmarked action.
2074 updateBookmarkedAction();
2076 // Set the focus if the new URL is blank.
2077 if (newUrlString == QStringLiteral(""))
2078 urlLineEditPointer->setFocus();
2081 // Store the current URL.
2082 currentUrl = newUrl;
2085 void BrowserWindow::updateUserAgentActions(const QString &userAgent, const bool &updateCustomUserAgentStatus)
2087 // Initialize the custom user agent flag.
2088 bool customUserAgent = false;
2090 // Check the indicated on-the-fly user agent.
2091 if (userAgent == UserAgentHelper::PRIVACY_BROWSER_USER_AGENT) // Privacy Browser.
2093 // Check the Privacy Browser user agent action.
2094 userAgentPrivacyBrowserActionPointer->setChecked(true);
2096 // Update the user agent menu action icon.
2097 userAgentMenuActionPointer->setIcon(QIcon(":/icons/privacy-mode.svg"));
2099 // Update the user agent menu action text.
2100 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Privacy Browser"));
2102 else if (userAgent == TabWidget::webEngineDefaultUserAgent) // WebEngine default.
2104 // check the WebEngine default user agent action.
2105 userAgentWebEngineDefaultActionPointer->setChecked(true);
2107 // Update the user agent menu action icon.
2108 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("qtlogo"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2110 // Update the user agent menu action text.
2111 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - WebEngine default"));
2113 else if (userAgent == UserAgentHelper::FIREFOX_LINUX_USER_AGENT) // Firefox on Linux.
2115 // Check the Firefox on Linux user agent action.
2116 userAgentFirefoxLinuxActionPointer->setChecked(true);
2118 // Update the user agent menu action icon.
2119 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2121 // Update the user agent menu action text.
2122 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Firefox on Linux"));
2124 else if (userAgent == UserAgentHelper::CHROMIUM_LINUX_USER_AGENT) // Chromium on Linux.
2126 // Check the Chromium on Linux user agent action.
2127 userAgentChromiumLinuxActionPointer->setChecked(true);
2129 // Update the user agent menu action icon.
2130 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2132 // Update the user agent menu action text.
2133 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Chromium on Linux"));
2135 else if (userAgent == UserAgentHelper::FIREFOX_WINDOWS_USER_AGENT) // Firefox on Windows.
2137 // Check the Firefox on Windows user agent action.
2138 userAgentFirefoxWindowsActionPointer->setChecked(true);
2140 // Update the user agent menu action icon.
2141 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2143 // Update the user agent menu action text.
2144 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Firefox on Windows"));
2146 else if (userAgent == UserAgentHelper::CHROME_WINDOWS_USER_AGENT) // Chrome on Windows.
2148 // Check the Chrome on Windows user agent action.
2149 userAgentChromeWindowsActionPointer->setChecked(true);
2151 // Update the user agent menu action icon.
2152 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2154 // Update the user agent menu action text.
2155 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Chrome on Windows"));
2157 else if (userAgent == UserAgentHelper::EDGE_WINDOWS_USER_AGENT) // Edge on Windows.
2159 // Check the Edge on Windows user agent action.
2160 userAgentEdgeWindowsActionPointer->setChecked(true);
2162 // Update the user agent menu action icon.
2163 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
2165 // Update the user agent menu action text.
2166 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Edge on Windows"));
2168 else if (userAgent == UserAgentHelper::SAFARI_MACOS_USER_AGENT) // Safari on macOS.
2170 // Check the Safari on macOS user agent action.
2171 userAgentSafariMacosActionPointer->setChecked(true);
2173 // Update the user agent menu action icon.
2174 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
2176 // Update the user agent menu action text.
2177 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Safari on macOS"));
2179 else // Custom user agent.
2181 // Check the user agent.
2182 userAgentCustomActionPointer->setChecked(true);
2184 // Update the user agent menu action icon.
2185 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
2187 // Update the user agent menu action text.
2188 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Custom"));
2190 // Set the custom user agent text.
2191 userAgentCustomActionPointer->setText(userAgent);
2193 // Set the custom user agent flag.
2194 customUserAgent = true;
2197 // Update the custom user agent enabled boolean.
2198 // 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.
2199 if (updateCustomUserAgentStatus)
2200 customUserAgentEnabled = customUserAgent;
2203 // Format the custom user agent.
2204 if (customUserAgentEnabled)
2206 // Enable the custom user agent.
2207 userAgentCustomActionPointer->setEnabled(true);
2211 // Disable the custom user agent.
2212 userAgentCustomActionPointer->setEnabled(false);
2214 // Reset the custom user agent text.
2215 userAgentCustomActionPointer->setText(i18nc("@action", "Custom"));
2219 void BrowserWindow::updateUserAgentLabel(const QString &userAgentDatabaseName) const
2221 // Update the user agent label.
2222 userAgentLabelPointer->setText(UserAgentHelper::getUserAgentFromDatabaseName(userAgentDatabaseName));
2225 void BrowserWindow::updateViewBookmarksToolBarCheckbox(const bool visible)
2227 // Update the view bookmarks toolbar checkbox.
2228 viewBookmarksToolBarActionPointer->setChecked(visible);
2230 // Initialize the bookmarks toolbar visibility tracker if Privacy Browser has just launched.
2231 if (bookmarksToolBarUninitialized)
2233 // Set the initialization flag.
2234 bookmarksToolBarUninitialized = false;
2236 // Store the current status of the bookmarks toolbar, which is used when exiting full screen browsing.
2237 bookmarksToolBarIsVisible = visible;
2241 void BrowserWindow::updateWindowTitle(const QString &title)
2243 // Update the window title.
2244 setWindowTitle(title);
2247 void BrowserWindow::updateZoomActions(const double &zoomFactor)
2249 // Set the current zoom factor.
2250 currentZoomFactor = zoomFactor;
2252 // Set the status of the default zoom action.
2253 zoomDefaultActionPointer->setEnabled(currentZoomFactor != defaultZoomFactor);
2255 // Set the status of the zoom in action and button.
2256 zoomInActionPointer->setEnabled(currentZoomFactor <= 4.99);
2257 zoomPlusButtonPointer->setEnabled(currentZoomFactor <= 4.99);
2259 // Set the status of the zoom out action and button.
2260 zoomMinusButtonPointer->setEnabled(currentZoomFactor > 0.25);
2261 zoomOutActionPointer->setEnabled(currentZoomFactor > 0.25);
2264 // 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.
2265 zoomFactorActionPointer->setText(ki18nc("The zoom factor action", "Zoom Factor - %1").subs(zoomFactor, 0, '0', 2).toString());
2267 // Update the status bar zoom factor label.
2268 currentZoomButtonPointer->setText(ki18nc("The status bar zoom, which is just the formatted zoom factor", "%1").subs(zoomFactor, 0, '0', 2).toString());
2271 void BrowserWindow::zoomDefault()
2273 // Set the new zoom factor.
2274 tabWidgetPointer->applyOnTheFlyZoomFactor(defaultZoomFactor);
2276 // Update the on-the-fly action text.
2277 updateZoomActions(defaultZoomFactor);