blob: 8fa3f04c6d24d95b522f7d2cf04e137bc36d7f7b [file] [log] [blame]
DRC2ff39b82011-07-28 08:38:59 +00001//
2// "$Id: Fl_Preferences.H 7949 2010-12-05 00:38:16Z greg.ercolano $"
3//
4// Preferences .
5//
6// Copyright 2002-2010 by Matthias Melcher.
7//
8// This library is free software; you can redistribute it and/or
9// modify it under the terms of the GNU Library General Public
10// License as published by the Free Software Foundation; either
11// version 2 of the License, or (at your option) any later version.
12//
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16// Library General Public License for more details.
17//
18// You should have received a copy of the GNU Library General Public
19// License along with this library; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21// USA.
22//
23// Please report all bugs and problems on the following page:
24//
25// http://www.fltk.org/str.php
26//
27
28/* \file
29 Fl_Preferences class . */
30
31#ifndef Fl_Preferences_H
32# define Fl_Preferences_H
33
34# include <stdio.h>
35# include "Fl_Export.H"
36
37/**
38 \brief Fl_Preferences provides methods to store user
39 settings between application starts.
40
41 It is similar to the
42 Registry on WIN32 and Preferences on MacOS, and provides a
43 simple configuration mechanism for UNIX.
44
45 Fl_Preferences uses a hierarchy to store data. It
46 bundles similar data into groups and manages entries into those
47 groups as name/value pairs.
48
49 Preferences are stored in text files that can be edited
50 manually. The file format is easy to read and relatively
51 forgiving. Preferences files are the same on all platforms. User
52 comments in preference files are preserved. Filenames are unique
53 for each application by using a vendor/application naming
54 scheme. The user must provide default values for all entries to
55 ensure proper operation should preferences be corrupted or not
56 yet exist.
57
58 Entries can be of any length. However, the size of each
59 preferences file should be kept small for performance
60 reasons. One application can have multiple preferences files.
61 Extensive binary data however should be stored in separate
62 files: see getUserdataPath().
63
64 \note Starting with FLTK 1.3, preference databases are expected to
65 be in utf8 encoding. Previous databases were stored in the
66 current chracter set or code page which renders them incompatible
67 for text entries using international characters.
68 */
69class FL_EXPORT Fl_Preferences {
70
71public:
72 /**
73 Define the scope of the preferences.
74 */
75 enum Root {
76 SYSTEM=0, ///< Preferences are used system-wide
77 USER ///< Preferences apply only to the current user
78 };
79
80 /**
81 Every Fl_Preferences-Group has a uniqe ID.
82
83 ID's can be retrieved from an Fl_Preferences-Group and can then be used
84 to create more Fl_Preference references to the same data set, as long as the
85 database remains open.
86 */
87 typedef void *ID;
88
89 static const char *newUUID();
90
91 Fl_Preferences( Root root, const char *vendor, const char *application );
92 Fl_Preferences( const char *path, const char *vendor, const char *application );
93 Fl_Preferences( Fl_Preferences &parent, const char *group );
94 Fl_Preferences( Fl_Preferences *parent, const char *group );
95 Fl_Preferences( Fl_Preferences &parent, int groupIndex );
96 Fl_Preferences( Fl_Preferences *parent, int groupIndex );
97 Fl_Preferences(const Fl_Preferences&);
98 Fl_Preferences( ID id );
99 virtual ~Fl_Preferences();
100
101 /** Return an ID that can later be reused to open more references to this dataset.
102 */
103 ID id() { return (ID)node; }
104
105 /** Remove the group with this ID from a database.
106 */
107 static char remove(ID id_) { return ((Node*)id_)->remove(); }
108
109 /** Return the name of this entry.
110 */
111 const char *name() { return node->name(); }
112
113 /** Return the the full path to this entry.
114 */
115 const char *path() { return node->path(); }
116
117 int groups();
118 const char *group( int num_group );
119 char groupExists( const char *key );
120 char deleteGroup( const char *group );
121 char deleteAllGroups();
122
123 int entries();
124 const char *entry( int index );
125 char entryExists( const char *key );
126 char deleteEntry( const char *entry );
127 char deleteAllEntries();
128
129 char clear();
130
131 char set( const char *entry, int value );
132 char set( const char *entry, float value );
133 char set( const char *entry, float value, int precision );
134 char set( const char *entry, double value );
135 char set( const char *entry, double value, int precision );
136 char set( const char *entry, const char *value );
137 char set( const char *entry, const void *value, int size );
138
139 char get( const char *entry, int &value, int defaultValue );
140 char get( const char *entry, float &value, float defaultValue );
141 char get( const char *entry, double &value, double defaultValue );
142 char get( const char *entry, char *&value, const char *defaultValue );
143 char get( const char *entry, char *value, const char *defaultValue, int maxSize );
144 char get( const char *entry, void *&value, const void *defaultValue, int defaultSize );
145 char get( const char *entry, void *value, const void *defaultValue, int defaultSize, int maxSize );
146
147 int size( const char *entry );
148
149 char getUserdataPath( char *path, int pathlen );
150
151 void flush();
152
153 // char export( const char *filename, Type fileFormat );
154 // char import( const char *filename );
155
156 /**
157 'Name' provides a simple method to create numerical or more complex
158 procedural names for entries and groups on the fly.
159
160 Example: prefs.set(Fl_Preferences::Name("File%d",i),file[i]);.
161
162 See test/preferences.cxx as a sample for writing arrays into preferences.<p>
163 'Name' is actually implemented as a class inside Fl_Preferences. It casts
164 into const char* and gets automatically destroyed after the enclosing call
165 ends.
166 */
167 class FL_EXPORT Name {
168
169 char *data_;
170
171 public:
172 Name( unsigned int n );
173 Name( const char *format, ... );
174
175 /**
176 Return the Name as a "C" string.
177 \internal
178 */
179 operator const char *() { return data_; }
180 ~Name();
181 };
182
183 /** \internal An entry associates a preference name to its corresponding value */
184 struct Entry {
185 char *name, *value;
186 };
187
188private:
189 Fl_Preferences() : node(0), rootNode(0) { }
190 Fl_Preferences &operator=(const Fl_Preferences&);
191
192 static char nameBuffer[128];
193 static char uuidBuffer[40];
194 static Fl_Preferences *runtimePrefs;
195
196 class RootNode;
197
198 class FL_EXPORT Node { // a node contains a list to all its entries
199 // and all means to manage the tree structure
200 Node *child_, *next_;
201 union { // these two are mutually exclusive
202 Node *parent_; // top_ bit clear
203 RootNode *root_; // top_ bit set
204 };
205 char *path_;
206 Entry *entry_;
207 int nEntry_, NEntry_;
208 unsigned char dirty_:1;
209 unsigned char top_:1;
210 unsigned char indexed_:1;
211 // indexing routines
212 Node **index_;
213 int nIndex_, NIndex_;
214 void createIndex();
215 void updateIndex();
216 void deleteIndex();
217 public:
218 static int lastEntrySet;
219 public:
220 Node( const char *path );
221 ~Node();
222 // node methods
223 int write( FILE *f );
224 const char *name();
225 const char *path() { return path_; }
226 Node *find( const char *path );
227 Node *search( const char *path, int offset=0 );
228 Node *childNode( int ix );
229 Node *addChild( const char *path );
230 void setParent( Node *parent );
231 Node *parent() { return top_?0L:parent_; }
232 void setRoot(RootNode *r) { root_ = r; top_ = 1; }
233 RootNode *findRoot();
234 char remove();
235 char dirty();
236 void deleteAllChildren();
237 // entry methods
238 int nChildren();
239 const char *child( int ix );
240 void set( const char *name, const char *value );
241 void set( const char *line );
242 void add( const char *line );
243 const char *get( const char *name );
244 int getEntry( const char *name );
245 char deleteEntry( const char *name );
246 void deleteAllEntries();
247 int nEntry() { return nEntry_; }
248 Entry &entry(int i) { return entry_[i]; }
249 };
250 friend class Node;
251
252 class FL_EXPORT RootNode { // the root node manages file paths and basic reading and writing
253 Fl_Preferences *prefs_;
254 char *filename_;
255 char *vendor_, *application_;
256 public:
257 RootNode( Fl_Preferences *, Root root, const char *vendor, const char *application );
258 RootNode( Fl_Preferences *, const char *path, const char *vendor, const char *application );
259 RootNode( Fl_Preferences * );
260 ~RootNode();
261 int read();
262 int write();
263 char getPath( char *path, int pathlen );
264 };
265 friend class RootNode;
266
267protected:
268 Node *node;
269 RootNode *rootNode;
270};
271
272#endif // !Fl_Preferences_H
273
274//
275// End of "$Id: Fl_Preferences.H 7949 2010-12-05 00:38:16Z greg.ercolano $".
276//