]>
git.saurik.com Git - wxWidgets.git/blob - include/wx/fileconf.h
1 /*****************************************************************************\
2 * Project: CppLib: C++ library for Windows/UNIX platfroms *
3 * File: fileconf.h - file based implementation of Config *
4 *---------------------------------------------------------------------------*
7 *---------------------------------------------------------------------------*
9 *---------------------------------------------------------------------------*
10 * Author: Vadim Zeitlin zeitlin@dptmaths.ens-cachan.fr> *
11 * adapted from earlier class by VZ & Karsten Ballüder *
14 \*****************************************************************************/
20 #pragma interface "fileconf.h"
23 // ----------------------------------------------------------------------------
25 // ----------------------------------------------------------------------------
27 // it won't compile without it anyhow
29 #error "Please define USE_WXCONFIG or remove fileconf.cpp from your makefile"
30 #endif // USE_WXCONFIG
32 // ----------------------------------------------------------------------------
34 // ----------------------------------------------------------------------------
37 wxFileConfig derives from base Config and implements file based config class,
38 i.e. it uses ASCII disk files to store the information. These files are
39 alternatively called INI, .conf or .rc in the documentation. They are
40 organized in groups or sections, which can nest (i.e. a group contains
41 subgroups, which contain their own subgroups &c). Each group has some
42 number of entries, which are "key = value" pairs. More precisely, the format
45 # comments are allowed after either ';' or '#' (Win/UNIX standard)
47 # blank lines (as above) are ignored
49 # global entries are members of special (no name) top group
53 # the start of the group 'Foo'
54 [Foo] # may put comments like this also
55 # following 3 lines are entries
57 another_key = " strings with spaces in the beginning should be quoted, \
58 otherwise the spaces are lost"
59 last_key = but you don't have to put " normally (nor quote them, like here)
61 # subgroup of the group 'Foo'
62 # (order is not important, only the name is: separator is '/', as in paths)
64 # entries prefixed with "!" are immutable, i.e. can't be changed if they are
65 # set in the system-wide config file
69 [Foo/Bar/Fubar] # depth is (theoretically :-) unlimited
70 # may have the same name as key in another section
71 bar_entry = whatever not
73 You have {read/write/delete}Entry functions (guess what they do) and also
74 setCurrentPath to select current group. enum{Subgroups/Entries} allow you
75 to get all entries in the config file (in the current group). Finally,
76 flush() writes immediately all changed entries to disk (otherwise it would
77 be done automatically in dtor)
79 wxFileConfig manages not less than 2 config files for each program: global
80 and local (or system and user if you prefer). Entries are read from both of
81 them and the local entries override the global ones unless the latter is
82 immutable (prefixed with '!') in which case a warning message is generated
83 and local value is ignored. Of course, the changes are always written to local
86 @@@@ describe environment variable expansion
89 class wxFileConfig
: public wxConfig
92 // construct the "standard" full name for global (system-wide) and
93 // local (user-specific) config files from the base file name.
95 // the following are the filenames returned by this functions:
97 // Unix /etc/file.ext ~/.file
98 // Win %windir%\file.ext %USERPROFILE%\file.ext
100 // where file is the basename of szFile, ext is it's extension
101 // or .conf (Unix) or .ini (Win) if it has none
102 static wxString
GetGlobalFileName(const char *szFile
);
103 static wxString
GetLocalFileName(const char *szFile
);
106 // if strGlobal is empty, only local config file is used
107 wxFileConfig(const wxString
& strLocal
,
108 const wxString
& strGlobal
= "");
109 // dtor will save unsaved data
110 virtual ~wxFileConfig();
112 // implement inherited pure virtual functions
113 virtual void SetPath(const wxString
& strPath
);
114 virtual const wxString
& GetPath() const { return m_strPath
; }
116 virtual bool GetFirstGroup(wxString
& str
, long& lIndex
);
117 virtual bool GetNextGroup (wxString
& str
, long& lIndex
);
118 virtual bool GetFirstEntry(wxString
& str
, long& lIndex
);
119 virtual bool GetNextEntry (wxString
& str
, long& lIndex
);
121 virtual bool HasGroup(const wxString
& strName
) const;
122 virtual bool HasEntry(const wxString
& strName
) const;
124 virtual bool Read(wxString
*pstr
, const char *szKey
,
125 const char *szDefault
= 0) const;
126 virtual const char *Read(const char *szKey
,
127 const char *szDefault
= 0) const;
128 virtual bool Read(long *pl
, const char *szKey
, long lDefault
) const;
129 virtual long Read(const char *szKey
, long lDefault
) const
130 { return wxConfig::Read(szKey
, lDefault
); }
131 virtual bool Write(const char *szKey
, const char *szValue
);
132 virtual bool Write(const char *szKey
, long lValue
);
133 virtual bool Flush(bool bCurrentOnly
= FALSE
);
135 virtual bool DeleteEntry(const char *szKey
, bool bGroupIfEmptyAlso
);
136 virtual bool DeleteGroup(const char *szKey
);
137 virtual bool DeleteAll();
144 // we store all lines of the local config file as a linked list in memory
149 LineList(const wxString
& str
, LineList
*pNext
= NULL
) : m_strLine(str
)
150 { SetNext(pNext
); SetPrev(NULL
); }
153 LineList
*Next() const { return m_pNext
; }
154 LineList
*Prev() const { return m_pPrev
; }
155 void SetNext(LineList
*pNext
) { m_pNext
= pNext
; }
156 void SetPrev(LineList
*pPrev
) { m_pPrev
= pPrev
; }
159 void SetText(const wxString
& str
) { m_strLine
= str
; }
160 const wxString
& Text() const { return m_strLine
; }
163 wxString m_strLine
; // line contents
164 LineList
*m_pNext
, // next node
165 *m_pPrev
; // previous one
168 // functions to work with this list
169 LineList
*LineListAppend(const wxString
& str
);
170 LineList
*LineListInsert(const wxString
& str
,
171 LineList
*pLine
); // NULL => Prepend()
172 void LineListRemove(LineList
*pLine
);
173 bool LineListIsEmpty();
176 // put the object in the initial state
179 // parse the whole file
180 void Parse(wxTextFile
& file
, bool bLocal
);
182 // the same as SetPath("/")
187 LineList
*m_linesHead
, // head of the linked list
188 *m_linesTail
; // tail
190 wxString m_strLocalFile
, // local file name passed to ctor
191 m_strGlobalFile
; // global
192 wxString m_strPath
; // current path (not '/' terminated)
194 ConfigGroup
*m_pRootGroup
, // the top (unnamed) group
195 *m_pCurrentGroup
; // the current group
197 //protected: --- if wxFileConfig::ConfigEntry is not public, functions in
198 // ConfigGroup such as Find/AddEntry can't return "ConfigEntry *"
200 WX_DEFINE_ARRAY(ConfigEntry
*, ArrayEntries
);
201 WX_DEFINE_ARRAY(ConfigGroup
*, ArrayGroups
);
206 ConfigGroup
*m_pParent
; // group that contains us
207 wxString m_strName
, // entry name
209 bool m_bDirty
, // changed since last read?
210 m_bImmutable
; // can be overriden locally?
211 int m_nLine
; // used if m_pLine == NULL only
212 LineList
*m_pLine
; // pointer to our line in the linked list
213 // or NULL if it was found in global file
216 ConfigEntry(ConfigGroup
*pParent
, const wxString
& strName
, int nLine
);
219 const wxString
& Name() const { return m_strName
; }
220 const wxString
& Value() const { return m_strValue
; }
221 ConfigGroup
*Group() const { return m_pParent
; }
222 bool IsDirty() const { return m_bDirty
; }
223 bool IsImmutable() const { return m_bImmutable
; }
224 bool IsLocal() const { return m_pLine
!= 0; }
225 int Line() const { return m_nLine
; }
226 LineList
*GetLine() const { return m_pLine
; }
228 // modify entry attributes
229 void SetValue(const wxString
& strValue
, bool bUser
= TRUE
);
231 void SetLine(LineList
*pLine
);
238 wxFileConfig
*m_pConfig
; // config object we belong to
239 ConfigGroup
*m_pParent
; // parent group (NULL for root group)
240 ArrayEntries m_aEntries
; // entries in this group
241 ArrayGroups m_aSubgroups
; // subgroups
242 wxString m_strName
; // group's name
243 bool m_bDirty
; // if FALSE => all subgroups are not dirty
244 LineList
*m_pLine
; // pointer to our line in the linked list
245 ConfigEntry
*m_pLastEntry
; // last entry of this group in the local file
246 ConfigGroup
*m_pLastGroup
; // last subgroup
250 ConfigGroup(ConfigGroup
*pParent
, const wxString
& strName
, wxFileConfig
*);
252 // dtor deletes all entries and subgroups also
256 const wxString
& Name() const { return m_strName
; }
257 ConfigGroup
*Parent() const { return m_pParent
; }
258 wxFileConfig
*Config() const { return m_pConfig
; }
259 bool IsDirty() const { return m_bDirty
; }
261 bool IsEmpty() const { return Entries().IsEmpty() && Groups().IsEmpty(); }
262 const ArrayEntries
& Entries() const { return m_aEntries
; }
263 const ArrayGroups
& Groups() const { return m_aSubgroups
; }
265 // find entry/subgroup (NULL if not found)
266 ConfigGroup
*FindSubgroup(const char *szName
) const;
267 ConfigEntry
*FindEntry (const char *szName
) const;
269 // delete entry/subgroup, return FALSE if doesn't exist
270 bool DeleteSubgroup(const char *szName
);
271 bool DeleteEntry(const char *szName
);
273 // create new entry/subgroup returning pointer to newly created element
274 ConfigGroup
*AddSubgroup(const wxString
& strName
);
275 ConfigEntry
*AddEntry (const wxString
& strName
, int nLine
= NOT_FOUND
);
277 // will also recursively set parent's dirty flag
279 void SetLine(LineList
*pLine
);
281 // the new entries in this subgroup will be inserted after the last subgroup
282 // or, if there is none, after the last entry
283 void SetLastEntry(ConfigEntry
*pLastEntry
) { m_pLastEntry
= pLastEntry
; }
284 void SetLastGroup(ConfigGroup
*pLastGroup
) { m_pLastGroup
= pLastGroup
; }
286 wxString
GetFullName() const;
288 // get the last line belonging to an entry/subgroup of this group
289 LineList
*GetGroupLine();
290 LineList
*GetLastEntryLine();
291 LineList
*GetLastGroupLine();