]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/fileconf.cpp
reset the tooltip text before changing it, this apparently prevents a spurious redraw...
[wxWidgets.git] / src / common / fileconf.cpp
index 0334138412d767b05070f9862f7761928ec1ce79..69df300ba2639319b675c1637f91a6edc3d05bba 100644 (file)
@@ -5,7 +5,7 @@
 // Modified by:
 // Created:     07.04.98 (adapted from appconf.cpp)
 // RCS-ID:      $Id$
 // Modified by:
 // Created:     07.04.98 (adapted from appconf.cpp)
 // RCS-ID:      $Id$
-// Copyright:   (c) 1997 Karsten Ballüder   &  Vadim Zeitlin
+// Copyright:   (c) 1997 Karsten Ballueder  &  Vadim Zeitlin
 //                       Ballueder@usa.net     <zeitlin@dptmaths.ens-cachan.fr>
 // Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 //                       Ballueder@usa.net     <zeitlin@dptmaths.ens-cachan.fr>
 // Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
 #include  "wx/stdpaths.h"
 
 
 #include  "wx/stdpaths.h"
 
-#if defined(__WXMAC__)
-    #include  "wx/mac/private.h"  // includes mac headers
-#endif
-
 #if defined(__WXMSW__)
     #include "wx/msw/private.h"
 #endif  //windows.h
 #if defined(__WXMSW__)
     #include "wx/msw/private.h"
 #endif  //windows.h
@@ -141,7 +137,7 @@ private:
   wxFileConfigLineList *m_pNext,        // next node
                        *m_pPrev;        // previous one
 
   wxFileConfigLineList *m_pNext,        // next node
                        *m_pPrev;        // previous one
 
-    DECLARE_NO_COPY_CLASS(wxFileConfigLineList)
+    wxDECLARE_NO_COPY_CLASS(wxFileConfigLineList);
 };
 
 // ----------------------------------------------------------------------------
 };
 
 // ----------------------------------------------------------------------------
@@ -182,7 +178,7 @@ public:
   void SetValue(const wxString& strValue, bool bUser = true);
   void SetLine(wxFileConfigLineList *pLine);
 
   void SetValue(const wxString& strValue, bool bUser = true);
   void SetLine(wxFileConfigLineList *pLine);
 
-    DECLARE_NO_COPY_CLASS(wxFileConfigEntry)
+    wxDECLARE_NO_COPY_CLASS(wxFileConfigEntry);
 };
 
 // ----------------------------------------------------------------------------
 };
 
 // ----------------------------------------------------------------------------
@@ -245,6 +241,7 @@ public:
 
   // get the last line belonging to an entry/subgroup of this group
   wxFileConfigLineList *GetGroupLine();     // line which contains [group]
 
   // get the last line belonging to an entry/subgroup of this group
   wxFileConfigLineList *GetGroupLine();     // line which contains [group]
+                                            // may be NULL for "/" only
   wxFileConfigLineList *GetLastEntryLine(); // after which our subgroups start
   wxFileConfigLineList *GetLastGroupLine(); // after which the next group starts
 
   wxFileConfigLineList *GetLastEntryLine(); // after which our subgroups start
   wxFileConfigLineList *GetLastGroupLine(); // after which the next group starts
 
@@ -253,7 +250,7 @@ public:
   void SetLastGroup(wxFileConfigGroup *pGroup)
     { m_pLastGroup = pGroup; }
 
   void SetLastGroup(wxFileConfigGroup *pGroup)
     { m_pLastGroup = pGroup; }
 
-  DECLARE_NO_COPY_CLASS(wxFileConfigGroup)
+  wxDECLARE_NO_COPY_CLASS(wxFileConfigGroup);
 };
 
 // ============================================================================
 };
 
 // ============================================================================
@@ -277,9 +274,9 @@ static void AddConfFileExtIfNeeded(wxFileName& fn)
 #if defined( __WXMAC__ )
         fn.SetName(fn.GetName() + wxT(" Preferences"));
 #elif defined( __UNIX__ )
 #if defined( __WXMAC__ )
         fn.SetName(fn.GetName() + wxT(" Preferences"));
 #elif defined( __UNIX__ )
-        fn.SetExt(wxT(".conf"));
+        fn.SetExt(wxT("conf"));
 #else   // Windows
 #else   // Windows
-        fn.SetExt(wxT(".ini"));
+        fn.SetExt(wxT("ini"));
 #endif  // UNIX/Win
     }
 }
 #endif  // UNIX/Win
     }
 }
@@ -314,7 +311,7 @@ wxFileName wxFileConfig::GetLocalFile(const wxString& szFile, int style)
 {
     wxFileName fn(GetLocalDir(style), szFile);
 
 {
     wxFileName fn(GetLocalDir(style), szFile);
 
-#ifdef __UNIX__
+#if defined( __UNIX__ ) && !defined( __WXMAC__ )
     if ( !(style & wxCONFIG_USE_SUBDIR) )
     {
         // dot-files under Unix start with, well, a dot (but OTOH they usually
     if ( !(style & wxCONFIG_USE_SUBDIR) )
     {
         // dot-files under Unix start with, well, a dot (but OTOH they usually
@@ -322,7 +319,7 @@ wxFileName wxFileConfig::GetLocalFile(const wxString& szFile, int style)
         fn.SetName(wxT('.') + fn.GetName());
     }
     else // we do append ".conf" extension to config files in subdirectories
         fn.SetName(wxT('.') + fn.GetName());
     }
     else // we do append ".conf" extension to config files in subdirectories
-#endif // __UNIX__
+#endif // defined( __UNIX__ ) && !defined( __WXMAC__ )
     {
         AddConfFileExtIfNeeded(fn);
     }
     {
         AddConfFileExtIfNeeded(fn);
     }
@@ -372,7 +369,16 @@ void wxFileConfig::Init()
         }
         else
         {
         }
         else
         {
-            wxLogWarning(_("can't open user configuration file '%s'."),  m_fnLocalFile.GetFullPath().c_str() );
+            const wxString path = m_fnLocalFile.GetFullPath();
+            wxLogWarning(_("can't open user configuration file '%s'."),
+                         path.c_str());
+
+            if ( m_fnLocalFile.FileExists() )
+            {
+                wxLogWarning(_("Changes won't be saved to avoid overwriting the existing file \"%s\""),
+                             path.c_str());
+                m_fnLocalFile.Clear();
+            }
         }
     }
 
         }
     }
 
@@ -458,7 +464,7 @@ wxFileConfig::wxFileConfig(wxInputStream &inStream, const wxMBConv& conv)
 
 #if wxUSE_UNICODE
     size_t len;
 
 #if wxUSE_UNICODE
     size_t len;
-    cbuf = conv.cMB2WC((char *)buf.GetData(), buf.GetDataLen(), &len);
+    cbuf = conv.cMB2WC((char *)buf.GetData(), buf.GetDataLen() + 1, &len);
     if ( !len && buf.GetDataLen() )
     {
         wxLogError(_("Failed to read config options."));
     if ( !len && buf.GetDataLen() )
     {
         wxLogError(_("Failed to read config options."));
@@ -479,7 +485,8 @@ wxFileConfig::wxFileConfig(wxInputStream &inStream, const wxMBConv& conv)
 
         // notice that we throw away the original EOL kind here, maybe we
         // should preserve it?
 
         // notice that we throw away the original EOL kind here, maybe we
         // should preserve it?
-        memText.AddLine(wxString(s, e));
+        if ( e != s )
+            memText.AddLine(wxString(s, e));
 
         if ( *e == '\0' )
             break;
 
         if ( *e == '\0' )
             break;
@@ -540,16 +547,8 @@ void wxFileConfig::Parse(const wxTextBuffer& buffer, bool bLocal)
 
     // add the line to linked list
     if ( bLocal )
 
     // add the line to linked list
     if ( bLocal )
-    {
       LineListAppend(strLine);
 
       LineListAppend(strLine);
 
-      // let the root group have its start line as well
-      if ( !n )
-      {
-        m_pCurrentGroup->SetLine(m_linesTail);
-      }
-    }
-
 
     // skip leading spaces
     for ( pStart = buf; wxIsspace(*pStart); pStart++ )
 
     // skip leading spaces
     for ( pStart = buf; wxIsspace(*pStart); pStart++ )
@@ -828,7 +827,7 @@ bool wxFileConfig::HasGroup(const wxString& strName) const
 
     const wxString pathOld = GetPath();
 
 
     const wxString pathOld = GetPath();
 
-    wxFileConfig *self = wx_const_cast(wxFileConfig *, this);
+    wxFileConfig *self = const_cast<wxFileConfig *>(this);
     const bool
         rc = self->DoSetPath(strName, false /* don't create missing components */);
 
     const bool
         rc = self->DoSetPath(strName, false /* don't create missing components */);
 
@@ -851,7 +850,7 @@ bool wxFileConfig::HasEntry(const wxString& entry) const
     // change to the path of the entry if necessary and remember the old path
     // to restore it later
     wxString pathOld;
     // 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);
+    wxFileConfig * const self = const_cast<wxFileConfig *>(this);
     if ( !path.empty() )
     {
         pathOld = GetPath();
     if ( !path.empty() )
     {
         pathOld = GetPath();
@@ -917,7 +916,7 @@ bool wxFileConfig::DoReadBinary(const wxString& key, wxMemoryBuffer* buf) const
     if ( !Read(key, &str) )
         return false;
 
     if ( !Read(key, &str) )
         return false;
 
-    *buf = wxBase64Decode(str.ToAscii());
+    *buf = wxBase64Decode(str);
     return true;
 }
 
     return true;
 }
 
@@ -948,8 +947,8 @@ bool wxFileConfig::DoWriteString(const wxString& key, const wxString& szValue)
 
         SetDirty();
 
 
         SetDirty();
 
-            // this will add a line for this group if it didn't have it before
-
+        // this will add a line for this group if it didn't have it before (or
+        // do nothing for the root but it's ok as it always exists anyhow)
         (void)m_pCurrentGroup->GetGroupLine();
     }
     else
         (void)m_pCurrentGroup->GetGroupLine();
     }
     else
@@ -1036,7 +1035,7 @@ bool wxFileConfig::Flush(bool /* bCurrentOnly */)
 
   ResetDirty();
 
 
   ResetDirty();
 
-#if defined(__WXMAC__)
+#if defined( __WXOSX_MAC__ ) && wxOSX_USE_CARBON
   m_fnLocalFile.MacSetTypeAndCreator('TEXT', 'ttxt');
 #endif // __WXMAC__
 
   m_fnLocalFile.MacSetTypeAndCreator('TEXT', 'ttxt');
 #endif // __WXMAC__
 
@@ -1309,9 +1308,6 @@ void wxFileConfig::LineListRemove(wxFileConfigLineList *pLine)
     else
         pNext->SetPrev(pPrev);
 
     else
         pNext->SetPrev(pPrev);
 
-    if ( m_pRootGroup->GetGroupLine() == pLine )
-        m_pRootGroup->SetLine(m_linesHead);
-
     wxLogTrace( FILECONF_TRACE_MASK,
                 _T("        head: %s"),
                 ((m_linesHead) ? (const wxChar*)m_linesHead->Text().c_str()
     wxLogTrace( FILECONF_TRACE_MASK,
                 _T("        head: %s"),
                 ((m_linesHead) ? (const wxChar*)m_linesHead->Text().c_str()
@@ -1682,9 +1678,9 @@ bool wxFileConfigGroup::DeleteSubgroup(wxFileConfigGroup *pGroup)
 
     wxLogTrace( FILECONF_TRACE_MASK,
                 _T("  (m_pLine) = prev: %p, this %p, next %p"),
 
     wxLogTrace( FILECONF_TRACE_MASK,
                 _T("  (m_pLine) = prev: %p, this %p, next %p"),
-                m_pLine ? wx_static_cast(void*, m_pLine->Prev()) : 0,
-                wx_static_cast(void*, m_pLine),
-                m_pLine ? wx_static_cast(void*, m_pLine->Next()) : 0 );
+                m_pLine ? static_cast<void*>(m_pLine->Prev()) : 0,
+                static_cast<void*>(m_pLine),
+                m_pLine ? static_cast<void*>(m_pLine->Next()) : 0 );
     wxLogTrace( FILECONF_TRACE_MASK,
                 _T("  text: '%s'"),
                 m_pLine ? (const wxChar*)m_pLine->Text().c_str()
     wxLogTrace( FILECONF_TRACE_MASK,
                 _T("  text: '%s'"),
                 m_pLine ? (const wxChar*)m_pLine->Text().c_str()
@@ -1800,29 +1796,21 @@ bool wxFileConfigGroup::DeleteEntry(const wxString& name)
       // our last entry is being deleted - find the last one which stays
       wxASSERT( m_pLine != NULL );  // if we have an entry with !NULL pLine...
 
       // our last entry is being deleted - find the last one which stays
       wxASSERT( m_pLine != NULL );  // if we have an entry with !NULL pLine...
 
-      // go back until we find another entry or reach the group's line
+      // find the previous entry (if any)
       wxFileConfigEntry *pNewLast = NULL;
       wxFileConfigEntry *pNewLast = NULL;
-      size_t n, nEntries = m_aEntries.GetCount();
-      wxFileConfigLineList *pl;
-      for ( pl = pLine->Prev(); pl != m_pLine; pl = pl->Prev() ) {
-        // is it our subgroup?
-        for ( n = 0; (pNewLast == NULL) && (n < nEntries); n++ ) {
-          if ( m_aEntries[n]->GetLine() == m_pLine )
-            pNewLast = m_aEntries[n];
-        }
-
-        if ( pNewLast != NULL ) // found?
+      const wxFileConfigLineList * const
+        pNewLastLine = m_pLastEntry->GetLine()->Prev();
+      const size_t nEntries = m_aEntries.GetCount();
+      for ( size_t n = 0; n < nEntries; n++ ) {
+        if ( m_aEntries[n]->GetLine() == pNewLastLine ) {
+          pNewLast = m_aEntries[n];
           break;
           break;
+        }
       }
 
       }
 
-      if ( pl == m_pLine ) {
-        wxASSERT( !pNewLast );  // how comes it has the same line as we?
-
-        // we've reached the group line without finding any subgroups
-        m_pLastEntry = NULL;
-      }
-      else
-        m_pLastEntry = pNewLast;
+      // pNewLast can be NULL here -- it's ok and can happen if we have no
+      // entries left
+      m_pLastEntry = pNewLast;
     }
 
     m_pConfig->LineListRemove(pLine);
     }
 
     m_pConfig->LineListRemove(pLine);
@@ -1960,47 +1948,66 @@ int CompareGroups(wxFileConfigGroup *p1, wxFileConfigGroup *p2)
 // undo FilterOutValue
 static wxString FilterInValue(const wxString& str)
 {
 // undo FilterOutValue
 static wxString FilterInValue(const wxString& str)
 {
-  wxString strResult;
-  strResult.Alloc(str.Len());
+    wxString strResult;
+    if ( str.empty() )
+        return strResult;
 
 
-  bool bQuoted = !str.empty() && str[0] == '"';
+    strResult.reserve(str.length());
 
 
-  for ( size_t n = bQuoted ? 1 : 0; n < str.Len(); n++ ) {
-    if ( str[n] == wxT('\\') ) {
-      switch ( str[++n].GetValue() ) {
-        case wxT('n'):
-          strResult += wxT('\n');
-          break;
+    wxString::const_iterator i = str.begin();
+    const bool bQuoted = *i == '"';
+    if ( bQuoted )
+        ++i;
 
 
-        case wxT('r'):
-          strResult += wxT('\r');
-          break;
+    for ( const wxString::const_iterator end = str.end(); i != end; ++i )
+    {
+        if ( *i == wxT('\\') )
+        {
+            if ( ++i == end )
+            {
+                wxLogWarning(_("trailing backslash ignored in '%s'"), str.c_str());
+                break;
+            }
 
 
-        case wxT('t'):
-          strResult += wxT('\t');
-          break;
+            switch ( (*i).GetValue() )
+            {
+                case wxT('n'):
+                    strResult += wxT('\n');
+                    break;
 
 
-        case wxT('\\'):
-          strResult += wxT('\\');
-          break;
+                case wxT('r'):
+                    strResult += wxT('\r');
+                    break;
 
 
-        case wxT('"'):
-          strResult += wxT('"');
-          break;
-      }
-    }
-    else {
-      if ( str[n] != wxT('"') || !bQuoted )
-        strResult += str[n];
-      else if ( n != str.Len() - 1 ) {
-        wxLogWarning(_("unexpected \" at position %d in '%s'."),
-                     n, str.c_str());
-      }
-      //else: it's the last quote of a quoted string, ok
+                case wxT('t'):
+                    strResult += wxT('\t');
+                    break;
+
+                case wxT('\\'):
+                    strResult += wxT('\\');
+                    break;
+
+                case wxT('"'):
+                    strResult += wxT('"');
+                    break;
+            }
+        }
+        else // not a backslash
+        {
+            if ( *i != wxT('"') || !bQuoted )
+            {
+                strResult += *i;
+            }
+            else if ( i != end - 1 )
+            {
+                wxLogWarning(_("unexpected \" at position %d in '%s'."),
+                             i - str.begin(), str.c_str());
+            }
+            //else: it's the last quote of a quoted string, ok
+        }
     }
     }
-  }
 
 
-  return strResult;
+    return strResult;
 }
 
 // quote the string before writing it to file
 }
 
 // quote the string before writing it to file