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 zoomDefaultActionPointer = actionCollectionPointer->addAction(QLatin1String("zoom_default"));
95 QAction *reloadAndBypassCacheActionPointer = actionCollectionPointer->addAction(QLatin1String("reload_and_bypass_cache"));
96 viewSourceActionPointer = actionCollectionPointer->addAction(QLatin1String("view_source"));
97 viewSourceInNewTabActionPointer = actionCollectionPointer->addAction(QLatin1String("view_source_in_new_tab"));
98 javaScriptActionPointer = actionCollectionPointer->addAction(QLatin1String("javascript"));
99 localStorageActionPointer = actionCollectionPointer->addAction(QLatin1String("local_storage"));
100 domStorageActionPointer = actionCollectionPointer->addAction(QLatin1String("dom_storage"));
101 userAgentPrivacyBrowserActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_privacy_browser"));
102 userAgentWebEngineDefaultActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_webengine_default"));
103 userAgentFirefoxLinuxActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_firefox_linux"));
104 userAgentChromiumLinuxActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_chromium_linux"));
105 userAgentFirefoxWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_firefox_windows"));
106 userAgentChromeWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_chrome_windows"));
107 userAgentEdgeWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_edge_windows"));
108 userAgentSafariMacosActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_safari_macos"));
109 userAgentCustomActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_custom"));
110 zoomFactorActionPointer = actionCollectionPointer->addAction(QLatin1String("zoom_factor"));
111 searchEngineMojeekActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_mojeek"));
112 searchEngineMonoclesActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_monocles"));
113 searchEngineMetagerActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_metager"));
114 searchEngineGoogleActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_google"));
115 searchEngineBingActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_bing"));
116 searchEngineYahooActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_yahoo"));
117 searchEngineCustomActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_custom"));
118 viewBookmarksToolBarActionPointer = actionCollectionPointer->addAction(QLatin1String("view_bookmarks_toolbar"));
119 QAction *domainSettingsActionPointer = actionCollectionPointer->addAction(QLatin1String("domain_settings"));
120 cookiesActionPointer = actionCollectionPointer->addAction(QLatin1String("cookies"));
121 findCaseSensitiveActionPointer = actionCollectionPointer->addAction(QLatin1String("find_case_sensitive"));
122 hideFindTextActionPointer = actionCollectionPointer->addAction(QLatin1String("hide_find_actions"));
124 // Create the action groups
125 QActionGroup *userAgentActionGroupPointer = new QActionGroup(this);
126 QActionGroup *searchEngineActionGroupPointer = new QActionGroup(this);
128 // Add the actions to the groups.
129 userAgentActionGroupPointer->addAction(userAgentPrivacyBrowserActionPointer);
130 userAgentActionGroupPointer->addAction(userAgentWebEngineDefaultActionPointer);
131 userAgentActionGroupPointer->addAction(userAgentFirefoxLinuxActionPointer);
132 userAgentActionGroupPointer->addAction(userAgentChromiumLinuxActionPointer);
133 userAgentActionGroupPointer->addAction(userAgentFirefoxWindowsActionPointer);
134 userAgentActionGroupPointer->addAction(userAgentChromeWindowsActionPointer);
135 userAgentActionGroupPointer->addAction(userAgentEdgeWindowsActionPointer);
136 userAgentActionGroupPointer->addAction(userAgentSafariMacosActionPointer);
137 userAgentActionGroupPointer->addAction(userAgentCustomActionPointer);
138 searchEngineActionGroupPointer->addAction(searchEngineMojeekActionPointer);
139 searchEngineActionGroupPointer->addAction(searchEngineMonoclesActionPointer);
140 searchEngineActionGroupPointer->addAction(searchEngineMetagerActionPointer);
141 searchEngineActionGroupPointer->addAction(searchEngineGoogleActionPointer);
142 searchEngineActionGroupPointer->addAction(searchEngineBingActionPointer);
143 searchEngineActionGroupPointer->addAction(searchEngineYahooActionPointer);
144 searchEngineActionGroupPointer->addAction(searchEngineCustomActionPointer);
146 // Set some actions to be checkable.
147 javaScriptActionPointer->setCheckable(true);
148 localStorageActionPointer->setCheckable(true);
149 domStorageActionPointer->setCheckable(true);
150 findCaseSensitiveActionPointer->setCheckable(true);
151 viewSourceActionPointer->setCheckable(true);
152 userAgentPrivacyBrowserActionPointer->setCheckable(true);
153 userAgentWebEngineDefaultActionPointer->setCheckable(true);
154 userAgentFirefoxLinuxActionPointer->setCheckable(true);
155 userAgentChromiumLinuxActionPointer->setCheckable(true);
156 userAgentFirefoxWindowsActionPointer->setCheckable(true);
157 userAgentChromeWindowsActionPointer->setCheckable(true);
158 userAgentEdgeWindowsActionPointer->setCheckable(true);
159 userAgentSafariMacosActionPointer->setCheckable(true);
160 userAgentCustomActionPointer->setCheckable(true);
161 searchEngineMojeekActionPointer->setCheckable(true);
162 searchEngineMonoclesActionPointer->setCheckable(true);
163 searchEngineMetagerActionPointer->setCheckable(true);
164 searchEngineGoogleActionPointer->setCheckable(true);
165 searchEngineBingActionPointer->setCheckable(true);
166 searchEngineYahooActionPointer->setCheckable(true);
167 searchEngineCustomActionPointer->setCheckable(true);
168 viewBookmarksToolBarActionPointer->setCheckable(true);
170 // Instantiate the user agent helper.
171 UserAgentHelper *userAgentHelperPointer = new UserAgentHelper();
173 // Set the action text.
174 viewSourceActionPointer->setText(i18nc("View source action", "View Source"));
175 viewSourceInNewTabActionPointer->setText(i18nc("View source in new tab action", "View Source in New Tab"));
176 newTabActionPointer->setText(i18nc("New tab action", "New Tab"));
177 newWindowActionPointer->setText(i18nc("New window action", "New Window"));
178 zoomDefaultActionPointer->setText(i18nc("Zoom default action", "Zoom Default"));
179 reloadAndBypassCacheActionPointer->setText(i18nc("Reload and bypass cache action", "Reload and Bypass Cache"));
180 javaScriptActionPointer->setText(i18nc("JavaScript action", "JavaScript"));
181 localStorageActionPointer->setText(i18nc("The Local Storage action", "Local Storage"));
182 domStorageActionPointer->setText(i18nc("DOM Storage action", "DOM Storage"));
183 userAgentPrivacyBrowserActionPointer->setText(userAgentHelperPointer->PRIVACY_BROWSER_TRANSLATED);
184 userAgentWebEngineDefaultActionPointer->setText(userAgentHelperPointer->WEB_ENGINE_DEFAULT_TRANSLATED);
185 userAgentFirefoxLinuxActionPointer->setText(userAgentHelperPointer->FIREFOX_LINUX_TRANSLATED);
186 userAgentChromiumLinuxActionPointer->setText(userAgentHelperPointer->CHROMIUM_LINUX_TRANSLATED);
187 userAgentFirefoxWindowsActionPointer->setText(userAgentHelperPointer->FIREFOX_WINDOWS_TRANSLATED);
188 userAgentChromeWindowsActionPointer->setText(userAgentHelperPointer->CHROME_WINDOWS_TRANSLATED);
189 userAgentEdgeWindowsActionPointer->setText(userAgentHelperPointer->EDGE_WINDOWS_TRANSLATED);
190 userAgentSafariMacosActionPointer->setText(userAgentHelperPointer->SAFARI_MACOS_TRANSLATED);
191 searchEngineMojeekActionPointer->setText(i18nc("Search engine", "Mojeek"));
192 searchEngineMonoclesActionPointer->setText(i18nc("Search engine", "Monocles"));
193 searchEngineMetagerActionPointer->setText(i18nc("Search engine", "MetaGer"));
194 searchEngineGoogleActionPointer->setText(i18nc("Search engine", "Google"));
195 searchEngineBingActionPointer->setText(i18nc("Search engine", "Bing"));
196 searchEngineYahooActionPointer->setText(i18nc("Search engine", "Yahoo"));
197 viewBookmarksToolBarActionPointer->setText(i18nc("View bookmarks toolbar", "View Bookmarks Toolbar"));
198 domainSettingsActionPointer->setText(i18nc("Domain Settings action", "Domain Settings"));
199 cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", 0));
200 findCaseSensitiveActionPointer->setText(i18nc("Find Case Sensitive action", "Find Case Sensitive"));
201 hideFindTextActionPointer->setText(i18nc("Hide Find Text action (the text should include the language-specific escape keyboard shortcut).", "Hide Find Text (Esc)"));
203 // Set the action icons. Gnome doesn't contain some of the icons that KDE has.
204 // The toolbar icons don't pick up unless the size is explicit, probably because the toolbar ends up being an intermediate size.
205 newTabActionPointer->setIcon(QIcon::fromTheme(QLatin1String("tab-new")));
206 newWindowActionPointer->setIcon(QIcon::fromTheme(QLatin1String("window-new")));
207 zoomDefaultActionPointer->setIcon(QIcon::fromTheme(QLatin1String("zoom-fit-best")));
208 reloadAndBypassCacheActionPointer->setIcon(QIcon::fromTheme(QLatin1String("view-refresh")));
209 viewSourceActionPointer->setIcon(QIcon::fromTheme(QLatin1String("view-choose"), QIcon::fromTheme(QLatin1String("accessories-text-editor"))));
210 viewSourceInNewTabActionPointer->setIcon(QIcon::fromTheme(QLatin1String("view-choose"), QIcon::fromTheme(QLatin1String("accessories-text-editor"))));
211 domStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("code-class"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/actions/gtk-unindent-ltr.png"))));
212 userAgentPrivacyBrowserActionPointer->setIcon(QIcon(":/icons/privacy-mode.svg"));
213 userAgentWebEngineDefaultActionPointer->setIcon(QIcon::fromTheme(QLatin1String("qtlogo"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
214 userAgentFirefoxLinuxActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"),
215 QIcon::fromTheme(QLatin1String("contact-new")))));
216 userAgentChromiumLinuxActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
217 userAgentFirefoxWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"),
218 QIcon::fromTheme(QLatin1String("contact-new")))));
219 userAgentChromeWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
220 userAgentEdgeWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
221 userAgentSafariMacosActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
222 userAgentCustomActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
223 searchEngineMojeekActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
224 searchEngineMonoclesActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
225 searchEngineMetagerActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
226 searchEngineGoogleActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-google"), QIcon::fromTheme(QLatin1String("edit-find"))));
227 searchEngineBingActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
228 searchEngineYahooActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-yahoo"), QIcon::fromTheme(QLatin1String("edit-find"))));
229 searchEngineCustomActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
230 zoomFactorActionPointer->setIcon(QIcon::fromTheme(QLatin1String("zoom-fit-best")));
231 editBookmarksActionPointer->setIcon(QIcon::fromTheme(QLatin1String("bookmark-edit"), QIcon::fromTheme(QLatin1String("bookmark-new"))));
232 viewBookmarksToolBarActionPointer->setIcon(QIcon::fromTheme(QLatin1String("bookmarks"), QIcon::fromTheme(QLatin1String("bookmark-new"))));
233 domainSettingsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("settings-configure"), QIcon::fromTheme(QLatin1String("preferences-desktop"))));
234 cookiesActionPointer->setIcon(QIcon::fromTheme(QLatin1String("preferences-web-browser-cookies"), QIcon::fromTheme(QLatin1String("appointment-new"))));
235 findCaseSensitiveActionPointer->setIcon(QIcon::fromTheme(QLatin1String("format-text-lowercase"), QIcon::fromTheme(QLatin1String("/usr/share/icons/gnome/32x32/apps/fonts.png"))));
236 hideFindTextActionPointer->setIcon(QIcon::fromTheme(QLatin1String("window-close-symbolic")));
238 // Create the key sequences.
239 QKeySequence ctrlTKeySequence = QKeySequence(i18nc("The open new tab key sequence.", "Ctrl+T"));
240 QKeySequence ctrlNKeySequence = QKeySequence(i18nc("The open new window key sequence.", "Ctrl+N"));
241 QKeySequence ctrl0KeySequence = QKeySequence(i18nc("The zoom default key sequence.", "Ctrl+0"));
242 QKeySequence ctrlF5KeySequence = QKeySequence(i18nc("The reload and bypass cache key sequence.", "Ctrl+F5"));
243 QKeySequence ctrlUKeySequence = QKeySequence(i18nc("The view source key sequence.", "Ctrl+U"));
244 QKeySequence ctrlShiftUKeySequence = QKeySequence(i18nc("The view source in new tab key sequence.", "Ctrl+Shift+U"));
245 QKeySequence ctrlShiftPKeySequence = QKeySequence(i18nc("The print preview key sequence.", "Ctrl+Shift+P"));
246 QKeySequence ctrlJKeySequence = QKeySequence(i18nc("The JavaScript key sequence.", "Ctrl+J"));
247 QKeySequence ctrlLKeySequence = QKeySequence(i18nc("The local storage key sequence.", "Ctrl+L"));
248 QKeySequence ctrlDKeySequence = QKeySequence(i18nc("The DOM storage key sequence.", "Ctrl+D"));
249 QKeySequence ctrlSKeySequence = QKeySequence(i18nc("The find case sensitive key sequence.", "Ctrl+S"));
250 QKeySequence ctrlAltPKeySequence = QKeySequence(i18nc("The Privacy Browser user agent key sequence.", "Ctrl+Alt+P"));
251 QKeySequence ctrlAltWKeySequence = QKeySequence(i18nc("The WebEngine Default user agent key sequence.", "Ctrl+Alt+W"));
252 QKeySequence ctrlAltFKeySequence = QKeySequence(i18nc("The Firefox on Linux user agent key sequence.", "Ctrl+Alt+F"));
253 QKeySequence ctrlAltCKeySequence = QKeySequence(i18nc("The Chromium on Linux user agent key sequence.", "Ctrl+Alt+C"));
254 QKeySequence ctrlAltShiftFKeySequence = QKeySequence(i18nc("The Firefox on Windows user agent key sequence.", "Ctrl+Alt+Shift+F"));
255 QKeySequence ctrlAltShiftCKeySequence = QKeySequence(i18nc("The Chrome on Windows user agent key sequence.", "Ctrl+Alt+Shift+C"));
256 QKeySequence ctrlAltEKeySequence = QKeySequence(i18nc("The Edge on Windows user agent key sequence.", "Ctrl+Alt+E"));
257 QKeySequence ctrlAltSKeySequence = QKeySequence(i18nc("The Safari on macOS user agent key sequence.", "Ctrl+Alt+S"));
258 QKeySequence altShiftCKeySequence = QKeySequence(i18nc("The custom user agent key sequence.", "Alt+Shift+C"));
259 QKeySequence ctrlAltZKeySequence = QKeySequence(i18nc("The zoom factor key sequence.", "Ctrl+Alt+Z"));
260 QKeySequence ctrlShiftMKeySequence = QKeySequence(i18nc("The Mojeek search engine key sequence.", "Ctrl+Shift+M"));
261 QKeySequence ctrlShiftOKeySequence = QKeySequence(i18nc("The Monocles search engine key sequence.", "Ctrl+Shift+O"));
262 QKeySequence ctrlShiftEKeySequence = QKeySequence(i18nc("The MetaGer search engine key sequence.", "Ctrl+Shift+E"));
263 QKeySequence ctrlShiftGKeySequence = QKeySequence(i18nc("The Google search engine key sequence.", "Ctrl+Shift+G"));
264 QKeySequence ctrlShiftBKeySequence = QKeySequence(i18nc("The Bing search engine key sequence.", "Ctrl+Shift+B"));
265 QKeySequence ctrlShiftYKeySequence = QKeySequence(i18nc("The Yahoo search engine key sequence.", "Ctrl+Shift+Y"));
266 QKeySequence ctrlShiftCKeySequence = QKeySequence(i18nc("The custom search engine key sequence.", "Ctrl+Shift+C"));
267 QKeySequence ctrlAltShiftBKeySequence = QKeySequence(i18nc("The edit bookmarks key sequence.", "Ctrl+Alt+Shift+B"));
268 QKeySequence ctrlAltBKeySequence = QKeySequence(i18nc("The view bookmarks toolbar key sequence.", "Ctrl+Alt+B"));
269 QKeySequence ctrlShiftDKeySequence = QKeySequence(i18nc("The domain settings key sequence.", "Ctrl+Shift+D"));
270 QKeySequence ctrlSemicolonKeySequence = QKeySequence(i18nc("The cookies dialog key sequence.", "Ctrl+;"));
272 // Set the action key sequences.
273 actionCollectionPointer->setDefaultShortcut(newTabActionPointer, ctrlTKeySequence);
274 actionCollectionPointer->setDefaultShortcut(newWindowActionPointer, ctrlNKeySequence);
275 actionCollectionPointer->setDefaultShortcut(zoomDefaultActionPointer, ctrl0KeySequence);
276 actionCollectionPointer->setDefaultShortcut(reloadAndBypassCacheActionPointer, ctrlF5KeySequence);
277 actionCollectionPointer->setDefaultShortcut(viewSourceActionPointer, ctrlUKeySequence);
278 actionCollectionPointer->setDefaultShortcut(viewSourceInNewTabActionPointer, ctrlShiftUKeySequence);
279 actionCollectionPointer->setDefaultShortcut(printPreviewActionPointer, ctrlShiftPKeySequence);
280 actionCollectionPointer->setDefaultShortcut(javaScriptActionPointer, ctrlJKeySequence);
281 actionCollectionPointer->setDefaultShortcut(localStorageActionPointer, ctrlLKeySequence);
282 actionCollectionPointer->setDefaultShortcut(domStorageActionPointer, ctrlDKeySequence);
283 actionCollectionPointer->setDefaultShortcut(findCaseSensitiveActionPointer, ctrlSKeySequence);
284 actionCollectionPointer->setDefaultShortcut(userAgentPrivacyBrowserActionPointer, ctrlAltPKeySequence);
285 actionCollectionPointer->setDefaultShortcut(userAgentWebEngineDefaultActionPointer, ctrlAltWKeySequence);
286 actionCollectionPointer->setDefaultShortcut(userAgentFirefoxLinuxActionPointer, ctrlAltFKeySequence);
287 actionCollectionPointer->setDefaultShortcut(userAgentChromiumLinuxActionPointer, ctrlAltCKeySequence);
288 actionCollectionPointer->setDefaultShortcut(userAgentFirefoxWindowsActionPointer, ctrlAltShiftFKeySequence);
289 actionCollectionPointer->setDefaultShortcut(userAgentChromeWindowsActionPointer, ctrlAltShiftCKeySequence);
290 actionCollectionPointer->setDefaultShortcut(userAgentEdgeWindowsActionPointer, ctrlAltEKeySequence);
291 actionCollectionPointer->setDefaultShortcut(userAgentSafariMacosActionPointer, ctrlAltSKeySequence);
292 actionCollectionPointer->setDefaultShortcut(userAgentCustomActionPointer, altShiftCKeySequence);
293 actionCollectionPointer->setDefaultShortcut(zoomFactorActionPointer, ctrlAltZKeySequence);
294 actionCollectionPointer->setDefaultShortcut(searchEngineMojeekActionPointer, ctrlShiftMKeySequence);
295 actionCollectionPointer->setDefaultShortcut(searchEngineMonoclesActionPointer, ctrlShiftOKeySequence);
296 actionCollectionPointer->setDefaultShortcut(searchEngineMetagerActionPointer, ctrlShiftEKeySequence);
297 actionCollectionPointer->setDefaultShortcut(searchEngineGoogleActionPointer, ctrlShiftGKeySequence);
298 actionCollectionPointer->setDefaultShortcut(searchEngineBingActionPointer, ctrlShiftBKeySequence);
299 actionCollectionPointer->setDefaultShortcut(searchEngineYahooActionPointer, ctrlShiftYKeySequence);
300 actionCollectionPointer->setDefaultShortcut(searchEngineCustomActionPointer, ctrlShiftCKeySequence);
301 actionCollectionPointer->setDefaultShortcut(editBookmarksActionPointer, ctrlAltShiftBKeySequence);
302 actionCollectionPointer->setDefaultShortcut(viewBookmarksToolBarActionPointer, ctrlAltBKeySequence);
303 actionCollectionPointer->setDefaultShortcut(domainSettingsActionPointer, ctrlShiftDKeySequence);
304 actionCollectionPointer->setDefaultShortcut(cookiesActionPointer, ctrlSemicolonKeySequence);
306 // Execute the actions.
307 connect(newTabActionPointer, SIGNAL(triggered()), tabWidgetPointer, SLOT(addTab()));
308 connect(newWindowActionPointer, SIGNAL(triggered()), this, SLOT(newWindow()));
309 connect(zoomDefaultActionPointer, SIGNAL(triggered()), this, SLOT(zoomDefault()));
310 connect(reloadAndBypassCacheActionPointer, SIGNAL(triggered()), this, SLOT(reloadAndBypassCache()));
311 connect(viewSourceActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewSource()));
312 connect(viewSourceInNewTabActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewSourceInNewTab()));
313 connect(zoomFactorActionPointer, SIGNAL(triggered()), this, SLOT(getZoomFactorFromUser()));
314 connect(viewBookmarksToolBarActionPointer, SIGNAL(triggered()), this, SLOT(toggleViewBookmarksToolBar()));
315 connect(cookiesActionPointer, SIGNAL(triggered()), this, SLOT(showCookiesDialog()));
316 connect(domainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(showDomainSettingsDialog()));
318 // Update the on-the-fly menus.
319 connect(tabWidgetPointer, SIGNAL(updateUserAgentActions(QString, bool)), this, SLOT(updateUserAgentActions(QString, bool)));
320 connect(tabWidgetPointer, SIGNAL(updateZoomActions(double)), this, SLOT(updateZoomActions(double)));
321 connect(tabWidgetPointer, SIGNAL(updateSearchEngineActions(QString, bool)), this, SLOT(updateSearchEngineActions(QString, bool)));
323 // Apply the on-the-fly settings when selected.
324 connect(userAgentActionGroupPointer, SIGNAL(triggered(QAction*)), tabWidgetPointer, SLOT(applyOnTheFlyUserAgent(QAction*)));
325 connect(searchEngineActionGroupPointer, SIGNAL(triggered(QAction*)), tabWidgetPointer, SLOT(applyOnTheFlySearchEngine(QAction*)));
327 // Process cookie changes.
328 connect(tabWidgetPointer, SIGNAL(updateCookiesAction(int)), this, SLOT(updateCookiesAction(int)));
330 // Store the default zoom factor.
331 connect(tabWidgetPointer, SIGNAL(updateDefaultZoomFactor(double)), this, SLOT(updateDefaultZoomFactor(double)));
333 // Connect the URL toolbar actions.
334 connect(javaScriptActionPointer, SIGNAL(triggered()), this, SLOT(toggleJavaScript()));
335 connect(localStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleLocalStorage()));
336 connect(domStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleDomStorage()));
338 // Update the URL toolbar actions.
339 connect(tabWidgetPointer, SIGNAL(updateBackAction(bool)), backActionPointer, SLOT(setEnabled(bool)));
340 connect(tabWidgetPointer, SIGNAL(updateForwardAction(bool)), forwardActionPointer, SLOT(setEnabled(bool)));
341 connect(tabWidgetPointer, SIGNAL(updateJavaScriptAction(bool)), this, SLOT(updateJavaScriptAction(bool)));
342 connect(tabWidgetPointer, SIGNAL(updateLocalStorageAction(bool)), this, SLOT(updateLocalStorageAction(bool)));
343 connect(tabWidgetPointer, SIGNAL(updateDomStorageAction(bool)), this, SLOT(updateDomStorageAction(bool)));
345 // Connect the find text actions.
346 connect(findCaseSensitiveActionPointer, SIGNAL(triggered()), this, SLOT(toggleFindCaseSensitive()));
347 connect(hideFindTextActionPointer, SIGNAL(triggered()), this, SLOT(hideFindTextActions()));
351 // Setup the GUI based on the browserwindowui.rc file.
352 setupGUI(StandardWindowOption::Default, ("browserwindowui.rc"));
354 // Get lists of the actions' associated widgets.
355 QList<QWidget*> userAgentAssociatedWidgetsPointerList = userAgentPrivacyBrowserActionPointer->associatedWidgets();
356 QList<QWidget*> searchEngineAssociatedWidgetsPointerList = searchEngineMojeekActionPointer->associatedWidgets();
358 // Get the menu widget pointers. It is the second entry, after the main window.
359 QWidget *userAgentMenuWidgetPointer = userAgentAssociatedWidgetsPointerList[1];
360 QWidget *searchEngineMenuWidgetPointer = searchEngineAssociatedWidgetsPointerList[1];
362 // Get the menu pointers.
363 QMenu *userAgentMenuPointer = qobject_cast<QMenu*>(userAgentMenuWidgetPointer);
364 QMenu *searchEngineMenuPointer = qobject_cast<QMenu*>(searchEngineMenuWidgetPointer);
366 // Get the menu actions.
367 userAgentMenuActionPointer = userAgentMenuPointer->menuAction();
368 searchEngineMenuActionPointer = searchEngineMenuPointer->menuAction();
370 // Get handles for the toolbars.
371 navigationToolBarPointer = toolBar(QLatin1String("navigation_toolbar"));
372 urlToolBarPointer = toolBar(QLatin1String("url_toolbar"));
373 bookmarksToolBarPointer = toolBar(QLatin1String("bookmarks_toolbar"));
375 // Populate the view bookmarks toolbar checkbox.
376 connect(bookmarksToolBarPointer, SIGNAL(visibilityChanged(bool)), this, SLOT(updateViewBookmarksToolBarCheckbox(bool)));
378 // Create the line edits.
379 urlLineEditPointer = new KLineEdit();
380 findTextLineEditPointer = new KLineEdit();
382 // Get the line edit size policies.
383 QSizePolicy urlLineEditSizePolicy = urlLineEditPointer->sizePolicy();
384 QSizePolicy findTextLineEditSizePolicy = findTextLineEditPointer->sizePolicy();
386 // Set the URL line edit horizontal stretch to be five times the find text line edit stretch.
387 urlLineEditSizePolicy.setHorizontalStretch(5);
388 findTextLineEditSizePolicy.setHorizontalStretch(1);
391 urlLineEditPointer->setSizePolicy(urlLineEditSizePolicy);
392 findTextLineEditPointer->setSizePolicy(findTextLineEditSizePolicy);
395 urlLineEditPointer->setMinimumWidth(350);
396 findTextLineEditPointer->setMinimumWidth(200);
397 findTextLineEditPointer->setMaximumWidth(350);
399 // Set the place holder text.
400 urlLineEditPointer->setPlaceholderText(i18nc("The URL line edit placeholder text", "URL or Search Terms"));
401 findTextLineEditPointer->setPlaceholderText(i18nc("The find line edit placeholder text", "Find Text"));
403 // Show the clear button on the find line edit.
404 findTextLineEditPointer->setClearButtonEnabled(true);
406 // Add the actions to the URL line edit.
407 bookmarkedActionPointer = urlLineEditPointer->addAction(QIcon::fromTheme("non-starred-symbolic"), QLineEdit::LeadingPosition);
408 QAction *addOrEditDomainSettingsActionPointer = urlLineEditPointer->addAction(QIcon::fromTheme("settings-configure", QIcon::fromTheme(QLatin1String("preferences-desktop"))),
409 QLineEdit::TrailingPosition);
411 // Set the bookmarked action pointer to be checkable.
412 bookmarkedActionPointer->setCheckable(true);
414 // Connect the URL line edit actions.
415 connect(bookmarkedActionPointer, SIGNAL(triggered()), this, SLOT(toggleBookmark()));
416 connect(addOrEditDomainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(addOrEditDomainSettings()));
418 // Create a find text label pointer.
419 findTextLabelPointer = new QLabel();
421 // Set the default label text.
422 findTextLabelPointer->setText(QLatin1String(" ") + i18nc("Default find results.", "0/0") + QLatin1String(" "));
424 // Insert the widgets into the toolbars.
425 urlToolBarPointer->insertWidget(javaScriptActionPointer, urlLineEditPointer);
426 findTextLineEditActionPointer = urlToolBarPointer->insertWidget(findNextActionPointer, findTextLineEditPointer);
427 findTextLabelActionPointer = urlToolBarPointer->insertWidget(findNextActionPointer, findTextLabelPointer);
429 // Initially hide the find text actions.
430 hideFindTextActions();
432 // Load a new URL from the URL line edit.
433 connect(urlLineEditPointer, SIGNAL(returnKeyPressed(const QString)), this, SLOT(loadUrlFromLineEdit(const QString)));
435 // Find text as it is typed.
436 connect(findTextLineEditPointer, SIGNAL(textEdited(const QString &)), tabWidgetPointer, SLOT(findText(const QString &)));
438 // Find next if the enter key is pressed.
439 connect(findTextLineEditPointer, SIGNAL(returnKeyPressed(const QString &)), tabWidgetPointer, SLOT(findText(const QString &)));
441 // Update find text when switching tabs.
442 connect(tabWidgetPointer, SIGNAL(updateFindText(const QString &, const bool)), this, SLOT(updateFindText(const QString &, const bool)));
444 // Update the find text results.
445 connect(tabWidgetPointer, SIGNAL(updateFindTextResults(const QWebEngineFindTextResult &)), this, SLOT(updateFindTextResults(const QWebEngineFindTextResult &)));
447 // Update the URL line edit on page loads.
448 connect(tabWidgetPointer, SIGNAL(updateUrlLineEdit(QUrl)), this, SLOT(updateUrlLineEdit(QUrl)));
450 // Update the window title.
451 connect(tabWidgetPointer, SIGNAL(updateWindowTitle(const QString)), this, SLOT(updateWindowTitle(const QString)));
453 // Get a handle for the status bar.
454 QStatusBar *statusBarPointer = statusBar();
456 // Create the status bar widgets.
457 progressBarPointer = new QProgressBar();
458 zoomMinusButtonPointer = new QPushButton();
459 currentZoomButtonPointer = new QPushButton();
460 zoomPlusButtonPointer = new QPushButton();
462 // Set the button icons.
463 zoomMinusButtonPointer->setIcon(QIcon::fromTheme(QStringLiteral("list-remove-symbolic")));
464 zoomPlusButtonPointer->setIcon(QIcon::fromTheme(QStringLiteral("list-add-symbolic")));
466 // Set the button icons to be flat (no borders).
467 zoomMinusButtonPointer->setFlat(true);
468 currentZoomButtonPointer->setFlat(true);
469 zoomPlusButtonPointer->setFlat(true);
471 // Handle clicks on the zoom buttons.
472 connect(zoomMinusButtonPointer, SIGNAL(clicked()), this, SLOT(decrementZoom()));
473 connect(currentZoomButtonPointer, SIGNAL(clicked()), this, SLOT(getZoomFactorFromUser()));
474 connect(zoomPlusButtonPointer, SIGNAL(clicked()), this, SLOT(incrementZoom()));
476 // Remove the padding around the current zoom button text.
477 currentZoomButtonPointer->setStyleSheet("padding: 0px;");
479 // Add the widgets to the far right of the status bar.
480 statusBarPointer->addPermanentWidget(progressBarPointer);
481 statusBarPointer->addPermanentWidget(zoomMinusButtonPointer);
482 statusBarPointer->addPermanentWidget(currentZoomButtonPointer);
483 statusBarPointer->addPermanentWidget(zoomPlusButtonPointer);
485 // Update the status bar with the URL when a link is hovered.
486 connect(tabWidgetPointer, SIGNAL(linkHovered(QString)), statusBarPointer, SLOT(showMessage(QString)));
488 // Update the progress bar.
489 connect(tabWidgetPointer, SIGNAL(showProgressBar(const int)), this, SLOT(showProgressBar(const int)));
490 connect(tabWidgetPointer, SIGNAL(hideProgressBar()), progressBarPointer, SLOT(hide()));
492 // Update the URL line edit focus.
493 connect(tabWidgetPointer, SIGNAL(clearUrlLineEditFocus()), this, SLOT(clearUrlLineEditFocus()));
495 // Get the URL line edit palettes.
496 normalBackgroundPalette = urlLineEditPointer->palette();
497 negativeBackgroundPalette = normalBackgroundPalette;
498 positiveBackgroundPalette = normalBackgroundPalette;
500 // Modify the palettes.
501 KColorScheme::adjustBackground(negativeBackgroundPalette, KColorScheme::NegativeBackground);
502 KColorScheme::adjustBackground(positiveBackgroundPalette, KColorScheme::PositiveBackground);
504 // Update the applied palette.
505 connect(tabWidgetPointer, SIGNAL(updateDomainSettingsIndicator(const bool)), this, SLOT(updateDomainSettingsIndicator(const bool)));
507 // Process full screen requests.
508 connect(tabWidgetPointer, SIGNAL(fullScreenRequested(bool)), this, SLOT(fullScreenRequested(bool)));
510 // Create keyboard shortcuts.
511 QShortcut *f11ShortcutPointer = new QShortcut(QKeySequence(i18nc("The toggle full screen shortcut.", "F11")), this);
512 QShortcut *escapeShortcutPointer = new QShortcut(QKeySequence::Cancel, this);
514 // Connect the keyboard shortcuts.
515 connect(f11ShortcutPointer, SIGNAL(activated()), fullScreenActionPointer, SLOT(trigger()));
516 connect(escapeShortcutPointer, SIGNAL(activated()), this, SLOT(escape()));
518 // Get a handle for the Bookmarks menu.
519 bookmarksMenuPointer = qobject_cast<QMenu*>(guiFactory()->container("bookmarks", this));
521 // Add a separator to the bookmarks menu.
522 bookmarksMenuPointer->addSeparator();
524 // Initialize the current bookmarks lists.
525 finalBookmarkFolderMenuActionList = QList<QPair<QMenu *, QAction *> *>();
526 bookmarksMenuActionList = QList<QPair<QMenu *, QAction *> *>();
527 bookmarksMenuSubmenuList = QList<QPair<QMenu *, QMenu *> *>();
528 bookmarksToolBarActionList = QList<QAction*>();
529 bookmarksToolBarSubfolderActionList = QList<QPair<QMenu *, QAction * > *>();
531 // Set the bookmarks toolbar context menu policy.
532 bookmarksToolBarPointer->setContextMenuPolicy(Qt::CustomContextMenu);
534 // Show the custom bookmark context menu when requested.
535 connect(bookmarksToolBarPointer, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showBookmarkContextMenu(const QPoint&)));
537 // Populate the bookmarks in this window.
538 populateBookmarksInThisWindow();
541 // 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.
542 updateJavaScriptAction(Settings::javaScriptEnabled());
543 updateLocalStorageAction(Settings::localStorageEnabled());
544 updateDomStorageAction(Settings::domStorageEnabled());
545 updateUserAgentActions(UserAgentHelper::getUserAgentFromDatabaseName(Settings::userAgent()), true);
546 updateZoomActions(Settings::zoomFactor());
548 // Populate the first tab.
549 if (firstWindow) // This is the first window.
551 // Load the initial website.
552 tabWidgetPointer->loadInitialWebsite();
554 else if (initialUrlStringPointer) // An initial URL was specified.
556 // Load the initial URL.
557 tabWidgetPointer->loadUrlFromLineEdit(*initialUrlStringPointer);
561 void BrowserWindow::addFinalBookmarkFolderMenuActions(QMenu *menuPointer, double folderId)
563 // Get the database ID.
564 int folderDatabaseId = BookmarksDatabase::getFolderDatabaseId(folderId);
567 menuPointer->addSeparator();
569 // Add the add bookmark action to the menu.
570 QAction *addBookmarkActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("bookmark-new")), i18nc("The add bookmark action", "Add Bookmark"), [=]
572 // Instantiate an add bookmark dialog.
573 AddBookmarkDialog *addBookmarkDialogPointer = new AddBookmarkDialog(tabWidgetPointer->getCurrentTabTitle(), tabWidgetPointer->getCurrentTabUrl(),
574 tabWidgetPointer->getCurrentTabFavoritIcon(), folderId);
576 // Update the displayed bookmarks when a new one is added.
577 connect(addBookmarkDialogPointer, SIGNAL(bookmarkAdded()), this, SLOT(populateBookmarksInAllWindows()));
580 addBookmarkDialogPointer->show();
584 // Add the add folder action to the menu.
585 QAction *addFolderActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("folder-add")), i18nc("The add folder action", "Add Folder"), [=]
587 // Instantiate an add folder dialog.
588 AddFolderDialog *addFolderDialogPointer = new AddFolderDialog(tabWidgetPointer->getCurrentTabFavoritIcon(), folderId);
590 // Update the displayed bookmarks when a folder is added.
591 connect(addFolderDialogPointer, SIGNAL(folderAdded()), this, SLOT(populateBookmarksInAllWindows()));
594 addFolderDialogPointer->show();
599 menuPointer->addSeparator();
601 // Add the open folder in new tabs action to the menu.
602 QAction *openFolderInNewTabsActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("The open folder in new tabs action", "Open Folder in New Tabs"), [=]
604 // Get all the folder URLs.
605 QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(folderId);
607 // Open the URLs in new tabs. `true` removes the URL line edit focus, `false` does not load a background tab.
608 for (QString url : *folderUrlsListPointer)
609 tabWidgetPointer->addTab(true, false, url);
613 // Add the open folder in background tabs action to the menu.
614 QAction *openFolderInBackgroundTabsActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")),
615 i18nc("The open folder in background tabs action", "Open Folder in Background Tabs"), [=]
617 // Get all the folder URLs.
618 QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(folderId);
620 // Open the URLs in new tabs. `true` removes the URL line edit focus, `true` loads a background tab.
621 for (QString url : *folderUrlsListPointer)
622 tabWidgetPointer->addTab(true, true, url);
626 // Add the open folder in new window action to the menu.
627 QAction *openFolderInNewWindowActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("window-new")), i18nc("The open folder in new window action", "Open Folder in New Window"), [=]
629 // Get all the folder URLs.
630 QList<QString> *folderUrlsListPointer = BookmarksDatabase::getAllFolderUrls(folderId);
632 // Create a new browser window.
633 BrowserWindow *browserWindowPointer = new BrowserWindow(false, &folderUrlsListPointer->first());
635 // Get a count of the folder URLs.
636 const int folderUrls = folderUrlsListPointer->count();
638 // Load all the other URLs. `true` removes the URL line edit focus, `true` loads a background tab.
639 for (int i = 1; i < folderUrls; ++i)
640 browserWindowPointer->tabWidgetPointer->addTab(true, true, folderUrlsListPointer->value(i));
642 // Show the new browser window.
643 browserWindowPointer->show();
648 menuPointer->addSeparator();
650 // Add the edit folder action to the menu if this is not the root bookmark menu.
653 QAction *editFolderActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("document-edit")), i18nc("The edit folder action", "Edit Folder"), [=]
655 // Get the current tab favorite icon.
656 QIcon currentTabFavoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
658 // Instantiate an edit folder dialog.
659 QDialog *editFolderDialogPointer = new EditFolderDialog(folderDatabaseId, currentTabFavoriteIcon);
662 editFolderDialogPointer->show();
664 // Process bookmark events.
665 connect(editFolderDialogPointer, SIGNAL(folderSaved()), this, SLOT(populateBookmarksInAllWindows()));
669 // Add the action to the beginning of the final bookmark folder menu action list.
670 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, editFolderActionPointer));
673 // Add the delete folder action to the menu.
674 QAction *deleteFolderActionPointer = menuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-delete")), i18nc("Delete folder context menu entry", "Delete Folder"), [=]
676 // Create an items to delete list.
677 QList<int>* itemsToDeleteListPointer = new QList<int>;
679 // Add the folder to the list of items to delete if it is not the root folder.
681 itemsToDeleteListPointer->append(folderDatabaseId);
683 // Add the folder contents to the list of items to delete.
684 itemsToDeleteListPointer->append(*BookmarksDatabase::getFolderContentsDatabaseIdsRecursively(folderId));
686 // Instantiate a delete dialog message box.
687 QMessageBox deleteDialogMessageBox;
690 deleteDialogMessageBox.setIcon(QMessageBox::Warning);
692 // Set the window title.
693 deleteDialogMessageBox.setWindowTitle(i18nc("Delete bookmarks dialog title", "Delete Bookmarks"));
696 deleteDialogMessageBox.setText(i18ncp("Delete bookmarks dialog main message", "Delete %1 bookmark item?", "Delete %1 bookmark items?", itemsToDeleteListPointer->count()));
698 // Set the informative text.
699 deleteDialogMessageBox.setInformativeText(i18nc("Delete bookmarks dialog secondary message", "This cannot be undone."));
701 // Set the standard buttons.
702 deleteDialogMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
704 // Set the default button.
705 deleteDialogMessageBox.setDefaultButton(QMessageBox::No);
707 // Display the dialog and capture the return value.
708 int returnValue = deleteDialogMessageBox.exec();
710 // Delete the domain if instructed.
711 if (returnValue == QMessageBox::Yes)
713 // Get the parent folder ID.
714 double parentFolderId = BookmarksDatabase::getParentFolderId(folderDatabaseId);
716 // Delete the folder and its contents.
717 for (const int databaseId : *itemsToDeleteListPointer)
718 BookmarksDatabase::deleteBookmark(databaseId);
720 // Update the display order of the bookmarks in the parent folder.
721 BookmarksDatabase::updateFolderContentsDisplayOrder(parentFolderId);
723 // Repopulate the bookmarks.
724 populateBookmarksInAllWindows();
729 // Add the key sequences if this is the root bookmarks menu.
732 // Create the key sequences.
733 QKeySequence ctrlBKeySequence = QKeySequence(i18nc("The add bookmark key sequence.", "Ctrl+B"));
734 QKeySequence metaFKeySequence = QKeySequence(i18nc("The add folder key sequence.", "Meta+F"));
736 // Set the action key sequences.
737 actionCollectionPointer->setDefaultShortcut(addBookmarkActionPointer, ctrlBKeySequence);
738 actionCollectionPointer->setDefaultShortcut(addFolderActionPointer, metaFKeySequence);
741 // Add the actions to the beginning of the final bookmark folder menu action list.
742 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, addBookmarkActionPointer));
743 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, addFolderActionPointer));
744 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, openFolderInNewTabsActionPointer));
745 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, openFolderInBackgroundTabsActionPointer));
746 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, openFolderInNewWindowActionPointer));
747 finalBookmarkFolderMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, deleteFolderActionPointer));
750 void BrowserWindow::addOrEditDomainSettings() const
752 // Remove the focus from the URL line edit.
753 urlLineEditPointer->clearFocus();
755 // Create the domain settings dialog pointer.
756 DomainSettingsDialog *domainSettingsDialogPointer;
758 // Get the current domain settings name.
759 QString ¤tDomainSettingsName = tabWidgetPointer->getDomainSettingsName();
761 // Run the commands according to the current domain settings status.
762 if (currentDomainSettingsName == QStringLiteral("")) // Domain settings are not currently applied.
764 // Instruct the domain settings dialog to add a new domain.
765 domainSettingsDialogPointer = new DomainSettingsDialog(DomainSettingsDialog::ADD_DOMAIN, currentUrl.host());
767 else // Domain settings are currently applied.
769 // Instruct the domain settings dialog to edit the current domain.
770 domainSettingsDialogPointer = new DomainSettingsDialog(DomainSettingsDialog::EDIT_DOMAIN, currentDomainSettingsName);
773 // Reload the tabs when domain settings are updated.
774 connect(domainSettingsDialogPointer, SIGNAL(domainSettingsUpdated()), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
777 domainSettingsDialogPointer->show();
780 void BrowserWindow::back() const
782 // Remove the focus from the URL line edit.
783 urlLineEditPointer->clearFocus();
786 tabWidgetPointer->back();
789 void BrowserWindow::clearUrlLineEditFocus() const
791 // Remove the focus from the URL line edit.
792 urlLineEditPointer->clearFocus();
795 void BrowserWindow::decrementZoom()
797 // Update the current zoom factor.
798 currentZoomFactor = currentZoomFactor - 0.25;
800 // Check to make sure the zoom factor is in the valid range (0.25 to 5.00).
801 if (currentZoomFactor < 0.25)
802 currentZoomFactor = 0.25;
804 // Set the new zoom factor.
805 tabWidgetPointer->applyOnTheFlyZoomFactor(currentZoomFactor);
807 // Update the on-the-fly action text.
808 updateZoomActions(currentZoomFactor);
811 void BrowserWindow::editBookmarks() const
813 // Instantiate an edit bookmarks dialog.
814 BookmarksDialog *bookmarksDialogPointer = new BookmarksDialog(tabWidgetPointer->getCurrentTabTitle(), tabWidgetPointer->getCurrentTabUrl(), tabWidgetPointer->getCurrentTabFavoritIcon());
816 // Update the displayed bookmarks when edited.
817 connect(bookmarksDialogPointer, SIGNAL(bookmarkUpdated()), this, SLOT(populateBookmarksInAllWindows()));
820 bookmarksDialogPointer->show();
823 void BrowserWindow::escape() const
825 // Process the escape according to the status of the browser.
826 if (fullScreenActionPointer->isChecked()) // Full screen browsing is enabled.
828 // Exit full screen browsing.
829 fullScreenActionPointer->trigger();
831 else if (!findTextLineEditPointer->text().isEmpty()) // Find text is populated.
833 // Clear the find text line edit.
834 findTextLineEditPointer->clear();
836 // Clear the search in the WebEngine.
837 tabWidgetPointer->findText(QStringLiteral(""));
839 else if (findTextLineEditActionPointer->isVisible()) // Find text actions are visible.
841 // Hide the find text actions.
842 hideFindTextActions();
846 void BrowserWindow::findNext() const
848 // Get the find string.
849 const QString findString = findTextLineEditPointer->text();
851 // Search for the text if it is not empty.
852 if (!findString.isEmpty())
853 tabWidgetPointer->findText(findString);
856 void BrowserWindow::findPrevious() const
858 // Get the find string.
859 const QString findString = findTextLineEditPointer->text();
861 // Search for the text if it is not empty.
862 if (!findString.isEmpty())
863 tabWidgetPointer->findPrevious(findString);
866 void BrowserWindow::forward() const
868 // Remove the focus from the URL line edit.
869 urlLineEditPointer->clearFocus();
872 tabWidgetPointer->forward();
875 void BrowserWindow::fullScreenRequested(const bool toggleOn)
877 // Toggle full screen mode.
878 if (toggleOn) // Turn full screen mode on.
880 // Enable full screen mode.
881 fullScreenActionPointer->setFullScreen(window(), true);
883 // Hide the menu bar if specified.
884 if (Settings::fullScreenHideMenuBar())
885 menuBar()->setVisible(false);
887 // Hide the toolbars if specified.
888 if (Settings::fullScreenHideToolBars())
890 navigationToolBarPointer->setVisible(false);
891 urlToolBarPointer->setVisible(false);
892 bookmarksToolBarPointer->setVisible(false);
895 // Hide the tab bar if specified.
896 if (Settings::fullScreenHideTabBar())
897 tabWidgetPointer->setTabBarVisible(false);
899 // Hide the status bar if specified.
900 if (Settings::fullScreenHideStatusBar())
901 statusBar()->setVisible(false);
903 else // Disable full screen browsing mode.
905 // Disable full screen mode.
906 fullScreenActionPointer->setFullScreen(window(), false);
908 // Show the menu bar.
909 menuBar()->setVisible(true);
911 // Show the toolbars.
912 navigationToolBarPointer->setVisible(true);
913 urlToolBarPointer->setVisible(true);
915 // Only show the bookmarks toolbar if it was previously visible.
916 if (bookmarksToolBarIsVisible)
917 bookmarksToolBarPointer->setVisible(true);
920 tabWidgetPointer->setTabBarVisible(true);
922 // Show the status bar.
923 statusBar()->setVisible(true);
927 void BrowserWindow::getZoomFactorFromUser()
929 // Create an OK flag.
932 // 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.
933 double newZoomFactor = QInputDialog::getDouble(this, i18nc("The on-the-fly zoom factor dialog title", "On-The-Fly Zoom Factor"),
934 i18nc("The instruction text of the on-the-fly zoom factor dialog", "Enter a zoom factor between 0.25 and 5.00"),
935 currentZoomFactor, .025, 5.00, 2, &okClicked, Qt::WindowFlags(), 0.25);
937 // Update the zoom factor if the user clicked OK.
940 // Set the new zoom factor.
941 tabWidgetPointer->applyOnTheFlyZoomFactor(newZoomFactor);
943 // Update the on-the-fly action text.
944 updateZoomActions(newZoomFactor);
948 void BrowserWindow::hideFindTextActions() const
950 // Hide the find text actions.
951 findTextLineEditActionPointer->setVisible(false);
952 findTextLabelActionPointer->setVisible(false);
953 findNextActionPointer->setVisible(false);
954 findPreviousActionPointer->setVisible(false);
955 findCaseSensitiveActionPointer->setVisible(false);
956 hideFindTextActionPointer->setVisible(false);
959 void BrowserWindow::home() const
961 // Remove the focus from the URL line edit.
962 urlLineEditPointer->clearFocus();
965 tabWidgetPointer->home();
968 void BrowserWindow::incrementZoom()
970 // Update the current zoom factor.
971 currentZoomFactor = currentZoomFactor + 0.25;
973 // Check to make sure the zoom factor is in the valid range (0.25 to 5.00).
974 if (currentZoomFactor > 5.0)
975 currentZoomFactor = 5.0;
977 // Set the new zoom factor.
978 tabWidgetPointer->applyOnTheFlyZoomFactor(currentZoomFactor);
980 // Update the on-the-fly action text.
981 updateZoomActions(currentZoomFactor);
984 void BrowserWindow::loadUrlFromLineEdit(const QString &url) const
986 // Remove the focus from the URL line edit.
987 urlLineEditPointer->clearFocus();
990 tabWidgetPointer->loadUrlFromLineEdit(url);
993 void BrowserWindow::newWindow() const
995 // Create a new browser window.
996 BrowserWindow *browserWindowPointer = new BrowserWindow();
998 // Show the new browser window.
999 browserWindowPointer->show();
1002 void BrowserWindow::populateBookmarksInAllWindows() const
1004 // Get a list of all the registered service names.
1005 QStringList registeredServiceNames = QDBusConnection::sessionBus().interface()->registeredServiceNames().value();
1007 // Get a list of all the Privacy Browser windows, which will be `com.stoutner.privacybrowser-` with the PID appended.
1008 QStringList privacyBrowserServiceNames = registeredServiceNames.filter("com.stoutner.privacybrowser");
1010 // Repopulate the bookmarks in each window.
1011 for (QString privacyBrowserServiceName : privacyBrowserServiceNames)
1013 // Prepare the D-Bus message.
1014 QDBusMessage dBusMessage = QDBusMessage::createMethodCall(privacyBrowserServiceName, "/privacybrowser/MainWindow_1", "com.stoutner.privacybrowser.BrowserWindow", "populateBookmarksInThisWindow");
1017 QDBusConnection::sessionBus().send(dBusMessage);
1021 void BrowserWindow::populateBookmarksInThisWindow()
1023 qDebug() << "Populating bookmarks.";
1025 // Remove all the final bookmark folder menu actions.
1026 for (QPair<QMenu *, QAction *> *finalBookmarkFolderMenuActionPair : finalBookmarkFolderMenuActionList)
1028 // Remove the action.
1029 finalBookmarkFolderMenuActionPair->first->removeAction(finalBookmarkFolderMenuActionPair->second);
1032 // Remove all the current menu bookmarks.
1033 for (QPair<QMenu *, QAction *> *bookmarkMenuActionPairPointer : bookmarksMenuActionList)
1035 // Remove the bookmark.
1036 bookmarkMenuActionPairPointer->first->removeAction(bookmarkMenuActionPairPointer->second);
1039 // Remove all the current menu subfolders.
1040 for (QPair<QMenu *, QMenu *> *submenuPairPointer : bookmarksMenuSubmenuList)
1042 // Remove the submenu from the parent menu.
1043 submenuPairPointer->first->removeAction(submenuPairPointer->second->menuAction());
1046 // Remove all the current toolbar subfolders.
1047 for (QPair<QMenu *, QAction *> *subfolderActionPairPointer : bookmarksToolBarSubfolderActionList)
1049 // Remove the action from the subfolder.
1050 subfolderActionPairPointer->first->removeAction(subfolderActionPairPointer->second);
1053 // Remove all the current toolbar bookmarks.
1054 for (QAction *bookmarkAction : bookmarksToolBarActionList)
1056 // Remove the bookmark.
1057 bookmarksToolBarPointer->removeAction(bookmarkAction);
1060 // Clear the current bookmark lists.
1061 bookmarksMenuActionList.clear();
1062 bookmarksMenuSubmenuList.clear();
1063 bookmarksToolBarActionList.clear();
1064 bookmarksToolBarSubfolderActionList.clear();
1066 // Populate the bookmarks subfolders, beginning with the root folder (`0`);
1067 populateBookmarksMenuSubfolders(0, bookmarksMenuPointer);
1069 // Populate the bookmarks toolbar.
1070 populateBookmarksToolBar();
1072 // Get a handle for the bookmark toolbar layout.
1073 QLayout *bookmarksToolBarLayoutPointer = bookmarksToolBarPointer->layout();
1075 // Get the count of the bookmarks.
1076 int bookmarkCount = bookmarksToolBarLayoutPointer->count();
1078 // Set the layout of each bookmark to be left aligned.
1079 for(int i = 0; i < bookmarkCount; ++i)
1080 bookmarksToolBarLayoutPointer->itemAt(i)->setAlignment(Qt::AlignLeft);
1082 // Update the bookmarked action.
1083 updateBookmarkedAction();
1086 void BrowserWindow::populateBookmarksMenuSubfolders(const double folderId, QMenu *menuPointer)
1088 // Get the folder contents.
1089 QList<BookmarkStruct> *folderContentsListPointer = BookmarksDatabase::getFolderContents(folderId);
1091 // Populate the bookmarks menu and toolbar.
1092 for (BookmarkStruct bookmarkStruct : *folderContentsListPointer)
1094 // Process the item according to the type.
1095 if (bookmarkStruct.isFolder) // This item is a folder.
1097 // Add a submenu to the menu.
1098 QMenu *submenuPointer = menuPointer->addMenu(bookmarkStruct.favoriteIcon, bookmarkStruct.name);
1100 // Add the submenu to the beginning of the list of menus to be deleted on repopulate.
1101 bookmarksMenuSubmenuList.prepend(new QPair<QMenu *, QMenu *>(menuPointer, submenuPointer));
1103 // Populate any subfolders.
1104 populateBookmarksMenuSubfolders(bookmarkStruct.folderId, submenuPointer);
1106 else // This item is a bookmark.
1108 // Add the bookmark to the menu.
1109 QAction *menuBookmarkActionPointer = menuPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name, [=]
1111 // Remove the focus from the URL line edit.
1112 urlLineEditPointer->clearFocus();
1115 tabWidgetPointer->loadUrlFromLineEdit(bookmarkStruct.url);
1119 // Add the actions to the beginning of the list of bookmarks to be deleted on repopulate.
1120 bookmarksMenuActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, menuBookmarkActionPointer));
1124 // Add the extra items at the bottom of the menu.
1125 addFinalBookmarkFolderMenuActions(menuPointer, folderId);
1128 void BrowserWindow::populateBookmarksToolBar()
1130 // Get the root folder contents (which has a folder ID of `0`).
1131 QList<BookmarkStruct> *folderContentsListPointer = BookmarksDatabase::getFolderContents(0);
1133 // Populate the bookmarks toolbar.
1134 for (BookmarkStruct bookmarkStruct : *folderContentsListPointer)
1136 // Process the item according to the type.
1137 if (bookmarkStruct.isFolder) // This item is a folder.
1139 // Add the subfolder action.
1140 QAction *toolBarSubfolderActionPointer = bookmarksToolBarPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name);
1142 // Add the bookmark database ID to the toolbar action.
1143 toolBarSubfolderActionPointer->setData(bookmarkStruct.databaseId);
1145 // Add the action to the beginning of the list of actions to be deleted on repopulate.
1146 bookmarksToolBarActionList.prepend(toolBarSubfolderActionPointer);
1148 // Create a subfolder menu.
1149 QMenu *subfolderMenuPointer = new QMenu();
1151 // Add the menu to the action.
1152 toolBarSubfolderActionPointer->setMenu(subfolderMenuPointer);
1154 // Add the submenu to the toolbar menu list.
1155 bookmarksToolBarMenuList.append(new QPair<QMenu *, const double>(subfolderMenuPointer, bookmarkStruct.folderId));
1157 // Set the popup mode for the menu.
1158 dynamic_cast<QToolButton *>(bookmarksToolBarPointer->widgetForAction(toolBarSubfolderActionPointer))->setPopupMode(QToolButton::InstantPopup);
1160 // Populate the subfolder.
1161 populateBookmarksToolBarSubfolders(bookmarkStruct.folderId, subfolderMenuPointer);
1163 else // This item is a bookmark.
1165 // Add the bookmark to the toolbar.
1166 QAction *toolBarBookmarkActionPointer = bookmarksToolBarPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name, [=]
1168 // Remove the focus from the URL line edit.
1169 urlLineEditPointer->clearFocus();
1172 tabWidgetPointer->loadUrlFromLineEdit(bookmarkStruct.url);
1176 // Add the bookmark database ID to the toolbar action.
1177 toolBarBookmarkActionPointer->setData(bookmarkStruct.databaseId);
1179 // Add the actions to the beginning of the current bookmarks lists.
1180 bookmarksToolBarActionList.prepend(toolBarBookmarkActionPointer);
1184 // 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.
1185 for (QPair<QMenu *, const double> *menuAndFolderIdPairPointer : bookmarksToolBarMenuList)
1187 // Populate the final bookmarks menu entries.
1188 addFinalBookmarkFolderMenuActions(menuAndFolderIdPairPointer->first, menuAndFolderIdPairPointer->second);
1192 void BrowserWindow::populateBookmarksToolBarSubfolders(const double folderId, QMenu *menuPointer)
1194 // Get the folder contents.
1195 QList<BookmarkStruct> *folderContentsListPointer = BookmarksDatabase::getFolderContents(folderId);
1197 // Populate the bookmarks folder.
1198 for (BookmarkStruct bookmarkStruct : *folderContentsListPointer)
1200 // Get the bookmark URL.
1201 QString bookmarkUrl = bookmarkStruct.url;
1203 // Process the item according to the type.
1204 if (bookmarkStruct.isFolder) // This item is a folder.
1206 // Add the subfolder action.
1207 QAction *toolBarSubfolderActionPointer = menuPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name);
1209 // Add the action to the beginning of the list of actions to be deleted on repopulate.
1210 bookmarksToolBarSubfolderActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, toolBarSubfolderActionPointer));
1212 // Create a subfolder menu.
1213 QMenu *subfolderMenuPointer = new QMenu();
1215 // Add the submenu to the action.
1216 toolBarSubfolderActionPointer->setMenu(subfolderMenuPointer);
1218 // Add the submenu to the toolbar menu list.
1219 bookmarksToolBarMenuList.append(new QPair<QMenu *, const double>(subfolderMenuPointer, bookmarkStruct.folderId));
1221 // Populate the subfolder menu.
1222 populateBookmarksToolBarSubfolders(bookmarkStruct.folderId, subfolderMenuPointer);
1224 else // This item is a bookmark.
1226 // Add the bookmark to the folder.
1227 QAction *toolBarBookmarkActionPointer = menuPointer->addAction(bookmarkStruct.favoriteIcon, bookmarkStruct.name, [=]
1229 // Remove the focus from the URL line edit.
1230 urlLineEditPointer->clearFocus();
1233 tabWidgetPointer->loadUrlFromLineEdit(bookmarkUrl);
1237 // Add the bookmark database ID to the toolbar action.
1238 toolBarBookmarkActionPointer->setData(bookmarkStruct.databaseId);
1240 // Add the action to the beginning of the list of actions to be deleted on repopulate.
1241 bookmarksToolBarSubfolderActionList.prepend(new QPair<QMenu *, QAction *>(menuPointer, toolBarBookmarkActionPointer));
1246 void BrowserWindow::refresh() const
1248 // Remove the focus from the URL line edit.
1249 urlLineEditPointer->clearFocus();
1251 // Refresh the web page.
1252 tabWidgetPointer->refresh();
1255 void BrowserWindow::reloadAndBypassCache() const
1257 // Remove the focus from the URL line edit.
1258 urlLineEditPointer->clearFocus();
1260 // Refresh the web page.
1261 tabWidgetPointer->refresh();
1264 void BrowserWindow::showBookmarkContextMenu(const QPoint &point)
1266 // Get the bookmark action.
1267 QAction *bookmarkActionPointer = bookmarksToolBarPointer->actionAt(point);
1269 // Check to see if an action was clicked.
1270 if (bookmarkActionPointer) // An action was clicked.
1272 // Create a bookmark context menu.
1273 QMenu *bookmarkContextMenuPointer = new QMenu();
1275 // Get the database ID from the action.
1276 int databaseId = bookmarkActionPointer->data().toInt();
1278 // Create the menu according to the type.
1279 if (BookmarksDatabase::isFolder(databaseId)) // A folder was clicked.
1281 // Populate the final bookmarks menu entries.
1282 addFinalBookmarkFolderMenuActions(bookmarkContextMenuPointer, BookmarksDatabase::getFolderId(databaseId));
1284 else // A bookmark was clicked.
1286 // Add the open in new tab action to the menu.
1287 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("Open bookmark in new tab context menu entry", "Open in New Tab"), [=]
1289 // Get the bookmark.
1290 BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
1292 // Open the bookmark in a new tab. `true` removes the URL line edit focus, `false` does not load a background tab.
1293 tabWidgetPointer->addTab(true, false, bookmarkStructPointer->url);
1297 // Add the open in background tab action to the menu.
1298 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("tab-new")), i18nc("Open bookmark in background tab context menu entry", "Open in Background Tab"), [=]
1300 // Get the bookmark.
1301 BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
1303 // Open the bookmark in a new tab. `true` removes the URL line edit focus, `true` loads a background tab.
1304 tabWidgetPointer->addTab(true, true, bookmarkStructPointer->url);
1308 // Add the open in new window action to the menu.
1309 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("window-new")), i18nc("Open bookmark in new window context menu entry", "Open in New Window"), [=]
1311 // Get the bookmark.
1312 BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
1314 // Create a new browser window and load the first URL. `false` indicates it is not the first browser window.
1315 BrowserWindow *browserWindowPointer = new BrowserWindow(false, &bookmarkStructPointer->url);
1317 // Show the new browser window.
1318 browserWindowPointer->show();
1323 bookmarkContextMenuPointer->addSeparator();
1325 // Add the edit action to the menu.
1326 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("document-edit")), i18nc("Edit bookmark context menu entry", "Edit"), [=]
1328 // Get the current tab favorite icon.
1329 QIcon currentTabFavoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
1331 // Instantiate an edit bookmark dialog.
1332 QDialog *editBookmarkDialogPointer = new EditBookmarkDialog(databaseId, currentTabFavoriteIcon);
1335 editBookmarkDialogPointer->show();
1337 // Process bookmark events.
1338 connect(editBookmarkDialogPointer, SIGNAL(bookmarkSaved()), this, SLOT(populateBookmarksInAllWindows()));
1342 // Add the copy URL action to the menu.
1343 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-copy")), i18nc("Copy bookmark URL context menu entry", "Copy URL"), [=]
1345 // Get the bookmark.
1346 BookmarkStruct *bookmarkStructPointer = BookmarksDatabase::getBookmark(databaseId);
1348 // Get a handle for the clipboard.
1349 QClipboard *clipboard = QGuiApplication::clipboard();
1351 // Place the URL on the keyboard.
1352 clipboard->setText(bookmarkStructPointer->url);
1357 bookmarkContextMenuPointer->addSeparator();
1359 // Add the delete action to the menu.
1360 bookmarkContextMenuPointer->addAction(QIcon::fromTheme(QLatin1String("edit-delete")), i18nc("Delete bookmark context menu entry", "Delete"), [=]
1362 // Get the parent folder ID.
1363 double parentFolderId = BookmarksDatabase::getParentFolderId(databaseId);
1365 // Delete the bookmark.
1366 BookmarksDatabase::deleteBookmark(databaseId);
1368 // Update the display order of the bookmarks in the parent folder.
1369 BookmarksDatabase::updateFolderContentsDisplayOrder(parentFolderId);
1371 // Repopulate the bookmarks.
1372 populateBookmarksInAllWindows();
1377 // Delete the menu from memory when it is closed.
1378 bookmarkContextMenuPointer->setAttribute(Qt::WA_DeleteOnClose);
1380 // Display the context menu.
1381 bookmarkContextMenuPointer->popup(bookmarksToolBarPointer->mapToGlobal(point));
1383 else // The toolbar background was clicked.
1385 // Temporarily set the context menu policy to the default.
1386 bookmarksToolBarPointer->setContextMenuPolicy(Qt::DefaultContextMenu);
1388 // Create a context menu event with the same position.
1389 QContextMenuEvent *contextMenuEventPointer = new QContextMenuEvent(QContextMenuEvent::Mouse, point);
1391 // Send the context menu event to the toolbar.
1392 QCoreApplication::sendEvent(bookmarksToolBarPointer, contextMenuEventPointer);
1394 // Reset the context menu policy.
1395 bookmarksToolBarPointer->setContextMenuPolicy(Qt::CustomContextMenu);
1399 void BrowserWindow::showCookiesDialog()
1401 // Remove the focus from the URL line edit.
1402 urlLineEditPointer->clearFocus();
1404 // Instantiate the cookie settings dialog.
1405 CookiesDialog *cookiesDialogPointer = new CookiesDialog(tabWidgetPointer->getCookieList());
1408 cookiesDialogPointer->show();
1410 // Connect the dialog signals.
1411 connect(cookiesDialogPointer, SIGNAL(addCookie(QNetworkCookie)), tabWidgetPointer, SLOT(addCookieToStore(QNetworkCookie)));
1412 connect(cookiesDialogPointer, SIGNAL(deleteAllCookies()), tabWidgetPointer, SLOT(deleteAllCookies()));
1413 connect(cookiesDialogPointer, SIGNAL(deleteCookie(QNetworkCookie)), tabWidgetPointer, SLOT(deleteCookieFromStore(QNetworkCookie)));
1416 void BrowserWindow::showDownloadLocationBrowseDialog() const
1418 // Get the current download location.
1419 QString currentDownloadLocation = downloadLocationComboBoxPointer->currentText();
1421 // Resolve the system download directory if specified.
1422 if (currentDownloadLocation == QStringLiteral("System Download Directory"))
1423 currentDownloadLocation = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
1425 // Get the new download location.
1426 QString newDownloadLocation = QFileDialog::getExistingDirectory(configDialogPointer, i18nc("Select download location dialog caption", "Select Download Location"), currentDownloadLocation);
1428 // Populate the download location combo box according to the new download location.
1429 if (newDownloadLocation == QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)) // The default download location was selected.
1431 // Populate the download location with the default text.
1432 downloadLocationComboBoxPointer->setCurrentText("System Download Directory");
1434 else if (newDownloadLocation != QStringLiteral("")) // A different directory was selected.
1436 // Populate the download location.
1437 downloadLocationComboBoxPointer->setCurrentText(newDownloadLocation);
1441 void BrowserWindow::showDomainSettingsDialog() const
1443 // Remove the focus from the URL line edit.
1444 urlLineEditPointer->clearFocus();
1446 // Instantiate the domain settings dialog.
1447 DomainSettingsDialog *domainSettingsDialogPointer = new DomainSettingsDialog();
1449 // Reload the tabs when domain settings are updated.
1450 connect(domainSettingsDialogPointer, SIGNAL(domainSettingsUpdated()), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
1453 domainSettingsDialogPointer->show();
1456 void BrowserWindow::showFindTextActions() const
1458 // Show the find text actions.
1459 findTextLineEditActionPointer->setVisible(true);
1460 findTextLabelActionPointer->setVisible(true);
1461 findNextActionPointer->setVisible(true);
1462 findPreviousActionPointer->setVisible(true);
1463 findCaseSensitiveActionPointer->setVisible(true);
1464 hideFindTextActionPointer->setVisible(true);
1466 // Set the focus on the find line edit.
1467 findTextLineEditPointer->setFocus();
1469 // Select all the text in the find line edit.
1470 findTextLineEditPointer->selectAll();
1473 void BrowserWindow::showProgressBar(const int &progress) const
1475 // Set the progress bar value.
1476 progressBarPointer->setValue(progress);
1478 // Show the progress bar.
1479 progressBarPointer->show();
1482 void BrowserWindow::showSettingsDialog()
1484 // Create the settings widgets.
1485 QWidget *privacySettingsWidgetPointer = new QWidget;
1486 QWidget *generalSettingsWidgetPointer = new QWidget;
1487 QWidget *spellCheckSettingsWidgetPointer = new QWidget;
1489 // Instantiate the settings UI.
1490 Ui::PrivacySettings privacySettingsUi;
1491 Ui::GeneralSettings generalSettingsUi;
1492 Ui::SpellCheckSettings spellCheckSettingsUi;
1494 // Setup the UI to display the settings widgets.
1495 privacySettingsUi.setupUi(privacySettingsWidgetPointer);
1496 generalSettingsUi.setupUi(generalSettingsWidgetPointer);
1497 spellCheckSettingsUi.setupUi(spellCheckSettingsWidgetPointer);
1499 // Get handles for the widgets.
1500 QComboBox *userAgentComboBoxPointer = privacySettingsUi.kcfg_userAgent;
1501 userAgentLabelPointer = privacySettingsUi.userAgentLabel;
1502 QComboBox *searchEngineComboBoxPointer = generalSettingsUi.kcfg_searchEngine;
1503 searchEngineLabelPointer = generalSettingsUi.searchEngineLabel;
1504 downloadLocationComboBoxPointer = generalSettingsUi.kcfg_downloadLocation;
1505 QPushButton *browseButtonPointer = generalSettingsUi.browseButton;
1506 QListWidget *spellCheckListWidgetPointer = spellCheckSettingsUi.spellCheckListWidget;
1508 // Populate the combo box labels.
1509 updateUserAgentLabel(userAgentComboBoxPointer->currentText());
1510 updateSearchEngineLabel(searchEngineComboBoxPointer->currentText());
1512 // Update the labels when the combo boxes change.
1513 connect(userAgentComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateUserAgentLabel(const QString)));
1514 connect(searchEngineComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateSearchEngineLabel(const QString)));
1516 // Connect the download location directory browse button.
1517 connect(browseButtonPointer, SIGNAL(clicked()), this, SLOT(showDownloadLocationBrowseDialog()));
1519 // Create a dictionaries QDir from the `QTWEBENGINE_DICTIONARIES_PATH` environment variable.
1520 QDir dictionariesDir = QDir(qEnvironmentVariable("QTWEBENGINE_DICTIONARIES_PATH"));
1522 // Get a dictionaries string list.
1523 QStringList dictionariesStringList = dictionariesDir.entryList(QStringList(QLatin1String("*.bdic")), QDir::Files | QDir::NoSymLinks);
1525 // Remove the `.bdic` file extensions from the dictionaries list.
1526 dictionariesStringList.replaceInStrings(QLatin1String(".bdic"), QLatin1String(""));
1528 // Get a list of the enabled spell check languages.
1529 QStringList enabledSpellCheckLanguagesList = Settings::spellCheckLanguages();
1531 // Add each dictionary to the spell check list widget.
1532 foreach(QString dictionaryString, dictionariesStringList)
1534 // Create a new list widget item pointer.
1535 QListWidgetItem *listWidgetItemPointer = new QListWidgetItem();
1537 // Create a dictionary check box widget with the name of the dictionary string.
1538 QCheckBox *dictionaryCheckBoxWidget = new QCheckBox(dictionaryString);
1540 // Check the language if it is currently enabled.
1541 if (enabledSpellCheckLanguagesList.contains(dictionaryString))
1542 dictionaryCheckBoxWidget->setCheckState(Qt::Checked);
1544 dictionaryCheckBoxWidget->setCheckState(Qt::Unchecked);
1546 // Add the list widget item to the spell check list widget.
1547 spellCheckListWidgetPointer->addItem(listWidgetItemPointer);
1549 // Set the list widget item check box widget.
1550 spellCheckListWidgetPointer->setItemWidget(listWidgetItemPointer, dictionaryCheckBoxWidget);
1553 // Get a handle for the KConfig skeleton.
1554 KConfigSkeleton *kConfigSkeletonPointer = Settings::self();
1556 // Instantiate a settings config dialog from the settings.kcfg file.
1557 configDialogPointer = new KConfigDialog(this, QLatin1String("settings"), kConfigSkeletonPointer);
1559 // Create a settings icon string.
1560 QString settingsIconString;
1562 // Get a settings icon that matches the theme.
1563 if (QIcon::hasThemeIcon("breeze-settings"))
1565 // KDE uses breeze-settings.
1566 settingsIconString = QLatin1String("breeze-settings");
1570 // Gnome uses preferences-desktop.
1571 settingsIconString = QLatin1String("preferences-desktop");
1574 // Add the settings widgets as config dialog pages.
1575 configDialogPointer->addPage(privacySettingsWidgetPointer, i18nc("Settings tab title", "Privacy"), QLatin1String("privacybrowser"));
1576 configDialogPointer->addPage(generalSettingsWidgetPointer, i18nc("Settings tab title", "General"), settingsIconString);
1577 configDialogPointer->addPage(spellCheckSettingsWidgetPointer, i18nc("Settings tab title", "Spell Check"), QLatin1String("tools-check-spelling"));
1579 // Get handles for the buttons.
1580 QPushButton *applyButtonPointer = configDialogPointer->button(QDialogButtonBox::Apply);
1581 QPushButton *okButtonPointer = configDialogPointer->button(QDialogButtonBox::Ok);
1583 // Prevent interaction with the parent window while the dialog is open.
1584 configDialogPointer->setWindowModality(Qt::WindowModal);
1587 configDialogPointer->show();
1589 // TODO. KConfigDialog does not respect expanding size policies. <https://redmine.stoutner.com/issues/823>
1590 //configDialogPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1591 //privacySettingsWidgetPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1592 //generalSettingsWidgetPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1593 //configDialogPointer->adjustSize();
1595 // Expand the config dialog.
1596 configDialogPointer->resize(1000, 500);
1598 // Create a save spell check languages lambda.
1599 auto saveSpellCheckLanguages = [spellCheckListWidgetPointer, kConfigSkeletonPointer, this] ()
1601 // Create a list of enabled languages.
1602 QStringList newSpellCheckLanguages = QStringList();
1604 // Get a count of all the languages.
1605 int allLanguagesCount = spellCheckListWidgetPointer->count();
1607 // Get a list of all the checked languages.
1608 for (int i = 0; i < allLanguagesCount; ++i) {
1609 // Get the language item.
1610 QListWidgetItem *languageItemPointer = spellCheckListWidgetPointer->item(i);
1612 // Get the language check box.
1613 QCheckBox *languageCheckBoxPointer = qobject_cast<QCheckBox*>(spellCheckListWidgetPointer->itemWidget(languageItemPointer));
1615 // Add the item to the enabled languages if it is checked.
1616 if (languageCheckBoxPointer->checkState() == Qt::Checked)
1619 QString languageString = languageCheckBoxPointer->text();
1621 // Remove all instances of `&`, which may have been added automatically when creating the check box text.
1622 languageString.remove(QChar('&'));
1624 // Add the language string to the list.
1625 newSpellCheckLanguages.append(languageString);
1629 // Update the spell check languages.
1630 if (Settings::spellCheckLanguages() != newSpellCheckLanguages)
1632 // Update the spell check languages.
1633 Settings::setSpellCheckLanguages(newSpellCheckLanguages);
1635 // Write the settings to disk.
1636 kConfigSkeletonPointer->save();
1639 // Apply the spell check languages.
1640 tabWidgetPointer->applySpellCheckLanguages();
1644 connect(applyButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages);
1645 connect(okButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages);
1647 // Apply the settings handled by KConfig.
1648 connect(configDialogPointer, SIGNAL(settingsChanged(QString)), tabWidgetPointer, SLOT(applyApplicationSettings()));
1649 connect(configDialogPointer, SIGNAL(settingsChanged(QString)), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
1652 QSize BrowserWindow::sizeHint() const
1654 // Return the default window size.
1655 return QSize(1500, 1200);
1658 void BrowserWindow::toggleBookmark()
1660 // Remove the focus from the URL line edit, which will have been focused when the user clicked on the bookmarked icon.
1661 urlLineEditPointer->clearFocus();
1663 // Create or delete the bookmark
1664 if (bookmarkedActionPointer->isChecked()) // The user checked the toggle. Create a bookmark.
1666 // Create a bookmark struct.
1667 BookmarkStruct *bookmarkStructPointer = new BookmarkStruct;
1669 // Populate the bookmark struct.
1670 bookmarkStructPointer->name = tabWidgetPointer->getCurrentTabTitle();
1671 bookmarkStructPointer->url = tabWidgetPointer->getCurrentTabUrl();
1672 bookmarkStructPointer->parentFolderId = 0;
1673 bookmarkStructPointer->favoriteIcon = tabWidgetPointer->getCurrentTabFavoritIcon();
1675 // Add the bookmark.
1676 BookmarksDatabase::addBookmark(bookmarkStructPointer);
1678 else // The user unchecked the toggle. Delete all related bookmarks.
1680 // Delete the bookmarks.
1681 BookmarksDatabase::deleteBookmarks(urlLineEditPointer->text());
1686 // Repopulate the bookmarks.
1687 populateBookmarksInAllWindows();
1690 void BrowserWindow::toggleDomStorage() const
1692 // Remove the focus from the URL line edit.
1693 urlLineEditPointer->clearFocus();
1695 // Toggle DOM storage.
1696 tabWidgetPointer->toggleDomStorage();
1699 void BrowserWindow::toggleFindCaseSensitive() const
1701 // Get the current find string.
1702 const QString findString = findTextLineEditPointer->text();
1704 // Toggle find case sensitive.
1705 tabWidgetPointer->toggleFindCaseSensitive(findString);
1708 void BrowserWindow::toggleJavaScript() const
1710 // Remove the focus from the URL line edit.
1711 urlLineEditPointer->clearFocus();
1713 // Toggle JavaScript.
1714 tabWidgetPointer->toggleJavaScript();
1717 void BrowserWindow::toggleLocalStorage() const
1719 // Remove the focus from the URL line edit.
1720 urlLineEditPointer->clearFocus();
1722 // Toggle local storage.
1723 tabWidgetPointer->toggleLocalStorage();
1726 void BrowserWindow::toggleFullScreen()
1728 // Toggle the full screen status.
1729 fullScreenRequested(fullScreenActionPointer->isChecked());
1732 void BrowserWindow::toggleViewSource() const
1734 // Get the current URL.
1735 QString url = urlLineEditPointer->text();
1738 if (url.startsWith(QLatin1String("view-source:"))) // The source is currently being viewed.
1740 // Remove `view-source:` from the URL.
1741 url = url.remove(0, 12);
1743 else // The source is not currently being viewed.
1745 // Prepend `view-source:` from the URL.
1746 url = url.prepend(QLatin1String("view-source:"));
1750 loadUrlFromLineEdit(url);
1753 void BrowserWindow::toggleViewBookmarksToolBar()
1755 // Store the current status of the bookmarks toolbar, which is used when exiting full screen browsing.
1756 bookmarksToolBarIsVisible = viewBookmarksToolBarActionPointer->isChecked();
1758 // Update the visibility of the bookmarks toolbar.
1759 bookmarksToolBarPointer->setVisible(bookmarksToolBarIsVisible);
1762 void BrowserWindow::toggleViewSourceInNewTab() const
1764 // Get the current URL.
1765 QString url = urlLineEditPointer->text();
1768 if (url.startsWith(QLatin1String("view-source:"))) // The source is currently being viewed.
1770 // Remove `view-source:` from the URL.
1771 url = url.remove(0, 12);
1773 else // The source is not currently being viewed.
1775 // Prepend `view-source:` from the URL.
1776 url = url.prepend(QLatin1String("view-source:"));
1779 // Add the new tab. `true` removes the URL line edit focus, `false` does not open a background tab.
1780 tabWidgetPointer->addTab(true, false, url);
1783 void BrowserWindow::updateBookmarkedAction() const
1785 // Update the bookmarked action to reflect the current state.
1786 if (bookmarkedActionPointer->isChecked())
1787 bookmarkedActionPointer->setIcon(QIcon::fromTheme("starred-symbolic"));
1789 bookmarkedActionPointer->setIcon(QIcon::fromTheme("non-starred-symbolic"));
1792 void BrowserWindow::updateCookiesAction(const int numberOfCookies) const
1794 // Update the action text.
1795 cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", numberOfCookies));
1798 void BrowserWindow::updateDefaultZoomFactor(const double newDefaultZoomFactor)
1800 // Store the new default zoom factor.
1801 defaultZoomFactor = newDefaultZoomFactor;
1804 void BrowserWindow::updateDomStorageAction(const bool &isEnabled) const
1806 // Set the action checked status.
1807 domStorageActionPointer->setChecked(isEnabled);
1810 void BrowserWindow::updateDomainSettingsIndicator(const bool status)
1812 // Set the domain palette according to the status.
1814 urlLineEditPointer->setPalette(positiveBackgroundPalette);
1816 urlLineEditPointer->setPalette(normalBackgroundPalette);
1819 void BrowserWindow::updateFindText(const QString &text, const bool findCaseSensitive) const
1822 findTextLineEditPointer->setText(text);
1824 // Set the find case sensitive action checked status.
1825 findCaseSensitiveActionPointer->setChecked(findCaseSensitive);
1828 void BrowserWindow::updateFindTextResults(const QWebEngineFindTextResult &findTextResult) const
1830 // Update the find text label.
1831 findTextLabelPointer->setText(QStringLiteral(" %1/%2 ").arg(findTextResult.activeMatch()).arg(findTextResult.numberOfMatches()));
1833 // Set the background color according to the find status.
1834 if (findTextLineEditPointer->text().isEmpty())
1835 findTextLineEditPointer->setPalette(normalBackgroundPalette);
1836 else if (findTextResult.numberOfMatches() == 0)
1837 findTextLineEditPointer->setPalette(negativeBackgroundPalette);
1839 findTextLineEditPointer->setPalette(positiveBackgroundPalette);
1842 void BrowserWindow::updateJavaScriptAction(const bool &isEnabled)
1844 // Update the JavaScript status.
1845 javaScriptEnabled = isEnabled;
1847 // Set the icon according to the status.
1848 if (javaScriptEnabled)
1849 javaScriptActionPointer->setIcon(QIcon(QLatin1String(":/icons/javascript-warning.svg")));
1851 javaScriptActionPointer->setIcon(QIcon(QLatin1String(":/icons/privacy-mode.svg")));
1853 // Set the action checked status.
1854 javaScriptActionPointer->setChecked(javaScriptEnabled);
1856 // Update the status of the DOM storage action.
1857 domStorageActionPointer->setEnabled(javaScriptEnabled & localStorageEnabled);
1860 void BrowserWindow::updateLocalStorageAction(const bool &isEnabled)
1862 // Update the local storage status.
1863 localStorageEnabled = isEnabled;
1865 // 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.
1866 if (localStorageEnabled)
1867 localStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("disk-quota-high"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/actions/document-save-as.png"))));
1869 localStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("disk-quota"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/apps/kfm.png"))));
1871 // Set the action checked status.
1872 localStorageActionPointer->setChecked(localStorageEnabled);
1874 // Update the status of the DOM storage action.
1875 domStorageActionPointer->setEnabled(localStorageEnabled & javaScriptEnabled);
1878 void BrowserWindow::updateSearchEngineActions(const QString &searchEngine, const bool &updateCustomSearchEngineStatus)
1880 // Initialize the custom search engine flag.
1881 bool customSearchEngine = false;
1883 if (searchEngine == "Mojeek") // Mojeek.
1885 // Check the Mojeek user agent action.
1886 searchEngineMojeekActionPointer->setChecked(true);
1888 // Update the search engine menu action icon.
1889 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1891 // Update the search engine menu action text.
1892 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Mojeek"));
1894 else if (searchEngine == "Monocles") // Monocles.
1896 // Check the Monocles user agent action.
1897 searchEngineMonoclesActionPointer->setChecked(true);
1899 // Update the search engine menu action icon.
1900 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1902 // Update the search engine menu action text.
1903 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Monocles"));
1905 else if (searchEngine == "MetaGer") // MetaGer.
1907 // Check the MetaGer user agent action.
1908 searchEngineMetagerActionPointer->setChecked(true);
1910 // Update the search engine menu action icon.
1911 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1913 // Update the search engine menu action text.
1914 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - MetaGer"));
1916 else if (searchEngine == "Google") // Google.
1918 // Check the Google user agent action.
1919 searchEngineGoogleActionPointer->setChecked(true);
1921 // Update the search engine menu action icon.
1922 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-google"), QIcon::fromTheme(QLatin1String("edit-find"))));
1924 // Update the search engine menu action text.
1925 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Google"));
1927 else if (searchEngine == "Bing") // Bing.
1929 // Check the Bing user agent action.
1930 searchEngineBingActionPointer->setChecked(true);
1932 // Update the search engine menu action icon.
1933 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1935 // Update the search engine menu action text.
1936 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Bing"));
1938 else if (searchEngine == "Yahoo") // Yahoo.
1940 // Check the Yahoo user agent action.
1941 searchEngineYahooActionPointer->setChecked(true);
1943 // Update the search engine menu action icon.
1944 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-yahoo"), QIcon::fromTheme(QLatin1String("edit-find"))));
1946 // Update the search engine menu action text.
1947 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Yahoo"));
1949 else // Custom search engine.
1951 // Check the user agent.
1952 searchEngineCustomActionPointer->setChecked(true);
1954 // Update the search engine menu action icon.
1955 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1957 // Update the search engine menu action text.
1958 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Custom"));
1960 // Set the custom search engine text.
1961 searchEngineCustomActionPointer->setText(searchEngine);
1963 // Set the custom search engine flag.
1964 customSearchEngine = true;
1967 // Update the custom search engine enabled boolean.
1968 if (updateCustomSearchEngineStatus)
1969 customSearchEngineEnabled = customSearchEngine;
1971 // Format the custom search engine.
1972 if (customSearchEngineEnabled)
1974 // Enable the custom search engine.
1975 searchEngineCustomActionPointer->setEnabled(true);
1979 // Disable the custom search engine.
1980 searchEngineCustomActionPointer->setEnabled(false);
1982 // Reset the custom search engine text.
1983 searchEngineCustomActionPointer->setText(i18nc("@action", "Custom"));
1987 void BrowserWindow::updateSearchEngineLabel(const QString &searchEngineString) const
1989 // Update the search engine label.
1990 searchEngineLabelPointer->setText(SearchEngineHelper::getSearchUrl(searchEngineString));
1993 void BrowserWindow::updateUrlLineEdit(const QUrl &newUrl)
1995 // Get the new URL string in encoded form, which displays punycode.
1996 QString newUrlString = newUrl.toEncoded();
1998 // Update the view source actions.
1999 if (newUrlString.startsWith(QLatin1String("view-source:"))) // The source is currently being viewed.
2001 // Mark the view source checkbox.
2002 viewSourceActionPointer->setChecked(true);
2004 // Update the view in new tab action text.
2005 viewSourceInNewTabActionPointer->setText(i18nc("View rendered website in new tab action", "View Rendered Website in New Tab"));
2007 else // The source is not currently being viewed.
2009 // Unmark the view source checkbox.
2010 viewSourceActionPointer->setChecked(false);
2012 // Update the view in new tab action text.
2013 viewSourceInNewTabActionPointer->setText(i18nc("View source in new tab action", "View Source in New Tab"));
2016 // Update the URL line edit if it does not have focus.
2017 if (!urlLineEditPointer->hasFocus())
2019 // Update the URL line edit.
2020 urlLineEditPointer->setText(newUrlString);
2022 // Set the bookmarked action status.
2023 bookmarkedActionPointer->setChecked(BookmarksDatabase::isBookmarked(newUrlString));
2025 // Update the bookmarked action.
2026 updateBookmarkedAction();
2028 // Set the focus if the new URL is blank.
2029 if (newUrlString == QStringLiteral(""))
2030 urlLineEditPointer->setFocus();
2033 // Store the current URL.
2034 currentUrl = newUrl;
2037 void BrowserWindow::updateUserAgentActions(const QString &userAgent, const bool &updateCustomUserAgentStatus)
2039 // Initialize the custom user agent flag.
2040 bool customUserAgent = false;
2042 // Check the indicated on-the-fly user agent.
2043 if (userAgent == UserAgentHelper::PRIVACY_BROWSER_USER_AGENT) // Privacy Browser.
2045 // Check the Privacy Browser user agent action.
2046 userAgentPrivacyBrowserActionPointer->setChecked(true);
2048 // Update the user agent menu action icon.
2049 userAgentMenuActionPointer->setIcon(QIcon(":/icons/privacy-mode.svg"));
2051 // Update the user agent menu action text.
2052 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Privacy Browser"));
2054 else if (userAgent == TabWidget::webEngineDefaultUserAgent) // WebEngine default.
2056 // check the WebEngine default user agent action.
2057 userAgentWebEngineDefaultActionPointer->setChecked(true);
2059 // Update the user agent menu action icon.
2060 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("qtlogo"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2062 // Update the user agent menu action text.
2063 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - WebEngine default"));
2065 else if (userAgent == UserAgentHelper::FIREFOX_LINUX_USER_AGENT) // Firefox on Linux.
2067 // Check the Firefox on Linux user agent action.
2068 userAgentFirefoxLinuxActionPointer->setChecked(true);
2070 // Update the user agent menu action icon.
2071 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2073 // Update the user agent menu action text.
2074 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Firefox on Linux"));
2076 else if (userAgent == UserAgentHelper::CHROMIUM_LINUX_USER_AGENT) // Chromium on Linux.
2078 // Check the Chromium on Linux user agent action.
2079 userAgentChromiumLinuxActionPointer->setChecked(true);
2081 // Update the user agent menu action icon.
2082 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2084 // Update the user agent menu action text.
2085 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Chromium on Linux"));
2087 else if (userAgent == UserAgentHelper::FIREFOX_WINDOWS_USER_AGENT) // Firefox on Windows.
2089 // Check the Firefox on Windows user agent action.
2090 userAgentFirefoxWindowsActionPointer->setChecked(true);
2092 // Update the user agent menu action icon.
2093 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2095 // Update the user agent menu action text.
2096 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Firefox on Windows"));
2098 else if (userAgent == UserAgentHelper::CHROME_WINDOWS_USER_AGENT) // Chrome on Windows.
2100 // Check the Chrome on Windows user agent action.
2101 userAgentChromeWindowsActionPointer->setChecked(true);
2103 // Update the user agent menu action icon.
2104 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
2106 // Update the user agent menu action text.
2107 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Chrome on Windows"));
2109 else if (userAgent == UserAgentHelper::EDGE_WINDOWS_USER_AGENT) // Edge on Windows.
2111 // Check the Edge on Windows user agent action.
2112 userAgentEdgeWindowsActionPointer->setChecked(true);
2114 // Update the user agent menu action icon.
2115 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
2117 // Update the user agent menu action text.
2118 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Edge on Windows"));
2120 else if (userAgent == UserAgentHelper::SAFARI_MACOS_USER_AGENT) // Safari on macOS.
2122 // Check the Safari on macOS user agent action.
2123 userAgentSafariMacosActionPointer->setChecked(true);
2125 // Update the user agent menu action icon.
2126 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
2128 // Update the user agent menu action text.
2129 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Safari on macOS"));
2131 else // Custom user agent.
2133 // Check the user agent.
2134 userAgentCustomActionPointer->setChecked(true);
2136 // Update the user agent menu action icon.
2137 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
2139 // Update the user agent menu action text.
2140 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Custom"));
2142 // Set the custom user agent text.
2143 userAgentCustomActionPointer->setText(userAgent);
2145 // Set the custom user agent flag.
2146 customUserAgent = true;
2149 // Update the custom user agent enabled boolean.
2150 // 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.
2151 if (updateCustomUserAgentStatus)
2152 customUserAgentEnabled = customUserAgent;
2155 // Format the custom user agent.
2156 if (customUserAgentEnabled)
2158 // Enable the custom user agent.
2159 userAgentCustomActionPointer->setEnabled(true);
2163 // Disable the custom user agent.
2164 userAgentCustomActionPointer->setEnabled(false);
2166 // Reset the custom user agent text.
2167 userAgentCustomActionPointer->setText(i18nc("@action", "Custom"));
2171 void BrowserWindow::updateUserAgentLabel(const QString &userAgentDatabaseName) const
2173 // Update the user agent label.
2174 userAgentLabelPointer->setText(UserAgentHelper::getUserAgentFromDatabaseName(userAgentDatabaseName));
2177 void BrowserWindow::updateViewBookmarksToolBarCheckbox(const bool visible)
2179 // Update the view bookmarks toolbar checkbox.
2180 viewBookmarksToolBarActionPointer->setChecked(visible);
2182 // Initialize the bookmarks toolbar visibility tracker if Privacy Browser has just launched.
2183 if (bookmarksToolBarUninitialized)
2185 // Set the initialization flag.
2186 bookmarksToolBarUninitialized = false;
2188 // Store the current status of the bookmarks toolbar, which is used when exiting full screen browsing.
2189 bookmarksToolBarIsVisible = visible;
2193 void BrowserWindow::updateWindowTitle(const QString &title)
2195 // Update the window title.
2196 setWindowTitle(title);
2199 void BrowserWindow::updateZoomActions(const double &zoomFactor)
2201 // Set the current zoom factor.
2202 currentZoomFactor = zoomFactor;
2204 // Set the status of the default zoom action.
2205 zoomDefaultActionPointer->setEnabled(currentZoomFactor != defaultZoomFactor);
2207 // Set the status of the zoom in action and button.
2208 zoomInActionPointer->setEnabled(currentZoomFactor <= 4.99);
2209 zoomPlusButtonPointer->setEnabled(currentZoomFactor <= 4.99);
2211 // Set the status of the zoom out action and button.
2212 zoomMinusButtonPointer->setEnabled(currentZoomFactor > 0.25);
2213 zoomOutActionPointer->setEnabled(currentZoomFactor > 0.25);
2216 // 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.
2217 zoomFactorActionPointer->setText(ki18nc("The zoom factor action", "Zoom Factor - %1").subs(zoomFactor, 0, '0', 2).toString());
2219 // Update the status bar zoom factor label.
2220 currentZoomButtonPointer->setText(ki18nc("The status bar zoom, which is just the formatted zoom factor", "%1").subs(zoomFactor, 0, '0', 2).toString());
2223 void BrowserWindow::zoomDefault()
2225 // Set the new zoom factor.
2226 tabWidgetPointer->applyOnTheFlyZoomFactor(defaultZoomFactor);
2228 // Update the on-the-fly action text.
2229 updateZoomActions(defaultZoomFactor);