18 #define XMLCONF_TRACE_MASK _T("xmlconf") 20 wxIMPLEMENT_ABSTRACT_CLASS(
wxXmlConfig, wxConfigBase)
23 const wxString& vendorName,
24 const wxString& localFilename,
25 const wxString& globalFilename,
27 const wxMBConv& WXUNUSED(conv) )
28 : wxConfigBase(appName, vendorName, m_strLocalFile, m_strGlobalFile, style),
29 m_strLocalFile(localFilename),
30 m_strGlobalFile(globalFilename),
31 m_pCurrentGroup(NULL),
35 if ( m_strLocalFile.empty() && (style & wxCONFIG_USE_LOCAL_FILE) )
36 m_strLocalFile = GetLocalFileName(GetAppName());
38 if ( m_strGlobalFile.empty() && (style & wxCONFIG_USE_GLOBAL_FILE) )
39 m_strGlobalFile = GetGlobalFileName(GetAppName());
43 if ( !m_strLocalFile.empty() )
44 SetStyle(GetStyle() | wxCONFIG_USE_LOCAL_FILE);
46 if ( !m_strGlobalFile.empty() )
47 SetStyle(GetStyle() | wxCONFIG_USE_GLOBAL_FILE);
51 if ( !(style & wxCONFIG_USE_RELATIVE_PATH) )
53 if ( !m_strLocalFile.empty() && !wxIsAbsolutePath(m_strLocalFile) )
55 m_strLocalFile.Prepend( GetLocalDir() );
58 if ( !m_strGlobalFile.empty() && !wxIsAbsolutePath(m_strGlobalFile) )
60 m_strGlobalFile.Prepend( GetGlobalDir() );
69 : m_pCurrentGroup(NULL),
73 SetStyle(GetStyle() | wxCONFIG_USE_LOCAL_FILE);
75 m_xmlDoc =
new wxXmlDocument( inStream );
76 if ( !m_xmlDoc->IsOk() )
78 wxLogError( _(
"can't parse user configuration") );
82 m_pCurrentGroup = m_xmlDoc->GetRoot();
102 if ( wxStrchr(szFile, wxT(
'.')) == NULL )
104 str << wxT(
".config");
115 if ( wxStrchr(szFile, wxT(
'.')) == NULL )
118 str << ::wxGetUserId();
119 str << wxT(
".config");
140 bool getNextGroup =
false;
151 if ( groupPos == lIndex )
154 str = pEntry->GetName();
160 pEntry = pEntry->GetNext();
177 bool getFirstEntry =
false;
188 if ( entryPos == lIndex )
191 str = pEntry->GetName();
192 getFirstEntry =
true;
197 pEntry = pEntry->GetNext();
201 return getFirstEntry;
210 size_t entriesCount = 0;
211 while( pEntry != NULL )
226 pEntry = pEntry->GetNext();
238 size_t groupsCount = 0;
239 while( pGroup != NULL )
251 pGroup = pGroup->GetNext();
259 if ( strName.empty() )
262 const wxString pathOld =
GetPath();
266 const bool rc =
self->DoSetPath( strName,
false );
268 self->SetPath( pathOld );
275 wxString path = entry.BeforeLast(wxCONFIG_PATH_SEPARATOR);
277 if ( path.empty() && *entry.c_str() == wxCONFIG_PATH_SEPARATOR )
279 path = wxCONFIG_PATH_SEPARATOR;
288 if ( pathOld.empty() )
289 pathOld = wxCONFIG_PATH_SEPARATOR;
291 if ( !self->DoSetPath( path,
false ) )
296 bool exists = (
FindEntry( entry ) != NULL );
299 if ( !pathOld.empty() )
301 self->SetPath( pathOld );
314 wxLogError(_(
"can't save user configuration file."));
325 wxASSERT_MSG( !wxStrchr(oldName, wxCONFIG_PATH_SEPARATOR), wxT(
"RenameEntry(): paths are not supported") );
334 wxString value = oldEntry->GetNodeContent();
341 newEntry->GetChildren()->SetContent( value );
348 wxASSERT_MSG( !wxStrchr(oldName, wxCONFIG_PATH_SEPARATOR), wxT(
"RenameGroup(): paths are not supported") );
371 bool deleteEntry =
false;
375 while( pCurrentEntry )
377 if (
IsEntry( pCurrentEntry ) && ( pCurrentEntry->GetName() == key ) )
380 pLastEntry = pCurrentEntry;
381 pCurrentEntry = pCurrentEntry->GetNext();
391 pLastEntry->SetNext( pNextEntry );
395 if ( pParentGroup && ( pParentGroup->GetChildren() == pCurrentEntry ) )
397 pParentGroup->SetChildren( pNextEntry );
399 pNextEntry->SetParent( pParentGroup );
403 delete pCurrentEntry;
410 wxString strPath =
GetPath().BeforeLast(wxCONFIG_PATH_SEPARATOR);
413 if ( !strPath.empty() )
428 bool deleteGroup =
false;
432 while( pCurrentGroup )
434 if (
IsGroup( pCurrentGroup ) && ( pCurrentGroup->GetName() == key ) )
440 pLastGroup->SetNext( pNextGroup );
446 if ( pParentGroup && ( pParentGroup->GetChildren() == pCurrentGroup ) )
448 pParentGroup->SetChildren( pNextGroup );
450 pNextGroup->SetParent( pParentGroup );
454 delete pCurrentGroup;
460 pLastGroup = pCurrentGroup;
461 pCurrentGroup = pCurrentGroup->GetNext();
475 wxLogSysError(_(
"can't delete user configuration file '%s'"),
487 bool wxXmlConfig::Save( wxOutputStream& os,
const wxMBConv& WXUNUSED(conv) )
489 wxASSERT_MSG(
m_xmlDoc != NULL, _(
"xml document is null") );
493 wxLogError( _(
"can't save user configuration file") );
505 wxConfigPathChanger path(
this, key);
508 if (pEntry == NULL) {
512 *pStr = pEntry->GetNodeContent();
520 if ( !Read(key, &str) )
526 return str.ToLong(pl);
531 wxConfigPathChanger path(
this, key);
532 wxString strName = path.Name();
534 wxLogTrace( XMLCONF_TRACE_MASK,
535 _T(
" Writing String '%s' = '%s' to Group '%s'"),
540 if ( strName.empty() )
543 wxASSERT_MSG( szValue.empty(), wxT(
"can't set value of a group!") );
546 wxLogTrace( XMLCONF_TRACE_MASK,
547 _T(
" Creating group '%s'"),
555 if ( strName[0u] == wxCONFIG_IMMUTABLE_PREFIX )
557 wxLogError( _(
"Config entry name cannot start with '%c'."),
558 wxCONFIG_IMMUTABLE_PREFIX);
564 if ( pEntry == NULL )
566 wxLogTrace( XMLCONF_TRACE_MASK,
567 _T(
" Adding Entry '%s'"),
572 wxLogTrace( XMLCONF_TRACE_MASK,
573 _T(
" Setting value '%s'"),
575 pEntry->GetChildren()->SetContent(szValue);
585 return Write(key, wxString::Format(_T(
"%ld"), lValue));
588 #if wxCHECK_VERSION(2,9,0) && wxUSE_BASE64 589 bool wxXmlConfig::DoReadBinary(
const wxString& key, wxMemoryBuffer* buf )
const 591 wxCHECK_MSG( buf,
false, wxT(
"NULL buffer") );
594 if ( !Read(key, &str) )
597 *buf = wxBase64Decode(str);
601 bool wxXmlConfig::DoWriteBinary(
const wxString& key,
const wxMemoryBuffer& buf )
603 return Write(key, wxBase64Encode(buf));
628 if ( globalXmlDoc.IsOk() )
630 Parse( globalXmlDoc,
false );
634 wxLogWarning( _(
"can't open global configuration file '%s'."),
m_strGlobalFile.c_str() );
642 if ( localXmlDoc.IsOk() )
644 Parse( localXmlDoc,
true );
648 wxLogWarning( _(
"can't open user configuration file '%s'."),
m_strLocalFile.c_str() );
654 m_xmlDoc->SetRoot(
new wxXmlNode( NULL, wxXML_ELEMENT_NODE, wxT(
"config") ) );
675 m_xmlDoc =
new wxXmlDocument( xmlDocument );
686 wxArrayString aParts;
688 if ( strPath.empty() ) {
693 if ( strPath[0] == wxCONFIG_PATH_SEPARATOR ) {
695 wxSplitPath(aParts, strPath);
700 strFullPath << wxCONFIG_PATH_SEPARATOR << strPath;
701 wxSplitPath(aParts, strFullPath);
707 for ( n = 0; n < aParts.Count(); n++ ) {
709 if ( pNextGroup == NULL )
711 if ( !createMissingComponents )
722 for ( n = 0; n < aParts.Count(); n++ ) {
723 m_strPath << wxCONFIG_PATH_SEPARATOR << aParts[n];
738 wxXmlNode *children = entry->GetChildren();
740 if ( children && ( children->GetType() == wxXML_TEXT_NODE ) )
761 if (
IsEntry( pCurrent ) && ( pCurrent->GetName() == key ) )
767 pCurrent = pCurrent->GetNext();
783 wxXmlNode *textNode =
new wxXmlNode( newEntry, wxXML_TEXT_NODE, wxT(
"") );
784 newEntry->AddChild( textNode );
786 newEntry->SetName( key );
789 pParent->SetChildren( newEntry );
791 pNext->SetParent( NULL );
806 if (
IsGroup( pCurrent ) && ( pCurrent->GetName() == key ) )
812 pCurrent = pCurrent->GetNext();
828 newGroup->SetName( key );
831 pParent->SetChildren( newGroup );
833 pNext->SetParent( NULL );
838 #endif // wxUSE_MLBASE
virtual bool GetNextEntry(wxString &str, long &lIndex) const
static wxString GetGlobalFileName(const wxChar *szFile)
virtual bool RenameGroup(const wxString &oldName, const wxString &newName)
virtual bool HasGroup(const wxString &strName) const
bool IsEntry(const wxXmlConfigEntry *entry) const
virtual size_t GetNumberOfEntries(bool bRecursive=false) const
static wxString GetLocalFileName(const wxChar *szFile)
void Parse(const wxXmlDocument &xmlDocument, bool bLocal)
virtual bool GetNextGroup(wxString &str, long &lIndex) const
wxXmlConfigEntry * FindEntry(const wxString &key) const
wxXmlConfigEntry * AddEntry(const wxString &key)
bool DoSetPath(const wxString &strPath, bool createMissingComponents)
virtual bool RenameEntry(const wxString &oldName, const wxString &newName)
wxXmlConfigGroup * AddGroup(const wxString &key)
virtual size_t GetNumberOfGroups(bool bRecursive=false) const
virtual bool DeleteEntry(const wxString &key, bool bGroupIfEmptyAlso=true)
virtual bool GetFirstEntry(wxString &str, long &lIndex) const
virtual bool HasEntry(const wxString &strName) const
virtual bool DoReadLong(const wxString &key, long *pl) const
virtual bool GetFirstGroup(wxString &str, long &lIndex) const
virtual bool DoWriteString(const wxString &key, const wxString &szValue)
wxXmlConfigGroup * FindGroup(const wxString &key) const
virtual bool DoWriteLong(const wxString &key, long lValue)
virtual void SetPath(const wxString &strPath)
virtual bool DeleteGroup(const wxString &key)
virtual bool DoReadString(const wxString &key, wxString *pStr) const
static wxString GetGlobalDir()
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())
static wxString GetLocalDir()
virtual const wxString & GetPath() const
bool IsGroup(const wxXmlConfigGroup *group) const
virtual bool Flush(bool bCurrentOnly=false)
wxXmlConfigGroup * m_pCurrentGroup