]>
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