qtui: Properly fix the SettingsDlg layout
[quassel.git] / src / qtui / settingsdlg.cpp
index b5fc125..d049286 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2005-08 by the Quassel Project                          *
+ *   Copyright (C) 2005-2018 by the Quassel Project                        *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
  ***************************************************************************/
 
+#include <QIcon>
+#include <QMessageBox>
+#include <QPushButton>
+
 #include "settingsdlg.h"
 
-SettingsDlg::SettingsDlg(QWidget *parent) : QDialog(parent) {
-  ui.setupUi(this);
-  _currentPage = 0;
+#include "client.h"
+
+SettingsDlg::SettingsDlg(QWidget *parent)
+    : QDialog(parent),
+    _currentPage(0)
+{
+    ui.setupUi(this);
+    setModal(true);
+    setAttribute(Qt::WA_DeleteOnClose, true);
+    setWindowIcon(QIcon::fromTheme("configure"));
 
-  //recommendedSize = layout()->minimumSize();
+    updateGeometry();
 
-  // make the scrollarea behave sanely
-  ui.settingsFrame->setWidgetResizable(true);
-  ui.settingsFrame->setWidget(ui.settingsStack);
+    ui.settingsTree->setRootIsDecorated(false);
 
-  updateGeometry();
+    connect(ui.settingsTree, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelected()));
+    connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(buttonClicked(QAbstractButton *)));
 
-  ui.settingsTree->setRootIsDecorated(false);
+    connect(Client::instance(), SIGNAL(coreConnectionStateChanged(bool)), SLOT(coreConnectionStateChanged()));
 
-  connect(ui.settingsTree, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelected()));
-  connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(buttonClicked(QAbstractButton *)));
+    setButtonStates();
 }
 
-/*
-QSize SettingsDlg::sizeHint() const {
-  return recommendedSize;
+
+void SettingsDlg::coreConnectionStateChanged()
+{
+    for (int i = 0; i < ui.settingsTree->topLevelItemCount(); i++) {
+        QTreeWidgetItem *catItem = ui.settingsTree->topLevelItem(i);
+        for (int j = 0; j < catItem->childCount(); j++) {
+            QTreeWidgetItem *item = catItem->child(j);
+            setItemState(item);
+        }
+        setItemState(catItem);
+    }
 }
-*/
 
-SettingsPage *SettingsDlg::currentPage() const {
-  return _currentPage;
+
+void SettingsDlg::setItemState(QTreeWidgetItem *item)
+{
+    SettingsPage *sp = qobject_cast<SettingsPage *>(item->data(0, SettingsPageRole).value<QObject *>());
+    Q_ASSERT(sp);
+    bool disabledDueToConnection = !Client::isConnected() && sp->needsCoreConnection();
+    bool disabledDueToOwnChoice = !sp->isSelectable();
+    item->setDisabled(disabledDueToConnection || disabledDueToOwnChoice);
 }
 
-void SettingsDlg::registerSettingsPage(SettingsPage *sp) {
-  sp->setParent(ui.settingsStack);
-  ui.settingsStack->addWidget(sp);
-  //recommendedSize = recommendedSize.expandedTo(sp->sizeHint());
-  //updateGeometry();
-  connect(sp, SIGNAL(changed(bool)), this, SLOT(setButtonStates()));
-
-  QTreeWidgetItem *cat;
-  QList<QTreeWidgetItem *> cats = ui.settingsTree->findItems(sp->category(), Qt::MatchExactly);
-  if(!cats.count()) {
-    cat = new QTreeWidgetItem(ui.settingsTree, QStringList(sp->category()));
-    cat->setExpanded(true);
-    cat->setFlags(Qt::ItemIsEnabled);
-  } else cat = cats[0];
-  QTreeWidgetItem *item = new QTreeWidgetItem(cat, QStringList(sp->title()));
-  treeItems[sp] = item;
-  pages[QString("%1$%2").arg(sp->category(), sp->title())] = sp;
-  sp->load();
-  // TESTING
-  selectPage(sp->category(), sp->title());
+
+void SettingsDlg::registerSettingsPage(SettingsPage *sp)
+{
+    sp->setParent(ui.settingsStack);
+    ui.settingsStack->addWidget(sp);
+
+    connect(sp, SIGNAL(changed(bool)), this, SLOT(setButtonStates()));
+
+    QTreeWidgetItem *cat;
+    QList<QTreeWidgetItem *> cats = ui.settingsTree->findItems(sp->category(), Qt::MatchExactly);
+    if (!cats.count()) {
+        cat = new QTreeWidgetItem(ui.settingsTree, QStringList(sp->category()));
+        cat->setExpanded(true);
+        cat->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
+    }
+    else {
+        cat = cats[0];
+    }
+
+    QTreeWidgetItem *item;
+    if (sp->title().isEmpty())
+        item = cat;
+    else
+        item = new QTreeWidgetItem(cat, QStringList(sp->title()));
+
+    item->setData(0, SettingsPageRole, QVariant::fromValue<QObject *>(sp));
+    pageIsLoaded[sp] = false;
+    if (!ui.settingsTree->selectedItems().count())
+        ui.settingsTree->setCurrentItem(item);
+
+    setItemState(item);
 }
 
-void SettingsDlg::selectPage(const QString &cat, const QString &title) {
-  SettingsPage *sp = pages[QString("%1$%2").arg(cat, title)];
-  if(!sp) {
-    _currentPage = 0;
-    ui.settingsStack->setCurrentIndex(0);
-    ui.settingsTree->setCurrentItem(0);
-    return;
-  }
-  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);
-    ui.settingsStack->setMinimumSize(sp->minimumSizeHint());  // we don't want our page shrinked, use scrollbars instead...
-    _currentPage = sp;
-  }
-  ui.settingsTree->setCurrentItem(treeItems[sp]);
-  setButtonStates();
+
+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()) {
+        if (sp->title().isEmpty()) {
+            ui.pageTitle->setText(sp->category());
+            setWindowTitle(tr("Configure %1").arg(sp->category()));
+        }
+        else {
+            ui.pageTitle->setText(sp->title());
+            setWindowTitle(tr("Configure %1").arg(sp->title()));
+        }
+
+        ui.settingsStack->setCurrentWidget(sp);
+        _currentPage = sp;
+    }
+    setButtonStates();
 }
 
-void SettingsDlg::itemSelected() {
-  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);
-  }
+
+void SettingsDlg::itemSelected()
+{
+    QList<QTreeWidgetItem *> items = ui.settingsTree->selectedItems();
+    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::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::setButtonStates()
+{
+    SettingsPage *sp = currentPage();
+    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)) {
+
+void SettingsDlg::buttonClicked(QAbstractButton *button)
+{
+    switch (ui.buttonBox->standardButton(button)) {
     case QDialogButtonBox::Ok:
-      if(currentPage() && currentPage()->hasChanged()) {
-        if(applyChanges()) accept();
-      } else accept();
-      break;
+        if (currentPage() && currentPage()->hasChanged()) {
+            if (applyChanges()) accept();
+        }
+        else accept();
+        break;
     case QDialogButtonBox::Apply:
-      applyChanges();
-      break;
+        applyChanges();
+        break;
     case QDialogButtonBox::Cancel:
-      undoChanges();
-      reject();
-      break;
+        undoChanges();
+        reject();
+        break;
     case QDialogButtonBox::Reset:
-      reload();
-      break;
+        reload();
+        break;
     case QDialogButtonBox::RestoreDefaults:
-      loadDefaults();
-      break;
+        loadDefaults();
+        break;
     default:
-      break;
-  }
+        break;
+    }
 }
 
-bool SettingsDlg::applyChanges() {
-  if(!currentPage()) return false;
-  if(currentPage()->aboutToSave()) {
-    currentPage()->save();
-    return true;
-  }
-  return false;
+
+bool SettingsDlg::applyChanges()
+{
+    if (!currentPage()) return false;
+    if (currentPage()->aboutToSave()) {
+        currentPage()->save();
+        return true;
+    }
+    return false;
 }
 
-void SettingsDlg::undoChanges() {
-  if(currentPage()) {
-    currentPage()->load();
-  }
+
+void SettingsDlg::undoChanges()
+{
+    if (currentPage()) {
+        currentPage()->load();
+    }
 }
 
-void SettingsDlg::reload() {
-  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::reload()
+{
+    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() {
-  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();
-  }
+
+void SettingsDlg::loadDefaults()
+{
+    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();
+    }
 }