]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/osx/carbon/dataview.cpp
linking fix for wxUSE_VALIDATORS==0
[wxWidgets.git] / src / osx / carbon / dataview.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/osx/carbon/dataview.cpp
3// Purpose: wxDataViewCtrl native carbon implementation
4// Author:
5// Id: $Id: dataview.cpp 58317 2009-01-23
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 == 1) && !defined(wxUSE_GENERICDATAVIEWCTRL)
14
15#ifndef WX_PRECOMP
16 #include "wx/app.h"
17 #include "wx/toplevel.h"
18 #include "wx/font.h"
19 #include "wx/settings.h"
20 #include "wx/utils.h"
21#endif
22
23#include "wx/osx/carbon/dataview.h"
24#include "wx/osx/private.h"
25#include "wx/osx/uma.h"
26#include "wx/renderer.h"
27
28#include <limits>
29
30// ============================================================================
31// Variables used locally in dataview.cpp
32// ============================================================================
33static DataBrowserGetContextualMenuUPP gDataBrowserTableViewGetContextualMenuUPP = NULL;
34static DataBrowserItemCompareUPP gDataBrowserTableViewItemCompareUPP = NULL;
35static DataBrowserItemDataUPP gDataBrowserTableViewItemDataUPP = NULL;
36static DataBrowserItemNotificationUPP gDataBrowserTableViewItemNotificationUPP = NULL;
37
38static DataBrowserAcceptDragUPP gDataBrowserTableViewAcceptDragUPP = NULL;
39static DataBrowserAddDragItemUPP gDataBrowserTableViewAddDragItemUPP = NULL;
40static DataBrowserReceiveDragUPP gDataBrowserTableViewReceiveDragUPP = NULL;
41
42static DataBrowserDrawItemUPP gDataBrowserTableViewDrawItemUPP = NULL;
43static DataBrowserEditItemUPP gDataBrowserTableViewEditItemUPP = NULL;
44static DataBrowserHitTestUPP gDataBrowserTableViewHitTestUPP = NULL;
45static DataBrowserTrackingUPP gDataBrowserTableViewTrackingUPP = NULL;
46
47// ============================================================================
48// Functions used locally in dataview.cpp
49// ============================================================================
50static DataBrowserItemID* CreateDataBrowserItemIDArray(size_t& noOfEntries, wxDataViewItemArray const& items) // returns a newly allocated pointer to valid data browser item IDs
51{
52 size_t const noOfItems = items.GetCount();
53
54 DataBrowserItemID* itemIDs(new DataBrowserItemID[noOfItems]);
55
56
57 // convert all valid data view items to data browser items
58 noOfEntries = 0;
59 for (size_t i=0; i<noOfItems; ++i)
60 if (items[i].IsOk())
61 {
62 itemIDs[noOfEntries] = reinterpret_cast<DataBrowserItemID>(items[i].GetID());
63 ++noOfEntries;
64 }
65 // done:
66 return itemIDs;
67}
68
69static const EventTypeSpec eventList[] =
70{
71 { kEventClassControl, kEventControlHit },
72 { kEventClassControl, kEventControlDraw }
73};
74
75static pascal OSStatus DataBrowserCtrlEventHandler(EventHandlerCallRef handler, EventRef EventReference, void* Data)
76{
77 wxDataViewCtrl* DataViewCtrlPtr((wxDataViewCtrl*) Data); // the 'Data' variable always contains a pointer to the data view control that installed the handler
78
79 wxMacCarbonEvent CarbonEvent(EventReference) ;
80
81
82 switch (GetEventKind(EventReference))
83 {
84 case kEventControlDraw:
85 {
86 OSStatus status;
87
88 DataViewCtrlPtr->MacSetDrawingContext(CarbonEvent.GetParameter<CGContextRef>(kEventParamCGContextRef,typeCGContextRef));
89 status = ::CallNextEventHandler(handler,EventReference);
90 DataViewCtrlPtr->MacSetDrawingContext(NULL);
91 return status;
92 }
93 case kEventControlHit :
94 if (CarbonEvent.GetParameter<ControlPartCode>(kEventParamControlPart,typeControlPartCode) == kControlButtonPart) // we only care about the header
95 {
96 ControlRef controlReference;
97 DataBrowserPropertyID columnPropertyID;
98 DataBrowserSortOrder order;
99 unsigned long columnIndex;
100 wxDataViewColumn* column;
101 OSStatus status;
102 wxDataViewEvent DataViewEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK,DataViewCtrlPtr->GetId());
103
104 CarbonEvent.GetParameter(kEventParamDirectObject,&controlReference);
105 // determine the column that triggered the event (this is the column that is responsible for sorting the data view):
106 status = ::GetDataBrowserSortProperty(controlReference,&columnPropertyID);
107 wxCHECK(status == noErr,status);
108 status = ::GetDataBrowserTableViewColumnPosition(controlReference,columnPropertyID,&columnIndex);
109 if (status == errDataBrowserPropertyNotFound) // user clicked into part of the header that does not have a property
110 return ::CallNextEventHandler(handler,EventReference);
111 wxCHECK(status == noErr,status);
112 column = DataViewCtrlPtr->GetColumn(columnIndex);
113 // set the column sort order:
114 status = ::GetDataBrowserSortOrder(controlReference,&order);
115 wxCHECK(status == noErr,status);
116 column->SetSortOrderVariable(order == kDataBrowserOrderIncreasing);
117 // initialize wxWidget event handler:
118 DataViewEvent.SetEventObject(DataViewCtrlPtr);
119 DataViewEvent.SetColumn(columnIndex);
120 DataViewEvent.SetDataViewColumn(column);
121 // finally sent the equivalent wxWidget event:
122 DataViewCtrlPtr->HandleWindowEvent(DataViewEvent);
123 return ::CallNextEventHandler(handler,EventReference);
124 }
125 else
126 return eventNotHandledErr;
127 }
128 return eventNotHandledErr;
129}
130
131static bool InitializeColumnDescription(DataBrowserListViewColumnDesc& columnDescription, wxDataViewColumn const* columnPtr, wxCFStringRef const& title)
132{
133 // set properties for the column:
134 columnDescription.propertyDesc.propertyID = columnPtr->GetNativeData()->GetPropertyID();
135 columnDescription.propertyDesc.propertyType = columnPtr->GetRenderer()->GetNativeData()->GetPropertyType();
136 columnDescription.propertyDesc.propertyFlags = kDataBrowserListViewSelectionColumn; // make the column selectable
137 if (columnPtr->IsReorderable())
138 columnDescription.propertyDesc.propertyFlags |= kDataBrowserListViewMovableColumn;
139 if (columnPtr->IsResizeable())
140 {
141 columnDescription.headerBtnDesc.minimumWidth = 0;
142 columnDescription.headerBtnDesc.maximumWidth = 30000; // 32767 is the theoretical maximum though but 30000 looks nicer
143 }
144 else
145 {
146 columnDescription.headerBtnDesc.minimumWidth = columnPtr->GetWidth();
147 columnDescription.headerBtnDesc.maximumWidth = columnPtr->GetWidth();
148 }
149 if (columnPtr->IsSortable())
150 columnDescription.propertyDesc.propertyFlags |= kDataBrowserListViewSortableColumn;
151 if ((columnPtr->GetRenderer()->GetMode() == wxDATAVIEW_CELL_EDITABLE) ||
152 (columnPtr->GetRenderer()->GetMode() == wxDATAVIEW_CELL_ACTIVATABLE))
153 columnDescription.propertyDesc.propertyFlags |= kDataBrowserPropertyIsEditable;
154 if ((columnDescription.propertyDesc.propertyType == kDataBrowserCustomType) ||
155 (columnDescription.propertyDesc.propertyType == kDataBrowserDateTimeType) ||
156 (columnDescription.propertyDesc.propertyType == kDataBrowserIconAndTextType) ||
157 (columnDescription.propertyDesc.propertyType == kDataBrowserTextType))
158 columnDescription.propertyDesc.propertyFlags |= kDataBrowserListViewTypeSelectColumn; // enables generally the possibility to have user input for the mentioned types
159#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
160 columnDescription.propertyDesc.propertyFlags |= kDataBrowserListViewNoGapForIconInHeaderButton;
161#endif
162 // set header's properties:
163 columnDescription.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
164 columnDescription.headerBtnDesc.titleOffset = 0;
165 columnDescription.headerBtnDesc.titleString = ::CFStringCreateCopy(kCFAllocatorDefault,title);
166 columnDescription.headerBtnDesc.initialOrder = kDataBrowserOrderIncreasing; // choose one of the orders as "undefined" is not supported anyway (s. ControlDefs.h in the HIToolbox framework)
167 columnDescription.headerBtnDesc.btnFontStyle.flags = kControlUseFontMask | kControlUseJustMask;
168 switch (columnPtr->GetAlignment())
169 {
170 case wxALIGN_CENTER:
171 case wxALIGN_CENTER_HORIZONTAL:
172 columnDescription.headerBtnDesc.btnFontStyle.just = teCenter;
173 break;
174 case wxALIGN_LEFT:
175 columnDescription.headerBtnDesc.btnFontStyle.just = teFlushLeft;
176 break;
177 case wxALIGN_RIGHT:
178 columnDescription.headerBtnDesc.btnFontStyle.just = teFlushRight;
179 break;
180 default:
181 columnDescription.headerBtnDesc.btnFontStyle.just = teFlushDefault;
182 }
183 columnDescription.headerBtnDesc.btnFontStyle.font = kControlFontViewSystemFont;
184 columnDescription.headerBtnDesc.btnFontStyle.style = normal;
185 if (columnPtr->GetBitmap().IsOk())
186 {
187 columnDescription.headerBtnDesc.btnContentInfo.contentType = kControlContentIconRef;
188 columnDescription.headerBtnDesc.btnContentInfo.u.iconRef = columnPtr->GetBitmap().GetIconRef();
189 }
190 else
191 {
192 // not text only as we otherwise could not add a bitmap later
193 // columnDescription.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly;
194 columnDescription.headerBtnDesc.btnContentInfo.contentType = kControlContentIconRef;
195 columnDescription.headerBtnDesc.btnContentInfo.u.iconRef = NULL;
196 }
197
198 // done:
199 return true;
200}
201
202// ============================================================================
203// Type definitions of locally used function pointers
204// ============================================================================
205DEFINE_ONE_SHOT_HANDLER_GETTER(DataBrowserCtrlEventHandler)
206
207// ============================================================================
208// Helper functions for dataview implementation on OSX
209// ============================================================================
210wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(parent), wxWindowID WXUNUSED(id), wxPoint const& pos, wxSize const& size,
211 long style, long WXUNUSED(extraStyle))
212{
213 return new wxMacDataViewDataBrowserListViewControl(wxpeer,pos,size,style);
214}
215
216// ============================================================================
217// wxMacDataBrowserTableViewControl
218// ============================================================================
219pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserCompareProc(ControlRef browser, DataBrowserItemID itemOneID, DataBrowserItemID itemTwoID, DataBrowserPropertyID sortProperty)
220{
221 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
222
223
224 if (ControlPtr != NULL)
225 return ControlPtr->DataBrowserCompareProc(itemOneID,itemTwoID,sortProperty);
226 else
227 return FALSE;
228} /* wxMacDataBrowserTableViewControl::DataBrowserCompareProc(ControlRef, DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID) */
229
230pascal void wxMacDataBrowserTableViewControl::DataBrowserGetContextualMenuProc(ControlRef browser, MenuRef* menu, UInt32* helpType, CFStringRef* helpItemString, AEDesc* selection)
231{
232 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
233
234
235 if (ControlPtr != NULL)
236 ControlPtr->DataBrowserGetContextualMenuProc(menu,helpType,helpItemString,selection);
237} /* wxMacDataBrowserTableViewControl::DataBrowserGetContextualMenuProc(ControlRef, MenuRef*, UInt32*, CFStringRef*, AEDesc*) */
238
239pascal OSStatus wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemDataRef itemData, Boolean getValue)
240{
241 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
242
243
244 if (ControlPtr != NULL)
245 return ControlPtr->DataBrowserGetSetItemDataProc(itemID,propertyID,itemData,getValue);
246 else
247 return errDataBrowserPropertyNotSupported;
248} /* wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemDataRef, Boolean) */
249
250pascal void wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserItemNotification message, DataBrowserItemDataRef itemData)
251{
252 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
253
254
255 if (ControlPtr != NULL)
256 ControlPtr->DataBrowserItemNotificationProc(itemID,message,itemData);
257} /* wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc(ControlRef, DataBrowserItemID, DataBrowserItemNotification, DataBrowserItemDataRef) */
258
259pascal void wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemState state, Rect const* rectangle, SInt16 bitDepth, Boolean colorDevice)
260{
261 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
262
263
264 if (ControlPtr != NULL)
265 ControlPtr->DataBrowserDrawItemProc(itemID,propertyID,state,rectangle,bitDepth,colorDevice);
266} /* wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemState, Rect const*, SInt16, Boolean) */
267
268pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserEditItemProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, CFStringRef theString, Rect* maxEditTextRect, Boolean* shrinkToFit)
269{
270 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
271
272
273 return ((ControlPtr != NULL) && ControlPtr->DataBrowserEditItemProc(itemID,propertyID,theString,maxEditTextRect,shrinkToFit));
274} /* wxMacDataBrowserTableViewControl::DataBrowserEditItemProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, CFStringRef, Rect*, Boolean*) */
275
276pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserHitTestProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, Rect const* theRect, Rect const* mouseRect)
277{
278 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
279
280
281 return ((ControlPtr != NULL) && ControlPtr->DataBrowserHitTestProc(itemID,propertyID,theRect,mouseRect));
282} /* wxMacDataBrowserTableViewControl::DataBrowserHitTestProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, Rect const*, Rect const*) */
283
284pascal DataBrowserTrackingResult wxMacDataBrowserTableViewControl::DataBrowserTrackingProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, Rect const* theRect, Point startPt, EventModifiers modifiers)
285{
286 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
287
288
289 if (ControlPtr != NULL)
290 return ControlPtr->DataBrowserTrackingProc(itemID,propertyID,theRect,startPt,modifiers);
291 else
292 return kDataBrowserNothingHit;
293} /* wxMacDataBrowserTableViewControl::DataBrowserTrackingProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, Rect const*, Point, EventModifiers) */
294
295pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserAcceptDragProc(ControlRef browser, DragReference dragRef, DataBrowserItemID itemID)
296{
297 wxMacDataBrowserTableViewControl* controlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
298
299
300 return ((controlPtr != NULL) && controlPtr->DataBrowserAcceptDragProc(dragRef,itemID));
301} /* wxMacDataBrowserTableViewControl::DataBrowserAcceptDragProc(ControlRef, DragReference, DataBrowserItemID) */
302
303pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserAddDragItemProc(ControlRef browser, DragReference dragRef, DataBrowserItemID itemID, ItemReference* itemRef)
304{
305 wxMacDataBrowserTableViewControl* controlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
306
307
308 return ((controlPtr != NULL) && controlPtr->DataBrowserAddDragItemProc(dragRef,itemID,itemRef));
309} /* wxMacDataBrowserTableViewControl::DataBrowserAddDragItemProc(ControlRef, DragReference, DataBrowserItemID, ItemReference*) */
310
311pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserReceiveDragProc(ControlRef browser, DragReference dragRef, DataBrowserItemID itemID)
312{
313 wxMacDataBrowserTableViewControl* controlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
314
315
316 return ((controlPtr != NULL) && controlPtr->DataBrowserReceiveDragProc(dragRef,itemID));
317} /* wxMacDataBrowserTableViewControl::DataBrowserReceiveDragProc(ControlRef, DragReference, DataBrowserItemID) */
318
319wxMacDataBrowserTableViewControl::wxMacDataBrowserTableViewControl(wxWindow* peer, wxPoint const& pos, wxSize const& size, long style)
320 :wxMacControl(peer)
321{
322 Rect bounds = wxMacGetBoundsForControl(peer,pos,size);
323 OSStatus err = ::CreateDataBrowserControl(MAC_WXHWND(peer->MacGetTopLevelWindowRef()),&bounds,kDataBrowserListView,&(this->m_controlRef));
324
325
326 SetReferenceInNativeControl();
327 verify_noerr(err);
328
329 ::InstallControlEventHandler(this->m_controlRef, GetDataBrowserCtrlEventHandlerUPP(), GetEventTypeCount(eventList), eventList, peer, (EventHandlerRef *)&m_macDataViewCtrlEventHandler);
330
331 // setup standard callbacks:
332 if (gDataBrowserTableViewGetContextualMenuUPP == NULL) gDataBrowserTableViewGetContextualMenuUPP = NewDataBrowserGetContextualMenuUPP(wxMacDataBrowserTableViewControl::DataBrowserGetContextualMenuProc);
333 if (gDataBrowserTableViewItemCompareUPP == NULL) gDataBrowserTableViewItemCompareUPP = NewDataBrowserItemCompareUPP (wxMacDataBrowserTableViewControl::DataBrowserCompareProc);
334 if (gDataBrowserTableViewItemDataUPP == NULL) gDataBrowserTableViewItemDataUPP = NewDataBrowserItemDataUPP (wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc);
335 if (gDataBrowserTableViewItemNotificationUPP == NULL)
336 {
337 gDataBrowserTableViewItemNotificationUPP =
338#if TARGET_API_MAC_OSX
339 (DataBrowserItemNotificationUPP) NewDataBrowserItemNotificationWithItemUPP(wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc);
340#else
341 NewDataBrowserItemNotificationUPP(wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc);
342#endif
343 }
344 // setup drag and drop callbacks:
345 if (gDataBrowserTableViewAcceptDragUPP == NULL) gDataBrowserTableViewAcceptDragUPP = NewDataBrowserAcceptDragUPP (wxMacDataBrowserTableViewControl::DataBrowserAcceptDragProc);
346 if (gDataBrowserTableViewAddDragItemUPP == NULL) gDataBrowserTableViewAddDragItemUPP = NewDataBrowserAddDragItemUPP(wxMacDataBrowserTableViewControl::DataBrowserAddDragItemProc);
347 if (gDataBrowserTableViewReceiveDragUPP == NULL) gDataBrowserTableViewReceiveDragUPP = NewDataBrowserReceiveDragUPP(wxMacDataBrowserTableViewControl::DataBrowserReceiveDragProc);
348
349 DataBrowserCallbacks callbacks; // variable definition
350
351 InitializeDataBrowserCallbacks(&callbacks,kDataBrowserLatestCallbacks);
352 callbacks.u.v1.getContextualMenuCallback = gDataBrowserTableViewGetContextualMenuUPP;
353 callbacks.u.v1.itemDataCallback = gDataBrowserTableViewItemDataUPP;
354 callbacks.u.v1.itemCompareCallback = gDataBrowserTableViewItemCompareUPP;
355 callbacks.u.v1.itemNotificationCallback = gDataBrowserTableViewItemNotificationUPP;
356 callbacks.u.v1.acceptDragCallback = gDataBrowserTableViewAcceptDragUPP;
357 callbacks.u.v1.addDragItemCallback = gDataBrowserTableViewAddDragItemUPP;
358 callbacks.u.v1.receiveDragCallback = gDataBrowserTableViewReceiveDragUPP;
359 this->SetCallbacks(&callbacks);
360
361 // setup callbacks for customized items:
362 if (gDataBrowserTableViewDrawItemUPP == NULL) gDataBrowserTableViewDrawItemUPP = NewDataBrowserDrawItemUPP(wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc);
363 if (gDataBrowserTableViewEditItemUPP == NULL) gDataBrowserTableViewEditItemUPP = NewDataBrowserEditItemUPP(wxMacDataBrowserTableViewControl::DataBrowserEditItemProc);
364 if (gDataBrowserTableViewHitTestUPP == NULL) gDataBrowserTableViewHitTestUPP = NewDataBrowserHitTestUPP (wxMacDataBrowserTableViewControl::DataBrowserHitTestProc);
365 if (gDataBrowserTableViewTrackingUPP == NULL) gDataBrowserTableViewTrackingUPP = NewDataBrowserTrackingUPP(wxMacDataBrowserTableViewControl::DataBrowserTrackingProc);
366
367 DataBrowserCustomCallbacks customCallbacks; // variable definition
368
369 InitializeDataBrowserCustomCallbacks(&customCallbacks,kDataBrowserLatestCallbacks);
370 customCallbacks.u.v1.drawItemCallback = gDataBrowserTableViewDrawItemUPP;
371 customCallbacks.u.v1.editTextCallback = gDataBrowserTableViewEditItemUPP;
372 customCallbacks.u.v1.hitTestCallback = gDataBrowserTableViewHitTestUPP;
373 customCallbacks.u.v1.trackingCallback = gDataBrowserTableViewTrackingUPP;
374 this->SetCustomCallbacks(&customCallbacks);
375
376 // style setting:
377 this->EnableCellSizeModification( ((style & wxDV_VARIABLE_LINE_HEIGHT) != 0), true );
378
379 DataBrowserSelectionFlags flags; // variable definition
380
381 if (this->GetSelectionFlags(&flags) == noErr) // get default settings
382 {
383 if ((style & wxDV_MULTIPLE) != 0)
384 flags &= ~kDataBrowserSelectOnlyOne;
385 else
386 flags |= kDataBrowserSelectOnlyOne;
387 (void) this->SetSelectionFlags(flags);
388 }
389
390 OptionBits attributes; // variable definition
391
392 if (this->GetAttributes(&attributes) == noErr) // get default settings
393 {
394 if ((style & wxDV_VERT_RULES) != 0)
395 attributes |= kDataBrowserAttributeListViewDrawColumnDividers;
396 else
397 attributes &= ~kDataBrowserAttributeListViewDrawColumnDividers;
398 if ((style & wxDV_ROW_LINES) != 0)
399 attributes |= kDataBrowserAttributeListViewAlternatingRowColors;
400 else
401 attributes &= ~kDataBrowserAttributeListViewAlternatingRowColors;
402 (void) this->SetAttributes(attributes);
403 }
404
405 if ((style & wxDV_NO_HEADER) != 0)
406 this->SetHeaderButtonHeight(0);
407} /* wxMacDataBrowserTableViewControl::wxMacDataBrowserTableViewControl(wxWindow*, wxPoint const&, wxSize const&, long) */
408
409wxMacDataBrowserTableViewControl::~wxMacDataBrowserTableViewControl(void)
410{
411 ::RemoveEventHandler((EventHandlerRef) m_macDataViewCtrlEventHandler);
412} /* wxMacDataBrowserTableViewControl::~wxMacDataBrowserTableViewControl(void) */
413
414//
415// callback handling
416//
417OSStatus wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks const* callbacks)
418{
419 return ::SetDataBrowserCallbacks(this->m_controlRef,callbacks);
420} /* wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks const*) */
421
422OSStatus wxMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks const* customCallbacks)
423{
424 return ::SetDataBrowserCustomCallbacks(this->m_controlRef,customCallbacks);
425} /* xMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks const*) */
426
427//
428// DnD handling
429//
430OSStatus wxMacDataBrowserTableViewControl::EnableAutomaticDragTracking(bool enable)
431{
432 return ::SetAutomaticControlDragTrackingEnabledForWindow(::GetControlOwner(this->m_controlRef),enable);
433}
434
435//
436// header handling
437//
438OSStatus wxMacDataBrowserTableViewControl::GetHeaderDesc(DataBrowserPropertyID propertyID, DataBrowserListViewHeaderDesc* desc) const
439{
440 desc->version = kDataBrowserListViewLatestHeaderDesc; // if this statement is missing the next call will fail (NOT DOCUMENTED!!)
441 return ::GetDataBrowserListViewHeaderDesc(this->m_controlRef,propertyID,desc);
442}
443
444OSStatus wxMacDataBrowserTableViewControl::SetHeaderDesc(DataBrowserPropertyID propertyID, DataBrowserListViewHeaderDesc* desc)
445{
446 return ::SetDataBrowserListViewHeaderDesc(this->m_controlRef,propertyID,desc);
447}
448
449//
450// layout handling
451//
452OSStatus wxMacDataBrowserTableViewControl::AutoSizeColumns()
453{
454 return AutoSizeDataBrowserListViewColumns(this->m_controlRef);
455}
456
457OSStatus wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool enableHeight, bool enableWidth)
458{
459 return ::SetDataBrowserTableViewGeometry(this->GetControlRef(),enableWidth,enableHeight);
460} /* wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool, bool) */
461
462OSStatus wxMacDataBrowserTableViewControl::GetAttributes(OptionBits* attributes)
463{
464 return ::DataBrowserGetAttributes(this->GetControlRef(),attributes);
465} /* wxMacDataBrowserTableViewControl::GetAttributes(OptionBits*) */
466
467OSStatus wxMacDataBrowserTableViewControl::GetColumnWidth(DataBrowserPropertyID propertyID, UInt16* width) const
468{
469 return ::GetDataBrowserTableViewNamedColumnWidth(this->m_controlRef,propertyID,width);
470}
471
472OSStatus wxMacDataBrowserTableViewControl::GetDefaultColumnWidth( UInt16 *width ) const
473{
474 return GetDataBrowserTableViewColumnWidth(this->m_controlRef, width );
475}
476
477OSStatus wxMacDataBrowserTableViewControl::GetDefaultRowHeight(UInt16* height) const
478{
479 return ::GetDataBrowserTableViewRowHeight(this->m_controlRef,height);
480}
481
482OSStatus wxMacDataBrowserTableViewControl::GetHeaderButtonHeight(UInt16 *height)
483{
484 return ::GetDataBrowserListViewHeaderBtnHeight(this->m_controlRef,height);
485}
486
487OSStatus wxMacDataBrowserTableViewControl::GetPartBounds(DataBrowserItemID item, DataBrowserPropertyID propertyID, DataBrowserPropertyPart part, Rect* bounds)
488{
489 return ::GetDataBrowserItemPartBounds(this->m_controlRef,item,propertyID,part,bounds);
490} /* wxMacDataBrowserTableViewControl::GetPartBounds(DataBrowserItemID, DataBrowswerPropertyID, DataBrowserPropertyPart, Rect*) */
491
492OSStatus wxMacDataBrowserTableViewControl::GetRowHeight(DataBrowserItemID item, UInt16* height) const
493{
494 return ::GetDataBrowserTableViewItemRowHeight(this->m_controlRef,item,height);
495} /* wxMacDataBrowserTableViewControl::GetRowHeight(DataBrowserItemID, UInt16*) const */
496
497OSStatus wxMacDataBrowserTableViewControl::GetScrollPosition( UInt32 *top , UInt32 *left ) const
498{
499 return GetDataBrowserScrollPosition(this->m_controlRef, top , left );
500}
501
502OSStatus wxMacDataBrowserTableViewControl::SetAttributes(OptionBits attributes)
503{
504 return ::DataBrowserChangeAttributes(this->GetControlRef(),attributes,~attributes);
505} /* wxMacDataBrowserTableViewControl::SetAttributes(OptionBits) */
506
507OSStatus wxMacDataBrowserTableViewControl::SetColumnWidth(DataBrowserPropertyID propertyID, UInt16 width)
508{
509 return ::SetDataBrowserTableViewNamedColumnWidth(this->m_controlRef,propertyID,width);
510}
511
512OSStatus wxMacDataBrowserTableViewControl::SetDefaultColumnWidth(UInt16 width)
513{
514 return ::SetDataBrowserTableViewColumnWidth(this->m_controlRef,width);
515}
516
517OSStatus wxMacDataBrowserTableViewControl::SetDefaultRowHeight(UInt16 height)
518{
519 return ::SetDataBrowserTableViewRowHeight(this->m_controlRef,height);
520}
521
522OSStatus wxMacDataBrowserTableViewControl::SetHasScrollBars(bool horiz, bool vert)
523{
524 return ::SetDataBrowserHasScrollBars(this->m_controlRef,horiz,vert);
525} /* wxMacDataBrowserTableViewControl::SetHasScrollBars(bool, bool) */
526
527OSStatus wxMacDataBrowserTableViewControl::SetHeaderButtonHeight(UInt16 height)
528{
529 return ::SetDataBrowserListViewHeaderBtnHeight(this->m_controlRef,height);
530} /* wxMacDataBrowserTableViewControl::SetHeaderButtonHeight(UInt16) */
531
532OSStatus wxMacDataBrowserTableViewControl::SetHiliteStyle(DataBrowserTableViewHiliteStyle hiliteStyle)
533{
534 return ::SetDataBrowserTableViewHiliteStyle(this->m_controlRef,hiliteStyle);
535} /*wxMacDataBrowserTableViewControl::SetHiliteStyle(DataBrowserTableViewHiliteStyle) */
536
537OSStatus wxMacDataBrowserTableViewControl::SetIndent(float Indent)
538{
539 return ::DataBrowserSetMetric(this->m_controlRef,kDataBrowserMetricDisclosureColumnPerDepthGap,true,Indent);
540} /* wxMacDataBrowserTableViewControl::SetIndent(float* Indent) */
541
542OSStatus wxMacDataBrowserTableViewControl::SetItemRowHeight(DataBrowserItemID item, UInt16 height)
543{
544 return ::SetDataBrowserTableViewItemRowHeight(this->m_controlRef,item,height);
545}
546
547OSStatus wxMacDataBrowserTableViewControl::SetScrollPosition(UInt32 top, UInt32 left)
548{
549 return ::SetDataBrowserScrollPosition(this->m_controlRef,top,left);
550}
551
552//
553// column handling
554//
555OSStatus wxMacDataBrowserTableViewControl::GetColumnCount(UInt32* numColumns) const
556{
557 return ::GetDataBrowserTableViewColumnCount(this->m_controlRef,numColumns);
558}
559
560OSStatus wxMacDataBrowserTableViewControl::GetColumnIndex(DataBrowserPropertyID propertyID, DataBrowserTableViewColumnIndex* index) const
561{
562 return ::GetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,index);
563} /* wxMacDataBrowserTableViewControl::GetColumnIndex(DataBrowserPropertyID, DataBrowserTableViewColumnIndex*) const */
564
565OSStatus wxMacDataBrowserTableViewControl::GetFreePropertyID(DataBrowserPropertyID* propertyID) const
566{
567 for (*propertyID=kMinPropertyID; *propertyID<std::numeric_limits<DataBrowserPropertyID>::max(); ++(*propertyID))
568 if (this->IsUsedPropertyID(*propertyID) == errDataBrowserPropertyNotFound)
569 return noErr;
570 return errDataBrowserPropertyNotSupported;
571} /* wxMacDataBrowserTableViewControl::GetFreePropertyID(DataBrowserPropertyID*) const */
572
573OSStatus wxMacDataBrowserTableViewControl::GetPropertyFlags(DataBrowserPropertyID propertyID, DataBrowserPropertyFlags *flags) const
574{
575 return ::GetDataBrowserPropertyFlags(this->m_controlRef,propertyID,flags);
576}
577
578OSStatus wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserItemDataRef itemData, DataBrowserPropertyID* propertyID) const
579{
580 return ::GetDataBrowserItemDataProperty(itemData,propertyID);
581} /* wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserItemDataRef, DataBrowserPropertyID*) */
582
583OSStatus wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserTableViewColumnIndex index, DataBrowserTableViewColumnID* propertyID) const
584{
585 return ::GetDataBrowserTableViewColumnProperty(this->m_controlRef,index,propertyID);
586} /* wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserTableViewColumnIndex, DataBrowserTableViewColumnID*) */
587
588OSStatus wxMacDataBrowserTableViewControl::IsUsedPropertyID(DataBrowserPropertyID propertyID) const
589{
590 // as the Mac interface does not provide a function that checks if the property id is in use or not a function is chosen that should not
591 // lead to a large overhead for the call but returns an error code if the property id does not exist, here we use the function that returns
592 // the column position for the property id:
593 DataBrowserTableViewColumnIndex index;
594
595 return ::GetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,&index);
596} /* wxMacDataBrowserTableViewControl::IsUsedPropertyId(DataBrowserPropertyID) const */
597
598OSStatus wxMacDataBrowserTableViewControl::RemoveColumnByProperty(DataBrowserTableViewColumnID propertyID)
599{
600 return ::RemoveDataBrowserTableViewColumn(this->m_controlRef,propertyID);
601} /* wxMacDataBrowserTableViewControl::RemoveColumnByProperty(DataBrowserTableViewColumnID) */
602
603OSStatus wxMacDataBrowserTableViewControl::RemoveColumnByIndex(DataBrowserTableViewColumnIndex index)
604{
605 DataBrowserTableViewColumnID propertyID;
606
607
608 this->GetPropertyID(index,&propertyID);
609 return ::RemoveDataBrowserTableViewColumn(this->m_controlRef,propertyID);
610} /* wxMacDataBrowserTableViewControl::RemoveColumnByIndex(DataBrowserTableViewColumnIndex) */
611
612OSStatus wxMacDataBrowserTableViewControl::SetColumnIndex(DataBrowserPropertyID propertyID, DataBrowserTableViewColumnIndex index)
613{
614 return ::SetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,index);
615} /* wxMacDataBrowserTableViewControl::SetColumnIndex(DataBrowserPropertyID, DataBrowserTableViewColumnIndex) */
616
617OSStatus wxMacDataBrowserTableViewControl::SetDisclosureColumn(DataBrowserPropertyID propertyID, Boolean expandableRows)
618{
619 return ::SetDataBrowserListViewDisclosureColumn(this->m_controlRef,propertyID,expandableRows);
620}
621
622OSStatus wxMacDataBrowserTableViewControl::SetPropertyFlags(DataBrowserPropertyID propertyID, DataBrowserPropertyFlags flags)
623{
624 return ::SetDataBrowserPropertyFlags(this->m_controlRef,propertyID,flags);
625} /* wxMacDataBrowserTableViewControl::SetPropertyFlags(DataBrowserPropertyID, DataBrowserPropertyFlags) */
626
627//
628// item handling
629//
630OSStatus wxMacDataBrowserTableViewControl::AddItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty)
631{
632 return ::AddDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty);
633} /* wxMacDataBrowserTableViewControl::AddItems(DataBrowserItemID, UInt32, DataBrowserItemID const*, DataBrowserPropertyID) */
634
635OSStatus wxMacDataBrowserTableViewControl::GetFreeItemID(DataBrowserItemID* id) const
636{
637 ItemCount noOfItems;
638
639 OSStatus status;
640
641
642 status = this->GetItemCount(&noOfItems);
643 wxCHECK_MSG(status == noErr,status,_("Could not retrieve number of items"));
644 if (noOfItems == 0)
645 {
646 *id = 1;
647 return noErr;
648 }
649 else
650 {
651 // as there might be a lot of items in the data browser and mostly the data is added item by item the largest used ID number is roughly in the order of magnitude
652 // as the number of items; therefore, start from the number of items to look for a new ID:
653 for (*id=noOfItems; *id<std::numeric_limits<DataBrowserItemID>::max(); ++(*id))
654 if (this->IsUsedItemID(*id) == errDataBrowserItemNotFound)
655 return noErr;
656 // as the first approach was not successful, try from the beginning:
657 for (*id=0; *id<noOfItems; ++(*id))
658 if (this->IsUsedItemID(*id) == errDataBrowserItemNotFound)
659 return noErr;
660 // sorry, data browser is full:
661 return errDataBrowserItemNotAdded;
662 }
663} /* wxMacDataBrowserTableViewControl::GetFreeItemID(DataBrowserItemID*) const */
664
665OSStatus wxMacDataBrowserTableViewControl::GetItemCount(DataBrowserItemID container, Boolean recurse, DataBrowserItemState state, ItemCount* numItems) const
666{
667 return GetDataBrowserItemCount(this->m_controlRef,container,recurse,state,numItems);
668} /* wxMacDataBrowserTableViewControl::GetItemCount(DataBrowserItemID, Boolean, DataBrowserItemState, ItemCount*) const */
669
670OSStatus wxMacDataBrowserTableViewControl::GetItemID( DataBrowserTableViewRowIndex row, DataBrowserItemID * item ) const
671{
672 return GetDataBrowserTableViewItemID(this->m_controlRef,row,item);
673}
674
675OSStatus wxMacDataBrowserTableViewControl::GetItems(DataBrowserItemID container, Boolean recurse, DataBrowserItemState state, Handle items) const
676{
677 return GetDataBrowserItems(this->m_controlRef,container,recurse,state,items);
678} /* wxMacDataBrowserTableViewControl::GetItems(DataBrowserItemID, Boolean, DataBrowserItemState, Handle) const */
679
680OSStatus wxMacDataBrowserTableViewControl::GetItemRow(DataBrowserItemID item, DataBrowserTableViewRowIndex* row) const
681{
682 return GetDataBrowserTableViewItemRow(this->m_controlRef,item,row);
683}
684
685OSStatus wxMacDataBrowserTableViewControl::GetItemState(DataBrowserItemID item, DataBrowserItemState* state) const
686{
687 return ::GetDataBrowserItemState(this->m_controlRef,item,state);
688}
689
690OSStatus wxMacDataBrowserTableViewControl::IsUsedItemID(DataBrowserItemID itemID) const
691{
692 // as the Mac interface does not provide a function that checks if the property id is in use or not a function is chosen that should not
693 // lead to a large overhead for the call but returns an error code if the property id does not exist, here we use the function that returns
694 // the column position for the property id:
695 DataBrowserTableViewColumnIndex index;
696
697 return ::GetDataBrowserTableViewItemRow(this->m_controlRef,itemID,&index);
698} /* wxMacDataBrowserTableViewControl::IsUsedItemID(DataBrowserItemID) const */
699
700OSStatus wxMacDataBrowserTableViewControl::RemoveItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty)
701{
702 return ::RemoveDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty);
703}
704
705OSStatus wxMacDataBrowserTableViewControl::RevealItem(DataBrowserItemID item, DataBrowserPropertyID propertyID, DataBrowserRevealOptions options) const
706{
707 return ::RevealDataBrowserItem(this->m_controlRef,item,propertyID,options);
708} /* wxMacDataBrowserTableViewControl::RevealItem(DataBrowserItemID item, DataBrowserPropertyID propertyID, DataBrowserRevealOptions options) const */
709
710OSStatus wxMacDataBrowserTableViewControl::UpdateItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty,
711 DataBrowserPropertyID propertyID) const
712{
713 return UpdateDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty,propertyID);
714}
715
716//
717// item selection
718//
719size_t wxMacDataBrowserTableViewControl::GetSelectedItemIDs(wxArrayDataBrowserItemID& itemIDs) const
720{
721 DataBrowserItemID* itemIDPtr;
722 Handle handle(::NewHandle(0));
723
724 size_t noOfItems;
725
726
727 wxCHECK_MSG(this->GetItems(kDataBrowserNoItem,true,kDataBrowserItemIsSelected,handle) == noErr,0,_("Could not get selected items."));
728 noOfItems = static_cast<size_t>(::GetHandleSize(handle)/sizeof(DataBrowserItemID));
729 itemIDs.Empty();
730 itemIDs.Alloc(noOfItems);
731 HLock(handle);
732 itemIDPtr = (DataBrowserItemID*) (*handle);
733 for (size_t i=0; i<noOfItems; ++i)
734 {
735 itemIDs.Add(*itemIDPtr);
736 ++itemIDPtr;
737 }
738 HUnlock(handle);
739 DisposeHandle(handle);
740 return noOfItems;
741} /* wxMacDataBrowserTableViewControl::GetSelectedItemIDs(wxArrayDataBrowserItemID&) const*/
742
743OSStatus wxMacDataBrowserTableViewControl::GetSelectionAnchor(DataBrowserItemID* first, DataBrowserItemID* last) const
744{
745 return ::GetDataBrowserSelectionAnchor(this->m_controlRef,first,last);
746} /* wxMacDataBrowserTableViewControl::GetSelectionAnchor(DataBrowserItemID*, DataBrowserItemID*) const */
747
748OSStatus wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags* flags) const
749{
750 return ::GetDataBrowserSelectionFlags(this->m_controlRef,flags);
751} /* wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags*) const */
752
753bool wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID item) const
754{
755 return ::IsDataBrowserItemSelected(this->m_controlRef,item);
756} /* wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID) const */
757
758OSStatus wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags flags)
759{
760 return ::SetDataBrowserSelectionFlags(this->m_controlRef,flags);
761} /* wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags) */
762
763OSStatus wxMacDataBrowserTableViewControl::SetSelectedItems(UInt32 numItems, DataBrowserItemID const* items, DataBrowserSetOption operation)
764{
765 return ::SetDataBrowserSelectedItems(this->m_controlRef, numItems, items, operation );
766} /* wxMacDataBrowserTableViewControl::SetSelectedItems(UInt32, DataBrowserItemID const*, DataBrowserSetOption) */
767
768OSStatus wxMacDataBrowserTableViewControl::GetSortOrder(DataBrowserSortOrder* order) const
769{
770 return ::GetDataBrowserSortOrder(this->m_controlRef,order);
771}
772
773OSStatus wxMacDataBrowserTableViewControl::GetSortProperty(DataBrowserPropertyID* propertyID) const
774{
775 return ::GetDataBrowserSortProperty(this->m_controlRef,propertyID);
776}
777
778OSStatus wxMacDataBrowserTableViewControl::Resort(DataBrowserItemID container, Boolean sortChildren)
779{
780 return ::SortDataBrowserContainer(this->m_controlRef,container,sortChildren);
781} /* wxMacDataBrowserTableViewControl::Resort(DataBrowserItemID, Boolean) */
782
783OSStatus wxMacDataBrowserTableViewControl::SetSortOrder(DataBrowserSortOrder order)
784{
785 return ::SetDataBrowserSortOrder(this->m_controlRef,order);
786}
787
788OSStatus wxMacDataBrowserTableViewControl::SetSortProperty(DataBrowserPropertyID propertyID)
789{
790 return ::SetDataBrowserSortProperty(this->m_controlRef,propertyID);
791}
792
793//
794// container handling
795//
796OSStatus wxMacDataBrowserTableViewControl::CloseContainer(DataBrowserItemID containerID)
797{
798 return ::CloseDataBrowserContainer(this->m_controlRef,containerID);
799} /* wxMacDataBrowserTableViewControl::CloseContainer(DataBrowserItemID) */
800
801OSStatus wxMacDataBrowserTableViewControl::OpenContainer(DataBrowserItemID containerID)
802{
803 return ::OpenDataBrowserContainer(this->m_controlRef,containerID);
804} /* wxMacDataBrowserTableViewControl::OpenContainer(DataBrowserItemID) */
805
806IMPLEMENT_ABSTRACT_CLASS(wxMacDataBrowserTableViewControl,wxMacControl)
807
808// ============================================================================
809// wxMacDataBrowserListViewControl
810// ============================================================================
811#pragma mark -
812//
813// column handling
814//
815OSStatus wxMacDataBrowserListViewControl::AddColumn(DataBrowserListViewColumnDesc *columnDesc, DataBrowserTableViewColumnIndex position)
816{
817 return AddDataBrowserListViewColumn(this->m_controlRef,columnDesc,position);
818} /* wxMacDataBrowserListViewControl::AddColumn(DataBrowserListViewColumnDesc*, DataBrowserTableViewColumnIndex) */
819
820// ============================================================================
821// wxMacDataViewDataBrowserListViewControl
822// ============================================================================
823#pragma mark -
824//
825// constructors / destructor
826//
827wxMacDataViewDataBrowserListViewControl::wxMacDataViewDataBrowserListViewControl(wxWindow* peer, wxPoint const& pos, wxSize const& size, long style)
828 :wxMacDataBrowserListViewControl(peer,pos,size,style)
829{
830 if ((style & wxBORDER_NONE) != 0)
831 this->SetData(kControlNoPart,kControlDataBrowserIncludesFrameAndFocusTag,(Boolean) false);
832 (void) this->EnableAutomaticDragTracking();
833 (void) this->SetHiliteStyle(kDataBrowserTableViewFillHilite);
834} /* wxMacDataViewDataBrowserListViewControl::wxMacDataViewDataBrowserListViewControl(wxWindow* , const wxPoint&, const wxSize&, long) */
835
836//
837// column related methods (inherited from wxDataViewWidgetImpl)
838//
839bool wxMacDataViewDataBrowserListViewControl::ClearColumns(void)
840{
841 UInt32 noOfColumns;
842
843
844 wxCHECK_MSG(this->GetColumnCount(&noOfColumns) == noErr,false,_("Could not determine number of columns."));
845 for (UInt32 i=0; i<noOfColumns; ++i)
846 wxCHECK_MSG(this->RemoveColumnByIndex(0) == noErr,false,_("Could not remove column."));
847 return true;
848}
849
850bool wxMacDataViewDataBrowserListViewControl::DeleteColumn(wxDataViewColumn* columnPtr)
851{
852 return (this->RemoveColumnByProperty(columnPtr->GetNativeData()->GetPropertyID()) == noErr);
853}
854
855void wxMacDataViewDataBrowserListViewControl::DoSetExpanderColumn(wxDataViewColumn const* columnPtr)
856{
857 this->SetDisclosureColumn(columnPtr->GetNativeData()->GetPropertyID(),false); // second parameter explicitely passed to ensure that arrow is centered
858}
859
860wxDataViewColumn* wxMacDataViewDataBrowserListViewControl::GetColumn(unsigned int pos) const
861{
862 DataBrowserPropertyID propertyID;
863
864
865 if (this->GetPropertyID(pos,&propertyID) == noErr)
866 return this->GetColumnPtr(propertyID);
867 else
868 return NULL;
869}
870
871int wxMacDataViewDataBrowserListViewControl::GetColumnPosition(wxDataViewColumn const* columnPtr) const
872{
873 if (columnPtr != NULL)
874 {
875 DataBrowserTableViewColumnIndex Position;
876
877 wxCHECK_MSG(this->GetColumnIndex(columnPtr->GetNativeData()->GetPropertyID(),&Position) == noErr,wxNOT_FOUND,_("Could not determine column's position"));
878 return static_cast<int>(Position);
879 }
880 else
881 return wxNOT_FOUND;
882}
883
884bool wxMacDataViewDataBrowserListViewControl::InsertColumn(unsigned int pos, wxDataViewColumn* columnPtr)
885{
886 DataBrowserListViewColumnDesc columnDescription;
887
888 DataBrowserPropertyID newPropertyID;
889
890 UInt32 noOfColumns;
891
892 wxCFStringRef title(columnPtr->GetTitle(),m_font.Ok() ? dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer())->GetFont().GetEncoding() : wxLocale::GetSystemEncoding());
893
894
895 // try to get new ID for the column:
896 wxCHECK_MSG(this->GetFreePropertyID(&newPropertyID) == noErr,false,_("Cannot create new column's ID. Probably max. number of columns reached."));
897 // set native data:
898 columnPtr->GetNativeData()->SetPropertyID(newPropertyID);
899 // create a column description, add column to the native control and do some final layout adjustments:
900 wxCHECK_MSG(::InitializeColumnDescription(columnDescription,columnPtr,title), false,_("Column description could not be initialized."));
901 wxCHECK_MSG(this->AddColumn(&columnDescription,pos) == noErr, false,_("Column could not be added."));
902 wxCHECK_MSG(this->SetColumnWidth(newPropertyID,columnPtr->GetWidth()) == noErr,false,_("Column width could not be set."));
903 wxCHECK_MSG(this->GetColumnCount(&noOfColumns) == noErr, false,_("Number of columns could not be determined."));
904 if (noOfColumns == 1)
905 {
906 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
907
908 wxCHECK_MSG(dataViewCtrlPtr != NULL,false,_("wxWidget's control not initialized."));
909 dataViewCtrlPtr->AddChildren(wxDataViewItem());
910 return true;
911 }
912 else
913 return this->Update(columnPtr);
914}
915
916//
917// item related methods (inherited from wxDataViewWidgetImpl)
918//
919bool wxMacDataViewDataBrowserListViewControl::Add(wxDataViewItem const& parent, wxDataViewItem const& item)
920{
921 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
922
923
924 return (( parent.IsOk() && this->AddItem(reinterpret_cast<DataBrowserItemID>(parent.GetID()),&itemID) == noErr) ||
925 (!(parent.IsOk()) && this->AddItem(kDataBrowserNoItem,&itemID) == noErr));
926}
927
928bool wxMacDataViewDataBrowserListViewControl::Add(wxDataViewItem const& parent, wxDataViewItemArray const& items)
929{
930 bool noFailureFlag;
931
932 DataBrowserItemID* itemIDs;
933
934 size_t noOfEntries;
935
936
937 // convert all valid data view items to data browser items:
938 itemIDs = ::CreateDataBrowserItemIDArray(noOfEntries,items);
939 // insert all valid items into control:
940 noFailureFlag = ((noOfEntries == 0) ||
941 !(parent.IsOk()) && (this->AddItems(kDataBrowserNoItem,noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr) ||
942 parent.IsOk() && (this->AddItems(reinterpret_cast<DataBrowserItemID>(parent.GetID()),noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr));
943 // give allocated array space free again:
944 delete[] itemIDs;
945 // done:
946 return noFailureFlag;
947}
948
949void wxMacDataViewDataBrowserListViewControl::Collapse(wxDataViewItem const& item)
950{
951 this->CloseContainer(reinterpret_cast<DataBrowserItemID>(item.GetID()));
952}
953
954void wxMacDataViewDataBrowserListViewControl::EnsureVisible(wxDataViewItem const& item, const wxDataViewColumn* columnPtr)
955{
956 DataBrowserPropertyID propertyID;
957
958
959 if (columnPtr != NULL)
960 propertyID = columnPtr->GetNativeData()->GetPropertyID();
961 else
962 propertyID = kDataBrowserNoItem;
963 this->RevealItem(reinterpret_cast<DataBrowserItemID>(item.GetID()),propertyID,kDataBrowserRevealOnly);
964}
965
966void wxMacDataViewDataBrowserListViewControl::Expand(wxDataViewItem const& item)
967{
968 this->OpenContainer(reinterpret_cast<DataBrowserItemID>(item.GetID()));
969}
970
971unsigned int wxMacDataViewDataBrowserListViewControl::GetCount(void) const
972{
973 ItemCount noOfItems;
974
975
976 wxCHECK_MSG(this->GetItemCount(&noOfItems) == noErr,0,_("Could not determine number of items"));
977 return noOfItems;
978}
979
980wxRect wxMacDataViewDataBrowserListViewControl::GetRectangle(wxDataViewItem const& item, wxDataViewColumn const* columnPtr)
981{
982 Rect MacRectangle;
983
984
985 if (this->GetPartBounds(reinterpret_cast<DataBrowserItemID>(item.GetID()),columnPtr->GetNativeData()->GetPropertyID(),kDataBrowserPropertyContentPart,&MacRectangle) == noErr)
986 {
987 wxRect rectangle;
988
989 ::wxMacNativeToRect(&MacRectangle,&rectangle);
990 return rectangle;
991 }
992 else
993 return wxRect();
994}
995
996bool wxMacDataViewDataBrowserListViewControl::IsExpanded(wxDataViewItem const& item) const
997{
998 DataBrowserItemState state = 0;
999
1000 if (this->GetItemState(reinterpret_cast<DataBrowserItemID>(item.GetID()),&state) != noErr)
1001 return false;
1002
1003 return ((state & kDataBrowserContainerIsOpen) != 0);
1004}
1005
1006bool wxMacDataViewDataBrowserListViewControl::Reload(void)
1007{
1008 bool noFailureFlag;
1009
1010 wxDataViewItemArray dataViewChildren;
1011
1012
1013 noFailureFlag = (this->RemoveItems() == noErr);
1014 this->SetScrollPosition(0,0); // even after having removed all items the scrollbars may remain at their old position -> reset them
1015 this->GetDataViewCtrl()->GetModel()->GetChildren(wxDataViewItem(),dataViewChildren);
1016 this->GetDataViewCtrl()->GetModel()->ItemsAdded(wxDataViewItem(),dataViewChildren);
1017
1018 return noFailureFlag;
1019}
1020
1021bool wxMacDataViewDataBrowserListViewControl::Remove(wxDataViewItem const& parent, wxDataViewItem const& item)
1022{
1023 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1024
1025
1026 return (this->RemoveItem(reinterpret_cast<DataBrowserItemID>(parent.GetID()),&itemID) == noErr);
1027}
1028
1029bool wxMacDataViewDataBrowserListViewControl::Remove(wxDataViewItem const& parent, wxDataViewItemArray const& items)
1030{
1031 bool noFailureFlag;
1032
1033 DataBrowserItemID* itemIDs;
1034
1035 size_t noOfEntries;
1036
1037
1038 // convert all valid data view items to data browser items:
1039 itemIDs = ::CreateDataBrowserItemIDArray(noOfEntries,items);
1040 // insert all valid items into control:
1041 noFailureFlag = ((noOfEntries == 0) ||
1042 !(parent.IsOk()) && (this->RemoveItems(kDataBrowserNoItem,noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr) ||
1043 parent.IsOk() && (this->RemoveItems(reinterpret_cast<DataBrowserItemID>(parent.GetID()),noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr));
1044 // give allocated array space free again:
1045 delete[] itemIDs;
1046 // done:
1047 return noFailureFlag;
1048}
1049
1050bool wxMacDataViewDataBrowserListViewControl::Update(wxDataViewColumn const* columnPtr)
1051{
1052 return (this->UpdateItems(kDataBrowserNoItem,0,NULL,kDataBrowserItemNoProperty,columnPtr->GetNativeData()->GetPropertyID()) == noErr);
1053}
1054
1055bool wxMacDataViewDataBrowserListViewControl::Update(wxDataViewItem const& parent, wxDataViewItem const& item)
1056{
1057 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1058
1059
1060 if (parent.IsOk())
1061 return (this->UpdateItem(reinterpret_cast<DataBrowserItemID>(parent.GetID()),&itemID) == noErr);
1062 else
1063 return (this->UpdateItem(kDataBrowserNoItem,&itemID) == noErr);
1064}
1065
1066bool wxMacDataViewDataBrowserListViewControl::Update(wxDataViewItem const& parent, wxDataViewItemArray const& items)
1067{
1068 bool noFailureFlag;
1069
1070 DataBrowserItemID* itemIDs;
1071
1072 size_t noOfEntries;
1073
1074
1075 // convert all valid data view items to data browser items:
1076 itemIDs = ::CreateDataBrowserItemIDArray(noOfEntries,items);
1077 if (parent.IsOk())
1078 noFailureFlag = (this->UpdateItems(reinterpret_cast<DataBrowserItemID>(parent.GetID()),noOfEntries,itemIDs,kDataBrowserItemNoProperty,kDataBrowserItemNoProperty) == noErr);
1079 else
1080 noFailureFlag = (this->UpdateItems(kDataBrowserNoItem,noOfEntries,itemIDs,kDataBrowserItemNoProperty,kDataBrowserItemNoProperty) == noErr);
1081 // release allocated array space:
1082 delete[] itemIDs;
1083 // done:
1084 return noFailureFlag;
1085}
1086
1087//
1088// model related methods
1089//
1090bool wxMacDataViewDataBrowserListViewControl::AssociateModel(wxDataViewModel* WXUNUSED(model))
1091{
1092 return true;
1093}
1094
1095//
1096// selection related methods (inherited from wxDataViewWidgetImpl)
1097//
1098int wxMacDataViewDataBrowserListViewControl::GetSelections(wxDataViewItemArray& sel) const
1099{
1100 size_t noOfSelectedItems;
1101
1102 wxArrayDataBrowserItemID itemIDs;
1103
1104
1105 noOfSelectedItems = this->GetSelectedItemIDs(itemIDs);
1106 sel.Empty();
1107 sel.SetCount(noOfSelectedItems);
1108 for (size_t i=0; i<noOfSelectedItems; ++i)
1109 sel[i] = wxDataViewItem(reinterpret_cast<void*>(itemIDs[i]));
1110 return static_cast<int>(noOfSelectedItems);
1111}
1112
1113bool wxMacDataViewDataBrowserListViewControl::IsSelected(wxDataViewItem const& item) const
1114{
1115 return this->IsItemSelected(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1116}
1117
1118void wxMacDataViewDataBrowserListViewControl::Select(wxDataViewItem const& item)
1119{
1120 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1121
1122
1123 this->SetSelectedItems(1,&itemID,kDataBrowserItemsAdd);
1124}
1125
1126void wxMacDataViewDataBrowserListViewControl::SelectAll(void)
1127{
1128 DataBrowserItemID* itemIDPtr;
1129
1130 Handle handle(::NewHandle(0));
1131
1132 size_t noOfItems;
1133
1134
1135 wxCHECK_RET(this->GetItems(kDataBrowserNoItem,true,kDataBrowserItemAnyState,handle) == noErr,_("Could not get items."));
1136 noOfItems = static_cast<size_t>(::GetHandleSize(handle)/sizeof(DataBrowserItemID));
1137 ::HLock(handle);
1138 itemIDPtr = (DataBrowserItemID*) (*handle);
1139 this->SetSelectedItems(noOfItems,itemIDPtr,kDataBrowserItemsAssign);
1140 ::HUnlock(handle);
1141 ::DisposeHandle(handle);
1142}
1143
1144void wxMacDataViewDataBrowserListViewControl::Unselect(wxDataViewItem const& item)
1145{
1146 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1147
1148
1149 this->SetSelectedItems(1,&itemID,kDataBrowserItemsRemove);
1150}
1151
1152void wxMacDataViewDataBrowserListViewControl::UnselectAll(void)
1153{
1154 DataBrowserItemID* itemIDPtr;
1155
1156 Handle handle(::NewHandle(0));
1157
1158 size_t noOfItems;
1159
1160
1161 wxCHECK_RET(this->GetItems(kDataBrowserNoItem,true,kDataBrowserItemAnyState,handle) == noErr,_("Could not get items."));
1162 noOfItems = static_cast<size_t>(::GetHandleSize(handle)/sizeof(DataBrowserItemID));
1163 ::HLock(handle);
1164 itemIDPtr = (DataBrowserItemID*) (*handle);
1165 this->SetSelectedItems(noOfItems,itemIDPtr,kDataBrowserItemsRemove);
1166 ::HUnlock(handle);
1167 ::DisposeHandle(handle);
1168}
1169
1170//
1171// sorting related methods
1172//
1173wxDataViewColumn* wxMacDataViewDataBrowserListViewControl::GetSortingColumn(void) const
1174{
1175 DataBrowserPropertyID propertyID;
1176
1177
1178 if (this->GetSortProperty(&propertyID) == noErr)
1179 return this->GetColumnPtr(propertyID);
1180 else
1181 return NULL;
1182}
1183
1184void wxMacDataViewDataBrowserListViewControl::Resort(void)
1185{
1186 (void) this->Resort();
1187}
1188
1189//
1190// other methods (inherited from wxDataViewWidgetImpl)
1191//
1192void
1193wxMacDataViewDataBrowserListViewControl::HitTest(const wxPoint& WXUNUSED(point),
1194 wxDataViewItem& item,
1195 wxDataViewColumn*& columnPtr) const
1196{
1197 // not yet implemented:
1198 item = wxDataViewItem();
1199 columnPtr = NULL;
1200}
1201
1202void wxMacDataViewDataBrowserListViewControl::DoSetIndent(int indent)
1203{
1204 this->SetIndent(static_cast<float>(indent));
1205}
1206
1207void wxMacDataViewDataBrowserListViewControl::SetRowHeight(wxDataViewItem const& item, unsigned int height)
1208{
1209 this->SetItemRowHeight(reinterpret_cast<DataBrowserItemID>(item.GetID()),static_cast<UInt16>(height));
1210}
1211
1212void wxMacDataViewDataBrowserListViewControl::OnSize(void)
1213{
1214 UInt32 noOfColumns;
1215
1216
1217 this->GetColumnCount(&noOfColumns);
1218 if (noOfColumns <= 1) // no horizontal scroll bar and the only column expands to the width of the whole control
1219 {
1220 this->SetHasScrollBars(false,true);
1221 this->AutoSizeColumns();
1222 }
1223 else // otherwise keep the current column size and have scrollbars in both directions
1224 this->SetHasScrollBars(true,true);
1225}
1226
1227//
1228// callback functions (inherited from wxMacDataBrowserTableViewControl)
1229//
1230Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID itemOneID, DataBrowserItemID itemTwoID, DataBrowserPropertyID sortProperty)
1231{
1232 DataBrowserSortOrder sortOrder;
1233
1234 DataBrowserTableViewColumnIndex modelColumnIndex;
1235
1236 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
1237
1238
1239 wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly."));
1240 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
1241 if (sortProperty >= kMinPropertyID)
1242 {
1243 // variable definition and initialization:
1244 wxDataViewColumn* ColumnPtr(this->GetColumnPtr(sortProperty));
1245
1246 wxCHECK_MSG(ColumnPtr != NULL,false,_("Could not determine column index."));
1247 modelColumnIndex = ColumnPtr->GetModelColumn();
1248 }
1249 else
1250 modelColumnIndex = 0;
1251 this->GetSortOrder(&sortOrder);
1252 return static_cast<Boolean>(dataViewCtrlPtr->GetModel()->Compare(wxDataViewItem(reinterpret_cast<void*>(itemOneID)),wxDataViewItem(reinterpret_cast<void*>(itemTwoID)),
1253 modelColumnIndex,sortOrder != kDataBrowserOrderDecreasing) < 0);
1254} /* wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID) */
1255
1256void wxMacDataViewDataBrowserListViewControl::DataBrowserGetContextualMenuProc(MenuRef* menu, UInt32* helpType, CFStringRef* helpItemString, AEDesc* WXUNUSED(selection))
1257 // In this method we do not supply a contextual menu handler at all but only send a wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU.
1258{
1259 wxArrayDataBrowserItemID itemIDs;
1260
1261 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
1262
1263
1264 wxCHECK_RET(dataViewCtrlPtr != NULL,_("wxWidget control pointer is not a data view pointer"));
1265 // initialize parameters so that no context menu will be displayed automatically by the native data browser:
1266 *menu = NULL;
1267 *helpType = kCMHelpItemNoHelp;
1268 *helpItemString = NULL;
1269 // create information for a context menu event:
1270 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU,dataViewCtrlPtr->GetId());
1271
1272 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1273 dataViewEvent.SetModel(dataViewCtrlPtr->GetModel());
1274 // get the item information;
1275 // theoretically more than one ID can be returned but the event can only handle one item, therefore all item related data is using the data of the first item in the array:
1276 if (this->GetSelectedItemIDs(itemIDs) > 0)
1277 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemIDs[0])));
1278 // finally send the equivalent wxWidget event:
1279 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1280} /* wxMacDataViewDataBrowserListViewControl::DataBrowserGetContextualMenuProc(MenuRef*, UInt32*, CFStringRef*, AEDesc*) */
1281
1282OSStatus wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemDataRef itemData, Boolean getValue)
1283{
1284 if (getValue)
1285 {
1286 // variable definitions:
1287 wxDataViewCtrl* dataViewCtrlPtr;
1288
1289 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1290 wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
1291 if (dataViewCtrlPtr->IsDeleting())
1292 return noErr; // if a delete process is running the data of editable fields cannot be saved because the associated model variable may already have been deleted
1293 else
1294 {
1295 // variable definitions:
1296 OSStatus errorStatus;
1297 wxDataViewColumn* dataViewColumnPtr;
1298
1299 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,errDataBrowserNotConfigured,_("Pointer to model not set correctly."));
1300 dataViewColumnPtr = this->GetColumnPtr(propertyID);
1301 wxCHECK_MSG((dataViewColumnPtr != NULL) && (dataViewColumnPtr->GetRenderer() != NULL),errDataBrowserNotConfigured,_("There is no column or renderer for the specified column index."));
1302
1303 wxDataViewItem dvItem(reinterpret_cast<void*>(itemID));
1304 unsigned int col = dataViewColumnPtr->GetModelColumn();
1305
1306 switch (dataViewColumnPtr->GetRenderer()->GetNativeData()->GetPropertyType())
1307 {
1308 case kDataBrowserCheckboxType:
1309 {
1310 // variable definition:
1311 ThemeButtonValue buttonValue;
1312
1313 errorStatus = ::GetDataBrowserItemDataButtonValue(itemData,&buttonValue);
1314 if (errorStatus == noErr)
1315 {
1316 if (buttonValue == kThemeButtonOn)
1317 {
1318 // variable definition and initialization:
1319 wxVariant modifiedData(true);
1320
1321 if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData, dvItem, col) &&
1322 dataViewCtrlPtr->GetModel()->ValueChanged(dvItem, col))
1323 return noErr;
1324 else
1325 return errDataBrowserInvalidPropertyData;
1326 }
1327 else if (buttonValue == kThemeButtonOff)
1328 {
1329 // variable definition and initialization:
1330 wxVariant modifiedData(false);
1331
1332 if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData, dvItem, col) &&
1333 dataViewCtrlPtr->GetModel()->ValueChanged(dvItem, col))
1334 return noErr;
1335 else
1336 return errDataBrowserInvalidPropertyData;
1337 }
1338 else
1339 return errDataBrowserInvalidPropertyData;
1340 }
1341 else
1342 return errorStatus;
1343 } /* block */
1344 case kDataBrowserTextType:
1345 {
1346 // variable definitions:
1347 CFStringRef stringReference;
1348
1349 errorStatus = ::GetDataBrowserItemDataText(itemData,&stringReference);
1350 if (errorStatus == noErr)
1351 {
1352 // variable definitions and initializations:
1353#if wxCHECK_VERSION(2,9,0)
1354 wxCFStringRef modifiedString(stringReference);
1355#else
1356 wxMacCFStringHolder modifiedString(stringReference);
1357#endif
1358 wxVariant modifiedData(modifiedString.AsString());
1359
1360 if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData, dvItem, col) &&
1361 dataViewCtrlPtr->GetModel()->ValueChanged(dvItem, col))
1362 return noErr;
1363 else
1364 return errDataBrowserInvalidPropertyData;
1365 }
1366 else
1367 return errorStatus;
1368 } /* block */
1369 default:
1370 return errDataBrowserPropertyNotSupported;
1371 }
1372 }
1373 }
1374 else
1375 {
1376 if (propertyID >= kMinPropertyID) // in case data columns set the data
1377 {
1378 // variable definitions:
1379 wxVariant variant;
1380 wxDataViewColumn* dataViewColumnPtr;
1381 wxDataViewCtrl* dataViewCtrlPtr;
1382
1383 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1384 wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
1385 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,errDataBrowserNotConfigured,_("Pointer to model not set correctly."));
1386 dataViewColumnPtr = this->GetColumnPtr(propertyID);
1387 wxCHECK_MSG(dataViewColumnPtr != NULL,errDataBrowserNotConfigured,_("No column for the specified column position existing."));
1388 wxCHECK_MSG(dataViewColumnPtr->GetRenderer() != NULL,errDataBrowserNotConfigured,_("No renderer specified for column."));
1389 dataViewCtrlPtr->GetModel()->GetValue(variant,wxDataViewItem(reinterpret_cast<void*>(itemID)),dataViewColumnPtr->GetModelColumn());
1390 if (!(variant.IsNull()))
1391 {
1392 dataViewColumnPtr->GetRenderer()->GetNativeData()->SetItemDataRef(itemData);
1393 dataViewColumnPtr->GetRenderer()->SetValue(variant);
1394 wxCHECK_MSG(dataViewColumnPtr->GetRenderer()->MacRender(),errDataBrowserNotConfigured,_("Rendering failed."));
1395 }
1396 return noErr;
1397 }
1398 else // react on special system requests
1399 {
1400 switch (propertyID)
1401 {
1402 case kDataBrowserContainerIsClosableProperty:
1403 {
1404 // variable definitions:
1405 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
1406
1407 wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
1408 // initialize wxWidget event:
1409 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING,dataViewCtrlPtr->GetId()); // variable definition
1410
1411 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1412 dataViewEvent.SetItem (wxDataViewItem(reinterpret_cast<void*>(itemID)));
1413 dataViewEvent.SetModel (dataViewCtrlPtr->GetModel());
1414 // finally send the equivalent wxWidget event:
1415 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1416 // opening the container is allowed if not vetoed:
1417 return ::SetDataBrowserItemDataBooleanValue(itemData,dataViewEvent.IsAllowed());
1418 } /* block */
1419 case kDataBrowserContainerIsOpenableProperty:
1420 {
1421 // variable definitions:
1422 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
1423
1424 wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
1425 // initialize wxWidget event:
1426 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING,dataViewCtrlPtr->GetId()); // variable definition
1427
1428 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1429 dataViewEvent.SetItem (wxDataViewItem(reinterpret_cast<void*>(itemID)));
1430 dataViewEvent.SetModel (dataViewCtrlPtr->GetModel());
1431 // finally send the equivalent wxWidget event:
1432 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1433 // opening the container is allowed if not vetoed:
1434 return ::SetDataBrowserItemDataBooleanValue(itemData,dataViewEvent.IsAllowed());
1435 } /* block */
1436 case kDataBrowserItemIsContainerProperty:
1437 {
1438 // variable definition:
1439 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
1440
1441 wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
1442 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,errDataBrowserNotConfigured,_("Pointer to model not set correctly."));
1443 return ::SetDataBrowserItemDataBooleanValue(itemData,dataViewCtrlPtr->GetModel()->IsContainer(wxDataViewItem(reinterpret_cast<void*>(itemID))));
1444 } /* block */
1445 case kDataBrowserItemIsEditableProperty:
1446 return ::SetDataBrowserItemDataBooleanValue(itemData,true);
1447 }
1448 }
1449 }
1450 return errDataBrowserPropertyNotSupported;
1451} /* wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc(DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemDataRef, Boolean) */
1452
1453void wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID itemID, DataBrowserItemNotification message, DataBrowserItemDataRef itemData)
1454{
1455 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
1456
1457
1458 // check if the data view control pointer still exists because this call back function can still be called when the control has already been deleted:
1459 if (dataViewCtrlPtr != NULL)
1460 switch (message)
1461 {
1462 case kDataBrowserContainerClosed:
1463 dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
1464 {
1465 // initialize wxWidget event:
1466 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED,dataViewCtrlPtr->GetId()); // variable definition
1467
1468 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1469 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
1470 // finally send the equivalent wxWidget event:
1471 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1472 } /* block */
1473 break;
1474 case kDataBrowserContainerOpened:
1475 dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
1476 {
1477 // initialize wxWidget event:
1478 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED,dataViewCtrlPtr->GetId()); // variable definition
1479
1480 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1481 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
1482 // finally send the equivalent wxWidget event:
1483 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1484 // add children to the expanded container:
1485 dataViewCtrlPtr->AddChildren(wxDataViewItem(reinterpret_cast<void*>(itemID)));
1486 } /* block */
1487 break;
1488 case kDataBrowserEditStarted:
1489 dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
1490 {
1491 // initialize wxWidget event:
1492 DataBrowserPropertyID propertyID;
1493 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED,dataViewCtrlPtr->GetId()); // variable definition
1494
1495 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1496 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
1497 if (this->GetPropertyID(itemData,&propertyID) == noErr)
1498 {
1499 // variable definition and initialization:
1500 DataBrowserTableViewColumnIndex columnIndex;
1501
1502 wxCHECK_RET(this->GetColumnIndex(propertyID,&columnIndex),_("Column index not found."));
1503 dataViewEvent.SetColumn(columnIndex);
1504 dataViewEvent.SetDataViewColumn(this->GetColumnPtr(propertyID));
1505 }
1506 // finally send the equivalent wxWidget event:
1507 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1508 } /* block */
1509 break;
1510 case kDataBrowserEditStopped:
1511 {
1512 // initialize wxWidget event:
1513 DataBrowserPropertyID propertyID;
1514 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE,dataViewCtrlPtr->GetId()); // variable definition
1515
1516 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1517 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
1518 if (this->GetPropertyID(itemData,&propertyID) == noErr)
1519 {
1520 // variable definition and initialization:
1521 DataBrowserTableViewColumnIndex columnIndex;
1522
1523 wxCHECK_RET(this->GetColumnIndex(propertyID,&columnIndex),_("Column index not found."));
1524 dataViewEvent.SetColumn(columnIndex);
1525 dataViewEvent.SetDataViewColumn(this->GetColumnPtr(propertyID));
1526 }
1527 // finally send the equivalent wxWidget event:
1528 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1529 } /* block */
1530 break;
1531 case kDataBrowserItemAdded:
1532 dataViewCtrlPtr->FinishCustomItemEditing();
1533 break;
1534 case kDataBrowserItemDeselected:
1535 dataViewCtrlPtr->FinishCustomItemEditing();
1536 break;
1537 case kDataBrowserItemDoubleClicked:
1538 {
1539 // initialize wxWidget event:
1540 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED,dataViewCtrlPtr->GetId()); // variable definition
1541
1542 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1543 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
1544 // finally send the equivalent wxWidget event:
1545 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1546 } /* block */
1547 break;
1548 case kDataBrowserItemRemoved:
1549 dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
1550 break;
1551 case kDataBrowserItemSelected:
1552 break; // not implemented by wxWidgets; see kDataBrowserSelectionSetChanged
1553 case kDataBrowserSelectionSetChanged:
1554 {
1555 // initialize wxWidget event:
1556 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED,dataViewCtrlPtr->GetId()); // variable definition
1557
1558 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1559 dataViewEvent.SetModel (dataViewCtrlPtr->GetModel());
1560 // finally send the equivalent wxWidget event:
1561 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1562 } /* block */
1563 break;
1564 case kDataBrowserTargetChanged: // no idea if this notification is ever sent
1565 break;
1566 case kDataBrowserUserStateChanged:
1567 {
1568 // finish custom item editing if necessary:
1569 dataViewCtrlPtr->FinishCustomItemEditing();
1570 // update column widths:
1571 for (size_t i=0; i<dataViewCtrlPtr->GetColumnCount(); ++i)
1572 {
1573 // constant definition for abbreviational purposes:
1574 wxDataViewColumn* const columnPtr = dataViewCtrlPtr->GetColumnPtr(i);
1575 // variable definition:
1576 UInt16 columnWidth;
1577
1578 wxCHECK_RET(this->GetColumnWidth(columnPtr->GetNativeData()->GetPropertyID(),&columnWidth) == noErr,_("Column width could not be determined"));
1579 columnPtr->SetWidthVariable(columnWidth);
1580 }
1581 // update sorting orders:
1582 DataBrowserPropertyID propertyID; // variable definition
1583
1584 if ((this->GetSortProperty(&propertyID) == noErr) && (propertyID >= kMinPropertyID))
1585 {
1586 DataBrowserSortOrder sortOrder;
1587 DataBrowserTableViewColumnIndex columnIndex;
1588
1589 if ((this->GetSortOrder(&sortOrder) == noErr) && (this->GetColumnIndex(propertyID,&columnIndex) == noErr))
1590 {
1591 // variable definition and initialization:
1592 wxDataViewColumn* columnPtr;
1593 columnPtr = dataViewCtrlPtr->GetColumn(columnIndex);
1594 // check if the sort order has changed:
1595 if ( columnPtr->IsSortOrderAscending() && (sortOrder == kDataBrowserOrderDecreasing) ||
1596 !(columnPtr->IsSortOrderAscending()) && (sortOrder == kDataBrowserOrderIncreasing))
1597 {
1598 columnPtr->SetSortOrder(!(columnPtr->IsSortOrderAscending()));
1599 // initialize wxWidget event:
1600 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED,dataViewCtrlPtr->GetId()); // variable defintion
1601
1602 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1603 dataViewEvent.SetColumn(columnIndex);
1604 dataViewEvent.SetDataViewColumn(columnPtr);
1605 // finally send the equivalent wxWidget event:
1606 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1607 }
1608 }
1609 }
1610 } /* block */
1611 break;
1612 }
1613} /* wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID, DataBrowserItemNotification, DataBrowserItemDataRef) */
1614
1615void
1616wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID itemID,
1617 DataBrowserPropertyID propertyID,
1618 DataBrowserItemState state,
1619 Rect const* rectangle,
1620 SInt16 WXUNUSED(bitDepth),
1621 Boolean WXUNUSED(colorDevice))
1622{
1623 DataBrowserTableViewColumnIndex columnIndex;
1624
1625 wxDataViewColumn* dataViewColumnPtr;
1626
1627 wxDataViewCtrl* dataViewCtrlPtr;
1628
1629 wxDataViewCustomRenderer* dataViewCustomRendererPtr;
1630
1631 wxVariant dataToRender;
1632
1633 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1634 wxCHECK_RET(dataViewCtrlPtr != NULL, _("Pointer to data view control not set correctly."));
1635 wxCHECK_RET(dataViewCtrlPtr->GetModel() != NULL, _("Pointer to model not set correctly."));
1636 wxCHECK_RET(this->GetColumnIndex(propertyID,&columnIndex) == noErr,_("Could not determine column index."));
1637 dataViewColumnPtr = this->GetColumnPtr(propertyID);
1638 wxCHECK_RET(dataViewColumnPtr != NULL,_("No column for the specified column existing."));
1639 dataViewCustomRendererPtr = dynamic_cast<wxDataViewCustomRenderer*>(dataViewColumnPtr->GetRenderer());
1640 wxCHECK_RET(dataViewCustomRendererPtr != NULL,_("No renderer or invalid renderer type specified for custom data column."));
1641 dataViewCtrlPtr->GetModel()->GetValue(dataToRender,wxDataViewItem(reinterpret_cast<void*>(itemID)),dataViewColumnPtr->GetModelColumn());
1642 dataViewCustomRendererPtr->SetValue(dataToRender);
1643
1644 wxDataViewItem dataItem( reinterpret_cast<void*>(itemID) );
1645 dataViewCtrlPtr->GetModel()->GetValue(dataToRender,dataItem,dataViewColumnPtr->GetModelColumn());
1646 dataViewCustomRendererPtr->SetValue(dataToRender);
1647
1648 // try to determine the content's size (drawable part):
1649 Rect content;
1650 RgnHandle rgn(NewRgn());
1651 UInt16 headerHeight;
1652
1653 if (GetControlRegion(m_controlRef,kControlContentMetaPart,rgn) == noErr)
1654 GetRegionBounds(rgn,&content);
1655 else
1656 GetControlBounds(m_controlRef, &content);
1657 ::DisposeRgn(rgn);
1658 // space for the header
1659 this->GetHeaderButtonHeight(&headerHeight);
1660 content.top += headerHeight;
1661 // extra space for the frame (todo: do not how to determine the space automatically from the control)
1662 content.top += 5;
1663 content.left += 5;
1664 content.right -= 3;
1665 content.bottom -= 3;
1666 // extra space for the scrollbars:
1667 content.bottom -= wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y);
1668 content.right -= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
1669
1670 wxDC *dc = dataViewCustomRendererPtr->GetDC();
1671
1672 int active_border_fudge = 0;
1673 if (dataViewCtrlPtr->HasFocus() && !dataViewCtrlPtr->HasFlag( wxBORDER_NONE ))
1674 active_border_fudge = 1;
1675 else
1676 active_border_fudge = -2;
1677
1678 wxRect cellrect( static_cast<int>(rectangle->left + active_border_fudge),
1679 static_cast<int>(rectangle->top + active_border_fudge),
1680 static_cast<int>(1+rectangle->right-rectangle->left),
1681 static_cast<int>(rectangle->bottom-rectangle->top) );
1682
1683 bool is_active = IsControlActive( this->m_controlRef );
1684 if (state == kDataBrowserItemIsSelected)
1685 {
1686 wxColour col( wxMacCreateCGColorFromHITheme( (is_active) ?
1687 kThemeBrushAlternatePrimaryHighlightColor
1688 : kThemeBrushSecondaryHighlightColor ) );
1689
1690 wxRect rect = cellrect;
1691 Rect itemrect;
1692 GetDataBrowserItemPartBounds( this->m_controlRef, itemID, propertyID,
1693 kDataBrowserPropertyEnclosingPart, &itemrect );
1694 rect.x = itemrect.left-2;
1695 rect.width = itemrect.right-itemrect.left+3;
1696
1697 wxDCPenChanger setPen(*dc, *wxTRANSPARENT_PEN);
1698 wxDCBrushChanger setBrush(*dc, col);
1699 dc->DrawRectangle(rect);
1700 }
1701
1702 wxDataViewModel *model = dataViewCtrlPtr->GetModel();
1703 if ((columnIndex == 0) || !model->IsContainer(dataItem) || model->HasContainerColumns(dataItem))
1704 {
1705 // make sure that 'Render' can draw only in the allowed area:
1706 dc->SetClippingRegion(content.left,content.top,content.right-content.left+1,content.bottom-content.top+1);
1707 (void) (dataViewCustomRendererPtr->Render( cellrect, dc,
1708 ((state == kDataBrowserItemIsSelected) ? wxDATAVIEW_CELL_SELECTED : 0)));
1709 dc->DestroyClippingRegion(); // probably not necessary
1710 }
1711
1712 dataViewCustomRendererPtr->SetDC(NULL);
1713} /* wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemState, Rect const*, SInt16, Boolean) */
1714
1715Boolean
1716wxMacDataViewDataBrowserListViewControl::DataBrowserEditItemProc(
1717 DataBrowserItemID WXUNUSED(itemID),
1718 DataBrowserPropertyID WXUNUSED(propertyID),
1719 CFStringRef WXUNUSED(theString),
1720 Rect* WXUNUSED(maxEditTextRect),
1721 Boolean* WXUNUSED(shrinkToFit))
1722{
1723 return false;
1724} /* wxMacDataViewDataBrowserListViewControl::DataBrowserEditItemProc(DataBrowserItemID, DataBrowserPropertyID, CFStringRef, Rect*, Boolean*) */
1725
1726Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserHitTestProc(DataBrowserItemID WXUNUSED(itemID), DataBrowserPropertyID WXUNUSED(property), Rect const* WXUNUSED(theRect), Rect const* WXUNUSED(mouseRect))
1727{
1728 return true;
1729} /* wxMacDataViewDataBrowserListViewControl::DataBrowserHitTestProc(DataBrowserItemID, DataBrowserPropertyID, Rect const*, Rect const*) */
1730
1731DataBrowserTrackingResult wxMacDataViewDataBrowserListViewControl::DataBrowserTrackingProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, Rect const* theRect, Point WXUNUSED(startPt), EventModifiers WXUNUSED(modifiers))
1732{
1733 wxDataViewColumn* dataViewColumnPtr;
1734
1735 wxDataViewCtrl* dataViewCtrlPtr;
1736
1737 wxDataViewCustomRenderer* dataViewCustomRendererPtr;
1738
1739 wxDataViewItem dataViewCustomRendererItem;
1740
1741
1742 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1743 wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly."));
1744 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
1745 dataViewCustomRendererItem = reinterpret_cast<void*>(itemID);
1746 wxCHECK_MSG(dataViewCustomRendererItem.IsOk(),kDataBrowserNothingHit,_("Invalid data view item"));
1747 dataViewColumnPtr = this->GetColumnPtr(propertyID);
1748 wxCHECK_MSG(dataViewColumnPtr != NULL,kDataBrowserNothingHit,_("No column existing."));
1749 dataViewCustomRendererPtr = dynamic_cast<wxDataViewCustomRenderer*>(dataViewColumnPtr->GetRenderer());
1750 wxCHECK_MSG(dataViewCustomRendererPtr != NULL,kDataBrowserNothingHit,_("No renderer or invalid renderer type specified for custom data column."));
1751 // if the currently edited item is identical to the to be edited nothing is done (this hit should only be handled in the control itself):
1752 if (dataViewCtrlPtr->GetCustomRendererItem() == dataViewCustomRendererItem)
1753 return kDataBrowserContentHit;
1754 // an(other) item is going to be edited and therefore the current editing - if existing - has to be finished:
1755 if (dataViewCtrlPtr->GetCustomRendererPtr() != NULL)
1756 {
1757 dataViewCtrlPtr->GetCustomRendererPtr()->FinishEditing();
1758 dataViewCtrlPtr->SetCustomRendererItem(wxDataViewItem());
1759 dataViewCtrlPtr->SetCustomRendererPtr (NULL);
1760 }
1761 // check if renderer has got a valid editor control for editing; if this is the case start editing of the new item:
1762 if (dataViewCustomRendererPtr->HasEditorCtrl())
1763 {
1764 // variable definition:
1765 wxRect wxRectangle;
1766
1767 ::wxMacNativeToRect(theRect,&wxRectangle);
1768 dataViewCustomRendererPtr->StartEditing(dataViewCustomRendererItem,wxRectangle);
1769 dataViewCtrlPtr->SetCustomRendererItem(dataViewCustomRendererItem);
1770 dataViewCtrlPtr->SetCustomRendererPtr (dataViewCustomRendererPtr);
1771 }
1772 return kDataBrowserContentHit;
1773} /* wxMacDataViewDataBrowserListViewControl::DataBrowserTrackingProc(DataBrowserItemID, DataBrowserPropertyID, Rect const*, Point, EventModifiers) */
1774
1775Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserAcceptDragProc(DragReference dragRef, DataBrowserItemID itemID)
1776{
1777 bool acceptDrag;
1778
1779 UInt16 noOfDraggedItems;
1780
1781 wxDataViewCtrl* dataViewCtrlPtr;
1782
1783
1784 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1785 wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly."));
1786 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
1787
1788 // send a drag possible event for each available and item und proceed with it unless the event is vetoed:
1789 ::CountDragItems(dragRef,&noOfDraggedItems);
1790 for (UInt16 indexDraggedItem=1; indexDraggedItem<=noOfDraggedItems; ++indexDraggedItem)
1791 {
1792 // collect native information:
1793 ItemReference itemRef;
1794 wxDataObjectComposite* dataObjects;
1795 wxMemoryBuffer buffer;
1796
1797 ::GetDragItemReferenceNumber(dragRef,indexDraggedItem,&itemRef); // the index begins with 1!
1798 dataObjects = this->GetDnDDataObjects(dragRef,itemRef);
1799 // create wxWidget's event:
1800 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE,dataViewCtrlPtr->GetId());
1801
1802 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1803 dataViewEvent.SetItem(reinterpret_cast<void*>(itemID)); // this is the item that receives the event
1804 // (can be an invalid item ID, this is especially useful if the dataview does not contain any items)
1805 dataViewEvent.SetModel(dataViewCtrlPtr->GetModel());
1806 dataViewEvent.SetDataObject(dataObjects);
1807 dataViewEvent.SetDataFormat(this->GetDnDDataFormat(dataObjects));
1808 if (dataViewEvent.GetDataFormat().GetType() != wxDF_INVALID)
1809 {
1810 dataViewEvent.SetDataSize(dataObjects->GetDataSize(dataViewEvent.GetDataFormat().GetType()));
1811 dataObjects->GetDataHere(dataViewEvent.GetDataFormat().GetType(),buffer.GetWriteBuf(dataViewEvent.GetDataSize()));
1812 buffer.UngetWriteBuf(dataViewEvent.GetDataSize());
1813 dataViewEvent.SetDataBuffer(buffer.GetData());
1814 }
1815
1816 // send event:
1817 acceptDrag = dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed();
1818 delete dataObjects;
1819 if (!acceptDrag)
1820 return false;
1821 }
1822 return true;
1823} /* wxMacDataViewDataBrowserListViewControl::DataBrowserAcceptDragProc(DragReference, DataBrowserItemID) */
1824
1825Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserAddDragItemProc(DragReference dragRef, DataBrowserItemID itemID, ItemReference* itemRef)
1826{
1827 Boolean addDragItem;
1828
1829 wxDataViewCtrl* dataViewCtrlPtr;
1830
1831 wxDataViewItem dataViewItem;
1832
1833
1834 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1835 wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly."));
1836 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
1837 dataViewItem = reinterpret_cast<void*>(itemID);
1838 wxCHECK_MSG(dataViewItem.IsOk(),false,_("Invalid data view item"));
1839
1840 // send a begin drag event and proceed with dragging unless the event is vetoed:
1841 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG,dataViewCtrlPtr->GetId());
1842
1843 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1844 dataViewEvent.SetItem(dataViewItem);
1845 dataViewEvent.SetModel(dataViewCtrlPtr->GetModel());
1846 // the dataview event object is also initialized with a default set of data; as it is a set of data and the user should be able to easily complete
1847 // the object a wxDataObjectComposite object is used;
1848 // currently, the composite object only contains a TAB concatenated string of all data:
1849 wxDataObjectComposite* dataObject(new wxDataObjectComposite());
1850
1851 dataObject->Add(new wxTextDataObject(::ConcatenateDataViewItemValues(dataViewCtrlPtr,dataViewItem)));
1852 dataViewEvent.SetDataObject(dataObject);
1853 // check if event has not been vetoed:
1854 addDragItem = dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed();
1855 if (addDragItem)
1856 {
1857 // for the internal drag & drop functions create two flavors:
1858 // - the data browser's item id;
1859 // - the data contained the dataview event object (if available).
1860 // Definition: a flavor is the type dependent representation of identical data.
1861 // Example: a number can be represented by its value and by its value converted to a string. In this case the flavor
1862 // of the number's internal representation is typeSInt32 while its string representation has got the flavor 'TEXT'.
1863 // Item id is one of the flavors:
1864 wxCHECK_MSG(::AddDragItemFlavor(dragRef,*itemRef,typeUInt32,&itemID,sizeof(itemID),0) == noErr,false,_("Unable to handle native drag&drop data"));
1865 // if the dataview event object contains data it is used for additional flavors; all natively known flavors are supported:
1866 if (dataViewEvent.GetDataObject() != NULL)
1867 {
1868 // constant definition for abbreviational purposes:
1869 size_t const noOfFormats = dataViewEvent.GetDataObject()->GetFormatCount();
1870
1871 if (noOfFormats > 0)
1872 {
1873 // variable definition:
1874 wxDataFormat* dataFormats;
1875
1876 dataFormats = new wxDataFormat[noOfFormats];
1877 dataViewEvent.GetDataObject()->GetAllFormats(dataFormats,wxDataObject::Get);
1878 for (size_t i=0; i<noOfFormats; ++i)
1879 switch (dataFormats[i].GetType())
1880 {
1881 case wxDF_INVALID:
1882 wxFAIL_MSG(_("Data object has invalid data format"));
1883 break;
1884 case wxDF_TEXT:
1885 {
1886 // constant definition for abbreviational purposes:
1887 size_t const dataSize = dataViewEvent.GetDataObject()->GetDataSize(wxDF_TEXT);
1888 // variable definition and initialization:
1889 wxMemoryBuffer dataObject(dataSize);
1890
1891 dataViewEvent.GetDataObject()->GetDataHere(wxDF_TEXT,dataObject.GetWriteBuf(dataSize));
1892 dataObject.UngetWriteBuf(dataSize);
1893 if (::AddDragItemFlavor(dragRef,*itemRef,'TEXT',dataObject.GetData(),dataSize,0) != noErr)
1894 wxFAIL_MSG(_("Adding flavor TEXT failed"));
1895 } /* block */
1896 break;
1897 case wxDF_UNICODETEXT:
1898 {
1899 // constant definition for abbreviational purposes:
1900 size_t const dataSize = dataViewEvent.GetDataObject()->GetDataSize(wxDF_TEXT);
1901 // as there is no direct access to the data copy it to a memory buffer:
1902 wxMemoryBuffer dataObject(dataSize);
1903
1904 dataViewEvent.GetDataObject()->GetDataHere(wxDF_TEXT,dataObject.GetWriteBuf(dataSize));
1905 dataObject.UngetWriteBuf(dataSize);
1906 // if the data is stored in unicode format the internal representation is utf-8 (not mentioned in the documentation but in the source code);
1907 // DnD uses fixed utf-16 representation -> use the OSX functions for a conversion:
1908 CFDataRef osxData (::CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,reinterpret_cast<UInt8*>(dataObject.GetData()),dataSize,kCFAllocatorNull));
1909 CFStringRef osxString(::CFStringCreateFromExternalRepresentation(kCFAllocatorDefault,osxData,kCFStringEncodingUTF8));
1910
1911 // the osxString contains now the data and therefore the previously occupied memory can be released and re-used:
1912 ::CFRelease(osxData);
1913 osxData = ::CFStringCreateExternalRepresentation(kCFAllocatorDefault,osxString,kCFStringEncodingUTF16,32);
1914 if (::AddDragItemFlavor(dragRef,*itemRef,'utxt',::CFDataGetBytePtr(osxData),::CFDataGetLength(osxData),0) != noErr)
1915 wxFAIL_MSG(_("Adding flavor utxt failed"));
1916 // clean up:
1917 ::CFRelease(osxData);
1918 ::CFRelease(osxString);
1919 } /* block */
1920 break;
1921 case wxDF_BITMAP:
1922 case wxDF_METAFILE:
1923 case wxDF_SYLK:
1924 case wxDF_DIF:
1925 case wxDF_TIFF:
1926 case wxDF_OEMTEXT:
1927 case wxDF_DIB:
1928 case wxDF_PALETTE:
1929 case wxDF_PENDATA:
1930 case wxDF_RIFF:
1931 case wxDF_WAVE:
1932 case wxDF_ENHMETAFILE:
1933 case wxDF_FILENAME:
1934 case wxDF_LOCALE:
1935 case wxDF_PRIVATE:
1936 case wxDF_HTML:
1937 break; // not (yet) supported data formats
1938 default:
1939 wxFAIL_MSG(_("Unknown data format"));
1940 }
1941 delete[] dataFormats;
1942 }
1943 }
1944 }
1945 // clean-up and return result:
1946 delete dataObject;
1947 return addDragItem;
1948} /* wxMacDataViewDataBrowserListViewControl::DataBrowserAddDragItemProc(DragReference, DataBrowserItemID, ItemReference*) */
1949
1950Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserReceiveDragProc(DragReference dragRef, DataBrowserItemID itemID)
1951{
1952 UInt16 noOfDraggedItems;
1953
1954 wxDataViewCtrl* dataViewCtrlPtr;
1955
1956
1957 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1958 wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly."));
1959 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
1960
1961 // send a drag possible event for each available and item und proceed with it unless the event is vetoed:
1962 ::CountDragItems(dragRef,&noOfDraggedItems);
1963 for (UInt16 indexDraggedItem=1; indexDraggedItem<=noOfDraggedItems; ++indexDraggedItem)
1964 {
1965 bool receiveDrag;
1966 ItemReference itemRef;
1967 wxDataObjectComposite* dataObjects;
1968 wxMemoryBuffer buffer;
1969
1970 // collect native information:
1971 ::GetDragItemReferenceNumber(dragRef,indexDraggedItem,&itemRef); // the index begins with 1!
1972 dataObjects = this->GetDnDDataObjects(dragRef,itemRef);
1973 // create wxWidget's event:
1974 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_DROP,dataViewCtrlPtr->GetId());
1975
1976 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1977 dataViewEvent.SetItem(reinterpret_cast<void*>(itemID)); // this is the item that receives the event
1978 // (can be an invalid item ID, this is especially useful if the dataview does not contain any items)
1979 dataViewEvent.SetModel(dataViewCtrlPtr->GetModel());
1980 dataViewEvent.SetDataObject(dataObjects);
1981 dataViewEvent.SetDataFormat(this->GetDnDDataFormat(dataObjects));
1982 if (dataViewEvent.GetDataFormat().GetType() != wxDF_INVALID)
1983 {
1984 dataViewEvent.SetDataSize(dataObjects->GetDataSize(dataViewEvent.GetDataFormat().GetType()));
1985 dataObjects->GetDataHere(dataViewEvent.GetDataFormat().GetType(),buffer.GetWriteBuf(dataViewEvent.GetDataSize()));
1986 buffer.UngetWriteBuf(dataViewEvent.GetDataSize());
1987 dataViewEvent.SetDataBuffer(buffer.GetData());
1988 }
1989
1990 // send event:
1991 receiveDrag = dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed();
1992 delete dataObjects;
1993 if (!receiveDrag)
1994 return false;
1995 }
1996 return true;
1997} /* wxMacDataViewDataBrowserListViewControl::DataBrowserReceiveDragProc(DragReference, DataBrowserItemID) */
1998
1999//
2000// drag & drop helper methods
2001//
2002wxDataFormat wxMacDataViewDataBrowserListViewControl::GetDnDDataFormat(wxDataObjectComposite* dataObjects)
2003{
2004 wxDataFormat resultFormat;
2005
2006
2007 if (dataObjects != NULL)
2008 {
2009 bool compatible(true);
2010
2011 size_t const noOfFormats = dataObjects->GetFormatCount();
2012 size_t indexFormat;
2013
2014 wxDataFormat* formats;
2015
2016 // get all formats and check afterwards if the formats are compatible; if they are compatible the preferred format is returned otherwise
2017 // wxDF_INVALID is returned;
2018 // currently compatible types (ordered by priority are):
2019 // - wxDF_UNICODETEXT - wxDF_TEXT
2020 formats = new wxDataFormat[noOfFormats];
2021 dataObjects->GetAllFormats(formats);
2022 indexFormat = 0;
2023 while ((indexFormat < noOfFormats) && compatible)
2024 {
2025 switch (resultFormat.GetType())
2026 {
2027 case wxDF_INVALID:
2028 resultFormat.SetType(formats[indexFormat].GetType()); // first format (should only be reached if indexFormat == 0
2029 break;
2030 case wxDF_TEXT:
2031 if (formats[indexFormat].GetType() == wxDF_UNICODETEXT)
2032 resultFormat.SetType(wxDF_UNICODETEXT);
2033 else // incompatible
2034 {
2035 resultFormat.SetType(wxDF_INVALID);
2036 compatible = false;
2037 }
2038 break;
2039 case wxDF_UNICODETEXT:
2040 if (formats[indexFormat].GetType() != wxDF_TEXT)
2041 {
2042 resultFormat.SetType(wxDF_INVALID);
2043 compatible = false;
2044 }
2045 break;
2046 default:
2047 resultFormat.SetType(wxDF_INVALID); // not (yet) supported format
2048 compatible = false;
2049 }
2050 ++indexFormat;
2051 } /* while */
2052 // clean up:
2053 delete[] formats;
2054 }
2055 else
2056 resultFormat = wxDF_INVALID;
2057 return resultFormat;
2058} /* wxMacDataViewDataBrowserListViewControl::GetDnDDataFormat(wxDataObjectComposite*) */
2059
2060wxDataObjectComposite* wxMacDataViewDataBrowserListViewControl::GetDnDDataObjects(DragReference dragRef, ItemReference itemRef) const
2061{
2062 UInt16 noOfFlavors;
2063
2064 wxDataObjectComposite* dataObject;
2065
2066
2067 ::CountDragItemFlavors(dragRef,itemRef,&noOfFlavors);
2068 if (noOfFlavors > 0)
2069 {
2070 // as the native drag data can be separated into TEXT and UTXT a pointer to a wxTextDataObject is used to track the existence of 'TEXT' and 'utxt' flavors:
2071 wxTextDataObject* textDataObject(NULL);
2072
2073 dataObject = new wxDataObjectComposite();
2074 for (UInt16 indexFlavor=1; indexFlavor<=noOfFlavors; ++indexFlavor)
2075 {
2076 // variable definition:
2077 FlavorType flavorDataObject;
2078
2079 if (::GetFlavorType(dragRef,itemRef,indexFlavor,&flavorDataObject) == noErr) // GetFlavorType uses a 1 based index!
2080 switch (flavorDataObject)
2081 {
2082 case 'TEXT':
2083 if (textDataObject == NULL) // otherwise a 'utxt' flavor has already been found that gets priority compared to the 'TEXT' flavor
2084 {
2085 // variable definitions:
2086 Size nativeDataSize;
2087 wxMemoryBuffer nativeData;
2088
2089 if ((::GetFlavorDataSize(dragRef,itemRef,'TEXT',&nativeDataSize) == noErr) &&
2090 (::GetFlavorData(dragRef,itemRef,'TEXT',nativeData.GetWriteBuf(nativeDataSize),&nativeDataSize,0) == noErr))
2091 {
2092 nativeData.UngetWriteBuf(nativeDataSize);
2093 textDataObject = new wxTextDataObject();
2094 if (textDataObject->SetData(nativeData.GetDataLen(),nativeData.GetData()))
2095 dataObject->Add(textDataObject);
2096 else
2097 {
2098 delete textDataObject;
2099 textDataObject = NULL;
2100 }
2101 }
2102 } /* block */
2103 break;
2104 case 'utxt':
2105 {
2106 // variable definition:
2107 Size nativeDataSize;
2108
2109 if (::GetFlavorDataSize(dragRef,itemRef,'utxt',&nativeDataSize) == noErr)
2110 {
2111 CFMutableDataRef draggedData;
2112
2113 draggedData = ::CFDataCreateMutable(kCFAllocatorDefault,nativeDataSize);
2114 ::CFDataSetLength(draggedData,nativeDataSize);
2115 if (::GetFlavorData(dragRef,itemRef,'utxt',::CFDataGetMutableBytePtr(draggedData),&nativeDataSize,0) == noErr)
2116 {
2117 // convert internally used UTF-16 representation to a UTF-8 representation:
2118 CFDataRef osxData;
2119 CFStringRef osxString;
2120
2121 osxString = ::CFStringCreateFromExternalRepresentation(kCFAllocatorDefault,draggedData,kCFStringEncodingUTF16); // BOM character is handled by this function automatically
2122 osxData = ::CFStringCreateExternalRepresentation(kCFAllocatorDefault,osxString,kCFStringEncodingUTF8,32);
2123 if (textDataObject == NULL)
2124 {
2125 textDataObject = new wxTextDataObject();
2126 if (textDataObject->SetData(::CFDataGetLength(osxData),::CFDataGetBytePtr(osxData)))
2127 dataObject->Add(textDataObject);
2128 else
2129 {
2130 delete textDataObject;
2131 textDataObject = NULL;
2132 }
2133 }
2134 else // overwrite data because the 'utxt' flavor has priority over the 'TEXT' flavor
2135 (void) textDataObject->SetData(::CFDataGetLength(osxData),::CFDataGetBytePtr(osxData));
2136 // clean up:
2137 ::CFRelease(osxData);
2138 ::CFRelease(osxString);
2139 }
2140 // clean up:
2141 ::CFRelease(draggedData);
2142 }
2143 } /* block */
2144 break;
2145 }
2146 }
2147 }
2148 else
2149 dataObject = NULL;
2150 return dataObject;
2151} /* wxMacDataViewDataBrowserListViewControl::GetDnDDataObjects(DragReference, ItemReference) const */
2152
2153//
2154// other methods
2155//
2156wxDataViewColumn* wxMacDataViewDataBrowserListViewControl::GetColumnPtr(DataBrowserPropertyID propertyID) const
2157{
2158 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
2159
2160 if (dataViewCtrlPtr != NULL)
2161 {
2162 size_t const noOfColumns = dataViewCtrlPtr->GetColumnCount();
2163
2164 for (size_t i=0; i<noOfColumns; ++i)
2165 if (dataViewCtrlPtr->GetColumnPtr(i)->GetNativeData()->GetPropertyID() == propertyID)
2166 return dataViewCtrlPtr->GetColumnPtr(i);
2167 }
2168 return NULL;
2169}
2170
2171// ---------------------------------------------------------
2172// wxDataViewRenderer
2173// ---------------------------------------------------------
2174wxDataViewRenderer::wxDataViewRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
2175 :wxDataViewRendererBase(varianttype,mode,align), m_alignment(align), m_mode(mode), m_NativeDataPtr(NULL)
2176{
2177}
2178
2179wxDataViewRenderer::~wxDataViewRenderer(void)
2180{
2181 delete this->m_NativeDataPtr;
2182}
2183
2184void wxDataViewRenderer::SetAlignment(int align)
2185{
2186 this->m_alignment = align;
2187}
2188
2189void wxDataViewRenderer::SetMode(wxDataViewCellMode mode)
2190{
2191 wxDataViewColumn* dataViewColumnPtr;
2192
2193
2194 m_mode = mode;
2195 dataViewColumnPtr = this->GetOwner();
2196 if (dataViewColumnPtr != NULL)
2197 {
2198 wxDataViewCtrl* dataViewCtrlPtr(dataViewColumnPtr->GetOwner());
2199
2200 if (dataViewCtrlPtr != NULL)
2201 {
2202 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2203
2204 if (macDataViewListCtrlPtr != NULL)
2205 {
2206 DataBrowserPropertyFlags flags;
2207
2208 verify_noerr(macDataViewListCtrlPtr->GetPropertyFlags(dataViewColumnPtr->GetNativeData()->GetPropertyID(),&flags));
2209 if ((mode == wxDATAVIEW_CELL_EDITABLE) ||
2210 (mode == wxDATAVIEW_CELL_ACTIVATABLE))
2211 flags |= kDataBrowserPropertyIsEditable;
2212 else
2213 flags &= ~kDataBrowserPropertyIsEditable;
2214 verify_noerr(macDataViewListCtrlPtr->SetPropertyFlags(dataViewColumnPtr->GetNativeData()->GetPropertyID(),flags));
2215 }
2216 }
2217 }
2218}
2219
2220void wxDataViewRenderer::SetNativeData(wxDataViewRendererNativeData* newNativeDataPtr)
2221{
2222 delete this->m_NativeDataPtr;
2223 this->m_NativeDataPtr = newNativeDataPtr;
2224}
2225
2226IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer,wxDataViewRendererBase)
2227
2228// ---------------------------------------------------------
2229// wxDataViewCustomRenderer
2230// ---------------------------------------------------------
2231wxDataViewCustomRenderer::wxDataViewCustomRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
2232 :wxDataViewRenderer(varianttype,mode,align), m_editorCtrlPtr(NULL), m_DCPtr(NULL)
2233{
2234 this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserCustomType));
2235}
2236
2237bool wxDataViewCustomRenderer::MacRender()
2238{
2239 return true;
2240}
2241
2242IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomRenderer, wxDataViewRenderer)
2243
2244// ---------------------------------------------------------
2245// wxDataViewTextRenderer
2246// ---------------------------------------------------------
2247wxDataViewTextRenderer::wxDataViewTextRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
2248 :wxDataViewRenderer(varianttype,mode,align)
2249{
2250 this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserTextType));
2251}
2252
2253bool wxDataViewTextRenderer::MacRender()
2254{
2255 wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Text renderer cannot render value; value type: ")) << this->GetValue().GetType());
2256
2257 wxCFStringRef cfString(this->GetValue().GetString(),(this->GetView()->GetFont().Ok() ? this->GetView()->GetFont().GetEncoding() : wxLocale::GetSystemEncoding()));
2258 return (::SetDataBrowserItemDataText(this->GetNativeData()->GetItemDataRef(),cfString) == noErr);
2259}
2260
2261IMPLEMENT_CLASS(wxDataViewTextRenderer,wxDataViewRenderer)
2262
2263// ---------------------------------------------------------
2264// wxDataViewBitmapRenderer
2265// ---------------------------------------------------------
2266wxDataViewBitmapRenderer::wxDataViewBitmapRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
2267 :wxDataViewRenderer(varianttype,mode,align)
2268{
2269 this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserIconType));
2270}
2271
2272bool wxDataViewBitmapRenderer::MacRender()
2273 // This method returns 'true' if
2274 // - the passed bitmap is valid and it could be assigned to the native data browser;
2275 // - the passed bitmap is invalid (or is not initialized); this case simulates a non-existing bitmap.
2276 // In all other cases the method returns 'false'.
2277{
2278 wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Bitmap renderer cannot render value; value type: ")) << this->GetValue().GetType());
2279
2280 wxBitmap bitmap;
2281
2282 bitmap << this->GetValue();
2283 return (!(bitmap.Ok()) || (::SetDataBrowserItemDataIcon(this->GetNativeData()->GetItemDataRef(),bitmap.GetIconRef()) == noErr));
2284}
2285
2286IMPLEMENT_CLASS(wxDataViewBitmapRenderer,wxDataViewRenderer)
2287
2288// ---------------------------------------------------------
2289// wxDataViewIconTextRenderer
2290// ---------------------------------------------------------
2291wxDataViewIconTextRenderer::wxDataViewIconTextRenderer(
2292 const wxString& varianttype,
2293 wxDataViewCellMode mode,
2294 int WXUNUSED(align))
2295 :wxDataViewRenderer(varianttype,mode)
2296{
2297 this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserIconAndTextType));
2298}
2299
2300bool wxDataViewIconTextRenderer::MacRender()
2301{
2302 wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Icon & text renderer cannot render value; value type: ")) << this->GetValue().GetType());
2303
2304 wxDataViewIconText iconText;
2305
2306 iconText << this->GetValue();
2307
2308 wxCFStringRef cfString(iconText.GetText(),(this->GetView()->GetFont().Ok() ? this->GetView()->GetFont().GetEncoding() : wxLocale::GetSystemEncoding()));
2309
2310 if (iconText.GetIcon().IsOk())
2311 if (::SetDataBrowserItemDataIcon(this->GetNativeData()->GetItemDataRef(),MAC_WXHICON(iconText.GetIcon().GetHICON())) != noErr)
2312 return false;
2313 return (::SetDataBrowserItemDataText(this->GetNativeData()->GetItemDataRef(),cfString) == noErr);
2314}
2315
2316IMPLEMENT_ABSTRACT_CLASS(wxDataViewIconTextRenderer,wxDataViewRenderer)
2317
2318
2319// ---------------------------------------------------------
2320// wxDataViewToggleRenderer
2321// ---------------------------------------------------------
2322wxDataViewToggleRenderer::wxDataViewToggleRenderer(
2323 const wxString& varianttype,
2324 wxDataViewCellMode mode,
2325 int WXUNUSED(align))
2326 :wxDataViewRenderer(varianttype,mode)
2327{
2328 this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserCheckboxType));
2329}
2330
2331bool wxDataViewToggleRenderer::MacRender()
2332{
2333 wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Toggle renderer cannot render value; value type: ")) << this->GetValue().GetType());
2334 return (::SetDataBrowserItemDataButtonValue(this->GetNativeData()->GetItemDataRef(),this->GetValue().GetBool()) == noErr);
2335}
2336
2337IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleRenderer,wxDataViewRenderer)
2338
2339// ---------------------------------------------------------
2340// wxDataViewProgressRenderer
2341// ---------------------------------------------------------
2342wxDataViewProgressRenderer::wxDataViewProgressRenderer(
2343 const wxString& WXUNUSED(label),
2344 wxString const& varianttype,
2345 wxDataViewCellMode mode,
2346 int align)
2347 :wxDataViewRenderer(varianttype,mode,align)
2348{
2349 this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserProgressBarType));
2350}
2351
2352bool wxDataViewProgressRenderer::MacRender()
2353{
2354 wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Progress renderer cannot render value type; value type: ")) << this->GetValue().GetType());
2355 return ((::SetDataBrowserItemDataMinimum(this->GetNativeData()->GetItemDataRef(), 0) == noErr) &&
2356 (::SetDataBrowserItemDataMaximum(this->GetNativeData()->GetItemDataRef(),100) == noErr) &&
2357 (::SetDataBrowserItemDataValue (this->GetNativeData()->GetItemDataRef(),this->GetValue().GetLong()) == noErr));
2358}
2359
2360IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressRenderer,wxDataViewRenderer)
2361
2362// ---------------------------------------------------------
2363// wxDataViewDateRenderer
2364// ---------------------------------------------------------
2365wxDataViewDateRenderer::wxDataViewDateRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
2366 :wxDataViewRenderer(varianttype,mode,align)
2367{
2368 this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserDateTimeType));
2369}
2370
2371bool wxDataViewDateRenderer::MacRender()
2372{
2373 wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Date renderer cannot render value; value type: ")) << this->GetValue().GetType());
2374 return (::SetDataBrowserItemDataDateTime(this->GetNativeData()->GetItemDataRef(),this->GetValue().GetDateTime().Subtract(wxDateTime(1,wxDateTime::Jan,1904)).GetSeconds().GetLo()) == noErr);
2375}
2376
2377IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer,wxDataViewRenderer)
2378
2379// ---------------------------------------------------------
2380// wxDataViewColumn
2381// ---------------------------------------------------------
2382wxDataViewColumn::wxDataViewColumn(const wxString& title, wxDataViewRenderer* renderer, unsigned int model_column, int width, wxAlignment align, int flags)
2383 :wxDataViewColumnBase(renderer, model_column), m_NativeDataPtr(new wxDataViewColumnNativeData()), m_title(title)
2384{
2385 this->InitCommon(width, align, flags);
2386 if ((renderer != NULL) && (renderer->GetAlignment() == wxDVR_DEFAULT_ALIGNMENT))
2387 renderer->SetAlignment(align);
2388}
2389
2390wxDataViewColumn::wxDataViewColumn(const wxBitmap& bitmap, wxDataViewRenderer* renderer, unsigned int model_column, int width, wxAlignment align, int flags)
2391 :wxDataViewColumnBase(bitmap, renderer, model_column), m_NativeDataPtr(new wxDataViewColumnNativeData())
2392{
2393 this->InitCommon(width, align, flags);
2394 if ((renderer != NULL) && (renderer->GetAlignment() == wxDVR_DEFAULT_ALIGNMENT))
2395 renderer->SetAlignment(align);
2396}
2397
2398wxDataViewColumn::~wxDataViewColumn(void)
2399{
2400 delete this->m_NativeDataPtr;
2401}
2402
2403bool wxDataViewColumn::IsSortKey() const
2404{
2405 wxDataViewCtrl * const dataViewCtrlPtr(GetOwner());
2406 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(
2407 dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(
2408 dataViewCtrlPtr->GetPeer()));
2409
2410 DataBrowserPropertyID propertyID;
2411 return (macDataViewListCtrlPtr->GetSortProperty(&propertyID) == noErr) &&
2412 (propertyID == this->GetNativeData()->GetPropertyID());
2413}
2414
2415void wxDataViewColumn::SetAlignment(wxAlignment align)
2416{
2417 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2418
2419
2420 m_alignment = align;
2421 if (dataViewCtrlPtr != NULL)
2422 {
2423 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2424
2425 if (macDataViewListCtrlPtr != NULL)
2426 {
2427 DataBrowserListViewHeaderDesc headerDescription;
2428
2429 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
2430 switch (align)
2431 {
2432 case wxALIGN_CENTER:
2433 case wxALIGN_CENTER_HORIZONTAL:
2434 headerDescription.btnFontStyle.just = teCenter;
2435 break;
2436 case wxALIGN_LEFT:
2437 headerDescription.btnFontStyle.just = teFlushLeft;
2438 break;
2439 case wxALIGN_RIGHT:
2440 headerDescription.btnFontStyle.just = teFlushRight;
2441 break;
2442 default:
2443 headerDescription.btnFontStyle.just = teFlushDefault;
2444 }
2445 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not set alignment."));
2446 }
2447 }
2448}
2449
2450void wxDataViewColumn::SetBitmap(wxBitmap const& bitmap)
2451{
2452 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2453
2454
2455 wxDataViewColumnBase::SetBitmap(bitmap);
2456 if (dataViewCtrlPtr != NULL)
2457 {
2458 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2459
2460 if (macDataViewListCtrlPtr != NULL)
2461 {
2462 DataBrowserListViewHeaderDesc headerDescription;
2463
2464 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
2465 if (this->GetBitmap().Ok())
2466 headerDescription.btnContentInfo.u.iconRef = this->GetBitmap().GetIconRef();
2467 else
2468 headerDescription.btnContentInfo.u.iconRef = NULL;
2469 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not set icon."));
2470 }
2471 }
2472}
2473
2474void wxDataViewColumn::SetMaxWidth(int maxWidth)
2475{
2476 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2477
2478
2479 m_maxWidth = maxWidth;
2480 if (dataViewCtrlPtr != NULL)
2481 {
2482 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2483
2484 if (macDataViewListCtrlPtr != NULL)
2485 {
2486 DataBrowserListViewHeaderDesc headerDescription;
2487
2488 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
2489 headerDescription.maximumWidth = static_cast<UInt16>(maxWidth);
2490 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not set maximum width."));
2491 }
2492 }
2493}
2494
2495void wxDataViewColumn::SetMinWidth(int minWidth)
2496{
2497 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2498
2499
2500 m_minWidth = minWidth;
2501 if (dataViewCtrlPtr != NULL)
2502 {
2503 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2504
2505 if (macDataViewListCtrlPtr != NULL)
2506 {
2507 DataBrowserListViewHeaderDesc headerDescription;
2508
2509 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
2510 headerDescription.minimumWidth = static_cast<UInt16>(minWidth);
2511 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not set minimum width."));
2512 }
2513 }
2514}
2515
2516void wxDataViewColumn::SetReorderable(bool reorderable)
2517{
2518 // first set the internal flag of the column:
2519 if (reorderable)
2520 m_flags |= wxDATAVIEW_COL_REORDERABLE;
2521 else
2522 m_flags &= ~wxDATAVIEW_COL_REORDERABLE;
2523 // if the column is associated with a control change also immediately the flags of the control:
2524 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2525
2526 if (dataViewCtrlPtr != NULL)
2527 {
2528 DataBrowserPropertyFlags flags;
2529 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2530
2531 wxCHECK_RET(macDataViewListCtrlPtr != NULL, _("Valid pointer to native data view control does not exist"));
2532 wxCHECK_RET(macDataViewListCtrlPtr->GetPropertyFlags(this->GetNativeData()->GetPropertyID(),&flags) == noErr,_("Could not get property flags."));
2533 if (reorderable)
2534 flags |= kDataBrowserListViewMovableColumn;
2535 else
2536 flags &= ~kDataBrowserListViewMovableColumn;
2537 wxCHECK_RET(macDataViewListCtrlPtr->SetPropertyFlags(this->GetNativeData()->GetPropertyID(),flags) == noErr,_("Could not set property flags."));
2538 }
2539}
2540
2541void wxDataViewColumn::SetResizeable(bool resizeable)
2542{
2543 // first set the internal flag of the column:
2544 if (resizeable)
2545 m_flags |= wxDATAVIEW_COL_RESIZABLE;
2546 else
2547 m_flags &= ~wxDATAVIEW_COL_RESIZABLE;
2548 // if the column is associated with a control change also immediately the flags of the control:
2549 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2550
2551 if (dataViewCtrlPtr != NULL)
2552 {
2553 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2554
2555 if (macDataViewListCtrlPtr != NULL)
2556 {
2557 DataBrowserListViewHeaderDesc headerDescription;
2558
2559 verify_noerr(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription));
2560 if (resizeable)
2561 {
2562 if (this->GetMinWidth() >= this->GetMaxWidth())
2563 {
2564 this->m_minWidth = 0;
2565 this->m_maxWidth = 30000;
2566 }
2567 headerDescription.minimumWidth = this->m_minWidth;
2568 headerDescription.maximumWidth = this->m_maxWidth;
2569 }
2570 else
2571 {
2572 headerDescription.minimumWidth = this->m_width;
2573 headerDescription.maximumWidth = this->m_width;
2574 }
2575 verify_noerr(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription));
2576 macDataViewListCtrlPtr->SetSortProperty(this->GetNativeData()->GetPropertyID());
2577 }
2578 }
2579}
2580
2581void wxDataViewColumn::SetSortable(bool sortable)
2582{
2583 // first set the internal flag of the column:
2584 if (sortable)
2585 m_flags |= wxDATAVIEW_COL_SORTABLE;
2586 else
2587 m_flags &= ~wxDATAVIEW_COL_SORTABLE;
2588 // if the column is associated with a control change also immediately the flags of the control:
2589 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2590
2591 if (dataViewCtrlPtr != NULL)
2592 {
2593 DataBrowserPropertyFlags flags;
2594 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2595
2596 wxCHECK_RET(macDataViewListCtrlPtr != NULL, _("Valid pointer to native data view control does not exist"));
2597 wxCHECK_RET(macDataViewListCtrlPtr->GetPropertyFlags(this->GetNativeData()->GetPropertyID(),&flags) == noErr,_("Could not get property flags."));
2598 if (sortable)
2599 flags |= kDataBrowserListViewSortableColumn;
2600 else
2601 flags &= ~kDataBrowserListViewSortableColumn;
2602 wxCHECK_RET(macDataViewListCtrlPtr->SetPropertyFlags(this->GetNativeData()->GetPropertyID(),flags) == noErr,_("Could not set property flags."));
2603 }
2604}
2605
2606void wxDataViewColumn::SetSortOrder(bool ascending)
2607{
2608 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2609
2610
2611 m_ascending = ascending;
2612 if (dataViewCtrlPtr != NULL)
2613 {
2614 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2615
2616 if (macDataViewListCtrlPtr != NULL)
2617 {
2618 DataBrowserListViewHeaderDesc headerDescription;
2619
2620 verify_noerr(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription));
2621 if (ascending)
2622 headerDescription.initialOrder = kDataBrowserOrderIncreasing;
2623 else
2624 headerDescription.initialOrder = kDataBrowserOrderDecreasing;
2625 verify_noerr(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription));
2626 macDataViewListCtrlPtr->SetSortProperty(this->GetNativeData()->GetPropertyID());
2627 }
2628 }
2629}
2630
2631void wxDataViewColumn::SetTitle(wxString const& title)
2632{
2633 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2634
2635
2636 m_title = title;
2637 if (dataViewCtrlPtr != NULL)
2638 {
2639 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2640
2641 if (macDataViewListCtrlPtr != NULL)
2642 {
2643 DataBrowserListViewHeaderDesc headerDescription;
2644 wxCFStringRef cfTitle(title,(dataViewCtrlPtr->GetFont().Ok() ? dataViewCtrlPtr->GetFont().GetEncoding() : wxLocale::GetSystemEncoding()));
2645
2646 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
2647 headerDescription.titleString = cfTitle;
2648 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not set header description."));
2649 }
2650 }
2651}
2652
2653void wxDataViewColumn::SetWidth(int width)
2654{
2655 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2656
2657
2658 if ((width >= m_minWidth) && (width <= m_maxWidth))
2659 {
2660 m_width = width;
2661 if (dataViewCtrlPtr != NULL)
2662 {
2663 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2664
2665 if (macDataViewListCtrlPtr != NULL)
2666 wxCHECK_RET(macDataViewListCtrlPtr->SetColumnWidth(this->GetNativeData()->GetPropertyID(),static_cast<UInt16>(width)) == noErr,_("Could not set column width."));
2667 }
2668 }
2669}
2670
2671void wxDataViewColumn::SetAsSortKey(bool WXUNUSED(sort))
2672{
2673 // see wxGTK native wxDataViewColumn implementation
2674 wxFAIL_MSG( "not implemented" );
2675}
2676
2677void wxDataViewColumn::SetNativeData(wxDataViewColumnNativeData* newNativeDataPtr)
2678{
2679 delete this->m_NativeDataPtr;
2680 this->m_NativeDataPtr = newNativeDataPtr;
2681}
2682
2683#endif // wxUSE_DATAVIEWCTRL && !wxUSE_GENERICDATAVIEWCTRL