]> git.saurik.com Git - wxWidgets.git/blob - src/common/datavcmn.cpp
Corrected/implemented sorting (by way of clicking on
[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 // do we need the neworder?
353 wxDataViewListModel::RowsReordered( NULL );
354 }
355
356 #if 0
357 static void Dump( wxDataViewListModel *model, unsigned int col )
358 {
359 unsigned int n = model->GetRowCount();
360 unsigned int i;
361 for (i = 0; i < n; i++)
362 {
363 wxVariant variant;
364 model->GetValue( variant, col, i );
365 wxString tmp;
366 tmp = variant.GetString();
367 wxPrintf( wxT("%d: %s\n"), (int) i, tmp.c_str() );
368 }
369 }
370 #endif
371
372 bool wxDataViewSortedListModel::ChildRowAppended()
373 {
374 // no need to fix up array
375
376 unsigned int len = m_array.GetCount();
377
378 unsigned int pos = m_array.Add( len );
379
380 if (pos == 0)
381 return wxDataViewListModel::RowPrepended();
382
383 if (pos == len)
384 return wxDataViewListModel::RowAppended();
385
386 return wxDataViewListModel::RowInserted( pos );
387 }
388
389 bool wxDataViewSortedListModel::ChildRowPrepended()
390 {
391 // fix up array
392 unsigned int i;
393 unsigned int len = m_array.GetCount();
394 for (i = 0; i < len; i++)
395 {
396 unsigned int value = m_array[i];
397 m_array[i] = value+1;
398 }
399
400 unsigned int pos = m_array.Add( 0 );
401
402 if (pos == 0)
403 return wxDataViewListModel::RowPrepended();
404
405 if (pos == len)
406 return wxDataViewListModel::RowAppended();
407
408 return wxDataViewListModel::RowInserted( pos );
409 }
410
411 bool wxDataViewSortedListModel::ChildRowInserted( unsigned int before )
412 {
413 // fix up array
414 unsigned int i;
415 unsigned int len = m_array.GetCount();
416 for (i = 0; i < len; i++)
417 {
418 unsigned int value = m_array[i];
419 if (value >= before)
420 m_array[i] = value+1;
421 }
422
423 unsigned int pos = m_array.Add( before );
424
425 if (pos == 0)
426 return wxDataViewListModel::RowPrepended();
427
428 if (pos == len)
429 return wxDataViewListModel::RowAppended();
430
431 return wxDataViewListModel::RowInserted( pos );
432 }
433
434 bool wxDataViewSortedListModel::ChildRowDeleted( unsigned int row )
435 {
436 unsigned int i;
437 unsigned int len = m_array.GetCount();
438 int pos = -1;
439 for (i = 0; i < len; i++)
440 {
441 unsigned int value = m_array[i];
442 if (value == row)
443 {
444 // delete later
445 pos = (int) i;
446 }
447 else
448 {
449 // Fix up array
450 if (value > row)
451 m_array[i] = value-1;
452 }
453 }
454
455 if (pos == -1)
456 return false; // we should probably assert
457
458 // remove
459 m_array.RemoveAt( (unsigned int) pos );
460
461 return wxDataViewListModel::RowDeleted( (unsigned int) pos);
462 }
463
464 bool wxDataViewSortedListModel::ChildRowChanged( unsigned int row )
465 {
466 unsigned int i;
467 unsigned int len = m_array.GetCount();
468
469 // Remove and readd sorted. Find out at which
470 // position it was and where it ended.
471 unsigned int start_pos = 0,end_pos = 0;
472 for (i = 0; i < len; i++)
473 if (m_array[i] == row)
474 {
475 start_pos = i;
476 break;
477 }
478 m_array.RemoveAt( start_pos );
479 m_array.Add( row );
480
481 for (i = 0; i < len; i++)
482 if (m_array[i] == row)
483 {
484 end_pos = i;
485 break;
486 }
487
488 if (end_pos == start_pos)
489 return wxDataViewListModel::RowChanged( start_pos );
490
491 // Create an array where order[old] -> new_pos, so that
492 // if nothing changed order[0] -> 0 etc.
493 unsigned int *order = new unsigned int[ len ];
494 // Fill up initial values.
495 for (i = 0; i < len; i++)
496 order[i] = i;
497
498 if (start_pos < end_pos)
499 {
500 for (i = start_pos; i < end_pos; i++)
501 order[i] = order[i+1];
502 order[end_pos] = start_pos;
503 }
504 else
505 {
506 for (i = end_pos; i > start_pos; i--)
507 order[i] = order[i-1];
508 order[start_pos] = end_pos;
509 }
510
511 wxDataViewListModel::RowsReordered( order );
512
513 delete [] order;
514
515 return true;
516 }
517
518 bool wxDataViewSortedListModel::ChildValueChanged( unsigned int col, unsigned int row )
519 {
520 unsigned int i;
521 unsigned int len = m_array.GetCount();
522
523 // Remove and readd sorted. Find out at which
524 // position it was and where it ended.
525 unsigned int start_pos = 0,end_pos = 0;
526 for (i = 0; i < len; i++)
527 if (m_array[i] == row)
528 {
529 start_pos = i;
530 break;
531 }
532 m_array.RemoveAt( start_pos );
533 m_array.Add( row );
534
535 for (i = 0; i < len; i++)
536 if (m_array[i] == row)
537 {
538 end_pos = i;
539 break;
540 }
541
542 if (end_pos == start_pos)
543 return wxDataViewListModel::ValueChanged( col, start_pos );
544
545 // Create an array where order[old] -> new_pos, so that
546 // if nothing changed order[0] -> 0 etc.
547 unsigned int *order = new unsigned int[ len ];
548 // Fill up initial values.
549 for (i = 0; i < len; i++)
550 order[i] = i;
551
552 if (start_pos < end_pos)
553 {
554 for (i = start_pos; i < end_pos; i++)
555 order[i] = order[i+1];
556 order[end_pos] = start_pos;
557 }
558 else
559 {
560 for (i = end_pos; i > start_pos; i--)
561 order[i] = order[i-1];
562 order[start_pos] = end_pos;
563 }
564
565 wxDataViewListModel::RowsReordered( order );
566
567 delete [] order;
568
569 return true;
570 }
571
572 bool wxDataViewSortedListModel::ChildRowsReordered( unsigned int *WXUNUSED(new_order) )
573 {
574 // Nothing needs to be done. If the sort criteria
575 // of this list don't change, the order of the
576 // items of the child list isn't relevant.
577 return true;
578 }
579
580 bool wxDataViewSortedListModel::ChildCleared()
581 {
582 return wxDataViewListModel::Cleared();
583 }
584
585 unsigned int wxDataViewSortedListModel::GetRowCount() const
586 {
587 return m_array.GetCount();
588 }
589
590 unsigned int wxDataViewSortedListModel::GetColumnCount() const
591 {
592 return m_child->GetColumnCount();
593 }
594
595 wxString wxDataViewSortedListModel::GetColumnType( unsigned int col ) const
596 {
597 return m_child->GetColumnType( col );
598 }
599
600 void wxDataViewSortedListModel::GetValue( wxVariant &variant, unsigned int col, unsigned int row ) const
601 {
602 unsigned int child_row = m_array[row];
603 m_child->GetValue( variant, col, child_row );
604 }
605
606 bool wxDataViewSortedListModel::SetValue( wxVariant &variant, unsigned int col, unsigned int row )
607 {
608 unsigned int child_row = m_array[row];
609 bool ret = m_child->SetValue( variant, col, child_row );
610
611 // Do nothing here as the change in the
612 // child model will be reported back.
613
614 return ret;
615 }
616
617 bool wxDataViewSortedListModel::RowAppended()
618 {
619 // you can only append
620 bool ret = m_child->RowAppended();
621
622 // Do nothing here as the change in the
623 // child model will be reported back.
624
625 return ret;
626 }
627
628 bool wxDataViewSortedListModel::RowPrepended()
629 {
630 // you can only append
631 bool ret = m_child->RowAppended();
632
633 // Do nothing here as the change in the
634 // child model will be reported back.
635
636 return ret;
637 }
638
639 bool wxDataViewSortedListModel::RowInserted( unsigned int WXUNUSED(before) )
640 {
641 // you can only append
642 bool ret = m_child->RowAppended();
643
644 // Do nothing here as the change in the
645 // child model will be reported back.
646
647 return ret;
648 }
649
650 bool wxDataViewSortedListModel::RowDeleted( unsigned int row )
651 {
652 unsigned int child_row = m_array[row];
653
654 bool ret = m_child->RowDeleted( child_row );
655
656 // Do nothing here as the change in the
657 // child model will be reported back.
658
659 return ret;
660 }
661
662 bool wxDataViewSortedListModel::RowChanged( unsigned int row )
663 {
664 unsigned int child_row = m_array[row];
665 bool ret = m_child->RowChanged( child_row );
666
667 // Do nothing here as the change in the
668 // child model will be reported back.
669
670 return ret;
671 }
672
673 bool wxDataViewSortedListModel::ValueChanged( unsigned int col, unsigned int row )
674 {
675 unsigned int child_row = m_array[row];
676 bool ret = m_child->ValueChanged( col, child_row );
677
678 // Do nothing here as the change in the
679 // child model will be reported back.
680
681 return ret;
682 }
683
684 bool wxDataViewSortedListModel::RowsReordered( unsigned int *WXUNUSED(new_order) )
685 {
686 // We sort them ourselves.
687
688 return false;
689 }
690
691 bool wxDataViewSortedListModel::Cleared()
692 {
693 bool ret = m_child->Cleared();
694
695 // Do nothing here as the change in the
696 // child model will be reported back.
697
698 return ret;
699 }
700
701 // ---------------------------------------------------------
702 // wxDataViewRendererBase
703 // ---------------------------------------------------------
704
705 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRendererBase, wxObject)
706
707 wxDataViewRendererBase::wxDataViewRendererBase( const wxString &varianttype,
708 wxDataViewCellMode WXUNUSED(mode),
709 int WXUNUSED(align) )
710 {
711 m_variantType = varianttype;
712 m_editorCtrl = NULL;
713 m_row = (unsigned int) -1;
714 }
715
716 const wxDataViewCtrl* wxDataViewRendererBase::GetView() const
717 {
718 return wx_const_cast(wxDataViewRendererBase*, this)->GetOwner()->GetOwner();
719 }
720
721 bool wxDataViewRendererBase::StartEditing( unsigned int row, wxRect labelRect )
722 {
723 m_row = row; // remember for later
724
725 unsigned int col = GetOwner()->GetModelColumn();
726 wxVariant value;
727 GetOwner()->GetOwner()->GetModel()->GetValue( value, col, row );
728
729 m_editorCtrl = CreateEditorCtrl( GetOwner()->GetOwner()->GetMainWindow(), labelRect, value );
730
731 m_editorCtrl->PushEventHandler(
732 new wxDataViewEditorCtrlEvtHandler( m_editorCtrl, (wxDataViewRenderer*) this ) );
733
734 m_editorCtrl->SetFocus();
735
736 return true;
737 }
738
739 void wxDataViewRendererBase::CancelEditing()
740 {
741 // m_editorCtrl->PopEventHandler( true );
742
743 delete m_editorCtrl;
744
745 GetOwner()->GetOwner()->GetMainWindow()->SetFocus();
746 }
747
748 bool wxDataViewRendererBase::FinishEditing()
749 {
750 // m_editorCtrl->PopEventHandler( true );
751
752 wxVariant value;
753 GetValueFromEditorCtrl( m_editorCtrl, value );
754
755 delete m_editorCtrl;
756
757 GetOwner()->GetOwner()->GetMainWindow()->SetFocus();
758
759 if (!Validate(value))
760 return false;
761
762 unsigned int col = GetOwner()->GetModelColumn();
763 GetOwner()->GetOwner()->GetModel()->SetValue( value, col, m_row );
764 GetOwner()->GetOwner()->GetModel()->ValueChanged( col, m_row );
765
766 return true;
767 }
768
769 //-----------------------------------------------------------------------------
770 // wxDataViewEditorCtrlEvtHandler
771 //-----------------------------------------------------------------------------
772
773 BEGIN_EVENT_TABLE(wxDataViewEditorCtrlEvtHandler, wxEvtHandler)
774 EVT_CHAR (wxDataViewEditorCtrlEvtHandler::OnChar)
775 EVT_KILL_FOCUS (wxDataViewEditorCtrlEvtHandler::OnKillFocus)
776 END_EVENT_TABLE()
777
778 wxDataViewEditorCtrlEvtHandler::wxDataViewEditorCtrlEvtHandler(
779 wxControl *editorCtrl,
780 wxDataViewRenderer *owner )
781 {
782 m_owner = owner;
783 m_editorCtrl = editorCtrl;
784
785 m_finished = false;
786 }
787
788 void wxDataViewEditorCtrlEvtHandler::OnChar( wxKeyEvent &event )
789 {
790 switch ( event.m_keyCode )
791 {
792 case WXK_RETURN:
793 m_finished = true;
794 m_owner->FinishEditing();
795 break;
796
797 case WXK_ESCAPE:
798 m_finished = true;
799 m_owner->CancelEditing();
800 break;
801
802 default:
803 event.Skip();
804 }
805 }
806
807 void wxDataViewEditorCtrlEvtHandler::OnKillFocus( wxFocusEvent &event )
808 {
809 if (!m_finished)
810 {
811 m_finished = true;
812 m_owner->FinishEditing();
813 }
814
815 // We must let the native text control handle focus
816 event.Skip();
817 }
818
819 // ---------------------------------------------------------
820 // wxDataViewColumnBase
821 // ---------------------------------------------------------
822
823 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumnBase, wxObject)
824
825 wxDataViewColumnBase::wxDataViewColumnBase(const wxString& WXUNUSED(title),
826 wxDataViewRenderer *renderer,
827 unsigned int model_column,
828 int WXUNUSED(width),
829 wxAlignment WXUNUSED(align),
830 int WXUNUSED(flags))
831 {
832 m_renderer = renderer;
833 m_model_column = model_column;
834 m_owner = NULL;
835 m_renderer->SetOwner( (wxDataViewColumn*) this );
836
837 // NOTE: the wxDataViewColumn's ctor must store the width, align, flags
838 // parameters inside the native control!
839 }
840
841 wxDataViewColumnBase::wxDataViewColumnBase(const wxBitmap& bitmap,
842 wxDataViewRenderer *renderer,
843 unsigned int model_column,
844 int WXUNUSED(width),
845 wxAlignment WXUNUSED(align),
846 int WXUNUSED(flags) )
847 {
848 m_renderer = renderer;
849 m_model_column = model_column;
850 m_bitmap = bitmap;
851 m_owner = NULL;
852 m_renderer->SetOwner( (wxDataViewColumn*) this );
853 }
854
855 wxDataViewColumnBase::~wxDataViewColumnBase()
856 {
857 if (m_renderer)
858 delete m_renderer;
859
860 if (GetOwner())
861 {
862 GetOwner()->GetModel()->RemoveViewingColumn( (wxDataViewColumn*) this );
863 }
864 }
865
866 int wxDataViewColumnBase::GetFlags() const
867 {
868 int ret = 0;
869
870 if (IsSortable())
871 ret |= wxDATAVIEW_COL_SORTABLE;
872 if (IsResizeable())
873 ret |= wxDATAVIEW_COL_RESIZABLE;
874 if (IsHidden())
875 ret |= wxDATAVIEW_COL_HIDDEN;
876
877 return ret;
878 }
879
880 void wxDataViewColumnBase::SetFlags(int flags)
881 {
882 SetSortable((flags & wxDATAVIEW_COL_SORTABLE) != 0);
883 SetResizeable((flags & wxDATAVIEW_COL_RESIZABLE) != 0);
884 SetHidden((flags & wxDATAVIEW_COL_HIDDEN) != 0);
885 }
886
887
888 // ---------------------------------------------------------
889 // wxDataViewCtrlBase
890 // ---------------------------------------------------------
891
892 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCtrlBase, wxControl)
893
894 wxDataViewCtrlBase::wxDataViewCtrlBase()
895 {
896 m_model = NULL;
897 m_cols.DeleteContents( true );
898 }
899
900 wxDataViewCtrlBase::~wxDataViewCtrlBase()
901 {
902 // IMPORTANT: before calling DecRef() on our model (since it may
903 // result in a free() call), erase all columns (since
904 // they hold a pointer to our model)
905 m_cols.Clear();
906
907 if (m_model)
908 {
909 m_model->DecRef();
910 m_model = NULL;
911 }
912 }
913
914 bool wxDataViewCtrlBase::AssociateModel( wxDataViewListModel *model )
915 {
916 if ( m_model )
917 m_model->DecRef(); // discard old model, if any
918
919 // add our own reference to the new model:
920 m_model = model;
921 if ( m_model )
922 m_model->IncRef();
923
924 return true;
925 }
926
927 wxDataViewListModel* wxDataViewCtrlBase::GetModel()
928 {
929 return m_model;
930 }
931
932 bool wxDataViewCtrlBase::AppendTextColumn( const wxString &label, unsigned int model_column,
933 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
934 {
935 return AppendColumn( new wxDataViewColumn( label,
936 new wxDataViewTextRenderer( wxT("string"), mode, (int)align ),
937 model_column, width, align, flags ) );
938 }
939
940 bool wxDataViewCtrlBase::AppendToggleColumn( const wxString &label, unsigned int model_column,
941 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
942 {
943 return AppendColumn( new wxDataViewColumn( label,
944 new wxDataViewToggleRenderer( wxT("bool"), mode, (int)align ),
945 model_column, width, align, flags ) );
946 }
947
948 bool wxDataViewCtrlBase::AppendProgressColumn( const wxString &label, unsigned int model_column,
949 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
950 {
951 return AppendColumn( new wxDataViewColumn( label,
952 new wxDataViewProgressRenderer( wxEmptyString, wxT("long"), mode, (int)align ),
953 model_column, width, align, flags ) );
954 }
955
956 bool wxDataViewCtrlBase::AppendDateColumn( const wxString &label, unsigned int model_column,
957 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
958 {
959 return AppendColumn( new wxDataViewColumn( label,
960 new wxDataViewDateRenderer( wxT("datetime"), mode, (int)align ),
961 model_column, width, align, flags ) );
962 }
963
964 bool wxDataViewCtrlBase::AppendBitmapColumn( const wxString &label, unsigned int model_column,
965 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
966 {
967 return AppendColumn( new wxDataViewColumn( label,
968 new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode, (int)align ),
969 model_column, width, align, flags ) );
970 }
971
972 bool wxDataViewCtrlBase::AppendTextColumn( const wxBitmap &label, unsigned int model_column,
973 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
974 {
975 return AppendColumn( new wxDataViewColumn( label,
976 new wxDataViewTextRenderer( wxT("string"), mode, (int)align ),
977 model_column, width, align, flags ) );
978 }
979
980 bool wxDataViewCtrlBase::AppendToggleColumn( const wxBitmap &label, unsigned int model_column,
981 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
982 {
983 return AppendColumn( new wxDataViewColumn( label,
984 new wxDataViewToggleRenderer( wxT("bool"), mode, (int)align ),
985 model_column, width, align, flags ) );
986 }
987
988 bool wxDataViewCtrlBase::AppendProgressColumn( const wxBitmap &label, unsigned int model_column,
989 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
990 {
991 return AppendColumn( new wxDataViewColumn( label,
992 new wxDataViewProgressRenderer( wxEmptyString, wxT("long"), mode, (int)align ),
993 model_column, width, align, flags ) );
994 }
995
996 bool wxDataViewCtrlBase::AppendDateColumn( const wxBitmap &label, unsigned int model_column,
997 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
998 {
999 return AppendColumn( new wxDataViewColumn( label,
1000 new wxDataViewDateRenderer( wxT("datetime"), mode, (int)align ),
1001 model_column, width, align, flags ) );
1002 }
1003
1004 bool wxDataViewCtrlBase::AppendBitmapColumn( const wxBitmap &label, unsigned int model_column,
1005 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1006 {
1007 return AppendColumn( new wxDataViewColumn( label,
1008 new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode, (int)align ),
1009 model_column, width, align, flags ) );
1010 }
1011
1012 bool wxDataViewCtrlBase::AppendColumn( wxDataViewColumn *col )
1013 {
1014 m_cols.Append( (wxObject*) col );
1015 col->SetOwner( (wxDataViewCtrl*) this );
1016 m_model->AddViewingColumn( col, col->GetModelColumn() );
1017 return true;
1018 }
1019
1020 unsigned int wxDataViewCtrlBase::GetColumnCount() const
1021 {
1022 return m_cols.GetCount();
1023 }
1024
1025 bool wxDataViewCtrlBase::DeleteColumn( unsigned int WXUNUSED(pos) )
1026 {
1027 return false;
1028 }
1029
1030 bool wxDataViewCtrlBase::ClearColumns()
1031 {
1032 return false;
1033 }
1034
1035 wxDataViewColumn* wxDataViewCtrlBase::GetColumn( unsigned int pos )
1036 {
1037 return (wxDataViewColumn*) m_cols[ pos ];
1038 }
1039
1040 // ---------------------------------------------------------
1041 // wxDataViewEvent
1042 // ---------------------------------------------------------
1043
1044 IMPLEMENT_DYNAMIC_CLASS(wxDataViewEvent,wxNotifyEvent)
1045
1046 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ROW_SELECTED)
1047 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ROW_ACTIVATED)
1048 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK)
1049 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK)
1050
1051
1052 #endif