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