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 "dialogs/CookiesDialog.h"
27 #include "dialogs/DomainSettingsDialog.h"
28 #include "helpers/SearchEngineHelper.h"
29 #include "helpers/UserAgentHelper.h"
31 // KDE Frameworks headers.
32 #include <KActionCollection>
33 #include <KColorScheme>
36 // Qt toolkit headers.
37 #include <QFileDialog>
38 #include <QInputDialog>
39 #include <QNetworkCookie>
43 #include <QWebEngineFindTextResult>
45 // Construct the class.
46 BrowserWindow::BrowserWindow(bool firstWindow) : KXmlGuiWindow()
48 // Initialize the variables.
49 javaScriptEnabled = false;
50 localStorageEnabled = false;
52 // Instantiate the privacy tab widget pointer.
53 tabWidgetPointer = new TabWidget(this);
55 // Set the privacy tab widget as the central widget.
56 setCentralWidget(tabWidgetPointer);
58 // Get a handle for the action collection.
59 KActionCollection *actionCollectionPointer = this->actionCollection();
61 // Add the standard actions.
62 KStandardAction::print(tabWidgetPointer, SLOT(print()), actionCollectionPointer);
63 QAction *printPreviewActionPointer = KStandardAction::printPreview(tabWidgetPointer, SLOT(printPreview()), actionCollectionPointer);
64 KStandardAction::quit(qApp, SLOT(closeAllWindows()), actionCollectionPointer);
65 KStandardAction::redisplay(this, SLOT(refresh()), actionCollectionPointer);
66 fullScreenActionPointer = KStandardAction::fullScreen(this, SLOT(toggleFullScreen()), this, actionCollectionPointer);
67 QAction *backActionPointer = KStandardAction::back(this, SLOT(back()), actionCollectionPointer);
68 QAction *forwardActionPointer = KStandardAction::forward(this, SLOT(forward()), actionCollectionPointer);
69 KStandardAction::home(this, SLOT(home()), actionCollectionPointer);
70 KStandardAction::preferences(this, SLOT(showSettingsDialog()), actionCollectionPointer);
71 KStandardAction::find(this, SLOT(showFindTextActions()), actionCollectionPointer);
72 findNextActionPointer = KStandardAction::findNext(this, SLOT(findNext()), actionCollectionPointer);
73 findPreviousActionPointer = KStandardAction::findPrev(this, SLOT(findPrevious()), actionCollectionPointer);
75 // Add the custom actions.
76 QAction *newTabActionPointer = actionCollectionPointer->addAction(QLatin1String("new_tab"));
77 QAction *newWindowActionPointer = actionCollectionPointer->addAction(QLatin1String("new_window"));
78 QAction *reloadAndBypassCacheActionPointer = actionCollectionPointer->addAction(QLatin1String("reload_and_bypass_cache"));
79 userAgentPrivacyBrowserActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_privacy_browser"));
80 userAgentWebEngineDefaultActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_webengine_default"));
81 userAgentFirefoxLinuxActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_firefox_linux"));
82 userAgentChromiumLinuxActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_chromium_linux"));
83 userAgentFirefoxWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_firefox_windows"));
84 userAgentChromeWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_chrome_windows"));
85 userAgentEdgeWindowsActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_edge_windows"));
86 userAgentSafariMacosActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_safari_macos"));
87 userAgentCustomActionPointer = actionCollectionPointer->addAction(QLatin1String("user_agent_custom"));
88 zoomFactorActionPointer = actionCollectionPointer->addAction(QLatin1String("zoom_factor"));
89 searchEngineMojeekActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_mojeek"));
90 searchEngineMonoclesActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_monocles"));
91 searchEngineMetagerActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_metager"));
92 searchEngineGoogleActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_google"));
93 searchEngineBingActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_bing"));
94 searchEngineYahooActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_yahoo"));
95 searchEngineCustomActionPointer = actionCollectionPointer->addAction(QLatin1String("search_engine_custom"));
96 QAction *domainSettingsActionPointer = actionCollectionPointer->addAction(QLatin1String("domain_settings"));
97 cookiesActionPointer = actionCollectionPointer->addAction(QLatin1String("cookies"));
98 javaScriptActionPointer = actionCollectionPointer->addAction(QLatin1String("javascript"));
99 localStorageActionPointer = actionCollectionPointer->addAction(QLatin1String("local_storage"));
100 domStorageActionPointer = actionCollectionPointer->addAction(QLatin1String("dom_storage"));
101 findCaseSensitiveActionPointer = actionCollectionPointer->addAction(QLatin1String("find_case_sensitive"));
102 hideFindTextActionPointer = actionCollectionPointer->addAction(QLatin1String("hide_find_actions"));
104 // Create the action groups
105 QActionGroup *userAgentActionGroupPointer = new QActionGroup(this);
106 QActionGroup *searchEngineActionGroupPointer = new QActionGroup(this);
108 // Add the actions to the groups.
109 userAgentActionGroupPointer->addAction(userAgentPrivacyBrowserActionPointer);
110 userAgentActionGroupPointer->addAction(userAgentWebEngineDefaultActionPointer);
111 userAgentActionGroupPointer->addAction(userAgentFirefoxLinuxActionPointer);
112 userAgentActionGroupPointer->addAction(userAgentChromiumLinuxActionPointer);
113 userAgentActionGroupPointer->addAction(userAgentFirefoxWindowsActionPointer);
114 userAgentActionGroupPointer->addAction(userAgentChromeWindowsActionPointer);
115 userAgentActionGroupPointer->addAction(userAgentEdgeWindowsActionPointer);
116 userAgentActionGroupPointer->addAction(userAgentSafariMacosActionPointer);
117 userAgentActionGroupPointer->addAction(userAgentCustomActionPointer);
118 searchEngineActionGroupPointer->addAction(searchEngineMojeekActionPointer);
119 searchEngineActionGroupPointer->addAction(searchEngineMonoclesActionPointer);
120 searchEngineActionGroupPointer->addAction(searchEngineMetagerActionPointer);
121 searchEngineActionGroupPointer->addAction(searchEngineGoogleActionPointer);
122 searchEngineActionGroupPointer->addAction(searchEngineBingActionPointer);
123 searchEngineActionGroupPointer->addAction(searchEngineYahooActionPointer);
124 searchEngineActionGroupPointer->addAction(searchEngineCustomActionPointer);
126 // Set some actions to be checkable.
127 javaScriptActionPointer->setCheckable(true);
128 localStorageActionPointer->setCheckable(true);
129 domStorageActionPointer->setCheckable(true);
130 findCaseSensitiveActionPointer->setCheckable(true);
131 userAgentPrivacyBrowserActionPointer->setCheckable(true);
132 userAgentWebEngineDefaultActionPointer->setCheckable(true);
133 userAgentFirefoxLinuxActionPointer->setCheckable(true);
134 userAgentChromiumLinuxActionPointer->setCheckable(true);
135 userAgentFirefoxWindowsActionPointer->setCheckable(true);
136 userAgentChromeWindowsActionPointer->setCheckable(true);
137 userAgentEdgeWindowsActionPointer->setCheckable(true);
138 userAgentSafariMacosActionPointer->setCheckable(true);
139 userAgentCustomActionPointer->setCheckable(true);
140 searchEngineMojeekActionPointer->setCheckable(true);
141 searchEngineMonoclesActionPointer->setCheckable(true);
142 searchEngineMetagerActionPointer->setCheckable(true);
143 searchEngineGoogleActionPointer->setCheckable(true);
144 searchEngineBingActionPointer->setCheckable(true);
145 searchEngineYahooActionPointer->setCheckable(true);
146 searchEngineCustomActionPointer->setCheckable(true);
148 // Instantiate the user agent helper.
149 UserAgentHelper *userAgentHelperPointer = new UserAgentHelper();
151 // Set the action text.
152 newTabActionPointer->setText(i18nc("New tab action", "New Tab"));
153 newWindowActionPointer->setText(i18nc("New window action", "New Window"));
154 reloadAndBypassCacheActionPointer->setText(i18nc("Reload and bypass cache action", "Reload and Bypass Cache"));
155 userAgentPrivacyBrowserActionPointer->setText(userAgentHelperPointer->PRIVACY_BROWSER_TRANSLATED);
156 userAgentWebEngineDefaultActionPointer->setText(userAgentHelperPointer->WEB_ENGINE_DEFAULT_TRANSLATED);
157 userAgentFirefoxLinuxActionPointer->setText(userAgentHelperPointer->FIREFOX_LINUX_TRANSLATED);
158 userAgentChromiumLinuxActionPointer->setText(userAgentHelperPointer->CHROMIUM_LINUX_TRANSLATED);
159 userAgentFirefoxWindowsActionPointer->setText(userAgentHelperPointer->FIREFOX_WINDOWS_TRANSLATED);
160 userAgentChromeWindowsActionPointer->setText(userAgentHelperPointer->CHROME_WINDOWS_TRANSLATED);
161 userAgentEdgeWindowsActionPointer->setText(userAgentHelperPointer->EDGE_WINDOWS_TRANSLATED);
162 userAgentSafariMacosActionPointer->setText(userAgentHelperPointer->SAFARI_MACOS_TRANSLATED);
163 searchEngineMojeekActionPointer->setText(i18nc("Search engine", "Mojeek"));
164 searchEngineMonoclesActionPointer->setText(i18nc("Search engine", "Monocles"));
165 searchEngineMetagerActionPointer->setText(i18nc("Search engine", "MetaGer"));
166 searchEngineGoogleActionPointer->setText(i18nc("Search engine", "Google"));
167 searchEngineBingActionPointer->setText(i18nc("Search engine", "Bing"));
168 searchEngineYahooActionPointer->setText(i18nc("Search engine", "Yahoo"));
169 domainSettingsActionPointer->setText(i18nc("Domain Settings action", "Domain Settings"));
170 cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", 0));
171 javaScriptActionPointer->setText(i18nc("JavaScript action", "JavaScript"));
172 localStorageActionPointer->setText(i18nc("The Local Storage action", "Local Storage"));
173 domStorageActionPointer->setText(i18nc("DOM Storage action", "DOM Storage"));
174 findCaseSensitiveActionPointer->setText(i18nc("Find Case Sensitive action", "Find Case Sensitive"));
175 hideFindTextActionPointer->setText(i18nc("Hide Find Text action", "Hide Find Text"));
177 // Set the action icons. Gnome doesn't contain some of the icons that KDE has.
178 // The toolbar icons don't pick up unless the size is explicit, probably because the toolbar ends up being an intermediate size.
179 newTabActionPointer->setIcon(QIcon::fromTheme(QLatin1String("tab-new")));
180 newWindowActionPointer->setIcon(QIcon::fromTheme(QLatin1String("window-new")));
181 reloadAndBypassCacheActionPointer->setIcon(QIcon::fromTheme(QLatin1String("view-refresh")));
182 userAgentPrivacyBrowserActionPointer->setIcon(QIcon(":/icons/privacy-mode.svg"));
183 userAgentWebEngineDefaultActionPointer->setIcon(QIcon::fromTheme(QLatin1String("qtlogo"), QIcon::fromTheme(QLatin1String("user-group-properties"),
184 QIcon::fromTheme(QLatin1String("contact-new")))));
185 userAgentFirefoxLinuxActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"),
186 QIcon::fromTheme(QLatin1String("contact-new")))));
187 userAgentChromiumLinuxActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"),
188 QIcon::fromTheme(QLatin1String("contact-new")))));
189 userAgentFirefoxWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"),
190 QIcon::fromTheme(QLatin1String("contact-new")))));
191 userAgentChromeWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"),
192 QIcon::fromTheme(QLatin1String("contact-new")))));
193 userAgentEdgeWindowsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
194 userAgentSafariMacosActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
195 userAgentCustomActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
196 searchEngineMojeekActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
197 searchEngineMonoclesActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
198 searchEngineMetagerActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
199 searchEngineGoogleActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-google"), QIcon::fromTheme(QLatin1String("edit-find"))));
200 searchEngineBingActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
201 searchEngineYahooActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-yahoo"), QIcon::fromTheme(QLatin1String("edit-find"))));
202 searchEngineCustomActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
203 zoomFactorActionPointer->setIcon(QIcon::fromTheme(QLatin1String("zoom-fit-best")));
204 domainSettingsActionPointer->setIcon(QIcon::fromTheme(QLatin1String("settings-configure"), QIcon::fromTheme(QLatin1String("preferences-desktop"))));
205 cookiesActionPointer->setIcon(QIcon::fromTheme(QLatin1String("preferences-web-browser-cookies"), QIcon::fromTheme(QLatin1String("appointment-new"))));
206 domStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("code-class"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/actions/gtk-unindent-ltr.png"))));
207 findCaseSensitiveActionPointer->setIcon(QIcon::fromTheme(QLatin1String("format-text-lowercase"), QIcon::fromTheme(QLatin1String("/usr/share/icons/gnome/32x32/apps/fonts.png"))));
208 hideFindTextActionPointer->setIcon(QIcon::fromTheme(QLatin1String("window-close-symbolic")));
210 // Create the key sequences.
211 QKeySequence ctrlTKeySequence = QKeySequence(i18nc("The open new tab key sequence.", "Ctrl+T"));
212 QKeySequence ctrlNKeySequence = QKeySequence(i18nc("The open new window key sequence.", "Ctrl+N"));
213 QKeySequence ctrlF5KeySequence = QKeySequence(i18nc("The reload and bypass cache key sequence.", "Ctrl+F5"));
214 QKeySequence ctrlShiftPKeySequence = QKeySequence(i18nc("The print preview key sequence.", "Ctrl+Shift+P"));
215 QKeySequence ctrlAltPKeySequence = QKeySequence(i18nc("The Privacy Browser user agent key sequence.", "Ctrl+Alt+P"));
216 QKeySequence ctrlAltWKeySequence = QKeySequence(i18nc("The WebEngine Default user agent key sequence.", "Ctrl+Alt+W"));
217 QKeySequence ctrlAltFKeySequence = QKeySequence(i18nc("The Firefox on Linux user agent key sequence.", "Ctrl+Alt+F"));
218 QKeySequence ctrlAltCKeySequence = QKeySequence(i18nc("The Chromium on Linux user agent key sequence.", "Ctrl+Alt+C"));
219 QKeySequence ctrlAltShiftFKeySequence = QKeySequence(i18nc("The Firefox on Windows user agent key sequence.", "Ctrl+Alt+Shift+F"));
220 QKeySequence ctrlAltShiftCKeySequence = QKeySequence(i18nc("The Chrome on Windows user agent key sequence.", "Ctrl+Alt+Shift+C"));
221 QKeySequence ctrlAltEKeySequence = QKeySequence(i18nc("The Edge on Windows user agent key sequence.", "Ctrl+Alt+E"));
222 QKeySequence ctrlAltSKeySequence = QKeySequence(i18nc("The Safari on macOS user agent key sequence.", "Ctrl+Alt+S"));
223 QKeySequence altShiftCKeySequence = QKeySequence(i18nc("The custom user agent key sequence.", "Alt+Shift+C"));
224 QKeySequence ctrlAltZKeySequence = QKeySequence(i18nc("The zoom factor key sequence.", "Ctrl+Alt+Z"));
225 QKeySequence ctrlShiftMKeySequence = QKeySequence(i18nc("The Mojeek search engine key sequence.", "Ctrl+Shift+M"));
226 QKeySequence ctrlShiftOKeySequence = QKeySequence(i18nc("The Monocles search engine key sequence.", "Ctrl+Shift+O"));
227 QKeySequence ctrlShiftEKeySequence = QKeySequence(i18nc("The MetaGer search engine key sequence.", "Ctrl+Shift+E"));
228 QKeySequence ctrlShiftGKeySequence = QKeySequence(i18nc("The Google search engine key sequence.", "Ctrl+Shift+G"));
229 QKeySequence ctrlShiftBKeySequence = QKeySequence(i18nc("The Bing search engine key sequence.", "Ctrl+Shift+B"));
230 QKeySequence ctrlShiftYKeySequence = QKeySequence(i18nc("The Yahoo search engine key sequence.", "Ctrl+Shift+Y"));
231 QKeySequence ctrlShiftCKeySequence = QKeySequence(i18nc("The custom search engine key sequence.", "Ctrl+Shift+C"));
232 QKeySequence ctrlDKeySequence = QKeySequence(i18nc("The domain settings key sequence.", "Ctrl+D"));
233 QKeySequence ctrlSemicolonKeySequence = QKeySequence(i18nc("The cookies dialog key sequence.", "Ctrl+;"));
235 // Set the action key sequences.
236 actionCollectionPointer->setDefaultShortcut(newTabActionPointer, ctrlTKeySequence);
237 actionCollectionPointer->setDefaultShortcut(newWindowActionPointer, ctrlNKeySequence);
238 actionCollectionPointer->setDefaultShortcut(reloadAndBypassCacheActionPointer, ctrlF5KeySequence);
239 actionCollectionPointer->setDefaultShortcut(printPreviewActionPointer, ctrlShiftPKeySequence);
240 actionCollectionPointer->setDefaultShortcut(userAgentPrivacyBrowserActionPointer, ctrlAltPKeySequence);
241 actionCollectionPointer->setDefaultShortcut(userAgentWebEngineDefaultActionPointer, ctrlAltWKeySequence);
242 actionCollectionPointer->setDefaultShortcut(userAgentFirefoxLinuxActionPointer, ctrlAltFKeySequence);
243 actionCollectionPointer->setDefaultShortcut(userAgentChromiumLinuxActionPointer, ctrlAltCKeySequence);
244 actionCollectionPointer->setDefaultShortcut(userAgentFirefoxWindowsActionPointer, ctrlAltShiftFKeySequence);
245 actionCollectionPointer->setDefaultShortcut(userAgentChromeWindowsActionPointer, ctrlAltShiftCKeySequence);
246 actionCollectionPointer->setDefaultShortcut(userAgentEdgeWindowsActionPointer, ctrlAltEKeySequence);
247 actionCollectionPointer->setDefaultShortcut(userAgentSafariMacosActionPointer, ctrlAltSKeySequence);
248 actionCollectionPointer->setDefaultShortcut(userAgentCustomActionPointer, altShiftCKeySequence);
249 actionCollectionPointer->setDefaultShortcut(zoomFactorActionPointer, ctrlAltZKeySequence);
250 actionCollectionPointer->setDefaultShortcut(searchEngineMojeekActionPointer, ctrlShiftMKeySequence);
251 actionCollectionPointer->setDefaultShortcut(searchEngineMonoclesActionPointer, ctrlShiftOKeySequence);
252 actionCollectionPointer->setDefaultShortcut(searchEngineMetagerActionPointer, ctrlShiftEKeySequence);
253 actionCollectionPointer->setDefaultShortcut(searchEngineGoogleActionPointer, ctrlShiftGKeySequence);
254 actionCollectionPointer->setDefaultShortcut(searchEngineBingActionPointer, ctrlShiftBKeySequence);
255 actionCollectionPointer->setDefaultShortcut(searchEngineYahooActionPointer, ctrlShiftYKeySequence);
256 actionCollectionPointer->setDefaultShortcut(searchEngineCustomActionPointer, ctrlShiftCKeySequence);
257 actionCollectionPointer->setDefaultShortcut(domainSettingsActionPointer, ctrlDKeySequence);
258 actionCollectionPointer->setDefaultShortcut(cookiesActionPointer, ctrlSemicolonKeySequence);
260 // Execute the actions.
261 connect(newTabActionPointer, SIGNAL(triggered()), tabWidgetPointer, SLOT(addTab()));
262 connect(newWindowActionPointer, SIGNAL(triggered()), this, SLOT(newWindow()));
263 connect(reloadAndBypassCacheActionPointer, SIGNAL(triggered()), this, SLOT(reloadAndBypassCache()));
264 connect(zoomFactorActionPointer, SIGNAL(triggered()), this, SLOT(getZoomFactorFromUser()));
265 connect(cookiesActionPointer, SIGNAL(triggered()), this, SLOT(showCookiesDialog()));
266 connect(domainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(showDomainSettingsDialog()));
268 // Update the on-the-fly menus.
269 connect(tabWidgetPointer, SIGNAL(updateUserAgentActions(QString, bool)), this, SLOT(updateUserAgentActions(QString, bool)));
270 connect(tabWidgetPointer, SIGNAL(updateZoomFactorAction(double)), this, SLOT(updateZoomFactorAction(double)));
271 connect(tabWidgetPointer, SIGNAL(updateSearchEngineActions(QString, bool)), this, SLOT(updateSearchEngineActions(QString, bool)));
273 // Apply the on-the-fly settings when selected.
274 connect(userAgentActionGroupPointer, SIGNAL(triggered(QAction*)), tabWidgetPointer, SLOT(applyOnTheFlyUserAgent(QAction*)));
275 connect(searchEngineActionGroupPointer, SIGNAL(triggered(QAction*)), tabWidgetPointer, SLOT(applyOnTheFlySearchEngine(QAction*)));
277 // Process cookie changes.
278 connect(tabWidgetPointer, SIGNAL(updateCookiesAction(int)), this, SLOT(updateCookiesAction(int)));
280 // Connect the URL toolbar actions.
281 connect(javaScriptActionPointer, SIGNAL(triggered()), this, SLOT(toggleJavaScript()));
282 connect(localStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleLocalStorage()));
283 connect(domStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleDomStorage()));
285 // Update the URL toolbar actions.
286 connect(tabWidgetPointer, SIGNAL(updateBackAction(bool)), backActionPointer, SLOT(setEnabled(bool)));
287 connect(tabWidgetPointer, SIGNAL(updateForwardAction(bool)), forwardActionPointer, SLOT(setEnabled(bool)));
288 connect(tabWidgetPointer, SIGNAL(updateJavaScriptAction(bool)), this, SLOT(updateJavaScriptAction(bool)));
289 connect(tabWidgetPointer, SIGNAL(updateLocalStorageAction(bool)), this, SLOT(updateLocalStorageAction(bool)));
290 connect(tabWidgetPointer, SIGNAL(updateDomStorageAction(bool)), this, SLOT(updateDomStorageAction(bool)));
292 // Connect the find text actions.
293 connect(findCaseSensitiveActionPointer, SIGNAL(triggered()), this, SLOT(toggleFindCaseSensitive()));
294 connect(hideFindTextActionPointer, SIGNAL(triggered()), this, SLOT(hideFindTextActions()));
296 // Setup the GUI based on the browserwindowui.rc file.
297 setupGUI(StandardWindowOption::Default, ("browserwindowui.rc"));
299 // Get lists of the actions' associated widgets.
300 QList<QWidget*> userAgentAssociatedWidgetsPointerList = userAgentPrivacyBrowserActionPointer->associatedWidgets();
301 QList<QWidget*> searchEngineAssociatedWidgetsPointerList = searchEngineMojeekActionPointer->associatedWidgets();
303 // Get the menu widget pointers. It is the second entry, after the main window.
304 QWidget *userAgentMenuWidgetPointer = userAgentAssociatedWidgetsPointerList[1];
305 QWidget *searchEngineMenuWidgetPointer = searchEngineAssociatedWidgetsPointerList[1];
307 // Get the menu pointers.
308 QMenu *userAgentMenuPointer = qobject_cast<QMenu*>(userAgentMenuWidgetPointer);
309 QMenu *searchEngineMenuPointer = qobject_cast<QMenu*>(searchEngineMenuWidgetPointer);
311 // Get the menu actions.
312 userAgentMenuActionPointer = userAgentMenuPointer->menuAction();
313 searchEngineMenuActionPointer = searchEngineMenuPointer->menuAction();
315 // Get handles for the toolbars.
316 navigationToolBarPointer = toolBar(QLatin1String("navigation_toolbar"));
317 urlToolBarPointer = toolBar(QLatin1String("url_toolbar"));
319 // Create the line edits.
320 urlLineEditPointer = new KLineEdit();
321 findTextLineEditPointer = new KLineEdit();
323 // Get the line edit size policies.
324 QSizePolicy urlLineEditSizePolicy = urlLineEditPointer->sizePolicy();
325 QSizePolicy findTextLineEditSizePolicy = findTextLineEditPointer->sizePolicy();
327 // Set the URL line edit horizontal stretch to be five times the find text line edit stretch.
328 urlLineEditSizePolicy.setHorizontalStretch(5);
329 findTextLineEditSizePolicy.setHorizontalStretch(1);
332 urlLineEditPointer->setSizePolicy(urlLineEditSizePolicy);
333 findTextLineEditPointer->setSizePolicy(findTextLineEditSizePolicy);
336 urlLineEditPointer->setMinimumWidth(350);
337 findTextLineEditPointer->setMinimumWidth(200);
338 findTextLineEditPointer->setMaximumWidth(350);
340 // Set the place holder text.
341 urlLineEditPointer->setPlaceholderText(i18nc("The URL line edit placeholder text", "URL or Search Terms"));
342 findTextLineEditPointer->setPlaceholderText(i18nc("The find line edit placeholder text", "Find Text"));
344 // Show the clear button on the find line edit.
345 findTextLineEditPointer->setClearButtonEnabled(true);
347 // Add an edit or add domain settings action to the URL line edit.
348 QAction *addOrEditDomainSettingsActionPointer = urlLineEditPointer->addAction(QIcon::fromTheme("settings-configure", QIcon::fromTheme(QLatin1String("preferences-desktop"))),
349 QLineEdit::TrailingPosition);
351 // Add or edit the current domain settings.
352 connect(addOrEditDomainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(addOrEditDomainSettings()));
354 // Create a find text label pointer.
355 findTextLabelPointer = new QLabel();
357 // Set the default label text.
358 findTextLabelPointer->setText(QLatin1String(" ") + i18nc("Default find results.", "0/0") + QLatin1String(" "));
360 // Insert the widgets into the toolbars.
361 urlToolBarPointer->insertWidget(javaScriptActionPointer, urlLineEditPointer);
362 findTextLineEditActionPointer = urlToolBarPointer->insertWidget(findNextActionPointer, findTextLineEditPointer);
363 findTextLabelActionPointer = urlToolBarPointer->insertWidget(findNextActionPointer, findTextLabelPointer);
365 // Initially hide the find text actions.
366 hideFindTextActions();
368 // Load a new URL from the URL line edit.
369 connect(urlLineEditPointer, SIGNAL(returnKeyPressed(const QString)), this, SLOT(loadUrlFromLineEdit(const QString)));
371 // Find text as it is typed.
372 connect(findTextLineEditPointer, SIGNAL(textEdited(const QString &)), tabWidgetPointer, SLOT(findText(const QString &)));
374 // Find next if the enter key is pressed.
375 connect(findTextLineEditPointer, SIGNAL(returnKeyPressed(const QString &)), tabWidgetPointer, SLOT(findText(const QString &)));
377 // Update find text when switching tabs.
378 connect(tabWidgetPointer, SIGNAL(updateFindText(const QString &, const bool)), this, SLOT(updateFindText(const QString &, const bool)));
380 // Update the find text results.
381 connect(tabWidgetPointer, SIGNAL(updateFindTextResults(const QWebEngineFindTextResult &)), this, SLOT(updateFindTextResults(const QWebEngineFindTextResult &)));
383 // Update the URL line edit on page loads.
384 connect(tabWidgetPointer, SIGNAL(updateUrlLineEdit(QUrl)), this, SLOT(updateUrlLineEdit(QUrl)));
386 // Update the window title.
387 connect(tabWidgetPointer, SIGNAL(updateWindowTitle(const QString)), this, SLOT(updateWindowTitle(const QString)));
389 // Get a handle for the status bar.
390 QStatusBar *statusBarPointer = statusBar();
392 // Create a progress bar.
393 progressBarPointer = new QProgressBar();
395 // Add the progress bar to to the status bar.
396 statusBarPointer->addPermanentWidget(progressBarPointer);
398 // Update the status bar with the URL when a link is hovered.
399 connect(tabWidgetPointer, SIGNAL(linkHovered(QString)), statusBarPointer, SLOT(showMessage(QString)));
401 // Update the progress bar.
402 connect(tabWidgetPointer, SIGNAL(showProgressBar(const int)), this, SLOT(showProgressBar(const int)));
403 connect(tabWidgetPointer, SIGNAL(hideProgressBar()), progressBarPointer, SLOT(hide()));
405 // Update the URL line edit focus.
406 connect(tabWidgetPointer, SIGNAL(clearUrlLineEditFocus()), this, SLOT(clearUrlLineEditFocus()));
408 // Get the URL line edit palettes.
409 normalBackgroundPalette = urlLineEditPointer->palette();
410 negativeBackgroundPalette = normalBackgroundPalette;
411 positiveBackgroundPalette = normalBackgroundPalette;
413 // Modify the palettes.
414 KColorScheme::adjustBackground(negativeBackgroundPalette, KColorScheme::NegativeBackground);
415 KColorScheme::adjustBackground(positiveBackgroundPalette, KColorScheme::PositiveBackground);
417 // Update the applied palette.
418 connect(tabWidgetPointer, SIGNAL(updateDomainSettingsIndicator(const bool)), this, SLOT(updateDomainSettingsIndicator(const bool)));
420 // Process full screen requests.
421 connect(tabWidgetPointer, SIGNAL(fullScreenRequested(bool)), this, SLOT(fullScreenRequested(bool)));
423 // Create keyboard shortcuts.
424 QShortcut *f11ShortcutPointer = new QShortcut(QKeySequence(i18nc("The toggle full screen shortcut.", "F11")), this);
425 QShortcut *escapeShortcutPointer = new QShortcut(QKeySequence::Cancel, this);
427 // Connect the keyboard shortcuts.
428 connect(f11ShortcutPointer, SIGNAL(activated()), fullScreenActionPointer, SLOT(trigger()));
429 connect(escapeShortcutPointer, SIGNAL(activated()), this, SLOT(escape()));
432 // 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.
433 updateJavaScriptAction(Settings::javaScriptEnabled());
434 updateLocalStorageAction(Settings::localStorageEnabled());
435 updateDomStorageAction(Settings::domStorageEnabled());
436 updateUserAgentActions(UserAgentHelper::getUserAgentFromDatabaseName(Settings::userAgent()), true);
437 updateZoomFactorAction(Settings::zoomFactor());
439 // Load the initial website if this is the first window.
441 tabWidgetPointer->loadInitialWebsite();
444 void BrowserWindow::addOrEditDomainSettings() const
446 // Remove the focus from the URL line edit.
447 urlLineEditPointer->clearFocus();
449 // Create the domain settings dialog pointer.
450 DomainSettingsDialog *domainSettingsDialogPointer;
452 // Get the current domain settings name.
453 QString ¤tDomainSettingsName = tabWidgetPointer->getDomainSettingsName();
455 // Run the commands according to the current domain settings status.
456 if (currentDomainSettingsName == QStringLiteral("")) // Domain settings are not currently applied.
458 // Instruct the domain settings dialog to add a new domain.
459 domainSettingsDialogPointer = new DomainSettingsDialog(DomainSettingsDialog::ADD_DOMAIN, currentUrl.host());
461 else // Domain settings are currently applied.
463 // Instruct the domain settings dialog to edit the current domain.
464 domainSettingsDialogPointer = new DomainSettingsDialog(DomainSettingsDialog::EDIT_DOMAIN, currentDomainSettingsName);
467 // Reload the tabs when domain settings are updated.
468 connect(domainSettingsDialogPointer, SIGNAL(domainSettingsUpdated()), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
471 domainSettingsDialogPointer->show();
474 void BrowserWindow::back() const
476 // Remove the focus from the URL line edit.
477 urlLineEditPointer->clearFocus();
480 tabWidgetPointer->back();
483 void BrowserWindow::clearUrlLineEditFocus() const
485 // Remove the focus from the URL line edit.
486 urlLineEditPointer->clearFocus();
489 void BrowserWindow::escape() const
491 // Process the escape according to the status of the browser.
492 if (fullScreenActionPointer->isChecked()) // Full screen browsing is enabled.
494 // Exit full screen browsing.
495 fullScreenActionPointer->trigger();
497 else if (!findTextLineEditPointer->text().isEmpty()) // Find text is populated.
499 // Clear the find text line edit.
500 findTextLineEditPointer->clear();
502 // Clear the search in the WebEngine.
503 tabWidgetPointer->findText(QStringLiteral(""));
505 else if (findTextLineEditActionPointer->isVisible()) // Find text actions are visible.
507 // Hide the find text actions.
508 hideFindTextActions();
512 void BrowserWindow::findNext() const
514 // Get the find string.
515 const QString findString = findTextLineEditPointer->text();
517 // Search for the text if it is not empty.
518 if (!findString.isEmpty())
519 tabWidgetPointer->findText(findString);
522 void BrowserWindow::findPrevious() const
524 // Get the find string.
525 const QString findString = findTextLineEditPointer->text();
527 // Search for the text if it is not empty.
528 if (!findString.isEmpty())
529 tabWidgetPointer->findPrevious(findString);
532 void BrowserWindow::forward() const
534 // Remove the focus from the URL line edit.
535 urlLineEditPointer->clearFocus();
538 tabWidgetPointer->forward();
541 void BrowserWindow::fullScreenRequested(const bool toggleOn)
543 // Toggle full screen mode.
544 if (toggleOn) // Turn full screen mode on.
546 // Set the window to be full screen.
547 fullScreenActionPointer->setFullScreen(window(), true);
549 // Hide all the bars.
550 menuBar()->setVisible(false);
551 navigationToolBarPointer->setVisible(false);
552 urlToolBarPointer->setVisible(false);
553 tabWidgetPointer->setTabBarVisible(false);
554 statusBar()->setVisible(false);
556 else // Turn full screen mode off.
558 // Set the window to not be full screen.
559 fullScreenActionPointer->setFullScreen(window(), false);
561 // Show all the bars.
562 menuBar()->setVisible(true);
563 navigationToolBarPointer->setVisible(true);
564 urlToolBarPointer->setVisible(true);
565 tabWidgetPointer->setTabBarVisible(true);
566 statusBar()->setVisible(true);
570 void BrowserWindow::getZoomFactorFromUser()
572 // Create an OK flag.
575 // 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.
576 double newZoomFactor = QInputDialog::getDouble(this, i18nc("The on-the-fly zoom factor dialog title", "On-The-Fly Zoom Factor"),
577 i18nc("The instruction text of the on-the-fly zoom factor dialog", "Enter a zoom factor between 0.25 and 5.00"),
578 currentZoomFactor, .025, 5.00, 2, &okClicked, Qt::WindowFlags(), 0.25);
580 // Update the zoom factor if the user clicked OK.
583 // Update the current zoom factor.
584 currentZoomFactor = newZoomFactor;
586 // Set the new zoom factor.
587 tabWidgetPointer->applyOnTheFlyZoomFactor(newZoomFactor);
589 // Update the on-the-fly action text.
590 updateZoomFactorAction(newZoomFactor);
594 void BrowserWindow::hideFindTextActions() const
596 // Hide the find text actions.
597 findTextLineEditActionPointer->setVisible(false);
598 findTextLabelActionPointer->setVisible(false);
599 findNextActionPointer->setVisible(false);
600 findPreviousActionPointer->setVisible(false);
601 findCaseSensitiveActionPointer->setVisible(false);
602 hideFindTextActionPointer->setVisible(false);
605 void BrowserWindow::home() const
607 // Remove the focus from the URL line edit.
608 urlLineEditPointer->clearFocus();
611 tabWidgetPointer->home();
614 void BrowserWindow::loadUrlFromLineEdit(const QString &url) const
616 // Remove the focus from the URL line edit.
617 urlLineEditPointer->clearFocus();
620 tabWidgetPointer->loadUrlFromLineEdit(url);
623 void BrowserWindow::newWindow() const
625 // Display a new instance of Privacy Browser.
626 (new BrowserWindow)->show();
629 void BrowserWindow::refresh() const
631 // Remove the focus from the URL line edit.
632 urlLineEditPointer->clearFocus();
634 // Refresh the web page.
635 tabWidgetPointer->refresh();
638 void BrowserWindow::reloadAndBypassCache() const
640 // Remove the focus from the URL line edit.
641 urlLineEditPointer->clearFocus();
643 // Refresh the web page.
644 tabWidgetPointer->refresh();
647 void BrowserWindow::showCookiesDialog()
649 // Remove the focus from the URL line edit.
650 urlLineEditPointer->clearFocus();
652 // Instantiate the cookie settings dialog.
653 CookiesDialog *cookiesDialogPointer = new CookiesDialog(tabWidgetPointer->getCookieList());
656 cookiesDialogPointer->show();
658 // Connect the dialog signals.
659 connect(cookiesDialogPointer, SIGNAL(addCookie(QNetworkCookie)), tabWidgetPointer, SLOT(addCookieToStore(QNetworkCookie)));
660 connect(cookiesDialogPointer, SIGNAL(deleteAllCookies()), tabWidgetPointer, SLOT(deleteAllCookies()));
661 connect(cookiesDialogPointer, SIGNAL(deleteCookie(QNetworkCookie)), tabWidgetPointer, SLOT(deleteCookieFromStore(QNetworkCookie)));
664 void BrowserWindow::showDownloadLocationBrowseDialog() const
666 // Get the current download location.
667 QString currentDownloadLocation = downloadLocationComboBoxPointer->currentText();
669 // Resolve the system download directory if specified.
670 if (currentDownloadLocation == QStringLiteral("System Download Directory"))
671 currentDownloadLocation = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
673 // Get the new download location.
674 QString newDownloadLocation = QFileDialog::getExistingDirectory(configDialogPointer, i18nc("Select download location dialog caption", "Select Download Location"), currentDownloadLocation);
676 // Populate the download location combo box according to the new download location.
677 if (newDownloadLocation == QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)) // The default download location was selected.
679 // Populate the download location with the default text.
680 downloadLocationComboBoxPointer->setCurrentText("System Download Directory");
682 else if (newDownloadLocation != QStringLiteral("")) // A different directory was selected.
684 // Populate the download location.
685 downloadLocationComboBoxPointer->setCurrentText(newDownloadLocation);
689 void BrowserWindow::showDomainSettingsDialog() const
691 // Remove the focus from the URL line edit.
692 urlLineEditPointer->clearFocus();
694 // Instantiate the domain settings dialog.
695 DomainSettingsDialog *domainSettingsDialogPointer = new DomainSettingsDialog();
697 // Reload the tabs when domain settings are updated.
698 connect(domainSettingsDialogPointer, SIGNAL(domainSettingsUpdated()), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
701 domainSettingsDialogPointer->show();
704 void BrowserWindow::showFindTextActions() const
706 // Show the find text actions.
707 findTextLineEditActionPointer->setVisible(true);
708 findTextLabelActionPointer->setVisible(true);
709 findNextActionPointer->setVisible(true);
710 findPreviousActionPointer->setVisible(true);
711 findCaseSensitiveActionPointer->setVisible(true);
712 hideFindTextActionPointer->setVisible(true);
714 // Set the focus on the find line edit.
715 findTextLineEditPointer->setFocus();
717 // Select all the text in the find line edit.
718 findTextLineEditPointer->selectAll();
721 void BrowserWindow::showProgressBar(const int &progress) const
723 // Set the progress bar value.
724 progressBarPointer->setValue(progress);
726 // Show the progress bar.
727 progressBarPointer->show();
730 void BrowserWindow::showSettingsDialog()
732 // Create the settings widgets.
733 QWidget *privacySettingsWidgetPointer = new QWidget;
734 QWidget *generalSettingsWidgetPointer = new QWidget;
735 QWidget *spellCheckSettingsWidgetPointer = new QWidget;
737 // Instantiate the settings UI.
738 Ui::PrivacySettings privacySettingsUi;
739 Ui::GeneralSettings generalSettingsUi;
740 Ui::SpellCheckSettings spellCheckSettingsUi;
742 // Setup the UI to display the settings widgets.
743 privacySettingsUi.setupUi(privacySettingsWidgetPointer);
744 generalSettingsUi.setupUi(generalSettingsWidgetPointer);
745 spellCheckSettingsUi.setupUi(spellCheckSettingsWidgetPointer);
747 // Get handles for the widgets.
748 QComboBox *userAgentComboBoxPointer = privacySettingsUi.kcfg_userAgent;
749 userAgentLabelPointer = privacySettingsUi.userAgentLabel;
750 QComboBox *searchEngineComboBoxPointer = generalSettingsUi.kcfg_searchEngine;
751 searchEngineLabelPointer = generalSettingsUi.searchEngineLabel;
752 downloadLocationComboBoxPointer = generalSettingsUi.kcfg_downloadLocation;
753 QPushButton *browseButtonPointer = generalSettingsUi.browseButton;
754 QListWidget *spellCheckListWidgetPointer = spellCheckSettingsUi.spellCheckListWidget;
756 // Populate the combo box labels.
757 updateUserAgentLabel(userAgentComboBoxPointer->currentText());
758 updateSearchEngineLabel(searchEngineComboBoxPointer->currentText());
760 // Update the labels when the combo boxes change.
761 connect(userAgentComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateUserAgentLabel(const QString)));
762 connect(searchEngineComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateSearchEngineLabel(const QString)));
764 // Connect the download location directory browse button.
765 connect(browseButtonPointer, SIGNAL(clicked()), this, SLOT(showDownloadLocationBrowseDialog()));
767 // Create a dictionaries QDir from the `QTWEBENGINE_DICTIONARIES_PATH` environment variable.
768 QDir dictionariesDir = QDir(qEnvironmentVariable("QTWEBENGINE_DICTIONARIES_PATH"));
770 // Get a dictionaries string list.
771 QStringList dictionariesStringList = dictionariesDir.entryList(QStringList(QLatin1String("*.bdic")), QDir::Files | QDir::NoSymLinks);
773 // Remove the `.bdic` file extensions from the dictionaries list.
774 dictionariesStringList.replaceInStrings(QLatin1String(".bdic"), QLatin1String(""));
776 // Get a list of the enabled spell check languages.
777 QStringList enabledSpellCheckLanguagesList = Settings::spellCheckLanguages();
779 // Add each dictionary to the spell check list widget.
780 foreach(QString dictionaryString, dictionariesStringList)
782 // Create a new list widget item pointer.
783 QListWidgetItem *listWidgetItemPointer = new QListWidgetItem();
785 // Create a dictionary check box widget with the name of the dictionary string.
786 QCheckBox *dictionaryCheckBoxWidget = new QCheckBox(dictionaryString);
788 // Check the language if it is currently enabled.
789 if (enabledSpellCheckLanguagesList.contains(dictionaryString))
790 dictionaryCheckBoxWidget->setCheckState(Qt::Checked);
792 dictionaryCheckBoxWidget->setCheckState(Qt::Unchecked);
794 // Add the list widget item to the spell check list widget.
795 spellCheckListWidgetPointer->addItem(listWidgetItemPointer);
797 // Set the list widget item check box widget.
798 spellCheckListWidgetPointer->setItemWidget(listWidgetItemPointer, dictionaryCheckBoxWidget);
801 // Get a handle for the KConfig skeleton.
802 KConfigSkeleton *kConfigSkeletonPointer = Settings::self();
804 // Instantiate a settings config dialog from the settings.kcfg file.
805 configDialogPointer = new KConfigDialog(this, QLatin1String("settings"), kConfigSkeletonPointer);
807 // Create a settings icon string.
808 QString settingsIconString;
810 // Get a settings icon that matches the theme.
811 if (QIcon::hasThemeIcon("breeze-settings"))
813 // KDE uses breeze-settings.
814 settingsIconString = QLatin1String("breeze-settings");
818 // Gnome uses preferences-desktop.
819 settingsIconString = QLatin1String("preferences-desktop");
822 // Add the settings widgets as config dialog pages.
823 configDialogPointer->addPage(privacySettingsWidgetPointer, i18nc("Settings tab title", "Privacy"), QLatin1String("privacybrowser"));
824 configDialogPointer->addPage(generalSettingsWidgetPointer, i18nc("Settings tab title", "General"), settingsIconString);
825 configDialogPointer->addPage(spellCheckSettingsWidgetPointer, i18nc("Settings tab title", "Spell Check"), QLatin1String("tools-check-spelling"));
827 // Get handles for the buttons.
828 QPushButton *applyButtonPointer = configDialogPointer->button(QDialogButtonBox::Apply);
829 QPushButton *okButtonPointer = configDialogPointer->button(QDialogButtonBox::Ok);
831 // Prevent interaction with the parent window while the dialog is open.
832 configDialogPointer->setWindowModality(Qt::WindowModal);
835 configDialogPointer->show();
837 // TODO. KConfigDialog does not respect expanding size policies. <https://redmine.stoutner.com/issues/823>
838 //configDialogPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
839 //privacySettingsWidgetPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
840 //generalSettingsWidgetPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
841 //configDialogPointer->adjustSize();
843 // Expand the config dialog.
844 configDialogPointer->resize(1000, 500);
846 // Create a save spell check languages lambda.
847 auto saveSpellCheckLanguages = [spellCheckListWidgetPointer, kConfigSkeletonPointer, this] ()
849 // Create a list of enabled languages.
850 QStringList newSpellCheckLanguages = QStringList();
852 // Get a count of all the languages.
853 int allLanguagesCount = spellCheckListWidgetPointer->count();
855 // Get a list of all the checked languages.
856 for (int i = 0; i < allLanguagesCount; ++i) {
857 // Get the language item.
858 QListWidgetItem *languageItemPointer = spellCheckListWidgetPointer->item(i);
860 // Get the language check box.
861 QCheckBox *languageCheckBoxPointer = qobject_cast<QCheckBox*>(spellCheckListWidgetPointer->itemWidget(languageItemPointer));
863 // Add the item to the enabled languages if it is checked.
864 if (languageCheckBoxPointer->checkState() == Qt::Checked)
867 QString languageString = languageCheckBoxPointer->text();
869 // Remove all instances of `&`, which may have been added automatically when creating the check box text.
870 languageString.remove(QChar('&'));
872 // Add the language string to the list.
873 newSpellCheckLanguages.append(languageString);
877 // Update the spell check languages.
878 if (Settings::spellCheckLanguages() != newSpellCheckLanguages)
880 // Update the spell check languages.
881 Settings::setSpellCheckLanguages(newSpellCheckLanguages);
883 // Write the settings to disk.
884 kConfigSkeletonPointer->save();
887 // Apply the spell check languages.
888 tabWidgetPointer->applySpellCheckLanguages();
892 connect(applyButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages);
893 connect(okButtonPointer, &QPushButton::clicked, this, saveSpellCheckLanguages);
895 // Apply the settings handled by KConfig.
896 connect(configDialogPointer, SIGNAL(settingsChanged(QString)), tabWidgetPointer, SLOT(applyApplicationSettings()));
897 connect(configDialogPointer, SIGNAL(settingsChanged(QString)), tabWidgetPointer, SLOT(applyDomainSettingsAndReload()));
900 QSize BrowserWindow::sizeHint() const
902 // Return the default window size.
903 return QSize(1500, 1200);
906 void BrowserWindow::toggleDomStorage() const
908 // Remove the focus from the URL line edit.
909 urlLineEditPointer->clearFocus();
911 // Toggle DOM storage.
912 tabWidgetPointer->toggleDomStorage();
915 void BrowserWindow::toggleFindCaseSensitive() const
917 // Get the current find string.
918 const QString findString = findTextLineEditPointer->text();
920 // Toggle find case sensitive.
921 tabWidgetPointer->toggleFindCaseSensitive(findString);
924 void BrowserWindow::toggleJavaScript() const
926 // Remove the focus from the URL line edit.
927 urlLineEditPointer->clearFocus();
929 // Toggle JavaScript.
930 tabWidgetPointer->toggleJavaScript();
933 void BrowserWindow::toggleLocalStorage() const
935 // Remove the focus from the URL line edit.
936 urlLineEditPointer->clearFocus();
938 // Toggle local storage.
939 tabWidgetPointer->toggleLocalStorage();
942 void BrowserWindow::toggleFullScreen()
944 // Toggle the full screen status.
945 if (fullScreenActionPointer->isChecked()) // Enable full screen browsing mode.
947 // Enable full screen mode.
948 fullScreenActionPointer->setFullScreen(window(), true);
950 // Hide the menu bar if specified.
951 if (Settings::fullScreenHideMenuBar())
952 menuBar()->setVisible(false);
954 // Hide the toolbars if specified.
955 if (Settings::fullScreenHideToolBars())
957 navigationToolBarPointer->setVisible(false);
958 urlToolBarPointer->setVisible(false);
961 // Hide the tab bar if specified.
962 if (Settings::fullScreenHideTabBar())
963 tabWidgetPointer->setTabBarVisible(false);
965 // Hide the status bar if specified.
966 if (Settings::fullScreenHideStatusBar())
967 statusBar()->setVisible(false);
969 else // Disable full screen browsing mode.
971 // Disable full screen mode.
972 fullScreenActionPointer->setFullScreen(window(), false);
974 // Show the menu bar.
975 menuBar()->setVisible(true);
977 // Show the toolbars.
978 navigationToolBarPointer->setVisible(true);
979 urlToolBarPointer->setVisible(true);
982 tabWidgetPointer->setTabBarVisible(true);
984 // Show the status bar.
985 statusBar()->setVisible(true);
989 void BrowserWindow::updateCookiesAction(const int numberOfCookies) const
991 // Update the action text.
992 cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", numberOfCookies));
995 void BrowserWindow::updateDomStorageAction(const bool &isEnabled) const
997 // Set the action checked status.
998 domStorageActionPointer->setChecked(isEnabled);
1001 void BrowserWindow::updateDomainSettingsIndicator(const bool status)
1003 // Set the domain palette according to the status.
1005 urlLineEditPointer->setPalette(positiveBackgroundPalette);
1007 urlLineEditPointer->setPalette(normalBackgroundPalette);
1010 void BrowserWindow::updateFindText(const QString &text, const bool findCaseSensitive) const
1013 findTextLineEditPointer->setText(text);
1015 // Set the find case sensitive action checked status.
1016 findCaseSensitiveActionPointer->setChecked(findCaseSensitive);
1019 void BrowserWindow::updateFindTextResults(const QWebEngineFindTextResult &findTextResult) const
1021 // Update the find text label.
1022 findTextLabelPointer->setText(QStringLiteral(" %1/%2 ").arg(findTextResult.activeMatch()).arg(findTextResult.numberOfMatches()));
1024 // Set the background color according to the find status.
1025 if (findTextLineEditPointer->text().isEmpty())
1026 findTextLineEditPointer->setPalette(normalBackgroundPalette);
1027 else if (findTextResult.numberOfMatches() == 0)
1028 findTextLineEditPointer->setPalette(negativeBackgroundPalette);
1030 findTextLineEditPointer->setPalette(positiveBackgroundPalette);
1033 void BrowserWindow::updateJavaScriptAction(const bool &isEnabled)
1035 // Update the JavaScript status.
1036 javaScriptEnabled = isEnabled;
1038 // Set the icon according to the status.
1039 if (javaScriptEnabled)
1040 javaScriptActionPointer->setIcon(QIcon(QLatin1String(":/icons/javascript-warning.svg")));
1042 javaScriptActionPointer->setIcon(QIcon(QLatin1String(":/icons/privacy-mode.svg")));
1044 // Set the action checked status.
1045 javaScriptActionPointer->setChecked(javaScriptEnabled);
1047 // Update the status of the DOM storage action.
1048 domStorageActionPointer->setEnabled(javaScriptEnabled & localStorageEnabled);
1051 void BrowserWindow::updateLocalStorageAction(const bool &isEnabled)
1053 // Update the local storage status.
1054 localStorageEnabled = isEnabled;
1056 // 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.
1057 if (localStorageEnabled)
1058 localStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("disk-quota-high"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/actions/filesaveas.png"))));
1060 localStorageActionPointer->setIcon(QIcon::fromTheme(QLatin1String("disk-quota"), QIcon(QLatin1String("/usr/share/icons/gnome/32x32/apps/kfm.png"))));
1062 // Set the action checked status.
1063 localStorageActionPointer->setChecked(localStorageEnabled);
1065 // Update the status of the DOM storage action.
1066 domStorageActionPointer->setEnabled(localStorageEnabled & javaScriptEnabled);
1069 void BrowserWindow::updateSearchEngineActions(const QString &searchEngine, const bool &updateCustomSearchEngineStatus)
1071 // Initialize the custom search engine flag.
1072 bool customSearchEngine = false;
1074 if (searchEngine == "Mojeek") // Mojeek.
1076 // Check the Mojeek user agent action.
1077 searchEngineMojeekActionPointer->setChecked(true);
1079 // Update the search engine menu action icon.
1080 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1082 // Update the search engine menu action text.
1083 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Mojeek"));
1085 else if (searchEngine == "Monocles") // Monocles.
1087 // Check the Monocles user agent action.
1088 searchEngineMonoclesActionPointer->setChecked(true);
1090 // Update the search engine menu action icon.
1091 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1093 // Update the search engine menu action text.
1094 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Monocles"));
1096 else if (searchEngine == "MetaGer") // MetaGer.
1098 // Check the MetaGer user agent action.
1099 searchEngineMetagerActionPointer->setChecked(true);
1101 // Update the search engine menu action icon.
1102 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1104 // Update the search engine menu action text.
1105 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - MetaGer"));
1107 else if (searchEngine == "Google") // Google.
1109 // Check the Google user agent action.
1110 searchEngineGoogleActionPointer->setChecked(true);
1112 // Update the search engine menu action icon.
1113 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-google"), QIcon::fromTheme(QLatin1String("edit-find"))));
1115 // Update the search engine menu action text.
1116 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Google"));
1118 else if (searchEngine == "Bing") // Bing.
1120 // Check the Bing user agent action.
1121 searchEngineBingActionPointer->setChecked(true);
1123 // Update the search engine menu action icon.
1124 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1126 // Update the search engine menu action text.
1127 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Bing"));
1129 else if (searchEngine == "Yahoo") // Yahoo.
1131 // Check the Yahoo user agent action.
1132 searchEngineYahooActionPointer->setChecked(true);
1134 // Update the search engine menu action icon.
1135 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("im-yahoo"), QIcon::fromTheme(QLatin1String("edit-find"))));
1137 // Update the search engine menu action text.
1138 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Yahoo"));
1140 else // Custom search engine.
1142 // Check the user agent.
1143 searchEngineCustomActionPointer->setChecked(true);
1145 // Update the search engine menu action icon.
1146 searchEngineMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("edit-find")));
1148 // Update the search engine menu action text.
1149 searchEngineMenuActionPointer->setText(i18nc("The main search engine menu action", "Search Engine - Custom"));
1151 // Set the custom search engine text.
1152 searchEngineCustomActionPointer->setText(searchEngine);
1154 // Set the custom search engine flag.
1155 customSearchEngine = true;
1158 // Update the custom search engine enabled boolean.
1159 if (updateCustomSearchEngineStatus)
1160 customSearchEngineEnabled = customSearchEngine;
1162 // Format the custom search engine.
1163 if (customSearchEngineEnabled)
1165 // Enable the custom search engine.
1166 searchEngineCustomActionPointer->setEnabled(true);
1170 // Disable the custom search engine.
1171 searchEngineCustomActionPointer->setEnabled(false);
1173 // Reset the custom search engine text.
1174 searchEngineCustomActionPointer->setText(i18nc("@action", "Custom"));
1178 void BrowserWindow::updateUserAgentActions(const QString &userAgent, const bool &updateCustomUserAgentStatus)
1180 // Initialize the custom user agent flag.
1181 bool customUserAgent = false;
1183 // Check the indicated on-the-fly user agent.
1184 if (userAgent == UserAgentHelper::PRIVACY_BROWSER_USER_AGENT) // Privacy Browser.
1186 // Check the Privacy Browser user agent action.
1187 userAgentPrivacyBrowserActionPointer->setChecked(true);
1189 // Update the user agent menu action icon.
1190 userAgentMenuActionPointer->setIcon(QIcon(":/icons/privacy-mode.svg"));
1192 // Update the user agent menu action text.
1193 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Privacy Browser"));
1195 else if (userAgent == TabWidget::webEngineDefaultUserAgent) // WebEngine default.
1197 // check the WebEngine default user agent action.
1198 userAgentWebEngineDefaultActionPointer->setChecked(true);
1200 // Update the user agent menu action icon.
1201 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("qtlogo"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
1203 // Update the user agent menu action text.
1204 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - WebEngine default"));
1206 else if (userAgent == UserAgentHelper::FIREFOX_LINUX_USER_AGENT) // Firefox on Linux.
1208 // Check the Firefox on Linux user agent action.
1209 userAgentFirefoxLinuxActionPointer->setChecked(true);
1211 // Update the user agent menu action icon.
1212 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
1214 // Update the user agent menu action text.
1215 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Firefox on Linux"));
1217 else if (userAgent == UserAgentHelper::CHROMIUM_LINUX_USER_AGENT) // Chromium on Linux.
1219 // Check the Chromium on Linux user agent action.
1220 userAgentChromiumLinuxActionPointer->setChecked(true);
1222 // Update the user agent menu action icon.
1223 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
1225 // Update the user agent menu action text.
1226 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Chromium on Linux"));
1228 else if (userAgent == UserAgentHelper::FIREFOX_WINDOWS_USER_AGENT) // Firefox on Windows.
1230 // Check the Firefox on Windows user agent action.
1231 userAgentFirefoxWindowsActionPointer->setChecked(true);
1233 // Update the user agent menu action icon.
1234 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("firefox-esr"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
1236 // Update the user agent menu action text.
1237 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Firefox on Windows"));
1239 else if (userAgent == UserAgentHelper::CHROME_WINDOWS_USER_AGENT) // Chrome on Windows.
1241 // Check the Chrome on Windows user agent action.
1242 userAgentChromeWindowsActionPointer->setChecked(true);
1244 // Update the user agent menu action icon.
1245 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("chromium"), QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new")))));
1247 // Update the user agent menu action text.
1248 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Chrome on Windows"));
1250 else if (userAgent == UserAgentHelper::EDGE_WINDOWS_USER_AGENT) // Edge on Windows.
1252 // Check the Edge on Windows user agent action.
1253 userAgentEdgeWindowsActionPointer->setChecked(true);
1255 // Update the user agent menu action icon.
1256 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
1258 // Update the user agent menu action text.
1259 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Edge on Windows"));
1261 else if (userAgent == UserAgentHelper::SAFARI_MACOS_USER_AGENT) // Safari on macOS.
1263 // Check the Safari on macOS user agent action.
1264 userAgentSafariMacosActionPointer->setChecked(true);
1266 // Update the user agent menu action icon.
1267 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
1269 // Update the user agent menu action text.
1270 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Safari on macOS"));
1272 else // Custom user agent.
1274 // Check the user agent.
1275 userAgentCustomActionPointer->setChecked(true);
1277 // Update the user agent menu action icon.
1278 userAgentMenuActionPointer->setIcon(QIcon::fromTheme(QLatin1String("user-group-properties"), QIcon::fromTheme(QLatin1String("contact-new"))));
1280 // Update the user agent menu action text.
1281 userAgentMenuActionPointer->setText(i18nc("The main user agent menu action", "User Agent - Custom"));
1283 // Set the custom user agent text.
1284 userAgentCustomActionPointer->setText(userAgent);
1286 // Set the custom user agent flag.
1287 customUserAgent = true;
1290 // Update the custom user agent enabled boolean.
1291 // 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.
1292 if (updateCustomUserAgentStatus)
1293 customUserAgentEnabled = customUserAgent;
1296 // Format the custom user agent.
1297 if (customUserAgentEnabled)
1299 // Enable the custom user agent.
1300 userAgentCustomActionPointer->setEnabled(true);
1304 // Disable the custom user agent.
1305 userAgentCustomActionPointer->setEnabled(false);
1307 // Reset the custom user agent text.
1308 userAgentCustomActionPointer->setText(i18nc("@action", "Custom"));
1312 void BrowserWindow::updateZoomFactorAction(const double &zoomFactor)
1314 // Set the current zoom factor.
1315 currentZoomFactor = zoomFactor;
1317 // Update the zoom factor action text, formatting the double with 2 decimal places.
1318 zoomFactorActionPointer->setText(ki18nc("@action", "Zoom Factor - %1").subs(zoomFactor, 0, '0', 2).toString());
1321 void BrowserWindow::updateSearchEngineLabel(const QString &searchEngineString) const
1323 // Update the search engine label.
1324 searchEngineLabelPointer->setText(SearchEngineHelper::getSearchUrl(searchEngineString));
1327 void BrowserWindow::updateUrlLineEdit(const QUrl &newUrl)
1329 // Update the URL line edit if it does not have focus.
1330 if (!urlLineEditPointer->hasFocus())
1332 // Get the new URL string.
1333 QString newUrlString = newUrl.toString();
1335 // Update the URL line edit.
1336 urlLineEditPointer->setText(newUrlString);
1338 // Set the focus if the new URL is blank.
1339 if (newUrlString == QStringLiteral(""))
1340 urlLineEditPointer->setFocus();
1343 // Store the current URL.
1344 currentUrl = newUrl;
1347 void BrowserWindow::updateUserAgentLabel(const QString &userAgentDatabaseName) const
1349 // Update the user agent label.
1350 userAgentLabelPointer->setText(UserAgentHelper::getUserAgentFromDatabaseName(userAgentDatabaseName));
1353 void BrowserWindow::updateWindowTitle(const QString &title)
1355 // Update the window title.
1356 setWindowTitle(title);