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