]> gitweb.stoutner.com Git - PrivacyBrowserPC.git/blobdiff - src/dialogs/DomainSettingsDialog.cpp
Block all CSP requests. https://redmine.stoutner.com/issues/1193
[PrivacyBrowserPC.git] / src / dialogs / DomainSettingsDialog.cpp
index 59d7bdb073628886be1e964237a208df26f03adc..96ea20f30ffd151ab03baf1124c9f2ccf5ed7d10 100644 (file)
@@ -1,21 +1,21 @@
-/*
- * Copyright 2022-2024 Soren Stoutner <soren@stoutner.com>.
+/* SPDX-License-Identifier: GPL-3.0-or-later
+ * SPDX-FileCopyrightText: 2022-2025 Soren Stoutner <soren@stoutner.com>
  *
  *
- * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
+ * 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.
+ * This program 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.
+ * This program 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/>.
// */
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
 
 // Application headers.
 #include "DomainSettingsDialog.h"
 
 // Application headers.
 #include "DomainSettingsDialog.h"
@@ -34,7 +34,7 @@ const int DomainSettingsDialog::SHOW_ALL_DOMAINS = 0;
 const int DomainSettingsDialog::EDIT_DOMAIN = 1;
 
 // Construct the class.
 const int DomainSettingsDialog::EDIT_DOMAIN = 1;
 
 // Construct the class.
-DomainSettingsDialog::DomainSettingsDialog(const int &startType, const QString &domainName) : QDialog(nullptr)
+DomainSettingsDialog::DomainSettingsDialog(QWidget *parentWidgetPointer, const int &startType, const QString &domainName) : QDialog(parentWidgetPointer)
 {
     // Set the window title.
     setWindowTitle(i18nc("The domain settings dialog window title", "Domain Settings"));
 {
     // Set the window title.
     setWindowTitle(i18nc("The domain settings dialog window title", "Domain Settings"));
@@ -67,15 +67,34 @@ DomainSettingsDialog::DomainSettingsDialog(const int &startType, const QString &
     userAgentWidgetPointer = domainSettingsDialogUi.userAgentWidget;
     userAgentComboBoxPointer = domainSettingsDialogUi.userAgentComboBox;
     userAgentLabelPointer = domainSettingsDialogUi.userAgentLabel;
     userAgentWidgetPointer = domainSettingsDialogUi.userAgentWidget;
     userAgentComboBoxPointer = domainSettingsDialogUi.userAgentComboBox;
     userAgentLabelPointer = domainSettingsDialogUi.userAgentLabel;
+    ultraPrivacyWidgetPointer = domainSettingsDialogUi.ultraPrivacyWidget;
+    ultraPrivacyComboBoxPointer = domainSettingsDialogUi.ultraPrivacyComboBox;
+    ultraPrivacyLabelPointer = domainSettingsDialogUi.ultraPrivacyLabel;
+    ultraListWidgetPointer = domainSettingsDialogUi.ultraListWidget;
+    ultraListComboBoxPointer = domainSettingsDialogUi.ultraListComboBox;
+    ultraListLabelPointer = domainSettingsDialogUi.ultraListLabel;
+    easyPrivacyWidgetPointer = domainSettingsDialogUi.easyPrivacyWidget;
+    easyPrivacyComboBoxPointer = domainSettingsDialogUi.easyPrivacyComboBox;
+    easyPrivacyLabelPointer = domainSettingsDialogUi.easyPrivacyLabel;
+    easyListWidgetPointer = domainSettingsDialogUi.easyListWidget;
+    easyListComboBoxPointer = domainSettingsDialogUi.easyListComboBox;
+    easyListLabelPointer = domainSettingsDialogUi.easyListLabel;
+    fanboysAnnoyanceListWidgetPointer = domainSettingsDialogUi.fanboysAnnoyanceListWidget;
+    fanboysAnnoyanceListComboBoxPointer = domainSettingsDialogUi.fanboysAnnoyanceListComboBox;
+    fanboysAnnoyanceListLabelPointer = domainSettingsDialogUi.fanboysAnnoyanceListLabel;
     zoomFactorWidgetPointer = domainSettingsDialogUi.zoomFactorWidget;
     zoomFactorComboBoxPointer = domainSettingsDialogUi.zoomFactorComboBox;
     customZoomFactorSpinBoxPointer = domainSettingsDialogUi.customZoomFactorSpinBox;
     QPushButton *addDomainButtonPointer = domainSettingsDialogUi.addDomainButton;
     deleteDomainButtonPointer = domainSettingsDialogUi.deleteDomainButton;
     zoomFactorWidgetPointer = domainSettingsDialogUi.zoomFactorWidget;
     zoomFactorComboBoxPointer = domainSettingsDialogUi.zoomFactorComboBox;
     customZoomFactorSpinBoxPointer = domainSettingsDialogUi.customZoomFactorSpinBox;
     QPushButton *addDomainButtonPointer = domainSettingsDialogUi.addDomainButton;
     deleteDomainButtonPointer = domainSettingsDialogUi.deleteDomainButton;
+    deleteAllDomainsButtonPointer = domainSettingsDialogUi.deleteAllDomainsButton;
     QDialogButtonBox *dialogButtonBoxPointer = domainSettingsDialogUi.dialogButtonBox;
     applyButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::StandardButton::Apply);
     resetButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::StandardButton::Reset);
 
     QDialogButtonBox *dialogButtonBoxPointer = domainSettingsDialogUi.dialogButtonBox;
     applyButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::StandardButton::Apply);
     resetButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::StandardButton::Reset);
 
+    // Set the button icons that require a fallback icon.
+    deleteAllDomainsButtonPointer->setIcon(QIcon::fromTheme(QLatin1String("albumfolder-user-trash"), QIcon::fromTheme(QLatin1String("list-remove"))));
+
     // Create a table model.
     domainsTableModelPointer = new QSqlTableModel(nullptr, QSqlDatabase::database(DomainsDatabase::CONNECTION_NAME));
 
     // Create a table model.
     domainsTableModelPointer = new QSqlTableModel(nullptr, QSqlDatabase::database(DomainsDatabase::CONNECTION_NAME));
 
@@ -110,13 +129,13 @@ DomainSettingsDialog::DomainSettingsDialog(const int &startType, const QString &
     highlightedPalette = defaultPalette;
 
     // Get the default highlight color.
     highlightedPalette = defaultPalette;
 
     // Get the default highlight color.
-    QColor highlightColor = defaultPalette.color(QPalette::Highlight);
+    QColor alphaHighlightColor = defaultPalette.color(QPalette::Highlight);
 
     // Set the highlight color to be partially transparent.
 
     // Set the highlight color to be partially transparent.
-    highlightColor.setAlpha(64);
+    alphaHighlightColor.setAlpha(64);
 
     // Set highlighted background color.
 
     // Set highlighted background color.
-    highlightedPalette.setColor(QPalette::Window, highlightColor);
+    highlightedPalette.setColor(QPalette::Window, alphaHighlightColor);
 
     // Setup the dialog according to the start type.
     switch (startType)
 
     // Setup the dialog according to the start type.
     switch (startType)
@@ -126,9 +145,6 @@ DomainSettingsDialog::DomainSettingsDialog(const int &startType, const QString &
             // Select the first entry in the list view.
             domainsListViewPointer->setCurrentIndex(domainsTableModelPointer->index(0, domainsTableModelPointer->fieldIndex(DomainsDatabase::DOMAIN_NAME)));
 
             // Select the first entry in the list view.
             domainsListViewPointer->setCurrentIndex(domainsTableModelPointer->index(0, domainsTableModelPointer->fieldIndex(DomainsDatabase::DOMAIN_NAME)));
 
-            // Populate the domain settings.
-            domainSelected(domainsSelectionModelPointer->currentIndex());
-
             break;
         }
 
             break;
         }
 
@@ -141,13 +157,13 @@ DomainSettingsDialog::DomainSettingsDialog(const int &startType, const QString &
             // Move to the new domain.
             domainsListViewPointer->setCurrentIndex(newDomainIndex[0]);
 
             // Move to the new domain.
             domainsListViewPointer->setCurrentIndex(newDomainIndex[0]);
 
-            // Populate the domain settings.
-            domainSelected(domainsSelectionModelPointer->currentIndex());
-
             break;
         }
     }
 
             break;
         }
     }
 
+    // Populate the domain settings.
+    domainSelected(domainsSelectionModelPointer->currentIndex());
+
     // Handle clicks on the domains.
     connect(domainsListViewPointer, SIGNAL(activated(QModelIndex)), this, SLOT(domainSelected(QModelIndex)));
 
     // Handle clicks on the domains.
     connect(domainsListViewPointer, SIGNAL(activated(QModelIndex)), this, SLOT(domainSelected(QModelIndex)));
 
@@ -157,19 +173,28 @@ DomainSettingsDialog::DomainSettingsDialog(const int &startType, const QString &
     connect(localStorageComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(localStorageChanged(int)));
     connect(domStorageComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(domStorageChanged(int)));
     connect(userAgentComboBoxPointer, SIGNAL(currentTextChanged(QString)), this, SLOT(userAgentChanged(QString)));
     connect(localStorageComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(localStorageChanged(int)));
     connect(domStorageComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(domStorageChanged(int)));
     connect(userAgentComboBoxPointer, SIGNAL(currentTextChanged(QString)), this, SLOT(userAgentChanged(QString)));
+    connect(ultraPrivacyComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(ultraPrivacyChanged(int)));
+    connect(ultraListComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(ultraListChanged(int)));
+    connect(easyPrivacyComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(easyPrivacyChanged(int)));
+    connect(easyListComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(easyListChanged(int)));
+    connect(fanboysAnnoyanceListComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(fanboysAnnoyanceListChanged(int)));
     connect(zoomFactorComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(zoomFactorComboBoxChanged(int)));
     connect(customZoomFactorSpinBoxPointer, SIGNAL(valueChanged(double)), this, SLOT(customZoomFactorChanged(double)));
 
     // Connect the buttons.
     connect(addDomainButtonPointer, SIGNAL(clicked()), this, SLOT(showAddMessageBox()));
     connect(deleteDomainButtonPointer, SIGNAL(clicked()), this, SLOT(showDeleteMessageBox()));
     connect(zoomFactorComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(zoomFactorComboBoxChanged(int)));
     connect(customZoomFactorSpinBoxPointer, SIGNAL(valueChanged(double)), this, SLOT(customZoomFactorChanged(double)));
 
     // Connect the buttons.
     connect(addDomainButtonPointer, SIGNAL(clicked()), this, SLOT(showAddMessageBox()));
     connect(deleteDomainButtonPointer, SIGNAL(clicked()), this, SLOT(showDeleteMessageBox()));
+    connect(deleteAllDomainsButtonPointer, SIGNAL(clicked()), this, SLOT(showDeleteAllMessageBox()));
     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(cancel()));
 
     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(cancel()));
 
-    // Update the UI.
-    updateUi();
+    // Update the DOM storage status.
+    updateDomStorageStatus();
+
+    // Update the buttons.
+    updateButtons();
 }
 
 void DomainSettingsDialog::apply() const
 }
 
 void DomainSettingsDialog::apply() const
@@ -190,11 +215,11 @@ void DomainSettingsDialog::apply() const
     // Select the new index.
     domainsListViewPointer->setCurrentIndex(newIndexList[0].siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::DOMAIN_NAME)));
 
     // Select the new index.
     domainsListViewPointer->setCurrentIndex(newIndexList[0].siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::DOMAIN_NAME)));
 
-    // Update the UI.
-    updateUi();
+    // Update the buttons.
+    updateButtons();
 
     // Emit the domain settings updated signal.
 
     // Emit the domain settings updated signal.
-    emit domainSettingsUpdated();
+    Q_EMIT domainSettingsUpdated();
 }
 
 void DomainSettingsDialog::cancel()
 }
 
 void DomainSettingsDialog::cancel()
@@ -206,25 +231,25 @@ void DomainSettingsDialog::cancel()
     reject();
 }
 
     reject();
 }
 
-void DomainSettingsDialog::customZoomFactorChanged(const double &newValue) const
+void DomainSettingsDialog::customZoomFactorChanged(const double newValue) const
 {
     // Update the domains table model.
     domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::CUSTOM_ZOOM_FACTOR)), newValue);
 
 {
     // Update the domains table model.
     domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::CUSTOM_ZOOM_FACTOR)), newValue);
 
-    // Update the UI.
-    updateUi();
+    // Update the buttons.
+    updateButtons();
 }
 
 }
 
-void DomainSettingsDialog::domStorageChanged(const int &newIndex) const
+void DomainSettingsDialog::domStorageChanged(const int newIndex) const
 {
     // Update the domains table model.
     domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::DOM_STORAGE)), newIndex);
 
     // Populate the DOM storage label.
 {
     // Update the domains table model.
     domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::DOM_STORAGE)), newIndex);
 
     // Populate the DOM storage label.
-    populateDomStorageLabel();
+    populateLabel(DOM_STORAGE);
 
 
-    // Update the UI.
-    updateUi();
+    // Update the buttons.
+    updateButtons();
 }
 
 void DomainSettingsDialog::domainNameChanged(const QString &updatedDomainName) const
 }
 
 void DomainSettingsDialog::domainNameChanged(const QString &updatedDomainName) const
@@ -232,8 +257,8 @@ void DomainSettingsDialog::domainNameChanged(const QString &updatedDomainName) c
     // Update the domains table model.
     domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex(), updatedDomainName);
 
     // Update the domains table model.
     domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex(), updatedDomainName);
 
-    // Update the UI.
-    updateUi();
+    // Update the buttons.
+    updateButtons();
 }
 
 void DomainSettingsDialog::domainSelected(const QModelIndex &modelIndex) const
 }
 
 void DomainSettingsDialog::domainSelected(const QModelIndex &modelIndex) const
@@ -262,12 +287,32 @@ void DomainSettingsDialog::domainSelected(const QModelIndex &modelIndex) const
     // Set the custom user agent if specified.
     if (userAgentIndex == -1) userAgentComboBoxPointer->setCurrentText(userAgent);
 
     // Set the custom user agent if specified.
     if (userAgentIndex == -1) userAgentComboBoxPointer->setCurrentText(userAgent);
 
+    // Populate the filter lists combo boxes.
+    ultraPrivacyComboBoxPointer->setCurrentIndex(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::ULTRAPRIVACY)).data().toInt());
+    ultraListComboBoxPointer->setCurrentIndex(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::ULTRALIST)).data().toInt());
+    easyPrivacyComboBoxPointer->setCurrentIndex(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::EASYPRIVACY)).data().toInt());
+    easyListComboBoxPointer->setCurrentIndex(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::EASYLIST)).data().toInt());
+    fanboysAnnoyanceListComboBoxPointer->setCurrentIndex(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::FANBOYS_ANNOYANCE_LIST)).data().toInt());
+
     // Get the zoom factor combo box index.
     int zoomFactorComboBoxIndex = modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::ZOOM_FACTOR)).data().toInt();
 
     // Populate the zoom factor combo box.
     zoomFactorComboBoxPointer->setCurrentIndex(zoomFactorComboBoxIndex);
 
     // Get the zoom factor combo box index.
     int zoomFactorComboBoxIndex = modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::ZOOM_FACTOR)).data().toInt();
 
     // Populate the zoom factor combo box.
     zoomFactorComboBoxPointer->setCurrentIndex(zoomFactorComboBoxIndex);
 
+    // Get the combo box palette.
+    QPalette comboBoxPalette = zoomFactorComboBoxPointer->palette();
+
+    // Get the combo box window color.
+    QColor comboBoxWindowColor = comboBoxPalette.color(QPalette::Window);
+
+    // Set the combo box window color back to the palette.  This makes the system think the palette has changed.
+    comboBoxPalette.setColor(QPalette::Window, comboBoxWindowColor);
+
+    // Explicitly set the combo box palette.  Because the system thinks the palette has been changed, and because the combo box palette is being explicitly set,
+    // the system will not propagate the highlighted palette from the widget pointer palette down to the combo box.  <https://redmine.stoutner.com/issues/1252>
+    zoomFactorComboBoxPointer->setPalette(comboBoxPalette);
+
     // Populate the custom zoom factor spin box according to the zoom factor combo box.
     if (zoomFactorComboBoxIndex == 0)  // System default zoom factor is selected.
     {
     // Populate the custom zoom factor spin box according to the zoom factor combo box.
     if (zoomFactorComboBoxIndex == 0)  // System default zoom factor is selected.
     {
@@ -290,37 +335,84 @@ void DomainSettingsDialog::domainSelected(const QModelIndex &modelIndex) const
     customZoomFactorSpinBoxPointer->setEnabled(zoomFactorComboBoxIndex);
 
     // Populate the labels.
     customZoomFactorSpinBoxPointer->setEnabled(zoomFactorComboBoxIndex);
 
     // Populate the labels.
-    populateJavaScriptLabel();
-    populateLocalStorageLabel();
-    populateDomStorageLabel();
+    populateLabel(JAVASCRIPT);
+    populateLabel(LOCAL_STORAGE);
+    populateLabel(DOM_STORAGE);
+    populateLabel(ULTRAPRIVACY);
+    populateLabel(ULTRALIST);
+    populateLabel(EASYPRIVACY);
+    populateLabel(EASYLIST);
+    populateLabel(FANBOYS_ANNOYANCE_LIST);
     populateUserAgentLabel(userAgentComboBoxPointer->currentText());
 
     populateUserAgentLabel(userAgentComboBoxPointer->currentText());
 
-    // Update the UI.
-    updateUi();
+    // Update the buttons.
+    updateButtons();
 }
 
 }
 
-void DomainSettingsDialog::javaScriptChanged(const int &newIndex) const
+void DomainSettingsDialog::easyListChanged(const int newIndex) const
+{
+    // Update the domains table model.
+    domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::EASYLIST)), newIndex);
+
+    // Populate the EasyList label.
+    populateLabel(EASYLIST);
+
+    // Update the buttons.
+    updateButtons();
+}
+
+void DomainSettingsDialog::easyPrivacyChanged(const int newIndex) const
+{
+    // Update the domains table model.
+    domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::EASYPRIVACY)), newIndex);
+
+    // Populate the EasyPrivacy label.
+    populateLabel(EASYPRIVACY);
+
+    // Update the buttons.
+    updateButtons();
+}
+
+void DomainSettingsDialog::fanboysAnnoyanceListChanged(const int newIndex) const
+{
+    // Update the domains table model.
+    domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::FANBOYS_ANNOYANCE_LIST)), newIndex);
+
+    // Populate the Fanboy's Annoyance List label.
+    populateLabel(FANBOYS_ANNOYANCE_LIST);
+
+    // Update the buttons.
+    updateButtons();
+}
+
+void DomainSettingsDialog::javaScriptChanged(const int newIndex) const
 {
     // Update the domains table model.
     domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::JAVASCRIPT)), newIndex);
 
     // Populate the JavaScript label.
 {
     // Update the domains table model.
     domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::JAVASCRIPT)), newIndex);
 
     // Populate the JavaScript label.
-    populateJavaScriptLabel();
+    populateLabel(JAVASCRIPT);
+
+    // Update the DOM storage status.
+    updateDomStorageStatus();
 
 
-    // Update the UI.
-    updateUi();
+    // Update the buttons.
+    updateButtons();
 }
 
 }
 
-void DomainSettingsDialog::localStorageChanged(const int &newIndex) const
+void DomainSettingsDialog::localStorageChanged(const int newIndex) const
 {
     // Update the domains table model.
     domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::LOCAL_STORAGE)), newIndex);
 
     // Populate the local storage label.
 {
     // Update the domains table model.
     domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::LOCAL_STORAGE)), newIndex);
 
     // Populate the local storage label.
-    populateLocalStorageLabel();
+    populateLabel(LOCAL_STORAGE);
+
+    // Update the DOM storage status.
+    updateDomStorageStatus();
 
 
-    // Update the UI.
-    updateUi();
+    // Update the buttons.
+    updateButtons();
 }
 
 void DomainSettingsDialog::ok()
 }
 
 void DomainSettingsDialog::ok()
@@ -329,142 +421,235 @@ void DomainSettingsDialog::ok()
     domainsTableModelPointer->submitAll();
 
     // Emit the domain settings updated signal.
     domainsTableModelPointer->submitAll();
 
     // Emit the domain settings updated signal.
-    emit domainSettingsUpdated();
+    Q_EMIT domainSettingsUpdated();
 
     // Close the dialog.
     accept();
 }
 
 
     // Close the dialog.
     accept();
 }
 
-void DomainSettingsDialog::populateDomStorageLabel() const
+void DomainSettingsDialog::populateLabel(const int label) const
 {
 {
-    // Populate the label according to the currently selected index.
-    switch (domStorageComboBoxPointer->currentIndex())
+    // Create the label strings.
+    QString enabledString;
+    QString enabledBoldString;
+    QString disabledString;
+    QString disabledBoldString;
+
+    // Create the system default bool.
+    bool systemDefaultEnabled;
+
+    // Create the widget pointers.
+    QWidget *widgetPointer;
+    QComboBox *comboBoxPointer;
+    QLabel *labelPointer;
+
+    // Populate the local variables.
+    switch (label)
     {
     {
-        case (DomainsDatabase::SYSTEM_DEFAULT):
+        case (JAVASCRIPT):
         {
         {
-            // Set the text according to the system default.
-            if (Settings::domStorageEnabled())
-                domStorageLabelPointer->setText(i18nc("Domain settings DOM storage label.", "DOM storage enabled"));
-            else
-                domStorageLabelPointer->setText(i18nc("Domain settings DOM storage label.", "DOM storage disabled"));
+            // Populate the label strings.
+            enabledString = i18nc("Domain settings JavaScript label.", "JavaScript enabled");
+            enabledBoldString = i18nc("Domain settings JavaScript label.  The <b> tags should be retained.", "<b>JavaScript enabled</b>");
+            disabledString = i18nc("Domain settings JavaScript label.", "JavaScript disabled");
+            disabledBoldString = i18nc("Domain settings JavaScript label.  The <b> tags should be retained.", "<b>JavaScript disabled</b>");
 
 
-            // Reset the palette.
-            domStorageWidgetPointer->setPalette(defaultPalette);
+            // Populate the system default bool.
+            systemDefaultEnabled = Settings::javaScriptEnabled();
+
+            // Populate the widget pointers.
+            widgetPointer = javaScriptWidgetPointer;
+            comboBoxPointer = javaScriptComboBoxPointer;
+            labelPointer = javaScriptLabelPointer;
 
             break;
         }
 
 
             break;
         }
 
-        case (DomainsDatabase::ENABLED):
+        case (LOCAL_STORAGE):
         {
         {
-            // Set the enabled text in bold.
-            domStorageLabelPointer->setText(i18nc("Domain settings DOM storage label.  The <b> tags should be retained.", "<b>DOM storage enabled</b>"));
+            // Populate the label strings.
+            enabledString = i18nc("Domain settings local storage label.", "Local storage enabled");
+            enabledBoldString = i18nc("Domain settings local storage label.  The <b> tags should be retained.", "<b>Local storage enabled</b>");
+            disabledString = i18nc("Domain settings local storage label.", "Local storage disabled");
+            disabledBoldString = i18nc("Domain settings local storage label.  The <b> tags should be retained.", "<b>Local storage disabled</b>");
+
+            // Populate the system default bool.
+            systemDefaultEnabled = Settings::localStorageEnabled();
 
 
-            // Set the palette.
-            domStorageWidgetPointer->setPalette(highlightedPalette);
+            // Populate the widget pointers.
+            widgetPointer = localStorageWidgetPointer;
+            comboBoxPointer = localStorageComboBoxPointer;
+            labelPointer = localStorageLabelPointer;
 
             break;
         }
 
 
             break;
         }
 
-        case (DomainsDatabase::DISABLED):
+        case (DOM_STORAGE):
         {
         {
-            // Set the disabled text in bold.
-            domStorageLabelPointer->setText(i18nc("Domain settings DOM storage label.  The <b> tags should be retained.", "<b>DOM storage disabled</b>"));
+            // Populate the label strings.
+            enabledString = i18nc("Domain settings DOM storage label.", "DOM storage enabled");
+            enabledBoldString = i18nc("Domain settings DOM storage label.  The <b> tags should be retained.", "<b>DOM storage enabled</b>");
+            disabledString = i18nc("Domain settings DOM storage label.", "DOM storage disabled");
+            disabledBoldString = i18nc("Domain settings DOM storage label.  The <b> tags should be retained.", "<b>DOM storage disabled</b>");
 
 
-            // Set the palette.
-            domStorageWidgetPointer->setPalette(highlightedPalette);
+            // Populate the system default bool.
+            systemDefaultEnabled = Settings::domStorageEnabled();
+
+            // Populate the widget pointers.
+            widgetPointer = domStorageWidgetPointer;
+            comboBoxPointer = domStorageComboBoxPointer;
+            labelPointer = domStorageLabelPointer;
 
             break;
         }
 
             break;
         }
-    }
-}
 
 
-void DomainSettingsDialog::populateJavaScriptLabel() const
-{
-    // Populate the label according to the currently selected index.
-    switch (javaScriptComboBoxPointer->currentIndex())
-    {
-        case (DomainsDatabase::SYSTEM_DEFAULT):
+        case (ULTRAPRIVACY):
         {
         {
-            // Set the text according to the system default.
-            if (Settings::javaScriptEnabled())
-                javaScriptLabelPointer->setText(i18nc("Domain settings JavaScript label.", "JavaScript enabled"));
-            else
-                javaScriptLabelPointer->setText(i18nc("Domain settings JavaScript label.", "JavaScript disabled"));
+            // Populate the label strings.
+            enabledString = i18nc("Domain settings UltraPrivacy enabled label.", "UltraPrivacy enabled");
+            enabledBoldString = i18nc("Domain settings UltraPrivacy enabled bold label.  The <b> tags should be retained.", "<b>UltraPrivacy enabled</b>");
+            disabledString = i18nc("Domain settings UltraPrivacy disabled label.", "UltraPrivacy disabled");
+            disabledBoldString = i18nc("Domain settings UltraPrivacy disabled bold label.  The <b> tags should be retained.", "<b>UltraPrivacy disabled</b>");
 
 
-            // Reset the palette.
-            javaScriptWidgetPointer->setPalette(defaultPalette);
+            // Populate the system default bool.
+            systemDefaultEnabled = Settings::ultraPrivacyEnabled();
+
+            // Populate the widget pointers.
+            widgetPointer = ultraPrivacyWidgetPointer;
+            comboBoxPointer = ultraPrivacyComboBoxPointer;
+            labelPointer = ultraPrivacyLabelPointer;
 
             break;
         }
 
 
             break;
         }
 
-        case (DomainsDatabase::ENABLED):
+        case (ULTRALIST):
         {
         {
-            // Set the enabled text in bold.
-            javaScriptLabelPointer->setText(i18nc("Domain settings JavaScript label.  The <b> tags should be retained.", "<b>JavaScript enabled</b>"));
+            // Populate the label strings.
+            enabledString = i18nc("Domain settings UltraList enabled label.", "UltraList enabled");
+            enabledBoldString = i18nc("Domain settings UltraList enabled bold label.  The <b> tags should be retained.", "<b>UltraList enabled</b>");
+            disabledString = i18nc("Domain settings UltraList disabled label.", "UltraList disabled");
+            disabledBoldString = i18nc("Domain settings UltraList disabled bold label.  The <b> tags should be retained.", "<b>UltraList disabled</b>");
+
+            // Populate the system default bool.
+            systemDefaultEnabled = Settings::ultraListEnabled();
 
 
-            // Set the palette.
-            javaScriptWidgetPointer->setPalette(highlightedPalette);
+            // Populate the widget pointers.
+            widgetPointer = ultraListWidgetPointer;
+            comboBoxPointer = ultraListComboBoxPointer;
+            labelPointer = ultraListLabelPointer;
 
             break;
         }
 
 
             break;
         }
 
-        case (DomainsDatabase::DISABLED):
+        case (EASYPRIVACY):
+        {
+            // Populate the label strings.
+            enabledString = i18nc("Domain settings EasyPrivacy enabled label.", "EasyPrivacy enabled");
+            enabledBoldString = i18nc("Domain settings EasyPrivacy enabled bold label.  The <b> tags should be retained.", "<b>EasyPrivacy enabled</b>");
+            disabledString = i18nc("Domain settings EasyPrivacy disabled label.", "EasyPrivacy disabled");
+            disabledBoldString = i18nc("Domain settings EasyPrivacy disabled bold label.  The <b> tags should be retained.", "<b>EasyPrivacy disabled</b>");
+
+            // Populate the system default bool.
+            systemDefaultEnabled = Settings::easyPrivacyEnabled();
+
+            // Populate the widget pointers.
+            widgetPointer = easyPrivacyWidgetPointer;
+            comboBoxPointer = easyPrivacyComboBoxPointer;
+            labelPointer = easyPrivacyLabelPointer;
+
+            break;
+        }
+
+        case (EASYLIST):
+        {
+            // Populate the label strings.
+            enabledString = i18nc("Domain settings EasyList enabled label.", "EasyList enabled");
+            enabledBoldString = i18nc("Domain settings EasyList enabled bold label.  The <b> tags should be retained.", "<b>EasyList enabled</b>");
+            disabledString = i18nc("Domain settings EasyList disabled label.", "EasyList disabled");
+            disabledBoldString = i18nc("Domain settings EasyList disabled bold label.  The <b> tags should be retained.", "<b>EasyList disabled</b>");
+
+            // Populate the system default bool.
+            systemDefaultEnabled = Settings::easyListEnabled();
+
+            // Populate the widget pointers.
+            widgetPointer = easyListWidgetPointer;
+            comboBoxPointer = easyListComboBoxPointer;
+            labelPointer = easyListLabelPointer;
+
+            break;
+        }
+
+        case (FANBOYS_ANNOYANCE_LIST):
         {
         {
-            // Set the disabled text in bold.
-            javaScriptLabelPointer->setText(i18nc("Domain settings JavaScript label.  The <b> tags should be retained.", "<b>JavaScript disabled</b>"));
+            // Populate the label strings.
+            enabledString = i18nc("Domain settings Fanboy’s Annoyance List enabled label.", "Fanboy’s Annoyance List enabled");
+            enabledBoldString = i18nc("Domain settings Fanboy’s Annoyance List enabled bold label.  The <b> tags should be retained.", "<b>Fanboy’s Annoyance List enabled</b>");
+            disabledString = i18nc("Domain settings Fanboy’s Annoyance List disabled label.", "Fanboy’s Annoyance List disabled");
+            disabledBoldString = i18nc("Domain settings Fanboy’s Annoyance List disabled bold label.  The <b> tags should be retained.", "<b>Fanboy’s Annoyance List disabled</b>");
+
+            // Populate the system default bool.
+            systemDefaultEnabled = Settings::fanboysAnnoyanceListEnabled();
 
 
-            // Set the palette.
-            javaScriptWidgetPointer->setPalette(highlightedPalette);
+            // Populate the widget pointers.
+            widgetPointer = fanboysAnnoyanceListWidgetPointer;
+            comboBoxPointer = fanboysAnnoyanceListComboBoxPointer;
+            labelPointer = fanboysAnnoyanceListLabelPointer;
 
             break;
         }
     }
 
             break;
         }
     }
-}
 
 
-void DomainSettingsDialog::populateLocalStorageLabel() const
-{
-    // Populate the label according to the currently selected index.
-    switch (localStorageComboBoxPointer->currentIndex())
+    // Get the combo box palette.
+    QPalette comboBoxPalette = comboBoxPointer->palette();
+
+    // Get the combo box window color.
+    QColor comboBoxWindowColor = comboBoxPalette.color(QPalette::Window);
+
+    // Set the combo box window color back to the palette.  This makes the system think the palette has changed.
+    comboBoxPalette.setColor(QPalette::Window, comboBoxWindowColor);
+
+    // Explicitly set the combo box palette.  Because the system thinks the palette has been changed, and because the combo box palette is being explicitly set,
+    // the system will not propagate the highlighted palette from the widget pointer palette down to the combo box.  <https://redmine.stoutner.com/issues/1252>
+    comboBoxPointer->setPalette(comboBoxPalette);
+
+    // Populate the label and widget palette according to the currently selected combo box index.
+    switch (comboBoxPointer->currentIndex())
     {
         case (DomainsDatabase::SYSTEM_DEFAULT):
         {
             // Set the text according to the system default.
     {
         case (DomainsDatabase::SYSTEM_DEFAULT):
         {
             // Set the text according to the system default.
-            if (Settings::localStorageEnabled())
-                localStorageLabelPointer->setText(i18nc("Domain settings local storage label.", "Local storage enabled"));
+            if (systemDefaultEnabled)
+                labelPointer->setText(enabledString);
             else
             else
-                localStorageLabelPointer->setText(i18nc("Domain settings local storage label.", "Local storage disabled"));
+                labelPointer->setText(disabledString);
 
             // Reset the palette.
 
             // Reset the palette.
-            localStorageWidgetPointer->setPalette(defaultPalette);
-
+            widgetPointer->setPalette(defaultPalette);
             break;
         }
 
         case (DomainsDatabase::ENABLED):
         {
             break;
         }
 
         case (DomainsDatabase::ENABLED):
         {
-            // Set the enabled text in bold.
-            localStorageLabelPointer->setText(i18nc("Domain settings local storage label.  The <b> tabs should be retained.", "<b>Local storage enabled</b>"));
-
-            // Set the palette.
-            localStorageWidgetPointer->setPalette(highlightedPalette);
+            // Set the enabled bold text.
+            labelPointer->setText(enabledBoldString);
 
 
+            // Set the widget palette.
+            widgetPointer->setPalette(highlightedPalette);
             break;
         }
 
         case (DomainsDatabase::DISABLED):
         {
             break;
         }
 
         case (DomainsDatabase::DISABLED):
         {
-            // Set the disabled text in bold.
-            localStorageLabelPointer->setText(i18nc("Domain settings local storage label.  The <b> tags should be retained.", "<b>Local storage disabled</b>"));
-
-            // Set the palette.
-            localStorageWidgetPointer->setPalette(highlightedPalette);
+            // Set the disabled bold text.
+            labelPointer->setText(disabledBoldString);
 
 
+            // Set the widget palette.
+            widgetPointer->setPalette(highlightedPalette);
             break;
         }
     }
 }
 
             break;
         }
     }
 }
 
-
 void DomainSettingsDialog::populateUserAgentLabel(const QString &userAgentName) const
 {
     // Populate the label according to the type.
 void DomainSettingsDialog::populateUserAgentLabel(const QString &userAgentName) const
 {
     // Populate the label according to the type.
@@ -479,9 +664,22 @@ void DomainSettingsDialog::populateUserAgentLabel(const QString &userAgentName)
     else
     {
         // Display the user agent name in bold.
     else
     {
         // Display the user agent name in bold.
-        userAgentLabelPointer->setText("<strong>" + userAgentName + "</strong>");
+        userAgentLabelPointer->setText(QLatin1String("<strong>") + userAgentName + QLatin1String("</strong>"));
+
+        // Get the combo box palette.
+        QPalette comboBoxPalette = userAgentComboBoxPointer->palette();
+
+        // Get the combo box window color.
+        QColor comboBoxWindowColor = comboBoxPalette.color(QPalette::Window);
 
 
-        // Set the palette.
+        // Set the combo box window color back to the palette.  This makes the system think the palette has changed.
+        comboBoxPalette.setColor(QPalette::Window, comboBoxWindowColor);
+
+        // Explicitly set the combo box palette.  Because the system thinks the palette has been changed, and because the combo box palette is being explicitly set,
+        // the system will not propagate the highlighted palette from the widget pointer palette down to the combo box.  <https://redmine.stoutner.com/issues/1252>
+        userAgentComboBoxPointer->setPalette(comboBoxPalette);
+
+        // Set the widget palette.
         userAgentWidgetPointer->setPalette(highlightedPalette);
     }
 }
         userAgentWidgetPointer->setPalette(highlightedPalette);
     }
 }
@@ -494,8 +692,8 @@ void DomainSettingsDialog::reset() const
     // Repopulate the domain settings.
     domainSelected(domainsListViewPointer->currentIndex());
 
     // Repopulate the domain settings.
     domainSelected(domainsListViewPointer->currentIndex());
 
-    // Update the UI.
-    updateUi();
+    // Update the buttons.
+    updateButtons();
 }
 
 void DomainSettingsDialog::showAddMessageBox()
 }
 
 void DomainSettingsDialog::showAddMessageBox()
@@ -530,39 +728,85 @@ void DomainSettingsDialog::showAddMessageBox()
         // Populate the domain settings.
         domainSelected(domainsSelectionModelPointer->currentIndex());
 
         // Populate the domain settings.
         domainSelected(domainsSelectionModelPointer->currentIndex());
 
-        // Update the UI.
-        updateUi();
+        // Update the buttons.
+        updateButtons();
 
         // Emit the domain settings updated signal.
 
         // Emit the domain settings updated signal.
-        emit domainSettingsUpdated();
+        Q_EMIT domainSettingsUpdated();
+    }
+}
+
+void DomainSettingsDialog::showDeleteAllMessageBox() const
+{
+    // Instantiate a delete all message box.
+    QMessageBox deleteAllMessageBox;
+
+    // Set the icon.
+    deleteAllMessageBox.setIcon(QMessageBox::Warning);
+
+    // Set the window title.
+    deleteAllMessageBox.setWindowTitle(i18nc("Delete all domains dialog title", "Delete All Domains"));
+
+    // Set the text.
+    deleteAllMessageBox.setText(i18nc("Delete all domains dialog main message", "Delete all domains?"));
+
+    // Set the informative test.
+    deleteAllMessageBox.setInformativeText(i18nc("Delete all domains dialog secondary message", "This action cannot be undone."));
+
+    // Set the standard buttons.
+    deleteAllMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+
+    // Set the default button.
+    deleteAllMessageBox.setDefaultButton(QMessageBox::No);
+
+    // Display the dialog and capture the return value.
+    int returnValue = deleteAllMessageBox.exec();
+
+    // Delete all domains if instructed.
+    if (returnValue == QMessageBox::Yes)
+    {
+        // Get the count of all rows.
+        int rowCount = domainsTableModelPointer->rowCount();
+
+        // Delete all the rows, starting with 0.
+        domainsTableModelPointer->removeRows(0, rowCount);
+
+        // Submit all pending changes.
+        domainsTableModelPointer->submitAll();
+
+        // Update the buttons.
+        updateButtons();
+
+        // Emit the domain settings updated signal.
+        Q_EMIT domainSettingsUpdated();
     }
 }
 
 void DomainSettingsDialog::showDeleteMessageBox() const
 {
     }
 }
 
 void DomainSettingsDialog::showDeleteMessageBox() const
 {
-    // Instantiate a delete dialog message box.
-    QMessageBox deleteDialogMessageBox;
+    // Instantiate a delete message box.
+    QMessageBox deleteMessageBox;
 
     // Set the icon.
 
     // Set the icon.
-    deleteDialogMessageBox.setIcon(QMessageBox::Warning);
+    deleteMessageBox.setIcon(QMessageBox::Warning);
 
     // Set the window title.
 
     // Set the window title.
-    deleteDialogMessageBox.setWindowTitle(i18nc("Delete domain dialog title", "Delete Domain"));
+    deleteMessageBox.setWindowTitle(i18nc("Delete domain dialog title", "Delete Domain"));
 
     // Set the text.
 
     // Set the text.
-    deleteDialogMessageBox.setText(i18nc("Delete domain dialog main message", "Delete the current domain?"));
+    deleteMessageBox.setText(i18nc("Delete domain dialog main message", "Delete the current domain?"));
 
     // Set the informative text.
 
     // Set the informative text.
-    deleteDialogMessageBox.setInformativeText(i18nc("Delete domain dialog secondary message", "Doing so will also save any pending changes that have been made to other domains."));
+    deleteMessageBox.setInformativeText(i18nc("Delete domain dialog secondary message", "Doing so will also save any pending changes that have been made to other domains."));
 
     // Set the standard buttons.
 
     // Set the standard buttons.
-    deleteDialogMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+    deleteMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
 
     // Set the default button.
 
     // Set the default button.
-    deleteDialogMessageBox.setDefaultButton(QMessageBox::No);
+    deleteMessageBox.setDefaultButton(QMessageBox::No);
 
     // Display the dialog and capture the return value.
 
     // Display the dialog and capture the return value.
-    int returnValue = deleteDialogMessageBox.exec();
+    int returnValue = deleteMessageBox.exec();
 
     // Delete the domain if instructed.
     if (returnValue == QMessageBox::Yes)
 
     // Delete the domain if instructed.
     if (returnValue == QMessageBox::Yes)
@@ -595,19 +839,49 @@ void DomainSettingsDialog::showDeleteMessageBox() const
             domainSelected(domainsListViewPointer->currentIndex());
         }
 
             domainSelected(domainsListViewPointer->currentIndex());
         }
 
-        // Update the Ui.
-        updateUi();
+        // Update the buttons.
+        updateButtons();
 
         // Emit the domain settings updated signal.
 
         // Emit the domain settings updated signal.
-        emit domainSettingsUpdated();
+        Q_EMIT domainSettingsUpdated();
     }
 }
 
     }
 }
 
-void DomainSettingsDialog::updateUi() const
+void DomainSettingsDialog::ultraListChanged(const int newIndex) const
+{
+    // Update the domains table model.
+    domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::ULTRALIST)), newIndex);
+
+    // Populate the UltraList label.
+    populateLabel(ULTRALIST);
+
+    // Update the buttons.
+    updateButtons();
+}
+
+void DomainSettingsDialog::ultraPrivacyChanged(const int newIndex) const
+{
+    // Update the domains table model.
+    domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::ULTRAPRIVACY)), newIndex);
+
+    // Populate the UltraPrivacy label.
+    populateLabel(ULTRAPRIVACY);
+
+    // Update the buttons.
+    updateButtons();
+}
+
+void DomainSettingsDialog::updateButtons() const
 {
 {
+    // Get
+    bool atLeastOneDomainSettingExists = domainsTableModelPointer->rowCount() > 0;
+
     // Update the delete button status.
     deleteDomainButtonPointer->setEnabled(domainsSelectionModelPointer->hasSelection());
 
     // Update the delete button status.
     deleteDomainButtonPointer->setEnabled(domainsSelectionModelPointer->hasSelection());
 
+    // Update the delete all button status.
+    deleteAllDomainsButtonPointer->setEnabled(atLeastOneDomainSettingExists);
+
     // Update the reset button status.
     resetButtonPointer->setEnabled(domainsTableModelPointer->isDirty());
 
     // Update the reset button status.
     resetButtonPointer->setEnabled(domainsTableModelPointer->isDirty());
 
@@ -615,7 +889,79 @@ void DomainSettingsDialog::updateUi() const
     applyButtonPointer->setEnabled(domainsTableModelPointer->isDirty());
 
     // Display the domain settings if there is at least one domain.
     applyButtonPointer->setEnabled(domainsTableModelPointer->isDirty());
 
     // Display the domain settings if there is at least one domain.
-    domainSettingsWidgetPointer->setVisible(domainsTableModelPointer->rowCount() > 0);
+    domainSettingsWidgetPointer->setVisible(atLeastOneDomainSettingExists);
+}
+
+void DomainSettingsDialog::updateDomStorageStatus() const
+{
+    // Instantiate tracking variables.
+    bool javaScriptEnabled;
+    bool localStorageEnabled;
+
+    // Populate the JavaScript tracker.
+    switch (javaScriptComboBoxPointer->currentIndex())
+    {
+        case (DomainsDatabase::SYSTEM_DEFAULT):
+        {
+            // Update the tracker according to the system default.
+            if (Settings::javaScriptEnabled())
+                javaScriptEnabled = true;
+            else
+                javaScriptEnabled = false;
+
+            break;
+        }
+
+        case (DomainsDatabase::ENABLED):
+        {
+            // Update the tracker.
+            javaScriptEnabled = true;
+
+            break;
+        }
+
+        case (DomainsDatabase::DISABLED):
+        {
+            // Update the tracker.
+            javaScriptEnabled = false;
+
+            break;
+        }
+    }
+
+    // Populate the local storage tracker.
+    switch (localStorageComboBoxPointer->currentIndex())
+    {
+        case (DomainsDatabase::SYSTEM_DEFAULT):
+        {
+            // Update the tracker according to the system default.
+            if (Settings::localStorageEnabled())
+                localStorageEnabled = true;
+            else
+                localStorageEnabled = false;
+
+            break;
+        }
+
+        case (DomainsDatabase::ENABLED):
+        {
+            // Update the tracker.
+            localStorageEnabled = true;
+
+            break;
+        }
+
+        case (DomainsDatabase::DISABLED):
+        {
+            // Update the tracker.
+            localStorageEnabled = false;
+
+            break;
+        }
+    }
+
+    // Only enable DOM storage if both JavaScript and local storage are enabled.
+    domStorageComboBoxPointer->setEnabled(javaScriptEnabled && localStorageEnabled);
 }
 
 void DomainSettingsDialog::userAgentChanged(const QString &updatedUserAgent) const
 }
 
 void DomainSettingsDialog::userAgentChanged(const QString &updatedUserAgent) const
@@ -627,11 +973,11 @@ void DomainSettingsDialog::userAgentChanged(const QString &updatedUserAgent) con
     // Populate the user agent label.
     populateUserAgentLabel(updatedUserAgent);
 
     // Populate the user agent label.
     populateUserAgentLabel(updatedUserAgent);
 
-    // Update the UI.
-    updateUi();
+    // Update the buttons.
+    updateButtons();
 }
 
 }
 
-void DomainSettingsDialog::zoomFactorComboBoxChanged(const int &newIndex) const
+void DomainSettingsDialog::zoomFactorComboBoxChanged(const int newIndex) const
 {
     // Get the current model index.
     QModelIndex modelIndex = domainsSelectionModelPointer->currentIndex();
 {
     // Get the current model index.
     QModelIndex modelIndex = domainsSelectionModelPointer->currentIndex();
@@ -660,6 +1006,6 @@ void DomainSettingsDialog::zoomFactorComboBoxChanged(const int &newIndex) const
     // Update the status of the custom zoom factor spin box.
     customZoomFactorSpinBoxPointer->setEnabled(newIndex);
 
     // Update the status of the custom zoom factor spin box.
     customZoomFactorSpinBoxPointer->setEnabled(newIndex);
 
-    // Update the UI.
-    updateUi();
+    // Update the buttons.
+    updateButtons();
 }
 }