+void CookiesDialog::addCookieFromDialog(const QNetworkCookie &cookie, const bool &isDurable) const
+{
+ // Add the cookie to the cookie list and the cookie store.
+ emit addCookie(cookie);
+
+ // Get the new domain string.
+ QString newDomain = cookie.domain();
+
+ // Check to see if the domain already exists in the model.
+ QList<QStandardItem*> currentDomainItemList = treeModelPointer->findItems(newDomain);
+
+ // Create a domain item pointer.
+ QStandardItem *domainNameItemPointer;
+
+ // Prepare the domain item pointer.
+ if (currentDomainItemList.isEmpty()) // The domain doesn't currently exist in the tree.
+ {
+ // Create the domain name item.
+ domainNameItemPointer = new QStandardItem(newDomain);
+
+ // Get the number of domains in the tree.
+ int numberOfDomains = treeModelPointer->invisibleRootItem()->rowCount();
+
+ // Create the insert domain row number and initially set it to be at the end of the list.
+ int insertDomainRowNumber = numberOfDomains;
+
+ // Create the new domain strings.
+ QString newDomainTopLevelDomain;
+ QString newDomainSecondLevelDomain;
+ QString newDomainThirdLevelDomain;
+
+ // Get the number of dots in the new domain string.
+ int newDomainDots = newDomain.count(QLatin1Char('.'));
+
+ // Get the new top level domain.
+ newDomainTopLevelDomain = newDomain.section('.', -1);
+
+ // Get the new second level domain if it contains at least one dot.
+ if (newDomainDots >= 1)
+ newDomainSecondLevelDomain = newDomain.section('.', -2);
+
+ // Get the new third level domain if it contains at least two dots.
+ if (newDomainDots >= 2)
+ newDomainThirdLevelDomain = newDomain.section('.', -3);
+
+ // Create while loop trackers.
+ bool locationFound = false;
+ int currentRow = 0;
+
+ // Check to see if the new domain should be inserted after an existing domain.
+ while (!locationFound && (currentRow < numberOfDomains)) {
+ // Get the current domain string.
+ QString currentDomain = treeModelPointer->invisibleRootItem()->child(currentRow, 0)->index().data().toString();
+
+ // Create the current domain strings.
+ QString currentDomainTopLevelDomain;
+ QString currentDomainSecondLevelDomain;
+ QString currentDomainThirdLevelDomain;
+
+ // Get the number of dots in the current domain string.
+ int currentDomainDots = currentDomain.count(QLatin1Char('.'));
+
+ // Get the current top level domain.
+ currentDomainTopLevelDomain = currentDomain.section('.', -1);
+
+ // Get the current second level domain if it contains at least one dot.
+ if (currentDomainDots >= 1)
+ currentDomainSecondLevelDomain = currentDomain.section('.', -2);
+
+ // Get the current third level domain if it contains at least two dots.
+ if (currentDomainDots >= 2)
+ currentDomainThirdLevelDomain = currentDomain.section('.', -3);
+
+ // Check to see if the new domain should be inserted after the current domain.
+ // Segments, like third level domains, that do not exist will be blank, which will cause the sorting to group similar domains.
+ if ((newDomainTopLevelDomain < currentDomainTopLevelDomain) || // The new top level domain `.com` is less than the current top level domain `.org`.
+ ((newDomainTopLevelDomain == currentDomainTopLevelDomain) && ((newDomainSecondLevelDomain < currentDomainSecondLevelDomain) || // `jessica.com` is less than `stoutner.com`.
+ ((newDomainSecondLevelDomain == currentDomainSecondLevelDomain) && ((newDomainThirdLevelDomain < currentDomainThirdLevelDomain) || // `apache.stoutner.com` < `www.stoutner.com`.
+ ((newDomainThirdLevelDomain == currentDomainThirdLevelDomain) && (newDomain < currentDomain))))))) // `first.www.stoutner.com` < `second.www.stoutner.com`.
+ {
+ // Insert the domain at the current row (because the rows are 0 based, this will insert it before the first domain where all the above checks fail).
+ insertDomainRowNumber = currentRow;
+
+ // Mark the location as found.
+ locationFound = true;
+ }
+
+ // Move to the next row.
+ ++currentRow;
+ }
+
+ // Add the domain to the tree.
+ treeModelPointer->invisibleRootItem()->insertRow(insertDomainRowNumber, domainNameItemPointer);
+ }
+ else // The domain already exists in the tree.
+ {
+ // Use the current domain standard item.
+ domainNameItemPointer = currentDomainItemList[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 cookie item list.
+ QList<QStandardItem*> cookieItemList;
+
+ // Create the cookie items.
+ QStandardItem *nameItemPointer = new QStandardItem(newCookieName);
+ QStandardItem *durableItemPointer = new QStandardItem(QString(isDurable ? i18n("yes") : i18n("no")));
+ QStandardItem *pathItemPointer = new QStandardItem(newCookiePath);
+ QStandardItem *expirationDateItemPointer = new QStandardItem(QString(cookie.expirationDate().toString()));
+ QStandardItem *isHttpOnlyItemPointer = new QStandardItem(QString(cookie.isHttpOnly() ? i18n("yes") : i18n("no")));
+ QStandardItem *isSecureItemPointer = new QStandardItem(QString(cookie.isSecure() ? i18n("yes") : i18n("no")));
+ QStandardItem *valueItemPointer = new QStandardItem(QString(cookie.value()));
+
+ // Populate the cookie item list.
+ cookieItemList.append(nameItemPointer);
+ cookieItemList.append(durableItemPointer);
+ cookieItemList.append(pathItemPointer);
+ cookieItemList.append(expirationDateItemPointer);
+ cookieItemList.append(isHttpOnlyItemPointer);
+ cookieItemList.append(isSecureItemPointer);
+ cookieItemList.append(valueItemPointer);
+
+ // Get the number of cookies in the domain.
+ int numberOfCookies = domainNameItemPointer->rowCount();
+
+ // Create the insert cookie row number and initially set it to be at the end of the list.
+ int insertCookieRowNumber = numberOfCookies;
+
+ // Create the trackers.
+ bool removeExistingRow = false;
+ bool rowFound = false;
+ int currentRow = 0;
+
+ while (!rowFound && currentRow < numberOfCookies)
+ {
+ // Get the current cookie name and path at the indicated row.
+ QString currentCookieName = domainNameItemPointer->child(currentRow, 0)->index().data().toString();
+ QString currentCookiePath = domainNameItemPointer->child(currentRow, 2)->index().data().toString();
+
+ // Check to see if the new cookie should be inserted after the current cookie.
+ if ((newCookieName < currentCookieName) || // The new cookie name comes before the current cookie name.
+ ((newCookieName == currentCookieName) && ((newCookiePath < currentCookiePath) || // The names are the same, but the new cookie path comes before the current cookie path.
+ (newCookiePath == currentCookiePath)))) // The core attributes of the cookies are the same.
+ {
+ // Remove the existing cookie if the core attributes are the same.
+ if ((newCookieName == currentCookieName) && (newCookiePath == currentCookiePath))
+ removeExistingRow = true;
+
+ // Insert the new cookie at this row.
+ insertCookieRowNumber = currentRow;
+
+ // Mark the row as found.
+ rowFound = true;
+ }
+
+ // Move to the next row.
+ ++currentRow;
+ }
+
+ // Remove the existing row if it is being edited.
+ if (removeExistingRow)
+ domainNameItemPointer->removeRow(insertCookieRowNumber);
+
+ // Add the cookie to the tree model.
+ domainNameItemPointer->insertRow(insertCookieRowNumber, cookieItemList);
+
+ // Get the new cookie model index.
+ QModelIndex newCookieIndex = nameItemPointer->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::deleteCookie(const QModelIndex &modelIndex, const bool &deleteDurableCookies) const
+{
+ // Create a partial cookie.
+ QNetworkCookie partialCookie;
+
+ // 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(2).data().toString());
+
+ // Create a cookie to delete.
+ QNetworkCookie cookieToDelete;
+
+ // Check if the cookie is durable.
+ bool isDurable = CookiesDatabase::isDurable(partialCookie);
+
+ // Only delete durable cookies if directed.
+ if (deleteDurableCookies || !isDurable)
+ {
+ // 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 model.
+ treeModelPointer->removeRow(modelIndex.row(), modelIndex.parent());
+
+ // Delete the cookie from the cookie list and cookie store.
+ emit deleteCookie(cookieToDelete);
+
+ // Delete the cookie from the durable cookies database.
+ if (isDurable)
+ CookiesDatabase::deleteCookie(cookieToDelete);
+ }
+}
+
+void CookiesDialog::deleteDomain(const QModelIndex &modelIndex, const bool &deleteDurableCookies) const
+{
+ // Get the parent index.
+ QModelIndex parentIndex = modelIndex.parent();
+
+ // Get the number of cookies in the domain.
+ int numberOfCookies = treeModelPointer->rowCount(modelIndex);
+
+ // Delete each child cookie, starting from the bottom.
+ for (int i = numberOfCookies; i > 0; --i)
+ deleteCookie(treeModelPointer->index(i-1, 0, modelIndex), deleteDurableCookies);
+
+ // Remove the domain if all the cookies have been deleted.
+ if (treeModelPointer->rowCount(modelIndex) == 0)
+ 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
+{
+ // Get the current model index.
+ QModelIndex currentIndex = treeSelectionModelPointer->currentIndex();
+
+ // Get the parent index.
+ QModelIndex parentIndex = currentIndex.parent();
+
+ // Remove the cookie from the tree model.
+ treeModelPointer->removeRow(currentIndex.row(), parentIndex);
+
+ // Remove the domain from the tree model if its only cookie has been deleted.
+ if (treeModelPointer->rowCount(parentIndex) == 0)
+ treeModelPointer->removeRow(parentIndex.row(), parentIndex.parent());
+
+ // Delete the cookie from the cookie list and cookie store.
+ emit deleteCookie(cookie);
+}
+
+void CookiesDialog::showAddCookieDialog()
+{
+ // Instantiate an add cookie dialog.
+ QDialog *addCookieDialogPointer = new AddOrEditCookieDialog(this, AddOrEditCookieDialog::AddCookie);
+
+ // Show the dialog.
+ addCookieDialogPointer->show();
+
+ // Add the cookie if directed.
+ connect(addCookieDialogPointer, SIGNAL(addCookie(QNetworkCookie, bool)), this, SLOT(addCookieFromDialog(QNetworkCookie, bool)));
+}
+