Version: 1.0.0
xmlconf.cpp
Go to the documentation of this file.
1 #include "wx/base/wxprec.h"
2 
3 #if wxUSE_XML_CONFIG
4 
5 //*****************************************************************************
6 // @file wxXmlConfig.cpp
7 // @author Nicolas Dextraze
8 // @web http://www.nicdex.com
9 // @date February 17, 2007
10 // @desc wxXmlConfig class implementation
11 //*****************************************************************************
12 
13 #include "wx/base/xmlconf.h"
14 #include <wx/log.h>
15 #include <wx/intl.h>
16 #include <wx/utils.h>
17 
18 #define XMLCONF_TRACE_MASK _T("xmlconf")
19 
20 wxIMPLEMENT_ABSTRACT_CLASS(wxXmlConfig, wxConfigBase)
21 
22 wxXmlConfig::wxXmlConfig( const wxString& appName,
23  const wxString& vendorName,
24  const wxString& localFilename,
25  const wxString& globalFilename,
26  long style,
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),
32  m_xmlDoc(NULL)
33 {
34  // Make up names for files if empty
35  if ( m_strLocalFile.empty() && (style & wxCONFIG_USE_LOCAL_FILE) )
36  m_strLocalFile = GetLocalFileName(GetAppName());
37 
38  if ( m_strGlobalFile.empty() && (style & wxCONFIG_USE_GLOBAL_FILE) )
39  m_strGlobalFile = GetGlobalFileName(GetAppName());
40 
41  // Check if styles are not supplied, but filenames are, in which case
42  // add the correct styles.
43  if ( !m_strLocalFile.empty() )
44  SetStyle(GetStyle() | wxCONFIG_USE_LOCAL_FILE);
45 
46  if ( !m_strGlobalFile.empty() )
47  SetStyle(GetStyle() | wxCONFIG_USE_GLOBAL_FILE);
48 
49  // if the path is not absolute, prepend the standard directory to it
50  // UNLESS wxCONFIG_USE_RELATIVE_PATH style is set
51  if ( !(style & wxCONFIG_USE_RELATIVE_PATH) )
52  {
53  if ( !m_strLocalFile.empty() && !wxIsAbsolutePath(m_strLocalFile) )
54  {
55  m_strLocalFile.Prepend( GetLocalDir() );
56  }
57 
58  if ( !m_strGlobalFile.empty() && !wxIsAbsolutePath(m_strGlobalFile) )
59  {
60  m_strGlobalFile.Prepend( GetGlobalDir() );
61  }
62  }
63 
64  Init();
65 }
66 
67 #ifdef wxUSE_STREAMS
68 wxXmlConfig::wxXmlConfig( wxInputStream& inStream, const wxMBConv& WXUNUSED(conv) )
69 : m_pCurrentGroup(NULL),
70 m_xmlDoc(NULL)
71 {
72  // always local_file when this constructor is called (?)
73  SetStyle(GetStyle() | wxCONFIG_USE_LOCAL_FILE);
74 
75  m_xmlDoc = new wxXmlDocument( inStream );
76  if ( !m_xmlDoc->IsOk() )
77  {
78  wxLogError( _("can't parse user configuration") );
79  }
80  else
81  {
82  m_pCurrentGroup = m_xmlDoc->GetRoot();
83 
84  SetRootPath();
85  ResetDirty();
86  }
87 }
88 #endif
89 
91 {
92  Flush();
93 
94  CleanUp();
95 }
96 
97 wxString wxXmlConfig::GetGlobalFileName( const wxChar *szFile )
98 {
99  wxString str = GetGlobalDir();
100  str << szFile;
101 
102  if ( wxStrchr(szFile, wxT('.')) == NULL )
103  {
104  str << wxT(".config");
105  }
106 
107  return str;
108 }
109 
110 wxString wxXmlConfig::GetLocalFileName( const wxChar *szFile )
111 {
112  wxString str = GetLocalDir();
113  str << szFile;
114 
115  if ( wxStrchr(szFile, wxT('.')) == NULL )
116  {
117  str << wxT('.');
118  str << ::wxGetUserId();
119  str << wxT(".config");
120  }
121 
122  return str;
123 }
124 
125 void wxXmlConfig::SetPath( const wxString& strPath )
126 {
127  DoSetPath( strPath, true );
128 }
129 
130 bool wxXmlConfig::GetFirstGroup( wxString& str, long& lIndex ) const
131 {
132  lIndex = 0;
133  return GetNextGroup( str, lIndex );
134 }
135 
136 bool wxXmlConfig::GetNextGroup( wxString& str, long& lIndex ) const
137 {
138  wxASSERT_MSG( m_pCurrentGroup != NULL, _("current group is null") );
139  wxASSERT_MSG( IsGroup(m_pCurrentGroup), _("current group is not a group") );
140  bool getNextGroup = false;
141 
142  if ( size_t(lIndex) < GetNumberOfGroups() )
143  {
144  wxXmlConfigEntry *pEntry = m_pCurrentGroup->GetChildren();
145 
146  long groupPos = 0;
147  while( pEntry )
148  {
149  if ( IsGroup( pEntry ) )
150  {
151  if ( groupPos == lIndex )
152  {
153  lIndex++;
154  str = pEntry->GetName();
155  getNextGroup = true;
156  break;
157  }
158  groupPos++;
159  }
160  pEntry = pEntry->GetNext();
161  }
162  }
163 
164  return getNextGroup;
165 }
166 
167 bool wxXmlConfig::GetFirstEntry( wxString& str, long& lIndex ) const
168 {
169  lIndex = 0;
170  return GetNextEntry( str, lIndex );
171 }
172 
173 bool wxXmlConfig::GetNextEntry( wxString& str, long& lIndex ) const
174 {
175  wxASSERT_MSG( m_pCurrentGroup != NULL, _("current group is null") );
176  wxASSERT_MSG( IsGroup(m_pCurrentGroup), _("current group is not a group") );
177  bool getFirstEntry = false;
178 
179  if ( size_t(lIndex) < GetNumberOfEntries() )
180  {
181  wxXmlConfigEntry *pEntry = m_pCurrentGroup->GetChildren();
182 
183  long entryPos = 0;
184  while( pEntry )
185  {
186  if ( IsEntry( pEntry ) )
187  {
188  if ( entryPos == lIndex )
189  {
190  lIndex++;
191  str = pEntry->GetName();
192  getFirstEntry = true;
193  break;
194  }
195  entryPos++;
196  }
197  pEntry = pEntry->GetNext();
198  }
199  }
200 
201  return getFirstEntry;
202 }
203 
204 size_t wxXmlConfig::GetNumberOfEntries( bool bRecursive ) const
205 {
206  wxASSERT_MSG( m_pCurrentGroup != NULL, _("current group is null") );
207  wxASSERT_MSG( IsGroup(m_pCurrentGroup), _("current group is not a group") );
208 
209  wxXmlConfigEntry *pEntry = m_pCurrentGroup->GetChildren();
210  size_t entriesCount = 0;
211  while( pEntry != NULL )
212  {
213  if ( IsGroup(pEntry) )
214  {
215  if ( bRecursive )
216  {
217  //wxConfigPathChanger path( this, GetPath() + wxT(wxCONFIG_PATH_SEPARATOR) + pEntry->GetName() + wxT(wxCONFIG_PATH_SEPARATOR) );
218  entriesCount += GetNumberOfEntries( bRecursive );
219  }
220  }
221  else if ( IsEntry(pEntry) )
222  {
223  entriesCount++;
224  }
225 
226  pEntry = pEntry->GetNext();
227  }
228 
229  return entriesCount;
230 }
231 
232 size_t wxXmlConfig::GetNumberOfGroups( bool bRecursive ) const
233 {
234  wxASSERT_MSG( m_pCurrentGroup != NULL, _("current group is null") );
235  wxASSERT_MSG( IsGroup(m_pCurrentGroup), _("current group is not a group") );
236 
237  wxXmlConfigGroup *pGroup = m_pCurrentGroup->GetChildren();
238  size_t groupsCount = 0;
239  while( pGroup != NULL )
240  {
241  if ( IsGroup(pGroup) ) // group
242  {
243  groupsCount++;
244  if ( bRecursive )
245  {
246  //wxConfigPathChanger path( this, GetPath() + wxT(wxCONFIG_PATH_SEPARATOR) + pGroup->GetName() + wxT(wxCONFIG_PATH_SEPARATOR) );
247  groupsCount += GetNumberOfGroups( bRecursive );
248  }
249  }
250 
251  pGroup = pGroup->GetNext();
252  }
253 
254  return groupsCount;
255 }
256 
257 bool wxXmlConfig::HasGroup( const wxString& strName ) const
258 {
259  if ( strName.empty() )
260  return false;
261 
262  const wxString pathOld = GetPath();
263 
264  wxXmlConfig *self = wx_const_cast( wxXmlConfig *, this );
265 
266  const bool rc = self->DoSetPath( strName,false );
267 
268  self->SetPath( pathOld );
269 
270  return rc;
271 }
272 
273 bool wxXmlConfig::HasEntry( const wxString& entry ) const
274 {
275  wxString path = entry.BeforeLast(wxCONFIG_PATH_SEPARATOR);
276 
277  if ( path.empty() && *entry.c_str() == wxCONFIG_PATH_SEPARATOR )
278  {
279  path = wxCONFIG_PATH_SEPARATOR;
280  }
281 
282  // set the path and keep a copy of the the current path to set it back after
283  wxString pathOld;
284  wxXmlConfig* const self = wx_const_cast( wxXmlConfig *, this );
285  if ( !path.empty() )
286  {
287  pathOld = GetPath();
288  if ( pathOld.empty() )
289  pathOld = wxCONFIG_PATH_SEPARATOR;
290 
291  if ( !self->DoSetPath( path, false ) )
292  return false;
293  }
294 
295  // we look for the entry
296  bool exists = ( FindEntry( entry ) != NULL );
297 
298  // we set back the old path
299  if ( !pathOld.empty() )
300  {
301  self->SetPath( pathOld );
302  }
303 
304  return exists;
305 }
306 
307 bool wxXmlConfig::Flush( bool WXUNUSED(bCurrentOnly) )
308 {
309  if ( !IsDirty() || !m_strLocalFile )
310  return true;
311 
312  if ( !m_xmlDoc->Save( m_strLocalFile ) )
313  {
314  wxLogError(_("can't save user configuration file."));
315  return false;
316  }
317 
318  ResetDirty();
319 
320  return true;
321 }
322 
323 bool wxXmlConfig::RenameEntry( const wxString& oldName, const wxString& newName )
324 {
325  wxASSERT_MSG( !wxStrchr(oldName, wxCONFIG_PATH_SEPARATOR), wxT("RenameEntry(): paths are not supported") );
326 
327  wxXmlConfigEntry *oldEntry = FindEntry( oldName );
328  if ( !oldEntry )
329  return false;
330 
331  if ( FindEntry( newName ) )
332  return false;
333 
334  wxString value = oldEntry->GetNodeContent();
335  if ( DeleteEntry( oldName ) )
336  return false;
337 
338  SetDirty();
339 
340  wxXmlConfigEntry *newEntry = AddEntry( newName );
341  newEntry->GetChildren()->SetContent( value );
342 
343  return true;
344 }
345 
346 bool wxXmlConfig::RenameGroup( const wxString& oldName, const wxString& newName )
347 {
348  wxASSERT_MSG( !wxStrchr(oldName, wxCONFIG_PATH_SEPARATOR), wxT("RenameGroup(): paths are not supported") );
349 
350  if ( !FindGroup( oldName ) )
351  return false;
352 
353  if ( FindGroup( newName ) )
354  return false;
355 
356  if ( DeleteGroup( oldName ) )
357  return false;
358 
359  SetDirty();
360 
361  AddGroup( newName );
362 
363  return true;
364 }
365 
366 bool wxXmlConfig::DeleteEntry( const wxString& key, bool bGroupIfEmptyAlso )
367 {
368  wxASSERT_MSG( m_pCurrentGroup != NULL, wxT("current group is null") );
369  wxASSERT_MSG( IsGroup(m_pCurrentGroup), wxT("current group is not a group") );
370 
371  bool deleteEntry = false;
372 
373  wxXmlConfigEntry *pLastEntry = NULL;
374  wxXmlConfigEntry *pCurrentEntry = m_pCurrentGroup->GetChildren();
375  while( pCurrentEntry )
376  {
377  if ( IsEntry( pCurrentEntry ) && ( pCurrentEntry->GetName() == key ) )
378  break;
379 
380  pLastEntry = pCurrentEntry;
381  pCurrentEntry = pCurrentEntry->GetNext();
382  }
383 
384  if ( pCurrentEntry )
385  {
386  wxXmlConfigEntry *pNextEntry = pCurrentEntry->GetNext();
387  wxXmlConfigGroup *pParentGroup = pCurrentEntry->GetParent();
388 
389  if ( pLastEntry )
390  {
391  pLastEntry->SetNext( pNextEntry );
392  }
393  else
394  {
395  if ( pParentGroup && ( pParentGroup->GetChildren() == pCurrentEntry ) )
396  {
397  pParentGroup->SetChildren( pNextEntry );
398  if ( pNextEntry )
399  pNextEntry->SetParent( pParentGroup );
400  }
401  }
402 
403  delete pCurrentEntry;
404 
405  deleteEntry = true;
406  }
407 
408  if ( ( GetNumberOfGroups() == 0 ) && ( GetNumberOfEntries() == 0 ) && bGroupIfEmptyAlso )
409  {
410  wxString strPath = GetPath().BeforeLast(wxCONFIG_PATH_SEPARATOR);
411  wxString groupName = m_pCurrentGroup->GetName();
412 
413  if ( !strPath.empty() )
414  {
415  SetPath( strPath );
416  DeleteGroup( groupName );
417  }
418  }
419 
420  return deleteEntry;
421 }
422 
423 bool wxXmlConfig::DeleteGroup( const wxString& key )
424 {
425  wxASSERT_MSG( m_pCurrentGroup != NULL, wxT("current group is null") );
426  wxASSERT_MSG( IsGroup(m_pCurrentGroup), wxT("current group is not a group") );
427 
428  bool deleteGroup = false;
429 
430  wxXmlConfigGroup *pLastGroup = NULL;
431  wxXmlConfigGroup *pCurrentGroup = m_pCurrentGroup->GetChildren();
432  while( pCurrentGroup )
433  {
434  if ( IsGroup( pCurrentGroup ) && ( pCurrentGroup->GetName() == key ) )
435  {
436  wxXmlConfigEntry *pNextGroup = pCurrentGroup->GetNext();
437 
438  if ( pLastGroup )
439  {
440  pLastGroup->SetNext( pNextGroup );
441  }
442  else
443  {
444  wxXmlConfigGroup *pParentGroup = pCurrentGroup->GetParent();
445 
446  if ( pParentGroup && ( pParentGroup->GetChildren() == pCurrentGroup ) )
447  {
448  pParentGroup->SetChildren( pNextGroup );
449  if ( pNextGroup )
450  pNextGroup->SetParent( pParentGroup );
451  }
452  }
453 
454  delete pCurrentGroup;
455 
456  deleteGroup = true;
457  break;
458  }
459 
460  pLastGroup = pCurrentGroup;
461  pCurrentGroup = pCurrentGroup->GetNext();
462  }
463 
464  return deleteGroup;
465 }
466 
468 {
469  CleanUp();
470 
471  if ( !m_strLocalFile.empty() )
472  {
473  if ( wxFile::Exists(m_strLocalFile) && wxRemove(m_strLocalFile) == -1 )
474  {
475  wxLogSysError(_("can't delete user configuration file '%s'"),
476  m_strLocalFile.c_str());
477  return false;
478  }
479  }
480 
481  Init();
482 
483  return true;
484 }
485 
486 #if wxUSE_STREAMS
487 bool wxXmlConfig::Save( wxOutputStream& os, const wxMBConv& WXUNUSED(conv) )
488 {
489  wxASSERT_MSG( m_xmlDoc != NULL, _("xml document is null") );
490 
491  if ( !m_xmlDoc->Save( os ) )
492  {
493  wxLogError( _("can't save user configuration file") );
494  return false;
495  }
496 
497  ResetDirty();
498 
499  return true;
500 }
501 #endif
502 
503 bool wxXmlConfig::DoReadString( const wxString& key, wxString* pStr ) const
504 {
505  wxConfigPathChanger path(this, key);
506 
507  wxXmlConfigEntry *pEntry = FindEntry(path.Name());
508  if (pEntry == NULL) {
509  return false;
510  }
511 
512  *pStr = pEntry->GetNodeContent();
513 
514  return true;
515 }
516 
517 bool wxXmlConfig::DoReadLong( const wxString& key, long* pl ) const
518 {
519  wxString str;
520  if ( !Read(key, &str) )
521  return false;
522 
523  // extra spaces shouldn't prevent us from reading numeric values
524  str.Trim();
525 
526  return str.ToLong(pl);
527 }
528 
529 bool wxXmlConfig::DoWriteString( const wxString& key, const wxString& szValue )
530 {
531  wxConfigPathChanger path(this, key);
532  wxString strName = path.Name();
533 
534  wxLogTrace( XMLCONF_TRACE_MASK,
535  _T(" Writing String '%s' = '%s' to Group '%s'"),
536  strName.c_str(),
537  szValue.c_str(),
538  GetPath().c_str() );
539 
540  if ( strName.empty() )
541  {
542  // setting the value of a group is an error
543  wxASSERT_MSG( szValue.empty(), wxT("can't set value of a group!") );
544 
545  // ... except if it's empty in which case it's a way to force it's creation
546  wxLogTrace( XMLCONF_TRACE_MASK,
547  _T(" Creating group '%s'"),
548  m_pCurrentGroup->GetName().c_str() );
549 
550  SetDirty();
551  }
552  else
553  {
554  // writing an entry check that the name is reasonable
555  if ( strName[0u] == wxCONFIG_IMMUTABLE_PREFIX )
556  {
557  wxLogError( _("Config entry name cannot start with '%c'."),
558  wxCONFIG_IMMUTABLE_PREFIX);
559  return false;
560  }
561 
562  wxXmlConfigEntry *pEntry = FindEntry(strName);
563 
564  if ( pEntry == NULL )
565  {
566  wxLogTrace( XMLCONF_TRACE_MASK,
567  _T(" Adding Entry '%s'"),
568  strName.c_str() );
569  pEntry = AddEntry(strName);
570  }
571 
572  wxLogTrace( XMLCONF_TRACE_MASK,
573  _T(" Setting value '%s'"),
574  szValue.c_str() );
575  pEntry->GetChildren()->SetContent(szValue);
576 
577  SetDirty();
578  }
579 
580  return true;
581 }
582 
583 bool wxXmlConfig::DoWriteLong( const wxString& key, long lValue )
584 {
585  return Write(key, wxString::Format(_T("%ld"), lValue));
586 }
587 
588 #if wxCHECK_VERSION(2,9,0) && wxUSE_BASE64
589 bool wxXmlConfig::DoReadBinary( const wxString& key, wxMemoryBuffer* buf ) const
590 {
591  wxCHECK_MSG( buf, false, wxT("NULL buffer") );
592 
593  wxString str;
594  if ( !Read(key, &str) )
595  return false;
596 
597  *buf = wxBase64Decode(str);
598  return true;
599 }
600 
601 bool wxXmlConfig::DoWriteBinary( const wxString& key, const wxMemoryBuffer& buf )
602 {
603  return Write(key, wxBase64Encode(buf));
604 }
605 #endif
606 
607 wxString wxXmlConfig::GetGlobalDir()
608 {
609  return wxT(".\\");
610 }
611 
612 wxString wxXmlConfig::GetLocalDir()
613 {
614  return wxT(".\\");
615 }
616 
617 void wxXmlConfig::Init()
618 {
619  //wxXmlDocument *globalXmlDoc = NULL;
620  //wxXmlDocument *localXmlDoc = NULL;
621 
622  m_xmlDoc = new wxXmlDocument();
623 
624  // open global file
625  if ( !m_strGlobalFile.empty() && wxFile::Exists(m_strGlobalFile) )
626  {
627  wxXmlDocument globalXmlDoc( m_strGlobalFile );
628  if ( globalXmlDoc.IsOk() )
629  {
630  Parse( globalXmlDoc, false );
631  }
632  else
633  {
634  wxLogWarning( _("can't open global configuration file '%s'."), m_strGlobalFile.c_str() );
635  }
636  }
637 
638  // parse the local file
639  if ( !m_strLocalFile.empty() && wxFile::Exists(m_strLocalFile) )
640  {
641  wxXmlDocument localXmlDoc( m_strLocalFile );
642  if ( localXmlDoc.IsOk() )
643  {
644  Parse( localXmlDoc, true );
645  }
646  else
647  {
648  wxLogWarning( _("can't open user configuration file '%s'."), m_strLocalFile.c_str() );
649  }
650  }
651 
652  if ( !m_xmlDoc->IsOk() )
653  {
654  m_xmlDoc->SetRoot( new wxXmlNode( NULL, wxXML_ELEMENT_NODE, wxT("config") ) );
655  }
656 
657  m_pCurrentGroup = m_xmlDoc->GetRoot();
658 
659  m_isDirty = false;
660 }
661 
662 void wxXmlConfig::CleanUp()
663 {
664  delete m_xmlDoc;
665  m_xmlDoc = NULL;
666 }
667 
668 //TODO: combining of xml tree
669 void wxXmlConfig::Parse( const wxXmlDocument& xmlDocument, bool WXUNUSED(bLocal) )
670 {
671  // for now we replace the document with the one provided in parameter
672  if ( m_xmlDoc )
673  delete m_xmlDoc;
674 
675  m_xmlDoc = new wxXmlDocument( xmlDocument );
676 }
677 
679 {
680  m_strPath.Empty();
681  m_pCurrentGroup = m_xmlDoc->GetRoot();
682 }
683 
684 bool wxXmlConfig::DoSetPath( const wxString& strPath, bool createMissingComponents )
685 {
686  wxArrayString aParts;
687 
688  if ( strPath.empty() ) {
689  SetRootPath();
690  return true;
691  }
692 
693  if ( strPath[0] == wxCONFIG_PATH_SEPARATOR ) {
694  // absolute path
695  wxSplitPath(aParts, strPath);
696  }
697  else {
698  // relative path, combine with current one
699  wxString strFullPath = m_strPath;
700  strFullPath << wxCONFIG_PATH_SEPARATOR << strPath;
701  wxSplitPath(aParts, strFullPath);
702  }
703 
704  // change current group
705  size_t n;
706  m_pCurrentGroup = m_xmlDoc->GetRoot();
707  for ( n = 0; n < aParts.Count(); n++ ) {
708  wxXmlConfigGroup *pNextGroup = FindGroup( aParts[n] );
709  if ( pNextGroup == NULL )
710  {
711  if ( !createMissingComponents )
712  return false;
713 
714  pNextGroup = AddGroup( aParts[n] );
715  }
716 
717  m_pCurrentGroup = pNextGroup;
718  }
719 
720  // recombine path parts in one variable
721  m_strPath.Empty();
722  for ( n = 0; n < aParts.Count(); n++ ) {
723  m_strPath << wxCONFIG_PATH_SEPARATOR << aParts[n];
724  }
725 
726  return true;
727 }
728 
729 bool wxXmlConfig::IsGroup( const wxXmlConfigGroup *group ) const
730 {
731  return !IsEntry( group );
732 }
733 
734 bool wxXmlConfig::IsEntry( const wxXmlConfigEntry *entry ) const
735 {
736  if ( entry )
737  {
738  wxXmlNode *children = entry->GetChildren();
739 
740  if ( children && ( children->GetType() == wxXML_TEXT_NODE ) )
741  return true;
742 
743  return false;
744  }
745  else
746  {
747  return false;
748  }
749 }
750 
751 wxXmlConfigEntry *wxXmlConfig::FindEntry( const wxString& key ) const
752 {
753  wxASSERT_MSG( m_pCurrentGroup != NULL, wxT("current group is null") );
754  wxASSERT_MSG( IsGroup(m_pCurrentGroup), wxT("current group is not a group") );
755 
756  wxXmlConfigEntry *entry = NULL;
757 
758  wxXmlConfigEntry *pCurrent = m_pCurrentGroup->GetChildren();
759  while( pCurrent )
760  {
761  if ( IsEntry( pCurrent ) && ( pCurrent->GetName() == key ) )
762  {
763  entry = pCurrent;
764  break;
765  }
766 
767  pCurrent = pCurrent->GetNext();
768  }
769 
770  return entry;
771 }
772 
773 wxXmlConfigEntry *wxXmlConfig::AddEntry( const wxString& key )
774 {
775  wxASSERT_MSG( m_pCurrentGroup != NULL, wxT("current group is null") );
776  wxASSERT_MSG( IsGroup(m_pCurrentGroup), wxT("current group is not a group") );
777 
778  wxXmlConfigGroup *pParent = m_pCurrentGroup;
779  wxXmlConfigEntry *pNext = m_pCurrentGroup->GetChildren();
780 
781  // create the new entry
782  wxXmlConfigEntry *newEntry = new wxXmlConfigEntry( pParent, wxXML_ELEMENT_NODE, key, wxEmptyString, NULL, pNext );
783  wxXmlNode *textNode = new wxXmlNode( newEntry, wxXML_TEXT_NODE, wxT("") );
784  newEntry->AddChild( textNode );
785 
786  newEntry->SetName( key );
787 
788  // adjust tree
789  pParent->SetChildren( newEntry );
790  if ( pNext )
791  pNext->SetParent( NULL );
792 
793  return newEntry;
794 }
795 
796 wxXmlConfigGroup *wxXmlConfig::FindGroup( const wxString& key ) const
797 {
798  wxASSERT_MSG( m_pCurrentGroup != NULL, wxT("current group is null") );
799  wxASSERT_MSG( IsGroup(m_pCurrentGroup), wxT("current group is not a group") );
800 
801  wxXmlConfigGroup *group = NULL;
802 
803  wxXmlConfigGroup *pCurrent = m_pCurrentGroup->GetChildren();
804  while( pCurrent )
805  {
806  if ( IsGroup( pCurrent ) && ( pCurrent->GetName() == key ) )
807  {
808  group = pCurrent;
809  break;
810  }
811 
812  pCurrent = pCurrent->GetNext();
813  }
814 
815  return group;
816 }
817 
818 wxXmlConfigGroup *wxXmlConfig::AddGroup( const wxString& key )
819 {
820  wxASSERT_MSG( m_pCurrentGroup != NULL, wxT("current group is null") );
821  wxASSERT_MSG( IsGroup(m_pCurrentGroup), wxT("current group is not a group") );
822 
823  wxXmlConfigGroup *pParent = m_pCurrentGroup;
824  wxXmlConfigGroup *pNext = m_pCurrentGroup->GetChildren();
825 
826  // create the new entry
827  wxXmlConfigGroup *newGroup = new wxXmlConfigGroup( pParent, wxXML_ELEMENT_NODE, key, wxEmptyString, NULL, pNext );
828  newGroup->SetName( key );
829 
830  // adjust tree
831  pParent->SetChildren( newGroup );
832  if ( pNext )
833  pNext->SetParent( NULL );
834 
835  return newGroup;
836 }
837 
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)
bool m_isDirty
Definition: xmlconf.h:120
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)
virtual ~wxXmlConfig()
#define wxXmlConfigEntry
Definition: xmlconf.h:31
wxXmlDocument * m_xmlDoc
Definition: xmlconf.h:115
void Parse(const wxXmlDocument &xmlDocument, bool bLocal)
virtual bool GetNextGroup(wxString &str, long &lIndex) const
wxXmlConfigEntry * FindEntry(const wxString &key) const
wxString m_strGlobalFile
Definition: xmlconf.h:118
wxXmlConfigEntry * AddEntry(const wxString &key)
bool DoSetPath(const wxString &strPath, bool createMissingComponents)
virtual bool DeleteAll()
void ResetDirty()
Definition: xmlconf.h:104
virtual bool RenameEntry(const wxString &oldName, const wxString &newName)
wxXmlConfigGroup * AddGroup(const wxString &key)
void CleanUp()
virtual size_t GetNumberOfGroups(bool bRecursive=false) const
bool IsDirty()
Definition: xmlconf.h:105
virtual bool DeleteEntry(const wxString &key, bool bGroupIfEmptyAlso=true)
virtual bool GetFirstEntry(wxString &str, long &lIndex) const
virtual bool HasEntry(const wxString &strName) const
void SetRootPath()
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)
wxString m_strLocalFile
Definition: xmlconf.h:117
virtual bool DeleteGroup(const wxString &key)
virtual bool DoReadString(const wxString &key, wxString *pStr) const
static wxString GetGlobalDir()
void SetDirty()
Definition: xmlconf.h:103
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()
wxString m_strPath
Definition: xmlconf.h:119
#define wxXmlConfigGroup
Definition: xmlconf.h:32
virtual const wxString & GetPath() const
Definition: xmlconf.h:53
bool IsGroup(const wxXmlConfigGroup *group) const
virtual bool Flush(bool bCurrentOnly=false)
wxXmlConfigGroup * m_pCurrentGroup
Definition: xmlconf.h:116