]> git.saurik.com Git - wxWidgets.git/blob - src/common/datavcmn.cpp
By default, align renderers as column header under GTK+, too.
[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(wxT("item %s: %l\n"), text.GetData(), (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 static int my_sort( int *v1, int *v2 )
301 {
302 return *v2-*v1;
303 }
304
305
306 wxDataViewIndexListModel::wxDataViewIndexListModel( unsigned int initial_size )
307 {
308 // IDs are ordered until an item gets deleted or inserted
309 m_ordered = true;
310
311 // build initial index
312 unsigned int i;
313 for (i = 1; i < initial_size+1; i++)
314 m_hash.Add( (void*) i );
315 m_lastIndex = initial_size + 1;
316 }
317
318 wxDataViewIndexListModel::~wxDataViewIndexListModel()
319 {
320 }
321
322 void wxDataViewIndexListModel::Reset( unsigned int new_size )
323 {
324 m_hash.Clear();
325
326 // IDs are ordered until an item gets deleted or inserted
327 m_ordered = true;
328
329 // build initial index
330 unsigned int i;
331 for (i = 1; i < new_size+1; i++)
332 m_hash.Add( (void*) i );
333 m_lastIndex = new_size + 1;
334
335 wxDataViewModel::Cleared();
336 }
337
338 void wxDataViewIndexListModel::RowPrepended()
339 {
340 m_ordered = false;
341
342 unsigned int id = m_lastIndex++;
343 m_hash.Insert( (void*) id, 0 );
344 wxDataViewItem item( (void*) id );
345 ItemAdded( wxDataViewItem(0), item );
346 }
347
348 void wxDataViewIndexListModel::RowInserted( unsigned int before )
349 {
350 m_ordered = false;
351
352 unsigned int id = m_lastIndex++;
353 m_hash.Insert( (void*) id, before );
354 wxDataViewItem item( (void*) id );
355 ItemAdded( wxDataViewItem(0), item );
356 }
357
358 void wxDataViewIndexListModel::RowAppended()
359 {
360 unsigned int id = m_lastIndex++;
361 m_hash.Add( (void*) id );
362 wxDataViewItem item( (void*) id );
363 ItemAdded( wxDataViewItem(0), item );
364 }
365
366 void wxDataViewIndexListModel::RowDeleted( unsigned int row )
367 {
368 m_ordered = false;
369
370 wxDataViewItem item( m_hash[row] );
371 wxDataViewModel::ItemDeleted( wxDataViewItem(0), item );
372 m_hash.RemoveAt( row );
373 }
374
375 void wxDataViewIndexListModel::RowsDeleted( const wxArrayInt &rows )
376 {
377 wxArrayInt sorted = rows;
378 sorted.Sort( my_sort );
379
380 m_ordered = false;
381
382 wxDataViewItemArray array;
383 unsigned int i;
384 for (i = 0; i < rows.GetCount(); i++)
385 {
386 wxDataViewItem item( m_hash[rows[i]] );
387 array.Add( item );
388 }
389 wxDataViewModel::ItemsDeleted( wxDataViewItem(0), array );
390
391 for (i = 0; i < sorted.GetCount(); i++)
392 m_hash.RemoveAt( sorted[i] );
393 }
394
395 void wxDataViewIndexListModel::RowChanged( unsigned int row )
396 {
397 wxDataViewModel::ItemChanged( GetItem(row) );
398 }
399
400 void wxDataViewIndexListModel::RowValueChanged( unsigned int row, unsigned int col )
401 {
402 wxDataViewModel::ValueChanged( GetItem(row), col );
403 }
404
405 unsigned int wxDataViewIndexListModel::GetRow( const wxDataViewItem &item ) const
406 {
407 if (m_ordered)
408 {
409 unsigned int pos = wxPtrToUInt( item.GetID() );
410 return pos-1;
411 }
412
413 // assert for not found
414 return (unsigned int) m_hash.Index( item.GetID() );
415 }
416
417 wxDataViewItem wxDataViewIndexListModel::GetItem( unsigned int row ) const
418 {
419 wxASSERT( row < m_hash.GetCount() );
420 return wxDataViewItem( m_hash[row] );
421 }
422
423 bool wxDataViewIndexListModel::HasDefaultCompare() const
424 {
425 return !m_ordered;
426 }
427
428 int wxDataViewIndexListModel::Compare(const wxDataViewItem& item1,
429 const wxDataViewItem& item2,
430 unsigned int WXUNUSED(column),
431 bool ascending)
432 {
433 if (m_ordered)
434 {
435 unsigned int pos1 = wxPtrToUInt(item1.GetID());
436 unsigned int pos2 = wxPtrToUInt(item2.GetID());
437
438 if (ascending)
439 return pos1 - pos2;
440 else
441 return pos2 - pos1;
442 }
443
444 if (ascending)
445 return GetRow(item1) - GetRow(item2);
446
447 return GetRow(item2) - GetRow(item1);
448 }
449
450 void wxDataViewIndexListModel::GetValue( wxVariant &variant,
451 const wxDataViewItem &item, unsigned int col ) const
452 {
453 GetValue( variant, GetRow(item), col );
454 }
455
456 bool wxDataViewIndexListModel::SetValue( const wxVariant &variant,
457 const wxDataViewItem &item, unsigned int col )
458 {
459 return SetValue( variant, GetRow(item), col );
460 }
461
462 bool wxDataViewIndexListModel::GetAttr( const wxDataViewItem &item, unsigned int col, wxDataViewItemAttr &attr )
463 {
464 return GetAttr( GetRow(item), col, attr );
465 }
466
467 wxDataViewItem wxDataViewIndexListModel::GetParent( const wxDataViewItem & WXUNUSED(item) ) const
468 {
469 return wxDataViewItem(0);
470 }
471
472 bool wxDataViewIndexListModel::IsContainer( const wxDataViewItem &item ) const
473 {
474 // only the invisible root item has children
475 if (!item.IsOk())
476 return true;
477
478 return false;
479 }
480
481 unsigned int wxDataViewIndexListModel::GetChildren( const wxDataViewItem &item, wxDataViewItemArray &children ) const
482 {
483 if (item.IsOk())
484 return 0;
485
486 children = m_hash;
487
488 return m_hash.GetCount();
489 }
490
491 // ---------------------------------------------------------
492 // wxDataViewVirtualListModel
493 // ---------------------------------------------------------
494
495 #ifndef __WXMAC__
496
497 wxDataViewVirtualListModel::wxDataViewVirtualListModel( unsigned int initial_size )
498 {
499 m_lastIndex = initial_size-1;
500 }
501
502 wxDataViewVirtualListModel::~wxDataViewVirtualListModel()
503 {
504 }
505
506 void wxDataViewVirtualListModel::Reset( unsigned int new_size )
507 {
508 m_lastIndex = new_size-1;
509
510 wxDataViewModel::Cleared();
511 }
512
513 void wxDataViewVirtualListModel::RowPrepended()
514 {
515 m_lastIndex++;
516 wxDataViewItem item( (void*) 0 );
517 ItemAdded( wxDataViewItem(0), item );
518 }
519
520 void wxDataViewVirtualListModel::RowInserted( unsigned int before )
521 {
522 m_lastIndex++;
523 wxDataViewItem item( (void*) before );
524 ItemAdded( wxDataViewItem(0), item );
525 }
526
527 void wxDataViewVirtualListModel::RowAppended()
528 {
529 m_lastIndex++;
530 wxDataViewItem item( (void*) m_lastIndex );
531 ItemAdded( wxDataViewItem(0), item );
532 }
533
534 void wxDataViewVirtualListModel::RowDeleted( unsigned int row )
535 {
536 wxDataViewItem item( (void*) row );
537 wxDataViewModel::ItemDeleted( wxDataViewItem(0), item );
538 m_lastIndex++;
539 }
540
541 void wxDataViewVirtualListModel::RowsDeleted( const wxArrayInt &rows )
542 {
543 wxArrayInt sorted = rows;
544 sorted.Sort( my_sort );
545
546 wxDataViewItemArray array;
547 unsigned int i;
548 for (i = 0; i < sorted.GetCount(); i++)
549 {
550 wxDataViewItem item( (void*) sorted[i] );
551 array.Add( item );
552 }
553 wxDataViewModel::ItemsDeleted( wxDataViewItem(0), array );
554
555 m_lastIndex -= rows.GetCount();
556 }
557
558 void wxDataViewVirtualListModel::RowChanged( unsigned int row )
559 {
560 wxDataViewModel::ItemChanged( GetItem(row) );
561 }
562
563 void wxDataViewVirtualListModel::RowValueChanged( unsigned int row, unsigned int col )
564 {
565 wxDataViewModel::ValueChanged( GetItem(row), col );
566 }
567
568 unsigned int wxDataViewVirtualListModel::GetRow( const wxDataViewItem &item ) const
569 {
570 return wxPtrToUInt( item.GetID() );
571 }
572
573 wxDataViewItem wxDataViewVirtualListModel::GetItem( unsigned int row ) const
574 {
575 return wxDataViewItem( (void*) row );
576 }
577
578 bool wxDataViewVirtualListModel::HasDefaultCompare() const
579 {
580 return true;
581 }
582
583 int wxDataViewVirtualListModel::Compare(const wxDataViewItem& item1,
584 const wxDataViewItem& item2,
585 unsigned int WXUNUSED(column),
586 bool ascending)
587 {
588 unsigned int pos1 = wxPtrToUInt(item1.GetID());
589 unsigned int pos2 = wxPtrToUInt(item2.GetID());
590
591 if (ascending)
592 return pos1 - pos2;
593 else
594 return pos2 - pos1;
595 }
596
597 void wxDataViewVirtualListModel::GetValue( wxVariant &variant,
598 const wxDataViewItem &item, unsigned int col ) const
599 {
600 GetValue( variant, GetRow(item), col );
601 }
602
603 bool wxDataViewVirtualListModel::SetValue( const wxVariant &variant,
604 const wxDataViewItem &item, unsigned int col )
605 {
606 return SetValue( variant, GetRow(item), col );
607 }
608
609 bool wxDataViewVirtualListModel::GetAttr( const wxDataViewItem &item, unsigned int col, wxDataViewItemAttr &attr )
610 {
611 return GetAttr( GetRow(item), col, attr );
612 }
613
614 wxDataViewItem wxDataViewVirtualListModel::GetParent( const wxDataViewItem & WXUNUSED(item) ) const
615 {
616 return wxDataViewItem(0);
617 }
618
619 bool wxDataViewVirtualListModel::IsContainer( const wxDataViewItem &item ) const
620 {
621 // only the invisible root item has children
622 if (!item.IsOk())
623 return true;
624
625 return false;
626 }
627
628 unsigned int wxDataViewVirtualListModel::GetChildren( const wxDataViewItem &WXUNUSED(item), wxDataViewItemArray &WXUNUSED(children) ) const
629 {
630 return 0; // should we report an error ?
631 }
632
633 #endif // __WXMAC__
634
635 //-----------------------------------------------------------------------------
636 // wxDataViewIconText
637 //-----------------------------------------------------------------------------
638
639 IMPLEMENT_DYNAMIC_CLASS(wxDataViewIconText,wxObject)
640
641 IMPLEMENT_VARIANT_OBJECT_EXPORTED(wxDataViewIconText, WXDLLIMPEXP_ADV)
642
643 bool operator == (const wxDataViewIconText &one, const wxDataViewIconText &two)
644 {
645 if (one.GetText() != two.GetText()) return false;
646 if (one.IsSameAs(two)) return false;
647 return true;
648 }
649
650 // ---------------------------------------------------------
651 // wxDataViewRendererBase
652 // ---------------------------------------------------------
653
654 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRendererBase, wxObject)
655
656 wxDataViewRendererBase::wxDataViewRendererBase( const wxString &varianttype,
657 wxDataViewCellMode WXUNUSED(mode),
658 int WXUNUSED(align) )
659 {
660 m_variantType = varianttype;
661 m_editorCtrl = NULL;
662 m_owner = NULL;
663 }
664
665 const wxDataViewCtrl* wxDataViewRendererBase::GetView() const
666 {
667 return wx_const_cast(wxDataViewRendererBase*, this)->GetOwner()->GetOwner();
668 }
669
670 bool wxDataViewRendererBase::StartEditing( const wxDataViewItem &item, wxRect labelRect )
671 {
672 m_item = item; // remember for later
673
674 unsigned int col = GetOwner()->GetModelColumn();
675 wxVariant value;
676 GetOwner()->GetOwner()->GetModel()->GetValue( value, item, col );
677
678 m_editorCtrl = CreateEditorCtrl( GetOwner()->GetOwner()->GetMainWindow(), labelRect, value );
679
680 wxDataViewEditorCtrlEvtHandler *handler =
681 new wxDataViewEditorCtrlEvtHandler( m_editorCtrl, (wxDataViewRenderer*) this );
682
683 m_editorCtrl->PushEventHandler( handler );
684
685 #if defined(__WXGTK20__) && !defined(wxUSE_GENERICDATAVIEWCTRL)
686 handler->SetFocusOnIdle();
687 #else
688 m_editorCtrl->SetFocus();
689 #endif
690
691 // Now we should send Editing Started event
692 wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED, GetOwner()->GetOwner()->GetId() );
693 event.SetDataViewColumn( GetOwner() );
694 event.SetModel( GetOwner()->GetOwner()->GetModel() );
695 event.SetItem( item );
696 GetOwner()->GetOwner()->GetEventHandler()->ProcessEvent( event );
697
698 return true;
699 }
700
701 void wxDataViewRendererBase::CancelEditing()
702 {
703 wxPendingDelete.Append( m_editorCtrl );
704
705 GetOwner()->GetOwner()->GetMainWindow()->SetFocus();
706
707 // m_editorCtrl->PopEventHandler( true );
708 }
709
710 bool wxDataViewRendererBase::FinishEditing()
711 {
712 wxVariant value;
713 GetValueFromEditorCtrl( m_editorCtrl, value );
714
715 wxPendingDelete.Append( m_editorCtrl );
716
717 GetOwner()->GetOwner()->GetMainWindow()->SetFocus();
718
719 if (!Validate(value))
720 return false;
721
722 unsigned int col = GetOwner()->GetModelColumn();
723 GetOwner()->GetOwner()->GetModel()->SetValue( value, m_item, col );
724 GetOwner()->GetOwner()->GetModel()->ValueChanged( m_item, col );
725
726 // m_editorCtrl->PopEventHandler( true );
727
728 // Now we should send Editing Done event
729 wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE, GetOwner()->GetOwner()->GetId() );
730 event.SetDataViewColumn( GetOwner() );
731 event.SetModel( GetOwner()->GetOwner()->GetModel() );
732 event.SetItem( m_item );
733 GetOwner()->GetOwner()->GetEventHandler()->ProcessEvent( event );
734
735 return true;
736 }
737
738 //-----------------------------------------------------------------------------
739 // wxDataViewEditorCtrlEvtHandler
740 //-----------------------------------------------------------------------------
741
742 BEGIN_EVENT_TABLE(wxDataViewEditorCtrlEvtHandler, wxEvtHandler)
743 EVT_CHAR (wxDataViewEditorCtrlEvtHandler::OnChar)
744 EVT_KILL_FOCUS (wxDataViewEditorCtrlEvtHandler::OnKillFocus)
745 EVT_IDLE (wxDataViewEditorCtrlEvtHandler::OnIdle)
746 END_EVENT_TABLE()
747
748 wxDataViewEditorCtrlEvtHandler::wxDataViewEditorCtrlEvtHandler(
749 wxControl *editorCtrl,
750 wxDataViewRenderer *owner )
751 {
752 m_owner = owner;
753 m_editorCtrl = editorCtrl;
754
755 m_finished = false;
756 }
757
758 void wxDataViewEditorCtrlEvtHandler::OnIdle( wxIdleEvent &event )
759 {
760 if (m_focusOnIdle)
761 {
762 m_focusOnIdle = false;
763 if (wxWindow::FindFocus() != m_editorCtrl)
764 m_editorCtrl->SetFocus();
765 }
766
767 event.Skip();
768 }
769
770 void wxDataViewEditorCtrlEvtHandler::OnChar( wxKeyEvent &event )
771 {
772 switch ( event.m_keyCode )
773 {
774 case WXK_RETURN:
775 wxPrintf( "OnChar RETURN\n" );
776 m_finished = true;
777 m_owner->FinishEditing();
778 break;
779
780 case WXK_ESCAPE:
781 m_finished = true;
782 m_owner->CancelEditing();
783 break;
784
785 default:
786 event.Skip();
787 }
788 }
789
790 void wxDataViewEditorCtrlEvtHandler::OnKillFocus( wxFocusEvent &event )
791 {
792 if (!m_finished)
793 {
794 wxPrintf( "OnKillFocus\n" );
795 m_finished = true;
796 m_owner->FinishEditing();
797 }
798
799 event.Skip();
800 }
801
802 // ---------------------------------------------------------
803 // wxDataViewColumnBase
804 // ---------------------------------------------------------
805
806 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumnBase, wxObject)
807
808 wxDataViewColumnBase::wxDataViewColumnBase(const wxString& WXUNUSED(title),
809 wxDataViewRenderer *renderer,
810 unsigned int model_column,
811 int WXUNUSED(width),
812 wxAlignment WXUNUSED(align),
813 int WXUNUSED(flags))
814 {
815 m_renderer = renderer;
816 m_model_column = model_column;
817 m_owner = NULL;
818 m_renderer->SetOwner( (wxDataViewColumn*) this );
819
820 // NOTE: the wxDataViewColumn's ctor must store the width, align, flags
821 // parameters inside the native control!
822 }
823
824 wxDataViewColumnBase::wxDataViewColumnBase(const wxBitmap& bitmap,
825 wxDataViewRenderer *renderer,
826 unsigned int model_column,
827 int WXUNUSED(width),
828 wxAlignment WXUNUSED(align),
829 int WXUNUSED(flags) )
830 {
831 m_renderer = renderer;
832 m_model_column = model_column;
833 m_bitmap = bitmap;
834 m_owner = NULL;
835 m_renderer->SetOwner( (wxDataViewColumn*) this );
836 }
837
838 wxDataViewColumnBase::~wxDataViewColumnBase()
839 {
840 if (m_renderer)
841 delete m_renderer;
842 }
843
844 int wxDataViewColumnBase::GetFlags() const
845 {
846 int ret = 0;
847
848 if (IsSortable())
849 ret |= wxDATAVIEW_COL_SORTABLE;
850 if (IsResizeable())
851 ret |= wxDATAVIEW_COL_RESIZABLE;
852 if (IsHidden())
853 ret |= wxDATAVIEW_COL_HIDDEN;
854
855 return ret;
856 }
857
858 void wxDataViewColumnBase::SetFlags(int flags)
859 {
860 SetSortable((flags & wxDATAVIEW_COL_SORTABLE) != 0);
861 SetResizeable((flags & wxDATAVIEW_COL_RESIZABLE) != 0);
862 SetHidden((flags & wxDATAVIEW_COL_HIDDEN) != 0);
863 SetReorderable((flags & wxDATAVIEW_COL_REORDERABLE) != 0);
864 }
865
866 // ---------------------------------------------------------
867 // wxDataViewCtrlBase
868 // ---------------------------------------------------------
869
870 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCtrlBase, wxControl)
871
872 wxDataViewCtrlBase::wxDataViewCtrlBase()
873 {
874 m_model = NULL;
875 m_expander_column = 0;
876 m_indent = 8;
877 }
878
879 wxDataViewCtrlBase::~wxDataViewCtrlBase()
880 {
881 if (m_model)
882 {
883 m_model->DecRef();
884 m_model = NULL;
885 }
886 }
887
888 bool wxDataViewCtrlBase::AssociateModel( wxDataViewModel *model )
889 {
890 if (m_model)
891 {
892 m_model->DecRef(); // discard old model, if any
893 }
894
895 // add our own reference to the new model:
896 m_model = model;
897 if (m_model)
898 {
899 m_model->IncRef();
900 }
901
902 return true;
903 }
904
905 wxDataViewModel* wxDataViewCtrlBase::GetModel()
906 {
907 return m_model;
908 }
909
910 const wxDataViewModel* wxDataViewCtrlBase::GetModel() const
911 {
912 return m_model;
913 }
914
915 wxDataViewColumn *
916 wxDataViewCtrlBase::AppendTextColumn( const wxString &label, unsigned int model_column,
917 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
918 {
919 wxDataViewColumn *ret = new wxDataViewColumn( label,
920 new wxDataViewTextRenderer( wxT("string"), mode ),
921 model_column, width, align, flags );
922 AppendColumn( ret );
923 return ret;
924 }
925
926 wxDataViewColumn *
927 wxDataViewCtrlBase::AppendIconTextColumn( const wxString &label, unsigned int model_column,
928 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
929 {
930 wxDataViewColumn *ret = new wxDataViewColumn( label,
931 new wxDataViewIconTextRenderer( wxT("wxDataViewIconText"), mode ),
932 model_column, width, align, flags );
933 AppendColumn( ret );
934 return ret;
935 }
936
937 wxDataViewColumn *
938 wxDataViewCtrlBase::AppendToggleColumn( const wxString &label, unsigned int model_column,
939 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
940 {
941
942 wxDataViewColumn *ret = new wxDataViewColumn( label,
943 new wxDataViewToggleRenderer( wxT("bool"), mode ),
944 model_column, width, align, flags );
945 AppendColumn( ret );
946 return ret;
947 }
948
949 wxDataViewColumn *
950 wxDataViewCtrlBase::AppendProgressColumn( const wxString &label, unsigned int model_column,
951 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
952 {
953 wxDataViewColumn *ret = new wxDataViewColumn( label,
954 new wxDataViewProgressRenderer( wxEmptyString, wxT("long"), mode ),
955 model_column, width, align, flags );
956 AppendColumn( ret );
957 return ret;
958 }
959
960 wxDataViewColumn *
961 wxDataViewCtrlBase::AppendDateColumn( const wxString &label, unsigned int model_column,
962 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
963 {
964 wxDataViewColumn *ret = new wxDataViewColumn( label,
965 new wxDataViewDateRenderer( wxT("datetime"), mode ),
966 model_column, width, align, flags );
967 AppendColumn( ret );
968 return ret;
969 }
970
971 wxDataViewColumn *
972 wxDataViewCtrlBase::AppendBitmapColumn( const wxString &label, unsigned int model_column,
973 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
974 {
975 wxDataViewColumn *ret = new wxDataViewColumn( label,
976 new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode ),
977 model_column, width, align, flags );
978 AppendColumn( ret );
979 return ret;
980 }
981
982 wxDataViewColumn *
983 wxDataViewCtrlBase::AppendTextColumn( const wxBitmap &label, unsigned int model_column,
984 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
985 {
986 wxDataViewColumn *ret = new wxDataViewColumn( label,
987 new wxDataViewTextRenderer( wxT("string"), mode ),
988 model_column, width, align, flags );
989 AppendColumn( ret );
990 return ret;
991 }
992
993 wxDataViewColumn *
994 wxDataViewCtrlBase::AppendIconTextColumn( const wxBitmap &label, unsigned int model_column,
995 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
996 {
997 wxDataViewColumn *ret = new wxDataViewColumn( label,
998 new wxDataViewIconTextRenderer( wxT("wxDataViewIconText"), mode ),
999 model_column, width, align, flags );
1000 AppendColumn( ret );
1001 return ret;
1002 }
1003
1004 wxDataViewColumn *
1005 wxDataViewCtrlBase::AppendToggleColumn( const wxBitmap &label, unsigned int model_column,
1006 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1007 {
1008 wxDataViewColumn *ret = new wxDataViewColumn( label,
1009 new wxDataViewToggleRenderer( wxT("bool"), mode ),
1010 model_column, width, align, flags );
1011 AppendColumn( ret );
1012 return ret;
1013 }
1014
1015 wxDataViewColumn *
1016 wxDataViewCtrlBase::AppendProgressColumn( const wxBitmap &label, unsigned int model_column,
1017 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1018 {
1019 wxDataViewColumn *ret = new wxDataViewColumn( label,
1020 new wxDataViewProgressRenderer( wxEmptyString, wxT("long"), mode ),
1021 model_column, width, align, flags );
1022 AppendColumn( ret );
1023 return ret;
1024 }
1025
1026 wxDataViewColumn *
1027 wxDataViewCtrlBase::AppendDateColumn( const wxBitmap &label, unsigned int model_column,
1028 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1029 {
1030 wxDataViewColumn *ret = new wxDataViewColumn( label,
1031 new wxDataViewDateRenderer( wxT("datetime"), mode ),
1032 model_column, width, align, flags );
1033 AppendColumn( ret );
1034 return ret;
1035 }
1036
1037 wxDataViewColumn *
1038 wxDataViewCtrlBase::AppendBitmapColumn( const wxBitmap &label, unsigned int model_column,
1039 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1040 {
1041 wxDataViewColumn *ret = new wxDataViewColumn( label,
1042 new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode ),
1043 model_column, width, align, flags );
1044 AppendColumn( ret );
1045 return ret;
1046 }
1047
1048 wxDataViewColumn *
1049 wxDataViewCtrlBase::PrependTextColumn( const wxString &label, unsigned int model_column,
1050 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1051 {
1052 wxDataViewColumn *ret = new wxDataViewColumn( label,
1053 new wxDataViewTextRenderer( wxT("string"), mode ),
1054 model_column, width, align, flags );
1055 PrependColumn( ret );
1056 return ret;
1057 }
1058
1059 wxDataViewColumn *
1060 wxDataViewCtrlBase::PrependIconTextColumn( const wxString &label, unsigned int model_column,
1061 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1062 {
1063 wxDataViewColumn *ret = new wxDataViewColumn( label,
1064 new wxDataViewIconTextRenderer( wxT("wxDataViewIconText"), mode ),
1065 model_column, width, align, flags );
1066 PrependColumn( ret );
1067 return ret;
1068 }
1069
1070 wxDataViewColumn *
1071 wxDataViewCtrlBase::PrependToggleColumn( const wxString &label, unsigned int model_column,
1072 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1073 {
1074
1075 wxDataViewColumn *ret = new wxDataViewColumn( label,
1076 new wxDataViewToggleRenderer( wxT("bool"), mode ),
1077 model_column, width, align, flags );
1078 PrependColumn( ret );
1079 return ret;
1080 }
1081
1082 wxDataViewColumn *
1083 wxDataViewCtrlBase::PrependProgressColumn( const wxString &label, unsigned int model_column,
1084 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1085 {
1086 wxDataViewColumn *ret = new wxDataViewColumn( label,
1087 new wxDataViewProgressRenderer( wxEmptyString, wxT("long"), mode ),
1088 model_column, width, align, flags );
1089 PrependColumn( ret );
1090 return ret;
1091 }
1092
1093 wxDataViewColumn *
1094 wxDataViewCtrlBase::PrependDateColumn( const wxString &label, unsigned int model_column,
1095 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1096 {
1097 wxDataViewColumn *ret = new wxDataViewColumn( label,
1098 new wxDataViewDateRenderer( wxT("datetime"), mode ),
1099 model_column, width, align, flags );
1100 PrependColumn( ret );
1101 return ret;
1102 }
1103
1104 wxDataViewColumn *
1105 wxDataViewCtrlBase::PrependBitmapColumn( const wxString &label, unsigned int model_column,
1106 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1107 {
1108 wxDataViewColumn *ret = new wxDataViewColumn( label,
1109 new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode ),
1110 model_column, width, align, flags );
1111 PrependColumn( ret );
1112 return ret;
1113 }
1114
1115 wxDataViewColumn *
1116 wxDataViewCtrlBase::PrependTextColumn( const wxBitmap &label, unsigned int model_column,
1117 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1118 {
1119 wxDataViewColumn *ret = new wxDataViewColumn( label,
1120 new wxDataViewTextRenderer( wxT("string"), mode ),
1121 model_column, width, align, flags );
1122 PrependColumn( ret );
1123 return ret;
1124 }
1125
1126 wxDataViewColumn *
1127 wxDataViewCtrlBase::PrependIconTextColumn( const wxBitmap &label, unsigned int model_column,
1128 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1129 {
1130 wxDataViewColumn *ret = new wxDataViewColumn( label,
1131 new wxDataViewIconTextRenderer( wxT("wxDataViewIconText"), mode ),
1132 model_column, width, align, flags );
1133 PrependColumn( ret );
1134 return ret;
1135 }
1136
1137 wxDataViewColumn *
1138 wxDataViewCtrlBase::PrependToggleColumn( const wxBitmap &label, unsigned int model_column,
1139 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1140 {
1141 wxDataViewColumn *ret = new wxDataViewColumn( label,
1142 new wxDataViewToggleRenderer( wxT("bool"), mode ),
1143 model_column, width, align, flags );
1144 PrependColumn( ret );
1145 return ret;
1146 }
1147
1148 wxDataViewColumn *
1149 wxDataViewCtrlBase::PrependProgressColumn( const wxBitmap &label, unsigned int model_column,
1150 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1151 {
1152 wxDataViewColumn *ret = new wxDataViewColumn( label,
1153 new wxDataViewProgressRenderer( wxEmptyString, wxT("long"), mode ),
1154 model_column, width, align, flags );
1155 PrependColumn( ret );
1156 return ret;
1157 }
1158
1159 wxDataViewColumn *
1160 wxDataViewCtrlBase::PrependDateColumn( const wxBitmap &label, unsigned int model_column,
1161 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1162 {
1163 wxDataViewColumn *ret = new wxDataViewColumn( label,
1164 new wxDataViewDateRenderer( wxT("datetime"), mode ),
1165 model_column, width, align, flags );
1166 PrependColumn( ret );
1167 return ret;
1168 }
1169
1170 wxDataViewColumn *
1171 wxDataViewCtrlBase::PrependBitmapColumn( const wxBitmap &label, unsigned int model_column,
1172 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1173 {
1174 wxDataViewColumn *ret = new wxDataViewColumn( label,
1175 new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode ),
1176 model_column, width, align, flags );
1177 PrependColumn( ret );
1178 return ret;
1179 }
1180
1181 bool
1182 wxDataViewCtrlBase::AppendColumn( wxDataViewColumn *col )
1183 {
1184 col->SetOwner( (wxDataViewCtrl*) this );
1185 return true;
1186 }
1187
1188 bool
1189 wxDataViewCtrlBase::PrependColumn( wxDataViewColumn *col )
1190 {
1191 col->SetOwner( (wxDataViewCtrl*) this );
1192 return true;
1193 }
1194
1195 // ---------------------------------------------------------
1196 // wxDataViewEvent
1197 // ---------------------------------------------------------
1198
1199 IMPLEMENT_DYNAMIC_CLASS(wxDataViewEvent,wxNotifyEvent)
1200
1201 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED)
1202
1203 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED)
1204 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING)
1205 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED)
1206 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING)
1207 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED)
1208 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED)
1209 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE)
1210 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED)
1211
1212 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU)
1213
1214 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK)
1215 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK)
1216 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED)
1217 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_REORDERED)
1218
1219
1220 // -------------------------------------
1221 // wxDataViewSpinRenderer
1222 // -------------------------------------
1223
1224 wxDataViewSpinRenderer::wxDataViewSpinRenderer( int min, int max, wxDataViewCellMode mode, int alignment ) :
1225 wxDataViewCustomRenderer(wxT("long"), mode, alignment )
1226 {
1227 m_min = min;
1228 m_max = max;
1229 }
1230
1231 wxControl* wxDataViewSpinRenderer::CreateEditorCtrl( wxWindow *parent, wxRect labelRect, const wxVariant &value )
1232 {
1233 long l = value;
1234 wxSize size = labelRect.GetSize();
1235 #ifdef __WXMAC__
1236 size = wxSize( wxMax(70,labelRect.width ), -1 );
1237 #endif
1238 wxString str;
1239 str.Printf( wxT("%d"), (int) l );
1240 wxSpinCtrl *sc = new wxSpinCtrl( parent, wxID_ANY, str,
1241 labelRect.GetTopLeft(), size, wxSP_ARROW_KEYS, m_min, m_max, l );
1242 #ifdef __WXMAC__
1243 size = sc->GetSize();
1244 wxPoint pt = sc->GetPosition();
1245 sc->SetSize( pt.x - 4, pt.y - 4, size.x, size.y );
1246 #endif
1247
1248 return sc;
1249 }
1250
1251 bool wxDataViewSpinRenderer::GetValueFromEditorCtrl( wxControl* editor, wxVariant &value )
1252 {
1253 wxSpinCtrl *sc = (wxSpinCtrl*) editor;
1254 long l = sc->GetValue();
1255 value = l;
1256 return true;
1257 }
1258
1259 bool wxDataViewSpinRenderer::Render( wxRect rect, wxDC *dc, int state )
1260 {
1261 wxString str;
1262 str.Printf(wxT("%d"), (int) m_data );
1263 RenderText( str, 0, rect, dc, state );
1264 return true;
1265 }
1266
1267 wxSize wxDataViewSpinRenderer::GetSize() const
1268 {
1269 return wxSize(80,16);
1270 }
1271
1272 bool wxDataViewSpinRenderer::SetValue( const wxVariant &value )
1273 {
1274 m_data = value.GetLong();
1275 return true;
1276 }
1277
1278 bool wxDataViewSpinRenderer::GetValue( wxVariant &value ) const
1279 {
1280 value = m_data;
1281 return true;
1282 }
1283
1284 //-----------------------------------------------------------------------------
1285 // wxDataViewTreeStore
1286 //-----------------------------------------------------------------------------
1287
1288 wxDataViewTreeStoreNode::wxDataViewTreeStoreNode(
1289 wxDataViewTreeStoreNode *parent,
1290 const wxString &text, const wxIcon &icon, wxClientData *data )
1291 {
1292 m_parent = parent;
1293 m_text = text;
1294 m_icon = icon;
1295 m_data = data;
1296 }
1297
1298 wxDataViewTreeStoreNode::~wxDataViewTreeStoreNode()
1299 {
1300 if (m_data)
1301 delete m_data;
1302 }
1303
1304 #include "wx/listimpl.cpp"
1305 WX_DEFINE_LIST(wxDataViewTreeStoreNodeList)
1306
1307 wxDataViewTreeStoreContainerNode::wxDataViewTreeStoreContainerNode(
1308 wxDataViewTreeStoreNode *parent, const wxString &text,
1309 const wxIcon &icon, const wxIcon &expanded, wxClientData *data ) :
1310 wxDataViewTreeStoreNode( parent, text, icon, data )
1311 {
1312 m_iconExpanded = expanded;
1313 m_isExpanded = false;
1314 m_children.DeleteContents(true);
1315 }
1316
1317 wxDataViewTreeStoreContainerNode::~wxDataViewTreeStoreContainerNode()
1318 {
1319 }
1320
1321 //-----------------------------------------------------------------------------
1322
1323 wxDataViewTreeStore::wxDataViewTreeStore()
1324 {
1325 m_root = new wxDataViewTreeStoreContainerNode( NULL, wxEmptyString );
1326 }
1327
1328 wxDataViewTreeStore::~wxDataViewTreeStore()
1329 {
1330 delete m_root;
1331 }
1332
1333 wxDataViewItem wxDataViewTreeStore::AppendItem( const wxDataViewItem& parent,
1334 const wxString &text, const wxIcon &icon, wxClientData *data )
1335 {
1336 wxDataViewTreeStoreContainerNode *parent_node = FindContainerNode( parent );
1337 if (!parent_node) return wxDataViewItem(0);
1338
1339 wxDataViewTreeStoreNode *node =
1340 new wxDataViewTreeStoreNode( parent_node, text, icon, data );
1341 parent_node->GetChildren().Append( node );
1342
1343 // notify control
1344 ItemAdded( parent, node->GetItem() );
1345
1346 return node->GetItem();
1347 }
1348
1349 wxDataViewItem wxDataViewTreeStore::PrependItem( const wxDataViewItem& parent,
1350 const wxString &text, const wxIcon &icon, wxClientData *data )
1351 {
1352 wxDataViewTreeStoreContainerNode *parent_node = FindContainerNode( parent );
1353 if (!parent_node) return wxDataViewItem(0);
1354
1355 wxDataViewTreeStoreNode *node =
1356 new wxDataViewTreeStoreNode( parent_node, text, icon, data );
1357 parent_node->GetChildren().Insert( node );
1358
1359 // notify control
1360 ItemAdded( parent, node->GetItem() );
1361
1362 return node->GetItem();
1363 }
1364
1365 wxDataViewItem
1366 wxDataViewTreeStore::InsertItem(const wxDataViewItem& WXUNUSED(parent),
1367 const wxDataViewItem& WXUNUSED(previous),
1368 const wxString& WXUNUSED(text),
1369 const wxIcon& WXUNUSED(icon),
1370 wxClientData * WXUNUSED(data))
1371 {
1372 return wxDataViewItem(0);
1373 }
1374
1375 wxDataViewItem wxDataViewTreeStore::PrependContainer( const wxDataViewItem& parent,
1376 const wxString &text, const wxIcon &icon, const wxIcon &expanded,
1377 wxClientData *data )
1378 {
1379 wxDataViewTreeStoreContainerNode *parent_node = FindContainerNode( parent );
1380 if (!parent_node) return wxDataViewItem(0);
1381
1382 wxDataViewTreeStoreContainerNode *node =
1383 new wxDataViewTreeStoreContainerNode( parent_node, text, icon, expanded, data );
1384 parent_node->GetChildren().Insert( node );
1385
1386 // notify control
1387 ItemAdded( parent, node->GetItem() );
1388
1389 return node->GetItem();
1390 }
1391
1392 wxDataViewItem
1393 wxDataViewTreeStore::AppendContainer(const wxDataViewItem& parent,
1394 const wxString &text,
1395 const wxIcon& icon,
1396 const wxIcon& expanded,
1397 wxClientData * data)
1398 {
1399 wxDataViewTreeStoreContainerNode *parent_node = FindContainerNode( parent );
1400 if (!parent_node) return wxDataViewItem(0);
1401
1402 wxDataViewTreeStoreContainerNode *node =
1403 new wxDataViewTreeStoreContainerNode( parent_node, text, icon, expanded, data );
1404 parent_node->GetChildren().Append( node );
1405
1406 // notify control
1407 ItemAdded( parent, node->GetItem() );
1408
1409 return node->GetItem();
1410 }
1411
1412 wxDataViewItem
1413 wxDataViewTreeStore::InsertContainer(const wxDataViewItem& WXUNUSED(parent),
1414 const wxDataViewItem& WXUNUSED(previous),
1415 const wxString& WXUNUSED(text),
1416 const wxIcon& WXUNUSED(icon),
1417 const wxIcon& WXUNUSED(expanded),
1418 wxClientData * WXUNUSED(data))
1419 {
1420 return wxDataViewItem(0);
1421 }
1422
1423 wxDataViewItem wxDataViewTreeStore::GetNthChild( const wxDataViewItem& parent, unsigned int pos ) const
1424 {
1425 wxDataViewTreeStoreContainerNode *parent_node = FindContainerNode( parent );
1426 if (!parent_node) return wxDataViewItem(0);
1427
1428 wxDataViewTreeStoreNodeList::compatibility_iterator node = parent_node->GetChildren().Item( pos );
1429 if (node)
1430 return node->GetData();
1431
1432 return wxDataViewItem(0);
1433 }
1434
1435 int wxDataViewTreeStore::GetChildCount( const wxDataViewItem& parent ) const
1436 {
1437 wxDataViewTreeStoreNode *node = FindNode( parent );
1438 if (!node) return -1;
1439
1440 if (!node->IsContainer())
1441 return 0;
1442
1443 wxDataViewTreeStoreContainerNode *container_node = (wxDataViewTreeStoreContainerNode*) node;
1444 return (int) container_node->GetChildren().GetCount();
1445 }
1446
1447 void wxDataViewTreeStore::SetItemText( const wxDataViewItem& item, const wxString &text )
1448 {
1449 wxDataViewTreeStoreNode *node = FindNode( item );
1450 if (!node) return;
1451
1452 node->SetText( text );
1453
1454 // notify control
1455 ValueChanged( item, 0 );
1456 }
1457
1458 wxString wxDataViewTreeStore::GetItemText( const wxDataViewItem& item ) const
1459 {
1460 wxDataViewTreeStoreNode *node = FindNode( item );
1461 if (!node) return wxEmptyString;
1462
1463 return node->GetText();
1464 }
1465
1466 void wxDataViewTreeStore::SetItemIcon( const wxDataViewItem& item, const wxIcon &icon )
1467 {
1468 wxDataViewTreeStoreNode *node = FindNode( item );
1469 if (!node) return;
1470
1471 node->SetIcon( icon );
1472
1473 // notify control
1474 ValueChanged( item, 0 );
1475 }
1476
1477 const wxIcon &wxDataViewTreeStore::GetItemIcon( const wxDataViewItem& item ) const
1478 {
1479 wxDataViewTreeStoreNode *node = FindNode( item );
1480 if (!node) return wxNullIcon;
1481
1482 return node->GetIcon();
1483 }
1484
1485 void wxDataViewTreeStore::SetItemExpandedIcon( const wxDataViewItem& item, const wxIcon &icon )
1486 {
1487 wxDataViewTreeStoreContainerNode *node = FindContainerNode( item );
1488 if (!node) return;
1489
1490 node->SetExpandedIcon( icon );
1491
1492 // notify control
1493 ValueChanged( item, 0 );
1494 }
1495
1496 const wxIcon &wxDataViewTreeStore::GetItemExpandedIcon( const wxDataViewItem& item ) const
1497 {
1498 wxDataViewTreeStoreContainerNode *node = FindContainerNode( item );
1499 if (!node) return wxNullIcon;
1500
1501 return node->GetExpandedIcon();
1502 }
1503
1504 void wxDataViewTreeStore::SetItemData( const wxDataViewItem& item, wxClientData *data )
1505 {
1506 wxDataViewTreeStoreNode *node = FindNode( item );
1507 if (!node) return;
1508
1509 node->SetData( data );
1510
1511 // notify control? only sensible when sorting on client data
1512 // ValueChanged( item, 0 );
1513 }
1514
1515 wxClientData *wxDataViewTreeStore::GetItemData( const wxDataViewItem& item ) const
1516 {
1517 wxDataViewTreeStoreNode *node = FindNode( item );
1518 if (!node) return NULL;
1519
1520 return node->GetData();
1521 }
1522
1523 void wxDataViewTreeStore::DeleteItem( const wxDataViewItem& item )
1524 {
1525 if (!item.IsOk()) return;
1526
1527 wxDataViewItem parent_item = GetParent( item );
1528
1529 wxDataViewTreeStoreContainerNode *parent_node = FindContainerNode( parent_item );
1530 if (!parent_node) return;
1531
1532 wxDataViewTreeStoreContainerNode *node = FindContainerNode( item );
1533 if (!node) return;
1534
1535 parent_node->GetChildren().DeleteObject( node );
1536
1537 // notify control
1538 ItemDeleted( parent_item, item );
1539 }
1540
1541 void wxDataViewTreeStore::DeleteChildren( const wxDataViewItem& item )
1542 {
1543 wxDataViewTreeStoreContainerNode *node = FindContainerNode( item );
1544 if (!node) return;
1545
1546 wxDataViewItemArray array;
1547 wxDataViewTreeStoreNodeList::iterator iter;
1548 for (iter = node->GetChildren().begin(); iter != node->GetChildren().end(); iter++)
1549 {
1550 wxDataViewTreeStoreNode* child = *iter;
1551 array.Add( child->GetItem() );
1552 }
1553
1554 node->GetChildren().clear();
1555
1556 // notify control
1557 ItemsDeleted( item, array );
1558 }
1559
1560 void wxDataViewTreeStore::DeleteAllItems()
1561 {
1562 // TODO
1563 }
1564
1565 void
1566 wxDataViewTreeStore::GetValue(wxVariant &variant,
1567 const wxDataViewItem &item,
1568 unsigned int WXUNUSED(col)) const
1569 {
1570 // if (col != 0) return;
1571
1572 wxDataViewTreeStoreNode *node = FindNode( item );
1573 if (!node) return;
1574
1575 wxIcon icon( node->GetIcon());
1576 if (node->IsContainer())
1577 {
1578 wxDataViewTreeStoreContainerNode *container = (wxDataViewTreeStoreContainerNode*) node;
1579 if (container->IsExpanded() && container->GetExpandedIcon().IsOk())
1580 icon = container->GetExpandedIcon();
1581 }
1582
1583 wxDataViewIconText data( node->GetText(), icon );
1584
1585 variant << data;
1586 }
1587
1588 bool
1589 wxDataViewTreeStore::SetValue(const wxVariant& variant,
1590 const wxDataViewItem& item,
1591 unsigned int WXUNUSED(col))
1592 {
1593 // if (col != 0) return false;
1594
1595 wxDataViewTreeStoreNode *node = FindNode( item );
1596 if (!node) return false;
1597
1598 wxDataViewIconText data;
1599
1600 data << variant;
1601
1602 node->SetText( data.GetText() );
1603 node->SetIcon( data.GetIcon() );
1604
1605 return true;
1606 }
1607
1608 wxDataViewItem wxDataViewTreeStore::GetParent( const wxDataViewItem &item ) const
1609 {
1610 wxDataViewTreeStoreNode *node = FindNode( item );
1611 if (!node) return wxDataViewItem(0);
1612
1613 wxDataViewTreeStoreNode *parent = node->GetParent();
1614 if (!parent) return wxDataViewItem(0);
1615
1616 if (parent == m_root)
1617 return wxDataViewItem(0);
1618
1619 return parent->GetItem();
1620 }
1621
1622 bool wxDataViewTreeStore::IsContainer( const wxDataViewItem &item ) const
1623 {
1624 wxDataViewTreeStoreNode *node = FindNode( item );
1625 if (!node) return false;
1626
1627 return node->IsContainer();
1628 }
1629
1630 unsigned int wxDataViewTreeStore::GetChildren( const wxDataViewItem &item, wxDataViewItemArray &children ) const
1631 {
1632 wxDataViewTreeStoreContainerNode *node = FindContainerNode( item );
1633 if (!node) return 0;
1634
1635 wxDataViewTreeStoreNodeList::iterator iter;
1636 for (iter = node->GetChildren().begin(); iter != node->GetChildren().end(); iter++)
1637 {
1638 wxDataViewTreeStoreNode* child = *iter;
1639 children.Add( child->GetItem() );
1640 }
1641
1642 return node->GetChildren().GetCount();
1643 }
1644
1645 int wxDataViewTreeStore::Compare( const wxDataViewItem &item1, const wxDataViewItem &item2,
1646 unsigned int WXUNUSED(column), bool WXUNUSED(ascending) )
1647 {
1648 wxDataViewTreeStoreNode *node1 = FindNode( item1 );
1649 wxDataViewTreeStoreNode *node2 = FindNode( item2 );
1650
1651 if (!node1 || !node2)
1652 return 0;
1653
1654 wxDataViewTreeStoreContainerNode* parent1 =
1655 (wxDataViewTreeStoreContainerNode*) node1->GetParent();
1656 wxDataViewTreeStoreContainerNode* parent2 =
1657 (wxDataViewTreeStoreContainerNode*) node2->GetParent();
1658
1659 if (parent1 != parent2)
1660 {
1661 wxLogError( wxT("Comparing items with different parent.") );
1662 return 0;
1663 }
1664
1665 if (node1->IsContainer() && !!node2->IsContainer())
1666 return 1;
1667
1668 if (node2->IsContainer() && !!node1->IsContainer())
1669 return -1;
1670
1671 return parent1->GetChildren().IndexOf( node1 ) - parent1->GetChildren().IndexOf( node2 );
1672 }
1673
1674 wxDataViewTreeStoreNode *wxDataViewTreeStore::FindNode( const wxDataViewItem &item ) const
1675 {
1676 if (!item.IsOk())
1677 return m_root;
1678
1679 return (wxDataViewTreeStoreNode*) item.GetID();
1680 }
1681
1682 wxDataViewTreeStoreContainerNode *wxDataViewTreeStore::FindContainerNode( const wxDataViewItem &item ) const
1683 {
1684 if (!item.IsOk())
1685 return (wxDataViewTreeStoreContainerNode*) m_root;
1686
1687 wxDataViewTreeStoreNode* node = (wxDataViewTreeStoreNode*) item.GetID();
1688
1689 if (!node->IsContainer())
1690 return NULL;
1691
1692 return (wxDataViewTreeStoreContainerNode*) node;
1693 }
1694
1695 //-----------------------------------------------------------------------------
1696 // wxDataViewTreeCtrl
1697 //-----------------------------------------------------------------------------
1698
1699 IMPLEMENT_DYNAMIC_CLASS(wxDataViewTreeCtrl,wxDataViewCtrl)
1700
1701 BEGIN_EVENT_TABLE(wxDataViewTreeCtrl,wxDataViewCtrl)
1702 EVT_DATAVIEW_ITEM_EXPANDED(-1, wxDataViewTreeCtrl::OnExpanded)
1703 EVT_DATAVIEW_ITEM_COLLAPSED(-1, wxDataViewTreeCtrl::OnCollapsed)
1704 EVT_SIZE( wxDataViewTreeCtrl::OnSize )
1705 END_EVENT_TABLE()
1706
1707 wxDataViewTreeCtrl::wxDataViewTreeCtrl()
1708 {
1709 m_imageList = NULL;
1710 }
1711
1712 wxDataViewTreeCtrl::wxDataViewTreeCtrl( wxWindow *parent, wxWindowID id,
1713 const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator )
1714 {
1715 m_imageList = NULL;
1716 Create( parent, id, pos, size, style, validator );
1717
1718 wxDataViewTreeStore *store = new wxDataViewTreeStore;
1719 AssociateModel( store );
1720 store->DecRef();
1721
1722 AppendIconTextColumn(wxString(),0,wxDATAVIEW_CELL_INERT,-1);
1723 }
1724
1725 wxDataViewTreeCtrl::~wxDataViewTreeCtrl()
1726 {
1727 if (m_imageList)
1728 delete m_imageList;
1729 }
1730
1731 bool wxDataViewTreeCtrl::Create( wxWindow *parent, wxWindowID id,
1732 const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator )
1733 {
1734 return wxDataViewCtrl::Create( parent, id, pos, size, style, validator );
1735 }
1736
1737 void wxDataViewTreeCtrl::SetImageList( wxImageList *imagelist )
1738 {
1739 if (m_imageList)
1740 delete m_imageList;
1741
1742 m_imageList = imagelist;
1743 }
1744
1745 wxDataViewItem wxDataViewTreeCtrl::AppendItem( const wxDataViewItem& parent,
1746 const wxString &text, int iconIndex, wxClientData *data )
1747 {
1748 wxIcon icon = wxNullIcon;
1749 if (m_imageList && (iconIndex != -1))
1750 icon = m_imageList->GetIcon( iconIndex );
1751
1752 return GetStore()->AppendItem( parent, text, icon, data );
1753 }
1754
1755 wxDataViewItem wxDataViewTreeCtrl::PrependItem( const wxDataViewItem& parent,
1756 const wxString &text, int iconIndex, wxClientData *data )
1757 {
1758 wxIcon icon = wxNullIcon;
1759 if (m_imageList && (iconIndex != -1))
1760 icon = m_imageList->GetIcon( iconIndex );
1761
1762 return GetStore()->PrependItem( parent, text, icon, data );
1763 }
1764
1765 wxDataViewItem wxDataViewTreeCtrl::InsertItem( const wxDataViewItem& parent, const wxDataViewItem& previous,
1766 const wxString &text, int iconIndex, wxClientData *data )
1767 {
1768 wxIcon icon = wxNullIcon;
1769 if (m_imageList && (iconIndex != -1))
1770 icon = m_imageList->GetIcon( iconIndex );
1771
1772 return GetStore()->InsertItem( parent, previous, text, icon, data );
1773 }
1774
1775 wxDataViewItem wxDataViewTreeCtrl::PrependContainer( const wxDataViewItem& parent,
1776 const wxString &text, int iconIndex, int expandedIndex, wxClientData *data )
1777 {
1778 wxIcon icon = wxNullIcon;
1779 if (m_imageList && (iconIndex != -1))
1780 icon = m_imageList->GetIcon( iconIndex );
1781
1782 wxIcon expanded = wxNullIcon;
1783 if (m_imageList && (expandedIndex != -1))
1784 expanded = m_imageList->GetIcon( expandedIndex );
1785
1786 return GetStore()->PrependContainer( parent, text, icon, expanded, data );
1787 }
1788
1789 wxDataViewItem wxDataViewTreeCtrl::AppendContainer( const wxDataViewItem& parent,
1790 const wxString &text, int iconIndex, int expandedIndex, wxClientData *data )
1791 {
1792 wxIcon icon = wxNullIcon;
1793 if (m_imageList && (iconIndex != -1))
1794 icon = m_imageList->GetIcon( iconIndex );
1795
1796 wxIcon expanded = wxNullIcon;
1797 if (m_imageList && (expandedIndex != -1))
1798 expanded = m_imageList->GetIcon( expandedIndex );
1799
1800 return GetStore()->AppendContainer( parent, text, icon, expanded, data );
1801 }
1802
1803 wxDataViewItem wxDataViewTreeCtrl::InsertContainer( const wxDataViewItem& parent, const wxDataViewItem& previous,
1804 const wxString &text, int iconIndex, int expandedIndex, wxClientData *data )
1805 {
1806 wxIcon icon = wxNullIcon;
1807 if (m_imageList && (iconIndex != -1))
1808 icon = m_imageList->GetIcon( iconIndex );
1809
1810 wxIcon expanded = wxNullIcon;
1811 if (m_imageList && (expandedIndex != -1))
1812 expanded = m_imageList->GetIcon( expandedIndex );
1813
1814 return GetStore()->InsertContainer( parent, previous, text, icon, expanded, data );
1815 }
1816
1817 void wxDataViewTreeCtrl::OnExpanded( wxDataViewEvent &event )
1818 {
1819 if (m_imageList) return;
1820
1821 wxDataViewTreeStoreContainerNode* container = GetStore()->FindContainerNode( event.GetItem() );
1822 if (!container) return;
1823
1824 container->SetExpanded( true );
1825 GetStore()->ItemChanged( event.GetItem() );
1826 }
1827
1828 void wxDataViewTreeCtrl::OnCollapsed( wxDataViewEvent &event )
1829 {
1830 if (m_imageList) return;
1831
1832 wxDataViewTreeStoreContainerNode* container = GetStore()->FindContainerNode( event.GetItem() );
1833 if (!container) return;
1834
1835 container->SetExpanded( false );
1836 GetStore()->ItemChanged( event.GetItem() );
1837 }
1838
1839 void wxDataViewTreeCtrl::OnSize( wxSizeEvent &event )
1840 {
1841 #if defined(wxUSE_GENERICDATAVIEWCTRL)
1842 wxSize size = GetClientSize();
1843 wxDataViewColumn *col = GetColumn( 0 );
1844 if (col)
1845 col->SetWidth( size.x );
1846 #endif
1847 event.Skip( true );
1848 }
1849
1850 #endif // wxUSE_DATAVIEWCTRL
1851