2 * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
4 * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
6 * Privacy Browser PC is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * Privacy Browser PC is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
20 // Application headers.
21 #include "DurableCookiesDialog.h"
22 #include "ui_DurableCookiesDialog.h"
23 #include "databases/CookiesDatabase.h"
24 #include "delegates/ViewOnlyDelegate.h"
26 // KDE Frameworks headers.
27 #include <KLocalizedString>
29 DurableCookiesDialog::DurableCookiesDialog() : QDialog(nullptr)
31 // Set the dialog window title.
32 setWindowTitle(i18nc("The durable cookies dialog window title", "Durable Cookies"));
34 // Set the window modality.
35 setWindowModality(Qt::WindowModality::ApplicationModal);
37 // Instantiate the durable cookies dialog UI.
38 Ui::DurableCookiesDialog durableCookiesDialogUi;
41 durableCookiesDialogUi.setupUi(this);
43 // Get a handle for the table view.
44 QTableView *tableViewPointer = durableCookiesDialogUi.tableView;
46 // Create the durable cookies table model.
47 durableCookiesTableModelPointer = new QSqlTableModel(nullptr, QSqlDatabase::database(CookiesDatabase::CONNECTION_NAME));
50 durableCookiesTableModelPointer->setTable(CookiesDatabase::COOKIES_TABLE);
52 // Set the edit strategy.
53 durableCookiesTableModelPointer->setEditStrategy(QSqlTableModel::OnManualSubmit);
55 // Populate the model.
56 durableCookiesTableModelPointer->select();
59 tableViewPointer->setModel(durableCookiesTableModelPointer);
61 // Instantiate the view only delegate.
62 ViewOnlyDelegate *viewOnlyDelegatePointer = new ViewOnlyDelegate();
64 // Disable editing the first column.
65 tableViewPointer->setItemDelegateForColumn(0, viewOnlyDelegatePointer);
67 // Optimize the width of the columns.
68 tableViewPointer->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
70 // Get the seleciton model.
71 tableSelectionModelPointer = tableViewPointer->selectionModel();
73 // Update the UI when the selection changes.
74 connect(tableSelectionModelPointer, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(updateUi()));
76 // Update the UI when the table model data changes.
77 connect(durableCookiesTableModelPointer, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(updateUi()));
79 // Get handles for the buttons.
80 QPushButton *addCookieButtonPointer = durableCookiesDialogUi.addCookieButton;
81 deleteCookieButtonPointer = durableCookiesDialogUi.deleteCookieButton;
82 deleteAllCookiesButtonPointer = durableCookiesDialogUi.deleteAllCookiesButton;
83 QDialogButtonBox *dialogButtonBoxPointer = durableCookiesDialogUi.dialogButtonBox;
84 resetButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::Reset);
85 applyButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::Apply);
86 QPushButton *okButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::Ok);
88 // Set the OK button to be the default.
89 okButtonPointer->setDefault(true);
91 // Connect the buttons.
92 connect(addCookieButtonPointer, SIGNAL(clicked()), this, SLOT(addCookie()));
93 connect(deleteCookieButtonPointer, SIGNAL(clicked()), this, SLOT(deleteCookie()));
94 connect(deleteAllCookiesButtonPointer, SIGNAL(clicked()), this, SLOT(deleteAllCookies()));
95 connect(resetButtonPointer, SIGNAL(clicked()), this, SLOT(reset()));
96 connect(dialogButtonBoxPointer, SIGNAL(accepted()), this, SLOT(ok()));
97 connect(applyButtonPointer, SIGNAL(clicked()), this, SLOT(apply()));
98 connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject()));
100 // Connect the table model signals.
101 connect(durableCookiesTableModelPointer, SIGNAL(beforeDelete(int)), this, SLOT(beforeDelete(int)));
102 connect(durableCookiesTableModelPointer, SIGNAL(beforeUpdate(int, QSqlRecord &)), this, SLOT(beforeUpdate(int, QSqlRecord &)));
103 connect(durableCookiesTableModelPointer, SIGNAL(beforeInsert(QSqlRecord &)), this, SLOT(newCookie(QSqlRecord &)));
109 void DurableCookiesDialog::addCookie() const
111 // Add a new row to the bottom of the table.
112 durableCookiesTableModelPointer->insertRow(durableCookiesTableModelPointer->rowCount());
118 void DurableCookiesDialog::apply() const
120 // Submit all pending changes.
121 durableCookiesTableModelPointer->submitAll();
127 void DurableCookiesDialog::beforeDelete(int row) const
129 // Get the SQL record for the row to be deleted.
130 QSqlRecord sqlRecord = durableCookiesTableModelPointer->record(row);
132 // Create a network cookie.
133 QNetworkCookie cookie;
135 // Populate the network cookie.
136 cookie.setDomain(sqlRecord.value(CookiesDatabase::DOMAIN).toString());
137 cookie.setName(sqlRecord.value(CookiesDatabase::NAME).toByteArray());
138 cookie.setPath(sqlRecord.value(CookiesDatabase::PATH).toString());
140 // Delete the cookie.
141 emit deletingCookie(cookie);
144 void DurableCookiesDialog::beforeUpdate(int row, QSqlRecord &sqlRecord) const
146 // Tell the compiler to ignore the unused row parameter.
149 // Delete the old cookie if the core attributes are changing.
150 if (sqlRecord.isGenerated(CookiesDatabase::DOMAIN) || sqlRecord.isGenerated(CookiesDatabase::NAME) || sqlRecord.isGenerated(CookiesDatabase::PATH))
152 // Get the ID of the cookie
153 int id = sqlRecord.value(CookiesDatabase::_ID).toInt();
156 QNetworkCookie *cookiePointer = CookiesDatabase::getCookieById(id);
158 // Delete the cookie.
159 emit deletingCookie(*cookiePointer);
162 // Add the new cookie, which modifies any existing cookies with the same core attributes.
163 newCookie(sqlRecord);
166 void DurableCookiesDialog::deleteAllCookies() const
168 // Mark all the cookies for deletion.
169 durableCookiesTableModelPointer->removeRows(0, durableCookiesTableModelPointer->rowCount());
175 void DurableCookiesDialog::deleteCookie() const
177 // Delete the currently selected row.
178 durableCookiesTableModelPointer->removeRow(tableSelectionModelPointer->selectedRows()[0].row());
184 void DurableCookiesDialog::newCookie(QSqlRecord &sqlRecord) const
186 // Create a network cookie.
187 QNetworkCookie cookie;
189 // Populate the network cookie from the SQL record.
190 cookie.setDomain(sqlRecord.value(CookiesDatabase::DOMAIN).toString());
191 cookie.setName(sqlRecord.value(CookiesDatabase::NAME).toByteArray());
192 cookie.setPath(sqlRecord.value(CookiesDatabase::PATH).toString());
193 cookie.setExpirationDate(QDateTime::fromString(sqlRecord.value(CookiesDatabase::EXPIRATION_DATE).toString(), Qt::ISODate));
194 cookie.setHttpOnly(sqlRecord.value(CookiesDatabase::HTTP_ONLY).toBool());
195 cookie.setSecure(sqlRecord.value(CookiesDatabase::SECURE).toBool());
196 cookie.setValue(sqlRecord.value(CookiesDatabase::VALUE).toByteArray());
198 // Update the cookie in the cookies dialog tree, cookies list, and cookie store.
199 emit addingCookie(cookie, false);
202 void DurableCookiesDialog::ok()
204 // Submit all pending changes.
205 durableCookiesTableModelPointer->submitAll();
207 // Update the parent UI.
214 void DurableCookiesDialog::reset() const
216 // Cancel all pending changes.
217 durableCookiesTableModelPointer->revertAll();
223 void DurableCookiesDialog::updateUi() const
225 // Update the delete button status.
226 deleteCookieButtonPointer->setEnabled(tableSelectionModelPointer->hasSelection());
228 // Update the delete all button status.
229 deleteAllCookiesButtonPointer->setEnabled(durableCookiesTableModelPointer->rowCount() > 0);
231 // Update the reset button status.
232 resetButtonPointer->setEnabled(durableCookiesTableModelPointer->isDirty());
234 // Update the apply button status.
235 applyButtonPointer->setEnabled(durableCookiesTableModelPointer->isDirty());
237 // Update the parent UI.
238 emit updateParentUi();