From a75124d0da255513e83d2e62f963dd849829466b Mon Sep 17 00:00:00 2001
From: Robert Roebling <robert@roebling.de>
Date: Sat, 1 Dec 2007 19:01:47 +0000
Subject: [PATCH] Added wxDataViewTreeCtrl

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50404 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/category.tex         |   1 +
 docs/latex/wx/classes.tex          |   1 +
 docs/latex/wx/dataviewtreectrl.tex | 183 +++++++++++++++++++++++++++++
 include/wx/dataview.h              |  73 +++++++++++-
 samples/dataview/dataview.cpp      | 142 ++++++++++++----------
 src/common/datavcmn.cpp            | 160 ++++++++++++++++++++++++-
 6 files changed, 489 insertions(+), 71 deletions(-)
 create mode 100644 docs/latex/wx/dataviewtreectrl.tex

diff --git a/docs/latex/wx/category.tex b/docs/latex/wx/category.tex
index 3d8d604ffe..17b1f7782c 100644
--- a/docs/latex/wx/category.tex
+++ b/docs/latex/wx/category.tex
@@ -101,6 +101,7 @@ that are not static can have \helpref{validators}{wxvalidator} associated with t
 \twocolitem{\helpref{wxComboBox}{wxcombobox}}{A choice with an editable area}
 \twocolitem{\helpref{wxComboCtrl}{wxcomboctrl}}{A combobox with application defined popup}
 \twocolitem{\helpref{wxDataViewCtrl}{wxdataviewctrl}}{A control to tabular or tree like data}
+\twocolitem{\helpref{wxDataViewTreeCtrl}{wxdataviewtreectrl}}{A specialized wxDataViewCtrl with wxTreeCtrl-like API}
 \twocolitem{\helpref{wxGauge}{wxgauge}}{A control to represent a varying quantity, such as time remaining}
 \twocolitem{\helpref{wxGenericDirCtrl}{wxgenericdirctrl}}{A control for displaying a directory tree}
 \twocolitem{\helpref{wxHtmlListBox}{wxhtmllistbox}}{An abstract class for creating listboxes showing HTML content}
diff --git a/docs/latex/wx/classes.tex b/docs/latex/wx/classes.tex
index cfa0522bcc..bc5a406ec5 100644
--- a/docs/latex/wx/classes.tex
+++ b/docs/latex/wx/classes.tex
@@ -90,6 +90,7 @@
 \input dataviewitem.tex
 \input dataviewitemattr.tex
 \input dataviewrenderer.tex
+\input dataviewtreectrl.tex
 \input dataviewtreestore.tex
 \input dobjcomp.tex
 \input dobjsmpl.tex
diff --git a/docs/latex/wx/dataviewtreectrl.tex b/docs/latex/wx/dataviewtreectrl.tex
new file mode 100644
index 0000000000..80a31a091a
--- /dev/null
+++ b/docs/latex/wx/dataviewtreectrl.tex
@@ -0,0 +1,183 @@
+\section{\class{wxDataViewTreeCtrl}}\label{wxdataviewtreectrl}
+
+This class is a \helpref{wxDataViewCtrl}{wxdataviewctrl} which internally
+uses a \helpref{wxDataViewTreeStore}{wxdataviewtreestore} and forwards
+most of its API to that class. Additionally, it uses a \helpref{wxImageList}{wxImageList}
+to store a list of icons. The main purpose of this class is to look 
+like a \helpref{wxTreeCtrl}{wxtreectrl} to make a transition from it
+to the wxDataViewCtrl class simpler.
+
+\wxheading{Derived from}
+
+\helpref{wxDataViewCtrl}{wxdataviewctrl}
+
+\wxheading{Include files}
+
+<dataview.h>
+
+\wxheading{Data structures}
+
+\latexignore{\rtfignore{\wxheading{Members}}}
+
+
+\membersection{wxDataViewTreeCtrl::wxDataViewTreeCtrl}\label{wxdataviewtreectrlwxdataviewtreectrl}
+
+\func{}{wxDataViewTreeCtrl}{\void}
+
+Default constructor.
+
+\func{}{wxDataViewTreeCtrl}{\param{wxWindow* }{parent}, \param{wxWindowID }{id}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{const wxSize\& }{size = wxDefaultSize}, \param{long }{style = wxDV\_NO\_HEADER}, \param{const wxValidator\& }{validator = wxDefaultValidator}}
+
+Constructor. Calls \helpref{Create}{wxdataviewtreectrlcreate}.
+
+\membersection{wxDataViewTreeCtrl::\destruct{wxDataViewTreeCtrl}}\label{wxdataviewtreectrldtor}
+
+\func{}{\destruct{wxDataViewTreeCtrl}}{\void}
+
+Destructor. Deletes the image list if any.
+
+\membersection{wxDataViewTreeCtrl::AppendContainer}\label{wxdataviewtreectrlappendcontainer}
+
+\func{wxDataViewItem}{AppendContainer}{\param{const wxDataViewItem\& }{parent}, \param{const wxString\& }{text}, \param{int }{icon = -1}, \param{int }{expanded = -1}, \param{wxClientData* }{data = NULL}}
+
+
+\membersection{wxDataViewTreeCtrl::AppendItem}\label{wxdataviewtreectrlappenditem}
+
+\func{wxDataViewItem}{AppendItem}{\param{const wxDataViewItem\& }{parent}, \param{const wxString\& }{text}, \param{int }{icon = -1}, \param{wxClientData* }{data = NULL}}
+
+
+\membersection{wxDataViewTreeCtrl::Create}\label{wxdataviewtreectrlcreate}
+
+\func{bool}{Create}{\param{wxWindow* }{parent}, \param{wxWindowID }{id}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{const wxSize\& }{size = wxDefaultSize}, \param{long }{style = wxDV\_NO\_HEADER}, \param{const wxValidator\& }{validator = wxDefaultValidator}}
+
+Creates the control and a \helpref{wxDataViewTreeStore}{wxdataviewtreestore} as
+its internal model.
+
+\membersection{wxDataViewTreeCtrl::DeleteAllItems}\label{wxdataviewtreectrldeleteallitems}
+
+\func{void}{DeleteAllItems}{\void}
+
+Calls the identical method from wxDataViewTreeStore.
+
+\membersection{wxDataViewTreeCtrl::DeleteChildren}\label{wxdataviewtreectrldeletechildren}
+
+\func{void}{DeleteChildren}{\param{const wxDataViewItem\& }{item}}
+
+Calls the identical method from wxDataViewTreeStore.
+
+\membersection{wxDataViewTreeCtrl::DeleteItem}\label{wxdataviewtreectrldeleteitem}
+
+\func{void}{DeleteItem}{\param{const wxDataViewItem\& }{item}}
+
+Calls the identical method from wxDataViewTreeStore.
+
+\membersection{wxDataViewTreeCtrl::GetChildCount}\label{wxdataviewtreectrlgetchildcount}
+
+\constfunc{int}{GetChildCount}{\param{const wxDataViewItem\& }{parent}}
+
+Calls the identical method from wxDataViewTreeStore.
+
+\membersection{wxDataViewTreeCtrl::GetImageList}\label{wxdataviewtreectrlgetimagelist}
+
+\func{wxImageList*}{GetImageList}{\void}
+
+Returns the image list.
+
+\membersection{wxDataViewTreeCtrl::GetItemData}\label{wxdataviewtreectrlgetitemdata}
+
+\constfunc{wxClientData*}{GetItemData}{\param{const wxDataViewItem\& }{item}}
+
+Calls the identical method from wxDataViewTreeStore.
+
+\membersection{wxDataViewTreeCtrl::GetItemExpandedIcon}\label{wxdataviewtreectrlgetitemexpandedicon}
+
+\constfunc{const wxIcon\&}{GetItemExpandedIcon}{\param{const wxDataViewItem\& }{item}}
+
+Calls the identical method from wxDataViewTreeStore.
+
+\membersection{wxDataViewTreeCtrl::GetItemIcon}\label{wxdataviewtreectrlgetitemicon}
+
+\constfunc{const wxIcon\&}{GetItemIcon}{\param{const wxDataViewItem\& }{item}}
+
+Calls the identical method from wxDataViewTreeStore.
+
+\membersection{wxDataViewTreeCtrl::GetItemText}\label{wxdataviewtreectrlgetitemtext}
+
+\constfunc{wxString}{GetItemText}{\param{const wxDataViewItem\& }{item}}
+
+Calls the identical method from wxDataViewTreeStore.
+
+\membersection{wxDataViewTreeCtrl::GetNthChild}\label{wxdataviewtreectrlgetnthchild}
+
+\constfunc{wxDataViewItem}{GetNthChild}{\param{const wxDataViewItem\& }{parent}, \param{unsigned int }{pos}}
+
+Calls the identical method from wxDataViewTreeStore.
+
+\membersection{wxDataViewTreeCtrl::GetStore}\label{wxdataviewtreectrlgetstore}
+
+\func{wxDataViewTreeStore*}{GetStore}{\void}
+
+\constfunc{const wxDataViewTreeStore*}{GetStore}{\void}
+
+Returns the store.
+
+\membersection{wxDataViewTreeCtrl::InsertContainer}\label{wxdataviewtreectrlinsertcontainer}
+
+\func{wxDataViewItem}{InsertContainer}{\param{const wxDataViewItem\& }{parent}, \param{const wxDataViewItem\& }{previous}, \param{const wxString\& }{text}, \param{int }{icon = -1}, \param{int }{expanded = -1}, \param{wxClientData* }{data = NULL}}
+
+Calls the same method from wxDataViewTreeStore but uess
+and index position in the image list instead of a wxIcon.
+
+\membersection{wxDataViewTreeCtrl::InsertItem}\label{wxdataviewtreectrlinsertitem}
+
+\func{wxDataViewItem}{InsertItem}{\param{const wxDataViewItem\& }{parent}, \param{const wxDataViewItem\& }{previous}, \param{const wxString\& }{text}, \param{int }{icon = -1}, \param{wxClientData* }{data = NULL}}
+
+Calls the same method from wxDataViewTreeStore but uess
+and index position in the image list instead of a wxIcon.
+
+\membersection{wxDataViewTreeCtrl::PrependContainer}\label{wxdataviewtreectrlprependcontainer}
+
+\func{wxDataViewItem}{PrependContainer}{\param{const wxDataViewItem\& }{parent}, \param{const wxString\& }{text}, \param{int }{icon = -1}, \param{int }{expanded = -1}, \param{wxClientData* }{data = NULL}}
+
+Calls the same method from wxDataViewTreeStore but uess
+and index position in the image list instead of a wxIcon.
+
+\membersection{wxDataViewTreeCtrl::PrependItem}\label{wxdataviewtreectrlprependitem}
+
+\func{wxDataViewItem}{PrependItem}{\param{const wxDataViewItem\& }{parent}, \param{const wxString\& }{text}, \param{int }{icon = -1}, \param{wxClientData* }{data = NULL}}
+
+Calls the same method from wxDataViewTreeStore but uess
+and index position in the image list instead of a wxIcon.
+
+\membersection{wxDataViewTreeCtrl::SetImageList}\label{wxdataviewtreectrlsetimagelist}
+
+\func{void}{SetImageList}{\param{wxImageList* }{imagelist}}
+
+Sets the image list.
+
+\membersection{wxDataViewTreeCtrl::SetItemData}\label{wxdataviewtreectrlsetitemdata}
+
+\func{void}{SetItemData}{\param{const wxDataViewItem\& }{item}, \param{wxClientData* }{data}}
+
+Calls the identical method from wxDataViewTreeStore.
+
+
+\membersection{wxDataViewTreeCtrl::SetItemExpandedIcon}\label{wxdataviewtreectrlsetitemexpandedicon}
+
+\func{void}{SetItemExpandedIcon}{\param{const wxDataViewItem\& }{item}, \param{const wxIcon\& }{icon}}
+
+Calls the identical method from wxDataViewTreeStore.
+
+
+\membersection{wxDataViewTreeCtrl::SetItemIcon}\label{wxdataviewtreectrlsetitemicon}
+
+\func{void}{SetItemIcon}{\param{const wxDataViewItem\& }{item}, \param{const wxIcon\& }{icon}}
+
+Calls the identical method from wxDataViewTreeStore.
+
+
+\membersection{wxDataViewTreeCtrl::SetItemText}\label{wxdataviewtreectrlsetitemtext}
+
+\func{void}{SetItemText}{\param{const wxDataViewItem\& }{item}, \param{const wxString\& }{text}}
+
+Calls the identical method from wxDataViewTreeStore.
diff --git a/include/wx/dataview.h b/include/wx/dataview.h
index 01dfc25dc4..4a5e4f8893 100644
--- a/include/wx/dataview.h
+++ b/include/wx/dataview.h
@@ -22,6 +22,7 @@
 #include "wx/variant.h"
 #include "wx/dynarray.h"
 #include "wx/icon.h"
+#include "wx/imaglist.h"
 
 #if defined(__WXGTK20__)
     // for testing
@@ -506,6 +507,7 @@ public:
 
     virtual bool AssociateModel( wxDataViewModel *model );
     wxDataViewModel* GetModel();
+    const wxDataViewModel* GetModel() const;
 
     // short cuts
     wxDataViewColumn *PrependTextColumn( const wxString &label, unsigned int model_column,
@@ -848,12 +850,18 @@ public:
     const wxIcon &GetExpandedIcon() const
         { return m_iconExpanded; }
 
+    void SetExpanded( bool expanded = true )
+        { m_isExpanded = expanded; }
+    bool IsExpanded() const
+        { return m_isExpanded; }
+
     virtual bool IsContainer()
         { return true; }
 
 private:
     wxDataViewTreeStoreNodeList  m_children;
     wxIcon                       m_iconExpanded;
+    bool                         m_isExpanded;
 };
 
 //-----------------------------------------------------------------------------
@@ -925,14 +933,15 @@ public:
     wxDataViewTreeStoreNode *m_root;
 };
 
-#if 0
 class WXDLLIMPEXP_ADV wxDataViewTreeCtrl: public wxDataViewCtrl
 {
 public:
-    wxDataViewCtrl( wxWindow *parent, wxWindowID id,
+    wxDataViewTreeCtrl();
+    wxDataViewTreeCtrl( wxWindow *parent, wxWindowID id,
            const wxPoint& pos = wxDefaultPosition,
            const wxSize& size = wxDefaultSize, long style = wxDV_NO_HEADER,
            const wxValidator& validator = wxDefaultValidator );
+    ~wxDataViewTreeCtrl();
 
     bool Create( wxWindow *parent, wxWindowID id,
            const wxPoint& pos = wxDefaultPosition,
@@ -941,14 +950,68 @@ public:
 
     wxDataViewTreeStore *GetStore()
         { return (wxDataViewTreeStore*) GetModel(); }
+    const wxDataViewTreeStore *GetStore() const
+        { return (const wxDataViewTreeStore*) GetModel(); }
 
-    void OnExpand( wxDataViewCtrl &event );
-    void OnCollapse( wxDataViewCtrl &event );
+    void SetImageList( wxImageList *imagelist );
+    wxImageList* GetImageList() { return m_imageList; }
+    
+    wxDataViewItem AppendItem( const wxDataViewItem& parent,
+        const wxString &text, int icon = -1, wxClientData *data = NULL );
+    wxDataViewItem PrependItem( const wxDataViewItem& parent,
+        const wxString &text, int icon = -1, wxClientData *data = NULL );
+    wxDataViewItem InsertItem( const wxDataViewItem& parent, const wxDataViewItem& previous,
+        const wxString &text, int icon = -1, wxClientData *data = NULL );
+
+    wxDataViewItem PrependContainer( const wxDataViewItem& parent,
+        const wxString &text, int icon = -1, int expanded = -1,
+        wxClientData *data = NULL );
+    wxDataViewItem AppendContainer( const wxDataViewItem& parent,
+        const wxString &text, int icon = -1, int expanded = -1,
+        wxClientData *data = NULL );
+    wxDataViewItem InsertContainer( const wxDataViewItem& parent, const wxDataViewItem& previous,
+        const wxString &text, int icon = -1, int expanded = -1,
+        wxClientData *data = NULL );
+
+    wxDataViewItem GetNthChild( const wxDataViewItem& parent, unsigned int pos ) const
+        { return GetStore()->GetNthChild(parent, pos); }
+    int GetChildCount( const wxDataViewItem& parent ) const
+        { return GetStore()->GetChildCount(parent); }
+
+    void SetItemText( const wxDataViewItem& item, const wxString &text )
+        { GetStore()->SetItemText(item,text); }
+    wxString GetItemText( const wxDataViewItem& item ) const
+        { return GetStore()->GetItemText(item); }
+    void SetItemIcon( const wxDataViewItem& item, const wxIcon &icon )
+        { GetStore()->SetItemIcon(item,icon); }
+    const wxIcon &GetItemIcon( const wxDataViewItem& item ) const
+        { return GetStore()->GetItemIcon(item); }
+    void SetItemExpandedIcon( const wxDataViewItem& item, const wxIcon &icon )
+        { GetStore()->SetItemExpandedIcon(item,icon); }
+    const wxIcon &GetItemExpandedIcon( const wxDataViewItem& item ) const
+        { return GetStore()->GetItemExpandedIcon(item); }
+    void SetItemData( const wxDataViewItem& item, wxClientData *data )
+        { GetStore()->SetItemData(item,data); }
+    wxClientData *GetItemData( const wxDataViewItem& item ) const
+        { return GetStore()->GetItemData(item); }
+
+    void DeleteItem( const wxDataViewItem& item )
+        { GetStore()->DeleteItem(item); }
+    void DeleteChildren( const wxDataViewItem& item )
+        { GetStore()->DeleteChildren(item); }
+    void DeleteAllItems()
+        { GetStore()->DeleteAllItems(); }
+
+    void OnExpanded( wxDataViewEvent &event );
+    void OnCollapsed( wxDataViewEvent &event );
 
 private:
+    wxImageList  *m_imageList;
+
+private:
+    DECLARE_EVENT_TABLE()
     DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxDataViewTreeCtrl)
 };
-#endif
 
 #endif // wxUSE_DATAVIEWCTRL
 
diff --git a/samples/dataview/dataview.cpp b/samples/dataview/dataview.cpp
index be3d1edab3..8a191f9348 100644
--- a/samples/dataview/dataview.cpp
+++ b/samples/dataview/dataview.cpp
@@ -34,6 +34,36 @@
 
 #include "null.xpm"
 
+/* XPM */
+static const char *small1_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 6 1",
+". c Black",
+"o c #FFFFFF",
+"X c #000080",
+"O c #FFFF00",
+"  c None",
+"+ c #FF0000",
+/* pixels */
+"                ",
+"                ",
+"                ",
+"    .......     ",
+"    .XXXXX.     ",
+"    .oXXXX.     ",
+"    .oXXX.......",
+".....oXXX.OOOOO.",
+".+++.XXXX.oOOOO.",
+".o++......oOOOO.",
+".o++++.  .oOOOO.",
+".o++++.  .OOOOO.",
+".+++++.  .......",
+".......         ",
+"                ",
+"                "
+};
+
+
 
 #define DEFAULT_ALIGN                   wxALIGN_LEFT
 #define DATAVIEW_DEFAULT_STYLE          (wxDV_MULTIPLE|wxDV_HORIZ_RULES|wxDV_VERT_RULES)
@@ -327,7 +357,11 @@ class MyListModel: public wxDataViewIndexListModel
 {
 public:
     MyListModel() : 
-        wxDataViewIndexListModel( 100 )
+#ifdef __WXMAC__
+        wxDataViewIndexListModel( 1000 )
+#else
+        wxDataViewIndexListModel( 100000 )
+#endif
     {
         unsigned int i;
         for (i = 0; i < 100; i++)
@@ -380,7 +414,16 @@ public:
     {
         if (col==0)
         {
-            variant = m_array[ row ];
+            if (row >= m_array.GetCount())
+            {
+                wxString str;
+                str.Printf( "row %d", row );
+                variant = str;
+            }
+            else
+            {
+                variant = m_array[ row ];
+            }
         } else
         if (col==1)
         {
@@ -414,6 +457,9 @@ public:
     {
         if (col == 0)
         {
+            if (row >= m_array.GetCount())
+               return false;
+               
             m_array[row] = variant.GetString();
             return true;
         }
@@ -449,8 +495,6 @@ public:
     void OnQuit(wxCommandEvent& event);
     void OnAbout(wxCommandEvent& event);
     
-    void OnTestTreeCtrl(wxCommandEvent& event);
-    
     void OnAddMozart(wxCommandEvent& event);
     void OnDeleteMusic(wxCommandEvent& event);
     void OnDeleteYear(wxCommandEvent& event);
@@ -529,8 +573,6 @@ enum
     ID_ABOUT = wxID_ABOUT,
     ID_EXIT = wxID_EXIT,
     
-    ID_TEST_TREECTRL    = 40,
-    
     ID_MUSIC_CTRL       = 50,
     
     ID_ADD_MOZART       = 100,
@@ -544,7 +586,6 @@ enum
 
 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_MENU( ID_ABOUT, MyFrame::OnAbout )
-    EVT_MENU( ID_TEST_TREECTRL, MyFrame::OnTestTreeCtrl )
     EVT_MENU( ID_EXIT, MyFrame::OnQuit )
     EVT_BUTTON( ID_ADD_MOZART, MyFrame::OnAddMozart )
     EVT_BUTTON( ID_DELETE_MUSIC, MyFrame::OnDeleteMusic )
@@ -585,8 +626,6 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int
     wxMenu *file_menu = new wxMenu;
     file_menu->Append(ID_ABOUT, "&About");
     file_menu->AppendSeparator();
-    file_menu->Append(ID_TEST_TREECTRL, "Test &Treectrl");
-    file_menu->AppendSeparator();
     file_menu->Append(ID_EXIT, "E&xit");
 
     wxMenuBar *menu_bar = new wxMenuBar;
@@ -603,7 +642,7 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int
 
     m_musicCtrl = new wxDataViewCtrl( this, ID_MUSIC_CTRL, wxDefaultPosition,
                                     wxDefaultSize, wxDV_MULTIPLE );
-
+                                    
     m_music_model = new MyMusicModel;
     m_musicCtrl->AssociateModel( m_music_model.get() );
 
@@ -658,58 +697,18 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int
     button_sizer->Add( new wxButton( this, ID_GOTO, "Goto 50"), 0, wxALL, 10 );
     
     main_sizer->Add( button_sizer, 0, wxGROW, 0 );
+
+    wxBoxSizer *bottom_sizer = new wxBoxSizer( wxHORIZONTAL );
     
     m_log = new wxTextCtrl( this, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
     m_logOld = wxLog::SetActiveTarget(new wxLogTextCtrl(m_log));
     wxLogMessage("This is the log window");
 
-    main_sizer->Add( m_log, 1, wxGROW );
-    
-    SetSizer( main_sizer );
-}
-
-void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
-{
-    Close(true);
-}
-
-
-/* XPM */
-static const char *small1_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"16 16 6 1",
-". c Black",
-"o c #FFFFFF",
-"X c #000080",
-"O c #FFFF00",
-"  c None",
-"+ c #FF0000",
-/* pixels */
-"                ",
-"                ",
-"                ",
-"    .......     ",
-"    .XXXXX.     ",
-"    .oXXXX.     ",
-"    .oXXX.......",
-".....oXXX.OOOOO.",
-".+++.XXXX.oOOOO.",
-".o++......oOOOO.",
-".o++++.  .oOOOO.",
-".o++++.  .OOOOO.",
-".+++++.  .......",
-".......         ",
-"                ",
-"                "
-};
+    bottom_sizer->Add( m_log, 1, wxGROW );
+ 
+    // wxDataViewTreeStore
 
-void MyFrame::OnTestTreeCtrl(wxCommandEvent& WXUNUSED(event) )
-{
-    wxDialog dialog( this, -1, wxString(wxT("Test wxDataViewTreeStore")));
-    
-    wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
-    
-    wxDataViewCtrl *treectrl = new wxDataViewCtrl( &dialog, -1, 
+    wxDataViewCtrl *treectrl = new wxDataViewCtrl( this, -1, 
         wxDefaultPosition, wxSize(300,200), wxDV_NO_HEADER );
         
     wxDataViewTreeStore *store = new wxDataViewTreeStore;
@@ -722,17 +721,30 @@ void MyFrame::OnTestTreeCtrl(wxCommandEvent& WXUNUSED(event) )
 
     treectrl->AppendIconTextColumn( "no label", 0, wxDATAVIEW_CELL_INERT, 200 );
 
-    main_sizer->Add( treectrl, 1, wxGROW );
-    
+    bottom_sizer->Add( treectrl );
 
-    wxSizer *button_sizer = dialog.CreateButtonSizer( wxOK );
-    if (button_sizer)
-        main_sizer->Add( button_sizer, 0, wxGROW|wxALL, 10 );
-        
-    dialog.SetSizer( main_sizer );
-    main_sizer->Fit( &dialog );
+    // wxDataViewTreeCtrl
+
+    wxDataViewTreeCtrl *treectrl2 = new wxDataViewTreeCtrl( this, -1, wxDefaultPosition, wxSize(300,200) );
+    wxImageList *ilist = new wxImageList;
+    ilist->Add( wxIcon(small1_xpm) );
+    parent = treectrl2->AppendContainer( wxDataViewItem(0), "Root 1", 0 );
+    child = treectrl2->AppendItem( parent, "Child 1", 0 );
+    child = treectrl2->AppendItem( parent, "Child 2", 0 );
+    child = treectrl2->AppendItem( parent, "Child 3", 0 );
+    
+    bottom_sizer->Add( treectrl2 );
+    
+    // main sizer
+    
+    main_sizer->Add( bottom_sizer, 0, wxGROW );
     
-    dialog.ShowModal();
+    SetSizer( main_sizer );
+}
+
+void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
+{
+    Close(true);
 }
 
 void MyFrame::OnAddMozart(wxCommandEvent& WXUNUSED(event) )
diff --git a/src/common/datavcmn.cpp b/src/common/datavcmn.cpp
index 09353943d8..4d1c9dd89c 100644
--- a/src/common/datavcmn.cpp
+++ b/src/common/datavcmn.cpp
@@ -781,6 +781,11 @@ wxDataViewModel* wxDataViewCtrlBase::GetModel()
     return m_model;
 }
 
+const wxDataViewModel* wxDataViewCtrlBase::GetModel() const
+{
+    return m_model;
+}
+
 wxDataViewColumn *
 wxDataViewCtrlBase::AppendTextColumn( const wxString &label, unsigned int model_column,
                             wxDataViewCellMode mode, int width, wxAlignment align, int flags )
@@ -1163,6 +1168,7 @@ wxDataViewTreeStoreContainerNode::wxDataViewTreeStoreContainerNode(
     wxDataViewTreeStoreNode( parent, text, icon, data )
 {
     m_iconExpanded = expanded;
+    m_isExpanded = false;
     m_children.DeleteContents(true);
 }
 
@@ -1424,7 +1430,15 @@ wxDataViewTreeStore::GetValue(wxVariant &variant,
     wxDataViewTreeStoreNode *node = FindNode( item );
     if (!node) return;
 
-    wxDataViewIconText data( node->GetText(), node->GetIcon() );
+    wxIcon icon( node->GetIcon());
+    if (node->IsContainer())
+    {
+        wxDataViewTreeStoreContainerNode *container = (wxDataViewTreeStoreContainerNode*) node;
+        if (container->IsExpanded() && container->GetExpandedIcon().IsOk())
+           icon = container->GetExpandedIcon();
+    }
+    
+    wxDataViewIconText data( node->GetText(), icon );
 
     variant << data;
 }
@@ -1536,5 +1550,149 @@ wxDataViewTreeStoreContainerNode *wxDataViewTreeStore::FindContainerNode( const
     return (wxDataViewTreeStoreContainerNode*) node;
 }
 
+//-----------------------------------------------------------------------------
+// wxDataViewTreeCtrl
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxDataViewTreeCtrl,wxDataViewCtrl)
+
+BEGIN_EVENT_TABLE(wxDataViewTreeCtrl,wxDataViewCtrl)
+   EVT_DATAVIEW_ITEM_EXPANDED(-1, wxDataViewTreeCtrl::OnExpanded)
+   EVT_DATAVIEW_ITEM_COLLAPSED(-1, wxDataViewTreeCtrl::OnCollapsed)
+END_EVENT_TABLE()
+
+wxDataViewTreeCtrl::wxDataViewTreeCtrl()
+{
+    m_imageList = NULL;
+}
+
+wxDataViewTreeCtrl::wxDataViewTreeCtrl( wxWindow *parent, wxWindowID id,
+           const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator ) 
+{
+    m_imageList = NULL;
+    Create( parent, id, pos, size, style, validator );
+    
+    wxDataViewTreeStore *store = new wxDataViewTreeStore;
+    AssociateModel( store );
+    store->DecRef();
+    AppendIconTextColumn( "", 0, wxDATAVIEW_CELL_INERT, 200 );
+}
+
+wxDataViewTreeCtrl::~wxDataViewTreeCtrl()
+{
+    if (m_imageList)
+        delete m_imageList;
+}
+
+bool wxDataViewTreeCtrl::Create( wxWindow *parent, wxWindowID id,
+           const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator )
+{
+    return wxDataViewCtrl::Create( parent, id, pos, size, style, validator );
+}
+
+void wxDataViewTreeCtrl::SetImageList( wxImageList *imagelist )
+{
+    if (m_imageList)
+        delete m_imageList;
+
+    m_imageList = imagelist;   
+}
+    
+wxDataViewItem wxDataViewTreeCtrl::AppendItem( const wxDataViewItem& parent,
+        const wxString &text, int iconIndex, wxClientData *data )
+{
+    wxIcon icon = wxNullIcon;
+    if (m_imageList && (iconIndex != -1))
+        icon = m_imageList->GetIcon( iconIndex );
+        
+    return GetStore()->AppendItem( parent, text, icon, data );
+}
+
+wxDataViewItem wxDataViewTreeCtrl::PrependItem( const wxDataViewItem& parent,
+        const wxString &text, int iconIndex, wxClientData *data )
+{
+    wxIcon icon = wxNullIcon;
+    if (m_imageList && (iconIndex != -1))
+        icon = m_imageList->GetIcon( iconIndex );
+        
+    return GetStore()->PrependItem( parent, text, icon, data );
+}
+
+wxDataViewItem wxDataViewTreeCtrl::InsertItem( const wxDataViewItem& parent, const wxDataViewItem& previous,
+        const wxString &text, int iconIndex, wxClientData *data )
+{
+    wxIcon icon = wxNullIcon;
+    if (m_imageList && (iconIndex != -1))
+        icon = m_imageList->GetIcon( iconIndex );
+        
+    return GetStore()->InsertItem( parent, previous, text, icon, data );
+}
+
+wxDataViewItem wxDataViewTreeCtrl::PrependContainer( const wxDataViewItem& parent,
+        const wxString &text, int iconIndex, int expandedIndex, wxClientData *data )
+{
+    wxIcon icon = wxNullIcon;
+    if (m_imageList && (iconIndex != -1))
+        icon = m_imageList->GetIcon( iconIndex );
+        
+    wxIcon expanded = wxNullIcon;
+    if (m_imageList && (expandedIndex != -1))
+        expanded = m_imageList->GetIcon( expandedIndex );
+        
+    return GetStore()->PrependContainer( parent, text, icon, expanded, data );
+}
+
+wxDataViewItem wxDataViewTreeCtrl::AppendContainer( const wxDataViewItem& parent,
+        const wxString &text, int iconIndex, int expandedIndex, wxClientData *data )
+{
+    wxIcon icon = wxNullIcon;
+    if (m_imageList && (iconIndex != -1))
+        icon = m_imageList->GetIcon( iconIndex );
+        
+    wxIcon expanded = wxNullIcon;
+    if (m_imageList && (expandedIndex != -1))
+        expanded = m_imageList->GetIcon( expandedIndex );
+        
+    return GetStore()->AppendContainer( parent, text, icon, expanded, data );
+}
+
+wxDataViewItem wxDataViewTreeCtrl::InsertContainer( const wxDataViewItem& parent, const wxDataViewItem& previous,
+        const wxString &text, int iconIndex, int expandedIndex, wxClientData *data )
+{
+    wxIcon icon = wxNullIcon;
+    if (m_imageList && (iconIndex != -1))
+        icon = m_imageList->GetIcon( iconIndex );
+        
+    wxIcon expanded = wxNullIcon;
+    if (m_imageList && (expandedIndex != -1))
+        expanded = m_imageList->GetIcon( expandedIndex );
+        
+    return GetStore()->InsertContainer( parent, previous, text, icon, expanded, data );
+}
+
+
+void wxDataViewTreeCtrl::OnExpanded( wxDataViewEvent &event )
+{
+    if (m_imageList) return;
+    
+    wxDataViewTreeStoreContainerNode* container = GetStore()->FindContainerNode( event.GetItem() );
+    if (!container) return;
+    
+    container->SetExpanded( true );
+    GetStore()->ItemChanged( event.GetItem() );
+}
+
+void wxDataViewTreeCtrl::OnCollapsed( wxDataViewEvent &event )
+{
+    if (m_imageList) return;
+    
+    wxDataViewTreeStoreContainerNode* container = GetStore()->FindContainerNode( event.GetItem() );
+    if (!container) return;
+    
+    container->SetExpanded( false );
+    GetStore()->ItemChanged( event.GetItem() );
+}
+
+
 #endif // wxUSE_DATAVIEWCTRL
 
-- 
2.50.0

