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