]> git.saurik.com Git - wxWidgets.git/blob - samples/dataview/dataview.cpp
69ff26d5069528377eb9233c0bda3cebec8f84f0
[wxWidgets.git] / samples / dataview / dataview.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: dataview.cpp
3 // Purpose: wxDataViewCtrl wxWidgets sample
4 // Author: Robert Roebling
5 // Modified by: Francesco Montorsi
6 // Created: 06/01/06
7 // RCS-ID: $Id$
8 // Copyright: (c) Robert Roebling
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #ifndef WX_PRECOMP
20 #include "wx/wx.h"
21 #endif
22
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"
30
31 #ifndef __WXMSW__
32 #include "../sample.xpm"
33 #endif
34
35 #include "null.xpm"
36
37
38 #define DEFAULT_ALIGN wxALIGN_LEFT
39 #define DATAVIEW_DEFAULT_STYLE (wxDV_MULTIPLE|wxDV_HORIZ_RULES|wxDV_VERT_RULES)
40
41
42
43 // -------------------------------------
44 // MyMusicModel
45 // -------------------------------------
46
47 /*
48 Implement this data model
49 Title Artist Year
50 -------------------------------------------------------------
51 1: My Music:
52 2: Pop music
53 3: You are not alone Michael Jackson 1995
54 4: Take a bow Madonna 1994
55 5: Classical music
56 6: Ninth Symphony Ludwig v. Beethoven 1824
57 7: German Requiem Johannes Brahms 1868
58 */
59
60
61
62 class MyMusicModelNode;
63 WX_DEFINE_ARRAY_PTR( MyMusicModelNode*, MyMusicModelNodes );
64
65 class MyMusicModelNode
66 {
67 public:
68 MyMusicModelNode( MyMusicModelNode* parent,
69 const wxString &title, const wxString &artist, const wxString &year )
70 {
71 m_parent = parent;
72 m_title = title;
73 m_artist = artist;
74 m_year = year;
75 m_isContainer = false;
76 }
77
78 MyMusicModelNode( MyMusicModelNode* parent,
79 const wxString &branch )
80 {
81 m_parent = parent;
82 m_title = branch;
83 m_isContainer = true;
84 }
85
86 ~MyMusicModelNode()
87 {
88 size_t count = m_children.GetCount();
89 size_t i;
90 for (i = 0; i < count; i++)
91 {
92 MyMusicModelNode *child = m_children[i];
93 delete child;
94 }
95 }
96
97 bool IsContainer() { return m_isContainer; }
98
99 MyMusicModelNode* GetParent() { return m_parent; }
100 MyMusicModelNodes &GetChildren() { return m_children; }
101 MyMusicModelNode* GetNthChild( unsigned int n ) { return m_children.Item( n ); }
102 void Insert( MyMusicModelNode* child, unsigned int n) { m_children.Insert( child, n); }
103 void Append( MyMusicModelNode* child ) { m_children.Add( child ); }
104 unsigned int GetChildCount() { return m_children.GetCount(); }
105
106 public:
107 wxString m_title;
108 wxString m_artist;
109 wxString m_year;
110
111 private:
112 MyMusicModelNode *m_parent;
113 MyMusicModelNodes m_children;
114 bool m_isContainer;
115 };
116
117
118 class MyMusicModel: public wxDataViewModel
119 {
120 public:
121
122 // constructor
123
124 MyMusicModel()
125 {
126 m_root = new MyMusicModelNode( NULL, "My Music" );
127 m_pop = new MyMusicModelNode( m_root, "Pop music" );
128 m_root->Append( m_pop );
129 m_pop->Append( new MyMusicModelNode( m_pop,
130 "You are not alone", "Michael Jackson", "1995" ) );
131 m_pop->Append( new MyMusicModelNode( m_pop,
132 "Take a bow", "Madonna", "1994" ) );
133 m_classical = new MyMusicModelNode( m_root, "Classical music" );
134 m_root->Append( m_classical );
135 m_classical->Append( new MyMusicModelNode( m_classical,
136 "Ninth symphony", "Ludwig van Beethoven", "1824" ) );
137 m_classical->Append( new MyMusicModelNode( m_classical,
138 "German Requiem", "Johannes Brahms", "1868" ) );
139 m_classicalMusicIsKnownToControl = false;
140 }
141
142 // helper methods to change the model
143
144 void AddToClassical( const wxString &title, const wxString &artist, const wxString &year )
145 {
146 // add to data
147 MyMusicModelNode *child_node =
148 new MyMusicModelNode( m_classical, title, artist, year );
149 m_classical->Append( child_node );
150
151 if (m_classicalMusicIsKnownToControl)
152 {
153 // notify control
154 wxDataViewItem child( (void*) child_node );
155 wxDataViewItem parent( (void*) m_classical );
156 ItemAdded( parent, child );
157 }
158 }
159
160 void Delete( const wxDataViewItem &item )
161 {
162 MyMusicModelNode *node = (MyMusicModelNode*) item.GetID();
163 node->GetParent()->GetChildren().Remove( node );
164 delete node;
165
166 // notify control
167 ItemDeleted( item );
168 }
169
170 // implementation of base class virtuals to define model
171
172 virtual unsigned int GetColumnCount() const
173 {
174 return 3;
175 }
176
177 virtual wxString GetColumnType( unsigned int col ) const
178 {
179 return "string";
180 }
181
182 virtual void GetValue( wxVariant &variant,
183 const wxDataViewItem &item, unsigned int col ) const
184 {
185 MyMusicModelNode *node = (MyMusicModelNode*) item.GetID();
186 switch (col)
187 {
188 case 0: variant = node->m_title; break;
189 case 1: variant = node->m_artist; break;
190 case 2: variant = node->m_year; break;
191 default: wxLogError( "MyMusicModel::GetValue: wrong column" );
192 }
193 }
194
195 virtual bool SetValue( const wxVariant &variant,
196 const wxDataViewItem &item, unsigned int col )
197 {
198 MyMusicModelNode *node = (MyMusicModelNode*) item.GetID();
199 switch (col)
200 {
201 case 0: node->m_title = variant.GetString(); break;
202 case 1: node->m_artist = variant.GetString(); break;
203 case 2: node->m_year = variant.GetString(); break;
204 default: wxLogError( "MyMusicModel::SetValue: wrong column" );
205 }
206 }
207
208 virtual bool HasChildren( const wxDataViewItem &item ) const
209 {
210 MyMusicModelNode *node = (MyMusicModelNode*) item.GetID();
211 if (!node)
212 return true;
213
214 return node->IsContainer();
215 }
216
217 virtual wxDataViewItem GetFirstChild( const wxDataViewItem &parent ) const
218 {
219 MyMusicModelNode *node = (MyMusicModelNode*) parent.GetID();
220 if (!node)
221 return wxDataViewItem( (void*) m_root );
222
223 if (node->GetChildCount() == 0)
224 return wxDataViewItem( 0 );
225
226 if (node == m_classical)
227 {
228 MyMusicModel *model = (MyMusicModel*)(const MyMusicModel*) this;
229 model->m_classicalMusicIsKnownToControl = true;
230 }
231
232 MyMusicModelNode *first_child = node->GetChildren().Item( 0 );
233 return wxDataViewItem( (void*) first_child );
234 }
235
236 virtual wxDataViewItem GetNextSibling( const wxDataViewItem &item ) const
237 {
238 MyMusicModelNode *node = (MyMusicModelNode*) item.GetID();
239 MyMusicModelNode *parent = node->GetParent();
240 if (!parent)
241 return wxDataViewItem(0);
242
243 int pos = parent->GetChildren().Index( node );
244 if (pos == wxNOT_FOUND)
245 return wxDataViewItem(0);
246
247 if (pos == parent->GetChildCount()-1)
248 return wxDataViewItem(0);
249
250 node = parent->GetChildren().Item( pos+1 );
251 return wxDataViewItem( (void*) node );
252 }
253
254 private:
255 MyMusicModelNode* m_root;
256 MyMusicModelNode* m_pop;
257 MyMusicModelNode* m_classical;
258 bool m_classicalMusicIsKnownToControl;
259 };
260
261 // -------------------------------------
262 // MyApp
263 // -------------------------------------
264
265 class MyApp: public wxApp
266 {
267 public:
268 bool OnInit(void);
269 int OnExit();
270 };
271
272 // -------------------------------------
273 // MyFrame
274 // -------------------------------------
275
276 class MyFrame : public wxFrame
277 {
278 public:
279 MyFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h);
280
281 public:
282 void OnQuit(wxCommandEvent& event);
283 void OnAbout(wxCommandEvent& event);
284 void OnAdd(wxCommandEvent& event);
285 void OnDelete(wxCommandEvent& event);
286
287 private:
288 wxDataViewCtrl* m_dataview;
289 wxTextCtrl * m_log;
290 wxObjectDataPtr<MyMusicModel> m_model;
291
292 private:
293 DECLARE_EVENT_TABLE()
294 };
295
296 // -------------------------------------
297 // MyApp
298 // -------------------------------------
299
300 IMPLEMENT_APP(MyApp)
301
302 bool MyApp::OnInit(void)
303 {
304 if ( !wxApp::OnInit() )
305 return false;
306
307 // build the first frame
308 MyFrame *frame =
309 new MyFrame(NULL, wxT("wxDataViewCtrl feature test"), 10, 10, 700, 440);
310 frame->Show(true);
311
312 SetTopWindow(frame);
313 return true;
314 }
315
316 int MyApp::OnExit()
317 {
318 return 0;
319 }
320
321
322 // -------------------------------------
323 // MyFrame
324 // -------------------------------------
325
326 enum
327 {
328 // file menu
329 ID_ABOUT = wxID_ABOUT,
330 ID_EXIT = wxID_EXIT,
331
332 ID_ADD = 100,
333 ID_DELETE = 101,
334 };
335
336 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
337 EVT_MENU( ID_ABOUT, MyFrame::OnAbout )
338 EVT_MENU( ID_EXIT, MyFrame::OnQuit )
339 EVT_BUTTON( ID_ADD, MyFrame::OnAdd )
340 EVT_BUTTON( ID_DELETE, MyFrame::OnDelete )
341 END_EVENT_TABLE()
342
343 MyFrame::MyFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h):
344 wxFrame(frame, wxID_ANY, title, wxPoint(x, y), wxSize(w, h))
345 {
346 SetIcon(wxICON(sample));
347
348 // build the menus:
349
350 wxMenu *file_menu = new wxMenu;
351 file_menu->Append(ID_ABOUT, "&About");
352 file_menu->AppendSeparator();
353 file_menu->Append(ID_EXIT, "E&xit");
354
355 wxMenuBar *menu_bar = new wxMenuBar;
356 menu_bar->Append(file_menu, "&File");
357
358 SetMenuBar(menu_bar);
359 CreateStatusBar();
360
361 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
362
363 m_dataview = new wxDataViewCtrl( this, wxID_ANY, wxDefaultPosition,
364 wxDefaultSize );
365
366 m_model = new MyMusicModel;
367 m_dataview->AssociateModel( m_model.get() );
368
369 m_dataview->AppendTextColumn( "Title", 0, wxDATAVIEW_CELL_INERT, 200,
370 DEFAULT_ALIGN, wxDATAVIEW_COL_SORTABLE );
371 m_dataview->AppendTextColumn( "Artist", 1, wxDATAVIEW_CELL_INERT, 200,
372 DEFAULT_ALIGN, wxDATAVIEW_COL_SORTABLE );
373 m_dataview->AppendTextColumn( "Year", 2, wxDATAVIEW_CELL_INERT, 50,
374 DEFAULT_ALIGN );
375
376 main_sizer->Add( m_dataview, 2, wxGROW );
377
378 wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
379
380 button_sizer->Add( new wxButton( this, ID_ADD, "Add Mozart"), 0, wxALL, 10 );
381 button_sizer->Add( new wxButton( this, ID_DELETE, "Delete selected"), 0, wxALL, 10 );
382
383 main_sizer->Add( button_sizer, 0, 0, 0 );
384
385 m_log = new wxTextCtrl( this, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
386
387 main_sizer->Add( m_log, 1, wxGROW );
388
389 SetSizer( main_sizer );
390 }
391
392 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
393 {
394 Close(true);
395 }
396
397 void MyFrame::OnDelete(wxCommandEvent& WXUNUSED(event) )
398 {
399 wxDataViewItem item = m_dataview->GetSelection();
400 if (item.IsOk())
401 m_model->Delete( item );
402 }
403
404 void MyFrame::OnAdd(wxCommandEvent& WXUNUSED(event) )
405 {
406 m_model->AddToClassical( "Kleine Nachtmusik", "Wolfgang Mozart", "1787" );
407 }
408
409 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
410 {
411 wxAboutDialogInfo info;
412 info.SetName(_("DataView sample"));
413 info.SetDescription(_("This sample demonstrates the dataview control handling"));
414 info.SetCopyright(_T("(C) 2007 Robert Roebling"));
415
416 wxAboutBox(info);
417 }
418