]> git.saurik.com Git - wxWidgets.git/blame - src/msw/iniconf.cpp
Remove support for Gnome printing from wxGTK.
[wxWidgets.git] / src / msw / iniconf.cpp
CommitLineData
02569ba8
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/msw/iniconf.cpp
3// Purpose: implementation of wxIniConfig class
4// Author: Vadim Zeitlin
9869734d 5// Modified by:
02569ba8 6// Created: 27.07.98
02569ba8 7// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
65571936 8// Licence: wxWindows licence
02569ba8
VZ
9///////////////////////////////////////////////////////////////////////////////
10
a3b46648
UU
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
02569ba8 13
a3b46648 14#ifdef __BORLANDC__
ad9835c9 15 #pragma hdrstop
a3b46648 16#endif
02569ba8 17
61873536 18#if wxUSE_INICONF
f6bcfd97 19
ad9835c9 20#ifndef WX_PRECOMP
57bd4c60
WS
21 #include "wx/msw/wrapwin.h"
22 #include "wx/dynarray.h"
23 #include "wx/string.h"
24 #include "wx/intl.h"
25 #include "wx/event.h"
26 #include "wx/app.h"
27 #include "wx/utils.h"
28 #include "wx/log.h"
ad9835c9
WS
29#endif //WX_PRECOMP
30
3096bd2f 31#include "wx/config.h"
999836aa 32#include "wx/file.h"
02569ba8 33
3096bd2f 34#include "wx/msw/iniconf.h"
02569ba8 35
02569ba8
VZ
36// ----------------------------------------------------------------------------
37// constants
38// ----------------------------------------------------------------------------
39
40// we replace all path separators with this character
41#define PATH_SEP_REPLACE '_'
42
43// ============================================================================
44// implementation
45// ============================================================================
46
47// ----------------------------------------------------------------------------
48// ctor & dtor
49// ----------------------------------------------------------------------------
c4ec0ce8 50IMPLEMENT_ABSTRACT_CLASS(wxIniConfig, wxConfigBase)
02569ba8 51
9869734d
VZ
52wxIniConfig::wxIniConfig(const wxString& strAppName,
53 const wxString& strVendor,
54 const wxString& localFilename,
55 const wxString& globalFilename,
56 long style)
8f19c916
JS
57 : wxConfigBase(strAppName, strVendor, localFilename, globalFilename, style)
58
59#if 0 // This is too complex for some compilers, e.g. BC++ 5.01
ad9835c9 60 : wxConfigBase((strAppName.empty() && wxTheApp) ? wxTheApp->GetAppName()
d2c7e39b 61 : strAppName,
ad9835c9 62 strVendor.empty() ? (wxTheApp ? wxTheApp->GetVendorName()
d2c7e39b
JS
63 : strAppName)
64 : strVendor,
65 localFilename, globalFilename, style)
8f19c916 66#endif
02569ba8 67{
ad9835c9 68 if (strAppName.empty() && wxTheApp)
8f19c916 69 SetAppName(wxTheApp->GetAppName());
ad9835c9 70 if (strVendor.empty() && wxTheApp)
8f19c916
JS
71 SetVendorName(wxTheApp->GetVendorName());
72
18244936 73 m_strLocalFilename = localFilename;
ad9835c9 74 if (m_strLocalFilename.empty())
18244936 75 {
f6bcfd97 76 m_strLocalFilename = GetAppName() + wxT(".ini");
18244936
JS
77 }
78
79 // append the extension if none given and it's not an absolute file name
80 // (otherwise we assume that they know what they're doing)
81 if ( !wxIsPathSeparator(m_strLocalFilename[0u]) &&
f6bcfd97 82 m_strLocalFilename.Find(wxT('.')) == wxNOT_FOUND )
18244936 83 {
f6bcfd97 84 m_strLocalFilename << wxT(".ini");
18244936
JS
85 }
86
87 // set root path
fda7962d 88 SetPath(wxEmptyString);
02569ba8
VZ
89}
90
91wxIniConfig::~wxIniConfig()
92{
93}
94
95// ----------------------------------------------------------------------------
96// path management
97// ----------------------------------------------------------------------------
98
99void wxIniConfig::SetPath(const wxString& strPath)
100{
101 wxArrayString aParts;
102
ad9835c9 103 if ( strPath.empty() ) {
02569ba8
VZ
104 // nothing
105 }
106 else if ( strPath[0u] == wxCONFIG_PATH_SEPARATOR ) {
107 // absolute path
108 wxSplitPath(aParts, strPath);
109 }
110 else {
111 // relative path, combine with current one
112 wxString strFullPath = GetPath();
113 strFullPath << wxCONFIG_PATH_SEPARATOR << strPath;
114 wxSplitPath(aParts, strFullPath);
115 }
116
c86f1403 117 size_t nPartsCount = aParts.Count();
02569ba8
VZ
118 m_strPath.Empty();
119 if ( nPartsCount == 0 ) {
120 // go to the root
121 m_strGroup = PATH_SEP_REPLACE;
122 }
123 else {
124 // translate
125 m_strGroup = aParts[0u];
c86f1403 126 for ( size_t nPart = 1; nPart < nPartsCount; nPart++ ) {
02569ba8
VZ
127 if ( nPart > 1 )
128 m_strPath << PATH_SEP_REPLACE;
129 m_strPath << aParts[nPart];
130 }
131 }
132
133 // other functions assume that all this is true, i.e. there are no trailing
134 // underscores at the end except if the group is the root one
ad9835c9 135 wxASSERT( (m_strPath.empty() || m_strPath.Last() != PATH_SEP_REPLACE) &&
62448488 136 (m_strGroup == wxString(PATH_SEP_REPLACE) ||
02569ba8
VZ
137 m_strGroup.Last() != PATH_SEP_REPLACE) );
138}
139
140const wxString& wxIniConfig::GetPath() const
141{
142 static wxString s_str;
143
144 // always return abs path
145 s_str = wxCONFIG_PATH_SEPARATOR;
146
ce3ed50d 147 if ( m_strGroup == wxString(PATH_SEP_REPLACE) ) {
02569ba8
VZ
148 // we're at the root level, nothing to do
149 }
150 else {
151 s_str << m_strGroup;
ad9835c9 152 if ( !m_strPath.empty() )
02569ba8 153 s_str << wxCONFIG_PATH_SEPARATOR;
414721d0 154 for ( const wxStringCharType *p = m_strPath.wx_str(); *p != '\0'; p++ ) {
02569ba8
VZ
155 s_str << (*p == PATH_SEP_REPLACE ? wxCONFIG_PATH_SEPARATOR : *p);
156 }
157 }
158
159 return s_str;
160}
161
18244936 162wxString wxIniConfig::GetPrivateKeyName(const wxString& szKey) const
02569ba8
VZ
163{
164 wxString strKey;
165
ad9835c9 166 if ( !m_strPath.empty() )
02569ba8
VZ
167 strKey << m_strPath << PATH_SEP_REPLACE;
168
169 strKey << szKey;
170
171 return strKey;
172}
173
18244936 174wxString wxIniConfig::GetKeyName(const wxString& szKey) const
02569ba8
VZ
175{
176 wxString strKey;
177
62448488 178 if ( m_strGroup != wxString(PATH_SEP_REPLACE) )
02569ba8 179 strKey << m_strGroup << PATH_SEP_REPLACE;
ad9835c9 180 if ( !m_strPath.empty() )
02569ba8
VZ
181 strKey << m_strPath << PATH_SEP_REPLACE;
182
183 strKey << szKey;
184
185 return strKey;
186}
187
188// ----------------------------------------------------------------------------
189// enumeration
190// ----------------------------------------------------------------------------
191
192// not implemented
2eb10e2a 193bool wxIniConfig::GetFirstGroup(wxString& WXUNUSED(str), long& WXUNUSED(lIndex)) const
02569ba8 194{
ad9835c9 195 wxFAIL_MSG("not implemented");
02569ba8 196
ad9835c9 197 return false;
02569ba8
VZ
198}
199
2eb10e2a 200bool wxIniConfig::GetNextGroup (wxString& WXUNUSED(str), long& WXUNUSED(lIndex)) const
02569ba8 201{
ad9835c9 202 wxFAIL_MSG("not implemented");
02569ba8 203
ad9835c9 204 return false;
02569ba8
VZ
205}
206
2eb10e2a 207bool wxIniConfig::GetFirstEntry(wxString& WXUNUSED(str), long& WXUNUSED(lIndex)) const
02569ba8 208{
ad9835c9 209 wxFAIL_MSG("not implemented");
02569ba8 210
ad9835c9 211 return false;
02569ba8
VZ
212}
213
2eb10e2a 214bool wxIniConfig::GetNextEntry (wxString& WXUNUSED(str), long& WXUNUSED(lIndex)) const
02569ba8 215{
ad9835c9 216 wxFAIL_MSG("not implemented");
02569ba8 217
ad9835c9 218 return false;
02569ba8
VZ
219}
220
221// ----------------------------------------------------------------------------
222// misc info
223// ----------------------------------------------------------------------------
224
225// not implemented
2eb10e2a 226size_t wxIniConfig::GetNumberOfEntries(bool WXUNUSED(bRecursive)) const
02569ba8 227{
ad9835c9 228 wxFAIL_MSG("not implemented");
02569ba8 229
ad9835c9 230 return (size_t)-1;
02569ba8
VZ
231}
232
2eb10e2a 233size_t wxIniConfig::GetNumberOfGroups(bool WXUNUSED(bRecursive)) const
02569ba8 234{
ad9835c9 235 wxFAIL_MSG("not implemented");
02569ba8 236
ad9835c9 237 return (size_t)-1;
02569ba8
VZ
238}
239
2eb10e2a 240bool wxIniConfig::HasGroup(const wxString& WXUNUSED(strName)) const
02569ba8 241{
ad9835c9 242 wxFAIL_MSG("not implemented");
02569ba8 243
ad9835c9 244 return false;
02569ba8
VZ
245}
246
2eb10e2a 247bool wxIniConfig::HasEntry(const wxString& WXUNUSED(strName)) const
02569ba8 248{
ad9835c9 249 wxFAIL_MSG("not implemented");
02569ba8 250
ad9835c9 251 return false;
02569ba8
VZ
252}
253
254// is current group empty?
255bool wxIniConfig::IsEmpty() const
256{
7b673bef 257 wxChar szBuf[1024];
02569ba8 258
017dc06b 259 GetPrivateProfileString(m_strGroup.t_str(), NULL, wxT(""),
414721d0 260 szBuf, WXSIZEOF(szBuf),
017dc06b 261 m_strLocalFilename.t_str());
342a2719 262 if ( !wxIsEmpty(szBuf) )
ad9835c9 263 return false;
02569ba8 264
017dc06b 265 GetProfileString(m_strGroup.t_str(), NULL, wxT(""), szBuf, WXSIZEOF(szBuf));
342a2719 266 if ( !wxIsEmpty(szBuf) )
ad9835c9 267 return false;
02569ba8 268
ad9835c9 269 return true;
02569ba8
VZ
270}
271
272// ----------------------------------------------------------------------------
273// read/write
274// ----------------------------------------------------------------------------
275
2ba41305 276bool wxIniConfig::DoReadString(const wxString& szKey, wxString *pstr) const
02569ba8 277{
18244936 278 wxConfigPathChanger path(this, szKey);
02569ba8
VZ
279 wxString strKey = GetPrivateKeyName(path.Name());
280
7b673bef 281 wxChar szBuf[1024]; // FIXME: should dynamically allocate memory...
02569ba8
VZ
282
283 // first look in the private INI file
284
285 // NB: the lpDefault param to GetPrivateProfileString can't be NULL
017dc06b 286 GetPrivateProfileString(m_strGroup.t_str(), strKey.t_str(), wxT(""),
414721d0 287 szBuf, WXSIZEOF(szBuf),
017dc06b 288 m_strLocalFilename.t_str());
342a2719 289 if ( wxIsEmpty(szBuf) ) {
02569ba8
VZ
290 // now look in win.ini
291 wxString strKey = GetKeyName(path.Name());
017dc06b 292 GetProfileString(m_strGroup.t_str(), strKey.t_str(),
9a83f860 293 wxT(""), szBuf, WXSIZEOF(szBuf));
02569ba8
VZ
294 }
295
342a2719 296 if ( wxIsEmpty(szBuf) )
59af881e 297 return false;
0cb50c83
VZ
298
299 *pstr = szBuf;
59af881e 300 return true;
02569ba8
VZ
301}
302
2ba41305 303bool wxIniConfig::DoReadLong(const wxString& szKey, long *pl) const
02569ba8 304{
18244936 305 wxConfigPathChanger path(this, szKey);
02569ba8
VZ
306 wxString strKey = GetPrivateKeyName(path.Name());
307
308 // hack: we have no mean to know if it really found the default value or
309 // didn't find anything, so we call it twice
310
311 static const int nMagic = 17; // 17 is some "rare" number
312 static const int nMagic2 = 28; // arbitrary number != nMagic
017dc06b
VZ
313 long lVal = GetPrivateProfileInt(m_strGroup.t_str(), strKey.t_str(),
314 nMagic, m_strLocalFilename.t_str());
02569ba8
VZ
315 if ( lVal != nMagic ) {
316 // the value was read from the file
317 *pl = lVal;
59af881e 318 return true;
02569ba8
VZ
319 }
320
321 // is it really nMagic?
017dc06b
VZ
322 lVal = GetPrivateProfileInt(m_strGroup.t_str(), strKey.t_str(),
323 nMagic2, m_strLocalFilename.t_str());
519cb848 324 if ( lVal != nMagic2 ) {
02569ba8
VZ
325 // the nMagic it returned was indeed read from the file
326 *pl = lVal;
59af881e 327 return true;
02569ba8
VZ
328 }
329
519cb848
SC
330 // CS : I have no idea why they should look up in win.ini
331 // and if at all they have to do the same procedure using the two magic numbers
332 // otherwise it always returns true, even if the key was not there at all
333#if 0
02569ba8 334 // no, it was just returning the default value, so now look in win.ini
519cb848 335 *pl = GetProfileInt(GetVendorName(), GetKeyName(szKey), *pl);
02569ba8 336
59af881e 337 return true;
519cb848 338#endif
59af881e 339 return false ;
02569ba8
VZ
340}
341
2ba41305 342bool wxIniConfig::DoWriteString(const wxString& szKey, const wxString& szValue)
02569ba8 343{
18244936 344 wxConfigPathChanger path(this, szKey);
02569ba8
VZ
345 wxString strKey = GetPrivateKeyName(path.Name());
346
017dc06b
VZ
347 bool bOk = WritePrivateProfileString(m_strGroup.t_str(), strKey.t_str(),
348 szValue.t_str(),
349 m_strLocalFilename.t_str()) != 0;
02569ba8
VZ
350
351 if ( !bOk )
43b2d5e7 352 {
f6bcfd97 353 wxLogLastError(wxT("WritePrivateProfileString"));
43b2d5e7 354 }
02569ba8
VZ
355
356 return bOk;
357}
358
2ba41305 359bool wxIniConfig::DoWriteLong(const wxString& szKey, long lValue)
02569ba8 360{
9a83f860 361 return Write(szKey, wxString::Format(wxT("%ld"), lValue));
02569ba8
VZ
362}
363
11c467ef
VZ
364bool wxIniConfig::DoReadBinary(const wxString& WXUNUSED(key),
365 wxMemoryBuffer * WXUNUSED(buf)) const
366{
367 wxFAIL_MSG("not implemented");
368
369 return false;
370}
371
372bool wxIniConfig::DoWriteBinary(const wxString& WXUNUSED(key),
373 const wxMemoryBuffer& WXUNUSED(buf))
374{
375 wxFAIL_MSG("not implemented");
376
377 return false;
378}
379
02569ba8
VZ
380bool wxIniConfig::Flush(bool /* bCurrentOnly */)
381{
382 // this is just the way it works
414721d0 383 return WritePrivateProfileString(NULL, NULL, NULL,
017dc06b 384 m_strLocalFilename.t_str()) != 0;
02569ba8
VZ
385}
386
387// ----------------------------------------------------------------------------
388// delete
389// ----------------------------------------------------------------------------
390
1e6d9499 391bool wxIniConfig::DeleteEntry(const wxString& szKey, bool bGroupIfEmptyAlso)
02569ba8
VZ
392{
393 // passing NULL as value to WritePrivateProfileString deletes the key
2432b92d
JS
394 wxConfigPathChanger path(this, szKey);
395 wxString strKey = GetPrivateKeyName(path.Name());
396
017dc06b
VZ
397 if (WritePrivateProfileString(m_strGroup.t_str(), strKey.t_str(),
398 NULL, m_strLocalFilename.t_str()) == 0)
59af881e 399 return false;
2432b92d 400
02569ba8 401 if ( !bGroupIfEmptyAlso || !IsEmpty() )
59af881e 402 return true;
02569ba8
VZ
403
404 // delete the current group too
017dc06b
VZ
405 bool bOk = WritePrivateProfileString(m_strGroup.t_str(), NULL,
406 NULL, m_strLocalFilename.t_str()) != 0;
02569ba8
VZ
407
408 if ( !bOk )
43b2d5e7 409 {
f6bcfd97 410 wxLogLastError(wxT("WritePrivateProfileString"));
43b2d5e7 411 }
02569ba8
VZ
412
413 return bOk;
414}
415
1e6d9499 416bool wxIniConfig::DeleteGroup(const wxString& szKey)
02569ba8 417{
18244936 418 wxConfigPathChanger path(this, szKey);
02569ba8 419
9869734d 420 // passing NULL as section name to WritePrivateProfileString deletes the
02569ba8 421 // whole section according to the docs
017dc06b
VZ
422 bool bOk = WritePrivateProfileString(path.Name().t_str(), NULL,
423 NULL, m_strLocalFilename.t_str()) != 0;
02569ba8
VZ
424
425 if ( !bOk )
43b2d5e7 426 {
f6bcfd97 427 wxLogLastError(wxT("WritePrivateProfileString"));
43b2d5e7 428 }
02569ba8
VZ
429
430 return bOk;
431}
432
1e6d9499
JS
433#ifndef MAX_PATH
434#define MAX_PATH 256
435#endif
436
02569ba8
VZ
437bool wxIniConfig::DeleteAll()
438{
439 // first delete our group in win.ini
017dc06b 440 WriteProfileString(GetVendorName().t_str(), NULL, NULL);
02569ba8
VZ
441
442 // then delete our own ini file
7b673bef 443 wxChar szBuf[MAX_PATH];
c86f1403 444 size_t nRc = GetWindowsDirectory(szBuf, WXSIZEOF(szBuf));
02569ba8 445 if ( nRc == 0 )
a1665b22 446 {
f6bcfd97 447 wxLogLastError(wxT("GetWindowsDirectory"));
a1665b22 448 }
02569ba8 449 else if ( nRc > WXSIZEOF(szBuf) )
a1665b22 450 {
f6bcfd97 451 wxFAIL_MSG(wxT("buffer is too small for Windows directory."));
a1665b22 452 }
02569ba8
VZ
453
454 wxString strFile = szBuf;
18244936 455 strFile << '\\' << m_strLocalFilename;
02569ba8 456
cb820f80 457 if ( wxFile::Exists(strFile) && !wxRemoveFile(strFile) ) {
02569ba8 458 wxLogSysError(_("Can't delete the INI file '%s'"), strFile.c_str());
59af881e 459 return false;
02569ba8
VZ
460 }
461
59af881e 462 return true;
02569ba8 463}
574c0bbf 464
2eb10e2a
VZ
465bool wxIniConfig::RenameEntry(const wxString& WXUNUSED(oldName),
466 const wxString& WXUNUSED(newName))
574c0bbf
JS
467{
468 // Not implemented
59af881e 469 return false;
574c0bbf
JS
470}
471
2eb10e2a
VZ
472bool wxIniConfig::RenameGroup(const wxString& WXUNUSED(oldName),
473 const wxString& WXUNUSED(newName))
574c0bbf
JS
474{
475 // Not implemented
59af881e 476 return false;
574c0bbf 477}
f6bcfd97 478
61873536 479#endif // wxUSE_INICONF