2 * Copyright 2022-2024 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 "DomainSettingsDialog.h"
23 #include "ui_DomainSettingsDialog.h"
24 #include "databases/DomainsDatabase.h"
26 // Qt toolkit headers.
27 #include <QInputDialog>
28 #include <QMessageBox>
29 #include <QPushButton>
32 // Define the public static int constants.
33 const int DomainSettingsDialog::SHOW_ALL_DOMAINS = 0;
34 const int DomainSettingsDialog::EDIT_DOMAIN = 1;
36 // Construct the class.
37 DomainSettingsDialog::DomainSettingsDialog(QWidget *parentWidgetPointer, const int &startType, const QString &domainName) : QDialog(parentWidgetPointer)
39 // Set the window title.
40 setWindowTitle(i18nc("The domain settings dialog window title", "Domain Settings"));
42 // Set the window modality.
43 setWindowModality(Qt::WindowModality::ApplicationModal);
45 // Instantiate the user agent helper.
46 userAgentHelperPointer = new UserAgentHelper();
48 // Instantiate the domain settings dialog UI.
49 Ui::DomainSettingsDialog domainSettingsDialogUi;
52 domainSettingsDialogUi.setupUi(this);
54 // Get handles for the widgets.
55 domainsListViewPointer = domainSettingsDialogUi.domainsListView;
56 domainSettingsWidgetPointer = domainSettingsDialogUi.domainSettingsWidget;
57 domainNameLineEditPointer = domainSettingsDialogUi.domainNameLineEdit;
58 javaScriptWidgetPointer = domainSettingsDialogUi.javaScriptWidget;
59 javaScriptComboBoxPointer = domainSettingsDialogUi.javaScriptComboBox;
60 javaScriptLabelPointer = domainSettingsDialogUi.javaScriptLabel;
61 localStorageWidgetPointer = domainSettingsDialogUi.localStorageWidget;
62 localStorageComboBoxPointer = domainSettingsDialogUi.localStorageComboBox;
63 localStorageLabelPointer = domainSettingsDialogUi.localStorageLabel;
64 domStorageWidgetPointer = domainSettingsDialogUi.domStorageWidget;
65 domStorageComboBoxPointer = domainSettingsDialogUi.domStorageComboBox;
66 domStorageLabelPointer = domainSettingsDialogUi.domStorageLabel;
67 userAgentWidgetPointer = domainSettingsDialogUi.userAgentWidget;
68 userAgentComboBoxPointer = domainSettingsDialogUi.userAgentComboBox;
69 userAgentLabelPointer = domainSettingsDialogUi.userAgentLabel;
70 zoomFactorWidgetPointer = domainSettingsDialogUi.zoomFactorWidget;
71 zoomFactorComboBoxPointer = domainSettingsDialogUi.zoomFactorComboBox;
72 customZoomFactorSpinBoxPointer = domainSettingsDialogUi.customZoomFactorSpinBox;
73 QPushButton *addDomainButtonPointer = domainSettingsDialogUi.addDomainButton;
74 deleteDomainButtonPointer = domainSettingsDialogUi.deleteDomainButton;
75 QDialogButtonBox *dialogButtonBoxPointer = domainSettingsDialogUi.dialogButtonBox;
76 applyButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::StandardButton::Apply);
77 resetButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::StandardButton::Reset);
79 // Create a table model.
80 domainsTableModelPointer = new QSqlTableModel(nullptr, QSqlDatabase::database(DomainsDatabase::CONNECTION_NAME));
82 // Set the table for the model.
83 domainsTableModelPointer->setTable(DomainsDatabase::DOMAINS_TABLE);
85 // Set the edit strategy to be manual.
86 domainsTableModelPointer->setEditStrategy(QSqlTableModel::EditStrategy::OnManualSubmit);
88 // Sort the output alphabetically.
89 domainsTableModelPointer->setSort(1, Qt::SortOrder::AscendingOrder);
91 // Set the model for the list view.
92 domainsListViewPointer->setModel(domainsTableModelPointer);
94 // Set the visible column to be the domain name.
95 domainsListViewPointer->setModelColumn(1);
97 // Get the domains selection model pointer.
98 domainsSelectionModelPointer = domainsListViewPointer->selectionModel();
100 // Disable editing of the list view.
101 domainsListViewPointer->setEditTriggers(QAbstractItemView::NoEditTriggers);
103 // Read the data from the database and apply it to the table model.
104 domainsTableModelPointer->select();
106 // Get the default palette.
107 defaultPalette = javaScriptWidgetPointer->palette();
109 // Populate the highlighted palette.
110 highlightedPalette = defaultPalette;
112 // Get the default highlight color.
113 QColor highlightColor = defaultPalette.color(QPalette::Highlight);
115 // Set the highlight color to be partially transparent.
116 highlightColor.setAlpha(64);
118 // Set highlighted background color.
119 highlightedPalette.setColor(QPalette::Window, highlightColor);
121 // Setup the dialog according to the start type.
124 case SHOW_ALL_DOMAINS:
126 // Select the first entry in the list view.
127 domainsListViewPointer->setCurrentIndex(domainsTableModelPointer->index(0, domainsTableModelPointer->fieldIndex(DomainsDatabase::DOMAIN_NAME)));
134 // Find the index for the new domain. `1` returns the first match.
135 QModelIndexList newDomainIndex = domainsTableModelPointer->match(domainsTableModelPointer->index(0, domainsTableModelPointer->fieldIndex(DomainsDatabase::DOMAIN_NAME)),
136 Qt::DisplayRole, domainName, 1, Qt::MatchWrap);
138 // Move to the new domain.
139 domainsListViewPointer->setCurrentIndex(newDomainIndex[0]);
145 // Populate the domain settings.
146 domainSelected(domainsSelectionModelPointer->currentIndex());
148 // Handle clicks on the domains.
149 connect(domainsListViewPointer, SIGNAL(activated(QModelIndex)), this, SLOT(domainSelected(QModelIndex)));
151 // Process changes to the domain settings.
152 connect(domainNameLineEditPointer, SIGNAL(textEdited(QString)), this, SLOT(domainNameChanged(QString)));
153 connect(javaScriptComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(javaScriptChanged(int)));
154 connect(localStorageComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(localStorageChanged(int)));
155 connect(domStorageComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(domStorageChanged(int)));
156 connect(userAgentComboBoxPointer, SIGNAL(currentTextChanged(QString)), this, SLOT(userAgentChanged(QString)));
157 connect(zoomFactorComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(zoomFactorComboBoxChanged(int)));
158 connect(customZoomFactorSpinBoxPointer, SIGNAL(valueChanged(double)), this, SLOT(customZoomFactorChanged(double)));
160 // Connect the buttons.
161 connect(addDomainButtonPointer, SIGNAL(clicked()), this, SLOT(showAddMessageBox()));
162 connect(deleteDomainButtonPointer, SIGNAL(clicked()), this, SLOT(showDeleteMessageBox()));
163 connect(resetButtonPointer, SIGNAL(clicked()), this, SLOT(reset()));
164 connect(dialogButtonBoxPointer, SIGNAL(accepted()), this, SLOT(ok()));
165 connect(applyButtonPointer, SIGNAL(clicked()), this, SLOT(apply()));
166 connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(cancel()));
168 // Update the DOM storage status.
169 updateDomStorageStatus();
175 void DomainSettingsDialog::apply() const
177 // Get the current index.
178 QModelIndex currentIndex = domainsListViewPointer->currentIndex();
180 // Get the ID of the current index row.
181 QVariant currentId = currentIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::ID)).data();
183 // Submit all pending changes.
184 domainsTableModelPointer->submitAll();
186 // Find the new index for the selected id. The `1` keeps searching after the first match.
187 QModelIndexList newIndexList = domainsTableModelPointer->match(currentIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::ID)), Qt::DisplayRole, currentId,
190 // Select the new index.
191 domainsListViewPointer->setCurrentIndex(newIndexList[0].siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::DOMAIN_NAME)));
196 // Emit the domain settings updated signal.
197 emit domainSettingsUpdated();
200 void DomainSettingsDialog::cancel()
202 // Revert all pending changes.
203 domainsTableModelPointer->revertAll();
209 void DomainSettingsDialog::customZoomFactorChanged(const double &newValue) const
211 // Update the domains table model.
212 domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::CUSTOM_ZOOM_FACTOR)), newValue);
218 void DomainSettingsDialog::domStorageChanged(const int &newIndex) const
220 // Update the domains table model.
221 domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::DOM_STORAGE)), newIndex);
223 // Populate the DOM storage label.
224 populateDomStorageLabel();
230 void DomainSettingsDialog::domainNameChanged(const QString &updatedDomainName) const
232 // Update the domains table model.
233 domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex(), updatedDomainName);
239 void DomainSettingsDialog::domainSelected(const QModelIndex &modelIndex) const
241 // Populate the domain name line edit pointer.
242 domainNameLineEditPointer->setText(modelIndex.data().toString());
244 // Populate the JavaScript combo box.
245 javaScriptComboBoxPointer->setCurrentIndex(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::JAVASCRIPT)).data().toInt());
247 // Populate the local storage combo box.
248 localStorageComboBoxPointer->setCurrentIndex(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::LOCAL_STORAGE)).data().toInt());
250 // Populate the DOM storage combo box.
251 domStorageComboBoxPointer->setCurrentIndex(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::DOM_STORAGE)).data().toInt());
253 // Get the user agent string.
254 QString userAgent = modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::USER_AGENT)).data().toString();
256 // Get the user agent index.
257 int userAgentIndex = UserAgentHelper::getDomainSettingsUserAgentIndex(userAgent);
259 // Set the user agent combo box index.
260 userAgentComboBoxPointer->setCurrentIndex(userAgentIndex);
262 // Set the custom user agent if specified.
263 if (userAgentIndex == -1) userAgentComboBoxPointer->setCurrentText(userAgent);
265 // Get the zoom factor combo box index.
266 int zoomFactorComboBoxIndex = modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::ZOOM_FACTOR)).data().toInt();
268 // Populate the zoom factor combo box.
269 zoomFactorComboBoxPointer->setCurrentIndex(zoomFactorComboBoxIndex);
271 // Populate the custom zoom factor spin box according to the zoom factor combo box.
272 if (zoomFactorComboBoxIndex == 0) // System default zoom factor is selected.
274 // Display the default zoom factor.
275 customZoomFactorSpinBoxPointer->setValue(Settings::zoomFactor());
277 // Use the default palette.
278 zoomFactorWidgetPointer->setPalette(defaultPalette);
280 else // Custom zoom factor is selected.
282 // Display the custom zoom factor from the domain settings.
283 customZoomFactorSpinBoxPointer->setValue(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::CUSTOM_ZOOM_FACTOR)).data().toDouble());
285 // Use the highlighted palette.
286 zoomFactorWidgetPointer->setPalette(highlightedPalette);
289 // Set the initial status of the custom zoom factor spin box.
290 customZoomFactorSpinBoxPointer->setEnabled(zoomFactorComboBoxIndex);
292 // Populate the labels.
293 populateJavaScriptLabel();
294 populateLocalStorageLabel();
295 populateDomStorageLabel();
296 populateUserAgentLabel(userAgentComboBoxPointer->currentText());
302 void DomainSettingsDialog::javaScriptChanged(const int &newIndex) const
304 // Update the domains table model.
305 domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::JAVASCRIPT)), newIndex);
307 // Populate the JavaScript label.
308 populateJavaScriptLabel();
310 // Update the DOM storage status.
311 updateDomStorageStatus();
317 void DomainSettingsDialog::localStorageChanged(const int &newIndex) const
319 // Update the domains table model.
320 domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::LOCAL_STORAGE)), newIndex);
322 // Populate the local storage label.
323 populateLocalStorageLabel();
325 // Update the DOM storage status.
326 updateDomStorageStatus();
332 void DomainSettingsDialog::ok()
334 // Submit all pending changes.
335 domainsTableModelPointer->submitAll();
337 // Emit the domain settings updated signal.
338 emit domainSettingsUpdated();
344 void DomainSettingsDialog::populateDomStorageLabel() const
346 // Populate the label according to the currently selected index.
347 switch (domStorageComboBoxPointer->currentIndex())
349 case (DomainsDatabase::SYSTEM_DEFAULT):
351 // Set the text according to the system default.
352 if (Settings::domStorageEnabled())
353 domStorageLabelPointer->setText(i18nc("Domain settings DOM storage label.", "DOM storage enabled"));
355 domStorageLabelPointer->setText(i18nc("Domain settings DOM storage label.", "DOM storage disabled"));
357 // Reset the palette.
358 domStorageWidgetPointer->setPalette(defaultPalette);
363 case (DomainsDatabase::ENABLED):
365 // Set the enabled text in bold.
366 domStorageLabelPointer->setText(i18nc("Domain settings DOM storage label. The <b> tags should be retained.", "<b>DOM storage enabled</b>"));
369 domStorageWidgetPointer->setPalette(highlightedPalette);
374 case (DomainsDatabase::DISABLED):
376 // Set the disabled text in bold.
377 domStorageLabelPointer->setText(i18nc("Domain settings DOM storage label. The <b> tags should be retained.", "<b>DOM storage disabled</b>"));
380 domStorageWidgetPointer->setPalette(highlightedPalette);
387 void DomainSettingsDialog::populateJavaScriptLabel() const
389 // Populate the label according to the currently selected index.
390 switch (javaScriptComboBoxPointer->currentIndex())
392 case (DomainsDatabase::SYSTEM_DEFAULT):
394 // Set the text according to the system default.
395 if (Settings::javaScriptEnabled())
396 javaScriptLabelPointer->setText(i18nc("Domain settings JavaScript label.", "JavaScript enabled"));
398 javaScriptLabelPointer->setText(i18nc("Domain settings JavaScript label.", "JavaScript disabled"));
400 // Reset the palette.
401 javaScriptWidgetPointer->setPalette(defaultPalette);
406 case (DomainsDatabase::ENABLED):
408 // Set the enabled text in bold.
409 javaScriptLabelPointer->setText(i18nc("Domain settings JavaScript label. The <b> tags should be retained.", "<b>JavaScript enabled</b>"));
412 javaScriptWidgetPointer->setPalette(highlightedPalette);
417 case (DomainsDatabase::DISABLED):
419 // Set the disabled text in bold.
420 javaScriptLabelPointer->setText(i18nc("Domain settings JavaScript label. The <b> tags should be retained.", "<b>JavaScript disabled</b>"));
423 javaScriptWidgetPointer->setPalette(highlightedPalette);
430 void DomainSettingsDialog::populateLocalStorageLabel() const
432 // Populate the label according to the currently selected index.
433 switch (localStorageComboBoxPointer->currentIndex())
435 case (DomainsDatabase::SYSTEM_DEFAULT):
437 // Set the text according to the system default.
438 if (Settings::localStorageEnabled())
439 localStorageLabelPointer->setText(i18nc("Domain settings local storage label.", "Local storage enabled"));
441 localStorageLabelPointer->setText(i18nc("Domain settings local storage label.", "Local storage disabled"));
443 // Reset the palette.
444 localStorageWidgetPointer->setPalette(defaultPalette);
449 case (DomainsDatabase::ENABLED):
451 // Set the enabled text in bold.
452 localStorageLabelPointer->setText(i18nc("Domain settings local storage label. The <b> tabs should be retained.", "<b>Local storage enabled</b>"));
455 localStorageWidgetPointer->setPalette(highlightedPalette);
460 case (DomainsDatabase::DISABLED):
462 // Set the disabled text in bold.
463 localStorageLabelPointer->setText(i18nc("Domain settings local storage label. The <b> tags should be retained.", "<b>Local storage disabled</b>"));
466 localStorageWidgetPointer->setPalette(highlightedPalette);
474 void DomainSettingsDialog::populateUserAgentLabel(const QString &userAgentName) const
476 // Populate the label according to the type.
477 if (userAgentName == userAgentHelperPointer->SYSTEM_DEFAULT_TRANSLATED)
479 // Display the system default user agent name.
480 userAgentLabelPointer->setText(userAgentHelperPointer->getTranslatedUserAgentNameFromDatabaseName(Settings::userAgent()));
482 // Reset the palette.
483 userAgentWidgetPointer->setPalette(defaultPalette);
487 // Display the user agent name in bold.
488 userAgentLabelPointer->setText("<strong>" + userAgentName + "</strong>");
491 userAgentWidgetPointer->setPalette(highlightedPalette);
495 void DomainSettingsDialog::reset() const
497 // Cancel all pending changes.
498 domainsTableModelPointer->revertAll();
500 // Repopulate the domain settings.
501 domainSelected(domainsListViewPointer->currentIndex());
507 void DomainSettingsDialog::showAddMessageBox()
509 // Create an OK flag.
512 // Display a dialog to request the new domain name from the user.
513 QString newDomainName = QInputDialog::getText(this, i18nc("Add domain dialog title", "Add Domain"),
514 i18nc("Add domain message. The \n\n are newline codes that should be retained",
515 "Add a new domain. Doing so will also save any pending changes that have been made to other domains.\n\n"
516 "*. may be prepended to a domain to include all subdomains (eg. *.stoutner.com)."),
517 QLineEdit::Normal, QString(), &okClicked);
519 // Add the new domain if the user clicked OK.
522 // Add the new domain.
523 DomainsDatabase::addDomain(newDomainName);
525 // Submit all pending changes. This reloads the model from the database, getting the new domain added above.
526 domainsTableModelPointer->submitAll();
529 // Find the index for the new domain. `-1` allows for multiple entries to be returned.
530 QModelIndexList newDomainIndex = domainsTableModelPointer->match(domainsTableModelPointer->index(0, domainsTableModelPointer->fieldIndex(DomainsDatabase::DOMAIN_NAME)),
531 Qt::DisplayRole, newDomainName, -1, Qt::MatchWrap);
533 // Move to the new domain. If there are multiple domains with the same name, the new one should be the last in the list.
534 domainsListViewPointer->setCurrentIndex(newDomainIndex[newDomainIndex.size() - 1]);
536 // Populate the domain settings.
537 domainSelected(domainsSelectionModelPointer->currentIndex());
542 // Emit the domain settings updated signal.
543 emit domainSettingsUpdated();
547 void DomainSettingsDialog::showDeleteMessageBox() const
549 // Instantiate a delete dialog message box.
550 QMessageBox deleteDialogMessageBox;
553 deleteDialogMessageBox.setIcon(QMessageBox::Warning);
555 // Set the window title.
556 deleteDialogMessageBox.setWindowTitle(i18nc("Delete domain dialog title", "Delete Domain"));
559 deleteDialogMessageBox.setText(i18nc("Delete domain dialog main message", "Delete the current domain?"));
561 // Set the informative text.
562 deleteDialogMessageBox.setInformativeText(i18nc("Delete domain dialog secondary message", "Doing so will also save any pending changes that have been made to other domains."));
564 // Set the standard buttons.
565 deleteDialogMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
567 // Set the default button.
568 deleteDialogMessageBox.setDefaultButton(QMessageBox::No);
570 // Display the dialog and capture the return value.
571 int returnValue = deleteDialogMessageBox.exec();
573 // Delete the domain if instructed.
574 if (returnValue == QMessageBox::Yes)
576 // Get the current index.
577 QModelIndex currentIndex = domainsListViewPointer->currentIndex();
579 // Delete the current row.
580 domainsTableModelPointer->removeRow(domainsSelectionModelPointer->currentIndex().row());
582 // Submit all pending changes.
583 domainsTableModelPointer->submitAll();
585 // Select the row next to the deleted item if one exists.
586 if (domainsTableModelPointer->rowCount() > 0)
588 // Check the row of the deleted item.
589 if (currentIndex.row() == 0) // The first row was deleted.
591 // Reselect the current index.
592 domainsListViewPointer->setCurrentIndex(currentIndex);
594 else // A subsequent row was deleted.
596 // Select the crow above the deleted itemm.
597 domainsListViewPointer->setCurrentIndex(currentIndex.siblingAtRow(currentIndex.row() - 1));
600 // Populate the domain settings.
601 domainSelected(domainsListViewPointer->currentIndex());
607 // Emit the domain settings updated signal.
608 emit domainSettingsUpdated();
612 void DomainSettingsDialog::updateDomStorageStatus() const
614 // Instantiate tracking variables.
615 bool javaScriptEnabled;
616 bool localStorageEnabled;
618 // Populate the JavaScript tracker.
619 switch (javaScriptComboBoxPointer->currentIndex())
621 case (DomainsDatabase::SYSTEM_DEFAULT):
623 // Update the tracker according to the system default.
624 if (Settings::javaScriptEnabled())
625 javaScriptEnabled = true;
627 javaScriptEnabled = false;
632 case (DomainsDatabase::ENABLED):
634 // Update the tracker.
635 javaScriptEnabled = true;
640 case (DomainsDatabase::DISABLED):
642 // Update the tracker.
643 javaScriptEnabled = false;
649 // Populate the local storage tracker.
650 switch (localStorageComboBoxPointer->currentIndex())
652 case (DomainsDatabase::SYSTEM_DEFAULT):
654 // Update the tracker according to the system default.
655 if (Settings::localStorageEnabled())
656 localStorageEnabled = true;
658 localStorageEnabled = false;
663 case (DomainsDatabase::ENABLED):
665 // Update the tracker.
666 localStorageEnabled = true;
671 case (DomainsDatabase::DISABLED):
673 // Update the tracker.
674 localStorageEnabled = false;
680 // Only enable DOM storage if both JavaScript and local storage are enabled.
681 domStorageComboBoxPointer->setEnabled(javaScriptEnabled && localStorageEnabled);
684 void DomainSettingsDialog::updateUi() const
686 // Update the delete button status.
687 deleteDomainButtonPointer->setEnabled(domainsSelectionModelPointer->hasSelection());
689 // Update the reset button status.
690 resetButtonPointer->setEnabled(domainsTableModelPointer->isDirty());
692 // Update the apply button status.
693 applyButtonPointer->setEnabled(domainsTableModelPointer->isDirty());
695 // Display the domain settings if there is at least one domain.
696 domainSettingsWidgetPointer->setVisible(domainsTableModelPointer->rowCount() > 0);
699 void DomainSettingsDialog::userAgentChanged(const QString &updatedUserAgent) const
701 // Update the domains table model.
702 domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::USER_AGENT)),
703 userAgentHelperPointer->getDatabaseUserAgentNameFromTranslatedName(updatedUserAgent));
705 // Populate the user agent label.
706 populateUserAgentLabel(updatedUserAgent);
712 void DomainSettingsDialog::zoomFactorComboBoxChanged(const int &newIndex) const
714 // Get the current model index.
715 QModelIndex modelIndex = domainsSelectionModelPointer->currentIndex();
717 // Update the domains table model.
718 domainsTableModelPointer->setData(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::ZOOM_FACTOR)), newIndex);
720 // Populate the custom zoom factor spin box according to the zoom factor combo box.
721 if (newIndex == 0) // System default zoom factor is selected.
723 // Display the default zoom factor.
724 customZoomFactorSpinBoxPointer->setValue(Settings::zoomFactor());
726 // Reset the palette.
727 zoomFactorWidgetPointer->setPalette(defaultPalette);
729 else // Custom zoom factor is selected.
731 // Display the custom zoom factor from the domain settings.
732 customZoomFactorSpinBoxPointer->setValue(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::CUSTOM_ZOOM_FACTOR)).data().toDouble());
734 // Use the highlighted palette.
735 zoomFactorWidgetPointer->setPalette(highlightedPalette);
738 // Update the status of the custom zoom factor spin box.
739 customZoomFactorSpinBoxPointer->setEnabled(newIndex);