1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/datavgen.cpp
3 // Purpose: wxDataViewCtrl generic implementation
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
17 #if wxUSE_DATAVIEWCTRL
19 #include "wx/dataview.h"
21 #ifdef wxUSE_GENERICDATAVIEWCTRL
25 #include "wx/msw/wrapwin.h"
29 #include "wx/dcclient.h"
31 #include "wx/settings.h"
34 #include "wx/stockitem.h"
35 #include "wx/calctrl.h"
36 #include "wx/popupwin.h"
37 #include "wx/renderer.h"
40 //-----------------------------------------------------------------------------
42 //-----------------------------------------------------------------------------
46 //-----------------------------------------------------------------------------
47 // wxDataViewHeaderWindow
48 //-----------------------------------------------------------------------------
50 class wxDataViewHeaderWindow
: public wxWindow
53 wxDataViewHeaderWindow( wxDataViewCtrl
*parent
,
55 const wxPoint
&pos
= wxDefaultPosition
,
56 const wxSize
&size
= wxDefaultSize
,
57 const wxString
&name
= wxT("wxdataviewctrlheaderwindow") );
58 virtual ~wxDataViewHeaderWindow();
60 void SetOwner( wxDataViewCtrl
* owner
) { m_owner
= owner
; }
61 wxDataViewCtrl
*GetOwner() { return m_owner
; }
63 void OnPaint( wxPaintEvent
&event
);
64 void OnMouse( wxMouseEvent
&event
);
65 void OnSetFocus( wxFocusEvent
&event
);
68 wxDataViewCtrl
*m_owner
;
69 wxCursor
*m_resizeCursor
;
72 DECLARE_DYNAMIC_CLASS(wxDataViewHeaderWindow
)
76 //-----------------------------------------------------------------------------
77 // wxDataViewRenameTimer
78 //-----------------------------------------------------------------------------
80 class wxDataViewRenameTimer
: public wxTimer
83 wxDataViewMainWindow
*m_owner
;
86 wxDataViewRenameTimer( wxDataViewMainWindow
*owner
);
90 //-----------------------------------------------------------------------------
91 // wxDataViewTextCtrlWrapper: wraps a wxTextCtrl for inline editing
92 //-----------------------------------------------------------------------------
94 class wxDataViewTextCtrlWrapper
: public wxEvtHandler
97 // NB: text must be a valid object but not Create()d yet
98 wxDataViewTextCtrlWrapper( wxDataViewMainWindow
*owner
,
100 wxDataViewListModel
*model
,
101 unsigned int col
, unsigned int row
,
104 wxTextCtrl
*GetText() const { return m_text
; }
106 void AcceptChangesAndFinish();
109 void OnChar( wxKeyEvent
&event
);
110 void OnKeyUp( wxKeyEvent
&event
);
111 void OnKillFocus( wxFocusEvent
&event
);
113 bool AcceptChanges();
117 wxDataViewMainWindow
*m_owner
;
119 wxString m_startValue
;
120 wxDataViewListModel
*m_model
;
124 bool m_aboutToFinish
;
126 DECLARE_EVENT_TABLE()
129 //-----------------------------------------------------------------------------
130 // wxDataViewMainWindow
131 //-----------------------------------------------------------------------------
133 WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_SIZE_T(unsigned int, wxDataViewSelection
, WXDLLIMPEXP_ADV
);
135 class wxDataViewMainWindow
: public wxWindow
138 wxDataViewMainWindow( wxDataViewCtrl
*parent
,
140 const wxPoint
&pos
= wxDefaultPosition
,
141 const wxSize
&size
= wxDefaultSize
,
142 const wxString
&name
= wxT("wxdataviewctrlmainwindow") );
143 virtual ~wxDataViewMainWindow();
145 // notifications from wxDataViewListModel
148 bool RowInserted( unsigned int before
);
149 bool RowDeleted( unsigned int row
);
150 bool RowChanged( unsigned int row
);
151 bool ValueChanged( unsigned int col
, unsigned int row
);
152 bool RowsReordered( unsigned int *new_order
);
155 void SetOwner( wxDataViewCtrl
* owner
) { m_owner
= owner
; }
156 wxDataViewCtrl
*GetOwner() { return m_owner
; }
158 void OnPaint( wxPaintEvent
&event
);
159 void OnArrowChar(unsigned int newCurrent
, const wxKeyEvent
& event
);
160 void OnChar( wxKeyEvent
&event
);
161 void OnMouse( wxMouseEvent
&event
);
162 void OnSetFocus( wxFocusEvent
&event
);
163 void OnKillFocus( wxFocusEvent
&event
);
165 void UpdateDisplay();
166 void RecalculateDisplay();
167 void OnInternalIdle();
169 void OnRenameTimer();
170 void FinishEditing( wxTextCtrl
*text
);
172 void ScrollWindow( int dx
, int dy
, const wxRect
*rect
);
174 bool HasCurrentRow() { return m_currentRow
!= (unsigned int)-1; }
175 void ChangeCurrentRow( unsigned int row
);
177 bool IsSingleSel() const { return !GetParent()->HasFlag(wxDV_MULTIPLE
); };
178 bool IsEmpty() { return GetRowCount() == 0; }
180 int GetCountPerPage();
181 int GetEndOfLastCol();
182 unsigned int GetFirstVisibleRow();
183 unsigned int GetLastVisibleRow();
184 unsigned int GetRowCount();
186 void SelectAllRows( bool on
);
187 void SelectRow( unsigned int row
, bool on
);
188 void SelectRows( unsigned int from
, unsigned int to
, bool on
);
189 void ReverseRowSelection( unsigned int row
);
190 bool IsRowSelected( unsigned int row
);
192 void RefreshRow( unsigned int row
);
193 void RefreshRows( unsigned int from
, unsigned int to
);
194 void RefreshRowsAfter( unsigned int firstRow
);
197 wxDataViewCtrl
*m_owner
;
201 wxDataViewColumn
*m_currentCol
;
202 unsigned int m_currentRow
;
203 wxDataViewSelection m_selection
;
205 wxDataViewRenameTimer
*m_renameTimer
;
206 wxDataViewTextCtrlWrapper
*m_textctrlWrapper
;
214 // for double click logic
215 unsigned int m_lineLastClicked
,
216 m_lineBeforeLastClicked
,
217 m_lineSelectSingleOnUp
;
220 DECLARE_DYNAMIC_CLASS(wxDataViewMainWindow
)
221 DECLARE_EVENT_TABLE()
224 // ---------------------------------------------------------
225 // wxGenericDataViewListModelNotifier
226 // ---------------------------------------------------------
228 class wxGenericDataViewListModelNotifier
: public wxDataViewListModelNotifier
231 wxGenericDataViewListModelNotifier( wxDataViewMainWindow
*mainWindow
)
232 { m_mainWindow
= mainWindow
; }
234 virtual bool RowAppended()
235 { return m_mainWindow
->RowAppended(); }
236 virtual bool RowPrepended()
237 { return m_mainWindow
->RowPrepended(); }
238 virtual bool RowInserted( unsigned int before
)
239 { return m_mainWindow
->RowInserted( before
); }
240 virtual bool RowDeleted( unsigned int row
)
241 { return m_mainWindow
->RowDeleted( row
); }
242 virtual bool RowChanged( unsigned int row
)
243 { return m_mainWindow
->RowChanged( row
); }
244 virtual bool ValueChanged( unsigned int col
, unsigned int row
)
245 { return m_mainWindow
->ValueChanged( col
, row
); }
246 virtual bool RowsReordered( unsigned int *new_order
)
247 { return m_mainWindow
->RowsReordered( new_order
); }
248 virtual bool Cleared()
249 { return m_mainWindow
->Cleared(); }
251 wxDataViewMainWindow
*m_mainWindow
;
254 // ---------------------------------------------------------
255 // wxDataViewRenderer
256 // ---------------------------------------------------------
258 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer
, wxDataViewRendererBase
)
260 wxDataViewRenderer::wxDataViewRenderer( const wxString
&varianttype
, wxDataViewCellMode mode
) :
261 wxDataViewRendererBase( varianttype
, mode
)
266 wxDataViewRenderer::~wxDataViewRenderer()
272 wxDC
*wxDataViewRenderer::GetDC()
276 if (GetOwner() == NULL
)
278 if (GetOwner()->GetOwner() == NULL
)
280 m_dc
= new wxClientDC( GetOwner()->GetOwner() );
286 // ---------------------------------------------------------
287 // wxDataViewCustomRenderer
288 // ---------------------------------------------------------
290 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomRenderer
, wxDataViewRenderer
)
292 wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString
&varianttype
,
293 wxDataViewCellMode mode
) :
294 wxDataViewRenderer( varianttype
, mode
)
298 // ---------------------------------------------------------
299 // wxDataViewTextRenderer
300 // ---------------------------------------------------------
302 IMPLEMENT_CLASS(wxDataViewTextRenderer
, wxDataViewCustomRenderer
)
304 wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString
&varianttype
, wxDataViewCellMode mode
) :
305 wxDataViewCustomRenderer( varianttype
, mode
)
309 bool wxDataViewTextRenderer::SetValue( const wxVariant
&value
)
311 m_text
= value
.GetString();
316 bool wxDataViewTextRenderer::GetValue( wxVariant
& WXUNUSED(value
) )
321 bool wxDataViewTextRenderer::Render( wxRect cell
, wxDC
*dc
, int WXUNUSED(state
) )
323 dc
->DrawText( m_text
, cell
.x
, cell
.y
);
328 wxSize
wxDataViewTextRenderer::GetSize()
330 return wxSize(80,20);
333 // ---------------------------------------------------------
334 // wxDataViewBitmapRenderer
335 // ---------------------------------------------------------
337 IMPLEMENT_CLASS(wxDataViewBitmapRenderer
, wxDataViewCustomRenderer
)
339 wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString
&varianttype
, wxDataViewCellMode mode
) :
340 wxDataViewCustomRenderer( varianttype
, mode
)
344 bool wxDataViewBitmapRenderer::SetValue( const wxVariant
&value
)
346 if (value
.GetType() == wxT("wxBitmap"))
348 if (value
.GetType() == wxT("wxIcon"))
354 bool wxDataViewBitmapRenderer::GetValue( wxVariant
& WXUNUSED(value
) )
359 bool wxDataViewBitmapRenderer::Render( wxRect cell
, wxDC
*dc
, int WXUNUSED(state
) )
362 dc
->DrawBitmap( m_bitmap
, cell
.x
, cell
.y
);
363 else if (m_icon
.Ok())
364 dc
->DrawIcon( m_icon
, cell
.x
, cell
.y
);
369 wxSize
wxDataViewBitmapRenderer::GetSize()
372 return wxSize( m_bitmap
.GetWidth(), m_bitmap
.GetHeight() );
373 else if (m_icon
.Ok())
374 return wxSize( m_icon
.GetWidth(), m_icon
.GetHeight() );
376 return wxSize(16,16);
379 // ---------------------------------------------------------
380 // wxDataViewToggleRenderer
381 // ---------------------------------------------------------
383 IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleRenderer
, wxDataViewCustomRenderer
)
385 wxDataViewToggleRenderer::wxDataViewToggleRenderer( const wxString
&varianttype
,
386 wxDataViewCellMode mode
) :
387 wxDataViewCustomRenderer( varianttype
, mode
)
392 bool wxDataViewToggleRenderer::SetValue( const wxVariant
&value
)
394 m_toggle
= value
.GetBool();
399 bool wxDataViewToggleRenderer::GetValue( wxVariant
&WXUNUSED(value
) )
404 bool wxDataViewToggleRenderer::Render( wxRect cell
, wxDC
*dc
, int WXUNUSED(state
) )
406 // User wxRenderer here
409 rect
.x
= cell
.x
+ cell
.width
/2 - 10;
411 rect
.y
= cell
.y
+ cell
.height
/2 - 10;
416 flags
|= wxCONTROL_CHECKED
;
417 if (GetMode() != wxDATAVIEW_CELL_ACTIVATABLE
)
418 flags
|= wxCONTROL_DISABLED
;
420 wxRendererNative::Get().DrawCheckBox(
421 GetOwner()->GetOwner(),
429 bool wxDataViewToggleRenderer::Activate( wxRect
WXUNUSED(cell
), wxDataViewListModel
*model
, unsigned int col
, unsigned int row
)
431 bool value
= !m_toggle
;
432 wxVariant variant
= value
;
433 model
->SetValue( variant
, col
, row
);
434 model
->ValueChanged( col
, row
);
438 wxSize
wxDataViewToggleRenderer::GetSize()
440 return wxSize(20,20);
443 // ---------------------------------------------------------
444 // wxDataViewProgressRenderer
445 // ---------------------------------------------------------
447 IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressRenderer
, wxDataViewCustomRenderer
)
449 wxDataViewProgressRenderer::wxDataViewProgressRenderer( const wxString
&label
,
450 const wxString
&varianttype
, wxDataViewCellMode mode
) :
451 wxDataViewCustomRenderer( varianttype
, mode
)
457 wxDataViewProgressRenderer::~wxDataViewProgressRenderer()
461 bool wxDataViewProgressRenderer::SetValue( const wxVariant
&value
)
463 m_value
= (long) value
;
465 if (m_value
< 0) m_value
= 0;
466 if (m_value
> 100) m_value
= 100;
471 bool wxDataViewProgressRenderer::Render( wxRect cell
, wxDC
*dc
, int WXUNUSED(state
) )
473 double pct
= (double)m_value
/ 100.0;
475 bar
.width
= (int)(cell
.width
* pct
);
476 dc
->SetPen( *wxTRANSPARENT_PEN
);
477 dc
->SetBrush( *wxBLUE_BRUSH
);
478 dc
->DrawRectangle( bar
);
480 dc
->SetBrush( *wxTRANSPARENT_BRUSH
);
481 dc
->SetPen( *wxBLACK_PEN
);
482 dc
->DrawRectangle( cell
);
487 wxSize
wxDataViewProgressRenderer::GetSize()
489 return wxSize(40,12);
492 // ---------------------------------------------------------
493 // wxDataViewDateRenderer
494 // ---------------------------------------------------------
496 class wxDataViewDateRendererPopupTransient
: public wxPopupTransientWindow
499 wxDataViewDateRendererPopupTransient( wxWindow
* parent
, wxDateTime
*value
,
500 wxDataViewListModel
*model
, unsigned int col
, unsigned int row
) :
501 wxPopupTransientWindow( parent
, wxBORDER_SIMPLE
)
506 m_cal
= new wxCalendarCtrl( this, wxID_ANY
, *value
);
507 wxBoxSizer
*sizer
= new wxBoxSizer( wxHORIZONTAL
);
508 sizer
->Add( m_cal
, 1, wxGROW
);
513 void OnCalendar( wxCalendarEvent
&event
);
515 wxCalendarCtrl
*m_cal
;
516 wxDataViewListModel
*m_model
;
521 virtual void OnDismiss()
526 DECLARE_EVENT_TABLE()
529 BEGIN_EVENT_TABLE(wxDataViewDateRendererPopupTransient
,wxPopupTransientWindow
)
530 EVT_CALENDAR( wxID_ANY
, wxDataViewDateRendererPopupTransient::OnCalendar
)
533 void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent
&event
)
535 wxDateTime date
= event
.GetDate();
536 wxVariant value
= date
;
537 m_model
->SetValue( value
, m_col
, m_row
);
538 m_model
->ValueChanged( m_col
, m_row
);
542 IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer
, wxDataViewCustomRenderer
)
544 wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString
&varianttype
,
545 wxDataViewCellMode mode
) :
546 wxDataViewCustomRenderer( varianttype
, mode
)
550 bool wxDataViewDateRenderer::SetValue( const wxVariant
&value
)
552 m_date
= value
.GetDateTime();
557 bool wxDataViewDateRenderer::Render( wxRect cell
, wxDC
*dc
, int WXUNUSED(state
) )
559 dc
->SetFont( GetOwner()->GetOwner()->GetFont() );
560 wxString tmp
= m_date
.FormatDate();
561 dc
->DrawText( tmp
, cell
.x
, cell
.y
);
566 wxSize
wxDataViewDateRenderer::GetSize()
568 wxDataViewCtrl
* view
= GetOwner()->GetOwner();
569 wxString tmp
= m_date
.FormatDate();
571 view
->GetTextExtent( tmp
, &x
, &y
, &d
);
572 return wxSize(x
,y
+d
);
575 bool wxDataViewDateRenderer::Activate( wxRect
WXUNUSED(cell
), wxDataViewListModel
*model
, unsigned int col
, unsigned int row
)
578 model
->GetValue( variant
, col
, row
);
579 wxDateTime value
= variant
.GetDateTime();
581 wxDataViewDateRendererPopupTransient
*popup
= new wxDataViewDateRendererPopupTransient(
582 GetOwner()->GetOwner()->GetParent(), &value
, model
, col
, row
);
583 wxPoint pos
= wxGetMousePosition();
586 popup
->Popup( popup
->m_cal
);
591 // ---------------------------------------------------------
593 // ---------------------------------------------------------
595 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumn
, wxDataViewColumnBase
)
597 wxDataViewColumn::wxDataViewColumn( const wxString
&title
, wxDataViewRenderer
*cell
, unsigned int model_column
,
598 int width
, int flags
) :
599 wxDataViewColumnBase( title
, cell
, model_column
, width
, flags
)
606 wxDataViewColumn::wxDataViewColumn( const wxBitmap
&bitmap
, wxDataViewRenderer
*cell
, unsigned int model_column
,
607 int width
, int flags
) :
608 wxDataViewColumnBase( bitmap
, cell
, model_column
, width
, flags
)
615 wxDataViewColumn::~wxDataViewColumn()
619 void wxDataViewColumn::SetTitle( const wxString
&title
)
621 wxDataViewColumnBase::SetTitle( title
);
625 int wxDataViewColumn::GetWidth()
630 //-----------------------------------------------------------------------------
631 // wxDataViewHeaderWindow
632 //-----------------------------------------------------------------------------
634 IMPLEMENT_ABSTRACT_CLASS(wxDataViewHeaderWindow
, wxWindow
)
636 BEGIN_EVENT_TABLE(wxDataViewHeaderWindow
,wxWindow
)
637 EVT_PAINT (wxDataViewHeaderWindow::OnPaint
)
638 EVT_MOUSE_EVENTS (wxDataViewHeaderWindow::OnMouse
)
639 EVT_SET_FOCUS (wxDataViewHeaderWindow::OnSetFocus
)
642 wxDataViewHeaderWindow::wxDataViewHeaderWindow( wxDataViewCtrl
*parent
, wxWindowID id
,
643 const wxPoint
&pos
, const wxSize
&size
, const wxString
&name
) :
644 wxWindow( parent
, id
, pos
, size
, 0, name
)
648 m_resizeCursor
= new wxCursor( wxCURSOR_SIZEWE
);
650 wxVisualAttributes attr
= wxPanel::GetClassDefaultAttributes();
651 SetOwnForegroundColour( attr
.colFg
);
652 SetOwnBackgroundColour( attr
.colBg
);
654 SetOwnFont( attr
.font
);
657 wxDataViewHeaderWindow::~wxDataViewHeaderWindow()
659 delete m_resizeCursor
;
662 void wxDataViewHeaderWindow::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
665 GetClientSize( &w
, &h
);
667 wxPaintDC
dc( this );
670 m_owner
->GetScrollPixelsPerUnit( &xpix
, NULL
);
673 m_owner
->GetViewStart( &x
, NULL
);
675 // account for the horz scrollbar offset
676 dc
.SetDeviceOrigin( -x
* xpix
, 0 );
678 dc
.SetFont( GetFont() );
680 unsigned int cols
= GetOwner()->GetNumberOfColumns();
683 for (i
= 0; i
< cols
; i
++)
685 wxDataViewColumn
*col
= GetOwner()->GetColumn( i
);
686 int width
= col
->GetWidth();
691 wxRendererNative::Get().DrawHeaderButton
695 wxRect(xpos
, 0, cw
, ch
-1),
696 m_parent
->IsEnabled() ? 0
697 : (int)wxCONTROL_DISABLED
700 dc
.DrawText( col
->GetTitle(), xpos
+3, 3 );
706 void wxDataViewHeaderWindow::OnMouse( wxMouseEvent
&WXUNUSED(event
) )
710 void wxDataViewHeaderWindow::OnSetFocus( wxFocusEvent
&event
)
712 GetParent()->SetFocus();
716 //-----------------------------------------------------------------------------
717 // wxDataViewRenameTimer
718 //-----------------------------------------------------------------------------
720 wxDataViewRenameTimer::wxDataViewRenameTimer( wxDataViewMainWindow
*owner
)
725 void wxDataViewRenameTimer::Notify()
727 m_owner
->OnRenameTimer();
730 //-----------------------------------------------------------------------------
731 // wxDataViewTextCtrlWrapper: wraps a wxTextCtrl for inline editing
732 //-----------------------------------------------------------------------------
734 BEGIN_EVENT_TABLE(wxDataViewTextCtrlWrapper
, wxEvtHandler
)
735 EVT_CHAR (wxDataViewTextCtrlWrapper::OnChar
)
736 EVT_KEY_UP (wxDataViewTextCtrlWrapper::OnKeyUp
)
737 EVT_KILL_FOCUS (wxDataViewTextCtrlWrapper::OnKillFocus
)
740 wxDataViewTextCtrlWrapper::wxDataViewTextCtrlWrapper(
741 wxDataViewMainWindow
*owner
,
743 wxDataViewListModel
*model
,
744 unsigned int col
, unsigned int row
,
754 m_aboutToFinish
= false;
757 model
->GetValue( value
, col
, row
);
758 m_startValue
= value
.GetString();
760 m_owner
->GetOwner()->CalcScrolledPosition(
761 rectLabel
.x
, rectLabel
.y
, &rectLabel
.x
, &rectLabel
.y
);
763 m_text
->Create( owner
, wxID_ANY
, m_startValue
,
764 wxPoint(rectLabel
.x
-2,rectLabel
.y
-2),
765 wxSize(rectLabel
.width
+7,rectLabel
.height
+4) );
768 m_text
->PushEventHandler(this);
771 void wxDataViewTextCtrlWrapper::AcceptChangesAndFinish()
773 m_aboutToFinish
= true;
775 // Notify the owner about the changes
778 // Even if vetoed, close the control (consistent with MSW)
782 void wxDataViewTextCtrlWrapper::OnChar( wxKeyEvent
&event
)
784 switch ( event
.m_keyCode
)
787 AcceptChangesAndFinish();
791 // m_owner->OnRenameCancelled( m_itemEdited );
800 void wxDataViewTextCtrlWrapper::OnKeyUp( wxKeyEvent
&event
)
808 // auto-grow the textctrl
809 wxSize parentSize
= m_owner
->GetSize();
810 wxPoint myPos
= m_text
->GetPosition();
811 wxSize mySize
= m_text
->GetSize();
813 m_text
->GetTextExtent(m_text
->GetValue() + _T("MM"), &sx
, &sy
);
814 if (myPos
.x
+ sx
> parentSize
.x
)
815 sx
= parentSize
.x
- myPos
.x
;
818 m_text
->SetSize(sx
, wxDefaultCoord
);
823 void wxDataViewTextCtrlWrapper::OnKillFocus( wxFocusEvent
&event
)
825 if ( !m_finished
&& !m_aboutToFinish
)
828 //if ( !AcceptChanges() )
829 // m_owner->OnRenameCancelled( m_itemEdited );
834 // We must let the native text control handle focus
838 bool wxDataViewTextCtrlWrapper::AcceptChanges()
840 const wxString value
= m_text
->GetValue();
842 if ( value
== m_startValue
)
843 // nothing changed, always accept
846 // if ( !m_owner->OnRenameAccept(m_itemEdited, value) )
847 // vetoed by the user
850 // accepted, do rename the item
853 m_model
->SetValue( variant
, m_col
, m_row
);
854 m_model
->ValueChanged( m_col
, m_row
);
859 void wxDataViewTextCtrlWrapper::Finish()
865 m_text
->RemoveEventHandler(this);
866 m_owner
->FinishEditing(m_text
);
869 wxPendingDelete
.Append( this );
873 //-----------------------------------------------------------------------------
874 // wxDataViewMainWindow
875 //-----------------------------------------------------------------------------
877 int LINKAGEMODE
wxDataViewSelectionCmp( unsigned int row1
, unsigned int row2
)
879 if (row1
> row2
) return 1;
880 if (row1
== row2
) return 0;
885 IMPLEMENT_ABSTRACT_CLASS(wxDataViewMainWindow
, wxWindow
)
887 BEGIN_EVENT_TABLE(wxDataViewMainWindow
,wxWindow
)
888 EVT_PAINT (wxDataViewMainWindow::OnPaint
)
889 EVT_MOUSE_EVENTS (wxDataViewMainWindow::OnMouse
)
890 EVT_SET_FOCUS (wxDataViewMainWindow::OnSetFocus
)
891 EVT_KILL_FOCUS (wxDataViewMainWindow::OnKillFocus
)
892 EVT_CHAR (wxDataViewMainWindow::OnChar
)
895 wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl
*parent
, wxWindowID id
,
896 const wxPoint
&pos
, const wxSize
&size
, const wxString
&name
) :
897 wxWindow( parent
, id
, pos
, size
, wxWANTS_CHARS
, name
),
898 m_selection( wxDataViewSelectionCmp
)
903 m_lastOnSame
= false;
904 m_renameTimer
= new wxDataViewRenameTimer( this );
905 m_textctrlWrapper
= NULL
;
907 // TODO: user better initial values/nothing selected
911 // TODO: we need to calculate this smartly
915 m_dragStart
= wxPoint(0,0);
916 m_lineLastClicked
= (unsigned int) -1;
917 m_lineBeforeLastClicked
= (unsigned int) -1;
918 m_lineSelectSingleOnUp
= (unsigned int) -1;
922 SetBackgroundColour( *wxWHITE
);
927 wxDataViewMainWindow::~wxDataViewMainWindow()
929 delete m_renameTimer
;
932 void wxDataViewMainWindow::OnRenameTimer()
934 // We have to call this here because changes may just have
935 // been made and no screen update taken place.
941 unsigned int cols
= GetOwner()->GetNumberOfColumns();
943 for (i
= 0; i
< cols
; i
++)
945 wxDataViewColumn
*c
= GetOwner()->GetColumn( i
);
946 if (c
== m_currentCol
)
948 xpos
+= c
->GetWidth();
950 wxRect
labelRect( xpos
, m_currentRow
* m_lineHeight
, m_currentCol
->GetWidth(), m_lineHeight
);
952 wxClassInfo
*textControlClass
= CLASSINFO(wxTextCtrl
);
954 wxTextCtrl
* const text
= (wxTextCtrl
*)textControlClass
->CreateObject();
955 m_textctrlWrapper
= new wxDataViewTextCtrlWrapper(this, text
, GetOwner()->GetModel(),
956 m_currentCol
->GetModelColumn(), m_currentRow
, labelRect
);
959 void wxDataViewMainWindow::FinishEditing( wxTextCtrl
*text
)
962 m_textctrlWrapper
= NULL
;
964 // SetFocusIgnoringChildren();
967 bool wxDataViewMainWindow::RowAppended()
972 bool wxDataViewMainWindow::RowPrepended()
977 bool wxDataViewMainWindow::RowInserted( unsigned int WXUNUSED(before
) )
982 bool wxDataViewMainWindow::RowDeleted( unsigned int WXUNUSED(row
) )
987 bool wxDataViewMainWindow::RowChanged( unsigned int WXUNUSED(row
) )
992 bool wxDataViewMainWindow::ValueChanged( unsigned int WXUNUSED(col
), unsigned int row
)
994 wxRect
rect( 0, row
*m_lineHeight
, 10000, m_lineHeight
);
995 m_owner
->CalcScrolledPosition( rect
.x
, rect
.y
, &rect
.x
, &rect
.y
);
996 Refresh( true, &rect
);
1001 bool wxDataViewMainWindow::RowsReordered( unsigned int *WXUNUSED(new_order
) )
1008 bool wxDataViewMainWindow::Cleared()
1013 void wxDataViewMainWindow::UpdateDisplay()
1018 void wxDataViewMainWindow::OnInternalIdle()
1020 wxWindow::OnInternalIdle();
1024 RecalculateDisplay();
1029 void wxDataViewMainWindow::RecalculateDisplay()
1031 wxDataViewListModel
*model
= GetOwner()->GetModel();
1039 unsigned int cols
= GetOwner()->GetNumberOfColumns();
1041 for (i
= 0; i
< cols
; i
++)
1043 wxDataViewColumn
*col
= GetOwner()->GetColumn( i
);
1044 width
+= col
->GetWidth();
1047 int height
= model
->GetNumberOfRows() * m_lineHeight
;
1049 SetVirtualSize( width
, height
);
1050 GetOwner()->SetScrollRate( 10, m_lineHeight
);
1055 void wxDataViewMainWindow::ScrollWindow( int dx
, int dy
, const wxRect
*rect
)
1057 wxWindow::ScrollWindow( dx
, dy
, rect
);
1058 GetOwner()->m_headerArea
->ScrollWindow( dx
, 0 );
1061 void wxDataViewMainWindow::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
1063 wxPaintDC
dc( this );
1065 GetOwner()->PrepareDC( dc
);
1067 dc
.SetFont( GetFont() );
1069 wxRect update
= GetUpdateRegion().GetBox();
1070 m_owner
->CalcUnscrolledPosition( update
.x
, update
.y
, &update
.x
, &update
.y
);
1072 wxDataViewListModel
*model
= GetOwner()->GetModel();
1074 unsigned int item_start
= wxMax( 0, (update
.y
/ m_lineHeight
) );
1075 unsigned int item_count
= wxMin( (int)(((update
.y
+ update
.height
) / m_lineHeight
) - item_start
+ 1),
1076 (int)(model
->GetNumberOfRows()-item_start
) );
1081 for (item
= item_start
; item
< item_start
+item_count
; item
++)
1083 if (m_selection
.Index( item
) != wxNOT_FOUND
)
1085 int flags
= wxCONTROL_SELECTED
;
1086 if (item
== m_currentRow
)
1087 flags
|= wxCONTROL_CURRENT
;
1089 flags
|= wxCONTROL_FOCUSED
;
1090 wxRect
rect( 0, item
*m_lineHeight
+1, GetEndOfLastCol(), m_lineHeight
-2 );
1091 wxRendererNative::Get().DrawItemSelectionRect
1101 if (item
== m_currentRow
)
1103 int flags
= wxCONTROL_CURRENT
;
1105 flags
|= wxCONTROL_FOCUSED
; // should have no effect
1106 wxRect
rect( 0, item
*m_lineHeight
+1, GetEndOfLastCol(), m_lineHeight
-2 );
1107 wxRendererNative::Get().DrawItemSelectionRect
1121 cell_rect
.height
= m_lineHeight
;
1122 unsigned int cols
= GetOwner()->GetNumberOfColumns();
1124 for (i
= 0; i
< cols
; i
++)
1126 wxDataViewColumn
*col
= GetOwner()->GetColumn( i
);
1127 wxDataViewRenderer
*cell
= col
->GetRenderer();
1128 cell_rect
.width
= col
->GetWidth();
1130 for (item
= item_start
; item
< item_start
+item_count
; item
++)
1132 cell_rect
.y
= item
*m_lineHeight
;
1134 model
->GetValue( value
, col
->GetModelColumn(), item
);
1135 cell
->SetValue( value
);
1136 wxSize size
= cell
->GetSize();
1137 // cannot be bigger than allocated space
1138 size
.x
= wxMin( size
.x
, cell_rect
.width
);
1139 size
.y
= wxMin( size
.y
, cell_rect
.height
);
1140 // TODO: check for left/right/centre alignment here
1143 item_rect
.x
= cell_rect
.x
+ (cell_rect
.width
/ 2) - (size
.x
/ 2);
1144 item_rect
.y
= cell_rect
.y
+ (cell_rect
.height
/ 2) - (size
.y
/ 2);
1146 item_rect
.width
= size
.x
;
1147 item_rect
.height
= size
.y
;
1148 cell
->Render( item_rect
, &dc
, 0 );
1151 cell_rect
.x
+= cell_rect
.width
;
1155 int wxDataViewMainWindow::GetCountPerPage()
1157 wxSize size
= GetClientSize();
1158 return size
.y
/ m_lineHeight
;
1161 int wxDataViewMainWindow::GetEndOfLastCol()
1165 for (i
= 0; i
< GetOwner()->GetNumberOfColumns(); i
++)
1167 wxDataViewColumn
*c
= GetOwner()->GetColumn( i
);
1168 width
+= c
->GetWidth();
1173 unsigned int wxDataViewMainWindow::GetFirstVisibleRow()
1177 m_owner
->CalcUnscrolledPosition( x
, y
, &x
, &y
);
1179 return y
/ m_lineHeight
;
1182 unsigned int wxDataViewMainWindow::GetLastVisibleRow()
1184 wxSize client_size
= GetClientSize();
1185 m_owner
->CalcUnscrolledPosition( client_size
.x
, client_size
.y
, &client_size
.x
, &client_size
.y
);
1187 return wxMin( GetRowCount()-1, ((unsigned)client_size
.y
/m_lineHeight
)+1 );
1190 unsigned int wxDataViewMainWindow::GetRowCount()
1192 return GetOwner()->GetModel()->GetNumberOfRows();
1195 void wxDataViewMainWindow::ChangeCurrentRow( unsigned int row
)
1202 void wxDataViewMainWindow::SelectAllRows( bool on
)
1209 m_selection
.Clear();
1210 for (unsigned int i
= 0; i
< GetRowCount(); i
++)
1211 m_selection
.Add( i
);
1216 unsigned int first_visible
= GetFirstVisibleRow();
1217 unsigned int last_visible
= GetLastVisibleRow();
1219 for (i
= 0; i
< m_selection
.GetCount(); i
++)
1221 unsigned int row
= m_selection
[i
];
1222 if ((row
>= first_visible
) && (row
<= last_visible
))
1225 m_selection
.Clear();
1229 void wxDataViewMainWindow::SelectRow( unsigned int row
, bool on
)
1231 if (m_selection
.Index( row
) == wxNOT_FOUND
)
1235 m_selection
.Add( row
);
1243 m_selection
.Remove( row
);
1249 void wxDataViewMainWindow::SelectRows( unsigned int from
, unsigned int to
, bool on
)
1253 unsigned int tmp
= from
;
1259 for (i
= from
; i
<= to
; i
++)
1261 if (m_selection
.Index( i
) == wxNOT_FOUND
)
1264 m_selection
.Add( i
);
1269 m_selection
.Remove( i
);
1272 RefreshRows( from
, to
);
1275 void wxDataViewMainWindow::ReverseRowSelection( unsigned int row
)
1277 if (m_selection
.Index( row
) == wxNOT_FOUND
)
1278 m_selection
.Add( row
);
1280 m_selection
.Remove( row
);
1284 bool wxDataViewMainWindow::IsRowSelected( unsigned int row
)
1286 return (m_selection
.Index( row
) != wxNOT_FOUND
);
1289 void wxDataViewMainWindow::RefreshRow( unsigned int row
)
1291 wxRect
rect( 0, row
*m_lineHeight
, GetEndOfLastCol(), m_lineHeight
);
1292 m_owner
->CalcScrolledPosition( rect
.x
, rect
.y
, &rect
.x
, &rect
.y
);
1294 wxSize client_size
= GetClientSize();
1295 wxRect
client_rect( 0, 0, client_size
.x
, client_size
.y
);
1296 wxRect intersect_rect
= client_rect
.Intersect( rect
);
1297 if (intersect_rect
.width
> 0)
1298 Refresh( true, &intersect_rect
);
1301 void wxDataViewMainWindow::RefreshRows( unsigned int from
, unsigned int to
)
1305 unsigned int tmp
= to
;
1310 wxRect
rect( 0, from
*m_lineHeight
, GetEndOfLastCol(), (to
-from
+1) * m_lineHeight
);
1311 m_owner
->CalcScrolledPosition( rect
.x
, rect
.y
, &rect
.x
, &rect
.y
);
1313 wxSize client_size
= GetClientSize();
1314 wxRect
client_rect( 0, 0, client_size
.x
, client_size
.y
);
1315 wxRect intersect_rect
= client_rect
.Intersect( rect
);
1316 if (intersect_rect
.width
> 0)
1317 Refresh( true, &intersect_rect
);
1320 void wxDataViewMainWindow::RefreshRowsAfter( unsigned int firstRow
)
1322 unsigned int count
= GetRowCount();
1323 if (firstRow
> count
)
1326 wxRect
rect( 0, firstRow
*m_lineHeight
, GetEndOfLastCol(), count
* m_lineHeight
);
1327 m_owner
->CalcScrolledPosition( rect
.x
, rect
.y
, &rect
.x
, &rect
.y
);
1329 wxSize client_size
= GetClientSize();
1330 wxRect
client_rect( 0, 0, client_size
.x
, client_size
.y
);
1331 wxRect intersect_rect
= client_rect
.Intersect( rect
);
1332 if (intersect_rect
.width
> 0)
1333 Refresh( true, &intersect_rect
);
1336 void wxDataViewMainWindow::OnArrowChar(unsigned int newCurrent
, const wxKeyEvent
& event
)
1338 wxCHECK_RET( newCurrent
< GetRowCount(),
1339 _T("invalid item index in OnArrowChar()") );
1341 // if there is no selection, we cannot move it anywhere
1342 if (!HasCurrentRow())
1345 unsigned int oldCurrent
= m_currentRow
;
1347 // in single selection we just ignore Shift as we can't select several
1349 if ( event
.ShiftDown() && !IsSingleSel() )
1351 RefreshRow( oldCurrent
);
1353 ChangeCurrentRow( newCurrent
);
1355 // select all the items between the old and the new one
1356 if ( oldCurrent
> newCurrent
)
1358 newCurrent
= oldCurrent
;
1359 oldCurrent
= m_currentRow
;
1362 SelectRows( oldCurrent
, newCurrent
, true );
1366 RefreshRow( oldCurrent
);
1368 // all previously selected items are unselected unless ctrl is held
1369 if ( !event
.ControlDown() )
1370 SelectAllRows(false);
1372 ChangeCurrentRow( newCurrent
);
1374 if ( !event
.ControlDown() )
1375 SelectRow( m_currentRow
, true );
1377 RefreshRow( m_currentRow
);
1383 void wxDataViewMainWindow::OnChar( wxKeyEvent
&event
)
1385 if (event
.GetKeyCode() == WXK_TAB
)
1387 wxNavigationKeyEvent nevent
;
1388 nevent
.SetWindowChange( event
.ControlDown() );
1389 nevent
.SetDirection( !event
.ShiftDown() );
1390 nevent
.SetEventObject( GetParent()->GetParent() );
1391 nevent
.SetCurrentFocus( m_parent
);
1392 if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent
))
1396 // no item -> nothing to do
1397 if (!HasCurrentRow())
1403 // don't use m_linesPerPage directly as it might not be computed yet
1404 const int pageSize
= GetCountPerPage();
1405 wxCHECK_RET( pageSize
, _T("should have non zero page size") );
1407 switch ( event
.GetKeyCode() )
1410 if ( m_currentRow
> 0 )
1411 OnArrowChar( m_currentRow
- 1, event
);
1415 if ( m_currentRow
< GetRowCount() - 1 )
1416 OnArrowChar( m_currentRow
+ 1, event
);
1421 OnArrowChar( GetRowCount() - 1, event
);
1426 OnArrowChar( 0, event
);
1431 int steps
= pageSize
- 1;
1432 int index
= m_currentRow
- steps
;
1436 OnArrowChar( index
, event
);
1442 int steps
= pageSize
- 1;
1443 unsigned int index
= m_currentRow
+ steps
;
1444 unsigned int count
= GetRowCount();
1445 if ( index
>= count
)
1448 OnArrowChar( index
, event
);
1457 void wxDataViewMainWindow::OnMouse( wxMouseEvent
&event
)
1459 if (event
.GetEventType() == wxEVT_MOUSEWHEEL
)
1461 // let the base handle mouse wheel events.
1466 int x
= event
.GetX();
1467 int y
= event
.GetY();
1468 m_owner
->CalcUnscrolledPosition( x
, y
, &x
, &y
);
1470 wxDataViewColumn
*col
= NULL
;
1473 unsigned int cols
= GetOwner()->GetNumberOfColumns();
1475 for (i
= 0; i
< cols
; i
++)
1477 wxDataViewColumn
*c
= GetOwner()->GetColumn( i
);
1478 if (x
< xpos
+ c
->GetWidth())
1483 xpos
+= c
->GetWidth();
1487 wxDataViewRenderer
*cell
= col
->GetRenderer();
1489 unsigned int current
= y
/ m_lineHeight
;
1491 if ((current
> GetRowCount()) || (x
> GetEndOfLastCol()))
1493 // Unselect all if below the last row ?
1497 wxDataViewListModel
*model
= GetOwner()->GetModel();
1499 if (event
.Dragging())
1501 if (m_dragCount
== 0)
1503 // we have to report the raw, physical coords as we want to be
1504 // able to call HitTest(event.m_pointDrag) from the user code to
1505 // get the item being dragged
1506 m_dragStart
= event
.GetPosition();
1511 if (m_dragCount
!= 3)
1514 if (event
.LeftIsDown())
1516 // Notify cell about drag
1525 bool forceClick
= false;
1527 if (event
.ButtonDClick())
1529 m_renameTimer
->Stop();
1530 m_lastOnSame
= false;
1533 if (event
.LeftDClick())
1535 if ( current
== m_lineLastClicked
)
1537 if (cell
->GetMode() == wxDATAVIEW_CELL_ACTIVATABLE
)
1540 model
->GetValue( value
, col
->GetModelColumn(), current
);
1541 cell
->SetValue( value
);
1542 wxRect
cell_rect( xpos
, current
* m_lineHeight
, col
->GetWidth(), m_lineHeight
);
1543 cell
->Activate( cell_rect
, model
, col
->GetModelColumn(), current
);
1549 // The first click was on another item, so don't interpret this as
1550 // a double click, but as a simple click instead
1557 if (m_lineSelectSingleOnUp
!= (unsigned int)-1)
1559 // select single line
1560 SelectAllRows( false );
1561 SelectRow( m_lineSelectSingleOnUp
, true );
1566 if ((col
== m_currentCol
) && (current
== m_currentRow
) &&
1567 (cell
->GetMode() == wxDATAVIEW_CELL_EDITABLE
) )
1569 m_renameTimer
->Start( 100, true );
1573 m_lastOnSame
= false;
1574 m_lineSelectSingleOnUp
= (unsigned int)-1;
1578 // This is necessary, because after a DnD operation in
1579 // from and to ourself, the up event is swallowed by the
1580 // DnD code. So on next non-up event (which means here and
1581 // now) m_lineSelectSingleOnUp should be reset.
1582 m_lineSelectSingleOnUp
= (unsigned int)-1;
1585 if (event
.RightDown())
1587 m_lineBeforeLastClicked
= m_lineLastClicked
;
1588 m_lineLastClicked
= current
;
1590 // If the item is already selected, do not update the selection.
1591 // Multi-selections should not be cleared if a selected item is clicked.
1592 if (!IsRowSelected(current
))
1594 SelectAllRows(false);
1595 ChangeCurrentRow(current
);
1596 SelectRow(m_currentRow
,true);
1599 // notify cell about right click
1602 // Allow generation of context menu event
1605 else if (event
.MiddleDown())
1607 // notify cell about middle click
1610 if (event
.LeftDown() || forceClick
)
1616 m_lineBeforeLastClicked
= m_lineLastClicked
;
1617 m_lineLastClicked
= current
;
1619 unsigned int oldCurrentRow
= m_currentRow
;
1620 bool oldWasSelected
= IsRowSelected(m_currentRow
);
1622 bool cmdModifierDown
= event
.CmdDown();
1623 if ( IsSingleSel() || !(cmdModifierDown
|| event
.ShiftDown()) )
1625 if ( IsSingleSel() || !IsRowSelected(current
) )
1627 SelectAllRows( false );
1629 ChangeCurrentRow(current
);
1631 SelectRow(m_currentRow
,true);
1633 else // multi sel & current is highlighted & no mod keys
1635 m_lineSelectSingleOnUp
= current
;
1636 ChangeCurrentRow(current
); // change focus
1639 else // multi sel & either ctrl or shift is down
1641 if (cmdModifierDown
)
1643 ChangeCurrentRow(current
);
1645 ReverseRowSelection(m_currentRow
);
1647 else if (event
.ShiftDown())
1649 ChangeCurrentRow(current
);
1651 unsigned int lineFrom
= oldCurrentRow
,
1654 if ( lineTo
< lineFrom
)
1657 lineFrom
= m_currentRow
;
1660 SelectRows(lineFrom
, lineTo
, true);
1662 else // !ctrl, !shift
1664 // test in the enclosing if should make it impossible
1665 wxFAIL_MSG( _T("how did we get here?") );
1669 if (m_currentRow
!= oldCurrentRow
)
1670 RefreshRow( oldCurrentRow
);
1672 wxDataViewColumn
*oldCurrentCol
= m_currentCol
;
1674 // Update selection here...
1677 m_lastOnSame
= !forceClick
&& ((col
== oldCurrentCol
) && (current
== oldCurrentRow
)) && oldWasSelected
;
1681 void wxDataViewMainWindow::OnSetFocus( wxFocusEvent
&event
)
1685 if (HasCurrentRow())
1691 void wxDataViewMainWindow::OnKillFocus( wxFocusEvent
&event
)
1695 if (HasCurrentRow())
1701 //-----------------------------------------------------------------------------
1703 //-----------------------------------------------------------------------------
1705 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl
, wxDataViewCtrlBase
)
1707 BEGIN_EVENT_TABLE(wxDataViewCtrl
, wxDataViewCtrlBase
)
1708 EVT_SIZE(wxDataViewCtrl::OnSize
)
1711 wxDataViewCtrl::~wxDataViewCtrl()
1714 GetModel()->RemoveNotifier( m_notifier
);
1717 void wxDataViewCtrl::Init()
1722 bool wxDataViewCtrl::Create(wxWindow
*parent
, wxWindowID id
,
1723 const wxPoint
& pos
, const wxSize
& size
,
1724 long style
, const wxValidator
& validator
)
1726 if (!wxControl::Create( parent
, id
, pos
, size
, style
| wxScrolledWindowStyle
|wxSUNKEN_BORDER
, validator
))
1732 MacSetClipChildren( true ) ;
1735 m_clientArea
= new wxDataViewMainWindow( this, wxID_ANY
);
1737 m_headerArea
= new wxDataViewHeaderWindow( this, wxID_ANY
, wxDefaultPosition
, wxSize(wxDefaultCoord
,22) );
1739 m_headerArea
= new wxDataViewHeaderWindow( this, wxID_ANY
, wxDefaultPosition
, wxSize(wxDefaultCoord
,25) );
1742 SetTargetWindow( m_clientArea
);
1744 wxBoxSizer
*sizer
= new wxBoxSizer( wxVERTICAL
);
1745 sizer
->Add( m_headerArea
, 0, wxGROW
);
1746 sizer
->Add( m_clientArea
, 1, wxGROW
);
1753 WXLRESULT
wxDataViewCtrl::MSWWindowProc(WXUINT nMsg
,
1757 WXLRESULT rc
= wxDataViewCtrlBase::MSWWindowProc(nMsg
, wParam
, lParam
);
1760 // we need to process arrows ourselves for scrolling
1761 if ( nMsg
== WM_GETDLGCODE
)
1763 rc
|= DLGC_WANTARROWS
;
1771 void wxDataViewCtrl::OnSize( wxSizeEvent
&WXUNUSED(event
) )
1773 // We need to override OnSize so that our scrolled
1774 // window a) does call Layout() to use sizers for
1775 // positioning the controls but b) does not query
1776 // the sizer for their size and use that for setting
1777 // the scrollable area as set that ourselves by
1778 // calling SetScrollbar() further down.
1785 bool wxDataViewCtrl::AssociateModel( wxDataViewListModel
*model
)
1787 if (!wxDataViewCtrlBase::AssociateModel( model
))
1790 m_notifier
= new wxGenericDataViewListModelNotifier( m_clientArea
);
1792 model
->AddNotifier( m_notifier
);
1794 m_clientArea
->UpdateDisplay();
1799 bool wxDataViewCtrl::AppendColumn( wxDataViewColumn
*col
)
1801 if (!wxDataViewCtrlBase::AppendColumn(col
))
1804 m_clientArea
->UpdateDisplay();
1809 void wxDataViewCtrl::SetSelection( int WXUNUSED(row
) )
1814 void wxDataViewCtrl::SetSelectionRange( unsigned int WXUNUSED(from
), unsigned int WXUNUSED(to
) )
1819 void wxDataViewCtrl::SetSelections( const wxArrayInt
& WXUNUSED(aSelections
) )
1824 void wxDataViewCtrl::Unselect( unsigned int WXUNUSED(row
) )
1829 bool wxDataViewCtrl::IsSelected( unsigned int WXUNUSED(row
) ) const
1836 int wxDataViewCtrl::GetSelection() const
1843 int wxDataViewCtrl::GetSelections(wxArrayInt
& WXUNUSED(aSelections
) ) const
1851 // !wxUSE_GENERICDATAVIEWCTRL
1854 // wxUSE_DATAVIEWCTRL