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