X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d7463f75f9c170c29b4965d27dccf535ac32cfde..677ded95390173ee6a17fcb476608ca9c2b16fe5:/utils/configtool/src/configtooldoc.cpp?ds=inline diff --git a/utils/configtool/src/configtooldoc.cpp b/utils/configtool/src/configtooldoc.cpp index d5ae2a8b24..122bd5926a 100644 --- a/utils/configtool/src/configtooldoc.cpp +++ b/utils/configtool/src/configtooldoc.cpp @@ -9,27 +9,28 @@ // Licence: ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "configtooldoc.h" #endif -#include "wx/wx.h" +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif -#include "wx/config.h" -#include "wx/textfile.h" +#ifndef WX_PRECOMP + #include "wx/process.h" #include "wx/mimetype.h" #include "wx/process.h" -#include "wx/wfstream.h" -#ifdef __BORLANDC__ -#pragma hdrstop #endif +#include "wx/textfile.h" +#include "wx/wfstream.h" +#include "wx/config.h" #include "configtooldoc.h" #include "configtoolview.h" #include "configtree.h" @@ -90,26 +91,24 @@ bool ctConfigToolDoc::OnCloseDocument() UpdateAllViews (NULL, & hint); DeleteItems(); - return TRUE; + return true; } else { - return FALSE; + return false; } } // Saves the doc bool ctConfigToolDoc::Save() { - bool ret = FALSE; + if (!IsModified() && m_savedYet) return true; - if (!IsModified() && m_savedYet) return TRUE; - if (m_documentFile == wxT("") || !m_savedYet) - ret = SaveAs(); - else - ret = OnSaveDocument(m_documentFile); + bool ret = (m_documentFile == wxT("") || !m_savedYet) ? + SaveAs() : + OnSaveDocument(m_documentFile); if ( ret ) - SetDocumentSaved(TRUE); + SetDocumentSaved(true); return ret; } @@ -138,8 +137,8 @@ bool ctConfigToolDoc::OnCreate(const wxString& path, long flags) SetTopItem(rootItem); - Modify(FALSE); - SetDocumentSaved(FALSE); + Modify(false); + SetDocumentSaved(false); wxString rootName(wxT("untitled")); wxStripExtension(rootName); @@ -158,7 +157,7 @@ bool ctConfigToolDoc::OnCreate(const wxString& path, long flags) ctConfigToolHint hint(NULL, ctInitialUpdate); UpdateAllViews (NULL, & hint); - SetFilename(GetFilename(), TRUE); + SetFilename(GetFilename(), true); } } return success; @@ -183,7 +182,7 @@ bool ctConfigToolDoc::OnSaveDocument(const wxString& filename) if (wxFileExists(tempFilename)) wxRemoveFile(tempFilename); - bool leaveBackup = TRUE; + bool leaveBackup = true; bool saved = DoSave(tempFilename); @@ -221,9 +220,9 @@ bool ctConfigToolDoc::OnSaveDocument(const wxString& filename) wxRemoveFile(tempFilename); } - Modify(FALSE); + Modify(false); ((ctConfigToolView*)GetFirstView())->OnChangeFilename(); - SetDocumentSaved(TRUE); + SetDocumentSaved(true); SetFilename(filename); wxGetApp().GetSettings().m_lastFilename = filename; } else @@ -255,7 +254,7 @@ bool ctConfigToolDoc::OnOpenDocument(const wxString& filename) UpdateAllViews (NULL, & hint); } - SetDocumentSaved(TRUE); // Necessary or it will pop up the Save As dialog + SetDocumentSaved(true); // Necessary or it will pop up the Save As dialog return opened; } @@ -265,16 +264,16 @@ bool ctConfigToolDoc::DoSave(const wxString& filename) { wxFileOutputStream stream(filename); if (!stream.Ok()) - return FALSE; + return false; stream << wxT("\n"); - stream << wxT(""); + stream << wxT(""); DoSave(m_topItem, stream, 1); stream << wxT("\n\n"); - return TRUE; + return true; } inline static void OutputIndentation(wxOutputStream& stream, int indent) @@ -326,7 +325,7 @@ bool ctConfigToolDoc::DoSave(ctConfigItem* item, wxOutputStream& stream, int ind stream << wxT("0"); // Output properties - wxNode* node = item->GetProperties().GetList().GetFirst(); + wxObjectList::compatibility_iterator node = item->GetProperties().GetList().GetFirst(); while (node) { ctProperty* prop = (ctProperty*) node->GetData(); @@ -352,7 +351,7 @@ bool ctConfigToolDoc::DoSave(ctConfigItem* item, wxOutputStream& stream, int ind stream << ctEscapeHTMLCharacters(prop->GetVariant().GetString()) ; stream << wxT("GetName() << wxT(">"); - node = node->Next(); + node = node->GetNext(); } // Output children @@ -362,7 +361,7 @@ bool ctConfigToolDoc::DoSave(ctConfigItem* item, wxOutputStream& stream, int ind ctConfigItem* child = (ctConfigItem*) node->GetData(); DoSave(child, stream, indent); - node = node->Next(); + node = node->GetNext(); } indent --; @@ -370,7 +369,7 @@ bool ctConfigToolDoc::DoSave(ctConfigItem* item, wxOutputStream& stream, int ind OutputIndentation(stream, indent*2); stream << wxT(""); - return TRUE; + return true; } /// Open the settings file @@ -391,20 +390,20 @@ bool ctConfigToolDoc::DoOpen(const wxString& filename) wxSimpleHtmlTag* firstSettingTag = settingsTag->GetChildren(); if (firstSettingTag) DoOpen(firstSettingTag, NULL); - return TRUE; + return true; } - return TRUE; + return true; } } - return FALSE; + return false; } static bool GetHtmlBoolValue(const wxString& value) { if (value == wxT("true") || value == wxT("TRUE") || value == wxT("1")) - return TRUE; + return true; else - return FALSE; + return false; } static int GetHtmlIntegerValue(const wxString& value) @@ -508,7 +507,7 @@ bool ctConfigToolDoc::DoOpen(wxSimpleHtmlTag* tag, ctConfigItem* parent) childTag->GetAttributeValue(description, wxT("description")); if (type == wxT("bool")) - prop->GetVariant() = wxVariant((bool) FALSE, name); + prop->GetVariant() = wxVariant(false, name); else if (type == wxT("double")) prop->GetVariant() = wxVariant((double) 0.0, name); else if (type == wxT("long")) @@ -516,7 +515,7 @@ bool ctConfigToolDoc::DoOpen(wxSimpleHtmlTag* tag, ctConfigItem* parent) else prop->GetVariant() = wxVariant(wxT(""), name); prop->SetDescription(description); - prop->SetCustom(TRUE); + prop->SetCustom(true); prop->SetEditorType(editorType); if (!choices.IsEmpty()) { @@ -534,7 +533,7 @@ bool ctConfigToolDoc::DoOpen(wxSimpleHtmlTag* tag, ctConfigItem* parent) else if (prop->GetVariant().GetType() == wxT("long")) prop->GetVariant() = (long) GetHtmlIntegerValue(childTag->GetNext()->GetTagText()); else if (prop->GetVariant().GetType() == wxT("bool")) - prop->GetVariant() = (bool) GetHtmlBoolValue(childTag->GetNext()->GetTagText()); + prop->GetVariant() = GetHtmlBoolValue(childTag->GetNext()->GetTagText()); else if (prop->GetVariant().GetType() == wxT("double")) prop->GetVariant() = (double) GetHtmlDoubleValue(childTag->GetNext()->GetTagText()); } @@ -543,7 +542,7 @@ bool ctConfigToolDoc::DoOpen(wxSimpleHtmlTag* tag, ctConfigItem* parent) } childTag = childTag->GetNext(); } - return TRUE; + return true; } /// Clear dependencies @@ -553,7 +552,7 @@ void ctConfigToolDoc::ClearDependencies(ctConfigItem* item) item = GetTopItem(); item->GetDependents().Clear(); - for ( wxNode* node = item->GetChildren().GetFirst(); node; node = node->GetNext() ) + for ( wxObjectList::compatibility_iterator node = item->GetChildren().GetFirst(); node; node = node->GetNext() ) { ctConfigItem* child = (ctConfigItem*) node->GetData(); ClearDependencies(child); @@ -575,6 +574,7 @@ void ctConfigToolDoc::RefreshDependencies(ctConfigItem* item) wxString precludes = item->GetPropertyString(wxT("precludes")); wxString enabledIf = item->GetPropertyString(wxT("enabled-if")); wxString enabledIfNot = item->GetPropertyString(wxT("enabled-if-not")); + wxString indeterminateIf = item->GetPropertyString(wxT("indeterminate-if")); wxString context = item->GetPropertyString(wxT("context")); if (!requires.IsEmpty()) @@ -589,6 +589,9 @@ void ctConfigToolDoc::RefreshDependencies(ctConfigItem* item) if (!enabledIf.IsEmpty()) item->StringToArray(enabledIf, requiresArr); + if (!indeterminateIf.IsEmpty()) + item->StringToArray(indeterminateIf, requiresArr); + // Add the parent to the list of dependencies, if the // parent is a check or radio group. ctConfigItem* parent = item->GetParent(); @@ -614,7 +617,7 @@ void ctConfigToolDoc::RefreshDependencies(ctConfigItem* item) otherItem->GetDependents().Append(item); } } - for ( wxNode* node = item->GetChildren().GetFirst(); node; node = node->GetNext() ) + for ( wxObjectList::compatibility_iterator node = item->GetChildren().GetFirst(); node; node = node->GetNext() ) { ctConfigItem* child = (ctConfigItem*) node->GetData(); RefreshDependencies(child); @@ -639,7 +642,7 @@ void ctConfigToolDoc::GenerateSetup(ctConfigItem* item, wxString& str) wxString name = item->GetName(); // We don't process the platform choice - if (item->GetName() == wxT("Platform")) + if (item->GetName() == wxT("Target")) return; if (item->IsInActiveContext() && @@ -663,7 +666,7 @@ void ctConfigToolDoc::GenerateSetup(ctConfigItem* item, wxString& str) } } - for ( wxNode* node = item->GetChildren().GetFirst(); node; node = node->GetNext() ) + for ( wxObjectList::compatibility_iterator node = item->GetChildren().GetFirst(); node; node = node->GetNext() ) { ctConfigItem* child = (ctConfigItem*) node->GetData(); GenerateSetup(child, str); @@ -677,8 +680,8 @@ wxString ctConfigToolDoc::GenerateConfigureCommand() wxString str; str << wxT("# configurewx\n# Generated by wxConfigTool\n\n"); - wxString path = GetFrameworkDir(TRUE); - bool makeUnix = TRUE; + wxString path = GetFrameworkDir(true); + bool makeUnix = true; if (!path.IsEmpty()) { if (makeUnix) @@ -689,11 +692,11 @@ wxString ctConfigToolDoc::GenerateConfigureCommand() str << path << wxT("configure"); - // Find the platform option to use - ctConfigItem* platformsFolder = GetTopItem()->FindItem(wxT("Platform")); + // Find the target to use + ctConfigItem* platformsFolder = GetTopItem()->FindItem(wxT("Target")); if (platformsFolder) { - for ( wxNode* node = platformsFolder->GetChildren().GetFirst(); node; node = node->GetNext() ) + for ( wxObjectList::compatibility_iterator node = platformsFolder->GetChildren().GetFirst(); node; node = node->GetNext() ) { ctConfigItem* child = (ctConfigItem*) node->GetData(); if (child->GetType() == ctTypeBoolRadio && child->IsEnabled()) @@ -714,7 +717,7 @@ void ctConfigToolDoc::GenerateConfigureCommand(ctConfigItem* item, wxString& str { // We don't process the platform group, since we've // already done so. - if (item->GetName() == wxT("Platform")) + if (item->GetName() == wxT("Target")) return; if (item->IsInActiveContext() && @@ -767,7 +770,7 @@ void ctConfigToolDoc::GenerateConfigureCommand(ctConfigItem* item, wxString& str } } - for ( wxNode* node = item->GetChildren().GetFirst(); node; node = node->GetNext() ) + for ( wxObjectList::compatibility_iterator node = item->GetChildren().GetFirst(); node; node = node->GetNext() ) { ctConfigItem* child = (ctConfigItem*) node->GetData(); GenerateConfigureCommand(child, str); @@ -782,7 +785,8 @@ wxString ctConfigToolDoc::GetFrameworkDir(bool makeUnix) { // Should probably allow other variables // to be used, and maybe expand variables within m_frameworkDir - path = wxGetenv(wxT("WXWIN")); + wxString pathEnv(wxGetenv(wxT("WXWIN"))); + path = pathEnv; #ifdef __WXMSW__ if (makeUnix) path.Replace(wxT("\\"), wxT("/")); @@ -791,6 +795,51 @@ wxString ctConfigToolDoc::GetFrameworkDir(bool makeUnix) return path; } +/// Finds the next item in the tree +ctConfigItem* ctConfigToolDoc::FindNextItem(ctConfigItem* item, bool wrap) +{ + if (!item) + return GetTopItem(); + + // First, try to find the first child + if (item->GetChildCount() > 0) + { + return item->GetChild(0); + } + else + { + ctConfigItem* p = item; + while (p) + { + ctConfigItem* toFind = FindNextSibling(p); + if (toFind) + return toFind; + p = p->GetParent(); + } + } + + // Finally, wrap around to the root. + if (wrap) + return GetTopItem(); + else + return NULL; +} + +/// Finds the next sibling in the tree +ctConfigItem* ctConfigToolDoc::FindNextSibling(ctConfigItem* item) +{ + if (item->GetParent()) + { + wxObjectList::compatibility_iterator node = item->GetParent()->GetChildren().Member(item); + if (node && node->GetNext()) + { + ctConfigItem* nextItem = (ctConfigItem*) node->GetNext()->GetData(); + return nextItem; + } + } + return NULL; +} + /* * Implements a document editing command. @@ -799,7 +848,7 @@ wxString ctConfigToolDoc::GetFrameworkDir(bool makeUnix) ctConfigCommand::ctConfigCommand(const wxString& name, int cmdId, ctConfigItem* activeState, ctConfigItem* savedState, ctConfigItem* parent, ctConfigItem* insertBefore, - bool ignoreFirstTime): wxCommand(TRUE, name) + bool ignoreFirstTime): wxCommand(true, name) { m_activeState = activeState; m_savedState = savedState; @@ -812,7 +861,7 @@ ctConfigCommand::ctConfigCommand(const wxString& name, int cmdId, ctConfigCommand::ctConfigCommand(const wxString& name, int cmdId, ctConfigItem* activeState, ctProperties* properties, - bool ignoreFirstTime): wxCommand(TRUE, name) + bool ignoreFirstTime): wxCommand(true, name) { m_activeState = activeState; m_savedState = NULL; @@ -834,12 +883,12 @@ ctConfigCommand::~ctConfigCommand() bool ctConfigCommand::Do() { - return DoAndUndo(TRUE); + return DoAndUndo(true); } bool ctConfigCommand::Undo() { - return DoAndUndo(FALSE); + return DoAndUndo(false); } // Combine Do and Undo into one @@ -867,7 +916,7 @@ bool ctConfigCommand::DoAndUndo(bool doCmd) m_savedState = m_activeState; m_activeState = NULL; - m_savedState->GetDocument()->Modify(TRUE); + m_savedState->GetDocument()->Modify(true); ctConfigToolView* view = (ctConfigToolView*) m_savedState->GetDocument()->GetFirstView(); view->OnChangeFilename(); } @@ -876,7 +925,7 @@ bool ctConfigCommand::DoAndUndo(bool doCmd) wxASSERT(m_savedState != NULL); wxASSERT(m_activeState == NULL); - m_savedState->GetDocument()->Modify(TRUE); + m_savedState->GetDocument()->Modify(true); m_savedState->Attach(m_parent, m_insertBefore); ctConfigToolView* view = (ctConfigToolView*) m_savedState->GetDocument()->GetFirstView(); view->AddItems(wxGetApp().GetMainFrame()->GetConfigTreeCtrl(), m_savedState); @@ -895,7 +944,7 @@ bool ctConfigCommand::DoAndUndo(bool doCmd) wxASSERT(m_savedState != NULL); wxASSERT(m_activeState == NULL); - m_savedState->GetDocument()->Modify(TRUE); + m_savedState->GetDocument()->Modify(true); m_savedState->Attach(m_parent, m_insertBefore); ctConfigToolView* view = (ctConfigToolView*) m_savedState->GetDocument()->GetFirstView(); view->AddItems(wxGetApp().GetMainFrame()->GetConfigTreeCtrl(), m_savedState); @@ -909,7 +958,7 @@ bool ctConfigCommand::DoAndUndo(bool doCmd) wxASSERT(m_savedState == NULL); wxASSERT(m_activeState != NULL); - m_activeState->GetDocument()->Modify(TRUE); + m_activeState->GetDocument()->Modify(true); ctConfigToolView* view = (ctConfigToolView*) m_activeState->GetDocument()->GetFirstView(); m_activeState->Detach(); m_savedState = m_activeState; @@ -925,7 +974,7 @@ bool ctConfigCommand::DoAndUndo(bool doCmd) wxASSERT(m_savedState != NULL); wxASSERT(m_activeState == NULL); - m_savedState->GetDocument()->Modify(TRUE); + m_savedState->GetDocument()->Modify(true); m_savedState->Attach(m_parent, m_insertBefore); ctConfigToolView* view = (ctConfigToolView*) m_savedState->GetDocument()->GetFirstView(); view->AddItems(wxGetApp().GetMainFrame()->GetConfigTreeCtrl(), m_savedState); @@ -939,7 +988,7 @@ bool ctConfigCommand::DoAndUndo(bool doCmd) wxASSERT(m_savedState == NULL); wxASSERT(m_activeState != NULL); - m_activeState->GetDocument()->Modify(TRUE); + m_activeState->GetDocument()->Modify(true); m_activeState->Detach(); m_savedState = m_activeState; m_activeState = NULL; @@ -963,7 +1012,7 @@ bool ctConfigCommand::DoAndUndo(bool doCmd) // Apply only those that need applying // (those properties in activeState that are not in propsTemp) - wxNode* node = m_activeState->GetProperties().GetList().GetFirst(); + wxObjectList::compatibility_iterator node = m_activeState->GetProperties().GetList().GetFirst(); while (node) { ctProperty* prop = (ctProperty*) node->GetData(); @@ -974,7 +1023,7 @@ bool ctConfigCommand::DoAndUndo(bool doCmd) } node = node->GetNext(); } - m_activeState->GetDocument()->Modify(TRUE); + m_activeState->GetDocument()->Modify(true); ctConfigToolView* view = (ctConfigToolView*) m_activeState->GetDocument()->GetFirstView(); if (view) { @@ -982,11 +1031,218 @@ bool ctConfigCommand::DoAndUndo(bool doCmd) m_activeState->GetDocument()->UpdateAllViews (NULL, & hint); } } - m_ignoreThis = FALSE; + m_ignoreThis = false; break; } } - return TRUE; + return true; +} + +IMPLEMENT_CLASS(ctConfiguration, wxObject) + +ctConfiguration::ctConfiguration() +{ + m_treeItemId = wxTreeItemId(); + m_parent = NULL; + m_topItem = NULL; +} + +ctConfiguration::ctConfiguration(ctConfiguration* parent, const wxString& name) +{ + m_treeItemId = wxTreeItemId(); + SetName(name); + m_parent = parent; + if (parent) + parent->AddChild(this); +} + +ctConfiguration::~ctConfiguration() +{ +/* + ctConfigTreeCtrl* treeCtrl = wxGetApp().GetMainFrame()->GetConfigTreeCtrl(); + if (m_treeItemId.IsOk() && treeCtrl) + { + ctTreeItemData* data = (ctTreeItemData*) treeCtrl->GetItemData(m_treeItemId); + if (data) + data->SetConfigItem(NULL); + } + if (GetParent()) + GetParent()->RemoveChild(this); + else + { + if (wxGetApp().GetMainFrame()->GetDocument() && + wxGetApp().GetMainFrame()->GetDocument()->GetTopItem() == this) + wxGetApp().GetMainFrame()->GetDocument()->SetTopItem(NULL); + } +*/ + + Clear(); } +/// Assignment operator. +void ctConfiguration::operator= (const ctConfiguration& configuration) +{ + m_name = configuration.m_name; + m_description = configuration.m_description; +} + +/// Clear children +void ctConfiguration::Clear() +{ + wxObjectList::compatibility_iterator node = m_children.GetFirst(); + while (node) + { + wxObjectList::compatibility_iterator next = node->GetNext(); + ctConfiguration* child = (ctConfiguration*) node->GetData(); + + // This should delete 'node' too, assuming + // child's m_parent points to 'this'. If not, + // it'll be cleaned up by m_children.Clear(). + delete child; + + node = next; + } + m_children.Clear(); +} + +// Get the nth child +ctConfiguration* ctConfiguration::GetChild(int n) const +{ + wxASSERT ( n < GetChildCount() && n > -1 ); + + if ( n < GetChildCount() && n > -1 ) + { + ctConfiguration* child = wxDynamicCast(m_children.Item(n)->GetData(), ctConfiguration); + return child; + } + else + return NULL; +} + +// Get the child count +int ctConfiguration::GetChildCount() const +{ + return m_children.GetCount(); +} + +/// Add a child +void ctConfiguration::AddChild(ctConfiguration* configuration) +{ + m_children.Append(configuration); + configuration->SetParent(this); +} + +/// Remove (but don't delete) a child +void ctConfiguration::RemoveChild(ctConfiguration* configuration) +{ + m_children.DeleteObject(configuration); + configuration->SetParent(NULL); +} + +/// Get the associated document (currently, assumes +/// there's only ever one document active) +ctConfigToolDoc* ctConfiguration::GetDocument() +{ + ctConfigToolDoc* doc = wxGetApp().GetMainFrame()->GetDocument(); + return doc; +} + +/// Find an item in this hierarchy +// TODO: ensure that names are unique, somehow. +ctConfiguration* ctConfiguration::FindConfiguration(const wxString& name) +{ + if (GetName() == name) + return this; + + for ( wxObjectList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext() ) + { + ctConfiguration* child = (ctConfiguration*) node->GetData(); + ctConfiguration* found = child->FindConfiguration(name); + if (found) + return found; + } + return NULL; +} + +/// Find the next sibling +ctConfiguration* ctConfiguration::FindNextSibling() +{ + if (!GetParent()) + return NULL; + wxObjectList::compatibility_iterator node = GetParent()->GetChildren().Member(this); + if (node && node->GetNext()) + { + return (ctConfiguration*) node->GetNext()->GetData(); + } + return NULL; +} + +/// Find the previous sibling +ctConfiguration* ctConfiguration::FindPreviousSibling() +{ + if (!GetParent()) + return NULL; + wxObjectList::compatibility_iterator node = GetParent()->GetChildren().Member(this); + if (node && node->GetPrevious()) + { + return (ctConfiguration*) node->GetPrevious()->GetData(); + } + return NULL; +} + +/// Create a clone of this and children +ctConfiguration* ctConfiguration::DeepClone() +{ + ctConfiguration* newItem = Clone(); + + for ( wxObjectList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext() ) + { + ctConfiguration* child = (ctConfiguration*) node->GetData(); + ctConfiguration* newChild = child->DeepClone(); + newItem->AddChild(newChild); + } + return newItem; +} + +/// Detach: remove from parent, and remove tree items +void ctConfiguration::Detach() +{ + // TODO + if (GetParent()) + GetParent()->RemoveChild(this); + else + GetDocument()->SetTopItem(NULL); + SetParent(NULL); + +/* + wxTreeItemId treeItem = GetTreeItemId(); + + DetachFromTree(); + + // Will delete the branch, but not the config items. + wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->Delete(treeItem); +*/ +} + +/// Hide from tree: make sure tree deletions won't delete +/// the config items +void ctConfiguration::DetachFromTree() +{ +/* + wxTreeItemId item = GetTreeItemId(); + + // TODO + ctTreeItemData* data = (ctTreeItemData*) wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->GetItemData(item); + data->SetConfigItem(NULL); + m_treeItemId = wxTreeItemId(); + + for ( wxNode* node = GetChildren().GetFirst(); node; node = node->GetNext() ) + { + ctConfiguration* child = (ctConfiguration*) node->GetData(); + child->DetachFromTree(); + } +*/ +} + +