]> git.saurik.com Git - wxWidgets.git/blame - src/common/datavcmn.cpp
Applied patch [ 1428990 ] wxUniv: patch for toolbar button remain in pressed status
[wxWidgets.git] / src / common / datavcmn.cpp
CommitLineData
239eaa41
RR
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
8045736e
RR
18#include "wx/defs.h"
19
20#if wxUSE_DATAVIEWCTRL
21
260b9be7 22#include "wx/object.h"
239eaa41
RR
23#include "wx/dataview.h"
24#include "wx/log.h"
25#include "wx/image.h"
26
27// ---------------------------------------------------------
28// wxDataViewModel
29// ---------------------------------------------------------
30
31IMPLEMENT_ABSTRACT_CLASS(wxDataViewModel, wxObject)
32
33// ---------------------------------------------------------
34// wxDataViewListModel
35// ---------------------------------------------------------
36
37IMPLEMENT_ABSTRACT_CLASS(wxDataViewListModel, wxDataViewModel)
38
39wxDataViewListModel::wxDataViewListModel()
40{
b5d777c7 41 m_viewingColumns.DeleteContents( true );
8f850e28 42 m_notifiers.DeleteContents( true );
239eaa41
RR
43}
44
45wxDataViewListModel::~wxDataViewListModel()
46{
239eaa41
RR
47}
48
49bool wxDataViewListModel::RowAppended()
50{
8f850e28
RR
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 }
239eaa41 61
8f850e28 62 return ret;
239eaa41
RR
63}
64
65bool wxDataViewListModel::RowPrepended()
66{
8f850e28
RR
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 }
239eaa41 77
8f850e28 78 return ret;
239eaa41
RR
79}
80
81bool wxDataViewListModel::RowInserted( size_t before )
82{
8f850e28
RR
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 }
239eaa41 93
8f850e28 94 return ret;
239eaa41
RR
95}
96
97bool wxDataViewListModel::RowDeleted( size_t row )
98{
8f850e28
RR
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 }
239eaa41 109
8f850e28 110 return ret;
239eaa41
RR
111}
112
113bool wxDataViewListModel::RowChanged( size_t row )
114{
8f850e28
RR
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 }
239eaa41 125
8f850e28 126 return ret;
239eaa41
RR
127}
128
a7f61f76 129bool wxDataViewListModel::ValueChanged( size_t col, size_t row )
239eaa41 130{
8f850e28 131 bool ret = true;
b5d777c7 132
8f850e28 133 wxNode *node = m_notifiers.GetFirst();
b5d777c7
RR
134 while (node)
135 {
8f850e28
RR
136 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
137 if (!notifier->ValueChanged( col, row ))
138 ret = false;
b5d777c7
RR
139 node = node->GetNext();
140 }
141
142 return ret;
239eaa41
RR
143}
144
4eccd3a1
RR
145bool wxDataViewListModel::RowsReordered( size_t *new_order )
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->RowsReordered( new_order ))
154 ret = false;
155 node = node->GetNext();
156 }
157
158 return ret;
159}
160
239eaa41
RR
161bool wxDataViewListModel::Cleared()
162{
8f850e28
RR
163 bool ret = true;
164
165 wxNode *node = m_notifiers.GetFirst();
166 while (node)
167 {
168 wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
169 if (!notifier->Cleared())
170 ret = false;
171 node = node->GetNext();
172 }
239eaa41 173
8f850e28 174 return ret;
239eaa41
RR
175}
176
b5d777c7
RR
177void wxDataViewListModel::AddViewingColumn( wxDataViewColumn *view_column, size_t model_column )
178{
179 m_viewingColumns.Append( new wxDataViewViewingColumn( view_column, model_column ) );
180}
181
182void wxDataViewListModel::RemoveViewingColumn( wxDataViewColumn *column )
183{
184 wxNode *node = m_viewingColumns.GetFirst();
185 while (node)
186 {
187 wxDataViewViewingColumn* tmp = (wxDataViewViewingColumn*) node->GetData();
188
189 if (tmp->m_viewColumn == column)
190 {
191 m_viewingColumns.DeleteObject( tmp );
192 return;
193 }
194
195 node = node->GetNext();
196 }
197}
198
8f850e28 199void wxDataViewListModel::AddNotifier( wxDataViewListModelNotifier *notifier )
239eaa41 200{
8f850e28
RR
201 m_notifiers.Append( notifier );
202 notifier->SetOwner( this );
239eaa41
RR
203}
204
8f850e28 205void wxDataViewListModel::RemoveNotifier( wxDataViewListModelNotifier *notifier )
239eaa41 206{
8f850e28 207 m_notifiers.DeleteObject( notifier );
239eaa41
RR
208}
209
8981608c 210// ---------------------------------------------------------
4eccd3a1
RR
211// wxDataViewSortedListModelNotifier
212// ---------------------------------------------------------
213
214class wxDataViewSortedListModelNotifier: public wxDataViewListModelNotifier
215{
216public:
217 wxDataViewSortedListModelNotifier( wxDataViewSortedListModel *model )
218 { m_model = model; }
219
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; }
229
230 wxDataViewSortedListModel *m_model;
231};
232
233// ---------------------------------------------------------
234// wxDataViewSortedListModel compare function
8981608c
RR
235// ---------------------------------------------------------
236
237int wxCALLBACK wxDataViewListModelSortedDefaultCompare
238 (size_t row1, size_t row2, size_t col, wxDataViewListModel* model )
239{
3f3af7e7
RR
240 wxVariant value1,value2;
241 model->GetValue( value1, col, row1 );
242 model->GetValue( value2, col, row2 );
8981608c
RR
243 if (value1.GetType() == wxT("string"))
244 {
245 wxString str1 = value1.GetString();
246 wxString str2 = value2.GetString();
247 return str1.Cmp( str2 );
248 }
249 if (value1.GetType() == wxT("long"))
250 {
251 long l1 = value1.GetLong();
252 long l2 = value2.GetLong();
253 return l1-l2;
254 }
255 if (value1.GetType() == wxT("double"))
256 {
257 double d1 = value1.GetDouble();
258 double d2 = value2.GetDouble();
259 if (d1 == d2) return 0;
260 if (d1 < d2) return 1;
261 return -1;
262 }
263 if (value1.GetType() == wxT("datetime"))
264 {
265 wxDateTime dt1 = value1.GetDateTime();
266 wxDateTime dt2 = value2.GetDateTime();
267 if (dt1.IsEqualTo(dt2)) return 0;
268 if (dt1.IsEarlierThan(dt2)) return 1;
269 return -1;
270 }
271
272 return 0;
273}
274
275static wxDataViewListModelCompare s_CmpFunc;
276static wxDataViewListModel *s_CmpModel;
277static size_t s_CmpCol;
278
279int LINKAGEMODE wxDataViewIntermediateCmp( size_t row1, size_t row2 )
280{
281 return s_CmpFunc( row1, row2, s_CmpCol, s_CmpModel );
282}
283
4eccd3a1
RR
284// ---------------------------------------------------------
285// wxDataViewSortedListModel
286// ---------------------------------------------------------
8981608c
RR
287
288IMPLEMENT_ABSTRACT_CLASS(wxDataViewSortedListModel, wxDataViewListModel)
289
290wxDataViewSortedListModel::wxDataViewSortedListModel( wxDataViewListModel *child ) :
291 m_array( wxDataViewIntermediateCmp )
292{
293 m_child = child;
294 s_CmpCol = 0;
295 s_CmpModel = child;
296 s_CmpFunc = wxDataViewListModelSortedDefaultCompare;
8f850e28 297
4eccd3a1
RR
298 m_notifierOnChild = new wxDataViewSortedListModelNotifier( this );
299 m_child->AddNotifier( m_notifierOnChild );
300
8f850e28 301 Resort();
8981608c
RR
302}
303
304wxDataViewSortedListModel::~wxDataViewSortedListModel()
305{
4eccd3a1 306 m_child->RemoveNotifier( m_notifierOnChild );
8981608c
RR
307}
308
8f850e28
RR
309void wxDataViewSortedListModel::Resort()
310{
311 m_array.Clear();
312 size_t n = m_child->GetNumberOfRows();
313 size_t i;
314 for (i = 0; i < n; i++)
315 m_array.Add( i );
316}
317
3f3af7e7
RR
318#if 0
319static void Dump( wxDataViewListModel *model, size_t col )
320{
321 size_t n = model->GetNumberOfRows();
322 size_t i;
323 for (i = 0; i < n; i++)
324 {
325 wxVariant variant;
326 model->GetValue( variant, col, i );
327 wxString tmp;
328 tmp = variant.GetString();
329 wxPrintf( wxT("%d: %s\n"), (int) i, tmp.c_str() );
330 }
331}
332#endif
333
4eccd3a1
RR
334bool wxDataViewSortedListModel::ChildValueChanged( size_t col, size_t row )
335{
336 size_t i;
337 size_t len = m_array.GetCount();
338
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)
344 {
345 start_pos = i;
346 break;
347 }
3f3af7e7 348 m_array.RemoveAt( start_pos );
4eccd3a1 349 m_array.Add( row );
3f3af7e7 350
4eccd3a1
RR
351 for (i = 0; i < len; i++)
352 if (m_array[i] == row)
353 {
354 end_pos = i;
355 break;
356 }
3f3af7e7 357
4eccd3a1
RR
358 if (end_pos == start_pos)
359 return wxDataViewListModel::ValueChanged( col, start_pos );
360
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++)
366 order[i] = i;
367
368 if (start_pos < end_pos)
369 {
370 for (i = start_pos; i < end_pos; i++)
371 order[i] = order[i+1];
372 order[end_pos] = start_pos;
373 }
374 else
375 {
376 for (i = end_pos; i > start_pos; i--)
377 order[i] = order[i-1];
378 order[start_pos] = end_pos;
379 }
380
3f3af7e7 381 wxDataViewListModel::RowsReordered( order );
4eccd3a1
RR
382
383 delete [] order;
384
385 return true;
386}
387
8981608c
RR
388size_t wxDataViewSortedListModel::GetNumberOfRows()
389{
3f3af7e7 390 return m_array.GetCount();
8981608c
RR
391}
392
393size_t wxDataViewSortedListModel::GetNumberOfCols()
394{
395 return m_child->GetNumberOfCols();
396}
397
398wxString wxDataViewSortedListModel::GetColType( size_t col )
399{
400 return m_child->GetColType( col );
401}
402
3f3af7e7 403void wxDataViewSortedListModel::GetValue( wxVariant &variant, size_t col, size_t row )
8981608c
RR
404{
405 size_t child_row = m_array[row];
3f3af7e7 406 m_child->GetValue( variant, col, child_row );
8981608c
RR
407}
408
409bool wxDataViewSortedListModel::SetValue( wxVariant &variant, size_t col, size_t row )
410{
411 size_t child_row = m_array[row];
412 bool ret = m_child->SetValue( variant, col, child_row );
4eccd3a1
RR
413
414 // Resort in ::ChildValueChanged() which gets reported back.
415
8981608c
RR
416 return ret;
417}
418
419bool wxDataViewSortedListModel::RowAppended()
420{
421 // you can only append
422 bool ret = m_child->RowAppended();
423
424 // report RowInsrted
425
426 return ret;
427}
428
429bool wxDataViewSortedListModel::RowPrepended()
430{
431 // you can only append
432 bool ret = m_child->RowAppended();
433
434 // report RowInsrted
435
436 return ret;
437}
438
439bool wxDataViewSortedListModel::RowInserted( size_t before )
440{
441 // you can only append
442 bool ret = m_child->RowAppended();
443
444 // report different RowInsrted
445
446 return ret;
447}
448
449bool wxDataViewSortedListModel::RowDeleted( size_t row )
450{
451 size_t child_row = m_array[row];
452
453 bool ret = m_child->RowDeleted( child_row );
454
4eccd3a1
RR
455 // Do nothing here as the change in the
456 // child model will be reported back.
8981608c
RR
457
458 return ret;
459}
460
461bool wxDataViewSortedListModel::RowChanged( size_t row )
462{
463 size_t child_row = m_array[row];
464 bool ret = m_child->RowChanged( child_row );
465
4eccd3a1
RR
466 // Do nothing here as the change in the
467 // child model will be reported back.
8981608c
RR
468
469 return ret;
470}
471
472bool wxDataViewSortedListModel::ValueChanged( size_t col, size_t row )
473{
474 size_t child_row = m_array[row];
475 bool ret = m_child->ValueChanged( col, child_row );
476
4eccd3a1
RR
477 // Do nothing here as the change in the
478 // child model will be reported back.
8981608c
RR
479
480 return ret;
481}
482
4eccd3a1
RR
483bool wxDataViewSortedListModel::RowsReordered( size_t *new_order )
484{
485 // We sort them ourselves.
486
487 return false;
488}
489
8981608c
RR
490bool wxDataViewSortedListModel::Cleared()
491{
492 bool ret = m_child->Cleared();
493
494 wxDataViewListModel::Cleared();
495
496 return ret;
497}
498
6842a71a
RR
499// ---------------------------------------------------------
500// wxDataViewCellBase
501// ---------------------------------------------------------
502
503IMPLEMENT_ABSTRACT_CLASS(wxDataViewCellBase, wxObject)
504
505wxDataViewCellBase::wxDataViewCellBase( const wxString &varianttype, wxDataViewCellMode mode )
506{
507 m_variantType = varianttype;
508 m_mode = mode;
509}
510
fa28826d
RR
511// ---------------------------------------------------------
512// wxDataViewColumnBase
513// ---------------------------------------------------------
514
515IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumnBase, wxObject)
516
6842a71a 517wxDataViewColumnBase::wxDataViewColumnBase( const wxString &title, wxDataViewCell *cell, size_t model_column, int flags)
fa28826d 518{
6842a71a
RR
519 m_cell = cell;
520 m_model_column = model_column;
fa28826d
RR
521 m_flags = flags;
522 m_title = title;
6842a71a
RR
523 m_owner = NULL;
524 m_cell->SetOwner( (wxDataViewColumn*) this );
525}
526
527wxDataViewColumnBase::~wxDataViewColumnBase()
528{
529 if (m_cell)
530 delete m_cell;
b5d777c7
RR
531
532 if (GetOwner())
533 {
534 GetOwner()->GetModel()->RemoveViewingColumn( (wxDataViewColumn*) this );
535 }
fa28826d
RR
536}
537
538void wxDataViewColumnBase::SetTitle( const wxString &title )
539{
540 m_title = title;
541}
542
543wxString wxDataViewColumnBase::GetTitle()
544{
545 return m_title;
546}
547
239eaa41
RR
548// ---------------------------------------------------------
549// wxDataViewCtrlBase
550// ---------------------------------------------------------
551
552IMPLEMENT_ABSTRACT_CLASS(wxDataViewCtrlBase, wxControl)
553
554wxDataViewCtrlBase::wxDataViewCtrlBase()
555{
556 m_model = NULL;
fa28826d 557 m_cols.DeleteContents( true );
239eaa41
RR
558}
559
560wxDataViewCtrlBase::~wxDataViewCtrlBase()
561{
239eaa41
RR
562}
563
6e2e590f 564bool wxDataViewCtrlBase::AssociateModel( wxDataViewListModel *model )
239eaa41 565{
239eaa41
RR
566 m_model = model;
567
568 return true;
569}
570
6e2e590f 571wxDataViewListModel* wxDataViewCtrlBase::GetModel()
239eaa41
RR
572{
573 return m_model;
574}
575
605c2c4a 576bool wxDataViewCtrlBase::AppendTextColumn( const wxString &label, size_t model_column )
fa28826d 577{
6842a71a 578 return AppendColumn( new wxDataViewColumn( label, new wxDataViewTextCell(), model_column ) );
fa28826d
RR
579}
580
605c2c4a
RR
581bool wxDataViewCtrlBase::AppendToggleColumn( const wxString &label, size_t model_column )
582{
583 return AppendColumn( new wxDataViewColumn( label, new wxDataViewToggleCell(), model_column ) );
584}
585
ad63bf41
RR
586bool wxDataViewCtrlBase::AppendProgressColumn( const wxString &label, size_t model_column )
587{
588 return AppendColumn( new wxDataViewColumn( label, new wxDataViewProgressCell(), model_column ) );
589}
590
4d496ecb
RR
591bool wxDataViewCtrlBase::AppendDateColumn( const wxString &label, size_t model_column )
592{
593 return AppendColumn( new wxDataViewColumn( label, new wxDataViewDateCell(), model_column ) );
594}
595
fa28826d
RR
596bool wxDataViewCtrlBase::AppendColumn( wxDataViewColumn *col )
597{
598 m_cols.Append( (wxObject*) col );
6842a71a 599 col->SetOwner( (wxDataViewCtrl*) this );
b5d777c7 600 m_model->AddViewingColumn( col, col->GetModelColumn() );
fa28826d
RR
601 return true;
602}
603
604size_t wxDataViewCtrlBase::GetNumberOfColumns()
605{
606 return m_cols.GetCount();
607}
608
609bool wxDataViewCtrlBase::DeleteColumn( size_t pos )
610{
611 return false;
612}
613
614bool wxDataViewCtrlBase::ClearColumns()
615{
616 return false;
617}
618
619wxDataViewColumn* wxDataViewCtrlBase::GetColumn( size_t pos )
620{
621 return (wxDataViewColumn*) m_cols[ pos ];
622}
623
8045736e 624#endif