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 javaScriptActionPointer = actionCollectionPointer->addAction(QLatin1String("javascript"));
100 localStorageActionPointer = actionCollectionPointer->addAction(QLatin1String("local_storage"));
101 domStorageActionPointer = actionCollectionPointer->addAction(QLatin1String("dom_storage"));
102 userAgentPrivacyBrowserActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_privacy_browser"));
103 userAgentWebEngineDefaultActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_webengine_default"));
104 userAgentFirefoxLinuxActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_firefox_linux"));
105 userAgentChromiumLinuxActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_chromium_linux"));
106 userAgentFirefoxWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_firefox_windows"));
107 userAgentChromeWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_chrome_windows"));
108 userAgentEdgeWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_edge_windows"));
109 userAgentSafariMacosActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_safari_macos"));
110 userAgentCustomActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_custom"));
111 zoomFactorActionPointer = actionCollectionPointer->addAction(QLatin1String("zoom_factor"));
112 searchEngineMojeekActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_mojeek"));
113 searchEngineMonoclesActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_monocles"));
114 searchEngineMetagerActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_metager"));
115 searchEngineGoogleActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_google"));
116 searchEngineBingActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_bing"));
117 searchEngineYahooActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_yahoo"));
118 searchEngineCustomActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_custom"));
119 viewBookmarksToolBarActionPointer = actionCollectionPointer->addAction(QLatin1String("view_bookmarks_toolbar"));
120 QAction *domainSettingsActionPointer = actionCollectionPointer->addAction(QLatin1String("domain_settings"));
121 cookiesActionPointer = actionCollectionPointer->addAction(QLatin1String("cookies"));
122 findCaseSensitiveActionPointer = actionCollectionPointer->addAction(QLatin1String("find_case_sensitive"));
123 hideFindTextActionPointer = actionCollectionPointer->addAction(QLatin1String("hide_find_actions"));
125 // Create the action groups
126 QActionGroup *userAgentActionGroupPointer = new QActionGroup(this);
127 QActionGroup *searchEngineActionGroupPointer = new QActionGroup(this);
129 // Add the actions to the groups.
130 userAgentActionGroupPointer->addAction(userAgentPrivacyBrowserActionPointer);
131 userAgentActionGroupPointer->addAction(userAgentWebEngineDefaultActionPointer);
132 userAgentActionGroupPointer->addAction(userAgentFirefoxLinuxActionPointer);
133 userAgentActionGroupPointer->addAction(userAgentChromiumLinuxActionPointer);
134 userAgentActionGroupPointer->addAction(userAgentFirefoxWindowsActionPointer);
135 userAgentActionGroupPointer->addAction(userAgentChromeWindowsActionPointer);
136 userAgentActionGroupPointer->addAction(userAgentEdgeWindowsActionPointer);
137 userAgentActionGroupPointer->addAction(userAgentSafariMacosActionPointer);
138 userAgentActionGroupPointer->addAction(userAgentCustomActionPointer);
139 searchEngineActionGroupPointer->addAction(searchEngineMojeekActionPointer);
140 searchEngineActionGroupPointer->addAction(searchEngineMonoclesActionPointer);
141 searchEngineActionGroupPointer->addAction(searchEngineMetagerActionPointer);
142 searchEngineActionGroupPointer->addAction(searchEngineGoogleActionPointer);
143 searchEngineActionGroupPointer->addAction(searchEngineBingActionPointer);
144 searchEngineActionGroupPointer->addAction(searchEngineYahooActionPointer);
145 searchEngineActionGroupPointer->addAction(searchEngineCustomActionPointer);
147 // Set some actions to be checkable.
148 javaScriptActionPointer->setCheckable(true);
149 localStorageActionPointer->setCheckable(true);
150 domStorageActionPointer->setCheckable(true);
151 findCaseSensitiveActionPointer->setCheckable(true);
152 viewSourceActionPointer->setCheckable(true);
153 userAgentPrivacyBrowserActionPointer->setCheckable(true);
154 userAgentWebEngineDefaultActionPointer->setCheckable(true);
155 userAgentFirefoxLinuxActionPointer->setCheckable(true);
156 userAgentChromiumLinuxActionPointer->setCheckable(true);
157 userAgentFirefoxWindowsActionPointer->setCheckable(true);
158 userAgentChromeWindowsActionPointer->setCheckable(true);
159 userAgentEdgeWindowsActionPointer->setCheckable(true);
160 userAgentSafariMacosActionPointer->setCheckable(true);
161 userAgentCustomActionPointer->setCheckable(true);
162 searchEngineMojeekActionPointer->setCheckable(true);
163 searchEngineMonoclesActionPointer->setCheckable(true);
164 searchEngineMetagerActionPointer->setCheckable(true);
165 searchEngineGoogleActionPointer->setCheckable(true);
166 searchEngineBingActionPointer->setCheckable(true);
167 searchEngineYahooActionPointer->setCheckable(true);
168 searchEngineCustomActionPointer->setCheckable(true);
169 viewBookmarksToolBarActionPointer->setCheckable(true);
171 // Instantiate the user agent helper.
172 UserAgentHelper *userAgentHelperPointer = new UserAgentHelper();
174 // Set the action text.
175 newTabActionPointer->setText(i18nc("New tab action", "New Tab"));
176 newWindowActionPointer->setText(i18nc("New window action", "New Window"));
177 saveArchiveActionPointer->setText(i18nc("Save archive action", "Save Archive"));
178 zoomDefaultActionPointer->setText(i18nc("Zoom default action", "Zoom Default"));
179 reloadAndBypassCacheActionPointer->setText(i18nc("Reload and bypass cache action", "Reload and Bypass Cache"));
180 viewSourceActionPointer->setText(i18nc("View source action", "View Source"));
181 viewSourceInNewTabActionPointer->setText(i18nc("View source in new tab action", "View Source in New Tab"));
182 javaScriptActionPointer->setText(i18nc("JavaScript action", "JavaScript"));
183 localStorageActionPointer->setText(i18nc("The Local Storage action", "Local Storage"));
184 domStorageActionPointer->setText(i18nc("DOM Storage action", "DOM Storage"));
185 userAgentPrivacyBrowserActionPointer->setText(userAgentHelperPointer->PRIVACY_BROWSER_TRANSLATED);
186 userAgentWebEngineDefaultActionPointer->setText(userAgentHelperPointer->WEB_ENGINE_DEFAULT_TRANSLATED);
187 userAgentFirefoxLinuxActionPointer->setText(userAgentHelperPointer->FIREFOX_LINUX_TRANSLATED);
188 userAgentChromiumLinuxActionPointer->setText(userAgentHelperPointer->CHROMIUM_LINUX_TRANSLATED);
189 userAgentFirefoxWindowsActionPointer->setText(userAgentHelperPointer->FIREFOX_WINDOWS_TRANSLATED);
190 userAgentChromeWindowsActionPointer->setText(userAgentHelperPointer->CHROME_WINDOWS_TRANSLATED);
191 userAgentEdgeWindowsActionPointer->setText(userAgentHelperPointer->EDGE_WINDOWS_TRANSLATED);
192 userAgentSafariMacosActionPointer->setText(userAgentHelperPointer->SAFARI_MACOS_TRANSLATED);
193 searchEngineMojeekActionPointer->setText(i18nc("Search engine", "Mojeek"));
194 searchEngineMonoclesActionPointer->setText(i18nc("Search engine", "Monocles"));
195 searchEngineMetagerActionPointer->setText(i18nc("Search engine", "MetaGer"));
196 searchEngineGoogleActionPointer->setText(i18nc("Search engine", "Google"));
197 searchEngineBingActionPointer->setText(i18nc("Search engine", "Bing"));
198 searchEngineYahooActionPointer->setText(i18nc("Search engine", "Yahoo"));
199 viewBookmarksToolBarActionPointer->setText(i18nc("View bookmarks toolbar", "View Bookmarks Toolbar"));
200 domainSettingsActionPointer->setText(i18nc("Domain Settings action", "Domain Settings"));
201 cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", 0));
202 findCaseSensitiveActionPointer->setText(i18nc("Find Case Sensitive action", "Find Case Sensitive"));
203 hideFindTextActionPointer->setText(i18nc("Hide Find Text action (the text should include the language-specific escape keyboard shortcut).", "Hide Find Text (Esc)"));
205 // Set the action icons. Gnome doesn't contain some of the icons that KDE has.
206 // The toolbar icons don't pick up unless the size is explicit, probably because the toolbar ends up being an intermediate size.
207 newTabActionPointer->setIcon(QIcon::fromTheme(QLatin1String("tab-new")));
208 newWindowActionPointer->setIcon(QIcon::fromTheme(QLatin1String("window-new")));
209 saveArchiveActionPointer->setIcon(QIcon::fromTheme(QLatin1String("document-save")));
210 zoomDefaultActionPointer->setIcon(QIcon::fromTheme(QLatin1String("zoom-fit-best")));
211 reloadAndBypassCacheActionPointer->setIcon(QIcon::fromTheme(QLatin1String("view-refresh")));
212 viewSourceActionPointer->setIcon(QIcon::fromTheme(QLatin1String("view-choose"), QIcon::fromTheme(QLatin1String("accessories-text-editor"))));
213 viewSourceInNewTabActionPointer->setIcon(QIcon::fromTheme(QLatin1String("view-choose"), QIcon::fromTheme(QLatin1String("accessories-text-editor"))));
214 domStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("code-class"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/actions/gtk-unindent-ltr.png"))));
215 userAgentPrivacyBrowserActionPointer->setIcon(QIcon(":/icons/privacy-mode.svg"));
216 userAgentWebEngineDefaultActionPointer->setIcon(QIcon::fromTheme(QLatin1String("qtlogo"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
217 userAgentFirefoxLinuxActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"),
218 QIcon::fromTheme(QLatin1String("contact-new")))));
219 userAgentChromiumLinuxActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
220 userAgentFirefoxWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"),
221 QIcon::fromTheme(QLatin1String("contact-new")))));
222 userAgentChromeWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
223 userAgentEdgeWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
224 userAgentSafariMacosActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
225 userAgentCustomActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
226 searchEngineMojeekActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
227 searchEngineMonoclesActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
228 searchEngineMetagerActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
229 searchEngineGoogleActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-google"), QIcon::fromTheme(QLatin1String("edit-find"))));
230 searchEngineBingActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
231 searchEngineYahooActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-yahoo"), QIcon::fromTheme(QLatin1String("edit-find"))));
232 searchEngineCustomActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
233 zoomFactorActionPointer->setIcon(QIcon::fromTheme(QLatin1String("zoom-fit-best")));
234 editBookmarksActionPointer->setIcon(QIcon::fromTheme(QLatin1String("bookmark-edit"), QIcon::fromTheme(QLatin1String("bookmark-new"))));
235 viewBookmarksToolBarActionPointer->setIcon(QIcon::fromTheme(QLatin1String("bookmarks"), QIcon::fromTheme(QLatin1String("bookmark-new"))));
236 domainSettingsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("settings-configure"), QIcon::fromTheme(QLatin1String("preferences-desktop"))));
237 cookiesActionPointer->setIcon(QIcon::fromTheme(QLatin1String("preferences-web-browser-cookies"), QIcon::fromTheme(QLatin1String("appointment-new"))));
238 findCaseSensitiveActionPointer->setIcon(QIcon::fromTheme(QLatin1String("format-text-lowercase"), QIcon::fromTheme(QLatin1String("/usr/share/icons/gnome/32x32/apps/fonts.png"))));
239 hideFindTextActionPointer->setIcon(QIcon::fromTheme(QLatin1String("window-close-symbolic")));
241 // Create the key sequences.
242 QKeySequence ctrlTKeySequence = QKeySequence(i18nc("The open new tab key sequence.", "Ctrl+T"));
243 QKeySequence ctrlNKeySequence = QKeySequence(i18nc("The open new window key sequence.", "Ctrl+N"));
244 QKeySequence ctrlAKeySequence = QKeySequence(i18nc("The save archive key sequence.", "Ctrl+A"));
245 QKeySequence ctrl0KeySequence = QKeySequence(i18nc("The zoom default key sequence.", "Ctrl+0"));
246 QKeySequence ctrlF5KeySequence = QKeySequence(i18nc("The reload and bypass cache key sequence.", "Ctrl+F5"));
247 QKeySequence ctrlUKeySequence = QKeySequence(i18nc("The view source key sequence.", "Ctrl+U"));
248 QKeySequence ctrlShiftUKeySequence = QKeySequence(i18nc("The view source in new tab key sequence.", "Ctrl+Shift+U"));
249 QKeySequence ctrlShiftPKeySequence = QKeySequence(i18nc("The print preview key sequence.", "Ctrl+Shift+P"));
250 QKeySequence ctrlJKeySequence = QKeySequence(i18nc("The JavaScript key sequence.", "Ctrl+J"));
251 QKeySequence ctrlLKeySequence = QKeySequence(i18nc("The local storage key sequence.", "Ctrl+L"));
252 QKeySequence ctrlDKeySequence = QKeySequence(i18nc("The DOM storage key sequence.", "Ctrl+D"));
253 QKeySequence ctrlSKeySequence = QKeySequence(i18nc("The find case sensitive key sequence.", "Ctrl+S"));
254 QKeySequence ctrlAltPKeySequence = QKeySequence(i18nc("The Privacy Browser user agent key sequence.", "Ctrl+Alt+P"));
255 QKeySequence ctrlAltWKeySequence = QKeySequence(i18nc("The WebEngine Default user agent key sequence.", "Ctrl+Alt+W"));
256 QKeySequence ctrlAltFKeySequence = QKeySequence(i18nc("The Firefox on Linux user agent key sequence.", "Ctrl+Alt+F"));
257 QKeySequence ctrlAltCKeySequence = QKeySequence(i18nc("The Chromium on Linux user agent key sequence.", "Ctrl+Alt+C"));
258 QKeySequence ctrlAltShiftFKeySequence = QKeySequence(i18nc("The Firefox on Windows user agent key sequence.", "Ctrl+Alt+Shift+F"));
259 QKeySequence ctrlAltShiftCKeySequence = QKeySequence(i18nc("The Chrome on Windows user agent key sequence.", "Ctrl+Alt+Shift+C"));
260 QKeySequence ctrlAltEKeySequence = QKeySequence(i18nc("The Edge on Windows user agent key sequence.", "Ctrl+Alt+E"));
261 QKeySequence ctrlAltSKeySequence = QKeySequence(i18nc("The Safari on macOS user agent key sequence.", "Ctrl+Alt+S"));
262 QKeySequence altShiftCKeySequence = QKeySequence(i18nc("The custom user agent key sequence.", "Alt+Shift+C"));
263 QKeySequence ctrlAltZKeySequence = QKeySequence(i18nc("The zoom factor key sequence.", "Ctrl+Alt+Z"));
264 QKeySequence ctrlShiftMKeySequence = QKeySequence(i18nc("The Mojeek search engine key sequence.", "Ctrl+Shift+M"));
265 QKeySequence ctrlShiftOKeySequence = QKeySequence(i18nc("The Monocles search engine key sequence.", "Ctrl+Shift+O"));
266 QKeySequence ctrlShiftEKeySequence = QKeySequence(i18nc("The MetaGer search engine key sequence.", "Ctrl+Shift+E"));
267 QKeySequence ctrlShiftGKeySequence = QKeySequence(i18nc("The Google search engine key sequence.", "Ctrl+Shift+G"));
268 QKeySequence ctrlShiftBKeySequence = QKeySequence(i18nc("The Bing search engine key sequence.", "Ctrl+Shift+B"));
269 QKeySequence ctrlShiftYKeySequence = QKeySequence(i18nc("The Yahoo search engine key sequence.", "Ctrl+Shift+Y"));
270 QKeySequence ctrlShiftCKeySequence = QKeySequence(i18nc("The custom search engine key sequence.", "Ctrl+Shift+C"));
271 QKeySequence ctrlAltShiftBKeySequence = QKeySequence(i18nc("The edit bookmarks key sequence.", "Ctrl+Alt+Shift+B"));
272 QKeySequence ctrlAltBKeySequence = QKeySequence(i18nc("The view bookmarks toolbar key sequence.", "Ctrl+Alt+B"));
273 QKeySequence ctrlShiftDKeySequence = QKeySequence(i18nc("The domain settings key sequence.", "Ctrl+Shift+D"));
274 QKeySequence ctrlSemicolonKeySequence = QKeySequence(i18nc("The cookies dialog key sequence.", "Ctrl+;"));
276 // Set the action key sequences.
277 actionCollectionPointer->setDefaultShortcut(newTabActionPointer, ctrlTKeySequence);
278 actionCollectionPointer->setDefaultShortcut(newWindowActionPointer, ctrlNKeySequence);
279 actionCollectionPointer->setDefaultShortcut(saveArchiveActionPointer, ctrlAKeySequence);
280 actionCollectionPointer->setDefaultShortcut(zoomDefaultActionPointer, ctrl0KeySequence);
281 actionCollectionPointer->setDefaultShortcut(reloadAndBypassCacheActionPointer, ctrlF5KeySequence);
282 actionCollectionPointer->setDefaultShortcut(viewSourceActionPointer, ctrlUKeySequence);
283 actionCollectionPointer->setDefaultShortcut(viewSourceInNewTabActionPointer, ctrlShiftUKeySequence);
284 actionCollectionPointer->setDefaultShortcut(printPreviewActionPointer, ctrlShiftPKeySequence);
285 actionCollectionPointer->setDefaultShortcut(javaScriptActionPointer, ctrlJKeySequence);
286 actionCollectionPointer->setDefaultShortcut(localStorageActionPointer, ctrlLKeySequence);
287 actionCollectionPointer->setDefaultShortcut(domStorageActionPointer, ctrlDKeySequence);
288 actionCollectionPointer->setDefaultShortcut(findCaseSensitiveActionPointer, ctrlSKeySequence);
289 actionCollectionPointer->setDefaultShortcut(userAgentPrivacyBrowserActionPointer, ctrlAltPKeySequence);
290 actionCollectionPointer->setDefaultShortcut(userAgentWebEngineDefaultActionPointer, ctrlAltWKeySequence);
291 actionCollectionPointer->setDefaultShortcut(userAgentFirefoxLinuxActionPointer, ctrlAltFKeySequence);
292 actionCollectionPointer->setDefaultShortcut(userAgentChromiumLinuxActionPointer, ctrlAltCKeySequence);
293 actionCollectionPointer->setDefaultShortcut(userAgentFirefoxWindowsActionPointer, ctrlAltShiftFKeySequence);
294 actionCollectionPointer->setDefaultShortcut(userAgentChromeWindowsActionPointer, ctrlAltShiftCKeySequence);
295 actionCollectionPointer->setDefaultShortcut(userAgentEdgeWindowsActionPointer, ctrlAltEKeySequence);
296 actionCollectionPointer->setDefaultShortcut(userAgentSafariMacosActionPointer, ctrlAltSKeySequence);
297 actionCollectionPointer->setDefaultShortcut(userAgentCustomActionPointer, altShiftCKeySequence);
298 actionCollectionPointer->setDefaultShortcut(zoomFactorActionPointer, ctrlAltZKeySequence);
299 actionCollectionPointer->setDefaultShortcut(searchEngineMojeekActionPointer, ctrlShiftMKeySequence);
300 actionCollectionPointer->setDefaultShortcut(searchEngineMonoclesActionPointer, ctrlShiftOKeySequence);
301 actionCollectionPointer->setDefaultShortcut(searchEngineMetagerActionPointer, ctrlShiftEKeySequence);
302 actionCollectionPointer->setDefaultShortcut(searchEngineGoogleActionPointer, ctrlShiftGKeySequence);
303 actionCollectionPointer->setDefaultShortcut(searchEngineBingActionPointer, ctrlShiftBKeySequence);
304 actionCollectionPointer->setDefaultShortcut(searchEngineYahooActionPointer, ctrlShiftYKeySequence);
305 actionCollectionPointer->setDefaultShortcut(searchEngineCustomActionPointer, ctrlShiftCKeySequence);
306 actionCollectionPointer->setDefaultShortcut(editBookmarksActionPointer, ctrlAltShiftBKeySequence);
307 actionCollectionPointer->setDefaultShortcut(viewBookmarksToolBarActionPointer, ctrlAltBKeySequence);
308 actionCollectionPointer->setDefaultShortcut(domainSettingsActionPointer, ctrlShiftDKeySequence);
309 actionCollectionPointer->setDefaultShortcut(cookiesActionPointer, ctrlSemicolonKeySequence);
311 // Execute the actions.
312 connect(newTabActionPointer, SIGNAL(triggered()), tabWidgetPointer, SLOT(addTab()));
313 connect(newWindowActionPointer, SIGNAL(triggered()), this, SLOT(newWindow()));
314 connect(saveArchiveActionPointer, SIGNAL(triggered()), tabWidgetPointer, SLOT(saveArchive()));
315 connect(zoomDefaultActionPointer, SIGNAL(triggered()), this, SLOT(zoomDefault()));
316 connect(reloadAndBypassCacheActionPointer, SIGNAL(triggered()), this, SLOT(reloadAndBypassCache()));
317 connect(viewSourceActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewSource()));
318 connect(viewSourceInNewTabActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewSourceInNewTab()));
319 connect(zoomFactorActionPointer, SIGNAL(triggered()), this, SLOT(getZoomFactorFromUser()));
320 connect(viewBookmarksToolBarActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewBookmarksToolBar()));
321 connect(cookiesActionPointer, SIGNAL(triggered()), this, SLOT(showCookiesDialog()));
322 connect(domainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(showDomainSettingsDialog()));
324 // Update the on-the-fly menus.
325 connect(tabWidgetPointer, SIGNAL(updateUserAgentActions(QString, bool)), this, SLOT(updateUserAgentActions(QString, bool)));
326 connect(tabWidgetPointer, SIGNAL(updateZoomActions(double)), this, SLOT(updateZoomActions(double)));
327 connect(tabWidgetPointer, SIGNAL(updateSearchEngineActions(QString, bool)), this, SLOT(updateSearchEngineActions(QString, bool)));
329 // Apply the on-the-fly settings when selected.
330 connect(userAgentActionGroupPointer, SIGNAL(triggered(QAction*)), tabWidgetPointer, SLOT(applyOnTheFlyUserAgent(QAction*)));
331 connect(searchEngineActionGroupPointer, SIGNAL(triggered(QAction*)), tabWidgetPointer, SLOT(applyOnTheFlySearchEngine(QAction*)));
333 // Process cookie changes.
334 connect(tabWidgetPointer, SIGNAL(updateCookiesAction(int)), this, SLOT(updateCookiesAction(int)));
336 // Store the default zoom factor.
337 connect(tabWidgetPointer, SIGNAL(updateDefaultZoomFactor(double)), this, SLOT(updateDefaultZoomFactor(double)));
339 // Connect the URL toolbar actions.
340 connect(javaScriptActionPointer, SIGNAL(triggered()), this, SLOT(toggleJavaScript()));
341 connect(localStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleLocalStorage()));
342 connect(domStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleDomStorage()));
344 // Update the URL toolbar actions.
345 connect(tabWidgetPointer, SIGNAL(updateBackAction(bool)), backActionPointer, SLOT(setEnabled(bool)));
346 connect(tabWidgetPointer, SIGNAL(updateForwardAction(bool)), forwardActionPointer, SLOT(setEnabled(bool)));
347 connect(tabWidgetPointer, SIGNAL(updateJavaScriptAction(bool)), this, SLOT(updateJavaScriptAction(bool)));
348 connect(tabWidgetPointer, SIGNAL(updateLocalStorageAction(bool)), this, SLOT(updateLocalStorageAction(bool)));
349 connect(tabWidgetPointer, SIGNAL(updateDomStorageAction(bool)), this, SLOT(updateDomStorageAction(bool)));
351 // Connect the find text actions.
352 connect(findCaseSensitiveActionPointer, SIGNAL(triggered()), this, SLOT(toggleFindCaseSensitive()));
353 connect(hideFindTextActionPointer, SIGNAL(triggered()), this, SLOT(hideFindTextActions()));
357 // Setup the GUI based on the browserwindowui.rc file.
358 setupGUI(StandardWindowOption::Default, ("browserwindowui.rc"));
360 // Get lists of the actions' associated widgets.
361 QList<QWidget*> userAgentAssociatedWidgetsPointerList = userAgentPrivacyBrowserActionPointer->associatedWidgets();
362 QList<QWidget*> searchEngineAssociatedWidgetsPointerList = searchEngineMojeekActionPointer->associatedWidgets();
364 // Get the menu widget pointers. It is the second entry, after the main window.
365 QWidget *userAgentMenuWidgetPointer = userAgentAssociatedWidgetsPointerList[1];
366 QWidget *searchEngineMenuWidgetPointer = searchEngineAssociatedWidgetsPointerList[1];
368 // Get the menu pointers.
369 QMenu *userAgentMenuPointer = qobject_cast<QMenu*>(userAgentMenuWidgetPointer);
370 QMenu *searchEngineMenuPointer = qobject_cast<QMenu*>(searchEngineMenuWidgetPointer);
372 // Get the menu actions.
373 userAgentMenuActionPointer = userAgentMenuPointer->menuAction();
374 searchEngineMenuActionPointer = searchEngineMenuPointer->menuAction();
376 // Get handles for the toolbars.
377 navigationToolBarPointer = toolBar(QLatin1String("navigation_toolbar"));
378 urlToolBarPointer = toolBar(QLatin1String("url_toolbar"));
379 bookmarksToolBarPointer = toolBar(QLatin1String("bookmarks_toolbar"));
381 // Populate the view bookmarks toolbar checkbox.
382 connect(bookmarksToolBarPointer, SIGNAL(visibilityChanged(bool)), this, SLOT(updateViewBookmarksToolBarCheckbox(bool)));
384 // Create the line edits.
385 urlLineEditPointer = new KLineEdit();
386 findTextLineEditPointer = new KLineEdit();
388 // Get the line edit size policies.
389 QSizePolicy urlLineEditSizePolicy = urlLineEditPointer->sizePolicy();
390 QSizePolicy findTextLineEditSizePolicy = findTextLineEditPointer->sizePolicy();
392 // Set the URL line edit horizontal stretch to be five times the find text line edit stretch.
393 urlLineEditSizePolicy.setHorizontalStretch(5);
394 findTextLineEditSizePolicy.setHorizontalStretch(1);
397 urlLineEditPointer->setSizePolicy(urlLineEditSizePolicy);
398 findTextLineEditPointer->setSizePolicy(findTextLineEditSizePolicy);
401 urlLineEditPointer->setMinimumWidth(350);
402 findTextLineEditPointer->setMinimumWidth(200);
403 findTextLineEditPointer->setMaximumWidth(350);
405 // Set the place holder text.
406 urlLineEditPointer->setPlaceholderText(i18nc("The URL line edit placeholder text", "URL or Search Terms"));
407 findTextLineEditPointer->setPlaceholderText(i18nc("The find line edit placeholder text", "Find Text"));
409 // Show the clear button on the find line edit.
410 findTextLineEditPointer->setClearButtonEnabled(true);
412 // Add the actions to the URL line edit.
413 bookmarkedActionPointer = urlLineEditPointer->addAction(QIcon::fromTheme("non-starred-symbolic"), QLineEdit::LeadingPosition);
414 QAction *addOrEditDomainSettingsActionPointer = urlLineEditPointer->addAction(QIcon::fromTheme("settings-configure", QIcon::fromTheme(QLatin1String("preferences-desktop"))),
415 QLineEdit::TrailingPosition);
417 // Set the bookmarked action pointer to be checkable.
418 bookmarkedActionPointer->setCheckable(true);
420 // Connect the URL line edit actions.
421 connect(bookmarkedActionPointer, SIGNAL(triggered()), this, SLOT(toggleBookmark()));
422 connect(addOrEditDomainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(addOrEditDomainSettings()));
424 // Create a find text label pointer.
425 findTextLabelPointer = new QLabel();
427 // Set the default label text.
428 findTextLabelPointer->setText(QLatin1String(" ") + i18nc("Default find results.", "0/0") + QLatin1String(" "));
430 // Insert the widgets into the toolbars.
431 urlToolBarPointer->insertWidget(javaScriptActionPointer, urlLineEditPointer);
432 findTextLineEditActionPointer = urlToolBarPointer->insertWidget(findNextActionPointer, findTextLineEditPointer);
433 findTextLabelActionPointer = urlToolBarPointer->insertWidget(findNextActionPointer, findTextLabelPointer);
435 // Initially hide the find text actions.
436 hideFindTextActions();
438 // Load a new URL from the URL line edit.
439 connect(urlLineEditPointer, SIGNAL(returnKeyPressed(const QString)), this, SLOT(loadUrlFromLineEdit(const QString)));
441 // Find text as it is typed.
442 connect(findTextLineEditPointer, SIGNAL(textEdited(const QString &)), tabWidgetPointer, SLOT(findText(const QString &)));
444 // Find next if the enter key is pressed.
445 connect(findTextLineEditPointer, SIGNAL(returnKeyPressed(const QString &)), tabWidgetPointer, SLOT(findText(const QString &)));
447 // Update find text when switching tabs.
448 connect(tabWidgetPointer, SIGNAL(updateFindText(const QString &, const bool)), this, SLOT(updateFindText(const QString &, const bool)));
450 // Update the find text results.
451 connect(tabWidgetPointer, SIGNAL(updateFindTextResults(const QWebEngineFindTextResult &)), this, SLOT(updateFindTextResults(const QWebEngineFindTextResult &)));
453 // Update the URL line edit on page loads.
454 connect(tabWidgetPointer, SIGNAL(updateUrlLineEdit(QUrl)), this, SLOT(updateUrlLineEdit(QUrl)));
456 // Update the window title.
457 connect(tabWidgetPointer, SIGNAL(updateWindowTitle(const QString)), this, SLOT(updateWindowTitle(const QString)));
459 // Get a handle for the status bar.
460 QStatusBar *statusBarPointer = statusBar();
462 // Create the status bar widgets.
463 progressBarPointer = new QProgressBar();
464 zoomMinusButtonPointer = new QPushButton();
465 currentZoomButtonPointer = new QPushButton();
466 zoomPlusButtonPointer = new QPushButton();
468 // Set the button icons.
469 zoomMinusButtonPointer->setIcon(QIcon::fromTheme(QStringLiteral("list-remove-symbolic")));
470 zoomPlusButtonPointer->setIcon(QIcon::fromTheme(QStringLiteral("list-add-symbolic")));
472 // Set the button icons to be flat (no borders).
473 zoomMinusButtonPointer->setFlat(true);
474 currentZoomButtonPointer->setFlat(true);
475 zoomPlusButtonPointer->setFlat(true);
477 // Handle clicks on the zoom buttons.
478 connect(zoomMinusButtonPointer, SIGNAL(clicked()), this, SLOT(decrementZoom()));
479 connect(currentZoomButtonPointer, SIGNAL(clicked()), this, SLOT(getZoomFactorFromUser()));
480 connect(zoomPlusButtonPointer, SIGNAL(clicked()), this, SLOT(incrementZoom()));
482 // Remove the padding around the current zoom button text.
483 currentZoomButtonPointer->setStyleSheet("padding: 0px;");
485 // Add the widgets to the far right of the status bar.
486 statusBarPointer->addPermanentWidget(progressBarPointer);
487 statusBarPointer->addPermanentWidget(zoomMinusButtonPointer);
488 statusBarPointer->addPermanentWidget(currentZoomButtonPointer);
489 statusBarPointer->addPermanentWidget(zoomPlusButtonPointer);
491 // Update the status bar with the URL when a link is hovered.
492 connect(tabWidgetPointer, SIGNAL(linkHovered(QString)), statusBarPointer, SLOT(showMessage(QString)));
494 // Update the progress bar.
495 connect(tabWidgetPointer, SIGNAL(showProgressBar(const int)), this, SLOT(showProgressBar(const int)));
496 connect(tabWidgetPointer, SIGNAL(hideProgressBar()), progressBarPointer, SLOT(hide()));
498 // Update the URL line edit focus.
499 connect(tabWidgetPointer, SIGNAL(clearUrlLineEditFocus()), this, SLOT(clearUrlLineEditFocus()));
501 // Get the URL line edit palettes.
502 normalBackgroundPalette = urlLineEditPointer->palette();
503 negativeBackgroundPalette = normalBackgroundPalette;
504 positiveBackgroundPalette = normalBackgroundPalette;
506 // Modify the palettes.
507 KColorScheme::adjustBackground(negativeBackgroundPalette, KColorScheme::NegativeBackground);
508 KColorScheme::adjustBackground(positiveBackgroundPalette, KColorScheme::PositiveBackground);
510 // Update the applied palette.
511 connect(tabWidgetPointer, SIGNAL(updateDomainSettingsIndicator(const bool)), this, SLOT(updateDomainSettingsIndicator(const bool)));
513 // Process full screen requests.
514 connect(tabWidgetPointer, SIGNAL(fullScreenRequested(bool)), this, SLOT(fullScreenRequested(bool)));
516 // Create keyboard shortcuts.
517 QShortcut *f11ShortcutPointer = new QShortcut(QKeySequence(i18nc("The toggle full screen shortcut.", "F11")), this);
518 QShortcut *escapeShortcutPointer = new QShortcut(QKeySequence::Cancel, this);
520 // Connect the keyboard shortcuts.
521 connect(f11ShortcutPointer, SIGNAL(activated()), fullScreenActionPointer, SLOT(trigger()));
522 connect(escapeShortcutPointer, SIGNAL(activated()), this, SLOT(escape()));
524 // Get a handle for the Bookmarks menu.
525 bookmarksMenuPointer = qobject_cast<QMenu*>(guiFactory()->container("bookmarks", this));
527 // Add a separator to the bookmarks menu.
528 bookmarksMenuPointer->addSeparator();
530 // Initialize the current bookmarks lists.
531 finalBookmarkFolderMenuActionList = QList<QPair<QMenu *, QAction *> *>();
532 bookmarksMenuActionList = QList<QPair<QMenu *, QAction *> *>();
533 bookmarksMenuSubmenuList = QList<QPair<QMenu *, QMenu *> *>();
534 bookmarksToolBarActionList = QList<QAction*>();
535 bookmarksToolBarSubfolderActionList = QList<QPair<QMenu *, QAction * > *>();
537 // Set the bookmarks toolbar context menu policy.
538 bookmarksToolBarPointer->setContextMenuPolicy(Qt::CustomContextMenu);
540 // Show the custom bookmark context menu when requested.
541 connect(bookmarksToolBarPointer, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showBookmarkContextMenu(const QPoint&)));
543 // Populate the bookmarks in this window.
544 populateBookmarksInThisWindow();
547 // 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.
548 updateJavaScriptAction(Settings::javaScriptEnabled());
549 updateLocalStorageAction(Settings::localStorageEnabled());
550 updateDomStorageAction(Settings::domStorageEnabled());
551 updateUserAgentActions(UserAgentHelper::getUserAgentFromDatabaseName(Settings::userAgent()), true);
552 updateZoomActions(Settings::zoomFactor());
554 // Populate the first tab.
555 if (firstWindow) // This is the first window.
557 // Load the initial website.
558 tabWidgetPointer->loadInitialWebsite();
560 else if (initialUrlStringPointer) // An initial URL was specified.
562 // Load the initial URL.
563 tabWidgetPointer->loadUrlFromLineEdit(*initialUrlStringPointer);
567 void BrowserWindow::addFinalBookmarkFolderMenuActions(QMenu *menuPointer, double folderId)
569 // Get the database ID.
570 int folderDatabaseId = BookmarksDatabase::getFolderDatabaseId(folderId);
573 menuPointer->addSeparator();
575 // Add the add bookmark action to the menu.
576 QAction *addBookmarkActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("bookmark-new")), i18nc("The add bookmark action", "Add Bookmark"), [=]
578 // Instantiate an add bookmark dialog.
579 AddBookmarkDialog *addBookmarkDialogPointer = new AddBookmarkDialog(tabWidgetPointer->getCurrentTabTitle(), tabWidgetPointer->getCurrentTabUrl(),
580 tabWidgetPointer->getCurrentTabFavoritIcon(), folderId);
582 // Update the displayed bookmarks when a new one is added.
583 connect(addBookmarkDialogPointer, SIGNAL(bookmarkAdded()), this, SLOT(populateBookmarksInAllWindows()));
586 addBookmarkDialogPointer->show();
590 // Add the add folder action to the menu.
591 QAction *addFolderActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("folder-add")), i18nc("The add folder action", "Add Folder"), [=]
593 // Instantiate an add folder dialog.
594 AddFolderDialog *addFolderDialogPointer = new AddFolderDialog(tabWidgetPointer->getCurrentTabFavoritIcon(), folderId);
596 // Update the displayed bookmarks when a folder is added.
597 connect(addFolderDialogPointer, SIGNAL(folderAdded()), this, SLOT(populateBookmarksInAllWindows()));
600 addFolderDialogPointer->show();
605 menuPointer->addSeparator();
607 // Add the open folder in new tabs action to the menu.
608 QAction *openFolderInNewTabsActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("The open folder in new tabs action", "Open Folder in New Tabs"), [=]
610 // Get all the folder URLs.
611 QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(folderId);
613 // Open the URLs in new tabs. `true` removes the URL line edit focus, `false` does not load a background tab.
614 for (QString url : *folderUrlsListPointer)
615 tabWidgetPointer->addTab(true, false, url);
619 // Add the open folder in background tabs action to the menu.
620 QAction *openFolderInBackgroundTabsActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")),
621 i18nc("The open folder in background tabs action", "Open Folder in Background Tabs"), [=]
623 // Get all the folder URLs.
624 QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(folderId);
626 // Open the URLs in new tabs. `true` removes the URL line edit focus, `true` loads a background tab.
627 for (QString url : *folderUrlsListPointer)
628 tabWidgetPointer->addTab(true, true, url);
632 // Add the open folder in new window action to the menu.
633 QAction *openFolderInNewWindowActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("window-new")), i18nc("The open folder in new window action", "Open Folder in New Window"), [=]
635 // Get all the folder URLs.
636 QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(folderId);
638 // Create a new browser window.
639 BrowserWindow *browserWindowPointer = new BrowserWindow(false, &folderUrlsListPointer->first());
641 // Get a count of the folder URLs.
642 const int folderUrls = folderUrlsListPointer->count();
644 // Load all the other URLs. `true` removes the URL line edit focus, `true` loads a background tab.
645 for (int i = 1; i < folderUrls; ++i)
646 browserWindowPointer->tabWidgetPointer->addTab(true, true, folderUrlsListPointer->value(i));
648 // Show the new browser window.
649 browserWindowPointer->show();
654 menuPointer->addSeparator();
656 // Add the edit folder action to the menu if this is not the root bookmark menu.
659 QAction *editFolderActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("document-edit")), i18nc("The edit folder action", "Edit Folder"), [=]
661 // Get the current tab favorite icon.
662 QIcon currentTabFavoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
664 // Instantiate an edit folder dialog.
665 QDialog *editFolderDialogPointer = new EditFolderDialog(folderDatabaseId, currentTabFavoriteIcon);
668 editFolderDialogPointer->show();
670 // Process bookmark events.
671 connect(editFolderDialogPointer, SIGNAL(folderSaved()), this, SLOT(populateBookmarksInAllWindows()));
675 // Add the action to the beginning of the final bookmark folder menu action list.
676 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, editFolderActionPointer));
679 // Add the delete folder action to the menu.
680 QAction *deleteFolderActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-delete")), i18nc("Delete folder context menu entry", "Delete Folder"), [=]
682 // Create an items to delete list.
683 QList<int>* itemsToDeleteListPointer = new QList<int>;
685 // Add the folder to the list of items to delete if it is not the root folder.
687 itemsToDeleteListPointer->append(folderDatabaseId);
689 // Add the folder contents to the list of items to delete.
690 itemsToDeleteListPointer->append(*BookmarksDatabase::getFolderContentsDatabaseIdsRecursively(folderId));
692 // Instantiate a delete dialog message box.
693 QMessageBox deleteDialogMessageBox;
696 deleteDialogMessageBox.setIcon(QMessageBox::Warning);
698 // Set the window title.
699 deleteDialogMessageBox.setWindowTitle(i18nc("Delete bookmarks dialog title", "Delete Bookmarks"));
702 deleteDialogMessageBox.setText(i18ncp("Delete bookmarks dialog main message", "Delete %1 bookmark item?", "Delete %1 bookmark items?", itemsToDeleteListPointer->count()));
704 // Set the informative text.
705 deleteDialogMessageBox.setInformativeText(i18nc("Delete bookmarks dialog secondary message", "This cannot be undone."));
707 // Set the standard buttons.
708 deleteDialogMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
710 // Set the default button.
711 deleteDialogMessageBox.setDefaultButton(QMessageBox::No);
713 // Display the dialog and capture the return value.
714 int returnValue = deleteDialogMessageBox.exec();
716 // Delete the domain if instructed.
717 if (returnValue == QMessageBox::Yes)
719 // Get the parent folder ID.
720 double parentFolderId = BookmarksDatabase::getParentFolderId(folderDatabaseId);
722 // Delete the folder and its contents.
723 for (const int databaseId : *itemsToDeleteListPointer)
724 BookmarksDatabase::deleteBookmark(databaseId);
726 // Update the display order of the bookmarks in the parent folder.
727 BookmarksDatabase::updateFolderContentsDisplayOrder(parentFolderId);
729 // Repopulate the bookmarks.
730 populateBookmarksInAllWindows();
735 // Add the key sequences if this is the root bookmarks menu.
738 // Create the key sequences.
739 QKeySequence ctrlBKeySequence = QKeySequence(i18nc("The add bookmark key sequence.", "Ctrl+B"));
740 QKeySequence metaFKeySequence = QKeySequence(i18nc("The add folder key sequence.", "Meta+F"));
742 // Set the action key sequences.
743 actionCollectionPointer->setDefaultShortcut(addBookmarkActionPointer, ctrlBKeySequence);
744 actionCollectionPointer->setDefaultShortcut(addFolderActionPointer, metaFKeySequence);
747 // Add the actions to the beginning of the final bookmark folder menu action list.
748 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, addBookmarkActionPointer));
749 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, addFolderActionPointer));
750 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, openFolderInNewTabsActionPointer));
751 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, openFolderInBackgroundTabsActionPointer));
752 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, openFolderInNewWindowActionPointer));
753 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, deleteFolderActionPointer));
756 void BrowserWindow::addOrEditDomainSettings() const
758 // Remove the focus from the URL line edit.
759 urlLineEditPointer->clearFocus();
761 // Create the domain settings dialog pointer.
762 DomainSettingsDialog *domainSettingsDialogPointer;
764 // Get the current domain settings name.
765 QString ¤tDomainSettingsName = tabWidgetPointer->getDomainSettingsName();
767 // Run the commands according to the current domain settings status.
768 if (currentDomainSettingsName == QStringLiteral("")) // Domain settings are not currently applied.
770 // Instruct the domain settings dialog to add a new domain.
771 domainSettingsDialogPointer = new DomainSettingsDialog(DomainSettingsDialog::ADD_DOMAIN, currentUrl.host());
773 else // Domain settings are currently applied.
775 // Instruct the domain settings dialog to edit the current domain.
776 domainSettingsDialogPointer = new DomainSettingsDialog(DomainSettingsDialog::EDIT_DOMAIN, currentDomainSettingsName);
779 // Reload the tabs when domain settings are updated.
780 connect(domainSettingsDialogPointer, SIGNAL(domainSettingsUpdated()), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
783 domainSettingsDialogPointer->show();
786 void BrowserWindow::back() const
788 // Remove the focus from the URL line edit.
789 urlLineEditPointer->clearFocus();
792 tabWidgetPointer->back();
795 void BrowserWindow::clearUrlLineEditFocus() const
797 // Remove the focus from the URL line edit.
798 urlLineEditPointer->clearFocus();
801 void BrowserWindow::decrementZoom()
803 // Update the current zoom factor.
804 currentZoomFactor = currentZoomFactor - 0.25;
806 // Check to make sure the zoom factor is in the valid range (0.25 to 5.00).
807 if (currentZoomFactor < 0.25)
808 currentZoomFactor = 0.25;
810 // Set the new zoom factor.
811 tabWidgetPointer->applyOnTheFlyZoomFactor(currentZoomFactor);
813 // Update the on-the-fly action text.
814 updateZoomActions(currentZoomFactor);
817 void BrowserWindow::editBookmarks() const
819 // Instantiate an edit bookmarks dialog.
820 BookmarksDialog *bookmarksDialogPointer = new BookmarksDialog(tabWidgetPointer->getCurrentTabTitle(), tabWidgetPointer->getCurrentTabUrl(), tabWidgetPointer->getCurrentTabFavoritIcon());
822 // Update the displayed bookmarks when edited.
823 connect(bookmarksDialogPointer, SIGNAL(bookmarkUpdated()), this, SLOT(populateBookmarksInAllWindows()));
826 bookmarksDialogPointer->show();
829 void BrowserWindow::escape() const
831 // Process the escape according to the status of the browser.
832 if (fullScreenActionPointer->isChecked()) // Full screen browsing is enabled.
834 // Exit full screen browsing.
835 fullScreenActionPointer->trigger();
837 else if (!findTextLineEditPointer->text().isEmpty()) // Find text is populated.
839 // Clear the find text line edit.
840 findTextLineEditPointer->clear();
842 // Clear the search in the WebEngine.
843 tabWidgetPointer->findText(QStringLiteral(""));
845 else if (findTextLineEditActionPointer->isVisible()) // Find text actions are visible.
847 // Hide the find text actions.
848 hideFindTextActions();
852 void BrowserWindow::findNext() const
854 // Get the find string.
855 const QString findString = findTextLineEditPointer->text();
857 // Search for the text if it is not empty.
858 if (!findString.isEmpty())
859 tabWidgetPointer->findText(findString);
862 void BrowserWindow::findPrevious() const
864 // Get the find string.
865 const QString findString = findTextLineEditPointer->text();
867 // Search for the text if it is not empty.
868 if (!findString.isEmpty())
869 tabWidgetPointer->findPrevious(findString);
872 void BrowserWindow::forward() const
874 // Remove the focus from the URL line edit.
875 urlLineEditPointer->clearFocus();
878 tabWidgetPointer->forward();
881 void BrowserWindow::fullScreenRequested(const bool toggleOn)
883 // Toggle full screen mode.
884 if (toggleOn) // Turn full screen mode on.
886 // Enable full screen mode.
887 fullScreenActionPointer->setFullScreen(window(), true);
889 // Hide the menu bar if specified.
890 if (Settings::fullScreenHideMenuBar())
891 menuBar()->setVisible(false);
893 // Hide the toolbars if specified.
894 if (Settings::fullScreenHideToolBars())
896 navigationToolBarPointer->setVisible(false);
897 urlToolBarPointer->setVisible(false);
898 bookmarksToolBarPointer->setVisible(false);
901 // Hide the tab bar if specified.
902 if (Settings::fullScreenHideTabBar())
903 tabWidgetPointer->setTabBarVisible(false);
905 // Hide the status bar if specified.
906 if (Settings::fullScreenHideStatusBar())
907 statusBar()->setVisible(false);
909 else // Disable full screen browsing mode.
911 // Disable full screen mode.
912 fullScreenActionPointer->setFullScreen(window(), false);
914 // Show the menu bar.
915 menuBar()->setVisible(true);
917 // Show the toolbars.
918 navigationToolBarPointer->setVisible(true);
919 urlToolBarPointer->setVisible(true);
921 // Only show the bookmarks toolbar if it was previously visible.
922 if (bookmarksToolBarIsVisible)
923 bookmarksToolBarPointer->setVisible(true);
926 tabWidgetPointer->setTabBarVisible(true);
928 // Show the status bar.
929 statusBar()->setVisible(true);
933 void BrowserWindow::getZoomFactorFromUser()
935 // Create an OK flag.
938 // 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.
939 double newZoomFactor = QInputDialog::getDouble(this, i18nc("The on-the-fly zoom factor dialog title", "On-The-Fly Zoom Factor"),
940 i18nc("The instruction text of the on-the-fly zoom factor dialog", "Enter a zoom factor between 0.25 and 5.00"),
941 currentZoomFactor, .025, 5.00, 2, &okClicked, Qt::WindowFlags(), 0.25);
943 // Update the zoom factor if the user clicked OK.
946 // Set the new zoom factor.
947 tabWidgetPointer->applyOnTheFlyZoomFactor(newZoomFactor);
949 // Update the on-the-fly action text.
950 updateZoomActions(newZoomFactor);
954 void BrowserWindow::hideFindTextActions() const
956 // Hide the find text actions.
957 findTextLineEditActionPointer->setVisible(false);
958 findTextLabelActionPointer->setVisible(false);
959 findNextActionPointer->setVisible(false);
960 findPreviousActionPointer->setVisible(false);
961 findCaseSensitiveActionPointer->setVisible(false);
962 hideFindTextActionPointer->setVisible(false);
965 void BrowserWindow::home() const
967 // Remove the focus from the URL line edit.
968 urlLineEditPointer->clearFocus();
971 tabWidgetPointer->home();
974 void BrowserWindow::incrementZoom()
976 // Update the current zoom factor.
977 currentZoomFactor = currentZoomFactor + 0.25;
979 // Check to make sure the zoom factor is in the valid range (0.25 to 5.00).
980 if (currentZoomFactor > 5.0)
981 currentZoomFactor = 5.0;
983 // Set the new zoom factor.
984 tabWidgetPointer->applyOnTheFlyZoomFactor(currentZoomFactor);
986 // Update the on-the-fly action text.
987 updateZoomActions(currentZoomFactor);
990 void BrowserWindow::loadUrlFromLineEdit(const QString &url) const
992 // Remove the focus from the URL line edit.
993 urlLineEditPointer->clearFocus();
996 tabWidgetPointer->loadUrlFromLineEdit(url);
999 void BrowserWindow::newWindow() const
1001 // Create a new browser window.
1002 BrowserWindow *browserWindowPointer = new BrowserWindow();
1004 // Show the new browser window.
1005 browserWindowPointer->show();
1008 void BrowserWindow::populateBookmarksInAllWindows() const
1010 // Get a list of all the registered service names.
1011 QStringList registeredServiceNames = QDBusConnection::sessionBus().interface()->registeredServiceNames().value();
1013 // Get a list of all the Privacy Browser windows, which will be `com.stoutner.privacybrowser-` with the PID appended.
1014 QStringList privacyBrowserServiceNames = registeredServiceNames.filter("com.stoutner.privacybrowser");
1016 // Repopulate the bookmarks in each window.
1017 for (QString privacyBrowserServiceName : privacyBrowserServiceNames)
1019 // Prepare the D-Bus message.
1020 QDBusMessage dBusMessage = QDBusMessage::createMethodCall(privacyBrowserServiceName, "/privacybrowser/MainWindow_1", "com.stoutner.privacybrowser.BrowserWindow", "populateBookmarksInThisWindow");
1023 QDBusConnection::sessionBus().send(dBusMessage);
1027 void BrowserWindow::populateBookmarksInThisWindow()
1029 qDebug() << "Populating bookmarks.";
1031 // Remove all the final bookmark folder menu actions.
1032 for (QPair<QMenu *, QAction *> *finalBookmarkFolderMenuActionPair : finalBookmarkFolderMenuActionList)
1034 // Remove the action.
1035 finalBookmarkFolderMenuActionPair->first->removeAction(finalBookmarkFolderMenuActionPair->second);
1038 // Remove all the current menu bookmarks.
1039 for (QPair<QMenu *, QAction *> *bookmarkMenuActionPairPointer : bookmarksMenuActionList)
1041 // Remove the bookmark.
1042 bookmarkMenuActionPairPointer->first->removeAction(bookmarkMenuActionPairPointer->second);
1045 // Remove all the current menu subfolders.
1046 for (QPair<QMenu *, QMenu *> *submenuPairPointer : bookmarksMenuSubmenuList)
1048 // Remove the submenu from the parent menu.
1049 submenuPairPointer->first->removeAction(submenuPairPointer->second->menuAction());
1052 // Remove all the current toolbar subfolders.
1053 for (QPair<QMenu *, QAction *> *subfolderActionPairPointer : bookmarksToolBarSubfolderActionList)
1055 // Remove the action from the subfolder.
1056 subfolderActionPairPointer->first->removeAction(subfolderActionPairPointer->second);
1059 // Remove all the current toolbar bookmarks.
1060 for (QAction *bookmarkAction : bookmarksToolBarActionList)
1062 // Remove the bookmark.
1063 bookmarksToolBarPointer->removeAction(bookmarkAction);
1066 // Clear the current bookmark lists.
1067 bookmarksMenuActionList.clear();
1068 bookmarksMenuSubmenuList.clear();
1069 bookmarksToolBarActionList.clear();
1070 bookmarksToolBarSubfolderActionList.clear();
1072 // Populate the bookmarks subfolders, beginning with the root folder (`0`);
1073 populateBookmarksMenuSubfolders(0, bookmarksMenuPointer);
1075 // Populate the bookmarks toolbar.
1076 populateBookmarksToolBar();
1078 // Get a handle for the bookmark toolbar layout.
1079 QLayout *bookmarksToolBarLayoutPointer = bookmarksToolBarPointer->layout();
1081 // Get the count of the bookmarks.
1082 int bookmarkCount = bookmarksToolBarLayoutPointer->count();
1084 // Set the layout of each bookmark to be left aligned.
1085 for(int i = 0; i < bookmarkCount; ++i)
1086 bookmarksToolBarLayoutPointer->itemAt(i)->setAlignment(Qt::AlignLeft);
1088 // Update the bookmarked action.
1089 updateBookmarkedAction();
1092 void BrowserWindow::populateBookmarksMenuSubfolders(const double folderId, QMenu *menuPointer)
1094 // Get the folder contents.
1095 QList<BookmarkStruct> *folderContentsListPointer = BookmarksDatabase::getFolderContents(folderId);
1097 // Populate the bookmarks menu and toolbar.
1098 for (BookmarkStruct bookmarkStruct : *folderContentsListPointer)
1100 // Process the item according to the type.
1101 if (bookmarkStruct.isFolder) // This item is a folder.
1103 // Add a submenu to the menu.
1104 QMenu *submenuPointer = menuPointer->addMenu(bookmarkStruct.favoriteIcon, bookmarkStruct.name);
1106 // Add the submenu to the beginning of the list of menus to be deleted on repopulate.
1107 bookmarksMenuSubmenuList.prepend(new QPair<QMenu *, QMenu *>(menuPointer, submenuPointer));
1109 // Populate any subfolders.
1110 populateBookmarksMenuSubfolders(bookmarkStruct.folderId, submenuPointer);
1112 else // This item is a bookmark.
1114 // Add the bookmark to the menu.
1115 QAction *menuBookmarkActionPointer = menuPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name, [=]
1117 // Remove the focus from the URL line edit.
1118 urlLineEditPointer->clearFocus();
1121 tabWidgetPointer->loadUrlFromLineEdit(bookmarkStruct.url);
1125 // Add the actions to the beginning of the list of bookmarks to be deleted on repopulate.
1126 bookmarksMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, menuBookmarkActionPointer));
1130 // Add the extra items at the bottom of the menu.
1131 addFinalBookmarkFolderMenuActions(menuPointer, folderId);
1134 void BrowserWindow::populateBookmarksToolBar()
1136 // Get the root folder contents (which has a folder ID of `0`).
1137 QList<BookmarkStruct> *folderContentsListPointer = BookmarksDatabase::getFolderContents(0);
1139 // Populate the bookmarks toolbar.
1140 for (BookmarkStruct bookmarkStruct : *folderContentsListPointer)
1142 // Process the item according to the type.
1143 if (bookmarkStruct.isFolder) // This item is a folder.
1145 // Add the subfolder action.
1146 QAction *toolBarSubfolderActionPointer = bookmarksToolBarPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name);
1148 // Add the bookmark database ID to the toolbar action.
1149 toolBarSubfolderActionPointer->setData(bookmarkStruct.databaseId);
1151 // Add the action to the beginning of the list of actions to be deleted on repopulate.
1152 bookmarksToolBarActionList.prepend(toolBarSubfolderActionPointer);
1154 // Create a subfolder menu.
1155 QMenu *subfolderMenuPointer = new QMenu();
1157 // Add the menu to the action.
1158 toolBarSubfolderActionPointer->setMenu(subfolderMenuPointer);
1160 // Add the submenu to the toolbar menu list.
1161 bookmarksToolBarMenuList.append(new QPair<QMenu *, const double>(subfolderMenuPointer, bookmarkStruct.folderId));
1163 // Set the popup mode for the menu.
1164 dynamic_cast<QToolButton *>(bookmarksToolBarPointer->widgetForAction(toolBarSubfolderActionPointer))->setPopupMode(QToolButton::InstantPopup);
1166 // Populate the subfolder.
1167 populateBookmarksToolBarSubfolders(bookmarkStruct.folderId, subfolderMenuPointer);
1169 else // This item is a bookmark.
1171 // Add the bookmark to the toolbar.
1172 QAction *toolBarBookmarkActionPointer = bookmarksToolBarPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name, [=]
1174 // Remove the focus from the URL line edit.
1175 urlLineEditPointer->clearFocus();
1178 tabWidgetPointer->loadUrlFromLineEdit(bookmarkStruct.url);
1182 // Add the bookmark database ID to the toolbar action.
1183 toolBarBookmarkActionPointer->setData(bookmarkStruct.databaseId);
1185 // Add the actions to the beginning of the current bookmarks lists.
1186 bookmarksToolBarActionList.prepend(toolBarBookmarkActionPointer);
1190 // 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.
1191 for (QPair<QMenu *, const double> *menuAndFolderIdPairPointer : bookmarksToolBarMenuList)
1193 // Populate the final bookmarks menu entries.
1194 addFinalBookmarkFolderMenuActions(menuAndFolderIdPairPointer->first, menuAndFolderIdPairPointer->second);
1198 void BrowserWindow::populateBookmarksToolBarSubfolders(const double folderId, QMenu *menuPointer)
1200 // Get the folder contents.
1201 QList<BookmarkStruct> *folderContentsListPointer = BookmarksDatabase::getFolderContents(folderId);
1203 // Populate the bookmarks folder.
1204 for (BookmarkStruct bookmarkStruct : *folderContentsListPointer)
1206 // Get the bookmark URL.
1207 QString bookmarkUrl = bookmarkStruct.url;
1209 // Process the item according to the type.
1210 if (bookmarkStruct.isFolder) // This item is a folder.
1212 // Add the subfolder action.
1213 QAction *toolBarSubfolderActionPointer = menuPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name);
1215 // Add the action to the beginning of the list of actions to be deleted on repopulate.
1216 bookmarksToolBarSubfolderActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, toolBarSubfolderActionPointer));
1218 // Create a subfolder menu.
1219 QMenu *subfolderMenuPointer = new QMenu();
1221 // Add the submenu to the action.
1222 toolBarSubfolderActionPointer->setMenu(subfolderMenuPointer);
1224 // Add the submenu to the toolbar menu list.
1225 bookmarksToolBarMenuList.append(new QPair<QMenu *, const double>(subfolderMenuPointer, bookmarkStruct.folderId));
1227 // Populate the subfolder menu.
1228 populateBookmarksToolBarSubfolders(bookmarkStruct.folderId, subfolderMenuPointer);
1230 else // This item is a bookmark.
1232 // Add the bookmark to the folder.
1233 QAction *toolBarBookmarkActionPointer = menuPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name, [=]
1235 // Remove the focus from the URL line edit.
1236 urlLineEditPointer->clearFocus();
1239 tabWidgetPointer->loadUrlFromLineEdit(bookmarkUrl);
1243 // Add the bookmark database ID to the toolbar action.
1244 toolBarBookmarkActionPointer->setData(bookmarkStruct.databaseId);
1246 // Add the action to the beginning of the list of actions to be deleted on repopulate.
1247 bookmarksToolBarSubfolderActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, toolBarBookmarkActionPointer));
1252 void BrowserWindow::refresh() const
1254 // Remove the focus from the URL line edit.
1255 urlLineEditPointer->clearFocus();
1257 // Refresh the web page.
1258 tabWidgetPointer->refresh();
1261 void BrowserWindow::reloadAndBypassCache() const
1263 // Remove the focus from the URL line edit.
1264 urlLineEditPointer->clearFocus();
1266 // Refresh the web page.
1267 tabWidgetPointer->refresh();
1270 void BrowserWindow::showBookmarkContextMenu(const QPoint &point)
1272 // Get the bookmark action.
1273 QAction *bookmarkActionPointer = bookmarksToolBarPointer->actionAt(point);
1275 // Check to see if an action was clicked.
1276 if (bookmarkActionPointer) // An action was clicked.
1278 // Create a bookmark context menu.
1279 QMenu *bookmarkContextMenuPointer = new QMenu();
1281 // Get the database ID from the action.
1282 int databaseId = bookmarkActionPointer->data().toInt();
1284 // Create the menu according to the type.
1285 if (BookmarksDatabase::isFolder(databaseId)) // A folder was clicked.
1287 // Populate the final bookmarks menu entries.
1288 addFinalBookmarkFolderMenuActions(bookmarkContextMenuPointer, BookmarksDatabase::getFolderId(databaseId));
1290 else // A bookmark was clicked.
1292 // Add the open in new tab action to the menu.
1293 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("Open bookmark in new tab context menu entry", "Open in New Tab"), [=]
1295 // Get the bookmark.
1296 BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
1298 // Open the bookmark in a new tab. `true` removes the URL line edit focus, `false` does not load a background tab.
1299 tabWidgetPointer->addTab(true, false, bookmarkStructPointer->url);
1303 // Add the open in background tab action to the menu.
1304 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("Open bookmark in background tab context menu entry", "Open in Background Tab"), [=]
1306 // Get the bookmark.
1307 BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
1309 // Open the bookmark in a new tab. `true` removes the URL line edit focus, `true` loads a background tab.
1310 tabWidgetPointer->addTab(true, true, bookmarkStructPointer->url);
1314 // Add the open in new window action to the menu.
1315 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("window-new")), i18nc("Open bookmark in new window context menu entry", "Open in New Window"), [=]
1317 // Get the bookmark.
1318 BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
1320 // Create a new browser window and load the first URL. `false` indicates it is not the first browser window.
1321 BrowserWindow *browserWindowPointer = new BrowserWindow(false, &bookmarkStructPointer->url);
1323 // Show the new browser window.
1324 browserWindowPointer->show();
1329 bookmarkContextMenuPointer->addSeparator();
1331 // Add the edit action to the menu.
1332 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("document-edit")), i18nc("Edit bookmark context menu entry", "Edit"), [=]
1334 // Get the current tab favorite icon.
1335 QIcon currentTabFavoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
1337 // Instantiate an edit bookmark dialog.
1338 QDialog *editBookmarkDialogPointer = new EditBookmarkDialog(databaseId, currentTabFavoriteIcon);
1341 editBookmarkDialogPointer->show();
1343 // Process bookmark events.
1344 connect(editBookmarkDialogPointer, SIGNAL(bookmarkSaved()), this, SLOT(populateBookmarksInAllWindows()));
1348 // Add the copy URL action to the menu.
1349 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-copy")), i18nc("Copy bookmark URL context menu entry", "Copy URL"), [=]
1351 // Get the bookmark.
1352 BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
1354 // Get a handle for the clipboard.
1355 QClipboard *clipboard = QGuiApplication::clipboard();
1357 // Place the URL on the keyboard.
1358 clipboard->setText(bookmarkStructPointer->url);
1363 bookmarkContextMenuPointer->addSeparator();
1365 // Add the delete action to the menu.
1366 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-delete")), i18nc("Delete bookmark context menu entry", "Delete"), [=]
1368 // Get the parent folder ID.
1369 double parentFolderId = BookmarksDatabase::getParentFolderId(databaseId);
1371 // Delete the bookmark.
1372 BookmarksDatabase::deleteBookmark(databaseId);
1374 // Update the display order of the bookmarks in the parent folder.
1375 BookmarksDatabase::updateFolderContentsDisplayOrder(parentFolderId);
1377 // Repopulate the bookmarks.
1378 populateBookmarksInAllWindows();
1383 // Delete the menu from memory when it is closed.
1384 bookmarkContextMenuPointer->setAttribute(Qt::WA_DeleteOnClose);
1386 // Display the context menu.
1387 bookmarkContextMenuPointer->popup(bookmarksToolBarPointer->mapToGlobal(point));
1389 else // The toolbar background was clicked.
1391 // Temporarily set the context menu policy to the default.
1392 bookmarksToolBarPointer->setContextMenuPolicy(Qt::DefaultContextMenu);
1394 // Create a context menu event with the same position.
1395 QContextMenuEvent *contextMenuEventPointer = new QContextMenuEvent(QContextMenuEvent::Mouse, point);
1397 // Send the context menu event to the toolbar.
1398 QCoreApplication::sendEvent(bookmarksToolBarPointer, contextMenuEventPointer);
1400 // Reset the context menu policy.
1401 bookmarksToolBarPointer->setContextMenuPolicy(Qt::CustomContextMenu);
1405 void BrowserWindow::showCookiesDialog()
1407 // Remove the focus from the URL line edit.
1408 urlLineEditPointer->clearFocus();
1410 // Instantiate the cookie settings dialog.
1411 CookiesDialog *cookiesDialogPointer = new CookiesDialog(tabWidgetPointer->getCookieList());
1414 cookiesDialogPointer->show();
1416 // Connect the dialog signals.
1417 connect(cookiesDialogPointer, SIGNAL(addCookie(QNetworkCookie)), tabWidgetPointer, SLOT(addCookieToStore(QNetworkCookie)));
1418 connect(cookiesDialogPointer, SIGNAL(deleteAllCookies()), tabWidgetPointer, SLOT(deleteAllCookies()));
1419 connect(cookiesDialogPointer, SIGNAL(deleteCookie(QNetworkCookie)), tabWidgetPointer, SLOT(deleteCookieFromStore(QNetworkCookie)));
1422 void BrowserWindow::showDownloadLocationBrowseDialog() const
1424 // Get the current download location.
1425 QString currentDownloadLocation = downloadLocationComboBoxPointer->currentText();
1427 // Resolve the system download directory if specified.
1428 if (currentDownloadLocation == QStringLiteral("System Download Directory"))
1429 currentDownloadLocation = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
1431 // Get the new download location.
1432 QString newDownloadLocation = QFileDialog::getExistingDirectory(configDialogPointer, i18nc("Select download location dialog caption", "Select Download Location"), currentDownloadLocation);
1434 // Populate the download location combo box according to the new download location.
1435 if (newDownloadLocation == QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)) // The default download location was selected.
1437 // Populate the download location with the default text.
1438 downloadLocationComboBoxPointer->setCurrentText("System Download Directory");
1440 else if (newDownloadLocation != QStringLiteral("")) // A different directory was selected.
1442 // Populate the download location.
1443 downloadLocationComboBoxPointer->setCurrentText(newDownloadLocation);
1447 void BrowserWindow::showDomainSettingsDialog() const
1449 // Remove the focus from the URL line edit.
1450 urlLineEditPointer->clearFocus();
1452 // Instantiate the domain settings dialog.
1453 DomainSettingsDialog *domainSettingsDialogPointer = new DomainSettingsDialog();
1455 // Reload the tabs when domain settings are updated.
1456 connect(domainSettingsDialogPointer, SIGNAL(domainSettingsUpdated()), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
1459 domainSettingsDialogPointer->show();
1462 void BrowserWindow::showFindTextActions() const
1464 // Show the find text actions.
1465 findTextLineEditActionPointer->setVisible(true);
1466 findTextLabelActionPointer->setVisible(true);
1467 findNextActionPointer->setVisible(true);
1468 findPreviousActionPointer->setVisible(true);
1469 findCaseSensitiveActionPointer->setVisible(true);
1470 hideFindTextActionPointer->setVisible(true);
1472 // Set the focus on the find line edit.
1473 findTextLineEditPointer->setFocus();
1475 // Select all the text in the find line edit.
1476 findTextLineEditPointer->selectAll();
1479 void BrowserWindow::showProgressBar(const int &progress) const
1481 // Set the progress bar value.
1482 progressBarPointer->setValue(progress);
1484 // Show the progress bar.
1485 progressBarPointer->show();
1488 void BrowserWindow::showSettingsDialog()
1490 // Create the settings widgets.
1491 QWidget *privacySettingsWidgetPointer = new QWidget;
1492 QWidget *generalSettingsWidgetPointer = new QWidget;
1493 QWidget *spellCheckSettingsWidgetPointer = new QWidget;
1495 // Instantiate the settings UI.
1496 Ui::PrivacySettings privacySettingsUi;
1497 Ui::GeneralSettings generalSettingsUi;
1498 Ui::SpellCheckSettings spellCheckSettingsUi;
1500 // Setup the UI to display the settings widgets.
1501 privacySettingsUi.setupUi(privacySettingsWidgetPointer);
1502 generalSettingsUi.setupUi(generalSettingsWidgetPointer);
1503 spellCheckSettingsUi.setupUi(spellCheckSettingsWidgetPointer);
1505 // Get handles for the widgets.
1506 QComboBox *userAgentComboBoxPointer = privacySettingsUi.kcfg_userAgent;
1507 userAgentLabelPointer = privacySettingsUi.userAgentLabel;
1508 QComboBox *searchEngineComboBoxPointer = generalSettingsUi.kcfg_searchEngine;
1509 searchEngineLabelPointer = generalSettingsUi.searchEngineLabel;
1510 downloadLocationComboBoxPointer = generalSettingsUi.kcfg_downloadLocation;
1511 QPushButton *browseButtonPointer = generalSettingsUi.browseButton;
1512 QListWidget *spellCheckListWidgetPointer = spellCheckSettingsUi.spellCheckListWidget;
1514 // Populate the combo box labels.
1515 updateUserAgentLabel(userAgentComboBoxPointer->currentText());
1516 updateSearchEngineLabel(searchEngineComboBoxPointer->currentText());
1518 // Update the labels when the combo boxes change.
1519 connect(userAgentComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateUserAgentLabel(const QString)));
1520 connect(searchEngineComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateSearchEngineLabel(const QString)));
1522 // Connect the download location directory browse button.
1523 connect(browseButtonPointer, SIGNAL(clicked()), this, SLOT(showDownloadLocationBrowseDialog()));
1525 // Create a dictionaries QDir from the `QTWEBENGINE_DICTIONARIES_PATH` environment variable.
1526 QDir dictionariesDir = QDir(qEnvironmentVariable("QTWEBENGINE_DICTIONARIES_PATH"));
1528 // Get a dictionaries string list.
1529 QStringList dictionariesStringList = dictionariesDir.entryList(QStringList(QLatin1String("*.bdic")), QDir::Files | QDir::NoSymLinks);
1531 // Remove the `.bdic` file extensions from the dictionaries list.
1532 dictionariesStringList.replaceInStrings(QLatin1String(".bdic"), QLatin1String(""));
1534 // Get a list of the enabled spell check languages.
1535 QStringList enabledSpellCheckLanguagesList = Settings::spellCheckLanguages();
1537 // Add each dictionary to the spell check list widget.
1538 foreach(QString dictionaryString, dictionariesStringList)
1540 // Create a new list widget item pointer.
1541 QListWidgetItem *listWidgetItemPointer = new QListWidgetItem();
1543 // Create a dictionary check box widget with the name of the dictionary string.
1544 QCheckBox *dictionaryCheckBoxWidget = new QCheckBox(dictionaryString);
1546 // Check the language if it is currently enabled.
1547 if (enabledSpellCheckLanguagesList.contains(dictionaryString))
1548 dictionaryCheckBoxWidget->setCheckState(Qt::Checked);
1550 dictionaryCheckBoxWidget->setCheckState(Qt::Unchecked);
1552 // Add the list widget item to the spell check list widget.
1553 spellCheckListWidgetPointer->addItem(listWidgetItemPointer);
1555 // Set the list widget item check box widget.
1556 spellCheckListWidgetPointer->setItemWidget(listWidgetItemPointer, dictionaryCheckBoxWidget);
1559 // Get a handle for the KConfig skeleton.
1560 KConfigSkeleton *kConfigSkeletonPointer = Settings::self();
1562 // Instantiate a settings config dialog from the settings.kcfg file.
1563 configDialogPointer = new KConfigDialog(this, QLatin1String("settings"), kConfigSkeletonPointer);
1565 // Create a settings icon string.
1566 QString settingsIconString;
1568 // Get a settings icon that matches the theme.
1569 if (QIcon::hasThemeIcon("breeze-settings"))
1571 // KDE uses breeze-settings.
1572 settingsIconString = QLatin1String("breeze-settings");
1576 // Gnome uses preferences-desktop.
1577 settingsIconString = QLatin1String("preferences-desktop");
1580 // Add the settings widgets as config dialog pages.
1581 configDialogPointer->addPage(privacySettingsWidgetPointer, i18nc("Settings tab title", "Privacy"), QLatin1String("privacybrowser"));
1582 configDialogPointer->addPage(generalSettingsWidgetPointer, i18nc("Settings tab title", "General"), settingsIconString);
1583 configDialogPointer->addPage(spellCheckSettingsWidgetPointer, i18nc("Settings tab title", "Spell Check"), QLatin1String("tools-check-spelling"));
1585 // Get handles for the buttons.
1586 QPushButton *applyButtonPointer = configDialogPointer->button(QDialogButtonBox::Apply);
1587 QPushButton *okButtonPointer = configDialogPointer->button(QDialogButtonBox::Ok);
1589 // Prevent interaction with the parent window while the dialog is open.
1590 configDialogPointer->setWindowModality(Qt::WindowModal);
1593 configDialogPointer->show();
1595 // TODO. KConfigDialog does not respect expanding size policies. <https://redmine.stoutner.com/issues/823>
1596 //configDialogPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1597 //privacySettingsWidgetPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1598 //generalSettingsWidgetPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1599 //configDialogPointer->adjustSize();
1601 // Expand the config dialog.
1602 configDialogPointer->resize(1000, 500);
1604 // Create a save spell check languages lambda.
1605 auto saveSpellCheckLanguages = [spellCheckListWidgetPointer, kConfigSkeletonPointer, this] ()
1607 // Create a list of enabled languages.
1608 QStringList newSpellCheckLanguages = QStringList();
1610 // Get a count of all the languages.
1611 int allLanguagesCount = spellCheckListWidgetPointer->count();
1613 // Get a list of all the checked languages.
1614 for (int i = 0; i < allLanguagesCount; ++i) {
1615 // Get the language item.
1616 QListWidgetItem *languageItemPointer = spellCheckListWidgetPointer->item(i);
1618 // Get the language check box.
1619 QCheckBox *languageCheckBoxPointer = qobject_cast<QCheckBox*>(spellCheckListWidgetPointer->itemWidget(languageItemPointer));
1621 // Add the item to the enabled languages if it is checked.
1622 if (languageCheckBoxPointer->checkState() == Qt::Checked)
1625 QString languageString = languageCheckBoxPointer->text();
1627 // Remove all instances of `&`, which may have been added automatically when creating the check box text.
1628 languageString.remove(QChar('&'));
1630 // Add the language string to the list.
1631 newSpellCheckLanguages.append(languageString);
1635 // Update the spell check languages.
1636 if (Settings::spellCheckLanguages() != newSpellCheckLanguages)
1638 // Update the spell check languages.
1639 Settings::setSpellCheckLanguages(newSpellCheckLanguages);
1641 // Write the settings to disk.
1642 kConfigSkeletonPointer->save();
1645 // Apply the spell check languages.
1646 tabWidgetPointer->applySpellCheckLanguages();
1650 connect(applyButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages);
1651 connect(okButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages);
1653 // Apply the settings handled by KConfig.
1654 connect(configDialogPointer, SIGNAL(settingsChanged(QString)), tabWidgetPointer, SLOT(applyApplicationSettings()));
1655 connect(configDialogPointer, SIGNAL(settingsChanged(QString)), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
1658 QSize BrowserWindow::sizeHint() const
1660 // Return the default window size.
1661 return QSize(1500, 1200);
1664 void BrowserWindow::toggleBookmark()
1666 // Remove the focus from the URL line edit, which will have been focused when the user clicked on the bookmarked icon.
1667 urlLineEditPointer->clearFocus();
1669 // Create or delete the bookmark
1670 if (bookmarkedActionPointer->isChecked()) // The user checked the toggle. Create a bookmark.
1672 // Create a bookmark struct.
1673 BookmarkStruct *bookmarkStructPointer = new BookmarkStruct;
1675 // Populate the bookmark struct.
1676 bookmarkStructPointer->name = tabWidgetPointer->getCurrentTabTitle();
1677 bookmarkStructPointer->url = tabWidgetPointer->getCurrentTabUrl();
1678 bookmarkStructPointer->parentFolderId = 0;
1679 bookmarkStructPointer->favoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
1681 // Add the bookmark.
1682 BookmarksDatabase::addBookmark(bookmarkStructPointer);
1684 else // The user unchecked the toggle. Delete all related bookmarks.
1686 // Delete the bookmarks.
1687 BookmarksDatabase::deleteBookmarks(urlLineEditPointer->text());
1692 // Repopulate the bookmarks.
1693 populateBookmarksInAllWindows();
1696 void BrowserWindow::toggleDomStorage() const
1698 // Remove the focus from the URL line edit.
1699 urlLineEditPointer->clearFocus();
1701 // Toggle DOM storage.
1702 tabWidgetPointer->toggleDomStorage();
1705 void BrowserWindow::toggleFindCaseSensitive() const
1707 // Get the current find string.
1708 const QString findString = findTextLineEditPointer->text();
1710 // Toggle find case sensitive.
1711 tabWidgetPointer->toggleFindCaseSensitive(findString);
1714 void BrowserWindow::toggleJavaScript() const
1716 // Remove the focus from the URL line edit.
1717 urlLineEditPointer->clearFocus();
1719 // Toggle JavaScript.
1720 tabWidgetPointer->toggleJavaScript();
1723 void BrowserWindow::toggleLocalStorage() const
1725 // Remove the focus from the URL line edit.
1726 urlLineEditPointer->clearFocus();
1728 // Toggle local storage.
1729 tabWidgetPointer->toggleLocalStorage();
1732 void BrowserWindow::toggleFullScreen()
1734 // Toggle the full screen status.
1735 fullScreenRequested(fullScreenActionPointer->isChecked());
1738 void BrowserWindow::toggleViewSource() const
1740 // Get the current URL.
1741 QString url = urlLineEditPointer->text();
1744 if (url.startsWith(QLatin1String("view-source:"))) // The source is currently being viewed.
1746 // Remove `view-source:` from the URL.
1747 url = url.remove(0, 12);
1749 else // The source is not currently being viewed.
1751 // Prepend `view-source:` from the URL.
1752 url = url.prepend(QLatin1String("view-source:"));
1756 loadUrlFromLineEdit(url);
1759 void BrowserWindow::toggleViewBookmarksToolBar()
1761 // Store the current status of the bookmarks toolbar, which is used when exiting full screen browsing.
1762 bookmarksToolBarIsVisible = viewBookmarksToolBarActionPointer->isChecked();
1764 // Update the visibility of the bookmarks toolbar.
1765 bookmarksToolBarPointer->setVisible(bookmarksToolBarIsVisible);
1768 void BrowserWindow::toggleViewSourceInNewTab() const
1770 // Get the current URL.
1771 QString url = urlLineEditPointer->text();
1774 if (url.startsWith(QLatin1String("view-source:"))) // The source is currently being viewed.
1776 // Remove `view-source:` from the URL.
1777 url = url.remove(0, 12);
1779 else // The source is not currently being viewed.
1781 // Prepend `view-source:` from the URL.
1782 url = url.prepend(QLatin1String("view-source:"));
1785 // Add the new tab. `true` removes the URL line edit focus, `false` does not open a background tab.
1786 tabWidgetPointer->addTab(true, false, url);
1789 void BrowserWindow::updateBookmarkedAction() const
1791 // Update the bookmarked action to reflect the current state.
1792 if (bookmarkedActionPointer->isChecked())
1793 bookmarkedActionPointer->setIcon(QIcon::fromTheme("starred-symbolic"));
1795 bookmarkedActionPointer->setIcon(QIcon::fromTheme("non-starred-symbolic"));
1798 void BrowserWindow::updateCookiesAction(const int numberOfCookies) const
1800 // Update the action text.
1801 cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", numberOfCookies));
1804 void BrowserWindow::updateDefaultZoomFactor(const double newDefaultZoomFactor)
1806 // Store the new default zoom factor.
1807 defaultZoomFactor = newDefaultZoomFactor;
1810 void BrowserWindow::updateDomStorageAction(const bool &isEnabled) const
1812 // Set the action checked status.
1813 domStorageActionPointer->setChecked(isEnabled);
1816 void BrowserWindow::updateDomainSettingsIndicator(const bool status)
1818 // Set the domain palette according to the status.
1820 urlLineEditPointer->setPalette(positiveBackgroundPalette);
1822 urlLineEditPointer->setPalette(normalBackgroundPalette);
1825 void BrowserWindow::updateFindText(const QString &text, const bool findCaseSensitive) const
1828 findTextLineEditPointer->setText(text);
1830 // Set the find case sensitive action checked status.
1831 findCaseSensitiveActionPointer->setChecked(findCaseSensitive);
1834 void BrowserWindow::updateFindTextResults(const QWebEngineFindTextResult &findTextResult) const
1836 // Update the find text label.
1837 findTextLabelPointer->setText(QStringLiteral(" %1/%2 ").arg(findTextResult.activeMatch()).arg(findTextResult.numberOfMatches()));
1839 // Set the background color according to the find status.
1840 if (findTextLineEditPointer->text().isEmpty())
1841 findTextLineEditPointer->setPalette(normalBackgroundPalette);
1842 else if (findTextResult.numberOfMatches() == 0)
1843 findTextLineEditPointer->setPalette(negativeBackgroundPalette);
1845 findTextLineEditPointer->setPalette(positiveBackgroundPalette);
1848 void BrowserWindow::updateJavaScriptAction(const bool &isEnabled)
1850 // Update the JavaScript status.
1851 javaScriptEnabled = isEnabled;
1853 // Set the icon according to the status.
1854 if (javaScriptEnabled)
1855 javaScriptActionPointer->setIcon(QIcon(QLatin1String(":/icons/javascript-warning.svg")));
1857 javaScriptActionPointer->setIcon(QIcon(QLatin1String(":/icons/privacy-mode.svg")));
1859 // Set the action checked status.
1860 javaScriptActionPointer->setChecked(javaScriptEnabled);
1862 // Update the status of the DOM storage action.
1863 domStorageActionPointer->setEnabled(javaScriptEnabled & localStorageEnabled);
1866 void BrowserWindow::updateLocalStorageAction(const bool &isEnabled)
1868 // Update the local storage status.
1869 localStorageEnabled = isEnabled;
1871 // 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.
1872 if (localStorageEnabled)
1873 localStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("disk-quota-high"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/actions/document-save-as.png"))));
1875 localStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("disk-quota"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/apps/kfm.png"))));
1877 // Set the action checked status.
1878 localStorageActionPointer->setChecked(localStorageEnabled);
1880 // Update the status of the DOM storage action.
1881 domStorageActionPointer->setEnabled(localStorageEnabled & javaScriptEnabled);
1884 void BrowserWindow::updateSearchEngineActions(const QString &searchEngine, const bool &updateCustomSearchEngineStatus)
1886 // Initialize the custom search engine flag.
1887 bool customSearchEngine = false;
1889 if (searchEngine == "Mojeek") // Mojeek.
1891 // Check the Mojeek user agent action.
1892 searchEngineMojeekActionPointer->setChecked(true);
1894 // Update the search engine menu action icon.
1895 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1897 // Update the search engine menu action text.
1898 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Mojeek"));
1900 else if (searchEngine == "Monocles") // Monocles.
1902 // Check the Monocles user agent action.
1903 searchEngineMonoclesActionPointer->setChecked(true);
1905 // Update the search engine menu action icon.
1906 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1908 // Update the search engine menu action text.
1909 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Monocles"));
1911 else if (searchEngine == "MetaGer") // MetaGer.
1913 // Check the MetaGer user agent action.
1914 searchEngineMetagerActionPointer->setChecked(true);
1916 // Update the search engine menu action icon.
1917 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1919 // Update the search engine menu action text.
1920 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - MetaGer"));
1922 else if (searchEngine == "Google") // Google.
1924 // Check the Google user agent action.
1925 searchEngineGoogleActionPointer->setChecked(true);
1927 // Update the search engine menu action icon.
1928 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-google"), QIcon::fromTheme(QLatin1String("edit-find"))));
1930 // Update the search engine menu action text.
1931 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Google"));
1933 else if (searchEngine == "Bing") // Bing.
1935 // Check the Bing user agent action.
1936 searchEngineBingActionPointer->setChecked(true);
1938 // Update the search engine menu action icon.
1939 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1941 // Update the search engine menu action text.
1942 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Bing"));
1944 else if (searchEngine == "Yahoo") // Yahoo.
1946 // Check the Yahoo user agent action.
1947 searchEngineYahooActionPointer->setChecked(true);
1949 // Update the search engine menu action icon.
1950 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-yahoo"), QIcon::fromTheme(QLatin1String("edit-find"))));
1952 // Update the search engine menu action text.
1953 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Yahoo"));
1955 else // Custom search engine.
1957 // Check the user agent.
1958 searchEngineCustomActionPointer->setChecked(true);
1960 // Update the search engine menu action icon.
1961 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1963 // Update the search engine menu action text.
1964 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Custom"));
1966 // Set the custom search engine text.
1967 searchEngineCustomActionPointer->setText(searchEngine);
1969 // Set the custom search engine flag.
1970 customSearchEngine = true;
1973 // Update the custom search engine enabled boolean.
1974 if (updateCustomSearchEngineStatus)
1975 customSearchEngineEnabled = customSearchEngine;
1977 // Format the custom search engine.
1978 if (customSearchEngineEnabled)
1980 // Enable the custom search engine.
1981 searchEngineCustomActionPointer->setEnabled(true);
1985 // Disable the custom search engine.
1986 searchEngineCustomActionPointer->setEnabled(false);
1988 // Reset the custom search engine text.
1989 searchEngineCustomActionPointer->setText(i18nc("@action", "Custom"));
1993 void BrowserWindow::updateSearchEngineLabel(const QString &searchEngineString) const
1995 // Update the search engine label.
1996 searchEngineLabelPointer->setText(SearchEngineHelper::getSearchUrl(searchEngineString));
1999 void BrowserWindow::updateUrlLineEdit(const QUrl &newUrl)
2001 // Get the new URL string in encoded form, which displays punycode.
2002 QString newUrlString = newUrl.toEncoded();
2004 // Update the view source actions.
2005 if (newUrlString.startsWith(QLatin1String("view-source:"))) // The source is currently being viewed.
2007 // Mark the view source checkbox.
2008 viewSourceActionPointer->setChecked(true);
2010 // Update the view in new tab action text.
2011 viewSourceInNewTabActionPointer->setText(i18nc("View rendered website in new tab action", "View Rendered Website in New Tab"));
2013 else // The source is not currently being viewed.
2015 // Unmark the view source checkbox.
2016 viewSourceActionPointer->setChecked(false);
2018 // Update the view in new tab action text.
2019 viewSourceInNewTabActionPointer->setText(i18nc("View source in new tab action", "View Source in New Tab"));
2022 // Update the URL line edit if it does not have focus.
2023 if (!urlLineEditPointer->hasFocus())
2025 // Update the URL line edit.
2026 urlLineEditPointer->setText(newUrlString);
2028 // Set the bookmarked action status.
2029 bookmarkedActionPointer->setChecked(BookmarksDatabase::isBookmarked(newUrlString));
2031 // Update the bookmarked action.
2032 updateBookmarkedAction();
2034 // Set the focus if the new URL is blank.
2035 if (newUrlString == QStringLiteral(""))
2036 urlLineEditPointer->setFocus();
2039 // Store the current URL.
2040 currentUrl = newUrl;
2043 void BrowserWindow::updateUserAgentActions(const QString &userAgent, const bool &updateCustomUserAgentStatus)
2045 // Initialize the custom user agent flag.
2046 bool customUserAgent = false;
2048 // Check the indicated on-the-fly user agent.
2049 if (userAgent == UserAgentHelper::PRIVACY_BROWSER_USER_AGENT) // Privacy Browser.
2051 // Check the Privacy Browser user agent action.
2052 userAgentPrivacyBrowserActionPointer->setChecked(true);
2054 // Update the user agent menu action icon.
2055 userAgentMenuActionPointer->setIcon(QIcon(":/icons/privacy-mode.svg"));
2057 // Update the user agent menu action text.
2058 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Privacy Browser"));
2060 else if (userAgent == TabWidget::webEngineDefaultUserAgent) // WebEngine default.
2062 // check the WebEngine default user agent action.
2063 userAgentWebEngineDefaultActionPointer->setChecked(true);
2065 // Update the user agent menu action icon.
2066 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("qtlogo"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2068 // Update the user agent menu action text.
2069 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - WebEngine default"));
2071 else if (userAgent == UserAgentHelper::FIREFOX_LINUX_USER_AGENT) // Firefox on Linux.
2073 // Check the Firefox on Linux user agent action.
2074 userAgentFirefoxLinuxActionPointer->setChecked(true);
2076 // Update the user agent menu action icon.
2077 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2079 // Update the user agent menu action text.
2080 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Firefox on Linux"));
2082 else if (userAgent == UserAgentHelper::CHROMIUM_LINUX_USER_AGENT) // Chromium on Linux.
2084 // Check the Chromium on Linux user agent action.
2085 userAgentChromiumLinuxActionPointer->setChecked(true);
2087 // Update the user agent menu action icon.
2088 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2090 // Update the user agent menu action text.
2091 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Chromium on Linux"));
2093 else if (userAgent == UserAgentHelper::FIREFOX_WINDOWS_USER_AGENT) // Firefox on Windows.
2095 // Check the Firefox on Windows user agent action.
2096 userAgentFirefoxWindowsActionPointer->setChecked(true);
2098 // Update the user agent menu action icon.
2099 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2101 // Update the user agent menu action text.
2102 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Firefox on Windows"));
2104 else if (userAgent == UserAgentHelper::CHROME_WINDOWS_USER_AGENT) // Chrome on Windows.
2106 // Check the Chrome on Windows user agent action.
2107 userAgentChromeWindowsActionPointer->setChecked(true);
2109 // Update the user agent menu action icon.
2110 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2112 // Update the user agent menu action text.
2113 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Chrome on Windows"));
2115 else if (userAgent == UserAgentHelper::EDGE_WINDOWS_USER_AGENT) // Edge on Windows.
2117 // Check the Edge on Windows user agent action.
2118 userAgentEdgeWindowsActionPointer->setChecked(true);
2120 // Update the user agent menu action icon.
2121 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
2123 // Update the user agent menu action text.
2124 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Edge on Windows"));
2126 else if (userAgent == UserAgentHelper::SAFARI_MACOS_USER_AGENT) // Safari on macOS.
2128 // Check the Safari on macOS user agent action.
2129 userAgentSafariMacosActionPointer->setChecked(true);
2131 // Update the user agent menu action icon.
2132 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
2134 // Update the user agent menu action text.
2135 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Safari on macOS"));
2137 else // Custom user agent.
2139 // Check the user agent.
2140 userAgentCustomActionPointer->setChecked(true);
2142 // Update the user agent menu action icon.
2143 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
2145 // Update the user agent menu action text.
2146 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Custom"));
2148 // Set the custom user agent text.
2149 userAgentCustomActionPointer->setText(userAgent);
2151 // Set the custom user agent flag.
2152 customUserAgent = true;
2155 // Update the custom user agent enabled boolean.
2156 // 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.
2157 if (updateCustomUserAgentStatus)
2158 customUserAgentEnabled = customUserAgent;
2161 // Format the custom user agent.
2162 if (customUserAgentEnabled)
2164 // Enable the custom user agent.
2165 userAgentCustomActionPointer->setEnabled(true);
2169 // Disable the custom user agent.
2170 userAgentCustomActionPointer->setEnabled(false);
2172 // Reset the custom user agent text.
2173 userAgentCustomActionPointer->setText(i18nc("@action", "Custom"));
2177 void BrowserWindow::updateUserAgentLabel(const QString &userAgentDatabaseName) const
2179 // Update the user agent label.
2180 userAgentLabelPointer->setText(UserAgentHelper::getUserAgentFromDatabaseName(userAgentDatabaseName));
2183 void BrowserWindow::updateViewBookmarksToolBarCheckbox(const bool visible)
2185 // Update the view bookmarks toolbar checkbox.
2186 viewBookmarksToolBarActionPointer->setChecked(visible);
2188 // Initialize the bookmarks toolbar visibility tracker if Privacy Browser has just launched.
2189 if (bookmarksToolBarUninitialized)
2191 // Set the initialization flag.
2192 bookmarksToolBarUninitialized = false;
2194 // Store the current status of the bookmarks toolbar, which is used when exiting full screen browsing.
2195 bookmarksToolBarIsVisible = visible;
2199 void BrowserWindow::updateWindowTitle(const QString &title)
2201 // Update the window title.
2202 setWindowTitle(title);
2205 void BrowserWindow::updateZoomActions(const double &zoomFactor)
2207 // Set the current zoom factor.
2208 currentZoomFactor = zoomFactor;
2210 // Set the status of the default zoom action.
2211 zoomDefaultActionPointer->setEnabled(currentZoomFactor != defaultZoomFactor);
2213 // Set the status of the zoom in action and button.
2214 zoomInActionPointer->setEnabled(currentZoomFactor <= 4.99);
2215 zoomPlusButtonPointer->setEnabled(currentZoomFactor <= 4.99);
2217 // Set the status of the zoom out action and button.
2218 zoomMinusButtonPointer->setEnabled(currentZoomFactor > 0.25);
2219 zoomOutActionPointer->setEnabled(currentZoomFactor > 0.25);
2222 // 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.
2223 zoomFactorActionPointer->setText(ki18nc("The zoom factor action", "Zoom Factor - %1").subs(zoomFactor, 0, '0', 2).toString());
2225 // Update the status bar zoom factor label.
2226 currentZoomButtonPointer->setText(ki18nc("The status bar zoom, which is just the formatted zoom factor", "%1").subs(zoomFactor, 0, '0', 2).toString());
2229 void BrowserWindow::zoomDefault()
2231 // Set the new zoom factor.
2232 tabWidgetPointer->applyOnTheFlyZoomFactor(defaultZoomFactor);
2234 // Update the on-the-fly action text.
2235 updateZoomActions(defaultZoomFactor);