From 8933c941521c591a962034ecf3486c9143bf1f80 Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Tue, 19 Apr 2022 15:23:31 -0700 Subject: [PATCH] Initial Cookies implementation using a QVBoxLayout. --- src/CMakeLists.txt | 2 + src/dialogs/CMakeLists.txt | 1 + src/dialogs/CookiesDialog.cpp | 180 +++++++++++++++++ src/dialogs/CookiesDialog.h | 53 +++++ src/dialogs/DomainSettingsDialog.cpp | 13 +- src/filters/MouseEventFilter.h | 1 - src/ui.rc/browser_ui.rc | 1 + src/ui/BrowserView.ui | 2 +- src/ui/CookieWidget.ui | 287 +++++++++++++++++++++++++++ src/ui/CookiesDialog.ui | 94 +++++++++ src/ui/DomainSettingsDialog.ui | 8 +- src/views/BrowserView.cpp | 25 ++- src/views/BrowserView.h | 9 + src/windows/BrowserWindow.cpp | 57 +++++- src/windows/BrowserWindow.h | 4 +- 15 files changed, 714 insertions(+), 23 deletions(-) create mode 100644 src/dialogs/CookiesDialog.cpp create mode 100644 src/dialogs/CookiesDialog.h create mode 100644 src/ui/CookieWidget.ui create mode 100644 src/ui/CookiesDialog.ui diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4d33710..ea4fecb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -36,6 +36,8 @@ kconfig_add_kcfg_files(privacy-browser settings/Settings.kcfgc) # Use KDE Frameworks to handle internationalization of the following UI files. ki18n_wrap_ui(privacy-browser ui/BrowserView.ui + ui/CookiesDialog.ui + ui/CookieWidget.ui ui/DomainSettingsDialog.ui ui/SettingsGeneral.ui ui/SettingsPrivacy.ui diff --git a/src/dialogs/CMakeLists.txt b/src/dialogs/CMakeLists.txt index e2effdb..ee3d9ff 100644 --- a/src/dialogs/CMakeLists.txt +++ b/src/dialogs/CMakeLists.txt @@ -18,5 +18,6 @@ # List the sources to include in the executable. target_sources(privacy-browser PRIVATE + CookiesDialog.cpp DomainSettingsDialog.cpp ) diff --git a/src/dialogs/CookiesDialog.cpp b/src/dialogs/CookiesDialog.cpp new file mode 100644 index 0000000..3321c65 --- /dev/null +++ b/src/dialogs/CookiesDialog.cpp @@ -0,0 +1,180 @@ +/* + * Copyright © 2022 Soren Stoutner . + * + * This file is part of Privacy Browser PC . + * + * Privacy Browser PC is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Privacy Browser PC is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Privacy Browser PC. If not, see . + */ + +// Application headers. +#include "CookiesDialog.h" +#include "ui_CookiesDialog.h" +#include "ui_CookieWidget.h" + +// The KDE Frameworks headers. +#include + +// The Qt toolkit headers. +#include +#include + +CookiesDialog::CookiesDialog(QList *originalCookieListPointer) : QDialog(nullptr), cookieListPointer(originalCookieListPointer) +{ + // Set the dialog window title. + setWindowTitle(i18nc("The cookies dialog window title", "Cookies")); + + // Set the window modality. + setWindowModality(Qt::WindowModality::WindowModal); + + // Instantiate the cookie settings dialog UI. + Ui::CookiesDialog cookiesDialogUi; + + // Setup the UI. + cookiesDialogUi.setupUi(this); + + // Create the scroll area widget. + QWidget *scrollAreaWidgetPointer = new QWidget(); + + // Create the cookies VBox layout. + cookiesVBoxLayoutPointer = new QVBoxLayout(); + + // Populate the VBoxLayout. + for (QNetworkCookie cookie : *cookieListPointer) + { + // Create a cookie display widget. + QWidget *cookieDisplayWidgetPointer = new QWidget(); + + // Instantiate the cookie widget dialog UI. + Ui::CookieWidget cookieWidgetUi; + + // Setup the UI. + cookieWidgetUi.setupUi(cookieDisplayWidgetPointer); + + // Get handles for the views. + QLabel *domainLabelPointer = cookieWidgetUi.domainLabel; + QLabel *nameLabelPointer = cookieWidgetUi.nameLabel; + QLabel *expirationDateLabelPointer = cookieWidgetUi.expirationDateLabel; + QLabel *pathLabelPointer = cookieWidgetUi.pathLabel; + QCheckBox *httpOnlyCheckBoxPointer = cookieWidgetUi.httpOnlyCheckBox; + QCheckBox *secureCheckBoxPointer = cookieWidgetUi.secureCheckBox; + QLabel *valueLabelPointer = cookieWidgetUi.valueLabel; + + // Populate the views. + domainLabelPointer->setText("" + cookie.domain() + ""); + nameLabelPointer->setText("" + cookie.name() + ""); + expirationDateLabelPointer->setText("" + cookie.expirationDate().toString() + ""); + pathLabelPointer->setText("" + cookie.path() + ""); + httpOnlyCheckBoxPointer->setChecked(cookie.isHttpOnly()); + secureCheckBoxPointer->setChecked(cookie.isSecure()); + valueLabelPointer->setText("" + cookie.value() + ""); + + // Add the widget to the cookies VBox layout. + cookiesVBoxLayoutPointer->addWidget(cookieDisplayWidgetPointer); + + // Create a line. + QFrame *lineFrame = new QFrame(); + + // Format the line. + lineFrame->setFrameShape(QFrame::HLine); + lineFrame->setFrameShadow(QFrame::Sunken); + + // Add the line to the cookies VBox layout. + cookiesVBoxLayoutPointer->addWidget(lineFrame); + } + + // Set the scroll area widget layout. + scrollAreaWidgetPointer->setLayout(cookiesVBoxLayoutPointer); + + // Get a handle for the scroll area. + QScrollArea *scrollAreaPointer = cookiesDialogUi.scrollArea; + + // Set the scroll area widget. + scrollAreaPointer->setWidget(scrollAreaWidgetPointer); + + // Get handles for the buttons. + QDialogButtonBox *dialogButtonBoxPointer = cookiesDialogUi.dialogButtonBox; + QPushButton *cancelButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::Close); + + // Add a delete all button to the dialog button box. + deleteAllButtonPointer = dialogButtonBoxPointer->addButton(i18nc("Delete all cookies button", "Delete all"), QDialogButtonBox::ActionRole); + + // Set the delete all button icon. + deleteAllButtonPointer->setIcon(QIcon::fromTheme("delete")); + + // Connect the buttons. + connect(deleteAllButtonPointer, SIGNAL(released()), this, SLOT(showDeleteAllMessageBox())); + connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject())); + + // Set the cancel button to be the default. + cancelButtonPointer->setDefault(true); + + // Update the UI. + updateUi(); +}; + +void CookiesDialog::showDeleteAllMessageBox() const +{ + // Instantiate a delete all message box. + QMessageBox deleteAllCookiesMessageBox; + + // Set the icon. + deleteAllCookiesMessageBox.setIcon(QMessageBox::Warning); + + // Set the window title. + deleteAllCookiesMessageBox.setWindowTitle(i18nc("Delete all cookies dialog title", "Delete All Cookies")); + + // Set the text. + deleteAllCookiesMessageBox.setText(i18nc("Delete all cookies dialog text", "Delete all cookies?")); + + // Set the standard buttons. + deleteAllCookiesMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + + // Set the default button. + deleteAllCookiesMessageBox.setDefaultButton(QMessageBox::No); + + // Display the dialog and capture the return value. + int returnValue = deleteAllCookiesMessageBox.exec(); + + // Delete all cookies if instructed. + if (returnValue == QMessageBox::Yes) + { + // Delete all the cookies. + emit deleteAllCookies(); + + // Clear the cookie list. + cookieListPointer->clear(); + + // Create a layout item pointer. + QLayoutItem *layoutItemPointer; + + // Delete each cookie widget. + while ((layoutItemPointer = cookiesVBoxLayoutPointer->takeAt(0)) != nullptr) + { + // Delete the widget. + delete layoutItemPointer->widget(); + + // Delete the layout. + delete layoutItemPointer; + } + + // Update the UI. + updateUi(); + } +} + +void CookiesDialog::updateUi() const +{ + // Set the status of the buttons. + deleteAllButtonPointer->setEnabled(cookieListPointer->count() > 0); +} diff --git a/src/dialogs/CookiesDialog.h b/src/dialogs/CookiesDialog.h new file mode 100644 index 0000000..17498ca --- /dev/null +++ b/src/dialogs/CookiesDialog.h @@ -0,0 +1,53 @@ +/* + * Copyright © 2022 Soren Stoutner . + * + * This file is part of Privacy Browser PC . + * + * Privacy Browser PC is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Privacy Browser PC is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Privacy Browser PC. If not, see . + */ + +#ifndef COOKIESDIALOG_H +#define COOKIESDIALOG_H + +// Qt toolkit headers. +#include +#include +#include + +class CookiesDialog : public QDialog +{ + // Include the Q_OBJECT macro. + Q_OBJECT + +public: + // The default constructor. + explicit CookiesDialog(QList *cookieListPointer); + +signals: + void deleteAllCookies() const; + +private Q_SLOTS: + // The private slots. + void showDeleteAllMessageBox() const; + +private: + // The private variables. + QList *cookieListPointer; + QVBoxLayout *cookiesVBoxLayoutPointer; + QPushButton *deleteAllButtonPointer; + + // The private functions. + void updateUi() const; +}; +#endif diff --git a/src/dialogs/DomainSettingsDialog.cpp b/src/dialogs/DomainSettingsDialog.cpp index b5be32a..42c713a 100644 --- a/src/dialogs/DomainSettingsDialog.cpp +++ b/src/dialogs/DomainSettingsDialog.cpp @@ -36,7 +36,13 @@ const int DomainSettingsDialog::EDIT_DOMAIN = 2; DomainSettingsDialog::DomainSettingsDialog(const int &startType, const QString &domainName) : QDialog(nullptr) { - // Instantiate the domain settings view UI. + // Set the window title. + setWindowTitle(i18nc("The domain settings dialog window title", "Domain Settings")); + + // Set the window modality. + setWindowModality(Qt::WindowModality::WindowModal);; + + // Instantiate the domain settings dialog UI. Ui::DomainSettingsDialog domainSettingsDialogUi; // Setup the UI. @@ -440,10 +446,10 @@ void DomainSettingsDialog::showDeleteMessageBox() const deleteDialogMessageBox.setWindowTitle(i18nc("Delete domain dialog title", "Delete Domain")); // Set the text. - deleteDialogMessageBox.setText(i18nc("Delete domain main message", "Delete the current domain?")); + deleteDialogMessageBox.setText(i18nc("Delete domain dialog main message", "Delete the current domain?")); // Set the informative text. - deleteDialogMessageBox.setInformativeText(i18nc("Delete domain secondary message", "Doing so will also save any pending changes that have been made to other domains.")); + deleteDialogMessageBox.setInformativeText(i18nc("Delete domain dialog secondary message", "Doing so will also save any pending changes that have been made to other domains.")); // Set the standard buttons. deleteDialogMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); @@ -454,6 +460,7 @@ void DomainSettingsDialog::showDeleteMessageBox() const // Display the dialog and capture the return value. int returnValue = deleteDialogMessageBox.exec(); + // Delete the domain if instructed. if (returnValue == QMessageBox::Yes) { // Get the current index. diff --git a/src/filters/MouseEventFilter.h b/src/filters/MouseEventFilter.h index 02e1b2d..4e4cc4f 100644 --- a/src/filters/MouseEventFilter.h +++ b/src/filters/MouseEventFilter.h @@ -22,7 +22,6 @@ // Qt headers. #include -#include class MouseEventFilter : public QObject { diff --git a/src/ui.rc/browser_ui.rc b/src/ui.rc/browser_ui.rc index 4c42e77..e75b573 100644 --- a/src/ui.rc/browser_ui.rc +++ b/src/ui.rc/browser_ui.rc @@ -61,6 +61,7 @@ + diff --git a/src/ui/BrowserView.ui b/src/ui/BrowserView.ui index 11219fa..26ba072 100644 --- a/src/ui/BrowserView.ui +++ b/src/ui/BrowserView.ui @@ -21,7 +21,7 @@ BrowserView - + diff --git a/src/ui/CookieWidget.ui b/src/ui/CookieWidget.ui new file mode 100644 index 0000000..efad03a --- /dev/null +++ b/src/ui/CookieWidget.ui @@ -0,0 +1,287 @@ + + + + + + CookieWidget + + + + + + + Qt::AlignLeft + + + + + + + Cookies prepended by a period are accessible to all subdomains. + + + + Qt::RichText + + + + <font size="+1">Domain:&nbsp;</font> + + + + + + + + Cookies prepended by a period are accessible to all subdomains. + + + + Qt::RichText + + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + The identifier of the cookie, which is unique when combined with the domain and the path. + + + + Qt::RichText + + + + <font size="+1">&nbsp;&nbsp;&nbsp;&nbsp;Name:&nbsp;</font> + + + + + + + + The identifier of the cookie, which is unique when combined with the domain and the path. + + + + Qt::RichText + + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + Qt::AlignLeft + + + + + + + Cookies without an expiration date are known as session cookies and are expected to be deleted every time the browser closes. + + + + Qt::RichText + + + + Expiration date:&nbsp; + + + + + + + + Cookies without an expiration date are known as session cookies and are expected to be deleted every time the browser closes. + + + + Qt::RichText + + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + Websites can restrict access to only a subpath of their URL. + + + + Qt::RichText + + + + &nbsp;&nbsp;&nbsp;&nbsp;Path:&nbsp; + + + + + + + + Websites can restrict access to only a subpath of their URL. + + + + Qt::RichText + + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + Qt::RichText + + + + &nbsp;&nbsp;&nbsp;&nbsp; + + + + + + + + + Restrict cookie access to HTTP (and HTTPS). This prevents JavaScript from accessing the cookie, which hardens it against cross-site scripting attacks. + + + + false + + + + + + + + Restrict cookie access to HTTP (and HTTPS). This prevents JavaScript from accessing the cookie, which hardens it against cross-site scripting attacks. + + + + Qt::RichText + + + + HTTP only&nbsp;&nbsp;&nbsp;&nbsp; + + + + + + + + + Only allow the cookie to be transferred across HTTPS (as opposed to HTTP). + + + + false + + + + + + + + Only allow the cookie to be transferred across HTTPS (as opposed to HTTP). + + + + Secure + + + + + + + + + + Qt::AlignLeft + + + + + + + The value contains the cookie data. + + + + Qt::RichText + + + + Value:&nbsp; + + + + + + + + The value contains the cookie data. + + + + true + + + + Qt::RichText + + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + diff --git a/src/ui/CookiesDialog.ui b/src/ui/CookiesDialog.ui new file mode 100644 index 0000000..69773c1 --- /dev/null +++ b/src/ui/CookiesDialog.ui @@ -0,0 +1,94 @@ + + + + + + CookiesDialog + + + + + + 0 + 0 + 1000 + 1500 + + + + + + + + + + + + + + + + Add cookie + + + + + + + + + + + + + Edit cookie + + + + + + + + + + + + + Delete cookie + + + + + + + + + + + + + QDialogButtonBox::Close + + + + + + + + diff --git a/src/ui/DomainSettingsDialog.ui b/src/ui/DomainSettingsDialog.ui index c39047c..ae9322d 100644 --- a/src/ui/DomainSettingsDialog.ui +++ b/src/ui/DomainSettingsDialog.ui @@ -21,7 +21,7 @@ DomainSettingsDialog - + 0 @@ -47,11 +47,11 @@ - Add Domain + Add domain - + @@ -64,7 +64,7 @@ - + diff --git a/src/views/BrowserView.cpp b/src/views/BrowserView.cpp index 873b947..07ce5f5 100644 --- a/src/views/BrowserView.cpp +++ b/src/views/BrowserView.cpp @@ -30,7 +30,6 @@ // Qt framework headers. #include -#include // Initialize the public static variables. QString BrowserView::webEngineDefaultUserAgent = QStringLiteral(""); @@ -50,7 +49,7 @@ BrowserView::BrowserView(QWidget *parent) : QWidget(parent) webEngineProfilePointer = new QWebEngineProfile(QStringLiteral("")); // Create a WebEngine page. - QWebEnginePage *webEnginePagePointer = new QWebEnginePage(webEngineProfilePointer); + webEnginePagePointer = new QWebEnginePage(webEngineProfilePointer); // Set the WebEngine page. webEngineViewPointer->setPage(webEnginePagePointer); @@ -58,6 +57,10 @@ BrowserView::BrowserView(QWidget *parent) : QWidget(parent) // Get handles for the aspects of the WebEngine. webEngineHistoryPointer = webEnginePagePointer->history(); webEngineSettingsPointer = webEngineViewPointer->settings(); + webEngineCookieStorePointer = webEngineProfilePointer->cookieStore(); + + // Store a copy of each cookie when it is added. + connect(webEngineCookieStorePointer, SIGNAL(cookieAdded(QNetworkCookie)), this, SLOT(cookieAdded(QNetworkCookie))); // Store a copy of the WebEngine default user agent. webEngineDefaultUserAgent = webEngineProfilePointer->httpUserAgent(); @@ -111,6 +114,12 @@ BrowserView::BrowserView(QWidget *parent) : QWidget(parent) webEngineViewPointer->setFocus(); } +BrowserView::~BrowserView() +{ + // Delay the deletion of the WebEngine page to prevent the following error: `Release of profile requested but WebEnginePage still not deleted. Expect troubles !` + webEnginePagePointer->deleteLater(); +} + void BrowserView::applyApplicationSettings() { // Set the search engine URL. @@ -302,6 +311,18 @@ void BrowserView::back() const webEngineViewPointer->back(); } +void BrowserView::cookieAdded(const QNetworkCookie &cookie) const +{ + // Add the cookie to the cookie list. + emit addCookie(cookie); +} + +void BrowserView::deleteAllCookies() const +{ + // Delete all the cookies. + webEngineCookieStorePointer->deleteAllCookies(); +} + void BrowserView::forward() const { // Go forward. diff --git a/src/views/BrowserView.h b/src/views/BrowserView.h index 29ae93c..0a88a2c 100644 --- a/src/views/BrowserView.h +++ b/src/views/BrowserView.h @@ -26,6 +26,7 @@ // Qt framework headers. #include #include +#include #include #include @@ -38,6 +39,9 @@ public: // The primary contructor. explicit BrowserView(QWidget *parent); + // The destructor. + ~BrowserView(); + // The public functions. void applyOnTheFlyZoomFactor(const double &zoomFactor); void loadInitialWebsite(); @@ -49,6 +53,7 @@ public: signals: // The signals. + void addCookie(const QNetworkCookie &cookie) const; void clearUrlLineEditFocus() const; void hideProgressBar() const; void linkHovered(const QString &linkUrl) const; @@ -71,6 +76,7 @@ public Q_SLOTS: void applyOnTheFlySearchEngine(QAction *searchEngineActionPointer); void applyOnTheFlyUserAgent(QAction *userAgentActionPointer) const; void back() const; + void deleteAllCookies() const; void forward() const; void home() const; void loadUrlFromLineEdit(QString url) const; @@ -80,6 +86,7 @@ public Q_SLOTS: private Q_SLOTS: // The private slots. + void cookieAdded(const QNetworkCookie &cookie) const; void loadFinished() const; void loadProgress(const int &progress) const; void loadStarted() const; @@ -90,7 +97,9 @@ private: // The private variables. double currentZoomFactor; // This can be removed once has been resolved. QString searchEngineUrl; + QWebEngineCookieStore *webEngineCookieStorePointer; QWebEngineHistory *webEngineHistoryPointer; + QWebEnginePage *webEnginePagePointer; QWebEngineProfile *webEngineProfilePointer; QWebEngineSettings *webEngineSettingsPointer; QWebEngineView *webEngineViewPointer; diff --git a/src/windows/BrowserWindow.cpp b/src/windows/BrowserWindow.cpp index 3ddba02..3293f02 100644 --- a/src/windows/BrowserWindow.cpp +++ b/src/windows/BrowserWindow.cpp @@ -22,6 +22,7 @@ #include "Settings.h" #include "ui_SettingsPrivacy.h" #include "ui_SettingsGeneral.h" +#include "dialogs/CookiesDialog.h" #include "dialogs/DomainSettingsDialog.h" #include "helpers/SearchEngineHelper.h" #include "helpers/UserAgentHelper.h" @@ -32,6 +33,7 @@ // Qt toolkit headers. #include +#include #include BrowserWindow::BrowserWindow() : KXmlGuiWindow() @@ -72,9 +74,10 @@ BrowserWindow::BrowserWindow() : KXmlGuiWindow() searchEngineBingActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_bing")); searchEngineYahooActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_yahoo")); searchEngineCustomActionPointer = actionCollectionPointer->addAction(QStringLiteral("search_engine_custom")); + QAction *domainSettingsActionPointer = actionCollectionPointer->addAction(QStringLiteral("domain_settings")); + QAction *cookiesActionPointer = actionCollectionPointer->addAction(QStringLiteral("cookies")); javaScriptActionPointer = actionCollectionPointer->addAction(QStringLiteral("javascript")); localStorageActionPointer = actionCollectionPointer->addAction(QStringLiteral("local_storage")); - domainSettingsActionPointer = actionCollectionPointer->addAction(QStringLiteral("domain_settings")); // Create the action groups QActionGroup *userAgentActionGroupPointer = new QActionGroup(this); @@ -131,9 +134,10 @@ BrowserWindow::BrowserWindow() : KXmlGuiWindow() searchEngineGoogleActionPointer->setText(i18nc("Search engine", "Google")); searchEngineBingActionPointer->setText(i18nc("Search engine", "Bing")); searchEngineYahooActionPointer->setText(i18nc("Search engine", "Yahoo")); - javaScriptActionPointer->setText(i18nc("JavaScript button", "JavaScript")); - localStorageActionPointer->setText(i18nc("Local Storage Button", "Local Storage")); - domainSettingsActionPointer->setText(i18nc("Domain Settings button", "Domain Settings")); + domainSettingsActionPointer->setText(i18nc("Domain Settings action", "Domain Settings")); + cookiesActionPointer->setText(i18nc("Cookies action", "Cookies")); + javaScriptActionPointer->setText(i18nc("JavaScript action", "JavaScript")); + localStorageActionPointer->setText(i18nc("Local Storage action", "Local Storage")); // Set the action icons. userAgentPrivacyBrowserActionPointer->setIcon(QIcon(":/icons/privacy-mode")); @@ -154,6 +158,7 @@ BrowserWindow::BrowserWindow() : KXmlGuiWindow() searchEngineCustomActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("search"))); zoomFactorActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("zoom"))); domainSettingsActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("settings-configure"))); + cookiesActionPointer->setIcon(QIcon::fromTheme(QStringLiteral("preferences-web-browser-cookies"))); // Update the on-the-fly menus. connect(browserViewPointer, SIGNAL(updateUserAgentActions(QString)), this, SLOT(updateUserAgentActions(QString))); @@ -166,11 +171,12 @@ BrowserWindow::BrowserWindow() : KXmlGuiWindow() // Display dialogs. connect(zoomFactorActionPointer, SIGNAL(triggered()), this, SLOT(getZoomFactorFromUser())); + connect(cookiesActionPointer, SIGNAL(triggered()), this, SLOT(openCookiesDialog())); + connect(domainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(openDomainSettings())); // Connect the URL toolbar actions. connect(javaScriptActionPointer, SIGNAL(triggered()), this, SLOT(toggleJavaScript())); connect(localStorageActionPointer, SIGNAL(triggered()), this, SLOT(toggleLocalStorage())); - connect(domainSettingsActionPointer, SIGNAL(triggered()), this, SLOT(openDomainSettings())); // Update the URL toolbar actions. connect(browserViewPointer, SIGNAL(updateBackAction(bool)), backActionPointer, SLOT(setEnabled(bool))); @@ -231,10 +237,29 @@ BrowserWindow::BrowserWindow() : KXmlGuiWindow() // Update the applied palette. connect(browserViewPointer, SIGNAL(updateDomainSettingsIndicator(bool, QString)), this, SLOT(updateDomainSettingsIndicator(bool, QString))); + // Initialize the cookie list. + cookieListPointer = new QList; + + // Add new cookies to the list. + connect(browserViewPointer, SIGNAL(addCookie(QNetworkCookie)), this, SLOT(addCookie(QNetworkCookie))); + // Load the initial website. browserViewPointer->loadInitialWebsite(); } +void BrowserWindow::addCookie(const QNetworkCookie &newCookie) const +{ + // Check to see if the list already contains a cookie with this ID. + for (QNetworkCookie existingCookie : *cookieListPointer) + { + // Remove the old version of the cookie. + if (existingCookie.hasSameIdentifier(newCookie)) cookieListPointer->removeOne(existingCookie); + } + + // Add the new cookie to the list. + cookieListPointer->append(newCookie); +} + void BrowserWindow::addOrEditDomainSettings() const { // Remove the focus from the URL line edit. @@ -340,6 +365,22 @@ void BrowserWindow::loadUrlFromLineEdit(const QString &url) const browserViewPointer->loadUrlFromLineEdit(url); } +void BrowserWindow::openCookiesDialog() +{ + // Remove the focus from the URL line edit. + urlLineEditPointer->clearFocus(); + + // Instantiate the cookie settings dialog. + CookiesDialog *cookiesDialogPointer = new CookiesDialog(cookieListPointer); + + // Show the dialog. + cookiesDialogPointer->show(); + + // Connect the dialog signals. + connect(cookiesDialogPointer, SIGNAL(deleteAllCookies()), browserViewPointer, SLOT(deleteAllCookies())); +} + + void BrowserWindow::openDomainSettings() const { // Remove the focus from the URL line edit. @@ -348,12 +389,6 @@ void BrowserWindow::openDomainSettings() const // Instantiate the domain settings dialog. DomainSettingsDialog *domainSettingsDialogPointer = new DomainSettingsDialog(); - // Set the dialog window title. - domainSettingsDialogPointer->setWindowTitle(i18nc("The domain settings dialog title", "Domain Settings")); - - // Set the modality. - domainSettingsDialogPointer->setWindowModality(Qt::WindowModality::WindowModal);; - // Show the dialog. domainSettingsDialogPointer->show(); diff --git a/src/windows/BrowserWindow.h b/src/windows/BrowserWindow.h index 60dea63..6995efc 100644 --- a/src/windows/BrowserWindow.h +++ b/src/windows/BrowserWindow.h @@ -45,6 +45,7 @@ public: private Q_SLOTS: // The private slots. + void addCookie(const QNetworkCookie &newCookie) const; void addOrEditDomainSettings() const; void back() const; void clearUrlLineEditFocus() const; @@ -53,6 +54,7 @@ private Q_SLOTS: void getZoomFactorFromUser(); void home() const; void loadUrlFromLineEdit(const QString &url) const; + void openCookiesDialog(); void openDomainSettings() const; void refresh() const; void settingsConfigure(); @@ -73,10 +75,10 @@ private: // The private variables. BrowserView *browserViewPointer; KConfigDialog *configDialogPointer; + QList *cookieListPointer; QString currentDomainSettingsDomain; QUrl currentUrl; double currentZoomFactor; - QAction *domainSettingsActionPointer; QPalette domainSettingsPalette; QAction *javaScriptActionPointer; QAction *localStorageActionPointer; -- 2.45.2