]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/fileconf.cpp
1. validator fixes: don't eat TAB. Added new SetBellOnError() function to
[wxWidgets.git] / src / common / fileconf.cpp
index a925bbae8ea4e34af9644531fa7bd503eeec57c9..7c358917a9735957860bf00f4fd45f7bfd32a6c2 100644 (file)
 #endif  //__BORLANDC__
 
 #ifndef   WX_PRECOMP
-  #include  <wx/string.h>
-  #include  <wx/intl.h>
+  #include  "wx/string.h"
+  #include  "wx/intl.h"
 #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/config.h>
-#include  <wx/fileconf.h>
+#include  "wx/app.h"
+#include  "wx/dynarray.h"
+#include  "wx/file.h"
+#include  "wx/log.h"
+#include  "wx/textfile.h"
+#include  "wx/config.h"
+#include  "wx/fileconf.h"
+
+#include  "wx/utils.h"    // for wxGetHomeDir
 
 // _WINDOWS_ is defined when windows.h is included,
 // __WXMSW__ is defined for MS Windows compilation
 // is 'c' a valid character in group name?
 // NB: wxCONFIG_IMMUTABLE_PREFIX and wxCONFIG_PATH_SEPARATOR must be valid chars,
 //     but _not_ ']' (group name delimiter)
-inline bool IsValid(char c) { return isalnum(c) || strchr("@_/-!.*%", c); }
+// NB2: we explicitly allow symbols from the 2nd half of the ASCII table
+inline bool IsValid(char c)
+{
+    return isalnum(c) || strchr("@_/-!.*%", c) || ((c & 0x80) != 0);
+}
 
 // compare functions for sorting the arrays
-static int CompareEntries(wxFileConfig::ConfigEntry *p1,
-                          wxFileConfig::ConfigEntry *p2);
-static int CompareGroups(wxFileConfig::ConfigGroup *p1,
-                         wxFileConfig::ConfigGroup *p2);
+static int CompareEntries(ConfigEntry *p1, ConfigEntry *p2);
+static int CompareGroups(ConfigGroup *p1, ConfigGroup *p2);
 
 // filter strings
 static wxString FilterIn(const wxString& str);
@@ -95,6 +99,8 @@ wxString wxFileConfig::GetGlobalDir()
     strDir = "/etc/";
   #elif defined(__WXSTUBS__)
     wxASSERT_MSG( FALSE, "TODO" ) ;
+  #elif defined(__WXMAC__)
+    wxASSERT_MSG( FALSE, "TODO" ) ;
   #else // Windows
     char szWinDir[MAX_PATH];
     ::GetWindowsDirectory(szWinDir, MAX_PATH);
@@ -109,9 +115,15 @@ wxString wxFileConfig::GetGlobalDir()
 wxString wxFileConfig::GetLocalDir()
 {
   wxString strDir;
-  
+
   wxGetHomeDir(&strDir);
 
+#ifdef  __UNIX__
+  if (strDir.Last() != '/') strDir << '/';
+#else
+  if (strDir.Last() != '\\') strDir << '\\';
+#endif
+
   return strDir;
 }
 
@@ -618,9 +630,9 @@ bool wxFileConfig::Write(const wxString& key, const wxString& szValue)
 bool wxFileConfig::Write(const wxString& key, long lValue)
 {
   // ltoa() is not ANSI :-(
-  char szBuf[40];   // should be good for sizeof(long) <= 16 (128 bits)
-  sprintf(szBuf, "%ld", lValue);
-  return Write(key, szBuf);
+  wxString buf;
+  buf.Printf("%ld", lValue);
+  return Write(key, buf);
 }
 
 bool wxFileConfig::Flush(bool /* bCurrentOnly */)
@@ -646,6 +658,50 @@ bool wxFileConfig::Flush(bool /* bCurrentOnly */)
   return file.Commit();
 }
 
+// ----------------------------------------------------------------------------
+// renaming groups/entries
+// ----------------------------------------------------------------------------
+
+bool wxFileConfig::RenameEntry(const wxString& oldName,
+                               const wxString& newName)
+{
+    // check that the entry exists
+    ConfigEntry *oldEntry = m_pCurrentGroup->FindEntry(oldName);
+    if ( !oldEntry )
+        return FALSE;
+
+    // check that the new entry doesn't already exist
+    if ( m_pCurrentGroup->FindEntry(newName) )
+        return FALSE;
+
+    // delete the old entry, create the new one
+    wxString value = oldEntry->Value();
+    if ( !m_pCurrentGroup->DeleteEntry(oldName) )
+        return FALSE;
+
+    ConfigEntry *newEntry = m_pCurrentGroup->AddEntry(newName);
+    newEntry->SetValue(value);
+
+    return TRUE;
+}
+
+bool wxFileConfig::RenameGroup(const wxString& oldName,
+                               const wxString& newName)
+{
+    // check that the group exists
+    ConfigGroup *group = m_pCurrentGroup->FindSubgroup(oldName);
+    if ( !group )
+        return FALSE;
+
+    // check that the new group doesn't already exist
+    if ( m_pCurrentGroup->FindSubgroup(newName) )
+        return FALSE;
+
+    group->Rename(newName);
+
+    return TRUE;
+}
+
 // ----------------------------------------------------------------------------
 // delete groups/entries
 // ----------------------------------------------------------------------------
@@ -696,7 +752,7 @@ bool wxFileConfig::DeleteAll()
 // ----------------------------------------------------------------------------
 
 // append a new line to the end of the list
-wxFileConfig::LineList *wxFileConfig::LineListAppend(const wxString& str)
+LineList *wxFileConfig::LineListAppend(const wxString& str)
 {
   LineList *pLine = new LineList(str);
 
@@ -715,7 +771,7 @@ wxFileConfig::LineList *wxFileConfig::LineListAppend(const wxString& str)
 }
 
 // insert a new line after the given one or in the very beginning if !pLine
-wxFileConfig::LineList *wxFileConfig::LineListInsert(const wxString& str,
+LineList *wxFileConfig::LineListInsert(const wxString& str,
                                                      LineList *pLine)
 {
   if ( pLine == m_linesTail )
@@ -754,7 +810,7 @@ void wxFileConfig::LineListRemove(LineList *pLine)
   // last entry?
   if ( pNext == NULL )
     m_linesTail = pPrev;
-  else    
+  else
     pNext->SetPrev(pPrev);
 
   delete pLine;
@@ -774,7 +830,7 @@ bool wxFileConfig::LineListIsEmpty()
 // ----------------------------------------------------------------------------
 
 // ctor
-wxFileConfig::ConfigGroup::ConfigGroup(wxFileConfig::ConfigGroup *pParent,
+ConfigGroup::ConfigGroup(ConfigGroup *pParent,
                                        const wxString& strName,
                                        wxFileConfig *pConfig)
                          : m_aEntries(CompareEntries),
@@ -791,7 +847,7 @@ wxFileConfig::ConfigGroup::ConfigGroup(wxFileConfig::ConfigGroup *pParent,
 }
 
 // dtor deletes all children
-wxFileConfig::ConfigGroup::~ConfigGroup()
+ConfigGroup::~ConfigGroup()
 {
   // entries
   size_t n, nCount = m_aEntries.Count();
@@ -808,7 +864,7 @@ wxFileConfig::ConfigGroup::~ConfigGroup()
 // line
 // ----------------------------------------------------------------------------
 
-void wxFileConfig::ConfigGroup::SetLine(LineList *pLine)
+void ConfigGroup::SetLine(LineList *pLine)
 {
   wxASSERT( m_pLine == NULL ); // shouldn't be called twice
 
@@ -844,12 +900,12 @@ void wxFileConfig::ConfigGroup::SetLine(LineList *pLine)
       backwards in the config file (OTOH, it's not that important) and as we
       would still need to do it for the subgroups the code wouldn't have been
       significantly less complicated.
- */
+*/
 
 // Return the line which contains "[our name]". If we're still not in the list,
 // add our line to it immediately after the last line of our parent group if we
 // have it or in the very beginning if we're the root group.
-wxFileConfig::LineList *wxFileConfig::ConfigGroup::GetGroupLine()
+LineList *ConfigGroup::GetGroupLine()
 {
   if ( m_pLine == NULL ) {
     ConfigGroup *pParent = Parent();
@@ -857,7 +913,7 @@ wxFileConfig::LineList *wxFileConfig::ConfigGroup::GetGroupLine()
     // this group wasn't present in local config file, add it now
     if ( pParent != NULL ) {
       wxString strFullName;
-      strFullName << "[" << GetFullName().c_str() + 1 << "]"; // +1: no '/'
+      strFullName << "[" << (GetFullName().c_str() + 1) << "]"; // +1: no '/'
       m_pLine = m_pConfig->LineListInsert(strFullName,
                                           pParent->GetLastGroupLine());
       pParent->SetLastGroup(this);  // we're surely after all the others
@@ -874,12 +930,12 @@ wxFileConfig::LineList *wxFileConfig::ConfigGroup::GetGroupLine()
 // Return the last line belonging to the subgroups of this group (after which
 // we can add a new subgroup), if we don't have any subgroups or entries our
 // last line is the group line (m_pLine) itself.
-wxFileConfig::LineList *wxFileConfig::ConfigGroup::GetLastGroupLine()
+LineList *ConfigGroup::GetLastGroupLine()
 {
   // if we have any subgroups, our last line is the last line of the last
   // subgroup
   if ( m_pLastGroup != NULL ) {
-    wxFileConfig::LineList *pLine = m_pLastGroup->GetLastGroupLine();
+    LineList *pLine = m_pLastGroup->GetLastGroupLine();
 
     wxASSERT( pLine != NULL );  // last group must have !NULL associated line
     return pLine;
@@ -892,10 +948,10 @@ wxFileConfig::LineList *wxFileConfig::ConfigGroup::GetLastGroupLine()
 // return the last line belonging to the entries of this group (after which
 // we can add a new entry), if we don't have any entries we will add the new
 // one immediately after the group line itself.
-wxFileConfig::LineList *wxFileConfig::ConfigGroup::GetLastEntryLine()
+LineList *ConfigGroup::GetLastEntryLine()
 {
   if ( m_pLastEntry != NULL ) {
-    wxFileConfig::LineList *pLine = m_pLastEntry->GetLine();
+    LineList *pLine = m_pLastEntry->GetLine();
 
     wxASSERT( pLine != NULL );  // last entry must have !NULL associated line
     return pLine;
@@ -909,7 +965,19 @@ wxFileConfig::LineList *wxFileConfig::ConfigGroup::GetLastEntryLine()
 // group name
 // ----------------------------------------------------------------------------
 
-wxString wxFileConfig::ConfigGroup::GetFullName() const
+void ConfigGroup::Rename(const wxString& newName)
+{
+    m_strName = newName;
+
+    LineList *line = GetGroupLine();
+    wxString strFullName;
+    strFullName << "[" << (GetFullName().c_str() + 1) << "]"; // +1: no '/'
+    line->SetText(strFullName);
+
+    SetDirty();
+}
+
+wxString ConfigGroup::GetFullName() const
 {
   if ( Parent() )
     return Parent()->GetFullName() + wxCONFIG_PATH_SEPARATOR + Name();
@@ -922,14 +990,14 @@ wxString wxFileConfig::ConfigGroup::GetFullName() const
 // ----------------------------------------------------------------------------
 
 // use binary search because the array is sorted
-wxFileConfig::ConfigEntry *
-wxFileConfig::ConfigGroup::FindEntry(const char *szName) const
+ConfigEntry *
+ConfigGroup::FindEntry(const char *szName) const
 {
   size_t i,
        lo = 0,
        hi = m_aEntries.Count();
   int res;
-  wxFileConfig::ConfigEntry *pEntry;
+  ConfigEntry *pEntry;
 
   while ( lo < hi ) {
     i = (lo + hi)/2;
@@ -952,14 +1020,14 @@ wxFileConfig::ConfigGroup::FindEntry(const char *szName) const
   return NULL;
 }
 
-wxFileConfig::ConfigGroup *
-wxFileConfig::ConfigGroup::FindSubgroup(const char *szName) const
+ConfigGroup *
+ConfigGroup::FindSubgroup(const char *szName) const
 {
   size_t i,
        lo = 0,
        hi = m_aSubgroups.Count();
   int res;
-  wxFileConfig::ConfigGroup *pGroup;
+  ConfigGroup *pGroup;
 
   while ( lo < hi ) {
     i = (lo + hi)/2;
@@ -987,8 +1055,8 @@ wxFileConfig::ConfigGroup::FindSubgroup(const char *szName) const
 // ----------------------------------------------------------------------------
 
 // create a new entry and add it to the current group
-wxFileConfig::ConfigEntry *
-wxFileConfig::ConfigGroup::AddEntry(const wxString& strName, int nLine)
+ConfigEntry *
+ConfigGroup::AddEntry(const wxString& strName, int nLine)
 {
   wxASSERT( FindEntry(strName) == NULL );
 
@@ -999,8 +1067,8 @@ wxFileConfig::ConfigGroup::AddEntry(const wxString& strName, int nLine)
 }
 
 // create a new group and add it to the current group
-wxFileConfig::ConfigGroup *
-wxFileConfig::ConfigGroup::AddSubgroup(const wxString& strName)
+ConfigGroup *
+ConfigGroup::AddSubgroup(const wxString& strName)
 {
   wxASSERT( FindSubgroup(strName) == NULL );
 
@@ -1021,7 +1089,7 @@ wxFileConfig::ConfigGroup::AddSubgroup(const wxString& strName)
   delete several of them.
  */
 
-bool wxFileConfig::ConfigGroup::DeleteSubgroupByName(const char *szName)
+bool ConfigGroup::DeleteSubgroupByName(const char *szName)
 {
   return DeleteSubgroup(FindSubgroup(szName));
 }
@@ -1029,7 +1097,7 @@ bool wxFileConfig::ConfigGroup::DeleteSubgroupByName(const char *szName)
 // doesn't delete the subgroup itself, but does remove references to it from
 // all other data structures (and normally the returned pointer should be
 // deleted a.s.a.p. because there is nothing much to be done with it anyhow)
-bool wxFileConfig::ConfigGroup::DeleteSubgroup(ConfigGroup *pGroup)
+bool ConfigGroup::DeleteSubgroup(ConfigGroup *pGroup)
 {
   wxCHECK( pGroup != NULL, FALSE ); // deleting non existing group?
 
@@ -1093,7 +1161,7 @@ bool wxFileConfig::ConfigGroup::DeleteSubgroup(ConfigGroup *pGroup)
   return TRUE;
 }
 
-bool wxFileConfig::ConfigGroup::DeleteEntry(const char *szName)
+bool ConfigGroup::DeleteEntry(const char *szName)
 {
   ConfigEntry *pEntry = FindEntry(szName);
   wxCHECK( pEntry != NULL, FALSE );  // deleting non existing item?
@@ -1146,7 +1214,7 @@ bool wxFileConfig::ConfigGroup::DeleteEntry(const char *szName)
 // ----------------------------------------------------------------------------
 //
 // ----------------------------------------------------------------------------
-void wxFileConfig::ConfigGroup::SetDirty()
+void ConfigGroup::SetDirty()
 {
   m_bDirty = TRUE;
   if ( Parent() != NULL )             // propagate upwards
@@ -1160,7 +1228,7 @@ void wxFileConfig::ConfigGroup::SetDirty()
 // ----------------------------------------------------------------------------
 // ctor
 // ----------------------------------------------------------------------------
-wxFileConfig::ConfigEntry::ConfigEntry(wxFileConfig::ConfigGroup *pParent,
+ConfigEntry::ConfigEntry(ConfigGroup *pParent,
                                        const wxString& strName,
                                        int nLine)
                          : m_strName(strName)
@@ -1182,7 +1250,7 @@ wxFileConfig::ConfigEntry::ConfigEntry(wxFileConfig::ConfigGroup *pParent,
 // set value
 // ----------------------------------------------------------------------------
 
-void wxFileConfig::ConfigEntry::SetLine(LineList *pLine)
+void ConfigEntry::SetLine(LineList *pLine)
 {
   if ( m_pLine != NULL ) {
     wxLogWarning(_("entry '%s' appears more than once in group '%s'"),
@@ -1195,7 +1263,7 @@ void wxFileConfig::ConfigEntry::SetLine(LineList *pLine)
 
 // second parameter is FALSE if we read the value from file and prevents the
 // entry from being marked as 'dirty'
-void wxFileConfig::ConfigEntry::SetValue(const wxString& strValue, bool bUser)
+void ConfigEntry::SetValue(const wxString& strValue, bool bUser)
 {
   if ( bUser && IsImmutable() ) {
     wxLogWarning(_("attempt to change immutable key '%s' ignored."),
@@ -1220,7 +1288,7 @@ void wxFileConfig::ConfigEntry::SetValue(const wxString& strValue, bool bUser)
     }
     else {
       // add a new line to the file
-      wxASSERT( m_nLine == NOT_FOUND );   // consistency check
+      wxASSERT( m_nLine == wxNOT_FOUND );   // consistency check
 
       m_pLine = Group()->Config()->LineListInsert(strLine,
                                                   Group()->GetLastEntryLine());
@@ -1231,7 +1299,7 @@ void wxFileConfig::ConfigEntry::SetValue(const wxString& strValue, bool bUser)
   }
 }
 
-void wxFileConfig::ConfigEntry::SetDirty()
+void ConfigEntry::SetDirty()
 {
   m_bDirty = TRUE;
   Group()->SetDirty();
@@ -1245,8 +1313,8 @@ void wxFileConfig::ConfigEntry::SetDirty()
 // compare functions for array sorting
 // ----------------------------------------------------------------------------
 
-int CompareEntries(wxFileConfig::ConfigEntry *p1,
-                   wxFileConfig::ConfigEntry *p2)
+int CompareEntries(ConfigEntry *p1,
+                   ConfigEntry *p2)
 {
   #if wxCONFIG_CASE_SENSITIVE
     return strcmp(p1->Name(), p2->Name());
@@ -1255,8 +1323,8 @@ int CompareEntries(wxFileConfig::ConfigEntry *p1,
   #endif
 }
 
-int CompareGroups(wxFileConfig::ConfigGroup *p1,
-                  wxFileConfig::ConfigGroup *p2)
+int CompareGroups(ConfigGroup *p1,
+                  ConfigGroup *p2)
 {
   #if wxCONFIG_CASE_SENSITIVE
     return strcmp(p1->Name(), p2->Name());
@@ -1320,7 +1388,7 @@ wxString FilterOut(const wxString& str)
 {
    if(str.IsEmpty())
       return str;
-   
+
   wxString strResult;
   strResult.Alloc(str.Len());
 
@@ -1370,3 +1438,10 @@ wxString FilterOut(const wxString& str)
 
   return strResult;
 }
+
+
+
+
+
+
+