]>
Commit | Line | Data |
---|---|---|
1 | /////////////////////////////////////////////////////////////////////////////// | |
2 | // Name: wx/fileconf.h | |
3 | // Purpose: wxFileConfig derivation of wxConfigBase | |
4 | // Author: Vadim Zeitlin | |
5 | // Modified by: | |
6 | // Created: 07.04.98 (adapted from appconf.cpp) | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) 1997 Karsten Ballueder & Vadim Zeitlin | |
9 | // Ballueder@usa.net <zeitlin@dptmaths.ens-cachan.fr> | |
10 | // Licence: wxWindows licence | |
11 | /////////////////////////////////////////////////////////////////////////////// | |
12 | ||
13 | #ifndef _FILECONF_H | |
14 | #define _FILECONF_H | |
15 | ||
16 | #include "wx/defs.h" | |
17 | ||
18 | #if wxUSE_CONFIG | |
19 | ||
20 | #include "wx/textfile.h" | |
21 | #include "wx/string.h" | |
22 | #include "wx/confbase.h" | |
23 | #include "wx/filename.h" | |
24 | ||
25 | // ---------------------------------------------------------------------------- | |
26 | // wxFileConfig | |
27 | // ---------------------------------------------------------------------------- | |
28 | ||
29 | /* | |
30 | wxFileConfig derives from base Config and implements file based config class, | |
31 | i.e. it uses ASCII disk files to store the information. These files are | |
32 | alternatively called INI, .conf or .rc in the documentation. They are | |
33 | organized in groups or sections, which can nest (i.e. a group contains | |
34 | subgroups, which contain their own subgroups &c). Each group has some | |
35 | number of entries, which are "key = value" pairs. More precisely, the format | |
36 | is: | |
37 | ||
38 | # comments are allowed after either ';' or '#' (Win/UNIX standard) | |
39 | ||
40 | # blank lines (as above) are ignored | |
41 | ||
42 | # global entries are members of special (no name) top group | |
43 | written_for = Windows | |
44 | platform = Linux | |
45 | ||
46 | # the start of the group 'Foo' | |
47 | [Foo] # may put comments like this also | |
48 | # following 3 lines are entries | |
49 | key = value | |
50 | another_key = " strings with spaces in the beginning should be quoted, \ | |
51 | otherwise the spaces are lost" | |
52 | last_key = but you don't have to put " normally (nor quote them, like here) | |
53 | ||
54 | # subgroup of the group 'Foo' | |
55 | # (order is not important, only the name is: separator is '/', as in paths) | |
56 | [Foo/Bar] | |
57 | # entries prefixed with "!" are immutable, i.e. can't be changed if they are | |
58 | # set in the system-wide config file | |
59 | !special_key = value | |
60 | bar_entry = whatever | |
61 | ||
62 | [Foo/Bar/Fubar] # depth is (theoretically :-) unlimited | |
63 | # may have the same name as key in another section | |
64 | bar_entry = whatever not | |
65 | ||
66 | You have {read/write/delete}Entry functions (guess what they do) and also | |
67 | setCurrentPath to select current group. enum{Subgroups/Entries} allow you | |
68 | to get all entries in the config file (in the current group). Finally, | |
69 | flush() writes immediately all changed entries to disk (otherwise it would | |
70 | be done automatically in dtor) | |
71 | ||
72 | wxFileConfig manages not less than 2 config files for each program: global | |
73 | and local (or system and user if you prefer). Entries are read from both of | |
74 | them and the local entries override the global ones unless the latter is | |
75 | immutable (prefixed with '!') in which case a warning message is generated | |
76 | and local value is ignored. Of course, the changes are always written to local | |
77 | file only. | |
78 | ||
79 | The names of these files can be specified in a number of ways. First of all, | |
80 | you can use the standard convention: using the ctor which takes 'strAppName' | |
81 | parameter will probably be sufficient for 90% of cases. If, for whatever | |
82 | reason you wish to use the files with some other names, you can always use the | |
83 | second ctor. | |
84 | ||
85 | wxFileConfig also may automatically expand the values of environment variables | |
86 | in the entries it reads: for example, if you have an entry | |
87 | score_file = $HOME/.score | |
88 | a call to Read(&str, "score_file") will return a complete path to .score file | |
89 | unless the expansion was previously disabled with SetExpandEnvVars(false) call | |
90 | (it's on by default, the current status can be retrieved with | |
91 | IsExpandingEnvVars function). | |
92 | */ | |
93 | class WXDLLIMPEXP_FWD_BASE wxFileConfigGroup; | |
94 | class WXDLLIMPEXP_FWD_BASE wxFileConfigEntry; | |
95 | class WXDLLIMPEXP_FWD_BASE wxFileConfigLineList; | |
96 | ||
97 | #if wxUSE_STREAMS | |
98 | class WXDLLIMPEXP_FWD_BASE wxInputStream; | |
99 | class WXDLLIMPEXP_FWD_BASE wxOutputStream; | |
100 | #endif // wxUSE_STREAMS | |
101 | ||
102 | class WXDLLIMPEXP_BASE wxFileConfig : public wxConfigBase | |
103 | { | |
104 | public: | |
105 | // construct the "standard" full name for global (system-wide) and | |
106 | // local (user-specific) config files from the base file name. | |
107 | // | |
108 | // the following are the filenames returned by this functions: | |
109 | // global local | |
110 | // Unix /etc/file.ext ~/.file | |
111 | // Win %windir%\file.ext %USERPROFILE%\file.ext | |
112 | // | |
113 | // where file is the basename of szFile, ext is its extension | |
114 | // or .conf (Unix) or .ini (Win) if it has none | |
115 | static wxFileName GetGlobalFile(const wxString& szFile); | |
116 | static wxFileName GetLocalFile(const wxString& szFile, int style = 0); | |
117 | ||
118 | static wxString GetGlobalFileName(const wxString& szFile) | |
119 | { | |
120 | return GetGlobalFile(szFile).GetFullPath(); | |
121 | } | |
122 | ||
123 | static wxString GetLocalFileName(const wxString& szFile, int style = 0) | |
124 | { | |
125 | return GetLocalFile(szFile, style).GetFullPath(); | |
126 | } | |
127 | ||
128 | // ctor & dtor | |
129 | // New constructor: one size fits all. Specify wxCONFIG_USE_LOCAL_FILE or | |
130 | // wxCONFIG_USE_GLOBAL_FILE to say which files should be used. | |
131 | wxFileConfig(const wxString& appName = wxEmptyString, | |
132 | const wxString& vendorName = wxEmptyString, | |
133 | const wxString& localFilename = wxEmptyString, | |
134 | const wxString& globalFilename = wxEmptyString, | |
135 | long style = wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_GLOBAL_FILE, | |
136 | const wxMBConv& conv = wxConvAuto()); | |
137 | ||
138 | #if wxUSE_STREAMS | |
139 | // ctor that takes an input stream. | |
140 | wxFileConfig(wxInputStream &inStream, const wxMBConv& conv = wxConvAuto()); | |
141 | #endif // wxUSE_STREAMS | |
142 | ||
143 | // dtor will save unsaved data | |
144 | virtual ~wxFileConfig(); | |
145 | ||
146 | // under Unix, set the umask to be used for the file creation, do nothing | |
147 | // under other systems | |
148 | #ifdef __UNIX__ | |
149 | void SetUmask(int mode) { m_umask = mode; } | |
150 | #else // !__UNIX__ | |
151 | void SetUmask(int WXUNUSED(mode)) { } | |
152 | #endif // __UNIX__/!__UNIX__ | |
153 | ||
154 | // implement inherited pure virtual functions | |
155 | virtual void SetPath(const wxString& strPath); | |
156 | virtual const wxString& GetPath() const; | |
157 | ||
158 | virtual bool GetFirstGroup(wxString& str, long& lIndex) const; | |
159 | virtual bool GetNextGroup (wxString& str, long& lIndex) const; | |
160 | virtual bool GetFirstEntry(wxString& str, long& lIndex) const; | |
161 | virtual bool GetNextEntry (wxString& str, long& lIndex) const; | |
162 | ||
163 | virtual size_t GetNumberOfEntries(bool bRecursive = false) const; | |
164 | virtual size_t GetNumberOfGroups(bool bRecursive = false) const; | |
165 | ||
166 | virtual bool HasGroup(const wxString& strName) const; | |
167 | virtual bool HasEntry(const wxString& strName) const; | |
168 | ||
169 | virtual bool Flush(bool bCurrentOnly = false); | |
170 | ||
171 | virtual bool RenameEntry(const wxString& oldName, const wxString& newName); | |
172 | virtual bool RenameGroup(const wxString& oldName, const wxString& newName); | |
173 | ||
174 | virtual bool DeleteEntry(const wxString& key, bool bGroupIfEmptyAlso = true); | |
175 | virtual bool DeleteGroup(const wxString& szKey); | |
176 | virtual bool DeleteAll(); | |
177 | ||
178 | // additional, wxFileConfig-specific, functionality | |
179 | #if wxUSE_STREAMS | |
180 | // save the entire config file text to the given stream, note that the text | |
181 | // won't be saved again in dtor when Flush() is called if you use this method | |
182 | // as it won't be "changed" any more | |
183 | virtual bool Save(wxOutputStream& os, const wxMBConv& conv = wxConvAuto()); | |
184 | #endif // wxUSE_STREAMS | |
185 | ||
186 | public: | |
187 | // functions to work with this list | |
188 | wxFileConfigLineList *LineListAppend(const wxString& str); | |
189 | wxFileConfigLineList *LineListInsert(const wxString& str, | |
190 | wxFileConfigLineList *pLine); // NULL => Prepend() | |
191 | void LineListRemove(wxFileConfigLineList *pLine); | |
192 | bool LineListIsEmpty(); | |
193 | ||
194 | protected: | |
195 | virtual bool DoReadString(const wxString& key, wxString *pStr) const; | |
196 | virtual bool DoReadLong(const wxString& key, long *pl) const; | |
197 | #if wxUSE_BASE64 | |
198 | virtual bool DoReadBinary(const wxString& key, wxMemoryBuffer* buf) const; | |
199 | #endif // wxUSE_BASE64 | |
200 | ||
201 | virtual bool DoWriteString(const wxString& key, const wxString& szValue); | |
202 | virtual bool DoWriteLong(const wxString& key, long lValue); | |
203 | #if wxUSE_BASE64 | |
204 | virtual bool DoWriteBinary(const wxString& key, const wxMemoryBuffer& buf); | |
205 | #endif // wxUSE_BASE64 | |
206 | ||
207 | private: | |
208 | // GetXXXFileName helpers: return ('/' terminated) directory names | |
209 | static wxString GetGlobalDir(); | |
210 | static wxString GetLocalDir(int style = 0); | |
211 | ||
212 | // common part of all ctors (assumes that m_str{Local|Global}File are already | |
213 | // initialized | |
214 | void Init(); | |
215 | ||
216 | // common part of from dtor and DeleteAll | |
217 | void CleanUp(); | |
218 | ||
219 | // parse the whole file | |
220 | void Parse(const wxTextBuffer& buffer, bool bLocal); | |
221 | ||
222 | // the same as SetPath("/") | |
223 | void SetRootPath(); | |
224 | ||
225 | // real SetPath() implementation, returns true if path could be set or false | |
226 | // if path doesn't exist and createMissingComponents == false | |
227 | bool DoSetPath(const wxString& strPath, bool createMissingComponents); | |
228 | ||
229 | // set/test the dirty flag | |
230 | void SetDirty() { m_isDirty = true; } | |
231 | void ResetDirty() { m_isDirty = false; } | |
232 | bool IsDirty() const { return m_isDirty; } | |
233 | ||
234 | ||
235 | // member variables | |
236 | // ---------------- | |
237 | wxFileConfigLineList *m_linesHead, // head of the linked list | |
238 | *m_linesTail; // tail | |
239 | ||
240 | wxFileName m_fnLocalFile, // local file name passed to ctor | |
241 | m_fnGlobalFile; // global | |
242 | wxString m_strPath; // current path (not '/' terminated) | |
243 | ||
244 | wxFileConfigGroup *m_pRootGroup, // the top (unnamed) group | |
245 | *m_pCurrentGroup; // the current group | |
246 | ||
247 | wxMBConv *m_conv; | |
248 | ||
249 | #ifdef __UNIX__ | |
250 | int m_umask; // the umask to use for file creation | |
251 | #endif // __UNIX__ | |
252 | ||
253 | bool m_isDirty; // if true, we have unsaved changes | |
254 | ||
255 | wxDECLARE_NO_COPY_CLASS(wxFileConfig); | |
256 | DECLARE_ABSTRACT_CLASS(wxFileConfig) | |
257 | }; | |
258 | ||
259 | #endif | |
260 | // wxUSE_CONFIG | |
261 | ||
262 | #endif | |
263 | //_FILECONF_H | |
264 |