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
= model
->GetValue( col
, row1
);
241 wxVariant value2
= model
->GetValue( col
, row2
);
242 if (value1
.GetType() == wxT("string"))
244 wxString str1
= value1
.GetString();
245 wxString str2
= value2
.GetString();
246 return str1
.Cmp( str2
);
248 if (value1
.GetType() == wxT("long"))
250 long l1
= value1
.GetLong();
251 long l2
= value2
.GetLong();
254 if (value1
.GetType() == wxT("double"))
256 double d1
= value1
.GetDouble();
257 double d2
= value2
.GetDouble();
258 if (d1
== d2
) return 0;
259 if (d1
< d2
) return 1;
262 if (value1
.GetType() == wxT("datetime"))
264 wxDateTime dt1
= value1
.GetDateTime();
265 wxDateTime dt2
= value2
.GetDateTime();
266 if (dt1
.IsEqualTo(dt2
)) return 0;
267 if (dt1
.IsEarlierThan(dt2
)) return 1;
274 static wxDataViewListModelCompare s_CmpFunc
;
275 static wxDataViewListModel
*s_CmpModel
;
276 static size_t s_CmpCol
;
278 int LINKAGEMODE
wxDataViewIntermediateCmp( size_t row1
, size_t row2
)
280 return s_CmpFunc( row1
, row2
, s_CmpCol
, s_CmpModel
);
283 // ---------------------------------------------------------
284 // wxDataViewSortedListModel
285 // ---------------------------------------------------------
287 IMPLEMENT_ABSTRACT_CLASS(wxDataViewSortedListModel
, wxDataViewListModel
)
289 wxDataViewSortedListModel::wxDataViewSortedListModel( wxDataViewListModel
*child
) :
290 m_array( wxDataViewIntermediateCmp
)
295 s_CmpFunc
= wxDataViewListModelSortedDefaultCompare
;
297 m_notifierOnChild
= new wxDataViewSortedListModelNotifier( this );
298 m_child
->AddNotifier( m_notifierOnChild
);
303 wxDataViewSortedListModel::~wxDataViewSortedListModel()
305 m_child
->RemoveNotifier( m_notifierOnChild
);
308 void wxDataViewSortedListModel::Resort()
311 size_t n
= m_child
->GetNumberOfRows();
313 for (i
= 0; i
< n
; i
++)
317 bool wxDataViewSortedListModel::ChildValueChanged( size_t col
, size_t row
)
320 size_t len
= m_array
.GetCount();
322 // Remove and readd sorted. Find out at which
323 // position it was and where it ended.
324 size_t start_pos
= 0,end_pos
= 0;
325 for (i
= 0; i
< len
; i
++)
326 if (m_array
[i
] == row
)
331 m_array
.Remove( row
);
333 for (i
= 0; i
< len
; i
++)
334 if (m_array
[i
] == row
)
340 if (end_pos
== start_pos
)
341 return wxDataViewListModel::ValueChanged( col
, start_pos
);
343 // Create an array where order[old] -> new_pos, so that
344 // if nothing changed order[0] -> 0 etc.
345 size_t *order
= new size_t[ len
];
346 // Fill up initial values.
347 for (i
= 0; i
< len
; i
++)
350 if (start_pos
< end_pos
)
352 for (i
= start_pos
; i
< end_pos
; i
++)
353 order
[i
] = order
[i
+1];
354 order
[end_pos
] = start_pos
;
358 for (i
= end_pos
; i
> start_pos
; i
--)
359 order
[i
] = order
[i
-1];
360 order
[start_pos
] = end_pos
;
363 RowsReordered( order
);
370 size_t wxDataViewSortedListModel::GetNumberOfRows()
372 return m_child
->GetNumberOfRows();
375 size_t wxDataViewSortedListModel::GetNumberOfCols()
377 return m_child
->GetNumberOfCols();
380 wxString
wxDataViewSortedListModel::GetColType( size_t col
)
382 return m_child
->GetColType( col
);
385 wxVariant
wxDataViewSortedListModel::GetValue( size_t col
, size_t row
)
387 size_t child_row
= m_array
[row
];
388 return m_child
->GetValue( col
, child_row
);
391 bool wxDataViewSortedListModel::SetValue( wxVariant
&variant
, size_t col
, size_t row
)
393 size_t child_row
= m_array
[row
];
394 bool ret
= m_child
->SetValue( variant
, col
, child_row
);
396 // Resort in ::ChildValueChanged() which gets reported back.
401 bool wxDataViewSortedListModel::RowAppended()
403 // you can only append
404 bool ret
= m_child
->RowAppended();
411 bool wxDataViewSortedListModel::RowPrepended()
413 // you can only append
414 bool ret
= m_child
->RowAppended();
421 bool wxDataViewSortedListModel::RowInserted( size_t before
)
423 // you can only append
424 bool ret
= m_child
->RowAppended();
426 // report different RowInsrted
431 bool wxDataViewSortedListModel::RowDeleted( size_t row
)
433 size_t child_row
= m_array
[row
];
435 bool ret
= m_child
->RowDeleted( child_row
);
437 // Do nothing here as the change in the
438 // child model will be reported back.
443 bool wxDataViewSortedListModel::RowChanged( size_t row
)
445 size_t child_row
= m_array
[row
];
446 bool ret
= m_child
->RowChanged( child_row
);
448 // Do nothing here as the change in the
449 // child model will be reported back.
454 bool wxDataViewSortedListModel::ValueChanged( size_t col
, size_t row
)
456 size_t child_row
= m_array
[row
];
457 bool ret
= m_child
->ValueChanged( col
, child_row
);
459 // Do nothing here as the change in the
460 // child model will be reported back.
465 bool wxDataViewSortedListModel::RowsReordered( size_t *new_order
)
467 // We sort them ourselves.
472 bool wxDataViewSortedListModel::Cleared()
474 bool ret
= m_child
->Cleared();
476 wxDataViewListModel::Cleared();
481 // ---------------------------------------------------------
482 // wxDataViewCellBase
483 // ---------------------------------------------------------
485 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCellBase
, wxObject
)
487 wxDataViewCellBase::wxDataViewCellBase( const wxString
&varianttype
, wxDataViewCellMode mode
)
489 m_variantType
= varianttype
;
493 // ---------------------------------------------------------
494 // wxDataViewColumnBase
495 // ---------------------------------------------------------
497 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumnBase
, wxObject
)
499 wxDataViewColumnBase::wxDataViewColumnBase( const wxString
&title
, wxDataViewCell
*cell
, size_t model_column
, int flags
)
502 m_model_column
= model_column
;
506 m_cell
->SetOwner( (wxDataViewColumn
*) this );
509 wxDataViewColumnBase::~wxDataViewColumnBase()
516 GetOwner()->GetModel()->RemoveViewingColumn( (wxDataViewColumn
*) this );
520 void wxDataViewColumnBase::SetTitle( const wxString
&title
)
525 wxString
wxDataViewColumnBase::GetTitle()
530 // ---------------------------------------------------------
531 // wxDataViewCtrlBase
532 // ---------------------------------------------------------
534 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCtrlBase
, wxControl
)
536 wxDataViewCtrlBase::wxDataViewCtrlBase()
539 m_cols
.DeleteContents( true );
542 wxDataViewCtrlBase::~wxDataViewCtrlBase()
546 bool wxDataViewCtrlBase::AssociateModel( wxDataViewListModel
*model
)
553 wxDataViewListModel
* wxDataViewCtrlBase::GetModel()
558 bool wxDataViewCtrlBase::AppendTextColumn( const wxString
&label
, size_t model_column
)
560 return AppendColumn( new wxDataViewColumn( label
, new wxDataViewTextCell(), model_column
) );
563 bool wxDataViewCtrlBase::AppendToggleColumn( const wxString
&label
, size_t model_column
)
565 return AppendColumn( new wxDataViewColumn( label
, new wxDataViewToggleCell(), model_column
) );
568 bool wxDataViewCtrlBase::AppendProgressColumn( const wxString
&label
, size_t model_column
)
570 return AppendColumn( new wxDataViewColumn( label
, new wxDataViewProgressCell(), model_column
) );
573 bool wxDataViewCtrlBase::AppendDateColumn( const wxString
&label
, size_t model_column
)
575 return AppendColumn( new wxDataViewColumn( label
, new wxDataViewDateCell(), model_column
) );
578 bool wxDataViewCtrlBase::AppendColumn( wxDataViewColumn
*col
)
580 m_cols
.Append( (wxObject
*) col
);
581 col
->SetOwner( (wxDataViewCtrl
*) this );
582 m_model
->AddViewingColumn( col
, col
->GetModelColumn() );
586 size_t wxDataViewCtrlBase::GetNumberOfColumns()
588 return m_cols
.GetCount();
591 bool wxDataViewCtrlBase::DeleteColumn( size_t pos
)
596 bool wxDataViewCtrlBase::ClearColumns()
601 wxDataViewColumn
* wxDataViewCtrlBase::GetColumn( size_t pos
)
603 return (wxDataViewColumn
*) m_cols
[ pos
];