1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxDataViewCtrl wxWidgets sample
4 // Author: Robert Roebling
5 // Modified by: Francesco Montorsi, Bo Yang
8 // Copyright: (c) Robert Roebling
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 // For compilers that support precompilation, includes "wx/wx.h".
14 #include "wx/wxprec.h"
24 #include "wx/dataview.h"
27 // ----------------------------------------------------------------------------
29 // ----------------------------------------------------------------------------
34 // ----------------------------------------------------------------------------
36 // ----------------------------------------------------------------------------
38 MyMusicTreeModel::MyMusicTreeModel()
40 m_root
= new MyMusicTreeModelNode( NULL
, wxT("My Music" ));
41 m_pop
= new MyMusicTreeModelNode( m_root
, wxT("Pop music") );
42 m_root
->Append( m_pop
);
43 m_pop
->Append( new MyMusicTreeModelNode( m_pop
,
44 wxT("You are not alone"), wxT("Michael Jackson"), 1995 ) );
45 m_pop
->Append( new MyMusicTreeModelNode( m_pop
,
46 wxT("Take a bow"), wxT("Madonna"), 1994 ) );
47 m_classical
= new MyMusicTreeModelNode( m_root
, wxT("Classical music") );
48 m_root
->Append( m_classical
);
49 m_ninth
= new MyMusicTreeModelNode( m_classical
,
50 wxT("Ninth symphony"), wxT("Ludwig van Beethoven"), 1824 );
51 m_classical
->Append( m_ninth
);
52 m_classical
->Append( new MyMusicTreeModelNode( m_classical
,
53 wxT("German Requiem"), wxT("Johannes Brahms"), 1868 ) );
54 m_classicalMusicIsKnownToControl
= false;
57 wxString
MyMusicTreeModel::GetTitle( const wxDataViewItem
&item
) const
59 MyMusicTreeModelNode
*node
= (MyMusicTreeModelNode
*) item
.GetID();
66 int MyMusicTreeModel::GetYear( const wxDataViewItem
&item
) const
68 MyMusicTreeModelNode
*node
= (MyMusicTreeModelNode
*) item
.GetID();
75 void MyMusicTreeModel::AddToClassical( const wxString
&title
, const wxString
&artist
, int year
)
78 MyMusicTreeModelNode
*child_node
=
79 new MyMusicTreeModelNode( m_classical
, title
, artist
, year
);
81 m_classical
->Append( child_node
);
83 if (m_classicalMusicIsKnownToControl
)
86 wxDataViewItem
child( (void*) child_node
);
87 wxDataViewItem
parent( (void*) m_classical
);
88 ItemAdded( parent
, child
);
92 void MyMusicTreeModel::Delete( const wxDataViewItem
&item
)
94 MyMusicTreeModelNode
*node
= (MyMusicTreeModelNode
*) item
.GetID();
95 wxDataViewItem
parent( node
->GetParent() );
97 node
->GetParent()->GetChildren().Remove( node
);
101 ItemDeleted( parent
, item
);
104 int MyMusicTreeModel::Compare( const wxDataViewItem
&item1
, const wxDataViewItem
&item2
,
105 unsigned int column
, bool ascending
)
107 if (IsContainer(item1
) && IsContainer(item2
))
109 wxVariant value1
,value2
;
110 GetValue( value1
, item1
, 0 );
111 GetValue( value2
, item2
, 0 );
113 wxString str1
= value1
.GetString();
114 wxString str2
= value2
.GetString();
115 int res
= str1
.Cmp( str2
);
118 // items must be different
119 wxUIntPtr litem1
= (wxUIntPtr
) item1
.GetID();
120 wxUIntPtr litem2
= (wxUIntPtr
) item2
.GetID();
122 return litem1
-litem2
;
125 return wxDataViewModel::Compare( item1
, item2
, column
, ascending
);
128 void MyMusicTreeModel::GetValue( wxVariant
&variant
,
129 const wxDataViewItem
&item
, unsigned int col
) const
131 MyMusicTreeModelNode
*node
= (MyMusicTreeModelNode
*) item
.GetID();
134 case 0: variant
= node
->m_title
; break;
135 case 1: variant
= node
->m_artist
; break;
136 case 2: variant
= (long) node
->m_year
; break;
137 case 3: variant
= node
->m_quality
; break;
139 // wxMac doesn't conceal the popularity progress renderer, return 0 for containers
140 if (IsContainer(item
))
143 variant
= (long) 80; // all music is very 80% popular
146 // Make size of red square depend on year
147 if (GetYear(item
) < 1900)
154 wxLogError( wxT("MyMusicTreeModel::GetValue: wrong column %d"), col
);
156 // provoke a crash when mouse button down
157 wxMouseState state
= wxGetMouseState();
158 if (state
.ShiftDown())
167 bool MyMusicTreeModel::SetValue( const wxVariant
&variant
,
168 const wxDataViewItem
&item
, unsigned int col
)
170 MyMusicTreeModelNode
*node
= (MyMusicTreeModelNode
*) item
.GetID();
173 case 0: node
->m_title
= variant
.GetString(); return true;
174 case 1: node
->m_artist
= variant
.GetString(); return true;
175 case 2: node
->m_year
= variant
.GetLong(); return true;
176 case 3: node
->m_quality
= variant
.GetString(); return true;
177 default: wxLogError( wxT("MyMusicTreeModel::SetValue: wrong column") );
182 wxDataViewItem
MyMusicTreeModel::GetParent( const wxDataViewItem
&item
) const
184 // the invisble root node has no parent
186 return wxDataViewItem(0);
188 MyMusicTreeModelNode
*node
= (MyMusicTreeModelNode
*) item
.GetID();
190 // "MyMusic" also has no parent
192 return wxDataViewItem(0);
194 return wxDataViewItem( (void*) node
->GetParent() );
197 bool MyMusicTreeModel::IsContainer( const wxDataViewItem
&item
) const
199 // the invisble root node can have children (in
200 // our model always "MyMusic")
204 MyMusicTreeModelNode
*node
= (MyMusicTreeModelNode
*) item
.GetID();
205 return node
->IsContainer();
208 unsigned int MyMusicTreeModel::GetChildren( const wxDataViewItem
&parent
, wxDataViewItemArray
&array
) const
210 MyMusicTreeModelNode
*node
= (MyMusicTreeModelNode
*) parent
.GetID();
213 array
.Add( wxDataViewItem( (void*) m_root
) );
217 if (node
== m_classical
)
219 MyMusicTreeModel
*model
= (MyMusicTreeModel
*)(const MyMusicTreeModel
*) this;
220 model
->m_classicalMusicIsKnownToControl
= true;
223 if (node
->GetChildCount() == 0)
228 unsigned int count
= node
->GetChildren().GetCount();
230 for (pos
= 0; pos
< count
; pos
++)
232 MyMusicTreeModelNode
*child
= node
->GetChildren().Item( pos
);
233 array
.Add( wxDataViewItem( (void*) child
) );
240 // ----------------------------------------------------------------------------
242 // ----------------------------------------------------------------------------
244 static int my_sort_reverse( int *v1
, int *v2
)
249 static int my_sort( int *v1
, int *v2
)
254 MyListModel::MyListModel() :
256 wxDataViewVirtualListModel( 1000 + 100 )
258 wxDataViewVirtualListModel( 100000 + 100 )
262 m_virtualItems
= 1000;
264 m_virtualItems
= 100000;
268 for (i
= 0; i
< 100; i
++)
271 str
.Printf( wxT("row number %d"), i
);
275 m_icon
= wxIcon( null_xpm
);
278 void MyListModel::Prepend( const wxString
&text
)
280 m_array
.Insert( text
, 0 );
284 void MyListModel::DeleteItem( const wxDataViewItem
&item
)
286 unsigned int row
= GetRow( item
);
287 if (row
>= m_array
.GetCount())
290 m_array
.RemoveAt( row
);
294 void MyListModel::DeleteItems( const wxDataViewItemArray
&items
)
298 for (i
= 0; i
< items
.GetCount(); i
++)
300 unsigned int row
= GetRow( items
[i
] );
301 if (row
< m_array
.GetCount())
305 // Sort in descending order so that the last
306 // row will be deleted first. Otherwise the
307 // remaining indeces would all be wrong.
308 rows
.Sort( my_sort_reverse
);
309 for (i
= 0; i
< rows
.GetCount(); i
++)
310 m_array
.RemoveAt( rows
[i
] );
312 // This is just to test if wxDataViewCtrl can
313 // cope with removing rows not sorted in
315 rows
.Sort( my_sort
);
319 void MyListModel::AddMany()
321 m_virtualItems
+= 1000;
322 Reset( m_array
.GetCount() + m_virtualItems
);
325 void MyListModel::GetValueByRow( wxVariant
&variant
,
326 unsigned int row
, unsigned int col
) const
330 if (row
>= m_array
.GetCount())
333 str
.Printf(wxT("row %d"), row
- m_array
.GetCount() );
338 variant
= m_array
[ row
];
343 wxDataViewIconText
data( wxT("test"), m_icon
);
348 if (row
>= m_array
.GetCount())
349 variant
= wxT("plain");
351 variant
= wxT("blue");
355 bool MyListModel::GetAttrByRow( unsigned int row
, unsigned int col
, wxDataViewItemAttr
&attr
)
360 if (row
< m_array
.GetCount())
362 attr
.SetColour( *wxBLUE
);
363 attr
.SetItalic( true );
369 bool MyListModel::SetValueByRow( const wxVariant
&variant
,
370 unsigned int row
, unsigned int col
)
374 if (row
>= m_array
.GetCount())
377 m_array
[row
] = variant
.GetString();