Fixing a bug where the unread messages backlog requester wouldn't
[quassel.git] / src / uisupport / settingspage.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-09 by the Quassel Project                          *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 #include "settingspage.h"
22
23 #include <QCheckBox>
24 #include <QComboBox>
25 #include <QSpinBox>
26 #include <QVariant>
27
28 #include "uisettings.h"
29
30 SettingsPage::SettingsPage(const QString &category, const QString &title, QWidget *parent)
31   : QWidget(parent),
32     _category(category),
33     _title(title),
34     _changed(false),
35     _autoWidgetsChanged(false)
36 {
37 }
38
39 void SettingsPage::setChangedState(bool hasChanged_) {
40   if(hasChanged_ != _changed) {
41     bool old = hasChanged();
42     _changed = hasChanged_;
43     if(hasChanged() != old)
44       emit changed(hasChanged());
45   }
46 }
47
48 void SettingsPage::load(QCheckBox *box, bool checked) {
49   box->setProperty("StoredValue", checked);
50   box->setChecked(checked);
51 }
52
53 bool SettingsPage::hasChanged(QCheckBox *box) {
54   return box->property("StoredValue").toBool() != box->isChecked();
55 }
56
57
58 void SettingsPage::load(QComboBox *box, int index) {
59   box->setProperty("StoredValue", index);
60   box->setCurrentIndex(index);
61 }
62
63 bool SettingsPage::hasChanged(QComboBox *box) {
64   return box->property("StoredValue").toInt() != box->currentIndex();
65 }
66
67 void SettingsPage::load(QSpinBox *box, int value) {
68   box->setProperty("StoredValue", value);
69   box->setValue(value);
70 }
71
72 bool SettingsPage::hasChanged(QSpinBox *box) {
73   return box->property("StoredValue").toInt() != box->value();
74 }
75
76 /*** Auto child widget handling ***/
77
78 void SettingsPage::initAutoWidgets() {
79   _autoWidgets.clear();
80
81   // find all descendants that should be considered auto widgets
82   // we need to climb the QObject tree recursively
83   findAutoWidgets(this, &_autoWidgets);
84
85   foreach(QObject *widget, _autoWidgets) {
86     if(widget->inherits("QAbstractButton") || widget->inherits("QGroupBox"))
87       connect(widget, SIGNAL(toggled(bool)), SLOT(autoWidgetHasChanged()));
88     else if(widget->inherits("QLineEdit") || widget->inherits("QTextEdit"))
89       connect(widget, SIGNAL(textChanged(const QString &)), SLOT(autoWidgetHasChanged()));
90     else if(widget->inherits("QComboBox"))
91       connect(widget, SIGNAL(currentIndexChanged(int)), SLOT(autoWidgetHasChanged()));
92     else if(widget->inherits("QSpinBox"))
93       connect(widget, SIGNAL(valueChanged(int)), SLOT(autoWidgetHasChanged()));
94     else
95       qWarning() << "SettingsPage::init(): Unknown autoWidget type" << widget->metaObject()->className();
96   }
97 }
98
99 void SettingsPage::findAutoWidgets(QObject *parent, QObjectList *autoList) const {
100   foreach(QObject *child, parent->children()) {
101     if(child->property("settingsKey").isValid())
102       autoList->append(child);
103     findAutoWidgets(child, autoList);
104   }
105 }
106
107 QByteArray SettingsPage::autoWidgetPropertyName(QObject *widget) const {
108   QByteArray prop;
109   if(widget->inherits("QAbstractButton") || widget->inherits("QGroupBox"))
110     prop = "checked";
111   else if(widget->inherits("QLineEdit") || widget->inherits("QTextEdit"))
112     prop = "text";
113   else if(widget->inherits("QComboBox"))
114     prop = "currentIndex";
115   else if(widget->inherits("QSpinBox"))
116     prop = "value";
117   else
118     qWarning() << "SettingsPage::autoWidgetPropertyName(): Unhandled widget type for" << widget;
119
120   return prop;
121 }
122
123 QString SettingsPage::autoWidgetSettingsKey(QObject *widget) const {
124   QString key = widget->property("settingsKey").toString();
125   if(key.isEmpty())
126     return QString("");
127   if(key.startsWith('/'))
128     key.remove(0, 1);
129   else
130     key.prepend(settingsKey() + '/');
131   return key;
132 }
133
134 void SettingsPage::autoWidgetHasChanged() {
135   bool changed_ = false;
136   foreach(QObject *widget, _autoWidgets) {
137     QVariant curValue = widget->property(autoWidgetPropertyName(widget));
138     if(!curValue.isValid())
139       qWarning() << "SettingsPage::autoWidgetHasChanged(): Unknown property";
140
141     if(curValue != widget->property("storedValue")) {
142       changed_ = true;
143       break;
144     }
145   }
146
147   if(changed_ != _autoWidgetsChanged) {
148     bool old = hasChanged();
149     _autoWidgetsChanged = changed_;
150     if(hasChanged() != old)
151       emit changed(hasChanged());
152   }
153 }
154
155 void SettingsPage::load() {
156   UiSettings s("");
157   foreach(QObject *widget, _autoWidgets) {
158     QString key = autoWidgetSettingsKey(widget);
159     QVariant val;
160     if(key.isEmpty())
161       val = loadAutoWidgetValue(widget->objectName());
162     else
163       val = s.value(key, QVariant());
164     if(!val.isValid())
165       val = widget->property("defaultValue");
166     widget->setProperty(autoWidgetPropertyName(widget), val);
167     widget->setProperty("storedValue", val);
168   }
169   bool old = hasChanged();
170   _autoWidgetsChanged = _changed = false;
171   if(hasChanged() != old)
172     emit changed(hasChanged());
173 }
174
175 void SettingsPage::save() {
176   UiSettings s("");
177   foreach(QObject *widget, _autoWidgets) {
178     QString key = autoWidgetSettingsKey(widget);
179     QVariant val = widget->property(autoWidgetPropertyName(widget));
180     widget->setProperty("storedValue", val);
181     if(key.isEmpty())
182       saveAutoWidgetValue(widget->objectName(), val);
183     else
184       s.setValue(key, val);
185   }
186   bool old = hasChanged();
187   _autoWidgetsChanged = _changed = false;
188   if(hasChanged() != old)
189     emit changed(hasChanged());
190 }
191
192 void SettingsPage::defaults() {
193   foreach(QObject *widget, _autoWidgets) {
194     QVariant val = widget->property("defaultValue");
195     widget->setProperty(autoWidgetPropertyName(widget), val);
196   }
197   autoWidgetHasChanged();
198 }
199
200 QVariant SettingsPage::loadAutoWidgetValue(const QString &widgetName) {
201   qWarning() << "Could not load value for SettingsPage widget" << widgetName;
202   return QVariant();
203 }
204
205 void SettingsPage::saveAutoWidgetValue(const QString &widgetName, const QVariant &) {
206   qWarning() << "Could not save value for SettingsPage widget" << widgetName;
207 }
208