Code: Select all
//*****************************************************************************
// @file wxXMLConfig.h
// @author Nicolas Dextraze
// @web http://www.nicdex.com
// @date February 17, 2007
// @desc wxXMLConfig class header
//*****************************************************************************
#pragma once
#include <wx/textfile.h>
#include <wx/confbase.h>
#include <wx/xml/xml.h>
#ifdef wxUSE_STREAMS
#include <wx/stream.h>
#endif
class wxXMLConfig;
#ifdef wxConfig
#undef wxConfig
#endif
#define wxConfig wxXMLConfig
#define wxXMLConfigEntry wxXmlNode
#define wxXMLConfigGroup wxXmlNode
class wxXMLConfig
: public wxConfigBase
{
public:
wxXMLConfig( const wxString& appName = wxEmptyString,
const wxString& vendorName = wxEmptyString,
const wxString& localFilename = wxEmptyString,
const wxString& globalFilename = wxEmptyString,
long style = wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_GLOBAL_FILE,
const wxMBConv& conv = wxConvAuto());
#ifdef wxUSE_STREAMS
wxXMLConfig( wxInputStream& inStream, const wxMBConv& conv = wxConvAuto() );
#endif
virtual ~wxXMLConfig();
static wxString GetGlobalFileName( const wxChar *szFile );
static wxString GetLocalFileName( const wxChar *szFile );
virtual void SetPath( const wxString& strPath );
virtual const wxString& GetPath() const { return m_strPath; }
virtual bool GetFirstGroup( wxString& str, long& lIndex ) const;
virtual bool GetNextGroup( wxString& str, long& lIndex ) const;
virtual bool GetFirstEntry( wxString& str, long& lIndex ) const;
virtual bool GetNextEntry( wxString& str, long& lIndex ) const;
virtual size_t GetNumberOfEntries( bool bRecursive = false ) const;
virtual size_t GetNumberOfGroups( bool bRecursive = false ) const;
virtual bool HasGroup( const wxString& strName ) const;
virtual bool HasEntry( const wxString& strName ) const;
virtual bool Flush( bool bCurrentOnly = false );
virtual bool RenameEntry( const wxString& oldName, const wxString& newName );
virtual bool RenameGroup( const wxString& oldName, const wxString& newName );
virtual bool DeleteEntry( const wxString& key, bool bGroupIfEmptyAlso = true );
virtual bool DeleteGroup( const wxString& key );
virtual bool DeleteAll();
#if wxUSE_STREAMS
virtual bool Save( wxOutputStream& os, const wxMBConv& conv = wxConvAuto() );
#endif
protected:
virtual bool DoReadString( const wxString& key, wxString* pStr ) const;
virtual bool DoReadLong( const wxString& key, long* pl ) const;
virtual bool DoWriteString( const wxString& key, const wxString& szValue );
virtual bool DoWriteLong( const wxString& key, long lValue );
private:
static wxString GetGlobalDir();
static wxString GetLocalDir();
void Init();
void CleanUp();
void Parse( const wxXmlDocument& xmlDocument, bool bLocal );
void SetRootPath();
bool DoSetPath( const wxString& strPath, bool createMissingComponents );
void SetDirty() { m_isDirty = true; }
void ResetDirty() { m_isDirty = false; }
bool IsDirty() { return m_isDirty; }
bool IsGroup( const wxXMLConfigGroup *group ) const;
bool IsEntry( const wxXMLConfigEntry *entry ) const;
wxXMLConfigEntry *FindEntry( const wxString& key ) const;
wxXMLConfigEntry *AddEntry( const wxString& key );
wxXMLConfigGroup *FindGroup( const wxString& key ) const;
wxXMLConfigGroup *AddGroup( const wxString& key );
wxXmlDocument *m_xmlDoc;
wxXMLConfigGroup *m_pCurrentGroup;
wxString m_strLocalFile;
wxString m_strGlobalFile;
wxString m_strPath;
bool m_isDirty;
DECLARE_NO_COPY_CLASS(wxXMLConfig);
};
Code: Select all
//*****************************************************************************
// @file wxXMLConfig.cpp
// @author Nicolas Dextraze
// @web http://www.nicdex.com
// @date February 17, 2007
// @desc wxXMLConfig class implementation
//*****************************************************************************
#include "wxXMLConfig.h"
#include <wx/log.h>
#include <wx/intl.h>
#include <wx/utils.h>
#define XMLCONF_TRACE_MASK _T("xmlconf")
wxXMLConfig::wxXMLConfig( const wxString& appName,
const wxString& vendorName,
const wxString& localFilename,
const wxString& globalFilename,
long style,
const wxMBConv& conv )
: wxConfigBase(appName, vendorName, m_strLocalFile, m_strGlobalFile, style),
m_strLocalFile(localFilename),
m_strGlobalFile(globalFilename),
m_pCurrentGroup(NULL),
m_xmlDoc(NULL)
{
// Make up names for files if empty
if ( m_strLocalFile.empty() && (style & wxCONFIG_USE_LOCAL_FILE) )
m_strLocalFile = GetLocalFileName(GetAppName());
if ( m_strGlobalFile.empty() && (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.empty() )
SetStyle(GetStyle() | wxCONFIG_USE_LOCAL_FILE);
if ( !m_strGlobalFile.empty() )
SetStyle(GetStyle() | wxCONFIG_USE_GLOBAL_FILE);
// if the path is not absolute, prepend the standard directory to it
// UNLESS wxCONFIG_USE_RELATIVE_PATH style is set
if ( !(style & wxCONFIG_USE_RELATIVE_PATH) )
{
if ( !m_strLocalFile.empty() && !wxIsAbsolutePath(m_strLocalFile) )
{
m_strLocalFile.Prepend( GetLocalDir() );
}
if ( !m_strGlobalFile.empty() && !wxIsAbsolutePath(m_strGlobalFile) )
{
m_strGlobalFile.Prepend( GetGlobalDir() );
}
}
Init();
}
#ifdef wxUSE_STREAMS
wxXMLConfig::wxXMLConfig( wxInputStream& inStream, const wxMBConv& conv )
: m_pCurrentGroup(NULL),
m_xmlDoc(NULL)
{
// always local_file when this constructor is called (?)
SetStyle(GetStyle() | wxCONFIG_USE_LOCAL_FILE);
m_xmlDoc = new wxXmlDocument( inStream );
if ( !m_xmlDoc->IsOk() )
{
wxLogError( _("can't parse user configuration") );
}
else
{
m_pCurrentGroup = m_xmlDoc->GetRoot();
SetRootPath();
ResetDirty();
}
}
#endif
wxXMLConfig::~wxXMLConfig()
{
Flush();
CleanUp();
}
wxString wxXMLConfig::GetGlobalFileName( const wxChar *szFile )
{
wxString str = GetGlobalDir();
str << szFile;
if ( wxStrchr(szFile, wxT('.')) == NULL )
{
str << wxT(".config");
}
return str;
}
wxString wxXMLConfig::GetLocalFileName( const wxChar *szFile )
{
wxString str = GetLocalDir();
str << szFile;
if ( wxStrchr(szFile, wxT('.')) == NULL )
{
str << wxT('.');
str << ::wxGetUserId();
str << wxT(".config");
}
return str;
}
void wxXMLConfig::SetPath( const wxString& strPath )
{
DoSetPath( strPath, true );
}
bool wxXMLConfig::GetFirstGroup( wxString& str, long& lIndex ) const
{
lIndex = 0;
return GetNextGroup( str, lIndex );
}
bool wxXMLConfig::GetNextGroup( wxString& str, long& lIndex ) const
{
wxASSERT_MSG( m_pCurrentGroup != NULL, _("current group is null") );
wxASSERT_MSG( IsGroup(m_pCurrentGroup), _("current group is not a group") );
bool getNextGroup = false;
if ( size_t(lIndex) < GetNumberOfGroups() )
{
wxXMLConfigEntry *pEntry = m_pCurrentGroup->GetChildren();
long groupPos = 0;
while( pEntry )
{
if ( IsGroup( pEntry ) )
{
if ( groupPos == lIndex )
{
lIndex++;
str = pEntry->GetName();
getNextGroup = true;
break;
}
groupPos++;
}
pEntry = pEntry->GetNext();
}
}
return getNextGroup;
}
bool wxXMLConfig::GetFirstEntry( wxString& str, long& lIndex ) const
{
lIndex = 0;
return GetNextEntry( str, lIndex );
}
bool wxXMLConfig::GetNextEntry( wxString& str, long& lIndex ) const
{
wxASSERT_MSG( m_pCurrentGroup != NULL, _("current group is null") );
wxASSERT_MSG( IsGroup(m_pCurrentGroup), _("current group is not a group") );
bool getFirstEntry = false;
if ( size_t(lIndex) < GetNumberOfEntries() )
{
wxXMLConfigEntry *pEntry = m_pCurrentGroup->GetChildren();
long entryPos = 0;
while( pEntry )
{
if ( IsEntry( pEntry ) )
{
if ( entryPos == lIndex )
{
lIndex++;
str = pEntry->GetName();
getFirstEntry = true;
break;
}
entryPos++;
}
pEntry = pEntry->GetNext();
}
}
return getFirstEntry;
}
size_t wxXMLConfig::GetNumberOfEntries( bool bRecursive ) const
{
wxASSERT_MSG( m_pCurrentGroup != NULL, _("current group is null") );
wxASSERT_MSG( IsGroup(m_pCurrentGroup), _("current group is not a group") );
wxXMLConfigEntry *pEntry = m_pCurrentGroup->GetChildren();
size_t entriesCount = 0;
while( pEntry != NULL )
{
if ( IsGroup(pEntry) )
{
if ( bRecursive )
{
//wxConfigPathChanger path( this, GetPath() + wxT(wxCONFIG_PATH_SEPARATOR) + pEntry->GetName() + wxT(wxCONFIG_PATH_SEPARATOR) );
entriesCount += GetNumberOfEntries( bRecursive );
}
}
else if ( IsEntry(pEntry) )
{
entriesCount++;
}
pEntry = pEntry->GetNext();
}
return entriesCount;
}
size_t wxXMLConfig::GetNumberOfGroups( bool bRecursive ) const
{
wxASSERT_MSG( m_pCurrentGroup != NULL, _("current group is null") );
wxASSERT_MSG( IsGroup(m_pCurrentGroup), _("current group is not a group") );
wxXMLConfigGroup *pGroup = m_pCurrentGroup->GetChildren();
size_t groupsCount = 0;
while( pGroup != NULL )
{
if ( IsGroup(pGroup) ) // group
{
groupsCount++;
if ( bRecursive )
{
//wxConfigPathChanger path( this, GetPath() + wxT(wxCONFIG_PATH_SEPARATOR) + pGroup->GetName() + wxT(wxCONFIG_PATH_SEPARATOR) );
groupsCount += GetNumberOfGroups( bRecursive );
}
}
pGroup = pGroup->GetNext();
}
return groupsCount;
}
bool wxXMLConfig::HasGroup( const wxString& strName ) const
{
if ( strName.empty() )
return false;
const wxString pathOld = GetPath();
wxXMLConfig *self = wx_const_cast( wxXMLConfig *, this );
const bool rc = self->DoSetPath( strName,false );
self->SetPath( pathOld );
return rc;
}
bool wxXMLConfig::HasEntry( const wxString& entry ) const
{
wxString path = entry.BeforeLast(wxCONFIG_PATH_SEPARATOR);
if ( path.empty() && *entry.c_str() == wxCONFIG_PATH_SEPARATOR )
{
path = wxCONFIG_PATH_SEPARATOR;
}
// set the path and keep a copy of the the current path to set it back after
wxString pathOld;
wxXMLConfig* const self = wx_const_cast( wxXMLConfig *, this );
if ( !path.empty() )
{
pathOld = GetPath();
if ( pathOld.empty() )
pathOld = wxCONFIG_PATH_SEPARATOR;
if ( !self->DoSetPath( path, false ) )
return false;
}
// we look for the entry
bool exists = ( FindEntry( entry ) != NULL );
// we set back the old path
if ( !pathOld.empty() )
{
self->SetPath( pathOld );
}
return exists;
}
bool wxXMLConfig::Flush( bool bCurrentOnly )
{
if ( !IsDirty() || !m_strLocalFile )
return true;
if ( !m_xmlDoc->Save( m_strLocalFile ) )
{
wxLogError(_("can't save user configuration file."));
return false;
}
ResetDirty();
return true;
}
bool wxXMLConfig::RenameEntry( const wxString& oldName, const wxString& newName )
{
wxASSERT_MSG( !wxStrchr(oldName, wxCONFIG_PATH_SEPARATOR), wxT("RenameEntry(): paths are not supported") );
wxXMLConfigEntry *oldEntry = FindEntry( oldName );
if ( !oldEntry )
return false;
if ( FindEntry( newName ) )
return false;
wxString value = oldEntry->GetNodeContent();
if ( DeleteEntry( oldName ) )
return false;
SetDirty();
wxXMLConfigEntry *newEntry = AddEntry( newName );
newEntry->GetChildren()->SetContent( value );
return true;
}
bool wxXMLConfig::RenameGroup( const wxString& oldName, const wxString& newName )
{
wxASSERT_MSG( !wxStrchr(oldName, wxCONFIG_PATH_SEPARATOR), wxT("RenameGroup(): paths are not supported") );
if ( !FindGroup( oldName ) )
return false;
if ( FindGroup( newName ) )
return false;
if ( DeleteGroup( oldName ) )
return false;
SetDirty();
AddGroup( newName );
return true;
}
bool wxXMLConfig::DeleteEntry( const wxString& key, bool bGroupIfEmptyAlso )
{
wxASSERT_MSG( m_pCurrentGroup != NULL, wxT("current group is null") );
wxASSERT_MSG( IsGroup(m_pCurrentGroup), wxT("current group is not a group") );
bool deleteEntry = false;
wxXMLConfigEntry *pLastEntry = NULL;
wxXMLConfigEntry *pCurrentEntry = m_pCurrentGroup->GetChildren();
while( pCurrentEntry )
{
if ( IsEntry( pCurrentEntry ) && ( pCurrentEntry->GetName() == key ) )
break;
pLastEntry = pCurrentEntry;
pCurrentEntry = pCurrentEntry->GetNext();
}
if ( pCurrentEntry )
{
wxXMLConfigEntry *pNextEntry = pCurrentEntry->GetNext();
wxXMLConfigGroup *pParentGroup = pCurrentEntry->GetParent();
if ( pLastEntry )
{
pLastEntry->SetNext( pNextEntry );
}
else
{
if ( pParentGroup && ( pParentGroup->GetChildren() == pCurrentEntry ) )
{
pParentGroup->SetChildren( pNextEntry );
if ( pNextEntry )
pNextEntry->SetParent( pParentGroup );
}
}
delete pCurrentEntry;
deleteEntry = true;
}
if ( ( GetNumberOfGroups() == 0 ) && ( GetNumberOfEntries() == 0 ) && bGroupIfEmptyAlso )
{
wxString strPath = GetPath().BeforeLast(wxCONFIG_PATH_SEPARATOR);
wxString groupName = m_pCurrentGroup->GetName();
if ( !strPath.empty() )
{
SetPath( strPath );
DeleteGroup( groupName );
}
}
return deleteEntry;
}
bool wxXMLConfig::DeleteGroup( const wxString& key )
{
wxASSERT_MSG( m_pCurrentGroup != NULL, wxT("current group is null") );
wxASSERT_MSG( IsGroup(m_pCurrentGroup), wxT("current group is not a group") );
bool deleteGroup = false;
wxXMLConfigGroup *pLastGroup = NULL;
wxXMLConfigGroup *pCurrentGroup = m_pCurrentGroup->GetChildren();
while( pCurrentGroup )
{
if ( IsGroup( pCurrentGroup ) && ( pCurrentGroup->GetName() == key ) )
{
wxXMLConfigEntry *pNextGroup = pCurrentGroup->GetNext();
if ( pLastGroup )
{
pLastGroup->SetNext( pNextGroup );
}
else
{
wxXMLConfigGroup *pParentGroup = pCurrentGroup->GetParent();
if ( pParentGroup && ( pParentGroup->GetChildren() == pCurrentGroup ) )
{
pParentGroup->SetChildren( pNextGroup );
if ( pNextGroup )
pNextGroup->SetParent( pParentGroup );
}
}
delete pCurrentGroup;
deleteGroup = true;
break;
}
pLastGroup = pCurrentGroup;
pCurrentGroup = pCurrentGroup->GetNext();
}
return deleteGroup;
}
bool wxXMLConfig::DeleteAll()
{
CleanUp();
if ( !m_strLocalFile.empty() )
{
if ( wxFile::Exists(m_strLocalFile) && wxRemove(m_strLocalFile) == -1 )
{
wxLogSysError(_("can't delete user configuration file '%s'"),
m_strLocalFile.c_str());
return false;
}
}
Init();
return true;
}
#if wxUSE_STREAMS
bool wxXMLConfig::Save( wxOutputStream& os, const wxMBConv& conv )
{
wxASSERT_MSG( m_xmlDoc != NULL, _("xml document is null") );
if ( !m_xmlDoc->Save( os ) )
{
wxLogError( _("can't save user configuration file") );
return false;
}
ResetDirty();
return true;
}
#endif
bool wxXMLConfig::DoReadString( const wxString& key, wxString* pStr ) const
{
wxConfigPathChanger path(this, key);
wxXMLConfigEntry *pEntry = FindEntry(path.Name());
if (pEntry == NULL) {
return false;
}
*pStr = pEntry->GetNodeContent();
return true;
}
bool wxXMLConfig::DoReadLong( const wxString& key, long* pl ) const
{
wxString str;
if ( !Read(key, &str) )
return false;
// extra spaces shouldn't prevent us from reading numeric values
str.Trim();
return str.ToLong(pl);
}
bool wxXMLConfig::DoWriteString( const wxString& key, const wxString& szValue )
{
wxConfigPathChanger path(this, key);
wxString strName = path.Name();
wxLogTrace( XMLCONF_TRACE_MASK,
_T(" Writing String '%s' = '%s' to Group '%s'"),
strName.c_str(),
szValue.c_str(),
GetPath().c_str() );
if ( strName.empty() )
{
// setting the value of a group is an error
wxASSERT_MSG( szValue.empty(), wxT("can't set value of a group!") );
// ... except if it's empty in which case it's a way to force it's creation
wxLogTrace( XMLCONF_TRACE_MASK,
_T(" Creating group '%s'"),
m_pCurrentGroup->GetName().c_str() );
SetDirty();
}
else
{
// writing an entry check that the name is reasonable
if ( strName[0u] == wxCONFIG_IMMUTABLE_PREFIX )
{
wxLogError( _("Config entry name cannot start with '%c'."),
wxCONFIG_IMMUTABLE_PREFIX);
return false;
}
wxXMLConfigEntry *pEntry = FindEntry(strName);
if ( pEntry == NULL )
{
wxLogTrace( XMLCONF_TRACE_MASK,
_T(" Adding Entry '%s'"),
strName.c_str() );
pEntry = AddEntry(strName);
}
wxLogTrace( XMLCONF_TRACE_MASK,
_T(" Setting value '%s'"),
szValue.c_str() );
pEntry->GetChildren()->SetContent(szValue);
SetDirty();
}
return true;
}
bool wxXMLConfig::DoWriteLong( const wxString& key, long lValue )
{
return Write(key, wxString::Format(_T("%ld"), lValue));
}
wxString wxXMLConfig::GetGlobalDir()
{
return wxT(".\\");
}
wxString wxXMLConfig::GetLocalDir()
{
return wxT(".\\");
}
void wxXMLConfig::Init()
{
wxXmlDocument *globalXmlDoc = NULL;
wxXmlDocument *localXmlDoc = NULL;
m_xmlDoc = new wxXmlDocument();
// open global file
if ( !m_strGlobalFile.empty() && wxFile::Exists(m_strGlobalFile) )
{
wxXmlDocument globalXmlDoc( m_strGlobalFile );
if ( globalXmlDoc.IsOk() )
{
Parse( globalXmlDoc, false );
}
else
{
wxLogWarning( _("can't open global configuration file '%s'."), m_strGlobalFile.c_str() );
}
}
// parse the local file
if ( !m_strLocalFile.empty() && wxFile::Exists(m_strLocalFile) )
{
wxXmlDocument localXmlDoc( m_strLocalFile );
if ( localXmlDoc.IsOk() )
{
Parse( localXmlDoc, true );
}
else
{
wxLogWarning( _("can't open user configuration file '%s'."), m_strLocalFile.c_str() );
}
}
if ( !m_xmlDoc->IsOk() )
{
m_xmlDoc->SetRoot( new wxXmlNode( NULL, wxXML_ELEMENT_NODE, wxT("config") ) );
}
m_pCurrentGroup = m_xmlDoc->GetRoot();
m_isDirty = false;
}
void wxXMLConfig::CleanUp()
{
delete m_xmlDoc;
m_xmlDoc = NULL;
}
//TODO: combining of xml tree
void wxXMLConfig::Parse( const wxXmlDocument& xmlDocument, bool bLocal )
{
// for now we replace the document with the one provided in parameter
if ( m_xmlDoc )
delete m_xmlDoc;
m_xmlDoc = new wxXmlDocument( xmlDocument );
}
void wxXMLConfig::SetRootPath()
{
m_strPath.Empty();
m_pCurrentGroup = m_xmlDoc->GetRoot();
}
bool wxXMLConfig::DoSetPath( const wxString& strPath, bool createMissingComponents )
{
wxArrayString aParts;
if ( strPath.empty() ) {
SetRootPath();
return true;
}
if ( strPath[0] == wxCONFIG_PATH_SEPARATOR ) {
// absolute path
wxSplitPath(aParts, strPath);
}
else {
// relative path, combine with current one
wxString strFullPath = m_strPath;
strFullPath << wxCONFIG_PATH_SEPARATOR << strPath;
wxSplitPath(aParts, strFullPath);
}
// change current group
size_t n;
m_pCurrentGroup = m_xmlDoc->GetRoot();
for ( n = 0; n < aParts.Count(); n++ ) {
wxXMLConfigGroup *pNextGroup = FindGroup( aParts[n] );
if ( pNextGroup == NULL )
{
if ( !createMissingComponents )
return false;
pNextGroup = AddGroup( aParts[n] );
}
m_pCurrentGroup = pNextGroup;
}
// recombine path parts in one variable
m_strPath.Empty();
for ( n = 0; n < aParts.Count(); n++ ) {
m_strPath << wxCONFIG_PATH_SEPARATOR << aParts[n];
}
return true;
}
bool wxXMLConfig::IsGroup( const wxXMLConfigGroup *group ) const
{
return !IsEntry( group );
}
bool wxXMLConfig::IsEntry( const wxXMLConfigEntry *entry ) const
{
if ( entry )
{
wxXmlNode *children = entry->GetChildren();
if ( children && ( children->GetType() == wxXML_TEXT_NODE ) )
return true;
return false;
}
else
{
return false;
}
}
wxXMLConfigEntry *wxXMLConfig::FindEntry( const wxString& key ) const
{
wxASSERT_MSG( m_pCurrentGroup != NULL, wxT("current group is null") );
wxASSERT_MSG( IsGroup(m_pCurrentGroup), wxT("current group is not a group") );
wxXMLConfigEntry *entry = NULL;
wxXMLConfigEntry *pCurrent = m_pCurrentGroup->GetChildren();
while( pCurrent )
{
if ( IsEntry( pCurrent ) && ( pCurrent->GetName() == key ) )
{
entry = pCurrent;
break;
}
pCurrent = pCurrent->GetNext();
}
return entry;
}
wxXMLConfigEntry *wxXMLConfig::AddEntry( const wxString& key )
{
wxASSERT_MSG( m_pCurrentGroup != NULL, wxT("current group is null") );
wxASSERT_MSG( IsGroup(m_pCurrentGroup), wxT("current group is not a group") );
wxXMLConfigGroup *pParent = m_pCurrentGroup;
wxXMLConfigEntry *pNext = m_pCurrentGroup->GetChildren();
// create the new entry
wxXMLConfigEntry *newEntry = new wxXMLConfigEntry( pParent, wxXML_ELEMENT_NODE, key, wxEmptyString, NULL, pNext );
wxXmlNode *textNode = new wxXmlNode( newEntry, wxXML_TEXT_NODE, wxT("") );
newEntry->AddChild( textNode );
newEntry->SetName( key );
// adjust tree
pParent->SetChildren( newEntry );
if ( pNext )
pNext->SetParent( NULL );
return newEntry;
}
wxXMLConfigGroup *wxXMLConfig::FindGroup( const wxString& key ) const
{
wxASSERT_MSG( m_pCurrentGroup != NULL, wxT("current group is null") );
wxASSERT_MSG( IsGroup(m_pCurrentGroup), wxT("current group is not a group") );
wxXMLConfigGroup *group = NULL;
wxXMLConfigGroup *pCurrent = m_pCurrentGroup->GetChildren();
while( pCurrent )
{
if ( IsGroup( pCurrent ) && ( pCurrent->GetName() == key ) )
{
group = pCurrent;
break;
}
pCurrent = pCurrent->GetNext();
}
return group;
}
wxXMLConfigGroup *wxXMLConfig::AddGroup( const wxString& key )
{
wxASSERT_MSG( m_pCurrentGroup != NULL, wxT("current group is null") );
wxASSERT_MSG( IsGroup(m_pCurrentGroup), wxT("current group is not a group") );
wxXMLConfigGroup *pParent = m_pCurrentGroup;
wxXMLConfigGroup *pNext = m_pCurrentGroup->GetChildren();
// create the new entry
wxXMLConfigGroup *newGroup = new wxXMLConfigGroup( pParent, wxXML_ELEMENT_NODE, key, wxEmptyString, NULL, pNext );
newGroup->SetName( key );
// adjust tree
pParent->SetChildren( newGroup );
if ( pNext )
pNext->SetParent( NULL );
return newGroup;
}
Code: Select all
wxXMLConfig* config = new wxXMLConfig(wxEmptyString,wxEmptyString,wxT("settings.xml"),wxEmptyString,wxCONFIG_USE_LOCAL_FILE);
wxConfigBase::Set(config);
wxConfigBase *pConfig = wxConfigBase::Get();
pConfig->Write(wxT("/SHORTCUTS/OPTIONSCREEN/alt"), 115);
pConfig->Write(wxT("/SHORTCUTS/SEARCH/ctrl"), 111);
pConfig->Write(wxT("/USER/name"), wxT("Bart"));
pConfig->SetPath(wxT("/USER/name2"));
pConfig->Write(wxT("/USER/lastname"), wxT("Simpson"));
pConfig->Write(wxT("/USER/ADDRESS/street"), wxT("street"));
pConfig->Write(wxT("/USER/ADDRESS/zip"), wxT("55555"));
pConfig->Write(wxT("/USER/ADDRESS/city"), wxT("city"));
pConfig->Write(wxT("/USER/ADDRESS/country"), wxT("USA"));
pConfig->Write(wxT("/USER/married"), false);
pConfig->Write(wxT("/SOUND/manufactor"), wxT("Creative"));
pConfig->Flush();
wxConfigBase::Set(NULL);
delete config;