# Use KDE Frameworks to handle internationalization of the following UI files.
ki18n_wrap_ui(privacy-browser
- ui/AddCookieDialog.ui
+ ui/AddOrEditCookieDialog.ui
ui/BrowserView.ui
- ui/CookieDisplayWidget.ui
ui/CookiesDialog.ui
ui/DomainSettingsDialog.ui
ui/SettingsGeneral.ui
+++ /dev/null
-/*
- * 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 "AddCookieDialog.h"
-#include "ui_AddCookieDialog.h"
-
-// KDE Framework headers.
-#include <KLocalizedString>
-
-// Qt toolkit header.
-#include <QPushButton>
-#include <QUrl>
-
-AddCookieDialog::AddCookieDialog() : QDialog(nullptr)
-{
- // Set the dialog window title.
- setWindowTitle(i18nc("The add cookie dialog window title", "Add Cookie"));
-
- // Set the window modality.
- setWindowModality(Qt::WindowModality::ApplicationModal);
-
- // Instantiate the cookie settings dialog UI.
- Ui::AddCookieDialog addCookieDialogUi;
-
- // Setup the UI.
- addCookieDialogUi.setupUi(this);
-
- // Get handles for the views.
- domainLineEditPointer = addCookieDialogUi.domainLineEdit;
- nameLineEditPointer = addCookieDialogUi.nameLineEdit;
- expirationCheckBoxPointer = addCookieDialogUi.expirationCheckBox;
- expirationDateTimeEditPointer = addCookieDialogUi.expirationDateTimeEdit;
- pathLineEditPointer = addCookieDialogUi.pathLineEdit;
- httpOnlyCheckBoxPointer = addCookieDialogUi.httpOnlyCheckBox;
- secureCheckBoxPointer = addCookieDialogUi.secureCheckBox;
- valueLineEditPointer = addCookieDialogUi.valueLineEdit;
- QDialogButtonBox *dialogButtonBoxPointer = addCookieDialogUi.dialogButtonBox;
- saveButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::Save);
-
- // Connect the line edits.
- connect(domainLineEditPointer, SIGNAL(textEdited(QString)), this, SLOT(updateUi()));
- connect(nameLineEditPointer, SIGNAL(textEdited(QString)), this, SLOT(updateUi()));
- connect(pathLineEditPointer, SIGNAL(textEdited(QString)), this, SLOT(updateUi()));
- connect(valueLineEditPointer, SIGNAL(textEdited(QString)), this, SLOT(updateUi()));
-
- // Connect the check boxes.
- connect(expirationCheckBoxPointer, SIGNAL(stateChanged(int)), this, SLOT(updateExpirationDateTimeState(int)));
-
- // Connect the buttons.
- connect(dialogButtonBoxPointer, SIGNAL(accepted()), this, SLOT(saveCookie()));
- connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject()));
-
- // Update the UI.
- updateUi();
-}
-
-void AddCookieDialog::saveCookie()
-{
- // Create the variables.
- QNetworkCookie cookie;
-
- // Populate the cookie.
- cookie.setDomain(domainLineEditPointer->text());
- cookie.setName(nameLineEditPointer->text().toUtf8());
- cookie.setPath(pathLineEditPointer->text());
- cookie.setHttpOnly(httpOnlyCheckBoxPointer->isChecked());
- cookie.setSecure(secureCheckBoxPointer->isChecked());
- cookie.setValue(valueLineEditPointer->text().toUtf8());
-
- // Populate the expiration date if it is specified.
- if (expirationCheckBoxPointer->isChecked()) cookie.setExpirationDate(expirationDateTimeEditPointer->dateTime());
-
- // Add the cookie.
- emit addCookie(cookie);
-
- // Close the dialog.
- reject();
-}
-
-void AddCookieDialog::updateExpirationDateTimeState(const int &newState) const
-{
- // Update the state of the of the expiration date time edit.
- switch (newState)
- {
- case Qt::Unchecked:
- // Disable the expiration date time.
- expirationDateTimeEditPointer->setEnabled(false);
-
- break;
-
- case Qt::Checked:
- // Enable the expiration date time edit.
- expirationDateTimeEditPointer->setEnabled(true);
-
- break;
- }
-}
-
-void AddCookieDialog::updateUi() const
-{
- // Update the state of the save button based on all the required fields containing text.
- saveButtonPointer->setDisabled(domainLineEditPointer->text().isEmpty() || nameLineEditPointer->text().isEmpty() || pathLineEditPointer->text().isEmpty() ||
- valueLineEditPointer->text().isEmpty());
-}
+++ /dev/null
-/*
- * 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 ADDCOOKIEDIALOG_H
-#define ADDCOOKIEDIALOG_H
-
-// Qt toolkit headers.
-#include <QCheckBox>
-#include <QDateTimeEdit>
-#include <QDialog>
-#include <QNetworkCookie>
-
-class AddCookieDialog : public QDialog
-{
- // Include the Q_OBJECT macro.
- Q_OBJECT
-
-public:
- // The default constructor.
- explicit AddCookieDialog();
-
-signals:
- // The signals.
- void addCookie(const QNetworkCookie &cookie) const;
-
-private Q_SLOTS:
- // The private slots.
- void saveCookie();
- void updateExpirationDateTimeState(const int &newState) const;
- void updateUi() const;
-
-private:
- // The private variables.
- QLineEdit *domainLineEditPointer;
- QCheckBox *expirationCheckBoxPointer;
- QDateTimeEdit *expirationDateTimeEditPointer;
- QCheckBox *httpOnlyCheckBoxPointer;
- QLineEdit *nameLineEditPointer;
- QLineEdit *pathLineEditPointer;
- QPushButton *saveButtonPointer;
- QCheckBox *secureCheckBoxPointer;
- QLineEdit *valueLineEditPointer;
-};
-#endif
--- /dev/null
+/*
+ * 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 "AddOrEditCookieDialog.h"
+#include "ui_AddOrEditCookieDialog.h"
+
+// KDE Framework headers.
+#include <KLocalizedString>
+
+// Qt toolkit header.
+#include <QPushButton>
+#include <QUrl>
+
+// Define the public static constants.
+const int AddOrEditCookieDialog::AddCookie = 0;
+const int AddOrEditCookieDialog::EditCookie = 1;
+
+AddOrEditCookieDialog::AddOrEditCookieDialog(const int &dialogType, const QNetworkCookie *cookiePointer) : QDialog(nullptr)
+{
+ // Set the dialog window title according to the dialog type.
+ if (dialogType == AddCookie)
+ setWindowTitle(i18nc("The add cookie dialog window title.", "Add Cookie"));
+ else
+ setWindowTitle(i18nc("The edit cookie dialog window title.", "Edit Cookie"));
+
+ // Populate the is edit dialog boolean.
+ isEditDialog = (dialogType == EditCookie);
+
+ // Set the window modality.
+ setWindowModality(Qt::WindowModality::ApplicationModal);
+
+ // Instantiate the cookie settings dialog UI.
+ Ui::AddOrEditCookieDialog addOrEditCookieDialogUi;
+
+ // Setup the UI.
+ addOrEditCookieDialogUi.setupUi(this);
+
+ // Get handles for the widgets.
+ domainLineEditPointer = addOrEditCookieDialogUi.domainLineEdit;
+ nameLineEditPointer = addOrEditCookieDialogUi.nameLineEdit;
+ expirationCheckBoxPointer = addOrEditCookieDialogUi.expirationCheckBox;
+ expirationDateTimeEditPointer = addOrEditCookieDialogUi.expirationDateTimeEdit;
+ pathLineEditPointer = addOrEditCookieDialogUi.pathLineEdit;
+ httpOnlyCheckBoxPointer = addOrEditCookieDialogUi.httpOnlyCheckBox;
+ secureCheckBoxPointer = addOrEditCookieDialogUi.secureCheckBox;
+ valueLineEditPointer = addOrEditCookieDialogUi.valueLineEdit;
+ QDialogButtonBox *dialogButtonBoxPointer = addOrEditCookieDialogUi.dialogButtonBox;
+ saveButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::Save);
+
+ // Populate the dialog if editing a cookie.
+ if (isEditDialog)
+ {
+ // Store the old cookie.
+ oldCookie = *cookiePointer;
+
+ // Populate the widgets.
+ domainLineEditPointer->setText(oldCookie.domain());
+ nameLineEditPointer->setText(oldCookie.name());
+ pathLineEditPointer->setText(oldCookie.path());
+ httpOnlyCheckBoxPointer->setChecked(oldCookie.isHttpOnly());
+ secureCheckBoxPointer->setChecked(oldCookie.isSecure());
+ valueLineEditPointer->setText(oldCookie.value());
+
+ // Populate the expiration date if it exists.
+ if (!oldCookie.isSessionCookie())
+ {
+ // Check the expiration box.
+ expirationCheckBoxPointer->setChecked(true);
+
+ // Enable the expiration date time edit.
+ expirationDateTimeEditPointer->setEnabled(true);
+
+ // Set the expiration date.
+ expirationDateTimeEditPointer->setDateTime(oldCookie.expirationDate());
+ }
+ }
+
+ // Connect the line edits.
+ connect(domainLineEditPointer, SIGNAL(textEdited(QString)), this, SLOT(updateUi()));
+ connect(nameLineEditPointer, SIGNAL(textEdited(QString)), this, SLOT(updateUi()));
+ connect(pathLineEditPointer, SIGNAL(textEdited(QString)), this, SLOT(updateUi()));
+ connect(valueLineEditPointer, SIGNAL(textEdited(QString)), this, SLOT(updateUi()));
+
+ // Connect the check boxes.
+ connect(expirationCheckBoxPointer, SIGNAL(stateChanged(int)), this, SLOT(updateExpirationDateTimeState(int)));
+
+ // Connect the buttons.
+ connect(dialogButtonBoxPointer, SIGNAL(accepted()), this, SLOT(saveCookie()));
+ connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject()));
+
+ // Update the UI.
+ updateUi();
+}
+
+void AddOrEditCookieDialog::saveCookie()
+{
+ // Delete the old cookie if this is an edit dialog.
+ if (isEditDialog)
+ emit deleteCookie(oldCookie);
+
+ // Create the variables.
+ QNetworkCookie cookie;
+
+ // Populate the cookie.
+ cookie.setDomain(domainLineEditPointer->text());
+ cookie.setName(nameLineEditPointer->text().toUtf8());
+ cookie.setPath(pathLineEditPointer->text());
+ cookie.setHttpOnly(httpOnlyCheckBoxPointer->isChecked());
+ cookie.setSecure(secureCheckBoxPointer->isChecked());
+ cookie.setValue(valueLineEditPointer->text().toUtf8());
+
+ // Populate the expiration date if it is specified.
+ if (expirationCheckBoxPointer->isChecked()) cookie.setExpirationDate(expirationDateTimeEditPointer->dateTime());
+
+ // Add the cookie.
+ emit addCookie(cookie);
+
+ // Close the dialog.
+ reject();
+}
+
+void AddOrEditCookieDialog::updateExpirationDateTimeState(const int &newState) const
+{
+ // Update the state of the of the expiration date time edit.
+ switch (newState)
+ {
+ case Qt::Unchecked:
+ // Disable the expiration date time.
+ expirationDateTimeEditPointer->setEnabled(false);
+
+ break;
+
+ case Qt::Checked:
+ // Enable the expiration date time edit.
+ expirationDateTimeEditPointer->setEnabled(true);
+
+ break;
+ }
+}
+
+void AddOrEditCookieDialog::updateUi() const
+{
+ // Update the state of the save button based on all the required fields containing text.
+ saveButtonPointer->setDisabled(domainLineEditPointer->text().isEmpty() || nameLineEditPointer->text().isEmpty() || pathLineEditPointer->text().isEmpty() ||
+ valueLineEditPointer->text().isEmpty());
+}
--- /dev/null
+/*
+ * 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 ADDOREDITCOOKIEDIALOG_H
+#define ADDOREDITCOOKIEDIALOG_H
+
+// Qt toolkit headers.
+#include <QCheckBox>
+#include <QDateTimeEdit>
+#include <QDialog>
+#include <QNetworkCookie>
+
+class AddOrEditCookieDialog : public QDialog
+{
+ // Include the Q_OBJECT macro.
+ Q_OBJECT
+
+public:
+ // The primary constructor.
+ explicit AddOrEditCookieDialog(const int &dialogType, const QNetworkCookie *cookiePointer = nullptr);
+
+ // The public static constants.
+ static const int AddCookie;
+ static const int EditCookie;
+
+signals:
+ // The signals.
+ void addCookie(const QNetworkCookie &cookie) const;
+ void deleteCookie(const QNetworkCookie &cookie) const;
+
+private Q_SLOTS:
+ // The private slots.
+ void saveCookie();
+ void updateExpirationDateTimeState(const int &newState) const;
+ void updateUi() const;
+
+private:
+ // The private widgets.
+ QLineEdit *domainLineEditPointer;
+ QCheckBox *expirationCheckBoxPointer;
+ QDateTimeEdit *expirationDateTimeEditPointer;
+ QCheckBox *httpOnlyCheckBoxPointer;
+ QLineEdit *nameLineEditPointer;
+ QLineEdit *pathLineEditPointer;
+ QPushButton *saveButtonPointer;
+ QCheckBox *secureCheckBoxPointer;
+ QLineEdit *valueLineEditPointer;
+
+ // The private variables.
+ QNetworkCookie oldCookie;
+ bool isEditDialog;
+};
+#endif
# List the sources to include in the executable.
target_sources(privacy-browser PRIVATE
- AddCookieDialog.cpp
+ AddOrEditCookieDialog.cpp
CookiesDialog.cpp
DomainSettingsDialog.cpp
)
*/
// Application headers.
-#include "AddCookieDialog.h"
+#include "AddOrEditCookieDialog.h"
#include "CookiesDialog.h"
-#include "ui_CookieDisplayWidget.h"
#include "ui_CookiesDialog.h"
// KDE Frameworks headers.
// Qt toolkit headers.
#include <QDateTime>
#include <QMessageBox>
+#include <QShortcut>
#include <QUrl>
-CookiesDialog::CookiesDialog(QList<QNetworkCookie> *originalCookieListPointer) : QDialog(nullptr), cookieListPointer(originalCookieListPointer)
+bool cookieSortPredicate(const QNetworkCookie &leftHandCookie, const QNetworkCookie &rightHandCookie)
+{
+ // Check to see if the domains are identical.
+ if (leftHandCookie.domain() == rightHandCookie.domain())
+ {
+ // Check to see if the names are identical.
+ if (leftHandCookie.name() == rightHandCookie.name())
+ {
+ // Sort the cookies by the path.
+ return (leftHandCookie.path() < rightHandCookie.path());
+ }
+ else // The name are not identical.
+ {
+ // Sort the cookies by the name.
+ return (leftHandCookie.name() < rightHandCookie.name());
+ }
+ }
+ else // The domains are not identical.
+ {
+ // Get copies of the domains.
+ QString leftHandDomain = leftHandCookie.domain();
+ QString rightHandDomain = rightHandCookie.domain();
+
+ // Get the top level domains.
+ QString leftHandTopLevelDomain = leftHandDomain.section('.', -1);
+ QString rightHandTopLevelDomain = rightHandDomain.section('.', -1);
+
+ // Get the second level domains.
+ QString leftHandSecondLevelDomain = leftHandDomain.section('.', -2);
+ QString rightHandSecondLevelDomain = rightHandDomain.section('.', -2);
+
+ // Get the third level domains.
+ QString leftHandThirdLevelDomain = leftHandDomain.section('.', -3);
+ QString rightHandThirdLevelDomain = rightHandDomain.section('.', -3);
+
+ // Check to see if the top level domains are the same.
+ if (leftHandTopLevelDomain == rightHandTopLevelDomain)
+ {
+ // Check to see if the second level domains are the same.
+ if (leftHandSecondLevelDomain == rightHandSecondLevelDomain)
+ {
+ // Check to see if the third level domains are the same.
+ if (leftHandThirdLevelDomain == rightHandThirdLevelDomain)
+ {
+ // Sort the cookies by the full domain because they share the same third level domain.
+ return (leftHandDomain < rightHandDomain);
+ }
+ else // The second level domains are the same, but the third level domains are different.
+ {
+ // Sort the cookies by the third level domains.
+ return (leftHandThirdLevelDomain < rightHandThirdLevelDomain);
+ }
+ }
+ else // The top level domains are the same, but the second level domains are diferent.
+ {
+ // Sort the cookies by the second level domain.
+ return (leftHandSecondLevelDomain < rightHandSecondLevelDomain);
+ }
+ }
+ else // The top level domains are different.
+ {
+ // Sort the cookies by the top level domain.
+ return (leftHandTopLevelDomain < rightHandTopLevelDomain);
+ }
+
+ }
+}
+
+CookiesDialog::CookiesDialog(std::forward_list<QNetworkCookie> *originalCookieListPointer) : QDialog(nullptr), cookieListPointer(originalCookieListPointer)
{
// Set the dialog window title.
setWindowTitle(i18nc("The cookies dialog window title", "Cookies"));
// Setup the UI.
cookiesDialogUi.setupUi(this);
- // Get a handle for the scroll area.
- QScrollArea *scrollAreaPointer = cookiesDialogUi.scrollArea;
+ // Get a handle for the tree view.
+ treeViewPointer = cookiesDialogUi.treeView;
- // Create the scroll area widget.
- QWidget *scrollAreaWidgetPointer = new QWidget();
+ // Initialize the standard item model.
+ standardItemModelPointer = new QStandardItemModel();
- // Set the scroll area widget.
- scrollAreaPointer->setWidget(scrollAreaWidgetPointer);
+ // Set the column count.
+ standardItemModelPointer->setColumnCount(6);
- // Create a scroll area VBox layout.
- QVBoxLayout *scrollAreaVBoxLayoutPointer = new QVBoxLayout();
+ // Set the header data.
+ standardItemModelPointer->setHeaderData(0, Qt::Horizontal, i18nc("The cookie Name header.", "Name"));
+ standardItemModelPointer->setHeaderData(1, Qt::Horizontal, i18nc("The cookie Path header.", "Path"));
+ standardItemModelPointer->setHeaderData(2, Qt::Horizontal, i18nc("The cookie Expiration Date header.", "Expiration Date"));
+ standardItemModelPointer->setHeaderData(3, Qt::Horizontal, i18nc("The cookie HTTP Only header.", "HTTP Only"));
+ standardItemModelPointer->setHeaderData(4, Qt::Horizontal, i18nc("The cookie Secure header.", "Secure"));
+ standardItemModelPointer->setHeaderData(5, Qt::Horizontal, i18nc("The cookie Value header.", "Value"));
- // Set the scroll area widget layout.
- scrollAreaWidgetPointer->setLayout(scrollAreaVBoxLayoutPointer);
+ // Set the header tool tips.
+ standardItemModelPointer->horizontalHeaderItem(0)->setToolTip(i18nc("The cookie Name tool tip.",
+ "The name identifies the cookie. Each cookie has a unique combination of domain, name, and path."));
+ standardItemModelPointer->horizontalHeaderItem(1)->setToolTip(i18nc("The cookie Path tool tip.", "Websites can restrict cookie access to subpath of their URL."));
+ standardItemModelPointer->horizontalHeaderItem(2)->setToolTip(i18nc("The cookie Expiration Date tool tip.",
+ "Cookies without an expiration date are known as session cookies and are expected to be deleted every time the browser closes."));
+ standardItemModelPointer->horizontalHeaderItem(3)->setToolTip(i18nc("The cookie HTTP Only tool tip.",
+ "Restrict cookie access to HTTP (and HTTPS). This prevents JavaScript from accessing the cookie, which hardens it against cross-site scripting attacks."));
+ standardItemModelPointer->horizontalHeaderItem(4)->setToolTip(i18nc("The cookie Secure tool tip.", "Only allow the cookie to be transferred across HTTPS (as opposed to HTTP)."));
+ standardItemModelPointer->horizontalHeaderItem(5)->setToolTip(i18nc("The cookie Value tool tip.", "The value contains the cookie data."));
- // Create the cookies VBox layout.
- cookiesVBoxLayoutPointer = new QVBoxLayout();
+ // Sort the cookie list.
+ cookieListPointer->sort(cookieSortPredicate);
- // Populate the scroll area VBox layout. The stretch prevents the cookies from expanding vertically if they are smaller than the dialog.
- scrollAreaVBoxLayoutPointer->addLayout(cookiesVBoxLayoutPointer);
- scrollAreaVBoxLayoutPointer->addStretch();
+ // Create the current domain string.
+ QString currentDomainString = "";
+
+ // Create the current domain standard item pointer.
+ QStandardItem *currentDomainStandardItemPointer;
// Populate the VBoxLayout.
for (QNetworkCookie cookie : *cookieListPointer)
{
- // Add the cookie to the layout.
- addCookieToLayout(cookie);
+ // Get the cookie domain.
+ QString cookieDomain = cookie.domain();
+
+ // Check to see if the cookie is a member of the current domain.
+ if (cookieDomain != currentDomainString) // Create a new domain in the tree.
+ {
+ // Create a list for the domain standard items.
+ QList<QStandardItem*> domainStandardItemList;
+
+ // Create the new domain standard items.
+ QStandardItem *domainStandardItemPointer = new QStandardItem(cookieDomain);
+ QStandardItem *pathStandardItemPointer = new QStandardItem(QStringLiteral(""));
+ QStandardItem *expirationDateStandardItemPointer = new QStandardItem(QStringLiteral(""));
+ QStandardItem *isHttpOnlyStandardItemPointer = new QStandardItem(QStringLiteral(""));
+ QStandardItem *isSecureStandardItemPointer = new QStandardItem(QStringLiteral(""));
+ QStandardItem *valueStandardItemPointer = new QStandardItem(QStringLiteral(""));
+
+ // Disable editing of the domain.
+ domainStandardItemPointer->setEditable(false);
+ pathStandardItemPointer->setEditable(false);
+ expirationDateStandardItemPointer->setEditable(false);
+ isHttpOnlyStandardItemPointer->setEditable(false);
+ isSecureStandardItemPointer->setEditable(false);
+ valueStandardItemPointer->setEditable(false);
+
+ // Populate the domain standard item list.
+ domainStandardItemList.append(domainStandardItemPointer);
+ domainStandardItemList.append(pathStandardItemPointer);
+ domainStandardItemList.append(expirationDateStandardItemPointer);
+ domainStandardItemList.append(isHttpOnlyStandardItemPointer);
+ domainStandardItemList.append(isSecureStandardItemPointer);
+ domainStandardItemList.append(valueStandardItemPointer);
+
+ // Add the domain to the tree.
+ standardItemModelPointer->invisibleRootItem()->appendRow(domainStandardItemList);
+
+ // Update the current domain string.
+ currentDomainString = cookieDomain;
+
+ // Update the current domain standard item pointer.
+ currentDomainStandardItemPointer = domainStandardItemPointer;
+ }
+
+ // Create a list for the cookie standard items.
+ QList<QStandardItem*> cookieStandardItemList;
+
+ // Create the cookie standard items.
+ QStandardItem *nameStandardItemPointer = new QStandardItem(QString(cookie.name()));
+ QStandardItem *pathStandardItemPointer = new QStandardItem(QString(cookie.path()));
+ QStandardItem *expirationDateStandardItemPointer = new QStandardItem(QString(cookie.expirationDate().toString()));
+ QStandardItem *isHttpOnlyStandardItemPointer = new QStandardItem(QString(cookie.isHttpOnly() ? i18n("yes") : i18n("no")));
+ QStandardItem *isSecureStandardItemPointer = new QStandardItem(QString(cookie.isSecure() ? i18n("yes") : i18n("no")));
+ QStandardItem *valueStandardItemPointer = new QStandardItem(QString(cookie.value()));
+
+ // Disable editing of the cookie standard items.
+ nameStandardItemPointer->setEditable(false);
+ pathStandardItemPointer->setEditable(false);
+ expirationDateStandardItemPointer->setEditable(false);
+ isHttpOnlyStandardItemPointer->setEditable(false);
+ isSecureStandardItemPointer->setEditable(false);
+ valueStandardItemPointer->setEditable(false);
+
+ // Populate the cookie standard item list.
+ cookieStandardItemList.append(nameStandardItemPointer);
+ cookieStandardItemList.append(pathStandardItemPointer);
+ cookieStandardItemList.append(expirationDateStandardItemPointer);
+ cookieStandardItemList.append(isHttpOnlyStandardItemPointer);
+ cookieStandardItemList.append(isSecureStandardItemPointer);
+ cookieStandardItemList.append(valueStandardItemPointer);
+
+ // Add the cookie to the tree.
+ currentDomainStandardItemPointer->appendRow(cookieStandardItemList);
}
+ // Auto resize the headers.
+ treeViewPointer->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+
+ // Disable stretching the last section. Otherwise, the Value field will be truncated to the width of the window when a row is expanded.
+ treeViewPointer->header()->setStretchLastSection(false);
+
+ // Don't elide the Value field (or any other field).
+ treeViewPointer->setTextElideMode(Qt::ElideNone);
+
+ // Indicate that all the rows are the same height, wich improves performance.
+ treeViewPointer->setUniformRowHeights(true);
+
+ // Set the tree view model.
+ treeViewPointer->setModel(standardItemModelPointer);
+
+ // Get a handle for the tree view selection model.
+ treeViewSelectionModelPointer = treeViewPointer->selectionModel();
+
+ // Listen for selection changes.
+ connect(treeViewSelectionModelPointer, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(updateUi()));
+
// Get handles for the buttons.
addCookieButtonPointer = cookiesDialogUi.addCookieButton;
+ editCookieButtonPointer = cookiesDialogUi.editCookieButton;
+ deleteCookieButtonPointer = cookiesDialogUi.deleteCookieButton;
QDialogButtonBox *dialogButtonBoxPointer = cookiesDialogUi.dialogButtonBox;
- QPushButton *cancelButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::Close);
+ QPushButton *closeButtonPointer = 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);
deleteAllButtonPointer->setIcon(QIcon::fromTheme("delete"));
// Connect the buttons.
- connect(addCookieButtonPointer, SIGNAL(clicked()), this, SLOT(showAddCookieMessageBox()));
+ connect(addCookieButtonPointer, SIGNAL(clicked()), this, SLOT(showAddCookieDialog()));
+ connect(editCookieButtonPointer, SIGNAL(clicked()), this, SLOT(showEditCookieDialog()));
+ connect(deleteCookieButtonPointer, SIGNAL(clicked()), this, SLOT(showDeleteCookieMessageBox()));
connect(deleteAllButtonPointer, SIGNAL(clicked()), this, SLOT(showDeleteAllMessageBox()));
connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject()));
// Set the cancel button to be the default.
- cancelButtonPointer->setDefault(true);
+ closeButtonPointer->setDefault(true);
+
+ // Create the keyboard shortcuts.
+ QShortcut *aShortcutPointer = new QShortcut(QKeySequence(i18nc("The add cookie key shortcut.", "a")), this);
+ QShortcut *eShortcutPointer = new QShortcut(QKeySequence(i18nc("The edit cookie key shorcut.", "e")), this);
+ QShortcut *dShortcutPointer = new QShortcut(QKeySequence(i18nc("The delete cookie key shortcut.", "d")), this);
+ QShortcut *deleteShortcutPointer = new QShortcut(QKeySequence::Delete, this);
+ QShortcut *lShortcutPointer = new QShortcut(QKeySequence(i18nc("The delete all key shortcut.", "l")), this);
+ QShortcut *cShortcutPointer = new QShortcut(QKeySequence(i18nc("The close key shortcut.", "c")), this);
+ QShortcut *quitShortcutPointer = new QShortcut(QKeySequence::Quit, this);
+
+ // Connect the keyboard shortcuts to the buttons.
+ connect(aShortcutPointer, SIGNAL(activated()), addCookieButtonPointer, SLOT(click()));
+ connect(eShortcutPointer, SIGNAL(activated()), editCookieButtonPointer, SLOT(click()));
+ connect(dShortcutPointer, SIGNAL(activated()), deleteCookieButtonPointer, SLOT(click()));
+ connect(deleteShortcutPointer, SIGNAL(activated()), deleteCookieButtonPointer, SLOT(click()));
+ connect(lShortcutPointer, SIGNAL(activated()), deleteAllButtonPointer, SLOT(click()));
+ connect(cShortcutPointer, SIGNAL(activated()), closeButtonPointer, SLOT(click()));
+ connect(quitShortcutPointer, SIGNAL(activated()), closeButtonPointer, SLOT(click()));
+
+ // Edit a cookie when it is double clicked.
+ connect(treeViewPointer, SIGNAL(doubleClicked(QModelIndex)), editCookieButtonPointer, SLOT(click()));
// Update the UI.
updateUi();
// Add the cookie to the cookie list and the cookie store.
emit addCookie(cookie);
- // Add the cookie to the VBox layout.
- addCookieToLayout(cookie);
+ // Get the new domain string.
+ QString newDomain = cookie.domain();
+
+ // Check to see if the domain already exists in the model.
+ QList<QStandardItem*> currentDomainStandardItemList = standardItemModelPointer->findItems(newDomain);
+
+ // Create a domain standard item pointer.
+ QStandardItem *domainStandardItemPointer;
+
+ // Prepare the domain standard item pointer.
+ if (currentDomainStandardItemList.isEmpty()) // The domain doesn't currently exist in the tree.
+ {
+ // Create a list for the domain standard items.
+ QList<QStandardItem*> domainStandardItemList;
+
+ // Create the new domain standard items.
+ domainStandardItemPointer = new QStandardItem(newDomain);
+ QStandardItem *pathStandardItemPointer = new QStandardItem(QStringLiteral(""));
+ QStandardItem *expirationDateStandardItemPointer = new QStandardItem(QStringLiteral(""));
+ QStandardItem *isHttpOnlyStandardItemPointer = new QStandardItem(QStringLiteral(""));
+ QStandardItem *isSecureStandardItemPointer = new QStandardItem(QStringLiteral(""));
+ QStandardItem *valueStandardItemPointer = new QStandardItem(QStringLiteral(""));
+
+ // Disable editing of the domain.
+ domainStandardItemPointer->setEditable(false);
+ pathStandardItemPointer->setEditable(false);
+ expirationDateStandardItemPointer->setEditable(false);
+ isHttpOnlyStandardItemPointer->setEditable(false);
+ isSecureStandardItemPointer->setEditable(false);
+ valueStandardItemPointer->setEditable(false);
+
+ // Populate the domain standard item list.
+ domainStandardItemList.append(domainStandardItemPointer);
+ domainStandardItemList.append(pathStandardItemPointer);
+ domainStandardItemList.append(expirationDateStandardItemPointer);
+ domainStandardItemList.append(isHttpOnlyStandardItemPointer);
+ domainStandardItemList.append(isSecureStandardItemPointer);
+ domainStandardItemList.append(valueStandardItemPointer);
+
+ // Create the insert domain row number.
+ int insertDomainRowNumber = 0;
+
+ // Get the number of domains in the tree.
+ int numberOfDomains = standardItemModelPointer->invisibleRootItem()->rowCount();
+
+ // Get the new domain strings.
+ QString newDomainTopLevelDomain = newDomain.section('.', -1);
+ QString newDomainSecondLevelDomain = newDomain.section('.', -2);
+ QString newDomainThirdLevelDomain = newDomain.section('.', -3);
+
+ // Iterate through all the domains.
+ for (int i = 0; i < numberOfDomains; ++i)
+ {
+ // Get the current domain strings.
+ QString currentDomain = standardItemModelPointer->invisibleRootItem()->child(i, 0)->index().data().toString();
+ QString currentDomainTopLevelDomain = currentDomain.section('.', -1);
+ QString currentDomainSecondLevelDomain = currentDomain.section('.', -2);
+ QString currentDomainThirdLevelDomain = currentDomain.section('.', -3);
+
+ // Check to see if the new domain should be inserted after the current domain.
+ if (newDomainTopLevelDomain > currentDomainTopLevelDomain)
+ {
+ // Insert the new domain after the current domain.
+ insertDomainRowNumber = i + 1;
+ }
+ else if ((newDomainTopLevelDomain == currentDomainTopLevelDomain) && (newDomainSecondLevelDomain > currentDomainSecondLevelDomain))
+ {
+ // Insert the new domain after the current domain.
+ insertDomainRowNumber = i + 1;
+ }
+ else if ((newDomainSecondLevelDomain == currentDomainSecondLevelDomain) && (newDomainThirdLevelDomain > currentDomainThirdLevelDomain))
+ {
+ // Insert the new domain after the current domain.
+ insertDomainRowNumber = i + 1;
+ }
+ else if ((newDomainThirdLevelDomain == currentDomainThirdLevelDomain) && (newDomain > currentDomain))
+ {
+ // Insert the new domain after the current domain.
+ insertDomainRowNumber = i + 1;
+ }
+ }
+
+ // Add the domain to the tree.
+ standardItemModelPointer->invisibleRootItem()->insertRow(insertDomainRowNumber, domainStandardItemList);
+ }
+ else // The domain already exists in the tree.
+ {
+ // Use the current domain standard item.
+ domainStandardItemPointer = currentDomainStandardItemList[0];
+ }
+
+ // Get strings for the new cookie name and path (used later in the placement of the row).
+ QString newCookieName = QString(cookie.name());
+ QString newCookiePath = QString(cookie.path());
+
+ // Create a list for the cookie standard items.
+ QList<QStandardItem*> cookieStandardItemList;
+
+ // Create the cookie standard items.
+ QStandardItem *nameStandardItemPointer = new QStandardItem(newCookieName);
+ QStandardItem *pathStandardItemPointer = new QStandardItem(newCookiePath);
+ QStandardItem *expirationDateStandardItemPointer = new QStandardItem(QString(cookie.expirationDate().toString()));
+ QStandardItem *isHttpOnlyStandardItemPointer = new QStandardItem(QString(cookie.isHttpOnly() ? i18n("yes") : i18n("no")));
+ QStandardItem *isSecureStandardItemPointer = new QStandardItem(QString(cookie.isSecure() ? i18n("yes") : i18n("no")));
+ QStandardItem *valueStandardItemPointer = new QStandardItem(QString(cookie.value()));
+
+ // Disable editing of the cookie standard items.
+ nameStandardItemPointer->setEditable(false);
+ pathStandardItemPointer->setEditable(false);
+ expirationDateStandardItemPointer->setEditable(false);
+ isHttpOnlyStandardItemPointer->setEditable(false);
+ isSecureStandardItemPointer->setEditable(false);
+ valueStandardItemPointer->setEditable(false);
+
+ // Populate the cookie standard item list.
+ cookieStandardItemList.append(nameStandardItemPointer);
+ cookieStandardItemList.append(pathStandardItemPointer);
+ cookieStandardItemList.append(expirationDateStandardItemPointer);
+ cookieStandardItemList.append(isHttpOnlyStandardItemPointer);
+ cookieStandardItemList.append(isSecureStandardItemPointer);
+ cookieStandardItemList.append(valueStandardItemPointer);
+
+ // Create the insert cookie row number.
+ int insertCookieRowNumber = 0;
+
+ // Get the number of cookies in the domain.
+ int numberOfCookies = domainStandardItemPointer->rowCount();
+
+ // Iterate through the cookies for this domain.
+ for (int i = 0; i < numberOfCookies; ++i)
+ {
+ // Get the current cookie name and path at the indicated row.
+ QString currentCookieName = domainStandardItemPointer->child(i, 0)->index().data().toString();
+ QString currentCookiePath = domainStandardItemPointer->child(i, 1)->index().data().toString();
+
+ // Check to see if the new cookie should be inserted after the current cookie.
+ if (newCookieName > currentCookieName)
+ {
+ // Insert the new cookie after the current cookie.
+ insertCookieRowNumber = i + 1;
+ }
+ else if ((newCookieName == currentCookieName) && (newCookiePath > currentCookiePath))
+ {
+ // Insert the new cookie after the current cookie.
+ insertCookieRowNumber = i + 1;
+ }
+ }
+
+ // Add the cookie to the tree.
+ domainStandardItemPointer->insertRow(insertCookieRowNumber, cookieStandardItemList);
+
+ // Get the new cookie model index.
+ QModelIndex newCookieIndex = nameStandardItemPointer->index();
+
+ // Set the new cookie to be the current index.
+ treeViewPointer->setCurrentIndex(newCookieIndex);
+
+ // Expand the parent of the new cookie.
+ treeViewPointer->expand(newCookieIndex.parent());
}
-void CookiesDialog::addCookieToLayout(const QNetworkCookie &cookie) const
+void CookiesDialog::deleteCookie(const QModelIndex &modelIndex) const
{
- // Create a cookie display widget.
- QWidget *cookieDisplayWidgetPointer = new QWidget();
+ // Create a partial cookie.
+ QNetworkCookie partialCookie;
- // Instantiate the cookie widget dialog UI.
- Ui::CookieDisplayWidget cookieDisplayWidgetUi;
+ // Populate the partial cookie from the current model index.
+ partialCookie.setDomain(modelIndex.parent().siblingAtColumn(0).data().toString());
+ partialCookie.setName(modelIndex.siblingAtColumn(0).data().toString().toUtf8());
+ partialCookie.setPath(modelIndex.siblingAtColumn(1).data().toString());
- // Setup the UI.
- cookieDisplayWidgetUi.setupUi(cookieDisplayWidgetPointer);
-
- // Get handles for the views.
- QLabel *domainLabelPointer = cookieDisplayWidgetUi.domainLabel;
- QLabel *nameLabelPointer = cookieDisplayWidgetUi.nameLabel;
- QLabel *expirationDateLabelPointer = cookieDisplayWidgetUi.expirationDateLabel;
- QLabel *pathLabelPointer = cookieDisplayWidgetUi.pathLabel;
- QCheckBox *httpOnlyCheckBoxPointer = cookieDisplayWidgetUi.httpOnlyCheckBox;
- QCheckBox *secureCheckBoxPointer = cookieDisplayWidgetUi.secureCheckBox;
- QLabel *valueLabelPointer = cookieDisplayWidgetUi.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 cookie display 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);
+ // Create a cookie to delete.
+ QNetworkCookie cookieToDelete;
+
+ // Search for the partial cookie in the cookie list.
+ for (QNetworkCookie cookie : *cookieListPointer)
+ {
+ // Store the cookie to delete if it has the same identifier as the partial cookie.
+ if (cookie.hasSameIdentifier(partialCookie))
+ cookieToDelete = cookie;
+ }
+
+ // Remove the cookie from the tree view.
+ standardItemModelPointer->removeRow(modelIndex.row(), modelIndex.parent());
+
+ // Delete the cookie from the cookie list and cookie store.
+ emit deleteCookie(cookieToDelete);
}
-void CookiesDialog::showAddCookieMessageBox() const
+void CookiesDialog::deleteCookieFromDialog(const QNetworkCookie &cookie) const
+{
+ // Get the current model index.
+ QModelIndex currentIndex = treeViewSelectionModelPointer->currentIndex();
+
+ // Get the parent index.
+ QModelIndex parentIndex = currentIndex.parent();
+
+ // Remove the cookie from the tree view.
+ standardItemModelPointer->removeRow(currentIndex.row(), parentIndex);
+
+ // Remove the domain from the tree view if its only cookie has been deleted.
+ if (standardItemModelPointer->rowCount(parentIndex) == 0)
+ standardItemModelPointer->removeRow(parentIndex.row(), parentIndex.parent());
+
+ // Delete the cookie from the cookie list and cookie store.
+ emit deleteCookie(cookie);
+}
+
+void CookiesDialog::showAddCookieDialog() const
{
// Instantiate an add cookie dialog.
- QDialog *addCookieDialogPointer = new AddCookieDialog();
+ QDialog *addCookieDialogPointer = new AddOrEditCookieDialog(AddOrEditCookieDialog::AddCookie);
// Show the dialog.
addCookieDialogPointer->show();
// Delete all the cookies.
emit deleteAllCookies();
- // Clear the cookie list.
- cookieListPointer->clear();
+ // Clear the standard item model.
+ standardItemModelPointer->clear();
+
+ // Update the UI.
+ updateUi();
+ }
+}
+
+void CookiesDialog::showDeleteCookieMessageBox() const
+{
+ // Get the current model index.
+ QModelIndex currentIndex = treeViewSelectionModelPointer->currentIndex();
+
+ // Get the parent model index.
+ QModelIndex parentIndex = currentIndex.parent();
+
+ // Determine if a domain is selected.
+ bool isDomain = standardItemModelPointer->hasChildren(currentIndex);
- // Create a layout item pointer.
- QLayoutItem *layoutItemPointer;
+ // Instantiate a delete cookie message box.
+ QMessageBox deleteCookieMessageBox;
- // Delete each cookie widget.
- while ((layoutItemPointer = cookiesVBoxLayoutPointer->takeAt(0)) != nullptr)
+ // Set the icon.
+ deleteCookieMessageBox.setIcon(QMessageBox::Warning);
+
+ if (isDomain)
+ {
+ // Get the number of cookies.
+ int numberOfCookiesToDelete = standardItemModelPointer->rowCount(currentIndex);
+
+ // Set the window title.
+ deleteCookieMessageBox.setWindowTitle(i18nc("Delete cookies dialog title", "Delete %1 Cookies", numberOfCookiesToDelete));
+
+ // Set the text.
+ deleteCookieMessageBox.setText(i18nc("Delete cookies dialog text", "Delete %1 cookies?", numberOfCookiesToDelete));
+ }
+ else
+ {
+ // Set the window title.
+ deleteCookieMessageBox.setWindowTitle(i18nc("Delete cookie dialog title", "Delete 1 Cookie"));
+
+ // Set the text.
+ deleteCookieMessageBox.setText(i18nc("Delete cookie dialog text", "Delete 1 cookie?"));
+ }
+
+ // Set the standard buttons.
+ deleteCookieMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+
+ // Set the default button.
+ deleteCookieMessageBox.setDefaultButton(QMessageBox::No);
+
+ // Display the dialog and capture the return value.
+ int returnValue = deleteCookieMessageBox.exec();
+
+ // Delete the cookie if instructed.
+ if (returnValue == QMessageBox::Yes)
+ {
+ // Delete the cookies according to the selection.
+ if (isDomain) // A domain is selected.
+ {
+ // Get the number of cookies.
+ int numberOfCookies = standardItemModelPointer->rowCount(currentIndex);
+
+ // Delete each child cookie.
+ for (int i = 0; i < numberOfCookies; ++i)
+ {
+ // Delete the cookie for the first child. Once this is deleted, the second child will become the first child.
+ deleteCookie(standardItemModelPointer->index(0, 0, currentIndex));
+ }
+
+ // Delete the domain from the tree view.
+ standardItemModelPointer->removeRow(currentIndex.row(), parentIndex);
+ }
+ else // A single cookie is selected.
{
- // Delete the widget.
- delete layoutItemPointer->widget();
+ // Delete the cookie.
+ deleteCookie(currentIndex);
- // Delete the layout.
- delete layoutItemPointer;
+ // Remove the domain row if its only cookie has been deleted.
+ if (standardItemModelPointer->rowCount(parentIndex) == 0)
+ standardItemModelPointer->removeRow(parentIndex.row(), parentIndex.parent());
}
+ }
+}
- // Update the UI.
- updateUi();
+void CookiesDialog::showEditCookieDialog() const
+{
+ // Get the current model index.
+ QModelIndex currentIndex = treeViewSelectionModelPointer->currentIndex();
+
+ // Create a partial cookie.
+ QNetworkCookie partialCookie;
+
+ // Populate the partial cookie from the current model index.
+ partialCookie.setDomain(currentIndex.parent().siblingAtColumn(0).data().toString());
+ partialCookie.setName(currentIndex.siblingAtColumn(0).data().toString().toUtf8());
+ partialCookie.setPath(currentIndex.siblingAtColumn(1).data().toString());
+
+ // Create a cookie to edit.
+ QNetworkCookie cookieToEdit;
+
+ // Search for the partial cookie in the cookie list.
+ for (QNetworkCookie cookie : *cookieListPointer)
+ {
+ // Store the cookie to edit if it has the same identifier as the partial cookie.
+ if (cookie.hasSameIdentifier(partialCookie))
+ cookieToEdit = cookie;
}
+
+ // Instantiate an edit cookie dialog.
+ QDialog *editCookieDialogPointer = new AddOrEditCookieDialog(AddOrEditCookieDialog::EditCookie, &cookieToEdit);
+
+ // Show the dialog.
+ editCookieDialogPointer->show();
+
+ // Process cookie events.
+ connect(editCookieDialogPointer, SIGNAL(addCookie(QNetworkCookie)), this, SLOT(addCookieFromDialog(QNetworkCookie)));
+ connect(editCookieDialogPointer, SIGNAL(deleteCookie(QNetworkCookie)), this, SLOT(deleteCookieFromDialog(QNetworkCookie)));
}
void CookiesDialog::updateUi() const
{
+ // Get the current index of the first column.
+ QModelIndex currentIndex = treeViewSelectionModelPointer->currentIndex().siblingAtColumn(0);
+
// Set the status of the buttons.
- deleteAllButtonPointer->setEnabled(cookieListPointer->count() > 0);
+ editCookieButtonPointer->setEnabled(treeViewSelectionModelPointer->hasSelection() && !standardItemModelPointer->hasChildren(currentIndex));
+ deleteCookieButtonPointer->setEnabled(treeViewSelectionModelPointer->hasSelection());;
+ deleteAllButtonPointer->setEnabled(standardItemModelPointer->hasChildren(standardItemModelPointer->invisibleRootItem()->index()));
+
+ // Update the delete cookie button text.
+ if (deleteCookieButtonPointer->isEnabled()) // The button is enabled.
+ {
+ if (standardItemModelPointer->hasChildren(currentIndex)) // A domain is selected.
+ {
+ // Update the button text.
+ deleteCookieButtonPointer->setText(i18nc("Delete cookies button.", "&Delete %1 cookies", standardItemModelPointer->rowCount(currentIndex)));
+ }
+ else // A single cookie is selected.
+ {
+ // Update the button text.
+ deleteCookieButtonPointer->setText(i18nc("Delete cookies button.", "&Delete 1 cookie"));
+ }
+ }
+ else // The button is disabled.
+ {
+ // Reset the button text.
+ deleteCookieButtonPointer->setText(i18nc("Delete cookie button.", "&Delete cookie"));
+ }
}
// Qt toolkit headers.
#include <QDialog>
+#include <QItemSelectionModel>
#include <QNetworkCookie>
-#include <QVBoxLayout>
+#include <QStandardItemModel>
+#include <QTreeView>
+
+// C++ headers.
+#include <forward_list>
class CookiesDialog : public QDialog
{
public:
// The primary constructor.
- explicit CookiesDialog(QList<QNetworkCookie> *cookieListPointer);
+ explicit CookiesDialog(std::forward_list<QNetworkCookie> *cookieListPointer);
signals:
// The signals.
void addCookie(const QNetworkCookie &cookie) const;
void deleteAllCookies() const;
+ void deleteCookie(const QNetworkCookie &cookie) const;
private Q_SLOTS:
// The private slots.
void addCookieFromDialog(const QNetworkCookie &cookie) const;
- void showAddCookieMessageBox() const;
+ void deleteCookieFromDialog(const QNetworkCookie &cookie) const;
+ void showAddCookieDialog() const;
void showDeleteAllMessageBox() const;
+ void showDeleteCookieMessageBox() const;
+ void showEditCookieDialog() const;
+ void updateUi() const;
private:
// The private variables.
+ QItemSelectionModel *treeViewSelectionModelPointer;
QPushButton *addCookieButtonPointer;
- QList<QNetworkCookie> *cookieListPointer;
- QVBoxLayout *cookiesVBoxLayoutPointer;
+ std::forward_list<QNetworkCookie> *cookieListPointer;
QPushButton *deleteAllButtonPointer;
+ QPushButton *deleteCookieButtonPointer;
+ QPushButton *editCookieButtonPointer;
+ QStandardItemModel *standardItemModelPointer;
+ QTreeView *treeViewPointer;
// The private functions.
- void addCookieToLayout(const QNetworkCookie &cookie) const;
- void updateUi() const;
+ void deleteCookie(const QModelIndex &modelIndex) const;
};
#endif
// The default constructor.
UserAgentHelper();
- // The public constants.
+ // The public static constants.
static const QString CHROMIUM_LINUX_DATABASE;
static const QString CHROMIUM_LINUX_TRANSLATED;
static const QString CHROMIUM_LINUX_USER_AGENT;
static const QString WEB_ENGINE_DEFAULT_DATABASE;
static const QString WEB_ENGINE_DEFAULT_TRANSLATED;
- // The public functions.
+ // The public static functions.
static QString getDatabaseUserAgentNameFromTranslatedName(const QString &translatedUserAgentName);
static int getDomainSettingsUserAgentIndex(const QString &userAgentName);
static QString getUserAgentFromDatabaseName(const QString &userAgentDatabaseName);
+++ /dev/null
-<?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>AddCookieDialog</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>Domain&nbsp;</string>
- </property>
- </widget>
- </item>
-
- <item>
- <widget class="QLineEdit" name="domainLineEdit">
- <property name="toolTip">
- <string>Cookies prepended by a period are accessible to all subdomains.</string>
- </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>&nbsp;&nbsp;&nbsp;&nbsp;Name&nbsp;</string>
- </property>
- </widget>
- </item>
-
- <item>
- <widget class="QLineEdit" name="nameLineEdit">
- <property name="toolTip">
- <string>The identifier of the cookie, which is unique when combined with the domain and the path.</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
-
- <item>
- <layout class="QHBoxLayout">
- <property name="alignment">
- <enum>Qt::AlignLeft</enum>
- </property>
-
- <!-- Expiration date. -->
- <item>
- <widget class="QCheckBox" name="expirationCheckBox">
- <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>
- </widget>
- </item>
-
- <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&nbsp;</string>
- </property>
- </widget>
- </item>
-
- <item>
- <widget class="QDateTimeEdit" name="expirationDateTimeEdit">
- <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="dateTime">
- <datetime>
- <year>2030</year>
- <month>1</month>
- <day>1</day>
- <hour>0</hour>
- <minute>0</minute>
- <second>0</second>
- </datetime>
- </property>
-
- <property name="calendarPopup">
- <bool>true</bool>
- </property>
-
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- </item>
-
- <!-- Path. -->
- <item>
- <widget class="QLabel">
- <property name="toolTip">
- <string>Websites can restrict cookie access to subpath of their URL.</string>
- </property>
-
- <property name="textFormat">
- <enum>Qt::RichText</enum>
- </property>
-
- <property name="text">
- <string>&nbsp;&nbsp;&nbsp;&nbsp;Path&nbsp;</string>
- </property>
- </widget>
- </item>
-
- <item>
- <widget class="QLineEdit" name="pathLineEdit">
- <property name="toolTip">
- <string>Websites can restrict cookie access to subpath of their URL.</string>
- </property>
-
- <property name="text">
- <string>/</string>
- </property>
- </widget>
- </item>
-
- <!-- A spacer label. Necessary to add space before the check box. -->
- <item>
- <widget class="QLabel">
- <property name="textFormat">
- <enum>Qt::RichText</enum>
- </property>
-
- <property name="text">
- <string>&nbsp;&nbsp;&nbsp;&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="checked">
- <bool>true</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&nbsp;&nbsp;&nbsp;&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="checked">
- <bool>true</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&nbsp;</string>
- </property>
- </widget>
- </item>
-
- <item>
- <widget class="QLineEdit" name="valueLineEdit">
- <property name="toolTip">
- <string>The value contains the cookie data.</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
-
- <!-- Spacer. -->
- <item>
- <spacer>
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- </spacer>
- </item>
-
- <!-- Dialog buttons. -->
- <item>
- <widget class="QDialogButtonBox" name="dialogButtonBox">
- <property name="standardButtons">
- <set>QDialogButtonBox::Save | QDialogButtonBox::Cancel</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
-</ui>
--- /dev/null
+<?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>AddOrEditCookieDialog</class>
+
+ <widget class="QWidget">
+ <layout class="QVBoxLayout">
+ <item>
+ <!-- First row. -->
+ <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="text">
+ <string>Domain</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="domainLineEdit" />
+ </item>
+
+ <item>
+ <widget class="QLabel">
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+
+ <!-- Spacer label. -->
+ <property name="text">
+ <string>&nbsp;&nbsp;&nbsp;</string>
+ </property>
+ </widget>
+ </item>
+
+ <!-- Name. -->
+ <item>
+ <widget class="QLabel">
+ <property name="toolTip">
+ <string>The name identifies the cookie. Each cookie has a unique combination of domain, name, and path.</string>
+ </property>
+
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="nameLineEdit" />
+ </item>
+ </layout>
+ </item>
+
+ <!-- Second row. -->
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="alignment">
+ <enum>Qt::AlignLeft</enum>
+ </property>
+
+ <!-- Path. -->
+ <item>
+ <widget class="QLabel">
+ <property name="toolTip">
+ <string>Websites can restrict cookie access to subpath of their URL.</string>
+ </property>
+
+ <property name="text">
+ <string>Path</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="pathLineEdit">
+ <property name="text">
+ <string>/</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLabel">
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+
+ <!-- Spacer label. -->
+ <property name="text">
+ <string>&nbsp;&nbsp;&nbsp;</string>
+ </property>
+ </widget>
+ </item>
+
+ <!-- Expiration date. -->
+ <item>
+ <widget class="QCheckBox" name="expirationCheckBox">
+ <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>
+ </widget>
+ </item>
+
+ <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="text">
+ <string>Expiration date</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLabel">
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+
+ <!-- Spacer label. -->
+ <property name="text">
+ <string>&nbsp;</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QDateTimeEdit" name="expirationDateTimeEdit">
+ <property name="dateTime">
+ <datetime>
+ <year>2030</year>
+ <month>1</month>
+ <day>1</day>
+ <hour>0</hour>
+ <minute>0</minute>
+ <second>0</second>
+ </datetime>
+ </property>
+
+ <property name="calendarPopup">
+ <bool>true</bool>
+ </property>
+
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLabel">
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+
+ <!-- Spacer label. -->
+ <property name="text">
+ <string>&nbsp;&nbsp;&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="checked">
+ <bool>true</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="text">
+ <string>HTTP only</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLabel">
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+
+ <!-- Spacer label. -->
+ <property name="text">
+ <string>&nbsp;&nbsp;&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="checked">
+ <bool>true</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>
+
+ <!-- Third row. -->
+ <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="text">
+ <string>Value</string>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <widget class="QLineEdit" name="valueLineEdit" />
+ </item>
+ </layout>
+ </item>
+
+ <!-- Spacer. -->
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </spacer>
+ </item>
+
+ <!-- Dialog buttons. -->
+ <item>
+ <widget class="QDialogButtonBox" name="dialogButtonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Save | QDialogButtonBox::Cancel</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+</ui>
+++ /dev/null
-<?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>CookieDisplayWidget</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><font size="+1">Domain:&nbsp;</font></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><font size="+1">&nbsp;&nbsp;&nbsp;&nbsp;Name:&nbsp;</font></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:&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 cookie access to a subpath of their URL.</string>
- </property>
-
- <property name="textFormat">
- <enum>Qt::RichText</enum>
- </property>
-
- <property name="text">
- <string>&nbsp;&nbsp;&nbsp;&nbsp;Path:&nbsp;</string>
- </property>
- </widget>
- </item>
-
- <item>
- <widget class="QLabel" name="pathLabel">
- <property name="toolTip">
- <string>Websites can restrict cookie access to 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 label. Necessary to add space before the check box. -->
- <item>
- <widget class="QLabel">
- <property name="textFormat">
- <enum>Qt::RichText</enum>
- </property>
-
- <property name="text">
- <string>&nbsp;&nbsp;&nbsp;&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&nbsp;&nbsp;&nbsp;&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:&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>
<layout class="QVBoxLayout">
<item>
<!-- Scroll area. -->
- <widget class="QScrollArea" name="scrollArea">
- <property name="widgetResizable">
- <bool>true</bool>
- </property>
- </widget>
+ <widget class="QTreeView" name="treeView" />
</item>
<item>
<item>
<widget class="QPushButton" name="addCookieButton">
<property name="text">
- <string>Add cookie</string>
+ <string>&Add cookie</string>
</property>
<property name="icon">
<!-- Edit cookie button. -->
<item>
- <widget class="QPushButton" name="editDomainButton">
+ <widget class="QPushButton" name="editCookieButton">
<property name="text">
- <string>Edit cookie</string>
+ <string>&Edit cookie</string>
</property>
<property name="icon">
<!-- Delete domain button. -->
<item>
- <widget class="QPushButton" name="deleteDomainButton">
+ <widget class="QPushButton" name="deleteCookieButton">
<property name="text">
- <string>Delete cookie</string>
+ <string>De&lete cookie</string>
</property>
<property name="icon">
webEngineSettingsPointer = webEngineViewPointer->settings();
webEngineCookieStorePointer = webEngineProfilePointer->cookieStore();
- // Store a copy of each cookie when it is added.
+ // Process cookie changes.
connect(webEngineCookieStorePointer, SIGNAL(cookieAdded(QNetworkCookie)), this, SLOT(cookieAdded(QNetworkCookie)));
+ connect(webEngineCookieStorePointer, SIGNAL(cookieRemoved(QNetworkCookie)), this, SLOT(cookieRemoved(QNetworkCookie)));
// Store a copy of the WebEngine default user agent.
webEngineDefaultUserAgent = webEngineProfilePointer->httpUserAgent();
emit addCookie(cookie);
}
+void BrowserView::cookieRemoved(const QNetworkCookie &cookie) const
+{
+ // Remove the cookie from the cookie list.
+ emit removeCookie(cookie);
+}
+
void BrowserView::deleteAllCookies() const
{
// Delete all the cookies.
webEngineCookieStorePointer->deleteAllCookies();
}
+void BrowserView::deleteCookieFromStore(const QNetworkCookie &cookie) const
+{
+ // Delete the cookie.
+ webEngineCookieStorePointer->deleteCookie(cookie);
+}
+
void BrowserView::forward() const
{
// Go forward.
signals:
// The signals.
void addCookie(const QNetworkCookie &cookie) const;
+ void removeCookie(const QNetworkCookie &cookie) const;
void clearUrlLineEditFocus() const;
void hideProgressBar() const;
void linkHovered(const QString &linkUrl) const;
void applyOnTheFlyUserAgent(QAction *userAgentActionPointer) const;
void back() const;
void deleteAllCookies() const;
+ void deleteCookieFromStore(const QNetworkCookie &cookie) const;
void forward() const;
void home() const;
void loadUrlFromLineEdit(QString url) const;
private Q_SLOTS:
// The private slots.
void cookieAdded(const QNetworkCookie &cookie) const;
+ void cookieRemoved(const QNetworkCookie &cookie) const;
void loadFinished() const;
void loadProgress(const int &progress) const;
void loadStarted() const;
connect(browserViewPointer, SIGNAL(updateDomainSettingsIndicator(bool, QString)), this, SLOT(updateDomainSettingsIndicator(bool, QString)));
// Initialize the cookie list.
- cookieListPointer = new QList<QNetworkCookie>;
+ cookieListPointer = new std::forward_list<QNetworkCookie>;
- // Add new cookies to the list.
+ // Process cookie changes.
connect(browserViewPointer, SIGNAL(addCookie(QNetworkCookie)), this, SLOT(addCookieToList(QNetworkCookie)));
+ connect(browserViewPointer, SIGNAL(removeCookie(QNetworkCookie)), this, SLOT(removeCookieFromList(QNetworkCookie)));
// Load the initial website.
browserViewPointer->loadInitialWebsite();
void BrowserWindow::addCookieToList(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);
- }
-
+ qDebug() << "Add cookie: " << newCookie.toRawForm();
// Add the new cookie to the list.
- cookieListPointer->append(newCookie);
+ cookieListPointer->push_front(newCookie);
}
void BrowserWindow::addOrEditDomainSettings() const
// Connect the dialog signals.
connect(cookiesDialogPointer, SIGNAL(addCookie(QNetworkCookie)), browserViewPointer, SLOT(addCookieToStore(QNetworkCookie)));
connect(cookiesDialogPointer, SIGNAL(deleteAllCookies()), browserViewPointer, SLOT(deleteAllCookies()));
+ connect(cookiesDialogPointer, SIGNAL(deleteCookie(QNetworkCookie)), browserViewPointer, SLOT(deleteCookieFromStore(QNetworkCookie)));
}
void BrowserWindow::openDomainSettings() const
browserViewPointer->refresh();
}
+void BrowserWindow::removeCookieFromList(const QNetworkCookie &cookie) const
+{
+ qDebug() << "Remove cookie: " << cookie.toRawForm();
+
+ // Remove the cookie from the list.
+ cookieListPointer->remove(cookie);
+}
+
void BrowserWindow::showProgressBar(const int &progress) const
{
// Set the progress bar value.
#include <QLabel>
#include <QProgressBar>
+// C++ headers.
+#include <forward_list>
+
class BrowserWindow : public KXmlGuiWindow
{
// Include the Q_OBJECT macro.
void openCookiesDialog();
void openDomainSettings() const;
void refresh() const;
+ void removeCookieFromList(const QNetworkCookie &cookie) const;
void settingsConfigure();
void showProgressBar(const int &progress) const;
void toggleJavaScript() const;
// The private variables.
BrowserView *browserViewPointer;
KConfigDialog *configDialogPointer;
- QList<QNetworkCookie> *cookieListPointer;
+ std::forward_list<QNetworkCookie> *cookieListPointer;
QString currentDomainSettingsDomain;
QUrl currentUrl;
double currentZoomFactor;