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