]> gitweb.stoutner.com Git - PrivacyBrowserPC.git/blobdiff - src/dialogs/DurableCookiesDialog.cpp
Add a durable cookies dialog.
[PrivacyBrowserPC.git] / src / dialogs / DurableCookiesDialog.cpp
diff --git a/src/dialogs/DurableCookiesDialog.cpp b/src/dialogs/DurableCookiesDialog.cpp
new file mode 100644 (file)
index 0000000..d998c20
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * 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 "DurableCookiesDialog.h"
+#include "ui_DurableCookiesDialog.h"
+#include "databases/CookiesDatabase.h"
+#include "delegates/ViewOnlyDelegate.h"
+
+// KDE Frameworks headers.
+#include <KLocalizedString>
+
+DurableCookiesDialog::DurableCookiesDialog() : QDialog(nullptr)
+{
+    // Set the dialog window title.
+    setWindowTitle(i18nc("The durable cookies dialog window title", "Durable Cookies"));
+
+    // Set the window modality.
+    setWindowModality(Qt::WindowModality::ApplicationModal);
+
+    // Instantiate the durable cookies dialog UI.
+    Ui::DurableCookiesDialog durableCookiesDialogUi;
+
+    // Setup the UI.
+    durableCookiesDialogUi.setupUi(this);
+
+    // Get a handle for the table view.
+    QTableView *tableViewPointer = durableCookiesDialogUi.tableView;
+
+    // Create the durable cookies table model.
+    durableCookiesTableModelPointer = new QSqlTableModel(nullptr, QSqlDatabase::database(CookiesDatabase::CONNECTION_NAME));
+
+    // Set the table.
+    durableCookiesTableModelPointer->setTable(CookiesDatabase::COOKIES_TABLE);
+
+    // Set the edit strategy.
+    durableCookiesTableModelPointer->setEditStrategy(QSqlTableModel::OnManualSubmit);
+
+    // Populate the model.
+    durableCookiesTableModelPointer->select();
+
+    // Set the model.
+    tableViewPointer->setModel(durableCookiesTableModelPointer);
+
+    // Instantiate the view only delegate.
+    ViewOnlyDelegate *viewOnlyDelegatePointer = new ViewOnlyDelegate();
+
+    // Disable editing the first column.
+    tableViewPointer->setItemDelegateForColumn(0, viewOnlyDelegatePointer);
+
+    // Optimize the width of the columns.
+    tableViewPointer->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
+
+    // Get the seleciton model.
+    tableSelectionModelPointer = tableViewPointer->selectionModel();
+
+    // Update the UI when the selection changes.
+    connect(tableSelectionModelPointer, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(updateUi()));
+
+    // Update the UI when the table model data changes.
+    connect(durableCookiesTableModelPointer, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(updateUi()));
+
+    // Get handles for the buttons.
+    QPushButton *addCookieButtonPointer = durableCookiesDialogUi.addCookieButton;
+    deleteCookieButtonPointer = durableCookiesDialogUi.deleteCookieButton;
+    deleteAllCookiesButtonPointer = durableCookiesDialogUi.deleteAllCookiesButton;
+    QDialogButtonBox *dialogButtonBoxPointer = durableCookiesDialogUi.dialogButtonBox;
+    resetButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::Reset);
+    applyButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::Apply);
+    QPushButton *okButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::Ok);
+
+    // Set the OK button to be the default.
+    okButtonPointer->setDefault(true);
+
+    // Connect the buttons.
+    connect(addCookieButtonPointer, SIGNAL(clicked()), this, SLOT(addCookie()));
+    connect(deleteCookieButtonPointer, SIGNAL(clicked()), this, SLOT(deleteCookie()));
+    connect(deleteAllCookiesButtonPointer, SIGNAL(clicked()), this, SLOT(deleteAllCookies()));
+    connect(resetButtonPointer, SIGNAL(clicked()), this, SLOT(reset()));
+    connect(dialogButtonBoxPointer, SIGNAL(accepted()), this, SLOT(ok()));
+    connect(applyButtonPointer, SIGNAL(clicked()), this, SLOT(apply()));
+    connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject()));
+
+    // Connect the table model signals.
+    connect(durableCookiesTableModelPointer, SIGNAL(beforeDelete(int)), this, SLOT(beforeDelete(int)));
+    connect(durableCookiesTableModelPointer, SIGNAL(beforeUpdate(int, QSqlRecord &)), this, SLOT(beforeUpdate(int, QSqlRecord &)));
+    connect(durableCookiesTableModelPointer, SIGNAL(beforeInsert(QSqlRecord &)), this, SLOT(newCookie(QSqlRecord &)));
+
+    // Update the UI.
+    updateUi();
+}
+
+void DurableCookiesDialog::addCookie() const
+{
+    // Add a new row to the bottom of the table.
+    durableCookiesTableModelPointer->insertRow(durableCookiesTableModelPointer->rowCount());
+
+    // Update the UI.
+    updateUi();
+}
+
+void DurableCookiesDialog::apply() const
+{
+    // Submit all pending changes.
+    durableCookiesTableModelPointer->submitAll();
+
+    // Update the UI.
+    updateUi();
+}
+
+void DurableCookiesDialog::beforeDelete(int row) const
+{
+    // Get the SQL record for the row to be deleted.
+    QSqlRecord sqlRecord = durableCookiesTableModelPointer->record(row);
+
+    // Create a network cookie.
+    QNetworkCookie cookie;
+
+    // Populate the network cookie.
+    cookie.setDomain(sqlRecord.value(CookiesDatabase::DOMAIN).toString());
+    cookie.setName(sqlRecord.value(CookiesDatabase::NAME).toByteArray());
+    cookie.setPath(sqlRecord.value(CookiesDatabase::PATH).toString());
+
+    // Delete the cookie.
+    emit deletingCookie(cookie);
+}
+
+void DurableCookiesDialog::beforeUpdate(int row, QSqlRecord &sqlRecord) const
+{
+    // Tell the compiler to ignore the unused row parameter.
+    (void) row;
+
+    // Delete the old cookie if the core attributes are changing.
+    if (sqlRecord.isGenerated(CookiesDatabase::DOMAIN) || sqlRecord.isGenerated(CookiesDatabase::NAME) || sqlRecord.isGenerated(CookiesDatabase::PATH))
+    {
+        // Get the ID of the cookie
+        int id = sqlRecord.value(CookiesDatabase::_ID).toInt();
+
+        // Get the cookie.
+        QNetworkCookie *cookiePointer = CookiesDatabase::getCookieById(id);
+
+        // Delete the cookie.
+        emit deletingCookie(*cookiePointer);
+    }
+
+    // Add the new cookie, which modifies any existing cookies with the same core attributes.
+    newCookie(sqlRecord);
+}
+
+void DurableCookiesDialog::deleteAllCookies() const
+{
+    // Mark all the cookies for deletion.
+    durableCookiesTableModelPointer->removeRows(0, durableCookiesTableModelPointer->rowCount());
+
+    // Update the UI.
+    updateUi();
+}
+
+void DurableCookiesDialog::deleteCookie() const
+{
+    // Delete the currently selected row.
+    durableCookiesTableModelPointer->removeRow(tableSelectionModelPointer->selectedRows()[0].row());
+
+    // Update the UI.
+    updateUi();
+}
+
+void DurableCookiesDialog::newCookie(QSqlRecord &sqlRecord) const
+{
+    // Create a network cookie.
+    QNetworkCookie cookie;
+
+    // Populate the network cookie from the SQL record.
+    cookie.setDomain(sqlRecord.value(CookiesDatabase::DOMAIN).toString());
+    cookie.setName(sqlRecord.value(CookiesDatabase::NAME).toByteArray());
+    cookie.setPath(sqlRecord.value(CookiesDatabase::PATH).toString());
+    cookie.setExpirationDate(QDateTime::fromString(sqlRecord.value(CookiesDatabase::EXPIRATION_DATE).toString(), Qt::ISODate));
+    cookie.setHttpOnly(sqlRecord.value(CookiesDatabase::HTTP_ONLY).toBool());
+    cookie.setSecure(sqlRecord.value(CookiesDatabase::SECURE).toBool());
+    cookie.setValue(sqlRecord.value(CookiesDatabase::VALUE).toByteArray());
+
+    // Update the cookie in the cookies dialog tree, cookies list, and cookie store.
+    emit addingCookie(cookie, false);
+}
+
+void DurableCookiesDialog::ok()
+{
+    // Submit all pending changes.
+    durableCookiesTableModelPointer->submitAll();
+
+    // Update the parent UI.
+    updateParentUi();
+
+    // Close the dialog.
+    accept();
+}
+
+void DurableCookiesDialog::reset() const
+{
+    // Cancel all pending changes.
+    durableCookiesTableModelPointer->revertAll();
+
+    // Update the UI.
+    updateUi();
+}
+
+void DurableCookiesDialog::updateUi() const
+{
+    // Update the delete button status.
+    deleteCookieButtonPointer->setEnabled(tableSelectionModelPointer->hasSelection());
+
+    // Update the delete all button status.
+    deleteAllCookiesButtonPointer->setEnabled(durableCookiesTableModelPointer->rowCount() > 0);
+
+    // Update the reset button status.
+    resetButtonPointer->setEnabled(durableCookiesTableModelPointer->isDirty());
+
+    // Update the apply button status.
+    applyButtonPointer->setEnabled(durableCookiesTableModelPointer->isDirty());
+
+    // Update the parent UI.
+    emit updateParentUi();
+}