]> gitweb.stoutner.com Git - PrivacyBrowserPC.git/blob - src/dialogs/DomainSettingsDialog.cpp
Enable downloading of files that require login cookies. https://redmine.stoutner...
[PrivacyBrowserPC.git] / src / dialogs / DomainSettingsDialog.cpp
1 /*
2  * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 // Application headers.
21 #include "DomainSettingsDialog.h"
22 #include "Settings.h"
23 #include "ui_DomainSettingsDialog.h"
24 #include "databases/DomainsDatabase.h"
25
26 // Qt toolkit headers.
27 #include <QInputDialog>
28 #include <QMessageBox>
29 #include <QPushButton>
30
31 // Define the public static int constants.
32 const int DomainSettingsDialog::SHOW_ALL_DOMAINS = 0;
33 const int DomainSettingsDialog::ADD_DOMAIN = 1;
34 const int DomainSettingsDialog::EDIT_DOMAIN = 2;
35
36 // Construct the class.
37 DomainSettingsDialog::DomainSettingsDialog(const int &startType, const QString &domainName) : QDialog(nullptr)
38 {
39     // Set the window title.
40     setWindowTitle(i18nc("The domain settings dialog window title", "Domain Settings"));
41
42     // Set the window modality.
43     setWindowModality(Qt::WindowModality::ApplicationModal);
44
45     // Instantiate the user agent helper.
46     userAgentHelperPointer = new UserAgentHelper();
47
48     // Instantiate the domain settings dialog UI.
49     Ui::DomainSettingsDialog domainSettingsDialogUi;
50
51     // Setup the UI.
52     domainSettingsDialogUi.setupUi(this);
53
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);
78
79     // Create a table model.
80     domainsTableModelPointer = new QSqlTableModel(nullptr, QSqlDatabase::database(DomainsDatabase::CONNECTION_NAME));
81
82     // Set the table for the model.
83     domainsTableModelPointer->setTable(DomainsDatabase::DOMAINS_TABLE);
84
85     // Set the edit strategy to be manual.
86     domainsTableModelPointer->setEditStrategy(QSqlTableModel::EditStrategy::OnManualSubmit);
87
88     // Sort the output alphabetically.
89     domainsTableModelPointer->setSort(1, Qt::SortOrder::AscendingOrder);
90
91     // Set the model for the list view.
92     domainsListViewPointer->setModel(domainsTableModelPointer);
93
94     // Set the visible column to be the domain name.
95     domainsListViewPointer->setModelColumn(1);
96
97     // Get the domains selection model pointer.
98     domainsSelectionModelPointer = domainsListViewPointer->selectionModel();
99
100     // Disable editing of the list view.
101     domainsListViewPointer->setEditTriggers(QAbstractItemView::NoEditTriggers);
102
103     // Read the data from the database and apply it to the table model.
104     domainsTableModelPointer->select();
105
106     // Get the default palette.
107     defaultPalette = javaScriptWidgetPointer->palette();
108
109     // Populate the highlighted palette.
110     highlightedPalette = defaultPalette;
111
112     // Get the default highlight color.
113     QColor highlightColor = defaultPalette.color(QPalette::Highlight);
114
115     // Set the highlight color to be partially transparent.
116     highlightColor.setAlpha(64);
117
118     // Set highlighted background color.
119     highlightedPalette.setColor(QPalette::Window, highlightColor);
120
121     // Setup the dialog according to the start type.
122     switch (startType)
123     {
124         case SHOW_ALL_DOMAINS:
125         {
126             // Select the first entry in the list view.
127             domainsListViewPointer->setCurrentIndex(domainsTableModelPointer->index(0, domainsTableModelPointer->fieldIndex(DomainsDatabase::DOMAIN_NAME)));
128
129             // Populate the domain settings.
130             domainSelected(domainsSelectionModelPointer->currentIndex());
131
132             break;
133         }
134
135         case ADD_DOMAIN:
136         {
137             // Add the new domain.
138             addDomain(domainName);
139
140             break;
141         }
142
143         case EDIT_DOMAIN:
144         {
145             // Find the index for the new domain.  `1` returns the first match.
146             QModelIndexList newDomainIndex = domainsTableModelPointer->match(domainsTableModelPointer->index(0, domainsTableModelPointer->fieldIndex(DomainsDatabase::DOMAIN_NAME)),
147                                                                              Qt::DisplayRole, domainName, 1, Qt::MatchWrap);
148
149             // Move to the new domain.
150             domainsListViewPointer->setCurrentIndex(newDomainIndex[0]);
151
152             // Populate the domain settings.
153             domainSelected(domainsSelectionModelPointer->currentIndex());
154
155             break;
156         }
157     }
158
159     // Handle clicks on the domains.
160     connect(domainsListViewPointer, SIGNAL(activated(QModelIndex)), this, SLOT(domainSelected(QModelIndex)));
161
162     // Process changes to the domain settings.
163     connect(domainNameLineEditPointer, SIGNAL(textEdited(QString)), this, SLOT(domainNameChanged(QString)));
164     connect(javaScriptComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(javaScriptChanged(int)));
165     connect(localStorageComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(localStorageChanged(int)));
166     connect(domStorageComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(domStorageChanged(int)));
167     connect(userAgentComboBoxPointer, SIGNAL(currentTextChanged(QString)), this, SLOT(userAgentChanged(QString)));
168     connect(zoomFactorComboBoxPointer, SIGNAL(currentIndexChanged(int)), this, SLOT(zoomFactorComboBoxChanged(int)));
169     connect(customZoomFactorSpinBoxPointer, SIGNAL(valueChanged(double)), this, SLOT(customZoomFactorChanged(double)));
170
171     // Connect the buttons.
172     connect(addDomainButtonPointer, SIGNAL(clicked()), this, SLOT(showAddMessageBox()));
173     connect(deleteDomainButtonPointer, SIGNAL(clicked()), this, SLOT(showDeleteMessageBox()));
174     connect(resetButtonPointer, SIGNAL(clicked()), this, SLOT(reset()));
175     connect(dialogButtonBoxPointer, SIGNAL(accepted()), this, SLOT(ok()));
176     connect(applyButtonPointer, SIGNAL(clicked()), this, SLOT(apply()));
177     connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(cancel()));
178
179     // Update the UI.
180     updateUi();
181 }
182
183 void DomainSettingsDialog::addDomain(const QString &domainName) const
184 {
185     // Create a new domain record.
186     QSqlRecord newDomainRecord = QSqlDatabase::database(DomainsDatabase::CONNECTION_NAME).record(DomainsDatabase::DOMAINS_TABLE);
187
188     // Set the values for the new domain.
189     newDomainRecord.setValue(domainsTableModelPointer->fieldIndex(DomainsDatabase::DOMAIN_NAME), domainName);
190     newDomainRecord.setValue(domainsTableModelPointer->fieldIndex(DomainsDatabase::JAVASCRIPT), DomainsDatabase::SYSTEM_DEFAULT);
191     newDomainRecord.setValue(domainsTableModelPointer->fieldIndex(DomainsDatabase::DOM_STORAGE), DomainsDatabase::SYSTEM_DEFAULT);
192     newDomainRecord.setValue(domainsTableModelPointer->fieldIndex(DomainsDatabase::USER_AGENT), UserAgentHelper::SYSTEM_DEFAULT_DATABASE);
193     newDomainRecord.setValue(domainsTableModelPointer->fieldIndex(DomainsDatabase::ZOOM_FACTOR), DomainsDatabase::SYSTEM_DEFAULT);
194     newDomainRecord.setValue(domainsTableModelPointer->fieldIndex(DomainsDatabase::CUSTOM_ZOOM_FACTOR), 1.0);
195
196     // Insert the new domain.  `-1` appends it to the end.
197     domainsTableModelPointer->insertRecord(-1, newDomainRecord);
198
199     // Submit all pending changes.
200     domainsTableModelPointer->submitAll();
201
202     // Find the index for the new domain.  `-1` allows for multiple entries to be returned.
203     QModelIndexList newDomainIndex = domainsTableModelPointer->match(domainsTableModelPointer->index(0, domainsTableModelPointer->fieldIndex(DomainsDatabase::DOMAIN_NAME)),
204                                                                      Qt::DisplayRole, domainName, -1, Qt::MatchWrap);
205
206     // Move to the new domain.  If there are multiple domains with the same name, the new one should be the last in the list.
207     domainsListViewPointer->setCurrentIndex(newDomainIndex[newDomainIndex.size() - 1]);
208
209     // Populate the domain settings.
210     domainSelected(domainsSelectionModelPointer->currentIndex());
211
212     // Update the UI.
213     updateUi();
214 }
215
216 void DomainSettingsDialog::apply() const
217 {
218     // Get the current index.
219     QModelIndex currentIndex = domainsListViewPointer->currentIndex();
220
221     // Get the ID of the current index row.
222     QVariant currentId = currentIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::_ID)).data();
223
224     // Submit all pending changes.
225     domainsTableModelPointer->submitAll();
226
227     // Find the new index for the selected id.  The `1` keeps searching after the first match.
228     QModelIndexList newIndexList = domainsTableModelPointer->match(currentIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::_ID)), Qt::DisplayRole, currentId,
229                                                                    1, Qt::MatchWrap);
230
231     // Select the new index.
232     domainsListViewPointer->setCurrentIndex(newIndexList[0].siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::DOMAIN_NAME)));
233
234     // Update the UI.
235     updateUi();
236
237     // Emit the domain settings updated signal.
238     emit domainSettingsUpdated();
239 }
240
241 void DomainSettingsDialog::cancel()
242 {
243     // Revert all pending changes.
244     domainsTableModelPointer->revertAll();
245
246     // Close the dialog.
247     reject();
248 }
249
250 void DomainSettingsDialog::customZoomFactorChanged(const double &newValue) const
251 {
252     // Update the domains table model.
253     domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::CUSTOM_ZOOM_FACTOR)), newValue);
254
255     // Update the UI.
256     updateUi();
257 }
258
259 void DomainSettingsDialog::domStorageChanged(const int &newIndex) const
260 {
261     // Update the domains table model.
262     domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::DOM_STORAGE)), newIndex);
263
264     // Populate the DOM storage label.
265     populateDomStorageLabel();
266
267     // Update the UI.
268     updateUi();
269 }
270
271 void DomainSettingsDialog::domainNameChanged(const QString &updatedDomainName) const
272 {
273     // Update the domains table model.
274     domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex(), updatedDomainName);
275
276     // Update the UI.
277     updateUi();
278 }
279
280 void DomainSettingsDialog::domainSelected(const QModelIndex &modelIndex) const
281 {
282     // Populate the domain name line edit pointer.
283     domainNameLineEditPointer->setText(modelIndex.data().toString());
284
285     // Populate the JavaScript combo box.
286     javaScriptComboBoxPointer->setCurrentIndex(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::JAVASCRIPT)).data().toInt());
287
288     // Populate the local storage combo box.
289     localStorageComboBoxPointer->setCurrentIndex(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::LOCAL_STORAGE)).data().toInt());
290
291     // Populate the DOM storage combo box.
292     domStorageComboBoxPointer->setCurrentIndex(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::DOM_STORAGE)).data().toInt());
293
294     // Get the user agent string.
295     QString userAgent = modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::USER_AGENT)).data().toString();
296
297     // Get the user agent index.
298     int userAgentIndex = UserAgentHelper::getDomainSettingsUserAgentIndex(userAgent);
299
300     // Set the user agent combo box index.
301     userAgentComboBoxPointer->setCurrentIndex(userAgentIndex);
302
303     // Set the custom user agent if specified.
304     if (userAgentIndex == -1) userAgentComboBoxPointer->setCurrentText(userAgent);
305
306     // Get the zoom factor combo box index.
307     int zoomFactorComboBoxIndex = modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::ZOOM_FACTOR)).data().toInt();
308
309     // Populate the zoom factor combo box.
310     zoomFactorComboBoxPointer->setCurrentIndex(zoomFactorComboBoxIndex);
311
312     // Populate the custom zoom factor spin box according to the zoom factor combo box.
313     if (zoomFactorComboBoxIndex == 0)  // System default zoom factor is selected.
314     {
315         // Display the default zoom factor.
316         customZoomFactorSpinBoxPointer->setValue(Settings::zoomFactor());
317     }
318     else  // Custom zoom factor is selected.
319     {
320         // Display the custom zoom factor from the domain settings.
321         customZoomFactorSpinBoxPointer->setValue(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::CUSTOM_ZOOM_FACTOR)).data().toDouble());
322     }
323
324     // Set the initial status of the custom zoom factor spin box.
325     customZoomFactorSpinBoxPointer->setEnabled(zoomFactorComboBoxIndex);
326
327     // Populate the labels.
328     populateJavaScriptLabel();
329     populateLocalStorageLabel();
330     populateDomStorageLabel();
331     populateUserAgentLabel(userAgentComboBoxPointer->currentText());
332
333     // Update the UI.
334     updateUi();
335 }
336
337 void DomainSettingsDialog::javaScriptChanged(const int &newIndex) const
338 {
339     // Update the domains table model.
340     domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::JAVASCRIPT)), newIndex);
341
342     // Populate the JavaScript label.
343     populateJavaScriptLabel();
344
345     // Update the UI.
346     updateUi();
347 }
348
349 void DomainSettingsDialog::localStorageChanged(const int &newIndex) const
350 {
351     // Update the domains table model.
352     domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::LOCAL_STORAGE)), newIndex);
353
354     // Poplate the local storage label.
355     populateLocalStorageLabel();
356
357     // Update the UI.
358     updateUi();
359 }
360
361 void DomainSettingsDialog::ok()
362 {
363     // Submit all pending changes.
364     domainsTableModelPointer->submitAll();
365
366     // Emit the domain settings updated signal.
367     domainSettingsUpdated();
368
369     // Close the dialog.
370     accept();
371 }
372
373 void DomainSettingsDialog::populateDomStorageLabel() const
374 {
375     // Populate the label according to the currently selected index.
376     switch (domStorageComboBoxPointer->currentIndex())
377     {
378         case (DomainsDatabase::SYSTEM_DEFAULT):
379         {
380             // Set the text according to the system default.
381             if (Settings::domStorageEnabled())
382                 domStorageLabelPointer->setText(i18nc("Domain settings DOM storage label.", "DOM storage enabled"));
383             else
384                 domStorageLabelPointer->setText(i18nc("Domain settings DOM storage label.", "DOM storage disabled"));
385
386             // Reset the palette.
387             domStorageWidgetPointer->setPalette(defaultPalette);
388
389             break;
390         }
391
392         case (DomainsDatabase::DISABLED):
393         {
394             // Set the disabled text in bold.
395             domStorageLabelPointer->setText(i18nc("Domain settings DOM storage label.  The <b> tags should be retained.", "<b>DOM storage disabled</b>"));
396
397             // Set the palette.
398             domStorageWidgetPointer->setPalette(highlightedPalette);
399
400             break;
401         }
402
403         case (DomainsDatabase::ENABLED):
404         {
405             // Set the enabled text in bold.
406             domStorageLabelPointer->setText(i18nc("Domain settings DOM storage label.  The <b> tags should be retained.", "<b>DOM storage enabled</b>"));
407
408             // Set the palette.
409             domStorageWidgetPointer->setPalette(highlightedPalette);
410
411             break;
412         }
413     }
414 }
415
416 void DomainSettingsDialog::populateJavaScriptLabel() const
417 {
418     // Populate the label according to the currently selected index.
419     switch (javaScriptComboBoxPointer->currentIndex())
420     {
421         case (DomainsDatabase::SYSTEM_DEFAULT):
422         {
423             // Set the text according to the system default.
424             if (Settings::javaScriptEnabled())
425                 javaScriptLabelPointer->setText(i18nc("Domain settings JavaScript label.", "JavaScript enabled"));
426             else
427                 javaScriptLabelPointer->setText(i18nc("Domain settings JavaScript label.", "JavaScript disabled"));
428
429             // Reset the palette.
430             javaScriptWidgetPointer->setPalette(defaultPalette);
431
432             break;
433         }
434
435         case (DomainsDatabase::DISABLED):
436         {
437             // Set the disabled text in bold.
438             javaScriptLabelPointer->setText(i18nc("Domain settings JavaScript label.  The <b> tags should be retained.", "<b>JavaScript disabled</b>"));
439
440             // Set the palette.
441             javaScriptWidgetPointer->setPalette(highlightedPalette);
442
443             break;
444         }
445
446         case (DomainsDatabase::ENABLED):
447         {
448             // Set the enabled text in bold.
449             javaScriptLabelPointer->setText(i18nc("Domain settings JavaScript label.  The <b> tags should be retained.", "<b>JavaScript enabled</b>"));
450
451             // Set the palette.
452             javaScriptWidgetPointer->setPalette(highlightedPalette);
453
454             break;
455         }
456     }
457 }
458
459 void DomainSettingsDialog::populateLocalStorageLabel() const
460 {
461     // Populate the label according to the currently selected index.
462     switch (localStorageComboBoxPointer->currentIndex())
463     {
464         case (DomainsDatabase::SYSTEM_DEFAULT):
465         {
466             // Set the text according to the system default.
467             if (Settings::localStorageEnabled())
468                 localStorageLabelPointer->setText(i18nc("Domain settings local storage label.", "Local storage enabled"));
469             else
470                 localStorageLabelPointer->setText(i18nc("Domain settings local storage label.", "Local storage disabled"));
471
472             // Reset the palette.
473             localStorageWidgetPointer->setPalette(defaultPalette);
474
475             break;
476         }
477
478         case (DomainsDatabase::DISABLED):
479         {
480             // Set the disabled text in bold.
481             localStorageLabelPointer->setText(i18nc("Domain settings local storage label.  The <b> tags should be retained.", "<b>Local storage disabled</b>"));
482
483             // Set the palette.
484             localStorageWidgetPointer->setPalette(highlightedPalette);
485
486             break;
487         }
488
489         case (DomainsDatabase::ENABLED):
490         {
491             // Set the enabled text in bold.
492             localStorageLabelPointer->setText(i18nc("Domain settings local storage label.  The <b> tabs should be retained.", "<b>Local storage enabled</b>"));
493
494             // Set the palette.
495             localStorageWidgetPointer->setPalette(highlightedPalette);
496
497             break;
498         }
499     }
500 }
501
502
503 void DomainSettingsDialog::populateUserAgentLabel(const QString &userAgentName) const
504 {
505     // Populate the label according to the type.
506     if (userAgentName == userAgentHelperPointer->SYSTEM_DEFAULT_TRANSLATED)
507     {
508         // Display the system default user agent name.
509         userAgentLabelPointer->setText(userAgentHelperPointer->getTranslatedUserAgentNameFromDatabaseName(Settings::userAgent()));
510
511         // Reset the palette.
512         userAgentWidgetPointer->setPalette(defaultPalette);
513     }
514     else
515     {
516         // Display the user agent name in bold.
517         userAgentLabelPointer->setText("<strong>" + userAgentName + "</strong>");
518
519         // Set the palette.
520         userAgentWidgetPointer->setPalette(highlightedPalette);
521     }
522 }
523
524 void DomainSettingsDialog::reset() const
525 {
526     // Cancel all pending changes.
527     domainsTableModelPointer->revertAll();
528
529     // Repopulate the domain settings.
530     domainSelected(domainsListViewPointer->currentIndex());
531
532     // Update the UI.
533     updateUi();
534 }
535
536 void DomainSettingsDialog::showAddMessageBox()
537 {
538     // Create an OK flag.
539     bool okClicked;
540
541     // Display a dialog to request the new domain name from the user.
542     QString newDomainName = QInputDialog::getText(this, i18nc("Add domain dialog title", "Add Domain"),
543                                                   i18nc("Add domain message.  The \n\n are newline codes that should be retained",
544                                                         "Add a new domain.  Doing so will also save any pending changes that have been made to other domains.\n\n"
545                                                         "*. may be prepended to a domain to include all subdomains (eg. *.stoutner.com)."),
546                                                   QLineEdit::Normal, QString(), &okClicked);
547
548     // Add the new domain if the user clicked OK.
549     if (okClicked) addDomain(newDomainName);
550 }
551
552 void DomainSettingsDialog::showDeleteMessageBox() const
553 {
554     // Instantiate a delete dialog message box.
555     QMessageBox deleteDialogMessageBox;
556
557     // Set the icon.
558     deleteDialogMessageBox.setIcon(QMessageBox::Warning);
559
560     // Set the window title.
561     deleteDialogMessageBox.setWindowTitle(i18nc("Delete domain dialog title", "Delete Domain"));
562
563     // Set the text.
564     deleteDialogMessageBox.setText(i18nc("Delete domain dialog main message", "Delete the current domain?"));
565
566     // Set the informative text.
567     deleteDialogMessageBox.setInformativeText(i18nc("Delete domain dialog secondary message", "Doing so will also save any pending changes that have been made to other domains."));
568
569     // Set the standard buttons.
570     deleteDialogMessageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
571
572     // Set the default button.
573     deleteDialogMessageBox.setDefaultButton(QMessageBox::No);
574
575     // Display the dialog and capture the return value.
576     int returnValue = deleteDialogMessageBox.exec();
577
578     // Delete the domain if instructed.
579     if (returnValue == QMessageBox::Yes)
580     {
581         // Get the current index.
582         QModelIndex currentIndex = domainsListViewPointer->currentIndex();
583
584         // Delete the current row.
585         domainsTableModelPointer->removeRow(domainsSelectionModelPointer->currentIndex().row());
586
587         // Submit all pending changes.
588         domainsTableModelPointer->submitAll();
589
590         // Select the row next to the deleted item if one exists.
591         if (domainsTableModelPointer->rowCount() > 0)
592         {
593             // Check the row of the deleted item.
594             if (currentIndex.row() == 0)  // The first row was deleted.
595             {
596                 // Reselect the current index.
597                 domainsListViewPointer->setCurrentIndex(currentIndex);
598             }
599             else  // A subsequent row was deleted.
600             {
601                 // Select the crow above the deleted itemm.
602                 domainsListViewPointer->setCurrentIndex(currentIndex.siblingAtRow(currentIndex.row() - 1));
603             }
604
605             // Populate the domain settings.
606             domainSelected(domainsListViewPointer->currentIndex());
607         }
608
609         // Update the Ui.
610         updateUi();
611     }
612 }
613
614 void DomainSettingsDialog::updateUi() const
615 {
616     // Update the delete button status.
617     deleteDomainButtonPointer->setEnabled(domainsSelectionModelPointer->hasSelection());
618
619     // Update the reset button status.
620     resetButtonPointer->setEnabled(domainsTableModelPointer->isDirty());
621
622     // Update the apply button status.
623     applyButtonPointer->setEnabled(domainsTableModelPointer->isDirty());
624
625     // Display the domain settings if there is at least one domain.
626     domainSettingsWidgetPointer->setVisible(domainsTableModelPointer->rowCount() > 0);
627 }
628
629 void DomainSettingsDialog::userAgentChanged(const QString &updatedUserAgent) const
630 {
631     // Update the domains table model.
632     domainsTableModelPointer->setData(domainsSelectionModelPointer->currentIndex().siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::USER_AGENT)),
633                                       userAgentHelperPointer->getDatabaseUserAgentNameFromTranslatedName(updatedUserAgent));
634
635     // Populate the user agent label.
636     populateUserAgentLabel(updatedUserAgent);
637
638     // Update the UI.
639     updateUi();
640 }
641
642 void DomainSettingsDialog::zoomFactorComboBoxChanged(const int &newIndex) const
643 {
644     // Get the current model index.
645     QModelIndex modelIndex = domainsSelectionModelPointer->currentIndex();
646
647     // Update the domains table model.
648     domainsTableModelPointer->setData(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::ZOOM_FACTOR)), newIndex);
649
650     // Populate the custom zoom factor spin box according to the zoom factor combo box.
651     if (newIndex == 0)  // System default zoom factor is selected.
652     {
653         // Display the default zoom factor.
654         customZoomFactorSpinBoxPointer->setValue(Settings::zoomFactor());
655
656         // Reset the palette.
657         zoomFactorWidgetPointer->setPalette(defaultPalette);
658     }
659     else  // Custom zoom factor is selected.
660     {
661         // Display the custom zoom factor from the domain settings.
662         customZoomFactorSpinBoxPointer->setValue(modelIndex.siblingAtColumn(domainsTableModelPointer->fieldIndex(DomainsDatabase::CUSTOM_ZOOM_FACTOR)).data().toDouble());
663
664         // Set the palette.
665         zoomFactorWidgetPointer->setPalette(highlightedPalette);
666     }
667
668     // Update the status of the custom zoom factor spin box.
669     customZoomFactorSpinBoxPointer->setEnabled(newIndex);
670
671     // Update the UI.
672     updateUi();
673 }