]> git.saurik.com Git - wxWidgets.git/blame - src/generic/datavgen.cpp
Fixed a crash when deleting the last timer
[wxWidgets.git] / src / generic / datavgen.cpp
CommitLineData
4ed7af08
RR
1/////////////////////////////////////////////////////////////////////////////
2// Name: datavgen.cpp
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
13#include "wx/defs.h"
14
15#if wxUSE_DATAVIEWCTRL
16
17#include "wx/dataview.h"
18
19#ifdef wxUSE_GENERICDATAVIEWCTRL
20
21#include "wx/stockitem.h"
22#include "wx/dcclient.h"
23#include "wx/calctrl.h"
24#include "wx/popupwin.h"
25#include "wx/sizer.h"
26#include "wx/log.h"
27#include "wx/renderer.h"
28
29#ifdef __WXMSW__
30 #include <windows.h> // for DLGC_WANTARROWS
31 #include "wx/msw/winundef.h"
32#endif
33
34//-----------------------------------------------------------------------------
35// classes
36//-----------------------------------------------------------------------------
37
38class wxDataViewCtrl;
39
40// ---------------------------------------------------------
41// wxGenericDataViewListModelNotifier
42// ---------------------------------------------------------
43
44class wxGenericDataViewListModelNotifier: public wxDataViewListModelNotifier
45{
46public:
47 wxGenericDataViewListModelNotifier( wxDataViewListModel *wx_model );
48
49 virtual bool RowAppended();
50 virtual bool RowPrepended();
51 virtual bool RowInserted( size_t before );
52 virtual bool RowDeleted( size_t row );
53 virtual bool RowChanged( size_t row );
54 virtual bool ValueChanged( size_t col, size_t row );
55 virtual bool RowsReordered( size_t *new_order );
56 virtual bool Cleared();
57
58 wxDataViewListModel *m_wx_model;
59};
60
61// ---------------------------------------------------------
62// wxGenericDataViewListModelNotifier
63// ---------------------------------------------------------
64
65wxGenericDataViewListModelNotifier::wxGenericDataViewListModelNotifier(
66 wxDataViewListModel *wx_model )
67{
68 m_wx_model = wx_model;
69}
70
71bool wxGenericDataViewListModelNotifier::RowAppended()
72{
73 size_t pos = m_wx_model->GetNumberOfRows()-1;
74
75 return false;
76}
77
78bool wxGenericDataViewListModelNotifier::RowPrepended()
79{
80 return false;
81}
82
83bool wxGenericDataViewListModelNotifier::RowInserted( size_t before )
84{
85 return false;
86}
87
88bool wxGenericDataViewListModelNotifier::RowDeleted( size_t row )
89{
90 return false;
91}
92
93bool wxGenericDataViewListModelNotifier::RowChanged( size_t row )
94{
95 return true;
96}
97
98bool wxGenericDataViewListModelNotifier::ValueChanged( size_t model_col, size_t model_row )
99{
100 wxNode *node = GetOwner()->m_viewingColumns.GetFirst();
101 while (node)
102 {
103 wxDataViewViewingColumn* viewing_column = (wxDataViewViewingColumn*) node->GetData();
104 if (viewing_column->m_modelColumn == model_col)
105 {
106
107 }
108
109 node = node->GetNext();
110 }
111
112 return false;
113}
114
115bool wxGenericDataViewListModelNotifier::RowsReordered( size_t *new_order )
116{
117 wxNode *node = GetOwner()->m_viewingColumns.GetFirst();
118 while (node)
119 {
120 wxDataViewViewingColumn* viewing_column = (wxDataViewViewingColumn*) node->GetData();
121
122 node = node->GetNext();
123 }
124
125 return false;
126}
127
128bool wxGenericDataViewListModelNotifier::Cleared()
129{
130 return false;
131}
132
133// ---------------------------------------------------------
134// wxDataViewCell
135// ---------------------------------------------------------
136
137IMPLEMENT_ABSTRACT_CLASS(wxDataViewCell, wxDataViewCellBase)
138
139wxDataViewCell::wxDataViewCell( const wxString &varianttype, wxDataViewCellMode mode ) :
140 wxDataViewCellBase( varianttype, mode )
141{
142}
143
144// ---------------------------------------------------------
145// wxDataViewTextCell
146// ---------------------------------------------------------
147
148IMPLEMENT_ABSTRACT_CLASS(wxDataViewTextCell, wxDataViewCell)
149
150wxDataViewTextCell::wxDataViewTextCell( const wxString &varianttype, wxDataViewCellMode mode ) :
151 wxDataViewCell( varianttype, mode )
152{
153}
154
155bool wxDataViewTextCell::SetValue( const wxVariant &value )
156{
157 return false;
158}
159
160bool wxDataViewTextCell::GetValue( wxVariant &value )
161{
162 return false;
163}
164
165// ---------------------------------------------------------
166// wxDataViewToggleCell
167// ---------------------------------------------------------
168
169IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleCell, wxDataViewCell)
170
171wxDataViewToggleCell::wxDataViewToggleCell( const wxString &varianttype,
172 wxDataViewCellMode mode ) :
173 wxDataViewCell( varianttype, mode )
174{
175}
176
177bool wxDataViewToggleCell::SetValue( const wxVariant &value )
178{
179 return false;
180}
181
182bool wxDataViewToggleCell::GetValue( wxVariant &value )
183{
184 return false;
185}
186
187// ---------------------------------------------------------
188// wxDataViewCustomCell
189// ---------------------------------------------------------
190
191IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomCell, wxDataViewCell)
192
193wxDataViewCustomCell::wxDataViewCustomCell( const wxString &varianttype,
194 wxDataViewCellMode mode ) :
195 wxDataViewCell( varianttype, mode )
196{
197 m_dc = NULL;
198
199 Init();
200}
201
202bool wxDataViewCustomCell::Init()
203{
204 return false;
205}
206
207wxDataViewCustomCell::~wxDataViewCustomCell()
208{
209 if (m_dc)
210 delete m_dc;
211}
212
213wxDC *wxDataViewCustomCell::GetDC()
214{
215 if (m_dc == NULL)
216 {
217 if (GetOwner() == NULL)
218 return NULL;
219 if (GetOwner()->GetOwner() == NULL)
220 return NULL;
221 m_dc = new wxClientDC( GetOwner()->GetOwner() );
222 }
223
224 return m_dc;
225}
226
227// ---------------------------------------------------------
228// wxDataViewProgressCell
229// ---------------------------------------------------------
230
231IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressCell, wxDataViewCustomCell)
232
233wxDataViewProgressCell::wxDataViewProgressCell( const wxString &label,
234 const wxString &varianttype, wxDataViewCellMode mode ) :
235 wxDataViewCustomCell( varianttype, mode )
236{
237 m_label = label;
238 m_value = 0;
239}
240
241wxDataViewProgressCell::~wxDataViewProgressCell()
242{
243}
244
245bool wxDataViewProgressCell::SetValue( const wxVariant &value )
246{
247 m_value = (long) value;
248
249 if (m_value < 0) m_value = 0;
250 if (m_value > 100) m_value = 100;
251
252 return true;
253}
254
255bool wxDataViewProgressCell::Render( wxRect cell, wxDC *dc, int state )
256{
257 double pct = (double)m_value / 100.0;
258 wxRect bar = cell;
259 bar.width = (int)(cell.width * pct);
260 dc->SetPen( *wxTRANSPARENT_PEN );
261 dc->SetBrush( *wxBLUE_BRUSH );
262 dc->DrawRectangle( bar );
263
264 dc->SetBrush( *wxTRANSPARENT_BRUSH );
265 dc->SetPen( *wxBLACK_PEN );
266 dc->DrawRectangle( cell );
267
268 return true;
269}
270
271wxSize wxDataViewProgressCell::GetSize()
272{
273 return wxSize(40,12);
274}
275
276// ---------------------------------------------------------
277// wxDataViewDateCell
278// ---------------------------------------------------------
279
280class wxDataViewDateCellPopupTransient: public wxPopupTransientWindow
281{
282public:
283 wxDataViewDateCellPopupTransient( wxWindow* parent, wxDateTime *value,
284 wxDataViewListModel *model, size_t col, size_t row ) :
285 wxPopupTransientWindow( parent, wxBORDER_SIMPLE )
286 {
287 m_model = model;
288 m_col = col;
289 m_row = row;
290 m_cal = new wxCalendarCtrl( this, -1, *value );
291 wxBoxSizer *sizer = new wxBoxSizer( wxHORIZONTAL );
292 sizer->Add( m_cal, 1, wxGROW );
293 SetSizer( sizer );
294 sizer->Fit( this );
295 }
296
297 virtual void OnDismiss()
298 {
299 }
300
301 void OnCalendar( wxCalendarEvent &event );
302
303 wxCalendarCtrl *m_cal;
304 wxDataViewListModel *m_model;
305 size_t m_col;
306 size_t m_row;
307
308private:
309 DECLARE_EVENT_TABLE()
310};
311
312BEGIN_EVENT_TABLE(wxDataViewDateCellPopupTransient,wxPopupTransientWindow)
313 EVT_CALENDAR( -1, wxDataViewDateCellPopupTransient::OnCalendar )
314END_EVENT_TABLE()
315
316void wxDataViewDateCellPopupTransient::OnCalendar( wxCalendarEvent &event )
317{
318 wxDateTime date = event.GetDate();
319 wxVariant value = date;
320 m_model->SetValue( value, m_col, m_row );
321 m_model->ValueChanged( m_col, m_row );
322 DismissAndNotify();
323}
324
325IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateCell, wxDataViewCustomCell)
326
327wxDataViewDateCell::wxDataViewDateCell( const wxString &varianttype,
328 wxDataViewCellMode mode ) :
329 wxDataViewCustomCell( varianttype, mode )
330{
331}
332
333bool wxDataViewDateCell::SetValue( const wxVariant &value )
334{
335 m_date = value.GetDateTime();
336
337 return true;
338}
339
340bool wxDataViewDateCell::Render( wxRect cell, wxDC *dc, int state )
341{
342 dc->SetFont( GetOwner()->GetOwner()->GetFont() );
343 wxString tmp = m_date.FormatDate();
344 dc->DrawText( tmp, cell.x, cell.y );
345
346 return true;
347}
348
349wxSize wxDataViewDateCell::GetSize()
350{
351 wxDataViewCtrl* view = GetOwner()->GetOwner();
352 wxString tmp = m_date.FormatDate();
353 wxCoord x,y,d;
354 view->GetTextExtent( tmp, &x, &y, &d );
355 return wxSize(x,y+d);
356}
357
358bool wxDataViewDateCell::Activate( wxRect cell, wxDataViewListModel *model, size_t col, size_t row )
359{
360 wxVariant variant;
361 model->GetValue( variant, col, row );
362 wxDateTime value = variant.GetDateTime();
363
364 wxDataViewDateCellPopupTransient *popup = new wxDataViewDateCellPopupTransient(
365 GetOwner()->GetOwner()->GetParent(), &value, model, col, row );
366 wxPoint pos = wxGetMousePosition();
367 popup->Move( pos );
368 popup->Layout();
369 popup->Popup( popup->m_cal );
370
371 return true;
372}
373
374// ---------------------------------------------------------
375// wxDataViewColumn
376// ---------------------------------------------------------
377
378IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumn, wxDataViewColumnBase)
379
380wxDataViewColumn::wxDataViewColumn( const wxString &title, wxDataViewCell *cell,
381 size_t model_column, int flags ) :
382 wxDataViewColumnBase( title, cell, model_column, flags )
383{
384}
385
386wxDataViewColumn::~wxDataViewColumn()
387{
388}
389
390void wxDataViewColumn::SetTitle( const wxString &title )
391{
392 wxDataViewColumnBase::SetTitle( title );
393
394}
395
396//-----------------------------------------------------------------------------
397// wxDataViewHeaderWindow
398//-----------------------------------------------------------------------------
399
400class wxDataViewHeaderWindow: public wxWindow
401{
402public:
403 wxDataViewHeaderWindow( wxDataViewCtrl *parent,
404 wxWindowID id,
405 const wxPoint &pos = wxDefaultPosition,
406 const wxSize &size = wxDefaultSize,
407 const wxString &name = wxT("wxdataviewctrlheaderwindow") );
408 ~wxDataViewHeaderWindow();
409
410 void SetOwner( wxDataViewCtrl* owner ) { m_owner = owner; }
411 wxDataViewCtrl *GetOwner() { return m_owner; }
412
413 void OnPaint( wxPaintEvent &event );
414 void OnMouse( wxMouseEvent &event );
415 void OnSetFocus( wxFocusEvent &event );
416
417private:
418 wxDataViewCtrl *m_owner;
419 wxCursor *m_resizeCursor;
420
421private:
422 DECLARE_DYNAMIC_CLASS(wxDataViewHeaderWindow)
423 DECLARE_EVENT_TABLE()
45778c96 424};
4ed7af08 425
45778c96 426IMPLEMENT_ABSTRACT_CLASS(wxDataViewHeaderWindow, wxWindow)
4ed7af08
RR
427
428BEGIN_EVENT_TABLE(wxDataViewHeaderWindow,wxWindow)
429 EVT_PAINT (wxDataViewHeaderWindow::OnPaint)
430 EVT_MOUSE_EVENTS (wxDataViewHeaderWindow::OnMouse)
431 EVT_SET_FOCUS (wxDataViewHeaderWindow::OnSetFocus)
432END_EVENT_TABLE()
433
434wxDataViewHeaderWindow::wxDataViewHeaderWindow( wxDataViewCtrl *parent, wxWindowID id,
435 const wxPoint &pos, const wxSize &size, const wxString &name ) :
436 wxWindow( parent, id, pos, size, 0, name )
437{
438 SetOwner( parent );
439
440 m_resizeCursor = new wxCursor( wxCURSOR_SIZEWE );
441
442 wxVisualAttributes attr = wxPanel::GetClassDefaultAttributes();
443 SetOwnForegroundColour( attr.colFg );
444 SetOwnBackgroundColour( attr.colBg );
445 if (!m_hasFont)
446 SetOwnFont( attr.font );
447}
448
449wxDataViewHeaderWindow::~wxDataViewHeaderWindow()
450{
451 delete m_resizeCursor;
452}
453
454void wxDataViewHeaderWindow::OnPaint( wxPaintEvent &event )
455{
456 wxPaintDC dc;
457 PrepareDC( dc );
458
459 int xpix;
460 m_owner->GetScrollPixelsPerUnit( &xpix, NULL );
461
462 int x;
463 m_owner->GetViewStart( &x, NULL );
464
465 // account for the horz scrollbar offset
466 dc.SetDeviceOrigin( -x * xpix, 0 );
467
468 dc.SetFont( GetFont() );
469
45778c96 470 dc.DrawText( wxT("This is the header.."), 5, 5 );
4ed7af08
RR
471}
472
473void wxDataViewHeaderWindow::OnMouse( wxMouseEvent &event )
474{
475}
476
477void wxDataViewHeaderWindow::OnSetFocus( wxFocusEvent &event )
478{
479 event.Skip();
480}
481
482//-----------------------------------------------------------------------------
483// wxDataViewMainWindow
484//-----------------------------------------------------------------------------
485
486class wxDataViewMainWindow: public wxWindow
487{
488public:
489 wxDataViewMainWindow( wxDataViewCtrl *parent,
490 wxWindowID id,
491 const wxPoint &pos = wxDefaultPosition,
492 const wxSize &size = wxDefaultSize,
493 const wxString &name = wxT("wxdataviewctrlmainwindow") );
494 ~wxDataViewMainWindow();
495
496 void SetOwner( wxDataViewCtrl* owner ) { m_owner = owner; }
497 wxDataViewCtrl *GetOwner() { return m_owner; }
498
499 void OnPaint( wxPaintEvent &event );
500 void OnMouse( wxMouseEvent &event );
501 void OnSetFocus( wxFocusEvent &event );
502
503private:
504 wxDataViewCtrl *m_owner;
505
506private:
507 DECLARE_DYNAMIC_CLASS(wxDataViewMainWindow)
508 DECLARE_EVENT_TABLE()
45778c96 509};
4ed7af08 510
45778c96 511IMPLEMENT_ABSTRACT_CLASS(wxDataViewMainWindow, wxWindow)
4ed7af08
RR
512
513BEGIN_EVENT_TABLE(wxDataViewMainWindow,wxWindow)
514 EVT_PAINT (wxDataViewMainWindow::OnPaint)
515 EVT_MOUSE_EVENTS (wxDataViewMainWindow::OnMouse)
516 EVT_SET_FOCUS (wxDataViewMainWindow::OnSetFocus)
517END_EVENT_TABLE()
518
519wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl *parent, wxWindowID id,
520 const wxPoint &pos, const wxSize &size, const wxString &name ) :
521 wxWindow( parent, id, pos, size, 0, name )
522{
523 SetOwner( parent );
524}
525
526wxDataViewMainWindow::~wxDataViewMainWindow()
527{
528}
529
530void wxDataViewMainWindow::OnPaint( wxPaintEvent &event )
531{
532 wxPaintDC dc( this );
533
534 PrepareDC( dc );
535
536 int dev_x, dev_y;
45778c96 537 m_owner->CalcScrolledPosition( 0, 0, &dev_x, &dev_y );
4ed7af08
RR
538
539 dc.SetFont( GetFont() );
540
541 dc.DrawText( wxT("main window"), 5, 5 );
542}
543
544void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
545{
546 event.Skip();
547}
548
549void wxDataViewMainWindow::OnSetFocus( wxFocusEvent &event )
550{
551 event.Skip();
552}
553
554//-----------------------------------------------------------------------------
555// wxDataViewCtrl
556//-----------------------------------------------------------------------------
557
558IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl, wxDataViewCtrlBase)
559
560wxDataViewCtrl::~wxDataViewCtrl()
561{
562 if (m_notifier)
563 GetModel()->RemoveNotifier( m_notifier );
564}
565
566void wxDataViewCtrl::Init()
567{
568 m_notifier = NULL;
569}
570
571bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id,
572 const wxPoint& pos, const wxSize& size,
573 long style, const wxValidator& validator )
574{
575 Init();
576
577#ifdef __WXMAC__
578 MacSetClipChildren( true ) ;
579#endif
580
581 m_clientArea = new wxDataViewMainWindow( this, -1 );
582 m_headerArea = new wxDataViewHeaderWindow( this, -1, wxDefaultPosition, wxSize(-1,25) );
583
584 SetTargetWindow( m_clientArea );
585
586 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
587 sizer->Add( m_headerArea, 0, wxGROW );
588 sizer->Add( m_clientArea, 1, wxGROW );
589 SetSizer( sizer );
590
591 return true;
592}
593
594#ifdef __WXMSW__
595WXLRESULT wxDataViewCtrl::MSWWindowProc(WXUINT nMsg,
596 WXWPARAM wParam,
597 WXLPARAM lParam)
598{
599 WXLRESULT rc = wxPanel::MSWWindowProc(nMsg, wParam, lParam);
600
601#ifndef __WXWINCE__
602 // we need to process arrows ourselves for scrolling
603 if ( nMsg == WM_GETDLGCODE )
604 {
605 rc |= DLGC_WANTARROWS;
606 }
607#endif
608
609 return rc;
610}
611#endif
612
613void wxDataViewCtrl::ScrollWindow( int dx, int dy, const wxRect *rect )
614{
615 wxDataViewCtrlBase::ScrollWindow( dx, dy, rect );
616 m_headerArea->ScrollWindow( dx, 0, rect );
617}
618
619bool wxDataViewCtrl::AssociateModel( wxDataViewListModel *model )
620{
621 if (!wxDataViewCtrlBase::AssociateModel( model ))
622 return false;
623
624 m_notifier = new wxGenericDataViewListModelNotifier( model );
625
626 model->AddNotifier( m_notifier );
627
628 return true;
629}
630
631bool wxDataViewCtrl::AppendColumn( wxDataViewColumn *col )
632{
633 if (!wxDataViewCtrlBase::AppendColumn(col))
634 return false;
635
636 return true;
637}
638
639#endif
640 // !wxUSE_GENERICDATAVIEWCTRL
641
642#endif
643 // wxUSE_DATAVIEWCTRL
644