]> git.saurik.com Git - wxWidgets.git/blob - src/common/datavcmn.cpp
Implemented dataview_model notification event to the ctrl
[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 #ifndef WX_PRECOMP
23 #include "wx/log.h"
24 #endif
25
26 const wxChar wxDataViewCtrlNameStr[] = wxT("dataviewCtrl");
27
28
29 // ---------------------------------------------------------
30 // wxDataViewListModel
31 // ---------------------------------------------------------
32
33 wxDataViewListModel::wxDataViewListModel()
34 {
35 m_notifiers.DeleteContents( true );
36 }
37
38 wxDataViewListModel::~wxDataViewListModel()
39 {
40 }
41
42 bool wxDataViewListModel::RowAppended()
43 {
44 bool ret = true;
45
46 wxList::compatibility_iterator node = m_notifiers.GetFirst();
47 while (node)
48 {
49 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
50 if (!notifier->RowAppended())
51 ret = false;
52 node = node->GetNext();
53 }
54
55 return ret;
56 }
57
58 bool wxDataViewListModel::RowPrepended()
59 {
60 bool ret = true;
61
62 wxList::compatibility_iterator node = m_notifiers.GetFirst();
63 while (node)
64 {
65 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
66 if (!notifier->RowPrepended())
67 ret = false;
68 node = node->GetNext();
69 }
70
71 return ret;
72 }
73
74 bool wxDataViewListModel::RowInserted( unsigned int before )
75 {
76 bool ret = true;
77
78 wxList::compatibility_iterator node = m_notifiers.GetFirst();
79 while (node)
80 {
81 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
82 if (!notifier->RowInserted(before))
83 ret = false;
84 node = node->GetNext();
85 }
86
87 return ret;
88 }
89
90 bool wxDataViewListModel::RowDeleted( unsigned int row )
91 {
92 bool ret = true;
93
94 wxList::compatibility_iterator node = m_notifiers.GetFirst();
95 while (node)
96 {
97 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
98 if (!notifier->RowDeleted( row ))
99 ret = false;
100 node = node->GetNext();
101 }
102
103 return ret;
104 }
105
106 bool wxDataViewListModel::RowChanged( unsigned int row )
107 {
108 bool ret = true;
109
110 wxList::compatibility_iterator node = m_notifiers.GetFirst();
111 while (node)
112 {
113 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
114 if (!notifier->RowChanged( row ))
115 ret = false;
116 node = node->GetNext();
117 }
118
119 return ret;
120 }
121
122 bool wxDataViewListModel::ValueChanged( unsigned int col, unsigned int row )
123 {
124 bool ret = true;
125
126 wxList::compatibility_iterator node = m_notifiers.GetFirst();
127 while (node)
128 {
129 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
130 if (!notifier->ValueChanged( col, row ))
131 ret = false;
132 node = node->GetNext();
133 }
134
135 return ret;
136 }
137
138 bool wxDataViewListModel::RowsReordered( unsigned int *new_order )
139 {
140 bool ret = true;
141
142 wxList::compatibility_iterator node = m_notifiers.GetFirst();
143 while (node)
144 {
145 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
146 if (!notifier->RowsReordered( new_order ))
147 ret = false;
148 node = node->GetNext();
149 }
150
151 return ret;
152 }
153
154 bool wxDataViewListModel::Cleared()
155 {
156 bool ret = true;
157
158 wxList::compatibility_iterator node = m_notifiers.GetFirst();
159 while (node)
160 {
161 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
162 if (!notifier->Cleared())
163 ret = false;
164 node = node->GetNext();
165 }
166
167 return ret;
168 }
169
170 void wxDataViewListModel::AddNotifier( wxDataViewListModelNotifier *notifier )
171 {
172 m_notifiers.Append( notifier );
173 notifier->SetOwner( this );
174 }
175
176 void wxDataViewListModel::RemoveNotifier( wxDataViewListModelNotifier *notifier )
177 {
178 m_notifiers.DeleteObject( notifier );
179 }
180
181 // ---------------------------------------------------------
182 // wxDataViewSortedListModelNotifier
183 // ---------------------------------------------------------
184
185 class wxDataViewSortedListModelNotifier: public wxDataViewListModelNotifier
186 {
187 public:
188 wxDataViewSortedListModelNotifier( wxDataViewSortedListModel *model )
189 { m_model = model; }
190
191 ~wxDataViewSortedListModelNotifier()
192 { m_model->DetachChild(); }
193
194 virtual bool RowAppended()
195 { return m_model->ChildRowAppended(); }
196
197 virtual bool RowPrepended()
198 { return m_model->ChildRowPrepended(); }
199
200 virtual bool RowInserted( unsigned int before )
201 { return m_model->ChildRowInserted( before ); }
202
203 virtual bool RowDeleted( unsigned int row )
204 { return m_model->ChildRowDeleted( row ); }
205
206 virtual bool RowChanged( unsigned int row )
207 { return m_model->ChildRowChanged( row ); }
208
209 virtual bool ValueChanged( unsigned int col, unsigned int row )
210 { return m_model->ChildValueChanged( col, row); }
211
212 virtual bool RowsReordered( unsigned int *new_order )
213 { return m_model->ChildRowsReordered( new_order ); }
214
215 virtual bool Cleared()
216 { return m_model->ChildCleared(); }
217
218 wxDataViewSortedListModel *m_model;
219 };
220
221 // ---------------------------------------------------------
222 // wxDataViewSortedListModel compare function
223 // ---------------------------------------------------------
224
225 int wxCALLBACK wxDataViewListModelSortedDefaultCompare
226 (unsigned int row1, unsigned int row2, unsigned int col, wxDataViewListModel* model )
227 {
228 wxVariant value1,value2;
229 model->GetValue( value1, col, row1 );
230 model->GetValue( value2, col, row2 );
231 if (value1.GetType() == wxT("string"))
232 {
233 wxString str1 = value1.GetString();
234 wxString str2 = value2.GetString();
235 return str1.Cmp( str2 );
236 }
237 if (value1.GetType() == wxT("long"))
238 {
239 long l1 = value1.GetLong();
240 long l2 = value2.GetLong();
241 return l1-l2;
242 }
243 if (value1.GetType() == wxT("double"))
244 {
245 double d1 = value1.GetDouble();
246 double d2 = value2.GetDouble();
247 if (d1 == d2) return 0;
248 if (d1 < d2) return 1;
249 return -1;
250 }
251 if (value1.GetType() == wxT("datetime"))
252 {
253 wxDateTime dt1 = value1.GetDateTime();
254 wxDateTime dt2 = value2.GetDateTime();
255 if (dt1.IsEqualTo(dt2)) return 0;
256 if (dt1.IsEarlierThan(dt2)) return 1;
257 return -1;
258 }
259
260 return 0;
261 }
262
263 int wxCALLBACK wxDataViewListModelSortedDefaultCompareDescending
264 (unsigned int row1, unsigned int row2, unsigned int col, wxDataViewListModel* model )
265 {
266 return wxDataViewListModelSortedDefaultCompare( row2, row1, col, model );
267 }
268
269 static wxDataViewListModelCompare s_CmpFunc;
270 static wxDataViewListModel *s_CmpModel;
271 static unsigned int s_CmpCol;
272
273 int LINKAGEMODE wxDataViewIntermediateCmp( unsigned int row1, unsigned int row2 )
274 {
275 return s_CmpFunc( row1, row2, s_CmpCol, s_CmpModel );
276 }
277
278 // ---------------------------------------------------------
279 // wxDataViewSortedListModel
280 // ---------------------------------------------------------
281
282 wxDataViewSortedListModel::wxDataViewSortedListModel( wxDataViewListModel *child ) :
283 m_array( wxDataViewIntermediateCmp )
284 {
285 m_child = child;
286
287 m_ascending = true;
288
289 m_notifierOnChild = new wxDataViewSortedListModelNotifier( this );
290 m_child->AddNotifier( m_notifierOnChild );
291
292 Resort();
293 }
294
295 wxDataViewSortedListModel::~wxDataViewSortedListModel()
296 {
297 if (m_child)
298 m_child->RemoveNotifier( m_notifierOnChild );
299 }
300
301 void wxDataViewSortedListModel::DetachChild()
302 {
303 m_child = NULL;
304 }
305
306 // FIXME
307 void wxDataViewSortedListModel::InitStatics()
308 {
309 s_CmpCol = 0;
310 s_CmpModel = m_child;
311 if (m_ascending)
312 s_CmpFunc = wxDataViewListModelSortedDefaultCompare;
313 else
314 s_CmpFunc = wxDataViewListModelSortedDefaultCompareDescending;
315 }
316
317 void wxDataViewSortedListModel::Resort()
318 {
319 InitStatics();
320
321 m_array.Clear();
322 unsigned int n = m_child->GetRowCount();
323 unsigned int i;
324 for (i = 0; i < n; i++)
325 m_array.Add( i );
326
327 // do we need the neworder?
328 wxDataViewListModel::RowsReordered( NULL );
329 }
330
331 #if 0
332 static void Dump( wxDataViewListModel *model, unsigned int col )
333 {
334 unsigned int n = model->GetRowCount();
335 unsigned int i;
336 for (i = 0; i < n; i++)
337 {
338 wxVariant variant;
339 model->GetValue( variant, col, i );
340 wxString tmp;
341 tmp = variant.GetString();
342 wxPrintf( wxT("%d: %s\n"), (int) i, tmp.c_str() );
343 }
344 }
345 #endif
346
347 bool wxDataViewSortedListModel::ChildRowAppended()
348 {
349 // no need to fix up array
350
351 unsigned int len = m_array.GetCount();
352
353 unsigned int pos = m_array.Add( len );
354
355 if (pos == 0)
356 return wxDataViewListModel::RowPrepended();
357
358 if (pos == len)
359 return wxDataViewListModel::RowAppended();
360
361 return wxDataViewListModel::RowInserted( pos );
362 }
363
364 bool wxDataViewSortedListModel::ChildRowPrepended()
365 {
366 // fix up array
367 unsigned int i;
368 unsigned int len = m_array.GetCount();
369 for (i = 0; i < len; i++)
370 {
371 unsigned int value = m_array[i];
372 m_array[i] = value+1;
373 }
374
375 unsigned int pos = m_array.Add( 0 );
376
377 if (pos == 0)
378 return wxDataViewListModel::RowPrepended();
379
380 if (pos == len)
381 return wxDataViewListModel::RowAppended();
382
383 return wxDataViewListModel::RowInserted( pos );
384 }
385
386 bool wxDataViewSortedListModel::ChildRowInserted( unsigned int before )
387 {
388 // fix up array
389 unsigned int i;
390 unsigned int len = m_array.GetCount();
391 for (i = 0; i < len; i++)
392 {
393 unsigned int value = m_array[i];
394 if (value >= before)
395 m_array[i] = value+1;
396 }
397
398 unsigned int pos = m_array.Add( before );
399
400 if (pos == 0)
401 return wxDataViewListModel::RowPrepended();
402
403 if (pos == len)
404 return wxDataViewListModel::RowAppended();
405
406 return wxDataViewListModel::RowInserted( pos );
407 }
408
409 bool wxDataViewSortedListModel::ChildRowDeleted( unsigned int row )
410 {
411 unsigned int i;
412 unsigned int len = m_array.GetCount();
413 int pos = -1;
414 for (i = 0; i < len; i++)
415 {
416 unsigned int value = m_array[i];
417 if (value == row)
418 {
419 // delete later
420 pos = (int) i;
421 }
422 else
423 {
424 // Fix up array
425 if (value > row)
426 m_array[i] = value-1;
427 }
428 }
429
430 if (pos == -1)
431 return false; // we should probably assert
432
433 // remove
434 m_array.RemoveAt( (unsigned int) pos );
435
436 return wxDataViewListModel::RowDeleted( (unsigned int) pos);
437 }
438
439 bool wxDataViewSortedListModel::ChildRowChanged( unsigned int row )
440 {
441 unsigned int i;
442 unsigned int len = m_array.GetCount();
443
444 // Remove and readd sorted. Find out at which
445 // position it was and where it ended.
446 unsigned int start_pos = 0,end_pos = 0;
447 for (i = 0; i < len; i++)
448 if (m_array[i] == row)
449 {
450 start_pos = i;
451 break;
452 }
453 m_array.RemoveAt( start_pos );
454 m_array.Add( row );
455
456 for (i = 0; i < len; i++)
457 if (m_array[i] == row)
458 {
459 end_pos = i;
460 break;
461 }
462
463 if (end_pos == start_pos)
464 return wxDataViewListModel::RowChanged( start_pos );
465
466 // Create an array where order[old] -> new_pos, so that
467 // if nothing changed order[0] -> 0 etc.
468 unsigned int *order = new unsigned int[ len ];
469 // Fill up initial values.
470 for (i = 0; i < len; i++)
471 order[i] = i;
472
473 if (start_pos < end_pos)
474 {
475 for (i = start_pos; i < end_pos; i++)
476 order[i] = order[i+1];
477 order[end_pos] = start_pos;
478 }
479 else
480 {
481 for (i = end_pos; i > start_pos; i--)
482 order[i] = order[i-1];
483 order[start_pos] = end_pos;
484 }
485
486 wxDataViewListModel::RowsReordered( order );
487
488 delete [] order;
489
490 return true;
491 }
492
493 bool wxDataViewSortedListModel::ChildValueChanged( unsigned int col, unsigned int row )
494 {
495 unsigned int i;
496 unsigned int len = m_array.GetCount();
497
498 // Remove and readd sorted. Find out at which
499 // position it was and where it ended.
500 unsigned int start_pos = 0,end_pos = 0;
501 for (i = 0; i < len; i++)
502 if (m_array[i] == row)
503 {
504 start_pos = i;
505 break;
506 }
507 m_array.RemoveAt( start_pos );
508 m_array.Add( row );
509
510 for (i = 0; i < len; i++)
511 if (m_array[i] == row)
512 {
513 end_pos = i;
514 break;
515 }
516
517 if (end_pos == start_pos)
518 return wxDataViewListModel::ValueChanged( col, start_pos );
519
520 // Create an array where order[old] -> new_pos, so that
521 // if nothing changed order[0] -> 0 etc.
522 unsigned int *order = new unsigned int[ len ];
523 // Fill up initial values.
524 for (i = 0; i < len; i++)
525 order[i] = i;
526
527 if (start_pos < end_pos)
528 {
529 for (i = start_pos; i < end_pos; i++)
530 order[i] = order[i+1];
531 order[end_pos] = start_pos;
532 }
533 else
534 {
535 for (i = end_pos; i > start_pos; i--)
536 order[i] = order[i-1];
537 order[start_pos] = end_pos;
538 }
539
540 wxDataViewListModel::RowsReordered( order );
541
542 delete [] order;
543
544 return true;
545 }
546
547 bool wxDataViewSortedListModel::ChildRowsReordered( unsigned int *WXUNUSED(new_order) )
548 {
549 // Nothing needs to be done. If the sort criteria
550 // of this list don't change, the order of the
551 // items of the child list isn't relevant.
552 return true;
553 }
554
555 bool wxDataViewSortedListModel::ChildCleared()
556 {
557 return wxDataViewListModel::Cleared();
558 }
559
560 unsigned int wxDataViewSortedListModel::GetRowCount() const
561 {
562 return m_array.GetCount();
563 }
564
565 unsigned int wxDataViewSortedListModel::GetColumnCount() const
566 {
567 return m_child->GetColumnCount();
568 }
569
570 wxString wxDataViewSortedListModel::GetColumnType( unsigned int col ) const
571 {
572 return m_child->GetColumnType( col );
573 }
574
575 void wxDataViewSortedListModel::GetValue( wxVariant &variant, unsigned int col, unsigned int row ) const
576 {
577 unsigned int child_row = m_array[row];
578 m_child->GetValue( variant, col, child_row );
579 }
580
581 bool wxDataViewSortedListModel::SetValue( const wxVariant &variant, unsigned int col, unsigned int row )
582 {
583 unsigned int child_row = m_array[row];
584 bool ret = m_child->SetValue( variant, col, child_row );
585
586 // Do nothing here as the change in the
587 // child model will be reported back.
588
589 return ret;
590 }
591
592 bool wxDataViewSortedListModel::RowAppended()
593 {
594 // you can only append
595 bool ret = m_child->RowAppended();
596
597 // Do nothing here as the change in the
598 // child model will be reported back.
599
600 return ret;
601 }
602
603 bool wxDataViewSortedListModel::RowPrepended()
604 {
605 // you can only append
606 bool ret = m_child->RowAppended();
607
608 // Do nothing here as the change in the
609 // child model will be reported back.
610
611 return ret;
612 }
613
614 bool wxDataViewSortedListModel::RowInserted( unsigned int WXUNUSED(before) )
615 {
616 // you can only append
617 bool ret = m_child->RowAppended();
618
619 // Do nothing here as the change in the
620 // child model will be reported back.
621
622 return ret;
623 }
624
625 bool wxDataViewSortedListModel::RowDeleted( unsigned int row )
626 {
627 unsigned int child_row = m_array[row];
628
629 bool ret = m_child->RowDeleted( child_row );
630
631 // Do nothing here as the change in the
632 // child model will be reported back.
633
634 return ret;
635 }
636
637 bool wxDataViewSortedListModel::RowChanged( unsigned int row )
638 {
639 unsigned int child_row = m_array[row];
640 bool ret = m_child->RowChanged( child_row );
641
642 // Do nothing here as the change in the
643 // child model will be reported back.
644
645 return ret;
646 }
647
648 bool wxDataViewSortedListModel::ValueChanged( unsigned int col, unsigned int row )
649 {
650 unsigned int child_row = m_array[row];
651 bool ret = m_child->ValueChanged( col, child_row );
652
653 // Do nothing here as the change in the
654 // child model will be reported back.
655
656 return ret;
657 }
658
659 bool wxDataViewSortedListModel::RowsReordered( unsigned int *WXUNUSED(new_order) )
660 {
661 // We sort them ourselves.
662
663 return false;
664 }
665
666 bool wxDataViewSortedListModel::Cleared()
667 {
668 bool ret = m_child->Cleared();
669
670 // Do nothing here as the change in the
671 // child model will be reported back.
672
673 return ret;
674 }
675
676 // ---------------------------------------------------------
677 // wxDataViewRendererBase
678 // ---------------------------------------------------------
679
680 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRendererBase, wxObject)
681
682 wxDataViewRendererBase::wxDataViewRendererBase( const wxString &varianttype,
683 wxDataViewCellMode WXUNUSED(mode),
684 int WXUNUSED(align) )
685 {
686 m_variantType = varianttype;
687 m_editorCtrl = NULL;
688 m_row = (unsigned int) -1;
689 }
690
691 const wxDataViewCtrl* wxDataViewRendererBase::GetView() const
692 {
693 return wx_const_cast(wxDataViewRendererBase*, this)->GetOwner()->GetOwner();
694 }
695
696 bool wxDataViewRendererBase::StartEditing( unsigned int row, wxRect labelRect )
697 {
698 m_row = row; // remember for later
699
700 unsigned int col = GetOwner()->GetModelColumn();
701 wxVariant value;
702 GetOwner()->GetOwner()->GetModel()->GetValue( value, col, row );
703
704 m_editorCtrl = CreateEditorCtrl( GetOwner()->GetOwner()->GetMainWindow(), labelRect, value );
705
706 wxDataViewEditorCtrlEvtHandler *handler =
707 new wxDataViewEditorCtrlEvtHandler( m_editorCtrl, (wxDataViewRenderer*) this );
708
709 m_editorCtrl->PushEventHandler( handler );
710
711 #if defined(__WXGTK20__) && !defined(wxUSE_GENERICDATAVIEWCTRL)
712 handler->SetFocusOnIdle();
713 #else
714 m_editorCtrl->SetFocus();
715 #endif
716
717 return true;
718 }
719
720 void wxDataViewRendererBase::CancelEditing()
721 {
722 wxPendingDelete.Append( m_editorCtrl );
723
724 GetOwner()->GetOwner()->GetMainWindow()->SetFocus();
725
726 // m_editorCtrl->PopEventHandler( true );
727 }
728
729 bool wxDataViewRendererBase::FinishEditing()
730 {
731 wxVariant value;
732 GetValueFromEditorCtrl( m_editorCtrl, value );
733
734 wxPendingDelete.Append( m_editorCtrl );
735
736 GetOwner()->GetOwner()->GetMainWindow()->SetFocus();
737
738 if (!Validate(value))
739 return false;
740
741 unsigned int col = GetOwner()->GetModelColumn();
742 GetOwner()->GetOwner()->GetModel()->SetValue( value, col, m_row );
743 GetOwner()->GetOwner()->GetModel()->ValueChanged( col, m_row );
744
745 // m_editorCtrl->PopEventHandler( true );
746
747 return true;
748 }
749
750 //-----------------------------------------------------------------------------
751 // wxDataViewEditorCtrlEvtHandler
752 //-----------------------------------------------------------------------------
753
754 BEGIN_EVENT_TABLE(wxDataViewEditorCtrlEvtHandler, wxEvtHandler)
755 EVT_CHAR (wxDataViewEditorCtrlEvtHandler::OnChar)
756 EVT_KILL_FOCUS (wxDataViewEditorCtrlEvtHandler::OnKillFocus)
757 EVT_IDLE (wxDataViewEditorCtrlEvtHandler::OnIdle)
758 END_EVENT_TABLE()
759
760 wxDataViewEditorCtrlEvtHandler::wxDataViewEditorCtrlEvtHandler(
761 wxControl *editorCtrl,
762 wxDataViewRenderer *owner )
763 {
764 m_owner = owner;
765 m_editorCtrl = editorCtrl;
766
767 m_finished = false;
768 }
769
770 void wxDataViewEditorCtrlEvtHandler::OnIdle( wxIdleEvent &event )
771 {
772 if (m_focusOnIdle)
773 {
774 m_focusOnIdle = false;
775 if (wxWindow::FindFocus() != m_editorCtrl)
776 m_editorCtrl->SetFocus();
777 }
778
779 event.Skip();
780 }
781
782 void wxDataViewEditorCtrlEvtHandler::OnChar( wxKeyEvent &event )
783 {
784 switch ( event.m_keyCode )
785 {
786 case WXK_RETURN:
787 m_finished = true;
788 m_owner->FinishEditing();
789 break;
790
791 case WXK_ESCAPE:
792 m_finished = true;
793 m_owner->CancelEditing();
794 break;
795
796 default:
797 event.Skip();
798 }
799 }
800
801 void wxDataViewEditorCtrlEvtHandler::OnKillFocus( wxFocusEvent &event )
802 {
803 if (!m_finished)
804 {
805 m_finished = true;
806 m_owner->FinishEditing();
807 }
808
809 event.Skip();
810 }
811
812 // ---------------------------------------------------------
813 // wxDataViewColumnBase
814 // ---------------------------------------------------------
815
816 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumnBase, wxObject)
817
818 wxDataViewColumnBase::wxDataViewColumnBase(const wxString& WXUNUSED(title),
819 wxDataViewRenderer *renderer,
820 unsigned int model_column,
821 int WXUNUSED(width),
822 wxAlignment WXUNUSED(align),
823 int WXUNUSED(flags))
824 {
825 m_renderer = renderer;
826 m_model_column = model_column;
827 m_owner = NULL;
828 m_renderer->SetOwner( (wxDataViewColumn*) this );
829
830 // NOTE: the wxDataViewColumn's ctor must store the width, align, flags
831 // parameters inside the native control!
832 }
833
834 wxDataViewColumnBase::wxDataViewColumnBase(const wxBitmap& bitmap,
835 wxDataViewRenderer *renderer,
836 unsigned int model_column,
837 int WXUNUSED(width),
838 wxAlignment WXUNUSED(align),
839 int WXUNUSED(flags) )
840 {
841 m_renderer = renderer;
842 m_model_column = model_column;
843 m_bitmap = bitmap;
844 m_owner = NULL;
845 m_renderer->SetOwner( (wxDataViewColumn*) this );
846 }
847
848 wxDataViewColumnBase::~wxDataViewColumnBase()
849 {
850 if (m_renderer)
851 delete m_renderer;
852 }
853
854 int wxDataViewColumnBase::GetFlags() const
855 {
856 int ret = 0;
857
858 if (IsSortable())
859 ret |= wxDATAVIEW_COL_SORTABLE;
860 if (IsResizeable())
861 ret |= wxDATAVIEW_COL_RESIZABLE;
862 if (IsHidden())
863 ret |= wxDATAVIEW_COL_HIDDEN;
864
865 return ret;
866 }
867
868 void wxDataViewColumnBase::SetFlags(int flags)
869 {
870 SetSortable((flags & wxDATAVIEW_COL_SORTABLE) != 0);
871 SetResizeable((flags & wxDATAVIEW_COL_RESIZABLE) != 0);
872 SetHidden((flags & wxDATAVIEW_COL_HIDDEN) != 0);
873 }
874
875 // ---------------------------------------------------------
876 // wxDataViewEventListModelNotifier
877 // ---------------------------------------------------------
878
879 class WXDLLIMPEXP_ADV wxDataViewEventListModelNotifier: public wxDataViewListModelNotifier
880 {
881 public:
882 wxDataViewEventListModelNotifier( wxDataViewCtrl *ctrl ) { m_ctrl = ctrl; }
883
884 bool SendEvent( wxEventType event_type, unsigned int row = 0, unsigned int col = 0 )
885 {
886 wxDataViewEvent event( event_type, m_ctrl->GetId() );
887 event.SetEventObject( m_ctrl );
888 event.SetModel( m_ctrl->GetModel() );
889 event.SetRow( row );
890 event.SetColumn( col );
891 m_ctrl->GetEventHandler()->ProcessEvent( event );
892 return true;
893 }
894
895 virtual bool RowAppended() { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ROW_APPENDED ); }
896 virtual bool RowPrepended() { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ROW_PREPENDED ); }
897 virtual bool RowInserted( unsigned int before )
898 { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ROW_INSERTED, before ); }
899 virtual bool RowDeleted( unsigned int row )
900 { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ROW_DELETED, row ); }
901 virtual bool RowChanged( unsigned int row )
902 { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ROW_CHANGED, row ); }
903 virtual bool ValueChanged( unsigned int col, unsigned int row )
904 { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_VALUE_CHANGED, row, col ); }
905 virtual bool RowsReordered( unsigned int *new_order )
906 { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ROWS_REORDERED ); }
907 virtual bool Cleared() { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_CLEARED ); }
908
909 private:
910 wxDataViewCtrl *m_ctrl;
911 };
912
913
914 // ---------------------------------------------------------
915 // wxDataViewCtrlBase
916 // ---------------------------------------------------------
917
918 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCtrlBase, wxControl)
919
920 wxDataViewCtrlBase::wxDataViewCtrlBase()
921 {
922 m_model = NULL;
923 m_cols.DeleteContents( true );
924 m_eventNotifier = NULL;
925 }
926
927 wxDataViewCtrlBase::~wxDataViewCtrlBase()
928 {
929 // IMPORTANT: before calling DecRef() on our model (since it may
930 // result in a free() call), erase all columns (since
931 // they hold a pointer to our model)
932 m_cols.Clear();
933
934 if (m_model)
935 {
936 if (m_eventNotifier)
937 m_model->RemoveNotifier( m_eventNotifier );
938 m_eventNotifier = NULL;
939
940 m_model->DecRef();
941 m_model = NULL;
942 }
943 }
944
945 bool wxDataViewCtrlBase::AssociateModel( wxDataViewListModel *model )
946 {
947 if (m_model)
948 {
949 if (m_eventNotifier)
950 m_model->RemoveNotifier( m_eventNotifier );
951 m_eventNotifier = NULL;
952
953 m_model->DecRef(); // discard old model, if any
954 }
955
956 // add our own reference to the new model:
957 m_model = model;
958 if (m_model)
959 {
960 m_model->IncRef();
961 m_eventNotifier = new wxDataViewEventListModelNotifier( (wxDataViewCtrl*) this );
962 m_model->AddNotifier( m_eventNotifier );
963 }
964
965 return true;
966 }
967
968 wxDataViewListModel* wxDataViewCtrlBase::GetModel()
969 {
970 return m_model;
971 }
972
973 bool wxDataViewCtrlBase::AppendTextColumn( const wxString &label, unsigned int model_column,
974 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
975 {
976 return AppendColumn( new wxDataViewColumn( label,
977 new wxDataViewTextRenderer( wxT("string"), mode, (int)align ),
978 model_column, width, align, flags ) );
979 }
980
981 bool wxDataViewCtrlBase::AppendToggleColumn( const wxString &label, unsigned int model_column,
982 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
983 {
984 return AppendColumn( new wxDataViewColumn( label,
985 new wxDataViewToggleRenderer( wxT("bool"), mode, (int)align ),
986 model_column, width, align, flags ) );
987 }
988
989 bool wxDataViewCtrlBase::AppendProgressColumn( const wxString &label, unsigned int model_column,
990 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
991 {
992 return AppendColumn( new wxDataViewColumn( label,
993 new wxDataViewProgressRenderer( wxEmptyString, wxT("long"), mode, (int)align ),
994 model_column, width, align, flags ) );
995 }
996
997 bool wxDataViewCtrlBase::AppendDateColumn( const wxString &label, unsigned int model_column,
998 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
999 {
1000 return AppendColumn( new wxDataViewColumn( label,
1001 new wxDataViewDateRenderer( wxT("datetime"), mode, (int)align ),
1002 model_column, width, align, flags ) );
1003 }
1004
1005 bool wxDataViewCtrlBase::AppendBitmapColumn( const wxString &label, unsigned int model_column,
1006 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1007 {
1008 return AppendColumn( new wxDataViewColumn( label,
1009 new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode, (int)align ),
1010 model_column, width, align, flags ) );
1011 }
1012
1013 bool wxDataViewCtrlBase::AppendTextColumn( const wxBitmap &label, unsigned int model_column,
1014 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1015 {
1016 return AppendColumn( new wxDataViewColumn( label,
1017 new wxDataViewTextRenderer( wxT("string"), mode, (int)align ),
1018 model_column, width, align, flags ) );
1019 }
1020
1021 bool wxDataViewCtrlBase::AppendToggleColumn( const wxBitmap &label, unsigned int model_column,
1022 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1023 {
1024 return AppendColumn( new wxDataViewColumn( label,
1025 new wxDataViewToggleRenderer( wxT("bool"), mode, (int)align ),
1026 model_column, width, align, flags ) );
1027 }
1028
1029 bool wxDataViewCtrlBase::AppendProgressColumn( const wxBitmap &label, unsigned int model_column,
1030 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1031 {
1032 return AppendColumn( new wxDataViewColumn( label,
1033 new wxDataViewProgressRenderer( wxEmptyString, wxT("long"), mode, (int)align ),
1034 model_column, width, align, flags ) );
1035 }
1036
1037 bool wxDataViewCtrlBase::AppendDateColumn( const wxBitmap &label, unsigned int model_column,
1038 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1039 {
1040 return AppendColumn( new wxDataViewColumn( label,
1041 new wxDataViewDateRenderer( wxT("datetime"), mode, (int)align ),
1042 model_column, width, align, flags ) );
1043 }
1044
1045 bool wxDataViewCtrlBase::AppendBitmapColumn( const wxBitmap &label, unsigned int model_column,
1046 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1047 {
1048 return AppendColumn( new wxDataViewColumn( label,
1049 new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode, (int)align ),
1050 model_column, width, align, flags ) );
1051 }
1052
1053 bool wxDataViewCtrlBase::AppendColumn( wxDataViewColumn *col )
1054 {
1055 m_cols.Append( (wxObject*) col );
1056 col->SetOwner( (wxDataViewCtrl*) this );
1057 return true;
1058 }
1059
1060 unsigned int wxDataViewCtrlBase::GetColumnCount() const
1061 {
1062 return m_cols.GetCount();
1063 }
1064
1065 bool wxDataViewCtrlBase::DeleteColumn( unsigned int WXUNUSED(pos) )
1066 {
1067 return false;
1068 }
1069
1070 bool wxDataViewCtrlBase::ClearColumns()
1071 {
1072 return false;
1073 }
1074
1075 wxDataViewColumn* wxDataViewCtrlBase::GetColumn( unsigned int pos )
1076 {
1077 return (wxDataViewColumn*) m_cols[ pos ];
1078 }
1079
1080 // ---------------------------------------------------------
1081 // wxDataViewEvent
1082 // ---------------------------------------------------------
1083
1084 IMPLEMENT_DYNAMIC_CLASS(wxDataViewEvent,wxNotifyEvent)
1085
1086 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ROW_SELECTED)
1087 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ROW_ACTIVATED)
1088 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK)
1089 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK)
1090
1091 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ROW_APPENDED)
1092 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ROW_PREPENDED)
1093 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ROW_INSERTED)
1094 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ROW_DELETED)
1095 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ROW_CHANGED)
1096 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_VALUE_CHANGED)
1097 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ROWS_REORDERED)
1098 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_CLEARED)
1099
1100 #endif