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