1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxFileConfig derivation of wxConfigBase
4 // Author: Vadim Zeitlin
6 // Created: 07.04.98 (adapted from appconf.cpp)
8 // Copyright: (c) 1997 Karsten Ballüder & Vadim Zeitlin
9 // Ballueder@usa.net <zeitlin@dptmaths.ens-cachan.fr>
10 // Licence: wxWindows licence
11 ///////////////////////////////////////////////////////////////////////////////
20 #include "wx/textfile.h"
21 #include "wx/string.h"
22 #include "wx/confbase.h"
23 #include "wx/filename.h"
25 // ----------------------------------------------------------------------------
27 // ----------------------------------------------------------------------------
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
38 # comments are allowed after either ';' or '#' (Win/UNIX standard)
40 # blank lines (as above) are ignored
42 # global entries are members of special (no name) top group
46 # the start of the group 'Foo'
47 [Foo] # may put comments like this also
48 # following 3 lines are entries
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)
54 # subgroup of the group 'Foo'
55 # (order is not important, only the name is: separator is '/', as in paths)
57 # entries prefixed with "!" are immutable, i.e. can't be changed if they are
58 # set in the system-wide config file
62 [Foo/Bar/Fubar] # depth is (theoretically :-) unlimited
63 # may have the same name as key in another section
64 bar_entry = whatever not
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)
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
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
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).
93 class WXDLLIMPEXP_FWD_BASE wxFileConfigGroup
;
94 class WXDLLIMPEXP_FWD_BASE wxFileConfigEntry
;
95 class WXDLLIMPEXP_FWD_BASE wxFileConfigLineList
;
98 class WXDLLIMPEXP_FWD_BASE wxInputStream
;
99 class WXDLLIMPEXP_FWD_BASE wxOutputStream
;
100 #endif // wxUSE_STREAMS
102 class WXDLLIMPEXP_BASE wxFileConfig
: public wxConfigBase
105 // construct the "standard" full name for global (system-wide) and
106 // local (user-specific) config files from the base file name.
108 // the following are the filenames returned by this functions:
110 // Unix /etc/file.ext ~/.file
111 // Win %windir%\file.ext %USERPROFILE%\file.ext
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);
118 static wxString
GetGlobalFileName(const wxString
& szFile
)
120 return GetGlobalFile(szFile
).GetFullPath();
123 static wxString
GetLocalFileName(const wxString
& szFile
, int style
= 0)
125 return GetLocalFile(szFile
, style
).GetFullPath();
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());
139 // ctor that takes an input stream.
140 wxFileConfig(wxInputStream
&inStream
, const wxMBConv
& conv
= wxConvAuto());
141 #endif // wxUSE_STREAMS
143 // dtor will save unsaved data
144 virtual ~wxFileConfig();
146 // under Unix, set the umask to be used for the file creation, do nothing
147 // under other systems
149 void SetUmask(int mode
) { m_umask
= mode
; }
151 void SetUmask(int WXUNUSED(mode
)) { }
152 #endif // __UNIX__/!__UNIX__
154 // implement inherited pure virtual functions
155 virtual void SetPath(const wxString
& strPath
);
156 virtual const wxString
& GetPath() const { return m_strPath
; }
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;
163 virtual size_t GetNumberOfEntries(bool bRecursive
= false) const;
164 virtual size_t GetNumberOfGroups(bool bRecursive
= false) const;
166 virtual bool HasGroup(const wxString
& strName
) const;
167 virtual bool HasEntry(const wxString
& strName
) const;
169 virtual bool Flush(bool bCurrentOnly
= false);
171 virtual bool RenameEntry(const wxString
& oldName
, const wxString
& newName
);
172 virtual bool RenameGroup(const wxString
& oldName
, const wxString
& newName
);
174 virtual bool DeleteEntry(const wxString
& key
, bool bGroupIfEmptyAlso
= true);
175 virtual bool DeleteGroup(const wxString
& szKey
);
176 virtual bool DeleteAll();
178 // additional, wxFileConfig-specific, functionality
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
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();
195 virtual bool DoReadString(const wxString
& key
, wxString
*pStr
) const;
196 virtual bool DoReadLong(const wxString
& key
, long *pl
) const;
198 virtual bool DoWriteString(const wxString
& key
, const wxString
& szValue
);
199 virtual bool DoWriteLong(const wxString
& key
, long lValue
);
202 // GetXXXFileName helpers: return ('/' terminated) directory names
203 static wxString
GetGlobalDir();
204 static wxString
GetLocalDir(int style
= 0);
206 // common part of all ctors (assumes that m_str{Local|Global}File are already
210 // common part of from dtor and DeleteAll
213 // parse the whole file
214 void Parse(const wxTextBuffer
& buffer
, bool bLocal
);
216 // the same as SetPath("/")
219 // real SetPath() implementation, returns true if path could be set or false
220 // if path doesn't exist and createMissingComponents == false
221 bool DoSetPath(const wxString
& strPath
, bool createMissingComponents
);
223 // set/test the dirty flag
224 void SetDirty() { m_isDirty
= true; }
225 void ResetDirty() { m_isDirty
= false; }
226 bool IsDirty() const { return m_isDirty
; }
231 wxFileConfigLineList
*m_linesHead
, // head of the linked list
232 *m_linesTail
; // tail
234 wxFileName m_fnLocalFile
, // local file name passed to ctor
235 m_fnGlobalFile
; // global
236 wxString m_strPath
; // current path (not '/' terminated)
238 wxFileConfigGroup
*m_pRootGroup
, // the top (unnamed) group
239 *m_pCurrentGroup
; // the current group
244 int m_umask
; // the umask to use for file creation
247 bool m_isDirty
; // if true, we have unsaved changes
249 DECLARE_NO_COPY_CLASS(wxFileConfig
)
250 DECLARE_ABSTRACT_CLASS(wxFileConfig
)