]>
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 // ----------------------------------------------------------------------------
54 wxIniConfig::wxIniConfig(const wxString
& strAppName
,
55 const wxString
& strVendor
,
56 const wxString
& localFilename
,
57 const wxString
& globalFilename
,
59 : wxConfigBase(strAppName
, strVendor
, localFilename
, globalFilename
, style
)
61 #if 0 // This is too complex for some compilers, e.g. BC++ 5.01
62 : wxConfigBase((strAppName
.empty() && wxTheApp
) ? wxTheApp
->GetAppName()
64 strVendor
.empty() ? (wxTheApp
? wxTheApp
->GetVendorName()
67 localFilename
, globalFilename
, style
)
70 if (strAppName
.empty() && wxTheApp
)
71 SetAppName(wxTheApp
->GetAppName());
72 if (strVendor
.empty() && wxTheApp
)
73 SetVendorName(wxTheApp
->GetVendorName());
75 m_strLocalFilename
= localFilename
;
76 if (m_strLocalFilename
.empty())
78 m_strLocalFilename
= GetAppName() + wxT(".ini");
81 // append the extension if none given and it's not an absolute file name
82 // (otherwise we assume that they know what they're doing)
83 if ( !wxIsPathSeparator(m_strLocalFilename
[0u]) &&
84 m_strLocalFilename
.Find(wxT('.')) == wxNOT_FOUND
)
86 m_strLocalFilename
<< wxT(".ini");
90 SetPath(wxEmptyString
);
93 wxIniConfig::~wxIniConfig()
97 // ----------------------------------------------------------------------------
99 // ----------------------------------------------------------------------------
101 void wxIniConfig::SetPath(const wxString
& strPath
)
103 wxArrayString aParts
;
105 if ( strPath
.empty() ) {
108 else if ( strPath
[0u] == wxCONFIG_PATH_SEPARATOR
) {
110 wxSplitPath(aParts
, strPath
);
113 // relative path, combine with current one
114 wxString strFullPath
= GetPath();
115 strFullPath
<< wxCONFIG_PATH_SEPARATOR
<< strPath
;
116 wxSplitPath(aParts
, strFullPath
);
119 size_t nPartsCount
= aParts
.Count();
121 if ( nPartsCount
== 0 ) {
123 m_strGroup
= PATH_SEP_REPLACE
;
127 m_strGroup
= aParts
[0u];
128 for ( size_t nPart
= 1; nPart
< nPartsCount
; nPart
++ ) {
130 m_strPath
<< PATH_SEP_REPLACE
;
131 m_strPath
<< aParts
[nPart
];
135 // other functions assume that all this is true, i.e. there are no trailing
136 // underscores at the end except if the group is the root one
137 wxASSERT( (m_strPath
.empty() || m_strPath
.Last() != PATH_SEP_REPLACE
) &&
138 (m_strGroup
== wxString(PATH_SEP_REPLACE
) ||
139 m_strGroup
.Last() != PATH_SEP_REPLACE
) );
142 const wxString
& wxIniConfig::GetPath() const
144 static wxString s_str
;
146 // always return abs path
147 s_str
= wxCONFIG_PATH_SEPARATOR
;
149 if ( m_strGroup
== wxString(PATH_SEP_REPLACE
) ) {
150 // we're at the root level, nothing to do
154 if ( !m_strPath
.empty() )
155 s_str
<< wxCONFIG_PATH_SEPARATOR
;
156 for ( const char *p
= m_strPath
; *p
!= '\0'; p
++ ) {
157 s_str
<< (*p
== PATH_SEP_REPLACE
? wxCONFIG_PATH_SEPARATOR
: *p
);
164 wxString
wxIniConfig::GetPrivateKeyName(const wxString
& szKey
) const
168 if ( !m_strPath
.empty() )
169 strKey
<< m_strPath
<< PATH_SEP_REPLACE
;
176 wxString
wxIniConfig::GetKeyName(const wxString
& szKey
) const
180 if ( m_strGroup
!= wxString(PATH_SEP_REPLACE
) )
181 strKey
<< m_strGroup
<< PATH_SEP_REPLACE
;
182 if ( !m_strPath
.empty() )
183 strKey
<< m_strPath
<< PATH_SEP_REPLACE
;
190 // ----------------------------------------------------------------------------
192 // ----------------------------------------------------------------------------
195 bool wxIniConfig::GetFirstGroup(wxString
& WXUNUSED(str
), long& WXUNUSED(lIndex
)) const
197 wxFAIL_MSG("not implemented");
202 bool wxIniConfig::GetNextGroup (wxString
& WXUNUSED(str
), long& WXUNUSED(lIndex
)) const
204 wxFAIL_MSG("not implemented");
209 bool wxIniConfig::GetFirstEntry(wxString
& WXUNUSED(str
), long& WXUNUSED(lIndex
)) const
211 wxFAIL_MSG("not implemented");
216 bool wxIniConfig::GetNextEntry (wxString
& WXUNUSED(str
), long& WXUNUSED(lIndex
)) const
218 wxFAIL_MSG("not implemented");
223 // ----------------------------------------------------------------------------
225 // ----------------------------------------------------------------------------
228 size_t wxIniConfig::GetNumberOfEntries(bool WXUNUSED(bRecursive
)) const
230 wxFAIL_MSG("not implemented");
235 size_t wxIniConfig::GetNumberOfGroups(bool WXUNUSED(bRecursive
)) const
237 wxFAIL_MSG("not implemented");
242 bool wxIniConfig::HasGroup(const wxString
& WXUNUSED(strName
)) const
244 wxFAIL_MSG("not implemented");
249 bool wxIniConfig::HasEntry(const wxString
& WXUNUSED(strName
)) const
251 wxFAIL_MSG("not implemented");
256 // is current group empty?
257 bool wxIniConfig::IsEmpty() const
261 GetPrivateProfileString(m_strGroup
, NULL
, "",
262 szBuf
, WXSIZEOF(szBuf
), m_strLocalFilename
);
263 if ( !::IsEmpty(szBuf
) )
266 GetProfileString(m_strGroup
, NULL
, "", szBuf
, WXSIZEOF(szBuf
));
267 if ( !::IsEmpty(szBuf
) )
273 // ----------------------------------------------------------------------------
275 // ----------------------------------------------------------------------------
277 bool wxIniConfig::DoReadString(const wxString
& szKey
, wxString
*pstr
) const
279 wxConfigPathChanger
path(this, szKey
);
280 wxString strKey
= GetPrivateKeyName(path
.Name());
282 char szBuf
[1024]; // @@ should dynamically allocate memory...
284 // first look in the private INI file
286 // NB: the lpDefault param to GetPrivateProfileString can't be NULL
287 GetPrivateProfileString(m_strGroup
, strKey
, "",
288 szBuf
, WXSIZEOF(szBuf
), m_strLocalFilename
);
289 if ( ::IsEmpty(szBuf
) ) {
290 // now look in win.ini
291 wxString strKey
= GetKeyName(path
.Name());
292 GetProfileString(m_strGroup
, strKey
, "", szBuf
, WXSIZEOF(szBuf
));
295 if ( ::IsEmpty(szBuf
) )
302 bool wxIniConfig::DoReadLong(const wxString
& szKey
, long *pl
) const
304 wxConfigPathChanger
path(this, szKey
);
305 wxString strKey
= GetPrivateKeyName(path
.Name());
307 // hack: we have no mean to know if it really found the default value or
308 // didn't find anything, so we call it twice
310 static const int nMagic
= 17; // 17 is some "rare" number
311 static const int nMagic2
= 28; // arbitrary number != nMagic
312 long lVal
= GetPrivateProfileInt(m_strGroup
, strKey
, nMagic
, m_strLocalFilename
);
313 if ( lVal
!= nMagic
) {
314 // the value was read from the file
319 // is it really nMagic?
320 lVal
= GetPrivateProfileInt(m_strGroup
, strKey
, nMagic2
, m_strLocalFilename
);
321 if ( lVal
!= nMagic2
) {
322 // the nMagic it returned was indeed read from the file
327 // CS : I have no idea why they should look up in win.ini
328 // and if at all they have to do the same procedure using the two magic numbers
329 // otherwise it always returns true, even if the key was not there at all
331 // no, it was just returning the default value, so now look in win.ini
332 *pl
= GetProfileInt(GetVendorName(), GetKeyName(szKey
), *pl
);
339 bool wxIniConfig::DoWriteString(const wxString
& szKey
, const wxString
& szValue
)
341 wxConfigPathChanger
path(this, szKey
);
342 wxString strKey
= GetPrivateKeyName(path
.Name());
344 bool bOk
= WritePrivateProfileString(m_strGroup
, strKey
,
345 szValue
, m_strLocalFilename
) != 0;
348 wxLogLastError(wxT("WritePrivateProfileString"));
353 bool wxIniConfig::DoWriteLong(const wxString
& szKey
, long lValue
)
355 // ltoa() is not ANSI :-(
356 char szBuf
[40]; // should be good for sizeof(long) <= 16 (128 bits)
357 sprintf(szBuf
, "%ld", lValue
);
359 return Write(szKey
, szBuf
);
362 bool wxIniConfig::Flush(bool /* bCurrentOnly */)
364 // this is just the way it works
365 return WritePrivateProfileString(NULL
, NULL
, NULL
, m_strLocalFilename
) != 0;
368 // ----------------------------------------------------------------------------
370 // ----------------------------------------------------------------------------
372 bool wxIniConfig::DeleteEntry(const wxString
& szKey
, bool bGroupIfEmptyAlso
)
374 // passing NULL as value to WritePrivateProfileString deletes the key
375 wxConfigPathChanger
path(this, szKey
);
376 wxString strKey
= GetPrivateKeyName(path
.Name());
378 if (WritePrivateProfileString(m_strGroup
, strKey
,
379 (const char*) NULL
, m_strLocalFilename
) == 0)
382 if ( !bGroupIfEmptyAlso
|| !IsEmpty() )
385 // delete the current group too
386 bool bOk
= WritePrivateProfileString(m_strGroup
, NULL
,
387 NULL
, m_strLocalFilename
) != 0;
390 wxLogLastError(wxT("WritePrivateProfileString"));
395 bool wxIniConfig::DeleteGroup(const wxString
& szKey
)
397 wxConfigPathChanger
path(this, szKey
);
399 // passing NULL as section name to WritePrivateProfileString deletes the
400 // whole section according to the docs
401 bool bOk
= WritePrivateProfileString(path
.Name(), NULL
,
402 NULL
, m_strLocalFilename
) != 0;
405 wxLogLastError(wxT("WritePrivateProfileString"));
414 bool wxIniConfig::DeleteAll()
416 // first delete our group in win.ini
417 WriteProfileString(GetVendorName(), NULL
, NULL
);
419 // then delete our own ini file
420 char szBuf
[MAX_PATH
];
421 size_t nRc
= GetWindowsDirectory(szBuf
, WXSIZEOF(szBuf
));
424 wxLogLastError(wxT("GetWindowsDirectory"));
426 else if ( nRc
> WXSIZEOF(szBuf
) )
428 wxFAIL_MSG(wxT("buffer is too small for Windows directory."));
431 wxString strFile
= szBuf
;
432 strFile
<< '\\' << m_strLocalFilename
;
434 if ( wxFile::Exists(strFile
) && !wxRemoveFile(strFile
) ) {
435 wxLogSysError(_("Can't delete the INI file '%s'"), strFile
.c_str());
442 bool wxIniConfig::RenameEntry(const wxString
& WXUNUSED(oldName
),
443 const wxString
& WXUNUSED(newName
))
449 bool wxIniConfig::RenameGroup(const wxString
& WXUNUSED(oldName
),
450 const wxString
& WXUNUSED(newName
))
457 // wxUSE_CONFIG && wxUSE_UNICODE