]> git.saurik.com Git - wxWidgets.git/blob - include/wx/fileconf.h
wxDataFormat typedef added
[wxWidgets.git] / include / wx / fileconf.h
1 /*****************************************************************************\
2 * Project: CppLib: C++ library for Windows/UNIX platfroms *
3 * File: fileconf.h - file based implementation of Config *
4 *---------------------------------------------------------------------------*
5 * Language: C++ *
6 * Platfrom: Any *
7 *---------------------------------------------------------------------------*
8 * Classes: *
9 *---------------------------------------------------------------------------*
10 * Author: Vadim Zeitlin zeitlin@dptmaths.ens-cachan.fr> *
11 * adapted from earlier class by VZ & Karsten Ballüder *
12 * History: *
13 * 27.04.98 created *
14 \*****************************************************************************/
15
16 #ifndef _FILECONF_H
17 #define _FILECONF_H
18
19 // ----------------------------------------------------------------------------
20 // wxFileConfig
21 // ----------------------------------------------------------------------------
22
23 /*
24 wxFileConfig derives from base Config and implements file based config class,
25 i.e. it uses ASCII disk files to store the information. These files are
26 alternatively called INI, .conf or .rc in the documentation. They are
27 organized in groups or sections, which can nest (i.e. a group contains
28 subgroups, which contain their own subgroups &c). Each group has some
29 number of entries, which are "key = value" pairs. More precisely, the format
30 is:
31
32 # comments are allowed after either ';' or '#' (Win/UNIX standard)
33
34 # blank lines (as above) are ignored
35
36 # global entries are members of special (no name) top group
37 written_for = Windows
38 platform = Linux
39
40 # the start of the group 'Foo'
41 [Foo] # may put comments like this also
42 # following 3 lines are entries
43 key = value
44 another_key = " strings with spaces in the beginning should be quoted, \
45 otherwise the spaces are lost"
46 last_key = but you don't have to put " normally (nor quote them, like here)
47
48 # subgroup of the group 'Foo'
49 # (order is not important, only the name is: separator is '/', as in paths)
50 [Foo/Bar]
51 # entries prefixed with "!" are immutable, i.e. can't be changed if they are
52 # set in the system-wide config file
53 !special_key = value
54 bar_entry = whatever
55
56 [Foo/Bar/Fubar] # depth is (theoretically :-) unlimited
57 # may have the same name as key in another section
58 bar_entry = whatever not
59
60 You have {read/write/delete}Entry functions (guess what they do) and also
61 setCurrentPath to select current group. enum{Subgroups/Entries} allow you
62 to get all entries in the config file (in the current group). Finally,
63 flush() writes immediately all changed entries to disk (otherwise it would
64 be done automatically in dtor)
65
66 wxFileConfig manages not less than 2 config files for each program: global
67 and local (or system and user if you prefer). Entries are read from both of
68 them and the local entries override the global ones unless the latter is
69 immutable (prefixed with '!') in which case a warning message is generated
70 and local value is ignored. Of course, the changes are always written to local
71 file only.
72
73 @@@@ describe environment variable expansion
74 */
75
76 class wxFileConfig : public wxConfig
77 {
78 public:
79 // construct the "standard" full name for global (system-wide) and
80 // local (user-specific) config files from the base file name.
81 //
82 // the following are the filenames returned by this functions:
83 // global local
84 // Unix /etc/file.ext ~/.file
85 // Win %windir%\file.ext %USERPROFILE%\file.ext
86 //
87 // where file is the basename of szFile, ext is it's extension
88 // or .conf (Unix) or .ini (Win) if it has none
89 static wxString GetGlobalFileName(const char *szFile);
90 static wxString GetLocalFileName(const char *szFile);
91
92 // ctor & dtor
93 // if strGlobal is empty, only local config file is used
94 wxFileConfig(const wxString& strLocal,
95 const wxString& strGlobal = "");
96 // dtor will save unsaved data
97 virtual ~wxFileConfig();
98
99 // implement inherited pure virtual functions
100 virtual void SetPath(const wxString& strPath);
101 virtual const wxString& GetPath() const { return m_strPath; }
102
103 virtual bool GetFirstGroup(wxString& str, long& lIndex);
104 virtual bool GetNextGroup (wxString& str, long& lIndex);
105 virtual bool GetFirstEntry(wxString& str, long& lIndex);
106 virtual bool GetNextEntry (wxString& str, long& lIndex);
107
108 virtual bool Read(wxString *pstr, const char *szKey,
109 const char *szDefault = 0) const;
110 virtual const char *Read(const char *szKey,
111 const char *szDefault = 0) const;
112 virtual bool Read(long *pl, const char *szKey, long lDefault) const;
113 virtual bool Write(const char *szKey, const char *szValue);
114 virtual bool Write(const char *szKey, long lValue);
115 virtual bool Flush(bool bCurrentOnly = FALSE);
116
117 virtual bool DeleteEntry(const char *szKey, bool bGroupIfEmptyAlso);
118 virtual bool DeleteGroup(const char *szKey);
119 virtual bool DeleteAll();
120
121 public:
122 // fwd decl
123 class ConfigGroup;
124 class ConfigEntry;
125
126 // we store all lines of the local config file as a linked list in memory
127 class LineList
128 {
129 public:
130 // ctor
131 LineList(const wxString& str, LineList *pNext = NULL) : m_strLine(str)
132 { SetNext(pNext); }
133
134 //
135 LineList *Next() const { return m_pNext; }
136 void SetNext(LineList *pNext) { m_pNext = pNext; }
137
138 //
139 void SetText(const wxString& str) { m_strLine = str; }
140 const wxString& Text() const { return m_strLine; }
141
142 private:
143 wxString m_strLine; // line contents
144 LineList *m_pNext; // next node
145 };
146
147 // functions to work with this list
148 LineList *LineListAppend(const wxString& str);
149 LineList *LineListInsert(const wxString& str,
150 LineList *pLine); // NULL => Append()
151 bool LineListIsEmpty();
152
153 private:
154 // put the object in the initial state
155 void Init();
156
157 // parse the whole file
158 void Parse(wxTextFile& file, bool bLocal);
159
160 // the same as SetPath("/")
161 void SetRootPath();
162
163 // member variables
164 // ----------------
165 LineList *m_linesHead, // head of the linked list
166 *m_linesTail; // tail
167
168 wxString m_strLocalFile, // local file name passed to ctor
169 m_strGlobalFile; // global
170 wxString m_strPath; // current path (not '/' terminated)
171
172 ConfigGroup *m_pRootGroup, // the top (unnamed) group
173 *m_pCurrentGroup; // the current group
174
175 //protected: --- if wxFileConfig::ConfigEntry is not public, functions in
176 // ConfigGroup such as Find/AddEntry can't return "ConfigEntry *"
177 public:
178 WX_DEFINE_ARRAY(ConfigEntry *, ArrayEntries);
179 WX_DEFINE_ARRAY(ConfigGroup *, ArrayGroups);
180
181 class ConfigEntry
182 {
183 private:
184 ConfigGroup *m_pParent; // group that contains us
185 wxString m_strName, // entry name
186 m_strValue; // value
187 bool m_bDirty, // changed since last read?
188 m_bImmutable; // can be overriden locally?
189 int m_nLine; // used if m_pLine == NULL only
190 LineList *m_pLine; // pointer to our line in the linked list
191 // or NULL if it was found in global file
192
193 public:
194 ConfigEntry(ConfigGroup *pParent, const wxString& strName, int nLine);
195
196 // simple accessors
197 const wxString& Name() const { return m_strName; }
198 const wxString& Value() const { return m_strValue; }
199 ConfigGroup *Group() const { return m_pParent; }
200 bool IsDirty() const { return m_bDirty; }
201 bool IsImmutable() const { return m_bImmutable; }
202 bool IsLocal() const { return m_pLine != 0; }
203 int Line() const { return m_nLine; }
204 LineList *GetLine() const { return m_pLine; }
205
206 // modify entry attributes
207 void SetValue(const wxString& strValue, bool bUser = TRUE);
208 void SetDirty();
209 void SetLine(LineList *pLine);
210 };
211
212 protected:
213 class ConfigGroup
214 {
215 private:
216 wxFileConfig *m_pConfig; // config object we belong to
217 ConfigGroup *m_pParent; // parent group (NULL for root group)
218 ArrayEntries m_aEntries; // entries in this group
219 ArrayGroups m_aSubgroups; // subgroups
220 wxString m_strName; // group's name
221 bool m_bDirty; // if FALSE => all subgroups are not dirty
222 LineList *m_pLine; // pointer to our line in the linked list
223 int m_nLastEntry, // last here means "last added"
224 m_nLastGroup; //
225
226 public:
227 // ctor
228 ConfigGroup(ConfigGroup *pParent, const wxString& strName, wxFileConfig *);
229
230 // dtor deletes all entries and subgroups also
231 ~ConfigGroup();
232
233 // simple accessors
234 const wxString& Name() const { return m_strName; }
235 ConfigGroup *Parent() const { return m_pParent; }
236 wxFileConfig *Config() const { return m_pConfig; }
237 bool IsDirty() const { return m_bDirty; }
238
239 bool IsEmpty() const { return Entries().IsEmpty() && Groups().IsEmpty(); }
240 const ArrayEntries& Entries() const { return m_aEntries; }
241 const ArrayGroups& Groups() const { return m_aSubgroups; }
242
243 // find entry/subgroup (NULL if not found)
244 ConfigGroup *FindSubgroup(const char *szName) const;
245 ConfigEntry *FindEntry (const char *szName) const;
246
247 // delete entry/subgroup, return FALSE if doesn't exist
248 bool DeleteSubgroup(const char *szName);
249 bool DeleteEntry(const char *szName);
250
251 // create new entry/subgroup returning pointer to newly created element
252 ConfigGroup *AddSubgroup(const wxString& strName);
253 ConfigEntry *AddEntry (const wxString& strName, int nLine = NOT_FOUND);
254
255 // will also recursively set parent's dirty flag
256 void SetDirty();
257 void SetLine(LineList *pLine);
258
259 wxString GetFullName() const;
260
261 // get the last line belonging to an entry/subgroup of this group
262 LineList *GetGroupLine();
263 LineList *GetLastEntryLine();
264 LineList *GetLastGroupLine();
265 };
266 };
267
268 #endif //_FILECONF_H
269