Skip to content

**** ****

for my bad memories..

wxTreeCtrl의 노드 상태 저장및 복구하기


wxWidgets의 wxTreeCtrl 위젯을 사용할때 노드의 상태를 복구 하고 싶을때 아래의 방법으로 한다.

#include <wx/wx.h> 
#include <wx/treectrl.h> 
#include <wx/xml/xml.h> 

class MyFrame : public wxFrame 
{ 
        wxTreeCtrl * m_TreeCtrl; 
        void CreateControls(); 
public: 
        bool Create(wxWindow * parent) 
        { 
                bool res = wxFrame::Create(parent, wxID_ANY, wxT("Tree Test")); 
                if(res) 
                { 
                        CreateControls(); 
                } 
                return res; 
        } 

        MyFrame() 
        { 
                Create(NULL); 
        }               

        void LoadTreeNodeState(wxTreeItemId id, wxXmlNode * node); 
        void SaveTreeNodeState(wxTreeItemId id, wxXmlNode * node); 

        DECLARE_EVENT_TABLE() 
        void OnOpen(wxCommandEvent & event); 
        void OnSave(wxCommandEvent & event); 
        void OnExit(wxCommandEvent & event); 
}; 

BEGIN_EVENT_TABLE(MyFrame, wxFrame) 
EVT_MENU(wxID_OPEN, MyFrame::OnOpen) 
EVT_MENU(wxID_SAVE, MyFrame::OnSave) 
EVT_MENU(wxID_EXIT, MyFrame::OnExit) 
END_EVENT_TABLE() 

void MyFrame::CreateControls() 
{ 
        wxMenuBar * menuBar = new wxMenuBar; 
        SetMenuBar(menuBar); 

        wxMenu * fileMenu = new wxMenu; 
        fileMenu->Append(wxID_OPEN, _("Open\tCtrl+O")); 
        fileMenu->Append(wxID_SAVE, _("Save\tCtrl+S")); 
        fileMenu->AppendSeparator(); 
        fileMenu->Append(wxID_EXIT, _("Exit\tAlt+F4")); 

        menuBar->Append(fileMenu, _("File")); 

        wxBoxSizer * sizer = new wxBoxSizer(wxVERTICAL); 
        m_TreeCtrl = new wxTreeCtrl(this, wxID_ANY, wxDefaultPosition, wxSize(400, 300), 
                wxTR_SINGLE|wxTR_HAS_BUTTONS|wxTR_LINES_AT_ROOT); 

        sizer->Add(m_TreeCtrl, 1, wxALL|wxEXPAND, 5); 

        CreateStatusBar(); 

        wxTreeItemId root_item = m_TreeCtrl->AddRoot(_("Root")); 
        wxTreeItemId id;        
        id = m_TreeCtrl->AppendItem(root_item, _("Group1")); 
        m_TreeCtrl->AppendItem(id, _("Child 1")); 
        m_TreeCtrl->AppendItem(id, _("Child 2")); 
        m_TreeCtrl->AppendItem(id, _("Child 3")); 
        id = m_TreeCtrl->AppendItem(root_item, _("Group2")); 
        m_TreeCtrl->AppendItem(id, _("Child 4")); 
        m_TreeCtrl->AppendItem(id, _("Child 5")); 
        m_TreeCtrl->AppendItem(id, _("Child 6")); 
        id = m_TreeCtrl->AppendItem(root_item, _("Group3")); 
        m_TreeCtrl->AppendItem(id, _("Child 7")); 
        m_TreeCtrl->AppendItem(id, _("Child 8")); 
        m_TreeCtrl->AppendItem(id, _("Child 9"));        
        sizer->Fit(this); 
} 

void MyFrame::LoadTreeNodeState(wxTreeItemId id, wxXmlNode * node) 
{        
        if(!node) return; 
        bool expanded = !(wxAtoi(node->GetPropVal(wxT("Expanded"), wxT("0"))) == 0); 
        if(expanded) 
        { 
                m_TreeCtrl->Expand(id); 
        } else m_TreeCtrl->Collapse(id); 
        wxTreeItemIdValue cookie; 
        wxTreeItemId child = m_TreeCtrl->GetFirstChild(id, cookie); 
        wxXmlNode * child_node = node->GetChildren(); 
        while(child.IsOk() && child_node) 
        { 
                LoadTreeNodeState(child, child_node); 
                if(child == m_TreeCtrl->GetLastChild(id)) break; 
                child = m_TreeCtrl->GetNextChild(id, cookie); 
                child_node = child_node->GetNext(); 
        } 
} 

void MyFrame::SaveTreeNodeState(wxTreeItemId id, wxXmlNode * node) 
{ 
        if(!node) return; 
        if(!id.IsOk()) return; 
        node->AddProperty(wxT("Expanded"), wxString::Format(wxT("%u"), !!m_TreeCtrl->IsExpanded(id))); 
        wxTreeItemIdValue cookie; 
        wxTreeItemId child = m_TreeCtrl->GetFirstChild(id, cookie); 
        wxXmlNode * child_node; 
        while(child.IsOk()) 
        { 
                child_node = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Item")); 
                node->AddChild(child_node); 
                SaveTreeNodeState(child, child_node); 
                if(child == m_TreeCtrl->GetLastChild(id)) break; 
                child = m_TreeCtrl->GetNextChild(id, cookie); 
                child_node = child_node->GetNext(); 
        } 
} 

void MyFrame::OnOpen(wxCommandEvent & event) 
{ 
        wxFileDialog dlg(this, wxFileSelectorPromptStr, wxEmptyString, wxEmptyString, 
                _("XML Files (*.xml)|*.xml"), wxFD_OPEN); 
        if(dlg.ShowModal() == wxID_OK) 
        { 
                wxXmlDocument document(dlg.GetPath()); 
                if(document.IsOk()) 
                { 
                        wxXmlNode * node = document.GetRoot(); 
                        LoadTreeNodeState(m_TreeCtrl->GetRootItem(), node); 
                } 
        } 
} 

void MyFrame::OnSave(wxCommandEvent & event) 
{ 
        wxFileDialog dlg(this, wxFileSelectorPromptStr, wxEmptyString, wxEmptyString, 
                _("XML Files (*.xml)|*.xml"), wxFD_SAVE); 
        if(dlg.ShowModal() == wxID_OK) 
        { 
                wxXmlDocument document; 
                wxTreeItemId root_item = m_TreeCtrl->GetRootItem(); 
                if(root_item.IsOk()) 
                { 
                        wxXmlNode * root_node = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Item")); 
                        document.SetRoot(root_node); 
                        SaveTreeNodeState(root_item, root_node); 
                        document.Save(dlg.GetPath()); 
                } 
        } 
} 

void MyFrame::OnExit(wxCommandEvent & event) 
{ 
        Close(); 
} 

class MyApp : public wxApp 
{ 
        virtual bool OnInit() 
        { 
                MyFrame * frame = new MyFrame; 
                SetTopWindow(frame); 
                frame->Centre(); 
                frame->Show(); 
                return true; 
        } 
}; 

IMPLEMENT_APP(MyApp); 

Categorized as: Programming



답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다


이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.