]> git.saurik.com Git - wxWidgets.git/blame - samples/dataview/mymodels.cpp
some docs enhancements, in particular to wxDataViewListCtrl.
[wxWidgets.git] / samples / dataview / mymodels.cpp
CommitLineData
bf19b714
FM
1/////////////////////////////////////////////////////////////////////////////\r
2// Name: mymodels.cpp\r
3// Purpose: wxDataViewCtrl wxWidgets sample\r
4// Author: Robert Roebling\r
5// Modified by: Francesco Montorsi, Bo Yang\r
6// Created: 06/01/06\r
7// RCS-ID: $Id$\r
8// Copyright: (c) Robert Roebling\r
9// Licence: wxWindows license\r
10/////////////////////////////////////////////////////////////////////////////\r
11\r
12\r
13// For compilers that support precompilation, includes "wx/wx.h".\r
14#include "wx/wxprec.h"\r
15\r
16#ifdef __BORLANDC__\r
17#pragma hdrstop\r
18#endif\r
19\r
20#ifndef WX_PRECOMP\r
21 #include "wx/wx.h"\r
22#endif\r
23\r
24#include "wx/dataview.h"\r
25#include "mymodels.h"\r
26\r
27// ----------------------------------------------------------------------------\r
28// resources\r
29// ----------------------------------------------------------------------------\r
30\r
31#include "null.xpm"\r
32\r
33\r
34// ----------------------------------------------------------------------------\r
35// MyMusicTreeModel\r
36// ----------------------------------------------------------------------------\r
37\r
38MyMusicTreeModel::MyMusicTreeModel()\r
39{\r
40 m_root = new MyMusicTreeModelNode( NULL, wxT("My Music" ));\r
41 m_pop = new MyMusicTreeModelNode( m_root, wxT("Pop music") );\r
42 m_root->Append( m_pop );\r
43 m_pop->Append( new MyMusicTreeModelNode( m_pop,\r
44 wxT("You are not alone"), wxT("Michael Jackson"), 1995 ) );\r
45 m_pop->Append( new MyMusicTreeModelNode( m_pop,\r
46 wxT("Take a bow"), wxT("Madonna"), 1994 ) );\r
47 m_classical = new MyMusicTreeModelNode( m_root, wxT("Classical music") );\r
48 m_root->Append( m_classical );\r
49 m_ninth = new MyMusicTreeModelNode( m_classical,\r
50 wxT("Ninth symphony"), wxT("Ludwig van Beethoven"), 1824 );\r
51 m_classical->Append( m_ninth );\r
52 m_classical->Append( new MyMusicTreeModelNode( m_classical,\r
53 wxT("German Requiem"), wxT("Johannes Brahms"), 1868 ) );\r
54 m_classicalMusicIsKnownToControl = false;\r
55}\r
56\r
57wxString MyMusicTreeModel::GetTitle( const wxDataViewItem &item ) const\r
58{\r
59 MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();\r
60 if (!node)\r
61 return wxEmptyString;\r
62\r
63 return node->m_title;\r
64}\r
65\r
66int MyMusicTreeModel::GetYear( const wxDataViewItem &item ) const\r
67{\r
68 MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();\r
69 if (!node)\r
70 return 2000;\r
71\r
72 return node->m_year;\r
73}\r
74\r
75void MyMusicTreeModel::AddToClassical( const wxString &title, const wxString &artist, int year )\r
76{\r
77 // add to data\r
78 MyMusicTreeModelNode *child_node =\r
79 new MyMusicTreeModelNode( m_classical, title, artist, year );\r
80\r
81 m_classical->Append( child_node );\r
82\r
83 if (m_classicalMusicIsKnownToControl)\r
84 {\r
85 // notify control\r
86 wxDataViewItem child( (void*) child_node );\r
87 wxDataViewItem parent( (void*) m_classical );\r
88 ItemAdded( parent, child );\r
89 }\r
90}\r
91\r
92void MyMusicTreeModel::Delete( const wxDataViewItem &item )\r
93{\r
94 MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();\r
95 wxDataViewItem parent( node->GetParent() );\r
96\r
97 node->GetParent()->GetChildren().Remove( node );\r
98 delete node;\r
99\r
100 // notify control\r
101 ItemDeleted( parent, item );\r
102}\r
103\r
104int MyMusicTreeModel::Compare( const wxDataViewItem &item1, const wxDataViewItem &item2,\r
105 unsigned int column, bool ascending )\r
106{\r
107 if (IsContainer(item1) && IsContainer(item2))\r
108 {\r
109 wxVariant value1,value2;\r
110 GetValue( value1, item1, 0 );\r
111 GetValue( value2, item2, 0 );\r
112\r
113 wxString str1 = value1.GetString();\r
114 wxString str2 = value2.GetString();\r
115 int res = str1.Cmp( str2 );\r
116 if (res) return res;\r
117\r
118 // items must be different\r
119 wxUIntPtr litem1 = (wxUIntPtr) item1.GetID();\r
120 wxUIntPtr litem2 = (wxUIntPtr) item2.GetID();\r
121\r
122 return litem1-litem2;\r
123 }\r
124\r
125 return wxDataViewModel::Compare( item1, item2, column, ascending );\r
126}\r
127\r
128void MyMusicTreeModel::GetValue( wxVariant &variant,\r
129 const wxDataViewItem &item, unsigned int col ) const\r
130{\r
131 MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();\r
132 switch (col)\r
133 {\r
134 case 0: variant = node->m_title; break;\r
135 case 1: variant = node->m_artist; break;\r
136 case 2: variant = (long) node->m_year; break;\r
137 case 3: variant = node->m_quality; break;\r
138 case 4:\r
139 // wxMac doesn't conceal the popularity progress renderer, return 0 for containers\r
140 if (IsContainer(item))\r
141 variant = (long) 0;\r
142 else\r
143 variant = (long) 80; // all music is very 80% popular\r
144 break;\r
145 case 5:\r
146 // Make size of red square depend on year\r
147 if (GetYear(item) < 1900)\r
148 variant = (long) 35;\r
149 else\r
150 variant = (long) 25;\r
151 break;\r
152 default:\r
153 {\r
154 wxLogError( wxT("MyMusicTreeModel::GetValue: wrong column %d"), col );\r
155\r
156 // provoke a crash when mouse button down\r
157 wxMouseState state = wxGetMouseState();\r
158 if (state.ShiftDown())\r
159 {\r
160 char *crash = 0;\r
161 *crash = 0;\r
162 }\r
163 }\r
164 }\r
165}\r
166\r
167bool MyMusicTreeModel::SetValue( const wxVariant &variant,\r
168 const wxDataViewItem &item, unsigned int col )\r
169{\r
170 MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();\r
171 switch (col)\r
172 {\r
173 case 0: node->m_title = variant.GetString(); return true;\r
174 case 1: node->m_artist = variant.GetString(); return true;\r
175 case 2: node->m_year = variant.GetLong(); return true;\r
176 case 3: node->m_quality = variant.GetString(); return true;\r
177 default: wxLogError( wxT("MyMusicTreeModel::SetValue: wrong column") );\r
178 }\r
179 return false;\r
180}\r
181\r
182wxDataViewItem MyMusicTreeModel::GetParent( const wxDataViewItem &item ) const\r
183{\r
184 // the invisble root node has no parent\r
185 if (!item.IsOk())\r
186 return wxDataViewItem(0);\r
187\r
188 MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();\r
189\r
190 // "MyMusic" also has no parent\r
191 if (node == m_root)\r
192 return wxDataViewItem(0);\r
193\r
194 return wxDataViewItem( (void*) node->GetParent() );\r
195}\r
196\r
197bool MyMusicTreeModel::IsContainer( const wxDataViewItem &item ) const\r
198{\r
199 // the invisble root node can have children (in\r
200 // our model always "MyMusic")\r
201 if (!item.IsOk())\r
202 return true;\r
203\r
204 MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();\r
205 return node->IsContainer();\r
206}\r
207\r
208unsigned int MyMusicTreeModel::GetChildren( const wxDataViewItem &parent, wxDataViewItemArray &array ) const\r
209{\r
210 MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) parent.GetID();\r
211 if (!node)\r
212 {\r
213 array.Add( wxDataViewItem( (void*) m_root ) );\r
214 return 1;\r
215 }\r
216\r
217 if (node == m_classical)\r
218 {\r
219 MyMusicTreeModel *model = (MyMusicTreeModel*)(const MyMusicTreeModel*) this;\r
220 model->m_classicalMusicIsKnownToControl = true;\r
221 }\r
222\r
223 if (node->GetChildCount() == 0)\r
224 {\r
225 return 0;\r
226 }\r
227\r
228 unsigned int count = node->GetChildren().GetCount();\r
229 unsigned int pos;\r
230 for (pos = 0; pos < count; pos++)\r
231 {\r
232 MyMusicTreeModelNode *child = node->GetChildren().Item( pos );\r
233 array.Add( wxDataViewItem( (void*) child ) );\r
234 }\r
235 return count;\r
236}\r
237\r
238\r
239\r
240// ----------------------------------------------------------------------------\r
241// MyListModel\r
242// ----------------------------------------------------------------------------\r
243\r
244static int my_sort_reverse( int *v1, int *v2 )\r
245{\r
246 return *v2-*v1;\r
247}\r
248\r
249static int my_sort( int *v1, int *v2 )\r
250{\r
251 return *v1-*v2;\r
252}\r
253\r
254MyListModel::MyListModel() :\r
255#ifdef __WXMAC__\r
256 wxDataViewVirtualListModel( 1000 + 100 )\r
257#else\r
258 wxDataViewVirtualListModel( 100000 + 100 )\r
259#endif\r
260{\r
261#ifdef __WXMAC__\r
262 m_virtualItems = 1000;\r
263#else\r
264 m_virtualItems = 100000;\r
265#endif\r
266\r
267 unsigned int i;\r
268 for (i = 0; i < 100; i++)\r
269 {\r
270 wxString str;\r
271 str.Printf( wxT("row number %d"), i );\r
272 m_array.Add( str );\r
273 }\r
274\r
275 m_icon = wxIcon( null_xpm );\r
276}\r
277\r
278void MyListModel::Prepend( const wxString &text )\r
279{\r
280 m_array.Insert( text, 0 );\r
281 RowPrepended();\r
282}\r
283\r
284void MyListModel::DeleteItem( const wxDataViewItem &item )\r
285{\r
286 unsigned int row = GetRow( item );\r
287 if (row >= m_array.GetCount())\r
288 return;\r
289\r
290 m_array.RemoveAt( row );\r
291 RowDeleted( row );\r
292}\r
293\r
294void MyListModel::DeleteItems( const wxDataViewItemArray &items )\r
295{\r
296 wxArrayInt rows;\r
297 unsigned int i;\r
298 for (i = 0; i < items.GetCount(); i++)\r
299 {\r
300 unsigned int row = GetRow( items[i] );\r
301 if (row < m_array.GetCount())\r
302 rows.Add( row );\r
303 }\r
304\r
305 // Sort in descending order so that the last\r
306 // row will be deleted first. Otherwise the\r
307 // remaining indeces would all be wrong.\r
308 rows.Sort( my_sort_reverse );\r
309 for (i = 0; i < rows.GetCount(); i++)\r
310 m_array.RemoveAt( rows[i] );\r
311\r
312 // This is just to test if wxDataViewCtrl can\r
313 // cope with removing rows not sorted in\r
314 // descending order\r
315 rows.Sort( my_sort );\r
316 RowsDeleted( rows );\r
317}\r
318\r
319void MyListModel::AddMany()\r
320{\r
321 m_virtualItems += 1000;\r
322 Reset( m_array.GetCount() + m_virtualItems );\r
323}\r
324\r
325void MyListModel::GetValueByRow( wxVariant &variant,\r
326 unsigned int row, unsigned int col ) const\r
327{\r
328 if (col==0)\r
329 {\r
330 if (row >= m_array.GetCount())\r
331 {\r
332 wxString str;\r
333 str.Printf(wxT("row %d"), row - m_array.GetCount() );\r
334 variant = str;\r
335 }\r
336 else\r
337 {\r
338 variant = m_array[ row ];\r
339 }\r
340 } else\r
341 if (col==1)\r
342 {\r
343 wxDataViewIconText data( wxT("test"), m_icon );\r
344 variant << data;\r
345 } else\r
346 if (col==2)\r
347 {\r
348 if (row >= m_array.GetCount())\r
349 variant = wxT("plain");\r
350 else\r
351 variant = wxT("blue");\r
352 }\r
353}\r
354\r
355bool MyListModel::GetAttrByRow( unsigned int row, unsigned int col, wxDataViewItemAttr &attr )\r
356{\r
357 if (col != 2)\r
358 return false;\r
359\r
360 if (row < m_array.GetCount())\r
361 {\r
362 attr.SetColour( *wxBLUE );\r
363 attr.SetItalic( true );\r
364 }\r
365\r
366 return true;\r
367}\r
368\r
369bool MyListModel::SetValueByRow( const wxVariant &variant,\r
370 unsigned int row, unsigned int col )\r
371{\r
372 if (col == 0)\r
373 {\r
374 if (row >= m_array.GetCount())\r
375 return false;\r
376\r
377 m_array[row] = variant.GetString();\r
378 return true;\r
379 }\r
380\r
381 return false;\r
382}\r