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: datavcmn.cpp 41670 2006-10-07 14:15:53Z RR $
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
26const wxChar wxDataViewCtrlNameStr[] = wxT("dataviewCtrl");
27
28// ---------------------------------------------------------
29// wxDataViewModel
30// ---------------------------------------------------------
31
32IMPLEMENT_ABSTRACT_CLASS(wxDataViewModel, wxObject)
33
34// ---------------------------------------------------------
35// wxDataViewListModel
36// ---------------------------------------------------------
37
38IMPLEMENT_ABSTRACT_CLASS(wxDataViewListModel, wxDataViewModel)
39
40wxDataViewListModel::wxDataViewListModel()
41{
42    m_viewingColumns.DeleteContents( true );
43    m_notifiers.DeleteContents( true );
44}
45
46wxDataViewListModel::~wxDataViewListModel()
47{
48}
49
50bool 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
66bool 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
82bool 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
98bool 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
114bool 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
130bool 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
146bool 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
162bool 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
178void wxDataViewListModel::AddViewingColumn( wxDataViewColumn *view_column, unsigned int model_column )
179{
180    m_viewingColumns.Append( new wxDataViewViewingColumn( view_column, model_column ) );
181}
182
183void 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
200void wxDataViewListModel::AddNotifier( wxDataViewListModelNotifier *notifier )
201{
202    m_notifiers.Append( notifier );
203    notifier->SetOwner( this );
204}
205
206void wxDataViewListModel::RemoveNotifier( wxDataViewListModelNotifier *notifier )
207{
208    m_notifiers.DeleteObject( notifier );
209}
210
211// ---------------------------------------------------------
212// wxDataViewSortedListModelNotifier
213// ---------------------------------------------------------
214
215class wxDataViewSortedListModelNotifier: public wxDataViewListModelNotifier
216{
217public:
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    wxDataViewSortedListModel *m_model;
246};
247
248// ---------------------------------------------------------
249// wxDataViewSortedListModel compare function
250// ---------------------------------------------------------
251
252int wxCALLBACK wxDataViewListModelSortedDefaultCompare
253      (unsigned int row1, unsigned int row2, unsigned int col, wxDataViewListModel* model )
254{
255    wxVariant value1,value2;
256    model->GetValue( value1, col, row1 );
257    model->GetValue( value2, col, row2 );
258    if (value1.GetType() == wxT("string"))
259    {
260        wxString str1 = value1.GetString();
261        wxString str2 = value2.GetString();
262        return str1.Cmp( str2 );
263    }
264    if (value1.GetType() == wxT("long"))
265    {
266        long l1 = value1.GetLong();
267        long l2 = value2.GetLong();
268        return l1-l2;
269    }
270    if (value1.GetType() == wxT("double"))
271    {
272        double d1 = value1.GetDouble();
273        double d2 = value2.GetDouble();
274        if (d1 == d2) return 0;
275        if (d1 < d2) return 1;
276        return -1;
277    }
278    if (value1.GetType() == wxT("datetime"))
279    {
280        wxDateTime dt1 = value1.GetDateTime();
281        wxDateTime dt2 = value2.GetDateTime();
282        if (dt1.IsEqualTo(dt2)) return 0;
283        if (dt1.IsEarlierThan(dt2)) return 1;
284        return -1;
285    }
286
287    return 0;
288}
289
290int wxCALLBACK wxDataViewListModelSortedDefaultCompareDescending
291      (unsigned int row1, unsigned int row2, unsigned int col, wxDataViewListModel* model )
292{
293    return wxDataViewListModelSortedDefaultCompare( row2, row1, col, model );
294}
295
296static wxDataViewListModelCompare   s_CmpFunc;
297static wxDataViewListModel         *s_CmpModel;
298static unsigned int                 s_CmpCol;
299
300int LINKAGEMODE wxDataViewIntermediateCmp( unsigned int row1, unsigned int row2 )
301{
302    return s_CmpFunc( row1, row2, s_CmpCol, s_CmpModel );
303}
304
305// ---------------------------------------------------------
306// wxDataViewSortedListModel
307// ---------------------------------------------------------
308
309IMPLEMENT_ABSTRACT_CLASS(wxDataViewSortedListModel, wxDataViewListModel)
310
311wxDataViewSortedListModel::wxDataViewSortedListModel( wxDataViewListModel *child ) :
312  m_array( wxDataViewIntermediateCmp )
313{
314    m_child = child;
315
316    m_ascending = true;
317
318    m_notifierOnChild = new wxDataViewSortedListModelNotifier( this );
319    m_child->AddNotifier( m_notifierOnChild );
320
321    Resort();
322}
323
324wxDataViewSortedListModel::~wxDataViewSortedListModel()
325{
326    m_child->RemoveNotifier( m_notifierOnChild );
327}
328
329// FIXME
330void wxDataViewSortedListModel::InitStatics()
331{
332    s_CmpCol = 0;
333    s_CmpModel = m_child;
334    if (m_ascending)
335        s_CmpFunc = wxDataViewListModelSortedDefaultCompare;
336    else
337        s_CmpFunc = wxDataViewListModelSortedDefaultCompareDescending;
338}
339
340void wxDataViewSortedListModel::Resort()
341{
342    InitStatics();
343
344    m_array.Clear();
345    unsigned int n = m_child->GetNumberOfRows();
346    unsigned int i;
347    for (i = 0; i < n; i++)
348        m_array.Add( i );
349}
350
351#if 0
352static void Dump( wxDataViewListModel *model, unsigned int col )
353{
354    unsigned int n = model->GetNumberOfRows();
355    unsigned int i;
356    for (i = 0; i < n; i++)
357    {
358        wxVariant variant;
359        model->GetValue( variant, col, i );
360        wxString tmp;
361        tmp = variant.GetString();
362        wxPrintf( wxT("%d: %s\n"), (int) i, tmp.c_str() );
363    }
364}
365#endif
366
367bool wxDataViewSortedListModel::ChildRowAppended()
368{
369    // no need to fix up array
370
371    unsigned int len = m_array.GetCount();
372
373    unsigned int pos = m_array.Add( len );
374
375    if (pos == 0)
376        return wxDataViewListModel::RowPrepended();
377
378    if (pos == len)
379        return wxDataViewListModel::RowAppended();
380
381    return wxDataViewListModel::RowInserted( pos );
382}
383
384bool wxDataViewSortedListModel::ChildRowPrepended()
385{
386    // fix up array
387    unsigned int i;
388    unsigned int len = m_array.GetCount();
389    for (i = 0; i < len; i++)
390    {
391        unsigned int value = m_array[i];
392        m_array[i] = value+1;
393    }
394
395    unsigned int pos = m_array.Add( 0 );
396
397    if (pos == 0)
398        return wxDataViewListModel::RowPrepended();
399
400    if (pos == len)
401        return wxDataViewListModel::RowAppended();
402
403    return wxDataViewListModel::RowInserted( pos );
404}
405
406bool wxDataViewSortedListModel::ChildRowInserted( unsigned int before )
407{
408    // fix up array
409    unsigned int i;
410    unsigned int len = m_array.GetCount();
411    for (i = 0; i < len; i++)
412    {
413        unsigned int value = m_array[i];
414        if (value >= before)
415           m_array[i] = value+1;
416    }
417
418    unsigned int pos = m_array.Add( before );
419
420    if (pos == 0)
421        return wxDataViewListModel::RowPrepended();
422
423    if (pos == len)
424        return wxDataViewListModel::RowAppended();
425
426    return wxDataViewListModel::RowInserted( pos );
427}
428
429bool wxDataViewSortedListModel::ChildRowDeleted( unsigned int row )
430{
431    unsigned int i;
432    unsigned int len = m_array.GetCount();
433    int pos = -1;
434    for (i = 0; i < len; i++)
435    {
436        unsigned int value = m_array[i];
437        if (value == row)
438        {
439            // delete later
440            pos = (int) i;
441        }
442        else
443        {
444            // Fix up array
445            if (value > row)
446                m_array[i] = value-1;
447        }
448    }
449
450    if (pos == -1)
451        return false; // we should probably assert
452
453    // remove
454    m_array.RemoveAt( (unsigned int) pos );
455
456    return wxDataViewListModel::RowDeleted( (unsigned int) pos);
457}
458
459bool wxDataViewSortedListModel::ChildRowChanged( unsigned int row )
460{
461    unsigned int i;
462    unsigned int len = m_array.GetCount();
463
464    // Remove and readd sorted. Find out at which
465    // position it was and where it ended.
466    unsigned int start_pos = 0,end_pos = 0;
467    for (i = 0; i < len; i++)
468        if (m_array[i] == row)
469        {
470            start_pos = i;
471            break;
472        }
473    m_array.RemoveAt( start_pos );
474    m_array.Add( row );
475
476    for (i = 0; i < len; i++)
477        if (m_array[i] == row)
478        {
479            end_pos = i;
480            break;
481        }
482
483    if (end_pos == start_pos)
484        return wxDataViewListModel::RowChanged( start_pos );
485
486    // Create an array where order[old] -> new_pos, so that
487    // if nothing changed order[0] -> 0 etc.
488    unsigned int *order = new unsigned int[ len ];
489    // Fill up initial values.
490    for (i = 0; i < len; i++)
491        order[i] = i;
492
493    if (start_pos < end_pos)
494    {
495        for (i = start_pos; i < end_pos; i++)
496            order[i] = order[i+1];
497        order[end_pos] = start_pos;
498    }
499    else
500    {
501        for (i = end_pos; i > start_pos; i--)
502            order[i] = order[i-1];
503        order[start_pos] = end_pos;
504    }
505
506    wxDataViewListModel::RowsReordered( order );
507
508    delete [] order;
509
510    return true;
511}
512
513bool wxDataViewSortedListModel::ChildValueChanged( unsigned int col, unsigned int row )
514{
515    unsigned int i;
516    unsigned int len = m_array.GetCount();
517
518    // Remove and readd sorted. Find out at which
519    // position it was and where it ended.
520    unsigned int start_pos = 0,end_pos = 0;
521    for (i = 0; i < len; i++)
522        if (m_array[i] == row)
523        {
524            start_pos = i;
525            break;
526        }
527    m_array.RemoveAt( start_pos );
528    m_array.Add( row );
529
530    for (i = 0; i < len; i++)
531        if (m_array[i] == row)
532        {
533            end_pos = i;
534            break;
535        }
536
537    if (end_pos == start_pos)
538        return wxDataViewListModel::ValueChanged( col, start_pos );
539
540    // Create an array where order[old] -> new_pos, so that
541    // if nothing changed order[0] -> 0 etc.
542    unsigned int *order = new unsigned int[ len ];
543    // Fill up initial values.
544    for (i = 0; i < len; i++)
545        order[i] = i;
546
547    if (start_pos < end_pos)
548    {
549        for (i = start_pos; i < end_pos; i++)
550            order[i] = order[i+1];
551        order[end_pos] = start_pos;
552    }
553    else
554    {
555        for (i = end_pos; i > start_pos; i--)
556            order[i] = order[i-1];
557        order[start_pos] = end_pos;
558    }
559
560    wxDataViewListModel::RowsReordered( order );
561
562    delete [] order;
563
564    return true;
565}
566
567bool wxDataViewSortedListModel::ChildRowsReordered( unsigned int *WXUNUSED(new_order) )
568{
569    // Nothing needs to be done. If the sort criteria
570    // of this list don't change, the order of the
571    // items of the child list isn't relevant.
572    return true;
573}
574
575bool wxDataViewSortedListModel::ChildCleared()
576{
577    return wxDataViewListModel::Cleared();
578}
579
580unsigned int wxDataViewSortedListModel::GetNumberOfRows()
581{
582    return m_array.GetCount();
583}
584
585unsigned int wxDataViewSortedListModel::GetNumberOfCols()
586{
587    return m_child->GetNumberOfCols();
588}
589
590wxString wxDataViewSortedListModel::GetColType( unsigned int col )
591{
592    return m_child->GetColType( col );
593}
594
595void wxDataViewSortedListModel::GetValue( wxVariant &variant, unsigned int col, unsigned int row )
596{
597    unsigned int child_row = m_array[row];
598    m_child->GetValue( variant, col, child_row );
599}
600
601bool wxDataViewSortedListModel::SetValue( wxVariant &variant, unsigned int col, unsigned int row )
602{
603    unsigned int child_row = m_array[row];
604    bool ret = m_child->SetValue( variant, col, child_row );
605
606    // Do nothing here as the change in the
607    // child model will be reported back.
608
609    return ret;
610}
611
612bool wxDataViewSortedListModel::RowAppended()
613{
614    // you can only append
615    bool ret = m_child->RowAppended();
616
617    // Do nothing here as the change in the
618    // child model will be reported back.
619
620    return ret;
621}
622
623bool wxDataViewSortedListModel::RowPrepended()
624{
625    // you can only append
626    bool ret = m_child->RowAppended();
627
628    // Do nothing here as the change in the
629    // child model will be reported back.
630
631    return ret;
632}
633
634bool wxDataViewSortedListModel::RowInserted( unsigned int WXUNUSED(before) )
635{
636    // you can only append
637    bool ret = m_child->RowAppended();
638
639    // Do nothing here as the change in the
640    // child model will be reported back.
641
642    return ret;
643}
644
645bool wxDataViewSortedListModel::RowDeleted( unsigned int row )
646{
647    unsigned int child_row = m_array[row];
648
649    bool ret = m_child->RowDeleted( child_row );
650
651    // Do nothing here as the change in the
652    // child model will be reported back.
653
654    return ret;
655}
656
657bool wxDataViewSortedListModel::RowChanged( unsigned int row )
658{
659    unsigned int child_row = m_array[row];
660    bool ret = m_child->RowChanged( child_row );
661
662    // Do nothing here as the change in the
663    // child model will be reported back.
664
665    return ret;
666}
667
668bool wxDataViewSortedListModel::ValueChanged( unsigned int col, unsigned int row )
669{
670    unsigned int child_row = m_array[row];
671    bool ret = m_child->ValueChanged( col, child_row );
672
673    // Do nothing here as the change in the
674    // child model will be reported back.
675
676    return ret;
677}
678
679bool wxDataViewSortedListModel::RowsReordered( unsigned int *WXUNUSED(new_order) )
680{
681    // We sort them ourselves.
682
683    return false;
684}
685
686bool wxDataViewSortedListModel::Cleared()
687{
688    bool ret = m_child->Cleared();
689
690    // Do nothing here as the change in the
691    // child model will be reported back.
692
693    return ret;
694}
695
696// ---------------------------------------------------------
697// wxDataViewRendererBase
698// ---------------------------------------------------------
699
700IMPLEMENT_ABSTRACT_CLASS(wxDataViewRendererBase, wxObject)
701
702wxDataViewRendererBase::wxDataViewRendererBase( const wxString &varianttype, wxDataViewCellMode mode )
703{
704    m_variantType = varianttype;
705    m_mode = mode;
706}
707
708// ---------------------------------------------------------
709// wxDataViewColumnBase
710// ---------------------------------------------------------
711
712IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumnBase, wxObject)
713
714wxDataViewColumnBase::wxDataViewColumnBase(const wxString& title,
715                                           wxDataViewRenderer *renderer,
716                                           unsigned int model_column,
717                                           int WXUNUSED(width),
718                                           int flags )
719{
720    m_renderer = renderer;
721    m_model_column = model_column;
722    m_flags = flags;
723    m_title = title;
724    m_owner = NULL;
725    m_renderer->SetOwner( (wxDataViewColumn*) this );
726}
727
728wxDataViewColumnBase::wxDataViewColumnBase(const wxBitmap& bitmap,
729                                           wxDataViewRenderer *renderer,
730                                           unsigned int model_column,
731                                           int WXUNUSED(width),
732                                           int flags )
733{
734    m_renderer = renderer;
735    m_model_column = model_column;
736    m_flags = flags;
737    m_bitmap = bitmap;
738    m_owner = NULL;
739    m_renderer->SetOwner( (wxDataViewColumn*) this );
740}
741
742wxDataViewColumnBase::~wxDataViewColumnBase()
743{
744    if (m_renderer)
745        delete m_renderer;
746
747    if (GetOwner())
748    {
749        GetOwner()->GetModel()->RemoveViewingColumn( (wxDataViewColumn*) this );
750    }
751}
752
753void wxDataViewColumnBase::SetTitle( const wxString &title )
754{
755    m_title = title;
756}
757
758wxString wxDataViewColumnBase::GetTitle()
759{
760    return m_title;
761}
762
763void wxDataViewColumnBase::SetBitmap( const wxBitmap &bitmap )
764{
765    m_bitmap = bitmap;
766}
767
768const wxBitmap &wxDataViewColumnBase::GetBitmap()
769{
770    return m_bitmap;
771}
772
773// ---------------------------------------------------------
774// wxDataViewCtrlBase
775// ---------------------------------------------------------
776
777IMPLEMENT_ABSTRACT_CLASS(wxDataViewCtrlBase, wxControl)
778
779wxDataViewCtrlBase::wxDataViewCtrlBase()
780{
781    m_model = NULL;
782    m_cols.DeleteContents( true );
783}
784
785wxDataViewCtrlBase::~wxDataViewCtrlBase()
786{
787}
788
789bool wxDataViewCtrlBase::AssociateModel( wxDataViewListModel *model )
790{
791    m_model = model;
792
793    return true;
794}
795
796wxDataViewListModel* wxDataViewCtrlBase::GetModel()
797{
798    return m_model;
799}
800
801bool wxDataViewCtrlBase::AppendTextColumn( const wxString &label, unsigned int model_column,
802                            wxDataViewCellMode mode, int width )
803{
804    return AppendColumn( new wxDataViewColumn( label,
805        new wxDataViewTextRenderer( wxT("string"), mode ), model_column, width ) );
806}
807
808bool wxDataViewCtrlBase::AppendToggleColumn( const wxString &label, unsigned int model_column,
809                            wxDataViewCellMode mode, int width )
810{
811    return AppendColumn( new wxDataViewColumn( label,
812        new wxDataViewToggleRenderer( wxT("bool"), mode ), model_column, width ) );
813}
814
815bool wxDataViewCtrlBase::AppendProgressColumn( const wxString &label, unsigned int model_column,
816                            wxDataViewCellMode mode, int width )
817{
818    return AppendColumn( new wxDataViewColumn( label,
819        new wxDataViewProgressRenderer( wxEmptyString, wxT("long"), mode ), model_column, width ) );
820}
821
822bool wxDataViewCtrlBase::AppendDateColumn( const wxString &label, unsigned int model_column,
823                            wxDataViewCellMode mode, int width )
824{
825    return AppendColumn( new wxDataViewColumn( label,
826        new wxDataViewDateRenderer( wxT("datetime"), mode), model_column, width ) );
827}
828
829bool wxDataViewCtrlBase::AppendBitmapColumn( const wxString &label, unsigned int model_column,
830                            wxDataViewCellMode mode, int width )
831{
832    return AppendColumn( new wxDataViewColumn( label,
833        new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode ), model_column, width ) );
834}
835
836bool wxDataViewCtrlBase::AppendTextColumn( const wxBitmap &label, unsigned int model_column,
837                            wxDataViewCellMode mode, int width )
838{
839    return AppendColumn( new wxDataViewColumn( label,
840        new wxDataViewTextRenderer( wxT("string"), mode ), model_column, width ) );
841}
842
843bool wxDataViewCtrlBase::AppendToggleColumn( const wxBitmap &label, unsigned int model_column,
844                            wxDataViewCellMode mode, int width )
845{
846    return AppendColumn( new wxDataViewColumn( label,
847        new wxDataViewToggleRenderer( wxT("bool"), mode ), model_column, width ) );
848}
849
850bool wxDataViewCtrlBase::AppendProgressColumn( const wxBitmap &label, unsigned int model_column,
851                            wxDataViewCellMode mode, int width )
852{
853    return AppendColumn( new wxDataViewColumn( label,
854        new wxDataViewProgressRenderer( wxEmptyString, wxT("long"), mode ), model_column, width ) );
855}
856
857bool wxDataViewCtrlBase::AppendDateColumn( const wxBitmap &label, unsigned int model_column,
858                            wxDataViewCellMode mode, int width )
859{
860    return AppendColumn( new wxDataViewColumn( label,
861        new wxDataViewDateRenderer( wxT("datetime"), mode ), model_column, width ) );
862}
863
864bool wxDataViewCtrlBase::AppendBitmapColumn( const wxBitmap &label, unsigned int model_column,
865                            wxDataViewCellMode mode, int width )
866{
867    return AppendColumn( new wxDataViewColumn( label,
868        new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode ), model_column, width ) );
869}
870
871bool wxDataViewCtrlBase::AppendColumn( wxDataViewColumn *col )
872{
873    m_cols.Append( (wxObject*) col );
874    col->SetOwner( (wxDataViewCtrl*) this );
875    m_model->AddViewingColumn( col, col->GetModelColumn() );
876    return true;
877}
878
879unsigned int wxDataViewCtrlBase::GetNumberOfColumns()
880{
881    return m_cols.GetCount();
882}
883
884bool wxDataViewCtrlBase::DeleteColumn( unsigned int WXUNUSED(pos) )
885{
886    return false;
887}
888
889bool wxDataViewCtrlBase::ClearColumns()
890{
891    return false;
892}
893
894wxDataViewColumn* wxDataViewCtrlBase::GetColumn( unsigned int pos )
895{
896    return (wxDataViewColumn*) m_cols[ pos ];
897}
898
899// ---------------------------------------------------------
900// wxDataViewEvent
901// ---------------------------------------------------------
902
903IMPLEMENT_DYNAMIC_CLASS(wxDataViewEvent,wxNotifyEvent)
904
905DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ROW_SELECTED)
906DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ROW_ACTIVATED)
907DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK)
908DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK)
909
910
911#endif
912