1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/datavcmn.cpp
3 // Purpose: wxDataViewCtrl base classes and common parts
4 // Author: Robert Roebling
7 // Copyright: (c) 2006, Robert Roebling
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
18 #if wxUSE_DATAVIEWCTRL
20 #include "wx/dataview.h"
26 const wxChar wxDataViewCtrlNameStr
[] = wxT("dataviewCtrl");
29 // ---------------------------------------------------------
30 // wxDataViewListModel
31 // ---------------------------------------------------------
33 wxDataViewModel::wxDataViewModel()
35 m_notifiers
.DeleteContents( true );
38 bool wxDataViewModel::ItemAdded( const wxDataViewItem
&parent
, const wxDataViewItem
&item
)
42 wxList::compatibility_iterator node
= m_notifiers
.GetFirst();
45 wxDataViewModelNotifier
* notifier
= (wxDataViewModelNotifier
*) node
->GetData();
46 if (!notifier
->ItemAdded( parent
, item
))
48 node
= node
->GetNext();
54 bool wxDataViewModel::ItemDeleted( const wxDataViewItem
&item
)
58 wxList::compatibility_iterator node
= m_notifiers
.GetFirst();
61 wxDataViewModelNotifier
* notifier
= (wxDataViewModelNotifier
*) node
->GetData();
62 if (!notifier
->ItemDeleted( item
))
64 node
= node
->GetNext();
70 bool wxDataViewModel::ItemChanged( const wxDataViewItem
&item
)
74 wxList::compatibility_iterator node
= m_notifiers
.GetFirst();
77 wxDataViewModelNotifier
* notifier
= (wxDataViewModelNotifier
*) node
->GetData();
78 if (!notifier
->ItemChanged( item
))
80 node
= node
->GetNext();
86 bool wxDataViewModel::ValueChanged( const wxDataViewItem
&item
, unsigned int col
)
90 wxList::compatibility_iterator node
= m_notifiers
.GetFirst();
93 wxDataViewModelNotifier
* notifier
= (wxDataViewModelNotifier
*) node
->GetData();
94 if (!notifier
->ValueChanged( item
, col
))
96 node
= node
->GetNext();
102 bool wxDataViewModel::Cleared()
106 wxList::compatibility_iterator node
= m_notifiers
.GetFirst();
109 wxDataViewModelNotifier
* notifier
= (wxDataViewModelNotifier
*) node
->GetData();
110 if (!notifier
->Cleared())
112 node
= node
->GetNext();
118 void wxDataViewModel::AddNotifier( wxDataViewModelNotifier
*notifier
)
120 m_notifiers
.Append( notifier
);
121 notifier
->SetOwner( this );
124 void wxDataViewModel::RemoveNotifier( wxDataViewModelNotifier
*notifier
)
126 m_notifiers
.DeleteObject( notifier
);
129 // ---------------------------------------------------------
130 // wxDataViewRendererBase
131 // ---------------------------------------------------------
133 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRendererBase
, wxObject
)
135 wxDataViewRendererBase::wxDataViewRendererBase( const wxString
&varianttype
,
136 wxDataViewCellMode
WXUNUSED(mode
),
137 int WXUNUSED(align
) )
139 m_variantType
= varianttype
;
143 const wxDataViewCtrl
* wxDataViewRendererBase::GetView() const
145 return wx_const_cast(wxDataViewRendererBase
*, this)->GetOwner()->GetOwner();
148 bool wxDataViewRendererBase::StartEditing( const wxDataViewItem
&item
, wxRect labelRect
)
150 m_item
= item
; // remember for later
152 unsigned int col
= GetOwner()->GetModelColumn();
154 GetOwner()->GetOwner()->GetModel()->GetValue( value
, item
, col
);
156 m_editorCtrl
= CreateEditorCtrl( GetOwner()->GetOwner()->GetMainWindow(), labelRect
, value
);
158 wxDataViewEditorCtrlEvtHandler
*handler
=
159 new wxDataViewEditorCtrlEvtHandler( m_editorCtrl
, (wxDataViewRenderer
*) this );
161 m_editorCtrl
->PushEventHandler( handler
);
163 #if defined(__WXGTK20__) && !defined(wxUSE_GENERICDATAVIEWCTRL)
164 handler
->SetFocusOnIdle();
166 m_editorCtrl
->SetFocus();
172 void wxDataViewRendererBase::CancelEditing()
174 wxPendingDelete
.Append( m_editorCtrl
);
176 GetOwner()->GetOwner()->GetMainWindow()->SetFocus();
178 // m_editorCtrl->PopEventHandler( true );
181 bool wxDataViewRendererBase::FinishEditing()
184 GetValueFromEditorCtrl( m_editorCtrl
, value
);
186 wxPendingDelete
.Append( m_editorCtrl
);
188 GetOwner()->GetOwner()->GetMainWindow()->SetFocus();
190 if (!Validate(value
))
193 unsigned int col
= GetOwner()->GetModelColumn();
194 GetOwner()->GetOwner()->GetModel()->SetValue( value
, m_item
, col
);
195 GetOwner()->GetOwner()->GetModel()->ValueChanged( m_item
, col
);
197 // m_editorCtrl->PopEventHandler( true );
202 //-----------------------------------------------------------------------------
203 // wxDataViewEditorCtrlEvtHandler
204 //-----------------------------------------------------------------------------
206 BEGIN_EVENT_TABLE(wxDataViewEditorCtrlEvtHandler
, wxEvtHandler
)
207 EVT_CHAR (wxDataViewEditorCtrlEvtHandler::OnChar
)
208 EVT_KILL_FOCUS (wxDataViewEditorCtrlEvtHandler::OnKillFocus
)
209 EVT_IDLE (wxDataViewEditorCtrlEvtHandler::OnIdle
)
212 wxDataViewEditorCtrlEvtHandler::wxDataViewEditorCtrlEvtHandler(
213 wxControl
*editorCtrl
,
214 wxDataViewRenderer
*owner
)
217 m_editorCtrl
= editorCtrl
;
222 void wxDataViewEditorCtrlEvtHandler::OnIdle( wxIdleEvent
&event
)
226 m_focusOnIdle
= false;
227 if (wxWindow::FindFocus() != m_editorCtrl
)
228 m_editorCtrl
->SetFocus();
234 void wxDataViewEditorCtrlEvtHandler::OnChar( wxKeyEvent
&event
)
236 switch ( event
.m_keyCode
)
240 m_owner
->FinishEditing();
245 m_owner
->CancelEditing();
253 void wxDataViewEditorCtrlEvtHandler::OnKillFocus( wxFocusEvent
&event
)
258 m_owner
->FinishEditing();
264 // ---------------------------------------------------------
265 // wxDataViewColumnBase
266 // ---------------------------------------------------------
268 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumnBase
, wxObject
)
270 wxDataViewColumnBase::wxDataViewColumnBase(const wxString
& WXUNUSED(title
),
271 wxDataViewRenderer
*renderer
,
272 unsigned int model_column
,
274 wxAlignment
WXUNUSED(align
),
277 m_renderer
= renderer
;
278 m_model_column
= model_column
;
280 m_renderer
->SetOwner( (wxDataViewColumn
*) this );
282 // NOTE: the wxDataViewColumn's ctor must store the width, align, flags
283 // parameters inside the native control!
286 wxDataViewColumnBase::wxDataViewColumnBase(const wxBitmap
& bitmap
,
287 wxDataViewRenderer
*renderer
,
288 unsigned int model_column
,
290 wxAlignment
WXUNUSED(align
),
291 int WXUNUSED(flags
) )
293 m_renderer
= renderer
;
294 m_model_column
= model_column
;
297 m_renderer
->SetOwner( (wxDataViewColumn
*) this );
300 wxDataViewColumnBase::~wxDataViewColumnBase()
306 int wxDataViewColumnBase::GetFlags() const
311 ret
|= wxDATAVIEW_COL_SORTABLE
;
313 ret
|= wxDATAVIEW_COL_RESIZABLE
;
315 ret
|= wxDATAVIEW_COL_HIDDEN
;
320 void wxDataViewColumnBase::SetFlags(int flags
)
322 SetSortable((flags
& wxDATAVIEW_COL_SORTABLE
) != 0);
323 SetResizeable((flags
& wxDATAVIEW_COL_RESIZABLE
) != 0);
324 SetHidden((flags
& wxDATAVIEW_COL_HIDDEN
) != 0);
327 // ---------------------------------------------------------
328 // wxDataViewEventModelNotifier
329 // ---------------------------------------------------------
331 class WXDLLIMPEXP_ADV wxDataViewEventModelNotifier
: public wxDataViewModelNotifier
334 wxDataViewEventModelNotifier( wxDataViewCtrl
*ctrl
) { m_ctrl
= ctrl
; }
336 bool SendEvent( wxEventType event_type
, const wxDataViewItem
&item
, unsigned int col
= 0 )
338 wxDataViewEvent
event( event_type
, m_ctrl
->GetId() );
339 event
.SetEventObject( m_ctrl
);
340 event
.SetModel( m_ctrl
->GetModel() );
341 event
.SetItem( item
);
342 event
.SetColumn( col
);
343 m_ctrl
->GetEventHandler()->ProcessEvent( event
);
347 virtual bool ItemAdded( const wxDataViewItem
&parent
, const wxDataViewItem
&item
)
348 { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_ADDED
, item
); }
349 virtual bool ItemDeleted( const wxDataViewItem
&item
)
350 { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_DELETED
, item
); }
351 virtual bool ItemChanged( const wxDataViewItem
&item
)
352 { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_CHANGED
, item
); }
353 virtual bool ValueChanged( const wxDataViewItem
&item
, unsigned int col
)
354 { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_VALUE_CHANGED
, item
, col
); }
355 virtual bool Cleared()
356 { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_CLEARED
, wxDataViewItem(0) ); }
359 wxDataViewCtrl
*m_ctrl
;
363 // ---------------------------------------------------------
364 // wxDataViewCtrlBase
365 // ---------------------------------------------------------
367 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCtrlBase
, wxControl
)
369 wxDataViewCtrlBase::wxDataViewCtrlBase()
372 m_cols
.DeleteContents( true );
373 m_eventNotifier
= NULL
;
376 wxDataViewCtrlBase::~wxDataViewCtrlBase()
378 // IMPORTANT: before calling DecRef() on our model (since it may
379 // result in a free() call), erase all columns (since
380 // they hold a pointer to our model)
386 m_model
->RemoveNotifier( m_eventNotifier
);
387 m_eventNotifier
= NULL
;
394 bool wxDataViewCtrlBase::AssociateModel( wxDataViewModel
*model
)
399 m_model
->RemoveNotifier( m_eventNotifier
);
400 m_eventNotifier
= NULL
;
402 m_model
->DecRef(); // discard old model, if any
405 // add our own reference to the new model:
410 m_eventNotifier
= new wxDataViewEventModelNotifier( (wxDataViewCtrl
*) this );
411 m_model
->AddNotifier( m_eventNotifier
);
417 wxDataViewModel
* wxDataViewCtrlBase::GetModel()
422 bool wxDataViewCtrlBase::AppendTextColumn( const wxString
&label
, unsigned int model_column
,
423 wxDataViewCellMode mode
, int width
, wxAlignment align
, int flags
)
425 return AppendColumn( new wxDataViewColumn( label
,
426 new wxDataViewTextRenderer( wxT("string"), mode
, (int)align
),
427 model_column
, width
, align
, flags
) );
430 bool wxDataViewCtrlBase::AppendToggleColumn( const wxString
&label
, unsigned int model_column
,
431 wxDataViewCellMode mode
, int width
, wxAlignment align
, int flags
)
433 return AppendColumn( new wxDataViewColumn( label
,
434 new wxDataViewToggleRenderer( wxT("bool"), mode
, (int)align
),
435 model_column
, width
, align
, flags
) );
438 bool wxDataViewCtrlBase::AppendProgressColumn( const wxString
&label
, unsigned int model_column
,
439 wxDataViewCellMode mode
, int width
, wxAlignment align
, int flags
)
441 return AppendColumn( new wxDataViewColumn( label
,
442 new wxDataViewProgressRenderer( wxEmptyString
, wxT("long"), mode
, (int)align
),
443 model_column
, width
, align
, flags
) );
446 bool wxDataViewCtrlBase::AppendDateColumn( const wxString
&label
, unsigned int model_column
,
447 wxDataViewCellMode mode
, int width
, wxAlignment align
, int flags
)
449 return AppendColumn( new wxDataViewColumn( label
,
450 new wxDataViewDateRenderer( wxT("datetime"), mode
, (int)align
),
451 model_column
, width
, align
, flags
) );
454 bool wxDataViewCtrlBase::AppendBitmapColumn( const wxString
&label
, unsigned int model_column
,
455 wxDataViewCellMode mode
, int width
, wxAlignment align
, int flags
)
457 return AppendColumn( new wxDataViewColumn( label
,
458 new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode
, (int)align
),
459 model_column
, width
, align
, flags
) );
462 bool wxDataViewCtrlBase::AppendTextColumn( const wxBitmap
&label
, unsigned int model_column
,
463 wxDataViewCellMode mode
, int width
, wxAlignment align
, int flags
)
465 return AppendColumn( new wxDataViewColumn( label
,
466 new wxDataViewTextRenderer( wxT("string"), mode
, (int)align
),
467 model_column
, width
, align
, flags
) );
470 bool wxDataViewCtrlBase::AppendToggleColumn( const wxBitmap
&label
, unsigned int model_column
,
471 wxDataViewCellMode mode
, int width
, wxAlignment align
, int flags
)
473 return AppendColumn( new wxDataViewColumn( label
,
474 new wxDataViewToggleRenderer( wxT("bool"), mode
, (int)align
),
475 model_column
, width
, align
, flags
) );
478 bool wxDataViewCtrlBase::AppendProgressColumn( const wxBitmap
&label
, unsigned int model_column
,
479 wxDataViewCellMode mode
, int width
, wxAlignment align
, int flags
)
481 return AppendColumn( new wxDataViewColumn( label
,
482 new wxDataViewProgressRenderer( wxEmptyString
, wxT("long"), mode
, (int)align
),
483 model_column
, width
, align
, flags
) );
486 bool wxDataViewCtrlBase::AppendDateColumn( const wxBitmap
&label
, unsigned int model_column
,
487 wxDataViewCellMode mode
, int width
, wxAlignment align
, int flags
)
489 return AppendColumn( new wxDataViewColumn( label
,
490 new wxDataViewDateRenderer( wxT("datetime"), mode
, (int)align
),
491 model_column
, width
, align
, flags
) );
494 bool wxDataViewCtrlBase::AppendBitmapColumn( const wxBitmap
&label
, unsigned int model_column
,
495 wxDataViewCellMode mode
, int width
, wxAlignment align
, int flags
)
497 return AppendColumn( new wxDataViewColumn( label
,
498 new wxDataViewBitmapRenderer( wxT("wxBitmap"), mode
, (int)align
),
499 model_column
, width
, align
, flags
) );
502 bool wxDataViewCtrlBase::AppendColumn( wxDataViewColumn
*col
)
504 m_cols
.Append( (wxObject
*) col
);
505 col
->SetOwner( (wxDataViewCtrl
*) this );
509 unsigned int wxDataViewCtrlBase::GetColumnCount() const
511 return m_cols
.GetCount();
514 bool wxDataViewCtrlBase::DeleteColumn( unsigned int WXUNUSED(pos
) )
519 bool wxDataViewCtrlBase::ClearColumns()
524 wxDataViewColumn
* wxDataViewCtrlBase::GetColumn( unsigned int pos
)
526 return (wxDataViewColumn
*) m_cols
[ pos
];
529 // ---------------------------------------------------------
531 // ---------------------------------------------------------
533 IMPLEMENT_DYNAMIC_CLASS(wxDataViewEvent
,wxNotifyEvent
)
535 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_SELECTED
)
536 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED
)
537 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK
)
538 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK
)
539 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED
)
541 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_ADDED
)
542 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_DELETED
)
543 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_CHANGED
)
544 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_VALUE_CHANGED
)
545 DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_CLEARED
)