24f3d55943d3dbecfe58514cf612ae3670bf5ad9
[duncan/yast2-qt4.git] / src / QY2Settings.h
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                          contributed Qt classes                      |
10 |                                                    (C) SuSE Linux AG |
11 \----------------------------------------------------------------------/
12
13   File:       QY2Settings.h
14
15   Author:     Stefan Hundhammer <sh@suse.de>
16
17   This is a pure Qt class - it can be used independently of YaST2.
18
19 /-*/
20
21
22 #ifndef QY2Settings_h
23 #define QY2Settings_h
24
25 #include <Qt/qstring.h>
26 #include <Qt/qmap.h>
27 #include <Qt3Support/q3dict.h>
28 #include <qstringlist.h>
29 #include <Qt3Support/q3textstream.h>
30
31 /**
32  * Utility class that handles program settings in .ini file format:
33  *
34  *      key="value"
35  *      key2 = value
36  *      ; comment
37  *      # comment
38  *
39  *      [section-title]
40  *      key = "value"
41  *      ; comment
42  *      key2="value"
43  *      key3 = _( "message that needs to be translated" )
44  *
45  *      [section-title2]
46  *      key="value"
47  *      key2="value"
48  *
49  * key=value pairs appear one on a line each. Leading and trailing whitespace
50  * is disregarded around both key and value. Value should be quoted (but
51  * doesn't need to). Quotes in value are escaped with \".
52  **/
53 class QY2Settings
54 {
55 public:
56
57     enum AccessMode
58     {
59         ReadOnly,
60         ReadWrite,
61         WriteOnly
62     };
63
64     /**
65      * Constructor. Reads settings from the specified file.
66      *
67      * Use readError() or readOk() afterwards to check for read errors.
68      **/
69     QY2Settings( const QString & fileName, AccessMode accessMode=ReadOnly );
70
71     /**
72      * Destructor.
73      *
74      * Writes any pending changes back to the file if there are any left
75      * if accessMode() is ReadWrite or WriteOnly.
76      **/
77     ~QY2Settings();
78
79     /**
80      * Returns 'true' if the settings couldn't be read from the file specified
81      * in the constructor.
82      **/
83     bool readError() const { return _readError; }
84
85     /**
86      * Returns 'true' if the settings were read without problems from the file
87      * specified in the constructor. This is simply the opposite of
88      * readError().
89      **/
90     bool readOk() const { return ! _readError; }
91
92     /**
93      * Select the specified section in the settings for subsequent get()
94      * calls. Until is used, the unnamed default section is used.
95      *
96      * In the settings file, a section is marked with
97      *
98      * [section-title]
99      *
100      * Using a null string (QString::null) switches back to the unnamed default
101      * section.
102      *
103      * Returns 'true' upon success, 'false' if there is no such section (in
104      * which case the unnamed default section will be selected).
105      **/
106     bool selectSection( const QString & section );
107
108     /**
109      * Select the default (unnamed) section for subsequent get() calls.
110      * This is the default unless selectSection() was called.
111      **/
112     void selectDefaultSection();
113
114     /**
115      * Returns the name of the current section or QString::null if the default
116      * section is used.
117      **/
118     QString currentSection() const { return _currentSectionName; }
119
120     /**
121      * Returns a list of all sections.
122      * 'includeUnnamed' specifies if the unnamed default section should be
123      * included in the list.
124      * The list sort order is undefined.
125      **/
126     QStringList sections( bool includeUnnamed = false ) const;
127
128     /**
129      * Returns the value for the specified key in the current section.
130      * If there is no such key, the specified fallback value is returned.
131      **/
132     QString get( const QString & key,
133                  const QString & fallback = "") const;
134
135     /**
136      * Same as get() with fallback always an empty string
137      **/
138     QString operator[] ( const QString & key );
139
140     /**
141      * Checks if the current section has the specified key.
142      **/
143     bool hasKey( const QString & key );
144
145     /**
146      * Returns a list of all keys in the current section.
147      * The list sort order is undefined.
148      **/
149     QStringList keys() const;
150
151     //
152     // Write access
153     //
154     // All write access functions will fail if the current access mode is not
155     // one of ReadWrite / WriteOnly.
156     //
157
158     /**
159      * Set the specified key to the specified value. Overwrites any existing
160      * key-value pair or adds a new one if there is no such key yet.
161      **/
162     void set( const QString & key, const QString & value );
163
164     /**
165      * Add a section with the specified name. If a section with that name
166      * already exists, it will only be selected and its old contents will
167      * remain untouched.
168      * In any case, this section becomes the current section.
169      **/
170     void addSection( const QString & section );
171
172     /**
173      * Clear all key=value pairs from the current section.
174      **/
175     void clearSection();
176
177     /**
178      * Writes changed settings back to the file specified in the constructor if
179      * accessMode() is ReadWrite or WriteOnly.
180      *
181      * Returns 'true' on success.
182      **/
183     bool save();
184
185     /**
186      * Returns 'true' if there are any changes that need to be written.
187      *
188      * Always returns 'false' if accessMode() is ReadOnly.
189      **/
190     bool pendingChanges() const { return _dirty; }
191
192     /**
193      * Returns the file name.
194      **/
195     QString fileName() const { return _fileName; }
196
197     /**
198      * Returns the access mode - one of ReadOnly, ReadWrite, WriteOnly.
199      **/
200     AccessMode accessMode() const { return _accessMode; }
201
202
203 protected:
204
205     class Section: public QMap<QString, QString>
206     {
207     public:
208         Section( const QString & name )
209             : QMap<QString, QString>()
210             , _name( name )
211             {}
212         QString name() const { return _name; }
213
214     protected:
215
216         QString _name;
217     };
218
219
220
221     /**
222      * Initialize the section data
223      **/
224     void initSections();
225
226     /**
227      * Read the settings file. Sets _readError depending on success or failure.
228      * Returns 'true' upon success.
229      **/
230     bool load();
231
232     /**
233      * Save one section to a stream
234      **/
235     void saveSection( Q3TextStream & stream, Section * section );
236
237
238     //
239     // Data members
240     //
241
242     QString             _fileName;
243     AccessMode          _accessMode;
244     bool                _readError;
245     QString             _currentSectionName;
246     Section *           _currentSection;
247     bool                _dirty;
248
249     Section *           _defaultSection;
250     Q3Dict<Section>     _sections;
251
252     typedef Q3DictIterator<Section>     SectionIterator;
253 };
254
255 #endif // QY2Settings_h