]>
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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  13 #pragma implementation "iniconf.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  24   #include  "wx/string.h" 
  31 // Doesn't yet compile in Unicode mode 
  33 #if wxUSE_CONFIG && !wxUSE_UNICODE 
  35 #include  "wx/dynarray.h" 
  37 #include  "wx/config.h" 
  40 #include  "wx/msw/iniconf.h" 
  42 // _WINDOWS_ is defined when windows.h is included, 
  43 // __WXMSW__ is defined for MS Windows compilation 
  44 #if       defined(__WXMSW__) && !defined(_WINDOWS_) 
  45   #include  "wx/msw/wrapwin.h" 
  48 // ---------------------------------------------------------------------------- 
  50 // ---------------------------------------------------------------------------- 
  52 // we replace all path separators with this character 
  53 #define PATH_SEP_REPLACE  '_' 
  55 // ============================================================================ 
  57 // ============================================================================ 
  59 // ---------------------------------------------------------------------------- 
  61 // ---------------------------------------------------------------------------- 
  63 wxIniConfig::wxIniConfig(const wxString
& strAppName
, 
  64                          const wxString
& strVendor
, 
  65                          const wxString
& localFilename
, 
  66                          const wxString
& globalFilename
, 
  68            : wxConfigBase(strAppName
, strVendor
, localFilename
, globalFilename
, style
) 
  70 #if 0 // This is too complex for some compilers, e.g. BC++ 5.01 
  71            : wxConfigBase((strAppName
.IsEmpty() && wxTheApp
) ? wxTheApp
->GetAppName() 
  73                           strVendor
.IsEmpty() ? (wxTheApp 
? wxTheApp
->GetVendorName() 
  76                           localFilename
, globalFilename
, style
) 
  79     if (strAppName
.IsEmpty() && wxTheApp
) 
  80         SetAppName(wxTheApp
->GetAppName()); 
  81     if (strVendor
.IsEmpty() && wxTheApp
) 
  82         SetVendorName(wxTheApp
->GetVendorName()); 
  84     m_strLocalFilename 
= localFilename
; 
  85     if (m_strLocalFilename
.IsEmpty()) 
  87         m_strLocalFilename 
= GetAppName() + wxT(".ini"); 
  90     // append the extension if none given and it's not an absolute file name 
  91     // (otherwise we assume that they know what they're doing) 
  92     if ( !wxIsPathSeparator(m_strLocalFilename
[0u]) && 
  93         m_strLocalFilename
.Find(wxT('.')) == wxNOT_FOUND 
) 
  95         m_strLocalFilename 
<< wxT(".ini"); 
  99     SetPath(wxEmptyString
); 
 102 wxIniConfig::~wxIniConfig() 
 106 // ---------------------------------------------------------------------------- 
 108 // ---------------------------------------------------------------------------- 
 110 void wxIniConfig::SetPath(const wxString
& strPath
) 
 112   wxArrayString aParts
; 
 114   if ( strPath
.IsEmpty() ) { 
 117   else if ( strPath
[0u] == wxCONFIG_PATH_SEPARATOR 
) { 
 119     wxSplitPath(aParts
, strPath
); 
 122     // relative path, combine with current one 
 123     wxString strFullPath 
= GetPath(); 
 124     strFullPath 
<< wxCONFIG_PATH_SEPARATOR 
<< strPath
; 
 125     wxSplitPath(aParts
, strFullPath
); 
 128   size_t nPartsCount 
= aParts
.Count(); 
 130   if ( nPartsCount 
== 0 ) { 
 132     m_strGroup 
= PATH_SEP_REPLACE
; 
 136     m_strGroup 
= aParts
[0u]; 
 137     for ( size_t nPart 
= 1; nPart 
< nPartsCount
; nPart
++ ) { 
 139         m_strPath 
<< PATH_SEP_REPLACE
; 
 140       m_strPath 
<< aParts
[nPart
]; 
 144   // other functions assume that all this is true, i.e. there are no trailing 
 145   // underscores at the end except if the group is the root one 
 146   wxASSERT( (m_strPath
.IsEmpty() || m_strPath
.Last() != PATH_SEP_REPLACE
) && 
 147             (m_strGroup 
== wxString(PATH_SEP_REPLACE
) || 
 148              m_strGroup
.Last() != PATH_SEP_REPLACE
) ); 
 151 const wxString
& wxIniConfig::GetPath() const 
 153   static wxString s_str
; 
 155   // always return abs path 
 156   s_str 
= wxCONFIG_PATH_SEPARATOR
; 
 158   if ( m_strGroup 
== wxString(PATH_SEP_REPLACE
) ) { 
 159     // we're at the root level, nothing to do 
 163     if ( !m_strPath
.IsEmpty() ) 
 164       s_str 
<< wxCONFIG_PATH_SEPARATOR
; 
 165     for ( const char *p 
= m_strPath
; *p 
!= '\0'; p
++ ) { 
 166       s_str 
<< (*p 
== PATH_SEP_REPLACE 
? wxCONFIG_PATH_SEPARATOR 
: *p
); 
 173 wxString 
wxIniConfig::GetPrivateKeyName(const wxString
& szKey
) const 
 177   if ( !m_strPath
.IsEmpty() ) 
 178     strKey 
<< m_strPath 
<< PATH_SEP_REPLACE
; 
 185 wxString 
wxIniConfig::GetKeyName(const wxString
& szKey
) const 
 189   if ( m_strGroup 
!= wxString(PATH_SEP_REPLACE
) ) 
 190     strKey 
<< m_strGroup 
<< PATH_SEP_REPLACE
; 
 191   if ( !m_strPath
.IsEmpty() ) 
 192     strKey 
<< m_strPath 
<< PATH_SEP_REPLACE
; 
 199 // ---------------------------------------------------------------------------- 
 201 // ---------------------------------------------------------------------------- 
 204 bool wxIniConfig::GetFirstGroup(wxString
& WXUNUSED(str
), long& WXUNUSED(lIndex
)) const 
 206   wxFAIL_MSG("not implemented"); 
 211 bool wxIniConfig::GetNextGroup (wxString
& WXUNUSED(str
), long& WXUNUSED(lIndex
)) const 
 213   wxFAIL_MSG("not implemented"); 
 218 bool wxIniConfig::GetFirstEntry(wxString
& WXUNUSED(str
), long& WXUNUSED(lIndex
)) const 
 220   wxFAIL_MSG("not implemented"); 
 225 bool wxIniConfig::GetNextEntry (wxString
& WXUNUSED(str
), long& WXUNUSED(lIndex
)) const 
 227   wxFAIL_MSG("not implemented"); 
 232 // ---------------------------------------------------------------------------- 
 234 // ---------------------------------------------------------------------------- 
 237 size_t wxIniConfig::GetNumberOfEntries(bool WXUNUSED(bRecursive
)) const 
 239   wxFAIL_MSG("not implemented"); 
 244 size_t wxIniConfig::GetNumberOfGroups(bool WXUNUSED(bRecursive
)) const 
 246   wxFAIL_MSG("not implemented"); 
 251 bool wxIniConfig::HasGroup(const wxString
& WXUNUSED(strName
)) const 
 253   wxFAIL_MSG("not implemented"); 
 258 bool wxIniConfig::HasEntry(const wxString
& WXUNUSED(strName
)) const 
 260   wxFAIL_MSG("not implemented"); 
 265 // is current group empty? 
 266 bool wxIniConfig::IsEmpty() const 
 270   GetPrivateProfileString(m_strGroup
, NULL
, "", 
 271                           szBuf
, WXSIZEOF(szBuf
), m_strLocalFilename
); 
 272   if ( !::IsEmpty(szBuf
) ) 
 275   GetProfileString(m_strGroup
, NULL
, "", szBuf
, WXSIZEOF(szBuf
)); 
 276   if ( !::IsEmpty(szBuf
) ) 
 282 // ---------------------------------------------------------------------------- 
 284 // ---------------------------------------------------------------------------- 
 286 bool wxIniConfig::DoReadString(const wxString
& szKey
, wxString 
*pstr
) const 
 288   wxConfigPathChanger 
path(this, szKey
); 
 289   wxString strKey 
= GetPrivateKeyName(path
.Name()); 
 291   char szBuf
[1024]; // @@ should dynamically allocate memory... 
 293   // first look in the private INI file 
 295   // NB: the lpDefault param to GetPrivateProfileString can't be NULL 
 296   GetPrivateProfileString(m_strGroup
, strKey
, "", 
 297                           szBuf
, WXSIZEOF(szBuf
), m_strLocalFilename
); 
 298   if ( ::IsEmpty(szBuf
) ) { 
 299     // now look in win.ini 
 300     wxString strKey 
= GetKeyName(path
.Name()); 
 301     GetProfileString(m_strGroup
, strKey
, "", szBuf
, WXSIZEOF(szBuf
)); 
 304   if ( ::IsEmpty(szBuf
) ) 
 311 bool wxIniConfig::DoReadLong(const wxString
& szKey
, long *pl
) const 
 313   wxConfigPathChanger 
path(this, szKey
); 
 314   wxString strKey 
= GetPrivateKeyName(path
.Name()); 
 316   // hack: we have no mean to know if it really found the default value or 
 317   // didn't find anything, so we call it twice 
 319   static const int nMagic  
= 17; // 17 is some "rare" number 
 320   static const int nMagic2 
= 28; // arbitrary number != nMagic 
 321   long lVal 
= GetPrivateProfileInt(m_strGroup
, strKey
, nMagic
, m_strLocalFilename
); 
 322   if ( lVal 
!= nMagic 
) { 
 323     // the value was read from the file 
 328   // is it really nMagic? 
 329   lVal 
= GetPrivateProfileInt(m_strGroup
, strKey
, nMagic2
, m_strLocalFilename
); 
 330   if ( lVal 
!= nMagic2 
) { 
 331     // the nMagic it returned was indeed read from the file 
 336   // CS : I have no idea why they should look up in win.ini 
 337   // and if at all they have to do the same procedure using the two magic numbers 
 338   // otherwise it always returns true, even if the key was not there at all 
 340   // no, it was just returning the default value, so now look in win.ini 
 341  *pl 
= GetProfileInt(GetVendorName(), GetKeyName(szKey
), *pl
); 
 348 bool wxIniConfig::DoWriteString(const wxString
& szKey
, const wxString
& szValue
) 
 350   wxConfigPathChanger 
path(this, szKey
); 
 351   wxString strKey 
= GetPrivateKeyName(path
.Name()); 
 353   bool bOk 
= WritePrivateProfileString(m_strGroup
, strKey
, 
 354                                        szValue
, m_strLocalFilename
) != 0; 
 357     wxLogLastError(wxT("WritePrivateProfileString")); 
 362 bool wxIniConfig::DoWriteLong(const wxString
& szKey
, long lValue
) 
 364   // ltoa() is not ANSI :-( 
 365   char szBuf
[40];   // should be good for sizeof(long) <= 16 (128 bits) 
 366   sprintf(szBuf
, "%ld", lValue
); 
 368   return Write(szKey
, szBuf
); 
 371 bool wxIniConfig::Flush(bool /* bCurrentOnly */) 
 373   // this is just the way it works 
 374   return WritePrivateProfileString(NULL
, NULL
, NULL
, m_strLocalFilename
) != 0; 
 377 // ---------------------------------------------------------------------------- 
 379 // ---------------------------------------------------------------------------- 
 381 bool wxIniConfig::DeleteEntry(const wxString
& szKey
, bool bGroupIfEmptyAlso
) 
 383   // passing NULL as value to WritePrivateProfileString deletes the key 
 384   wxConfigPathChanger 
path(this, szKey
); 
 385   wxString strKey 
= GetPrivateKeyName(path
.Name()); 
 387   if (WritePrivateProfileString(m_strGroup
, strKey
, 
 388                                          (const char*) NULL
, m_strLocalFilename
) == 0) 
 391   if ( !bGroupIfEmptyAlso 
|| !IsEmpty() ) 
 394   // delete the current group too 
 395   bool bOk 
= WritePrivateProfileString(m_strGroup
, NULL
, 
 396                                        NULL
, m_strLocalFilename
) != 0; 
 399     wxLogLastError(wxT("WritePrivateProfileString")); 
 404 bool wxIniConfig::DeleteGroup(const wxString
& szKey
) 
 406   wxConfigPathChanger 
path(this, szKey
); 
 408   // passing NULL as section name to WritePrivateProfileString deletes the 
 409   // whole section according to the docs 
 410   bool bOk 
= WritePrivateProfileString(path
.Name(), NULL
, 
 411                                        NULL
, m_strLocalFilename
) != 0; 
 414     wxLogLastError(wxT("WritePrivateProfileString")); 
 423 bool wxIniConfig::DeleteAll() 
 425   // first delete our group in win.ini 
 426   WriteProfileString(GetVendorName(), NULL
, NULL
); 
 428   // then delete our own ini file 
 429   char szBuf
[MAX_PATH
]; 
 430   size_t nRc 
= GetWindowsDirectory(szBuf
, WXSIZEOF(szBuf
)); 
 433     wxLogLastError(wxT("GetWindowsDirectory")); 
 435   else if ( nRc 
> WXSIZEOF(szBuf
) ) 
 437     wxFAIL_MSG(wxT("buffer is too small for Windows directory.")); 
 440   wxString strFile 
= szBuf
; 
 441   strFile 
<< '\\' << m_strLocalFilename
; 
 443   if ( wxFile::Exists(strFile
) && !wxRemoveFile(strFile
) ) { 
 444     wxLogSysError(_("Can't delete the INI file '%s'"), strFile
.c_str()); 
 451 bool wxIniConfig::RenameEntry(const wxString
& WXUNUSED(oldName
), 
 452                               const wxString
& WXUNUSED(newName
)) 
 458 bool wxIniConfig::RenameGroup(const wxString
& WXUNUSED(oldName
), 
 459                               const wxString
& WXUNUSED(newName
)) 
 466     // wxUSE_CONFIG && wxUSE_UNICODE