client: Fix SettingsPage::hasChanged() failure
[quassel.git] / src / uisupport / settingspage.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-2018 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) version 3.                                           *
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  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 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
40 void SettingsPage::setChangedState(bool hasChanged_)
41 {
42     if (hasChanged_ != _changed) {
43         bool old = hasChanged();
44         _changed = hasChanged_;
45         if (hasChanged() != old)
46             emit changed(hasChanged());
47     }
48 }
49
50
51 void SettingsPage::load(QCheckBox *box, bool checked)
52 {
53     box->setProperty("storedValue", checked);
54     box->setChecked(checked);
55 }
56
57
58 bool SettingsPage::hasChanged(QCheckBox *box)
59 {
60     return box->property("storedValue").toBool() != box->isChecked();
61 }
62
63
64 void SettingsPage::load(QComboBox *box, int index)
65 {
66     box->setProperty("storedValue", index);
67     box->setCurrentIndex(index);
68 }
69
70
71 bool SettingsPage::hasChanged(QComboBox *box)
72 {
73     return box->property("storedValue").toInt() != box->currentIndex();
74 }
75
76
77 void SettingsPage::load(QSpinBox *box, int value)
78 {
79     box->setProperty("storedValue", value);
80     box->setValue(value);
81 }
82
83
84 bool SettingsPage::hasChanged(QSpinBox *box)
85 {
86     return box->property("storedValue").toInt() != box->value();
87 }
88 }
89
90
91 /*** Auto child widget handling ***/
92
93 void SettingsPage::initAutoWidgets()
94 {
95     _autoWidgets.clear();
96
97     // find all descendants that should be considered auto widgets
98     // we need to climb the QObject tree recursively
99     findAutoWidgets(this, &_autoWidgets);
100
101     foreach(QObject *widget, _autoWidgets) {
102         if (widget->inherits("ColorButton"))
103             connect(widget, SIGNAL(colorChanged(QColor)), SLOT(autoWidgetHasChanged()));
104         else if (widget->inherits("QAbstractButton") || widget->inherits("QGroupBox"))
105             connect(widget, SIGNAL(toggled(bool)), SLOT(autoWidgetHasChanged()));
106         else if (widget->inherits("QLineEdit") || widget->inherits("QTextEdit"))
107             connect(widget, SIGNAL(textChanged(const QString &)), SLOT(autoWidgetHasChanged()));
108         else if (widget->inherits("QComboBox"))
109             connect(widget, SIGNAL(currentIndexChanged(int)), SLOT(autoWidgetHasChanged()));
110         else if (widget->inherits("QSpinBox"))
111             connect(widget, SIGNAL(valueChanged(int)), SLOT(autoWidgetHasChanged()));
112         else if (widget->inherits("FontSelector"))
113             connect(widget, SIGNAL(fontChanged(QFont)), SLOT(autoWidgetHasChanged()));
114         else
115             qWarning() << "SettingsPage::init(): Unknown autoWidget type" << widget->metaObject()->className();
116     }
117 }
118
119
120 void SettingsPage::findAutoWidgets(QObject *parent, QObjectList *autoList) const
121 {
122     foreach(QObject *child, parent->children()) {
123         if (child->property("settingsKey").isValid())
124             autoList->append(child);
125         findAutoWidgets(child, autoList);
126     }
127 }
128
129
130 QByteArray SettingsPage::autoWidgetPropertyName(QObject *widget) const
131 {
132     QByteArray prop;
133     if (widget->inherits("ColorButton"))
134         prop = "color";
135     else if (widget->inherits("QAbstractButton") || widget->inherits("QGroupBox"))
136         prop = "checked";
137     else if (widget->inherits("QLineEdit") || widget->inherits("QTextEdit"))
138         prop = "text";
139     else if (widget->inherits("QComboBox"))
140         prop = "currentIndex";
141     else if (widget->inherits("QSpinBox"))
142         prop = "value";
143     else if (widget->inherits("FontSelector"))
144         prop = "selectedFont";
145     else
146         qWarning() << "SettingsPage::autoWidgetPropertyName(): Unhandled widget type for" << widget;
147
148     return prop;
149 }
150
151
152 QString SettingsPage::autoWidgetSettingsKey(QObject *widget) const
153 {
154     QString key = widget->property("settingsKey").toString();
155     if (key.isEmpty())
156         return QString("");
157     if (key.startsWith('/'))
158         key.remove(0, 1);
159     else
160         key.prepend(settingsKey() + '/');
161     return key;
162 }
163
164
165 void SettingsPage::autoWidgetHasChanged()
166 {
167     bool changed_ = false;
168     foreach(QObject *widget, _autoWidgets) {
169         QVariant curValue = widget->property(autoWidgetPropertyName(widget));
170         if (!curValue.isValid())
171             qWarning() << "SettingsPage::autoWidgetHasChanged(): Unknown property";
172
173         if (curValue != widget->property("storedValue")) {
174             changed_ = true;
175             break;
176         }
177     }
178
179     if (changed_ != _autoWidgetsChanged) {
180         bool old = hasChanged();
181         _autoWidgetsChanged = changed_;
182         if (hasChanged() != old)
183             emit changed(hasChanged());
184     }
185 }
186
187
188 void SettingsPage::load()
189 {
190     UiSettings s("");
191     foreach(QObject *widget, _autoWidgets) {
192         QString key = autoWidgetSettingsKey(widget);
193         QVariant val;
194         if (key.isEmpty())
195             val = loadAutoWidgetValue(widget->objectName());
196         else
197             val = s.value(key, QVariant());
198         if (!val.isValid())
199             val = widget->property("defaultValue");
200         widget->setProperty(autoWidgetPropertyName(widget), val);
201         widget->setProperty("storedValue", val);
202     }
203     bool old = hasChanged();
204     _autoWidgetsChanged = _changed = false;
205     if (hasChanged() != old)
206         emit changed(hasChanged());
207 }
208
209
210 void SettingsPage::save()
211 {
212     UiSettings s("");
213     foreach(QObject *widget, _autoWidgets) {
214         QString key = autoWidgetSettingsKey(widget);
215         QVariant val = widget->property(autoWidgetPropertyName(widget));
216         widget->setProperty("storedValue", val);
217         if (key.isEmpty())
218             saveAutoWidgetValue(widget->objectName(), val);
219         else
220             s.setValue(key, val);
221     }
222     bool old = hasChanged();
223     _autoWidgetsChanged = _changed = false;
224     if (hasChanged() != old)
225         emit changed(hasChanged());
226 }
227
228
229 void SettingsPage::defaults()
230 {
231     foreach(QObject *widget, _autoWidgets) {
232         QVariant val = widget->property("defaultValue");
233         widget->setProperty(autoWidgetPropertyName(widget), val);
234     }
235     autoWidgetHasChanged();
236 }
237
238
239 QVariant SettingsPage::loadAutoWidgetValue(const QString &widgetName)
240 {
241     qWarning() << "Could not load value for SettingsPage widget" << widgetName;
242     return QVariant();
243 }
244
245
246 void SettingsPage::saveAutoWidgetValue(const QString &widgetName, const QVariant &)
247 {
248     qWarning() << "Could not save value for SettingsPage widget" << widgetName;
249 }