]> git.saurik.com Git - wxWidgets.git/blob - src/common/datavcmn.cpp
cleanup copy-and-paste
[wxWidgets.git] / src / common / datavcmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/datavcmn.cpp
3 // Purpose: wxDataViewCtrl base classes and common parts
4 // Author: Robert Roebling
5 // Created: 2006/02/20
6 // RCS-ID: $Id$
7 // Copyright: (c) 2006, Robert Roebling
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17
18 #if wxUSE_DATAVIEWCTRL
19
20 #include "wx/dataview.h"
21
22 #include "wx/spinctrl.h"
23
24 #ifndef WX_PRECOMP
25 #include "wx/dc.h"
26 #include "wx/settings.h"
27 #include "wx/log.h"
28 #include "wx/icon.h"
29 #include "wx/crt.h"
30 #endif
31
32 const wxChar wxDataViewCtrlNameStr[] = wxT("dataviewCtrl");
33
34
35 bool operator == (const wxDataViewItem &left, const wxDataViewItem &right)
36 {
37 return (left.GetID() == right.GetID() );
38 }
39
40 #ifdef __WXDEBUG__
41 void wxDataViewItem::Print(const wxString& text) const
42 {
43 wxPrintf("item %s: %l\n", text, (long)m_id);
44 }
45 #endif
46
47 // ---------------------------------------------------------
48 // wxDataViewModelNotifier
49 // ---------------------------------------------------------
50
51 #include "wx/listimpl.cpp"
52 WX_DEFINE_LIST(wxDataViewModelNotifiers)
53
54 bool wxDataViewModelNotifier::ItemsAdded( const wxDataViewItem &parent, const wxDataViewItemArray &items )
55 {
56 size_t count = items.GetCount();
57 size_t i;
58 for (i = 0; i < count; i++)
59 if (!ItemAdded( parent, items[i] )) return false;
60
61 return true;
62 }
63
64 bool wxDataViewModelNotifier::ItemsDeleted( const wxDataViewItem &parent, const wxDataViewItemArray &items )
65 {
66 size_t count = items.GetCount();
67 size_t i;
68 for (i = 0; i < count; i++)
69 if (!ItemDeleted( parent, items[i] )) return false;
70
71 return true;
72 }
73
74 bool wxDataViewModelNotifier::ItemsChanged( const wxDataViewItemArray &items )
75 {
76 size_t count = items.GetCount();
77 size_t i;
78 for (i = 0; i < count; i++)
79 if (!ItemChanged( items[i] )) return false;
80
81 return true;
82 }
83
84 // ---------------------------------------------------------
85 // wxDataViewModel
86 // ---------------------------------------------------------
87
88 wxDataViewModel::wxDataViewModel()
89 {
90 m_notifiers.DeleteContents( true );
91 }
92
93 bool wxDataViewModel::ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item )
94 {
95 bool ret = true;
96
97 wxDataViewModelNotifiers::iterator iter;
98 for (iter = m_notifiers.begin(); iter != m_notifiers.end(); ++iter)
99 {
100 wxDataViewModelNotifier* notifier = *iter;
101 if (!notifier->ItemAdded( parent, item ))
102 ret = false;
103 }
104
105 return ret;
106 }
107
108 bool wxDataViewModel::ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item )
109 {
110 bool ret = true;
111
112 wxDataViewModelNotifiers::iterator iter;
113 for (iter = m_notifiers.begin(); iter != m_notifiers.end(); ++iter)
114 {
115 wxDataViewModelNotifier* notifier = *iter;
116 if (!notifier->ItemDeleted( parent, item ))
117 ret = false;
118 }
119
120 return ret;
121 }
122
123 bool wxDataViewModel::ItemChanged( const wxDataViewItem &item )
124 {
125 bool ret = true;
126
127 wxDataViewModelNotifiers::iterator iter;
128 for (iter = m_notifiers.begin(); iter != m_notifiers.end(); ++iter)
129 {
130 wxDataViewModelNotifier* notifier = *iter;
131 if (!notifier->ItemChanged( item ))
132 ret = false;
133 }
134
135 return ret;
136 }
137
138 bool wxDataViewModel::ItemsAdded( const wxDataViewItem &parent, const wxDataViewItemArray &items )
139 {
140 bool ret = true;
141
142 wxDataViewModelNotifiers::iterator iter;
143 for (iter = m_notifiers.begin(); iter != m_notifiers.end(); ++iter)
144 {
145 wxDataViewModelNotifier* notifier = *iter;
146 if (!notifier->ItemsAdded( parent, items ))
147 ret = false;
148 }
149
150 return ret;
151 }
152
153 bool wxDataViewModel::ItemsDeleted( const wxDataViewItem &parent, const wxDataViewItemArray &items )
154 {
155 bool ret = true;
156
157 wxDataViewModelNotifiers::iterator iter;
158 for (iter = m_notifiers.begin(); iter != m_notifiers.end(); ++iter)
159 {
160 wxDataViewModelNotifier* notifier = *iter;
161 if (!notifier->ItemsDeleted( parent, items ))
162 ret = false;
163 }
164
165 return ret;
166 }
167
168 bool wxDataViewModel::ItemsChanged( const wxDataViewItemArray &items )
169 {
170 bool ret = true;
171
172 wxDataViewModelNotifiers::iterator iter;
173 for (iter = m_notifiers.begin(); iter != m_notifiers.end(); ++iter)
174 {
175 wxDataViewModelNotifier* notifier = *iter;
176 if (!notifier->ItemsChanged( items ))
177 ret = false;
178 }
179
180 return ret;
181 }
182
183 bool wxDataViewModel::ValueChanged( const wxDataViewItem &item, unsigned int col )
184 {
185 bool ret = true;
186
187 wxDataViewModelNotifiers::iterator iter;
188 for (iter = m_notifiers.begin(); iter != m_notifiers.end(); ++iter)
189 {
190 wxDataViewModelNotifier* notifier = *iter;
191 if (!notifier->ValueChanged( item, col ))
192 ret = false;
193 }
194
195 return ret;
196 }
197
198 bool wxDataViewModel::Cleared()
199 {
200 bool ret = true;
201
202 wxDataViewModelNotifiers::iterator iter;
203 for (iter = m_notifiers.begin(); iter != m_notifiers.end(); ++iter)
204 {
205 wxDataViewModelNotifier* notifier = *iter;
206 if (!notifier->Cleared())
207 ret = false;
208 }
209
210 return ret;
211 }
212
213 void wxDataViewModel::Resort()
214 {
215 wxDataViewModelNotifiers::iterator iter;
216 for (iter = m_notifiers.begin(); iter != m_notifiers.end(); ++iter)
217 {
218 wxDataViewModelNotifier* notifier = *iter;
219 notifier->Resort();
220 }
221 }
222
223 void wxDataViewModel::AddNotifier( wxDataViewModelNotifier *notifier )
224 {
225 m_notifiers.push_back( notifier );
226 notifier->SetOwner( this );
227 }
228
229 void wxDataViewModel::RemoveNotifier( wxDataViewModelNotifier *notifier )
230 {
231 m_notifiers.DeleteObject( notifier );
232 }
233
234 int wxDataViewModel::Compare( const wxDataViewItem &item1, const wxDataViewItem &item2,
235 unsigned int column, bool ascending )
236 {
237 // sort branches before leaves
238 bool item1_is_container = IsContainer(item1);
239 bool item2_is_container = IsContainer(item2);
240
241 if (item1_is_container && !item2_is_container)
242 return 1;
243 if (item2_is_container && !item1_is_container)
244 return -1;
245
246 wxVariant value1,value2;
247 GetValue( value1, item1, column );
248 GetValue( value2, item2, column );
249
250 if (!ascending)
251 {
252 wxVariant temp = value1;
253 value1 = value2;
254 value2 = temp;
255 }
256
257 if (value1.GetType() == wxT("string"))
258 {
259 wxString str1 = value1.GetString();
260 wxString str2 = value2.GetString();
261 int res = str1.Cmp( str2 );
262 if (res) return res;
263 } else
264 if (value1.GetType() == wxT("long"))
265 {
266 long l1 = value1.GetLong();
267 long l2 = value2.GetLong();
268 long res = l1-l2;
269 if (res) return res;
270 } else
271 if (value1.GetType() == wxT("double"))
272 {
273 double d1 = value1.GetDouble();
274 double d2 = value2.GetDouble();
275 if (d1 < d2) return 1;
276 if (d1 > d2) return -1;
277 } else
278 if (value1.GetType() == wxT("datetime"))
279 {
280 wxDateTime dt1 = value1.GetDateTime();
281 wxDateTime dt2 = value2.GetDateTime();
282 if (dt1.IsEarlierThan(dt2)) return 1;
283 if (dt2.IsEarlierThan(dt1)) return -11;
284 }
285
286 // items must be different
287 unsigned long litem1 = (unsigned long) item1.GetID();
288 unsigned long litem2 = (unsigned long) item2.GetID();
289
290 if (!ascending)
291 return litem2-litem2;
292
293 return litem1-litem2;
294 }
295
296 // ---------------------------------------------------------
297 // wxDataViewIndexListModel
298 // ---------------------------------------------------------
299
300 wxDataViewIndexListModel::wxDataViewIndexListModel( unsigned int initial_size )
301 {
302 // build initial index
303 unsigned int i;
304 for (i = 1; i < initial_size+1; i++)
305 m_hash.Add( (void*) i );
306 m_lastIndex = initial_size + 1;
307 }
308
309 wxDataViewIndexListModel::~wxDataViewIndexListModel()
310 {
311 }
312
313 void wxDataViewIndexListModel::RowPrepended()
314 {
315 unsigned int id = m_lastIndex++;
316 m_hash.Insert( (void*) id, 0 );
317 wxDataViewItem item( (void*) id );
318 ItemAdded( wxDataViewItem(0), item );
319 }
320
321 void wxDataViewIndexListModel::RowInserted( unsigned int before )
322 {
323 unsigned int id = m_lastIndex++;
324 m_hash.Insert( (void*) id, before );
325 wxDataViewItem item( (void*) id );
326 ItemAdded( wxDataViewItem(0), item );
327 }
328
329 void wxDataViewIndexListModel::RowAppended()
330 {
331 unsigned int id = m_lastIndex++;
332 m_hash.Add( (void*) id );
333 wxDataViewItem item( (void*) id );
334 ItemAdded( wxDataViewItem(0), item );
335 }
336
337 void wxDataViewIndexListModel::RowDeleted( unsigned int row )
338 {
339 wxDataViewItem item( m_hash[row] );
340 wxDataViewModel::ItemDeleted( wxDataViewItem(0), item );
341 m_hash.RemoveAt( row );
342 }
343
344 void wxDataViewIndexListModel::RowChanged( unsigned int row )
345 {
346 wxDataViewModel::ItemChanged( GetItem(row) );
347 }
348
349 void wxDataViewIndexListModel::RowValueChanged( unsigned int row, unsigned int col )
350 {
351 wxDataViewModel::ValueChanged( GetItem(row), col );
352 }
353
354 unsigned int wxDataViewIndexListModel::GetRow( const wxDataViewItem &item ) const
355 {
356 // assert for not found
357 return (unsigned int) m_hash.Index( item.GetID() );
358 }
359
360 wxDataViewItem wxDataViewIndexListModel::GetItem( unsigned int row ) const
361 {
362 wxASSERT( row < m_hash.GetCount() );
363 return wxDataViewItem( m_hash[row] );
364 }
365
366 int wxDataViewIndexListModel::Compare(const wxDataViewItem& item1,
367 const wxDataViewItem& item2,
368 unsigned int WXUNUSED(column),
369 bool ascending)
370 {
371 if (ascending)
372 return GetRow(item1) - GetRow(item2);
373
374 return GetRow(item2) - GetRow(item1);
375 }
376
377 void wxDataViewIndexListModel::GetValue( wxVariant &variant,
378 const wxDataViewItem &item, unsigned int col ) const
379 {
380 GetValue( variant, GetRow(item), col );
381 }
382
383 bool wxDataViewIndexListModel::SetValue( const wxVariant &variant,
384 const wxDataViewItem &item, unsigned int col )
385 {
386 return SetValue( variant, GetRow(item), col );
387 }
388
389 bool wxDataViewIndexListModel::GetAttr( const wxDataViewItem &item, unsigned int col, wxDataViewItemAttr &attr )
390 {
391 return GetAttr( GetRow(item), col, attr );
392 }
393
394 wxDataViewItem wxDataViewIndexListModel::GetParent( const wxDataViewItem & WXUNUSED(item) ) const
395 {
396 return wxDataViewItem(0);
397 }
398
399 bool wxDataViewIndexListModel::IsContainer( const wxDataViewItem &item ) const
400 {
401 // only the invisible root item has children
402 if (!item.IsOk())
403 return true;
404
405 return false;
406 }
407
408 unsigned int wxDataViewIndexListModel::GetChildren( const wxDataViewItem &item, wxDataViewItemArray &children ) const
409 {
410 if (item.IsOk())
411 return 0;
412
413 children = m_hash;
414
415 return m_hash.GetCount();
416 }
417
418 //-----------------------------------------------------------------------------
419 // wxDataViewIconText
420 //-----------------------------------------------------------------------------
421
422 IMPLEMENT_DYNAMIC_CLASS(wxDataViewIconText,wxObject)
423
424 IMPLEMENT_VARIANT_OBJECT_EXPORTED(wxDataViewIconText, WXDLLIMPEXP_ADV)
425
426 bool operator == (const wxDataViewIconText &one, const wxDataViewIconText &two)
427 {
428 if (one.GetText() != two.GetText()) return false;
429 if (one.IsSameAs(two)) return false;
430 return true;
431 }
432
433 // ---------------------------------------------------------
434 // wxDataViewRendererBase
435 // ---------------------------------------------------------
436
437 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRendererBase, wxObject)
438
439 wxDataViewRendererBase::wxDataViewRendererBase( const wxString &varianttype,
440 wxDataViewCellMode WXUNUSED(mode),
441 int WXUNUSED(align) )
442 {
443 m_variantType = varianttype;
444 m_editorCtrl = NULL;
445 }
446
447 const wxDataViewCtrl* wxDataViewRendererBase::GetView() const
448 {
449 return wx_const_cast(wxDataViewRendererBase*, this)->GetOwner()->GetOwner();
450 }
451
452 bool wxDataViewRendererBase::StartEditing( const wxDataViewItem &item, wxRect labelRect )
453 {
454 m_item = item; // remember for later
455
456 unsigned int col = GetOwner()->GetModelColumn();
457 wxVariant value;
458 GetOwner()->GetOwner()->GetModel()->GetValue( value, item, col );
459
460 m_editorCtrl = CreateEditorCtrl( GetOwner()->GetOwner()->GetMainWindow(), labelRect, value );
461
462 wxDataViewEditorCtrlEvtHandler *handler =
463 new wxDataViewEditorCtrlEvtHandler( m_editorCtrl, (wxDataViewRenderer*) this );
464
465 m_editorCtrl->PushEventHandler( handler );
466
467 #if defined(__WXGTK20__) && !defined(wxUSE_GENERICDATAVIEWCTRL)
468 handler->SetFocusOnIdle();
469 #else
470 m_editorCtrl->SetFocus();
471 #endif
472
473 // Now we should send Editing Started event
474 wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED, GetOwner()->GetOwner()->GetId() );
475 event.SetDataViewColumn( GetOwner() );
476 event.SetModel( GetOwner()->GetOwner()->GetModel() );
477 event.SetItem( item );
478 GetOwner()->GetOwner()->GetEventHandler()->ProcessEvent( event );
479
480 return true;
481 }
482
483 void wxDataViewRendererBase::CancelEditing()
484 {
485 wxPendingDelete.Append( m_editorCtrl );
486
487 GetOwner()->GetOwner()->GetMainWindow()->SetFocus();
488
489 // m_editorCtrl->PopEventHandler( true );
490 }
491
492 bool wxDataViewRendererBase::FinishEditing()
493 {
494 wxVariant value;
495 GetValueFromEditorCtrl( m_editorCtrl, value );
496
497 wxPendingDelete.Append( m_editorCtrl );
498
499 GetOwner()->GetOwner()->GetMainWindow()->SetFocus();
500
501 if (!Validate(value))
502 return false;
503
504 unsigned int col = GetOwner()->GetModelColumn();
505 GetOwner()->GetOwner()->GetModel()->SetValue( value, m_item, col );
506 GetOwner()->GetOwner()->GetModel()->ValueChanged( m_item, col );
507
508 // m_editorCtrl->PopEventHandler( true );
509
510 // Now we should send Editing Done event
511 wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE, GetOwner()->GetOwner()->GetId() );
512 event.SetDataViewColumn( GetOwner() );
513 event.SetModel( GetOwner()->GetOwner()->GetModel() );
514 event.SetItem( m_item );
515 GetOwner()->GetOwner()->GetEventHandler()->ProcessEvent( event );
516
517 return true;
518 }
519
520 //-----------------------------------------------------------------------------
521 // wxDataViewEditorCtrlEvtHandler
522 //-----------------------------------------------------------------------------
523
524 BEGIN_EVENT_TABLE(wxDataViewEditorCtrlEvtHandler, wxEvtHandler)
525 EVT_CHAR (wxDataViewEditorCtrlEvtHandler::OnChar)
526 EVT_KILL_FOCUS (wxDataViewEditorCtrlEvtHandler::OnKillFocus)
527 EVT_IDLE (wxDataViewEditorCtrlEvtHandler::OnIdle)
528 END_EVENT_TABLE()
529
530 wxDataViewEditorCtrlEvtHandler::wxDataViewEditorCtrlEvtHandler(
531 wxControl *editorCtrl,
532 wxDataViewRenderer *owner )
533 {
534 m_owner = owner;
535 m_editorCtrl = editorCtrl;
536
537 m_finished = false;
538 }
539
540 void wxDataViewEditorCtrlEvtHandler::OnIdle( wxIdleEvent &event )
541 {
542 if (m_focusOnIdle)
543 {
544 m_focusOnIdle = false;
545 if (wxWindow::FindFocus() != m_editorCtrl)
546 m_editorCtrl->SetFocus();
547 }
548
549 event.Skip();
550 }
551
552 void wxDataViewEditorCtrlEvtHandler::OnChar( wxKeyEvent &event )
553 {
554 switch ( event.m_keyCode )
555 {
556 case WXK_RETURN:
557 m_finished = true;
558 m_owner->FinishEditing();
559 break;
560
561 case WXK_ESCAPE:
562 m_finished = true;
563 m_owner->CancelEditing();
564 break;
565
566 default:
567 event.Skip();
568 }
569 }
570
571 void wxDataViewEditorCtrlEvtHandler::OnKillFocus( wxFocusEvent &event )
572 {
573 if (!m_finished)
574 {
575 m_finished = true;
576 m_owner->FinishEditing();
577 }
578
579 event.Skip();
580 }
581
582 // ---------------------------------------------------------
583 // wxDataViewColumnBase
584 // ---------------------------------------------------------
585
586 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumnBase, wxObject)
587
588 wxDataViewColumnBase::wxDataViewColumnBase(const wxString& WXUNUSED(title),
589 wxDataViewRenderer *renderer,
590 unsigned int model_column,
591 int WXUNUSED(width),
592 wxAlignment WXUNUSED(align),
593 int WXUNUSED(flags))
594 {
595 m_renderer = renderer;
596 m_model_column = model_column;
597 m_owner = NULL;
598 m_renderer->SetOwner( (wxDataViewColumn*) this );
599
600 // NOTE: the wxDataViewColumn's ctor must store the width, align, flags
601 // parameters inside the native control!
602 }
603
604 wxDataViewColumnBase::wxDataViewColumnBase(const wxBitmap& bitmap,
605 wxDataViewRenderer *renderer,
606 unsigned int model_column,
607 int WXUNUSED(width),
608 wxAlignment WXUNUSED(align),
609 int WXUNUSED(flags) )
610 {
611 m_renderer = renderer;
612 m_model_column = model_column;
613 m_bitmap = bitmap;
614 m_owner = NULL;
615 m_renderer->SetOwner( (wxDataViewColumn*) this );
616 }
617
618 wxDataViewColumnBase::~wxDataViewColumnBase()
619 {
620 if (m_renderer)
621 delete m_renderer;
622 }
623
624 int wxDataViewColumnBase::GetFlags() const
625 {
626 int ret = 0;
627
628 if (IsSortable())
629 ret |= wxDATAVIEW_COL_SORTABLE;
630 if (IsResizeable())
631 ret |= wxDATAVIEW_COL_RESIZABLE;
632 if (IsHidden())
633 ret |= wxDATAVIEW_COL_HIDDEN;
634
635 return ret;
636 }
637
638 void wxDataViewColumnBase::SetFlags(int flags)
639 {
640 SetSortable((flags & wxDATAVIEW_COL_SORTABLE) != 0);
641 SetResizeable((flags & wxDATAVIEW_COL_RESIZABLE) != 0);
642 SetHidden((flags & wxDATAVIEW_COL_HIDDEN) != 0);
643 }
644
645 // ---------------------------------------------------------
646 // wxDataViewCtrlBase
647 // ---------------------------------------------------------
648
649 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCtrlBase, wxControl)
650
651 wxDataViewCtrlBase::wxDataViewCtrlBase()
652 {
653 m_model = NULL;
654 m_expander_column = 0;
655 m_indent = 8;
656 }
657
658 wxDataViewCtrlBase::~wxDataViewCtrlBase()
659 {
660 if (m_model)
661 {
662 m_model->DecRef();
663 m_model = NULL;
664 }
665 }
666
667 bool wxDataViewCtrlBase::AssociateModel( wxDataViewModel *model )
668 {
669 if (m_model)
670 {
671 m_model->DecRef(); // discard old model, if any
672 }
673
674 // add our own reference to the new model:
675 m_model = model;
676 if (m_model)
677 {
678 m_model->IncRef();
679 }
680
681 return true;
682 }
683
684 wxDataViewModel* wxDataViewCtrlBase::GetModel()
685 {
686 return m_model;
687 }
688
689 wxDataViewColumn *
690 wxDataViewCtrlBase::AppendTextColumn( const wxString &label, unsigned int model_column,
691 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
692 {
693 wxDataViewColumn *ret = new wxDataViewColumn( label,
694 new wxDataViewTextRenderer( wxT("string"), mode, (int)align ),
695 model_column, width, align, flags );
696 AppendColumn( ret );
697 return ret;
698 }
699
700 wxDataViewColumn *
701 wxDataViewCtrlBase::AppendIconTextColumn( const wxString &label, unsigned int model_column,
702 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
703 {
704 wxDataViewColumn *ret = new wxDataViewColumn( label,
705 new wxDataViewIconTextRenderer( wxT("wxDataViewIconText"), mode, (int)align ),
706 model_column, width, align, flags );
707 AppendColumn( ret );
708 return ret;
709 }
710
711 wxDataViewColumn *
712 wxDataViewCtrlBase::AppendToggleColumn( const wxString &label, unsigned int model_column,
713 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
714 {
715
716 wxDataViewColumn *ret = new wxDataViewColumn( label,
717 new wxDataViewToggleRenderer( wxT("bool"), mode, (int)align ),
718 model_column, width, align, flags );
719 AppendColumn( ret );
720 return ret;
721 }
722
723 wxDataViewColumn *
724 wxDataViewCtrlBase::AppendProgressColumn( const wxString &label, unsigned int model_column,
725 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
726 {
727 wxDataViewColumn *ret = new wxDataViewColumn( label,
728 new wxDataViewProgressRenderer( wxEmptyString, wxT("long"), mode, (int)align ),
729 model_column, width, align, flags );
730 AppendColumn( ret );
731 return ret;
732 }
733
734 wxDataViewColumn *
735 wxDataViewCtrlBase::AppendDateColumn( const wxString &label, unsigned int model_column,
736 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
737 {
738 wxDataViewColumn *ret = new wxDataViewColumn( label,
739 new wxDataViewDateRenderer( wxT("datetime"), mode, (int)align ),
740 model_column, width, align, flags );
741 AppendColumn( ret );
742 return ret;
743 }
744
745 wxDataViewColumn *
746 wxDataViewCtrlBase::AppendBitmapColumn( const wxString &label, unsigned int model_column,
747 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
748 {
749 wxDataViewColumn *ret = new wxDataViewColumn( label,
750 new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode, (int)align ),
751 model_column, width, align, flags );
752 AppendColumn( ret );
753 return ret;
754 }
755
756 wxDataViewColumn *
757 wxDataViewCtrlBase::AppendTextColumn( const wxBitmap &label, unsigned int model_column,
758 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
759 {
760 wxDataViewColumn *ret = new wxDataViewColumn( label,
761 new wxDataViewTextRenderer( wxT("string"), mode, (int)align ),
762 model_column, width, align, flags );
763 AppendColumn( ret );
764 return ret;
765 }
766
767 wxDataViewColumn *
768 wxDataViewCtrlBase::AppendIconTextColumn( const wxBitmap &label, unsigned int model_column,
769 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
770 {
771 wxDataViewColumn *ret = new wxDataViewColumn( label,
772 new wxDataViewIconTextRenderer( wxT("wxDataViewIconText"), mode, (int)align ),
773 model_column, width, align, flags );
774 AppendColumn( ret );
775 return ret;
776 }
777
778 wxDataViewColumn *
779 wxDataViewCtrlBase::AppendToggleColumn( const wxBitmap &label, unsigned int model_column,
780 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
781 {
782 wxDataViewColumn *ret = new wxDataViewColumn( label,
783 new wxDataViewToggleRenderer( wxT("bool"), mode, (int)align ),
784 model_column, width, align, flags );
785 AppendColumn( ret );
786 return ret;
787 }
788
789 wxDataViewColumn *
790 wxDataViewCtrlBase::AppendProgressColumn( const wxBitmap &label, unsigned int model_column,
791 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
792 {
793 wxDataViewColumn *ret = new wxDataViewColumn( label,
794 new wxDataViewProgressRenderer( wxEmptyString, wxT("long"), mode, (int)align ),
795 model_column, width, align, flags );
796 AppendColumn( ret );
797 return ret;
798 }
799
800 wxDataViewColumn *
801 wxDataViewCtrlBase::AppendDateColumn( const wxBitmap &label, unsigned int model_column,
802 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
803 {
804 wxDataViewColumn *ret = new wxDataViewColumn( label,
805 new wxDataViewDateRenderer( wxT("datetime"), mode, (int)align ),
806 model_column, width, align, flags );
807 AppendColumn( ret );
808 return ret;
809 }
810
811 wxDataViewColumn *
812 wxDataViewCtrlBase::AppendBitmapColumn( const wxBitmap &label, unsigned int model_column,
813 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
814 {
815 wxDataViewColumn *ret = new wxDataViewColumn( label,
816 new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode, (int)align ),
817 model_column, width, align, flags );
818 AppendColumn( ret );
819 return ret;
820 }
821
822 wxDataViewColumn *
823 wxDataViewCtrlBase::PrependTextColumn( const wxString &label, unsigned int model_column,
824 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
825 {
826 wxDataViewColumn *ret = new wxDataViewColumn( label,
827 new wxDataViewTextRenderer( wxT("string"), mode, (int)align ),
828 model_column, width, align, flags );
829 PrependColumn( ret );
830 return ret;
831 }
832
833 wxDataViewColumn *
834 wxDataViewCtrlBase::PrependIconTextColumn( const wxString &label, unsigned int model_column,
835 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
836 {
837 wxDataViewColumn *ret = new wxDataViewColumn( label,
838 new wxDataViewIconTextRenderer( wxT("wxDataViewIconText"), mode, (int)align ),
839 model_column, width, align, flags );
840 PrependColumn( ret );
841 return ret;
842 }
843
844 wxDataViewColumn *
845 wxDataViewCtrlBase::PrependToggleColumn( const wxString &label, unsigned int model_column,
846 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
847 {
848
849 wxDataViewColumn *ret = new wxDataViewColumn( label,
850 new wxDataViewToggleRenderer( wxT("bool"), mode, (int)align ),
851 model_column, width, align, flags );
852 PrependColumn( ret );
853 return ret;
854 }
855
856 wxDataViewColumn *
857 wxDataViewCtrlBase::PrependProgressColumn( const wxString &label, unsigned int model_column,
858 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
859 {
860 wxDataViewColumn *ret = new wxDataViewColumn( label,
861 new wxDataViewProgressRenderer( wxEmptyString, wxT("long"), mode, (int)align ),
862 model_column, width, align, flags );
863 PrependColumn( ret );
864 return ret;
865 }
866
867 wxDataViewColumn *
868 wxDataViewCtrlBase::PrependDateColumn( const wxString &label, unsigned int model_column,
869 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
870 {
871 wxDataViewColumn *ret = new wxDataViewColumn( label,
872 new wxDataViewDateRenderer( wxT("datetime"), mode, (int)align ),
873 model_column, width, align, flags );
874 PrependColumn( ret );
875 return ret;
876 }
877
878 wxDataViewColumn *
879 wxDataViewCtrlBase::PrependBitmapColumn( const wxString &label, unsigned int model_column,
880 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
881 {
882 wxDataViewColumn *ret = new wxDataViewColumn( label,
883 new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode, (int)align ),
884 model_column, width, align, flags );
885 PrependColumn( ret );
886 return ret;
887 }
888
889 wxDataViewColumn *
890 wxDataViewCtrlBase::PrependTextColumn( const wxBitmap &label, unsigned int model_column,
891 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
892 {
893 wxDataViewColumn *ret = new wxDataViewColumn( label,
894 new wxDataViewTextRenderer( wxT("string"), mode, (int)align ),
895 model_column, width, align, flags );
896 PrependColumn( ret );
897 return ret;
898 }
899
900 wxDataViewColumn *
901 wxDataViewCtrlBase::PrependIconTextColumn( const wxBitmap &label, unsigned int model_column,
902 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
903 {
904 wxDataViewColumn *ret = new wxDataViewColumn( label,
905 new wxDataViewIconTextRenderer( wxT("wxDataViewIconText"), mode, (int)align ),
906 model_column, width, align, flags );
907 PrependColumn( ret );
908 return ret;
909 }
910
911 wxDataViewColumn *
912 wxDataViewCtrlBase::PrependToggleColumn( const wxBitmap &label, unsigned int model_column,
913 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
914 {
915 wxDataViewColumn *ret = new wxDataViewColumn( label,
916 new wxDataViewToggleRenderer( wxT("bool"), mode, (int)align ),
917 model_column, width, align, flags );
918 PrependColumn( ret );
919 return ret;
920 }
921
922 wxDataViewColumn *
923 wxDataViewCtrlBase::PrependProgressColumn( const wxBitmap &label, unsigned int model_column,
924 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
925 {
926 wxDataViewColumn *ret = new wxDataViewColumn( label,
927 new wxDataViewProgressRenderer( wxEmptyString, wxT("long"), mode, (int)align ),
928 model_column, width, align, flags );
929 PrependColumn( ret );
930 return ret;
931 }
932
933 wxDataViewColumn *
934 wxDataViewCtrlBase::PrependDateColumn( const wxBitmap &label, unsigned int model_column,
935 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
936 {
937 wxDataViewColumn *ret = new wxDataViewColumn( label,
938 new wxDataViewDateRenderer( wxT("datetime"), mode, (int)align ),
939 model_column, width, align, flags );
940 PrependColumn( ret );
941 return ret;
942 }
943
944 wxDataViewColumn *
945 wxDataViewCtrlBase::PrependBitmapColumn( const wxBitmap &label, unsigned int model_column,
946 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
947 {
948 wxDataViewColumn *ret = new wxDataViewColumn( label,
949 new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode, (int)align ),
950 model_column, width, align, flags );
951 PrependColumn( ret );
952 return ret;
953 }
954
955 bool
956 wxDataViewCtrlBase::AppendColumn( wxDataViewColumn *col )
957 {
958 col->SetOwner( (wxDataViewCtrl*) this );
959 return true;
960 }
961
962 bool
963 wxDataViewCtrlBase::PrependColumn( wxDataViewColumn *col )
964 {
965 col->SetOwner( (wxDataViewCtrl*) this );
966 return true;
967 }
968
969 // ---------------------------------------------------------
970 // wxDataViewEvent
971 // ---------------------------------------------------------
972
973 IMPLEMENT_DYNAMIC_CLASS(wxDataViewEvent,wxNotifyEvent)
974
975 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED)
976
977 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED)
978 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING)
979 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED)
980 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING)
981 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED)
982 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED)
983 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE)
984 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED)
985
986 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK)
987 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK)
988 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED)
989
990
991 // -------------------------------------
992 // wxDataViewSpinRenderer
993 // -------------------------------------
994
995 wxDataViewSpinRenderer::wxDataViewSpinRenderer( int min, int max, wxDataViewCellMode mode, int alignment ) :
996 wxDataViewCustomRenderer( "long", mode, alignment )
997 {
998 m_min = min;
999 m_max = max;
1000 }
1001
1002 wxControl* wxDataViewSpinRenderer::CreateEditorCtrl( wxWindow *parent, wxRect labelRect, const wxVariant &value )
1003 {
1004 long l = value;
1005 return new wxSpinCtrl( parent, wxID_ANY, wxEmptyString,
1006 labelRect.GetTopLeft(), labelRect.GetSize(), wxSP_ARROW_KEYS, m_min, m_max, l );
1007 }
1008
1009 bool wxDataViewSpinRenderer::GetValueFromEditorCtrl( wxControl* editor, wxVariant &value )
1010 {
1011 wxSpinCtrl *sc = (wxSpinCtrl*) editor;
1012 long l = sc->GetValue();
1013 value = l;
1014 return true;
1015 }
1016
1017 bool wxDataViewSpinRenderer::Render( wxRect rect, wxDC *dc, int state )
1018 {
1019 wxString str;
1020 str.Printf( "%d", (int) m_data );
1021 RenderText( str, 0, rect, dc, state );
1022 return true;
1023 }
1024
1025 wxSize wxDataViewSpinRenderer::GetSize() const
1026 {
1027 return wxSize(80,16);
1028 }
1029
1030 bool wxDataViewSpinRenderer::SetValue( const wxVariant &value )
1031 {
1032 m_data = value.GetLong();
1033 return true;
1034 }
1035
1036 bool wxDataViewSpinRenderer::GetValue( wxVariant &value ) const
1037 {
1038 value = m_data;
1039 return true;
1040 }
1041
1042 //-----------------------------------------------------------------------------
1043 // wxDataViewTreeStore
1044 //-----------------------------------------------------------------------------
1045
1046 wxDataViewTreeStoreNode::wxDataViewTreeStoreNode(
1047 wxDataViewTreeStoreNode *parent,
1048 const wxString &text, const wxIcon &icon, wxClientData *data )
1049 {
1050 m_parent = parent;
1051 m_text = text;
1052 m_icon = icon;
1053 m_data = data;
1054 }
1055
1056 wxDataViewTreeStoreNode::~wxDataViewTreeStoreNode()
1057 {
1058 if (m_data)
1059 delete m_data;
1060 }
1061
1062 #include "wx/listimpl.cpp"
1063 WX_DEFINE_LIST(wxDataViewTreeStoreNodeList)
1064
1065 wxDataViewTreeStoreContainerNode::wxDataViewTreeStoreContainerNode(
1066 wxDataViewTreeStoreNode *parent, const wxString &text,
1067 const wxIcon &icon, const wxIcon &expanded, wxClientData *data ) :
1068 wxDataViewTreeStoreNode( parent, text, icon, data )
1069 {
1070 m_iconExpanded = expanded;
1071 m_children.DeleteContents(true);
1072 }
1073
1074 wxDataViewTreeStoreContainerNode::~wxDataViewTreeStoreContainerNode()
1075 {
1076 }
1077
1078 //-----------------------------------------------------------------------------
1079
1080 wxDataViewTreeStore::wxDataViewTreeStore()
1081 {
1082 m_root = new wxDataViewTreeStoreContainerNode( NULL, wxEmptyString );
1083 }
1084
1085 wxDataViewTreeStore::~wxDataViewTreeStore()
1086 {
1087 delete m_root;
1088 }
1089
1090 wxDataViewItem wxDataViewTreeStore::AppendItem( const wxDataViewItem& parent,
1091 const wxString &text, const wxIcon &icon, wxClientData *data )
1092 {
1093 wxDataViewTreeStoreContainerNode *parent_node = FindContainerNode( parent );
1094 if (!parent_node) return wxDataViewItem(0);
1095
1096 wxDataViewTreeStoreNode *node =
1097 new wxDataViewTreeStoreNode( parent_node, text, icon, data );
1098 parent_node->GetChildren().Append( node );
1099
1100 // notify control
1101 ItemAdded( parent, node->GetItem() );
1102
1103 return node->GetItem();
1104 }
1105
1106 wxDataViewItem wxDataViewTreeStore::PrependItem( const wxDataViewItem& parent,
1107 const wxString &text, const wxIcon &icon, wxClientData *data )
1108 {
1109 wxDataViewTreeStoreContainerNode *parent_node = FindContainerNode( parent );
1110 if (!parent_node) return wxDataViewItem(0);
1111
1112 wxDataViewTreeStoreNode *node =
1113 new wxDataViewTreeStoreNode( parent_node, text, icon, data );
1114 parent_node->GetChildren().Insert( node );
1115
1116 // notify control
1117 ItemAdded( parent, node->GetItem() );
1118
1119 return node->GetItem();
1120 }
1121
1122 wxDataViewItem
1123 wxDataViewTreeStore::InsertItem(const wxDataViewItem& WXUNUSED(parent),
1124 const wxDataViewItem& WXUNUSED(previous),
1125 const wxString& WXUNUSED(text),
1126 const wxIcon& WXUNUSED(icon),
1127 wxClientData * WXUNUSED(data))
1128 {
1129 return wxDataViewItem(0);
1130 }
1131
1132 wxDataViewItem wxDataViewTreeStore::PrependContainer( const wxDataViewItem& parent,
1133 const wxString &text, const wxIcon &icon, const wxIcon &expanded,
1134 wxClientData *data )
1135 {
1136 wxDataViewTreeStoreContainerNode *parent_node = FindContainerNode( parent );
1137 if (!parent_node) return wxDataViewItem(0);
1138
1139 wxDataViewTreeStoreContainerNode *node =
1140 new wxDataViewTreeStoreContainerNode( parent_node, text, icon, expanded, data );
1141 parent_node->GetChildren().Insert( node );
1142
1143 // notify control
1144 ItemAdded( parent, node->GetItem() );
1145
1146 return node->GetItem();
1147 }
1148
1149 wxDataViewItem
1150 wxDataViewTreeStore::AppendContainer(const wxDataViewItem& parent,
1151 const wxString &text,
1152 const wxIcon& icon,
1153 const wxIcon& expanded,
1154 wxClientData * data)
1155 {
1156 wxDataViewTreeStoreContainerNode *parent_node = FindContainerNode( parent );
1157 if (!parent_node) return wxDataViewItem(0);
1158
1159 wxDataViewTreeStoreContainerNode *node =
1160 new wxDataViewTreeStoreContainerNode( parent_node, text, icon, expanded, data );
1161 parent_node->GetChildren().Append( node );
1162
1163 // notify control
1164 ItemAdded( parent, node->GetItem() );
1165
1166 return node->GetItem();
1167 }
1168
1169 wxDataViewItem
1170 wxDataViewTreeStore::InsertContainer(const wxDataViewItem& WXUNUSED(parent),
1171 const wxDataViewItem& WXUNUSED(previous),
1172 const wxString& WXUNUSED(text),
1173 const wxIcon& WXUNUSED(icon),
1174 const wxIcon& WXUNUSED(expanded),
1175 wxClientData * WXUNUSED(data))
1176 {
1177 return wxDataViewItem(0);
1178 }
1179
1180 wxDataViewItem wxDataViewTreeStore::GetNthChild( const wxDataViewItem& parent, unsigned int pos ) const
1181 {
1182 wxDataViewTreeStoreContainerNode *parent_node = FindContainerNode( parent );
1183 if (!parent_node) return wxDataViewItem(0);
1184
1185 wxDataViewTreeStoreNodeList::compatibility_iterator node = parent_node->GetChildren().Item( pos );
1186 if (node)
1187 return node->GetData();
1188
1189 return wxDataViewItem(0);
1190 }
1191
1192 int wxDataViewTreeStore::GetChildCount( const wxDataViewItem& parent ) const
1193 {
1194 wxDataViewTreeStoreNode *node = FindNode( parent );
1195 if (!node) return -1;
1196
1197 if (!node->IsContainer())
1198 return 0;
1199
1200 wxDataViewTreeStoreContainerNode *container_node = (wxDataViewTreeStoreContainerNode*) node;
1201 return (int) container_node->GetChildren().GetCount();
1202 }
1203
1204 void wxDataViewTreeStore::SetItemText( const wxDataViewItem& item, const wxString &text )
1205 {
1206 wxDataViewTreeStoreNode *node = FindNode( item );
1207 if (!node) return;
1208
1209 node->SetText( text );
1210
1211 // notify control
1212 ValueChanged( item, 0 );
1213 }
1214
1215 wxString wxDataViewTreeStore::GetItemText( const wxDataViewItem& item ) const
1216 {
1217 wxDataViewTreeStoreNode *node = FindNode( item );
1218 if (!node) return wxEmptyString;
1219
1220 return node->GetText();
1221 }
1222
1223 void wxDataViewTreeStore::SetItemIcon( const wxDataViewItem& item, const wxIcon &icon )
1224 {
1225 wxDataViewTreeStoreNode *node = FindNode( item );
1226 if (!node) return;
1227
1228 node->SetIcon( icon );
1229
1230 // notify control
1231 ValueChanged( item, 0 );
1232 }
1233
1234 const wxIcon &wxDataViewTreeStore::GetItemIcon( const wxDataViewItem& item ) const
1235 {
1236 wxDataViewTreeStoreNode *node = FindNode( item );
1237 if (!node) return wxNullIcon;
1238
1239 return node->GetIcon();
1240 }
1241
1242 void wxDataViewTreeStore::SetItemExpandedIcon( const wxDataViewItem& item, const wxIcon &icon )
1243 {
1244 wxDataViewTreeStoreContainerNode *node = FindContainerNode( item );
1245 if (!node) return;
1246
1247 node->SetExpandedIcon( icon );
1248
1249 // notify control
1250 ValueChanged( item, 0 );
1251 }
1252
1253 const wxIcon &wxDataViewTreeStore::GetItemExpandedIcon( const wxDataViewItem& item ) const
1254 {
1255 wxDataViewTreeStoreContainerNode *node = FindContainerNode( item );
1256 if (!node) return wxNullIcon;
1257
1258 return node->GetExpandedIcon();
1259 }
1260
1261 void wxDataViewTreeStore::SetItemData( const wxDataViewItem& item, wxClientData *data )
1262 {
1263 wxDataViewTreeStoreNode *node = FindNode( item );
1264 if (!node) return;
1265
1266 node->SetData( data );
1267
1268 // notify control? only sensible when sorting on client data
1269 // ValueChanged( item, 0 );
1270 }
1271
1272 wxClientData *wxDataViewTreeStore::GetItemData( const wxDataViewItem& item ) const
1273 {
1274 wxDataViewTreeStoreNode *node = FindNode( item );
1275 if (!node) return NULL;
1276
1277 return node->GetData();
1278 }
1279
1280 void wxDataViewTreeStore::DeleteItem( const wxDataViewItem& item )
1281 {
1282 if (!item.IsOk()) return;
1283
1284 wxDataViewItem parent_item = GetParent( item );
1285
1286 wxDataViewTreeStoreContainerNode *parent_node = FindContainerNode( parent_item );
1287 if (!parent_node) return;
1288
1289 wxDataViewTreeStoreContainerNode *node = FindContainerNode( item );
1290 if (!node) return;
1291
1292 parent_node->GetChildren().DeleteObject( node );
1293
1294 // notify control
1295 ItemDeleted( parent_item, item );
1296 }
1297
1298 void wxDataViewTreeStore::DeleteChildren( const wxDataViewItem& item )
1299 {
1300 wxDataViewTreeStoreContainerNode *node = FindContainerNode( item );
1301 if (!node) return;
1302
1303 wxDataViewItemArray array;
1304 wxDataViewTreeStoreNodeList::iterator iter;
1305 for (iter = node->GetChildren().begin(); iter != node->GetChildren().end(); iter++)
1306 {
1307 wxDataViewTreeStoreNode* child = *iter;
1308 array.Add( child->GetItem() );
1309 }
1310
1311 node->GetChildren().clear();
1312
1313 // notify control
1314 ItemsDeleted( item, array );
1315 }
1316
1317 void wxDataViewTreeStore::DeleteAllItems()
1318 {
1319 // TODO
1320 }
1321
1322 void
1323 wxDataViewTreeStore::GetValue(wxVariant &variant,
1324 const wxDataViewItem &item,
1325 unsigned int WXUNUSED(col)) const
1326 {
1327 // if (col != 0) return;
1328
1329 wxDataViewTreeStoreNode *node = FindNode( item );
1330 if (!node) return;
1331
1332 wxDataViewIconText data( node->GetText(), node->GetIcon() );
1333
1334 variant << data;
1335 }
1336
1337 bool
1338 wxDataViewTreeStore::SetValue(const wxVariant& variant,
1339 const wxDataViewItem& item,
1340 unsigned int WXUNUSED(col))
1341 {
1342 // if (col != 0) return false;
1343
1344 wxDataViewTreeStoreNode *node = FindNode( item );
1345 if (!node) return false;
1346
1347 wxDataViewIconText data;
1348
1349 data << variant;
1350
1351 node->SetText( data.GetText() );
1352 node->SetIcon( data.GetIcon() );
1353
1354 return true;
1355 }
1356
1357 wxDataViewItem wxDataViewTreeStore::GetParent( const wxDataViewItem &item ) const
1358 {
1359 wxDataViewTreeStoreNode *node = FindNode( item );
1360 if (!node) return wxDataViewItem(0);
1361
1362 wxDataViewTreeStoreNode *parent = node->GetParent();
1363 if (!parent) return wxDataViewItem(0);
1364
1365 if (parent == m_root)
1366 return wxDataViewItem(0);
1367
1368 return parent->GetItem();
1369 }
1370
1371 bool wxDataViewTreeStore::IsContainer( const wxDataViewItem &item ) const
1372 {
1373 wxDataViewTreeStoreNode *node = FindNode( item );
1374 if (!node) return false;
1375
1376 return node->IsContainer();
1377 }
1378
1379 unsigned int wxDataViewTreeStore::GetChildren( const wxDataViewItem &item, wxDataViewItemArray &children ) const
1380 {
1381 wxDataViewTreeStoreContainerNode *node = FindContainerNode( item );
1382 if (!node) return 0;
1383
1384 wxDataViewTreeStoreNodeList::iterator iter;
1385 for (iter = node->GetChildren().begin(); iter != node->GetChildren().end(); iter++)
1386 {
1387 wxDataViewTreeStoreNode* child = *iter;
1388 children.Add( child->GetItem() );
1389 }
1390
1391 return node->GetChildren().GetCount();
1392 }
1393
1394 int wxDataViewTreeStore::Compare( const wxDataViewItem &item1, const wxDataViewItem &item2,
1395 unsigned int WXUNUSED(column), bool WXUNUSED(ascending) )
1396 {
1397 wxDataViewTreeStoreNode *node1 = FindNode( item1 );
1398 wxDataViewTreeStoreNode *node2 = FindNode( item2 );
1399
1400 if (!node1 || !node2)
1401 return 0;
1402
1403 wxDataViewTreeStoreContainerNode* parent1 =
1404 (wxDataViewTreeStoreContainerNode*) node1->GetParent();
1405 wxDataViewTreeStoreContainerNode* parent2 =
1406 (wxDataViewTreeStoreContainerNode*) node2->GetParent();
1407
1408 if (parent1 != parent2)
1409 {
1410 wxLogError( wxT("Comparing items with different parent.") );
1411 return 0;
1412 }
1413
1414 if (node1->IsContainer() && !!node2->IsContainer())
1415 return 1;
1416
1417 if (node2->IsContainer() && !!node1->IsContainer())
1418 return -1;
1419
1420 return parent1->GetChildren().IndexOf( node1 ) - parent1->GetChildren().IndexOf( node2 );
1421 }
1422
1423 wxDataViewTreeStoreNode *wxDataViewTreeStore::FindNode( const wxDataViewItem &item ) const
1424 {
1425 if (!item.IsOk())
1426 return m_root;
1427
1428 return (wxDataViewTreeStoreNode*) item.GetID();
1429 }
1430
1431 wxDataViewTreeStoreContainerNode *wxDataViewTreeStore::FindContainerNode( const wxDataViewItem &item ) const
1432 {
1433 if (!item.IsOk())
1434 return (wxDataViewTreeStoreContainerNode*) m_root;
1435
1436 wxDataViewTreeStoreNode* node = (wxDataViewTreeStoreNode*) item.GetID();
1437
1438 if (!node->IsContainer())
1439 return NULL;
1440
1441 return (wxDataViewTreeStoreContainerNode*) node;
1442 }
1443
1444 #endif // wxUSE_DATAVIEWCTRL
1445