]>
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 licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
19 // Doesn't yet compile in Unicode mode
21 #if wxUSE_CONFIG && !wxUSE_UNICODE
24 #include "wx/msw/wrapwin.h"
25 #include "wx/dynarray.h"
26 #include "wx/string.h"
34 #include "wx/config.h"
37 #include "wx/msw/iniconf.h"
39 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
43 // we replace all path separators with this character
44 #define PATH_SEP_REPLACE '_'
46 // ============================================================================
48 // ============================================================================
50 // ----------------------------------------------------------------------------
52 // ----------------------------------------------------------------------------
53 IMPLEMENT_ABSTRACT_CLASS(wxIniConfig
, wxConfigBase
)
55 wxIniConfig::wxIniConfig(const wxString
& strAppName
,
56 const wxString
& strVendor
,
57 const wxString
& localFilename
,
58 const wxString
& globalFilename
,
60 : wxConfigBase(strAppName
, strVendor
, localFilename
, globalFilename
, style
)
62 #if 0 // This is too complex for some compilers, e.g. BC++ 5.01
63 : wxConfigBase((strAppName
.empty() && wxTheApp
) ? wxTheApp
->GetAppName()
65 strVendor
.empty() ? (wxTheApp
? wxTheApp
->GetVendorName()
68 localFilename
, globalFilename
, style
)
71 if (strAppName
.empty() && wxTheApp
)
72 SetAppName(wxTheApp
->GetAppName());
73 if (strVendor
.empty() && wxTheApp
)
74 SetVendorName(wxTheApp
->GetVendorName());
76 m_strLocalFilename
= localFilename
;
77 if (m_strLocalFilename
.empty())
79 m_strLocalFilename
= GetAppName() + wxT(".ini");
82 // append the extension if none given and it's not an absolute file name
83 // (otherwise we assume that they know what they're doing)
84 if ( !wxIsPathSeparator(m_strLocalFilename
[0u]) &&
85 m_strLocalFilename
.Find(wxT('.')) == wxNOT_FOUND
)
87 m_strLocalFilename
<< wxT(".ini");
91 SetPath(wxEmptyString
);
94 wxIniConfig::~wxIniConfig()
98 // ----------------------------------------------------------------------------
100 // ----------------------------------------------------------------------------
102 void wxIniConfig::SetPath(const wxString
& strPath
)
104 wxArrayString aParts
;
106 if ( strPath
.empty() ) {
109 else if ( strPath
[0u] == wxCONFIG_PATH_SEPARATOR
) {
111 wxSplitPath(aParts
, strPath
);
114 // relative path, combine with current one
115 wxString strFullPath
= GetPath();
116 strFullPath
<< wxCONFIG_PATH_SEPARATOR
<< strPath
;
117 wxSplitPath(aParts
, strFullPath
);
120 size_t nPartsCount
= aParts
.Count();
122 if ( nPartsCount
== 0 ) {
124 m_strGroup
= PATH_SEP_REPLACE
;
128 m_strGroup
= aParts
[0u];
129 for ( size_t nPart
= 1; nPart
< nPartsCount
; nPart
++ ) {
131 m_strPath
<< PATH_SEP_REPLACE
;
132 m_strPath
<< aParts
[nPart
];
136 // other functions assume that all this is true, i.e. there are no trailing
137 // underscores at the end except if the group is the root one
138 wxASSERT( (m_strPath
.empty() || m_strPath
.Last() != PATH_SEP_REPLACE
) &&
139 (m_strGroup
== wxString(PATH_SEP_REPLACE
) ||
140 m_strGroup
.Last() != PATH_SEP_REPLACE
) );
143 const wxString
& wxIniConfig::GetPath() const
145 static wxString s_str
;
147 // always return abs path
148 s_str
= wxCONFIG_PATH_SEPARATOR
;
150 if ( m_strGroup
== wxString(PATH_SEP_REPLACE
) ) {
151 // we're at the root level, nothing to do
155 if ( !m_strPath
.empty() )
156 s_str
<< wxCONFIG_PATH_SEPARATOR
;
157 for ( const char *p
= m_strPath
; *p
!= '\0'; p
++ ) {
158 s_str
<< (*p
== PATH_SEP_REPLACE
? wxCONFIG_PATH_SEPARATOR
: *p
);
165 wxString
wxIniConfig::GetPrivateKeyName(const wxString
& szKey
) const
169 if ( !m_strPath
.empty() )
170 strKey
<< m_strPath
<< PATH_SEP_REPLACE
;
177 wxString
wxIniConfig::GetKeyName(const wxString
& szKey
) const
181 if ( m_strGroup
!= wxString(PATH_SEP_REPLACE
) )
182 strKey
<< m_strGroup
<< PATH_SEP_REPLACE
;
183 if ( !m_strPath
.empty() )
184 strKey
<< m_strPath
<< PATH_SEP_REPLACE
;
191 // ----------------------------------------------------------------------------
193 // ----------------------------------------------------------------------------
196 bool wxIniConfig::GetFirstGroup(wxString
& WXUNUSED(str
), long& WXUNUSED(lIndex
)) const
198 wxFAIL_MSG("not implemented");
203 bool wxIniConfig::GetNextGroup (wxString
& WXUNUSED(str
), long& WXUNUSED(lIndex
)) const
205 wxFAIL_MSG("not implemented");
210 bool wxIniConfig::GetFirstEntry(wxString
& WXUNUSED(str
), long& WXUNUSED(lIndex
)) const
212 wxFAIL_MSG("not implemented");
217 bool wxIniConfig::GetNextEntry (wxString
& WXUNUSED(str
), long& WXUNUSED(lIndex
)) const
219 wxFAIL_MSG("not implemented");
224 // ----------------------------------------------------------------------------
226 // ----------------------------------------------------------------------------
229 size_t wxIniConfig::GetNumberOfEntries(bool WXUNUSED(bRecursive
)) const
231 wxFAIL_MSG("not implemented");
236 size_t wxIniConfig::GetNumberOfGroups(bool WXUNUSED(bRecursive
)) const
238 wxFAIL_MSG("not implemented");
243 bool wxIniConfig::HasGroup(const wxString
& WXUNUSED(strName
)) const
245 wxFAIL_MSG("not implemented");
250 bool wxIniConfig::HasEntry(const wxString
& WXUNUSED(strName
)) const
252 wxFAIL_MSG("not implemented");
257 // is current group empty?
258 bool wxIniConfig::IsEmpty() const
262 GetPrivateProfileString(m_strGroup
, NULL
, "",
263 szBuf
, WXSIZEOF(szBuf
), m_strLocalFilename
);
264 if ( !wxIsEmpty(szBuf
) )
267 GetProfileString(m_strGroup
, NULL
, "", szBuf
, WXSIZEOF(szBuf
));
268 if ( !wxIsEmpty(szBuf
) )
274 // ----------------------------------------------------------------------------
276 // ----------------------------------------------------------------------------
278 bool wxIniConfig::DoReadString(const wxString
& szKey
, wxString
*pstr
) const
280 wxConfigPathChanger
path(this, szKey
);
281 wxString strKey
= GetPrivateKeyName(path
.Name());
283 char szBuf
[1024]; // @@ should dynamically allocate memory...
285 // first look in the private INI file
287 // NB: the lpDefault param to GetPrivateProfileString can't be NULL
288 GetPrivateProfileString(m_strGroup
, strKey
, "",
289 szBuf
, WXSIZEOF(szBuf
), m_strLocalFilename
);
290 if ( wxIsEmpty(szBuf
) ) {
291 // now look in win.ini
292 wxString strKey
= GetKeyName(path
.Name());
293 GetProfileString(m_strGroup
, strKey
, "", szBuf
, WXSIZEOF(szBuf
));
296 if ( wxIsEmpty(szBuf
) )
303 bool wxIniConfig::DoReadLong(const wxString
& szKey
, long *pl
) const
305 wxConfigPathChanger
path(this, szKey
);
306 wxString strKey
= GetPrivateKeyName(path
.Name());
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
311 static const int nMagic
= 17; // 17 is some "rare" number
312 static const int nMagic2
= 28; // arbitrary number != nMagic
313 long lVal
= GetPrivateProfileInt(m_strGroup
, strKey
, nMagic
, m_strLocalFilename
);
314 if ( lVal
!= nMagic
) {
315 // the value was read from the file
320 // is it really nMagic?
321 lVal
= GetPrivateProfileInt(m_strGroup
, strKey
, nMagic2
, m_strLocalFilename
);
322 if ( lVal
!= nMagic2
) {
323 // the nMagic it returned was indeed read from the file
328 // CS : I have no idea why they should look up in win.ini
329 // and if at all they have to do the same procedure using the two magic numbers
330 // otherwise it always returns true, even if the key was not there at all
332 // no, it was just returning the default value, so now look in win.ini
333 *pl
= GetProfileInt(GetVendorName(), GetKeyName(szKey
), *pl
);
340 bool wxIniConfig::DoWriteString(const wxString
& szKey
, const wxString
& szValue
)
342 wxConfigPathChanger
path(this, szKey
);
343 wxString strKey
= GetPrivateKeyName(path
.Name());
345 bool bOk
= WritePrivateProfileString(m_strGroup
, strKey
,
346 szValue
, m_strLocalFilename
) != 0;
349 wxLogLastError(wxT("WritePrivateProfileString"));
354 bool wxIniConfig::DoWriteLong(const wxString
& szKey
, long lValue
)
356 // ltoa() is not ANSI :-(
357 char szBuf
[40]; // should be good for sizeof(long) <= 16 (128 bits)
358 sprintf(szBuf
, "%ld", lValue
);
360 return Write(szKey
, szBuf
);
363 bool wxIniConfig::Flush(bool /* bCurrentOnly */)
365 // this is just the way it works
366 return WritePrivateProfileString(NULL
, NULL
, NULL
, m_strLocalFilename
) != 0;
369 // ----------------------------------------------------------------------------
371 // ----------------------------------------------------------------------------
373 bool wxIniConfig::DeleteEntry(const wxString
& szKey
, bool bGroupIfEmptyAlso
)
375 // passing NULL as value to WritePrivateProfileString deletes the key
376 wxConfigPathChanger
path(this, szKey
);
377 wxString strKey
= GetPrivateKeyName(path
.Name());
379 if (WritePrivateProfileString(m_strGroup
, strKey
,
380 (const char*) NULL
, m_strLocalFilename
) == 0)
383 if ( !bGroupIfEmptyAlso
|| !IsEmpty() )
386 // delete the current group too
387 bool bOk
= WritePrivateProfileString(m_strGroup
, NULL
,
388 NULL
, m_strLocalFilename
) != 0;
391 wxLogLastError(wxT("WritePrivateProfileString"));
396 bool wxIniConfig::DeleteGroup(const wxString
& szKey
)
398 wxConfigPathChanger
path(this, szKey
);
400 // passing NULL as section name to WritePrivateProfileString deletes the
401 // whole section according to the docs
402 bool bOk
= WritePrivateProfileString(path
.Name(), NULL
,
403 NULL
, m_strLocalFilename
) != 0;
406 wxLogLastError(wxT("WritePrivateProfileString"));
415 bool wxIniConfig::DeleteAll()
417 // first delete our group in win.ini
418 WriteProfileString(GetVendorName(), NULL
, NULL
);
420 // then delete our own ini file
421 char szBuf
[MAX_PATH
];
422 size_t nRc
= GetWindowsDirectory(szBuf
, WXSIZEOF(szBuf
));
425 wxLogLastError(wxT("GetWindowsDirectory"));
427 else if ( nRc
> WXSIZEOF(szBuf
) )
429 wxFAIL_MSG(wxT("buffer is too small for Windows directory."));
432 wxString strFile
= szBuf
;
433 strFile
<< '\\' << m_strLocalFilename
;
435 if ( wxFile::Exists(strFile
) && !wxRemoveFile(strFile
) ) {
436 wxLogSysError(_("Can't delete the INI file '%s'"), strFile
.c_str());
443 bool wxIniConfig::RenameEntry(const wxString
& WXUNUSED(oldName
),
444 const wxString
& WXUNUSED(newName
))
450 bool wxIniConfig::RenameGroup(const wxString
& WXUNUSED(oldName
),
451 const wxString
& WXUNUSED(newName
))
458 // wxUSE_CONFIG && wxUSE_UNICODE