]> git.saurik.com Git - wxWidgets.git/blob - samples/dataview/dataview.cpp
2b013e6d9a45cf1b8b65779c3a10abf54a060ef2
[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, const wxUint32 id,
69 const wxString &title, const wxString &artist, const wxString &year )
70 {
71 m_parent = parent;
72 m_id = id;
73 m_title = title;
74 m_artist = artist;
75 m_year = year;
76 m_isContainer = false;
77 }
78
79 MyMusicModelNode( MyMusicModelNode* parent, const wxUint32 id,
80 const wxString &branch )
81 {
82 m_parent = parent;
83 m_id = id;
84 m_title = branch;
85 m_isContainer = true;
86 }
87
88 ~MyMusicModelNode()
89 {
90 size_t count = m_children.GetCount();
91 size_t i;
92 for (i = 0; i < count; i++)
93 {
94 MyMusicModelNode *child = m_children[i];
95 delete child;
96 }
97 }
98
99 wxUint32 GetID() { return m_id; }
100 bool IsContainer() { return m_isContainer; }
101
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(); }
108
109 public:
110 wxString m_title;
111 wxString m_artist;
112 wxString m_year;
113
114 private:
115 MyMusicModelNode *m_parent;
116 MyMusicModelNodes m_children;
117 wxUint32 m_id;
118 bool m_isContainer;
119 };
120
121
122 class MyMusicModel: public wxDataViewModel
123 {
124 public:
125 MyMusicModel()
126 {
127 m_idCounter = 0;
128 m_root = new MyMusicModelNode( NULL, GetNewId(), "My Music" );
129 m_pop = new MyMusicModelNode( m_root, GetNewId(), "Pop music" );
130 m_root->Append( m_pop );
131 m_pop->Append( new MyMusicModelNode( m_pop, GetNewId(),
132 "You are not alone", "Michael Jackson", "1995" ) );
133 m_pop->Append( new MyMusicModelNode( m_pop, GetNewId(),
134 "Take a bow", "Madonna", "1994" ) );
135 m_classical = new MyMusicModelNode( m_root, GetNewId(), "Classical music" );
136 m_root->Append( m_classical );
137 m_classical->Append( new MyMusicModelNode( m_classical, GetNewId(),
138 "Ninth symphony", "Ludwig van Beethoven", "1824" ) );
139 m_classical->Append( new MyMusicModelNode( m_classical, GetNewId(),
140 "German Requiem", "Johannes Brahms", "1868" ) );
141 m_classicalMusicIsKnownToControl = false;
142 }
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, GetNewId(), title, artist, year );
149 m_classical->Append( child_node );
150
151 if (m_classicalMusicIsKnownToControl)
152 {
153 // notify control
154 wxDataViewItem child( child_node->GetID() );
155 wxDataViewItem parent( m_classical->GetID() );
156 ItemAdded( parent, child );
157 }
158 }
159
160 virtual unsigned int GetColumnCount() const
161 {
162 return 3;
163 }
164
165 virtual wxString GetColumnType( unsigned int col ) const
166 {
167 return "string";
168 }
169
170 virtual void GetValue( wxVariant &variant,
171 const wxDataViewItem &item, unsigned int col ) const
172 {
173 MyMusicModelNode *node = FindNode( item );
174 switch (col)
175 {
176 case 0: variant = node->m_title; break;
177 case 1: variant = node->m_artist; break;
178 case 2: variant = node->m_year; break;
179 default: wxLogError( "MyMusicModel::GetValue: wrong column" );
180 }
181 }
182
183 virtual bool SetValue( const wxVariant &variant,
184 const wxDataViewItem &item, unsigned int col )
185 {
186 MyMusicModelNode *node = FindNode( item );
187 switch (col)
188 {
189 case 0: node->m_title = variant.GetString(); break;
190 case 1: node->m_artist = variant.GetString(); break;
191 case 2: node->m_year = variant.GetString(); break;
192 default: wxLogError( "MyMusicModel::SetValue: wrong column" );
193 }
194 }
195
196 virtual bool HasChildren( const wxDataViewItem &item ) const
197 {
198 if (item.GetID() == 0)
199 return true;
200
201 MyMusicModelNode *node = FindNode( item );
202 return node->IsContainer();
203 }
204
205 virtual wxDataViewItem GetFirstChild( const wxDataViewItem &parent ) const
206 {
207 if (parent.GetID() == 0)
208 return wxDataViewItem( m_root->GetID() );
209
210 MyMusicModelNode *node = FindNode( parent );
211
212 if (node->GetChildCount() == 0)
213 return wxDataViewItem( 0 );
214
215 if (node == m_classical)
216 {
217 MyMusicModel *model = (MyMusicModel*)(const MyMusicModel*) this;
218 model->m_classicalMusicIsKnownToControl = true;
219 }
220
221 MyMusicModelNode *first_child = node->GetChildren().Item( 0 );
222 return wxDataViewItem( first_child->GetID() );
223 }
224
225 virtual wxDataViewItem GetNextSibling( const wxDataViewItem &item ) const
226 {
227 MyMusicModelNode *node = FindNode( item );
228 MyMusicModelNode *parent = node->GetParent();
229 if (!parent)
230 return wxDataViewItem(0);
231
232 int pos = parent->GetChildren().Index( node );
233 if (pos == wxNOT_FOUND)
234 return wxDataViewItem(0);
235
236 if (pos == parent->GetChildCount()-1)
237 return wxDataViewItem(0);
238
239 node = parent->GetChildren().Item( pos+1 );
240 return wxDataViewItem( node->GetID() );
241 }
242
243 private:
244 wxUint32 GetNewId() { m_idCounter++; return m_idCounter; }
245
246 MyMusicModelNode *FindNodeRec( MyMusicModelNode *node, const wxDataViewItem &item ) const
247 {
248 if (node->GetID() == item.GetID())
249 return node;
250
251 size_t count = node->GetChildCount();
252 size_t i;
253 for (i = 0; i < count; i++)
254 {
255 MyMusicModelNode *child = node->GetChildren().Item( i );
256 MyMusicModelNode *node2 = FindNodeRec( child, item );
257 if (node2)
258 return node2;
259 }
260 return NULL;
261 }
262
263 MyMusicModelNode *FindNode( const wxDataViewItem &item ) const
264 {
265 if (item.GetID() == 0)
266 return NULL;
267
268 if (!m_root)
269 return NULL;
270
271 return FindNodeRec( m_root, item );
272 }
273
274 MyMusicModelNode* m_root;
275 MyMusicModelNode* m_pop;
276 MyMusicModelNode* m_classical;
277 bool m_classicalMusicIsKnownToControl;
278 wxUint32 m_idCounter;
279 };
280
281 // -------------------------------------
282 // MyApp
283 // -------------------------------------
284
285 class MyApp: public wxApp
286 {
287 public:
288 bool OnInit(void);
289 int OnExit();
290 };
291
292 // -------------------------------------
293 // MyFrame
294 // -------------------------------------
295
296 class MyFrame : public wxFrame
297 {
298 public:
299 MyFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h);
300
301 public:
302 void OnQuit(wxCommandEvent& event);
303 void OnAbout(wxCommandEvent& event);
304 void OnAdd(wxCommandEvent& event);
305
306 private:
307 wxDataViewCtrl* m_dataview;
308 wxTextCtrl * m_log;
309 wxObjectDataPtr<MyMusicModel> m_model;
310
311 private:
312 DECLARE_EVENT_TABLE()
313 };
314
315 // -------------------------------------
316 // MyApp
317 // -------------------------------------
318
319 IMPLEMENT_APP(MyApp)
320
321 bool MyApp::OnInit(void)
322 {
323 if ( !wxApp::OnInit() )
324 return false;
325
326 // build the first frame
327 MyFrame *frame =
328 new MyFrame(NULL, wxT("wxDataViewCtrl feature test"), 10, 10, 700, 440);
329 frame->Show(true);
330
331 SetTopWindow(frame);
332 return true;
333 }
334
335 int MyApp::OnExit()
336 {
337 return 0;
338 }
339
340
341 // -------------------------------------
342 // MyFrame
343 // -------------------------------------
344
345 enum
346 {
347 // file menu
348 ID_ABOUT = wxID_ABOUT,
349 ID_EXIT = wxID_EXIT,
350
351 ID_ADD = 100,
352 };
353
354 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
355 EVT_MENU( ID_ABOUT, MyFrame::OnAbout )
356 EVT_MENU( ID_EXIT, MyFrame::OnQuit )
357 EVT_BUTTON( ID_ADD, MyFrame::OnAdd )
358 END_EVENT_TABLE()
359
360 MyFrame::MyFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h):
361 wxFrame(frame, wxID_ANY, title, wxPoint(x, y), wxSize(w, h))
362 {
363 SetIcon(wxICON(sample));
364
365 // build the menus:
366
367 wxMenu *file_menu = new wxMenu;
368 file_menu->Append(ID_ABOUT, "&About");
369 file_menu->AppendSeparator();
370 file_menu->Append(ID_EXIT, "E&xit");
371
372 wxMenuBar *menu_bar = new wxMenuBar;
373 menu_bar->Append(file_menu, "&File");
374
375 SetMenuBar(menu_bar);
376 CreateStatusBar();
377
378 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
379
380 m_dataview = new wxDataViewCtrl( this, wxID_ANY, wxDefaultPosition,
381 wxDefaultSize );
382
383 m_model = new MyMusicModel;
384 m_dataview->AssociateModel( m_model.get() );
385
386 m_dataview->AppendTextColumn( "Title", 0, wxDATAVIEW_CELL_INERT, 200,
387 DEFAULT_ALIGN, wxDATAVIEW_COL_SORTABLE );
388 m_dataview->AppendTextColumn( "Artist", 1, wxDATAVIEW_CELL_INERT, 200,
389 DEFAULT_ALIGN, wxDATAVIEW_COL_SORTABLE );
390 m_dataview->AppendTextColumn( "Year", 2, wxDATAVIEW_CELL_INERT, 50,
391 DEFAULT_ALIGN );
392
393 main_sizer->Add( m_dataview, 2, wxGROW );
394
395 wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
396
397 button_sizer->Add( new wxButton( this, ID_ADD, "Add Mozart"), 0, wxALL, 10 );
398
399 main_sizer->Add( button_sizer, 0, 0, 0 );
400
401 m_log = new wxTextCtrl( this, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
402
403 main_sizer->Add( m_log, 1, wxGROW );
404
405 SetSizer( main_sizer );
406 }
407
408 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
409 {
410 Close(true);
411 }
412
413 void MyFrame::OnAdd(wxCommandEvent& WXUNUSED(event) )
414 {
415 #if 0
416 // ignore selection, do something better later
417 wxDataViewItem item = m_dataview->GetSelection();
418 if (item.IsOk())
419 {
420 if (m_model->HasChildren(item))
421 {
422 }
423 else
424 {
425 }
426 }
427 #endif
428
429 m_model->AddToClassical( "Kleine Nachtmusik", "Wolfgang Mozart", "1787" );
430 }
431
432 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
433 {
434 wxAboutDialogInfo info;
435 info.SetName(_("DataView sample"));
436 info.SetDescription(_("This sample demonstrates the dataview control handling"));
437 info.SetCopyright(_T("(C) 2007 Robert Roebling"));
438
439 wxAboutBox(info);
440 }
441