X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/57436bb7dbd331de64d05007960aa1fc966f8de9..974dee61a9a0f72652488fc4120a82846990345b:/src/common/fileconf.cpp diff --git a/src/common/fileconf.cpp b/src/common/fileconf.cpp index c70e7e5a5c..a3bcdb5983 100644 --- a/src/common/fileconf.cpp +++ b/src/common/fileconf.cpp @@ -14,46 +14,45 @@ // headers // ---------------------------------------------------------------------------- +// For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ - #pragma hdrstop + #pragma hdrstop #endif //__BORLANDC__ #if wxUSE_CONFIG && wxUSE_FILECONFIG #ifndef WX_PRECOMP - #include "wx/string.h" - #include "wx/intl.h" + #include "wx/dynarray.h" + #include "wx/string.h" + #include "wx/intl.h" + #include "wx/log.h" + #include "wx/app.h" + #include "wx/utils.h" // for wxGetHomeDir + #if wxUSE_STREAMS + #include "wx/stream.h" + #endif // wxUSE_STREAMS #endif //WX_PRECOMP -#include "wx/app.h" -#include "wx/dynarray.h" #include "wx/file.h" -#include "wx/log.h" #include "wx/textfile.h" #include "wx/memtext.h" #include "wx/config.h" #include "wx/fileconf.h" #include "wx/filefn.h" -#if wxUSE_STREAMS - #include "wx/stream.h" -#endif // wxUSE_STREAMS - -#include "wx/utils.h" // for wxGetHomeDir - #if defined(__WXMAC__) - #include "wx/mac/private.h" // includes mac headers - #include "wx/filename.h" // for MacSetTypeAndCreator + #include "wx/mac/private.h" // includes mac headers + #include "wx/filename.h" // for MacSetTypeAndCreator #endif #if defined(__WXMSW__) - #include "wx/msw/private.h" + #include "wx/msw/private.h" #endif //windows.h #if defined(__WXPM__) - #define INCL_DOS - #include + #define INCL_DOS + #include #endif #include @@ -69,7 +68,7 @@ // ---------------------------------------------------------------------------- #ifndef MAX_PATH - #define MAX_PATH 512 + #define MAX_PATH 512 #endif #define FILECONF_TRACE_MASK _T("fileconf") @@ -283,7 +282,7 @@ wxString wxFileConfig::GetGlobalDir() strDir.Printf(wxT("%c:\\OS2\\"), 'A'+drive-1); } #elif defined(__WXSTUBS__) - wxASSERT_MSG( false, wxT("TODO") ) ; + wxFAIL_MSG( wxT("TODO") ); #elif defined(__DOS__) // There's no such thing as global cfg dir in MS-DOS, let's return // current directory (FIXME_MGL?) @@ -394,7 +393,7 @@ void wxFileConfig::Init() { wxTextFile fileGlobal(m_strGlobalFile); - if ( fileGlobal.Open(m_conv/*ignored in ANSI build*/) ) + if ( fileGlobal.Open(*m_conv/*ignored in ANSI build*/) ) { Parse(fileGlobal, false /* global */); SetRootPath(); @@ -409,7 +408,7 @@ void wxFileConfig::Init() if ( !m_strLocalFile.empty() && wxFile::Exists(m_strLocalFile) ) { wxTextFile fileLocal(m_strLocalFile); - if ( fileLocal.Open(m_conv/*ignored in ANSI build*/) ) + if ( fileLocal.Open(*m_conv/*ignored in ANSI build*/) ) { Parse(fileLocal, true /* local */); SetRootPath(); @@ -426,12 +425,13 @@ void wxFileConfig::Init() // constructor supports creation of wxFileConfig objects of any type wxFileConfig::wxFileConfig(const wxString& appName, const wxString& vendorName, const wxString& strLocal, const wxString& strGlobal, - long style, wxMBConv& conv) + long style, + const wxMBConv& conv) : wxConfigBase(::GetAppName(appName), vendorName, strLocal, strGlobal, style), m_strLocalFile(strLocal), m_strGlobalFile(strGlobal), - m_conv(conv) + m_conv(conv.Clone()) { // Make up names for files if empty if ( m_strLocalFile.empty() && (style & wxCONFIG_USE_LOCAL_FILE) ) @@ -474,8 +474,8 @@ wxFileConfig::wxFileConfig(const wxString& appName, const wxString& vendorName, #if wxUSE_STREAMS -wxFileConfig::wxFileConfig(wxInputStream &inStream, wxMBConv& conv) - : m_conv(conv) +wxFileConfig::wxFileConfig(wxInputStream &inStream, const wxMBConv& conv) + : m_conv(conv.Clone()) { // always local_file when this constructor is called (?) SetStyle(GetStyle() | wxCONFIG_USE_LOCAL_FILE); @@ -570,6 +570,8 @@ wxFileConfig::~wxFileConfig() Flush(); CleanUp(); + + delete m_conv; } // ---------------------------------------------------------------------------- @@ -887,12 +889,44 @@ bool wxFileConfig::HasGroup(const wxString& strName) const return rc; } -bool wxFileConfig::HasEntry(const wxString& strName) const +bool wxFileConfig::HasEntry(const wxString& entry) const { - wxConfigPathChanger path(this, strName); + // path is the part before the last "/" + wxString path = entry.BeforeLast(wxCONFIG_PATH_SEPARATOR); - wxFileConfigEntry *pEntry = m_pCurrentGroup->FindEntry(path.Name()); - return pEntry != NULL; + // except in the special case of "/keyname" when there is nothing before "/" + if ( path.empty() && *entry.c_str() == wxCONFIG_PATH_SEPARATOR ) + { + path = wxCONFIG_PATH_SEPARATOR; + } + + // change to the path of the entry if necessary and remember the old path + // to restore it later + wxString pathOld; + wxFileConfig * const self = wx_const_cast(wxFileConfig *, this); + if ( !path.empty() ) + { + pathOld = GetPath(); + if ( pathOld.empty() ) + pathOld = wxCONFIG_PATH_SEPARATOR; + + if ( !self->DoSetPath(path, false /* don't create if doesn't exist */) ) + { + return false; + } + } + + // check if the entry exists in this group + const bool exists = m_pCurrentGroup->FindEntry( + entry.AfterLast(wxCONFIG_PATH_SEPARATOR)) != NULL; + + // restore the old path if we changed it above + if ( !pathOld.empty() ) + { + self->SetPath(pathOld); + } + + return exists; } // ---------------------------------------------------------------------------- @@ -1011,7 +1045,7 @@ bool wxFileConfig::Flush(bool /* bCurrentOnly */) { wxString line = p->Text(); line += wxTextFile::GetEOL(); - if ( !file.Write(line, m_conv) ) + if ( !file.Write(line, *m_conv) ) { wxLogError(_("can't write user configuration file.")); return false; @@ -1036,7 +1070,7 @@ bool wxFileConfig::Flush(bool /* bCurrentOnly */) #if wxUSE_STREAMS -bool wxFileConfig::Save(wxOutputStream& os, wxMBConv& conv) +bool wxFileConfig::Save(wxOutputStream& os, const wxMBConv& conv) { // save unconditionally, even if not dirty for ( wxFileConfigLineList *p = m_linesHead; p != NULL; p = p->Next() ) @@ -1143,6 +1177,8 @@ bool wxFileConfig::DeleteGroup(const wxString& key) if ( !m_pCurrentGroup->DeleteSubgroupByName(path.Name()) ) return false; + path.UpdateIfDeleted(); + SetDirty(); return true; @@ -1160,9 +1196,6 @@ bool wxFileConfig::DeleteAll() m_strLocalFile.c_str()); return false; } - - m_strLocalFile = - m_strGlobalFile = wxEmptyString; } Init(); @@ -1651,12 +1684,12 @@ bool wxFileConfigGroup::DeleteSubgroup(wxFileConfigGroup *pGroup) wxLogTrace( FILECONF_TRACE_MASK, _T(" (m_pLine) = prev: %p, this %p, next %p"), - ((m_pLine) ? m_pLine->Prev() : 0), + m_pLine ? m_pLine->Prev() : NULL, m_pLine, - ((m_pLine) ? m_pLine->Next() : 0) ); + m_pLine ? m_pLine->Next() : NULL ); wxLogTrace( FILECONF_TRACE_MASK, _T(" text: '%s'"), - ((m_pLine) ? m_pLine->Text().c_str() : wxEmptyString) ); + m_pLine ? m_pLine->Text().c_str() : wxEmptyString ); // delete all entries... size_t nCount = pGroup->m_aEntries.Count(); @@ -1901,20 +1934,20 @@ void wxFileConfigEntry::SetValue(const wxString& strValue, bool bUser) int CompareEntries(wxFileConfigEntry *p1, wxFileConfigEntry *p2) { - #if wxCONFIG_CASE_SENSITIVE +#if wxCONFIG_CASE_SENSITIVE return wxStrcmp(p1->Name(), p2->Name()); - #else +#else return wxStricmp(p1->Name(), p2->Name()); - #endif +#endif } int CompareGroups(wxFileConfigGroup *p1, wxFileConfigGroup *p2) { - #if wxCONFIG_CASE_SENSITIVE +#if wxCONFIG_CASE_SENSITIVE return wxStrcmp(p1->Name(), p2->Name()); - #else +#else return wxStricmp(p1->Name(), p2->Name()); - #endif +#endif } // ---------------------------------------------------------------------------- @@ -2030,8 +2063,11 @@ static wxString FilterInEntryName(const wxString& str) strResult.Alloc(str.Len()); for ( const wxChar *pc = str.c_str(); *pc != '\0'; pc++ ) { - if ( *pc == wxT('\\') ) - pc++; + if ( *pc == wxT('\\') ) { + // we need to test it here or we'd skip past the NUL in the loop line + if ( *++pc == _T('\0') ) + break; + } strResult += *pc; }