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"
20 #if wxUSE_DATAVIEWCTRL
22 #include "wx/object.h"
23 #include "wx/dataview.h"
27 // ---------------------------------------------------------
29 // ---------------------------------------------------------
31 IMPLEMENT_ABSTRACT_CLASS(wxDataViewModel
, wxObject
)
33 // ---------------------------------------------------------
34 // wxDataViewListModel
35 // ---------------------------------------------------------
37 IMPLEMENT_ABSTRACT_CLASS(wxDataViewListModel
, wxDataViewModel
)
39 wxDataViewListModel::wxDataViewListModel()
41 m_viewingColumns
.DeleteContents( true );
42 m_notifiers
.DeleteContents( true );
45 wxDataViewListModel::~wxDataViewListModel()
49 bool wxDataViewListModel::RowAppended()
53 wxNode
*node
= m_notifiers
.GetFirst();
56 wxDataViewListModelNotifier
* notifier
= (wxDataViewListModelNotifier
*) node
->GetData();
57 if (!notifier
->RowAppended())
59 node
= node
->GetNext();
65 bool wxDataViewListModel::RowPrepended()
69 wxNode
*node
= m_notifiers
.GetFirst();
72 wxDataViewListModelNotifier
* notifier
= (wxDataViewListModelNotifier
*) node
->GetData();
73 if (!notifier
->RowPrepended())
75 node
= node
->GetNext();
81 bool wxDataViewListModel::RowInserted( size_t before
)
85 wxNode
*node
= m_notifiers
.GetFirst();
88 wxDataViewListModelNotifier
* notifier
= (wxDataViewListModelNotifier
*) node
->GetData();
89 if (!notifier
->RowInserted(before
))
91 node
= node
->GetNext();
97 bool wxDataViewListModel::RowDeleted( size_t row
)
101 wxNode
*node
= m_notifiers
.GetFirst();
104 wxDataViewListModelNotifier
* notifier
= (wxDataViewListModelNotifier
*) node
->GetData();
105 if (!notifier
->RowDeleted( row
))
107 node
= node
->GetNext();
113 bool wxDataViewListModel::RowChanged( size_t row
)
117 wxNode
*node
= m_notifiers
.GetFirst();
120 wxDataViewListModelNotifier
* notifier
= (wxDataViewListModelNotifier
*) node
->GetData();
121 if (!notifier
->RowChanged( row
))
123 node
= node
->GetNext();
129 bool wxDataViewListModel::ValueChanged( size_t col
, size_t row
)
133 wxNode
*node
= m_notifiers
.GetFirst();
136 wxDataViewListModelNotifier
* notifier
= (wxDataViewListModelNotifier
*) node
->GetData();
137 if (!notifier
->ValueChanged( col
, row
))
139 node
= node
->GetNext();
145 bool wxDataViewListModel::RowsReordered( size_t *new_order
)
149 wxNode
*node
= m_notifiers
.GetFirst();
152 wxDataViewListModelNotifier
* notifier
= (wxDataViewListModelNotifier
*) node
->GetData();
153 if (!notifier
->RowsReordered( new_order
))
155 node
= node
->GetNext();
161 bool wxDataViewListModel::Cleared()
165 wxNode
*node
= m_notifiers
.GetFirst();
168 wxDataViewListModelNotifier
* notifier
= (wxDataViewListModelNotifier
*) node
->GetData();
169 if (!notifier
->Cleared())
171 node
= node
->GetNext();
177 void wxDataViewListModel::AddViewingColumn( wxDataViewColumn
*view_column
, size_t model_column
)
179 m_viewingColumns
.Append( new wxDataViewViewingColumn( view_column
, model_column
) );
182 void wxDataViewListModel::RemoveViewingColumn( wxDataViewColumn
*column
)
184 wxNode
*node
= m_viewingColumns
.GetFirst();
187 wxDataViewViewingColumn
* tmp
= (wxDataViewViewingColumn
*) node
->GetData();
189 if (tmp
->m_viewColumn
== column
)
191 m_viewingColumns
.DeleteObject( tmp
);
195 node
= node
->GetNext();
199 void wxDataViewListModel::AddNotifier( wxDataViewListModelNotifier
*notifier
)
201 m_notifiers
.Append( notifier
);
202 notifier
->SetOwner( this );
205 void wxDataViewListModel::RemoveNotifier( wxDataViewListModelNotifier
*notifier
)
207 m_notifiers
.DeleteObject( notifier
);
210 // ---------------------------------------------------------
211 // wxDataViewSortedListModelNotifier
212 // ---------------------------------------------------------
214 class wxDataViewSortedListModelNotifier
: public wxDataViewListModelNotifier
217 wxDataViewSortedListModelNotifier( wxDataViewSortedListModel
*model
)
220 virtual bool RowAppended() { return true; }
221 virtual bool RowPrepended() { return true; }
222 virtual bool RowInserted( size_t before
) { return true; }
223 virtual bool RowDeleted( size_t row
) { return true; }
224 virtual bool RowChanged( size_t row
) { return true; }
225 virtual bool ValueChanged( size_t col
, size_t row
)
226 { return m_model
->ChildValueChanged( col
, row
); }
227 virtual bool RowsReordered( size_t *new_order
) { return true; }
228 virtual bool Cleared() { return true; }
230 wxDataViewSortedListModel
*m_model
;
233 // ---------------------------------------------------------
234 // wxDataViewSortedListModel compare function
235 // ---------------------------------------------------------
237 int wxCALLBACK wxDataViewListModelSortedDefaultCompare
238 (size_t row1
, size_t row2
, size_t col
, wxDataViewListModel
* model
)
240 wxVariant value1
,value2
;
241 model
->GetValue( value1
, col
, row1
);
242 model
->GetValue( value2
, col
, row2
);
243 if (value1
.GetType() == wxT("string"))
245 wxString str1
= value1
.GetString();
246 wxString str2
= value2
.GetString();
247 return str1
.Cmp( str2
);
249 if (value1
.GetType() == wxT("long"))
251 long l1
= value1
.GetLong();
252 long l2
= value2
.GetLong();
255 if (value1
.GetType() == wxT("double"))
257 double d1
= value1
.GetDouble();
258 double d2
= value2
.GetDouble();
259 if (d1
== d2
) return 0;
260 if (d1
< d2
) return 1;
263 if (value1
.GetType() == wxT("datetime"))
265 wxDateTime dt1
= value1
.GetDateTime();
266 wxDateTime dt2
= value2
.GetDateTime();
267 if (dt1
.IsEqualTo(dt2
)) return 0;
268 if (dt1
.IsEarlierThan(dt2
)) return 1;
275 static wxDataViewListModelCompare s_CmpFunc
;
276 static wxDataViewListModel
*s_CmpModel
;
277 static size_t s_CmpCol
;
279 int LINKAGEMODE
wxDataViewIntermediateCmp( size_t row1
, size_t row2
)
281 return s_CmpFunc( row1
, row2
, s_CmpCol
, s_CmpModel
);
284 // ---------------------------------------------------------
285 // wxDataViewSortedListModel
286 // ---------------------------------------------------------
288 IMPLEMENT_ABSTRACT_CLASS(wxDataViewSortedListModel
, wxDataViewListModel
)
290 wxDataViewSortedListModel::wxDataViewSortedListModel( wxDataViewListModel
*child
) :
291 m_array( wxDataViewIntermediateCmp
)
296 s_CmpFunc
= wxDataViewListModelSortedDefaultCompare
;
298 m_notifierOnChild
= new wxDataViewSortedListModelNotifier( this );
299 m_child
->AddNotifier( m_notifierOnChild
);
304 wxDataViewSortedListModel::~wxDataViewSortedListModel()
306 m_child
->RemoveNotifier( m_notifierOnChild
);
309 void wxDataViewSortedListModel::Resort()
312 size_t n
= m_child
->GetNumberOfRows();
314 for (i
= 0; i
< n
; i
++)
319 static void Dump( wxDataViewListModel
*model
, size_t col
)
321 size_t n
= model
->GetNumberOfRows();
323 for (i
= 0; i
< n
; i
++)
326 model
->GetValue( variant
, col
, i
);
328 tmp
= variant
.GetString();
329 wxPrintf( wxT("%d: %s\n"), (int) i
, tmp
.c_str() );
334 bool wxDataViewSortedListModel::ChildValueChanged( size_t col
, size_t row
)
337 size_t len
= m_array
.GetCount();
339 // Remove and readd sorted. Find out at which
340 // position it was and where it ended.
341 size_t start_pos
= 0,end_pos
= 0;
342 for (i
= 0; i
< len
; i
++)
343 if (m_array
[i
] == row
)
348 m_array
.RemoveAt( start_pos
);
351 for (i
= 0; i
< len
; i
++)
352 if (m_array
[i
] == row
)
358 if (end_pos
== start_pos
)
359 return wxDataViewListModel::ValueChanged( col
, start_pos
);
361 // Create an array where order[old] -> new_pos, so that
362 // if nothing changed order[0] -> 0 etc.
363 size_t *order
= new size_t[ len
];
364 // Fill up initial values.
365 for (i
= 0; i
< len
; i
++)
368 if (start_pos
< end_pos
)
370 for (i
= start_pos
; i
< end_pos
; i
++)
371 order
[i
] = order
[i
+1];
372 order
[end_pos
] = start_pos
;
376 for (i
= end_pos
; i
> start_pos
; i
--)
377 order
[i
] = order
[i
-1];
378 order
[start_pos
] = end_pos
;
381 wxDataViewListModel::RowsReordered( order
);
388 size_t wxDataViewSortedListModel::GetNumberOfRows()
390 return m_array
.GetCount();
393 size_t wxDataViewSortedListModel::GetNumberOfCols()
395 return m_child
->GetNumberOfCols();
398 wxString
wxDataViewSortedListModel::GetColType( size_t col
)
400 return m_child
->GetColType( col
);
403 void wxDataViewSortedListModel::GetValue( wxVariant
&variant
, size_t col
, size_t row
)
405 size_t child_row
= m_array
[row
];
406 m_child
->GetValue( variant
, col
, child_row
);
409 bool wxDataViewSortedListModel::SetValue( wxVariant
&variant
, size_t col
, size_t row
)
411 size_t child_row
= m_array
[row
];
412 bool ret
= m_child
->SetValue( variant
, col
, child_row
);
414 // Resort in ::ChildValueChanged() which gets reported back.
419 bool wxDataViewSortedListModel::RowAppended()
421 // you can only append
422 bool ret
= m_child
->RowAppended();
429 bool wxDataViewSortedListModel::RowPrepended()
431 // you can only append
432 bool ret
= m_child
->RowAppended();
439 bool wxDataViewSortedListModel::RowInserted( size_t before
)
441 // you can only append
442 bool ret
= m_child
->RowAppended();
444 // report different RowInsrted
449 bool wxDataViewSortedListModel::RowDeleted( size_t row
)
451 size_t child_row
= m_array
[row
];
453 bool ret
= m_child
->RowDeleted( child_row
);
455 // Do nothing here as the change in the
456 // child model will be reported back.
461 bool wxDataViewSortedListModel::RowChanged( size_t row
)
463 size_t child_row
= m_array
[row
];
464 bool ret
= m_child
->RowChanged( child_row
);
466 // Do nothing here as the change in the
467 // child model will be reported back.
472 bool wxDataViewSortedListModel::ValueChanged( size_t col
, size_t row
)
474 size_t child_row
= m_array
[row
];
475 bool ret
= m_child
->ValueChanged( col
, child_row
);
477 // Do nothing here as the change in the
478 // child model will be reported back.
483 bool wxDataViewSortedListModel::RowsReordered( size_t *new_order
)
485 // We sort them ourselves.
490 bool wxDataViewSortedListModel::Cleared()
492 bool ret
= m_child
->Cleared();
494 wxDataViewListModel::Cleared();
499 // ---------------------------------------------------------
500 // wxDataViewCellBase
501 // ---------------------------------------------------------
503 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCellBase
, wxObject
)
505 wxDataViewCellBase::wxDataViewCellBase( const wxString
&varianttype
, wxDataViewCellMode mode
)
507 m_variantType
= varianttype
;
511 // ---------------------------------------------------------
512 // wxDataViewColumnBase
513 // ---------------------------------------------------------
515 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumnBase
, wxObject
)
517 wxDataViewColumnBase::wxDataViewColumnBase( const wxString
&title
, wxDataViewCell
*cell
, size_t model_column
, int flags
)
520 m_model_column
= model_column
;
524 m_cell
->SetOwner( (wxDataViewColumn
*) this );
527 wxDataViewColumnBase::~wxDataViewColumnBase()
534 GetOwner()->GetModel()->RemoveViewingColumn( (wxDataViewColumn
*) this );
538 void wxDataViewColumnBase::SetTitle( const wxString
&title
)
543 wxString
wxDataViewColumnBase::GetTitle()
548 // ---------------------------------------------------------
549 // wxDataViewCtrlBase
550 // ---------------------------------------------------------
552 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCtrlBase
, wxControl
)
554 wxDataViewCtrlBase::wxDataViewCtrlBase()
557 m_cols
.DeleteContents( true );
560 wxDataViewCtrlBase::~wxDataViewCtrlBase()
564 bool wxDataViewCtrlBase::AssociateModel( wxDataViewListModel
*model
)
571 wxDataViewListModel
* wxDataViewCtrlBase::GetModel()
576 bool wxDataViewCtrlBase::AppendTextColumn( const wxString
&label
, size_t model_column
)
578 return AppendColumn( new wxDataViewColumn( label
, new wxDataViewTextCell(), model_column
) );
581 bool wxDataViewCtrlBase::AppendToggleColumn( const wxString
&label
, size_t model_column
)
583 return AppendColumn( new wxDataViewColumn( label
, new wxDataViewToggleCell(), model_column
) );
586 bool wxDataViewCtrlBase::AppendProgressColumn( const wxString
&label
, size_t model_column
)
588 return AppendColumn( new wxDataViewColumn( label
, new wxDataViewProgressCell(), model_column
) );
591 bool wxDataViewCtrlBase::AppendDateColumn( const wxString
&label
, size_t model_column
)
593 return AppendColumn( new wxDataViewColumn( label
, new wxDataViewDateCell(), model_column
) );
596 bool wxDataViewCtrlBase::AppendColumn( wxDataViewColumn
*col
)
598 m_cols
.Append( (wxObject
*) col
);
599 col
->SetOwner( (wxDataViewCtrl
*) this );
600 m_model
->AddViewingColumn( col
, col
->GetModelColumn() );
604 size_t wxDataViewCtrlBase::GetNumberOfColumns()
606 return m_cols
.GetCount();
609 bool wxDataViewCtrlBase::DeleteColumn( size_t pos
)
614 bool wxDataViewCtrlBase::ClearColumns()
619 wxDataViewColumn
* wxDataViewCtrlBase::GetColumn( size_t pos
)
621 return (wxDataViewColumn
*) m_cols
[ pos
];