]> gitweb.stoutner.com Git - PrivacyBrowserPC.git/blob - src/windows/BrowserWindow.cpp
4a61438f1f8a9402d567a83beed3330a27199a90
[PrivacyBrowserPC.git] / src / windows / BrowserWindow.cpp
1 /*
2  * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 // Application headers.
21 #include "BrowserWindow.h"
22 #include "Settings.h"
23 #include "ui_SettingsPrivacy.h"
24 #include "ui_SettingsGeneral.h"
25 #include "databases/CookiesDatabase.h"
26 #include "dialogs/CookiesDialog.h"
27 #include "dialogs/DomainSettingsDialog.h"
28 #include "helpers/SearchEngineHelper.h"
29 #include "helpers/UserAgentHelper.h"
30
31 // KDE Frameworks headers.
32 #include <KActionCollection>
33 #include <KToolBar>
34
35 // Qt toolkit headers.
36 #include <QInputDialog>
37 #include <QNetworkCookie>
38 #include <QStatusBar>
39
40 // Construct the class.
41 BrowserWindow::BrowserWindow() : KXmlGuiWindow()
42 {
43     // Initialize the variables.
44     cookieListPointer = new std::list<QNetworkCookie>;
45     javaScriptEnabled = false;
46     localStorageEnabled = false;
47
48     // Instantiate the main view pointer.
49     browserViewPointer = new BrowserView(this);
50
51     // Set the main view as the central widget.
52     setCentralWidget(browserViewPointer);
53
54     // Get a handle for the action collection.
55     KActionCollection *actionCollectionPointer = this->actionCollection();
56
57     // Add the standard actions.
58     QAction *backActionPointer = KStandardAction::back(this, SLOT(back()), actionCollectionPointer);
59     QAction *forwardActionPointer = KStandardAction::forward(this, SLOT(forward()), actionCollectionPointer);
60     KStandardAction::home(this, SLOT(home()), actionCollectionPointer);
61     KStandardAction::openNew(this, SLOT(fileNew()), actionCollectionPointer);
62     KStandardAction::quit(qApp, SLOT(closeAllWindows()), actionCollectionPointer);
63     KStandardAction::preferences(this, SLOT(settingsConfigure()), actionCollectionPointer);
64     KStandardAction::redisplay(this, SLOT(refresh()), actionCollectionPointer);
65
66     // Add the custom actions.
67     userAgentPrivacyBrowserActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_privacy_browser"));
68     userAgentWebEngineDefaultActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_webengine_default"));
69     userAgentFirefoxLinuxActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_firefox_linux"));
70     userAgentChromiumLinuxActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_chromium_linux"));
71     userAgentFirefoxWindowsActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_firefox_windows"));
72     userAgentChromeWindowsActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_chrome_windows"));
73     userAgentEdgeWindowsActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_edge_windows"));
74     userAgentSafariMacosActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_safari_macos"));
75     userAgentCustomActionPointer = actionCollectionPointer->addAction(QStringLiteral("user_agent_custom"));
76     zoomFactorActionPointer = actionCollectionPointer->addAction(QStringLiteral("zoom_factor"));
77     searchEngineMojeekActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_mojeek"));
78     searchEngineMonoclesActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_monocles"));
79     searchEngineMetagerActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_metager"));
80     searchEngineGoogleActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_google"));
81     searchEngineBingActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_bing"));
82     searchEngineYahooActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_yahoo"));
83     searchEngineCustomActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_custom"));
84     QAction *domainSettingsActionPointer = actionCollectionPointer->addAction(QStringLiteral("domain_settings"));
85     cookiesActionPointer = actionCollectionPointer->addAction(QStringLiteral("cookies"));
86     javaScriptActionPointer = actionCollectionPointer->addAction(QStringLiteral("javascript"));
87     localStorageActionPointer = actionCollectionPointer->addAction(QStringLiteral("local_storage"));
88     domStorageActionPointer = actionCollectionPointer->addAction(QStringLiteral("dom_storage"));
89
90     // Create the action groups
91     QActionGroup *userAgentActionGroupPointer = new QActionGroup(this);
92     QActionGroup *searchEngineActionGroupPointer = new QActionGroup(this);
93
94     // Add the actions to the groups.
95     userAgentActionGroupPointer->addAction(userAgentPrivacyBrowserActionPointer);
96     userAgentActionGroupPointer->addAction(userAgentWebEngineDefaultActionPointer);
97     userAgentActionGroupPointer->addAction(userAgentFirefoxLinuxActionPointer);
98     userAgentActionGroupPointer->addAction(userAgentChromiumLinuxActionPointer);
99     userAgentActionGroupPointer->addAction(userAgentFirefoxWindowsActionPointer);
100     userAgentActionGroupPointer->addAction(userAgentChromeWindowsActionPointer);
101     userAgentActionGroupPointer->addAction(userAgentEdgeWindowsActionPointer);
102     userAgentActionGroupPointer->addAction(userAgentSafariMacosActionPointer);
103     userAgentActionGroupPointer->addAction(userAgentCustomActionPointer);
104     searchEngineActionGroupPointer->addAction(searchEngineMojeekActionPointer);
105     searchEngineActionGroupPointer->addAction(searchEngineMonoclesActionPointer);
106     searchEngineActionGroupPointer->addAction(searchEngineMetagerActionPointer);
107     searchEngineActionGroupPointer->addAction(searchEngineGoogleActionPointer);
108     searchEngineActionGroupPointer->addAction(searchEngineBingActionPointer);
109     searchEngineActionGroupPointer->addAction(searchEngineYahooActionPointer);
110     searchEngineActionGroupPointer->addAction(searchEngineCustomActionPointer);
111
112     // Set some actions to be checkable.
113     javaScriptActionPointer->setCheckable(true);
114     localStorageActionPointer->setCheckable(true);
115     domStorageActionPointer->setCheckable(true);
116     userAgentPrivacyBrowserActionPointer->setCheckable(true);
117     userAgentWebEngineDefaultActionPointer->setCheckable(true);
118     userAgentFirefoxLinuxActionPointer->setCheckable(true);
119     userAgentChromiumLinuxActionPointer->setCheckable(true);
120     userAgentFirefoxWindowsActionPointer->setCheckable(true);
121     userAgentChromeWindowsActionPointer->setCheckable(true);
122     userAgentEdgeWindowsActionPointer->setCheckable(true);
123     userAgentSafariMacosActionPointer->setCheckable(true);
124     userAgentCustomActionPointer->setCheckable(true);
125     searchEngineMojeekActionPointer->setCheckable(true);
126     searchEngineMonoclesActionPointer->setCheckable(true);
127     searchEngineMetagerActionPointer->setCheckable(true);
128     searchEngineGoogleActionPointer->setCheckable(true);
129     searchEngineBingActionPointer->setCheckable(true);
130     searchEngineYahooActionPointer->setCheckable(true);
131     searchEngineCustomActionPointer->setCheckable(true);
132
133     // Set the action text.
134     userAgentPrivacyBrowserActionPointer->setText(UserAgentHelper::PRIVACY_BROWSER_TRANSLATED);
135     userAgentWebEngineDefaultActionPointer->setText(UserAgentHelper::WEB_ENGINE_DEFAULT_TRANSLATED);
136     userAgentFirefoxLinuxActionPointer->setText(UserAgentHelper::FIREFOX_LINUX_TRANSLATED);
137     userAgentChromiumLinuxActionPointer->setText(UserAgentHelper::CHROMIUM_LINUX_TRANSLATED);
138     userAgentFirefoxWindowsActionPointer->setText(UserAgentHelper::FIREFOX_WINDOWS_TRANSLATED);
139     userAgentChromeWindowsActionPointer->setText(UserAgentHelper::CHROME_WINDOWS_TRANSLATED);
140     userAgentEdgeWindowsActionPointer->setText(UserAgentHelper::EDGE_WINDOWS_TRANSLATED);
141     userAgentSafariMacosActionPointer->setText(UserAgentHelper::SAFARI_MACOS_TRANSLATED);
142     searchEngineMojeekActionPointer->setText(i18nc("Search engine", "Mojeek"));
143     searchEngineMonoclesActionPointer->setText(i18nc("Search engine", "Monocles"));
144     searchEngineMetagerActionPointer->setText(i18nc("Search engine", "MetaGer"));
145     searchEngineGoogleActionPointer->setText(i18nc("Search engine", "Google"));
146     searchEngineBingActionPointer->setText(i18nc("Search engine", "Bing"));
147     searchEngineYahooActionPointer->setText(i18nc("Search engine", "Yahoo"));
148     domainSettingsActionPointer->setText(i18nc("Domain Settings action", "Domain Settings"));
149     cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", cookieListPointer->size()));
150     javaScriptActionPointer->setText(i18nc("JavaScript action", "JavaScript"));
151     localStorageActionPointer->setText(i18nc("The Local Storage action", "Local Storage"));
152     domStorageActionPointer->setText(i18nc("DOM Storage action", "DOM Storage"));
153
154     // Set the action icons.
155     userAgentPrivacyBrowserActionPointer->setIcon(QIcon(":/icons/privacy-mode"));
156     userAgentWebEngineDefaultActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("user-group-properties")));
157     userAgentFirefoxLinuxActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("firefox-esr")));
158     userAgentChromiumLinuxActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("chromium")));
159     userAgentFirefoxWindowsActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("firefox-esr")));
160     userAgentChromeWindowsActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("chromium")));
161     userAgentEdgeWindowsActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("user-group-properties")));
162     userAgentSafariMacosActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("user-group-properties")));
163     userAgentCustomActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("user-group-properties")));
164     searchEngineMojeekActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("search")));
165     searchEngineMonoclesActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("search")));
166     searchEngineMetagerActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("search")));
167     searchEngineGoogleActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("im-google")));
168     searchEngineBingActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("search")));
169     searchEngineYahooActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("im-yahoo")));
170     searchEngineCustomActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("search")));
171     zoomFactorActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("zoom")));
172     domainSettingsActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("settings-configure")));
173     cookiesActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("preferences-web-browser-cookies")));
174     domStorageActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("view-web-browser-dom-tree")));
175
176     // Update the on-the-fly menus.
177     connect(browserViewPointer, SIGNAL(updateUserAgentActions(QString)), this, SLOT(updateUserAgentActions(QString)));
178     connect(browserViewPointer, SIGNAL(updateZoomFactorAction(double)), this, SLOT(updateZoomFactorAction(double)));
179     connect(browserViewPointer, SIGNAL(updateSearchEngineActions(QString)), this, SLOT(updateSearchEngineActions(QString)));
180
181     // Apply the on-the-fly settings when selected.
182     connect(userAgentActionGroupPointer, SIGNAL(triggered(QAction*)), browserViewPointer, SLOT(applyOnTheFlyUserAgent(QAction*)));
183     connect(searchEngineActionGroupPointer, SIGNAL(triggered(QAction*)), browserViewPointer, SLOT(applyOnTheFlySearchEngine(QAction*)));
184
185     // Display dialogs.
186     connect(zoomFactorActionPointer, SIGNAL(triggered()), this, SLOT(getZoomFactorFromUser()));
187     connect(cookiesActionPointer, SIGNAL(triggered()), this, SLOT(openCookiesDialog()));
188     connect(domainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(openDomainSettings()));
189
190     // Connect the URL toolbar actions.
191     connect(javaScriptActionPointer, SIGNAL(triggered()), this, SLOT(toggleJavaScript()));
192     connect(localStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleLocalStorage()));
193     connect(domStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleDomStorage()));
194
195     // Update the URL toolbar actions.
196     connect(browserViewPointer, SIGNAL(updateBackAction(bool)), backActionPointer, SLOT(setEnabled(bool)));
197     connect(browserViewPointer, SIGNAL(updateForwardAction(bool)), forwardActionPointer, SLOT(setEnabled(bool)));
198     connect(browserViewPointer, SIGNAL(updateJavaScriptAction(bool)), this, SLOT(updateJavaScriptAction(bool)));
199     connect(browserViewPointer, SIGNAL(updateLocalStorageAction(bool)), this, SLOT(updateLocalStorageAction(bool)));
200     connect(browserViewPointer, SIGNAL(updateDomStorageAction(bool)), this, SLOT(updateDomStorageAction(bool)));
201
202     // Setup the GUI based on the browser_ui.rc file.
203     setupGUI(StandardWindowOption::Default, ("browser_ui.rc"));
204
205     // Get a handle for the URL toolbar.
206     KToolBar *urlToolBarPointer = toolBar(QStringLiteral("url_toolbar"));
207
208     // Create a URL line edit.
209     urlLineEditPointer = new KLineEdit();
210
211     // Add an edit or add domain settings action to the URL line edit.
212     QAction *addOrEditDomainSettingsActionPointer = urlLineEditPointer->addAction(QIcon::fromTheme("settings-configure"), QLineEdit::TrailingPosition);
213
214     // Add or edit the current domain settings.
215     connect(addOrEditDomainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(addOrEditDomainSettings()));
216
217     // Populate the URL toolbar.
218     urlToolBarPointer->insertWidget(javaScriptActionPointer, urlLineEditPointer);
219
220     // Load a new URL from the URL line edit.
221     connect(urlLineEditPointer, SIGNAL(returnKeyPressed(const QString)), this, SLOT(loadUrlFromLineEdit(const QString)));
222
223     // Update the URL line edit on page loads.
224     connect(browserViewPointer, SIGNAL(updateUrlLineEdit(QUrl)), this, SLOT(updateUrlLineEdit(QUrl)));
225
226     // Get a handle for the status bar.
227     QStatusBar *statusBarPointer = statusBar();
228
229     // Create a progress bar.
230     progressBarPointer = new QProgressBar();
231
232     // Add the progress bar to to the status bar.
233     statusBarPointer->addPermanentWidget(progressBarPointer);
234
235     // Update the status bar with the URL when a link is hovered.
236     connect(browserViewPointer, SIGNAL(linkHovered(QString)), statusBarPointer, SLOT(showMessage(QString)));
237
238     // Update the progress bar.
239     connect(browserViewPointer, SIGNAL(showProgressBar(const int)), this, SLOT(showProgressBar(const int)));
240     connect(browserViewPointer, SIGNAL(hideProgressBar()), progressBarPointer, SLOT(hide()));
241
242     // Clear the URL line edit focus when requested.
243     connect(browserViewPointer, SIGNAL(clearUrlLineEditFocus()), this, SLOT(clearUrlLineEditFocus()));
244
245     // Get the URL line edit palettes.
246     noDomainSettingsPalette = urlLineEditPointer->palette();
247     domainSettingsPalette = urlLineEditPointer->palette();
248
249     // Modify the domain settings palette.
250     domainSettingsPalette.setColor(QPalette::Base, QColor("#C8E6C9"));
251
252     // Update the applied palette.
253     connect(browserViewPointer, SIGNAL(updateDomainSettingsIndicator(bool, QString)), this, SLOT(updateDomainSettingsIndicator(bool, QString)));
254
255     // Process cookie changes.
256     connect(browserViewPointer, SIGNAL(addCookie(QNetworkCookie)), this, SLOT(addCookieToList(QNetworkCookie)));
257     connect(browserViewPointer, SIGNAL(removeCookie(QNetworkCookie)), this, SLOT(removeCookieFromList(QNetworkCookie)));
258
259     // Load the initial website.
260     browserViewPointer->loadInitialWebsite();
261 }
262
263 void BrowserWindow::addCookieToList(const QNetworkCookie &newCookie) const
264 {
265     qDebug() << "Add cookie:  " << newCookie.toRawForm();
266
267     // Add the new cookie to the list.
268     cookieListPointer->push_front(newCookie);
269
270     // Update the action text.
271     cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", cookieListPointer->size()));
272
273     // Update the cookie if it is durable and has new data.
274     if (CookiesDatabase::isUpdate(newCookie))
275         CookiesDatabase::updateCookie(newCookie);
276 }
277
278 void BrowserWindow::addOrEditDomainSettings() const
279 {
280     // Remove the focus from the URL line edit.
281     urlLineEditPointer->clearFocus();
282
283     // Create the domain settings dialog pointer.
284     DomainSettingsDialog *domainSettingsDialogPointer;
285
286     // Run the commands according to the current domain settings status.
287     if (currentDomainSettingsDomain == "")  // Domain settings are not currently applied.
288     {
289         // Instruct the domain settings dialog to add a new domain.
290         domainSettingsDialogPointer = new DomainSettingsDialog(DomainSettingsDialog::ADD_DOMAIN, currentUrl.host());
291     }
292     else  // Domain settings are currently applied.
293     {
294         // Instruct the domain settings dialog to edit the current domain.
295         domainSettingsDialogPointer = new DomainSettingsDialog(DomainSettingsDialog::EDIT_DOMAIN, currentDomainSettingsDomain);
296     }
297
298     // Set the dialog window title.
299     domainSettingsDialogPointer->setWindowTitle(i18nc("The domain settings dialog title", "Domain Settings"));
300
301     // Set the modality.
302     domainSettingsDialogPointer->setWindowModality(Qt::WindowModality::WindowModal);;
303
304     // Show the dialog.
305     domainSettingsDialogPointer->show();
306
307     // Reload the tabs when domain settings are updated.
308     connect(domainSettingsDialogPointer, SIGNAL(domainSettingsUpdated()), browserViewPointer, SLOT(applyDomainSettingsAndReload()));
309 }
310
311 void BrowserWindow::back() const
312 {
313     // Remove the focus from the URL line edit.
314     urlLineEditPointer->clearFocus();
315
316     // Go back.
317     browserViewPointer->back();
318 }
319
320 void BrowserWindow::clearUrlLineEditFocus() const
321 {
322     // Remove the focus from the URL line edit.
323     urlLineEditPointer->clearFocus();
324 }
325
326 void BrowserWindow::fileNew() const
327 {
328     // Display a new instance of Privacy Browser.
329     (new BrowserWindow)->show();
330 }
331
332 void BrowserWindow::forward() const
333 {
334     // Remove the focus from the URL line edit.
335     urlLineEditPointer->clearFocus();
336
337     // Go forward.
338     browserViewPointer->forward();
339 }
340
341 void BrowserWindow::getZoomFactorFromUser()
342 {
343     // Create an OK flag.
344     bool okClicked;
345
346     // 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.
347     double newZoomFactor = QInputDialog::getDouble(this, i18nc("The on-the-fly zoom factor dialog title", "On-The-Fly Zoom Factor"),
348                                                    i18nc("The instruction text of the on-the-fly zoom factor dialog", "Enter a zoom factor between 0.25 and 5.00"),
349                                                    currentZoomFactor, .025, 5.00, 2, &okClicked, Qt::WindowFlags(), 0.25);
350
351     // Update the zoom factor if the user clicked OK.
352     if (okClicked)
353     {
354         // Update the current zoom factor.
355         currentZoomFactor = newZoomFactor;
356
357         // Set the new zoom factor.
358         browserViewPointer->applyOnTheFlyZoomFactor(newZoomFactor);
359
360         // Update the on-the-fly action text.
361         updateZoomFactorAction(newZoomFactor);
362     }
363 }
364
365 void BrowserWindow::home() const
366 {
367     // Remove the focus from the URL line edit.
368     urlLineEditPointer->clearFocus();
369
370     // Go home.
371     browserViewPointer->home();
372 }
373
374 void BrowserWindow::loadUrlFromLineEdit(const QString &url) const
375 {
376     // Remove the focus from the URL line edit.
377     urlLineEditPointer->clearFocus();
378
379     // Load the URL.
380     browserViewPointer->loadUrlFromLineEdit(url);
381 }
382
383 void BrowserWindow::openCookiesDialog()
384 {
385     // Remove the focus from the URL line edit.
386     urlLineEditPointer->clearFocus();
387
388     // Instantiate the cookie settings dialog.
389     CookiesDialog *cookiesDialogPointer = new CookiesDialog(cookieListPointer);
390
391     // Show the dialog.
392     cookiesDialogPointer->show();
393
394     // Connect the dialog signals.
395     connect(cookiesDialogPointer, SIGNAL(addCookie(QNetworkCookie)), browserViewPointer, SLOT(addCookieToStore(QNetworkCookie)));
396     connect(cookiesDialogPointer, SIGNAL(deleteAllCookies()), browserViewPointer, SLOT(deleteAllCookies()));
397     connect(cookiesDialogPointer, SIGNAL(deleteCookie(QNetworkCookie)), browserViewPointer, SLOT(deleteCookieFromStore(QNetworkCookie)));
398 }
399
400 void BrowserWindow::openDomainSettings() const
401 {
402     // Remove the focus from the URL line edit.
403     urlLineEditPointer->clearFocus();
404
405     // Instantiate the domain settings dialog.
406     DomainSettingsDialog *domainSettingsDialogPointer = new DomainSettingsDialog();
407
408     // Show the dialog.
409     domainSettingsDialogPointer->show();
410
411     // Reload the tabs when domain settings are updated.
412     connect(domainSettingsDialogPointer, SIGNAL(domainSettingsUpdated()), browserViewPointer, SLOT(applyDomainSettingsAndReload()));
413 }
414
415 void BrowserWindow::refresh() const
416 {
417     // Remove the focus from the URL line edit.
418     urlLineEditPointer->clearFocus();
419
420     // Refresh the web page.
421     browserViewPointer->refresh();
422 }
423
424 void BrowserWindow::removeCookieFromList(const QNetworkCookie &cookie) const
425 {
426     qDebug() << "Remove cookie:  " << cookie.toRawForm();
427
428     // Remove the cookie from the list.
429     cookieListPointer->remove(cookie);
430
431     // Update the action text.
432     cookiesActionPointer->setText(i18nc("The Cookies action, which also displays the number of cookies", "Cookies - %1", cookieListPointer->size()));
433 }
434
435 void BrowserWindow::showProgressBar(const int &progress) const
436 {
437     // Set the progress bar value.
438     progressBarPointer->setValue(progress);
439
440     // Show the progress bar.
441     progressBarPointer->show();
442 }
443
444 QSize BrowserWindow::sizeHint() const
445 {
446     // Return the default window size.
447     return QSize(1500, 1200);
448 }
449
450 void BrowserWindow::settingsConfigure()
451 {
452     // Check to make sure the dialog box isn't already displayed.
453     if (KConfigDialog::exists(QStringLiteral("settings")))
454     {
455         // Show the existing config dialog if it is hidden.
456         configDialogPointer->show();
457
458         // Raise the existing config dialog if it is below other windows.
459         configDialogPointer->raise();
460
461         // Restore the existing config dialog if it has been minimized.
462         if (configDialogPointer->isMinimized()) {
463             configDialogPointer->showNormal();
464         }
465
466         // Activate the existing config dialog, which brings its virtual desktop into focus.
467         configDialogPointer->activateWindow();
468     }
469     else
470     {
471         // Create the settings widgets.
472         QWidget *privacySettingsWidgetPointer = new QWidget;
473         QWidget *generalSettingsWidgetPointer = new QWidget;
474
475         // Instantiate the settings UI.
476         Ui::PrivacySettings privacySettingsUi;
477         Ui::GeneralSettings generalSettingsUi;
478
479         // Setup the UI to display the settings widgets.
480         privacySettingsUi.setupUi(privacySettingsWidgetPointer);
481         generalSettingsUi.setupUi(generalSettingsWidgetPointer);
482
483         // Get handles for the widgets.
484         QComboBox *userAgentComboBoxPointer = privacySettingsUi.kcfg_userAgent;
485         userAgentLabelPointer = privacySettingsUi.userAgentLabel;
486         QComboBox *searchEngineComboBoxPointer = generalSettingsUi.kcfg_searchEngine;
487         searchEngineLabelPointer = generalSettingsUi.searchEngineLabel;
488
489         // Populate the combo box labels.
490         updateUserAgentLabel(userAgentComboBoxPointer->currentText());
491         updateSearchEngineLabel(searchEngineComboBoxPointer->currentText());
492
493         // Update the labels when the combo boxes change.
494         connect(userAgentComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateUserAgentLabel(const QString)));
495         connect(searchEngineComboBoxPointer, SIGNAL(currentTextChanged(const QString)), this, SLOT(updateSearchEngineLabel(const QString)));
496
497         // Instantiate a settings config dialog from the settings.kcfg file.
498         configDialogPointer = new KConfigDialog(this, QStringLiteral("settings"), Settings::self());
499
500         // Add the settings widgets as config dialog pages.
501         configDialogPointer->addPage(privacySettingsWidgetPointer, i18nc("@title:tab", "Privacy"), QStringLiteral("privacy-browser"));
502         configDialogPointer->addPage(generalSettingsWidgetPointer, i18nc("@title:tab", "General"), QStringLiteral("breeze-settings"));
503
504         // Delete the config dialog when it is closed.
505         configDialogPointer->setAttribute(Qt::WA_DeleteOnClose);
506
507         // Make it so.
508         configDialogPointer->show();
509
510         // TODO.  KConfigDialog does not respect expanding size policies.  <https://redmine.stoutner.com/issues/823>
511         //configDialogPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
512         //privacySettingsWidgetPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
513         //generalSettingsWidgetPointer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
514         //configDialogPointer->adjustSize();
515
516         // Expand the config dialog.
517         configDialogPointer->resize(1000, 500);
518
519         // Apply the settings when they are updated.
520         connect(configDialogPointer, SIGNAL(settingsChanged(QString)), browserViewPointer, SLOT(applyApplicationSettings()));
521         connect(configDialogPointer, SIGNAL(settingsChanged(QString)), browserViewPointer, SLOT(applyDomainSettingsAndReload()));
522     }
523 }
524
525 void BrowserWindow::toggleLocalStorage() const
526 {
527     // Remove the focus from teh URL line edit.
528     urlLineEditPointer->clearFocus();
529
530     // Toggle local storage.
531     browserViewPointer->toggleLocalStorage();
532 }
533
534 void BrowserWindow::toggleJavaScript() const
535 {
536     // Remove the focus from the URL line edit.
537     urlLineEditPointer->clearFocus();
538
539     // Toggle JavaScript.
540     browserViewPointer->toggleJavaScript();
541 }
542
543 void BrowserWindow::toggleDomStorage() const
544 {
545     // Remove the focus from the URL line edit.
546     urlLineEditPointer->clearFocus();
547
548     // Toggle DOM storage.
549     browserViewPointer->toggleDomStorage();
550 }
551
552 void BrowserWindow::updateDomStorageAction(const bool &isEnabled) const
553 {
554     // Set the action checked status.
555     domStorageActionPointer->setChecked(isEnabled);
556 }
557
558 void BrowserWindow::updateDomainSettingsIndicator(const bool &status, const QString &domainSettingsDomain)
559 {
560     // Set the domain palette according to the status.
561     if (status)
562         urlLineEditPointer->setPalette(domainSettingsPalette);
563     else
564         urlLineEditPointer->setPalette(noDomainSettingsPalette);
565
566     // Store the domain.
567     currentDomainSettingsDomain = domainSettingsDomain;
568 }
569
570 void BrowserWindow::updateJavaScriptAction(const bool &isEnabled)
571 {
572     // Update the JavaScript status.
573     javaScriptEnabled = isEnabled;
574
575     // Set the icon according to the status.
576     if (javaScriptEnabled)
577         javaScriptActionPointer->setIcon(QIcon(QStringLiteral(":/icons/javascript-warning")));
578     else
579         javaScriptActionPointer->setIcon(QIcon(QStringLiteral(":/icons/privacy-mode")));
580
581     // Set the action checked status.
582     javaScriptActionPointer->setChecked(javaScriptEnabled);
583
584     // Update the status of the DOM storage action.
585     domStorageActionPointer->setEnabled(javaScriptEnabled & localStorageEnabled);
586 }
587
588 void BrowserWindow::updateLocalStorageAction(const bool &isEnabled)
589 {
590     // Update the local storage status.
591     localStorageEnabled = isEnabled;
592
593     // Update the icon.
594     if (localStorageEnabled)
595         localStorageActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("disk-quota-high")));
596     else
597         localStorageActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("disk-quota")));
598
599     // Set the action checked status.
600     localStorageActionPointer->setChecked(localStorageEnabled);
601
602     // Update the status of the DOM storage action.
603     domStorageActionPointer->setEnabled(localStorageEnabled & javaScriptEnabled);
604 }
605
606 void BrowserWindow::updateSearchEngineActions(const QString &searchEngine) const
607 {
608     // Initialize the custom search engine flag.
609     bool customSearchEngine = false;
610
611     if (searchEngine == "Mojeek")  // Mojeek.
612     {
613         searchEngineMojeekActionPointer->setChecked(true);
614     }
615     else if (searchEngine == "Monocles")  // Monocles.
616     {
617         searchEngineMonoclesActionPointer->setChecked(true);
618     }
619     else if (searchEngine == "MetaGer")  // MetaGer.
620     {
621         searchEngineMetagerActionPointer->setChecked(true);
622     }
623     else if (searchEngine == "Google")  // Google.
624     {
625         searchEngineGoogleActionPointer->setChecked(true);
626     }
627     else if (searchEngine == "Bing")  // Bing.
628     {
629         searchEngineBingActionPointer->setChecked(true);
630     }
631     else if (searchEngine == "Yahoo")  // Yahoo.
632     {
633         searchEngineYahooActionPointer->setChecked(true);
634     }
635     else  // Custom search engine.
636     {
637         // Check the user agent.
638         searchEngineCustomActionPointer->setChecked(true);
639
640         // Set the custom search engine flag.
641         customSearchEngine = true;
642     }
643
644     // Format the custom search engine.
645     if (customSearchEngine)
646     {
647         // Enable the custom search engine.
648         searchEngineCustomActionPointer->setEnabled(true);
649
650         // Set the custom search engine text.
651         searchEngineCustomActionPointer->setText(searchEngine);
652     }
653     else
654     {
655         // Disable the custom search engine.
656         searchEngineCustomActionPointer->setEnabled(false);
657
658         // Reset the custom search engine text.
659         searchEngineCustomActionPointer->setText(i18nc("@action", "Custom"));
660     }
661 }
662
663 void BrowserWindow::updateUserAgentActions(const QString &userAgent) const
664 {
665     // Initialize the custom user agent flag.
666     bool customUserAgent = false;
667
668     // Check the indicated on-the-fly user agent.
669     if (userAgent == UserAgentHelper::PRIVACY_BROWSER_USER_AGENT) userAgentPrivacyBrowserActionPointer->setChecked(true);  // Privacy Browser.
670     else if (userAgent == BrowserView::webEngineDefaultUserAgent) userAgentWebEngineDefaultActionPointer->setChecked(true);  // WebEngine default.
671     else if (userAgent == UserAgentHelper::FIREFOX_LINUX_USER_AGENT) userAgentFirefoxLinuxActionPointer->setChecked(true);  // Firefox Linux.
672     else if (userAgent == UserAgentHelper::CHROMIUM_LINUX_USER_AGENT) userAgentChromiumLinuxActionPointer->setChecked(true);  // Chromium Linux.
673     else if (userAgent == UserAgentHelper::FIREFOX_WINDOWS_USER_AGENT) userAgentFirefoxWindowsActionPointer->setChecked(true);  // Firefox Windows.
674     else if (userAgent == UserAgentHelper::CHROME_WINDOWS_USER_AGENT) userAgentChromeWindowsActionPointer->setChecked(true);  // Chrome Windows.
675     else if (userAgent == UserAgentHelper::EDGE_WINDOWS_USER_AGENT) userAgentEdgeWindowsActionPointer->setChecked(true);  // Edge Windows.
676     else if (userAgent == UserAgentHelper::SAFARI_MACOS_USER_AGENT) userAgentSafariMacosActionPointer->setChecked(true);  // Safara macOS.
677     else  // Custom user agent.
678     {
679         // Check the user agent.
680         userAgentCustomActionPointer->setChecked(true);
681
682         // Set the custom user agent flag.
683         customUserAgent = true;
684     }
685
686
687     // Format the custom user agent.
688     if (customUserAgent)
689     {
690         // Enable the custom user agent.
691         userAgentCustomActionPointer->setEnabled(true);
692
693         // Set the custom user agent text.
694         userAgentCustomActionPointer->setText(userAgent);
695     }
696     else
697     {
698         // Disable the custom user agent.
699         userAgentCustomActionPointer->setEnabled(false);
700
701         // Reset the custom user agent text.
702         userAgentCustomActionPointer->setText(i18nc("@action", "Custom"));
703     }
704 }
705
706 void BrowserWindow::updateZoomFactorAction(const double &zoomFactor)
707 {
708     // Set the current zoom factor.
709     currentZoomFactor = zoomFactor;
710
711     // Update the zoom factor action text, formatting the double with 2 decimal places.
712     zoomFactorActionPointer->setText(ki18nc("@action", "Zoom Factor - %1").subs(zoomFactor, 0, '0', 2).toString());
713 }
714
715 void BrowserWindow::updateSearchEngineLabel(const QString &searchEngineString) const
716 {
717     // Update the search engine label.
718     searchEngineLabelPointer->setText(SearchEngineHelper::getSearchUrl(searchEngineString));
719 }
720
721 void BrowserWindow::updateUrlLineEdit(const QUrl &newUrl)
722 {
723     // Update the URL line edit if it does not have focus.
724     if (!urlLineEditPointer->hasFocus())
725     {
726         // Update the URL line edit.
727         urlLineEditPointer->setText(newUrl.toString());
728     }
729
730     // Store the current URL.
731     currentUrl = newUrl;
732 }
733
734 void BrowserWindow::updateUserAgentLabel(const QString &userAgentDatabaseName) const
735 {
736     // Update the user agent label.
737     userAgentLabelPointer->setText(UserAgentHelper::getUserAgentFromDatabaseName(userAgentDatabaseName));
738 }