1/*
2 * This file is part of the KDE libraries
3 * Copyright (C) 2003 Benjamin C Meyer (ben+kdelibs at meyerhome dot net)
4 * Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21#ifndef KCONFIGDIALOGMANAGER_H
22#define KCONFIGDIALOGMANAGER_H
23
24#include <kdeui_export.h>
25
26#include <QtCore/QObject>
27#include <QtCore/QHash>
28
29class KCoreConfigSkeleton;
30class KConfigSkeleton;
31class KConfigSkeletonItem;
32class QWidget;
33
34/**
35 * @short Provides a means of automatically retrieving,
36 * saving and resetting KConfigSkeleton based settings in a dialog.
37 *
38 * The KConfigDialogManager class provides a means of automatically
39 * retrieving, saving and resetting basic settings.
40 * It also can emit signals when settings have been changed
41 * (settings were saved) or modified (the user changes a checkbox
42 * from on to off).
43 *
44 * The names of the widgets to be managed have to correspond to the names of the
45 * configuration entries in the KConfigSkeleton object plus an additional
46 * "kcfg_" prefix. For example a widget named "kcfg_MyOption" would be
47 * associated to the configuration entry "MyOption".
48 *
49 * New widgets can be added to the map using the static functions propertyMap() and
50 * changedMap(). Note that you can't just add any class. The class must have a
51 * matching Q_PROPERTY(...) macro defined, and a signal which emitted when the
52 * property changed. Note: by default, the property which defined as "USER true"
53 * is used.
54 *
55 * For example (note that KColorButton is already added and it doesn't need to
56 * manually added):
57 *
58 * kcolorbutton.h defines the following property:
59 * \code
60 * Q_PROPERTY( QColor color READ color WRITE setColor USER true )
61 * \endcode
62 * and signal:
63 * \code
64 * void changed( const QColor &newColor );
65 * \endcode
66 *
67 * To add KColorButton the following code would be inserted in the main:
68 *
69 * \code
70 * KConfigDialogManager::changedMap()->insert("KColorButton", SIGNAL(changed(const QColor &)));
71 * \endcode
72 *
73 * If you want to use a widget's property that is not the USER property,
74 * you can define which property to use in the widget's kcfg_property:
75 * \code
76 * KUrlRequester *myWidget = new KUrlRequester;
77 * myWidget->setProperty("kcfg_property", QByteArray("text"));
78 * \endcode
79 *
80 * Alternatively you can set the kcfg_property using designer.
81 *
82 * @author Benjamin C Meyer <ben+kdelibs at meyerhome dot net>
83 * @author Waldo Bastian <bastian@kde.org>
84 */
85class KDEUI_EXPORT KConfigDialogManager : public QObject {
86
87Q_OBJECT
88
89Q_SIGNALS:
90 /**
91 * One or more of the settings have been saved (such as when the user
92 * clicks on the Apply button). This is only emitted by updateSettings()
93 * whenever one or more setting were changed and consequently saved.
94 */
95 void settingsChanged();
96
97 /**
98 * TODO: Verify
99 * One or more of the settings have been changed.
100 * @param widget - The widget group (pass in via addWidget()) that
101 * contains the one or more modified setting.
102 * @see settingsChanged()
103 */
104 void settingsChanged( QWidget *widget );
105
106 /**
107 * If retrieveSettings() was told to track changes then if
108 * any known setting was changed this signal will be emitted. Note
109 * that a settings can be modified several times and might go back to the
110 * original saved state. hasChanged() will tell you if anything has
111 * actually changed from the saved values.
112 */
113 void widgetModified();
114
115
116public:
117
118 /**
119 * Constructor.
120 * @param parent Dialog widget to manage
121 * @param conf Object that contains settings
122 */
123 KConfigDialogManager(QWidget *parent, KCoreConfigSkeleton *conf);
124
125 /**
126 * Constructor.
127 * @param parent Dialog widget to manage
128 * @param conf Object that contains settings
129 */
130 KConfigDialogManager(QWidget *parent, KConfigSkeleton *conf);
131
132 /**
133 * Destructor.
134 */
135 ~KConfigDialogManager();
136
137 /**
138 * Add additional widgets to manage
139 * @param widget Additional widget to manage, inlcuding all its children
140 */
141 void addWidget(QWidget *widget);
142
143 /**
144 * Returns whether the current state of the known widgets are
145 * different from the state in the config object.
146 */
147 bool hasChanged() const;
148
149 /**
150 * Returns whether the current state of the known widgets are
151 * the same as the default state in the config object.
152 */
153 bool isDefault() const;
154
155 /**
156 * Retrieve the property map
157 */
158 static QHash<QString, QByteArray> *propertyMap();
159
160 /**
161 * Retrieve the widget change map
162 */
163 static QHash<QString, QByteArray> *changedMap();
164
165public Q_SLOTS:
166 /**
167 * Traverse the specified widgets, saving the settings of all known
168 * widgets in the settings object.
169 *
170 * Example use: User clicks Ok or Apply button in a configure dialog.
171 */
172 void updateSettings();
173
174 /**
175 * Traverse the specified widgets, sets the state of all known
176 * widgets according to the state in the settings object.
177 *
178 * Example use: Initialisation of dialog.
179 * Example use: User clicks Reset button in a configure dialog.
180 */
181 void updateWidgets();
182
183 /**
184 * Traverse the specified widgets, sets the state of all known
185 * widgets according to the default state in the settings object.
186 *
187 * Example use: User clicks Defaults button in a configure dialog.
188 */
189 void updateWidgetsDefault();
190
191protected:
192
193 /**
194 * @param trackChanges - If any changes by the widgets should be tracked
195 * set true. This causes the emitting the modified() signal when
196 * something changes.
197 * TODO: @return bool - True if any setting was changed from the default.
198 */
199 void init(bool trackChanges);
200
201 /**
202 * Recursive function that finds all known children.
203 * Goes through the children of widget and if any are known and not being
204 * ignored, stores them in currentGroup. Also checks if the widget
205 * should be disabled because it is set immutable.
206 * @param widget - Parent of the children to look at.
207 * @param trackChanges - If true then tracks any changes to the children of
208 * widget that are known.
209 * @return bool - If a widget was set to something other than its default.
210 */
211 bool parseChildren(const QWidget *widget, bool trackChanges);
212
213 /**
214 * Finds the USER property name using Qt's MetaProperty system, and caches
215 * it in the property map (the cache could be retrieved by propertyMap() ).
216 */
217 QByteArray getUserProperty(const QWidget *widget) const;
218
219 /**
220 * Find the property to use for a widget by querying the kcfg_property
221 * property of the widget. Like a widget can use a property other than the
222 * USER property.
223 * @since 4.3
224 */
225 QByteArray getCustomProperty(const QWidget *widget) const;
226
227 /**
228 * Set a property
229 */
230 void setProperty(QWidget *w, const QVariant &v);
231
232 /**
233 * Retrieve a property
234 */
235 QVariant property(QWidget *w) const;
236
237 /**
238 * Setup secondary widget properties
239 */
240 void setupWidget(QWidget *widget, KConfigSkeletonItem *item);
241
242 /**
243 * Initializes the property maps
244 */
245 static void initMaps();
246
247private:
248 class Private;
249 friend class Private;
250
251 /**
252 * KConfigDialogManager Private class.
253 */
254 Private *const d;
255
256 Q_DISABLE_COPY(KConfigDialogManager)
257};
258
259#endif // KCONFIGDIALOGMANAGER_H
260
261