Initial Cookies implementation using a QVBoxLayout.
authorSoren Stoutner <soren@stoutner.com>
Tue, 19 Apr 2022 22:23:31 +0000 (15:23 -0700)
committerSoren Stoutner <soren@stoutner.com>
Tue, 19 Apr 2022 22:25:48 +0000 (15:25 -0700)
15 files changed:
src/CMakeLists.txt
src/dialogs/CMakeLists.txt
src/dialogs/CookiesDialog.cpp [new file with mode: 0644]
src/dialogs/CookiesDialog.h [new file with mode: 0644]
src/dialogs/DomainSettingsDialog.cpp
src/filters/MouseEventFilter.h
src/ui.rc/browser_ui.rc
src/ui/BrowserView.ui
src/ui/CookieWidget.ui [new file with mode: 0644]
src/ui/CookiesDialog.ui [new file with mode: 0644]
src/ui/DomainSettingsDialog.ui
src/views/BrowserView.cpp
src/views/BrowserView.h
src/windows/BrowserWindow.cpp
src/windows/BrowserWindow.h

index 4d33710bb035c2c688fd4caef84aa632a7d67d23..ea4fecb7f4d06c0c4c9e9662061853898b913342 100644 (file)
@@ -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
 # 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
     ui/DomainSettingsDialog.ui
     ui/SettingsGeneral.ui
     ui/SettingsPrivacy.ui
index e2effdb38a2700287481e6689854e573829dced4..ee3d9ff681d4cfce1141d3242096b4be51deeeb7 100644 (file)
@@ -18,5 +18,6 @@
 
 # List the sources to include in the executable.
 target_sources(privacy-browser PRIVATE
 
 # List the sources to include in the executable.
 target_sources(privacy-browser PRIVATE
+    CookiesDialog.cpp
     DomainSettingsDialog.cpp
 )
     DomainSettingsDialog.cpp
 )
diff --git a/src/dialogs/CookiesDialog.cpp b/src/dialogs/CookiesDialog.cpp
new file mode 100644 (file)
index 0000000..3321c65
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser PC <https://www.stoutner.com/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 <http://www.gnu.org/licenses/>.
+ */
+
+// Application headers.
+#include "CookiesDialog.h"
+#include "ui_CookiesDialog.h"
+#include "ui_CookieWidget.h"
+
+// The KDE Frameworks headers.
+#include <KLocalizedString>
+
+// The Qt toolkit headers.
+#include <QDateTime>
+#include <QMessageBox>
+
+CookiesDialog::CookiesDialog(QList<QNetworkCookie> *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("<font size=\"+1\"><b>" + cookie.domain() + "</b></font>");
+        nameLabelPointer->setText("<font size=\"+1\"><b>" + cookie.name() + "</b></font>");
+        expirationDateLabelPointer->setText("<b>" + cookie.expirationDate().toString() + "</b>");
+        pathLabelPointer->setText("<b>" + cookie.path() + "</b>");
+        httpOnlyCheckBoxPointer->setChecked(cookie.isHttpOnly());
+        secureCheckBoxPointer->setChecked(cookie.isSecure());
+        valueLabelPointer->setText("<b>" + cookie.value() + "</b>");
+
+        // 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 (file)
index 0000000..17498ca
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser PC <https://www.stoutner.com/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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef COOKIESDIALOG_H
+#define COOKIESDIALOG_H
+
+// Qt toolkit headers.
+#include <QDialog>
+#include <QNetworkCookie>
+#include <QVBoxLayout>
+
+class CookiesDialog : public QDialog
+{
+    // Include the Q_OBJECT macro.
+    Q_OBJECT
+
+public:
+    // The default constructor.
+    explicit CookiesDialog(QList<QNetworkCookie> *cookieListPointer);
+
+signals:
+    void deleteAllCookies() const;
+
+private Q_SLOTS:
+    // The private slots.
+    void showDeleteAllMessageBox() const;
+
+private:
+    // The private variables.
+    QList<QNetworkCookie> *cookieListPointer;
+    QVBoxLayout *cookiesVBoxLayoutPointer;
+    QPushButton *deleteAllButtonPointer;
+
+    // The private functions.
+    void updateUi() const;
+};
+#endif
index b5be32a29effaf1d99607a45b44512889ac54725..42c713ab90e6a75046fb88612d2b2cbb4d9aedb6 100644 (file)
@@ -36,7 +36,13 @@ const int DomainSettingsDialog::EDIT_DOMAIN = 2;
 
 DomainSettingsDialog::DomainSettingsDialog(const int &startType, const QString &domainName) : QDialog(nullptr)
 {
 
 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.
     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.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.
 
     // 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);
 
     // 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();
 
     // 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.
     if (returnValue == QMessageBox::Yes)
     {
         // Get the current index.
index 02e1b2de0b8b0b8566a84020dbf6af9b02d361f3..4e4cc4fc14f24180c8dc713d2d6aff906fd24372 100644 (file)
@@ -22,7 +22,6 @@
 
 // Qt headers.
 #include <QObject>
 
 // Qt headers.
 #include <QObject>
-#include <QWebEngineView>
 
 class MouseEventFilter : public QObject
 {
 
 class MouseEventFilter : public QObject
 {
index 4c42e77146e9625599a0af95f3ce677da184d346..e75b573239e884213a89b0ef7bb93a74ad578c7e 100644 (file)
@@ -61,6 +61,7 @@
         <!-- Settings. -->
         <Menu name="settings">
             <Action name="domain_settings" />
         <!-- Settings. -->
         <Menu name="settings">
             <Action name="domain_settings" />
+            <Action name="cookies" />
         </Menu>
     </MenuBar>
 
         </Menu>
     </MenuBar>
 
index 11219fafbe48bd6b31d6160dc7f3f408bfd78b10..26ba07233231578e5120193e1c7308cc9afaacc4 100644 (file)
@@ -21,7 +21,7 @@
 <ui version="4.0">
     <class>BrowserView</class>
     <!-- Main widget. -->
 <ui version="4.0">
     <class>BrowserView</class>
     <!-- Main widget. -->
-    <widget class="QWidget" name="BrowserView">
+    <widget class="QWidget">
         <!-- Main layout. -->
         <layout class="QVBoxLayout">
             <!-- Set the spacing between items to 0. -->
         <!-- Main layout. -->
         <layout class="QVBoxLayout">
             <!-- Set the spacing between items to 0. -->
diff --git a/src/ui/CookieWidget.ui b/src/ui/CookieWidget.ui
new file mode 100644 (file)
index 0000000..efad03a
--- /dev/null
@@ -0,0 +1,287 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+
+  This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+
+  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 <http://www.gnu.org/licenses/>. -->
+
+<ui version="4.0">
+    <class>CookieWidget</class>
+
+    <widget class="QWidget">
+        <layout class="QVBoxLayout">
+            <item>
+                <layout class="QHBoxLayout">
+                    <property name="alignment">
+                        <enum>Qt::AlignLeft</enum>
+                    </property>
+
+                    <!-- Domain. -->
+                    <item>
+                        <widget class="QLabel">
+                            <property name="toolTip">
+                                <string>Cookies prepended by a period are accessible to all subdomains.</string>
+                            </property>
+
+                            <property name="textFormat">
+                                <enum>Qt::RichText</enum>
+                            </property>
+
+                            <property name="text">
+                                <string>&lt;font size=&quot;+1&quot;&gt;Domain:&amp;nbsp;&lt;/font&gt;</string>
+                            </property>
+                        </widget>
+                    </item>
+
+                    <item>
+                        <widget class="QLabel" name="domainLabel">
+                            <property name="toolTip">
+                                <string>Cookies prepended by a period are accessible to all subdomains.</string>
+                            </property>
+
+                            <property name="textFormat">
+                                <enum>Qt::RichText</enum>
+                            </property>
+
+                            <property name="textInteractionFlags">
+                                <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+                            </property>
+                        </widget>
+                    </item>
+
+                    <!-- Name. -->
+                    <item>
+                        <widget class="QLabel">
+                            <property name="toolTip">
+                                <string>The identifier of the cookie, which is unique when combined with the domain and the path.</string>
+                            </property>
+
+                            <property name="textFormat">
+                                <enum>Qt::RichText</enum>
+                            </property>
+
+                            <property name="text">
+                                <string>&lt;font size=&quot;+1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Name:&amp;nbsp;&lt;/font&gt;</string>
+                            </property>
+                        </widget>
+                    </item>
+
+                    <item>
+                        <widget class="QLabel" name="nameLabel">
+                            <property name="toolTip">
+                                <string>The identifier of the cookie, which is unique when combined with the domain and the path.</string>
+                            </property>
+
+                            <property name="textFormat">
+                                <enum>Qt::RichText</enum>
+                            </property>
+
+                            <property name="textInteractionFlags">
+                                <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+                            </property>
+                        </widget>
+                    </item>
+                </layout>
+            </item>
+
+            <item>
+                <layout class="QHBoxLayout">
+                    <property name="alignment">
+                        <enum>Qt::AlignLeft</enum>
+                    </property>
+
+                    <!-- Expiration date. -->
+                    <item>
+                        <widget class="QLabel">
+                            <property name="toolTip">
+                                <string>Cookies without an expiration date are known as session cookies and are expected to be deleted every time the browser closes.</string>
+                            </property>
+
+                            <property name="textFormat">
+                                <enum>Qt::RichText</enum>
+                            </property>
+
+                            <property name="text">
+                                <string>Expiration date:&amp;nbsp;</string>
+                            </property>
+                        </widget>
+                    </item>
+
+                    <item>
+                        <widget class="QLabel" name="expirationDateLabel">
+                            <property name="toolTip">
+                                <string>Cookies without an expiration date are known as session cookies and are expected to be deleted every time the browser closes.</string>
+                            </property>
+
+                            <property name="textFormat">
+                                <enum>Qt::RichText</enum>
+                            </property>
+
+                            <property name="textInteractionFlags">
+                                <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+                            </property>
+                        </widget>
+                    </item>
+
+                    <!-- Path. -->
+                    <item>
+                        <widget class="QLabel">
+                            <property name="toolTip">
+                                <string>Websites can restrict access to only a subpath of their URL.</string>
+                            </property>
+
+                            <property name="textFormat">
+                                <enum>Qt::RichText</enum>
+                            </property>
+
+                            <property name="text">
+                                <string>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Path:&amp;nbsp;</string>
+                            </property>
+                        </widget>
+                    </item>
+
+                    <item>
+                        <widget class="QLabel" name="pathLabel">
+                            <property name="toolTip">
+                                <string>Websites can restrict access to only a subpath of their URL.</string>
+                            </property>
+
+                            <property name="textFormat">
+                                <enum>Qt::RichText</enum>
+                            </property>
+
+                            <property name="textInteractionFlags">
+                                <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+                            </property>
+                        </widget>
+                    </item>
+
+                    <!-- A spacer labe.  Necessary to add space before the check box. -->
+                    <item>
+                        <widget class="QLabel">
+                            <property name="textFormat">
+                                <enum>Qt::RichText</enum>
+                            </property>
+
+                            <property name="text">
+                                <string>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;</string>
+                            </property>
+                        </widget>
+                    </item>
+
+                    <!-- HTTP only. -->
+                    <item>
+                        <widget class="QCheckBox" name="httpOnlyCheckBox">
+                            <property name="toolTip">
+                                <string>Restrict cookie access to HTTP (and HTTPS). This prevents JavaScript from accessing the cookie, which hardens it against cross-site scripting attacks.</string>
+                            </property>
+
+                            <property name="enabled">
+                                <bool>false</bool>
+                            </property>
+                        </widget>
+                    </item>
+
+                    <item>
+                        <widget class="QLabel">
+                            <property name="toolTip">
+                                <string>Restrict cookie access to HTTP (and HTTPS). This prevents JavaScript from accessing the cookie, which hardens it against cross-site scripting attacks.</string>
+                            </property>
+
+                            <property name="textFormat">
+                                <enum>Qt::RichText</enum>
+                            </property>
+
+                            <property name="text">
+                                <string>HTTP only&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;</string>
+                            </property>
+                        </widget>
+                    </item>
+
+                    <!-- Secure. -->
+                    <item>
+                        <widget class="QCheckBox" name="secureCheckBox">
+                            <property name="toolTip">
+                                <string>Only allow the cookie to be transferred across HTTPS (as opposed to HTTP).</string>
+                            </property>
+
+                            <property name="enabled">
+                                <bool>false</bool>
+                            </property>
+                        </widget>
+                    </item>
+
+                    <item>
+                        <widget class="QLabel">
+                            <property name="toolTip">
+                                <string>Only allow the cookie to be transferred across HTTPS (as opposed to HTTP).</string>
+                            </property>
+
+                            <property name="text">
+                                <string>Secure</string>
+                            </property>
+                        </widget>
+                    </item>
+                </layout>
+            </item>
+
+            <item>
+                <layout class="QHBoxLayout">
+                    <property name="alignment">
+                        <enum>Qt::AlignLeft</enum>
+                    </property>
+
+                    <!-- Value. -->
+                    <item>
+                        <widget class="QLabel">
+                            <property name="toolTip">
+                                <string>The value contains the cookie data.</string>
+                            </property>
+
+                            <property name="textFormat">
+                                <enum>Qt::RichText</enum>
+                            </property>
+
+                            <property name="text">
+                                <string>Value:&amp;nbsp;</string>
+                            </property>
+                        </widget>
+                    </item>
+
+                    <item>
+                        <widget class="QLabel" name="valueLabel">
+                            <property name="toolTip">
+                                <string>The value contains the cookie data.</string>
+                            </property>
+
+                            <property name="wordWrap">
+                                <bool>true</bool>
+                            </property>
+
+                            <property name="textFormat">
+                                <enum>Qt::RichText</enum>
+                            </property>
+
+                            <property name="textInteractionFlags">
+                                <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+                            </property>
+                        </widget>
+                    </item>
+                </layout>
+            </item>
+        </layout>
+    </widget>
+</ui>
diff --git a/src/ui/CookiesDialog.ui b/src/ui/CookiesDialog.ui
new file mode 100644 (file)
index 0000000..69773c1
--- /dev/null
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+
+  This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-android>.
+
+  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 <http://www.gnu.org/licenses/>. -->
+
+<ui version="4.0">
+    <class>CookiesDialog</class>
+
+
+    <widget class="QWidget">
+        <property name="geometry">
+            <rect>
+                <x>0</x>
+                <y>0</y>
+                <height>1000</height>
+                <width>1500</width>
+            </rect>
+        </property>
+
+        <layout class="QVBoxLayout">
+            <item>
+                <!-- Scroll area. -->
+                <widget class="QScrollArea" name="scrollArea" />
+            </item>
+
+            <item>
+                <layout class="QHBoxLayout">
+                    <!-- Add cookie button. -->
+                    <item>
+                        <widget class="QPushButton" name="addCookieButton">
+                            <property name="text">
+                                <string>Add cookie</string>
+                            </property>
+
+                            <property name="icon">
+                                <iconset theme="list-add" />
+                            </property>
+                        </widget>
+                    </item>
+
+                    <!-- Edit cookie button. -->
+                    <item>
+                        <widget class="QPushButton" name="editDomainButton">
+                            <property name="text">
+                                <string>Edit cookie</string>
+                            </property>
+
+                            <property name="icon">
+                                <iconset theme="edit-entry" />
+                            </property>
+                        </widget>
+                    </item>
+
+                    <!-- Delete domain button. -->
+                    <item>
+                        <widget class="QPushButton" name="deleteDomainButton">
+                            <property name="text">
+                                <string>Delete cookie</string>
+                            </property>
+
+                            <property name="icon">
+                                <iconset theme="list-remove" />
+                            </property>
+                        </widget>
+                    </item>
+
+                    <!-- Close button. -->
+                    <item>
+                        <widget class="QDialogButtonBox" name="dialogButtonBox">
+                            <property name="standardButtons">
+                                <set>QDialogButtonBox::Close</set>
+                            </property>
+                        </widget>
+                    </item>
+                </layout>
+            </item>
+        </layout>
+    </widget>
+</ui>
index c39047ce5249e21c45e9a9d0620779dcf13e07ed..ae9322d8401558569e9fcbc14d28ad9d73f71b7e 100644 (file)
@@ -21,7 +21,7 @@
 <ui version="4.0">
     <class>DomainSettingsDialog</class>
 
 <ui version="4.0">
     <class>DomainSettingsDialog</class>
 
-    <widget class="QWidget" name="DomainSettingsDialog">
+    <widget class="QWidget">
         <property name="geometry">
             <rect>
                 <x>0</x>
         <property name="geometry">
             <rect>
                 <x>0</x>
                             <item>
                                 <widget class="QPushButton" name="addDomainButton">
                                     <property name="text">
                             <item>
                                 <widget class="QPushButton" name="addDomainButton">
                                     <property name="text">
-                                        <string>Add Domain</string>
+                                        <string>Add domain</string>
                                     </property>
 
                                     <property name="icon">
                                     </property>
 
                                     <property name="icon">
-                                        <iconset theme="list-add"/>
+                                        <iconset theme="list-add" />
                                     </property>
                                 </widget>
                             </item>
                                     </property>
                                 </widget>
                             </item>
@@ -64,7 +64,7 @@
                                     </property>
 
                                     <property name="icon">
                                     </property>
 
                                     <property name="icon">
-                                        <iconset theme="list-remove"/>
+                                        <iconset theme="list-remove" />
                                     </property>
                                 </widget>
                             </item>
                                     </property>
                                 </widget>
                             </item>
index 873b9476da8bd0cce0bd441e742e0f79d7febb05..07ce5f5d897039339513fa075e6ed401d3d67906 100644 (file)
@@ -30,7 +30,6 @@
 
 // Qt framework headers.
 #include <QAction>
 
 // Qt framework headers.
 #include <QAction>
-#include <QWebEngineProfile>
 
 // Initialize the public static variables.
 QString BrowserView::webEngineDefaultUserAgent = QStringLiteral("");
 
 // 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.
     webEngineProfilePointer = new QWebEngineProfile(QStringLiteral(""));
 
     // Create a WebEngine page.
-    QWebEnginePage *webEnginePagePointer = new QWebEnginePage(webEngineProfilePointer);
+    webEnginePagePointer = new QWebEnginePage(webEngineProfilePointer);
 
     // Set the WebEngine page.
     webEngineViewPointer->setPage(webEnginePagePointer);
 
     // 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();
     // 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();
 
     // Store a copy of the WebEngine default user agent.
     webEngineDefaultUserAgent = webEngineProfilePointer->httpUserAgent();
@@ -111,6 +114,12 @@ BrowserView::BrowserView(QWidget *parent) : QWidget(parent)
     webEngineViewPointer->setFocus();
 }
 
     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.
 void BrowserView::applyApplicationSettings()
 {
     // Set the search engine URL.
@@ -302,6 +311,18 @@ void BrowserView::back() const
     webEngineViewPointer->back();
 }
 
     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.
 void BrowserView::forward() const
 {
     // Go forward.
index 29ae93c04ebe91221b00f923e9a6d243c3d6ad1b..0a88a2ca0788dc96f51601fa0e664619c806380a 100644 (file)
@@ -26,6 +26,7 @@
 // Qt framework headers.
 #include <QPushButton>
 #include <QWebEngineHistory>
 // Qt framework headers.
 #include <QPushButton>
 #include <QWebEngineHistory>
+#include <QWebEngineProfile>
 #include <QWebEngineSettings>
 #include <QWebEngineView>
 
 #include <QWebEngineSettings>
 #include <QWebEngineView>
 
@@ -38,6 +39,9 @@ public:
     // The primary contructor.
     explicit BrowserView(QWidget *parent);
 
     // The primary contructor.
     explicit BrowserView(QWidget *parent);
 
+    // The destructor.
+    ~BrowserView();
+
     // The public functions.
     void applyOnTheFlyZoomFactor(const double &zoomFactor);
     void loadInitialWebsite();
     // The public functions.
     void applyOnTheFlyZoomFactor(const double &zoomFactor);
     void loadInitialWebsite();
@@ -49,6 +53,7 @@ public:
 
 signals:
     // The signals.
 
 signals:
     // The signals.
+    void addCookie(const QNetworkCookie &cookie) const;
     void clearUrlLineEditFocus() const;
     void hideProgressBar() const;
     void linkHovered(const QString &linkUrl) 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 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;
     void forward() const;
     void home() const;
     void loadUrlFromLineEdit(QString url) const;
@@ -80,6 +86,7 @@ public Q_SLOTS:
 
 private Q_SLOTS:
     // The private 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;
     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 <https://redmine.stoutner.com/issues/799> has been resolved.
     QString searchEngineUrl;
     // The private variables.
     double currentZoomFactor;  // This can be removed once <https://redmine.stoutner.com/issues/799> has been resolved.
     QString searchEngineUrl;
+    QWebEngineCookieStore *webEngineCookieStorePointer;
     QWebEngineHistory *webEngineHistoryPointer;
     QWebEngineHistory *webEngineHistoryPointer;
+    QWebEnginePage *webEnginePagePointer;
     QWebEngineProfile *webEngineProfilePointer;
     QWebEngineSettings *webEngineSettingsPointer;
     QWebEngineView *webEngineViewPointer;
     QWebEngineProfile *webEngineProfilePointer;
     QWebEngineSettings *webEngineSettingsPointer;
     QWebEngineView *webEngineViewPointer;
index 3ddba02c9e3809475a6d7393354b5cbc5eae33fb..3293f02dbb4983eccd9246d052bcfdce0f6c256a 100644 (file)
@@ -22,6 +22,7 @@
 #include "Settings.h"
 #include "ui_SettingsPrivacy.h"
 #include "ui_SettingsGeneral.h"
 #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"
 #include "dialogs/DomainSettingsDialog.h"
 #include "helpers/SearchEngineHelper.h"
 #include "helpers/UserAgentHelper.h"
@@ -32,6 +33,7 @@
 
 // Qt toolkit headers.
 #include <QInputDialog>
 
 // Qt toolkit headers.
 #include <QInputDialog>
+#include <QNetworkCookie>
 #include <QStatusBar>
 
 BrowserWindow::BrowserWindow() : KXmlGuiWindow()
 #include <QStatusBar>
 
 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"));
     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"));
     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);
 
     // 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"));
     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"));
 
     // 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")));
     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)));
 
     // 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()));
 
     // 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 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)));
 
     // 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)));
 
     // Update the applied palette.
     connect(browserViewPointer, SIGNAL(updateDomainSettingsIndicator(bool, QString)), this, SLOT(updateDomainSettingsIndicator(bool, QString)));
 
+    // Initialize the cookie list.
+    cookieListPointer = new QList<QNetworkCookie>;
+
+    // Add new cookies to the list.
+    connect(browserViewPointer, SIGNAL(addCookie(QNetworkCookie)), this, SLOT(addCookie(QNetworkCookie)));
+
     // Load the initial website.
     browserViewPointer->loadInitialWebsite();
 }
 
     // 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.
 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);
 }
 
     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.
 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();
 
     // 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();
 
     // Show the dialog.
     domainSettingsDialogPointer->show();
 
index 60dea63b7aa5604c936aad11badd9c30a6f71ebb..6995efc026a6b270c285ac6b64f5cddfea0b0c35 100644 (file)
@@ -45,6 +45,7 @@ public:
 
 private Q_SLOTS:
     // The private slots.
 
 private Q_SLOTS:
     // The private slots.
+    void addCookie(const QNetworkCookie &newCookie) const;
     void addOrEditDomainSettings() const;
     void back() const;
     void clearUrlLineEditFocus() 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 getZoomFactorFromUser();
     void home() const;
     void loadUrlFromLineEdit(const QString &url) const;
+    void openCookiesDialog();
     void openDomainSettings() const;
     void refresh() const;
     void settingsConfigure();
     void openDomainSettings() const;
     void refresh() const;
     void settingsConfigure();
@@ -73,10 +75,10 @@ private:
     // The private variables.
     BrowserView *browserViewPointer;
     KConfigDialog *configDialogPointer;
     // The private variables.
     BrowserView *browserViewPointer;
     KConfigDialog *configDialogPointer;
+    QList<QNetworkCookie> *cookieListPointer;
     QString currentDomainSettingsDomain;
     QUrl currentUrl;
     double currentZoomFactor;
     QString currentDomainSettingsDomain;
     QUrl currentUrl;
     double currentZoomFactor;
-    QAction *domainSettingsActionPointer;
     QPalette domainSettingsPalette;
     QAction *javaScriptActionPointer;
     QAction *localStorageActionPointer;
     QPalette domainSettingsPalette;
     QAction *javaScriptActionPointer;
     QAction *localStorageActionPointer;