1 // 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 */ 69 class FL_EXPORT Fl_Preferences { 70 71 public: 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 */ id()103 ID id() { return (ID)node; } 104 105 /** Remove the group with this ID from a database. 106 */ remove(ID id_)107 static char remove(ID id_) { return ((Node*)id_)->remove(); } 108 109 /** Return the name of this entry. 110 */ name()111 const char *name() { return node->name(); } 112 113 /** Return the the full path to this entry. 114 */ path()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 188 private: Fl_Preferences()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(); path()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 ); parent()231 Node *parent() { return top_?0L:parent_; } setRoot(RootNode * r)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(); nEntry()247 int nEntry() { return nEntry_; } entry(int i)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 267 protected: 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 // 277