]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/iniconf.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/iniconf.cpp
3 // Purpose: implementation of wxIniConfig class
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "iniconf.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
24 #include <wx/string.h>
29 #include <wx/dynarray.h>
31 #include <wx/config.h>
33 #include <wx/msw/iniconf.h>
35 // _WINDOWS_ is defined when windows.h is included,
36 // __WXMSW__ is defined for MS Windows compilation
37 #if defined(__WXMSW__) && !defined(_WINDOWS_)
41 // ----------------------------------------------------------------------------
43 // ----------------------------------------------------------------------------
45 // we replace all path separators with this character
46 #define PATH_SEP_REPLACE '_'
48 // ============================================================================
50 // ============================================================================
52 // ----------------------------------------------------------------------------
54 // ----------------------------------------------------------------------------
56 wxIniConfig::wxIniConfig(const wxString
& strAppName
, const wxString
& strVendor
,
57 const wxString
& localFilename
, const wxString
& globalFilename
, long style
):
58 wxConfigBase(strAppName
, strVendor
, localFilename
, globalFilename
, style
)
60 if ( GetAppName().IsEmpty() )
64 app
= wxTheApp
->GetAppName();
65 wxASSERT( !app
.IsEmpty() );
69 // Vendor name is required in wxIniConfig.
70 // TODO: should it be required? Why isn't appName used instead? -- JACS
71 if ( GetVendorName().IsEmpty() )
75 vendor
= wxTheApp
->GetVendorName();
78 SetVendorName(vendor
);
81 m_strLocalFilename
= localFilename
;
82 if (m_strLocalFilename
.IsEmpty())
84 m_strLocalFilename
= GetAppName() + ".ini";
87 // append the extension if none given and it's not an absolute file name
88 // (otherwise we assume that they know what they're doing)
89 if ( !wxIsPathSeparator(m_strLocalFilename
[0u]) &&
90 m_strLocalFilename
.Find('.') == NOT_FOUND
)
92 m_strLocalFilename
<< ".ini";
99 wxIniConfig::~wxIniConfig()
103 // ----------------------------------------------------------------------------
105 // ----------------------------------------------------------------------------
107 void wxIniConfig::SetPath(const wxString
& strPath
)
109 wxArrayString aParts
;
111 if ( strPath
.IsEmpty() ) {
114 else if ( strPath
[0u] == wxCONFIG_PATH_SEPARATOR
) {
116 wxSplitPath(aParts
, strPath
);
119 // relative path, combine with current one
120 wxString strFullPath
= GetPath();
121 strFullPath
<< wxCONFIG_PATH_SEPARATOR
<< strPath
;
122 wxSplitPath(aParts
, strFullPath
);
125 size_t nPartsCount
= aParts
.Count();
127 if ( nPartsCount
== 0 ) {
129 m_strGroup
= PATH_SEP_REPLACE
;
133 m_strGroup
= aParts
[0u];
134 for ( size_t nPart
= 1; nPart
< nPartsCount
; nPart
++ ) {
136 m_strPath
<< PATH_SEP_REPLACE
;
137 m_strPath
<< aParts
[nPart
];
141 // other functions assume that all this is true, i.e. there are no trailing
142 // underscores at the end except if the group is the root one
143 wxASSERT( (m_strPath
.IsEmpty() || m_strPath
.Last() != PATH_SEP_REPLACE
) &&
144 (m_strGroup
== wxString(PATH_SEP_REPLACE
) ||
145 m_strGroup
.Last() != PATH_SEP_REPLACE
) );
148 const wxString
& wxIniConfig::GetPath() const
150 static wxString s_str
;
152 // always return abs path
153 s_str
= wxCONFIG_PATH_SEPARATOR
;
155 if ( m_strGroup
== (const char*) PATH_SEP_REPLACE
) {
156 // we're at the root level, nothing to do
160 if ( !m_strPath
.IsEmpty() )
161 s_str
<< wxCONFIG_PATH_SEPARATOR
;
162 for ( const char *p
= m_strPath
; *p
!= '\0'; p
++ ) {
163 s_str
<< (*p
== PATH_SEP_REPLACE
? wxCONFIG_PATH_SEPARATOR
: *p
);
170 wxString
wxIniConfig::GetPrivateKeyName(const wxString
& szKey
) const
174 if ( !m_strPath
.IsEmpty() )
175 strKey
<< m_strPath
<< PATH_SEP_REPLACE
;
182 wxString
wxIniConfig::GetKeyName(const wxString
& szKey
) const
186 if ( m_strGroup
!= wxString(PATH_SEP_REPLACE
) )
187 strKey
<< m_strGroup
<< PATH_SEP_REPLACE
;
188 if ( !m_strPath
.IsEmpty() )
189 strKey
<< m_strPath
<< PATH_SEP_REPLACE
;
196 // ----------------------------------------------------------------------------
198 // ----------------------------------------------------------------------------
201 bool wxIniConfig::GetFirstGroup(wxString
& str
, long& lIndex
) const
203 wxFAIL_MSG("not implemented");
208 bool wxIniConfig::GetNextGroup (wxString
& str
, long& lIndex
) const
210 wxFAIL_MSG("not implemented");
215 bool wxIniConfig::GetFirstEntry(wxString
& str
, long& lIndex
) const
217 wxFAIL_MSG("not implemented");
222 bool wxIniConfig::GetNextEntry (wxString
& str
, long& lIndex
) const
224 wxFAIL_MSG("not implemented");
229 // ----------------------------------------------------------------------------
231 // ----------------------------------------------------------------------------
234 size_t wxIniConfig::GetNumberOfEntries(bool bRecursive
) const
236 wxFAIL_MSG("not implemented");
241 size_t wxIniConfig::GetNumberOfGroups(bool bRecursive
) const
243 wxFAIL_MSG("not implemented");
248 bool wxIniConfig::HasGroup(const wxString
& strName
) const
250 wxFAIL_MSG("not implemented");
255 bool wxIniConfig::HasEntry(const wxString
& strName
) const
257 wxFAIL_MSG("not implemented");
262 // is current group empty?
263 bool wxIniConfig::IsEmpty() const
267 GetPrivateProfileString(m_strGroup
, NULL
, "",
268 szBuf
, WXSIZEOF(szBuf
), m_strLocalFilename
);
269 if ( !::IsEmpty(szBuf
) )
272 GetProfileString(m_strGroup
, NULL
, "", szBuf
, WXSIZEOF(szBuf
));
273 if ( !::IsEmpty(szBuf
) )
279 // ----------------------------------------------------------------------------
281 // ----------------------------------------------------------------------------
283 bool wxIniConfig::Read(const wxString
& szKey
, wxString
*pstr
) const
285 wxConfigPathChanger
path(this, szKey
);
286 wxString strKey
= GetPrivateKeyName(path
.Name());
288 char szBuf
[1024]; // @@ should dynamically allocate memory...
290 // first look in the private INI file
292 // NB: the lpDefault param to GetPrivateProfileString can't be NULL
293 GetPrivateProfileString(m_strGroup
, strKey
, "",
294 szBuf
, WXSIZEOF(szBuf
), m_strLocalFilename
);
295 if ( ::IsEmpty(szBuf
) ) {
296 // now look in win.ini
297 wxString strKey
= GetKeyName(path
.Name());
298 GetProfileString(m_strGroup
, strKey
, "", szBuf
, WXSIZEOF(szBuf
));
301 if ( ::IsEmpty(szBuf
) ) {
309 bool wxIniConfig::Read(const wxString
& szKey
, wxString
*pstr
,
310 const wxString
& szDefault
) const
312 wxConfigPathChanger
path(this, szKey
);
313 wxString strKey
= GetPrivateKeyName(path
.Name());
315 char szBuf
[1024]; // @@ should dynamically allocate memory...
317 // first look in the private INI file
319 // NB: the lpDefault param to GetPrivateProfileString can't be NULL
320 GetPrivateProfileString(m_strGroup
, strKey
, "",
321 szBuf
, WXSIZEOF(szBuf
), m_strLocalFilename
);
322 if ( ::IsEmpty(szBuf
) ) {
323 // now look in win.ini
324 wxString strKey
= GetKeyName(path
.Name());
325 GetProfileString(m_strGroup
, strKey
, "", szBuf
, WXSIZEOF(szBuf
));
328 if ( ::IsEmpty(szBuf
) ) {
337 bool wxIniConfig::Read(const wxString
& szKey
, long *pl
) const
339 wxConfigPathChanger
path(this, szKey
);
340 wxString strKey
= GetPrivateKeyName(path
.Name());
342 // hack: we have no mean to know if it really found the default value or
343 // didn't find anything, so we call it twice
345 static const int nMagic
= 17; // 17 is some "rare" number
346 static const int nMagic2
= 28; // arbitrary number != nMagic
347 long lVal
= GetPrivateProfileInt(m_strGroup
, strKey
, nMagic
, m_strLocalFilename
);
348 if ( lVal
!= nMagic
) {
349 // the value was read from the file
354 // is it really nMagic?
355 lVal
= GetPrivateProfileInt(m_strGroup
, strKey
, nMagic2
, m_strLocalFilename
);
356 if ( lVal
== nMagic
) {
357 // the nMagic it returned was indeed read from the file
362 // no, it was just returning the default value, so now look in win.ini
363 *pl
= GetProfileInt(GetVendorName(), GetKeyName(szKey
), *pl
);
368 bool wxIniConfig::Write(const wxString
& szKey
, const wxString
& szValue
)
370 wxConfigPathChanger
path(this, szKey
);
371 wxString strKey
= GetPrivateKeyName(path
.Name());
373 bool bOk
= WritePrivateProfileString(m_strGroup
, strKey
,
374 szValue
, m_strLocalFilename
) != 0;
377 wxLogLastError("WritePrivateProfileString");
382 bool wxIniConfig::Write(const wxString
& szKey
, long lValue
)
384 // ltoa() is not ANSI :-(
385 char szBuf
[40]; // should be good for sizeof(long) <= 16 (128 bits)
386 sprintf(szBuf
, "%ld", lValue
);
388 return Write(szKey
, szBuf
);
391 bool wxIniConfig::Flush(bool /* bCurrentOnly */)
393 // this is just the way it works
394 return WritePrivateProfileString(NULL
, NULL
, NULL
, m_strLocalFilename
) != 0;
397 // ----------------------------------------------------------------------------
399 // ----------------------------------------------------------------------------
401 bool wxIniConfig::DeleteEntry(const wxString
& szKey
, bool bGroupIfEmptyAlso
)
403 // passing NULL as value to WritePrivateProfileString deletes the key
404 if ( !Write(szKey
, (const char *)NULL
) )
407 if ( !bGroupIfEmptyAlso
|| !IsEmpty() )
410 // delete the current group too
411 bool bOk
= WritePrivateProfileString(m_strGroup
, NULL
,
412 NULL
, m_strLocalFilename
) != 0;
415 wxLogLastError("WritePrivateProfileString");
420 bool wxIniConfig::DeleteGroup(const wxString
& szKey
)
422 wxConfigPathChanger
path(this, szKey
);
424 // passing NULL as section name to WritePrivateProfileString deletes the
425 // whole section according to the docs
426 bool bOk
= WritePrivateProfileString(path
.Name(), NULL
,
427 NULL
, m_strLocalFilename
) != 0;
430 wxLogLastError("WritePrivateProfileString");
439 bool wxIniConfig::DeleteAll()
441 // first delete our group in win.ini
442 WriteProfileString(GetVendorName(), NULL
, NULL
);
444 // then delete our own ini file
445 char szBuf
[MAX_PATH
];
446 size_t nRc
= GetWindowsDirectory(szBuf
, WXSIZEOF(szBuf
));
448 wxLogLastError("GetWindowsDirectory");
449 else if ( nRc
> WXSIZEOF(szBuf
) )
450 wxFAIL_MSG("buffer is too small for Windows directory.");
452 wxString strFile
= szBuf
;
453 strFile
<< '\\' << m_strLocalFilename
;
455 if ( !wxRemoveFile(strFile
) ) {
456 wxLogSysError(_("Can't delete the INI file '%s'"), strFile
.c_str());