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