Make settings dialog modal, fixes BR #399
[quassel.git] / src / qtui / settingsdlg.cpp
index 6c7d24a..55e7041 100644 (file)
 
 #include "settingsdlg.h"
 
-SettingsDlg::SettingsDlg(QWidget *parent) : QDialog(parent) {
+SettingsDlg::SettingsDlg(QWidget *parent)
+  : QDialog(parent),
+    _currentPage(0)
+{
+  setModal(true);
   ui.setupUi(this);
-  _currentPage = 0;
 
-  //ui.settingsFrame->setWidgetResizable(true);
-  //ui.settingsFrame->setWidget(ui.settingsStack);
+  updateGeometry();
+
   ui.settingsTree->setRootIsDecorated(false);
 
   connect(ui.settingsTree, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelected()));
   connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(buttonClicked(QAbstractButton *)));
 }
 
-SettingsPage *SettingsDlg::currentPage() const {
-  return _currentPage;
-}
-
 void SettingsDlg::registerSettingsPage(SettingsPage *sp) {
   sp->setParent(ui.settingsStack);
   ui.settingsStack->addWidget(sp);
+
   connect(sp, SIGNAL(changed(bool)), this, SLOT(setButtonStates()));
 
   QTreeWidgetItem *cat;
@@ -47,55 +47,74 @@ void SettingsDlg::registerSettingsPage(SettingsPage *sp) {
     cat = new QTreeWidgetItem(ui.settingsTree, QStringList(sp->category()));
     cat->setExpanded(true);
     cat->setFlags(Qt::ItemIsEnabled);
-  } else cat = cats[0];
-  new QTreeWidgetItem(cat, QStringList(sp->title()));
-  pages[QString("%1$%2").arg(sp->category(), sp->title())] = sp;
-  updateGeometry();
-  // TESTING
-  selectPage(sp->category(), sp->title());
+  } else {
+    cat = cats[0];
+  }
+  QTreeWidgetItem *item = new QTreeWidgetItem(cat, QStringList(sp->title()));
+  item->setData(0, SettingsPageRole, qVariantFromValue<QObject *>(sp));
+  pageIsLoaded[sp] = false;
 }
 
-void SettingsDlg::selectPage(const QString &cat, const QString &title) {
-  SettingsPage *sp = pages[QString("%1$%2").arg(cat, title)];
-  Q_ASSERT(sp); // FIXME allow for invalid settings pages
-  ui.settingsStack->setCurrentWidget(sp);
-  _currentPage = sp;
+void SettingsDlg::selectPage(SettingsPage *sp) {
+  if(!sp) {
+    _currentPage = 0;
+    ui.settingsStack->setCurrentIndex(0);
+    ui.pageTitle->setText(tr("Settings"));
+    return;
+  }
+
+  if(!pageIsLoaded[sp]) {
+    sp->load();
+    pageIsLoaded[sp] = true;
+  }
+
+  if(sp != currentPage() && currentPage() != 0 && currentPage()->hasChanged()) {
+    int ret = QMessageBox::warning(this, tr("Save changes"),
+                                  tr("There are unsaved changes on the current configuration page. Would you like to apply your changes now?"),
+                                  QMessageBox::Discard|QMessageBox::Save|QMessageBox::Cancel, QMessageBox::Cancel);
+    if(ret == QMessageBox::Save) {
+      if(!applyChanges()) sp = currentPage();
+    } else if(ret == QMessageBox::Discard) {
+      undoChanges();
+    } else sp = currentPage();
+  }
+
+  if(sp != currentPage()) {
+    ui.pageTitle->setText(sp->title());
+    ui.settingsStack->setCurrentWidget(sp);
+    _currentPage = sp;
+  }
   setButtonStates();
 }
 
 void SettingsDlg::itemSelected() {
-  // Check if we have changed anything...
-  // TODO
-
   QList<QTreeWidgetItem *> items = ui.settingsTree->selectedItems();
-  if(!items.count()) {
-    return;
-  } else {
-    QTreeWidgetItem *parent = items[0]->parent();
-    if(!parent) return;
-    QString cat = parent->text(0);
-    QString title = items[0]->text(0);
-    selectPage(cat, title);
-    ui.pageTitle->setText(title);
+  SettingsPage *sp = 0;
+  if(!items.isEmpty()) {
+    sp = qobject_cast<SettingsPage *>(items[0]->data(0, SettingsPageRole).value<QObject *>());
   }
+  selectPage(sp);
 }
 
 void SettingsDlg::setButtonStates() {
   SettingsPage *sp = currentPage();
-  ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(sp && sp->hasChanged());
   ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(sp && sp->hasChanged());
   ui.buttonBox->button(QDialogButtonBox::Reset)->setEnabled(sp && sp->hasChanged());
+  ui.buttonBox->button(QDialogButtonBox::RestoreDefaults)->setEnabled(sp && sp->hasDefaults());
 }
 
 void SettingsDlg::buttonClicked(QAbstractButton *button) {
   switch(ui.buttonBox->standardButton(button)) {
     case QDialogButtonBox::Ok:
-      if(applyChanges()) accept();
+      if(currentPage() && currentPage()->hasChanged()) {
+        if(applyChanges()) accept();
+      } else accept();
       break;
     case QDialogButtonBox::Apply:
       applyChanges();
       break;
     case QDialogButtonBox::Cancel:
+      undoChanges();
       reject();
       break;
     case QDialogButtonBox::Reset:
@@ -118,13 +137,26 @@ bool SettingsDlg::applyChanges() {
   return false;
 }
 
-// TODO add messagebox
+void SettingsDlg::undoChanges() {
+  if(currentPage()) {
+    currentPage()->load();
+  }
+}
+
 void SettingsDlg::reload() {
-  SettingsPage *page = qobject_cast<SettingsPage *>(ui.settingsStack->currentWidget());
-  if(page) page->load();
+  if(!currentPage()) return;
+  int ret = QMessageBox::question(this, tr("Reload Settings"), tr("Do you like to reload the settings, undoing your changes on this page?"),
+                                  QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
+  if(ret == QMessageBox::Yes) {
+    currentPage()->load();
+  }
 }
 
 void SettingsDlg::loadDefaults() {
-  SettingsPage *page = qobject_cast<SettingsPage *>(ui.settingsStack->currentWidget());
-  if(page) page->defaults();
+  if(!currentPage()) return;
+  int ret = QMessageBox::question(this, tr("Restore Defaults"), tr("Do you like to restore the default values for this page?"),
+                                  QMessageBox::RestoreDefaults|QMessageBox::Cancel, QMessageBox::Cancel);
+  if(ret == QMessageBox::RestoreDefaults) {
+    currentPage()->defaults();
+  }
 }