]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/fileconf.cpp
fixed SetWindowStyleFlag() to not remove WS_VISIBLE; also refresh the control automat...
[wxWidgets.git] / src / common / fileconf.cpp
index 36537f99cffb477f4756670b1c5b02a98705b518..6215e1fe374fe64873da631475003bb2e88e6051 100644 (file)
@@ -10,7 +10,7 @@
 // Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
 #pragma implementation "fileconf.h"
 #endif
 
@@ -24,7 +24,7 @@
   #pragma hdrstop
 #endif  //__BORLANDC__
 
-#if wxUSE_CONFIG
+#if wxUSE_CONFIG && wxUSE_FILECONFIG
 
 #ifndef   WX_PRECOMP
   #include  "wx/string.h"
@@ -106,8 +106,15 @@ static wxString GetAppName(const wxString& appname);
 // "template" array types
 // ----------------------------------------------------------------------------
 
-WX_DEFINE_SORTED_EXPORTED_ARRAY(wxFileConfigEntry *, ArrayEntries);
-WX_DEFINE_SORTED_EXPORTED_ARRAY(wxFileConfigGroup *, ArrayGroups);
+#ifdef WXMAKINGDLL_BASE
+    WX_DEFINE_SORTED_USER_EXPORTED_ARRAY(wxFileConfigEntry *, ArrayEntries,
+                                         WXDLLIMPEXP_BASE);
+    WX_DEFINE_SORTED_USER_EXPORTED_ARRAY(wxFileConfigGroup *, ArrayGroups,
+                                         WXDLLIMPEXP_BASE);
+#else
+    WX_DEFINE_SORTED_ARRAY(wxFileConfigEntry *, ArrayEntries);
+    WX_DEFINE_SORTED_ARRAY(wxFileConfigGroup *, ArrayGroups);
+#endif
 
 // ----------------------------------------------------------------------------
 // wxFileConfigLineList
@@ -178,7 +185,7 @@ public:
                   GetLine()     const { return m_pLine;      }
 
   // modify entry attributes
-  void SetValue(const wxString& strValue, bool bUser = TRUE);
+  void SetValue(const wxString& strValue, bool bUser = true);
   void SetDirty();
   void SetLine(wxFileConfigLineList *pLine);
 
@@ -197,7 +204,7 @@ private:
   ArrayEntries  m_aEntries;         // entries in this group
   ArrayGroups   m_aSubgroups;       // subgroups
   wxString      m_strName;          // group's name
-  bool          m_bDirty;           // if FALSE => all subgroups are not dirty
+  bool          m_bDirty;           // if false => all subgroups are not dirty
   wxFileConfigLineList *m_pLine;    // pointer to our line in the linked list
   wxFileConfigEntry *m_pLastEntry;  // last entry/subgroup of this group in the
   wxFileConfigGroup *m_pLastGroup;  // local file (we insert new ones after it)
@@ -226,7 +233,7 @@ public:
   wxFileConfigGroup *FindSubgroup(const wxChar *szName) const;
   wxFileConfigEntry *FindEntry   (const wxChar *szName) const;
 
-  // delete entry/subgroup, return FALSE if doesn't exist
+  // delete entry/subgroup, return false if doesn't exist
   bool DeleteSubgroupByName(const wxChar *szName);
   bool DeleteEntry(const wxChar *szName);
 
@@ -286,7 +293,7 @@ wxString wxFileConfig::GetGlobalDir()
         strDir.Printf(wxT("%c:\\OS2\\"), 'A'+drive-1);
     }
 #elif defined(__WXSTUBS__)
-    wxASSERT_MSG( FALSE, wxT("TODO") ) ;
+    wxASSERT_MSG( false, wxT("TODO") ) ;
 #elif defined(__DOS__)
     // There's no such thing as global cfg dir in MS-DOS, let's return
     // current directory (FIXME_MGL?)
@@ -392,7 +399,7 @@ void wxFileConfig::Init()
 
         if ( fileGlobal.Open(m_conv/*ignored in ANSI build*/) )
         {
-            Parse(fileGlobal, FALSE /* global */);
+            Parse(fileGlobal, false /* global */);
             SetRootPath();
         }
         else
@@ -407,7 +414,7 @@ void wxFileConfig::Init()
         wxTextFile fileLocal(m_strLocalFile);
         if ( fileLocal.Open(m_conv/*ignored in ANSI build*/) )
         {
-            Parse(fileLocal, TRUE /* local */);
+            Parse(fileLocal, true /* local */);
             SetRootPath();
         }
         else
@@ -487,10 +494,21 @@ wxFileConfig::wxFileConfig(wxInputStream &inStream, wxMBConv& conv)
         wxString strTmp;
 
         char buf[1024];
-        while ( !inStream.Read(buf, WXSIZEOF(buf)).Eof() )
-            strTmp.append(wxConvertMB2WX(buf), inStream.LastRead());
+        do
+        {
+            inStream.Read(buf, WXSIZEOF(buf));
 
-        strTmp.append(wxConvertMB2WX(buf), inStream.LastRead());
+            const wxStreamError err = inStream.GetLastError();
+
+            if ( err != wxSTREAM_NO_ERROR && err != wxSTREAM_EOF )
+            {
+                wxLogError(_("Error reading config options."));
+                break;
+            }
+
+            strTmp.append(wxConvertMB2WX(buf), inStream.LastRead());
+        }
+        while ( !inStream.Eof() );
 
         strTrans = wxTextBuffer::Translate(strTmp);
     }
@@ -522,7 +540,7 @@ wxFileConfig::wxFileConfig(wxInputStream &inStream, wxMBConv& conv)
     memText.AddLine(strTrans);
 
     // Finally we can parse it all.
-    Parse(memText, TRUE /* local */);
+    Parse(memText, true /* local */);
 
     SetRootPath();
 }
@@ -616,15 +634,19 @@ void wxFileConfig::Parse(wxTextBuffer& buffer, bool bLocal)
       SetPath(strGroup);
 
       if ( bLocal )
+      {
+        if ( m_pCurrentGroup->Parent() )
+          m_pCurrentGroup->Parent()->SetLastGroup(m_pCurrentGroup);
         m_pCurrentGroup->SetLine(m_linesTail);
+      }
 
       // check that there is nothing except comments left on this line
-      bool bCont = TRUE;
+      bool bCont = true;
       while ( *++pEnd != wxT('\0') && bCont ) {
         switch ( *pEnd ) {
           case wxT('#'):
           case wxT(';'):
-            bCont = FALSE;
+            bCont = false;
             break;
 
           case wxT(' '):
@@ -635,13 +657,13 @@ void wxFileConfig::Parse(wxTextBuffer& buffer, bool bLocal)
           default:
             wxLogWarning(_("file '%s', line %d: '%s' ignored after group header."),
                          buffer.GetName(), n + 1, pEnd);
-            bCont = FALSE;
+            bCont = false;
         }
       }
     }
     else {                        // a key
       const wxChar *pEnd = pStart;
-      while ( *pEnd && *pEnd != wxT('=') && !wxIsspace(*pEnd) ) {
+      while ( *pEnd && *pEnd != wxT('=') /* && !wxIsspace(*pEnd)*/ ) {
         if ( *pEnd == wxT('\\') ) {
           // next character may be space or not - still take it because it's
           // quoted (unless there is nothing)
@@ -655,7 +677,7 @@ void wxFileConfig::Parse(wxTextBuffer& buffer, bool bLocal)
         pEnd++;
       }
 
-      wxString strKey(FilterInEntryName(wxString(pStart, pEnd)));
+      wxString strKey(FilterInEntryName(wxString(pStart, pEnd).Trim()));
 
       // skip whitespace
       while ( wxIsspace(*pEnd) )
@@ -671,9 +693,6 @@ void wxFileConfig::Parse(wxTextBuffer& buffer, bool bLocal)
         if ( pEntry == NULL ) {
           // new entry
           pEntry = m_pCurrentGroup->AddEntry(strKey, n);
-
-          if ( bLocal )
-            pEntry->SetLine(m_linesTail);
         }
         else {
           if ( bLocal && pEntry->IsImmutable() ) {
@@ -691,11 +710,12 @@ void wxFileConfig::Parse(wxTextBuffer& buffer, bool bLocal)
             wxLogWarning(_("file '%s', line %d: key '%s' was first found at line %d."),
                          buffer.GetName(), n + 1, strKey.c_str(), pEntry->Line());
 
-            if ( bLocal )
-              pEntry->SetLine(m_linesTail);
           }
         }
 
+        if ( bLocal )
+          pEntry->SetLine(m_linesTail);
+
         // skip whitespace
         while ( wxIsspace(*pEnd) )
           pEnd++;
@@ -704,7 +724,7 @@ void wxFileConfig::Parse(wxTextBuffer& buffer, bool bLocal)
         if ( !(GetStyle() & wxCONFIG_USE_NO_ESCAPE_CHARACTERS) )
             value = FilterInValue(value);
 
-        pEntry->SetValue(value, FALSE);
+        pEntry->SetValue(value, false);
       }
     }
   }
@@ -771,10 +791,10 @@ bool wxFileConfig::GetNextGroup (wxString& str, long& lIndex) const
 {
   if ( size_t(lIndex) < m_pCurrentGroup->Groups().Count() ) {
     str = m_pCurrentGroup->Groups()[(size_t)lIndex++]->Name();
-    return TRUE;
+    return true;
   }
   else
-    return FALSE;
+    return false;
 }
 
 bool wxFileConfig::GetFirstEntry(wxString& str, long& lIndex) const
@@ -787,10 +807,10 @@ bool wxFileConfig::GetNextEntry (wxString& str, long& lIndex) const
 {
   if ( size_t(lIndex) < m_pCurrentGroup->Entries().Count() ) {
     str = m_pCurrentGroup->Entries()[(size_t)lIndex++]->Name();
-    return TRUE;
+    return true;
   }
   else
-    return FALSE;
+    return false;
 }
 
 size_t wxFileConfig::GetNumberOfEntries(bool bRecursive) const
@@ -801,7 +821,7 @@ size_t wxFileConfig::GetNumberOfEntries(bool bRecursive) const
     size_t nSubgroups = m_pCurrentGroup->Groups().Count();
     for ( size_t nGroup = 0; nGroup < nSubgroups; nGroup++ ) {
       CONST_CAST m_pCurrentGroup = m_pCurrentGroup->Groups()[nGroup];
-      n += GetNumberOfEntries(TRUE);
+      n += GetNumberOfEntries(true);
       CONST_CAST m_pCurrentGroup = pOldCurrentGroup;
     }
   }
@@ -817,7 +837,7 @@ size_t wxFileConfig::GetNumberOfGroups(bool bRecursive) const
     size_t nSubgroups = m_pCurrentGroup->Groups().Count();
     for ( size_t nGroup = 0; nGroup < nSubgroups; nGroup++ ) {
       CONST_CAST m_pCurrentGroup = m_pCurrentGroup->Groups()[nGroup];
-      n += GetNumberOfGroups(TRUE);
+      n += GetNumberOfGroups(true);
       CONST_CAST m_pCurrentGroup = pOldCurrentGroup;
     }
   }
@@ -855,19 +875,19 @@ bool wxFileConfig::DoReadString(const wxString& key, wxString* pStr) const
 
   wxFileConfigEntry *pEntry = m_pCurrentGroup->FindEntry(path.Name());
   if (pEntry == NULL) {
-    return FALSE;
+    return false;
   }
 
   *pStr = pEntry->Value();
 
-  return TRUE;
+  return true;
 }
 
 bool wxFileConfig::DoReadLong(const wxString& key, long *pl) const
 {
     wxString str;
     if ( !Read(key, &str) )
-        return FALSE;
+        return false;
 
     // extra spaces shouldn't prevent us from reading numeric values
     str.Trim();
@@ -913,7 +933,7 @@ bool wxFileConfig::DoWriteString(const wxString& key, const wxString& szValue)
         {
             wxLogError( _("Config entry name cannot start with '%c'."),
                         wxCONFIG_IMMUTABLE_PREFIX);
-            return FALSE;
+            return false;
         }
 
         wxFileConfigEntry   *pEntry = m_pCurrentGroup->FindEntry(strName);
@@ -932,7 +952,7 @@ bool wxFileConfig::DoWriteString(const wxString& key, const wxString& szValue)
         pEntry->SetValue(szValue);
     }
 
-    return TRUE;
+    return true;
 }
 
 bool wxFileConfig::DoWriteLong(const wxString& key, long lValue)
@@ -943,7 +963,7 @@ bool wxFileConfig::DoWriteLong(const wxString& key, long lValue)
 bool wxFileConfig::Flush(bool /* bCurrentOnly */)
 {
   if ( LineListIsEmpty() || !m_pRootGroup->IsDirty() || !m_strLocalFile )
-    return TRUE;
+    return true;
 
 #ifdef __UNIX__
   // set the umask if needed
@@ -959,7 +979,7 @@ bool wxFileConfig::Flush(bool /* bCurrentOnly */)
   if ( !file.IsOpened() )
   {
     wxLogError(_("can't open user configuration file."));
-    return FALSE;
+    return false;
   }
 
   // write all strings to file
@@ -970,26 +990,30 @@ bool wxFileConfig::Flush(bool /* bCurrentOnly */)
     if ( !file.Write(line, m_conv) )
     {
       wxLogError(_("can't write user configuration file."));
-      return FALSE;
+      return false;
     }
   }
 
   bool ret = file.Commit();
 
 #if defined(__WXMAC__)
-  if ( ret )
-  {
-       FSSpec spec ;
-
-       wxMacFilename2FSSpec( m_strLocalFile , &spec ) ;
-       FInfo finfo ;
-       if ( FSpGetFInfo( &spec , &finfo ) == noErr )
-       {
-               finfo.fdType = 'TEXT' ;
-               finfo.fdCreator = 'ttxt' ;
-               FSpSetFInfo( &spec , &finfo ) ;
-       }
-  }
+    if ( ret )
+    {
+        FSRef fsRef ;
+        FSCatalogInfo catInfo;
+        FileInfo *finfo ;
+
+        if ( wxMacPathToFSRef( m_strLocalFile , &fsRef ) == noErr )
+        {
+            if ( FSGetCatalogInfo (&fsRef, kFSCatInfoFinderInfo, &catInfo, NULL, NULL, NULL) == noErr )
+            {
+                finfo = (FileInfo*)&catInfo.finderInfo;
+                finfo->fileType = 'TEXT' ;
+                finfo->fileCreator = 'ttxt' ;
+                FSSetCatalogInfo( &fsRef, kFSCatInfoFinderInfo, &catInfo ) ;
+            }
+        }
+    }
 #endif // __WXMAC__
 
 #ifdef __UNIX__
@@ -1013,21 +1037,21 @@ bool wxFileConfig::RenameEntry(const wxString& oldName,
     // check that the entry exists
     wxFileConfigEntry *oldEntry = m_pCurrentGroup->FindEntry(oldName);
     if ( !oldEntry )
-        return FALSE;
+        return false;
 
     // check that the new entry doesn't already exist
     if ( m_pCurrentGroup->FindEntry(newName) )
-        return FALSE;
+        return false;
 
     // delete the old entry, create the new one
     wxString value = oldEntry->Value();
     if ( !m_pCurrentGroup->DeleteEntry(oldName) )
-        return FALSE;
+        return false;
 
     wxFileConfigEntry *newEntry = m_pCurrentGroup->AddEntry(newName);
     newEntry->SetValue(value);
 
-    return TRUE;
+    return true;
 }
 
 bool wxFileConfig::RenameGroup(const wxString& oldName,
@@ -1036,15 +1060,15 @@ bool wxFileConfig::RenameGroup(const wxString& oldName,
     // check that the group exists
     wxFileConfigGroup *group = m_pCurrentGroup->FindSubgroup(oldName);
     if ( !group )
-        return FALSE;
+        return false;
 
     // check that the new group doesn't already exist
     if ( m_pCurrentGroup->FindSubgroup(newName) )
-        return FALSE;
+        return false;
 
     group->Rename(newName);
 
-    return TRUE;
+    return true;
 }
 
 // ----------------------------------------------------------------------------
@@ -1056,7 +1080,7 @@ bool wxFileConfig::DeleteEntry(const wxString& key, bool bGroupIfEmptyAlso)
   wxConfigPathChanger path(this, key);
 
   if ( !m_pCurrentGroup->DeleteEntry(path.Name()) )
-    return FALSE;
+    return false;
 
   if ( bGroupIfEmptyAlso && m_pCurrentGroup->IsEmpty() ) {
     if ( m_pCurrentGroup != m_pRootGroup ) {
@@ -1067,7 +1091,7 @@ bool wxFileConfig::DeleteEntry(const wxString& key, bool bGroupIfEmptyAlso)
     //else: never delete the root group
   }
 
-  return TRUE;
+  return true;
 }
 
 bool wxFileConfig::DeleteGroup(const wxString& key)
@@ -1081,13 +1105,16 @@ bool wxFileConfig::DeleteAll()
 {
   CleanUp();
 
-  if ( wxRemove(m_strLocalFile) == -1 )
-    wxLogSysError(_("can't delete user configuration file '%s'"), m_strLocalFile.c_str());
+  if ( wxFile::Exists(m_strLocalFile) && wxRemove(m_strLocalFile) == -1 )
+  {
+      wxLogSysError(_("can't delete user configuration file '%s'"), m_strLocalFile.c_str());
+      return false;
+  }
 
   m_strLocalFile = m_strGlobalFile = wxT("");
   Init();
 
-  return TRUE;
+  return true;
 }
 
 // ----------------------------------------------------------------------------
@@ -1242,7 +1269,7 @@ wxFileConfigGroup::wxFileConfigGroup(wxFileConfigGroup *pParent,
 {
   m_pConfig = pConfig;
   m_pParent = pParent;
-  m_bDirty  = FALSE;
+  m_bDirty  = false;
   m_pLine   = NULL;
 
   m_pLastEntry = NULL;
@@ -1538,14 +1565,14 @@ bool wxFileConfigGroup::DeleteSubgroupByName(const wxChar *szName)
 {
     wxFileConfigGroup * const pGroup = FindSubgroup(szName);
 
-    return pGroup ? DeleteSubgroup(pGroup) : FALSE;
+    return pGroup ? DeleteSubgroup(pGroup) : false;
 }
 
 // Delete the subgroup and remove all references to it from
 // other data structures.
 bool wxFileConfigGroup::DeleteSubgroup(wxFileConfigGroup *pGroup)
 {
-    wxCHECK_MSG( pGroup, FALSE, _T("deleting non existing group?") );
+    wxCHECK_MSG( pGroup, false, _T("deleting non existing group?") );
 
     wxLogTrace( _T("wxFileConfig"),
                 _T("Deleting group '%s' from '%s'"),
@@ -1679,13 +1706,13 @@ bool wxFileConfigGroup::DeleteSubgroup(wxFileConfigGroup *pGroup)
     m_aSubgroups.Remove(pGroup);
     delete pGroup;
 
-    return TRUE;
+    return true;
 }
 
 bool wxFileConfigGroup::DeleteEntry(const wxChar *szName)
 {
   wxFileConfigEntry *pEntry = FindEntry(szName);
-  wxCHECK( pEntry != NULL, FALSE );  // deleting non existing item?
+  wxCHECK( pEntry != NULL, false );  // deleting non existing item?
 
   wxFileConfigLineList *pLine = pEntry->GetLine();
   if ( pLine != NULL ) {
@@ -1729,7 +1756,7 @@ bool wxFileConfigGroup::DeleteEntry(const wxChar *szName)
   m_aEntries.Remove(pEntry);
   delete pEntry;
 
-  return TRUE;
+  return true;
 }
 
 // ----------------------------------------------------------------------------
@@ -1737,7 +1764,7 @@ bool wxFileConfigGroup::DeleteEntry(const wxChar *szName)
 // ----------------------------------------------------------------------------
 void wxFileConfigGroup::SetDirty()
 {
-  m_bDirty = TRUE;
+  m_bDirty = true;
   if ( Parent() != NULL )             // propagate upwards
     Parent()->SetDirty();
 }
@@ -1761,7 +1788,7 @@ wxFileConfigEntry::wxFileConfigEntry(wxFileConfigGroup *pParent,
   m_pLine   = NULL;
 
   m_bDirty =
-  m_bHasValue = FALSE;
+  m_bHasValue = false;
 
   m_bImmutable = strName[0] == wxCONFIG_IMMUTABLE_PREFIX;
   if ( m_bImmutable )
@@ -1783,7 +1810,7 @@ void wxFileConfigEntry::SetLine(wxFileConfigLineList *pLine)
   Group()->SetLastEntry(this);
 }
 
-// second parameter is FALSE if we read the value from file and prevents the
+// second parameter is false if we read the value from file and prevents the
 // entry from being marked as 'dirty'
 void wxFileConfigEntry::SetValue(const wxString& strValue, bool bUser)
 {
@@ -1801,7 +1828,7 @@ void wxFileConfigEntry::SetValue(const wxString& strValue, bool bUser)
     if ( m_bHasValue && strValue == m_strValue )
         return;
 
-    m_bHasValue = TRUE;
+    m_bHasValue = true;
     m_strValue = strValue;
 
     if ( bUser )
@@ -1827,8 +1854,6 @@ void wxFileConfigEntry::SetValue(const wxString& strValue, bool bUser)
         else // this entry didn't exist in the local file
         {
             // add a new line to the file
-            wxASSERT( m_nLine == wxNOT_FOUND );   // consistency check
-
             wxFileConfigLineList *line = Group()->GetLastEntryLine();
             m_pLine = Group()->Config()->LineListInsert(strLine, line);
 
@@ -1841,7 +1866,7 @@ void wxFileConfigEntry::SetValue(const wxString& strValue, bool bUser)
 
 void wxFileConfigEntry::SetDirty()
 {
-  m_bDirty = TRUE;
+  m_bDirty = true;
   Group()->SetDirty();
 }
 
@@ -2000,14 +2025,22 @@ static wxString FilterOutEntryName(const wxString& str)
   strResult.Alloc(str.Len());
 
   for ( const wxChar *pc = str.c_str(); *pc != wxT('\0'); pc++ ) {
-    wxChar c = *pc;
+    const wxChar c = *pc;
 
     // we explicitly allow some of "safe" chars and 8bit ASCII characters
-    // which will probably never have special meaning
+    // which will probably never have special meaning and with which we can't
+    // use isalnum() anyhow (in ASCII built, in Unicode it's just fine)
+    //
     // NB: note that wxCONFIG_IMMUTABLE_PREFIX and wxCONFIG_PATH_SEPARATOR
     //     should *not* be quoted
-    if ( !wxIsalnum(c) && !wxStrchr(wxT("@_/-!.*%"), c) && ((c & 0x80) == 0) )
+    if (
+#if !wxUSE_UNICODE
+            ((unsigned char)c < 127) &&
+#endif // ANSI
+         !wxIsalnum(c) && !wxStrchr(wxT("@_/-!.*%"), c) )
+    {
       strResult += wxT('\\');
+    }
 
     strResult += c;
   }