]>
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
7 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
21 #include "wx/msw/wrapwin.h"
22 #include "wx/dynarray.h"
23 #include "wx/string.h"
31 #include "wx/config.h"
34 #include "wx/msw/iniconf.h"
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 // we replace all path separators with this character
41 #define PATH_SEP_REPLACE '_'
43 // ============================================================================
45 // ============================================================================
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
50 IMPLEMENT_ABSTRACT_CLASS(wxIniConfig
, wxConfigBase
)
52 wxIniConfig::wxIniConfig(const wxString
& strAppName
,
53 const wxString
& strVendor
,
54 const wxString
& localFilename
,
55 const wxString
& globalFilename
,
57 : wxConfigBase(strAppName
, strVendor
, localFilename
, globalFilename
, style
)
59 #if 0 // This is too complex for some compilers, e.g. BC++ 5.01
60 : wxConfigBase((strAppName
.empty() && wxTheApp
) ? wxTheApp
->GetAppName()
62 strVendor
.empty() ? (wxTheApp
? wxTheApp
->GetVendorName()
65 localFilename
, globalFilename
, style
)
68 if (strAppName
.empty() && wxTheApp
)
69 SetAppName(wxTheApp
->GetAppName());
70 if (strVendor
.empty() && wxTheApp
)
71 SetVendorName(wxTheApp
->GetVendorName());
73 m_strLocalFilename
= localFilename
;
74 if (m_strLocalFilename
.empty())
76 m_strLocalFilename
= GetAppName() + wxT(".ini");
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]) &&
82 m_strLocalFilename
.Find(wxT('.')) == wxNOT_FOUND
)
84 m_strLocalFilename
<< wxT(".ini");
88 SetPath(wxEmptyString
);
91 wxIniConfig::~wxIniConfig()
95 // ----------------------------------------------------------------------------
97 // ----------------------------------------------------------------------------
99 void wxIniConfig::SetPath(const wxString
& strPath
)
101 wxArrayString aParts
;
103 if ( strPath
.empty() ) {
106 else if ( strPath
[0u] == wxCONFIG_PATH_SEPARATOR
) {
108 wxSplitPath(aParts
, strPath
);
111 // relative path, combine with current one
112 wxString strFullPath
= GetPath();
113 strFullPath
<< wxCONFIG_PATH_SEPARATOR
<< strPath
;
114 wxSplitPath(aParts
, strFullPath
);
117 size_t nPartsCount
= aParts
.Count();
119 if ( nPartsCount
== 0 ) {
121 m_strGroup
= PATH_SEP_REPLACE
;
125 m_strGroup
= aParts
[0u];
126 for ( size_t nPart
= 1; nPart
< nPartsCount
; nPart
++ ) {
128 m_strPath
<< PATH_SEP_REPLACE
;
129 m_strPath
<< aParts
[nPart
];
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
135 wxASSERT( (m_strPath
.empty() || m_strPath
.Last() != PATH_SEP_REPLACE
) &&
136 (m_strGroup
== wxString(PATH_SEP_REPLACE
) ||
137 m_strGroup
.Last() != PATH_SEP_REPLACE
) );
140 const wxString
& wxIniConfig::GetPath() const
142 static wxString s_str
;
144 // always return abs path
145 s_str
= wxCONFIG_PATH_SEPARATOR
;
147 if ( m_strGroup
== wxString(PATH_SEP_REPLACE
) ) {
148 // we're at the root level, nothing to do
152 if ( !m_strPath
.empty() )
153 s_str
<< wxCONFIG_PATH_SEPARATOR
;
154 for ( const wxStringCharType
*p
= m_strPath
.wx_str(); *p
!= '\0'; p
++ ) {
155 s_str
<< (*p
== PATH_SEP_REPLACE
? wxCONFIG_PATH_SEPARATOR
: *p
);
162 wxString
wxIniConfig::GetPrivateKeyName(const wxString
& szKey
) const
166 if ( !m_strPath
.empty() )
167 strKey
<< m_strPath
<< PATH_SEP_REPLACE
;
174 wxString
wxIniConfig::GetKeyName(const wxString
& szKey
) const
178 if ( m_strGroup
!= wxString(PATH_SEP_REPLACE
) )
179 strKey
<< m_strGroup
<< PATH_SEP_REPLACE
;
180 if ( !m_strPath
.empty() )
181 strKey
<< m_strPath
<< PATH_SEP_REPLACE
;
188 // ----------------------------------------------------------------------------
190 // ----------------------------------------------------------------------------
193 bool wxIniConfig::GetFirstGroup(wxString
& WXUNUSED(str
), long& WXUNUSED(lIndex
)) const
195 wxFAIL_MSG("not implemented");
200 bool wxIniConfig::GetNextGroup (wxString
& WXUNUSED(str
), long& WXUNUSED(lIndex
)) const
202 wxFAIL_MSG("not implemented");
207 bool wxIniConfig::GetFirstEntry(wxString
& WXUNUSED(str
), long& WXUNUSED(lIndex
)) const
209 wxFAIL_MSG("not implemented");
214 bool wxIniConfig::GetNextEntry (wxString
& WXUNUSED(str
), long& WXUNUSED(lIndex
)) const
216 wxFAIL_MSG("not implemented");
221 // ----------------------------------------------------------------------------
223 // ----------------------------------------------------------------------------
226 size_t wxIniConfig::GetNumberOfEntries(bool WXUNUSED(bRecursive
)) const
228 wxFAIL_MSG("not implemented");
233 size_t wxIniConfig::GetNumberOfGroups(bool WXUNUSED(bRecursive
)) const
235 wxFAIL_MSG("not implemented");
240 bool wxIniConfig::HasGroup(const wxString
& WXUNUSED(strName
)) const
242 wxFAIL_MSG("not implemented");
247 bool wxIniConfig::HasEntry(const wxString
& WXUNUSED(strName
)) const
249 wxFAIL_MSG("not implemented");
254 // is current group empty?
255 bool wxIniConfig::IsEmpty() const
259 GetPrivateProfileString(m_strGroup
.t_str(), NULL
, wxT(""),
260 szBuf
, WXSIZEOF(szBuf
),
261 m_strLocalFilename
.t_str());
262 if ( !wxIsEmpty(szBuf
) )
265 GetProfileString(m_strGroup
.t_str(), NULL
, wxT(""), szBuf
, WXSIZEOF(szBuf
));
266 if ( !wxIsEmpty(szBuf
) )
272 // ----------------------------------------------------------------------------
274 // ----------------------------------------------------------------------------
276 bool wxIniConfig::DoReadString(const wxString
& szKey
, wxString
*pstr
) const
278 wxConfigPathChanger
path(this, szKey
);
279 wxString strKey
= GetPrivateKeyName(path
.Name());
281 wxChar szBuf
[1024]; // FIXME: should dynamically allocate memory...
283 // first look in the private INI file
285 // NB: the lpDefault param to GetPrivateProfileString can't be NULL
286 GetPrivateProfileString(m_strGroup
.t_str(), strKey
.t_str(), wxT(""),
287 szBuf
, WXSIZEOF(szBuf
),
288 m_strLocalFilename
.t_str());
289 if ( wxIsEmpty(szBuf
) ) {
290 // now look in win.ini
291 wxString strKey
= GetKeyName(path
.Name());
292 GetProfileString(m_strGroup
.t_str(), strKey
.t_str(),
293 wxT(""), 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
.t_str(), strKey
.t_str(),
314 nMagic
, m_strLocalFilename
.t_str());
315 if ( lVal
!= nMagic
) {
316 // the value was read from the file
321 // is it really nMagic?
322 lVal
= GetPrivateProfileInt(m_strGroup
.t_str(), strKey
.t_str(),
323 nMagic2
, m_strLocalFilename
.t_str());
324 if ( lVal
!= nMagic2
) {
325 // the nMagic it returned was indeed read from the file
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
334 // no, it was just returning the default value, so now look in win.ini
335 *pl
= GetProfileInt(GetVendorName(), GetKeyName(szKey
), *pl
);
342 bool wxIniConfig::DoWriteString(const wxString
& szKey
, const wxString
& szValue
)
344 wxConfigPathChanger
path(this, szKey
);
345 wxString strKey
= GetPrivateKeyName(path
.Name());
347 bool bOk
= WritePrivateProfileString(m_strGroup
.t_str(), strKey
.t_str(),
349 m_strLocalFilename
.t_str()) != 0;
353 wxLogLastError(wxT("WritePrivateProfileString"));
359 bool wxIniConfig::DoWriteLong(const wxString
& szKey
, long lValue
)
361 return Write(szKey
, wxString::Format(wxT("%ld"), lValue
));
364 bool wxIniConfig::DoReadBinary(const wxString
& WXUNUSED(key
),
365 wxMemoryBuffer
* WXUNUSED(buf
)) const
367 wxFAIL_MSG("not implemented");
372 bool wxIniConfig::DoWriteBinary(const wxString
& WXUNUSED(key
),
373 const wxMemoryBuffer
& WXUNUSED(buf
))
375 wxFAIL_MSG("not implemented");
380 bool wxIniConfig::Flush(bool /* bCurrentOnly */)
382 // this is just the way it works
383 return WritePrivateProfileString(NULL
, NULL
, NULL
,
384 m_strLocalFilename
.t_str()) != 0;
387 // ----------------------------------------------------------------------------
389 // ----------------------------------------------------------------------------
391 bool wxIniConfig::DeleteEntry(const wxString
& szKey
, bool bGroupIfEmptyAlso
)
393 // passing NULL as value to WritePrivateProfileString deletes the key
394 wxConfigPathChanger
path(this, szKey
);
395 wxString strKey
= GetPrivateKeyName(path
.Name());
397 if (WritePrivateProfileString(m_strGroup
.t_str(), strKey
.t_str(),
398 NULL
, m_strLocalFilename
.t_str()) == 0)
401 if ( !bGroupIfEmptyAlso
|| !IsEmpty() )
404 // delete the current group too
405 bool bOk
= WritePrivateProfileString(m_strGroup
.t_str(), NULL
,
406 NULL
, m_strLocalFilename
.t_str()) != 0;
410 wxLogLastError(wxT("WritePrivateProfileString"));
416 bool wxIniConfig::DeleteGroup(const wxString
& szKey
)
418 wxConfigPathChanger
path(this, szKey
);
420 // passing NULL as section name to WritePrivateProfileString deletes the
421 // whole section according to the docs
422 bool bOk
= WritePrivateProfileString(path
.Name().t_str(), NULL
,
423 NULL
, m_strLocalFilename
.t_str()) != 0;
427 wxLogLastError(wxT("WritePrivateProfileString"));
437 bool wxIniConfig::DeleteAll()
439 // first delete our group in win.ini
440 WriteProfileString(GetVendorName().t_str(), NULL
, NULL
);
442 // then delete our own ini file
443 wxChar szBuf
[MAX_PATH
];
444 size_t nRc
= GetWindowsDirectory(szBuf
, WXSIZEOF(szBuf
));
447 wxLogLastError(wxT("GetWindowsDirectory"));
449 else if ( nRc
> WXSIZEOF(szBuf
) )
451 wxFAIL_MSG(wxT("buffer is too small for Windows directory."));
454 wxString strFile
= szBuf
;
455 strFile
<< '\\' << m_strLocalFilename
;
457 if ( wxFile::Exists(strFile
) && !wxRemoveFile(strFile
) ) {
458 wxLogSysError(_("Can't delete the INI file '%s'"), strFile
.c_str());
465 bool wxIniConfig::RenameEntry(const wxString
& WXUNUSED(oldName
),
466 const wxString
& WXUNUSED(newName
))
472 bool wxIniConfig::RenameGroup(const wxString
& WXUNUSED(oldName
),
473 const wxString
& WXUNUSED(newName
))
479 #endif // wxUSE_INICONF