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 "AddOrEditCookieDialog.h"
22 #include "CookiesDialog.h"
23 #include "ui_CookiesDialog.h"
25 // KDE Frameworks headers.
26 #include <KLocalizedString>
28 // Qt toolkit headers.
30 #include <QMessageBox>
34 bool cookieSortPredicate(const QNetworkCookie &leftHandCookie, const QNetworkCookie &rightHandCookie)
36 // Check to see if the domains are identical.
37 if (leftHandCookie.domain() == rightHandCookie.domain())
39 // Check to see if the names are identical.
40 if (leftHandCookie.name() == rightHandCookie.name())
42 // Sort the cookies by the path.
43 return (leftHandCookie.path() < rightHandCookie.path());
45 else // The name are not identical.
47 // Sort the cookies by the name.
48 return (leftHandCookie.name() < rightHandCookie.name());
51 else // The domains are not identical.
53 // Get copies of the domains.
54 QString leftHandDomain = leftHandCookie.domain();
55 QString rightHandDomain = rightHandCookie.domain();
57 // Get the top level domains.
58 QString leftHandTopLevelDomain = leftHandDomain.section('.', -1);
59 QString rightHandTopLevelDomain = rightHandDomain.section('.', -1);
61 // Get the second level domains.
62 QString leftHandSecondLevelDomain = leftHandDomain.section('.', -2);
63 QString rightHandSecondLevelDomain = rightHandDomain.section('.', -2);
65 // Get the third level domains.
66 QString leftHandThirdLevelDomain = leftHandDomain.section('.', -3);
67 QString rightHandThirdLevelDomain = rightHandDomain.section('.', -3);
69 // Check to see if the top level domains are the same.
70 if (leftHandTopLevelDomain == rightHandTopLevelDomain)
72 // Check to see if the second level domains are the same.
73 if (leftHandSecondLevelDomain == rightHandSecondLevelDomain)
75 // Check to see if the third level domains are the same.
76 if (leftHandThirdLevelDomain == rightHandThirdLevelDomain)
78 // Sort the cookies by the full domain because they share the same third level domain.
79 return (leftHandDomain < rightHandDomain);
81 else // The second level domains are the same, but the third level domains are different.
83 // Sort the cookies by the third level domains.
84 return (leftHandThirdLevelDomain < rightHandThirdLevelDomain);
87 else // The top level domains are the same, but the second level domains are diferent.
89 // Sort the cookies by the second level domain.
90 return (leftHandSecondLevelDomain < rightHandSecondLevelDomain);
93 else // The top level domains are different.
95 // Sort the cookies by the top level domain.
96 return (leftHandTopLevelDomain < rightHandTopLevelDomain);
102 CookiesDialog::CookiesDialog(std::forward_list<QNetworkCookie> *originalCookieListPointer) : QDialog(nullptr), cookieListPointer(originalCookieListPointer)
104 // Set the dialog window title.
105 setWindowTitle(i18nc("The cookies dialog window title", "Cookies"));
107 // Set the window modality.
108 setWindowModality(Qt::WindowModality::ApplicationModal);
110 // Instantiate the cookie settings dialog UI.
111 Ui::CookiesDialog cookiesDialogUi;
114 cookiesDialogUi.setupUi(this);
116 // Get a handle for the tree view.
117 treeViewPointer = cookiesDialogUi.treeView;
119 // Initialize the standard item model.
120 standardItemModelPointer = new QStandardItemModel();
122 // Set the column count.
123 standardItemModelPointer->setColumnCount(6);
125 // Set the header data.
126 standardItemModelPointer->setHeaderData(0, Qt::Horizontal, i18nc("The cookie Name header.", "Name"));
127 standardItemModelPointer->setHeaderData(1, Qt::Horizontal, i18nc("The cookie Path header.", "Path"));
128 standardItemModelPointer->setHeaderData(2, Qt::Horizontal, i18nc("The cookie Expiration Date header.", "Expiration Date"));
129 standardItemModelPointer->setHeaderData(3, Qt::Horizontal, i18nc("The cookie HTTP Only header.", "HTTP Only"));
130 standardItemModelPointer->setHeaderData(4, Qt::Horizontal, i18nc("The cookie Secure header.", "Secure"));
131 standardItemModelPointer->setHeaderData(5, Qt::Horizontal, i18nc("The cookie Value header.", "Value"));
133 // Set the header tool tips.
134 standardItemModelPointer->horizontalHeaderItem(0)->setToolTip(i18nc("The cookie Name tool tip.",
135 "The name identifies the cookie. Each cookie has a unique combination of domain, name, and path."));
136 standardItemModelPointer->horizontalHeaderItem(1)->setToolTip(i18nc("The cookie Path tool tip.", "Websites can restrict cookie access to subpath of their URL."));
137 standardItemModelPointer->horizontalHeaderItem(2)->setToolTip(i18nc("The cookie Expiration Date tool tip.",
138 "Cookies without an expiration date are known as session cookies and are expected to be deleted every time the browser closes."));
139 standardItemModelPointer->horizontalHeaderItem(3)->setToolTip(i18nc("The cookie HTTP Only tool tip.",
140 "Restrict cookie access to HTTP (and HTTPS). This prevents JavaScript from accessing the cookie, which hardens it against cross-site scripting attacks."));
141 standardItemModelPointer->horizontalHeaderItem(4)->setToolTip(i18nc("The cookie Secure tool tip.", "Only allow the cookie to be transferred across HTTPS (as opposed to HTTP)."));
142 standardItemModelPointer->horizontalHeaderItem(5)->setToolTip(i18nc("The cookie Value tool tip.", "The value contains the cookie data."));
144 // Sort the cookie list.
145 cookieListPointer->sort(cookieSortPredicate);
147 // Create the current domain string.
148 QString currentDomainString = "";
150 // Create the current domain standard item pointer.
151 QStandardItem *currentDomainStandardItemPointer;
153 // Populate the VBoxLayout.
154 for (QNetworkCookie cookie : *cookieListPointer)
156 // Get the cookie domain.
157 QString cookieDomain = cookie.domain();
159 // Check to see if the cookie is a member of the current domain.
160 if (cookieDomain != currentDomainString) // Create a new domain in the tree.
162 // Create a list for the domain standard items.
163 QList<QStandardItem*> domainStandardItemList;
165 // Create the new domain standard items.
166 QStandardItem *domainStandardItemPointer = new QStandardItem(cookieDomain);
167 QStandardItem *pathStandardItemPointer = new QStandardItem(QStringLiteral(""));
168 QStandardItem *expirationDateStandardItemPointer = new QStandardItem(QStringLiteral(""));
169 QStandardItem *isHttpOnlyStandardItemPointer = new QStandardItem(QStringLiteral(""));
170 QStandardItem *isSecureStandardItemPointer = new QStandardItem(QStringLiteral(""));
171 QStandardItem *valueStandardItemPointer = new QStandardItem(QStringLiteral(""));
173 // Disable editing of the domain.
174 domainStandardItemPointer->setEditable(false);
175 pathStandardItemPointer->setEditable(false);
176 expirationDateStandardItemPointer->setEditable(false);
177 isHttpOnlyStandardItemPointer->setEditable(false);
178 isSecureStandardItemPointer->setEditable(false);
179 valueStandardItemPointer->setEditable(false);
181 // Populate the domain standard item list.
182 domainStandardItemList.append(domainStandardItemPointer);
183 domainStandardItemList.append(pathStandardItemPointer);
184 domainStandardItemList.append(expirationDateStandardItemPointer);
185 domainStandardItemList.append(isHttpOnlyStandardItemPointer);
186 domainStandardItemList.append(isSecureStandardItemPointer);
187 domainStandardItemList.append(valueStandardItemPointer);
189 // Add the domain to the tree.
190 standardItemModelPointer->invisibleRootItem()->appendRow(domainStandardItemList);
192 // Update the current domain string.
193 currentDomainString = cookieDomain;
195 // Update the current domain standard item pointer.
196 currentDomainStandardItemPointer = domainStandardItemPointer;
199 // Create a list for the cookie standard items.
200 QList<QStandardItem*> cookieStandardItemList;
202 // Create the cookie standard items.
203 QStandardItem *nameStandardItemPointer = new QStandardItem(QString(cookie.name()));
204 QStandardItem *pathStandardItemPointer = new QStandardItem(QString(cookie.path()));
205 QStandardItem *expirationDateStandardItemPointer = new QStandardItem(QString(cookie.expirationDate().toString()));
206 QStandardItem *isHttpOnlyStandardItemPointer = new QStandardItem(QString(cookie.isHttpOnly() ? i18n("yes") : i18n("no")));
207 QStandardItem *isSecureStandardItemPointer = new QStandardItem(QString(cookie.isSecure() ? i18n("yes") : i18n("no")));
208 QStandardItem *valueStandardItemPointer = new QStandardItem(QString(cookie.value()));
210 // Disable editing of the cookie standard items.
211 nameStandardItemPointer->setEditable(false);
212 pathStandardItemPointer->setEditable(false);
213 expirationDateStandardItemPointer->setEditable(false);
214 isHttpOnlyStandardItemPointer->setEditable(false);
215 isSecureStandardItemPointer->setEditable(false);
216 valueStandardItemPointer->setEditable(false);
218 // Populate the cookie standard item list.
219 cookieStandardItemList.append(nameStandardItemPointer);
220 cookieStandardItemList.append(pathStandardItemPointer);
221 cookieStandardItemList.append(expirationDateStandardItemPointer);
222 cookieStandardItemList.append(isHttpOnlyStandardItemPointer);
223 cookieStandardItemList.append(isSecureStandardItemPointer);
224 cookieStandardItemList.append(valueStandardItemPointer);
226 // Add the cookie to the tree.
227 currentDomainStandardItemPointer->appendRow(cookieStandardItemList);
230 // Auto resize the headers.
231 treeViewPointer->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
233 // Disable stretching the last section. Otherwise, the Value field will be truncated to the width of the window when a row is expanded.
234 treeViewPointer->header()->setStretchLastSection(false);
236 // Don't elide the Value field (or any other field).
237 treeViewPointer->setTextElideMode(Qt::ElideNone);
239 // Indicate that all the rows are the same height, wich improves performance.
240 treeViewPointer->setUniformRowHeights(true);
242 // Set the tree view model.
243 treeViewPointer->setModel(standardItemModelPointer);
245 // Get a handle for the tree view selection model.
246 treeViewSelectionModelPointer = treeViewPointer->selectionModel();
248 // Listen for selection changes.
249 connect(treeViewSelectionModelPointer, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(updateUi()));
251 // Get handles for the buttons.
252 addCookieButtonPointer = cookiesDialogUi.addCookieButton;
253 editCookieButtonPointer = cookiesDialogUi.editCookieButton;
254 deleteCookieButtonPointer = cookiesDialogUi.deleteCookieButton;
255 QDialogButtonBox *dialogButtonBoxPointer = cookiesDialogUi.dialogButtonBox;
256 QPushButton *closeButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::Close);
258 // Add a delete all button to the dialog button box.
259 deleteAllButtonPointer = dialogButtonBoxPointer->addButton(i18nc("Delete all cookies button", "Delete all"), QDialogButtonBox::ActionRole);
261 // Set the delete all button icon.
262 deleteAllButtonPointer->setIcon(QIcon::fromTheme("delete"));
264 // Connect the buttons.
265 connect(addCookieButtonPointer, SIGNAL(clicked()), this, SLOT(showAddCookieDialog()));
266 connect(editCookieButtonPointer, SIGNAL(clicked()), this, SLOT(showEditCookieDialog()));
267 connect(deleteCookieButtonPointer, SIGNAL(clicked()), this, SLOT(showDeleteCookieMessageBox()));
268 connect(deleteAllButtonPointer, SIGNAL(clicked()), this, SLOT(showDeleteAllMessageBox()));
269 connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject()));
271 // Set the cancel button to be the default.
272 closeButtonPointer->setDefault(true);
274 // Create the keyboard shortcuts.
275 QShortcut *aShortcutPointer = new QShortcut(QKeySequence(i18nc("The add cookie key shortcut.", "a")), this);
276 QShortcut *eShortcutPointer = new QShortcut(QKeySequence(i18nc("The edit cookie key shorcut.", "e")), this);
277 QShortcut *dShortcutPointer = new QShortcut(QKeySequence(i18nc("The delete cookie key shortcut.", "d")), this);
278 QShortcut *deleteShortcutPointer = new QShortcut(QKeySequence::Delete, this);
279 QShortcut *lShortcutPointer = new QShortcut(QKeySequence(i18nc("The delete all key shortcut.", "l")), this);
280 QShortcut *cShortcutPointer = new QShortcut(QKeySequence(i18nc("The close key shortcut.", "c")), this);
281 QShortcut *quitShortcutPointer = new QShortcut(QKeySequence::Quit, this);
283 // Connect the keyboard shortcuts to the buttons.
284 connect(aShortcutPointer, SIGNAL(activated()), addCookieButtonPointer, SLOT(click()));
285 connect(eShortcutPointer, SIGNAL(activated()), editCookieButtonPointer, SLOT(click()));
286 connect(dShortcutPointer, SIGNAL(activated()), deleteCookieButtonPointer, SLOT(click()));
287 connect(deleteShortcutPointer, SIGNAL(activated()), deleteCookieButtonPointer, SLOT(click()));
288 connect(lShortcutPointer, SIGNAL(activated()), deleteAllButtonPointer, SLOT(click()));
289 connect(cShortcutPointer, SIGNAL(activated()), closeButtonPointer, SLOT(click()));
290 connect(quitShortcutPointer, SIGNAL(activated()), closeButtonPointer, SLOT(click()));
292 // Edit a cookie when it is double clicked.
293 connect(treeViewPointer, SIGNAL(doubleClicked(QModelIndex)), editCookieButtonPointer, SLOT(click()));
299 void CookiesDialog::addCookieFromDialog(const QNetworkCookie &cookie) const
301 // Add the cookie to the cookie list and the cookie store.
302 emit addCookie(cookie);
304 // Get the new domain string.
305 QString newDomain = cookie.domain();
307 // Check to see if the domain already exists in the model.
308 QList<QStandardItem*> currentDomainStandardItemList = standardItemModelPointer->findItems(newDomain);
310 // Create a domain standard item pointer.
311 QStandardItem *domainStandardItemPointer;
313 // Prepare the domain standard item pointer.
314 if (currentDomainStandardItemList.isEmpty()) // The domain doesn't currently exist in the tree.
316 // Create a list for the domain standard items.
317 QList<QStandardItem*> domainStandardItemList;
319 // Create the new domain standard items.
320 domainStandardItemPointer = new QStandardItem(newDomain);
321 QStandardItem *pathStandardItemPointer = new QStandardItem(QStringLiteral(""));
322 QStandardItem *expirationDateStandardItemPointer = new QStandardItem(QStringLiteral(""));
323 QStandardItem *isHttpOnlyStandardItemPointer = new QStandardItem(QStringLiteral(""));
324 QStandardItem *isSecureStandardItemPointer = new QStandardItem(QStringLiteral(""));
325 QStandardItem *valueStandardItemPointer = new QStandardItem(QStringLiteral(""));
327 // Disable editing of the domain.
328 domainStandardItemPointer->setEditable(false);
329 pathStandardItemPointer->setEditable(false);
330 expirationDateStandardItemPointer->setEditable(false);
331 isHttpOnlyStandardItemPointer->setEditable(false);
332 isSecureStandardItemPointer->setEditable(false);
333 valueStandardItemPointer->setEditable(false);
335 // Populate the domain standard item list.
336 domainStandardItemList.append(domainStandardItemPointer);
337 domainStandardItemList.append(pathStandardItemPointer);
338 domainStandardItemList.append(expirationDateStandardItemPointer);
339 domainStandardItemList.append(isHttpOnlyStandardItemPointer);
340 domainStandardItemList.append(isSecureStandardItemPointer);
341 domainStandardItemList.append(valueStandardItemPointer);
343 // Create the insert domain row number.
344 int insertDomainRowNumber = 0;
346 // Get the number of domains in the tree.
347 int numberOfDomains = standardItemModelPointer->invisibleRootItem()->rowCount();
349 // Get the new domain strings.
350 QString newDomainTopLevelDomain = newDomain.section('.', -1);
351 QString newDomainSecondLevelDomain = newDomain.section('.', -2);
352 QString newDomainThirdLevelDomain = newDomain.section('.', -3);
354 // Iterate through all the domains.
355 for (int i = 0; i < numberOfDomains; ++i)
357 // Get the current domain strings.
358 QString currentDomain = standardItemModelPointer->invisibleRootItem()->child(i, 0)->index().data().toString();
359 QString currentDomainTopLevelDomain = currentDomain.section('.', -1);
360 QString currentDomainSecondLevelDomain = currentDomain.section('.', -2);
361 QString currentDomainThirdLevelDomain = currentDomain.section('.', -3);
363 // Check to see if the new domain should be inserted after the current domain.
364 if (newDomainTopLevelDomain > currentDomainTopLevelDomain)
366 // Insert the new domain after the current domain.
367 insertDomainRowNumber = i + 1;
369 else if ((newDomainTopLevelDomain == currentDomainTopLevelDomain) && (newDomainSecondLevelDomain > currentDomainSecondLevelDomain))
371 // Insert the new domain after the current domain.
372 insertDomainRowNumber = i + 1;
374 else if ((newDomainSecondLevelDomain == currentDomainSecondLevelDomain) && (newDomainThirdLevelDomain > currentDomainThirdLevelDomain))
376 // Insert the new domain after the current domain.
377 insertDomainRowNumber = i + 1;
379 else if ((newDomainThirdLevelDomain == currentDomainThirdLevelDomain) && (newDomain > currentDomain))
381 // Insert the new domain after the current domain.
382 insertDomainRowNumber = i + 1;
386 // Add the domain to the tree.
387 standardItemModelPointer->invisibleRootItem()->insertRow(insertDomainRowNumber, domainStandardItemList);
389 else // The domain already exists in the tree.
391 // Use the current domain standard item.
392 domainStandardItemPointer = currentDomainStandardItemList[0];
395 // Get strings for the new cookie name and path (used later in the placement of the row).
396 QString newCookieName = QString(cookie.name());
397 QString newCookiePath = QString(cookie.path());
399 // Create a list for the cookie standard items.
400 QList<QStandardItem*> cookieStandardItemList;
402 // Create the cookie standard items.
403 QStandardItem *nameStandardItemPointer = new QStandardItem(newCookieName);
404 QStandardItem *pathStandardItemPointer = new QStandardItem(newCookiePath);
405 QStandardItem *expirationDateStandardItemPointer = new QStandardItem(QString(cookie.expirationDate().toString()));
406 QStandardItem *isHttpOnlyStandardItemPointer = new QStandardItem(QString(cookie.isHttpOnly() ? i18n("yes") : i18n("no")));
407 QStandardItem *isSecureStandardItemPointer = new QStandardItem(QString(cookie.isSecure() ? i18n("yes") : i18n("no")));
408 QStandardItem *valueStandardItemPointer = new QStandardItem(QString(cookie.value()));
410 // Disable editing of the cookie standard items.
411 nameStandardItemPointer->setEditable(false);
412 pathStandardItemPointer->setEditable(false);
413 expirationDateStandardItemPointer->setEditable(false);
414 isHttpOnlyStandardItemPointer->setEditable(false);
415 isSecureStandardItemPointer->setEditable(false);
416 valueStandardItemPointer->setEditable(false);
418 // Populate the cookie standard item list.
419 cookieStandardItemList.append(nameStandardItemPointer);
420 cookieStandardItemList.append(pathStandardItemPointer);
421 cookieStandardItemList.append(expirationDateStandardItemPointer);
422 cookieStandardItemList.append(isHttpOnlyStandardItemPointer);
423 cookieStandardItemList.append(isSecureStandardItemPointer);
424 cookieStandardItemList.append(valueStandardItemPointer);
426 // Create the insert cookie row number.
427 int insertCookieRowNumber = 0;
429 // Get the number of cookies in the domain.
430 int numberOfCookies = domainStandardItemPointer->rowCount();
432 // Iterate through the cookies for this domain.
433 for (int i = 0; i < numberOfCookies; ++i)
435 // Get the current cookie name and path at the indicated row.
436 QString currentCookieName = domainStandardItemPointer->child(i, 0)->index().data().toString();
437 QString currentCookiePath = domainStandardItemPointer->child(i, 1)->index().data().toString();
439 // Check to see if the new cookie should be inserted after the current cookie.
440 if (newCookieName > currentCookieName)
442 // Insert the new cookie after the current cookie.
443 insertCookieRowNumber = i + 1;
445 else if ((newCookieName == currentCookieName) && (newCookiePath > currentCookiePath))
447 // Insert the new cookie after the current cookie.
448 insertCookieRowNumber = i + 1;
452 // Add the cookie to the tree.
453 domainStandardItemPointer->insertRow(insertCookieRowNumber, cookieStandardItemList);
455 // Get the new cookie model index.
456 QModelIndex newCookieIndex = nameStandardItemPointer->index();
458 // Set the new cookie to be the current index.
459 treeViewPointer->setCurrentIndex(newCookieIndex);
461 // Expand the parent of the new cookie.
462 treeViewPointer->expand(newCookieIndex.parent());
465 void CookiesDialog::deleteCookie(const QModelIndex &modelIndex) const
467 // Create a partial cookie.
468 QNetworkCookie partialCookie;
470 // Populate the partial cookie from the current model index.
471 partialCookie.setDomain(modelIndex.parent().siblingAtColumn(0).data().toString());
472 partialCookie.setName(modelIndex.siblingAtColumn(0).data().toString().toUtf8());
473 partialCookie.setPath(modelIndex.siblingAtColumn(1).data().toString());
475 // Create a cookie to delete.
476 QNetworkCookie cookieToDelete;
478 // Search for the partial cookie in the cookie list.
479 for (QNetworkCookie cookie : *cookieListPointer)
481 // Store the cookie to delete if it has the same identifier as the partial cookie.
482 if (cookie.hasSameIdentifier(partialCookie))
483 cookieToDelete = cookie;
486 // Remove the cookie from the tree view.
487 standardItemModelPointer->removeRow(modelIndex.row(), modelIndex.parent());
489 // Delete the cookie from the cookie list and cookie store.
490 emit deleteCookie(cookieToDelete);
493 void CookiesDialog::deleteCookieFromDialog(const QNetworkCookie &cookie) const
495 // Get the current model index.
496 QModelIndex currentIndex = treeViewSelectionModelPointer->currentIndex();
498 // Get the parent index.
499 QModelIndex parentIndex = currentIndex.parent();
501 // Remove the cookie from the tree view.
502 standardItemModelPointer->removeRow(currentIndex.row(), parentIndex);
504 // Remove the domain from the tree view if its only cookie has been deleted.
505 if (standardItemModelPointer->rowCount(parentIndex) == 0)
506 standardItemModelPointer->removeRow(parentIndex.row(), parentIndex.parent());
508 // Delete the cookie from the cookie list and cookie store.
509 emit deleteCookie(cookie);
512 void CookiesDialog::showAddCookieDialog() const
514 // Instantiate an add cookie dialog.
515 QDialog *addCookieDialogPointer = new AddOrEditCookieDialog(AddOrEditCookieDialog::AddCookie);
518 addCookieDialogPointer->show();
520 // Add the cookie if directed.
521 connect(addCookieDialogPointer, SIGNAL(addCookie(QNetworkCookie)), this, SLOT(addCookieFromDialog(QNetworkCookie)));
524 void CookiesDialog::showDeleteAllMessageBox() const
526 // Instantiate a delete all message box.
527 QMessageBox deleteAllCookiesMessageBox;
530 deleteAllCookiesMessageBox.setIcon(QMessageBox::Warning);
532 // Set the window title.
533 deleteAllCookiesMessageBox.setWindowTitle(i18nc("Delete all cookies dialog title", "Delete All Cookies"));
536 deleteAllCookiesMessageBox.setText(i18nc("Delete all cookies dialog text", "Delete all cookies?"));
538 // Set the standard buttons.
539 deleteAllCookiesMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
541 // Set the default button.
542 deleteAllCookiesMessageBox.setDefaultButton(QMessageBox::No);
544 // Display the dialog and capture the return value.
545 int returnValue = deleteAllCookiesMessageBox.exec();
547 // Delete all cookies if instructed.
548 if (returnValue == QMessageBox::Yes)
550 // Delete all the cookies.
551 emit deleteAllCookies();
553 // Clear the standard item model.
554 standardItemModelPointer->clear();
561 void CookiesDialog::showDeleteCookieMessageBox() const
563 // Get the current model index.
564 QModelIndex currentIndex = treeViewSelectionModelPointer->currentIndex();
566 // Get the parent model index.
567 QModelIndex parentIndex = currentIndex.parent();
569 // Determine if a domain is selected.
570 bool isDomain = standardItemModelPointer->hasChildren(currentIndex);
572 // Instantiate a delete cookie message box.
573 QMessageBox deleteCookieMessageBox;
576 deleteCookieMessageBox.setIcon(QMessageBox::Warning);
580 // Get the number of cookies.
581 int numberOfCookiesToDelete = standardItemModelPointer->rowCount(currentIndex);
583 // Set the window title.
584 deleteCookieMessageBox.setWindowTitle(i18nc("Delete cookies dialog title", "Delete %1 Cookies", numberOfCookiesToDelete));
587 deleteCookieMessageBox.setText(i18nc("Delete cookies dialog text", "Delete %1 cookies?", numberOfCookiesToDelete));
591 // Set the window title.
592 deleteCookieMessageBox.setWindowTitle(i18nc("Delete cookie dialog title", "Delete 1 Cookie"));
595 deleteCookieMessageBox.setText(i18nc("Delete cookie dialog text", "Delete 1 cookie?"));
598 // Set the standard buttons.
599 deleteCookieMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
601 // Set the default button.
602 deleteCookieMessageBox.setDefaultButton(QMessageBox::No);
604 // Display the dialog and capture the return value.
605 int returnValue = deleteCookieMessageBox.exec();
607 // Delete the cookie if instructed.
608 if (returnValue == QMessageBox::Yes)
610 // Delete the cookies according to the selection.
611 if (isDomain) // A domain is selected.
613 // Get the number of cookies.
614 int numberOfCookies = standardItemModelPointer->rowCount(currentIndex);
616 // Delete each child cookie.
617 for (int i = 0; i < numberOfCookies; ++i)
619 // Delete the cookie for the first child. Once this is deleted, the second child will become the first child.
620 deleteCookie(standardItemModelPointer->index(0, 0, currentIndex));
623 // Delete the domain from the tree view.
624 standardItemModelPointer->removeRow(currentIndex.row(), parentIndex);
626 else // A single cookie is selected.
628 // Delete the cookie.
629 deleteCookie(currentIndex);
631 // Remove the domain row if its only cookie has been deleted.
632 if (standardItemModelPointer->rowCount(parentIndex) == 0)
633 standardItemModelPointer->removeRow(parentIndex.row(), parentIndex.parent());
638 void CookiesDialog::showEditCookieDialog() const
640 // Get the current model index.
641 QModelIndex currentIndex = treeViewSelectionModelPointer->currentIndex();
643 // Create a partial cookie.
644 QNetworkCookie partialCookie;
646 // Populate the partial cookie from the current model index.
647 partialCookie.setDomain(currentIndex.parent().siblingAtColumn(0).data().toString());
648 partialCookie.setName(currentIndex.siblingAtColumn(0).data().toString().toUtf8());
649 partialCookie.setPath(currentIndex.siblingAtColumn(1).data().toString());
651 // Create a cookie to edit.
652 QNetworkCookie cookieToEdit;
654 // Search for the partial cookie in the cookie list.
655 for (QNetworkCookie cookie : *cookieListPointer)
657 // Store the cookie to edit if it has the same identifier as the partial cookie.
658 if (cookie.hasSameIdentifier(partialCookie))
659 cookieToEdit = cookie;
662 // Instantiate an edit cookie dialog.
663 QDialog *editCookieDialogPointer = new AddOrEditCookieDialog(AddOrEditCookieDialog::EditCookie, &cookieToEdit);
666 editCookieDialogPointer->show();
668 // Process cookie events.
669 connect(editCookieDialogPointer, SIGNAL(addCookie(QNetworkCookie)), this, SLOT(addCookieFromDialog(QNetworkCookie)));
670 connect(editCookieDialogPointer, SIGNAL(deleteCookie(QNetworkCookie)), this, SLOT(deleteCookieFromDialog(QNetworkCookie)));
673 void CookiesDialog::updateUi() const
675 // Get the current index of the first column.
676 QModelIndex currentIndex = treeViewSelectionModelPointer->currentIndex().siblingAtColumn(0);
678 // Set the status of the buttons.
679 editCookieButtonPointer->setEnabled(treeViewSelectionModelPointer->hasSelection() && !standardItemModelPointer->hasChildren(currentIndex));
680 deleteCookieButtonPointer->setEnabled(treeViewSelectionModelPointer->hasSelection());;
681 deleteAllButtonPointer->setEnabled(standardItemModelPointer->hasChildren(standardItemModelPointer->invisibleRootItem()->index()));
683 // Update the delete cookie button text.
684 if (deleteCookieButtonPointer->isEnabled()) // The button is enabled.
686 if (standardItemModelPointer->hasChildren(currentIndex)) // A domain is selected.
688 // Update the button text.
689 deleteCookieButtonPointer->setText(i18nc("Delete cookies button.", "&Delete %1 cookies", standardItemModelPointer->rowCount(currentIndex)));
691 else // A single cookie is selected.
693 // Update the button text.
694 deleteCookieButtonPointer->setText(i18nc("Delete cookies button.", "&Delete 1 cookie"));
697 else // The button is disabled.
699 // Reset the button text.
700 deleteCookieButtonPointer->setText(i18nc("Delete cookie button.", "&Delete cookie"));