]> git.saurik.com Git - wxWidgets.git/blame - src/generic/datavgen.cpp
allow building wxXRC with wxUSE_HTML=0: make linking work in absence of wxHTML library
[wxWidgets.git] / src / generic / datavgen.cpp
CommitLineData
4ed7af08 1/////////////////////////////////////////////////////////////////////////////
f554a14b 2// Name: src/generic/datavgen.cpp
4ed7af08
RR
3// Purpose: wxDataViewCtrl generic implementation
4// Author: Robert Roebling
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10// For compilers that support precompilation, includes "wx.h".
11#include "wx/wxprec.h"
12
ed4b0fdc
WS
13#ifdef __BORLANDC__
14 #pragma hdrstop
15#endif
16
4ed7af08
RR
17#if wxUSE_DATAVIEWCTRL
18
19#include "wx/dataview.h"
20
21#ifdef wxUSE_GENERICDATAVIEWCTRL
22
f554a14b 23#ifndef WX_PRECOMP
57bd4c60
WS
24 #ifdef __WXMSW__
25 #include "wx/msw/wrapwin.h"
26 #endif
f554a14b
WS
27 #include "wx/sizer.h"
28 #include "wx/log.h"
ed4b0fdc 29 #include "wx/dcclient.h"
c0badb70 30 #include "wx/timer.h"
9eddec69 31 #include "wx/settings.h"
8d0ca292 32 #include "wx/msgdlg.h"
f554a14b
WS
33#endif
34
4ed7af08 35#include "wx/stockitem.h"
4ed7af08
RR
36#include "wx/calctrl.h"
37#include "wx/popupwin.h"
4ed7af08 38#include "wx/renderer.h"
2e992e06 39#include "wx/dcbuffer.h"
2586d4a1 40#include "wx/icon.h"
4ed7af08 41
4ed7af08
RR
42//-----------------------------------------------------------------------------
43// classes
44//-----------------------------------------------------------------------------
45
46class wxDataViewCtrl;
47
a0f3af5f
RR
48//-----------------------------------------------------------------------------
49// wxDataViewHeaderWindow
50//-----------------------------------------------------------------------------
4ed7af08 51
a0f3af5f 52class wxDataViewHeaderWindow: public wxWindow
4ed7af08
RR
53{
54public:
a0f3af5f
RR
55 wxDataViewHeaderWindow( wxDataViewCtrl *parent,
56 wxWindowID id,
57 const wxPoint &pos = wxDefaultPosition,
58 const wxSize &size = wxDefaultSize,
59 const wxString &name = wxT("wxdataviewctrlheaderwindow") );
d3c7fc99 60 virtual ~wxDataViewHeaderWindow();
4ed7af08 61
a0f3af5f
RR
62 void SetOwner( wxDataViewCtrl* owner ) { m_owner = owner; }
63 wxDataViewCtrl *GetOwner() { return m_owner; }
4ed7af08 64
a0f3af5f
RR
65 void OnPaint( wxPaintEvent &event );
66 void OnMouse( wxMouseEvent &event );
67 void OnSetFocus( wxFocusEvent &event );
f554a14b 68
a0f3af5f
RR
69private:
70 wxDataViewCtrl *m_owner;
71 wxCursor *m_resizeCursor;
f554a14b 72
a0f3af5f
RR
73private:
74 DECLARE_DYNAMIC_CLASS(wxDataViewHeaderWindow)
75 DECLARE_EVENT_TABLE()
76};
4ed7af08 77
0fcce6b9
RR
78//-----------------------------------------------------------------------------
79// wxDataViewRenameTimer
80//-----------------------------------------------------------------------------
81
82class wxDataViewRenameTimer: public wxTimer
83{
84private:
85 wxDataViewMainWindow *m_owner;
86
87public:
88 wxDataViewRenameTimer( wxDataViewMainWindow *owner );
89 void Notify();
90};
91
92//-----------------------------------------------------------------------------
93// wxDataViewTextCtrlWrapper: wraps a wxTextCtrl for inline editing
94//-----------------------------------------------------------------------------
95
96class wxDataViewTextCtrlWrapper : public wxEvtHandler
97{
98public:
99 // NB: text must be a valid object but not Create()d yet
100 wxDataViewTextCtrlWrapper( wxDataViewMainWindow *owner,
101 wxTextCtrl *text,
102 wxDataViewListModel *model,
0a71f9e9 103 unsigned int col, unsigned int row,
0fcce6b9
RR
104 wxRect cellLabel );
105
106 wxTextCtrl *GetText() const { return m_text; }
107
108 void AcceptChangesAndFinish();
109
110protected:
111 void OnChar( wxKeyEvent &event );
112 void OnKeyUp( wxKeyEvent &event );
113 void OnKillFocus( wxFocusEvent &event );
114
115 bool AcceptChanges();
116 void Finish();
117
118private:
119 wxDataViewMainWindow *m_owner;
120 wxTextCtrl *m_text;
121 wxString m_startValue;
122 wxDataViewListModel *m_model;
0a71f9e9
RR
123 unsigned int m_col;
124 unsigned int m_row;
0fcce6b9
RR
125 bool m_finished;
126 bool m_aboutToFinish;
127
128 DECLARE_EVENT_TABLE()
129};
130
a0f3af5f
RR
131//-----------------------------------------------------------------------------
132// wxDataViewMainWindow
133//-----------------------------------------------------------------------------
4ed7af08 134
0a71f9e9 135WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_SIZE_T(unsigned int, wxDataViewSelection, WXDLLIMPEXP_ADV);
cab07038 136
a0f3af5f 137class wxDataViewMainWindow: public wxWindow
4ed7af08 138{
a0f3af5f
RR
139public:
140 wxDataViewMainWindow( wxDataViewCtrl *parent,
141 wxWindowID id,
142 const wxPoint &pos = wxDefaultPosition,
143 const wxSize &size = wxDefaultSize,
144 const wxString &name = wxT("wxdataviewctrlmainwindow") );
d3c7fc99 145 virtual ~wxDataViewMainWindow();
4ed7af08 146
a0f3af5f
RR
147 // notifications from wxDataViewListModel
148 bool RowAppended();
149 bool RowPrepended();
0a71f9e9
RR
150 bool RowInserted( unsigned int before );
151 bool RowDeleted( unsigned int row );
152 bool RowChanged( unsigned int row );
153 bool ValueChanged( unsigned int col, unsigned int row );
154 bool RowsReordered( unsigned int *new_order );
a0f3af5f 155 bool Cleared();
4ed7af08 156
a0f3af5f
RR
157 void SetOwner( wxDataViewCtrl* owner ) { m_owner = owner; }
158 wxDataViewCtrl *GetOwner() { return m_owner; }
4ed7af08 159
a0f3af5f 160 void OnPaint( wxPaintEvent &event );
0a71f9e9 161 void OnArrowChar(unsigned int newCurrent, const wxKeyEvent& event);
cab07038 162 void OnChar( wxKeyEvent &event );
a0f3af5f
RR
163 void OnMouse( wxMouseEvent &event );
164 void OnSetFocus( wxFocusEvent &event );
cab07038 165 void OnKillFocus( wxFocusEvent &event );
f554a14b 166
a0f3af5f
RR
167 void UpdateDisplay();
168 void RecalculateDisplay();
169 void OnInternalIdle();
f554a14b 170
0fcce6b9
RR
171 void OnRenameTimer();
172 void FinishEditing( wxTextCtrl *text );
173
a0f3af5f 174 void ScrollWindow( int dx, int dy, const wxRect *rect );
120b9b05 175
0a71f9e9
RR
176 bool HasCurrentRow() { return m_currentRow != (unsigned int)-1; }
177 void ChangeCurrentRow( unsigned int row );
120b9b05 178
cab07038
RR
179 bool IsSingleSel() const { return !GetParent()->HasFlag(wxDV_MULTIPLE); };
180 bool IsEmpty() { return GetRowCount() == 0; }
120b9b05 181
cab07038 182 int GetCountPerPage();
e21f75bd 183 int GetEndOfLastCol();
0a71f9e9
RR
184 unsigned int GetFirstVisibleRow();
185 unsigned int GetLastVisibleRow();
186 unsigned int GetRowCount();
120b9b05 187
cab07038 188 void SelectAllRows( bool on );
0a71f9e9
RR
189 void SelectRow( unsigned int row, bool on );
190 void SelectRows( unsigned int from, unsigned int to, bool on );
191 void ReverseRowSelection( unsigned int row );
192 bool IsRowSelected( unsigned int row );
120b9b05 193
0a71f9e9
RR
194 void RefreshRow( unsigned int row );
195 void RefreshRows( unsigned int from, unsigned int to );
196 void RefreshRowsAfter( unsigned int firstRow );
120b9b05 197
a0f3af5f 198private:
0fcce6b9
RR
199 wxDataViewCtrl *m_owner;
200 int m_lineHeight;
201 bool m_dirty;
120b9b05 202
0fcce6b9 203 wxDataViewColumn *m_currentCol;
0a71f9e9 204 unsigned int m_currentRow;
cab07038 205 wxDataViewSelection m_selection;
120b9b05 206
0fcce6b9
RR
207 wxDataViewRenameTimer *m_renameTimer;
208 wxDataViewTextCtrlWrapper *m_textctrlWrapper;
209 bool m_lastOnSame;
f554a14b 210
cab07038
RR
211 bool m_hasFocus;
212
e21f75bd
RR
213 int m_dragCount;
214 wxPoint m_dragStart;
215
216 // for double click logic
0a71f9e9 217 unsigned int m_lineLastClicked,
e21f75bd
RR
218 m_lineBeforeLastClicked,
219 m_lineSelectSingleOnUp;
cab07038 220
a0f3af5f
RR
221private:
222 DECLARE_DYNAMIC_CLASS(wxDataViewMainWindow)
223 DECLARE_EVENT_TABLE()
224};
4ed7af08 225
f554a14b 226// ---------------------------------------------------------
a0f3af5f 227// wxGenericDataViewListModelNotifier
f554a14b 228// ---------------------------------------------------------
a0f3af5f
RR
229
230class wxGenericDataViewListModelNotifier: public wxDataViewListModelNotifier
4ed7af08 231{
a0f3af5f
RR
232public:
233 wxGenericDataViewListModelNotifier( wxDataViewMainWindow *mainWindow )
234 { m_mainWindow = mainWindow; }
f554a14b 235
a0f3af5f
RR
236 virtual bool RowAppended()
237 { return m_mainWindow->RowAppended(); }
238 virtual bool RowPrepended()
239 { return m_mainWindow->RowPrepended(); }
0a71f9e9 240 virtual bool RowInserted( unsigned int before )
a0f3af5f 241 { return m_mainWindow->RowInserted( before ); }
0a71f9e9 242 virtual bool RowDeleted( unsigned int row )
a0f3af5f 243 { return m_mainWindow->RowDeleted( row ); }
0a71f9e9 244 virtual bool RowChanged( unsigned int row )
a0f3af5f 245 { return m_mainWindow->RowChanged( row ); }
0a71f9e9 246 virtual bool ValueChanged( unsigned int col, unsigned int row )
a0f3af5f 247 { return m_mainWindow->ValueChanged( col, row ); }
0a71f9e9 248 virtual bool RowsReordered( unsigned int *new_order )
a0f3af5f
RR
249 { return m_mainWindow->RowsReordered( new_order ); }
250 virtual bool Cleared()
251 { return m_mainWindow->Cleared(); }
f554a14b 252
a0f3af5f
RR
253 wxDataViewMainWindow *m_mainWindow;
254};
4ed7af08 255
f554a14b 256// ---------------------------------------------------------
baa9ebc4 257// wxDataViewRenderer
f554a14b 258// ---------------------------------------------------------
4ed7af08 259
baa9ebc4 260IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer, wxDataViewRendererBase)
4ed7af08 261
baa9ebc4
RR
262wxDataViewRenderer::wxDataViewRenderer( const wxString &varianttype, wxDataViewCellMode mode ) :
263 wxDataViewRendererBase( varianttype, mode )
4ed7af08 264{
3d9d7cc4 265 m_dc = NULL;
4ed7af08
RR
266}
267
baa9ebc4 268wxDataViewRenderer::~wxDataViewRenderer()
3d9d7cc4
RR
269{
270 if (m_dc)
271 delete m_dc;
272}
273
baa9ebc4 274wxDC *wxDataViewRenderer::GetDC()
3d9d7cc4
RR
275{
276 if (m_dc == NULL)
277 {
278 if (GetOwner() == NULL)
279 return NULL;
280 if (GetOwner()->GetOwner() == NULL)
281 return NULL;
282 m_dc = new wxClientDC( GetOwner()->GetOwner() );
283 }
f554a14b 284
3d9d7cc4
RR
285 return m_dc;
286}
287
f554a14b 288// ---------------------------------------------------------
baa9ebc4 289// wxDataViewCustomRenderer
f554a14b 290// ---------------------------------------------------------
3d9d7cc4 291
baa9ebc4 292IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomRenderer, wxDataViewRenderer)
3d9d7cc4 293
baa9ebc4 294wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString &varianttype,
3d9d7cc4 295 wxDataViewCellMode mode ) :
baa9ebc4 296 wxDataViewRenderer( varianttype, mode )
3d9d7cc4
RR
297{
298}
299
f554a14b 300// ---------------------------------------------------------
baa9ebc4 301// wxDataViewTextRenderer
f554a14b 302// ---------------------------------------------------------
4ed7af08 303
baa9ebc4 304IMPLEMENT_CLASS(wxDataViewTextRenderer, wxDataViewCustomRenderer)
4ed7af08 305
baa9ebc4
RR
306wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString &varianttype, wxDataViewCellMode mode ) :
307 wxDataViewCustomRenderer( varianttype, mode )
4ed7af08
RR
308{
309}
310
baa9ebc4 311bool wxDataViewTextRenderer::SetValue( const wxVariant &value )
4ed7af08 312{
90675b95 313 m_text = value.GetString();
f554a14b 314
90675b95 315 return true;
4ed7af08
RR
316}
317
baa9ebc4 318bool wxDataViewTextRenderer::GetValue( wxVariant& WXUNUSED(value) )
4ed7af08
RR
319{
320 return false;
321}
322
baa9ebc4 323bool wxDataViewTextRenderer::Render( wxRect cell, wxDC *dc, int WXUNUSED(state) )
3d9d7cc4 324{
90675b95
RR
325 dc->DrawText( m_text, cell.x, cell.y );
326
327 return true;
3d9d7cc4
RR
328}
329
baa9ebc4 330wxSize wxDataViewTextRenderer::GetSize()
3d9d7cc4
RR
331{
332 return wxSize(80,20);
333}
334
2586d4a1 335// ---------------------------------------------------------
baa9ebc4 336// wxDataViewBitmapRenderer
2586d4a1
RR
337// ---------------------------------------------------------
338
baa9ebc4 339IMPLEMENT_CLASS(wxDataViewBitmapRenderer, wxDataViewCustomRenderer)
2586d4a1 340
baa9ebc4
RR
341wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString &varianttype, wxDataViewCellMode mode ) :
342 wxDataViewCustomRenderer( varianttype, mode )
2586d4a1
RR
343{
344}
345
baa9ebc4 346bool wxDataViewBitmapRenderer::SetValue( const wxVariant &value )
2586d4a1
RR
347{
348 if (value.GetType() == wxT("wxBitmap"))
349 m_bitmap << value;
350 if (value.GetType() == wxT("wxIcon"))
351 m_icon << value;
352
353 return true;
354}
355
baa9ebc4 356bool wxDataViewBitmapRenderer::GetValue( wxVariant& WXUNUSED(value) )
2586d4a1
RR
357{
358 return false;
359}
360
baa9ebc4 361bool wxDataViewBitmapRenderer::Render( wxRect cell, wxDC *dc, int WXUNUSED(state) )
2586d4a1
RR
362{
363 if (m_bitmap.Ok())
364 dc->DrawBitmap( m_bitmap, cell.x, cell.y );
365 else if (m_icon.Ok())
366 dc->DrawIcon( m_icon, cell.x, cell.y );
367
368 return true;
369}
370
baa9ebc4 371wxSize wxDataViewBitmapRenderer::GetSize()
2586d4a1
RR
372{
373 if (m_bitmap.Ok())
374 return wxSize( m_bitmap.GetWidth(), m_bitmap.GetHeight() );
375 else if (m_icon.Ok())
376 return wxSize( m_icon.GetWidth(), m_icon.GetHeight() );
377
378 return wxSize(16,16);
379}
380
f554a14b 381// ---------------------------------------------------------
baa9ebc4 382// wxDataViewToggleRenderer
f554a14b 383// ---------------------------------------------------------
4ed7af08 384
baa9ebc4 385IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleRenderer, wxDataViewCustomRenderer)
4ed7af08 386
baa9ebc4 387wxDataViewToggleRenderer::wxDataViewToggleRenderer( const wxString &varianttype,
4ed7af08 388 wxDataViewCellMode mode ) :
baa9ebc4 389 wxDataViewCustomRenderer( varianttype, mode )
4ed7af08 390{
90675b95 391 m_toggle = false;
4ed7af08
RR
392}
393
baa9ebc4 394bool wxDataViewToggleRenderer::SetValue( const wxVariant &value )
4ed7af08 395{
90675b95 396 m_toggle = value.GetBool();
f554a14b 397
a8461d31 398 return true;
4ed7af08
RR
399}
400
baa9ebc4 401bool wxDataViewToggleRenderer::GetValue( wxVariant &WXUNUSED(value) )
4ed7af08
RR
402{
403 return false;
404}
f554a14b 405
baa9ebc4 406bool wxDataViewToggleRenderer::Render( wxRect cell, wxDC *dc, int WXUNUSED(state) )
4ed7af08 407{
90675b95 408 // User wxRenderer here
f554a14b 409
90675b95
RR
410 wxRect rect;
411 rect.x = cell.x + cell.width/2 - 10;
412 rect.width = 20;
413 rect.y = cell.y + cell.height/2 - 10;
414 rect.height = 20;
120b9b05 415
862d8041 416 int flags = 0;
90675b95 417 if (m_toggle)
862d8041
RR
418 flags |= wxCONTROL_CHECKED;
419 if (GetMode() != wxDATAVIEW_CELL_ACTIVATABLE)
420 flags |= wxCONTROL_DISABLED;
421
90b903c2 422 wxRendererNative::Get().DrawCheckBox(
862d8041
RR
423 GetOwner()->GetOwner(),
424 *dc,
425 rect,
426 flags );
f554a14b 427
90675b95 428 return true;
4ed7af08
RR
429}
430
baa9ebc4 431bool wxDataViewToggleRenderer::Activate( wxRect WXUNUSED(cell), wxDataViewListModel *model, unsigned int col, unsigned int row )
0fdc2321
RR
432{
433 bool value = !m_toggle;
434 wxVariant variant = value;
435 model->SetValue( variant, col, row );
f554a14b 436 model->ValueChanged( col, row );
0fdc2321
RR
437 return true;
438}
439
baa9ebc4 440wxSize wxDataViewToggleRenderer::GetSize()
4ed7af08 441{
3d9d7cc4 442 return wxSize(20,20);
4ed7af08
RR
443}
444
f554a14b 445// ---------------------------------------------------------
baa9ebc4 446// wxDataViewProgressRenderer
f554a14b 447// ---------------------------------------------------------
4ed7af08 448
baa9ebc4 449IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressRenderer, wxDataViewCustomRenderer)
4ed7af08 450
baa9ebc4 451wxDataViewProgressRenderer::wxDataViewProgressRenderer( const wxString &label,
4ed7af08 452 const wxString &varianttype, wxDataViewCellMode mode ) :
baa9ebc4 453 wxDataViewCustomRenderer( varianttype, mode )
4ed7af08
RR
454{
455 m_label = label;
456 m_value = 0;
457}
458
baa9ebc4 459wxDataViewProgressRenderer::~wxDataViewProgressRenderer()
4ed7af08
RR
460{
461}
462
baa9ebc4 463bool wxDataViewProgressRenderer::SetValue( const wxVariant &value )
4ed7af08
RR
464{
465 m_value = (long) value;
f554a14b 466
4ed7af08
RR
467 if (m_value < 0) m_value = 0;
468 if (m_value > 100) m_value = 100;
f554a14b 469
4ed7af08
RR
470 return true;
471}
f554a14b 472
baa9ebc4 473bool wxDataViewProgressRenderer::Render( wxRect cell, wxDC *dc, int WXUNUSED(state) )
4ed7af08
RR
474{
475 double pct = (double)m_value / 100.0;
476 wxRect bar = cell;
477 bar.width = (int)(cell.width * pct);
478 dc->SetPen( *wxTRANSPARENT_PEN );
479 dc->SetBrush( *wxBLUE_BRUSH );
480 dc->DrawRectangle( bar );
481
482 dc->SetBrush( *wxTRANSPARENT_BRUSH );
483 dc->SetPen( *wxBLACK_PEN );
484 dc->DrawRectangle( cell );
f554a14b 485
4ed7af08
RR
486 return true;
487}
488
baa9ebc4 489wxSize wxDataViewProgressRenderer::GetSize()
4ed7af08
RR
490{
491 return wxSize(40,12);
492}
f554a14b
WS
493
494// ---------------------------------------------------------
baa9ebc4 495// wxDataViewDateRenderer
f554a14b 496// ---------------------------------------------------------
4ed7af08 497
21ead767
VZ
498#define wxUSE_DATE_RENDERER_POPUP (wxUSE_CALENDARCTRL && wxUSE_POPUPWIN)
499
500#if wxUSE_DATE_RENDERER_POPUP
8d0ca292 501
baa9ebc4 502class wxDataViewDateRendererPopupTransient: public wxPopupTransientWindow
4ed7af08 503{
f554a14b 504public:
baa9ebc4 505 wxDataViewDateRendererPopupTransient( wxWindow* parent, wxDateTime *value,
0a71f9e9 506 wxDataViewListModel *model, unsigned int col, unsigned int row ) :
4ed7af08
RR
507 wxPopupTransientWindow( parent, wxBORDER_SIMPLE )
508 {
509 m_model = model;
510 m_col = col;
511 m_row = row;
f554a14b 512 m_cal = new wxCalendarCtrl( this, wxID_ANY, *value );
4ed7af08
RR
513 wxBoxSizer *sizer = new wxBoxSizer( wxHORIZONTAL );
514 sizer->Add( m_cal, 1, wxGROW );
515 SetSizer( sizer );
516 sizer->Fit( this );
517 }
f554a14b 518
4ed7af08 519 void OnCalendar( wxCalendarEvent &event );
f554a14b 520
4ed7af08 521 wxCalendarCtrl *m_cal;
f554a14b 522 wxDataViewListModel *m_model;
0a71f9e9
RR
523 unsigned int m_col;
524 unsigned int m_row;
f554a14b 525
a8461d31
PC
526protected:
527 virtual void OnDismiss()
528 {
529 }
530
4ed7af08
RR
531private:
532 DECLARE_EVENT_TABLE()
533};
534
baa9ebc4
RR
535BEGIN_EVENT_TABLE(wxDataViewDateRendererPopupTransient,wxPopupTransientWindow)
536 EVT_CALENDAR( wxID_ANY, wxDataViewDateRendererPopupTransient::OnCalendar )
4ed7af08
RR
537END_EVENT_TABLE()
538
baa9ebc4 539void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent &event )
4ed7af08
RR
540{
541 wxDateTime date = event.GetDate();
542 wxVariant value = date;
543 m_model->SetValue( value, m_col, m_row );
544 m_model->ValueChanged( m_col, m_row );
545 DismissAndNotify();
546}
547
21ead767 548#endif // wxUSE_DATE_RENDERER_POPUP
8d0ca292 549
baa9ebc4 550IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer, wxDataViewCustomRenderer)
4ed7af08 551
baa9ebc4 552wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString &varianttype,
4ed7af08 553 wxDataViewCellMode mode ) :
baa9ebc4 554 wxDataViewCustomRenderer( varianttype, mode )
4ed7af08
RR
555{
556}
f554a14b 557
baa9ebc4 558bool wxDataViewDateRenderer::SetValue( const wxVariant &value )
4ed7af08
RR
559{
560 m_date = value.GetDateTime();
f554a14b 561
4ed7af08
RR
562 return true;
563}
564
baa9ebc4 565bool wxDataViewDateRenderer::Render( wxRect cell, wxDC *dc, int WXUNUSED(state) )
4ed7af08
RR
566{
567 dc->SetFont( GetOwner()->GetOwner()->GetFont() );
568 wxString tmp = m_date.FormatDate();
569 dc->DrawText( tmp, cell.x, cell.y );
570
571 return true;
572}
573
baa9ebc4 574wxSize wxDataViewDateRenderer::GetSize()
4ed7af08
RR
575{
576 wxDataViewCtrl* view = GetOwner()->GetOwner();
577 wxString tmp = m_date.FormatDate();
578 wxCoord x,y,d;
579 view->GetTextExtent( tmp, &x, &y, &d );
580 return wxSize(x,y+d);
581}
582
baa9ebc4 583bool wxDataViewDateRenderer::Activate( wxRect WXUNUSED(cell), wxDataViewListModel *model, unsigned int col, unsigned int row )
4ed7af08
RR
584{
585 wxVariant variant;
586 model->GetValue( variant, col, row );
587 wxDateTime value = variant.GetDateTime();
588
21ead767 589#if wxUSE_DATE_RENDERER_POPUP
baa9ebc4 590 wxDataViewDateRendererPopupTransient *popup = new wxDataViewDateRendererPopupTransient(
4ed7af08
RR
591 GetOwner()->GetOwner()->GetParent(), &value, model, col, row );
592 wxPoint pos = wxGetMousePosition();
593 popup->Move( pos );
594 popup->Layout();
595 popup->Popup( popup->m_cal );
21ead767 596#else // !wxUSE_DATE_RENDERER_POPUP
8d0ca292 597 wxMessageBox(value.Format());
21ead767 598#endif // wxUSE_DATE_RENDERER_POPUP/!wxUSE_DATE_RENDERER_POPUP
4ed7af08
RR
599 return true;
600}
601
f554a14b 602// ---------------------------------------------------------
4ed7af08 603// wxDataViewColumn
f554a14b 604// ---------------------------------------------------------
4ed7af08
RR
605
606IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumn, wxDataViewColumnBase)
607
baa9ebc4 608wxDataViewColumn::wxDataViewColumn( const wxString &title, wxDataViewRenderer *cell, unsigned int model_column,
008b5a66
RR
609 int width, int flags ) :
610 wxDataViewColumnBase( title, cell, model_column, width, flags )
4ed7af08 611{
008b5a66
RR
612 m_width = width;
613 if (m_width < 0)
614 m_width = 80;
4ed7af08
RR
615}
616
07a84e7b
RR
617wxDataViewColumn::wxDataViewColumn( const wxBitmap &bitmap, wxDataViewRenderer *cell, unsigned int model_column,
618 int width, int flags ) :
619 wxDataViewColumnBase( bitmap, cell, model_column, width, flags )
620{
621 m_width = width;
622 if (m_width < 0)
623 m_width = 30;
624}
625
47cef10f
RR
626void wxDataViewColumn::SetAlignment( wxAlignment WXUNUSED(align) )
627{
628 // TODO
629}
630
31fb32e1
RR
631void wxDataViewColumn::SetSortable( bool WXUNUSED(sortable) )
632{
633 // TODO
634}
635
636bool wxDataViewColumn::GetSortable()
8d0ca292 637{
31fb32e1
RR
638 // TODO
639 return false;
640}
641
47cef10f
RR
642void wxDataViewColumn::SetSortOrder( bool WXUNUSED(ascending) )
643{
644 // TODO
645}
646
31fb32e1
RR
647bool wxDataViewColumn::IsSortOrderAscending()
648{
649 // TODO
650 return true;
651}
652
653
4ed7af08
RR
654wxDataViewColumn::~wxDataViewColumn()
655{
656}
657
658void wxDataViewColumn::SetTitle( const wxString &title )
659{
660 wxDataViewColumnBase::SetTitle( title );
f554a14b 661
4ed7af08
RR
662}
663
47cef10f
RR
664void wxDataViewColumn::SetBitmap( const wxBitmap &bitmap )
665{
666 wxDataViewColumnBase::SetBitmap( bitmap );
667
668}
669
533544f2
RR
670int wxDataViewColumn::GetWidth()
671{
672 return m_width;
673}
674
4ed7af08
RR
675//-----------------------------------------------------------------------------
676// wxDataViewHeaderWindow
677//-----------------------------------------------------------------------------
678
45778c96 679IMPLEMENT_ABSTRACT_CLASS(wxDataViewHeaderWindow, wxWindow)
4ed7af08
RR
680
681BEGIN_EVENT_TABLE(wxDataViewHeaderWindow,wxWindow)
682 EVT_PAINT (wxDataViewHeaderWindow::OnPaint)
683 EVT_MOUSE_EVENTS (wxDataViewHeaderWindow::OnMouse)
684 EVT_SET_FOCUS (wxDataViewHeaderWindow::OnSetFocus)
685END_EVENT_TABLE()
686
687wxDataViewHeaderWindow::wxDataViewHeaderWindow( wxDataViewCtrl *parent, wxWindowID id,
688 const wxPoint &pos, const wxSize &size, const wxString &name ) :
689 wxWindow( parent, id, pos, size, 0, name )
690{
691 SetOwner( parent );
4b3feaa7 692
4ed7af08 693 m_resizeCursor = new wxCursor( wxCURSOR_SIZEWE );
f554a14b 694
4ed7af08 695 wxVisualAttributes attr = wxPanel::GetClassDefaultAttributes();
2e992e06 696 SetBackgroundStyle( wxBG_STYLE_CUSTOM );
4ed7af08
RR
697 SetOwnForegroundColour( attr.colFg );
698 SetOwnBackgroundColour( attr.colBg );
699 if (!m_hasFont)
700 SetOwnFont( attr.font );
701}
702
703wxDataViewHeaderWindow::~wxDataViewHeaderWindow()
704{
705 delete m_resizeCursor;
706}
707
f554a14b 708void wxDataViewHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
4ed7af08 709{
4b3feaa7
RR
710 int w, h;
711 GetClientSize( &w, &h );
712
2e992e06
VZ
713 wxAutoBufferedPaintDC dc( this );
714
715 dc.SetBackground(GetBackgroundColour());
716 dc.Clear();
f554a14b 717
4ed7af08
RR
718 int xpix;
719 m_owner->GetScrollPixelsPerUnit( &xpix, NULL );
720
721 int x;
722 m_owner->GetViewStart( &x, NULL );
723
724 // account for the horz scrollbar offset
725 dc.SetDeviceOrigin( -x * xpix, 0 );
f554a14b 726
4ed7af08 727 dc.SetFont( GetFont() );
f554a14b 728
0a71f9e9
RR
729 unsigned int cols = GetOwner()->GetNumberOfColumns();
730 unsigned int i;
4b3feaa7
RR
731 int xpos = 0;
732 for (i = 0; i < cols; i++)
733 {
734 wxDataViewColumn *col = GetOwner()->GetColumn( i );
735 int width = col->GetWidth();
f554a14b 736
4b3feaa7
RR
737 int cw = width;
738 int ch = h;
4b3feaa7
RR
739
740 wxRendererNative::Get().DrawHeaderButton
741 (
742 this,
743 dc,
72664514 744 wxRect(xpos, 0, cw, ch-1),
4b3feaa7
RR
745 m_parent->IsEnabled() ? 0
746 : (int)wxCONTROL_DISABLED
747 );
748
f554a14b
WS
749 dc.DrawText( col->GetTitle(), xpos+3, 3 );
750
4b3feaa7
RR
751 xpos += width;
752 }
4ed7af08
RR
753}
754
f554a14b 755void wxDataViewHeaderWindow::OnMouse( wxMouseEvent &WXUNUSED(event) )
4ed7af08
RR
756{
757}
758
759void wxDataViewHeaderWindow::OnSetFocus( wxFocusEvent &event )
760{
cab07038 761 GetParent()->SetFocus();
4ed7af08
RR
762 event.Skip();
763}
764
0fcce6b9
RR
765//-----------------------------------------------------------------------------
766// wxDataViewRenameTimer
767//-----------------------------------------------------------------------------
768
769wxDataViewRenameTimer::wxDataViewRenameTimer( wxDataViewMainWindow *owner )
770{
771 m_owner = owner;
772}
773
774void wxDataViewRenameTimer::Notify()
775{
776 m_owner->OnRenameTimer();
777}
778
779//-----------------------------------------------------------------------------
780// wxDataViewTextCtrlWrapper: wraps a wxTextCtrl for inline editing
781//-----------------------------------------------------------------------------
782
783BEGIN_EVENT_TABLE(wxDataViewTextCtrlWrapper, wxEvtHandler)
784 EVT_CHAR (wxDataViewTextCtrlWrapper::OnChar)
785 EVT_KEY_UP (wxDataViewTextCtrlWrapper::OnKeyUp)
786 EVT_KILL_FOCUS (wxDataViewTextCtrlWrapper::OnKillFocus)
787END_EVENT_TABLE()
788
789wxDataViewTextCtrlWrapper::wxDataViewTextCtrlWrapper(
790 wxDataViewMainWindow *owner,
791 wxTextCtrl *text,
792 wxDataViewListModel *model,
0a71f9e9 793 unsigned int col, unsigned int row,
0fcce6b9
RR
794 wxRect rectLabel )
795{
796 m_owner = owner;
797 m_model = model;
798 m_row = row;
799 m_col = col;
120b9b05
WS
800 m_text = text;
801
0fcce6b9
RR
802 m_finished = false;
803 m_aboutToFinish = false;
120b9b05 804
0fcce6b9
RR
805 wxVariant value;
806 model->GetValue( value, col, row );
807 m_startValue = value.GetString();
120b9b05 808
0fcce6b9
RR
809 m_owner->GetOwner()->CalcScrolledPosition(
810 rectLabel.x, rectLabel.y, &rectLabel.x, &rectLabel.y );
811
812 m_text->Create( owner, wxID_ANY, m_startValue,
813 wxPoint(rectLabel.x-2,rectLabel.y-2),
814 wxSize(rectLabel.width+7,rectLabel.height+4) );
815 m_text->SetFocus();
120b9b05 816
0fcce6b9
RR
817 m_text->PushEventHandler(this);
818}
819
820void wxDataViewTextCtrlWrapper::AcceptChangesAndFinish()
821{
822 m_aboutToFinish = true;
823
824 // Notify the owner about the changes
825 AcceptChanges();
826
827 // Even if vetoed, close the control (consistent with MSW)
828 Finish();
829}
830
831void wxDataViewTextCtrlWrapper::OnChar( wxKeyEvent &event )
832{
833 switch ( event.m_keyCode )
834 {
835 case WXK_RETURN:
836 AcceptChangesAndFinish();
837 break;
838
839 case WXK_ESCAPE:
840 // m_owner->OnRenameCancelled( m_itemEdited );
841 Finish();
842 break;
843
844 default:
845 event.Skip();
846 }
847}
848
849void wxDataViewTextCtrlWrapper::OnKeyUp( wxKeyEvent &event )
850{
851 if (m_finished)
852 {
853 event.Skip();
854 return;
855 }
856
857 // auto-grow the textctrl
858 wxSize parentSize = m_owner->GetSize();
859 wxPoint myPos = m_text->GetPosition();
860 wxSize mySize = m_text->GetSize();
861 int sx, sy;
862 m_text->GetTextExtent(m_text->GetValue() + _T("MM"), &sx, &sy);
863 if (myPos.x + sx > parentSize.x)
864 sx = parentSize.x - myPos.x;
865 if (mySize.x > sx)
866 sx = mySize.x;
867 m_text->SetSize(sx, wxDefaultCoord);
868
869 event.Skip();
870}
871
872void wxDataViewTextCtrlWrapper::OnKillFocus( wxFocusEvent &event )
873{
874 if ( !m_finished && !m_aboutToFinish )
875 {
876 AcceptChanges();
877 //if ( !AcceptChanges() )
878 // m_owner->OnRenameCancelled( m_itemEdited );
120b9b05 879
0fcce6b9
RR
880 Finish();
881 }
882
883 // We must let the native text control handle focus
884 event.Skip();
885}
886
887bool wxDataViewTextCtrlWrapper::AcceptChanges()
888{
889 const wxString value = m_text->GetValue();
890
891 if ( value == m_startValue )
892 // nothing changed, always accept
893 return true;
894
895// if ( !m_owner->OnRenameAccept(m_itemEdited, value) )
896 // vetoed by the user
897// return false;
898
899 // accepted, do rename the item
900 wxVariant variant;
901 variant = value;
902 m_model->SetValue( variant, m_col, m_row );
903 m_model->ValueChanged( m_col, m_row );
904
905 return true;
906}
907
908void wxDataViewTextCtrlWrapper::Finish()
909{
910 if ( !m_finished )
911 {
912 m_finished = true;
913
914 m_text->RemoveEventHandler(this);
915 m_owner->FinishEditing(m_text);
916
917 // delete later
918 wxPendingDelete.Append( this );
919 }
920}
921
4ed7af08
RR
922//-----------------------------------------------------------------------------
923// wxDataViewMainWindow
924//-----------------------------------------------------------------------------
925
0a71f9e9 926int LINKAGEMODE wxDataViewSelectionCmp( unsigned int row1, unsigned int row2 )
cab07038
RR
927{
928 if (row1 > row2) return 1;
929 if (row1 == row2) return 0;
930 return -1;
931}
932
933
45778c96 934IMPLEMENT_ABSTRACT_CLASS(wxDataViewMainWindow, wxWindow)
4ed7af08
RR
935
936BEGIN_EVENT_TABLE(wxDataViewMainWindow,wxWindow)
937 EVT_PAINT (wxDataViewMainWindow::OnPaint)
938 EVT_MOUSE_EVENTS (wxDataViewMainWindow::OnMouse)
939 EVT_SET_FOCUS (wxDataViewMainWindow::OnSetFocus)
cab07038
RR
940 EVT_KILL_FOCUS (wxDataViewMainWindow::OnKillFocus)
941 EVT_CHAR (wxDataViewMainWindow::OnChar)
4ed7af08
RR
942END_EVENT_TABLE()
943
944wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl *parent, wxWindowID id,
945 const wxPoint &pos, const wxSize &size, const wxString &name ) :
72664514 946 wxWindow( parent, id, pos, size, wxWANTS_CHARS, name ),
cab07038 947 m_selection( wxDataViewSelectionCmp )
120b9b05 948
4ed7af08
RR
949{
950 SetOwner( parent );
f554a14b 951
0fcce6b9
RR
952 m_lastOnSame = false;
953 m_renameTimer = new wxDataViewRenameTimer( this );
954 m_textctrlWrapper = NULL;
120b9b05 955
0fcce6b9
RR
956 // TODO: user better initial values/nothing selected
957 m_currentCol = NULL;
958 m_currentRow = 0;
959
960 // TODO: we need to calculate this smartly
4b3feaa7 961 m_lineHeight = 20;
e21f75bd
RR
962
963 m_dragCount = 0;
964 m_dragStart = wxPoint(0,0);
0a71f9e9
RR
965 m_lineLastClicked = (unsigned int) -1;
966 m_lineBeforeLastClicked = (unsigned int) -1;
967 m_lineSelectSingleOnUp = (unsigned int) -1;
120b9b05 968
cab07038 969 m_hasFocus = false;
f554a14b 970
2e992e06 971 SetBackgroundStyle( wxBG_STYLE_CUSTOM );
72664514
RR
972 SetBackgroundColour( *wxWHITE );
973
4b3feaa7 974 UpdateDisplay();
4ed7af08
RR
975}
976
977wxDataViewMainWindow::~wxDataViewMainWindow()
978{
0fcce6b9
RR
979 delete m_renameTimer;
980}
981
982void wxDataViewMainWindow::OnRenameTimer()
983{
984 // We have to call this here because changes may just have
985 // been made and no screen update taken place.
986 if ( m_dirty )
987 wxSafeYield();
988
989
990 int xpos = 0;
0a71f9e9
RR
991 unsigned int cols = GetOwner()->GetNumberOfColumns();
992 unsigned int i;
0fcce6b9
RR
993 for (i = 0; i < cols; i++)
994 {
995 wxDataViewColumn *c = GetOwner()->GetColumn( i );
996 if (c == m_currentCol)
997 break;
998 xpos += c->GetWidth();
999 }
1000 wxRect labelRect( xpos, m_currentRow * m_lineHeight, m_currentCol->GetWidth(), m_lineHeight );
1001
1002 wxClassInfo *textControlClass = CLASSINFO(wxTextCtrl);
1003
1004 wxTextCtrl * const text = (wxTextCtrl *)textControlClass->CreateObject();
120b9b05 1005 m_textctrlWrapper = new wxDataViewTextCtrlWrapper(this, text, GetOwner()->GetModel(),
0fcce6b9
RR
1006 m_currentCol->GetModelColumn(), m_currentRow, labelRect );
1007}
1008
1009void wxDataViewMainWindow::FinishEditing( wxTextCtrl *text )
1010{
1011 delete text;
1012 m_textctrlWrapper = NULL;
1013 SetFocus();
1014 // SetFocusIgnoringChildren();
4ed7af08
RR
1015}
1016
a0f3af5f
RR
1017bool wxDataViewMainWindow::RowAppended()
1018{
1019 return false;
1020}
1021
1022bool wxDataViewMainWindow::RowPrepended()
1023{
1024 return false;
1025}
1026
0a71f9e9 1027bool wxDataViewMainWindow::RowInserted( unsigned int WXUNUSED(before) )
a0f3af5f
RR
1028{
1029 return false;
1030}
1031
0a71f9e9 1032bool wxDataViewMainWindow::RowDeleted( unsigned int WXUNUSED(row) )
a0f3af5f
RR
1033{
1034 return false;
1035}
1036
0a71f9e9 1037bool wxDataViewMainWindow::RowChanged( unsigned int WXUNUSED(row) )
a0f3af5f
RR
1038{
1039 return false;
1040}
1041
0a71f9e9 1042bool wxDataViewMainWindow::ValueChanged( unsigned int WXUNUSED(col), unsigned int row )
a0f3af5f 1043{
0fdc2321
RR
1044 wxRect rect( 0, row*m_lineHeight, 10000, m_lineHeight );
1045 m_owner->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
1046 Refresh( true, &rect );
1047
1048 return true;
a0f3af5f
RR
1049}
1050
0a71f9e9 1051bool wxDataViewMainWindow::RowsReordered( unsigned int *WXUNUSED(new_order) )
a0f3af5f 1052{
0fcce6b9 1053 Refresh();
120b9b05 1054
0fcce6b9 1055 return true;
a0f3af5f
RR
1056}
1057
1058bool wxDataViewMainWindow::Cleared()
1059{
1060 return false;
1061}
1062
4b3feaa7
RR
1063void wxDataViewMainWindow::UpdateDisplay()
1064{
1065 m_dirty = true;
1066}
1067
1068void wxDataViewMainWindow::OnInternalIdle()
1069{
1070 wxWindow::OnInternalIdle();
f554a14b 1071
4b3feaa7
RR
1072 if (m_dirty)
1073 {
1074 RecalculateDisplay();
1075 m_dirty = false;
1076 }
1077}
1078
1079void wxDataViewMainWindow::RecalculateDisplay()
1080{
1081 wxDataViewListModel *model = GetOwner()->GetModel();
1082 if (!model)
1083 {
1084 Refresh();
1085 return;
1086 }
f554a14b 1087
4b3feaa7 1088 int width = 0;
0a71f9e9
RR
1089 unsigned int cols = GetOwner()->GetNumberOfColumns();
1090 unsigned int i;
4b3feaa7
RR
1091 for (i = 0; i < cols; i++)
1092 {
1093 wxDataViewColumn *col = GetOwner()->GetColumn( i );
1094 width += col->GetWidth();
1095 }
f554a14b 1096
4b3feaa7
RR
1097 int height = model->GetNumberOfRows() * m_lineHeight;
1098
1099 SetVirtualSize( width, height );
1100 GetOwner()->SetScrollRate( 10, m_lineHeight );
f554a14b 1101
4b3feaa7
RR
1102 Refresh();
1103}
1104
1105void wxDataViewMainWindow::ScrollWindow( int dx, int dy, const wxRect *rect )
1106{
1107 wxWindow::ScrollWindow( dx, dy, rect );
1108 GetOwner()->m_headerArea->ScrollWindow( dx, 0 );
1109}
1110
f554a14b 1111void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
4ed7af08 1112{
2e992e06
VZ
1113 wxAutoBufferedPaintDC dc( this );
1114
1115 dc.SetBackground(GetBackgroundColour());
1116 dc.Clear();
4ed7af08 1117
4b3feaa7 1118 GetOwner()->PrepareDC( dc );
4ed7af08
RR
1119
1120 dc.SetFont( GetFont() );
90675b95
RR
1121
1122 wxRect update = GetUpdateRegion().GetBox();
1123 m_owner->CalcUnscrolledPosition( update.x, update.y, &update.x, &update.y );
f554a14b 1124
90675b95 1125 wxDataViewListModel *model = GetOwner()->GetModel();
f554a14b 1126
0a71f9e9
RR
1127 unsigned int item_start = wxMax( 0, (update.y / m_lineHeight) );
1128 unsigned int item_count = wxMin( (int)(((update.y + update.height) / m_lineHeight) - item_start + 1),
a87594c6 1129 (int)(model->GetNumberOfRows()-item_start) );
90675b95 1130
120b9b05 1131
cab07038 1132
0a71f9e9 1133 unsigned int item;
cab07038
RR
1134 for (item = item_start; item < item_start+item_count; item++)
1135 {
1136 if (m_selection.Index( item ) != wxNOT_FOUND)
1137 {
daebb44c
RR
1138 int flags = wxCONTROL_SELECTED;
1139 if (item == m_currentRow)
1140 flags |= wxCONTROL_CURRENT;
1141 if (m_hasFocus)
1142 flags |= wxCONTROL_FOCUSED;
e21f75bd 1143 wxRect rect( 0, item*m_lineHeight+1, GetEndOfLastCol(), m_lineHeight-2 );
daebb44c
RR
1144 wxRendererNative::Get().DrawItemSelectionRect
1145 (
1146 this,
1147 dc,
1148 rect,
1149 flags
1150 );
1151 }
1152 else
1153 {
1154 if (item == m_currentRow)
1155 {
1156 int flags = wxCONTROL_CURRENT;
1157 if (m_hasFocus)
1158 flags |= wxCONTROL_FOCUSED; // should have no effect
1159 wxRect rect( 0, item*m_lineHeight+1, GetEndOfLastCol(), m_lineHeight-2 );
1160 wxRendererNative::Get().DrawItemSelectionRect
1161 (
1162 this,
1163 dc,
1164 rect,
1165 flags
1166 );
120b9b05 1167
daebb44c 1168 }
cab07038
RR
1169 }
1170 }
120b9b05 1171
90675b95
RR
1172 wxRect cell_rect;
1173 cell_rect.x = 0;
1174 cell_rect.height = m_lineHeight;
0a71f9e9
RR
1175 unsigned int cols = GetOwner()->GetNumberOfColumns();
1176 unsigned int i;
90675b95
RR
1177 for (i = 0; i < cols; i++)
1178 {
1179 wxDataViewColumn *col = GetOwner()->GetColumn( i );
baa9ebc4 1180 wxDataViewRenderer *cell = col->GetRenderer();
90675b95 1181 cell_rect.width = col->GetWidth();
f554a14b 1182
0fcce6b9 1183 for (item = item_start; item < item_start+item_count; item++)
90675b95
RR
1184 {
1185 cell_rect.y = item*m_lineHeight;
1186 wxVariant value;
1187 model->GetValue( value, col->GetModelColumn(), item );
1188 cell->SetValue( value );
4064f7de
RR
1189 wxSize size = cell->GetSize();
1190 // cannot be bigger than allocated space
1191 size.x = wxMin( size.x, cell_rect.width );
1192 size.y = wxMin( size.y, cell_rect.height );
1193 // TODO: check for left/right/centre alignment here
1194 wxRect item_rect;
1195 // for now: centre
1196 item_rect.x = cell_rect.x + (cell_rect.width / 2) - (size.x / 2);
1197 item_rect.y = cell_rect.y + (cell_rect.height / 2) - (size.y / 2);
f554a14b 1198
4064f7de
RR
1199 item_rect.width = size.x;
1200 item_rect.height= size.y;
64b3c262
VZ
1201
1202 int state = 0;
1203 if (item == m_currentRow)
1204 state |= wxDATAVIEW_CELL_SELECTED;
1205 cell->Render( item_rect, &dc, state );
90675b95 1206 }
f554a14b 1207
90675b95
RR
1208 cell_rect.x += cell_rect.width;
1209 }
4ed7af08
RR
1210}
1211
cab07038
RR
1212int wxDataViewMainWindow::GetCountPerPage()
1213{
1214 wxSize size = GetClientSize();
1215 return size.y / m_lineHeight;
1216}
1217
e21f75bd
RR
1218int wxDataViewMainWindow::GetEndOfLastCol()
1219{
1220 int width = 0;
0a71f9e9 1221 unsigned int i;
e21f75bd
RR
1222 for (i = 0; i < GetOwner()->GetNumberOfColumns(); i++)
1223 {
1224 wxDataViewColumn *c = GetOwner()->GetColumn( i );
1225 width += c->GetWidth();
1226 }
1227 return width;
1228}
1229
0a71f9e9 1230unsigned int wxDataViewMainWindow::GetFirstVisibleRow()
72664514
RR
1231{
1232 int x = 0;
1233 int y = 0;
1234 m_owner->CalcUnscrolledPosition( x, y, &x, &y );
120b9b05 1235
72664514
RR
1236 return y / m_lineHeight;
1237}
1238
0a71f9e9 1239unsigned int wxDataViewMainWindow::GetLastVisibleRow()
72664514
RR
1240{
1241 wxSize client_size = GetClientSize();
1242 m_owner->CalcUnscrolledPosition( client_size.x, client_size.y, &client_size.x, &client_size.y );
1243
5637e131 1244 return wxMin( GetRowCount()-1, ((unsigned)client_size.y/m_lineHeight)+1 );
72664514
RR
1245}
1246
0a71f9e9 1247unsigned int wxDataViewMainWindow::GetRowCount()
cab07038
RR
1248{
1249 return GetOwner()->GetModel()->GetNumberOfRows();
1250}
1251
0a71f9e9 1252void wxDataViewMainWindow::ChangeCurrentRow( unsigned int row )
e21f75bd
RR
1253{
1254 m_currentRow = row;
120b9b05 1255
e21f75bd
RR
1256 // send event
1257}
1258
cab07038
RR
1259void wxDataViewMainWindow::SelectAllRows( bool on )
1260{
4a851b11
VZ
1261 if (IsEmpty())
1262 return;
120b9b05 1263
cab07038
RR
1264 if (on)
1265 {
72664514 1266 m_selection.Clear();
0a71f9e9 1267 for (unsigned int i = 0; i < GetRowCount(); i++)
cab07038 1268 m_selection.Add( i );
72664514
RR
1269 Refresh();
1270 }
1271 else
1272 {
0a71f9e9
RR
1273 unsigned int first_visible = GetFirstVisibleRow();
1274 unsigned int last_visible = GetLastVisibleRow();
1275 unsigned int i;
72664514 1276 for (i = 0; i < m_selection.GetCount(); i++)
120b9b05 1277 {
0a71f9e9 1278 unsigned int row = m_selection[i];
72664514
RR
1279 if ((row >= first_visible) && (row <= last_visible))
1280 RefreshRow( row );
1281 }
1282 m_selection.Clear();
cab07038 1283 }
cab07038
RR
1284}
1285
0a71f9e9 1286void wxDataViewMainWindow::SelectRow( unsigned int row, bool on )
cab07038
RR
1287{
1288 if (m_selection.Index( row ) == wxNOT_FOUND)
1289 {
1290 if (on)
1291 {
1292 m_selection.Add( row );
1293 RefreshRow( row );
1294 }
1295 }
1296 else
1297 {
1298 if (!on)
1299 {
1300 m_selection.Remove( row );
1301 RefreshRow( row );
1302 }
1303 }
1304}
1305
0a71f9e9 1306void wxDataViewMainWindow::SelectRows( unsigned int from, unsigned int to, bool on )
cab07038
RR
1307{
1308 if (from > to)
1309 {
0a71f9e9 1310 unsigned int tmp = from;
cab07038
RR
1311 from = to;
1312 to = tmp;
1313 }
1314
0a71f9e9 1315 unsigned int i;
cab07038
RR
1316 for (i = from; i <= to; i++)
1317 {
1318 if (m_selection.Index( i ) == wxNOT_FOUND)
1319 {
1320 if (on)
1321 m_selection.Add( i );
1322 }
1323 else
1324 {
1325 if (!on)
1326 m_selection.Remove( i );
1327 }
1328 }
1329 RefreshRows( from, to );
1330}
1331
0a71f9e9 1332void wxDataViewMainWindow::ReverseRowSelection( unsigned int row )
cab07038
RR
1333{
1334 if (m_selection.Index( row ) == wxNOT_FOUND)
1335 m_selection.Add( row );
1336 else
1337 m_selection.Remove( row );
120b9b05 1338 RefreshRow( row );
cab07038
RR
1339}
1340
0a71f9e9 1341bool wxDataViewMainWindow::IsRowSelected( unsigned int row )
cab07038
RR
1342{
1343 return (m_selection.Index( row ) != wxNOT_FOUND);
1344}
1345
0a71f9e9 1346void wxDataViewMainWindow::RefreshRow( unsigned int row )
cab07038 1347{
e21f75bd 1348 wxRect rect( 0, row*m_lineHeight, GetEndOfLastCol(), m_lineHeight );
cab07038 1349 m_owner->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
120b9b05 1350
cab07038
RR
1351 wxSize client_size = GetClientSize();
1352 wxRect client_rect( 0, 0, client_size.x, client_size.y );
1353 wxRect intersect_rect = client_rect.Intersect( rect );
1354 if (intersect_rect.width > 0)
1355 Refresh( true, &intersect_rect );
1356}
1357
0a71f9e9 1358void wxDataViewMainWindow::RefreshRows( unsigned int from, unsigned int to )
cab07038
RR
1359{
1360 if (from > to)
1361 {
0a71f9e9 1362 unsigned int tmp = to;
cab07038
RR
1363 to = from;
1364 from = tmp;
1365 }
1366
e21f75bd 1367 wxRect rect( 0, from*m_lineHeight, GetEndOfLastCol(), (to-from+1) * m_lineHeight );
cab07038 1368 m_owner->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
120b9b05 1369
cab07038
RR
1370 wxSize client_size = GetClientSize();
1371 wxRect client_rect( 0, 0, client_size.x, client_size.y );
1372 wxRect intersect_rect = client_rect.Intersect( rect );
1373 if (intersect_rect.width > 0)
1374 Refresh( true, &intersect_rect );
1375}
1376
0a71f9e9 1377void wxDataViewMainWindow::RefreshRowsAfter( unsigned int firstRow )
cab07038 1378{
0a71f9e9 1379 unsigned int count = GetRowCount();
4a851b11
VZ
1380 if (firstRow > count)
1381 return;
120b9b05 1382
e21f75bd 1383 wxRect rect( 0, firstRow*m_lineHeight, GetEndOfLastCol(), count * m_lineHeight );
cab07038 1384 m_owner->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
120b9b05 1385
cab07038
RR
1386 wxSize client_size = GetClientSize();
1387 wxRect client_rect( 0, 0, client_size.x, client_size.y );
1388 wxRect intersect_rect = client_rect.Intersect( rect );
1389 if (intersect_rect.width > 0)
1390 Refresh( true, &intersect_rect );
1391}
1392
0a71f9e9 1393void wxDataViewMainWindow::OnArrowChar(unsigned int newCurrent, const wxKeyEvent& event)
cab07038 1394{
4a851b11 1395 wxCHECK_RET( newCurrent < GetRowCount(),
cab07038
RR
1396 _T("invalid item index in OnArrowChar()") );
1397
1398 // if there is no selection, we cannot move it anywhere
1399 if (!HasCurrentRow())
1400 return;
1401
0a71f9e9 1402 unsigned int oldCurrent = m_currentRow;
cab07038
RR
1403
1404 // in single selection we just ignore Shift as we can't select several
1405 // items anyhow
e21f75bd 1406 if ( event.ShiftDown() && !IsSingleSel() )
cab07038
RR
1407 {
1408 RefreshRow( oldCurrent );
120b9b05 1409
e21f75bd 1410 ChangeCurrentRow( newCurrent );
cab07038
RR
1411
1412 // select all the items between the old and the new one
1413 if ( oldCurrent > newCurrent )
1414 {
1415 newCurrent = oldCurrent;
1416 oldCurrent = m_currentRow;
1417 }
1418
1419 SelectRows( oldCurrent, newCurrent, true );
1420 }
1421 else // !shift
1422 {
72664514 1423 RefreshRow( oldCurrent );
120b9b05 1424
cab07038
RR
1425 // all previously selected items are unselected unless ctrl is held
1426 if ( !event.ControlDown() )
1427 SelectAllRows(false);
1428
e21f75bd 1429 ChangeCurrentRow( newCurrent );
cab07038
RR
1430
1431 if ( !event.ControlDown() )
1432 SelectRow( m_currentRow, true );
72664514
RR
1433 else
1434 RefreshRow( m_currentRow );
cab07038
RR
1435 }
1436
1437 // MoveToFocus();
1438}
1439
1440void wxDataViewMainWindow::OnChar( wxKeyEvent &event )
1441{
1442 if (event.GetKeyCode() == WXK_TAB)
1443 {
1444 wxNavigationKeyEvent nevent;
1445 nevent.SetWindowChange( event.ControlDown() );
1446 nevent.SetDirection( !event.ShiftDown() );
1447 nevent.SetEventObject( GetParent()->GetParent() );
1448 nevent.SetCurrentFocus( m_parent );
1449 if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent ))
1450 return;
1451 }
1452
1453 // no item -> nothing to do
1454 if (!HasCurrentRow())
1455 {
1456 event.Skip();
1457 return;
1458 }
120b9b05 1459
cab07038
RR
1460 // don't use m_linesPerPage directly as it might not be computed yet
1461 const int pageSize = GetCountPerPage();
1462 wxCHECK_RET( pageSize, _T("should have non zero page size") );
1463
1464 switch ( event.GetKeyCode() )
1465 {
1466 case WXK_UP:
1467 if ( m_currentRow > 0 )
1468 OnArrowChar( m_currentRow - 1, event );
1469 break;
1470
1471 case WXK_DOWN:
4a851b11 1472 if ( m_currentRow < GetRowCount() - 1 )
cab07038
RR
1473 OnArrowChar( m_currentRow + 1, event );
1474 break;
1475
1476 case WXK_END:
1477 if (!IsEmpty())
1478 OnArrowChar( GetRowCount() - 1, event );
1479 break;
1480
1481 case WXK_HOME:
1482 if (!IsEmpty())
1483 OnArrowChar( 0, event );
1484 break;
1485
1486 case WXK_PAGEUP:
1487 {
1488 int steps = pageSize - 1;
1489 int index = m_currentRow - steps;
1490 if (index < 0)
1491 index = 0;
1492
1493 OnArrowChar( index, event );
1494 }
1495 break;
1496
1497 case WXK_PAGEDOWN:
1498 {
1499 int steps = pageSize - 1;
0a71f9e9
RR
1500 unsigned int index = m_currentRow + steps;
1501 unsigned int count = GetRowCount();
cab07038
RR
1502 if ( index >= count )
1503 index = count - 1;
1504
1505 OnArrowChar( index, event );
1506 }
1507 break;
1508
1509 default:
1510 event.Skip();
1511 }
1512}
1513
4ed7af08
RR
1514void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
1515{
e21f75bd
RR
1516 if (event.GetEventType() == wxEVT_MOUSEWHEEL)
1517 {
1518 // let the base handle mouse wheel events.
1519 event.Skip();
1520 return;
1521 }
1522
0fdc2321
RR
1523 int x = event.GetX();
1524 int y = event.GetY();
1525 m_owner->CalcUnscrolledPosition( x, y, &x, &y );
1526
1527 wxDataViewColumn *col = NULL;
1528
1529 int xpos = 0;
0a71f9e9
RR
1530 unsigned int cols = GetOwner()->GetNumberOfColumns();
1531 unsigned int i;
0fdc2321
RR
1532 for (i = 0; i < cols; i++)
1533 {
1534 wxDataViewColumn *c = GetOwner()->GetColumn( i );
1535 if (x < xpos + c->GetWidth())
1536 {
1537 col = c;
1538 break;
1539 }
1540 xpos += c->GetWidth();
1541 }
f554a14b 1542 if (!col)
0fdc2321 1543 return;
baa9ebc4 1544 wxDataViewRenderer *cell = col->GetRenderer();
f554a14b 1545
0a71f9e9 1546 unsigned int current = y / m_lineHeight;
120b9b05 1547
e21f75bd
RR
1548 if ((current > GetRowCount()) || (x > GetEndOfLastCol()))
1549 {
1550 // Unselect all if below the last row ?
1551 return;
1552 }
f554a14b 1553
0fdc2321
RR
1554 wxDataViewListModel *model = GetOwner()->GetModel();
1555
e21f75bd
RR
1556 if (event.Dragging())
1557 {
1558 if (m_dragCount == 0)
1559 {
1560 // we have to report the raw, physical coords as we want to be
1561 // able to call HitTest(event.m_pointDrag) from the user code to
1562 // get the item being dragged
1563 m_dragStart = event.GetPosition();
1564 }
1565
1566 m_dragCount++;
1567
1568 if (m_dragCount != 3)
1569 return;
1570
1571 if (event.LeftIsDown())
1572 {
1573 // Notify cell about drag
1574 }
1575 return;
1576 }
1577 else
1578 {
1579 m_dragCount = 0;
1580 }
1581
1582 bool forceClick = false;
1583
0fcce6b9
RR
1584 if (event.ButtonDClick())
1585 {
1586 m_renameTimer->Stop();
1587 m_lastOnSame = false;
1588 }
1589
0fdc2321
RR
1590 if (event.LeftDClick())
1591 {
e21f75bd 1592 if ( current == m_lineLastClicked )
0fdc2321 1593 {
e21f75bd
RR
1594 if (cell->GetMode() == wxDATAVIEW_CELL_ACTIVATABLE)
1595 {
1596 wxVariant value;
1597 model->GetValue( value, col->GetModelColumn(), current );
1598 cell->SetValue( value );
1599 wxRect cell_rect( xpos, current * m_lineHeight, col->GetWidth(), m_lineHeight );
1600 cell->Activate( cell_rect, model, col->GetModelColumn(), current );
1601 }
1602 return;
1603 }
1604 else
1605 {
1606 // The first click was on another item, so don't interpret this as
1607 // a double click, but as a simple click instead
1608 forceClick = true;
0fdc2321 1609 }
120b9b05 1610 }
f554a14b 1611
0fcce6b9
RR
1612 if (event.LeftUp())
1613 {
0a71f9e9 1614 if (m_lineSelectSingleOnUp != (unsigned int)-1)
e21f75bd
RR
1615 {
1616 // select single line
1617 SelectAllRows( false );
1618 SelectRow( m_lineSelectSingleOnUp, true );
1619 }
120b9b05 1620
0fcce6b9
RR
1621 if (m_lastOnSame)
1622 {
a8461d31 1623 if ((col == m_currentCol) && (current == m_currentRow) &&
0fcce6b9
RR
1624 (cell->GetMode() == wxDATAVIEW_CELL_EDITABLE) )
1625 {
1626 m_renameTimer->Start( 100, true );
1627 }
1628 }
1629
1630 m_lastOnSame = false;
0a71f9e9 1631 m_lineSelectSingleOnUp = (unsigned int)-1;
120b9b05 1632 }
e21f75bd
RR
1633 else
1634 {
1635 // This is necessary, because after a DnD operation in
1636 // from and to ourself, the up event is swallowed by the
1637 // DnD code. So on next non-up event (which means here and
1638 // now) m_lineSelectSingleOnUp should be reset.
0a71f9e9 1639 m_lineSelectSingleOnUp = (unsigned int)-1;
e21f75bd
RR
1640 }
1641
1642 if (event.RightDown())
1643 {
1644 m_lineBeforeLastClicked = m_lineLastClicked;
1645 m_lineLastClicked = current;
1646
1647 // If the item is already selected, do not update the selection.
1648 // Multi-selections should not be cleared if a selected item is clicked.
1649 if (!IsRowSelected(current))
1650 {
1651 SelectAllRows(false);
1652 ChangeCurrentRow(current);
1653 SelectRow(m_currentRow,true);
1654 }
1655
1656 // notify cell about right click
1657 // cell->...
120b9b05 1658
e21f75bd
RR
1659 // Allow generation of context menu event
1660 event.Skip();
1661 }
1662 else if (event.MiddleDown())
1663 {
1664 // notify cell about middle click
1665 // cell->...
1666 }
1667 if (event.LeftDown() || forceClick)
0fcce6b9 1668 {
72664514
RR
1669#ifdef __WXMSW__
1670 SetFocus();
1671#endif
120b9b05 1672
e21f75bd
RR
1673 m_lineBeforeLastClicked = m_lineLastClicked;
1674 m_lineLastClicked = current;
1675
0a71f9e9 1676 unsigned int oldCurrentRow = m_currentRow;
e21f75bd
RR
1677 bool oldWasSelected = IsRowSelected(m_currentRow);
1678
1679 bool cmdModifierDown = event.CmdDown();
1680 if ( IsSingleSel() || !(cmdModifierDown || event.ShiftDown()) )
1681 {
1682 if ( IsSingleSel() || !IsRowSelected(current) )
1683 {
1684 SelectAllRows( false );
1685
1686 ChangeCurrentRow(current);
1687
1688 SelectRow(m_currentRow,true);
1689 }
1690 else // multi sel & current is highlighted & no mod keys
1691 {
1692 m_lineSelectSingleOnUp = current;
1693 ChangeCurrentRow(current); // change focus
1694 }
1695 }
1696 else // multi sel & either ctrl or shift is down
1697 {
1698 if (cmdModifierDown)
1699 {
1700 ChangeCurrentRow(current);
1701
1702 ReverseRowSelection(m_currentRow);
1703 }
1704 else if (event.ShiftDown())
1705 {
1706 ChangeCurrentRow(current);
1707
0a71f9e9 1708 unsigned int lineFrom = oldCurrentRow,
e21f75bd
RR
1709 lineTo = current;
1710
1711 if ( lineTo < lineFrom )
1712 {
1713 lineTo = lineFrom;
1714 lineFrom = m_currentRow;
1715 }
1716
1717 SelectRows(lineFrom, lineTo, true);
1718 }
1719 else // !ctrl, !shift
1720 {
1721 // test in the enclosing if should make it impossible
1722 wxFAIL_MSG( _T("how did we get here?") );
1723 }
1724 }
1725
72664514
RR
1726 if (m_currentRow != oldCurrentRow)
1727 RefreshRow( oldCurrentRow );
e21f75bd 1728
0fcce6b9 1729 wxDataViewColumn *oldCurrentCol = m_currentCol;
120b9b05 1730
0fcce6b9
RR
1731 // Update selection here...
1732 m_currentCol = col;
120b9b05 1733
e21f75bd 1734 m_lastOnSame = !forceClick && ((col == oldCurrentCol) && (current == oldCurrentRow)) && oldWasSelected;
0fdc2321 1735 }
4ed7af08
RR
1736}
1737
1738void wxDataViewMainWindow::OnSetFocus( wxFocusEvent &event )
1739{
cab07038 1740 m_hasFocus = true;
120b9b05 1741
cab07038
RR
1742 if (HasCurrentRow())
1743 Refresh();
120b9b05 1744
cab07038
RR
1745 event.Skip();
1746}
1747
1748void wxDataViewMainWindow::OnKillFocus( wxFocusEvent &event )
1749{
1750 m_hasFocus = false;
120b9b05 1751
cab07038
RR
1752 if (HasCurrentRow())
1753 Refresh();
120b9b05 1754
4ed7af08
RR
1755 event.Skip();
1756}
1757
1758//-----------------------------------------------------------------------------
1759// wxDataViewCtrl
1760//-----------------------------------------------------------------------------
1761
1762IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl, wxDataViewCtrlBase)
1763
4b3feaa7
RR
1764BEGIN_EVENT_TABLE(wxDataViewCtrl, wxDataViewCtrlBase)
1765 EVT_SIZE(wxDataViewCtrl::OnSize)
1766END_EVENT_TABLE()
1767
4ed7af08
RR
1768wxDataViewCtrl::~wxDataViewCtrl()
1769{
1770 if (m_notifier)
1771 GetModel()->RemoveNotifier( m_notifier );
1772}
1773
1774void wxDataViewCtrl::Init()
1775{
1776 m_notifier = NULL;
1777}
1778
1779bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id,
f554a14b 1780 const wxPoint& pos, const wxSize& size,
4ed7af08
RR
1781 long style, const wxValidator& validator )
1782{
4b3feaa7
RR
1783 if (!wxControl::Create( parent, id, pos, size, style | wxScrolledWindowStyle|wxSUNKEN_BORDER, validator))
1784 return false;
1785
4ed7af08 1786 Init();
f554a14b 1787
4ed7af08
RR
1788#ifdef __WXMAC__
1789 MacSetClipChildren( true ) ;
1790#endif
1791
f554a14b 1792 m_clientArea = new wxDataViewMainWindow( this, wxID_ANY );
72664514
RR
1793#ifdef __WXMSW__
1794 m_headerArea = new wxDataViewHeaderWindow( this, wxID_ANY, wxDefaultPosition, wxSize(wxDefaultCoord,22) );
1795#else
f554a14b 1796 m_headerArea = new wxDataViewHeaderWindow( this, wxID_ANY, wxDefaultPosition, wxSize(wxDefaultCoord,25) );
120b9b05 1797#endif
f554a14b 1798
4ed7af08 1799 SetTargetWindow( m_clientArea );
f554a14b 1800
4ed7af08
RR
1801 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
1802 sizer->Add( m_headerArea, 0, wxGROW );
1803 sizer->Add( m_clientArea, 1, wxGROW );
1804 SetSizer( sizer );
1805
1806 return true;
1807}
1808
1809#ifdef __WXMSW__
1810WXLRESULT wxDataViewCtrl::MSWWindowProc(WXUINT nMsg,
1811 WXWPARAM wParam,
1812 WXLPARAM lParam)
1813{
b910a8ad 1814 WXLRESULT rc = wxDataViewCtrlBase::MSWWindowProc(nMsg, wParam, lParam);
4ed7af08
RR
1815
1816#ifndef __WXWINCE__
1817 // we need to process arrows ourselves for scrolling
1818 if ( nMsg == WM_GETDLGCODE )
1819 {
1820 rc |= DLGC_WANTARROWS;
1821 }
1822#endif
1823
1824 return rc;
1825}
1826#endif
1827
f554a14b 1828void wxDataViewCtrl::OnSize( wxSizeEvent &WXUNUSED(event) )
4ed7af08 1829{
4b3feaa7
RR
1830 // We need to override OnSize so that our scrolled
1831 // window a) does call Layout() to use sizers for
1832 // positioning the controls but b) does not query
1833 // the sizer for their size and use that for setting
1834 // the scrollable area as set that ourselves by
1835 // calling SetScrollbar() further down.
1836
1837 Layout();
1838
1839 AdjustScrollbars();
4ed7af08
RR
1840}
1841
1842bool wxDataViewCtrl::AssociateModel( wxDataViewListModel *model )
1843{
1844 if (!wxDataViewCtrlBase::AssociateModel( model ))
1845 return false;
1846
a0f3af5f 1847 m_notifier = new wxGenericDataViewListModelNotifier( m_clientArea );
4ed7af08 1848
f554a14b 1849 model->AddNotifier( m_notifier );
4ed7af08 1850
4b3feaa7 1851 m_clientArea->UpdateDisplay();
f554a14b 1852
4ed7af08
RR
1853 return true;
1854}
1855
1856bool wxDataViewCtrl::AppendColumn( wxDataViewColumn *col )
1857{
1858 if (!wxDataViewCtrlBase::AppendColumn(col))
1859 return false;
f554a14b 1860
4b3feaa7 1861 m_clientArea->UpdateDisplay();
f554a14b 1862
4ed7af08
RR
1863 return true;
1864}
1865
df387169 1866void wxDataViewCtrl::SetSelection( int WXUNUSED(row) )
6ff7eee7 1867{
df387169 1868 // FIXME - TODO
6ff7eee7
RR
1869}
1870
df387169 1871void wxDataViewCtrl::SetSelectionRange( unsigned int WXUNUSED(from), unsigned int WXUNUSED(to) )
6ff7eee7 1872{
df387169 1873 // FIXME - TODO
6ff7eee7
RR
1874}
1875
df387169 1876void wxDataViewCtrl::SetSelections( const wxArrayInt& WXUNUSED(aSelections) )
6ff7eee7 1877{
df387169 1878 // FIXME - TODO
6ff7eee7 1879}
df387169
WS
1880
1881void wxDataViewCtrl::Unselect( unsigned int WXUNUSED(row) )
fc211fe5 1882{
df387169 1883 // FIXME - TODO
fc211fe5
RR
1884}
1885
df387169 1886bool wxDataViewCtrl::IsSelected( unsigned int WXUNUSED(row) ) const
6ff7eee7 1887{
df387169
WS
1888 // FIXME - TODO
1889
6ff7eee7
RR
1890 return false;
1891}
1892
1893int wxDataViewCtrl::GetSelection() const
1894{
df387169
WS
1895 // FIXME - TODO
1896
6ff7eee7
RR
1897 return -1;
1898}
1899
df387169 1900int wxDataViewCtrl::GetSelections(wxArrayInt& WXUNUSED(aSelections) ) const
6ff7eee7 1901{
df387169
WS
1902 // FIXME - TODO
1903
6ff7eee7
RR
1904 return 0;
1905}
1906
f554a14b 1907#endif
4ed7af08
RR
1908 // !wxUSE_GENERICDATAVIEWCTRL
1909
f554a14b 1910#endif
4ed7af08 1911 // wxUSE_DATAVIEWCTRL