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 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 viewSourceActionPointer = actionCollectionPointer->addAction(QLatin1String("view_source"));
98 viewSourceInNewTabActionPointer = actionCollectionPointer->addAction(QLatin1String("view_source_in_new_tab"));
99 developerToolsActionPointer = actionCollectionPointer->addAction(QLatin1String("developer_tools"));
100 javaScriptActionPointer = actionCollectionPointer->addAction(QLatin1String("javascript"));
101 localStorageActionPointer = actionCollectionPointer->addAction(QLatin1String("local_storage"));
102 domStorageActionPointer = actionCollectionPointer->addAction(QLatin1String("dom_storage"));
103 userAgentPrivacyBrowserActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_privacy_browser"));
104 userAgentWebEngineDefaultActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_webengine_default"));
105 userAgentFirefoxLinuxActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_firefox_linux"));
106 userAgentChromiumLinuxActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_chromium_linux"));
107 userAgentFirefoxWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_firefox_windows"));
108 userAgentChromeWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_chrome_windows"));
109 userAgentEdgeWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_edge_windows"));
110 userAgentSafariMacosActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_safari_macos"));
111 userAgentCustomActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_custom"));
112 zoomFactorActionPointer = actionCollectionPointer->addAction(QLatin1String("zoom_factor"));
113 searchEngineMojeekActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_mojeek"));
114 searchEngineMonoclesActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_monocles"));
115 searchEngineMetagerActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_metager"));
116 searchEngineGoogleActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_google"));
117 searchEngineBingActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_bing"));
118 searchEngineYahooActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_yahoo"));
119 searchEngineCustomActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_custom"));
120 viewBookmarksToolBarActionPointer = actionCollectionPointer->addAction(QLatin1String("view_bookmarks_toolbar"));
121 QAction *domainSettingsActionPointer = actionCollectionPointer->addAction(QLatin1String("domain_settings"));
122 cookiesActionPointer = actionCollectionPointer->addAction(QLatin1String("cookies"));
123 findCaseSensitiveActionPointer = actionCollectionPointer->addAction(QLatin1String("find_case_sensitive"));
124 hideFindTextActionPointer = actionCollectionPointer->addAction(QLatin1String("hide_find_actions"));
126 // Create the action groups
127 QActionGroup *userAgentActionGroupPointer = new QActionGroup(this);
128 QActionGroup *searchEngineActionGroupPointer = new QActionGroup(this);
130 // Add the actions to the groups.
131 userAgentActionGroupPointer->addAction(userAgentPrivacyBrowserActionPointer);
132 userAgentActionGroupPointer->addAction(userAgentWebEngineDefaultActionPointer);
133 userAgentActionGroupPointer->addAction(userAgentFirefoxLinuxActionPointer);
134 userAgentActionGroupPointer->addAction(userAgentChromiumLinuxActionPointer);
135 userAgentActionGroupPointer->addAction(userAgentFirefoxWindowsActionPointer);
136 userAgentActionGroupPointer->addAction(userAgentChromeWindowsActionPointer);
137 userAgentActionGroupPointer->addAction(userAgentEdgeWindowsActionPointer);
138 userAgentActionGroupPointer->addAction(userAgentSafariMacosActionPointer);
139 userAgentActionGroupPointer->addAction(userAgentCustomActionPointer);
140 searchEngineActionGroupPointer->addAction(searchEngineMojeekActionPointer);
141 searchEngineActionGroupPointer->addAction(searchEngineMonoclesActionPointer);
142 searchEngineActionGroupPointer->addAction(searchEngineMetagerActionPointer);
143 searchEngineActionGroupPointer->addAction(searchEngineGoogleActionPointer);
144 searchEngineActionGroupPointer->addAction(searchEngineBingActionPointer);
145 searchEngineActionGroupPointer->addAction(searchEngineYahooActionPointer);
146 searchEngineActionGroupPointer->addAction(searchEngineCustomActionPointer);
148 // Set some actions to be checkable.
149 javaScriptActionPointer->setCheckable(true);
150 localStorageActionPointer->setCheckable(true);
151 domStorageActionPointer->setCheckable(true);
152 findCaseSensitiveActionPointer->setCheckable(true);
153 viewSourceActionPointer->setCheckable(true);
154 developerToolsActionPointer->setCheckable(true);
155 userAgentPrivacyBrowserActionPointer->setCheckable(true);
156 userAgentWebEngineDefaultActionPointer->setCheckable(true);
157 userAgentFirefoxLinuxActionPointer->setCheckable(true);
158 userAgentChromiumLinuxActionPointer->setCheckable(true);
159 userAgentFirefoxWindowsActionPointer->setCheckable(true);
160 userAgentChromeWindowsActionPointer->setCheckable(true);
161 userAgentEdgeWindowsActionPointer->setCheckable(true);
162 userAgentSafariMacosActionPointer->setCheckable(true);
163 userAgentCustomActionPointer->setCheckable(true);
164 searchEngineMojeekActionPointer->setCheckable(true);
165 searchEngineMonoclesActionPointer->setCheckable(true);
166 searchEngineMetagerActionPointer->setCheckable(true);
167 searchEngineGoogleActionPointer->setCheckable(true);
168 searchEngineBingActionPointer->setCheckable(true);
169 searchEngineYahooActionPointer->setCheckable(true);
170 searchEngineCustomActionPointer->setCheckable(true);
171 viewBookmarksToolBarActionPointer->setCheckable(true);
173 // Instantiate the user agent helper.
174 UserAgentHelper *userAgentHelperPointer = new UserAgentHelper();
176 // Set the action text.
177 newTabActionPointer->setText(i18nc("New tab action", "New Tab"));
178 newWindowActionPointer->setText(i18nc("New window action", "New Window"));
179 saveArchiveActionPointer->setText(i18nc("Save archive action", "Save Archive"));
180 zoomDefaultActionPointer->setText(i18nc("Zoom default action", "Zoom Default"));
181 reloadAndBypassCacheActionPointer->setText(i18nc("Reload and bypass cache action", "Reload and Bypass Cache"));
182 viewSourceActionPointer->setText(i18nc("View source action", "View Source"));
183 viewSourceInNewTabActionPointer->setText(i18nc("View source in new tab action", "View Source in New Tab"));
184 developerToolsActionPointer->setText(i18nc("Developer tools action", "Developer Tools"));
185 javaScriptActionPointer->setText(i18nc("JavaScript action", "JavaScript"));
186 localStorageActionPointer->setText(i18nc("The Local Storage action", "Local Storage"));
187 domStorageActionPointer->setText(i18nc("DOM Storage action", "DOM Storage"));
188 userAgentPrivacyBrowserActionPointer->setText(userAgentHelperPointer->PRIVACY_BROWSER_TRANSLATED);
189 userAgentWebEngineDefaultActionPointer->setText(userAgentHelperPointer->WEB_ENGINE_DEFAULT_TRANSLATED);
190 userAgentFirefoxLinuxActionPointer->setText(userAgentHelperPointer->FIREFOX_LINUX_TRANSLATED);
191 userAgentChromiumLinuxActionPointer->setText(userAgentHelperPointer->CHROMIUM_LINUX_TRANSLATED);
192 userAgentFirefoxWindowsActionPointer->setText(userAgentHelperPointer->FIREFOX_WINDOWS_TRANSLATED);
193 userAgentChromeWindowsActionPointer->setText(userAgentHelperPointer->CHROME_WINDOWS_TRANSLATED);
194 userAgentEdgeWindowsActionPointer->setText(userAgentHelperPointer->EDGE_WINDOWS_TRANSLATED);
195 userAgentSafariMacosActionPointer->setText(userAgentHelperPointer->SAFARI_MACOS_TRANSLATED);
196 searchEngineMojeekActionPointer->setText(i18nc("Search engine", "Mojeek"));
197 searchEngineMonoclesActionPointer->setText(i18nc("Search engine", "Monocles"));
198 searchEngineMetagerActionPointer->setText(i18nc("Search engine", "MetaGer"));
199 searchEngineGoogleActionPointer->setText(i18nc("Search engine", "Google"));
200 searchEngineBingActionPointer->setText(i18nc("Search engine", "Bing"));
201 searchEngineYahooActionPointer->setText(i18nc("Search engine", "Yahoo"));
202 viewBookmarksToolBarActionPointer->setText(i18nc("View bookmarks toolbar", "View Bookmarks Toolbar"));
203 domainSettingsActionPointer->setText(i18nc("Domain Settings action", "Domain Settings"));
204 cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", 0));
205 findCaseSensitiveActionPointer->setText(i18nc("Find Case Sensitive action", "Find Case Sensitive"));
206 hideFindTextActionPointer->setText(i18nc("Hide Find Text action (the text should include the language-specific escape keyboard shortcut).", "Hide Find Text (Esc)"));
208 // Set the action icons. Gnome doesn't contain some of the icons that KDE has.
209 // The toolbar icons don't pick up unless the size is explicit, probably because the toolbar ends up being an intermediate size.
210 newTabActionPointer->setIcon(QIcon::fromTheme(QLatin1String("tab-new")));
211 newWindowActionPointer->setIcon(QIcon::fromTheme(QLatin1String("window-new")));
212 saveArchiveActionPointer->setIcon(QIcon::fromTheme(QLatin1String("document-save")));
213 zoomDefaultActionPointer->setIcon(QIcon::fromTheme(QLatin1String("zoom-fit-best")));
214 reloadAndBypassCacheActionPointer->setIcon(QIcon::fromTheme(QLatin1String("view-refresh")));
215 viewSourceActionPointer->setIcon(QIcon::fromTheme(QLatin1String("view-choose"), QIcon::fromTheme(QLatin1String("accessories-text-editor"))));
216 viewSourceInNewTabActionPointer->setIcon(QIcon::fromTheme(QLatin1String("view-choose"), QIcon::fromTheme(QLatin1String("accessories-text-editor"))));
217 developerToolsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("add-subtitle"), QIcon::fromTheme("system-run")));
218 domStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("code-class"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/actions/gtk-unindent-ltr.png"))));
219 userAgentPrivacyBrowserActionPointer->setIcon(QIcon(":/icons/privacy-mode.svg"));
220 userAgentWebEngineDefaultActionPointer->setIcon(QIcon::fromTheme(QLatin1String("qtlogo"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
221 userAgentFirefoxLinuxActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"),
222 QIcon::fromTheme(QLatin1String("contact-new")))));
223 userAgentChromiumLinuxActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
224 userAgentFirefoxWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"),
225 QIcon::fromTheme(QLatin1String("contact-new")))));
226 userAgentChromeWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
227 userAgentEdgeWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
228 userAgentSafariMacosActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
229 userAgentCustomActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
230 searchEngineMojeekActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
231 searchEngineMonoclesActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
232 searchEngineMetagerActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
233 searchEngineGoogleActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-google"), QIcon::fromTheme(QLatin1String("edit-find"))));
234 searchEngineBingActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
235 searchEngineYahooActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-yahoo"), QIcon::fromTheme(QLatin1String("edit-find"))));
236 searchEngineCustomActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
237 zoomFactorActionPointer->setIcon(QIcon::fromTheme(QLatin1String("zoom-fit-best")));
238 editBookmarksActionPointer->setIcon(QIcon::fromTheme(QLatin1String("bookmark-edit"), QIcon::fromTheme(QLatin1String("bookmark-new"))));
239 viewBookmarksToolBarActionPointer->setIcon(QIcon::fromTheme(QLatin1String("bookmarks"), QIcon::fromTheme(QLatin1String("bookmark-new"))));
240 domainSettingsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("settings-configure"), QIcon::fromTheme(QLatin1String("preferences-desktop"))));
241 cookiesActionPointer->setIcon(QIcon::fromTheme(QLatin1String("preferences-web-browser-cookies"), QIcon::fromTheme(QLatin1String("appointment-new"))));
242 findCaseSensitiveActionPointer->setIcon(QIcon::fromTheme(QLatin1String("format-text-lowercase"), QIcon::fromTheme(QLatin1String("/usr/share/icons/gnome/32x32/apps/fonts.png"))));
243 hideFindTextActionPointer->setIcon(QIcon::fromTheme(QLatin1String("window-close-symbolic")));
245 // Create the key sequences.
246 QKeySequence ctrlTKeySequence = QKeySequence(i18nc("The open new tab key sequence.", "Ctrl+T"));
247 QKeySequence ctrlNKeySequence = QKeySequence(i18nc("The open new window key sequence.", "Ctrl+N"));
248 QKeySequence ctrlAKeySequence = QKeySequence(i18nc("The save archive key sequence.", "Ctrl+A"));
249 QKeySequence ctrl0KeySequence = QKeySequence(i18nc("The zoom default key sequence.", "Ctrl+0"));
250 QKeySequence ctrlF5KeySequence = QKeySequence(i18nc("The reload and bypass cache key sequence.", "Ctrl+F5"));
251 QKeySequence ctrlUKeySequence = QKeySequence(i18nc("The view source key sequence.", "Ctrl+U"));
252 QKeySequence ctrlShiftUKeySequence = QKeySequence(i18nc("The view source in new tab key sequence.", "Ctrl+Shift+U"));
253 QKeySequence f12KeySequence = QKeySequence(i18nc("The developer tools key sequence.", "F12"));
254 QKeySequence ctrlShiftPKeySequence = QKeySequence(i18nc("The print preview key sequence.", "Ctrl+Shift+P"));
255 QKeySequence ctrlJKeySequence = QKeySequence(i18nc("The JavaScript key sequence.", "Ctrl+J"));
256 QKeySequence ctrlLKeySequence = QKeySequence(i18nc("The local storage key sequence.", "Ctrl+L"));
257 QKeySequence ctrlDKeySequence = QKeySequence(i18nc("The DOM storage key sequence.", "Ctrl+D"));
258 QKeySequence ctrlSKeySequence = QKeySequence(i18nc("The find case sensitive key sequence.", "Ctrl+S"));
259 QKeySequence ctrlAltPKeySequence = QKeySequence(i18nc("The Privacy Browser user agent key sequence.", "Ctrl+Alt+P"));
260 QKeySequence ctrlAltWKeySequence = QKeySequence(i18nc("The WebEngine Default user agent key sequence.", "Ctrl+Alt+W"));
261 QKeySequence ctrlAltFKeySequence = QKeySequence(i18nc("The Firefox on Linux user agent key sequence.", "Ctrl+Alt+F"));
262 QKeySequence ctrlAltCKeySequence = QKeySequence(i18nc("The Chromium on Linux user agent key sequence.", "Ctrl+Alt+C"));
263 QKeySequence ctrlAltShiftFKeySequence = QKeySequence(i18nc("The Firefox on Windows user agent key sequence.", "Ctrl+Alt+Shift+F"));
264 QKeySequence ctrlAltShiftCKeySequence = QKeySequence(i18nc("The Chrome on Windows user agent key sequence.", "Ctrl+Alt+Shift+C"));
265 QKeySequence ctrlAltEKeySequence = QKeySequence(i18nc("The Edge on Windows user agent key sequence.", "Ctrl+Alt+E"));
266 QKeySequence ctrlAltSKeySequence = QKeySequence(i18nc("The Safari on macOS user agent key sequence.", "Ctrl+Alt+S"));
267 QKeySequence altShiftCKeySequence = QKeySequence(i18nc("The custom user agent key sequence.", "Alt+Shift+C"));
268 QKeySequence ctrlAltZKeySequence = QKeySequence(i18nc("The zoom factor key sequence.", "Ctrl+Alt+Z"));
269 QKeySequence ctrlShiftMKeySequence = QKeySequence(i18nc("The Mojeek search engine key sequence.", "Ctrl+Shift+M"));
270 QKeySequence ctrlShiftOKeySequence = QKeySequence(i18nc("The Monocles search engine key sequence.", "Ctrl+Shift+O"));
271 QKeySequence ctrlShiftEKeySequence = QKeySequence(i18nc("The MetaGer search engine key sequence.", "Ctrl+Shift+E"));
272 QKeySequence ctrlShiftGKeySequence = QKeySequence(i18nc("The Google search engine key sequence.", "Ctrl+Shift+G"));
273 QKeySequence ctrlShiftBKeySequence = QKeySequence(i18nc("The Bing search engine key sequence.", "Ctrl+Shift+B"));
274 QKeySequence ctrlShiftYKeySequence = QKeySequence(i18nc("The Yahoo search engine key sequence.", "Ctrl+Shift+Y"));
275 QKeySequence ctrlShiftCKeySequence = QKeySequence(i18nc("The custom search engine key sequence.", "Ctrl+Shift+C"));
276 QKeySequence ctrlAltShiftBKeySequence = QKeySequence(i18nc("The edit bookmarks key sequence.", "Ctrl+Alt+Shift+B"));
277 QKeySequence ctrlAltBKeySequence = QKeySequence(i18nc("The view bookmarks toolbar key sequence.", "Ctrl+Alt+B"));
278 QKeySequence ctrlShiftDKeySequence = QKeySequence(i18nc("The domain settings key sequence.", "Ctrl+Shift+D"));
279 QKeySequence ctrlSemicolonKeySequence = QKeySequence(i18nc("The cookies dialog key sequence.", "Ctrl+;"));
281 // Set the action key sequences.
282 actionCollectionPointer->setDefaultShortcut(newTabActionPointer, ctrlTKeySequence);
283 actionCollectionPointer->setDefaultShortcut(newWindowActionPointer, ctrlNKeySequence);
284 actionCollectionPointer->setDefaultShortcut(saveArchiveActionPointer, ctrlAKeySequence);
285 actionCollectionPointer->setDefaultShortcut(zoomDefaultActionPointer, ctrl0KeySequence);
286 actionCollectionPointer->setDefaultShortcut(reloadAndBypassCacheActionPointer, ctrlF5KeySequence);
287 actionCollectionPointer->setDefaultShortcut(viewSourceActionPointer, ctrlUKeySequence);
288 actionCollectionPointer->setDefaultShortcut(viewSourceInNewTabActionPointer, ctrlShiftUKeySequence);
289 actionCollectionPointer->setDefaultShortcut(developerToolsActionPointer, f12KeySequence);
290 actionCollectionPointer->setDefaultShortcut(printPreviewActionPointer, ctrlShiftPKeySequence);
291 actionCollectionPointer->setDefaultShortcut(javaScriptActionPointer, ctrlJKeySequence);
292 actionCollectionPointer->setDefaultShortcut(localStorageActionPointer, ctrlLKeySequence);
293 actionCollectionPointer->setDefaultShortcut(domStorageActionPointer, ctrlDKeySequence);
294 actionCollectionPointer->setDefaultShortcut(findCaseSensitiveActionPointer, ctrlSKeySequence);
295 actionCollectionPointer->setDefaultShortcut(userAgentPrivacyBrowserActionPointer, ctrlAltPKeySequence);
296 actionCollectionPointer->setDefaultShortcut(userAgentWebEngineDefaultActionPointer, ctrlAltWKeySequence);
297 actionCollectionPointer->setDefaultShortcut(userAgentFirefoxLinuxActionPointer, ctrlAltFKeySequence);
298 actionCollectionPointer->setDefaultShortcut(userAgentChromiumLinuxActionPointer, ctrlAltCKeySequence);
299 actionCollectionPointer->setDefaultShortcut(userAgentFirefoxWindowsActionPointer, ctrlAltShiftFKeySequence);
300 actionCollectionPointer->setDefaultShortcut(userAgentChromeWindowsActionPointer, ctrlAltShiftCKeySequence);
301 actionCollectionPointer->setDefaultShortcut(userAgentEdgeWindowsActionPointer, ctrlAltEKeySequence);
302 actionCollectionPointer->setDefaultShortcut(userAgentSafariMacosActionPointer, ctrlAltSKeySequence);
303 actionCollectionPointer->setDefaultShortcut(userAgentCustomActionPointer, altShiftCKeySequence);
304 actionCollectionPointer->setDefaultShortcut(zoomFactorActionPointer, ctrlAltZKeySequence);
305 actionCollectionPointer->setDefaultShortcut(searchEngineMojeekActionPointer, ctrlShiftMKeySequence);
306 actionCollectionPointer->setDefaultShortcut(searchEngineMonoclesActionPointer, ctrlShiftOKeySequence);
307 actionCollectionPointer->setDefaultShortcut(searchEngineMetagerActionPointer, ctrlShiftEKeySequence);
308 actionCollectionPointer->setDefaultShortcut(searchEngineGoogleActionPointer, ctrlShiftGKeySequence);
309 actionCollectionPointer->setDefaultShortcut(searchEngineBingActionPointer, ctrlShiftBKeySequence);
310 actionCollectionPointer->setDefaultShortcut(searchEngineYahooActionPointer, ctrlShiftYKeySequence);
311 actionCollectionPointer->setDefaultShortcut(searchEngineCustomActionPointer, ctrlShiftCKeySequence);
312 actionCollectionPointer->setDefaultShortcut(editBookmarksActionPointer, ctrlAltShiftBKeySequence);
313 actionCollectionPointer->setDefaultShortcut(viewBookmarksToolBarActionPointer, ctrlAltBKeySequence);
314 actionCollectionPointer->setDefaultShortcut(domainSettingsActionPointer, ctrlShiftDKeySequence);
315 actionCollectionPointer->setDefaultShortcut(cookiesActionPointer, ctrlSemicolonKeySequence);
317 // Execute the actions.
318 connect(newTabActionPointer, SIGNAL(triggered()), tabWidgetPointer, SLOT(addTab()));
319 connect(newWindowActionPointer, SIGNAL(triggered()), this, SLOT(newWindow()));
320 connect(saveArchiveActionPointer, SIGNAL(triggered()), tabWidgetPointer, SLOT(saveArchive()));
321 connect(zoomDefaultActionPointer, SIGNAL(triggered()), this, SLOT(zoomDefault()));
322 connect(reloadAndBypassCacheActionPointer, SIGNAL(triggered()), this, SLOT(reloadAndBypassCache()));
323 connect(viewSourceActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewSource()));
324 connect(viewSourceInNewTabActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewSourceInNewTab()));
325 connect(developerToolsActionPointer, SIGNAL(triggered()), this, SLOT(toggleDeveloperTools()));
326 connect(zoomFactorActionPointer, SIGNAL(triggered()), this, SLOT(getZoomFactorFromUser()));
327 connect(viewBookmarksToolBarActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewBookmarksToolBar()));
328 connect(cookiesActionPointer, SIGNAL(triggered()), this, SLOT(showCookiesDialog()));
329 connect(domainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(showDomainSettingsDialog()));
331 // Update the on-the-fly menus.
332 connect(tabWidgetPointer, SIGNAL(updateUserAgentActions(QString, bool)), this, SLOT(updateUserAgentActions(QString, bool)));
333 connect(tabWidgetPointer, SIGNAL(updateZoomActions(double)), this, SLOT(updateZoomActions(double)));
334 connect(tabWidgetPointer, SIGNAL(updateSearchEngineActions(QString, bool)), this, SLOT(updateSearchEngineActions(QString, bool)));
336 // Apply the on-the-fly settings when selected.
337 connect(userAgentActionGroupPointer, SIGNAL(triggered(QAction*)), tabWidgetPointer, SLOT(applyOnTheFlyUserAgent(QAction*)));
338 connect(searchEngineActionGroupPointer, SIGNAL(triggered(QAction*)), tabWidgetPointer, SLOT(applyOnTheFlySearchEngine(QAction*)));
340 // Process cookie changes.
341 connect(tabWidgetPointer, SIGNAL(updateCookiesAction(int)), this, SLOT(updateCookiesAction(int)));
343 // Store the default zoom factor.
344 connect(tabWidgetPointer, SIGNAL(updateDefaultZoomFactor(double)), this, SLOT(updateDefaultZoomFactor(double)));
346 // Connect the URL toolbar actions.
347 connect(javaScriptActionPointer, SIGNAL(triggered()), this, SLOT(toggleJavaScript()));
348 connect(localStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleLocalStorage()));
349 connect(domStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleDomStorage()));
351 // Update the actions from the tab widget.
352 connect(tabWidgetPointer, SIGNAL(updateDeveloperToolsAction(bool)), developerToolsActionPointer, SLOT(setChecked(bool)));
353 connect(tabWidgetPointer, SIGNAL(updateBackAction(bool)), backActionPointer, SLOT(setEnabled(bool)));
354 connect(tabWidgetPointer, SIGNAL(updateForwardAction(bool)), forwardActionPointer, SLOT(setEnabled(bool)));
355 connect(tabWidgetPointer, SIGNAL(updateJavaScriptAction(bool)), this, SLOT(updateJavaScriptAction(bool)));
356 connect(tabWidgetPointer, SIGNAL(updateLocalStorageAction(bool)), this, SLOT(updateLocalStorageAction(bool)));
357 connect(tabWidgetPointer, SIGNAL(updateDomStorageAction(bool)), this, SLOT(updateDomStorageAction(bool)));
359 // Connect the find text actions.
360 connect(findCaseSensitiveActionPointer, SIGNAL(triggered()), this, SLOT(toggleFindCaseSensitive()));
361 connect(hideFindTextActionPointer, SIGNAL(triggered()), this, SLOT(hideFindTextActions()));
365 // Setup the GUI based on the browserwindowui.rc file.
366 setupGUI(StandardWindowOption::Default, ("browserwindowui.rc"));
368 // Get lists of the actions' associated widgets.
369 QList<QWidget*> userAgentAssociatedWidgetsPointerList = userAgentPrivacyBrowserActionPointer->associatedWidgets();
370 QList<QWidget*> searchEngineAssociatedWidgetsPointerList = searchEngineMojeekActionPointer->associatedWidgets();
372 // Get the menu widget pointers. It is the second entry, after the main window.
373 QWidget *userAgentMenuWidgetPointer = userAgentAssociatedWidgetsPointerList[1];
374 QWidget *searchEngineMenuWidgetPointer = searchEngineAssociatedWidgetsPointerList[1];
376 // Get the menu pointers.
377 QMenu *userAgentMenuPointer = qobject_cast<QMenu*>(userAgentMenuWidgetPointer);
378 QMenu *searchEngineMenuPointer = qobject_cast<QMenu*>(searchEngineMenuWidgetPointer);
380 // Get the menu actions.
381 userAgentMenuActionPointer = userAgentMenuPointer->menuAction();
382 searchEngineMenuActionPointer = searchEngineMenuPointer->menuAction();
384 // Get handles for the toolbars.
385 navigationToolBarPointer = toolBar(QLatin1String("navigation_toolbar"));
386 urlToolBarPointer = toolBar(QLatin1String("url_toolbar"));
387 bookmarksToolBarPointer = toolBar(QLatin1String("bookmarks_toolbar"));
389 // Populate the view bookmarks toolbar checkbox.
390 connect(bookmarksToolBarPointer, SIGNAL(visibilityChanged(bool)), this, SLOT(updateViewBookmarksToolBarCheckbox(bool)));
392 // Create the line edits.
393 urlLineEditPointer = new KLineEdit();
394 findTextLineEditPointer = new KLineEdit();
396 // Get the line edit size policies.
397 QSizePolicy urlLineEditSizePolicy = urlLineEditPointer->sizePolicy();
398 QSizePolicy findTextLineEditSizePolicy = findTextLineEditPointer->sizePolicy();
400 // Set the URL line edit horizontal stretch to be five times the find text line edit stretch.
401 urlLineEditSizePolicy.setHorizontalStretch(5);
402 findTextLineEditSizePolicy.setHorizontalStretch(1);
405 urlLineEditPointer->setSizePolicy(urlLineEditSizePolicy);
406 findTextLineEditPointer->setSizePolicy(findTextLineEditSizePolicy);
409 urlLineEditPointer->setMinimumWidth(350);
410 findTextLineEditPointer->setMinimumWidth(200);
411 findTextLineEditPointer->setMaximumWidth(350);
413 // Set the place holder text.
414 urlLineEditPointer->setPlaceholderText(i18nc("The URL line edit placeholder text", "URL or Search Terms"));
415 findTextLineEditPointer->setPlaceholderText(i18nc("The find line edit placeholder text", "Find Text"));
417 // Show the clear button on the find line edit.
418 findTextLineEditPointer->setClearButtonEnabled(true);
420 // Add the actions to the URL line edit.
421 bookmarkedActionPointer = urlLineEditPointer->addAction(QIcon::fromTheme("non-starred-symbolic"), QLineEdit::LeadingPosition);
422 QAction *addOrEditDomainSettingsActionPointer = urlLineEditPointer->addAction(QIcon::fromTheme("settings-configure", QIcon::fromTheme(QLatin1String("preferences-desktop"))),
423 QLineEdit::TrailingPosition);
425 // Set the bookmarked action pointer to be checkable.
426 bookmarkedActionPointer->setCheckable(true);
428 // Connect the URL line edit actions.
429 connect(bookmarkedActionPointer, SIGNAL(triggered()), this, SLOT(toggleBookmark()));
430 connect(addOrEditDomainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(addOrEditDomainSettings()));
432 // Create a find text label pointer.
433 findTextLabelPointer = new QLabel();
435 // Set the default label text.
436 findTextLabelPointer->setText(QLatin1String(" ") + i18nc("Default find results.", "0/0") + QLatin1String(" "));
438 // Insert the widgets into the toolbars.
439 urlToolBarPointer->insertWidget(javaScriptActionPointer, urlLineEditPointer);
440 findTextLineEditActionPointer = urlToolBarPointer->insertWidget(findNextActionPointer, findTextLineEditPointer);
441 findTextLabelActionPointer = urlToolBarPointer->insertWidget(findNextActionPointer, findTextLabelPointer);
443 // Initially hide the find text actions.
444 hideFindTextActions();
446 // Load a new URL from the URL line edit.
447 connect(urlLineEditPointer, SIGNAL(returnKeyPressed(const QString)), this, SLOT(loadUrlFromLineEdit(const QString)));
449 // Find text as it is typed.
450 connect(findTextLineEditPointer, SIGNAL(textEdited(const QString &)), tabWidgetPointer, SLOT(findText(const QString &)));
452 // Find next if the enter key is pressed.
453 connect(findTextLineEditPointer, SIGNAL(returnKeyPressed(const QString &)), tabWidgetPointer, SLOT(findText(const QString &)));
455 // Update find text when switching tabs.
456 connect(tabWidgetPointer, SIGNAL(updateFindText(const QString &, const bool)), this, SLOT(updateFindText(const QString &, const bool)));
458 // Update the find text results.
459 connect(tabWidgetPointer, SIGNAL(updateFindTextResults(const QWebEngineFindTextResult &)), this, SLOT(updateFindTextResults(const QWebEngineFindTextResult &)));
461 // Update the URL line edit on page loads.
462 connect(tabWidgetPointer, SIGNAL(updateUrlLineEdit(QUrl)), this, SLOT(updateUrlLineEdit(QUrl)));
464 // Update the window title.
465 connect(tabWidgetPointer, SIGNAL(updateWindowTitle(const QString)), this, SLOT(updateWindowTitle(const QString)));
467 // Get a handle for the status bar.
468 QStatusBar *statusBarPointer = statusBar();
470 // Create the status bar widgets.
471 progressBarPointer = new QProgressBar();
472 zoomMinusButtonPointer = new QPushButton();
473 currentZoomButtonPointer = new QPushButton();
474 zoomPlusButtonPointer = new QPushButton();
476 // Set the button icons.
477 zoomMinusButtonPointer->setIcon(QIcon::fromTheme(QStringLiteral("list-remove-symbolic")));
478 zoomPlusButtonPointer->setIcon(QIcon::fromTheme(QStringLiteral("list-add-symbolic")));
480 // Set the button icons to be flat (no borders).
481 zoomMinusButtonPointer->setFlat(true);
482 currentZoomButtonPointer->setFlat(true);
483 zoomPlusButtonPointer->setFlat(true);
485 // Handle clicks on the zoom buttons.
486 connect(zoomMinusButtonPointer, SIGNAL(clicked()), this, SLOT(decrementZoom()));
487 connect(currentZoomButtonPointer, SIGNAL(clicked()), this, SLOT(getZoomFactorFromUser()));
488 connect(zoomPlusButtonPointer, SIGNAL(clicked()), this, SLOT(incrementZoom()));
490 // Remove the padding around the current zoom button text.
491 currentZoomButtonPointer->setStyleSheet("padding: 0px;");
493 // Add the widgets to the far right of the status bar.
494 statusBarPointer->addPermanentWidget(progressBarPointer);
495 statusBarPointer->addPermanentWidget(zoomMinusButtonPointer);
496 statusBarPointer->addPermanentWidget(currentZoomButtonPointer);
497 statusBarPointer->addPermanentWidget(zoomPlusButtonPointer);
499 // Update the status bar with the URL when a link is hovered.
500 connect(tabWidgetPointer, SIGNAL(linkHovered(QString)), statusBarPointer, SLOT(showMessage(QString)));
502 // Update the progress bar.
503 connect(tabWidgetPointer, SIGNAL(showProgressBar(const int)), this, SLOT(showProgressBar(const int)));
504 connect(tabWidgetPointer, SIGNAL(hideProgressBar()), progressBarPointer, SLOT(hide()));
506 // Update the URL line edit focus.
507 connect(tabWidgetPointer, SIGNAL(clearUrlLineEditFocus()), this, SLOT(clearUrlLineEditFocus()));
509 // Get the URL line edit palettes.
510 normalBackgroundPalette = urlLineEditPointer->palette();
511 negativeBackgroundPalette = normalBackgroundPalette;
512 positiveBackgroundPalette = normalBackgroundPalette;
514 // Modify the palettes.
515 KColorScheme::adjustBackground(negativeBackgroundPalette, KColorScheme::NegativeBackground);
516 KColorScheme::adjustBackground(positiveBackgroundPalette, KColorScheme::PositiveBackground);
518 // Update the applied palette.
519 connect(tabWidgetPointer, SIGNAL(updateDomainSettingsIndicator(const bool)), this, SLOT(updateDomainSettingsIndicator(const bool)));
521 // Process full screen requests.
522 connect(tabWidgetPointer, SIGNAL(fullScreenRequested(bool)), this, SLOT(fullScreenRequested(bool)));
524 // Create keyboard shortcuts.
525 QShortcut *f11ShortcutPointer = new QShortcut(QKeySequence(i18nc("The toggle full screen shortcut.", "F11")), this);
526 QShortcut *escapeShortcutPointer = new QShortcut(QKeySequence::Cancel, this);
528 // Connect the keyboard shortcuts.
529 connect(f11ShortcutPointer, SIGNAL(activated()), fullScreenActionPointer, SLOT(trigger()));
530 connect(escapeShortcutPointer, SIGNAL(activated()), this, SLOT(escape()));
532 // Get a handle for the Bookmarks menu.
533 bookmarksMenuPointer = qobject_cast<QMenu*>(guiFactory()->container("bookmarks", this));
535 // Add a separator to the bookmarks menu.
536 bookmarksMenuPointer->addSeparator();
538 // Initialize the current bookmarks lists.
539 finalBookmarkFolderMenuActionList = QList<QPair<QMenu *, QAction *> *>();
540 bookmarksMenuActionList = QList<QPair<QMenu *, QAction *> *>();
541 bookmarksMenuSubmenuList = QList<QPair<QMenu *, QMenu *> *>();
542 bookmarksToolBarActionList = QList<QAction*>();
543 bookmarksToolBarSubfolderActionList = QList<QPair<QMenu *, QAction * > *>();
545 // Set the bookmarks toolbar context menu policy.
546 bookmarksToolBarPointer->setContextMenuPolicy(Qt::CustomContextMenu);
548 // Show the custom bookmark context menu when requested.
549 connect(bookmarksToolBarPointer, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showBookmarkContextMenu(const QPoint&)));
551 // Populate the bookmarks in this window.
552 populateBookmarksInThisWindow();
555 // 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.
556 updateJavaScriptAction(Settings::javaScriptEnabled());
557 updateLocalStorageAction(Settings::localStorageEnabled());
558 updateDomStorageAction(Settings::domStorageEnabled());
559 updateUserAgentActions(UserAgentHelper::getUserAgentFromDatabaseName(Settings::userAgent()), true);
560 updateZoomActions(Settings::zoomFactor());
562 // Populate the first tab.
563 if (firstWindow) // This is the first window.
565 // Load the initial website.
566 tabWidgetPointer->loadInitialWebsite();
568 else if (initialUrlStringPointer) // An initial URL was specified.
570 // Load the initial URL.
571 tabWidgetPointer->loadUrlFromLineEdit(*initialUrlStringPointer);
575 void BrowserWindow::addFinalBookmarkFolderMenuActions(QMenu *menuPointer, double folderId)
577 // Get the database ID.
578 int folderDatabaseId = BookmarksDatabase::getFolderDatabaseId(folderId);
581 menuPointer->addSeparator();
583 // Add the add bookmark action to the menu.
584 QAction *addBookmarkActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("bookmark-new")), i18nc("The add bookmark action", "Add Bookmark"), [=]
586 // Instantiate an add bookmark dialog.
587 AddBookmarkDialog *addBookmarkDialogPointer = new AddBookmarkDialog(tabWidgetPointer->getCurrentTabTitle(), tabWidgetPointer->getCurrentTabUrl(),
588 tabWidgetPointer->getCurrentTabFavoritIcon(), folderId);
590 // Update the displayed bookmarks when a new one is added.
591 connect(addBookmarkDialogPointer, SIGNAL(bookmarkAdded()), this, SLOT(populateBookmarksInAllWindows()));
594 addBookmarkDialogPointer->show();
598 // Add the add folder action to the menu.
599 QAction *addFolderActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("folder-add")), i18nc("The add folder action", "Add Folder"), [=]
601 // Instantiate an add folder dialog.
602 AddFolderDialog *addFolderDialogPointer = new AddFolderDialog(tabWidgetPointer->getCurrentTabFavoritIcon(), folderId);
604 // Update the displayed bookmarks when a folder is added.
605 connect(addFolderDialogPointer, SIGNAL(folderAdded()), this, SLOT(populateBookmarksInAllWindows()));
608 addFolderDialogPointer->show();
613 menuPointer->addSeparator();
615 // Add the open folder in new tabs action to the menu.
616 QAction *openFolderInNewTabsActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("The open folder in new tabs action", "Open Folder in New Tabs"), [=]
618 // Get all the folder URLs.
619 QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(folderId);
621 // Open the URLs in new tabs. `true` removes the URL line edit focus, `false` does not load a background tab.
622 for (QString url : *folderUrlsListPointer)
623 tabWidgetPointer->addTab(true, false, url);
627 // Add the open folder in background tabs action to the menu.
628 QAction *openFolderInBackgroundTabsActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")),
629 i18nc("The open folder in background tabs action", "Open Folder in Background Tabs"), [=]
631 // Get all the folder URLs.
632 QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(folderId);
634 // Open the URLs in new tabs. `true` removes the URL line edit focus, `true` loads a background tab.
635 for (QString url : *folderUrlsListPointer)
636 tabWidgetPointer->addTab(true, true, url);
640 // Add the open folder in new window action to the menu.
641 QAction *openFolderInNewWindowActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("window-new")), i18nc("The open folder in new window action", "Open Folder in New Window"), [=]
643 // Get all the folder URLs.
644 QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(folderId);
646 // Create a new browser window.
647 BrowserWindow *browserWindowPointer = new BrowserWindow(false, &folderUrlsListPointer->first());
649 // Get a count of the folder URLs.
650 const int folderUrls = folderUrlsListPointer->count();
652 // Load all the other URLs. `true` removes the URL line edit focus, `true` loads a background tab.
653 for (int i = 1; i < folderUrls; ++i)
654 browserWindowPointer->tabWidgetPointer->addTab(true, true, folderUrlsListPointer->value(i));
656 // Show the new browser window.
657 browserWindowPointer->show();
662 menuPointer->addSeparator();
664 // Add the edit folder action to the menu if this is not the root bookmark menu.
667 QAction *editFolderActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("document-edit")), i18nc("The edit folder action", "Edit Folder"), [=]
669 // Get the current tab favorite icon.
670 QIcon currentTabFavoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
672 // Instantiate an edit folder dialog.
673 QDialog *editFolderDialogPointer = new EditFolderDialog(folderDatabaseId, currentTabFavoriteIcon);
676 editFolderDialogPointer->show();
678 // Process bookmark events.
679 connect(editFolderDialogPointer, SIGNAL(folderSaved()), this, SLOT(populateBookmarksInAllWindows()));
683 // Add the action to the beginning of the final bookmark folder menu action list.
684 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, editFolderActionPointer));
687 // Add the delete folder action to the menu.
688 QAction *deleteFolderActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-delete")), i18nc("Delete folder context menu entry", "Delete Folder"), [=]
690 // Create an items to delete list.
691 QList<int>* itemsToDeleteListPointer = new QList<int>;
693 // Add the folder to the list of items to delete if it is not the root folder.
695 itemsToDeleteListPointer->append(folderDatabaseId);
697 // Add the folder contents to the list of items to delete.
698 itemsToDeleteListPointer->append(*BookmarksDatabase::getFolderContentsDatabaseIdsRecursively(folderId));
700 // Instantiate a delete dialog message box.
701 QMessageBox deleteDialogMessageBox;
704 deleteDialogMessageBox.setIcon(QMessageBox::Warning);
706 // Set the window title.
707 deleteDialogMessageBox.setWindowTitle(i18nc("Delete bookmarks dialog title", "Delete Bookmarks"));
710 deleteDialogMessageBox.setText(i18ncp("Delete bookmarks dialog main message", "Delete %1 bookmark item?", "Delete %1 bookmark items?", itemsToDeleteListPointer->count()));
712 // Set the informative text.
713 deleteDialogMessageBox.setInformativeText(i18nc("Delete bookmarks dialog secondary message", "This cannot be undone."));
715 // Set the standard buttons.
716 deleteDialogMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
718 // Set the default button.
719 deleteDialogMessageBox.setDefaultButton(QMessageBox::No);
721 // Display the dialog and capture the return value.
722 int returnValue = deleteDialogMessageBox.exec();
724 // Delete the domain if instructed.
725 if (returnValue == QMessageBox::Yes)
727 // Get the parent folder ID.
728 double parentFolderId = BookmarksDatabase::getParentFolderId(folderDatabaseId);
730 // Delete the folder and its contents.
731 for (const int databaseId : *itemsToDeleteListPointer)
732 BookmarksDatabase::deleteBookmark(databaseId);
734 // Update the display order of the bookmarks in the parent folder.
735 BookmarksDatabase::updateFolderContentsDisplayOrder(parentFolderId);
737 // Repopulate the bookmarks.
738 populateBookmarksInAllWindows();
743 // Add the key sequences if this is the root bookmarks menu.
746 // Create the key sequences.
747 QKeySequence ctrlBKeySequence = QKeySequence(i18nc("The add bookmark key sequence.", "Ctrl+B"));
748 QKeySequence metaFKeySequence = QKeySequence(i18nc("The add folder key sequence.", "Meta+F"));
750 // Set the action key sequences.
751 actionCollectionPointer->setDefaultShortcut(addBookmarkActionPointer, ctrlBKeySequence);
752 actionCollectionPointer->setDefaultShortcut(addFolderActionPointer, metaFKeySequence);
755 // Add the actions to the beginning of the final bookmark folder menu action list.
756 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, addBookmarkActionPointer));
757 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, addFolderActionPointer));
758 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, openFolderInNewTabsActionPointer));
759 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, openFolderInBackgroundTabsActionPointer));
760 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, openFolderInNewWindowActionPointer));
761 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, deleteFolderActionPointer));
764 void BrowserWindow::addOrEditDomainSettings() const
766 // Remove the focus from the URL line edit.
767 urlLineEditPointer->clearFocus();
769 // Create the domain settings dialog pointer.
770 DomainSettingsDialog *domainSettingsDialogPointer;
772 // Get the current domain settings name.
773 QString ¤tDomainSettingsName = tabWidgetPointer->getDomainSettingsName();
775 // Run the commands according to the current domain settings status.
776 if (currentDomainSettingsName == QStringLiteral("")) // Domain settings are not currently applied.
778 // Instruct the domain settings dialog to add a new domain.
779 domainSettingsDialogPointer = new DomainSettingsDialog(DomainSettingsDialog::ADD_DOMAIN, currentUrl.host());
781 else // Domain settings are currently applied.
783 // Instruct the domain settings dialog to edit the current domain.
784 domainSettingsDialogPointer = new DomainSettingsDialog(DomainSettingsDialog::EDIT_DOMAIN, currentDomainSettingsName);
787 // Reload the tabs when domain settings are updated.
788 connect(domainSettingsDialogPointer, SIGNAL(domainSettingsUpdated()), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
791 domainSettingsDialogPointer->show();
794 void BrowserWindow::back() const
796 // Remove the focus from the URL line edit.
797 urlLineEditPointer->clearFocus();
800 tabWidgetPointer->back();
803 void BrowserWindow::clearUrlLineEditFocus() const
805 // Remove the focus from the URL line edit.
806 urlLineEditPointer->clearFocus();
809 void BrowserWindow::decrementZoom()
811 // Update the current zoom factor.
812 currentZoomFactor = currentZoomFactor - 0.25;
814 // Check to make sure the zoom factor is in the valid range (0.25 to 5.00).
815 if (currentZoomFactor < 0.25)
816 currentZoomFactor = 0.25;
818 // Set the new zoom factor.
819 tabWidgetPointer->applyOnTheFlyZoomFactor(currentZoomFactor);
821 // Update the on-the-fly action text.
822 updateZoomActions(currentZoomFactor);
825 void BrowserWindow::editBookmarks() const
827 // Instantiate an edit bookmarks dialog.
828 BookmarksDialog *bookmarksDialogPointer = new BookmarksDialog(tabWidgetPointer->getCurrentTabTitle(), tabWidgetPointer->getCurrentTabUrl(), tabWidgetPointer->getCurrentTabFavoritIcon());
830 // Update the displayed bookmarks when edited.
831 connect(bookmarksDialogPointer, SIGNAL(bookmarkUpdated()), this, SLOT(populateBookmarksInAllWindows()));
834 bookmarksDialogPointer->show();
837 void BrowserWindow::escape() const
839 // Process the escape according to the status of the browser.
840 if (fullScreenActionPointer->isChecked()) // Full screen browsing is enabled.
842 // Exit full screen browsing.
843 fullScreenActionPointer->trigger();
845 else if (!findTextLineEditPointer->text().isEmpty()) // Find text is populated.
847 // Clear the find text line edit.
848 findTextLineEditPointer->clear();
850 // Clear the search in the WebEngine.
851 tabWidgetPointer->findText(QStringLiteral(""));
853 else if (findTextLineEditActionPointer->isVisible()) // Find text actions are visible.
855 // Hide the find text actions.
856 hideFindTextActions();
860 void BrowserWindow::findNext() const
862 // Get the find string.
863 const QString findString = findTextLineEditPointer->text();
865 // Search for the text if it is not empty.
866 if (!findString.isEmpty())
867 tabWidgetPointer->findText(findString);
870 void BrowserWindow::findPrevious() const
872 // Get the find string.
873 const QString findString = findTextLineEditPointer->text();
875 // Search for the text if it is not empty.
876 if (!findString.isEmpty())
877 tabWidgetPointer->findPrevious(findString);
880 void BrowserWindow::forward() const
882 // Remove the focus from the URL line edit.
883 urlLineEditPointer->clearFocus();
886 tabWidgetPointer->forward();
889 void BrowserWindow::fullScreenRequested(const bool toggleOn)
891 // Toggle full screen mode.
892 if (toggleOn) // Turn full screen mode on.
894 // Enable full screen mode.
895 fullScreenActionPointer->setFullScreen(window(), true);
897 // Hide the menu bar if specified.
898 if (Settings::fullScreenHideMenuBar())
899 menuBar()->setVisible(false);
901 // Hide the toolbars if specified.
902 if (Settings::fullScreenHideToolBars())
904 navigationToolBarPointer->setVisible(false);
905 urlToolBarPointer->setVisible(false);
906 bookmarksToolBarPointer->setVisible(false);
909 // Hide the tab bar if specified.
910 if (Settings::fullScreenHideTabBar())
911 tabWidgetPointer->setTabBarVisible(false);
913 // Hide the status bar if specified.
914 if (Settings::fullScreenHideStatusBar())
915 statusBar()->setVisible(false);
917 else // Disable full screen browsing mode.
919 // Disable full screen mode.
920 fullScreenActionPointer->setFullScreen(window(), false);
922 // Show the menu bar.
923 menuBar()->setVisible(true);
925 // Show the toolbars.
926 navigationToolBarPointer->setVisible(true);
927 urlToolBarPointer->setVisible(true);
929 // Only show the bookmarks toolbar if it was previously visible.
930 if (bookmarksToolBarIsVisible)
931 bookmarksToolBarPointer->setVisible(true);
934 tabWidgetPointer->setTabBarVisible(true);
936 // Show the status bar.
937 statusBar()->setVisible(true);
941 void BrowserWindow::getZoomFactorFromUser()
943 // Create an OK flag.
946 // 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.
947 double newZoomFactor = QInputDialog::getDouble(this, i18nc("The on-the-fly zoom factor dialog title", "On-The-Fly Zoom Factor"),
948 i18nc("The instruction text of the on-the-fly zoom factor dialog", "Enter a zoom factor between 0.25 and 5.00"),
949 currentZoomFactor, .025, 5.00, 2, &okClicked, Qt::WindowFlags(), 0.25);
951 // Update the zoom factor if the user clicked OK.
954 // Set the new zoom factor.
955 tabWidgetPointer->applyOnTheFlyZoomFactor(newZoomFactor);
957 // Update the on-the-fly action text.
958 updateZoomActions(newZoomFactor);
962 void BrowserWindow::hideFindTextActions() const
964 // Hide the find text actions.
965 findTextLineEditActionPointer->setVisible(false);
966 findTextLabelActionPointer->setVisible(false);
967 findNextActionPointer->setVisible(false);
968 findPreviousActionPointer->setVisible(false);
969 findCaseSensitiveActionPointer->setVisible(false);
970 hideFindTextActionPointer->setVisible(false);
973 void BrowserWindow::home() const
975 // Remove the focus from the URL line edit.
976 urlLineEditPointer->clearFocus();
979 tabWidgetPointer->home();
982 void BrowserWindow::incrementZoom()
984 // Update the current zoom factor.
985 currentZoomFactor = currentZoomFactor + 0.25;
987 // Check to make sure the zoom factor is in the valid range (0.25 to 5.00).
988 if (currentZoomFactor > 5.0)
989 currentZoomFactor = 5.0;
991 // Set the new zoom factor.
992 tabWidgetPointer->applyOnTheFlyZoomFactor(currentZoomFactor);
994 // Update the on-the-fly action text.
995 updateZoomActions(currentZoomFactor);
998 void BrowserWindow::loadUrlFromLineEdit(const QString &url) const
1000 // Remove the focus from the URL line edit.
1001 urlLineEditPointer->clearFocus();
1004 tabWidgetPointer->loadUrlFromLineEdit(url);
1007 void BrowserWindow::newWindow() const
1009 // Create a new browser window.
1010 BrowserWindow *browserWindowPointer = new BrowserWindow();
1012 // Show the new browser window.
1013 browserWindowPointer->show();
1016 void BrowserWindow::populateBookmarksInAllWindows() const
1018 // Get a list of all the registered service names.
1019 QStringList registeredServiceNames = QDBusConnection::sessionBus().interface()->registeredServiceNames().value();
1021 // Get a list of all the Privacy Browser windows, which will be `com.stoutner.privacybrowser-` with the PID appended.
1022 QStringList privacyBrowserServiceNames = registeredServiceNames.filter("com.stoutner.privacybrowser");
1024 // Repopulate the bookmarks in each window.
1025 for (QString privacyBrowserServiceName : privacyBrowserServiceNames)
1027 // Prepare the D-Bus message.
1028 QDBusMessage dBusMessage = QDBusMessage::createMethodCall(privacyBrowserServiceName, "/privacybrowser/MainWindow_1", "com.stoutner.privacybrowser.BrowserWindow", "populateBookmarksInThisWindow");
1031 QDBusConnection::sessionBus().send(dBusMessage);
1035 void BrowserWindow::populateBookmarksInThisWindow()
1037 // Remove all the final bookmark folder menu actions.
1038 for (QPair<QMenu *, QAction *> *finalBookmarkFolderMenuActionPair : finalBookmarkFolderMenuActionList)
1040 // Remove the action.
1041 finalBookmarkFolderMenuActionPair->first->removeAction(finalBookmarkFolderMenuActionPair->second);
1044 // Remove all the current menu bookmarks.
1045 for (QPair<QMenu *, QAction *> *bookmarkMenuActionPairPointer : bookmarksMenuActionList)
1047 // Remove the bookmark.
1048 bookmarkMenuActionPairPointer->first->removeAction(bookmarkMenuActionPairPointer->second);
1051 // Remove all the current menu subfolders.
1052 for (QPair<QMenu *, QMenu *> *submenuPairPointer : bookmarksMenuSubmenuList)
1054 // Remove the submenu from the parent menu.
1055 submenuPairPointer->first->removeAction(submenuPairPointer->second->menuAction());
1058 // Remove all the current toolbar subfolders.
1059 for (QPair<QMenu *, QAction *> *subfolderActionPairPointer : bookmarksToolBarSubfolderActionList)
1061 // Remove the action from the subfolder.
1062 subfolderActionPairPointer->first->removeAction(subfolderActionPairPointer->second);
1065 // Remove all the current toolbar bookmarks.
1066 for (QAction *bookmarkAction : bookmarksToolBarActionList)
1068 // Remove the bookmark.
1069 bookmarksToolBarPointer->removeAction(bookmarkAction);
1072 // Clear the current bookmark lists.
1073 bookmarksMenuActionList.clear();
1074 bookmarksMenuSubmenuList.clear();
1075 bookmarksToolBarActionList.clear();
1076 bookmarksToolBarSubfolderActionList.clear();
1078 // Populate the bookmarks subfolders, beginning with the root folder (`0`);
1079 populateBookmarksMenuSubfolders(0, bookmarksMenuPointer);
1081 // Populate the bookmarks toolbar.
1082 populateBookmarksToolBar();
1084 // Get a handle for the bookmark toolbar layout.
1085 QLayout *bookmarksToolBarLayoutPointer = bookmarksToolBarPointer->layout();
1087 // Get the count of the bookmarks.
1088 int bookmarkCount = bookmarksToolBarLayoutPointer->count();
1090 // Set the layout of each bookmark to be left aligned.
1091 for(int i = 0; i < bookmarkCount; ++i)
1092 bookmarksToolBarLayoutPointer->itemAt(i)->setAlignment(Qt::AlignLeft);
1094 // Update the bookmarked action.
1095 updateBookmarkedAction();
1098 void BrowserWindow::populateBookmarksMenuSubfolders(const double folderId, QMenu *menuPointer)
1100 // Get the folder contents.
1101 QList<BookmarkStruct> *folderContentsListPointer = BookmarksDatabase::getFolderContents(folderId);
1103 // Populate the bookmarks menu and toolbar.
1104 for (BookmarkStruct bookmarkStruct : *folderContentsListPointer)
1106 // Process the item according to the type.
1107 if (bookmarkStruct.isFolder) // This item is a folder.
1109 // Add a submenu to the menu.
1110 QMenu *submenuPointer = menuPointer->addMenu(bookmarkStruct.favoriteIcon, bookmarkStruct.name);
1112 // Add the submenu to the beginning of the list of menus to be deleted on repopulate.
1113 bookmarksMenuSubmenuList.prepend(new QPair<QMenu *, QMenu *>(menuPointer, submenuPointer));
1115 // Populate any subfolders.
1116 populateBookmarksMenuSubfolders(bookmarkStruct.folderId, submenuPointer);
1118 else // This item is a bookmark.
1120 // Add the bookmark to the menu.
1121 QAction *menuBookmarkActionPointer = menuPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name, [=]
1123 // Remove the focus from the URL line edit.
1124 urlLineEditPointer->clearFocus();
1127 tabWidgetPointer->loadUrlFromLineEdit(bookmarkStruct.url);
1131 // Add the actions to the beginning of the list of bookmarks to be deleted on repopulate.
1132 bookmarksMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, menuBookmarkActionPointer));
1136 // Add the extra items at the bottom of the menu.
1137 addFinalBookmarkFolderMenuActions(menuPointer, folderId);
1140 void BrowserWindow::populateBookmarksToolBar()
1142 // Get the root folder contents (which has a folder ID of `0`).
1143 QList<BookmarkStruct> *folderContentsListPointer = BookmarksDatabase::getFolderContents(0);
1145 // Populate the bookmarks toolbar.
1146 for (BookmarkStruct bookmarkStruct : *folderContentsListPointer)
1148 // Process the item according to the type.
1149 if (bookmarkStruct.isFolder) // This item is a folder.
1151 // Add the subfolder action.
1152 QAction *toolBarSubfolderActionPointer = bookmarksToolBarPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name);
1154 // Add the bookmark database ID to the toolbar action.
1155 toolBarSubfolderActionPointer->setData(bookmarkStruct.databaseId);
1157 // Add the action to the beginning of the list of actions to be deleted on repopulate.
1158 bookmarksToolBarActionList.prepend(toolBarSubfolderActionPointer);
1160 // Create a subfolder menu.
1161 QMenu *subfolderMenuPointer = new QMenu();
1163 // Add the menu to the action.
1164 toolBarSubfolderActionPointer->setMenu(subfolderMenuPointer);
1166 // Add the submenu to the toolbar menu list.
1167 bookmarksToolBarMenuList.append(new QPair<QMenu *, const double>(subfolderMenuPointer, bookmarkStruct.folderId));
1169 // Set the popup mode for the menu.
1170 dynamic_cast<QToolButton *>(bookmarksToolBarPointer->widgetForAction(toolBarSubfolderActionPointer))->setPopupMode(QToolButton::InstantPopup);
1172 // Populate the subfolder.
1173 populateBookmarksToolBarSubfolders(bookmarkStruct.folderId, subfolderMenuPointer);
1175 else // This item is a bookmark.
1177 // Add the bookmark to the toolbar.
1178 QAction *toolBarBookmarkActionPointer = bookmarksToolBarPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name, [=]
1180 // Remove the focus from the URL line edit.
1181 urlLineEditPointer->clearFocus();
1184 tabWidgetPointer->loadUrlFromLineEdit(bookmarkStruct.url);
1188 // Add the bookmark database ID to the toolbar action.
1189 toolBarBookmarkActionPointer->setData(bookmarkStruct.databaseId);
1191 // Add the actions to the beginning of the current bookmarks lists.
1192 bookmarksToolBarActionList.prepend(toolBarBookmarkActionPointer);
1196 // 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.
1197 for (QPair<QMenu *, const double> *menuAndFolderIdPairPointer : bookmarksToolBarMenuList)
1199 // Populate the final bookmarks menu entries.
1200 addFinalBookmarkFolderMenuActions(menuAndFolderIdPairPointer->first, menuAndFolderIdPairPointer->second);
1204 void BrowserWindow::populateBookmarksToolBarSubfolders(const double folderId, QMenu *menuPointer)
1206 // Get the folder contents.
1207 QList<BookmarkStruct> *folderContentsListPointer = BookmarksDatabase::getFolderContents(folderId);
1209 // Populate the bookmarks folder.
1210 for (BookmarkStruct bookmarkStruct : *folderContentsListPointer)
1212 // Get the bookmark URL.
1213 QString bookmarkUrl = bookmarkStruct.url;
1215 // Process the item according to the type.
1216 if (bookmarkStruct.isFolder) // This item is a folder.
1218 // Add the subfolder action.
1219 QAction *toolBarSubfolderActionPointer = menuPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name);
1221 // Add the action to the beginning of the list of actions to be deleted on repopulate.
1222 bookmarksToolBarSubfolderActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, toolBarSubfolderActionPointer));
1224 // Create a subfolder menu.
1225 QMenu *subfolderMenuPointer = new QMenu();
1227 // Add the submenu to the action.
1228 toolBarSubfolderActionPointer->setMenu(subfolderMenuPointer);
1230 // Add the submenu to the toolbar menu list.
1231 bookmarksToolBarMenuList.append(new QPair<QMenu *, const double>(subfolderMenuPointer, bookmarkStruct.folderId));
1233 // Populate the subfolder menu.
1234 populateBookmarksToolBarSubfolders(bookmarkStruct.folderId, subfolderMenuPointer);
1236 else // This item is a bookmark.
1238 // Add the bookmark to the folder.
1239 QAction *toolBarBookmarkActionPointer = menuPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name, [=]
1241 // Remove the focus from the URL line edit.
1242 urlLineEditPointer->clearFocus();
1245 tabWidgetPointer->loadUrlFromLineEdit(bookmarkUrl);
1249 // Add the bookmark database ID to the toolbar action.
1250 toolBarBookmarkActionPointer->setData(bookmarkStruct.databaseId);
1252 // Add the action to the beginning of the list of actions to be deleted on repopulate.
1253 bookmarksToolBarSubfolderActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, toolBarBookmarkActionPointer));
1258 void BrowserWindow::refresh() const
1260 // Remove the focus from the URL line edit.
1261 urlLineEditPointer->clearFocus();
1263 // Refresh the web page.
1264 tabWidgetPointer->refresh();
1267 void BrowserWindow::reloadAndBypassCache() const
1269 // Remove the focus from the URL line edit.
1270 urlLineEditPointer->clearFocus();
1272 // Refresh the web page.
1273 tabWidgetPointer->refresh();
1276 void BrowserWindow::showBookmarkContextMenu(const QPoint &point)
1278 // Get the bookmark action.
1279 QAction *bookmarkActionPointer = bookmarksToolBarPointer->actionAt(point);
1281 // Check to see if an action was clicked.
1282 if (bookmarkActionPointer) // An action was clicked.
1284 // Create a bookmark context menu.
1285 QMenu *bookmarkContextMenuPointer = new QMenu();
1287 // Get the database ID from the action.
1288 int databaseId = bookmarkActionPointer->data().toInt();
1290 // Create the menu according to the type.
1291 if (BookmarksDatabase::isFolder(databaseId)) // A folder was clicked.
1293 // Populate the final bookmarks menu entries.
1294 addFinalBookmarkFolderMenuActions(bookmarkContextMenuPointer, BookmarksDatabase::getFolderId(databaseId));
1296 else // A bookmark was clicked.
1298 // Add the open in new tab action to the menu.
1299 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("Open bookmark in new tab context menu entry", "Open in New Tab"), [=]
1301 // Get the bookmark.
1302 BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
1304 // Open the bookmark in a new tab. `true` removes the URL line edit focus, `false` does not load a background tab.
1305 tabWidgetPointer->addTab(true, false, bookmarkStructPointer->url);
1309 // Add the open in background tab action to the menu.
1310 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("Open bookmark in background tab context menu entry", "Open in Background Tab"), [=]
1312 // Get the bookmark.
1313 BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
1315 // Open the bookmark in a new tab. `true` removes the URL line edit focus, `true` loads a background tab.
1316 tabWidgetPointer->addTab(true, true, bookmarkStructPointer->url);
1320 // Add the open in new window action to the menu.
1321 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("window-new")), i18nc("Open bookmark in new window context menu entry", "Open in New Window"), [=]
1323 // Get the bookmark.
1324 BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
1326 // Create a new browser window and load the first URL. `false` indicates it is not the first browser window.
1327 BrowserWindow *browserWindowPointer = new BrowserWindow(false, &bookmarkStructPointer->url);
1329 // Show the new browser window.
1330 browserWindowPointer->show();
1335 bookmarkContextMenuPointer->addSeparator();
1337 // Add the edit action to the menu.
1338 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("document-edit")), i18nc("Edit bookmark context menu entry", "Edit"), [=]
1340 // Get the current tab favorite icon.
1341 QIcon currentTabFavoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
1343 // Instantiate an edit bookmark dialog.
1344 QDialog *editBookmarkDialogPointer = new EditBookmarkDialog(databaseId, currentTabFavoriteIcon);
1347 editBookmarkDialogPointer->show();
1349 // Process bookmark events.
1350 connect(editBookmarkDialogPointer, SIGNAL(bookmarkSaved()), this, SLOT(populateBookmarksInAllWindows()));
1354 // Add the copy URL action to the menu.
1355 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-copy")), i18nc("Copy bookmark URL context menu entry", "Copy URL"), [=]
1357 // Get the bookmark.
1358 BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
1360 // Get a handle for the clipboard.
1361 QClipboard *clipboard = QGuiApplication::clipboard();
1363 // Place the URL on the keyboard.
1364 clipboard->setText(bookmarkStructPointer->url);
1369 bookmarkContextMenuPointer->addSeparator();
1371 // Add the delete action to the menu.
1372 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-delete")), i18nc("Delete bookmark context menu entry", "Delete"), [=]
1374 // Get the parent folder ID.
1375 double parentFolderId = BookmarksDatabase::getParentFolderId(databaseId);
1377 // Delete the bookmark.
1378 BookmarksDatabase::deleteBookmark(databaseId);
1380 // Update the display order of the bookmarks in the parent folder.
1381 BookmarksDatabase::updateFolderContentsDisplayOrder(parentFolderId);
1383 // Repopulate the bookmarks.
1384 populateBookmarksInAllWindows();
1389 // Delete the menu from memory when it is closed.
1390 bookmarkContextMenuPointer->setAttribute(Qt::WA_DeleteOnClose);
1392 // Display the context menu.
1393 bookmarkContextMenuPointer->popup(bookmarksToolBarPointer->mapToGlobal(point));
1395 else // The toolbar background was clicked.
1397 // Temporarily set the context menu policy to the default.
1398 bookmarksToolBarPointer->setContextMenuPolicy(Qt::DefaultContextMenu);
1400 // Create a context menu event with the same position.
1401 QContextMenuEvent *contextMenuEventPointer = new QContextMenuEvent(QContextMenuEvent::Mouse, point);
1403 // Send the context menu event to the toolbar.
1404 QCoreApplication::sendEvent(bookmarksToolBarPointer, contextMenuEventPointer);
1406 // Reset the context menu policy.
1407 bookmarksToolBarPointer->setContextMenuPolicy(Qt::CustomContextMenu);
1411 void BrowserWindow::showCookiesDialog()
1413 // Remove the focus from the URL line edit.
1414 urlLineEditPointer->clearFocus();
1416 // Instantiate the cookie settings dialog.
1417 CookiesDialog *cookiesDialogPointer = new CookiesDialog(tabWidgetPointer->getCookieList());
1420 cookiesDialogPointer->show();
1422 // Connect the dialog signals.
1423 connect(cookiesDialogPointer, SIGNAL(addCookie(QNetworkCookie)), tabWidgetPointer, SLOT(addCookieToStore(QNetworkCookie)));
1424 connect(cookiesDialogPointer, SIGNAL(deleteAllCookies()), tabWidgetPointer, SLOT(deleteAllCookies()));
1425 connect(cookiesDialogPointer, SIGNAL(deleteCookie(QNetworkCookie)), tabWidgetPointer, SLOT(deleteCookieFromStore(QNetworkCookie)));
1428 void BrowserWindow::showDownloadLocationBrowseDialog() const
1430 // Get the current download location.
1431 QString currentDownloadLocation = downloadLocationComboBoxPointer->currentText();
1433 // Resolve the system download directory if specified.
1434 if (currentDownloadLocation == QStringLiteral("System Download Directory"))
1435 currentDownloadLocation = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
1437 // Get the new download location.
1438 QString newDownloadLocation = QFileDialog::getExistingDirectory(configDialogPointer, i18nc("Select download location dialog caption", "Select Download Location"), currentDownloadLocation);
1440 // Populate the download location combo box according to the new download location.
1441 if (newDownloadLocation == QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)) // The default download location was selected.
1443 // Populate the download location with the default text.
1444 downloadLocationComboBoxPointer->setCurrentText("System Download Directory");
1446 else if (newDownloadLocation != QStringLiteral("")) // A different directory was selected.
1448 // Populate the download location.
1449 downloadLocationComboBoxPointer->setCurrentText(newDownloadLocation);
1453 void BrowserWindow::showDomainSettingsDialog() const
1455 // Remove the focus from the URL line edit.
1456 urlLineEditPointer->clearFocus();
1458 // Instantiate the domain settings dialog.
1459 DomainSettingsDialog *domainSettingsDialogPointer = new DomainSettingsDialog();
1461 // Reload the tabs when domain settings are updated.
1462 connect(domainSettingsDialogPointer, SIGNAL(domainSettingsUpdated()), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
1465 domainSettingsDialogPointer->show();
1468 void BrowserWindow::showFindTextActions() const
1470 // Show the find text actions.
1471 findTextLineEditActionPointer->setVisible(true);
1472 findTextLabelActionPointer->setVisible(true);
1473 findNextActionPointer->setVisible(true);
1474 findPreviousActionPointer->setVisible(true);
1475 findCaseSensitiveActionPointer->setVisible(true);
1476 hideFindTextActionPointer->setVisible(true);
1478 // Set the focus on the find line edit.
1479 findTextLineEditPointer->setFocus();
1481 // Select all the text in the find line edit.
1482 findTextLineEditPointer->selectAll();
1485 void BrowserWindow::showProgressBar(const int &progress) const
1487 // Set the progress bar value.
1488 progressBarPointer->setValue(progress);
1490 // Show the progress bar.
1491 progressBarPointer->show();
1494 void BrowserWindow::showSettingsDialog()
1496 // Create the settings widgets.
1497 QWidget *privacySettingsWidgetPointer = new QWidget;
1498 QWidget *generalSettingsWidgetPointer = new QWidget;
1499 QWidget *spellCheckSettingsWidgetPointer = new QWidget;
1501 // Instantiate the settings UI.
1502 Ui::PrivacySettings privacySettingsUi;
1503 Ui::GeneralSettings generalSettingsUi;
1504 Ui::SpellCheckSettings spellCheckSettingsUi;
1506 // Setup the UI to display the settings widgets.
1507 privacySettingsUi.setupUi(privacySettingsWidgetPointer);
1508 generalSettingsUi.setupUi(generalSettingsWidgetPointer);
1509 spellCheckSettingsUi.setupUi(spellCheckSettingsWidgetPointer);
1511 // Get handles for the widgets.
1512 QComboBox *userAgentComboBoxPointer = privacySettingsUi.kcfg_userAgent;
1513 userAgentLabelPointer = privacySettingsUi.userAgentLabel;
1514 QComboBox *searchEngineComboBoxPointer = generalSettingsUi.kcfg_searchEngine;
1515 searchEngineLabelPointer = generalSettingsUi.searchEngineLabel;
1516 downloadLocationComboBoxPointer = generalSettingsUi.kcfg_downloadLocation;
1517 QPushButton *browseButtonPointer = generalSettingsUi.browseButton;
1518 QListWidget *spellCheckListWidgetPointer = spellCheckSettingsUi.spellCheckListWidget;
1520 // Populate the combo box labels.
1521 updateUserAgentLabel(userAgentComboBoxPointer->currentText());
1522 updateSearchEngineLabel(searchEngineComboBoxPointer->currentText());
1524 // Update the labels when the combo boxes change.
1525 connect(userAgentComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateUserAgentLabel(const QString)));
1526 connect(searchEngineComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateSearchEngineLabel(const QString)));
1528 // Connect the download location directory browse button.
1529 connect(browseButtonPointer, SIGNAL(clicked()), this, SLOT(showDownloadLocationBrowseDialog()));
1531 // Create a dictionaries QDir from the `QTWEBENGINE_DICTIONARIES_PATH` environment variable.
1532 QDir dictionariesDir = QDir(qEnvironmentVariable("QTWEBENGINE_DICTIONARIES_PATH"));
1534 // Get a dictionaries string list.
1535 QStringList dictionariesStringList = dictionariesDir.entryList(QStringList(QLatin1String("*.bdic")), QDir::Files | QDir::NoSymLinks);
1537 // Remove the `.bdic` file extensions from the dictionaries list.
1538 dictionariesStringList.replaceInStrings(QLatin1String(".bdic"), QLatin1String(""));
1540 // Get a list of the enabled spell check languages.
1541 QStringList enabledSpellCheckLanguagesList = Settings::spellCheckLanguages();
1543 // Add each dictionary to the spell check list widget.
1544 foreach(QString dictionaryString, dictionariesStringList)
1546 // Create a new list widget item pointer.
1547 QListWidgetItem *listWidgetItemPointer = new QListWidgetItem();
1549 // Create a dictionary check box widget with the name of the dictionary string.
1550 QCheckBox *dictionaryCheckBoxWidget = new QCheckBox(dictionaryString);
1552 // Check the language if it is currently enabled.
1553 if (enabledSpellCheckLanguagesList.contains(dictionaryString))
1554 dictionaryCheckBoxWidget->setCheckState(Qt::Checked);
1556 dictionaryCheckBoxWidget->setCheckState(Qt::Unchecked);
1558 // Add the list widget item to the spell check list widget.
1559 spellCheckListWidgetPointer->addItem(listWidgetItemPointer);
1561 // Set the list widget item check box widget.
1562 spellCheckListWidgetPointer->setItemWidget(listWidgetItemPointer, dictionaryCheckBoxWidget);
1565 // Get a handle for the KConfig skeleton.
1566 KConfigSkeleton *kConfigSkeletonPointer = Settings::self();
1568 // Instantiate a settings config dialog from the settings.kcfg file.
1569 configDialogPointer = new KConfigDialog(this, QLatin1String("settings"), kConfigSkeletonPointer);
1571 // Create a settings icon string.
1572 QString settingsIconString;
1574 // Get a settings icon that matches the theme.
1575 if (QIcon::hasThemeIcon("breeze-settings"))
1577 // KDE uses breeze-settings.
1578 settingsIconString = QLatin1String("breeze-settings");
1582 // Gnome uses preferences-desktop.
1583 settingsIconString = QLatin1String("preferences-desktop");
1586 // Add the settings widgets as config dialog pages.
1587 configDialogPointer->addPage(privacySettingsWidgetPointer, i18nc("Settings tab title", "Privacy"), QLatin1String("privacybrowser"));
1588 configDialogPointer->addPage(generalSettingsWidgetPointer, i18nc("Settings tab title", "General"), settingsIconString);
1589 configDialogPointer->addPage(spellCheckSettingsWidgetPointer, i18nc("Settings tab title", "Spell Check"), QLatin1String("tools-check-spelling"));
1591 // Get handles for the buttons.
1592 QPushButton *applyButtonPointer = configDialogPointer->button(QDialogButtonBox::Apply);
1593 QPushButton *okButtonPointer = configDialogPointer->button(QDialogButtonBox::Ok);
1595 // Prevent interaction with the parent window while the dialog is open.
1596 configDialogPointer->setWindowModality(Qt::WindowModal);
1599 configDialogPointer->show();
1601 // TODO. KConfigDialog does not respect expanding size policies. <https://redmine.stoutner.com/issues/823>
1602 //configDialogPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1603 //privacySettingsWidgetPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1604 //generalSettingsWidgetPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1605 //configDialogPointer->adjustSize();
1607 // Expand the config dialog.
1608 configDialogPointer->resize(1000, 500);
1610 // Create a save spell check languages lambda.
1611 auto saveSpellCheckLanguages = [spellCheckListWidgetPointer, kConfigSkeletonPointer, this] ()
1613 // Create a list of enabled languages.
1614 QStringList newSpellCheckLanguages = QStringList();
1616 // Get a count of all the languages.
1617 int allLanguagesCount = spellCheckListWidgetPointer->count();
1619 // Get a list of all the checked languages.
1620 for (int i = 0; i < allLanguagesCount; ++i) {
1621 // Get the language item.
1622 QListWidgetItem *languageItemPointer = spellCheckListWidgetPointer->item(i);
1624 // Get the language check box.
1625 QCheckBox *languageCheckBoxPointer = qobject_cast<QCheckBox*>(spellCheckListWidgetPointer->itemWidget(languageItemPointer));
1627 // Add the item to the enabled languages if it is checked.
1628 if (languageCheckBoxPointer->checkState() == Qt::Checked)
1631 QString languageString = languageCheckBoxPointer->text();
1633 // Remove all instances of `&`, which may have been added automatically when creating the check box text.
1634 languageString.remove(QChar('&'));
1636 // Add the language string to the list.
1637 newSpellCheckLanguages.append(languageString);
1641 // Update the spell check languages.
1642 if (Settings::spellCheckLanguages() != newSpellCheckLanguages)
1644 // Update the spell check languages.
1645 Settings::setSpellCheckLanguages(newSpellCheckLanguages);
1647 // Write the settings to disk.
1648 kConfigSkeletonPointer->save();
1651 // Apply the spell check languages.
1652 tabWidgetPointer->applySpellCheckLanguages();
1656 connect(applyButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages);
1657 connect(okButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages);
1659 // Apply the settings handled by KConfig.
1660 connect(configDialogPointer, SIGNAL(settingsChanged(QString)), tabWidgetPointer, SLOT(applyApplicationSettings()));
1661 connect(configDialogPointer, SIGNAL(settingsChanged(QString)), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
1664 QSize BrowserWindow::sizeHint() const
1666 // Return the default window size.
1667 return QSize(1500, 1200);
1670 void BrowserWindow::toggleBookmark()
1672 // Remove the focus from the URL line edit, which will have been focused when the user clicked on the bookmarked icon.
1673 urlLineEditPointer->clearFocus();
1675 // Create or delete the bookmark
1676 if (bookmarkedActionPointer->isChecked()) // The user checked the toggle. Create a bookmark.
1678 // Create a bookmark struct.
1679 BookmarkStruct *bookmarkStructPointer = new BookmarkStruct;
1681 // Populate the bookmark struct.
1682 bookmarkStructPointer->name = tabWidgetPointer->getCurrentTabTitle();
1683 bookmarkStructPointer->url = tabWidgetPointer->getCurrentTabUrl();
1684 bookmarkStructPointer->parentFolderId = 0;
1685 bookmarkStructPointer->favoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
1687 // Add the bookmark.
1688 BookmarksDatabase::addBookmark(bookmarkStructPointer);
1690 else // The user unchecked the toggle. Delete all related bookmarks.
1692 // Delete the bookmarks.
1693 BookmarksDatabase::deleteBookmarks(urlLineEditPointer->text());
1698 // Repopulate the bookmarks.
1699 populateBookmarksInAllWindows();
1702 void BrowserWindow::toggleDeveloperTools() const
1704 // Toggle the developer tools.
1705 tabWidgetPointer->toggleDeveloperTools(developerToolsActionPointer->isChecked());
1708 void BrowserWindow::toggleDomStorage() const
1710 // Remove the focus from the URL line edit.
1711 urlLineEditPointer->clearFocus();
1713 // Toggle DOM storage.
1714 tabWidgetPointer->toggleDomStorage();
1717 void BrowserWindow::toggleFindCaseSensitive() const
1719 // Get the current find string.
1720 const QString findString = findTextLineEditPointer->text();
1722 // Toggle find case sensitive.
1723 tabWidgetPointer->toggleFindCaseSensitive(findString);
1726 void BrowserWindow::toggleJavaScript() const
1728 // Remove the focus from the URL line edit.
1729 urlLineEditPointer->clearFocus();
1731 // Toggle JavaScript.
1732 tabWidgetPointer->toggleJavaScript();
1735 void BrowserWindow::toggleLocalStorage() const
1737 // Remove the focus from the URL line edit.
1738 urlLineEditPointer->clearFocus();
1740 // Toggle local storage.
1741 tabWidgetPointer->toggleLocalStorage();
1744 void BrowserWindow::toggleFullScreen()
1746 // Toggle the full screen status.
1747 fullScreenRequested(fullScreenActionPointer->isChecked());
1750 void BrowserWindow::toggleViewSource() const
1752 // Get the current URL.
1753 QString url = urlLineEditPointer->text();
1756 if (url.startsWith(QLatin1String("view-source:"))) // The source is currently being viewed.
1758 // Remove `view-source:` from the URL.
1759 url = url.remove(0, 12);
1761 else // The source is not currently being viewed.
1763 // Prepend `view-source:` from the URL.
1764 url = url.prepend(QLatin1String("view-source:"));
1768 loadUrlFromLineEdit(url);
1771 void BrowserWindow::toggleViewBookmarksToolBar()
1773 // Store the current status of the bookmarks toolbar, which is used when exiting full screen browsing.
1774 bookmarksToolBarIsVisible = viewBookmarksToolBarActionPointer->isChecked();
1776 // Update the visibility of the bookmarks toolbar.
1777 bookmarksToolBarPointer->setVisible(bookmarksToolBarIsVisible);
1780 void BrowserWindow::toggleViewSourceInNewTab() 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:"));
1797 // Add the new tab. `true` removes the URL line edit focus, `false` does not open a background tab.
1798 tabWidgetPointer->addTab(true, false, url);
1801 void BrowserWindow::updateBookmarkedAction() const
1803 // Update the bookmarked action to reflect the current state.
1804 if (bookmarkedActionPointer->isChecked())
1805 bookmarkedActionPointer->setIcon(QIcon::fromTheme("starred-symbolic"));
1807 bookmarkedActionPointer->setIcon(QIcon::fromTheme("non-starred-symbolic"));
1810 void BrowserWindow::updateCookiesAction(const int numberOfCookies) const
1812 // Update the action text.
1813 cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", numberOfCookies));
1816 void BrowserWindow::updateDefaultZoomFactor(const double newDefaultZoomFactor)
1818 // Store the new default zoom factor.
1819 defaultZoomFactor = newDefaultZoomFactor;
1822 void BrowserWindow::updateDomStorageAction(const bool &isEnabled) const
1824 // Set the action checked status.
1825 domStorageActionPointer->setChecked(isEnabled);
1828 void BrowserWindow::updateDomainSettingsIndicator(const bool status)
1830 // Set the domain palette according to the status.
1832 urlLineEditPointer->setPalette(positiveBackgroundPalette);
1834 urlLineEditPointer->setPalette(normalBackgroundPalette);
1837 void BrowserWindow::updateFindText(const QString &text, const bool findCaseSensitive) const
1840 findTextLineEditPointer->setText(text);
1842 // Set the find case sensitive action checked status.
1843 findCaseSensitiveActionPointer->setChecked(findCaseSensitive);
1846 void BrowserWindow::updateFindTextResults(const QWebEngineFindTextResult &findTextResult) const
1848 // Update the find text label.
1849 findTextLabelPointer->setText(QStringLiteral(" %1/%2 ").arg(findTextResult.activeMatch()).arg(findTextResult.numberOfMatches()));
1851 // Set the background color according to the find status.
1852 if (findTextLineEditPointer->text().isEmpty())
1853 findTextLineEditPointer->setPalette(normalBackgroundPalette);
1854 else if (findTextResult.numberOfMatches() == 0)
1855 findTextLineEditPointer->setPalette(negativeBackgroundPalette);
1857 findTextLineEditPointer->setPalette(positiveBackgroundPalette);
1860 void BrowserWindow::updateJavaScriptAction(const bool &isEnabled)
1862 // Update the JavaScript status.
1863 javaScriptEnabled = isEnabled;
1865 // Set the icon according to the status.
1866 if (javaScriptEnabled)
1867 javaScriptActionPointer->setIcon(QIcon(QLatin1String(":/icons/javascript-warning.svg")));
1869 javaScriptActionPointer->setIcon(QIcon(QLatin1String(":/icons/privacy-mode.svg")));
1871 // Set the action checked status.
1872 javaScriptActionPointer->setChecked(javaScriptEnabled);
1874 // Update the status of the DOM storage action.
1875 domStorageActionPointer->setEnabled(javaScriptEnabled & localStorageEnabled);
1878 void BrowserWindow::updateLocalStorageAction(const bool &isEnabled)
1880 // Update the local storage status.
1881 localStorageEnabled = isEnabled;
1883 // 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.
1884 if (localStorageEnabled)
1885 localStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("disk-quota-high"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/actions/document-save-as.png"))));
1887 localStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("disk-quota"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/apps/kfm.png"))));
1889 // Set the action checked status.
1890 localStorageActionPointer->setChecked(localStorageEnabled);
1892 // Update the status of the DOM storage action.
1893 domStorageActionPointer->setEnabled(localStorageEnabled & javaScriptEnabled);
1896 void BrowserWindow::updateSearchEngineActions(const QString &searchEngine, const bool &updateCustomSearchEngineStatus)
1898 // Initialize the custom search engine flag.
1899 bool customSearchEngine = false;
1901 if (searchEngine == "Mojeek") // Mojeek.
1903 // Check the Mojeek user agent action.
1904 searchEngineMojeekActionPointer->setChecked(true);
1906 // Update the search engine menu action icon.
1907 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1909 // Update the search engine menu action text.
1910 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Mojeek"));
1912 else if (searchEngine == "Monocles") // Monocles.
1914 // Check the Monocles user agent action.
1915 searchEngineMonoclesActionPointer->setChecked(true);
1917 // Update the search engine menu action icon.
1918 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1920 // Update the search engine menu action text.
1921 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Monocles"));
1923 else if (searchEngine == "MetaGer") // MetaGer.
1925 // Check the MetaGer user agent action.
1926 searchEngineMetagerActionPointer->setChecked(true);
1928 // Update the search engine menu action icon.
1929 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1931 // Update the search engine menu action text.
1932 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - MetaGer"));
1934 else if (searchEngine == "Google") // Google.
1936 // Check the Google user agent action.
1937 searchEngineGoogleActionPointer->setChecked(true);
1939 // Update the search engine menu action icon.
1940 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-google"), QIcon::fromTheme(QLatin1String("edit-find"))));
1942 // Update the search engine menu action text.
1943 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Google"));
1945 else if (searchEngine == "Bing") // Bing.
1947 // Check the Bing user agent action.
1948 searchEngineBingActionPointer->setChecked(true);
1950 // Update the search engine menu action icon.
1951 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1953 // Update the search engine menu action text.
1954 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Bing"));
1956 else if (searchEngine == "Yahoo") // Yahoo.
1958 // Check the Yahoo user agent action.
1959 searchEngineYahooActionPointer->setChecked(true);
1961 // Update the search engine menu action icon.
1962 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-yahoo"), QIcon::fromTheme(QLatin1String("edit-find"))));
1964 // Update the search engine menu action text.
1965 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Yahoo"));
1967 else // Custom search engine.
1969 // Check the user agent.
1970 searchEngineCustomActionPointer->setChecked(true);
1972 // Update the search engine menu action icon.
1973 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1975 // Update the search engine menu action text.
1976 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Custom"));
1978 // Set the custom search engine text.
1979 searchEngineCustomActionPointer->setText(searchEngine);
1981 // Set the custom search engine flag.
1982 customSearchEngine = true;
1985 // Update the custom search engine enabled boolean.
1986 if (updateCustomSearchEngineStatus)
1987 customSearchEngineEnabled = customSearchEngine;
1989 // Format the custom search engine.
1990 if (customSearchEngineEnabled)
1992 // Enable the custom search engine.
1993 searchEngineCustomActionPointer->setEnabled(true);
1997 // Disable the custom search engine.
1998 searchEngineCustomActionPointer->setEnabled(false);
2000 // Reset the custom search engine text.
2001 searchEngineCustomActionPointer->setText(i18nc("@action", "Custom"));
2005 void BrowserWindow::updateSearchEngineLabel(const QString &searchEngineString) const
2007 // Update the search engine label.
2008 searchEngineLabelPointer->setText(SearchEngineHelper::getSearchUrl(searchEngineString));
2011 void BrowserWindow::updateUrlLineEdit(const QUrl &newUrl)
2013 // Get the new URL string in encoded form, which displays punycode.
2014 QString newUrlString = newUrl.toEncoded();
2016 // Update the view source actions.
2017 if (newUrlString.startsWith(QLatin1String("view-source:"))) // The source is currently being viewed.
2019 // Mark the view source checkbox.
2020 viewSourceActionPointer->setChecked(true);
2022 // Update the view in new tab action text.
2023 viewSourceInNewTabActionPointer->setText(i18nc("View rendered website in new tab action", "View Rendered Website in New Tab"));
2025 else // The source is not currently being viewed.
2027 // Unmark the view source checkbox.
2028 viewSourceActionPointer->setChecked(false);
2030 // Update the view in new tab action text.
2031 viewSourceInNewTabActionPointer->setText(i18nc("View source in new tab action", "View Source in New Tab"));
2034 // Update the URL line edit if it does not have focus.
2035 if (!urlLineEditPointer->hasFocus())
2037 // Update the URL line edit.
2038 urlLineEditPointer->setText(newUrlString);
2040 // Set the bookmarked action status.
2041 bookmarkedActionPointer->setChecked(BookmarksDatabase::isBookmarked(newUrlString));
2043 // Update the bookmarked action.
2044 updateBookmarkedAction();
2046 // Set the focus if the new URL is blank.
2047 if (newUrlString == QStringLiteral(""))
2048 urlLineEditPointer->setFocus();
2051 // Store the current URL.
2052 currentUrl = newUrl;
2055 void BrowserWindow::updateUserAgentActions(const QString &userAgent, const bool &updateCustomUserAgentStatus)
2057 // Initialize the custom user agent flag.
2058 bool customUserAgent = false;
2060 // Check the indicated on-the-fly user agent.
2061 if (userAgent == UserAgentHelper::PRIVACY_BROWSER_USER_AGENT) // Privacy Browser.
2063 // Check the Privacy Browser user agent action.
2064 userAgentPrivacyBrowserActionPointer->setChecked(true);
2066 // Update the user agent menu action icon.
2067 userAgentMenuActionPointer->setIcon(QIcon(":/icons/privacy-mode.svg"));
2069 // Update the user agent menu action text.
2070 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Privacy Browser"));
2072 else if (userAgent == TabWidget::webEngineDefaultUserAgent) // WebEngine default.
2074 // check the WebEngine default user agent action.
2075 userAgentWebEngineDefaultActionPointer->setChecked(true);
2077 // Update the user agent menu action icon.
2078 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("qtlogo"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2080 // Update the user agent menu action text.
2081 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - WebEngine default"));
2083 else if (userAgent == UserAgentHelper::FIREFOX_LINUX_USER_AGENT) // Firefox on Linux.
2085 // Check the Firefox on Linux user agent action.
2086 userAgentFirefoxLinuxActionPointer->setChecked(true);
2088 // Update the user agent menu action icon.
2089 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2091 // Update the user agent menu action text.
2092 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Firefox on Linux"));
2094 else if (userAgent == UserAgentHelper::CHROMIUM_LINUX_USER_AGENT) // Chromium on Linux.
2096 // Check the Chromium on Linux user agent action.
2097 userAgentChromiumLinuxActionPointer->setChecked(true);
2099 // Update the user agent menu action icon.
2100 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2102 // Update the user agent menu action text.
2103 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Chromium on Linux"));
2105 else if (userAgent == UserAgentHelper::FIREFOX_WINDOWS_USER_AGENT) // Firefox on Windows.
2107 // Check the Firefox on Windows user agent action.
2108 userAgentFirefoxWindowsActionPointer->setChecked(true);
2110 // Update the user agent menu action icon.
2111 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2113 // Update the user agent menu action text.
2114 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Firefox on Windows"));
2116 else if (userAgent == UserAgentHelper::CHROME_WINDOWS_USER_AGENT) // Chrome on Windows.
2118 // Check the Chrome on Windows user agent action.
2119 userAgentChromeWindowsActionPointer->setChecked(true);
2121 // Update the user agent menu action icon.
2122 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2124 // Update the user agent menu action text.
2125 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Chrome on Windows"));
2127 else if (userAgent == UserAgentHelper::EDGE_WINDOWS_USER_AGENT) // Edge on Windows.
2129 // Check the Edge on Windows user agent action.
2130 userAgentEdgeWindowsActionPointer->setChecked(true);
2132 // Update the user agent menu action icon.
2133 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
2135 // Update the user agent menu action text.
2136 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Edge on Windows"));
2138 else if (userAgent == UserAgentHelper::SAFARI_MACOS_USER_AGENT) // Safari on macOS.
2140 // Check the Safari on macOS user agent action.
2141 userAgentSafariMacosActionPointer->setChecked(true);
2143 // Update the user agent menu action icon.
2144 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
2146 // Update the user agent menu action text.
2147 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Safari on macOS"));
2149 else // Custom user agent.
2151 // Check the user agent.
2152 userAgentCustomActionPointer->setChecked(true);
2154 // Update the user agent menu action icon.
2155 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
2157 // Update the user agent menu action text.
2158 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Custom"));
2160 // Set the custom user agent text.
2161 userAgentCustomActionPointer->setText(userAgent);
2163 // Set the custom user agent flag.
2164 customUserAgent = true;
2167 // Update the custom user agent enabled boolean.
2168 // 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.
2169 if (updateCustomUserAgentStatus)
2170 customUserAgentEnabled = customUserAgent;
2173 // Format the custom user agent.
2174 if (customUserAgentEnabled)
2176 // Enable the custom user agent.
2177 userAgentCustomActionPointer->setEnabled(true);
2181 // Disable the custom user agent.
2182 userAgentCustomActionPointer->setEnabled(false);
2184 // Reset the custom user agent text.
2185 userAgentCustomActionPointer->setText(i18nc("@action", "Custom"));
2189 void BrowserWindow::updateUserAgentLabel(const QString &userAgentDatabaseName) const
2191 // Update the user agent label.
2192 userAgentLabelPointer->setText(UserAgentHelper::getUserAgentFromDatabaseName(userAgentDatabaseName));
2195 void BrowserWindow::updateViewBookmarksToolBarCheckbox(const bool visible)
2197 // Update the view bookmarks toolbar checkbox.
2198 viewBookmarksToolBarActionPointer->setChecked(visible);
2200 // Initialize the bookmarks toolbar visibility tracker if Privacy Browser has just launched.
2201 if (bookmarksToolBarUninitialized)
2203 // Set the initialization flag.
2204 bookmarksToolBarUninitialized = false;
2206 // Store the current status of the bookmarks toolbar, which is used when exiting full screen browsing.
2207 bookmarksToolBarIsVisible = visible;
2211 void BrowserWindow::updateWindowTitle(const QString &title)
2213 // Update the window title.
2214 setWindowTitle(title);
2217 void BrowserWindow::updateZoomActions(const double &zoomFactor)
2219 // Set the current zoom factor.
2220 currentZoomFactor = zoomFactor;
2222 // Set the status of the default zoom action.
2223 zoomDefaultActionPointer->setEnabled(currentZoomFactor != defaultZoomFactor);
2225 // Set the status of the zoom in action and button.
2226 zoomInActionPointer->setEnabled(currentZoomFactor <= 4.99);
2227 zoomPlusButtonPointer->setEnabled(currentZoomFactor <= 4.99);
2229 // Set the status of the zoom out action and button.
2230 zoomMinusButtonPointer->setEnabled(currentZoomFactor > 0.25);
2231 zoomOutActionPointer->setEnabled(currentZoomFactor > 0.25);
2234 // 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.
2235 zoomFactorActionPointer->setText(ki18nc("The zoom factor action", "Zoom Factor - %1").subs(zoomFactor, 0, '0', 2).toString());
2237 // Update the status bar zoom factor label.
2238 currentZoomButtonPointer->setText(ki18nc("The status bar zoom, which is just the formatted zoom factor", "%1").subs(zoomFactor, 0, '0', 2).toString());
2241 void BrowserWindow::zoomDefault()
2243 // Set the new zoom factor.
2244 tabWidgetPointer->applyOnTheFlyZoomFactor(defaultZoomFactor);
2246 // Update the on-the-fly action text.
2247 updateZoomActions(defaultZoomFactor);