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