]> git.saurik.com Git - wxWidgets.git/blob - src/common/datavcmn.cpp
Moved code around preparing the sorted model.
[wxWidgets.git] / src / common / datavcmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/datavcmn.cpp
3 // Purpose: wxDataViewCtrl base classes and common parts
4 // Author: Robert Roebling
5 // Created: 2006/02/20
6 // RCS-ID: $Id$
7 // Copyright: (c) 2006, Robert Roebling
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17
18 #include "wx/defs.h"
19
20 #if wxUSE_DATAVIEWCTRL
21
22 #include "wx/object.h"
23 #include "wx/dataview.h"
24 #include "wx/log.h"
25 #include "wx/image.h"
26
27 // ---------------------------------------------------------
28 // wxDataViewModel
29 // ---------------------------------------------------------
30
31 IMPLEMENT_ABSTRACT_CLASS(wxDataViewModel, wxObject)
32
33 // ---------------------------------------------------------
34 // wxDataViewListModel
35 // ---------------------------------------------------------
36
37 IMPLEMENT_ABSTRACT_CLASS(wxDataViewListModel, wxDataViewModel)
38
39 wxDataViewListModel::wxDataViewListModel()
40 {
41 m_viewingColumns.DeleteContents( true );
42 m_notifiers.DeleteContents( true );
43 }
44
45 wxDataViewListModel::~wxDataViewListModel()
46 {
47 }
48
49 bool wxDataViewListModel::RowAppended()
50 {
51 bool ret = true;
52
53 wxNode *node = m_notifiers.GetFirst();
54 while (node)
55 {
56 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
57 if (!notifier->RowAppended())
58 ret = false;
59 node = node->GetNext();
60 }
61
62 return ret;
63 }
64
65 bool wxDataViewListModel::RowPrepended()
66 {
67 bool ret = true;
68
69 wxNode *node = m_notifiers.GetFirst();
70 while (node)
71 {
72 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
73 if (!notifier->RowPrepended())
74 ret = false;
75 node = node->GetNext();
76 }
77
78 return ret;
79 }
80
81 bool wxDataViewListModel::RowInserted( size_t before )
82 {
83 bool ret = true;
84
85 wxNode *node = m_notifiers.GetFirst();
86 while (node)
87 {
88 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
89 if (!notifier->RowInserted(before))
90 ret = false;
91 node = node->GetNext();
92 }
93
94 return ret;
95 }
96
97 bool wxDataViewListModel::RowDeleted( size_t row )
98 {
99 bool ret = true;
100
101 wxNode *node = m_notifiers.GetFirst();
102 while (node)
103 {
104 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
105 if (!notifier->RowDeleted( row ))
106 ret = false;
107 node = node->GetNext();
108 }
109
110 return ret;
111 }
112
113 bool wxDataViewListModel::RowChanged( size_t row )
114 {
115 bool ret = true;
116
117 wxNode *node = m_notifiers.GetFirst();
118 while (node)
119 {
120 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
121 if (!notifier->RowChanged( row ))
122 ret = false;
123 node = node->GetNext();
124 }
125
126 return ret;
127 }
128
129 bool wxDataViewListModel::ValueChanged( size_t col, size_t row )
130 {
131 bool ret = true;
132
133 wxNode *node = m_notifiers.GetFirst();
134 while (node)
135 {
136 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
137 if (!notifier->ValueChanged( col, row ))
138 ret = false;
139 node = node->GetNext();
140 }
141
142 return ret;
143 }
144
145 bool wxDataViewListModel::Cleared()
146 {
147 bool ret = true;
148
149 wxNode *node = m_notifiers.GetFirst();
150 while (node)
151 {
152 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
153 if (!notifier->Cleared())
154 ret = false;
155 node = node->GetNext();
156 }
157
158 return ret;
159 }
160
161 void wxDataViewListModel::AddViewingColumn( wxDataViewColumn *view_column, size_t model_column )
162 {
163 m_viewingColumns.Append( new wxDataViewViewingColumn( view_column, model_column ) );
164 }
165
166 void wxDataViewListModel::RemoveViewingColumn( wxDataViewColumn *column )
167 {
168 wxNode *node = m_viewingColumns.GetFirst();
169 while (node)
170 {
171 wxDataViewViewingColumn* tmp = (wxDataViewViewingColumn*) node->GetData();
172
173 if (tmp->m_viewColumn == column)
174 {
175 m_viewingColumns.DeleteObject( tmp );
176 return;
177 }
178
179 node = node->GetNext();
180 }
181 }
182
183 void wxDataViewListModel::AddNotifier( wxDataViewListModelNotifier *notifier )
184 {
185 m_notifiers.Append( notifier );
186 notifier->SetOwner( this );
187 }
188
189 void wxDataViewListModel::RemoveNotifier( wxDataViewListModelNotifier *notifier )
190 {
191 m_notifiers.DeleteObject( notifier );
192 }
193
194 // ---------------------------------------------------------
195 // wxDataViewSortedListModel
196 // ---------------------------------------------------------
197
198 int wxCALLBACK wxDataViewListModelSortedDefaultCompare
199 (size_t row1, size_t row2, size_t col, wxDataViewListModel* model )
200 {
201 wxVariant value1 = model->GetValue( col, row1 );
202 wxVariant value2 = model->GetValue( col, row2 );
203 if (value1.GetType() == wxT("string"))
204 {
205 wxString str1 = value1.GetString();
206 wxString str2 = value2.GetString();
207 return str1.Cmp( str2 );
208 }
209 if (value1.GetType() == wxT("long"))
210 {
211 long l1 = value1.GetLong();
212 long l2 = value2.GetLong();
213 return l1-l2;
214 }
215 if (value1.GetType() == wxT("double"))
216 {
217 double d1 = value1.GetDouble();
218 double d2 = value2.GetDouble();
219 if (d1 == d2) return 0;
220 if (d1 < d2) return 1;
221 return -1;
222 }
223 if (value1.GetType() == wxT("datetime"))
224 {
225 wxDateTime dt1 = value1.GetDateTime();
226 wxDateTime dt2 = value2.GetDateTime();
227 if (dt1.IsEqualTo(dt2)) return 0;
228 if (dt1.IsEarlierThan(dt2)) return 1;
229 return -1;
230 }
231
232 return 0;
233 }
234
235 static wxDataViewListModelCompare s_CmpFunc;
236 static wxDataViewListModel *s_CmpModel;
237 static size_t s_CmpCol;
238
239 int LINKAGEMODE wxDataViewIntermediateCmp( size_t row1, size_t row2 )
240 {
241 return s_CmpFunc( row1, row2, s_CmpCol, s_CmpModel );
242 }
243
244
245 IMPLEMENT_ABSTRACT_CLASS(wxDataViewSortedListModel, wxDataViewListModel)
246
247 wxDataViewSortedListModel::wxDataViewSortedListModel( wxDataViewListModel *child ) :
248 m_array( wxDataViewIntermediateCmp )
249 {
250 m_child = child;
251 s_CmpCol = 0;
252 s_CmpModel = child;
253 s_CmpFunc = wxDataViewListModelSortedDefaultCompare;
254
255 Resort();
256 }
257
258 wxDataViewSortedListModel::~wxDataViewSortedListModel()
259 {
260 }
261
262 void wxDataViewSortedListModel::Resort()
263 {
264 m_array.Clear();
265 size_t n = m_child->GetNumberOfRows();
266 size_t i;
267 for (i = 0; i < n; i++)
268 m_array.Add( i );
269 }
270
271 size_t wxDataViewSortedListModel::GetNumberOfRows()
272 {
273 return m_child->GetNumberOfRows();
274 }
275
276 size_t wxDataViewSortedListModel::GetNumberOfCols()
277 {
278 return m_child->GetNumberOfCols();
279 }
280
281 wxString wxDataViewSortedListModel::GetColType( size_t col )
282 {
283 return m_child->GetColType( col );
284 }
285
286 wxVariant wxDataViewSortedListModel::GetValue( size_t col, size_t row )
287 {
288 size_t child_row = m_array[row];
289 return m_child->GetValue( col, child_row );
290 }
291
292 bool wxDataViewSortedListModel::SetValue( wxVariant &variant, size_t col, size_t row )
293 {
294 size_t child_row = m_array[row];
295 bool ret = m_child->SetValue( variant, col, child_row );
296 // resort in ::ValueChanged()
297 return ret;
298 }
299
300 bool wxDataViewSortedListModel::RowAppended()
301 {
302 // you can only append
303 bool ret = m_child->RowAppended();
304
305 // report RowInsrted
306
307 return ret;
308 }
309
310 bool wxDataViewSortedListModel::RowPrepended()
311 {
312 // you can only append
313 bool ret = m_child->RowAppended();
314
315 // report RowInsrted
316
317 return ret;
318 }
319
320 bool wxDataViewSortedListModel::RowInserted( size_t before )
321 {
322 // you can only append
323 bool ret = m_child->RowAppended();
324
325 // report different RowInsrted
326
327 return ret;
328 }
329
330 bool wxDataViewSortedListModel::RowDeleted( size_t row )
331 {
332 size_t child_row = m_array[row];
333
334 bool ret = m_child->RowDeleted( child_row );
335
336 wxDataViewListModel::RowDeleted( row );
337
338 return ret;
339 }
340
341 bool wxDataViewSortedListModel::RowChanged( size_t row )
342 {
343 size_t child_row = m_array[row];
344 bool ret = m_child->RowChanged( child_row );
345
346 // report delete old pos, inserted new pos
347
348 return ret;
349 }
350
351 bool wxDataViewSortedListModel::ValueChanged( size_t col, size_t row )
352 {
353 size_t child_row = m_array[row];
354 bool ret = m_child->ValueChanged( col, child_row );
355
356 // Do nothing if not the sorted col..
357 // report delete old pos, inserted new pos
358
359 return ret;
360 }
361
362 bool wxDataViewSortedListModel::Cleared()
363 {
364 bool ret = m_child->Cleared();
365
366 wxDataViewListModel::Cleared();
367
368 return ret;
369 }
370
371 // ---------------------------------------------------------
372 // wxDataViewCellBase
373 // ---------------------------------------------------------
374
375 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCellBase, wxObject)
376
377 wxDataViewCellBase::wxDataViewCellBase( const wxString &varianttype, wxDataViewCellMode mode )
378 {
379 m_variantType = varianttype;
380 m_mode = mode;
381 }
382
383 // ---------------------------------------------------------
384 // wxDataViewColumnBase
385 // ---------------------------------------------------------
386
387 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumnBase, wxObject)
388
389 wxDataViewColumnBase::wxDataViewColumnBase( const wxString &title, wxDataViewCell *cell, size_t model_column, int flags)
390 {
391 m_cell = cell;
392 m_model_column = model_column;
393 m_flags = flags;
394 m_title = title;
395 m_owner = NULL;
396 m_cell->SetOwner( (wxDataViewColumn*) this );
397 }
398
399 wxDataViewColumnBase::~wxDataViewColumnBase()
400 {
401 if (m_cell)
402 delete m_cell;
403
404 if (GetOwner())
405 {
406 GetOwner()->GetModel()->RemoveViewingColumn( (wxDataViewColumn*) this );
407 }
408 }
409
410 void wxDataViewColumnBase::SetTitle( const wxString &title )
411 {
412 m_title = title;
413 }
414
415 wxString wxDataViewColumnBase::GetTitle()
416 {
417 return m_title;
418 }
419
420 // ---------------------------------------------------------
421 // wxDataViewCtrlBase
422 // ---------------------------------------------------------
423
424 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCtrlBase, wxControl)
425
426 wxDataViewCtrlBase::wxDataViewCtrlBase()
427 {
428 m_model = NULL;
429 m_cols.DeleteContents( true );
430 }
431
432 wxDataViewCtrlBase::~wxDataViewCtrlBase()
433 {
434 if (m_model)
435 delete m_model;
436 }
437
438 bool wxDataViewCtrlBase::AssociateModel( wxDataViewListModel *model )
439 {
440 if (m_model)
441 delete m_model;
442
443 m_model = model;
444
445 return true;
446 }
447
448 wxDataViewListModel* wxDataViewCtrlBase::GetModel()
449 {
450 return m_model;
451 }
452
453 bool wxDataViewCtrlBase::AppendTextColumn( const wxString &label, size_t model_column )
454 {
455 return AppendColumn( new wxDataViewColumn( label, new wxDataViewTextCell(), model_column ) );
456 }
457
458 bool wxDataViewCtrlBase::AppendToggleColumn( const wxString &label, size_t model_column )
459 {
460 return AppendColumn( new wxDataViewColumn( label, new wxDataViewToggleCell(), model_column ) );
461 }
462
463 bool wxDataViewCtrlBase::AppendProgressColumn( const wxString &label, size_t model_column )
464 {
465 return AppendColumn( new wxDataViewColumn( label, new wxDataViewProgressCell(), model_column ) );
466 }
467
468 bool wxDataViewCtrlBase::AppendDateColumn( const wxString &label, size_t model_column )
469 {
470 return AppendColumn( new wxDataViewColumn( label, new wxDataViewDateCell(), model_column ) );
471 }
472
473 bool wxDataViewCtrlBase::AppendColumn( wxDataViewColumn *col )
474 {
475 m_cols.Append( (wxObject*) col );
476 col->SetOwner( (wxDataViewCtrl*) this );
477 m_model->AddViewingColumn( col, col->GetModelColumn() );
478 return true;
479 }
480
481 size_t wxDataViewCtrlBase::GetNumberOfColumns()
482 {
483 return m_cols.GetCount();
484 }
485
486 bool wxDataViewCtrlBase::DeleteColumn( size_t pos )
487 {
488 return false;
489 }
490
491 bool wxDataViewCtrlBase::ClearColumns()
492 {
493 return false;
494 }
495
496 wxDataViewColumn* wxDataViewCtrlBase::GetColumn( size_t pos )
497 {
498 return (wxDataViewColumn*) m_cols[ pos ];
499 }
500
501 #endif