]> git.saurik.com Git - wxWidgets.git/blob - src/common/datavcmn.cpp
Fix inplace editing of custom controls for
[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 wxDataViewEditorCtrlEvtHandler *handler =
732 new wxDataViewEditorCtrlEvtHandler( m_editorCtrl, (wxDataViewRenderer*) this );
733
734 m_editorCtrl->PushEventHandler( handler );
735
736 #if defined(__WXGTK20__) && !defined(wxUSE_GENERICDATAVIEWCTRL)
737 handler->SetFocusOnIdle();
738 #else
739 m_editorCtrl->SetFocus();
740 #endif
741
742 return true;
743 }
744
745 void wxDataViewRendererBase::CancelEditing()
746 {
747 // m_editorCtrl->PopEventHandler( true );
748
749 delete m_editorCtrl;
750
751 GetOwner()->GetOwner()->GetMainWindow()->SetFocus();
752 }
753
754 bool wxDataViewRendererBase::FinishEditing()
755 {
756 // m_editorCtrl->PopEventHandler( true );
757
758 wxVariant value;
759 GetValueFromEditorCtrl( m_editorCtrl, value );
760
761 delete m_editorCtrl;
762
763 GetOwner()->GetOwner()->GetMainWindow()->SetFocus();
764
765 if (!Validate(value))
766 return false;
767
768 unsigned int col = GetOwner()->GetModelColumn();
769 GetOwner()->GetOwner()->GetModel()->SetValue( value, col, m_row );
770 GetOwner()->GetOwner()->GetModel()->ValueChanged( col, m_row );
771
772 return true;
773 }
774
775 //-----------------------------------------------------------------------------
776 // wxDataViewEditorCtrlEvtHandler
777 //-----------------------------------------------------------------------------
778
779 BEGIN_EVENT_TABLE(wxDataViewEditorCtrlEvtHandler, wxEvtHandler)
780 EVT_CHAR (wxDataViewEditorCtrlEvtHandler::OnChar)
781 EVT_KILL_FOCUS (wxDataViewEditorCtrlEvtHandler::OnKillFocus)
782 EVT_IDLE (wxDataViewEditorCtrlEvtHandler::OnIdle)
783 END_EVENT_TABLE()
784
785 wxDataViewEditorCtrlEvtHandler::wxDataViewEditorCtrlEvtHandler(
786 wxControl *editorCtrl,
787 wxDataViewRenderer *owner )
788 {
789 m_owner = owner;
790 m_editorCtrl = editorCtrl;
791
792 m_finished = false;
793 }
794
795 void wxDataViewEditorCtrlEvtHandler::OnIdle( wxIdleEvent &event )
796 {
797 if (m_focusOnIdle)
798 {
799 m_focusOnIdle = false;
800 if (wxWindow::FindFocus() != m_editorCtrl)
801 m_editorCtrl->SetFocus();
802 }
803
804 event.Skip();
805 }
806
807 void wxDataViewEditorCtrlEvtHandler::OnChar( wxKeyEvent &event )
808 {
809 switch ( event.m_keyCode )
810 {
811 case WXK_RETURN:
812 m_finished = true;
813 m_owner->FinishEditing();
814 break;
815
816 case WXK_ESCAPE:
817 m_finished = true;
818 m_owner->CancelEditing();
819 break;
820
821 default:
822 event.Skip();
823 }
824 }
825
826 void wxDataViewEditorCtrlEvtHandler::OnKillFocus( wxFocusEvent &event )
827 {
828 if (!m_finished)
829 {
830 m_finished = true;
831 m_owner->FinishEditing();
832 }
833
834 // We must let the native text control handle focus
835 event.Skip();
836 }
837
838 // ---------------------------------------------------------
839 // wxDataViewColumnBase
840 // ---------------------------------------------------------
841
842 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumnBase, wxObject)
843
844 wxDataViewColumnBase::wxDataViewColumnBase(const wxString& WXUNUSED(title),
845 wxDataViewRenderer *renderer,
846 unsigned int model_column,
847 int WXUNUSED(width),
848 wxAlignment WXUNUSED(align),
849 int WXUNUSED(flags))
850 {
851 m_renderer = renderer;
852 m_model_column = model_column;
853 m_owner = NULL;
854 m_renderer->SetOwner( (wxDataViewColumn*) this );
855
856 // NOTE: the wxDataViewColumn's ctor must store the width, align, flags
857 // parameters inside the native control!
858 }
859
860 wxDataViewColumnBase::wxDataViewColumnBase(const wxBitmap& bitmap,
861 wxDataViewRenderer *renderer,
862 unsigned int model_column,
863 int WXUNUSED(width),
864 wxAlignment WXUNUSED(align),
865 int WXUNUSED(flags) )
866 {
867 m_renderer = renderer;
868 m_model_column = model_column;
869 m_bitmap = bitmap;
870 m_owner = NULL;
871 m_renderer->SetOwner( (wxDataViewColumn*) this );
872 }
873
874 wxDataViewColumnBase::~wxDataViewColumnBase()
875 {
876 if (m_renderer)
877 delete m_renderer;
878
879 if (GetOwner())
880 {
881 GetOwner()->GetModel()->RemoveViewingColumn( (wxDataViewColumn*) this );
882 }
883 }
884
885 int wxDataViewColumnBase::GetFlags() const
886 {
887 int ret = 0;
888
889 if (IsSortable())
890 ret |= wxDATAVIEW_COL_SORTABLE;
891 if (IsResizeable())
892 ret |= wxDATAVIEW_COL_RESIZABLE;
893 if (IsHidden())
894 ret |= wxDATAVIEW_COL_HIDDEN;
895
896 return ret;
897 }
898
899 void wxDataViewColumnBase::SetFlags(int flags)
900 {
901 SetSortable((flags & wxDATAVIEW_COL_SORTABLE) != 0);
902 SetResizeable((flags & wxDATAVIEW_COL_RESIZABLE) != 0);
903 SetHidden((flags & wxDATAVIEW_COL_HIDDEN) != 0);
904 }
905
906
907 // ---------------------------------------------------------
908 // wxDataViewCtrlBase
909 // ---------------------------------------------------------
910
911 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCtrlBase, wxControl)
912
913 wxDataViewCtrlBase::wxDataViewCtrlBase()
914 {
915 m_model = NULL;
916 m_cols.DeleteContents( true );
917 }
918
919 wxDataViewCtrlBase::~wxDataViewCtrlBase()
920 {
921 // IMPORTANT: before calling DecRef() on our model (since it may
922 // result in a free() call), erase all columns (since
923 // they hold a pointer to our model)
924 m_cols.Clear();
925
926 if (m_model)
927 {
928 m_model->DecRef();
929 m_model = NULL;
930 }
931 }
932
933 bool wxDataViewCtrlBase::AssociateModel( wxDataViewListModel *model )
934 {
935 if ( m_model )
936 m_model->DecRef(); // discard old model, if any
937
938 // add our own reference to the new model:
939 m_model = model;
940 if ( m_model )
941 m_model->IncRef();
942
943 return true;
944 }
945
946 wxDataViewListModel* wxDataViewCtrlBase::GetModel()
947 {
948 return m_model;
949 }
950
951 bool wxDataViewCtrlBase::AppendTextColumn( const wxString &label, unsigned int model_column,
952 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
953 {
954 return AppendColumn( new wxDataViewColumn( label,
955 new wxDataViewTextRenderer( wxT("string"), mode, (int)align ),
956 model_column, width, align, flags ) );
957 }
958
959 bool wxDataViewCtrlBase::AppendToggleColumn( const wxString &label, unsigned int model_column,
960 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
961 {
962 return AppendColumn( new wxDataViewColumn( label,
963 new wxDataViewToggleRenderer( wxT("bool"), mode, (int)align ),
964 model_column, width, align, flags ) );
965 }
966
967 bool wxDataViewCtrlBase::AppendProgressColumn( const wxString &label, unsigned int model_column,
968 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
969 {
970 return AppendColumn( new wxDataViewColumn( label,
971 new wxDataViewProgressRenderer( wxEmptyString, wxT("long"), mode, (int)align ),
972 model_column, width, align, flags ) );
973 }
974
975 bool wxDataViewCtrlBase::AppendDateColumn( const wxString &label, unsigned int model_column,
976 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
977 {
978 return AppendColumn( new wxDataViewColumn( label,
979 new wxDataViewDateRenderer( wxT("datetime"), mode, (int)align ),
980 model_column, width, align, flags ) );
981 }
982
983 bool wxDataViewCtrlBase::AppendBitmapColumn( const wxString &label, unsigned int model_column,
984 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
985 {
986 return AppendColumn( new wxDataViewColumn( label,
987 new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode, (int)align ),
988 model_column, width, align, flags ) );
989 }
990
991 bool wxDataViewCtrlBase::AppendTextColumn( const wxBitmap &label, unsigned int model_column,
992 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
993 {
994 return AppendColumn( new wxDataViewColumn( label,
995 new wxDataViewTextRenderer( wxT("string"), mode, (int)align ),
996 model_column, width, align, flags ) );
997 }
998
999 bool wxDataViewCtrlBase::AppendToggleColumn( const wxBitmap &label, unsigned int model_column,
1000 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1001 {
1002 return AppendColumn( new wxDataViewColumn( label,
1003 new wxDataViewToggleRenderer( wxT("bool"), mode, (int)align ),
1004 model_column, width, align, flags ) );
1005 }
1006
1007 bool wxDataViewCtrlBase::AppendProgressColumn( const wxBitmap &label, unsigned int model_column,
1008 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1009 {
1010 return AppendColumn( new wxDataViewColumn( label,
1011 new wxDataViewProgressRenderer( wxEmptyString, wxT("long"), mode, (int)align ),
1012 model_column, width, align, flags ) );
1013 }
1014
1015 bool wxDataViewCtrlBase::AppendDateColumn( const wxBitmap &label, unsigned int model_column,
1016 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1017 {
1018 return AppendColumn( new wxDataViewColumn( label,
1019 new wxDataViewDateRenderer( wxT("datetime"), mode, (int)align ),
1020 model_column, width, align, flags ) );
1021 }
1022
1023 bool wxDataViewCtrlBase::AppendBitmapColumn( const wxBitmap &label, unsigned int model_column,
1024 wxDataViewCellMode mode, int width, wxAlignment align, int flags )
1025 {
1026 return AppendColumn( new wxDataViewColumn( label,
1027 new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode, (int)align ),
1028 model_column, width, align, flags ) );
1029 }
1030
1031 bool wxDataViewCtrlBase::AppendColumn( wxDataViewColumn *col )
1032 {
1033 m_cols.Append( (wxObject*) col );
1034 col->SetOwner( (wxDataViewCtrl*) this );
1035 m_model->AddViewingColumn( col, col->GetModelColumn() );
1036 return true;
1037 }
1038
1039 unsigned int wxDataViewCtrlBase::GetColumnCount() const
1040 {
1041 return m_cols.GetCount();
1042 }
1043
1044 bool wxDataViewCtrlBase::DeleteColumn( unsigned int WXUNUSED(pos) )
1045 {
1046 return false;
1047 }
1048
1049 bool wxDataViewCtrlBase::ClearColumns()
1050 {
1051 return false;
1052 }
1053
1054 wxDataViewColumn* wxDataViewCtrlBase::GetColumn( unsigned int pos )
1055 {
1056 return (wxDataViewColumn*) m_cols[ pos ];
1057 }
1058
1059 // ---------------------------------------------------------
1060 // wxDataViewEvent
1061 // ---------------------------------------------------------
1062
1063 IMPLEMENT_DYNAMIC_CLASS(wxDataViewEvent,wxNotifyEvent)
1064
1065 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ROW_SELECTED)
1066 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ROW_ACTIVATED)
1067 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK)
1068 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK)
1069
1070
1071 #endif