]> git.saurik.com Git - wxWidgets.git/blame - src/msw/regconf.cpp
Turned wxIcon inline constructors to real constructors
[wxWidgets.git] / src / msw / regconf.cpp
CommitLineData
19454fa0
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: msw/regconf.cpp
6d833566 3// Purpose:
19454fa0 4// Author: Vadim Zeitlin
6d833566 5// Modified by:
19454fa0
VZ
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
cfe780fb
JS
12#ifdef __GNUG__
13#pragma implementation "regconf.h"
14#endif
15
19454fa0
VZ
16// ============================================================================
17// declarations
18// ============================================================================
19
20// ----------------------------------------------------------------------------
21// headers
22// ----------------------------------------------------------------------------
82cf4761
VZ
23
24#ifdef __GNUG__
25 #pragma implementation "regconf.h"
26#endif
27
28#include "wx/wxprec.h"
29
30#ifdef __BORLANDC__
31 #pragma hdrstop
32#endif //__BORLANDC__
33
34#ifndef WX_PRECOMP
35 #include <wx/string.h>
36#endif //WX_PRECOMP
37
38#include <wx/log.h>
19454fa0 39#include <wx/config.h>
6d833566 40#include <wx/msw/registry.h>
82cf4761 41#include <wx/msw/regconf.h>
19454fa0
VZ
42
43// ----------------------------------------------------------------------------
44// constants
45// ----------------------------------------------------------------------------
46
47// we put our data in HKLM\SOFTWARE_KEY\appname
48#define SOFTWARE_KEY wxString("Software\\")
49
50// ----------------------------------------------------------------------------
51// global functions
52// ----------------------------------------------------------------------------
53
54// get the value if the key is opened and it exists
55bool TryGetValue(const wxRegKey& key, const wxString& str, wxString& strVal)
56{
57 return key.IsOpened() && key.HasValue(str) && key.QueryValue(str, strVal);
58}
59
60bool TryGetValue(const wxRegKey& key, const wxString& str, long *plVal)
61{
62 return key.IsOpened() && key.HasValue(str) && key.QueryValue(str, plVal);
63}
64
65// ============================================================================
66// implementation
67// ============================================================================
68
69// ----------------------------------------------------------------------------
70// ctor/dtor
71// ----------------------------------------------------------------------------
72wxRegConfig::wxRegConfig(const wxString& strRoot)
6d833566 73 : m_keyLocalRoot(wxRegKey::HKCU, SOFTWARE_KEY + strRoot),
19454fa0 74 m_keyLocal(m_keyLocalRoot, ""),
6d833566 75 m_keyGlobalRoot(wxRegKey::HKLM, SOFTWARE_KEY + strRoot),
19454fa0
VZ
76 m_keyGlobal(m_keyGlobalRoot, "")
77{
78 // Create() will Open() if key already exists
79 m_keyLocalRoot.Create();
80
81 wxLogNull nolog;
82 m_keyGlobalRoot.Open();
83}
84
85wxRegConfig::~wxRegConfig()
86{
87 // nothing to do - key will be closed in their dtors
88}
89
90// ----------------------------------------------------------------------------
91// path management
92// ----------------------------------------------------------------------------
93void wxRegConfig::SetPath(const wxString& strPath)
94{
82cf4761 95 wxArrayString aParts;
19454fa0
VZ
96
97 if ( strPath.IsEmpty() )
98 return;
99
4d0c0756 100 if ( strPath[0] == wxCONFIG_PATH_SEPARATOR ) {
19454fa0 101 // absolute path
82cf4761 102 wxSplitPath(aParts, strPath);
19454fa0
VZ
103 }
104 else {
105 // relative path, combine with current one
106 wxString strFullPath = GetPath();
4d0c0756 107 strFullPath << wxCONFIG_PATH_SEPARATOR << strPath;
82cf4761 108 wxSplitPath(aParts, strFullPath);
19454fa0
VZ
109 }
110
111 // recombine path parts in one variable
112 wxString strRegPath;
113 m_strPath.Empty();
114 for ( uint n = 0; n < aParts.Count(); n++ ) {
115 strRegPath << '\\' << aParts[n];
4d0c0756 116 m_strPath << wxCONFIG_PATH_SEPARATOR << aParts[n];
19454fa0
VZ
117 }
118
119 // change current key(s)
120 m_keyLocal.SetName(m_keyLocalRoot, strRegPath);
121 m_keyGlobal.SetName(m_keyGlobalRoot, strRegPath);
122 m_keyLocal.Create();
123
124 wxLogNull nolog;
125 m_keyGlobal.Open();
126}
127
128// ----------------------------------------------------------------------------
129// enumeration (works only with current group)
130// ----------------------------------------------------------------------------
131
132/*
6d833566 133 We want to enumerate all local keys/values after the global ones, but, of
19454fa0
VZ
134 course, we don't want to repeat a key which appears locally as well as
135 globally twice.
136
137 We use the 15th bit of lIndex for distinction between global and local.
138 */
139
140#define LOCAL_MASK 0x8000
141#define IS_LOCAL_INDEX(l) (((l) & LOCAL_MASK) != 0)
142
02569ba8 143bool wxRegConfig::GetFirstGroup(wxString& str, long& lIndex) const
19454fa0
VZ
144{
145 lIndex = 0;
146 return GetNextGroup(str, lIndex);
147}
148
02569ba8 149bool wxRegConfig::GetNextGroup(wxString& str, long& lIndex) const
19454fa0
VZ
150{
151 // are we already enumerating local entries?
152 if ( m_keyGlobal.IsOpened() && !IS_LOCAL_INDEX(lIndex) ) {
153 // try to find a global entry which doesn't appear locally
154 do {
155 if ( !m_keyGlobal.GetNextKey(str, lIndex) ) {
156 // no more global entries
157 lIndex |= LOCAL_MASK;
158 break;
159 }
160 } while( m_keyLocal.HasSubKey(str) );
161 }
162
163 // much easier with local entries: get the next one we find
164 // (don't forget to clear our flag bit and set it again later)
165 lIndex &= ~LOCAL_MASK;
166 bool bOk = m_keyLocal.GetNextKey(str, lIndex);
167 lIndex |= LOCAL_MASK;
168
169 return bOk;
170}
171
02569ba8 172bool wxRegConfig::GetFirstEntry(wxString& str, long& lIndex) const
19454fa0
VZ
173{
174 lIndex = 0;
82cf4761 175 return GetNextEntry(str, lIndex);
19454fa0
VZ
176}
177
02569ba8 178bool wxRegConfig::GetNextEntry(wxString& str, long& lIndex) const
19454fa0
VZ
179{
180 // are we already enumerating local entries?
181 if ( m_keyGlobal.IsOpened() && !IS_LOCAL_INDEX(lIndex) ) {
182 // try to find a global entry which doesn't appear locally
183 do {
82cf4761 184 if ( !m_keyGlobal.GetNextValue(str, lIndex) ) {
19454fa0
VZ
185 // no more global entries
186 lIndex |= LOCAL_MASK;
187 break;
188 }
82cf4761 189 } while( m_keyLocal.HasValue(str) );
19454fa0
VZ
190 }
191
192 // much easier with local entries: get the next one we find
193 // (don't forget to clear our flag bit and set it again later)
194 lIndex &= ~LOCAL_MASK;
82cf4761 195 bool bOk = m_keyLocal.GetNextValue(str, lIndex);
19454fa0
VZ
196 lIndex |= LOCAL_MASK;
197
198 return bOk;
199}
200
6a23cbce 201uint wxRegConfig::GetNumberOfEntries(bool bRecursive) const
82cf4761
VZ
202{
203 uint nEntries = 0;
204
205 // dummy vars
206 wxString str;
207 long l;
6a23cbce 208 bool bCont = ((wxRegConfig*)this)->GetFirstEntry(str, l);
82cf4761
VZ
209 while ( bCont ) {
210 nEntries++;
211
6a23cbce 212 bCont = ((wxRegConfig*)this)->GetNextEntry(str, l);
82cf4761
VZ
213 }
214
215 return nEntries;
216}
217
6a23cbce 218uint wxRegConfig::GetNumberOfGroups(bool bRecursive) const
82cf4761
VZ
219{
220 uint nGroups = 0;
221
222 // dummy vars
223 wxString str;
224 long l;
6a23cbce 225 bool bCont = ((wxRegConfig*)this)->GetFirstGroup(str, l);
82cf4761
VZ
226 while ( bCont ) {
227 nGroups++;
228
6a23cbce 229 bCont = ((wxRegConfig*)this)->GetNextGroup(str, l);
82cf4761
VZ
230 }
231
232 return nGroups;
233}
234
6d833566
VZ
235// ----------------------------------------------------------------------------
236// tests for existence
237// ----------------------------------------------------------------------------
238
239bool wxRegConfig::HasGroup(const wxString& strName) const
240{
241 return m_keyLocal.HasSubKey(strName) || m_keyGlobal.HasSubKey(strName);
242}
243
244bool wxRegConfig::HasEntry(const wxString& strName) const
245{
246 return m_keyLocal.HasValue(strName) || m_keyGlobal.HasValue(strName);
247}
248
19454fa0
VZ
249// ----------------------------------------------------------------------------
250// reading/writing
251// ----------------------------------------------------------------------------
252
02569ba8
VZ
253bool wxRegConfig::Read(wxString *pStr,
254 const char *szKey,
255 const char *szDefault) const
19454fa0
VZ
256{
257 PathChanger path(this, szKey);
258
cf447356 259 bool bQueryGlobal = TRUE;
19454fa0
VZ
260
261 // if immutable key exists in global key we must check that it's not
262 // overriden by the local key with the same name
263 if ( IsImmutable(path.Name()) ) {
02569ba8 264 if ( TryGetValue(m_keyGlobal, path.Name(), *pStr) ) {
19454fa0 265 if ( m_keyLocal.HasValue(path.Name()) ) {
6d833566 266 wxLogWarning("User value for immutable key '%s' ignored.",
19454fa0
VZ
267 path.Name().c_str());
268 }
269
cf447356 270 return TRUE;
19454fa0
VZ
271 }
272 else {
273 // don't waste time - it's not there anyhow
cf447356 274 bQueryGlobal = FALSE;
19454fa0
VZ
275 }
276 }
277
278 // first try local key
02569ba8
VZ
279 if ( TryGetValue(m_keyLocal, path.Name(), *pStr) ||
280 (bQueryGlobal && TryGetValue(m_keyGlobal, path.Name(), *pStr)) ) {
cf447356 281 return TRUE;
19454fa0
VZ
282 }
283
baeed289 284 if(IsRecordingDefaults())
b1670f96 285 ((wxRegConfig*)this)->Write(szKey,szDefault);
baeed289 286
19454fa0 287 // default value
02569ba8 288 *pStr = szDefault;
cf447356 289 return FALSE;
19454fa0
VZ
290}
291
02569ba8 292bool wxRegConfig::Read(long *plResult, const char *szKey, long lDefault) const
19454fa0
VZ
293{
294 PathChanger path(this, szKey);
295
cf447356 296 bool bQueryGlobal = TRUE;
19454fa0
VZ
297
298 // if immutable key exists in global key we must check that it's not
299 // overriden by the local key with the same name
300 if ( IsImmutable(path.Name()) ) {
02569ba8 301 if ( TryGetValue(m_keyGlobal, path.Name(), plResult) ) {
19454fa0 302 if ( m_keyLocal.HasValue(path.Name()) ) {
6d833566 303 wxLogWarning("User value for immutable key '%s' ignored.",
19454fa0
VZ
304 path.Name().c_str());
305 }
306
cf447356 307 return TRUE;
19454fa0
VZ
308 }
309 else {
310 // don't waste time - it's not there anyhow
cf447356 311 bQueryGlobal = FALSE;
19454fa0
VZ
312 }
313 }
314
315 // first try local key
02569ba8
VZ
316 if ( TryGetValue(m_keyLocal, path.Name(), plResult) ||
317 (bQueryGlobal && TryGetValue(m_keyGlobal, path.Name(), plResult)) ) {
cf447356 318 return TRUE;
19454fa0
VZ
319 }
320
321 // default
02569ba8 322 *plResult = lDefault;
cf447356 323 return FALSE;
19454fa0
VZ
324}
325
326bool wxRegConfig::Write(const char *szKey, const char *szValue)
327{
328 PathChanger path(this, szKey);
329
330 if ( IsImmutable(path.Name()) ) {
331 wxLogError("Can't change immutable entry '%s'.", path.Name().c_str());
cf447356 332 return FALSE;
19454fa0
VZ
333 }
334
335 return m_keyLocal.SetValue(path.Name(), szValue);
336}
337
338bool wxRegConfig::Write(const char *szKey, long lValue)
339{
340 PathChanger path(this, szKey);
341
342 if ( IsImmutable(path.Name()) ) {
343 wxLogError("Can't change immutable entry '%s'.", path.Name().c_str());
cf447356 344 return FALSE;
19454fa0
VZ
345 }
346
347 return m_keyLocal.SetValue(path.Name(), lValue);
348}
349
350// ----------------------------------------------------------------------------
351// deleting
352// ----------------------------------------------------------------------------
353bool wxRegConfig::DeleteEntry(const char *szValue, bool bGroupIfEmptyAlso)
354{
355 PathChanger path(this, szValue);
356
357 if ( !m_keyLocal.DeleteValue(path.Name()) )
cf447356 358 return FALSE;
19454fa0 359
82cf4761 360 if ( !m_keyLocal.HasSubkeys() ) {
4d0c0756 361 wxString strKey = GetPath().Right(wxCONFIG_PATH_SEPARATOR);
19454fa0
VZ
362 SetPath(".."); // changes m_keyLocal
363 return m_keyLocal.DeleteKey(strKey);
364 }
365
cf447356 366 return TRUE;
19454fa0
VZ
367}
368
369bool wxRegConfig::DeleteGroup(const char *szKey)
370{
371 PathChanger path(this, szKey);
372
373 return m_keyLocal.DeleteKey(path.Name());
374}
375
376bool wxRegConfig::DeleteAll()
377{
19454fa0
VZ
378 m_keyLocal.Close();
379 m_keyGlobal.Close();
380
381 bool bOk = m_keyLocalRoot.DeleteSelf();
382 if ( bOk )
383 bOk = m_keyGlobalRoot.DeleteSelf();
384
385 return bOk;
386}