]> git.saurik.com Git - wxWidgets.git/blame - src/msw/regconf.cpp
* Deleted all ^M
[wxWidgets.git] / src / msw / regconf.cpp
CommitLineData
19454fa0
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: msw/regconf.cpp
3// Purpose:
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 27.04.98
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9// Licence: wxWindows license
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19#include <wx/wx.h>
20#include <wx/config.h>
21#include <wx/regconf.h>
22#include <wx/registry.h>
23
24// ----------------------------------------------------------------------------
25// constants
26// ----------------------------------------------------------------------------
27
28// we put our data in HKLM\SOFTWARE_KEY\appname
29#define SOFTWARE_KEY wxString("Software\\")
30
31// ----------------------------------------------------------------------------
32// global functions
33// ----------------------------------------------------------------------------
34
35// get the value if the key is opened and it exists
36bool TryGetValue(const wxRegKey& key, const wxString& str, wxString& strVal)
37{
38 return key.IsOpened() && key.HasValue(str) && key.QueryValue(str, strVal);
39}
40
41bool TryGetValue(const wxRegKey& key, const wxString& str, long *plVal)
42{
43 return key.IsOpened() && key.HasValue(str) && key.QueryValue(str, plVal);
44}
45
46// ============================================================================
47// implementation
48// ============================================================================
49
50// ----------------------------------------------------------------------------
51// ctor/dtor
52// ----------------------------------------------------------------------------
53wxRegConfig::wxRegConfig(const wxString& strRoot)
54 : m_keyLocalRoot(wxRegKey::HKCU, SOFTWARE_KEY + strRoot),
55 m_keyLocal(m_keyLocalRoot, ""),
56 m_keyGlobalRoot(wxRegKey::HKLM, SOFTWARE_KEY + strRoot),
57 m_keyGlobal(m_keyGlobalRoot, "")
58{
59 // Create() will Open() if key already exists
60 m_keyLocalRoot.Create();
61
62 wxLogNull nolog;
63 m_keyGlobalRoot.Open();
64}
65
66wxRegConfig::~wxRegConfig()
67{
68 // nothing to do - key will be closed in their dtors
69}
70
71// ----------------------------------------------------------------------------
72// path management
73// ----------------------------------------------------------------------------
74void wxRegConfig::SetPath(const wxString& strPath)
75{
76 ArrayString aParts;
77
78 if ( strPath.IsEmpty() )
79 return;
80
81 if ( strPath[0] == APPCONF_PATH_SEPARATOR ) {
82 // absolute path
83 SplitPath(aParts, strPath);
84 }
85 else {
86 // relative path, combine with current one
87 wxString strFullPath = GetPath();
88 strFullPath << APPCONF_PATH_SEPARATOR << strPath;
89 SplitPath(aParts, strFullPath);
90 }
91
92 // recombine path parts in one variable
93 wxString strRegPath;
94 m_strPath.Empty();
95 for ( uint n = 0; n < aParts.Count(); n++ ) {
96 strRegPath << '\\' << aParts[n];
97 m_strPath << APPCONF_PATH_SEPARATOR << aParts[n];
98 }
99
100 // change current key(s)
101 m_keyLocal.SetName(m_keyLocalRoot, strRegPath);
102 m_keyGlobal.SetName(m_keyGlobalRoot, strRegPath);
103 m_keyLocal.Create();
104
105 wxLogNull nolog;
106 m_keyGlobal.Open();
107}
108
109// ----------------------------------------------------------------------------
110// enumeration (works only with current group)
111// ----------------------------------------------------------------------------
112
113/*
114 We want to enumerate all local keys/values after the global ones, but, of
115 course, we don't want to repeat a key which appears locally as well as
116 globally twice.
117
118 We use the 15th bit of lIndex for distinction between global and local.
119 */
120
121#define LOCAL_MASK 0x8000
122#define IS_LOCAL_INDEX(l) (((l) & LOCAL_MASK) != 0)
123
124bool wxRegConfig::GetFirstGroup(wxString& str, long& lIndex)
125{
126 lIndex = 0;
127 return GetNextGroup(str, lIndex);
128}
129
130bool wxRegConfig::GetNextGroup (wxString& str, long& lIndex)
131{
132 // are we already enumerating local entries?
133 if ( m_keyGlobal.IsOpened() && !IS_LOCAL_INDEX(lIndex) ) {
134 // try to find a global entry which doesn't appear locally
135 do {
136 if ( !m_keyGlobal.GetNextKey(str, lIndex) ) {
137 // no more global entries
138 lIndex |= LOCAL_MASK;
139 break;
140 }
141 } while( m_keyLocal.HasSubKey(str) );
142 }
143
144 // much easier with local entries: get the next one we find
145 // (don't forget to clear our flag bit and set it again later)
146 lIndex &= ~LOCAL_MASK;
147 bool bOk = m_keyLocal.GetNextKey(str, lIndex);
148 lIndex |= LOCAL_MASK;
149
150 return bOk;
151}
152
153bool wxRegConfig::GetFirstEntry(wxString& str, long& lIndex)
154{
155 lIndex = 0;
156 return GetNextGroup(str, lIndex);
157}
158
159bool wxRegConfig::GetNextEntry (wxString& str, long& lIndex)
160{
161 // are we already enumerating local entries?
162 if ( m_keyGlobal.IsOpened() && !IS_LOCAL_INDEX(lIndex) ) {
163 // try to find a global entry which doesn't appear locally
164 do {
165 if ( !m_keyGlobal.GetNextKey(str, lIndex) ) {
166 // no more global entries
167 lIndex |= LOCAL_MASK;
168 break;
169 }
170 } while( m_keyLocal.HasSubKey(str) );
171 }
172
173 // much easier with local entries: get the next one we find
174 // (don't forget to clear our flag bit and set it again later)
175 lIndex &= ~LOCAL_MASK;
176 bool bOk = m_keyLocal.GetNextKey(str, lIndex);
177 lIndex |= LOCAL_MASK;
178
179 return bOk;
180}
181
182// ----------------------------------------------------------------------------
183// reading/writing
184// ----------------------------------------------------------------------------
185
186bool wxRegConfig::Read(wxString& str,
187 const char *szKey,
188 const char *szDefault) const
189{
190 PathChanger path(this, szKey);
191
cf447356 192 bool bQueryGlobal = TRUE;
19454fa0
VZ
193
194 // if immutable key exists in global key we must check that it's not
195 // overriden by the local key with the same name
196 if ( IsImmutable(path.Name()) ) {
197 if ( TryGetValue(m_keyGlobal, path.Name(), str) ) {
198 if ( m_keyLocal.HasValue(path.Name()) ) {
199 wxLogWarning("User value for immutable key '%s' ignored.",
200 path.Name().c_str());
201 }
202
cf447356 203 return TRUE;
19454fa0
VZ
204 }
205 else {
206 // don't waste time - it's not there anyhow
cf447356 207 bQueryGlobal = FALSE;
19454fa0
VZ
208 }
209 }
210
211 // first try local key
212 if ( TryGetValue(m_keyLocal, path.Name(), str) ||
213 (bQueryGlobal && TryGetValue(m_keyGlobal, path.Name(), str)) ) {
cf447356 214 return TRUE;
19454fa0
VZ
215 }
216
217 // default value
218 str = szDefault;
cf447356 219 return FALSE;
19454fa0
VZ
220}
221
222bool wxRegConfig::Read(long &lValue, const char *szKey, long lDefault) const
223{
224 PathChanger path(this, szKey);
225
cf447356 226 bool bQueryGlobal = TRUE;
19454fa0
VZ
227
228 // if immutable key exists in global key we must check that it's not
229 // overriden by the local key with the same name
230 if ( IsImmutable(path.Name()) ) {
231 if ( TryGetValue(m_keyGlobal, path.Name(), &lValue) ) {
232 if ( m_keyLocal.HasValue(path.Name()) ) {
233 wxLogWarning("User value for immutable key '%s' ignored.",
234 path.Name().c_str());
235 }
236
cf447356 237 return TRUE;
19454fa0
VZ
238 }
239 else {
240 // don't waste time - it's not there anyhow
cf447356 241 bQueryGlobal = FALSE;
19454fa0
VZ
242 }
243 }
244
245 // first try local key
246 if ( TryGetValue(m_keyLocal, path.Name(), &lValue) ||
247 (bQueryGlobal && TryGetValue(m_keyGlobal, path.Name(), &lValue)) ) {
cf447356 248 return TRUE;
19454fa0
VZ
249 }
250
251 // default
252 lValue = lDefault;
cf447356 253 return FALSE;
19454fa0
VZ
254}
255
256bool wxRegConfig::Write(const char *szKey, const char *szValue)
257{
258 PathChanger path(this, szKey);
259
260 if ( IsImmutable(path.Name()) ) {
261 wxLogError("Can't change immutable entry '%s'.", path.Name().c_str());
cf447356 262 return FALSE;
19454fa0
VZ
263 }
264
265 return m_keyLocal.SetValue(path.Name(), szValue);
266}
267
268bool wxRegConfig::Write(const char *szKey, long lValue)
269{
270 PathChanger path(this, szKey);
271
272 if ( IsImmutable(path.Name()) ) {
273 wxLogError("Can't change immutable entry '%s'.", path.Name().c_str());
cf447356 274 return FALSE;
19454fa0
VZ
275 }
276
277 return m_keyLocal.SetValue(path.Name(), lValue);
278}
279
280// ----------------------------------------------------------------------------
281// deleting
282// ----------------------------------------------------------------------------
283bool wxRegConfig::DeleteEntry(const char *szValue, bool bGroupIfEmptyAlso)
284{
285 PathChanger path(this, szValue);
286
287 if ( !m_keyLocal.DeleteValue(path.Name()) )
cf447356 288 return FALSE;
19454fa0
VZ
289
290 if ( m_keyLocal.IsEmpty() ) {
291 wxString strKey = GetPath().Right(APPCONF_PATH_SEPARATOR);
292 SetPath(".."); // changes m_keyLocal
293 return m_keyLocal.DeleteKey(strKey);
294 }
295
cf447356 296 return TRUE;
19454fa0
VZ
297}
298
299bool wxRegConfig::DeleteGroup(const char *szKey)
300{
301 PathChanger path(this, szKey);
302
303 return m_keyLocal.DeleteKey(path.Name());
304}
305
306bool wxRegConfig::DeleteAll()
307{
308 // first of all, prevent the creation of new registry entries
cf447356 309 Config::EnableAutosave(FALSE);
19454fa0
VZ
310
311 m_keyLocal.Close();
312 m_keyGlobal.Close();
313
314 bool bOk = m_keyLocalRoot.DeleteSelf();
315 if ( bOk )
316 bOk = m_keyGlobalRoot.DeleteSelf();
317
318 return bOk;
319}