]> git.saurik.com Git - wxWidgets.git/blame - src/osx/dataview_osx.cpp
Fix for #15224: wxRichTextTable: Setting a cell's text colour affects subsequent...
[wxWidgets.git] / src / osx / dataview_osx.cpp
CommitLineData
e86edab0
RR
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/osx/dataview_osx.cpp
3// Purpose: wxDataViewCtrl native mac implementation
4// Author:
e86edab0
RR
5// Copyright: (c) 2009
6// Licence: wxWindows licence
7/////////////////////////////////////////////////////////////////////////////
8
9// For compilers that support precompilation, includes "wx.h".
10#include "wx/wxprec.h"
11
12#if (wxUSE_DATAVIEWCTRL != 0) && (!defined(wxUSE_GENERICDATAVIEWCTRL) || (wxUSE_GENERICDATAVIEWCTRL == 0))
13
e86edab0
RR
14#include <limits>
15
16#ifndef WX_PRECOMP
17 #include "wx/timer.h"
18 #include "wx/settings.h"
19 #include "wx/dcclient.h"
20 #include "wx/icon.h"
21#endif
f0e867e9
VZ
22#if wxOSX_USE_CARBON
23#include "wx/osx/carbon/dataview.h"
24#endif
e86edab0
RR
25
26#include "wx/osx/core/dataview.h"
27#include "wx/osx/private.h"
28#include "wx/renderer.h"
29
30// ============================================================================
31// Helper functions for dataviewe implementation on OSX
32// ============================================================================
33wxString ConcatenateDataViewItemValues(wxDataViewCtrl const* dataViewCtrlPtr, wxDataViewItem const& dataViewItem)
34{
35 wxString dataString; // contains the TAB concatenated data
36
37
38 for (size_t i=0; i<dataViewCtrlPtr->GetColumnCount(); i++)
39 {
40 // variable definition:
41 wxVariant dataValue;
608129e5 42
e86edab0
RR
43 dataViewCtrlPtr->GetModel()->GetValue(dataValue,dataViewItem,dataViewCtrlPtr->GetColumn(i)->GetModelColumn());
44 if (i > 0)
45 dataString << wxT('\t');
46 dataString << dataValue.MakeString();
47 }
48 return dataString;
49}
50
51// ============================================================================
52// wxOSXDataViewModelNotifier
53// ============================================================================
54class wxOSXDataViewModelNotifier : public wxDataViewModelNotifier
55{
56public:
57 //
58 // constructors / destructor
59 //
60 wxOSXDataViewModelNotifier(wxDataViewCtrl* initDataViewCtrlPtr);
61
62 //
63 // inherited methods from wxDataViewModelNotifier
64 //
65 virtual bool ItemAdded (wxDataViewItem const &parent, wxDataViewItem const &item);
66 virtual bool ItemsAdded (wxDataViewItem const& parent, wxDataViewItemArray const& items);
67 virtual bool ItemChanged (wxDataViewItem const& item);
68 virtual bool ItemsChanged(wxDataViewItemArray const& items);
69 virtual bool ItemDeleted (wxDataViewItem const& parent, wxDataViewItem const& item);
70 virtual bool ItemsDeleted(wxDataViewItem const& parent, wxDataViewItemArray const& items);
71 virtual bool ValueChanged(wxDataViewItem const& item, unsigned int col);
72 virtual bool Cleared();
73 virtual void Resort();
74
75protected:
76 // if the dataview control can have a variable row height this method sets the dataview's control row height of
77 // the passed item to the maximum value occupied by the item in all columns
78 void AdjustRowHeight(wxDataViewItem const& item);
79 // ... and the same method for a couple of items:
80 void AdjustRowHeights(wxDataViewItemArray const& items);
b06ed2f8
VS
81 // adjust wxCOL_WIDTH_AUTOSIZE columns to fit the data
82 void AdjustAutosizedColumns();
e86edab0
RR
83
84private:
85 wxDataViewCtrl* m_DataViewCtrlPtr;
86};
87
88//
89// constructors / destructor
90//
91wxOSXDataViewModelNotifier::wxOSXDataViewModelNotifier(wxDataViewCtrl* initDataViewCtrlPtr)
92 :m_DataViewCtrlPtr(initDataViewCtrlPtr)
93{
94 if (initDataViewCtrlPtr == NULL)
8d96f54d 95 wxFAIL_MSG("Pointer to dataview control must not be NULL");
e86edab0
RR
96}
97
98bool wxOSXDataViewModelNotifier::ItemAdded(wxDataViewItem const& parent, wxDataViewItem const& item)
99{
100 bool noFailureFlag;
101
102
8d96f54d 103 wxCHECK_MSG(item.IsOk(),false,"Added item is invalid.");
de40d736
VZ
104 noFailureFlag = m_DataViewCtrlPtr->GetDataViewPeer()->Add(parent,item);
105 AdjustRowHeight(item);
e86edab0
RR
106 return noFailureFlag;
107}
108
109bool wxOSXDataViewModelNotifier::ItemsAdded(wxDataViewItem const& parent, wxDataViewItemArray const& items)
110{
111 bool noFailureFlag;
112
113
114 // insert all valid items into control:
de40d736 115 noFailureFlag = m_DataViewCtrlPtr->GetDataViewPeer()->Add(parent,items);
e86edab0 116 // adjust row heights:
de40d736 117 AdjustRowHeights(items);
e86edab0
RR
118 // done:
119 return noFailureFlag;
120}
121
122bool wxOSXDataViewModelNotifier::ItemChanged(wxDataViewItem const& item)
123{
8d96f54d
VS
124 wxCHECK_MSG(item.IsOk(), false,"Changed item is invalid.");
125 wxCHECK_MSG(GetOwner() != NULL,false,"Owner not initialized.");
de40d736 126 if (m_DataViewCtrlPtr->GetDataViewPeer()->Update(GetOwner()->GetParent(item),item))
e86edab0
RR
127 {
128 // sent the equivalent wxWidget event:
ce7fe42e 129 wxDataViewEvent dataViewEvent(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED,m_DataViewCtrlPtr->GetId());
e86edab0 130
de40d736 131 dataViewEvent.SetEventObject(m_DataViewCtrlPtr);
e86edab0
RR
132 dataViewEvent.SetItem(item);
133 // sent the equivalent wxWidget event:
de40d736 134 m_DataViewCtrlPtr->HandleWindowEvent(dataViewEvent);
e86edab0 135 // row height may have to be adjusted:
de40d736 136 AdjustRowHeight(item);
b06ed2f8 137 AdjustAutosizedColumns();
e86edab0
RR
138 // done
139 return true;
140 }
141 else
142 return false;
143}
144
145bool wxOSXDataViewModelNotifier::ItemsChanged(wxDataViewItemArray const& items)
146{
147 size_t const noOfItems = items.GetCount();
148
ce7fe42e 149 wxDataViewEvent dataViewEvent(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED,m_DataViewCtrlPtr->GetId());
e86edab0
RR
150
151
de40d736 152 dataViewEvent.SetEventObject(m_DataViewCtrlPtr);
e86edab0 153 for (size_t indexItem=0; indexItem<noOfItems; ++indexItem)
de40d736 154 if (m_DataViewCtrlPtr->GetDataViewPeer()->Update(GetOwner()->GetParent(items[indexItem]),items[indexItem]))
e86edab0
RR
155 {
156 // send for all changed items a wxWidget event:
157 dataViewEvent.SetItem(items[indexItem]);
de40d736 158 m_DataViewCtrlPtr->HandleWindowEvent(dataViewEvent);
e86edab0
RR
159 }
160 else
161 return false;
162 // if this location is reached all items have been updated:
de40d736 163 AdjustRowHeights(items);
b06ed2f8 164 AdjustAutosizedColumns();
e86edab0
RR
165 // done:
166 return true;
167}
168
169bool wxOSXDataViewModelNotifier::ItemDeleted(wxDataViewItem const& parent, wxDataViewItem const& item)
170{
171 bool noFailureFlag;
172
173
8d96f54d 174 wxCHECK_MSG(item.IsOk(),false,"To be deleted item is invalid.");
e86edab0
RR
175 // when this method is called and currently an item is being edited this item may have already been deleted in the model (the passed item and the being edited item have
176 // not to be identical because the being edited item might be below the passed item in the hierarchy);
177 // to prevent the control trying to ask the model to update an already deleted item the control is informed that currently a deleting process
178 // has been started and that variables can currently not be updated even when requested by the system:
de40d736
VZ
179 m_DataViewCtrlPtr->SetDeleting(true);
180 noFailureFlag = m_DataViewCtrlPtr->GetDataViewPeer()->Remove(parent,item);
e86edab0 181 // enable automatic updating again:
de40d736 182 m_DataViewCtrlPtr->SetDeleting(false);
b06ed2f8
VS
183
184 AdjustAutosizedColumns();
e86edab0
RR
185 // done:
186 return noFailureFlag;
187}
188
189bool wxOSXDataViewModelNotifier::ItemsDeleted(wxDataViewItem const& parent, wxDataViewItemArray const& items)
190{
191 bool noFailureFlag;
192
193
194 // when this method is called and currently an item is being edited this item may have already been deleted in the model (the passed item and the being edited item have
195 // not to be identical because the being edited item might be below the passed item in the hierarchy);
196 // to prevent the control trying to ask the model to update an already deleted item the control is informed that currently a deleting process
197 // has been started and that variables can currently not be updated even when requested by the system:
de40d736 198 m_DataViewCtrlPtr->SetDeleting(true);
e86edab0 199 // delete all specified items:
de40d736 200 noFailureFlag = m_DataViewCtrlPtr->GetDataViewPeer()->Remove(parent,items);
e86edab0 201 // enable automatic updating again:
de40d736 202 m_DataViewCtrlPtr->SetDeleting(false);
b06ed2f8
VS
203
204 AdjustAutosizedColumns();
e86edab0
RR
205 // done:
206 return noFailureFlag;
207}
208
209bool wxOSXDataViewModelNotifier::ValueChanged(wxDataViewItem const& item, unsigned int col)
210{
8d96f54d
VS
211 wxCHECK_MSG(item.IsOk(), false,"Passed item is invalid.");
212 wxCHECK_MSG(GetOwner() != NULL,false,"Owner not initialized.");
de40d736 213 if (m_DataViewCtrlPtr->GetDataViewPeer()->Update(GetOwner()->GetParent(item),item))
e86edab0 214 {
ce7fe42e 215 wxDataViewEvent dataViewEvent(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED,m_DataViewCtrlPtr->GetId());
e86edab0 216
de40d736 217 dataViewEvent.SetEventObject(m_DataViewCtrlPtr);
e86edab0
RR
218 dataViewEvent.SetColumn(col);
219 dataViewEvent.SetItem(item);
220 // send the equivalent wxWidget event:
de40d736 221 m_DataViewCtrlPtr->HandleWindowEvent(dataViewEvent);
b06ed2f8
VS
222
223 AdjustAutosizedColumns();
e86edab0
RR
224 // done
225 return true;
226 }
227 else
228 return false;
229}
230
231bool wxOSXDataViewModelNotifier::Cleared()
232{
de40d736 233 return m_DataViewCtrlPtr->GetDataViewPeer()->Reload();
e86edab0
RR
234}
235
236void wxOSXDataViewModelNotifier::Resort()
237{
de40d736 238 m_DataViewCtrlPtr->GetDataViewPeer()->Resort();
e86edab0
RR
239}
240
241void wxOSXDataViewModelNotifier::AdjustRowHeight(wxDataViewItem const& item)
242{
de40d736 243 if ((m_DataViewCtrlPtr->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT) != 0)
e86edab0 244 {
de40d736 245 wxDataViewModel *model = GetOwner();
e86edab0
RR
246
247 int height = 20; // TODO find out standard height
de40d736 248 unsigned int num = m_DataViewCtrlPtr->GetColumnCount();
e86edab0
RR
249 unsigned int col;
250 for (col = 0; col < num; col++)
251 {
de40d736 252 wxDataViewColumn* column(m_DataViewCtrlPtr->GetColumnPtr(col));
608129e5 253
e86edab0
RR
254 if (!(column->IsHidden()))
255 {
256 wxDataViewCustomRenderer *renderer = dynamic_cast<wxDataViewCustomRenderer*>(column->GetRenderer());
257 if (renderer)
258 {
259 wxVariant value;
260 model->GetValue( value, item, column->GetModelColumn() );
261 renderer->SetValue( value );
262 height = wxMax( height, renderer->GetSize().y );
263 }
264 }
265 }
266 if (height > 20)
de40d736 267 m_DataViewCtrlPtr->GetDataViewPeer()->SetRowHeight(item,height);
e86edab0
RR
268 }
269}
270
271void wxOSXDataViewModelNotifier::AdjustRowHeights(wxDataViewItemArray const& items)
272{
de40d736 273 if ((m_DataViewCtrlPtr->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT) != 0)
e86edab0
RR
274 {
275 size_t const noOfItems = items.GetCount();
276
de40d736 277 wxDataViewModel *model = GetOwner();
e86edab0
RR
278
279 for (size_t itemIndex=0; itemIndex<noOfItems; ++itemIndex)
280 {
281 int height = 20; // TODO find out standard height
de40d736 282 unsigned int num = m_DataViewCtrlPtr->GetColumnCount();
e86edab0
RR
283 unsigned int col;
284
285 for (col = 0; col < num; col++)
286 {
de40d736 287 wxDataViewColumn* column(m_DataViewCtrlPtr->GetColumnPtr(col));
608129e5 288
e86edab0
RR
289 if (!(column->IsHidden()))
290 {
291 wxDataViewCustomRenderer *renderer = dynamic_cast<wxDataViewCustomRenderer*>(column->GetRenderer());
292 if (renderer)
293 {
294 wxVariant value;
295 model->GetValue( value, items[itemIndex], column->GetModelColumn() );
296 renderer->SetValue( value );
297 height = wxMax( height, renderer->GetSize().y );
298 }
299 }
300 }
301 if (height > 20)
de40d736 302 m_DataViewCtrlPtr->GetDataViewPeer()->SetRowHeight(items[itemIndex],height);
e86edab0
RR
303 }
304 }
305}
306
b06ed2f8
VS
307void wxOSXDataViewModelNotifier::AdjustAutosizedColumns()
308{
309 unsigned count = m_DataViewCtrlPtr->GetColumnCount();
310 for ( unsigned col = 0; col < count; col++ )
311 {
312 wxDataViewColumn *column = m_DataViewCtrlPtr->GetColumnPtr(col);
313
314 if ( column->GetWidthVariable() == wxCOL_WIDTH_AUTOSIZE )
315 m_DataViewCtrlPtr->GetDataViewPeer()->FitColumnWidthToContent(col);
316 }
317}
318
e86edab0
RR
319// ---------------------------------------------------------
320// wxDataViewCustomRenderer
321// The constructor, the implementation macro and environment
322// dependent methods can be found in the environment's
323// source file.
324// ---------------------------------------------------------
de40d736 325wxDataViewCustomRenderer::~wxDataViewCustomRenderer()
e86edab0 326{
de40d736 327 delete m_DCPtr;
e86edab0
RR
328}
329
e86edab0
RR
330wxDC* wxDataViewCustomRenderer::GetDC()
331{
de40d736
VZ
332 if ((m_DCPtr == NULL) && (GetOwner() != NULL) && (GetOwner()->GetOwner() != NULL))
333 m_DCPtr = new wxClientDC(GetOwner()->GetOwner());
334 return m_DCPtr;
e86edab0
RR
335}
336
337void wxDataViewCustomRenderer::SetDC(wxDC* newDCPtr)
338{
339 delete m_DCPtr;
340 m_DCPtr = newDCPtr;
341}
342
e86edab0
RR
343//-----------------------------------------------------------------------------
344// wxDataViewCtrl
345//-----------------------------------------------------------------------------
346
347wxDataViewCtrl::~wxDataViewCtrl()
348{
de40d736 349 ClearColumns();
a2c3fc7c
VZ
350
351 // Ensure that the already destructed controls is not notified about changes
352 // in the model any more.
353 if (m_ModelNotifier != NULL)
354 m_ModelNotifier->GetOwner()->RemoveNotifier(m_ModelNotifier);
e86edab0
RR
355}
356
357void wxDataViewCtrl::Init()
358{
359 m_CustomRendererPtr = NULL;
360 m_Deleting = false;
e86edab0 361 m_cgContext = NULL;
a2c3fc7c 362 m_ModelNotifier = NULL;
e86edab0
RR
363}
364
62e9285a
VZ
365bool wxDataViewCtrl::Create(wxWindow *parent,
366 wxWindowID id,
367 const wxPoint& pos,
368 const wxSize& size,
369 long style,
370 const wxValidator& validator,
371 const wxString& name)
e86edab0 372{
d15694e8 373 DontCreatePeer();
62e9285a 374 if (!(wxControl::Create(parent,id,pos,size,style,validator,name)))
e86edab0 375 return false;
22756322 376 SetPeer(::CreateDataView(this,parent,id,pos,size,style,GetExtraStyle()));
e86edab0 377
de40d736 378 MacPostControlCreate(pos,size);
e86edab0
RR
379
380 return true;
381}
382
383bool wxDataViewCtrl::AssociateModel(wxDataViewModel* model)
384{
de40d736 385 wxDataViewWidgetImpl* dataViewWidgetPtr(GetDataViewPeer());
e86edab0
RR
386
387
8d96f54d 388 wxCHECK_MSG(dataViewWidgetPtr != NULL,false,"Pointer to native control must not be NULL.");
a2c3fc7c
VZ
389
390 // We could have been associated with another model previously, break the
391 // association in this case.
392 if ( m_ModelNotifier )
393 m_ModelNotifier->GetOwner()->RemoveNotifier(m_ModelNotifier);
394
e86edab0
RR
395 if (wxDataViewCtrlBase::AssociateModel(model) && dataViewWidgetPtr->AssociateModel(model))
396 {
397 if (model != NULL)
a2c3fc7c
VZ
398 {
399 m_ModelNotifier = new wxOSXDataViewModelNotifier(this);
400 model->AddNotifier(m_ModelNotifier);
401 }
e86edab0
RR
402 return true;
403 }
404 else
405 return false;
406}
407
408bool wxDataViewCtrl::AppendColumn(wxDataViewColumn* columnPtr)
409{
410 return wxDataViewCtrl::InsertColumn( GetColumnCount(), columnPtr );
411}
412
413bool wxDataViewCtrl::PrependColumn(wxDataViewColumn* columnPtr)
414{
415 return wxDataViewCtrl::InsertColumn( 0, columnPtr );
416}
417
418bool wxDataViewCtrl::InsertColumn(unsigned int pos, wxDataViewColumn* columnPtr)
419{
de40d736 420 wxDataViewWidgetImpl* dataViewWidgetPtr(GetDataViewPeer());
e86edab0
RR
421
422 // first, some error checking:
8d96f54d
VS
423 wxCHECK_MSG(dataViewWidgetPtr != NULL, false,"Pointer to native control must not be NULL.");
424 wxCHECK_MSG(columnPtr != NULL, false,"Column pointer must not be NULL.");
425 wxCHECK_MSG(columnPtr->GetRenderer() != NULL, false,"Column does not have a renderer.");
426 wxCHECK_MSG(GetModel() != NULL, false,"No model associated with control.");
450b4305 427 wxCHECK_MSG(columnPtr->GetModelColumn() < GetModel()->GetColumnCount(),false,"Column's model column has no equivalent in the associated model.");
e86edab0
RR
428
429 // add column to wxWidget's internal structure:
de40d736 430 if (wxDataViewCtrlBase::InsertColumn(pos,columnPtr))
e86edab0 431 {
de40d736 432 m_ColumnPtrs.Add(columnPtr);
e86edab0
RR
433 // if the insertion in the native control is successful the rest can also be initialized:
434 if (dataViewWidgetPtr->InsertColumn(pos,columnPtr))
435 {
436 // make sure that the data is up-to-date...
437 // if the newly appended column is the first column add the initial data to the control and mark the column as an expander column,
438 // otherwise ask the control to 'update' the data in the newly appended column:
de40d736
VZ
439 if (GetColumnCount() == 1)
440 SetExpanderColumn(columnPtr);
e86edab0
RR
441 // done:
442 return true;
443 }
444 else
445 {
446 // clean-up:
de40d736 447 m_ColumnPtrs.Remove(columnPtr);
e86edab0
RR
448 delete columnPtr;
449 // and send a message in debug mode:
8d96f54d 450 wxFAIL_MSG("Column could not be added to native control.");
e86edab0
RR
451 // failed:
452 return false;
453 }
454 }
455 else
456 {
457 // clean-up:
458 delete columnPtr;
8d96f54d 459 wxFAIL_MSG("Could not add column to internal structures.");
e86edab0
RR
460 // failed:
461 return false;
462 }
463}
464
465bool wxDataViewCtrl::ClearColumns()
466{
de40d736 467 if (GetDataViewPeer()->ClearColumns())
e86edab0 468 {
de40d736 469 WX_CLEAR_ARRAY(m_ColumnPtrs);
e86edab0
RR
470 return true;
471 }
472 else
473 return false;
474}
475
476bool wxDataViewCtrl::DeleteColumn(wxDataViewColumn* columnPtr)
477{
de40d736 478 if (GetDataViewPeer()->DeleteColumn(columnPtr))
e86edab0 479 {
de40d736 480 m_ColumnPtrs.Remove(columnPtr);
e86edab0
RR
481 delete columnPtr;
482 return true;
483 }
484 else
485 return false;
486}
487
488wxDataViewColumn* wxDataViewCtrl::GetColumn(unsigned int pos) const
489{
de40d736 490 return GetDataViewPeer()->GetColumn(pos);
e86edab0
RR
491}
492
493unsigned int wxDataViewCtrl::GetColumnCount() const
494{
de40d736 495 return m_ColumnPtrs.GetCount();
e86edab0
RR
496}
497
498int wxDataViewCtrl::GetColumnPosition(wxDataViewColumn const* columnPtr) const
499{
de40d736 500 return GetDataViewPeer()->GetColumnPosition(columnPtr);
e86edab0
RR
501}
502
503void wxDataViewCtrl::Collapse(wxDataViewItem const& item)
504{
de40d736 505 GetDataViewPeer()->Collapse(item);
e86edab0
RR
506}
507
508void wxDataViewCtrl::EnsureVisible(wxDataViewItem const& item, wxDataViewColumn const* columnPtr)
509{
510 if (item.IsOk())
511 {
de40d736
VZ
512 ExpandAncestors(item); // make sure that the item exists in the control
513 GetDataViewPeer()->EnsureVisible(item,columnPtr);
e86edab0
RR
514 }
515}
516
517void wxDataViewCtrl::Expand(wxDataViewItem const& item)
518{
de40d736 519 return GetDataViewPeer()->Expand(item);
e86edab0
RR
520}
521
522bool wxDataViewCtrl::IsExpanded( const wxDataViewItem & item ) const
523{
de40d736 524 return (item.IsOk() && GetDataViewPeer()->IsExpanded(item));
e86edab0
RR
525}
526
527wxDataViewColumn* wxDataViewCtrl::GetSortingColumn() const
528{
de40d736 529 return GetDataViewPeer()->GetSortingColumn();
e86edab0
RR
530}
531
532unsigned int wxDataViewCtrl::GetCount() const
533{
de40d736 534 return GetDataViewPeer()->GetCount();
e86edab0
RR
535}
536
80ce465c
VZ
537wxDataViewItem wxDataViewCtrl::DoGetCurrentItem() const
538{
539 return GetDataViewPeer()->GetCurrentItem();
540}
541
542void wxDataViewCtrl::DoSetCurrentItem(const wxDataViewItem& item)
543{
544 GetDataViewPeer()->SetCurrentItem(item);
545}
546
ee1377e1
VS
547wxDataViewColumn *wxDataViewCtrl::GetCurrentColumn() const
548{
549 return GetDataViewPeer()->GetCurrentColumn();
550}
551
e86edab0
RR
552wxRect wxDataViewCtrl::GetItemRect(wxDataViewItem const& item, wxDataViewColumn const* columnPtr) const
553{
554 if (item.IsOk() && (columnPtr != NULL))
de40d736 555 return GetDataViewPeer()->GetRectangle(item,columnPtr);
e86edab0
RR
556 else
557 return wxRect();
558}
559
fa93d732 560int wxDataViewCtrl::GetSelectedItemsCount() const
e86edab0 561{
fa93d732 562 return GetDataViewPeer()->GetSelectedItemsCount();
e86edab0
RR
563}
564
565int wxDataViewCtrl::GetSelections(wxDataViewItemArray& sel) const
566{
de40d736 567 return GetDataViewPeer()->GetSelections(sel);
e86edab0
RR
568}
569
570void wxDataViewCtrl::HitTest(wxPoint const& point, wxDataViewItem& item, wxDataViewColumn*& columnPtr) const
571{
de40d736 572 return GetDataViewPeer()->HitTest(point,item,columnPtr);
e86edab0
RR
573}
574
575bool wxDataViewCtrl::IsSelected(wxDataViewItem const& item) const
576{
de40d736 577 return GetDataViewPeer()->IsSelected(item);
e86edab0
RR
578}
579
580void wxDataViewCtrl::Select(wxDataViewItem const& item)
581{
582 if (item.IsOk())
583 {
de40d736
VZ
584 ExpandAncestors(item); // make sure that the item exists in the control
585 GetDataViewPeer()->Select(item);
e86edab0
RR
586 }
587}
588
de40d736 589void wxDataViewCtrl::SelectAll()
e86edab0 590{
de40d736 591 GetDataViewPeer()->SelectAll();
e86edab0
RR
592}
593
594void wxDataViewCtrl::SetSelections(wxDataViewItemArray const& sel)
595{
596 size_t const noOfSelections = sel.GetCount();
597
598 size_t i;
599
600 wxDataViewItem last_parent;
601
602
603 // make sure that all to be selected items are visible in the control:
604 for (i = 0; i < noOfSelections; i++)
605 {
606 wxDataViewItem item = sel[i];
de40d736 607 wxDataViewItem parent = GetModel()->GetParent( item );
e86edab0
RR
608
609 if (parent.IsOk() && (parent != last_parent))
de40d736 610 ExpandAncestors(item);
e86edab0
RR
611 last_parent = parent;
612 }
613
614 // finally select the items:
de40d736 615 wxDataViewWidgetImpl* dataViewWidgetPtr(GetDataViewPeer()); // variable definition for abbreviational purposes
e86edab0
RR
616
617 for (i=0; i<noOfSelections; ++i)
618 dataViewWidgetPtr->Select(sel[i]);
619}
620
621void wxDataViewCtrl::Unselect(wxDataViewItem const& item)
622{
623 if (item.IsOk())
de40d736 624 GetDataViewPeer()->Unselect(item);
e86edab0
RR
625}
626
de40d736 627void wxDataViewCtrl::UnselectAll()
e86edab0 628{
de40d736 629 GetDataViewPeer()->UnselectAll();
e86edab0
RR
630}
631
632//
633// implementation
634//
de40d736 635wxDataViewWidgetImpl* wxDataViewCtrl::GetDataViewPeer() const
e86edab0 636{
de40d736 637 return dynamic_cast<wxDataViewWidgetImpl*>(GetPeer());
e86edab0
RR
638}
639
640void wxDataViewCtrl::AddChildren(wxDataViewItem const& parentItem)
641{
642 int noOfChildren;
643
644 wxDataViewItemArray items;
645
646
8d96f54d 647 wxCHECK_RET(GetModel() != NULL,"Model pointer not initialized.");
de40d736
VZ
648 noOfChildren = GetModel()->GetChildren(parentItem,items);
649 (void) GetModel()->ItemsAdded(parentItem,items);
e86edab0
RR
650}
651
907f09f4 652void wxDataViewCtrl::EditItem(const wxDataViewItem& item, const wxDataViewColumn *column)
eeea3b03 653{
907f09f4 654 GetDataViewPeer()->StartEditor(item, GetColumnPosition(column));
eeea3b03
RD
655}
656
de40d736 657void wxDataViewCtrl::FinishCustomItemEditing()
e86edab0 658{
de40d736 659 if (GetCustomRendererItem().IsOk())
e86edab0 660 {
de40d736
VZ
661 GetCustomRendererPtr()->FinishEditing();
662 SetCustomRendererItem(wxDataViewItem());
663 SetCustomRendererPtr (NULL);
e86edab0
RR
664 }
665}
666
667/*static*/
8f2a8de6
VZ
668wxVisualAttributes
669wxDataViewCtrl::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
e86edab0
RR
670{
671 wxVisualAttributes attr;
672
673 attr.colFg = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
674 attr.colBg = wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX );
7eb8aeb8
SC
675 static wxFont font = wxFont(wxOSX_SYSTEM_FONT_VIEWS);
676 attr.font = font;
e86edab0
RR
677
678 return attr;
679}
680
681// inherited methods from wxDataViewCtrlBase
682void wxDataViewCtrl::DoSetExpanderColumn()
683{
de40d736
VZ
684 if (GetExpanderColumn() != NULL)
685 GetDataViewPeer()->DoSetExpanderColumn(GetExpanderColumn());
e86edab0
RR
686}
687
688void wxDataViewCtrl::DoSetIndent()
689{
de40d736 690 GetDataViewPeer()->DoSetIndent(GetIndent());
e86edab0
RR
691}
692
693// event handling:
694void wxDataViewCtrl::OnSize(wxSizeEvent& event)
695{
de40d736 696 unsigned int const noOfColumns = GetColumnCount();
e86edab0
RR
697
698
699 // reset DC of all custom renderers because DC has changed:
700 for (unsigned int i=0; i<noOfColumns; ++i)
701 {
de40d736 702 wxDataViewColumn* dataViewColumnPtr(GetColumn(i));
e86edab0
RR
703
704 if (dataViewColumnPtr != NULL)
705 {
706 wxDataViewCustomRenderer* dataViewCustomRendererPtr(dynamic_cast<wxDataViewCustomRenderer*>(dataViewColumnPtr->GetRenderer()));
707
708 if (dataViewCustomRendererPtr != NULL)
709 dataViewCustomRendererPtr->SetDC(NULL);
710 }
711 }
712
713 // update the layout of the native control after a size event:
de40d736 714 GetDataViewPeer()->OnSize();
e86edab0
RR
715
716 event.Skip();
717}
718
35d85392
RR
719wxSize wxDataViewCtrl::DoGetBestSize() const
720{
721 wxSize best = wxControl::DoGetBestSize();
722 best.y = 80;
608129e5 723
35d85392
RR
724 return best;
725}
726
727void wxDataViewCtrl::OnMouse(wxMouseEvent& event)
728{
729 event.Skip();
608129e5 730
f0e867e9 731#if wxOSX_USE_CARBON
35d85392
RR
732 if (GetModel() == NULL)
733 return;
734
1f920487 735 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(GetPeer()));
35d85392
RR
736
737 int NoOfChildren;
738 wxDataViewItemArray items;
739 NoOfChildren = GetModel()->GetChildren( wxDataViewItem(), items);
740 if (NoOfChildren == 0)
741 return;
742 wxDataViewItem firstChild = items[0];
743
744 UInt16 headerHeight = 0;
745 MacDataViewListCtrlPtr->GetHeaderButtonHeight(&headerHeight);
608129e5
VZ
746
747
35d85392
RR
748 if (event.GetY() < headerHeight)
749 {
750 unsigned int col_count = GetColumnCount();
751 unsigned int col;
752 for (col = 0; col < col_count; col++)
753 {
754 wxDataViewColumn *column = GetColumn( col );
755 if (column->IsHidden())
756 continue;
608129e5 757
35d85392 758 Rect itemrect;
608129e5 759 ::GetDataBrowserItemPartBounds( MacDataViewListCtrlPtr->GetControlRef(),
1f920487 760 reinterpret_cast<DataBrowserItemID>(firstChild.GetID()), column->GetNativeData()->GetPropertyID(),
35d85392 761 kDataBrowserPropertyEnclosingPart, &itemrect );
608129e5 762
35d85392
RR
763 if (abs( event.GetX() - itemrect.right) < 3)
764 {
765 if (column->GetFlags() & wxDATAVIEW_COL_RESIZABLE)
766 SetCursor( wxCursor( wxCURSOR_SIZEWE ) );
767 else
768 SetCursor( *wxSTANDARD_CURSOR );
769 return;
770 }
771 }
608129e5 772
35d85392 773 }
35d85392
RR
774 SetCursor( *wxSTANDARD_CURSOR );
775#endif
776}
777
e86edab0
RR
778IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl,wxDataViewCtrlBase)
779
780BEGIN_EVENT_TABLE(wxDataViewCtrl,wxDataViewCtrlBase)
781 EVT_SIZE(wxDataViewCtrl::OnSize)
35d85392 782 EVT_MOTION(wxDataViewCtrl::OnMouse)
e86edab0
RR
783END_EVENT_TABLE()
784
785#endif // (wxUSE_DATAVIEWCTRL != 0) && (!defined(wxUSE_GENERICDATAVIEWCTRL) || (wxUSE_GENERICDATAVIEWCTRL == 0))
786