1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxDataViewCtrl wxWidgets sample 
   4 // Author:      Robert Roebling 
   5 // Modified by: Francesco Montorsi 
   8 // Copyright:   (c) Robert Roebling 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx/wx.h". 
  13 #include "wx/wxprec.h" 
  23 #include "wx/datetime.h" 
  24 #include "wx/splitter.h" 
  25 #include "wx/aboutdlg.h" 
  26 #include "wx/choicdlg.h" 
  27 #include "wx/numdlg.h" 
  28 #include "wx/dataview.h" 
  29 #include "wx/spinctrl.h" 
  32     #include "../sample.xpm" 
  38 #define DEFAULT_ALIGN                   wxALIGN_LEFT 
  39 #define DATAVIEW_DEFAULT_STYLE          (wxDV_MULTIPLE|wxDV_HORIZ_RULES|wxDV_VERT_RULES) 
  43 // ------------------------------------- 
  45 // ------------------------------------- 
  48 Implement this data model 
  50 ------------------------------------------------------------- 
  53         3:  You are not alone   Michael Jackson      1995 
  54         4:  Take a bow          Madonna              1994 
  56         6:  Ninth Symphony      Ludwig v. Beethoven  1824 
  57         7:  German Requiem      Johannes Brahms      1868 
  62 class MyMusicModelNode
; 
  63 WX_DEFINE_ARRAY_PTR( MyMusicModelNode
*, MyMusicModelNodes 
); 
  65 class MyMusicModelNode
 
  68     MyMusicModelNode( MyMusicModelNode
* parent
, const wxUint32 id
, 
  69                       const wxString 
&title
, const wxString 
&artist
, const wxString 
&year 
) 
  76         m_isContainer 
= false; 
  79     MyMusicModelNode( MyMusicModelNode
* parent
, const wxUint32 id
, 
  80                       const wxString 
&branch 
) 
  90         size_t count 
= m_children
.GetCount(); 
  92         for (i 
= 0; i 
< count
; i
++) 
  94             MyMusicModelNode 
*child 
= m_children
[i
]; 
  99     wxUint32 
GetID()                                      { return m_id
; } 
 100     bool IsContainer()                                    { return m_isContainer
; } 
 102     MyMusicModelNode
* GetParent()                         { return m_parent
; } 
 103     MyMusicModelNodes 
&GetChildren()                      { return m_children
; } 
 104     MyMusicModelNode
* GetNthChild( unsigned int n 
)       { return m_children
.Item( n 
); } 
 105     void Insert( MyMusicModelNode
* child
, unsigned int n
) { m_children
.Insert( child
, n
); } 
 106     void Append( MyMusicModelNode
* child 
)                { m_children
.Add( child 
); } 
 107     unsigned int GetChildCount()                          { return m_children
.GetCount(); } 
 115     MyMusicModelNode   
*m_parent
; 
 116     MyMusicModelNodes   m_children
;  
 122 class MyMusicModel
: public wxDataViewModel
 
 131         m_root 
= new MyMusicModelNode( NULL
, GetNewId(), "My Music" ); 
 132         m_pop 
= new MyMusicModelNode( m_root
, GetNewId(), "Pop music" ); 
 133         m_root
->Append( m_pop 
); 
 134         m_pop
->Append( new MyMusicModelNode( m_pop
, GetNewId(),  
 135             "You are not alone", "Michael Jackson", "1995" ) ); 
 136         m_pop
->Append( new MyMusicModelNode( m_pop
, GetNewId(),  
 137             "Take a bow", "Madonna", "1994" ) ); 
 138         m_classical 
= new MyMusicModelNode( m_root
, GetNewId(), "Classical music" ); 
 139         m_root
->Append( m_classical 
); 
 140         m_classical
->Append( new MyMusicModelNode( m_classical
, GetNewId(),  
 141             "Ninth symphony", "Ludwig van Beethoven", "1824" ) ); 
 142         m_classical
->Append( new MyMusicModelNode( m_classical
, GetNewId(),  
 143             "German Requiem", "Johannes Brahms", "1868" ) ); 
 144         m_classicalMusicIsKnownToControl 
= false; 
 147     // helper methods to change the model 
 149     void AddToClassical( const wxString 
&title
, const wxString 
&artist
, const wxString 
&year 
) 
 152         MyMusicModelNode 
*child_node 
=  
 153             new MyMusicModelNode( m_classical
, GetNewId(), title
, artist
, year 
); 
 154         m_classical
->Append( child_node 
); 
 156         if (m_classicalMusicIsKnownToControl
) 
 159             wxDataViewItem 
child( (void*) child_node
->GetID() ); 
 160             wxDataViewItem 
parent( (void*) m_classical
->GetID() ); 
 161             ItemAdded( parent
, child 
); 
 165     void Delete( const wxDataViewItem 
&item 
) 
 167         MyMusicModelNode 
*node 
= FindNode( item 
); 
 168         node
->GetParent()->GetChildren().Remove( node 
); 
 175     // implementation of base class virtuals to define model 
 177     virtual unsigned int GetColumnCount() const 
 182     virtual wxString 
GetColumnType( unsigned int col 
) const 
 187     virtual void GetValue( wxVariant 
&variant
,  
 188                            const wxDataViewItem 
&item
, unsigned int col 
) const 
 190         MyMusicModelNode 
*node 
= FindNode( item 
); 
 193             case 0: variant 
= node
->m_title
; break; 
 194             case 1: variant 
= node
->m_artist
; break; 
 195             case 2: variant 
= node
->m_year
; break; 
 196             default: wxLogError( "MyMusicModel::GetValue: wrong column" ); 
 200     virtual bool SetValue( const wxVariant 
&variant
,  
 201                            const wxDataViewItem 
&item
, unsigned int col 
) 
 203         MyMusicModelNode 
*node 
= FindNode( item 
); 
 206             case 0: node
->m_title 
= variant
.GetString(); break; 
 207             case 1: node
->m_artist  
= variant
.GetString(); break; 
 208             case 2: node
->m_year  
= variant
.GetString(); break; 
 209             default: wxLogError( "MyMusicModel::SetValue: wrong column" ); 
 213     virtual bool HasChildren( const wxDataViewItem 
&item 
) const 
 215         if (item
.GetID() == 0) 
 218         MyMusicModelNode 
*node 
= FindNode( item 
); 
 219         return node
->IsContainer(); 
 222     virtual wxDataViewItem 
GetFirstChild( const wxDataViewItem 
&parent 
) const 
 224         if (parent
.GetID() == 0) 
 225             return wxDataViewItem( (void*) m_root
->GetID() ); 
 227         MyMusicModelNode 
*node 
= FindNode( parent 
); 
 229         if (node
->GetChildCount() == 0) 
 230             return wxDataViewItem( 0 ); 
 232         if (node 
== m_classical
) 
 234             MyMusicModel 
*model 
= (MyMusicModel
*)(const MyMusicModel
*) this; 
 235             model
->m_classicalMusicIsKnownToControl 
= true; 
 238         MyMusicModelNode 
*first_child 
= node
->GetChildren().Item( 0 ); 
 239         return wxDataViewItem( (void*) first_child
->GetID() ); 
 242     virtual wxDataViewItem 
GetNextSibling( const wxDataViewItem 
&item 
) const 
 244         MyMusicModelNode 
*node 
= FindNode( item 
); 
 245         MyMusicModelNode 
*parent 
= node
->GetParent(); 
 247             return wxDataViewItem(0); 
 249         int pos 
= parent
->GetChildren().Index( node 
); 
 250         if (pos 
== wxNOT_FOUND
) 
 251             return wxDataViewItem(0); 
 253         if (pos 
== parent
->GetChildCount()-1) 
 254             return wxDataViewItem(0); 
 256         node 
= parent
->GetChildren().Item( pos
+1 ); 
 257         return wxDataViewItem( (void*) node
->GetID() ); 
 261     wxUint32 
GetNewId() { m_idCounter
++; return m_idCounter
; } 
 263     MyMusicModelNode 
*FindNodeRec( MyMusicModelNode 
*node
, const wxDataViewItem 
&item 
) const 
 265         if (node
->GetID() == (wxUint32
) item
.GetID()) 
 268         size_t count 
= node
->GetChildCount(); 
 270         for (i 
= 0; i 
< count
; i
++) 
 272             MyMusicModelNode 
*child 
= node
->GetChildren().Item( i 
); 
 273             MyMusicModelNode 
*node2 
= FindNodeRec( child
, item 
); 
 280     MyMusicModelNode 
*FindNode( const wxDataViewItem 
&item 
) const 
 282         if (item
.GetID() == 0) 
 288         return FindNodeRec( m_root
, item 
); 
 291     MyMusicModelNode
*   m_root
; 
 292     MyMusicModelNode
*   m_pop
; 
 293     MyMusicModelNode
*   m_classical
; 
 294     bool                m_classicalMusicIsKnownToControl
; 
 295     wxUint32            m_idCounter
; 
 298 // ------------------------------------- 
 300 // ------------------------------------- 
 302 class MyApp
: public wxApp
 
 309 // ------------------------------------- 
 311 // ------------------------------------- 
 313 class MyFrame 
: public wxFrame
 
 316     MyFrame(wxFrame 
*frame
, wxChar 
*title
, int x
, int y
, int w
, int h
); 
 319     void OnQuit(wxCommandEvent
& event
); 
 320     void OnAbout(wxCommandEvent
& event
); 
 321     void OnAdd(wxCommandEvent
& event
); 
 322     void OnDelete(wxCommandEvent
& event
); 
 325     wxDataViewCtrl
* m_dataview
; 
 327     wxObjectDataPtr
<MyMusicModel
> m_model
; 
 330     DECLARE_EVENT_TABLE() 
 333 // ------------------------------------- 
 335 // ------------------------------------- 
 339 bool MyApp::OnInit(void) 
 341     if ( !wxApp::OnInit() ) 
 344     // build the first frame 
 346         new MyFrame(NULL
, wxT("wxDataViewCtrl feature test"), 10, 10, 700, 440); 
 359 // ------------------------------------- 
 361 // ------------------------------------- 
 366     ID_ABOUT 
= wxID_ABOUT
, 
 373 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
) 
 374     EVT_MENU( ID_ABOUT
, MyFrame::OnAbout 
) 
 375     EVT_MENU( ID_EXIT
, MyFrame::OnQuit 
) 
 376     EVT_BUTTON( ID_ADD
, MyFrame::OnAdd 
) 
 377     EVT_BUTTON( ID_DELETE
, MyFrame::OnDelete 
) 
 380 MyFrame::MyFrame(wxFrame 
*frame
, wxChar 
*title
, int x
, int y
, int w
, int h
): 
 381   wxFrame(frame
, wxID_ANY
, title
, wxPoint(x
, y
), wxSize(w
, h
)) 
 383     SetIcon(wxICON(sample
)); 
 387     wxMenu 
*file_menu 
= new wxMenu
; 
 388     file_menu
->Append(ID_ABOUT
, "&About"); 
 389     file_menu
->AppendSeparator(); 
 390     file_menu
->Append(ID_EXIT
, "E&xit"); 
 392     wxMenuBar 
*menu_bar 
= new wxMenuBar
; 
 393     menu_bar
->Append(file_menu
, "&File"); 
 395     SetMenuBar(menu_bar
); 
 398     wxBoxSizer 
*main_sizer 
= new wxBoxSizer( wxVERTICAL 
); 
 400     m_dataview 
= new wxDataViewCtrl( this, wxID_ANY
, wxDefaultPosition
, 
 403     m_model 
= new MyMusicModel
; 
 404     m_dataview
->AssociateModel( m_model
.get() ); 
 406     m_dataview
->AppendTextColumn( "Title", 0, wxDATAVIEW_CELL_INERT
, 200,  
 407                                      DEFAULT_ALIGN
, wxDATAVIEW_COL_SORTABLE 
); 
 408     m_dataview
->AppendTextColumn( "Artist", 1, wxDATAVIEW_CELL_INERT
, 200, 
 409                                      DEFAULT_ALIGN
, wxDATAVIEW_COL_SORTABLE 
); 
 410     m_dataview
->AppendTextColumn( "Year", 2, wxDATAVIEW_CELL_INERT
, 50, 
 413     main_sizer
->Add( m_dataview
, 2, wxGROW 
); 
 415     wxBoxSizer 
*button_sizer 
= new wxBoxSizer( wxHORIZONTAL 
); 
 417     button_sizer
->Add( new wxButton( this, ID_ADD
, "Add Mozart"), 0, wxALL
, 10 ); 
 418     button_sizer
->Add( new wxButton( this, ID_DELETE
, "Delete selected"), 0, wxALL
, 10 ); 
 420     main_sizer
->Add( button_sizer
, 0, 0, 0 ); 
 422     m_log 
= new wxTextCtrl( this, -1, "", wxDefaultPosition
, wxDefaultSize
, wxTE_MULTILINE 
); 
 424     main_sizer
->Add( m_log
, 1, wxGROW 
); 
 426     SetSizer( main_sizer 
); 
 429 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
) ) 
 434 void MyFrame::OnDelete(wxCommandEvent
& WXUNUSED(event
) ) 
 436     wxDataViewItem item 
= m_dataview
->GetSelection(); 
 438         m_model
->Delete( item 
); 
 441 void MyFrame::OnAdd(wxCommandEvent
& WXUNUSED(event
) ) 
 443     m_model
->AddToClassical( "Kleine Nachtmusik", "Wolfgang Mozart", "1787" ); 
 446 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
) ) 
 448     wxAboutDialogInfo info
; 
 449     info
.SetName(_("DataView sample")); 
 450     info
.SetDescription(_("This sample demonstrates the dataview control handling")); 
 451     info
.SetCopyright(_T("(C) 2007 Robert Roebling"));