#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/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
// ----------------------------------------------------------------------------
#define CONST_CAST ((wxFileConfig *)this)->
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+#ifndef MAX_PATH
+ #define MAX_PATH 512
+#endif
+
// ----------------------------------------------------------------------------
// global functions declarations
// ----------------------------------------------------------------------------
// is 'c' a valid character in group name?
-// NB: APPCONF_IMMUTABLE_PREFIX and APPCONF_PATH_SEPARATOR must be valid chars,
+// 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);
// ----------------------------------------------------------------------------
// static functions
// ----------------------------------------------------------------------------
-wxString wxFileConfig::GetGlobalFileName(const char *szFile)
+wxString wxFileConfig::GetGlobalDir()
{
- wxString str;
+ wxString strDir;
+
+ #ifdef __UNIX__
+ 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);
+
+ strDir = szWinDir;
+ strDir << '\\';
+ #endif // Unix/Windows
+
+ return strDir;
+}
+
+wxString wxFileConfig::GetLocalDir()
+{
+ wxString strDir;
- bool bNoExt = strchr(szFile, '.') == NULL;
+ wxGetHomeDir(&strDir);
+
+#ifdef __UNIX__
+ if (strDir.Last() != '/') strDir << '/';
+#else
+ if (strDir.Last() != '\\') strDir << '\\';
+#endif
+
+ return strDir;
+}
+wxString wxFileConfig::GetGlobalFileName(const char *szFile)
+{
+ wxString str = GetGlobalDir();
+ str << szFile;
+
+ if ( strchr(szFile, '.') == NULL )
#ifdef __UNIX__
- str << "/etc/" << szFile;
- if ( bNoExt )
- str << ".conf";
+ str << ".conf";
#else // Windows
- #ifndef _MAX_PATH
- #define _MAX_PATH 512
- #endif
-
- char szWinDir[_MAX_PATH];
- ::GetWindowsDirectory(szWinDir, _MAX_PATH);
- str << szWinDir << "\\" << szFile;
- if ( bNoExt )
- str << ".ini";
+ str << ".ini";
#endif // UNIX/Win
return str;
wxString wxFileConfig::GetLocalFileName(const char *szFile)
{
- wxString str;
+ wxString str = GetLocalDir();
#ifdef __UNIX__
- const char *szHome = getenv("HOME");
- if ( szHome == NULL ) {
- // we're homeless...
- wxLogWarning(_("can't find user's HOME, using current directory."));
- szHome = ".";
- }
- str << szHome << "/." << szFile;
- #else // Windows
- #ifdef __WIN32__
- const char *szHome = getenv("HOMEDRIVE");
- if ( szHome != NULL )
- str << szHome;
- szHome = getenv("HOMEPATH");
- if ( szHome != NULL )
- str << szHome;
- str << szFile;
- if ( strchr(szFile, '.') == NULL )
- str << ".ini";
- #else // Win16
- // Win16 has no idea about home, so use the current directory instead
- str << ".\\" << szFile;
- #endif // WIN16/32
- #endif // UNIX/Win
+ str << '.';
+ #endif
+
+ str << szFile;
+
+ #ifdef __WXMSW__
+ if ( strchr(szFile, '.') == NULL )
+ str << ".ini";
+ #endif
return str;
}
m_linesHead =
m_linesTail = NULL;
- m_strPath.Empty();
-}
-
-wxFileConfig::wxFileConfig(const wxString& strLocal, const wxString& strGlobal)
- : m_strLocalFile(strLocal), m_strGlobalFile(strGlobal)
-{
- Init();
-
// it's not an error if (one of the) file(s) doesn't exist
// parse the global file
- if ( !strGlobal.IsEmpty() ) {
- if ( wxFile::Exists(strGlobal) ) {
- wxTextFile fileGlobal(strGlobal);
+ if ( !m_strGlobalFile.IsEmpty() && wxFile::Exists(m_strGlobalFile) ) {
+ wxTextFile fileGlobal(m_strGlobalFile);
- if ( fileGlobal.Open() ) {
- Parse(fileGlobal, FALSE /* global */);
- SetRootPath();
- }
- else
- wxLogWarning(_("can't open global configuration file '%s'."),
- strGlobal.c_str());
+ if ( fileGlobal.Open() ) {
+ Parse(fileGlobal, FALSE /* global */);
+ SetRootPath();
}
+ else
+ wxLogWarning(_("can't open global configuration file '%s'."),
+ m_strGlobalFile.c_str());
}
// parse the local file
- if ( wxFile::Exists(strLocal) ) {
- wxTextFile fileLocal(strLocal);
+ if ( !m_strLocalFile.IsEmpty() && wxFile::Exists(m_strLocalFile) ) {
+ wxTextFile fileLocal(m_strLocalFile);
if ( fileLocal.Open() ) {
Parse(fileLocal, TRUE /* local */);
SetRootPath();
}
else
wxLogWarning(_("can't open user configuration file '%s'."),
- strLocal.c_str());
+ m_strLocalFile.c_str());
}
}
-wxFileConfig::~wxFileConfig()
+// 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)
+ : wxConfigBase(appName, vendorName, strLocal, strGlobal, style),
+ m_strLocalFile(strLocal), m_strGlobalFile(strGlobal)
+{
+ // Make up an application name if not supplied
+ if (appName.IsEmpty() && wxTheApp)
+ {
+ SetAppName(wxTheApp->GetAppName());
+ }
+
+ // Make up names for files if empty
+ if ( m_strLocalFile.IsEmpty() && (style & wxCONFIG_USE_LOCAL_FILE) )
+ {
+ m_strLocalFile = GetLocalFileName(GetAppName());
+ }
+
+ if ( m_strGlobalFile.IsEmpty() && (style & wxCONFIG_USE_GLOBAL_FILE) )
+ {
+ m_strGlobalFile = GetGlobalFileName(GetAppName());
+ }
+
+ // Check if styles are not supplied, but filenames are, in which case
+ // add the correct styles.
+ if ( !m_strLocalFile.IsEmpty() )
+ SetStyle(GetStyle() | wxCONFIG_USE_LOCAL_FILE);
+
+ if ( !m_strGlobalFile.IsEmpty() )
+ SetStyle(GetStyle() | wxCONFIG_USE_GLOBAL_FILE);
+
+ // if the path is not absolute, prepend the standard directory to it
+ if ( !m_strLocalFile.IsEmpty() && !wxIsAbsolutePath(m_strLocalFile) )
+ {
+ wxString strLocal = m_strLocalFile;
+ m_strLocalFile = GetLocalDir();
+ m_strLocalFile << strLocal;
+ }
+
+ if ( !m_strGlobalFile.IsEmpty() && !wxIsAbsolutePath(m_strGlobalFile) )
+ {
+ wxString strGlobal = m_strGlobalFile;
+ m_strGlobalFile = GetGlobalDir();
+ m_strGlobalFile << strGlobal;
+ }
+
+ Init();
+}
+
+void wxFileConfig::CleanUp()
{
- Flush();
delete m_pRootGroup;
LineList *pCur = m_linesHead;
}
}
+wxFileConfig::~wxFileConfig()
+{
+ Flush();
+
+ CleanUp();
+}
+
// ----------------------------------------------------------------------------
// parse a config file
// ----------------------------------------------------------------------------
const char *pEnd;
wxString strLine;
- uint nLineCount = file.GetLineCount();
- for ( uint n = 0; n < nLineCount; n++ ) {
+ size_t nLineCount = file.GetLineCount();
+ for ( size_t n = 0; n < nLineCount; n++ ) {
strLine = file[n];
// add the line to linked list
// group name here is always considered as abs path
wxString strGroup;
pStart++;
- strGroup << APPCONF_PATH_SEPARATOR << wxString(pStart, pEnd - pStart);
+ strGroup << wxCONFIG_PATH_SEPARATOR << wxString(pStart, pEnd - pStart);
// will create it if doesn't yet exist
SetPath(strGroup);
return;
}
- if ( strPath[0] == APPCONF_PATH_SEPARATOR ) {
+ if ( strPath[0] == wxCONFIG_PATH_SEPARATOR ) {
// absolute path
wxSplitPath(aParts, strPath);
}
else {
// relative path, combine with current one
wxString strFullPath = m_strPath;
- strFullPath << APPCONF_PATH_SEPARATOR << strPath;
+ strFullPath << wxCONFIG_PATH_SEPARATOR << strPath;
wxSplitPath(aParts, strFullPath);
}
// change current group
- uint n;
+ size_t n;
m_pCurrentGroup = m_pRootGroup;
for ( n = 0; n < aParts.Count(); n++ ) {
ConfigGroup *pNextGroup = m_pCurrentGroup->FindSubgroup(aParts[n]);
// recombine path parts in one variable
m_strPath.Empty();
for ( n = 0; n < aParts.Count(); n++ ) {
- m_strPath << APPCONF_PATH_SEPARATOR << aParts[n];
+ m_strPath << wxCONFIG_PATH_SEPARATOR << aParts[n];
}
}
// enumeration
// ----------------------------------------------------------------------------
-bool wxFileConfig::GetFirstGroup(wxString& str, long& lIndex)
+bool wxFileConfig::GetFirstGroup(wxString& str, long& lIndex) const
{
lIndex = 0;
return GetNextGroup(str, lIndex);
}
-bool wxFileConfig::GetNextGroup (wxString& str, long& lIndex)
+bool wxFileConfig::GetNextGroup (wxString& str, long& lIndex) const
{
- if ( uint(lIndex) < m_pCurrentGroup->Groups().Count() ) {
+ if ( size_t(lIndex) < m_pCurrentGroup->Groups().Count() ) {
str = m_pCurrentGroup->Groups()[lIndex++]->Name();
return TRUE;
}
return FALSE;
}
-bool wxFileConfig::GetFirstEntry(wxString& str, long& lIndex)
+bool wxFileConfig::GetFirstEntry(wxString& str, long& lIndex) const
{
lIndex = 0;
return GetNextEntry(str, lIndex);
}
-bool wxFileConfig::GetNextEntry (wxString& str, long& lIndex)
+bool wxFileConfig::GetNextEntry (wxString& str, long& lIndex) const
{
- if ( uint(lIndex) < m_pCurrentGroup->Entries().Count() ) {
+ if ( size_t(lIndex) < m_pCurrentGroup->Entries().Count() ) {
str = m_pCurrentGroup->Entries()[lIndex++]->Name();
return TRUE;
}
return FALSE;
}
-uint wxFileConfig::GetNumberOfEntries(bool bRecursive) const
+size_t wxFileConfig::GetNumberOfEntries(bool bRecursive) const
{
- uint n = m_pCurrentGroup->Entries().Count();
+ size_t n = m_pCurrentGroup->Entries().Count();
if ( bRecursive ) {
ConfigGroup *pOldCurrentGroup = m_pCurrentGroup;
- uint nSubgroups = m_pCurrentGroup->Groups().Count();
- for ( uint nGroup = 0; nGroup < nSubgroups; nGroup++ ) {
+ 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);
CONST_CAST m_pCurrentGroup = pOldCurrentGroup;
return n;
}
-uint wxFileConfig::GetNumberOfGroups(bool bRecursive) const
+size_t wxFileConfig::GetNumberOfGroups(bool bRecursive) const
{
- uint n = m_pCurrentGroup->Groups().Count();
+ size_t n = m_pCurrentGroup->Groups().Count();
if ( bRecursive ) {
ConfigGroup *pOldCurrentGroup = m_pCurrentGroup;
- uint nSubgroups = m_pCurrentGroup->Groups().Count();
- for ( uint nGroup = 0; nGroup < nSubgroups; nGroup++ ) {
+ 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);
CONST_CAST m_pCurrentGroup = pOldCurrentGroup;
bool wxFileConfig::HasGroup(const wxString& strName) const
{
- PathChanger path(this, strName);
+ wxConfigPathChanger path(this, strName);
ConfigGroup *pGroup = m_pCurrentGroup->FindSubgroup(path.Name());
return pGroup != NULL;
bool wxFileConfig::HasEntry(const wxString& strName) const
{
- PathChanger path(this, strName);
+ wxConfigPathChanger path(this, strName);
ConfigEntry *pEntry = m_pCurrentGroup->FindEntry(path.Name());
return pEntry != NULL;
// read/write values
// ----------------------------------------------------------------------------
-bool wxFileConfig::Read(wxString *pstr,
- const char *szKey,
- const char *szDefault) const
+bool wxFileConfig::Read(const wxString& key,
+ wxString* pStr) const
{
- PathChanger path(this, szKey);
+ wxConfigPathChanger path(this, key);
ConfigEntry *pEntry = m_pCurrentGroup->FindEntry(path.Name());
if (pEntry == NULL) {
- *pstr = ExpandEnvVars(szDefault);
return FALSE;
}
else {
- *pstr = ExpandEnvVars(pEntry->Value());
+ *pStr = ExpandEnvVars(pEntry->Value());
return TRUE;
}
}
-const char *wxFileConfig::Read(const char *szKey,
- const char *szDefault) const
+bool wxFileConfig::Read(const wxString& key,
+ wxString* pStr, const wxString& defVal) const
{
- static wxString s_str;
- Read(&s_str, szKey, szDefault);
+ wxConfigPathChanger path(this, key);
- return s_str.c_str();
+ ConfigEntry *pEntry = m_pCurrentGroup->FindEntry(path.Name());
+ if (pEntry == NULL) {
+ if( IsRecordingDefaults() )
+ ((wxFileConfig *)this)->Write(key,defVal);
+ *pStr = ExpandEnvVars(defVal);
+ return FALSE;
+ }
+ else {
+ *pStr = ExpandEnvVars(pEntry->Value());
+ return TRUE;
+ }
}
-bool wxFileConfig::Read(long *pl, const char *szKey, long lDefault) const
+bool wxFileConfig::Read(const wxString& key, long *pl) const
{
wxString str;
- if ( Read(&str, szKey) ) {
+ if ( Read(key, & str) ) {
*pl = atol(str);
return TRUE;
}
else {
- *pl = lDefault;
return FALSE;
}
}
-bool wxFileConfig::Write(const char *szKey, const char *szValue)
+bool wxFileConfig::Write(const wxString& key, const wxString& szValue)
{
- PathChanger path(this, szKey);
+ wxConfigPathChanger path(this, key);
wxString strName = path.Name();
if ( strName.IsEmpty() ) {
// setting the value of a group is an error
- wxASSERT_MSG( IsEmpty(szValue), "can't set value of a group!" );
+ wxASSERT_MSG( IsEmpty(szValue), _("can't set value of a group!") );
// ... except if it's empty in which case it's a way to force it's creation
m_pCurrentGroup->SetDirty();
// writing an entry
// check that the name is reasonable
- if ( strName[0u] == APPCONF_IMMUTABLE_PREFIX ) {
+ if ( strName[0u] == wxCONFIG_IMMUTABLE_PREFIX ) {
wxLogError(_("Entry name can't start with '%c'."),
- APPCONF_IMMUTABLE_PREFIX);
+ wxCONFIG_IMMUTABLE_PREFIX);
return FALSE;
}
return TRUE;
}
-bool wxFileConfig::Write(const char *szKey, long lValue)
+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(szKey, szBuf);
+ wxString buf;
+ buf.Printf("%ld", lValue);
+ return Write(key, buf);
}
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
// ----------------------------------------------------------------------------
-bool wxFileConfig::DeleteEntry(const char *szKey, bool bGroupIfEmptyAlso)
+bool wxFileConfig::DeleteEntry(const wxString& key, bool bGroupIfEmptyAlso)
{
- PathChanger path(this, szKey);
+ wxConfigPathChanger path(this, key);
if ( !m_pCurrentGroup->DeleteEntry(path.Name()) )
return FALSE;
if ( m_pCurrentGroup != m_pRootGroup ) {
ConfigGroup *pGroup = m_pCurrentGroup;
SetPath(".."); // changes m_pCurrentGroup!
- m_pCurrentGroup->DeleteSubgroup(pGroup->Name());
+ m_pCurrentGroup->DeleteSubgroupByName(pGroup->Name());
}
//else: never delete the root group
}
return TRUE;
}
-bool wxFileConfig::DeleteGroup(const char *szKey)
+bool wxFileConfig::DeleteGroup(const wxString& key)
{
- PathChanger path(this, szKey);
+ wxConfigPathChanger path(this, key);
- return m_pCurrentGroup->DeleteSubgroup(path.Name());
+ return m_pCurrentGroup->DeleteSubgroupByName(path.Name());
}
bool wxFileConfig::DeleteAll()
{
+ CleanUp();
+
const char *szFile = m_strLocalFile;
- delete m_pRootGroup;
- Init();
if ( remove(szFile) == -1 )
wxLogSysError(_("can't delete user configuration file '%s'"), szFile);
- szFile = m_strGlobalFile;
- if ( remove(szFile) )
- wxLogSysError(_("can't delete system configuration file '%s'"), szFile);
+ m_strLocalFile = m_strGlobalFile = "";
+ Init();
return TRUE;
}
// ----------------------------------------------------------------------------
// 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);
}
// 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 )
// last entry?
if ( pNext == NULL )
m_linesTail = pPrev;
- else
+ else
pNext->SetPrev(pPrev);
delete pLine;
// ----------------------------------------------------------------------------
// ctor
-wxFileConfig::ConfigGroup::ConfigGroup(wxFileConfig::ConfigGroup *pParent,
+ConfigGroup::ConfigGroup(ConfigGroup *pParent,
const wxString& strName,
wxFileConfig *pConfig)
: m_aEntries(CompareEntries),
}
// dtor deletes all children
-wxFileConfig::ConfigGroup::~ConfigGroup()
+ConfigGroup::~ConfigGroup()
{
// entries
- uint n, nCount = m_aEntries.Count();
+ size_t n, nCount = m_aEntries.Count();
for ( n = 0; n < nCount; n++ )
delete m_aEntries[n];
// line
// ----------------------------------------------------------------------------
-void wxFileConfig::ConfigGroup::SetLine(LineList *pLine)
+void ConfigGroup::SetLine(LineList *pLine)
{
wxASSERT( m_pLine == NULL ); // shouldn't be called twice
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();
// 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
// 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;
// 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;
// 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() + APPCONF_PATH_SEPARATOR + Name();
+ return Parent()->GetFullName() + wxCONFIG_PATH_SEPARATOR + Name();
else
return "";
}
// ----------------------------------------------------------------------------
// use binary search because the array is sorted
-wxFileConfig::ConfigEntry *
-wxFileConfig::ConfigGroup::FindEntry(const char *szName) const
+ConfigEntry *
+ConfigGroup::FindEntry(const char *szName) const
{
- uint i,
+ size_t i,
lo = 0,
hi = m_aEntries.Count();
int res;
- wxFileConfig::ConfigEntry *pEntry;
+ ConfigEntry *pEntry;
while ( lo < hi ) {
i = (lo + hi)/2;
pEntry = m_aEntries[i];
- #if APPCONF_CASE_SENSITIVE
+ #if wxCONFIG_CASE_SENSITIVE
res = strcmp(pEntry->Name(), szName);
#else
res = Stricmp(pEntry->Name(), szName);
return NULL;
}
-wxFileConfig::ConfigGroup *
-wxFileConfig::ConfigGroup::FindSubgroup(const char *szName) const
+ConfigGroup *
+ConfigGroup::FindSubgroup(const char *szName) const
{
- uint i,
+ size_t i,
lo = 0,
hi = m_aSubgroups.Count();
int res;
- wxFileConfig::ConfigGroup *pGroup;
+ ConfigGroup *pGroup;
while ( lo < hi ) {
i = (lo + hi)/2;
pGroup = m_aSubgroups[i];
- #if APPCONF_CASE_SENSITIVE
+ #if wxCONFIG_CASE_SENSITIVE
res = strcmp(pGroup->Name(), szName);
#else
res = Stricmp(pGroup->Name(), szName);
// ----------------------------------------------------------------------------
// 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 );
}
// 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 );
delete several of them.
*/
-bool wxFileConfig::ConfigGroup::DeleteSubgroup(const char *szName)
+bool ConfigGroup::DeleteSubgroupByName(const char *szName)
+{
+ return DeleteSubgroup(FindSubgroup(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 ConfigGroup::DeleteSubgroup(ConfigGroup *pGroup)
{
- ConfigGroup *pGroup = FindSubgroup(szName);
wxCHECK( pGroup != NULL, FALSE ); // deleting non existing group?
// delete all entries
- uint nCount = pGroup->m_aEntries.Count();
- for ( uint nEntry = 0; nEntry < nCount; nEntry++ ) {
+ size_t nCount = pGroup->m_aEntries.Count();
+ for ( size_t nEntry = 0; nEntry < nCount; nEntry++ ) {
LineList *pLine = pGroup->m_aEntries[nEntry]->GetLine();
if ( pLine != NULL )
m_pConfig->LineListRemove(pLine);
}
+ // and subgroups of this sungroup
+ nCount = pGroup->m_aSubgroups.Count();
+ for ( size_t nGroup = 0; nGroup < nCount; nGroup++ ) {
+ pGroup->DeleteSubgroup(pGroup->m_aSubgroups[nGroup]);
+ }
+
LineList *pLine = pGroup->m_pLine;
if ( pLine != NULL ) {
// notice that we may do this test inside the previous "if" because the
// go back until we find a subgroup or reach the group's line
ConfigGroup *pNewLast = NULL;
- uint n, nSubgroups = m_aSubgroups.Count();
- for ( LineList *pl = pLine->Prev(); pl != m_pLine; pl = pl->Prev() ) {
+ size_t n, nSubgroups = m_aSubgroups.Count();
+ LineList *pl;
+ for ( pl = pLine->Prev(); pl != m_pLine; pl = pl->Prev() ) {
// is it our subgroup?
for ( n = 0; (pNewLast == NULL) && (n < nSubgroups); n++ ) {
// do _not_ call GetGroupLine! we don't want to add it to the local
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?
// go back until we find another entry or reach the group's line
ConfigEntry *pNewLast = NULL;
- uint n, nEntries = m_aEntries.Count();
- for ( LineList *pl = pLine->Prev(); pl != m_pLine; pl = pl->Prev() ) {
+ size_t n, nEntries = m_aEntries.Count();
+ LineList *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 )
// ----------------------------------------------------------------------------
//
// ----------------------------------------------------------------------------
-void wxFileConfig::ConfigGroup::SetDirty()
+void ConfigGroup::SetDirty()
{
m_bDirty = TRUE;
if ( Parent() != NULL ) // propagate upwards
// ----------------------------------------------------------------------------
// ctor
// ----------------------------------------------------------------------------
-wxFileConfig::ConfigEntry::ConfigEntry(wxFileConfig::ConfigGroup *pParent,
+ConfigEntry::ConfigEntry(ConfigGroup *pParent,
const wxString& strName,
int nLine)
: m_strName(strName)
m_bDirty = FALSE;
- m_bImmutable = strName[0] == APPCONF_IMMUTABLE_PREFIX;
+ m_bImmutable = strName[0] == wxCONFIG_IMMUTABLE_PREFIX;
if ( m_bImmutable )
m_strName.erase(0, 1); // remove first character
}
// 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'"),
// 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."),
}
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());
}
}
-void wxFileConfig::ConfigEntry::SetDirty()
+void ConfigEntry::SetDirty()
{
m_bDirty = TRUE;
Group()->SetDirty();
// compare functions for array sorting
// ----------------------------------------------------------------------------
-int CompareEntries(wxFileConfig::ConfigEntry *p1,
- wxFileConfig::ConfigEntry *p2)
+int CompareEntries(ConfigEntry *p1,
+ ConfigEntry *p2)
{
- #if APPCONF_CASE_SENSITIVE
+ #if wxCONFIG_CASE_SENSITIVE
return strcmp(p1->Name(), p2->Name());
#else
return Stricmp(p1->Name(), p2->Name());
#endif
}
-int CompareGroups(wxFileConfig::ConfigGroup *p1,
- wxFileConfig::ConfigGroup *p2)
+int CompareGroups(ConfigGroup *p1,
+ ConfigGroup *p2)
{
- #if APPCONF_CASE_SENSITIVE
+ #if wxCONFIG_CASE_SENSITIVE
return strcmp(p1->Name(), p2->Name());
#else
return Stricmp(p1->Name(), p2->Name());
bool bQuoted = !str.IsEmpty() && str[0] == '"';
- for ( uint n = bQuoted ? 1 : 0; n < str.Len(); n++ ) {
+ for ( size_t n = bQuoted ? 1 : 0; n < str.Len(); n++ ) {
if ( str[n] == '\\' ) {
switch ( str[++n] ) {
case 'n':
// quote the string before writing it to file
wxString FilterOut(const wxString& str)
{
+ if(str.IsEmpty())
+ return str;
+
wxString strResult;
strResult.Alloc(str.Len());
strResult += '"';
char c;
- for ( uint n = 0; n < str.Len(); n++ ) {
+ for ( size_t n = 0; n < str.Len(); n++ ) {
switch ( str[n] ) {
case '\n':
c = 'n';
break;
case '"':
- if ( bQuote )
+ if ( bQuote ) {
c = '"';
+ break;
+ }
//else: fall through
default:
return strResult;
}
+
+
+
+
+
+
+