]> git.saurik.com Git - wxWidgets.git/blame - src/generic/datavgen.cpp
restored (as deprecated) accidentally removed wx{Dir|File}Dialog::Get/SetStyle()
[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
8d0ca292
WS
498#if wxUSE_CALENDARCTRL
499
baa9ebc4 500class wxDataViewDateRendererPopupTransient: public wxPopupTransientWindow
4ed7af08 501{
f554a14b 502public:
baa9ebc4 503 wxDataViewDateRendererPopupTransient( wxWindow* parent, wxDateTime *value,
0a71f9e9 504 wxDataViewListModel *model, unsigned int col, unsigned int row ) :
4ed7af08
RR
505 wxPopupTransientWindow( parent, wxBORDER_SIMPLE )
506 {
507 m_model = model;
508 m_col = col;
509 m_row = row;
f554a14b 510 m_cal = new wxCalendarCtrl( this, wxID_ANY, *value );
4ed7af08
RR
511 wxBoxSizer *sizer = new wxBoxSizer( wxHORIZONTAL );
512 sizer->Add( m_cal, 1, wxGROW );
513 SetSizer( sizer );
514 sizer->Fit( this );
515 }
f554a14b 516
4ed7af08 517 void OnCalendar( wxCalendarEvent &event );
f554a14b 518
4ed7af08 519 wxCalendarCtrl *m_cal;
f554a14b 520 wxDataViewListModel *m_model;
0a71f9e9
RR
521 unsigned int m_col;
522 unsigned int m_row;
f554a14b 523
a8461d31
PC
524protected:
525 virtual void OnDismiss()
526 {
527 }
528
4ed7af08
RR
529private:
530 DECLARE_EVENT_TABLE()
531};
532
baa9ebc4
RR
533BEGIN_EVENT_TABLE(wxDataViewDateRendererPopupTransient,wxPopupTransientWindow)
534 EVT_CALENDAR( wxID_ANY, wxDataViewDateRendererPopupTransient::OnCalendar )
4ed7af08
RR
535END_EVENT_TABLE()
536
baa9ebc4 537void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent &event )
4ed7af08
RR
538{
539 wxDateTime date = event.GetDate();
540 wxVariant value = date;
541 m_model->SetValue( value, m_col, m_row );
542 m_model->ValueChanged( m_col, m_row );
543 DismissAndNotify();
544}
545
8d0ca292
WS
546#endif // wxUSE_CALENDARCTRL
547
baa9ebc4 548IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer, wxDataViewCustomRenderer)
4ed7af08 549
baa9ebc4 550wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString &varianttype,
4ed7af08 551 wxDataViewCellMode mode ) :
baa9ebc4 552 wxDataViewCustomRenderer( varianttype, mode )
4ed7af08
RR
553{
554}
f554a14b 555
baa9ebc4 556bool wxDataViewDateRenderer::SetValue( const wxVariant &value )
4ed7af08
RR
557{
558 m_date = value.GetDateTime();
f554a14b 559
4ed7af08
RR
560 return true;
561}
562
baa9ebc4 563bool wxDataViewDateRenderer::Render( wxRect cell, wxDC *dc, int WXUNUSED(state) )
4ed7af08
RR
564{
565 dc->SetFont( GetOwner()->GetOwner()->GetFont() );
566 wxString tmp = m_date.FormatDate();
567 dc->DrawText( tmp, cell.x, cell.y );
568
569 return true;
570}
571
baa9ebc4 572wxSize wxDataViewDateRenderer::GetSize()
4ed7af08
RR
573{
574 wxDataViewCtrl* view = GetOwner()->GetOwner();
575 wxString tmp = m_date.FormatDate();
576 wxCoord x,y,d;
577 view->GetTextExtent( tmp, &x, &y, &d );
578 return wxSize(x,y+d);
579}
580
baa9ebc4 581bool wxDataViewDateRenderer::Activate( wxRect WXUNUSED(cell), wxDataViewListModel *model, unsigned int col, unsigned int row )
4ed7af08
RR
582{
583 wxVariant variant;
584 model->GetValue( variant, col, row );
585 wxDateTime value = variant.GetDateTime();
586
8d0ca292 587#if wxUSE_CALENDARCTRL
baa9ebc4 588 wxDataViewDateRendererPopupTransient *popup = new wxDataViewDateRendererPopupTransient(
4ed7af08
RR
589 GetOwner()->GetOwner()->GetParent(), &value, model, col, row );
590 wxPoint pos = wxGetMousePosition();
591 popup->Move( pos );
592 popup->Layout();
593 popup->Popup( popup->m_cal );
8d0ca292
WS
594#else
595 wxMessageBox(value.Format());
596#endif
4ed7af08
RR
597 return true;
598}
599
f554a14b 600// ---------------------------------------------------------
4ed7af08 601// wxDataViewColumn
f554a14b 602// ---------------------------------------------------------
4ed7af08
RR
603
604IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumn, wxDataViewColumnBase)
605
baa9ebc4 606wxDataViewColumn::wxDataViewColumn( const wxString &title, wxDataViewRenderer *cell, unsigned int model_column,
008b5a66
RR
607 int width, int flags ) :
608 wxDataViewColumnBase( title, cell, model_column, width, flags )
4ed7af08 609{
008b5a66
RR
610 m_width = width;
611 if (m_width < 0)
612 m_width = 80;
4ed7af08
RR
613}
614
07a84e7b
RR
615wxDataViewColumn::wxDataViewColumn( const wxBitmap &bitmap, wxDataViewRenderer *cell, unsigned int model_column,
616 int width, int flags ) :
617 wxDataViewColumnBase( bitmap, cell, model_column, width, flags )
618{
619 m_width = width;
620 if (m_width < 0)
621 m_width = 30;
622}
623
47cef10f
RR
624void wxDataViewColumn::SetAlignment( wxAlignment WXUNUSED(align) )
625{
626 // TODO
627}
628
31fb32e1
RR
629void wxDataViewColumn::SetSortable( bool WXUNUSED(sortable) )
630{
631 // TODO
632}
633
634bool wxDataViewColumn::GetSortable()
8d0ca292 635{
31fb32e1
RR
636 // TODO
637 return false;
638}
639
47cef10f
RR
640void wxDataViewColumn::SetSortOrder( bool WXUNUSED(ascending) )
641{
642 // TODO
643}
644
31fb32e1
RR
645bool wxDataViewColumn::IsSortOrderAscending()
646{
647 // TODO
648 return true;
649}
650
651
4ed7af08
RR
652wxDataViewColumn::~wxDataViewColumn()
653{
654}
655
656void wxDataViewColumn::SetTitle( const wxString &title )
657{
658 wxDataViewColumnBase::SetTitle( title );
f554a14b 659
4ed7af08
RR
660}
661
47cef10f
RR
662void wxDataViewColumn::SetBitmap( const wxBitmap &bitmap )
663{
664 wxDataViewColumnBase::SetBitmap( bitmap );
665
666}
667
533544f2
RR
668int wxDataViewColumn::GetWidth()
669{
670 return m_width;
671}
672
4ed7af08
RR
673//-----------------------------------------------------------------------------
674// wxDataViewHeaderWindow
675//-----------------------------------------------------------------------------
676
45778c96 677IMPLEMENT_ABSTRACT_CLASS(wxDataViewHeaderWindow, wxWindow)
4ed7af08
RR
678
679BEGIN_EVENT_TABLE(wxDataViewHeaderWindow,wxWindow)
680 EVT_PAINT (wxDataViewHeaderWindow::OnPaint)
681 EVT_MOUSE_EVENTS (wxDataViewHeaderWindow::OnMouse)
682 EVT_SET_FOCUS (wxDataViewHeaderWindow::OnSetFocus)
683END_EVENT_TABLE()
684
685wxDataViewHeaderWindow::wxDataViewHeaderWindow( wxDataViewCtrl *parent, wxWindowID id,
686 const wxPoint &pos, const wxSize &size, const wxString &name ) :
687 wxWindow( parent, id, pos, size, 0, name )
688{
689 SetOwner( parent );
4b3feaa7 690
4ed7af08 691 m_resizeCursor = new wxCursor( wxCURSOR_SIZEWE );
f554a14b 692
4ed7af08 693 wxVisualAttributes attr = wxPanel::GetClassDefaultAttributes();
2e992e06 694 SetBackgroundStyle( wxBG_STYLE_CUSTOM );
4ed7af08
RR
695 SetOwnForegroundColour( attr.colFg );
696 SetOwnBackgroundColour( attr.colBg );
697 if (!m_hasFont)
698 SetOwnFont( attr.font );
699}
700
701wxDataViewHeaderWindow::~wxDataViewHeaderWindow()
702{
703 delete m_resizeCursor;
704}
705
f554a14b 706void wxDataViewHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
4ed7af08 707{
4b3feaa7
RR
708 int w, h;
709 GetClientSize( &w, &h );
710
2e992e06
VZ
711 wxAutoBufferedPaintDC dc( this );
712
713 dc.SetBackground(GetBackgroundColour());
714 dc.Clear();
f554a14b 715
4ed7af08
RR
716 int xpix;
717 m_owner->GetScrollPixelsPerUnit( &xpix, NULL );
718
719 int x;
720 m_owner->GetViewStart( &x, NULL );
721
722 // account for the horz scrollbar offset
723 dc.SetDeviceOrigin( -x * xpix, 0 );
f554a14b 724
4ed7af08 725 dc.SetFont( GetFont() );
f554a14b 726
0a71f9e9
RR
727 unsigned int cols = GetOwner()->GetNumberOfColumns();
728 unsigned int i;
4b3feaa7
RR
729 int xpos = 0;
730 for (i = 0; i < cols; i++)
731 {
732 wxDataViewColumn *col = GetOwner()->GetColumn( i );
733 int width = col->GetWidth();
f554a14b 734
4b3feaa7
RR
735 int cw = width;
736 int ch = h;
4b3feaa7
RR
737
738 wxRendererNative::Get().DrawHeaderButton
739 (
740 this,
741 dc,
72664514 742 wxRect(xpos, 0, cw, ch-1),
4b3feaa7
RR
743 m_parent->IsEnabled() ? 0
744 : (int)wxCONTROL_DISABLED
745 );
746
f554a14b
WS
747 dc.DrawText( col->GetTitle(), xpos+3, 3 );
748
4b3feaa7
RR
749 xpos += width;
750 }
4ed7af08
RR
751}
752
f554a14b 753void wxDataViewHeaderWindow::OnMouse( wxMouseEvent &WXUNUSED(event) )
4ed7af08
RR
754{
755}
756
757void wxDataViewHeaderWindow::OnSetFocus( wxFocusEvent &event )
758{
cab07038 759 GetParent()->SetFocus();
4ed7af08
RR
760 event.Skip();
761}
762
0fcce6b9
RR
763//-----------------------------------------------------------------------------
764// wxDataViewRenameTimer
765//-----------------------------------------------------------------------------
766
767wxDataViewRenameTimer::wxDataViewRenameTimer( wxDataViewMainWindow *owner )
768{
769 m_owner = owner;
770}
771
772void wxDataViewRenameTimer::Notify()
773{
774 m_owner->OnRenameTimer();
775}
776
777//-----------------------------------------------------------------------------
778// wxDataViewTextCtrlWrapper: wraps a wxTextCtrl for inline editing
779//-----------------------------------------------------------------------------
780
781BEGIN_EVENT_TABLE(wxDataViewTextCtrlWrapper, wxEvtHandler)
782 EVT_CHAR (wxDataViewTextCtrlWrapper::OnChar)
783 EVT_KEY_UP (wxDataViewTextCtrlWrapper::OnKeyUp)
784 EVT_KILL_FOCUS (wxDataViewTextCtrlWrapper::OnKillFocus)
785END_EVENT_TABLE()
786
787wxDataViewTextCtrlWrapper::wxDataViewTextCtrlWrapper(
788 wxDataViewMainWindow *owner,
789 wxTextCtrl *text,
790 wxDataViewListModel *model,
0a71f9e9 791 unsigned int col, unsigned int row,
0fcce6b9
RR
792 wxRect rectLabel )
793{
794 m_owner = owner;
795 m_model = model;
796 m_row = row;
797 m_col = col;
120b9b05
WS
798 m_text = text;
799
0fcce6b9
RR
800 m_finished = false;
801 m_aboutToFinish = false;
120b9b05 802
0fcce6b9
RR
803 wxVariant value;
804 model->GetValue( value, col, row );
805 m_startValue = value.GetString();
120b9b05 806
0fcce6b9
RR
807 m_owner->GetOwner()->CalcScrolledPosition(
808 rectLabel.x, rectLabel.y, &rectLabel.x, &rectLabel.y );
809
810 m_text->Create( owner, wxID_ANY, m_startValue,
811 wxPoint(rectLabel.x-2,rectLabel.y-2),
812 wxSize(rectLabel.width+7,rectLabel.height+4) );
813 m_text->SetFocus();
120b9b05 814
0fcce6b9
RR
815 m_text->PushEventHandler(this);
816}
817
818void wxDataViewTextCtrlWrapper::AcceptChangesAndFinish()
819{
820 m_aboutToFinish = true;
821
822 // Notify the owner about the changes
823 AcceptChanges();
824
825 // Even if vetoed, close the control (consistent with MSW)
826 Finish();
827}
828
829void wxDataViewTextCtrlWrapper::OnChar( wxKeyEvent &event )
830{
831 switch ( event.m_keyCode )
832 {
833 case WXK_RETURN:
834 AcceptChangesAndFinish();
835 break;
836
837 case WXK_ESCAPE:
838 // m_owner->OnRenameCancelled( m_itemEdited );
839 Finish();
840 break;
841
842 default:
843 event.Skip();
844 }
845}
846
847void wxDataViewTextCtrlWrapper::OnKeyUp( wxKeyEvent &event )
848{
849 if (m_finished)
850 {
851 event.Skip();
852 return;
853 }
854
855 // auto-grow the textctrl
856 wxSize parentSize = m_owner->GetSize();
857 wxPoint myPos = m_text->GetPosition();
858 wxSize mySize = m_text->GetSize();
859 int sx, sy;
860 m_text->GetTextExtent(m_text->GetValue() + _T("MM"), &sx, &sy);
861 if (myPos.x + sx > parentSize.x)
862 sx = parentSize.x - myPos.x;
863 if (mySize.x > sx)
864 sx = mySize.x;
865 m_text->SetSize(sx, wxDefaultCoord);
866
867 event.Skip();
868}
869
870void wxDataViewTextCtrlWrapper::OnKillFocus( wxFocusEvent &event )
871{
872 if ( !m_finished && !m_aboutToFinish )
873 {
874 AcceptChanges();
875 //if ( !AcceptChanges() )
876 // m_owner->OnRenameCancelled( m_itemEdited );
120b9b05 877
0fcce6b9
RR
878 Finish();
879 }
880
881 // We must let the native text control handle focus
882 event.Skip();
883}
884
885bool wxDataViewTextCtrlWrapper::AcceptChanges()
886{
887 const wxString value = m_text->GetValue();
888
889 if ( value == m_startValue )
890 // nothing changed, always accept
891 return true;
892
893// if ( !m_owner->OnRenameAccept(m_itemEdited, value) )
894 // vetoed by the user
895// return false;
896
897 // accepted, do rename the item
898 wxVariant variant;
899 variant = value;
900 m_model->SetValue( variant, m_col, m_row );
901 m_model->ValueChanged( m_col, m_row );
902
903 return true;
904}
905
906void wxDataViewTextCtrlWrapper::Finish()
907{
908 if ( !m_finished )
909 {
910 m_finished = true;
911
912 m_text->RemoveEventHandler(this);
913 m_owner->FinishEditing(m_text);
914
915 // delete later
916 wxPendingDelete.Append( this );
917 }
918}
919
4ed7af08
RR
920//-----------------------------------------------------------------------------
921// wxDataViewMainWindow
922//-----------------------------------------------------------------------------
923
0a71f9e9 924int LINKAGEMODE wxDataViewSelectionCmp( unsigned int row1, unsigned int row2 )
cab07038
RR
925{
926 if (row1 > row2) return 1;
927 if (row1 == row2) return 0;
928 return -1;
929}
930
931
45778c96 932IMPLEMENT_ABSTRACT_CLASS(wxDataViewMainWindow, wxWindow)
4ed7af08
RR
933
934BEGIN_EVENT_TABLE(wxDataViewMainWindow,wxWindow)
935 EVT_PAINT (wxDataViewMainWindow::OnPaint)
936 EVT_MOUSE_EVENTS (wxDataViewMainWindow::OnMouse)
937 EVT_SET_FOCUS (wxDataViewMainWindow::OnSetFocus)
cab07038
RR
938 EVT_KILL_FOCUS (wxDataViewMainWindow::OnKillFocus)
939 EVT_CHAR (wxDataViewMainWindow::OnChar)
4ed7af08
RR
940END_EVENT_TABLE()
941
942wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl *parent, wxWindowID id,
943 const wxPoint &pos, const wxSize &size, const wxString &name ) :
72664514 944 wxWindow( parent, id, pos, size, wxWANTS_CHARS, name ),
cab07038 945 m_selection( wxDataViewSelectionCmp )
120b9b05 946
4ed7af08
RR
947{
948 SetOwner( parent );
f554a14b 949
0fcce6b9
RR
950 m_lastOnSame = false;
951 m_renameTimer = new wxDataViewRenameTimer( this );
952 m_textctrlWrapper = NULL;
120b9b05 953
0fcce6b9
RR
954 // TODO: user better initial values/nothing selected
955 m_currentCol = NULL;
956 m_currentRow = 0;
957
958 // TODO: we need to calculate this smartly
4b3feaa7 959 m_lineHeight = 20;
e21f75bd
RR
960
961 m_dragCount = 0;
962 m_dragStart = wxPoint(0,0);
0a71f9e9
RR
963 m_lineLastClicked = (unsigned int) -1;
964 m_lineBeforeLastClicked = (unsigned int) -1;
965 m_lineSelectSingleOnUp = (unsigned int) -1;
120b9b05 966
cab07038 967 m_hasFocus = false;
f554a14b 968
2e992e06 969 SetBackgroundStyle( wxBG_STYLE_CUSTOM );
72664514
RR
970 SetBackgroundColour( *wxWHITE );
971
4b3feaa7 972 UpdateDisplay();
4ed7af08
RR
973}
974
975wxDataViewMainWindow::~wxDataViewMainWindow()
976{
0fcce6b9
RR
977 delete m_renameTimer;
978}
979
980void wxDataViewMainWindow::OnRenameTimer()
981{
982 // We have to call this here because changes may just have
983 // been made and no screen update taken place.
984 if ( m_dirty )
985 wxSafeYield();
986
987
988 int xpos = 0;
0a71f9e9
RR
989 unsigned int cols = GetOwner()->GetNumberOfColumns();
990 unsigned int i;
0fcce6b9
RR
991 for (i = 0; i < cols; i++)
992 {
993 wxDataViewColumn *c = GetOwner()->GetColumn( i );
994 if (c == m_currentCol)
995 break;
996 xpos += c->GetWidth();
997 }
998 wxRect labelRect( xpos, m_currentRow * m_lineHeight, m_currentCol->GetWidth(), m_lineHeight );
999
1000 wxClassInfo *textControlClass = CLASSINFO(wxTextCtrl);
1001
1002 wxTextCtrl * const text = (wxTextCtrl *)textControlClass->CreateObject();
120b9b05 1003 m_textctrlWrapper = new wxDataViewTextCtrlWrapper(this, text, GetOwner()->GetModel(),
0fcce6b9
RR
1004 m_currentCol->GetModelColumn(), m_currentRow, labelRect );
1005}
1006
1007void wxDataViewMainWindow::FinishEditing( wxTextCtrl *text )
1008{
1009 delete text;
1010 m_textctrlWrapper = NULL;
1011 SetFocus();
1012 // SetFocusIgnoringChildren();
4ed7af08
RR
1013}
1014
a0f3af5f
RR
1015bool wxDataViewMainWindow::RowAppended()
1016{
1017 return false;
1018}
1019
1020bool wxDataViewMainWindow::RowPrepended()
1021{
1022 return false;
1023}
1024
0a71f9e9 1025bool wxDataViewMainWindow::RowInserted( unsigned int WXUNUSED(before) )
a0f3af5f
RR
1026{
1027 return false;
1028}
1029
0a71f9e9 1030bool wxDataViewMainWindow::RowDeleted( unsigned int WXUNUSED(row) )
a0f3af5f
RR
1031{
1032 return false;
1033}
1034
0a71f9e9 1035bool wxDataViewMainWindow::RowChanged( unsigned int WXUNUSED(row) )
a0f3af5f
RR
1036{
1037 return false;
1038}
1039
0a71f9e9 1040bool wxDataViewMainWindow::ValueChanged( unsigned int WXUNUSED(col), unsigned int row )
a0f3af5f 1041{
0fdc2321
RR
1042 wxRect rect( 0, row*m_lineHeight, 10000, m_lineHeight );
1043 m_owner->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
1044 Refresh( true, &rect );
1045
1046 return true;
a0f3af5f
RR
1047}
1048
0a71f9e9 1049bool wxDataViewMainWindow::RowsReordered( unsigned int *WXUNUSED(new_order) )
a0f3af5f 1050{
0fcce6b9 1051 Refresh();
120b9b05 1052
0fcce6b9 1053 return true;
a0f3af5f
RR
1054}
1055
1056bool wxDataViewMainWindow::Cleared()
1057{
1058 return false;
1059}
1060
4b3feaa7
RR
1061void wxDataViewMainWindow::UpdateDisplay()
1062{
1063 m_dirty = true;
1064}
1065
1066void wxDataViewMainWindow::OnInternalIdle()
1067{
1068 wxWindow::OnInternalIdle();
f554a14b 1069
4b3feaa7
RR
1070 if (m_dirty)
1071 {
1072 RecalculateDisplay();
1073 m_dirty = false;
1074 }
1075}
1076
1077void wxDataViewMainWindow::RecalculateDisplay()
1078{
1079 wxDataViewListModel *model = GetOwner()->GetModel();
1080 if (!model)
1081 {
1082 Refresh();
1083 return;
1084 }
f554a14b 1085
4b3feaa7 1086 int width = 0;
0a71f9e9
RR
1087 unsigned int cols = GetOwner()->GetNumberOfColumns();
1088 unsigned int i;
4b3feaa7
RR
1089 for (i = 0; i < cols; i++)
1090 {
1091 wxDataViewColumn *col = GetOwner()->GetColumn( i );
1092 width += col->GetWidth();
1093 }
f554a14b 1094
4b3feaa7
RR
1095 int height = model->GetNumberOfRows() * m_lineHeight;
1096
1097 SetVirtualSize( width, height );
1098 GetOwner()->SetScrollRate( 10, m_lineHeight );
f554a14b 1099
4b3feaa7
RR
1100 Refresh();
1101}
1102
1103void wxDataViewMainWindow::ScrollWindow( int dx, int dy, const wxRect *rect )
1104{
1105 wxWindow::ScrollWindow( dx, dy, rect );
1106 GetOwner()->m_headerArea->ScrollWindow( dx, 0 );
1107}
1108
f554a14b 1109void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
4ed7af08 1110{
2e992e06
VZ
1111 wxAutoBufferedPaintDC dc( this );
1112
1113 dc.SetBackground(GetBackgroundColour());
1114 dc.Clear();
4ed7af08 1115
4b3feaa7 1116 GetOwner()->PrepareDC( dc );
4ed7af08
RR
1117
1118 dc.SetFont( GetFont() );
90675b95
RR
1119
1120 wxRect update = GetUpdateRegion().GetBox();
1121 m_owner->CalcUnscrolledPosition( update.x, update.y, &update.x, &update.y );
f554a14b 1122
90675b95 1123 wxDataViewListModel *model = GetOwner()->GetModel();
f554a14b 1124
0a71f9e9
RR
1125 unsigned int item_start = wxMax( 0, (update.y / m_lineHeight) );
1126 unsigned int item_count = wxMin( (int)(((update.y + update.height) / m_lineHeight) - item_start + 1),
a87594c6 1127 (int)(model->GetNumberOfRows()-item_start) );
90675b95 1128
120b9b05 1129
cab07038 1130
0a71f9e9 1131 unsigned int item;
cab07038
RR
1132 for (item = item_start; item < item_start+item_count; item++)
1133 {
1134 if (m_selection.Index( item ) != wxNOT_FOUND)
1135 {
daebb44c
RR
1136 int flags = wxCONTROL_SELECTED;
1137 if (item == m_currentRow)
1138 flags |= wxCONTROL_CURRENT;
1139 if (m_hasFocus)
1140 flags |= wxCONTROL_FOCUSED;
e21f75bd 1141 wxRect rect( 0, item*m_lineHeight+1, GetEndOfLastCol(), m_lineHeight-2 );
daebb44c
RR
1142 wxRendererNative::Get().DrawItemSelectionRect
1143 (
1144 this,
1145 dc,
1146 rect,
1147 flags
1148 );
1149 }
1150 else
1151 {
1152 if (item == m_currentRow)
1153 {
1154 int flags = wxCONTROL_CURRENT;
1155 if (m_hasFocus)
1156 flags |= wxCONTROL_FOCUSED; // should have no effect
1157 wxRect rect( 0, item*m_lineHeight+1, GetEndOfLastCol(), m_lineHeight-2 );
1158 wxRendererNative::Get().DrawItemSelectionRect
1159 (
1160 this,
1161 dc,
1162 rect,
1163 flags
1164 );
120b9b05 1165
daebb44c 1166 }
cab07038
RR
1167 }
1168 }
120b9b05 1169
90675b95
RR
1170 wxRect cell_rect;
1171 cell_rect.x = 0;
1172 cell_rect.height = m_lineHeight;
0a71f9e9
RR
1173 unsigned int cols = GetOwner()->GetNumberOfColumns();
1174 unsigned int i;
90675b95
RR
1175 for (i = 0; i < cols; i++)
1176 {
1177 wxDataViewColumn *col = GetOwner()->GetColumn( i );
baa9ebc4 1178 wxDataViewRenderer *cell = col->GetRenderer();
90675b95 1179 cell_rect.width = col->GetWidth();
f554a14b 1180
0fcce6b9 1181 for (item = item_start; item < item_start+item_count; item++)
90675b95
RR
1182 {
1183 cell_rect.y = item*m_lineHeight;
1184 wxVariant value;
1185 model->GetValue( value, col->GetModelColumn(), item );
1186 cell->SetValue( value );
4064f7de
RR
1187 wxSize size = cell->GetSize();
1188 // cannot be bigger than allocated space
1189 size.x = wxMin( size.x, cell_rect.width );
1190 size.y = wxMin( size.y, cell_rect.height );
1191 // TODO: check for left/right/centre alignment here
1192 wxRect item_rect;
1193 // for now: centre
1194 item_rect.x = cell_rect.x + (cell_rect.width / 2) - (size.x / 2);
1195 item_rect.y = cell_rect.y + (cell_rect.height / 2) - (size.y / 2);
f554a14b 1196
4064f7de
RR
1197 item_rect.width = size.x;
1198 item_rect.height= size.y;
64b3c262
VZ
1199
1200 int state = 0;
1201 if (item == m_currentRow)
1202 state |= wxDATAVIEW_CELL_SELECTED;
1203 cell->Render( item_rect, &dc, state );
90675b95 1204 }
f554a14b 1205
90675b95
RR
1206 cell_rect.x += cell_rect.width;
1207 }
4ed7af08
RR
1208}
1209
cab07038
RR
1210int wxDataViewMainWindow::GetCountPerPage()
1211{
1212 wxSize size = GetClientSize();
1213 return size.y / m_lineHeight;
1214}
1215
e21f75bd
RR
1216int wxDataViewMainWindow::GetEndOfLastCol()
1217{
1218 int width = 0;
0a71f9e9 1219 unsigned int i;
e21f75bd
RR
1220 for (i = 0; i < GetOwner()->GetNumberOfColumns(); i++)
1221 {
1222 wxDataViewColumn *c = GetOwner()->GetColumn( i );
1223 width += c->GetWidth();
1224 }
1225 return width;
1226}
1227
0a71f9e9 1228unsigned int wxDataViewMainWindow::GetFirstVisibleRow()
72664514
RR
1229{
1230 int x = 0;
1231 int y = 0;
1232 m_owner->CalcUnscrolledPosition( x, y, &x, &y );
120b9b05 1233
72664514
RR
1234 return y / m_lineHeight;
1235}
1236
0a71f9e9 1237unsigned int wxDataViewMainWindow::GetLastVisibleRow()
72664514
RR
1238{
1239 wxSize client_size = GetClientSize();
1240 m_owner->CalcUnscrolledPosition( client_size.x, client_size.y, &client_size.x, &client_size.y );
1241
5637e131 1242 return wxMin( GetRowCount()-1, ((unsigned)client_size.y/m_lineHeight)+1 );
72664514
RR
1243}
1244
0a71f9e9 1245unsigned int wxDataViewMainWindow::GetRowCount()
cab07038
RR
1246{
1247 return GetOwner()->GetModel()->GetNumberOfRows();
1248}
1249
0a71f9e9 1250void wxDataViewMainWindow::ChangeCurrentRow( unsigned int row )
e21f75bd
RR
1251{
1252 m_currentRow = row;
120b9b05 1253
e21f75bd
RR
1254 // send event
1255}
1256
cab07038
RR
1257void wxDataViewMainWindow::SelectAllRows( bool on )
1258{
4a851b11
VZ
1259 if (IsEmpty())
1260 return;
120b9b05 1261
cab07038
RR
1262 if (on)
1263 {
72664514 1264 m_selection.Clear();
0a71f9e9 1265 for (unsigned int i = 0; i < GetRowCount(); i++)
cab07038 1266 m_selection.Add( i );
72664514
RR
1267 Refresh();
1268 }
1269 else
1270 {
0a71f9e9
RR
1271 unsigned int first_visible = GetFirstVisibleRow();
1272 unsigned int last_visible = GetLastVisibleRow();
1273 unsigned int i;
72664514 1274 for (i = 0; i < m_selection.GetCount(); i++)
120b9b05 1275 {
0a71f9e9 1276 unsigned int row = m_selection[i];
72664514
RR
1277 if ((row >= first_visible) && (row <= last_visible))
1278 RefreshRow( row );
1279 }
1280 m_selection.Clear();
cab07038 1281 }
cab07038
RR
1282}
1283
0a71f9e9 1284void wxDataViewMainWindow::SelectRow( unsigned int row, bool on )
cab07038
RR
1285{
1286 if (m_selection.Index( row ) == wxNOT_FOUND)
1287 {
1288 if (on)
1289 {
1290 m_selection.Add( row );
1291 RefreshRow( row );
1292 }
1293 }
1294 else
1295 {
1296 if (!on)
1297 {
1298 m_selection.Remove( row );
1299 RefreshRow( row );
1300 }
1301 }
1302}
1303
0a71f9e9 1304void wxDataViewMainWindow::SelectRows( unsigned int from, unsigned int to, bool on )
cab07038
RR
1305{
1306 if (from > to)
1307 {
0a71f9e9 1308 unsigned int tmp = from;
cab07038
RR
1309 from = to;
1310 to = tmp;
1311 }
1312
0a71f9e9 1313 unsigned int i;
cab07038
RR
1314 for (i = from; i <= to; i++)
1315 {
1316 if (m_selection.Index( i ) == wxNOT_FOUND)
1317 {
1318 if (on)
1319 m_selection.Add( i );
1320 }
1321 else
1322 {
1323 if (!on)
1324 m_selection.Remove( i );
1325 }
1326 }
1327 RefreshRows( from, to );
1328}
1329
0a71f9e9 1330void wxDataViewMainWindow::ReverseRowSelection( unsigned int row )
cab07038
RR
1331{
1332 if (m_selection.Index( row ) == wxNOT_FOUND)
1333 m_selection.Add( row );
1334 else
1335 m_selection.Remove( row );
120b9b05 1336 RefreshRow( row );
cab07038
RR
1337}
1338
0a71f9e9 1339bool wxDataViewMainWindow::IsRowSelected( unsigned int row )
cab07038
RR
1340{
1341 return (m_selection.Index( row ) != wxNOT_FOUND);
1342}
1343
0a71f9e9 1344void wxDataViewMainWindow::RefreshRow( unsigned int row )
cab07038 1345{
e21f75bd 1346 wxRect rect( 0, row*m_lineHeight, GetEndOfLastCol(), m_lineHeight );
cab07038 1347 m_owner->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
120b9b05 1348
cab07038
RR
1349 wxSize client_size = GetClientSize();
1350 wxRect client_rect( 0, 0, client_size.x, client_size.y );
1351 wxRect intersect_rect = client_rect.Intersect( rect );
1352 if (intersect_rect.width > 0)
1353 Refresh( true, &intersect_rect );
1354}
1355
0a71f9e9 1356void wxDataViewMainWindow::RefreshRows( unsigned int from, unsigned int to )
cab07038
RR
1357{
1358 if (from > to)
1359 {
0a71f9e9 1360 unsigned int tmp = to;
cab07038
RR
1361 to = from;
1362 from = tmp;
1363 }
1364
e21f75bd 1365 wxRect rect( 0, from*m_lineHeight, GetEndOfLastCol(), (to-from+1) * m_lineHeight );
cab07038 1366 m_owner->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
120b9b05 1367
cab07038
RR
1368 wxSize client_size = GetClientSize();
1369 wxRect client_rect( 0, 0, client_size.x, client_size.y );
1370 wxRect intersect_rect = client_rect.Intersect( rect );
1371 if (intersect_rect.width > 0)
1372 Refresh( true, &intersect_rect );
1373}
1374
0a71f9e9 1375void wxDataViewMainWindow::RefreshRowsAfter( unsigned int firstRow )
cab07038 1376{
0a71f9e9 1377 unsigned int count = GetRowCount();
4a851b11
VZ
1378 if (firstRow > count)
1379 return;
120b9b05 1380
e21f75bd 1381 wxRect rect( 0, firstRow*m_lineHeight, GetEndOfLastCol(), count * m_lineHeight );
cab07038 1382 m_owner->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
120b9b05 1383
cab07038
RR
1384 wxSize client_size = GetClientSize();
1385 wxRect client_rect( 0, 0, client_size.x, client_size.y );
1386 wxRect intersect_rect = client_rect.Intersect( rect );
1387 if (intersect_rect.width > 0)
1388 Refresh( true, &intersect_rect );
1389}
1390
0a71f9e9 1391void wxDataViewMainWindow::OnArrowChar(unsigned int newCurrent, const wxKeyEvent& event)
cab07038 1392{
4a851b11 1393 wxCHECK_RET( newCurrent < GetRowCount(),
cab07038
RR
1394 _T("invalid item index in OnArrowChar()") );
1395
1396 // if there is no selection, we cannot move it anywhere
1397 if (!HasCurrentRow())
1398 return;
1399
0a71f9e9 1400 unsigned int oldCurrent = m_currentRow;
cab07038
RR
1401
1402 // in single selection we just ignore Shift as we can't select several
1403 // items anyhow
e21f75bd 1404 if ( event.ShiftDown() && !IsSingleSel() )
cab07038
RR
1405 {
1406 RefreshRow( oldCurrent );
120b9b05 1407
e21f75bd 1408 ChangeCurrentRow( newCurrent );
cab07038
RR
1409
1410 // select all the items between the old and the new one
1411 if ( oldCurrent > newCurrent )
1412 {
1413 newCurrent = oldCurrent;
1414 oldCurrent = m_currentRow;
1415 }
1416
1417 SelectRows( oldCurrent, newCurrent, true );
1418 }
1419 else // !shift
1420 {
72664514 1421 RefreshRow( oldCurrent );
120b9b05 1422
cab07038
RR
1423 // all previously selected items are unselected unless ctrl is held
1424 if ( !event.ControlDown() )
1425 SelectAllRows(false);
1426
e21f75bd 1427 ChangeCurrentRow( newCurrent );
cab07038
RR
1428
1429 if ( !event.ControlDown() )
1430 SelectRow( m_currentRow, true );
72664514
RR
1431 else
1432 RefreshRow( m_currentRow );
cab07038
RR
1433 }
1434
1435 // MoveToFocus();
1436}
1437
1438void wxDataViewMainWindow::OnChar( wxKeyEvent &event )
1439{
1440 if (event.GetKeyCode() == WXK_TAB)
1441 {
1442 wxNavigationKeyEvent nevent;
1443 nevent.SetWindowChange( event.ControlDown() );
1444 nevent.SetDirection( !event.ShiftDown() );
1445 nevent.SetEventObject( GetParent()->GetParent() );
1446 nevent.SetCurrentFocus( m_parent );
1447 if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent ))
1448 return;
1449 }
1450
1451 // no item -> nothing to do
1452 if (!HasCurrentRow())
1453 {
1454 event.Skip();
1455 return;
1456 }
120b9b05 1457
cab07038
RR
1458 // don't use m_linesPerPage directly as it might not be computed yet
1459 const int pageSize = GetCountPerPage();
1460 wxCHECK_RET( pageSize, _T("should have non zero page size") );
1461
1462 switch ( event.GetKeyCode() )
1463 {
1464 case WXK_UP:
1465 if ( m_currentRow > 0 )
1466 OnArrowChar( m_currentRow - 1, event );
1467 break;
1468
1469 case WXK_DOWN:
4a851b11 1470 if ( m_currentRow < GetRowCount() - 1 )
cab07038
RR
1471 OnArrowChar( m_currentRow + 1, event );
1472 break;
1473
1474 case WXK_END:
1475 if (!IsEmpty())
1476 OnArrowChar( GetRowCount() - 1, event );
1477 break;
1478
1479 case WXK_HOME:
1480 if (!IsEmpty())
1481 OnArrowChar( 0, event );
1482 break;
1483
1484 case WXK_PAGEUP:
1485 {
1486 int steps = pageSize - 1;
1487 int index = m_currentRow - steps;
1488 if (index < 0)
1489 index = 0;
1490
1491 OnArrowChar( index, event );
1492 }
1493 break;
1494
1495 case WXK_PAGEDOWN:
1496 {
1497 int steps = pageSize - 1;
0a71f9e9
RR
1498 unsigned int index = m_currentRow + steps;
1499 unsigned int count = GetRowCount();
cab07038
RR
1500 if ( index >= count )
1501 index = count - 1;
1502
1503 OnArrowChar( index, event );
1504 }
1505 break;
1506
1507 default:
1508 event.Skip();
1509 }
1510}
1511
4ed7af08
RR
1512void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
1513{
e21f75bd
RR
1514 if (event.GetEventType() == wxEVT_MOUSEWHEEL)
1515 {
1516 // let the base handle mouse wheel events.
1517 event.Skip();
1518 return;
1519 }
1520
0fdc2321
RR
1521 int x = event.GetX();
1522 int y = event.GetY();
1523 m_owner->CalcUnscrolledPosition( x, y, &x, &y );
1524
1525 wxDataViewColumn *col = NULL;
1526
1527 int xpos = 0;
0a71f9e9
RR
1528 unsigned int cols = GetOwner()->GetNumberOfColumns();
1529 unsigned int i;
0fdc2321
RR
1530 for (i = 0; i < cols; i++)
1531 {
1532 wxDataViewColumn *c = GetOwner()->GetColumn( i );
1533 if (x < xpos + c->GetWidth())
1534 {
1535 col = c;
1536 break;
1537 }
1538 xpos += c->GetWidth();
1539 }
f554a14b 1540 if (!col)
0fdc2321 1541 return;
baa9ebc4 1542 wxDataViewRenderer *cell = col->GetRenderer();
f554a14b 1543
0a71f9e9 1544 unsigned int current = y / m_lineHeight;
120b9b05 1545
e21f75bd
RR
1546 if ((current > GetRowCount()) || (x > GetEndOfLastCol()))
1547 {
1548 // Unselect all if below the last row ?
1549 return;
1550 }
f554a14b 1551
0fdc2321
RR
1552 wxDataViewListModel *model = GetOwner()->GetModel();
1553
e21f75bd
RR
1554 if (event.Dragging())
1555 {
1556 if (m_dragCount == 0)
1557 {
1558 // we have to report the raw, physical coords as we want to be
1559 // able to call HitTest(event.m_pointDrag) from the user code to
1560 // get the item being dragged
1561 m_dragStart = event.GetPosition();
1562 }
1563
1564 m_dragCount++;
1565
1566 if (m_dragCount != 3)
1567 return;
1568
1569 if (event.LeftIsDown())
1570 {
1571 // Notify cell about drag
1572 }
1573 return;
1574 }
1575 else
1576 {
1577 m_dragCount = 0;
1578 }
1579
1580 bool forceClick = false;
1581
0fcce6b9
RR
1582 if (event.ButtonDClick())
1583 {
1584 m_renameTimer->Stop();
1585 m_lastOnSame = false;
1586 }
1587
0fdc2321
RR
1588 if (event.LeftDClick())
1589 {
e21f75bd 1590 if ( current == m_lineLastClicked )
0fdc2321 1591 {
e21f75bd
RR
1592 if (cell->GetMode() == wxDATAVIEW_CELL_ACTIVATABLE)
1593 {
1594 wxVariant value;
1595 model->GetValue( value, col->GetModelColumn(), current );
1596 cell->SetValue( value );
1597 wxRect cell_rect( xpos, current * m_lineHeight, col->GetWidth(), m_lineHeight );
1598 cell->Activate( cell_rect, model, col->GetModelColumn(), current );
1599 }
1600 return;
1601 }
1602 else
1603 {
1604 // The first click was on another item, so don't interpret this as
1605 // a double click, but as a simple click instead
1606 forceClick = true;
0fdc2321 1607 }
120b9b05 1608 }
f554a14b 1609
0fcce6b9
RR
1610 if (event.LeftUp())
1611 {
0a71f9e9 1612 if (m_lineSelectSingleOnUp != (unsigned int)-1)
e21f75bd
RR
1613 {
1614 // select single line
1615 SelectAllRows( false );
1616 SelectRow( m_lineSelectSingleOnUp, true );
1617 }
120b9b05 1618
0fcce6b9
RR
1619 if (m_lastOnSame)
1620 {
a8461d31 1621 if ((col == m_currentCol) && (current == m_currentRow) &&
0fcce6b9
RR
1622 (cell->GetMode() == wxDATAVIEW_CELL_EDITABLE) )
1623 {
1624 m_renameTimer->Start( 100, true );
1625 }
1626 }
1627
1628 m_lastOnSame = false;
0a71f9e9 1629 m_lineSelectSingleOnUp = (unsigned int)-1;
120b9b05 1630 }
e21f75bd
RR
1631 else
1632 {
1633 // This is necessary, because after a DnD operation in
1634 // from and to ourself, the up event is swallowed by the
1635 // DnD code. So on next non-up event (which means here and
1636 // now) m_lineSelectSingleOnUp should be reset.
0a71f9e9 1637 m_lineSelectSingleOnUp = (unsigned int)-1;
e21f75bd
RR
1638 }
1639
1640 if (event.RightDown())
1641 {
1642 m_lineBeforeLastClicked = m_lineLastClicked;
1643 m_lineLastClicked = current;
1644
1645 // If the item is already selected, do not update the selection.
1646 // Multi-selections should not be cleared if a selected item is clicked.
1647 if (!IsRowSelected(current))
1648 {
1649 SelectAllRows(false);
1650 ChangeCurrentRow(current);
1651 SelectRow(m_currentRow,true);
1652 }
1653
1654 // notify cell about right click
1655 // cell->...
120b9b05 1656
e21f75bd
RR
1657 // Allow generation of context menu event
1658 event.Skip();
1659 }
1660 else if (event.MiddleDown())
1661 {
1662 // notify cell about middle click
1663 // cell->...
1664 }
1665 if (event.LeftDown() || forceClick)
0fcce6b9 1666 {
72664514
RR
1667#ifdef __WXMSW__
1668 SetFocus();
1669#endif
120b9b05 1670
e21f75bd
RR
1671 m_lineBeforeLastClicked = m_lineLastClicked;
1672 m_lineLastClicked = current;
1673
0a71f9e9 1674 unsigned int oldCurrentRow = m_currentRow;
e21f75bd
RR
1675 bool oldWasSelected = IsRowSelected(m_currentRow);
1676
1677 bool cmdModifierDown = event.CmdDown();
1678 if ( IsSingleSel() || !(cmdModifierDown || event.ShiftDown()) )
1679 {
1680 if ( IsSingleSel() || !IsRowSelected(current) )
1681 {
1682 SelectAllRows( false );
1683
1684 ChangeCurrentRow(current);
1685
1686 SelectRow(m_currentRow,true);
1687 }
1688 else // multi sel & current is highlighted & no mod keys
1689 {
1690 m_lineSelectSingleOnUp = current;
1691 ChangeCurrentRow(current); // change focus
1692 }
1693 }
1694 else // multi sel & either ctrl or shift is down
1695 {
1696 if (cmdModifierDown)
1697 {
1698 ChangeCurrentRow(current);
1699
1700 ReverseRowSelection(m_currentRow);
1701 }
1702 else if (event.ShiftDown())
1703 {
1704 ChangeCurrentRow(current);
1705
0a71f9e9 1706 unsigned int lineFrom = oldCurrentRow,
e21f75bd
RR
1707 lineTo = current;
1708
1709 if ( lineTo < lineFrom )
1710 {
1711 lineTo = lineFrom;
1712 lineFrom = m_currentRow;
1713 }
1714
1715 SelectRows(lineFrom, lineTo, true);
1716 }
1717 else // !ctrl, !shift
1718 {
1719 // test in the enclosing if should make it impossible
1720 wxFAIL_MSG( _T("how did we get here?") );
1721 }
1722 }
1723
72664514
RR
1724 if (m_currentRow != oldCurrentRow)
1725 RefreshRow( oldCurrentRow );
e21f75bd 1726
0fcce6b9 1727 wxDataViewColumn *oldCurrentCol = m_currentCol;
120b9b05 1728
0fcce6b9
RR
1729 // Update selection here...
1730 m_currentCol = col;
120b9b05 1731
e21f75bd 1732 m_lastOnSame = !forceClick && ((col == oldCurrentCol) && (current == oldCurrentRow)) && oldWasSelected;
0fdc2321 1733 }
4ed7af08
RR
1734}
1735
1736void wxDataViewMainWindow::OnSetFocus( wxFocusEvent &event )
1737{
cab07038 1738 m_hasFocus = true;
120b9b05 1739
cab07038
RR
1740 if (HasCurrentRow())
1741 Refresh();
120b9b05 1742
cab07038
RR
1743 event.Skip();
1744}
1745
1746void wxDataViewMainWindow::OnKillFocus( wxFocusEvent &event )
1747{
1748 m_hasFocus = false;
120b9b05 1749
cab07038
RR
1750 if (HasCurrentRow())
1751 Refresh();
120b9b05 1752
4ed7af08
RR
1753 event.Skip();
1754}
1755
1756//-----------------------------------------------------------------------------
1757// wxDataViewCtrl
1758//-----------------------------------------------------------------------------
1759
1760IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl, wxDataViewCtrlBase)
1761
4b3feaa7
RR
1762BEGIN_EVENT_TABLE(wxDataViewCtrl, wxDataViewCtrlBase)
1763 EVT_SIZE(wxDataViewCtrl::OnSize)
1764END_EVENT_TABLE()
1765
4ed7af08
RR
1766wxDataViewCtrl::~wxDataViewCtrl()
1767{
1768 if (m_notifier)
1769 GetModel()->RemoveNotifier( m_notifier );
1770}
1771
1772void wxDataViewCtrl::Init()
1773{
1774 m_notifier = NULL;
1775}
1776
1777bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id,
f554a14b 1778 const wxPoint& pos, const wxSize& size,
4ed7af08
RR
1779 long style, const wxValidator& validator )
1780{
4b3feaa7
RR
1781 if (!wxControl::Create( parent, id, pos, size, style | wxScrolledWindowStyle|wxSUNKEN_BORDER, validator))
1782 return false;
1783
4ed7af08 1784 Init();
f554a14b 1785
4ed7af08
RR
1786#ifdef __WXMAC__
1787 MacSetClipChildren( true ) ;
1788#endif
1789
f554a14b 1790 m_clientArea = new wxDataViewMainWindow( this, wxID_ANY );
72664514
RR
1791#ifdef __WXMSW__
1792 m_headerArea = new wxDataViewHeaderWindow( this, wxID_ANY, wxDefaultPosition, wxSize(wxDefaultCoord,22) );
1793#else
f554a14b 1794 m_headerArea = new wxDataViewHeaderWindow( this, wxID_ANY, wxDefaultPosition, wxSize(wxDefaultCoord,25) );
120b9b05 1795#endif
f554a14b 1796
4ed7af08 1797 SetTargetWindow( m_clientArea );
f554a14b 1798
4ed7af08
RR
1799 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
1800 sizer->Add( m_headerArea, 0, wxGROW );
1801 sizer->Add( m_clientArea, 1, wxGROW );
1802 SetSizer( sizer );
1803
1804 return true;
1805}
1806
1807#ifdef __WXMSW__
1808WXLRESULT wxDataViewCtrl::MSWWindowProc(WXUINT nMsg,
1809 WXWPARAM wParam,
1810 WXLPARAM lParam)
1811{
b910a8ad 1812 WXLRESULT rc = wxDataViewCtrlBase::MSWWindowProc(nMsg, wParam, lParam);
4ed7af08
RR
1813
1814#ifndef __WXWINCE__
1815 // we need to process arrows ourselves for scrolling
1816 if ( nMsg == WM_GETDLGCODE )
1817 {
1818 rc |= DLGC_WANTARROWS;
1819 }
1820#endif
1821
1822 return rc;
1823}
1824#endif
1825
f554a14b 1826void wxDataViewCtrl::OnSize( wxSizeEvent &WXUNUSED(event) )
4ed7af08 1827{
4b3feaa7
RR
1828 // We need to override OnSize so that our scrolled
1829 // window a) does call Layout() to use sizers for
1830 // positioning the controls but b) does not query
1831 // the sizer for their size and use that for setting
1832 // the scrollable area as set that ourselves by
1833 // calling SetScrollbar() further down.
1834
1835 Layout();
1836
1837 AdjustScrollbars();
4ed7af08
RR
1838}
1839
1840bool wxDataViewCtrl::AssociateModel( wxDataViewListModel *model )
1841{
1842 if (!wxDataViewCtrlBase::AssociateModel( model ))
1843 return false;
1844
a0f3af5f 1845 m_notifier = new wxGenericDataViewListModelNotifier( m_clientArea );
4ed7af08 1846
f554a14b 1847 model->AddNotifier( m_notifier );
4ed7af08 1848
4b3feaa7 1849 m_clientArea->UpdateDisplay();
f554a14b 1850
4ed7af08
RR
1851 return true;
1852}
1853
1854bool wxDataViewCtrl::AppendColumn( wxDataViewColumn *col )
1855{
1856 if (!wxDataViewCtrlBase::AppendColumn(col))
1857 return false;
f554a14b 1858
4b3feaa7 1859 m_clientArea->UpdateDisplay();
f554a14b 1860
4ed7af08
RR
1861 return true;
1862}
1863
df387169 1864void wxDataViewCtrl::SetSelection( int WXUNUSED(row) )
6ff7eee7 1865{
df387169 1866 // FIXME - TODO
6ff7eee7
RR
1867}
1868
df387169 1869void wxDataViewCtrl::SetSelectionRange( unsigned int WXUNUSED(from), unsigned int WXUNUSED(to) )
6ff7eee7 1870{
df387169 1871 // FIXME - TODO
6ff7eee7
RR
1872}
1873
df387169 1874void wxDataViewCtrl::SetSelections( const wxArrayInt& WXUNUSED(aSelections) )
6ff7eee7 1875{
df387169 1876 // FIXME - TODO
6ff7eee7 1877}
df387169
WS
1878
1879void wxDataViewCtrl::Unselect( unsigned int WXUNUSED(row) )
fc211fe5 1880{
df387169 1881 // FIXME - TODO
fc211fe5
RR
1882}
1883
df387169 1884bool wxDataViewCtrl::IsSelected( unsigned int WXUNUSED(row) ) const
6ff7eee7 1885{
df387169
WS
1886 // FIXME - TODO
1887
6ff7eee7
RR
1888 return false;
1889}
1890
1891int wxDataViewCtrl::GetSelection() const
1892{
df387169
WS
1893 // FIXME - TODO
1894
6ff7eee7
RR
1895 return -1;
1896}
1897
df387169 1898int wxDataViewCtrl::GetSelections(wxArrayInt& WXUNUSED(aSelections) ) const
6ff7eee7 1899{
df387169
WS
1900 // FIXME - TODO
1901
6ff7eee7
RR
1902 return 0;
1903}
1904
f554a14b 1905#endif
4ed7af08
RR
1906 // !wxUSE_GENERICDATAVIEWCTRL
1907
f554a14b 1908#endif
4ed7af08 1909 // wxUSE_DATAVIEWCTRL