uis/BrowserView.ui
uis/CookiesDialog.ui
uis/DomainSettingsDialog.ui
+ uis/DurableCookiesDialog.ui
uis/SettingsGeneral.ui
uis/SettingsPrivacy.ui
)
# Add the subdirectories.
add_subdirectory(databases)
+add_subdirectory(delegates)
add_subdirectory(dialogs)
add_subdirectory(filters)
add_subdirectory(helpers)
}
}
+int CookiesDatabase::cookieCount()
+{
+ // Get a handle for the cookies database.
+ QSqlDatabase cookiesDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Instantiate a count cookies query.
+ QSqlQuery countCookiesQuery(cookiesDatabase);
+
+ // Set the query to be forward only.
+ countCookiesQuery.setForwardOnly(true);
+
+ // Prepare the query.
+ countCookiesQuery.prepare("SELECT " + _ID + " FROM " + COOKIES_TABLE);
+
+ // Execute the query.
+ countCookiesQuery.exec();
+
+ // Move to the last row.
+ countCookiesQuery.last();
+
+ // Get the number of rows (which is zero based).
+ int numberOfCookies = countCookiesQuery.at() + 1;
+
+ // Return the number of cookies.
+ return numberOfCookies;
+}
+
void CookiesDatabase::deleteAllCookies()
{
// Get a handle for the cookies database.
return cookieListPointer;
}
+QNetworkCookie* CookiesDatabase::getCookieById(const int &id)
+{
+ // Get a handle for the cookies database.
+ QSqlDatabase cookiesDatabase = QSqlDatabase::database(CONNECTION_NAME);
+
+ // Instantiate a cookie query.
+ QSqlQuery cookieQuery(cookiesDatabase);
+
+ // Set the query to be forward only.
+ cookieQuery.setForwardOnly(true);
+
+ // Prepare the cookies query.
+ cookieQuery.prepare("SELECT * FROM " + COOKIES_TABLE + " WHERE " + _ID + " = :id");
+
+ // Bind the values.
+ cookieQuery.bindValue(":id", id);
+
+ // Execute the query.
+ cookieQuery.exec();
+
+ // Move to the first entry.
+ cookieQuery.first();
+
+ // Create a cookie.
+ QNetworkCookie *cookiePointer = new QNetworkCookie();
+
+ // Populate the cookie.
+ cookiePointer->setDomain(cookieQuery.value(DOMAIN).toString());
+ cookiePointer->setName(cookieQuery.value(NAME).toString().toUtf8());
+ cookiePointer->setPath(cookieQuery.value(PATH).toString());
+ cookiePointer->setExpirationDate(QDateTime::fromString(cookieQuery.value(EXPIRATION_DATE).toString(), Qt::ISODate));
+ cookiePointer->setHttpOnly(cookieQuery.value(HTTP_ONLY).toBool());
+ cookiePointer->setSecure(cookieQuery.value(SECURE).toBool());
+ cookiePointer->setValue(cookieQuery.value(VALUE).toString().toUtf8());
+
+ // Return the cookie.
+ return cookiePointer;
+}
+
bool CookiesDatabase::isDurable(const QNetworkCookie &cookie)
{
// Get a handle for the cookies database.
// The public functions.
static void addDatabase();
static void addCookie(const QNetworkCookie &cookie);
+ static int cookieCount();
static void deleteAllCookies();
static void deleteCookie(const QNetworkCookie &cookie);
static QList<QNetworkCookie*>* getCookies();
+ static QNetworkCookie* getCookieById(const int &id);
static bool isDurable(const QNetworkCookie &cookie);
static bool isUpdate(const QNetworkCookie &cookie);
static void updateCookie(const QNetworkCookie &cookie);
--- /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/>.
+
+
+# List the sources to include in the executable.
+target_sources(privacy-browser PRIVATE
+ ViewOnlyDelegate.cpp
+)
--- /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 "ViewOnlyDelegate.h"
+
+ViewOnlyDelegate::ViewOnlyDelegate(QObject *parentPointer) : QStyledItemDelegate(parentPointer) {}
+
+QWidget* ViewOnlyDelegate::createEditor(QWidget *parentWidgetPointer, const QStyleOptionViewItem &styleOptionsViewItem, const QModelIndex &modelIndex) const
+{
+ // Instruct the compiler to ignore the unused variables.
+ (void) parentWidgetPointer;
+ (void) styleOptionsViewItem;
+ (void) modelIndex;
+
+ // Disable editing.
+ return nullptr;
+}
--- /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 VIEWONLYDELEGATE_H
+#define VIEWONLYDELEGATE_H
+
+// Qt toolkit headers.
+#include <QStyledItemDelegate>
+
+class ViewOnlyDelegate : public QStyledItemDelegate
+{
+ // Include the Q_OBJECT macro.
+ Q_OBJECT
+
+public:
+ // The default constructor.
+ explicit ViewOnlyDelegate(QObject *parentPointer = nullptr);
+
+ // The public functions.
+ QWidget* createEditor(QWidget *parentWidgetPointer, const QStyleOptionViewItem &styleOptionsViewItem, const QModelIndex &modelIndex) const override;
+};
+#endif
AddOrEditCookieDialog.cpp
CookiesDialog.cpp
DomainSettingsDialog.cpp
+ DurableCookiesDialog.cpp
)
// Application headers.
#include "AddOrEditCookieDialog.h"
#include "CookiesDialog.h"
+#include "DurableCookiesDialog.h"
#include "ui_CookiesDialog.h"
#include "databases/CookiesDatabase.h"
#include <QShortcut>
#include <QUrl>
-// Construct the class.
+// Define the cookie sort predicate.
bool cookieSortPredicate(const QNetworkCookie &leftHandCookie, const QNetworkCookie &rightHandCookie)
{
// Check to see if the domains are identical.
// Sort the cookies by the top level domain.
return (leftHandTopLevelDomain < rightHandTopLevelDomain);
}
-
}
}
+// Construct the class.
CookiesDialog::CookiesDialog(std::list<QNetworkCookie> *originalCookieListPointer) : QDialog(nullptr), cookieListPointer(originalCookieListPointer)
{
// Set the dialog window title.
// Indicate that all the rows are the same height, wich improves performance.
treeViewPointer->setUniformRowHeights(true);
- // Disable editing.
+ // Disable editing in the tree view.
treeViewPointer->setEditTriggers(QAbstractItemView::NoEditTriggers);
// Set the tree model.
addCookieButtonPointer = cookiesDialogUi.addCookieButton;
editCookieButtonPointer = cookiesDialogUi.editCookieButton;
deleteCookieButtonPointer = cookiesDialogUi.deleteCookieButton;
+ deleteAllButtonPointer = cookiesDialogUi.deleteAllCookiesButton;
QDialogButtonBox *dialogButtonBoxPointer = cookiesDialogUi.dialogButtonBox;
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);
+ // Add buttons to the dialog button box.
+ durableCookiesButtonPointer = dialogButtonBoxPointer->addButton(i18nc("View the durable cookies button", "Durable cookies - %1", CookiesDatabase::cookieCount()),
+ QDialogButtonBox::ActionRole);
- // Set the delete all button icon.
- deleteAllButtonPointer->setIcon(QIcon::fromTheme("delete"));
+ // Set the button icons.
+ durableCookiesButtonPointer->setIcon(QIcon::fromTheme("view-visible"));
// Connect the buttons.
connect(addCookieButtonPointer, SIGNAL(clicked()), this, SLOT(showAddCookieDialog()));
connect(editCookieButtonPointer, SIGNAL(clicked()), this, SLOT(showEditCookieDialog()));
connect(deleteCookieButtonPointer, SIGNAL(clicked()), this, SLOT(showDeleteCookieMessageBox()));
+ connect(durableCookiesButtonPointer, SIGNAL(clicked()), this, SLOT(showDurableCookiesDialog()));
connect(deleteAllButtonPointer, SIGNAL(clicked()), this, SLOT(showDeleteAllMessageBox()));
connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject()));
- // Set the cancel button to be the default.
+ // Set the close button to be the default.
closeButtonPointer->setDefault(true);
// Create the keyboard shortcuts.
treeModelPointer->removeRow(modelIndex.row(), parentIndex);
}
+void CookiesDialog::deleteCookieFromDatabase(const QNetworkCookie &cookie) const
+{
+ // Get a list of the matching domains. There should only be one item in this list
+ QList<QStandardItem *> domainList = treeModelPointer->findItems(cookie.domain());
+
+ // Find any matching cookies.
+ for (QStandardItem *domainItemPointer : domainList)
+ {
+ // Get the number of cookies in the domain.
+ int numberOfCookies = domainItemPointer->rowCount();
+
+ // Initialize the tracking variables.
+ bool cookieFound = false;
+ int currentRow = 0;
+
+ // Find the cookie in the tree model.
+ while (!cookieFound && (currentRow < numberOfCookies))
+ {
+ // Get the name item.
+ QStandardItem *nameItemPointer = domainItemPointer->child(currentRow);
+
+ // Get the name model index.
+ QModelIndex nameModelIndex = nameItemPointer->index();
+
+ // Check to see if the name and the path match.
+ if ((nameModelIndex.data().toString() == cookie.name()) && (nameModelIndex.siblingAtColumn(2).data().toString() == cookie.path()))
+ {
+ // Set the current index.
+ treeSelectionModelPointer->setCurrentIndex(nameModelIndex, QItemSelectionModel::ClearAndSelect);
+
+ // Delete the cookie.
+ deleteCookieFromDialog(cookie);
+
+ // Mark the cookie as found.
+ cookieFound = true;
+ }
+
+ // Move to the next row.
+ ++currentRow;
+ }
+ }
+}
void CookiesDialog::deleteCookieFromDialog(const QNetworkCookie &cookie) const
{
}
}
+void CookiesDialog::showDurableCookiesDialog() const
+{
+ // Instantiate a durable cookies dialog.
+ QDialog *durableCookiesDialogPointer = new DurableCookiesDialog();
+
+ // Show the dialog.
+ durableCookiesDialogPointer->show();
+
+ // Process cookie changes.
+ connect(durableCookiesDialogPointer, SIGNAL(addingCookie(QNetworkCookie, bool)), this, SLOT(addCookieFromDialog(QNetworkCookie, bool)));
+ connect(durableCookiesDialogPointer, SIGNAL(deletingCookie(QNetworkCookie)), this, SLOT(deleteCookieFromDatabase(QNetworkCookie)));
+ connect(durableCookiesDialogPointer, SIGNAL(updateParentUi()), this, SLOT(updateUi()));
+}
+
void CookiesDialog::showEditCookieDialog() const
{
// Get the current model index.
// Reset the button text.
deleteCookieButtonPointer->setText(i18nc("Delete cookie button.", "&Delete cookie"));
}
+
+ // Update the text of the durable cookies button.
+ durableCookiesButtonPointer->setText(i18nc("View the durable cookies button", "Durable cookies - %1", CookiesDatabase::cookieCount()));
}
private Q_SLOTS:
// The private slots.
void addCookieFromDialog(const QNetworkCookie &cookie, const bool &isDurable) const;
+ void deleteCookieFromDatabase(const QNetworkCookie &cookie) const;
void deleteCookieFromDialog(const QNetworkCookie &cookie) const;
void showAddCookieDialog() const;
void showDeleteAllMessageBox() const;
void showDeleteCookieMessageBox() const;
+ void showDurableCookiesDialog() const;
void showEditCookieDialog() const;
void updateUi() const;
std::list<QNetworkCookie> *cookieListPointer;
QPushButton *deleteAllButtonPointer;
QPushButton *deleteCookieButtonPointer;
+ QPushButton *durableCookiesButtonPointer;
QPushButton *editCookieButtonPointer;
QStandardItemModel *treeModelPointer;
QItemSelectionModel *treeSelectionModelPointer;
// Update the delete button status.
deleteDomainButtonPointer->setEnabled(domainsSelectionModelPointer->hasSelection());
- // Update the apply button status.
- applyButtonPointer->setEnabled(domainsTableModelPointer->isDirty());
-
// Update the reset button status.
resetButtonPointer->setEnabled(domainsTableModelPointer->isDirty());
+ // Update the apply button status.
+ applyButtonPointer->setEnabled(domainsTableModelPointer->isDirty());
+
// Display the domain settings if there is at least one domain.
domainSettingsWidgetPointer->setVisible(domainsTableModelPointer->rowCount() > 0);
}
--- /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 "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();
+}
--- /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 DURABLECOOKIESDIALOG_H
+#define DURABLECOOKIESDIALOG_H
+
+// Qt toolkit headers.
+#include <QDialog>
+#include <QItemSelectionModel>
+#include <QNetworkCookie>
+#include <QSqlTableModel>
+
+class DurableCookiesDialog : public QDialog
+{
+ // Include the Q_OBJECT macro.
+ Q_OBJECT
+
+public:
+ // The default constructor.
+ explicit DurableCookiesDialog();
+
+signals:
+ // The signals.
+ void addingCookie(const QNetworkCookie &cookie, const bool &addToDatabase) const;
+ void deletingCookie(const QNetworkCookie &cookie) const;
+ void updateParentUi() const;
+
+private Q_SLOTS:
+ // The private slots.
+ void addCookie() const;
+ void apply() const;
+ void beforeDelete(int row) const;
+ void beforeUpdate(int row, QSqlRecord &sqlRecord) const;
+ void deleteAllCookies() const;
+ void deleteCookie() const;
+ void newCookie(QSqlRecord &sqlRecord) const;
+ void ok();
+ void reset() const;
+ void updateUi() const;
+
+private:
+ // The private variables.
+ QPushButton *applyButtonPointer;
+ QPushButton *deleteAllCookiesButtonPointer;
+ QPushButton *deleteCookieButtonPointer;
+ QSqlTableModel *durableCookiesTableModelPointer;
+ QItemSelectionModel *tableSelectionModelPointer;
+ QPushButton *resetButtonPointer;
+};
+#endif
if (eventPointer->type() == QEvent::MouseButtonPress)
{
// Tell the compiler to ignore the unused object pointer.
- (void)objectPointer;
+ (void) objectPointer;
// Cast the event to a mouse event.
QMouseEvent *mouseEventPointer = static_cast<QMouseEvent *>(eventPointer);
</property>
<layout class="QVBoxLayout">
+ <!-- Tree view. -->
<item>
- <!-- Scroll area. -->
<widget class="QTreeView" name="treeView" />
</item>
+ <!-- Buttons. -->
<item>
<layout class="QHBoxLayout">
<!-- Add cookie button. -->
</widget>
</item>
- <!-- Delete domain button. -->
+ <!-- Delete cookie button. -->
<item>
<widget class="QPushButton" name="deleteCookieButton">
<property name="text">
- <string>De&lete cookie</string>
+ <string>&Delete cookie</string>
</property>
<property name="icon">
</widget>
</item>
- <!-- Close button. -->
+ <!-- Delete all cookies button. -->
+ <item>
+ <widget class="QPushButton" name="deleteAllCookiesButton">
+ <property name="text">
+ <string>Delete &all</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="delete" />
+ </property>
+ </widget>
+ </item>
+
+ <!-- Close button - dialog button box. -->
<item>
<widget class="QDialogButtonBox" name="dialogButtonBox">
<property name="standardButtons">
--- /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>DurableCookiesDialog</class>
+
+ <widget class="QWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <height>900</height>
+ <width>1400</width>
+ </rect>
+ </property>
+
+ <layout class="QVBoxLayout">
+ <!-- Table view. -->
+ <item>
+ <widget class="QTableView" name="tableView">
+ <property name="selectionMode">
+ <enum>QAbstractItemView::SingleSelection</enum>
+ </property>
+
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ </widget>
+ </item>
+
+ <!-- Buttons. -->
+ <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>
+
+ <!-- Delete cookie button. -->
+ <item>
+ <widget class="QPushButton" name="deleteCookieButton">
+ <property name="text">
+ <string>&Delete cookie</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="list-remove" />
+ </property>
+ </widget>
+ </item>
+
+ <!-- Delete all cookies button. -->
+ <item>
+ <widget class="QPushButton" name="deleteAllCookiesButton">
+ <property name="text">
+ <string>Delete &all</string>
+ </property>
+
+ <property name="icon">
+ <iconset theme="delete" />
+ </property>
+ </widget>
+ </item>
+
+ <!-- Spacer. -->
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </spacer>
+ </item>
+
+ <!-- Dialog button box - reset, OK, apply and close. -->
+ <item>
+ <widget class="QDialogButtonBox" name="dialogButtonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Reset | QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Cancel</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+</ui>