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