1 | /*************************************************************************** |
2 | * Copyright (C) 2005-2014 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 | #ifndef _SETTINGSPAGE_H_ |
22 | #define _SETTINGSPAGE_H_ |
23 | |
24 | #include <QWidget> |
25 | |
26 | class QCheckBox; |
27 | class QComboBox; |
28 | class QSpinBox; |
29 | |
30 | //! A SettingsPage is a page in the settings dialog. |
31 | /** The SettingsDlg provides suitable standard buttons, such as Ok, Apply, Cancel, Restore Defaults and Reset. |
32 | * Some pages might also be used in standalone dialogs or other containers. A SettingsPage provides suitable |
33 | * slots and signals to allow interaction with the container. |
34 | * |
35 | * A derived class needs to keep track of its changed state. Whenever a child widget changes, it needs to be |
36 | * compared to its value in permanent storage, and the changed state updated accordingly by calling setChangedState(). |
37 | * For most standard widgets, SettingsPage can do this automatically if desired. Such a child widget needs to have |
38 | * a dynamic property \c settingsKey that maps to the key in the client configuration file. This key is appended |
39 | * to settingsKey(), which must be set to a non-null value in a derived class. If the widget's key starts with '/', |
40 | * its key is treated as a global path starting from the root, rather than from settingsKey(). |
41 | * A second dynamic property \c defaultValue can be defined in child widgets as well. |
42 | * |
43 | * For widgets requiring special ways for storing and saving, define the property settingsKey and leave it empty. In this |
44 | * case, the methods saveAutoWidgetValue() and loadAutoWidgetValue() will be called with the widget's objectName as parameter. |
45 | * |
46 | * SettingsPage manages loading, saving, setting to default and setting the changed state for all automatic child widgets. |
47 | * Derived classes must be sure to call initAutoWidgets() *after* setupUi(); they also need to call the baseclass implementations |
48 | * of load(), save() and defaults() (preferably at the end of the derived function, since they call setChangedState(false)). |
49 | * |
50 | * The following widgets can be handled for now: |
51 | * - QGroupBox (isChecked()) |
52 | * - QAbstractButton (isChecked(), e.g. for QCheckBox and QRadioButton) |
53 | * - QLineEdit, QTextEdit (text()) |
54 | * - QComboBox (currentIndex()) |
55 | * - QSpinBox (value()) |
56 | */ |
57 | class SettingsPage : public QWidget |
58 | { |
59 | Q_OBJECT |
60 | |
61 | public: |
62 | SettingsPage(const QString &category, const QString &name, QWidget *parent = 0); |
63 | virtual ~SettingsPage() {}; |
64 | |
65 | //! The category of this settings page. |
66 | inline virtual QString category() const { return _category; } |
67 | |
68 | //! The title of this settings page. |
69 | inline virtual QString title() const { return _title; } |
70 | |
71 | //! Whether the settingspage needs a core connection to be selectable |
72 | /** This is a hint for the settingspage dialog. Do not rely on the settingspage not being |
73 | * visible if disconnected, and care about disabling it yourself. |
74 | */ |
75 | inline virtual bool needsCoreConnection() const { return false; } |
76 | |
77 | //! The key this settings page stores its values under |
78 | /** This needs to be overriden to enable automatic loading/saving/hasChanged checking of widgets. |
79 | * The child widgets' values will be stored in client settings under this key. Every widget that |
80 | * should be automatically handled needs to have a \c settingsKey property set, and should also provide |
81 | * a \c defaultValue property. |
82 | * You can return an empty string (as opposed to a null string) to use the config root as a base, and |
83 | * you can override this key for individual widgets by prefixing their SettingsKey with /. |
84 | */ |
85 | inline virtual QString settingsKey() const { return QString(); } |
86 | |
87 | //! Derived classes need to define this and return true if they have default settings. |
88 | /** If this method returns true, the "Restore Defaults" button in the SettingsDlg is |
89 | * enabled. You also need to provide an implementation of defaults() then. |
90 | * |
91 | * The default implementation returns false. |
92 | */ |
93 | inline virtual bool hasDefaults() const { return false; } |
94 | |
95 | //! Check if there are changes in the page, compared to the state saved in permanent storage. |
96 | inline bool hasChanged() const { return _changed || _autoWidgetsChanged; } |
97 | |
98 | //! Called immediately before save() is called. |
99 | /** Derived classes should return false if saving is not possible (e.g. the current settings are invalid). |
100 | * \return false, if the SettingsPage cannot be saved in its current state. |
101 | */ |
102 | inline virtual bool aboutToSave() { return true; } |
103 | |
104 | //! sets checked state depending on \checked and stores the value for later comparision |
105 | static void load(QCheckBox *box, bool checked); |
106 | static bool hasChanged(QCheckBox *box); |
107 | static void load(QComboBox *box, int index); |
108 | static bool hasChanged(QComboBox *box); |
109 | static void load(QSpinBox *box, int value); |
110 | static bool hasChanged(QSpinBox *box); |
111 | |
112 | public slots: |
113 | //! Save settings to permanent storage. |
114 | /** This baseclass implementation saves the autoWidgets, so be sure to call it if you use |
115 | * this feature in your settingsPage! |
116 | */ |
117 | virtual void save(); |
118 | |
119 | //! Load settings from permanent storage, overriding any changes the user might have made in the dialog. |
120 | /** This baseclass implementation loads the autoWidgets, so be sure to call it if you use |
121 | * this feature in your settingsPage! |
122 | */ |
123 | virtual void load(); |
124 | |
125 | //! Restore defaults, overriding any changes the user might have made in the dialog. |
126 | /** This baseclass implementation loads the defaults of the autoWidgets (if available), so be sure |
127 | * to call it if you use this feature in your settingsPage! |
128 | */ |
129 | virtual void defaults(); |
130 | |
131 | protected slots: |
132 | //! Calling this slot is equivalent to calling setChangedState(true). |
133 | inline void changed() { setChangedState(true); } |
134 | |
135 | //! This should be called whenever the widget state changes from unchanged to change or the other way round. |
136 | void setChangedState(bool hasChanged = true); |
137 | |
138 | protected: |
139 | void initAutoWidgets(); |
140 | virtual QVariant loadAutoWidgetValue(const QString &widgetName); |
141 | virtual void saveAutoWidgetValue(const QString &widgetName, const QVariant &value); |
142 | |
143 | signals: |
144 | //! Emitted whenever the widget state changes. |
145 | void changed(bool hasChanged); |
146 | |
147 | private slots: |
148 | // for auto stuff |
149 | void autoWidgetHasChanged(); |
150 | |
151 | private: |
152 | void findAutoWidgets(QObject *parent, QObjectList *widgetList) const; |
153 | QByteArray autoWidgetPropertyName(QObject *widget) const; |
154 | QString autoWidgetSettingsKey(QObject *widget) const; |
155 | |
156 | QString _category, _title; |
157 | bool _changed, _autoWidgetsChanged; |
158 | QObjectList _autoWidgets; |
159 | }; |
160 | |
161 | |
162 | #endif |
163 | |