Fix sending wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK, fixes #10894: Missing OSX...
[wxWidgets.git] / src / osx / carbon / dataview.cpp
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 // ============================================================================
33 static DataBrowserGetContextualMenuUPP gDataBrowserTableViewGetContextualMenuUPP = NULL;
34 static DataBrowserItemCompareUPP gDataBrowserTableViewItemCompareUPP = NULL;
35 static DataBrowserItemDataUPP gDataBrowserTableViewItemDataUPP = NULL;
36 static DataBrowserItemNotificationUPP gDataBrowserTableViewItemNotificationUPP = NULL;
37
38 static DataBrowserAcceptDragUPP gDataBrowserTableViewAcceptDragUPP = NULL;
39 static DataBrowserAddDragItemUPP gDataBrowserTableViewAddDragItemUPP = NULL;
40 static DataBrowserReceiveDragUPP gDataBrowserTableViewReceiveDragUPP = NULL;
41
42 static DataBrowserDrawItemUPP gDataBrowserTableViewDrawItemUPP = NULL;
43 static DataBrowserEditItemUPP gDataBrowserTableViewEditItemUPP = NULL;
44 static DataBrowserHitTestUPP gDataBrowserTableViewHitTestUPP = NULL;
45 static DataBrowserTrackingUPP gDataBrowserTableViewTrackingUPP = NULL;
46
47 // ============================================================================
48 // Functions used locally in dataview.cpp
49 // ============================================================================
50 static 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
69 static const EventTypeSpec eventList[] =
70 {
71 { kEventClassControl, kEventControlHit },
72 { kEventClassControl, kEventControlDraw }
73 };
74
75 static 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
131 static 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 // ============================================================================
205 DEFINE_ONE_SHOT_HANDLER_GETTER(DataBrowserCtrlEventHandler)
206
207 // ============================================================================
208 // Helper functions for dataview implementation on OSX
209 // ============================================================================
210 wxWidgetImplType* 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 // ============================================================================
219 pascal 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 errDataBrowserPropertyNotSupported;
228 } /* wxMacDataBrowserTableViewControl::DataBrowserCompareProc(ControlRef, DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID) */
229
230 pascal 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
239 pascal 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
250 pascal 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
259 pascal 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
268 pascal 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
276 pascal 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
284 pascal 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
295 pascal 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
303 pascal 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
311 pascal 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
319 wxMacDataBrowserTableViewControl::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
409 wxMacDataBrowserTableViewControl::~wxMacDataBrowserTableViewControl(void)
410 {
411 ::RemoveEventHandler((EventHandlerRef) m_macDataViewCtrlEventHandler);
412 } /* wxMacDataBrowserTableViewControl::~wxMacDataBrowserTableViewControl(void) */
413
414 //
415 // callback handling
416 //
417 OSStatus wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks const* callbacks)
418 {
419 return ::SetDataBrowserCallbacks(this->m_controlRef,callbacks);
420 } /* wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks const*) */
421
422 OSStatus wxMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks const* customCallbacks)
423 {
424 return ::SetDataBrowserCustomCallbacks(this->m_controlRef,customCallbacks);
425 } /* xMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks const*) */
426
427 //
428 // DnD handling
429 //
430 OSStatus wxMacDataBrowserTableViewControl::EnableAutomaticDragTracking(bool enable)
431 {
432 return ::SetAutomaticControlDragTrackingEnabledForWindow(::GetControlOwner(this->m_controlRef),enable);
433 }
434
435 //
436 // header handling
437 //
438 OSStatus 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
444 OSStatus wxMacDataBrowserTableViewControl::SetHeaderDesc(DataBrowserPropertyID propertyID, DataBrowserListViewHeaderDesc* desc)
445 {
446 return ::SetDataBrowserListViewHeaderDesc(this->m_controlRef,propertyID,desc);
447 }
448
449 //
450 // layout handling
451 //
452 OSStatus wxMacDataBrowserTableViewControl::AutoSizeColumns()
453 {
454 return AutoSizeDataBrowserListViewColumns(this->m_controlRef);
455 }
456
457 OSStatus wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool enableHeight, bool enableWidth)
458 {
459 return ::SetDataBrowserTableViewGeometry(this->GetControlRef(),enableWidth,enableHeight);
460 } /* wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool, bool) */
461
462 OSStatus wxMacDataBrowserTableViewControl::GetAttributes(OptionBits* attributes)
463 {
464 return ::DataBrowserGetAttributes(this->GetControlRef(),attributes);
465 } /* wxMacDataBrowserTableViewControl::GetAttributes(OptionBits*) */
466
467 OSStatus wxMacDataBrowserTableViewControl::GetColumnWidth(DataBrowserPropertyID propertyID, UInt16* width) const
468 {
469 return ::GetDataBrowserTableViewNamedColumnWidth(this->m_controlRef,propertyID,width);
470 }
471
472 OSStatus wxMacDataBrowserTableViewControl::GetDefaultColumnWidth( UInt16 *width ) const
473 {
474 return GetDataBrowserTableViewColumnWidth(this->m_controlRef, width );
475 }
476
477 OSStatus wxMacDataBrowserTableViewControl::GetDefaultRowHeight(UInt16* height) const
478 {
479 return ::GetDataBrowserTableViewRowHeight(this->m_controlRef,height);
480 }
481
482 OSStatus wxMacDataBrowserTableViewControl::GetHeaderButtonHeight(UInt16 *height)
483 {
484 return ::GetDataBrowserListViewHeaderBtnHeight(this->m_controlRef,height);
485 }
486
487 OSStatus 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
492 OSStatus wxMacDataBrowserTableViewControl::GetRowHeight(DataBrowserItemID item, UInt16* height) const
493 {
494 return ::GetDataBrowserTableViewItemRowHeight(this->m_controlRef,item,height);
495 } /* wxMacDataBrowserTableViewControl::GetRowHeight(DataBrowserItemID, UInt16*) const */
496
497 OSStatus wxMacDataBrowserTableViewControl::GetScrollPosition( UInt32 *top , UInt32 *left ) const
498 {
499 return GetDataBrowserScrollPosition(this->m_controlRef, top , left );
500 }
501
502 OSStatus wxMacDataBrowserTableViewControl::SetAttributes(OptionBits attributes)
503 {
504 return ::DataBrowserChangeAttributes(this->GetControlRef(),attributes,~attributes);
505 } /* wxMacDataBrowserTableViewControl::SetAttributes(OptionBits) */
506
507 OSStatus wxMacDataBrowserTableViewControl::SetColumnWidth(DataBrowserPropertyID propertyID, UInt16 width)
508 {
509 return ::SetDataBrowserTableViewNamedColumnWidth(this->m_controlRef,propertyID,width);
510 }
511
512 OSStatus wxMacDataBrowserTableViewControl::SetDefaultColumnWidth(UInt16 width)
513 {
514 return ::SetDataBrowserTableViewColumnWidth(this->m_controlRef,width);
515 }
516
517 OSStatus wxMacDataBrowserTableViewControl::SetDefaultRowHeight(UInt16 height)
518 {
519 return ::SetDataBrowserTableViewRowHeight(this->m_controlRef,height);
520 }
521
522 OSStatus wxMacDataBrowserTableViewControl::SetHasScrollBars(bool horiz, bool vert)
523 {
524 return ::SetDataBrowserHasScrollBars(this->m_controlRef,horiz,vert);
525 } /* wxMacDataBrowserTableViewControl::SetHasScrollBars(bool, bool) */
526
527 OSStatus wxMacDataBrowserTableViewControl::SetHeaderButtonHeight(UInt16 height)
528 {
529 return ::SetDataBrowserListViewHeaderBtnHeight(this->m_controlRef,height);
530 } /* wxMacDataBrowserTableViewControl::SetHeaderButtonHeight(UInt16) */
531
532 OSStatus wxMacDataBrowserTableViewControl::SetHiliteStyle(DataBrowserTableViewHiliteStyle hiliteStyle)
533 {
534 return ::SetDataBrowserTableViewHiliteStyle(this->m_controlRef,hiliteStyle);
535 } /*wxMacDataBrowserTableViewControl::SetHiliteStyle(DataBrowserTableViewHiliteStyle) */
536
537 OSStatus wxMacDataBrowserTableViewControl::SetIndent(float Indent)
538 {
539 return ::DataBrowserSetMetric(this->m_controlRef,kDataBrowserMetricDisclosureColumnPerDepthGap,true,Indent);
540 } /* wxMacDataBrowserTableViewControl::SetIndent(float* Indent) */
541
542 OSStatus wxMacDataBrowserTableViewControl::SetItemRowHeight(DataBrowserItemID item, UInt16 height)
543 {
544 return ::SetDataBrowserTableViewItemRowHeight(this->m_controlRef,item,height);
545 }
546
547 OSStatus wxMacDataBrowserTableViewControl::SetScrollPosition(UInt32 top, UInt32 left)
548 {
549 return ::SetDataBrowserScrollPosition(this->m_controlRef,top,left);
550 }
551
552 //
553 // column handling
554 //
555 OSStatus wxMacDataBrowserTableViewControl::GetColumnCount(UInt32* numColumns) const
556 {
557 return ::GetDataBrowserTableViewColumnCount(this->m_controlRef,numColumns);
558 }
559
560 OSStatus wxMacDataBrowserTableViewControl::GetColumnIndex(DataBrowserPropertyID propertyID, DataBrowserTableViewColumnIndex* index) const
561 {
562 return ::GetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,index);
563 } /* wxMacDataBrowserTableViewControl::GetColumnIndex(DataBrowserPropertyID, DataBrowserTableViewColumnIndex*) const */
564
565 OSStatus 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
573 OSStatus wxMacDataBrowserTableViewControl::GetPropertyFlags(DataBrowserPropertyID propertyID, DataBrowserPropertyFlags *flags) const
574 {
575 return ::GetDataBrowserPropertyFlags(this->m_controlRef,propertyID,flags);
576 }
577
578 OSStatus wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserItemDataRef itemData, DataBrowserPropertyID* propertyID) const
579 {
580 return ::GetDataBrowserItemDataProperty(itemData,propertyID);
581 } /* wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserItemDataRef, DataBrowserPropertyID*) */
582
583 OSStatus wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserTableViewColumnIndex index, DataBrowserTableViewColumnID* propertyID) const
584 {
585 return ::GetDataBrowserTableViewColumnProperty(this->m_controlRef,index,propertyID);
586 } /* wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserTableViewColumnIndex, DataBrowserTableViewColumnID*) */
587
588 OSStatus 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
598 OSStatus wxMacDataBrowserTableViewControl::RemoveColumnByProperty(DataBrowserTableViewColumnID propertyID)
599 {
600 return ::RemoveDataBrowserTableViewColumn(this->m_controlRef,propertyID);
601 } /* wxMacDataBrowserTableViewControl::RemoveColumnByProperty(DataBrowserTableViewColumnID) */
602
603 OSStatus 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
612 OSStatus wxMacDataBrowserTableViewControl::SetColumnIndex(DataBrowserPropertyID propertyID, DataBrowserTableViewColumnIndex index)
613 {
614 return ::SetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,index);
615 } /* wxMacDataBrowserTableViewControl::SetColumnIndex(DataBrowserPropertyID, DataBrowserTableViewColumnIndex) */
616
617 OSStatus wxMacDataBrowserTableViewControl::SetDisclosureColumn(DataBrowserPropertyID propertyID, Boolean expandableRows)
618 {
619 return ::SetDataBrowserListViewDisclosureColumn(this->m_controlRef,propertyID,expandableRows);
620 }
621
622 OSStatus 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 //
630 OSStatus 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
635 OSStatus 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
665 OSStatus 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
670 OSStatus wxMacDataBrowserTableViewControl::GetItemID( DataBrowserTableViewRowIndex row, DataBrowserItemID * item ) const
671 {
672 return GetDataBrowserTableViewItemID(this->m_controlRef,row,item);
673 }
674
675 OSStatus 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
680 OSStatus wxMacDataBrowserTableViewControl::GetItemRow(DataBrowserItemID item, DataBrowserTableViewRowIndex* row) const
681 {
682 return GetDataBrowserTableViewItemRow(this->m_controlRef,item,row);
683 }
684
685 OSStatus wxMacDataBrowserTableViewControl::GetItemState(DataBrowserItemID item, DataBrowserItemState* state) const
686 {
687 return ::GetDataBrowserItemState(this->m_controlRef,item,state);
688 }
689
690 OSStatus 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
700 OSStatus wxMacDataBrowserTableViewControl::RemoveItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty)
701 {
702 return ::RemoveDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty);
703 }
704
705 OSStatus 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
710 OSStatus 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 //
719 size_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
743 OSStatus wxMacDataBrowserTableViewControl::GetSelectionAnchor(DataBrowserItemID* first, DataBrowserItemID* last) const
744 {
745 return ::GetDataBrowserSelectionAnchor(this->m_controlRef,first,last);
746 } /* wxMacDataBrowserTableViewControl::GetSelectionAnchor(DataBrowserItemID*, DataBrowserItemID*) const */
747
748 OSStatus wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags* flags) const
749 {
750 return ::GetDataBrowserSelectionFlags(this->m_controlRef,flags);
751 } /* wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags*) const */
752
753 bool wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID item) const
754 {
755 return ::IsDataBrowserItemSelected(this->m_controlRef,item);
756 } /* wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID) const */
757
758 OSStatus wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags flags)
759 {
760 return ::SetDataBrowserSelectionFlags(this->m_controlRef,flags);
761 } /* wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags) */
762
763 OSStatus 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
768 OSStatus wxMacDataBrowserTableViewControl::GetSortOrder(DataBrowserSortOrder* order) const
769 {
770 return ::GetDataBrowserSortOrder(this->m_controlRef,order);
771 }
772
773 OSStatus wxMacDataBrowserTableViewControl::GetSortProperty(DataBrowserPropertyID* propertyID) const
774 {
775 return ::GetDataBrowserSortProperty(this->m_controlRef,propertyID);
776 }
777
778 OSStatus wxMacDataBrowserTableViewControl::Resort(DataBrowserItemID container, Boolean sortChildren)
779 {
780 return ::SortDataBrowserContainer(this->m_controlRef,container,sortChildren);
781 } /* wxMacDataBrowserTableViewControl::Resort(DataBrowserItemID, Boolean) */
782
783 OSStatus wxMacDataBrowserTableViewControl::SetSortOrder(DataBrowserSortOrder order)
784 {
785 return ::SetDataBrowserSortOrder(this->m_controlRef,order);
786 }
787
788 OSStatus wxMacDataBrowserTableViewControl::SetSortProperty(DataBrowserPropertyID propertyID)
789 {
790 return ::SetDataBrowserSortProperty(this->m_controlRef,propertyID);
791 }
792
793 //
794 // container handling
795 //
796 OSStatus wxMacDataBrowserTableViewControl::CloseContainer(DataBrowserItemID containerID)
797 {
798 return ::CloseDataBrowserContainer(this->m_controlRef,containerID);
799 } /* wxMacDataBrowserTableViewControl::CloseContainer(DataBrowserItemID) */
800
801 OSStatus wxMacDataBrowserTableViewControl::OpenContainer(DataBrowserItemID containerID)
802 {
803 return ::OpenDataBrowserContainer(this->m_controlRef,containerID);
804 } /* wxMacDataBrowserTableViewControl::OpenContainer(DataBrowserItemID) */
805
806 IMPLEMENT_ABSTRACT_CLASS(wxMacDataBrowserTableViewControl,wxMacControl)
807
808 // ============================================================================
809 // wxMacDataBrowserListViewControl
810 // ============================================================================
811 #pragma mark -
812 //
813 // column handling
814 //
815 OSStatus 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 //
827 wxMacDataViewDataBrowserListViewControl::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 //
839 bool 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
850 bool wxMacDataViewDataBrowserListViewControl::DeleteColumn(wxDataViewColumn* columnPtr)
851 {
852 return (this->RemoveColumnByProperty(columnPtr->GetNativeData()->GetPropertyID()) == noErr);
853 }
854
855 void 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
860 wxDataViewColumn* 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
871 int 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
884 bool 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 //
919 bool 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
928 bool 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
949 void wxMacDataViewDataBrowserListViewControl::Collapse(wxDataViewItem const& item)
950 {
951 this->CloseContainer(reinterpret_cast<DataBrowserItemID>(item.GetID()));
952 }
953
954 void 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
966 void wxMacDataViewDataBrowserListViewControl::Expand(wxDataViewItem const& item)
967 {
968 this->OpenContainer(reinterpret_cast<DataBrowserItemID>(item.GetID()));
969 }
970
971 unsigned 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
980 wxRect 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
996 bool wxMacDataViewDataBrowserListViewControl::IsExpanded(wxDataViewItem const& item) const
997 {
998 DataBrowserItemState state;
999
1000
1001 return ((this->GetItemState(reinterpret_cast<DataBrowserItemID>(item.GetID()),&state) == noErr) &&
1002 (state & kDataBrowserContainerIsOpen != 0));
1003 }
1004
1005 bool wxMacDataViewDataBrowserListViewControl::Reload(void)
1006 {
1007 bool noFailureFlag;
1008
1009 wxDataViewItemArray dataViewChildren;
1010
1011
1012 noFailureFlag = (this->RemoveItems() == noErr);
1013 this->SetScrollPosition(0,0); // even after having removed all items the scrollbars may remain at their old position -> reset them
1014 this->GetDataViewCtrl()->GetModel()->GetChildren(wxDataViewItem(),dataViewChildren);
1015 this->GetDataViewCtrl()->GetModel()->ItemsAdded(wxDataViewItem(),dataViewChildren);
1016
1017 return noFailureFlag;
1018 }
1019
1020 bool wxMacDataViewDataBrowserListViewControl::Remove(wxDataViewItem const& parent, wxDataViewItem const& item)
1021 {
1022 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1023
1024
1025 return (this->RemoveItem(reinterpret_cast<DataBrowserItemID>(parent.GetID()),&itemID) == noErr);
1026 }
1027
1028 bool wxMacDataViewDataBrowserListViewControl::Remove(wxDataViewItem const& parent, wxDataViewItemArray const& items)
1029 {
1030 bool noFailureFlag;
1031
1032 DataBrowserItemID* itemIDs;
1033
1034 size_t noOfEntries;
1035
1036
1037 // convert all valid data view items to data browser items:
1038 itemIDs = ::CreateDataBrowserItemIDArray(noOfEntries,items);
1039 // insert all valid items into control:
1040 noFailureFlag = ((noOfEntries == 0) ||
1041 !(parent.IsOk()) && (this->RemoveItems(kDataBrowserNoItem,noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr) ||
1042 parent.IsOk() && (this->RemoveItems(reinterpret_cast<DataBrowserItemID>(parent.GetID()),noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr));
1043 // give allocated array space free again:
1044 delete[] itemIDs;
1045 // done:
1046 return noFailureFlag;
1047 }
1048
1049 bool wxMacDataViewDataBrowserListViewControl::Update(wxDataViewColumn const* columnPtr)
1050 {
1051 return (this->UpdateItems(kDataBrowserNoItem,0,NULL,kDataBrowserItemNoProperty,columnPtr->GetNativeData()->GetPropertyID()) == noErr);
1052 }
1053
1054 bool wxMacDataViewDataBrowserListViewControl::Update(wxDataViewItem const& parent, wxDataViewItem const& item)
1055 {
1056 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1057
1058
1059 if (parent.IsOk())
1060 return (this->UpdateItem(reinterpret_cast<DataBrowserItemID>(parent.GetID()),&itemID) == noErr);
1061 else
1062 return (this->UpdateItem(kDataBrowserNoItem,&itemID) == noErr);
1063 }
1064
1065 bool wxMacDataViewDataBrowserListViewControl::Update(wxDataViewItem const& parent, wxDataViewItemArray const& items)
1066 {
1067 bool noFailureFlag;
1068
1069 DataBrowserItemID* itemIDs;
1070
1071 size_t noOfEntries;
1072
1073
1074 // convert all valid data view items to data browser items:
1075 itemIDs = ::CreateDataBrowserItemIDArray(noOfEntries,items);
1076 if (parent.IsOk())
1077 noFailureFlag = (this->UpdateItems(reinterpret_cast<DataBrowserItemID>(parent.GetID()),noOfEntries,itemIDs,kDataBrowserItemNoProperty,kDataBrowserItemNoProperty) == noErr);
1078 else
1079 noFailureFlag = (this->UpdateItems(kDataBrowserNoItem,noOfEntries,itemIDs,kDataBrowserItemNoProperty,kDataBrowserItemNoProperty) == noErr);
1080 // release allocated array space:
1081 delete[] itemIDs;
1082 // done:
1083 return noFailureFlag;
1084 }
1085
1086 //
1087 // model related methods
1088 //
1089 bool wxMacDataViewDataBrowserListViewControl::AssociateModel(wxDataViewModel* WXUNUSED(model))
1090 {
1091 return true;
1092 }
1093
1094 //
1095 // selection related methods (inherited from wxDataViewWidgetImpl)
1096 //
1097 int wxMacDataViewDataBrowserListViewControl::GetSelections(wxDataViewItemArray& sel) const
1098 {
1099 size_t noOfSelectedItems;
1100
1101 wxArrayDataBrowserItemID itemIDs;
1102
1103
1104 noOfSelectedItems = this->GetSelectedItemIDs(itemIDs);
1105 sel.Empty();
1106 sel.SetCount(noOfSelectedItems);
1107 for (size_t i=0; i<noOfSelectedItems; ++i)
1108 sel[i] = wxDataViewItem(reinterpret_cast<void*>(itemIDs[i]));
1109 return static_cast<int>(noOfSelectedItems);
1110 }
1111
1112 bool wxMacDataViewDataBrowserListViewControl::IsSelected(wxDataViewItem const& item) const
1113 {
1114 return this->IsItemSelected(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1115 }
1116
1117 void wxMacDataViewDataBrowserListViewControl::Select(wxDataViewItem const& item)
1118 {
1119 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1120
1121
1122 this->SetSelectedItems(1,&itemID,kDataBrowserItemsAdd);
1123 }
1124
1125 void wxMacDataViewDataBrowserListViewControl::SelectAll(void)
1126 {
1127 DataBrowserItemID* itemIDPtr;
1128
1129 Handle handle(::NewHandle(0));
1130
1131 size_t noOfItems;
1132
1133
1134 wxCHECK_RET(this->GetItems(kDataBrowserNoItem,true,kDataBrowserItemAnyState,handle) == noErr,_("Could not get items."));
1135 noOfItems = static_cast<size_t>(::GetHandleSize(handle)/sizeof(DataBrowserItemID));
1136 ::HLock(handle);
1137 itemIDPtr = (DataBrowserItemID*) (*handle);
1138 this->SetSelectedItems(noOfItems,itemIDPtr,kDataBrowserItemsAssign);
1139 ::HUnlock(handle);
1140 ::DisposeHandle(handle);
1141 }
1142
1143 void wxMacDataViewDataBrowserListViewControl::Unselect(wxDataViewItem const& item)
1144 {
1145 DataBrowserItemID itemID(reinterpret_cast<DataBrowserItemID>(item.GetID()));
1146
1147
1148 this->SetSelectedItems(1,&itemID,kDataBrowserItemsRemove);
1149 }
1150
1151 void wxMacDataViewDataBrowserListViewControl::UnselectAll(void)
1152 {
1153 DataBrowserItemID* itemIDPtr;
1154
1155 Handle handle(::NewHandle(0));
1156
1157 size_t noOfItems;
1158
1159
1160 wxCHECK_RET(this->GetItems(kDataBrowserNoItem,true,kDataBrowserItemAnyState,handle) == noErr,_("Could not get items."));
1161 noOfItems = static_cast<size_t>(::GetHandleSize(handle)/sizeof(DataBrowserItemID));
1162 ::HLock(handle);
1163 itemIDPtr = (DataBrowserItemID*) (*handle);
1164 this->SetSelectedItems(noOfItems,itemIDPtr,kDataBrowserItemsRemove);
1165 ::HUnlock(handle);
1166 ::DisposeHandle(handle);
1167 }
1168
1169 //
1170 // sorting related methods
1171 //
1172 wxDataViewColumn* wxMacDataViewDataBrowserListViewControl::GetSortingColumn(void) const
1173 {
1174 DataBrowserPropertyID propertyID;
1175
1176
1177 if (this->GetSortProperty(&propertyID) == noErr)
1178 return this->GetColumnPtr(propertyID);
1179 else
1180 return NULL;
1181 }
1182
1183 void wxMacDataViewDataBrowserListViewControl::Resort(void)
1184 {
1185 (void) this->Resort();
1186 }
1187
1188 //
1189 // other methods (inherited from wxDataViewWidgetImpl)
1190 //
1191 void wxMacDataViewDataBrowserListViewControl::HitTest(wxPoint const& point, wxDataViewItem& item, wxDataViewColumn*& columnPtr) const
1192 {
1193 // not yet implemented:
1194 item = wxDataViewItem();
1195 columnPtr = NULL;
1196 }
1197
1198 void wxMacDataViewDataBrowserListViewControl::DoSetIndent(int indent)
1199 {
1200 this->SetIndent(static_cast<float>(indent));
1201 }
1202
1203 void wxMacDataViewDataBrowserListViewControl::SetRowHeight(wxDataViewItem const& item, unsigned int height)
1204 {
1205 this->SetItemRowHeight(reinterpret_cast<DataBrowserItemID>(item.GetID()),static_cast<UInt16>(height));
1206 }
1207
1208 void wxMacDataViewDataBrowserListViewControl::OnSize(void)
1209 {
1210 UInt32 noOfColumns;
1211
1212
1213 this->GetColumnCount(&noOfColumns);
1214 if (noOfColumns <= 1) // no horizontal scroll bar and the only column expands to the width of the whole control
1215 {
1216 this->SetHasScrollBars(false,true);
1217 this->AutoSizeColumns();
1218 }
1219 else // otherwise keep the current column size and have scrollbars in both directions
1220 this->SetHasScrollBars(true,true);
1221 }
1222
1223 //
1224 // callback functions (inherited from wxMacDataBrowserTableViewControl)
1225 //
1226 Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID itemOneID, DataBrowserItemID itemTwoID, DataBrowserPropertyID sortProperty)
1227 {
1228 DataBrowserSortOrder sortOrder;
1229
1230 DataBrowserTableViewColumnIndex modelColumnIndex;
1231
1232 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
1233
1234
1235 wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly."));
1236 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
1237 if (sortProperty >= kMinPropertyID)
1238 {
1239 // variable definition and initialization:
1240 wxDataViewColumn* ColumnPtr(this->GetColumnPtr(sortProperty));
1241
1242 wxCHECK_MSG(ColumnPtr != NULL,false,_("Could not determine column index."));
1243 modelColumnIndex = ColumnPtr->GetModelColumn();
1244 }
1245 else
1246 modelColumnIndex = 0;
1247 this->GetSortOrder(&sortOrder);
1248 return static_cast<Boolean>(dataViewCtrlPtr->GetModel()->Compare(wxDataViewItem(reinterpret_cast<void*>(itemOneID)),wxDataViewItem(reinterpret_cast<void*>(itemTwoID)),
1249 modelColumnIndex,sortOrder != kDataBrowserOrderDecreasing) < 0);
1250 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID) */
1251
1252 void wxMacDataViewDataBrowserListViewControl::DataBrowserGetContextualMenuProc(MenuRef* menu, UInt32* helpType, CFStringRef* helpItemString, AEDesc* WXUNUSED(selection))
1253 // In this method we do not supply a contextual menu handler at all but only send a wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU.
1254 {
1255 wxArrayDataBrowserItemID itemIDs;
1256
1257 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
1258
1259
1260 wxCHECK_RET(dataViewCtrlPtr != NULL,_("wxWidget control pointer is not a data view pointer"));
1261 // initialize parameters so that no context menu will be displayed automatically by the native data browser:
1262 *menu = NULL;
1263 *helpType = kCMHelpItemNoHelp;
1264 *helpItemString = NULL;
1265 // create information for a context menu event:
1266 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU,dataViewCtrlPtr->GetId());
1267
1268 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1269 dataViewEvent.SetModel(dataViewCtrlPtr->GetModel());
1270 // get the item information;
1271 // 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:
1272 if (this->GetSelectedItemIDs(itemIDs) > 0)
1273 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemIDs[0])));
1274 // finally send the equivalent wxWidget event:
1275 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1276 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserGetContextualMenuProc(MenuRef*, UInt32*, CFStringRef*, AEDesc*) */
1277
1278 OSStatus wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemDataRef itemData, Boolean getValue)
1279 {
1280 if (getValue)
1281 {
1282 // variable definitions:
1283 wxDataViewCtrl* dataViewCtrlPtr;
1284
1285 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1286 wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
1287 if (dataViewCtrlPtr->IsDeleting())
1288 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
1289 else
1290 {
1291 // variable definitions:
1292 OSStatus errorStatus;
1293 wxDataViewColumn* dataViewColumnPtr;
1294
1295 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,errDataBrowserNotConfigured,_("Pointer to model not set correctly."));
1296 dataViewColumnPtr = this->GetColumnPtr(propertyID);
1297 wxCHECK_MSG((dataViewColumnPtr != NULL) && (dataViewColumnPtr->GetRenderer() != NULL),errDataBrowserNotConfigured,_("There is no column or renderer for the specified column index."));
1298
1299 wxDataViewItem dvItem(reinterpret_cast<void*>(itemID));
1300 unsigned int col = dataViewColumnPtr->GetModelColumn();
1301
1302 switch (dataViewColumnPtr->GetRenderer()->GetNativeData()->GetPropertyType())
1303 {
1304 case kDataBrowserCheckboxType:
1305 {
1306 // variable definition:
1307 ThemeButtonValue buttonValue;
1308
1309 errorStatus = ::GetDataBrowserItemDataButtonValue(itemData,&buttonValue);
1310 if (errorStatus == noErr)
1311 {
1312 if (buttonValue == kThemeButtonOn)
1313 {
1314 // variable definition and initialization:
1315 wxVariant modifiedData(true);
1316
1317 if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData, dvItem, col) &&
1318 dataViewCtrlPtr->GetModel()->ValueChanged(dvItem, col))
1319 return noErr;
1320 else
1321 return errDataBrowserInvalidPropertyData;
1322 }
1323 else if (buttonValue == kThemeButtonOff)
1324 {
1325 // variable definition and initialization:
1326 wxVariant modifiedData(false);
1327
1328 if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData, dvItem, col) &&
1329 dataViewCtrlPtr->GetModel()->ValueChanged(dvItem, col))
1330 return noErr;
1331 else
1332 return errDataBrowserInvalidPropertyData;
1333 }
1334 else
1335 return errDataBrowserInvalidPropertyData;
1336 }
1337 else
1338 return errorStatus;
1339 } /* block */
1340 case kDataBrowserTextType:
1341 {
1342 // variable definitions:
1343 CFStringRef stringReference;
1344
1345 errorStatus = ::GetDataBrowserItemDataText(itemData,&stringReference);
1346 if (errorStatus == noErr)
1347 {
1348 // variable definitions and initializations:
1349 #if wxCHECK_VERSION(2,9,0)
1350 wxCFStringRef modifiedString(stringReference);
1351 #else
1352 wxMacCFStringHolder modifiedString(stringReference);
1353 #endif
1354 wxVariant modifiedData(modifiedString.AsString());
1355
1356 if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData, dvItem, col) &&
1357 dataViewCtrlPtr->GetModel()->ValueChanged(dvItem, col))
1358 return noErr;
1359 else
1360 return errDataBrowserInvalidPropertyData;
1361 }
1362 else
1363 return errorStatus;
1364 } /* block */
1365 default:
1366 return errDataBrowserPropertyNotSupported;
1367 }
1368 }
1369 }
1370 else
1371 {
1372 if (propertyID >= kMinPropertyID) // in case data columns set the data
1373 {
1374 // variable definitions:
1375 wxVariant variant;
1376 wxDataViewColumn* dataViewColumnPtr;
1377 wxDataViewCtrl* dataViewCtrlPtr;
1378
1379 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1380 wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
1381 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,errDataBrowserNotConfigured,_("Pointer to model not set correctly."));
1382 dataViewColumnPtr = this->GetColumnPtr(propertyID);
1383 wxCHECK_MSG(dataViewColumnPtr != NULL,errDataBrowserNotConfigured,_("No column for the specified column position existing."));
1384 wxCHECK_MSG(dataViewColumnPtr->GetRenderer() != NULL,errDataBrowserNotConfigured,_("No renderer specified for column."));
1385 dataViewCtrlPtr->GetModel()->GetValue(variant,wxDataViewItem(reinterpret_cast<void*>(itemID)),dataViewColumnPtr->GetModelColumn());
1386 if (!(variant.IsNull()))
1387 {
1388 dataViewColumnPtr->GetRenderer()->GetNativeData()->SetItemDataRef(itemData);
1389 dataViewColumnPtr->GetRenderer()->SetValue(variant);
1390 wxCHECK_MSG(dataViewColumnPtr->GetRenderer()->Render(),errDataBrowserNotConfigured,_("Rendering failed."));
1391 }
1392 return noErr;
1393 }
1394 else // react on special system requests
1395 {
1396 switch (propertyID)
1397 {
1398 case kDataBrowserContainerIsClosableProperty:
1399 {
1400 // variable definitions:
1401 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
1402
1403 wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
1404 // initialize wxWidget event:
1405 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING,dataViewCtrlPtr->GetId()); // variable definition
1406
1407 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1408 dataViewEvent.SetItem (wxDataViewItem(reinterpret_cast<void*>(itemID)));
1409 dataViewEvent.SetModel (dataViewCtrlPtr->GetModel());
1410 // finally send the equivalent wxWidget event:
1411 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1412 // opening the container is allowed if not vetoed:
1413 return ::SetDataBrowserItemDataBooleanValue(itemData,dataViewEvent.IsAllowed());
1414 } /* block */
1415 case kDataBrowserContainerIsOpenableProperty:
1416 {
1417 // variable definitions:
1418 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
1419
1420 wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
1421 // initialize wxWidget event:
1422 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING,dataViewCtrlPtr->GetId()); // variable definition
1423
1424 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1425 dataViewEvent.SetItem (wxDataViewItem(reinterpret_cast<void*>(itemID)));
1426 dataViewEvent.SetModel (dataViewCtrlPtr->GetModel());
1427 // finally send the equivalent wxWidget event:
1428 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1429 // opening the container is allowed if not vetoed:
1430 return ::SetDataBrowserItemDataBooleanValue(itemData,dataViewEvent.IsAllowed());
1431 } /* block */
1432 case kDataBrowserItemIsContainerProperty:
1433 {
1434 // variable definition:
1435 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
1436
1437 wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
1438 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,errDataBrowserNotConfigured,_("Pointer to model not set correctly."));
1439 return ::SetDataBrowserItemDataBooleanValue(itemData,dataViewCtrlPtr->GetModel()->IsContainer(wxDataViewItem(reinterpret_cast<void*>(itemID))));
1440 } /* block */
1441 case kDataBrowserItemIsEditableProperty:
1442 return ::SetDataBrowserItemDataBooleanValue(itemData,true);
1443 }
1444 }
1445 }
1446 return errDataBrowserPropertyNotSupported;
1447 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc(DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemDataRef, Boolean) */
1448
1449 void wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID itemID, DataBrowserItemNotification message, DataBrowserItemDataRef itemData)
1450 {
1451 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
1452
1453
1454 // 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:
1455 if (dataViewCtrlPtr != NULL)
1456 switch (message)
1457 {
1458 case kDataBrowserContainerClosed:
1459 dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
1460 {
1461 // initialize wxWidget event:
1462 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED,dataViewCtrlPtr->GetId()); // variable definition
1463
1464 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1465 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
1466 // finally send the equivalent wxWidget event:
1467 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1468 } /* block */
1469 break;
1470 case kDataBrowserContainerOpened:
1471 dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
1472 {
1473 // initialize wxWidget event:
1474 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED,dataViewCtrlPtr->GetId()); // variable definition
1475
1476 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1477 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
1478 // finally send the equivalent wxWidget event:
1479 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1480 // add children to the expanded container:
1481 dataViewCtrlPtr->AddChildren(wxDataViewItem(reinterpret_cast<void*>(itemID)));
1482 } /* block */
1483 break;
1484 case kDataBrowserEditStarted:
1485 dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
1486 {
1487 // initialize wxWidget event:
1488 DataBrowserPropertyID propertyID;
1489 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED,dataViewCtrlPtr->GetId()); // variable definition
1490
1491 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1492 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
1493 if (this->GetPropertyID(itemData,&propertyID) == noErr)
1494 {
1495 // variable definition and initialization:
1496 DataBrowserTableViewColumnIndex columnIndex;
1497
1498 wxCHECK_RET(this->GetColumnIndex(propertyID,&columnIndex),_("Column index not found."));
1499 dataViewEvent.SetColumn(columnIndex);
1500 dataViewEvent.SetDataViewColumn(this->GetColumnPtr(propertyID));
1501 }
1502 // finally send the equivalent wxWidget event:
1503 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1504 } /* block */
1505 break;
1506 case kDataBrowserEditStopped:
1507 {
1508 // initialize wxWidget event:
1509 DataBrowserPropertyID propertyID;
1510 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE,dataViewCtrlPtr->GetId()); // variable definition
1511
1512 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1513 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
1514 if (this->GetPropertyID(itemData,&propertyID) == noErr)
1515 {
1516 // variable definition and initialization:
1517 DataBrowserTableViewColumnIndex columnIndex;
1518
1519 wxCHECK_RET(this->GetColumnIndex(propertyID,&columnIndex),_("Column index not found."));
1520 dataViewEvent.SetColumn(columnIndex);
1521 dataViewEvent.SetDataViewColumn(this->GetColumnPtr(propertyID));
1522 }
1523 // finally send the equivalent wxWidget event:
1524 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1525 } /* block */
1526 break;
1527 case kDataBrowserItemAdded:
1528 dataViewCtrlPtr->FinishCustomItemEditing();
1529 break;
1530 case kDataBrowserItemDeselected:
1531 dataViewCtrlPtr->FinishCustomItemEditing();
1532 break;
1533 case kDataBrowserItemDoubleClicked:
1534 {
1535 // initialize wxWidget event:
1536 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED,dataViewCtrlPtr->GetId()); // variable definition
1537
1538 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1539 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
1540 // finally send the equivalent wxWidget event:
1541 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1542 } /* block */
1543 break;
1544 case kDataBrowserItemRemoved:
1545 dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
1546 break;
1547 case kDataBrowserItemSelected:
1548 break; // not implemented by wxWidgets; see kDataBrowserSelectionSetChanged
1549 case kDataBrowserSelectionSetChanged:
1550 {
1551 // initialize wxWidget event:
1552 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED,dataViewCtrlPtr->GetId()); // variable definition
1553
1554 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1555 dataViewEvent.SetModel (dataViewCtrlPtr->GetModel());
1556 // finally send the equivalent wxWidget event:
1557 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1558 } /* block */
1559 break;
1560 case kDataBrowserTargetChanged: // no idea if this notification is ever sent
1561 break;
1562 case kDataBrowserUserStateChanged:
1563 {
1564 // finish custom item editing if necessary:
1565 dataViewCtrlPtr->FinishCustomItemEditing();
1566 // update column widths:
1567 for (size_t i=0; i<dataViewCtrlPtr->GetColumnCount(); ++i)
1568 {
1569 // constant definition for abbreviational purposes:
1570 wxDataViewColumn* const columnPtr = dataViewCtrlPtr->GetColumnPtr(i);
1571 // variable definition:
1572 UInt16 columnWidth;
1573
1574 wxCHECK_RET(this->GetColumnWidth(columnPtr->GetNativeData()->GetPropertyID(),&columnWidth) == noErr,_("Column width could not be determined"));
1575 columnPtr->SetWidthVariable(columnWidth);
1576 }
1577 // update sorting orders:
1578 DataBrowserPropertyID propertyID; // variable definition
1579
1580 if ((this->GetSortProperty(&propertyID) == noErr) && (propertyID >= kMinPropertyID))
1581 {
1582 DataBrowserSortOrder sortOrder;
1583 DataBrowserTableViewColumnIndex columnIndex;
1584
1585 if ((this->GetSortOrder(&sortOrder) == noErr) && (this->GetColumnIndex(propertyID,&columnIndex) == noErr))
1586 {
1587 // variable definition and initialization:
1588 wxDataViewColumn* columnPtr;
1589 columnPtr = dataViewCtrlPtr->GetColumn(columnIndex);
1590 // check if the sort order has changed:
1591 if ( columnPtr->IsSortOrderAscending() && (sortOrder == kDataBrowserOrderDecreasing) ||
1592 !(columnPtr->IsSortOrderAscending()) && (sortOrder == kDataBrowserOrderIncreasing))
1593 {
1594 columnPtr->SetSortOrder(!(columnPtr->IsSortOrderAscending()));
1595 // initialize wxWidget event:
1596 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED,dataViewCtrlPtr->GetId()); // variable defintion
1597
1598 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1599 dataViewEvent.SetColumn(columnIndex);
1600 dataViewEvent.SetDataViewColumn(columnPtr);
1601 // finally send the equivalent wxWidget event:
1602 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1603 }
1604 }
1605 }
1606 } /* block */
1607 break;
1608 }
1609 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID, DataBrowserItemNotification, DataBrowserItemDataRef) */
1610
1611 void wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemState state, Rect const* rectangle, SInt16 bitDepth, Boolean colorDevice)
1612 {
1613 DataBrowserTableViewColumnIndex columnIndex;
1614
1615 wxDataViewColumn* dataViewColumnPtr;
1616
1617 wxDataViewCtrl* dataViewCtrlPtr;
1618
1619 wxDataViewCustomRenderer* dataViewCustomRendererPtr;
1620
1621 wxVariant dataToRender;
1622
1623 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1624 wxCHECK_RET(dataViewCtrlPtr != NULL, _("Pointer to data view control not set correctly."));
1625 wxCHECK_RET(dataViewCtrlPtr->GetModel() != NULL, _("Pointer to model not set correctly."));
1626 wxCHECK_RET(this->GetColumnIndex(propertyID,&columnIndex) == noErr,_("Could not determine column index."));
1627 dataViewColumnPtr = this->GetColumnPtr(propertyID);
1628 wxCHECK_RET(dataViewColumnPtr != NULL,_("No column for the specified column existing."));
1629 dataViewCustomRendererPtr = dynamic_cast<wxDataViewCustomRenderer*>(dataViewColumnPtr->GetRenderer());
1630 wxCHECK_RET(dataViewCustomRendererPtr != NULL,_("No renderer or invalid renderer type specified for custom data column."));
1631 dataViewCtrlPtr->GetModel()->GetValue(dataToRender,wxDataViewItem(reinterpret_cast<void*>(itemID)),dataViewColumnPtr->GetModelColumn());
1632 dataViewCustomRendererPtr->SetValue(dataToRender);
1633
1634 wxDataViewItem dataItem( reinterpret_cast<void*>(itemID) );
1635 dataViewCtrlPtr->GetModel()->GetValue(dataToRender,dataItem,dataViewColumnPtr->GetModelColumn());
1636 dataViewCustomRendererPtr->SetValue(dataToRender);
1637
1638 // try to determine the content's size (drawable part):
1639 Rect content;
1640 RgnHandle rgn(NewRgn());
1641 UInt16 headerHeight;
1642
1643 if (GetControlRegion(m_controlRef,kControlContentMetaPart,rgn) == noErr)
1644 GetRegionBounds(rgn,&content);
1645 else
1646 GetControlBounds(m_controlRef, &content);
1647 ::DisposeRgn(rgn);
1648 // space for the header
1649 this->GetHeaderButtonHeight(&headerHeight);
1650 content.top += headerHeight;
1651 // extra space for the frame (todo: do not how to determine the space automatically from the control)
1652 content.top += 5;
1653 content.left += 5;
1654 content.right -= 3;
1655 content.bottom -= 3;
1656 // extra space for the scrollbars:
1657 content.bottom -= wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y);
1658 content.right -= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
1659
1660 wxDC *dc = dataViewCustomRendererPtr->GetDC();
1661
1662 int active_border_fudge = 0;
1663 if (dataViewCtrlPtr->HasFocus() && !dataViewCtrlPtr->HasFlag( wxBORDER_NONE ))
1664 active_border_fudge = 1;
1665 else
1666 active_border_fudge = -2;
1667
1668 wxRect cellrect( static_cast<int>(rectangle->left + active_border_fudge),
1669 static_cast<int>(rectangle->top + active_border_fudge),
1670 static_cast<int>(1+rectangle->right-rectangle->left),
1671 static_cast<int>(rectangle->bottom-rectangle->top) );
1672
1673 bool is_active = IsControlActive( this->m_controlRef );
1674 if (state == kDataBrowserItemIsSelected)
1675 {
1676
1677 wxColour col( wxMacCreateCGColorFromHITheme( (is_active) ?
1678 kThemeBrushAlternatePrimaryHighlightColor
1679 : kThemeBrushSecondaryHighlightColor ) );
1680
1681 wxRect rect = cellrect;
1682 Rect itemrect;
1683 GetDataBrowserItemPartBounds( this->m_controlRef, itemID, propertyID,
1684 kDataBrowserPropertyEnclosingPart, &itemrect );
1685 rect.x = itemrect.left-2;
1686 rect.width = itemrect.right-itemrect.left+3;
1687
1688 wxBrush selBrush( col );
1689 wxPen oldpen( dc->GetPen() );
1690 wxBrush oldbrush( dc->GetBrush() );
1691 dc->SetPen( *wxTRANSPARENT_PEN );
1692 dc->SetBrush( selBrush );
1693 dc->DrawRectangle(rect);
1694 dc->SetBrush( oldbrush );
1695 dc->SetPen( oldpen );
1696 }
1697
1698 wxDataViewModel *model = dataViewCtrlPtr->GetModel();
1699 if ((columnIndex == 0) || !model->IsContainer(dataItem) || model->HasContainerColumns(dataItem))
1700 {
1701 // make sure that 'Render' can draw only in the allowed area:
1702 dc->SetClippingRegion(content.left,content.top,content.right-content.left+1,content.bottom-content.top+1);
1703 (void) (dataViewCustomRendererPtr->Render( cellrect, dc,
1704 ((state == kDataBrowserItemIsSelected) ? wxDATAVIEW_CELL_SELECTED : 0)));
1705 dc->DestroyClippingRegion(); // probably not necessary
1706 }
1707
1708 dataViewCustomRendererPtr->SetDC(NULL);
1709 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemState, Rect const*, SInt16, Boolean) */
1710
1711 Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserEditItemProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, CFStringRef theString, Rect* maxEditTextRect, Boolean* shrinkToFit)
1712 {
1713 return false;
1714 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserEditItemProc(DataBrowserItemID, DataBrowserPropertyID, CFStringRef, Rect*, Boolean*) */
1715
1716 Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserHitTestProc(DataBrowserItemID WXUNUSED(itemID), DataBrowserPropertyID WXUNUSED(property), Rect const* WXUNUSED(theRect), Rect const* WXUNUSED(mouseRect))
1717 {
1718 return true;
1719 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserHitTestProc(DataBrowserItemID, DataBrowserPropertyID, Rect const*, Rect const*) */
1720
1721 DataBrowserTrackingResult wxMacDataViewDataBrowserListViewControl::DataBrowserTrackingProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, Rect const* theRect, Point WXUNUSED(startPt), EventModifiers WXUNUSED(modifiers))
1722 {
1723 wxDataViewColumn* dataViewColumnPtr;
1724
1725 wxDataViewCtrl* dataViewCtrlPtr;
1726
1727 wxDataViewCustomRenderer* dataViewCustomRendererPtr;
1728
1729 wxDataViewItem dataViewCustomRendererItem;
1730
1731
1732 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1733 wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly."));
1734 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
1735 dataViewCustomRendererItem = reinterpret_cast<void*>(itemID);
1736 wxCHECK_MSG(dataViewCustomRendererItem.IsOk(),kDataBrowserNothingHit,_("Invalid data view item"));
1737 dataViewColumnPtr = this->GetColumnPtr(propertyID);
1738 wxCHECK_MSG(dataViewColumnPtr != NULL,kDataBrowserNothingHit,_("No column existing."));
1739 dataViewCustomRendererPtr = dynamic_cast<wxDataViewCustomRenderer*>(dataViewColumnPtr->GetRenderer());
1740 wxCHECK_MSG(dataViewCustomRendererPtr != NULL,kDataBrowserNothingHit,_("No renderer or invalid renderer type specified for custom data column."));
1741 // 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):
1742 if (dataViewCtrlPtr->GetCustomRendererItem() == dataViewCustomRendererItem)
1743 return kDataBrowserContentHit;
1744 // an(other) item is going to be edited and therefore the current editing - if existing - has to be finished:
1745 if (dataViewCtrlPtr->GetCustomRendererPtr() != NULL)
1746 {
1747 dataViewCtrlPtr->GetCustomRendererPtr()->FinishEditing();
1748 dataViewCtrlPtr->SetCustomRendererItem(wxDataViewItem());
1749 dataViewCtrlPtr->SetCustomRendererPtr (NULL);
1750 }
1751 // check if renderer has got a valid editor control for editing; if this is the case start editing of the new item:
1752 if (dataViewCustomRendererPtr->HasEditorCtrl())
1753 {
1754 // variable definition:
1755 wxRect wxRectangle;
1756
1757 ::wxMacNativeToRect(theRect,&wxRectangle);
1758 dataViewCustomRendererPtr->StartEditing(dataViewCustomRendererItem,wxRectangle);
1759 dataViewCtrlPtr->SetCustomRendererItem(dataViewCustomRendererItem);
1760 dataViewCtrlPtr->SetCustomRendererPtr (dataViewCustomRendererPtr);
1761 }
1762 return kDataBrowserContentHit;
1763 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserTrackingProc(DataBrowserItemID, DataBrowserPropertyID, Rect const*, Point, EventModifiers) */
1764
1765 Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserAcceptDragProc(DragReference dragRef, DataBrowserItemID itemID)
1766 {
1767 bool acceptDrag;
1768
1769 UInt16 noOfDraggedItems;
1770
1771 wxDataViewCtrl* dataViewCtrlPtr;
1772
1773
1774 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1775 wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly."));
1776 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
1777
1778 // send a drag possible event for each available and item und proceed with it unless the event is vetoed:
1779 ::CountDragItems(dragRef,&noOfDraggedItems);
1780 for (UInt16 indexDraggedItem=1; indexDraggedItem<=noOfDraggedItems; ++indexDraggedItem)
1781 {
1782 // collect native information:
1783 ItemReference itemRef;
1784 wxDataObjectComposite* dataObjects;
1785 wxMemoryBuffer buffer;
1786
1787 ::GetDragItemReferenceNumber(dragRef,indexDraggedItem,&itemRef); // the index begins with 1!
1788 dataObjects = this->GetDnDDataObjects(dragRef,itemRef);
1789 // create wxWidget's event:
1790 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE,dataViewCtrlPtr->GetId());
1791
1792 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1793 dataViewEvent.SetItem(reinterpret_cast<void*>(itemID)); // this is the item that receives the event
1794 // (can be an invalid item ID, this is especially useful if the dataview does not contain any items)
1795 dataViewEvent.SetModel(dataViewCtrlPtr->GetModel());
1796 dataViewEvent.SetDataObject(dataObjects);
1797 dataViewEvent.SetDataFormat(this->GetDnDDataFormat(dataObjects));
1798 if (dataViewEvent.GetDataFormat().GetType() != wxDF_INVALID)
1799 {
1800 dataViewEvent.SetDataSize(dataObjects->GetDataSize(dataViewEvent.GetDataFormat().GetType()));
1801 dataObjects->GetDataHere(dataViewEvent.GetDataFormat().GetType(),buffer.GetWriteBuf(dataViewEvent.GetDataSize()));
1802 buffer.UngetWriteBuf(dataViewEvent.GetDataSize());
1803 dataViewEvent.SetDataBuffer(buffer.GetData());
1804 }
1805
1806 // send event:
1807 acceptDrag = dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed();
1808 delete dataObjects;
1809 if (!acceptDrag)
1810 return false;
1811 }
1812 return true;
1813 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserAcceptDragProc(DragReference, DataBrowserItemID) */
1814
1815 Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserAddDragItemProc(DragReference dragRef, DataBrowserItemID itemID, ItemReference* itemRef)
1816 {
1817 Boolean addDragItem;
1818
1819 wxDataViewCtrl* dataViewCtrlPtr;
1820
1821 wxDataViewItem dataViewItem;
1822
1823
1824 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1825 wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly."));
1826 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
1827 dataViewItem = reinterpret_cast<void*>(itemID);
1828 wxCHECK_MSG(dataViewItem.IsOk(),false,_("Invalid data view item"));
1829
1830 // send a begin drag event and proceed with dragging unless the event is vetoed:
1831 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG,dataViewCtrlPtr->GetId());
1832
1833 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1834 dataViewEvent.SetItem(dataViewItem);
1835 dataViewEvent.SetModel(dataViewCtrlPtr->GetModel());
1836 // 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
1837 // the object a wxDataObjectComposite object is used;
1838 // currently, the composite object only contains a TAB concatenated string of all data:
1839 wxDataObjectComposite* dataObject(new wxDataObjectComposite());
1840
1841 dataObject->Add(new wxTextDataObject(::ConcatenateDataViewItemValues(dataViewCtrlPtr,dataViewItem)));
1842 dataViewEvent.SetDataObject(dataObject);
1843 // check if event has not been vetoed:
1844 addDragItem = dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed();
1845 if (addDragItem)
1846 {
1847 // for the internal drag & drop functions create two flavors:
1848 // - the data browser's item id;
1849 // - the data contained the dataview event object (if available).
1850 // Definition: a flavor is the type dependent representation of identical data.
1851 // Example: a number can be represented by its value and by its value converted to a string. In this case the flavor
1852 // of the number's internal representation is typeSInt32 while its string representation has got the flavor 'TEXT'.
1853 // Item id is one of the flavors:
1854 wxCHECK_MSG(::AddDragItemFlavor(dragRef,*itemRef,typeUInt32,&itemID,sizeof(itemID),0) == noErr,false,_("Unable to handle native drag&drop data"));
1855 // if the dataview event object contains data it is used for additional flavors; all natively known flavors are supported:
1856 if (dataViewEvent.GetDataObject() != NULL)
1857 {
1858 // constant definition for abbreviational purposes:
1859 size_t const noOfFormats = dataViewEvent.GetDataObject()->GetFormatCount();
1860
1861 if (noOfFormats > 0)
1862 {
1863 // variable definition:
1864 wxDataFormat* dataFormats;
1865
1866 dataFormats = new wxDataFormat[noOfFormats];
1867 dataViewEvent.GetDataObject()->GetAllFormats(dataFormats,wxDataObject::Get);
1868 for (size_t i=0; i<noOfFormats; ++i)
1869 switch (dataFormats[i].GetType())
1870 {
1871 case wxDF_INVALID:
1872 wxFAIL_MSG(_("Data object has invalid data format"));
1873 break;
1874 case wxDF_TEXT:
1875 {
1876 // constant definition for abbreviational purposes:
1877 size_t const dataSize = dataViewEvent.GetDataObject()->GetDataSize(wxDF_TEXT);
1878 // variable definition and initialization:
1879 wxMemoryBuffer dataObject(dataSize);
1880
1881 dataViewEvent.GetDataObject()->GetDataHere(wxDF_TEXT,dataObject.GetWriteBuf(dataSize));
1882 dataObject.UngetWriteBuf(dataSize);
1883 if (::AddDragItemFlavor(dragRef,*itemRef,'TEXT',dataObject.GetData(),dataSize,0) != noErr)
1884 wxFAIL_MSG(_("Adding flavor TEXT failed"));
1885 } /* block */
1886 break;
1887 case wxDF_UNICODETEXT:
1888 {
1889 // constant definition for abbreviational purposes:
1890 size_t const dataSize = dataViewEvent.GetDataObject()->GetDataSize(wxDF_TEXT);
1891 // as there is no direct access to the data copy it to a memory buffer:
1892 wxMemoryBuffer dataObject(dataSize);
1893
1894 dataViewEvent.GetDataObject()->GetDataHere(wxDF_TEXT,dataObject.GetWriteBuf(dataSize));
1895 dataObject.UngetWriteBuf(dataSize);
1896 // if the data is stored in unicode format the internal representation is utf-8 (not mentioned in the documentation but in the source code);
1897 // DnD uses fixed utf-16 representation -> use the OSX functions for a conversion:
1898 CFDataRef osxData (::CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,reinterpret_cast<UInt8*>(dataObject.GetData()),dataSize,kCFAllocatorNull));
1899 CFStringRef osxString(::CFStringCreateFromExternalRepresentation(kCFAllocatorDefault,osxData,kCFStringEncodingUTF8));
1900
1901 // the osxString contains now the data and therefore the previously occupied memory can be released and re-used:
1902 ::CFRelease(osxData);
1903 osxData = ::CFStringCreateExternalRepresentation(kCFAllocatorDefault,osxString,kCFStringEncodingUTF16,32);
1904 if (::AddDragItemFlavor(dragRef,*itemRef,'utxt',::CFDataGetBytePtr(osxData),::CFDataGetLength(osxData),0) != noErr)
1905 wxFAIL_MSG(_("Adding flavor utxt failed"));
1906 // clean up:
1907 ::CFRelease(osxData);
1908 ::CFRelease(osxString);
1909 } /* block */
1910 break;
1911 case wxDF_BITMAP:
1912 case wxDF_METAFILE:
1913 case wxDF_SYLK:
1914 case wxDF_DIF:
1915 case wxDF_TIFF:
1916 case wxDF_OEMTEXT:
1917 case wxDF_DIB:
1918 case wxDF_PALETTE:
1919 case wxDF_PENDATA:
1920 case wxDF_RIFF:
1921 case wxDF_WAVE:
1922 case wxDF_ENHMETAFILE:
1923 case wxDF_FILENAME:
1924 case wxDF_LOCALE:
1925 case wxDF_PRIVATE:
1926 case wxDF_HTML:
1927 break; // not (yet) supported data formats
1928 default:
1929 wxFAIL_MSG(_("Unknown data format"));
1930 }
1931 delete[] dataFormats;
1932 }
1933 }
1934 }
1935 // clean-up and return result:
1936 delete dataObject;
1937 return addDragItem;
1938 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserAddDragItemProc(DragReference, DataBrowserItemID, ItemReference*) */
1939
1940 Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserReceiveDragProc(DragReference dragRef, DataBrowserItemID itemID)
1941 {
1942 UInt16 noOfDraggedItems;
1943
1944 wxDataViewCtrl* dataViewCtrlPtr;
1945
1946
1947 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1948 wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly."));
1949 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
1950
1951 // send a drag possible event for each available and item und proceed with it unless the event is vetoed:
1952 ::CountDragItems(dragRef,&noOfDraggedItems);
1953 for (UInt16 indexDraggedItem=1; indexDraggedItem<=noOfDraggedItems; ++indexDraggedItem)
1954 {
1955 bool receiveDrag;
1956 ItemReference itemRef;
1957 wxDataObjectComposite* dataObjects;
1958 wxMemoryBuffer buffer;
1959
1960 // collect native information:
1961 ::GetDragItemReferenceNumber(dragRef,indexDraggedItem,&itemRef); // the index begins with 1!
1962 dataObjects = this->GetDnDDataObjects(dragRef,itemRef);
1963 // create wxWidget's event:
1964 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_DROP,dataViewCtrlPtr->GetId());
1965
1966 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1967 dataViewEvent.SetItem(reinterpret_cast<void*>(itemID)); // this is the item that receives the event
1968 // (can be an invalid item ID, this is especially useful if the dataview does not contain any items)
1969 dataViewEvent.SetModel(dataViewCtrlPtr->GetModel());
1970 dataViewEvent.SetDataObject(dataObjects);
1971 dataViewEvent.SetDataFormat(this->GetDnDDataFormat(dataObjects));
1972 if (dataViewEvent.GetDataFormat().GetType() != wxDF_INVALID)
1973 {
1974 dataViewEvent.SetDataSize(dataObjects->GetDataSize(dataViewEvent.GetDataFormat().GetType()));
1975 dataObjects->GetDataHere(dataViewEvent.GetDataFormat().GetType(),buffer.GetWriteBuf(dataViewEvent.GetDataSize()));
1976 buffer.UngetWriteBuf(dataViewEvent.GetDataSize());
1977 dataViewEvent.SetDataBuffer(buffer.GetData());
1978 }
1979
1980 // send event:
1981 receiveDrag = dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed();
1982 delete dataObjects;
1983 if (!receiveDrag)
1984 return false;
1985 }
1986 return true;
1987 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserReceiveDragProc(DragReference, DataBrowserItemID) */
1988
1989 //
1990 // drag & drop helper methods
1991 //
1992 wxDataFormat wxMacDataViewDataBrowserListViewControl::GetDnDDataFormat(wxDataObjectComposite* dataObjects)
1993 {
1994 wxDataFormat resultFormat;
1995
1996
1997 if (dataObjects != NULL)
1998 {
1999 bool compatible(true);
2000
2001 size_t const noOfFormats = dataObjects->GetFormatCount();
2002 size_t indexFormat;
2003
2004 wxDataFormat* formats;
2005
2006 // get all formats and check afterwards if the formats are compatible; if they are compatible the preferred format is returned otherwise
2007 // wxDF_INVALID is returned;
2008 // currently compatible types (ordered by priority are):
2009 // - wxDF_UNICODETEXT - wxDF_TEXT
2010 formats = new wxDataFormat[noOfFormats];
2011 dataObjects->GetAllFormats(formats);
2012 indexFormat = 0;
2013 while ((indexFormat < noOfFormats) && compatible)
2014 {
2015 switch (resultFormat.GetType())
2016 {
2017 case wxDF_INVALID:
2018 resultFormat.SetType(formats[indexFormat].GetType()); // first format (should only be reached if indexFormat == 0
2019 break;
2020 case wxDF_TEXT:
2021 if (formats[indexFormat].GetType() == wxDF_UNICODETEXT)
2022 resultFormat.SetType(wxDF_UNICODETEXT);
2023 else // incompatible
2024 {
2025 resultFormat.SetType(wxDF_INVALID);
2026 compatible = false;
2027 }
2028 break;
2029 case wxDF_UNICODETEXT:
2030 if (formats[indexFormat].GetType() != wxDF_TEXT)
2031 {
2032 resultFormat.SetType(wxDF_INVALID);
2033 compatible = false;
2034 }
2035 break;
2036 default:
2037 resultFormat.SetType(wxDF_INVALID); // not (yet) supported format
2038 compatible = false;
2039 }
2040 ++indexFormat;
2041 } /* while */
2042 // clean up:
2043 delete[] formats;
2044 }
2045 else
2046 resultFormat = wxDF_INVALID;
2047 return resultFormat;
2048 } /* wxMacDataViewDataBrowserListViewControl::GetDnDDataFormat(wxDataObjectComposite*) */
2049
2050 wxDataObjectComposite* wxMacDataViewDataBrowserListViewControl::GetDnDDataObjects(DragReference dragRef, ItemReference itemRef) const
2051 {
2052 UInt16 noOfFlavors;
2053
2054 wxDataObjectComposite* dataObject;
2055
2056
2057 ::CountDragItemFlavors(dragRef,itemRef,&noOfFlavors);
2058 if (noOfFlavors > 0)
2059 {
2060 // 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:
2061 wxTextDataObject* textDataObject(NULL);
2062
2063 dataObject = new wxDataObjectComposite();
2064 for (UInt16 indexFlavor=1; indexFlavor<=noOfFlavors; ++indexFlavor)
2065 {
2066 // variable definition:
2067 FlavorType flavorDataObject;
2068
2069 if (::GetFlavorType(dragRef,itemRef,indexFlavor,&flavorDataObject) == noErr) // GetFlavorType uses a 1 based index!
2070 switch (flavorDataObject)
2071 {
2072 case 'TEXT':
2073 if (textDataObject == NULL) // otherwise a 'utxt' flavor has already been found that gets priority compared to the 'TEXT' flavor
2074 {
2075 // variable definitions:
2076 Size nativeDataSize;
2077 wxMemoryBuffer nativeData;
2078
2079 if ((::GetFlavorDataSize(dragRef,itemRef,'TEXT',&nativeDataSize) == noErr) &&
2080 (::GetFlavorData(dragRef,itemRef,'TEXT',nativeData.GetWriteBuf(nativeDataSize),&nativeDataSize,0) == noErr))
2081 {
2082 nativeData.UngetWriteBuf(nativeDataSize);
2083 textDataObject = new wxTextDataObject();
2084 if (textDataObject->SetData(nativeData.GetDataLen(),nativeData.GetData()))
2085 dataObject->Add(textDataObject);
2086 else
2087 {
2088 delete textDataObject;
2089 textDataObject = NULL;
2090 }
2091 }
2092 } /* block */
2093 break;
2094 case 'utxt':
2095 {
2096 // variable definition:
2097 Size nativeDataSize;
2098
2099 if (::GetFlavorDataSize(dragRef,itemRef,'utxt',&nativeDataSize) == noErr)
2100 {
2101 CFMutableDataRef draggedData;
2102
2103 draggedData = ::CFDataCreateMutable(kCFAllocatorDefault,nativeDataSize);
2104 ::CFDataSetLength(draggedData,nativeDataSize);
2105 if (::GetFlavorData(dragRef,itemRef,'utxt',::CFDataGetMutableBytePtr(draggedData),&nativeDataSize,0) == noErr)
2106 {
2107 // convert internally used UTF-16 representation to a UTF-8 representation:
2108 CFDataRef osxData;
2109 CFStringRef osxString;
2110
2111 osxString = ::CFStringCreateFromExternalRepresentation(kCFAllocatorDefault,draggedData,kCFStringEncodingUTF16); // BOM character is handled by this function automatically
2112 osxData = ::CFStringCreateExternalRepresentation(kCFAllocatorDefault,osxString,kCFStringEncodingUTF8,32);
2113 if (textDataObject == NULL)
2114 {
2115 textDataObject = new wxTextDataObject();
2116 if (textDataObject->SetData(::CFDataGetLength(osxData),::CFDataGetBytePtr(osxData)))
2117 dataObject->Add(textDataObject);
2118 else
2119 {
2120 delete textDataObject;
2121 textDataObject = NULL;
2122 }
2123 }
2124 else // overwrite data because the 'utxt' flavor has priority over the 'TEXT' flavor
2125 (void) textDataObject->SetData(::CFDataGetLength(osxData),::CFDataGetBytePtr(osxData));
2126 // clean up:
2127 ::CFRelease(osxData);
2128 ::CFRelease(osxString);
2129 }
2130 // clean up:
2131 ::CFRelease(draggedData);
2132 }
2133 } /* block */
2134 break;
2135 }
2136 }
2137 }
2138 else
2139 dataObject = NULL;
2140 return dataObject;
2141 } /* wxMacDataViewDataBrowserListViewControl::GetDnDDataObjects(DragReference, ItemReference) const */
2142
2143 //
2144 // other methods
2145 //
2146 wxDataViewColumn* wxMacDataViewDataBrowserListViewControl::GetColumnPtr(DataBrowserPropertyID propertyID) const
2147 {
2148 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
2149
2150 if (dataViewCtrlPtr != NULL)
2151 {
2152 size_t const noOfColumns = dataViewCtrlPtr->GetColumnCount();
2153
2154 for (size_t i=0; i<noOfColumns; ++i)
2155 if (dataViewCtrlPtr->GetColumnPtr(i)->GetNativeData()->GetPropertyID() == propertyID)
2156 return dataViewCtrlPtr->GetColumnPtr(i);
2157 }
2158 return NULL;
2159 }
2160
2161 // ---------------------------------------------------------
2162 // wxDataViewRenderer
2163 // ---------------------------------------------------------
2164 wxDataViewRenderer::wxDataViewRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
2165 :wxDataViewRendererBase(varianttype,mode,align), m_alignment(align), m_mode(mode), m_NativeDataPtr(NULL)
2166 {
2167 }
2168
2169 wxDataViewRenderer::~wxDataViewRenderer(void)
2170 {
2171 delete this->m_NativeDataPtr;
2172 }
2173
2174 void wxDataViewRenderer::SetAlignment(int align)
2175 {
2176 this->m_alignment = align;
2177 }
2178
2179 void wxDataViewRenderer::SetMode(wxDataViewCellMode mode)
2180 {
2181 wxDataViewColumn* dataViewColumnPtr;
2182
2183
2184 m_mode = mode;
2185 dataViewColumnPtr = this->GetOwner();
2186 if (dataViewColumnPtr != NULL)
2187 {
2188 wxDataViewCtrl* dataViewCtrlPtr(dataViewColumnPtr->GetOwner());
2189
2190 if (dataViewCtrlPtr != NULL)
2191 {
2192 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2193
2194 if (macDataViewListCtrlPtr != NULL)
2195 {
2196 DataBrowserPropertyFlags flags;
2197
2198 verify_noerr(macDataViewListCtrlPtr->GetPropertyFlags(dataViewColumnPtr->GetNativeData()->GetPropertyID(),&flags));
2199 if ((mode == wxDATAVIEW_CELL_EDITABLE) ||
2200 (mode == wxDATAVIEW_CELL_ACTIVATABLE))
2201 flags |= kDataBrowserPropertyIsEditable;
2202 else
2203 flags &= ~kDataBrowserPropertyIsEditable;
2204 verify_noerr(macDataViewListCtrlPtr->SetPropertyFlags(dataViewColumnPtr->GetNativeData()->GetPropertyID(),flags));
2205 }
2206 }
2207 }
2208 }
2209
2210 void wxDataViewRenderer::SetNativeData(wxDataViewRendererNativeData* newNativeDataPtr)
2211 {
2212 delete this->m_NativeDataPtr;
2213 this->m_NativeDataPtr = newNativeDataPtr;
2214 }
2215
2216 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer,wxDataViewRendererBase)
2217
2218 // ---------------------------------------------------------
2219 // wxDataViewCustomRenderer
2220 // ---------------------------------------------------------
2221 wxDataViewCustomRenderer::wxDataViewCustomRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
2222 :wxDataViewRenderer(varianttype,mode,align), m_editorCtrlPtr(NULL), m_DCPtr(NULL)
2223 {
2224 this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserCustomType));
2225 }
2226
2227 bool wxDataViewCustomRenderer::Render()
2228 {
2229 return true;
2230 }
2231
2232 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomRenderer, wxDataViewRenderer)
2233
2234 // ---------------------------------------------------------
2235 // wxDataViewTextRenderer
2236 // ---------------------------------------------------------
2237 wxDataViewTextRenderer::wxDataViewTextRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
2238 :wxDataViewRenderer(varianttype,mode,align)
2239 {
2240 this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserTextType));
2241 }
2242
2243 bool wxDataViewTextRenderer::Render()
2244 {
2245 wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Text renderer cannot render value; value type: ")) << this->GetValue().GetType());
2246
2247 wxCFStringRef cfString(this->GetValue().GetString(),(this->GetView()->GetFont().Ok() ? this->GetView()->GetFont().GetEncoding() : wxLocale::GetSystemEncoding()));
2248 return (::SetDataBrowserItemDataText(this->GetNativeData()->GetItemDataRef(),cfString) == noErr);
2249 }
2250
2251 IMPLEMENT_CLASS(wxDataViewTextRenderer,wxDataViewRenderer)
2252
2253 // ---------------------------------------------------------
2254 // wxDataViewBitmapRenderer
2255 // ---------------------------------------------------------
2256 wxDataViewBitmapRenderer::wxDataViewBitmapRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
2257 :wxDataViewRenderer(varianttype,mode,align)
2258 {
2259 this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserIconType));
2260 }
2261
2262 bool wxDataViewBitmapRenderer::Render()
2263 // This method returns 'true' if
2264 // - the passed bitmap is valid and it could be assigned to the native data browser;
2265 // - the passed bitmap is invalid (or is not initialized); this case simulates a non-existing bitmap.
2266 // In all other cases the method returns 'false'.
2267 {
2268 wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Bitmap renderer cannot render value; value type: ")) << this->GetValue().GetType());
2269
2270 wxBitmap bitmap;
2271
2272 bitmap << this->GetValue();
2273 return (!(bitmap.Ok()) || (::SetDataBrowserItemDataIcon(this->GetNativeData()->GetItemDataRef(),bitmap.GetIconRef()) == noErr));
2274 }
2275
2276 IMPLEMENT_CLASS(wxDataViewBitmapRenderer,wxDataViewRenderer)
2277
2278 // ---------------------------------------------------------
2279 // wxDataViewIconTextRenderer
2280 // ---------------------------------------------------------
2281 wxDataViewIconTextRenderer::wxDataViewIconTextRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
2282 :wxDataViewRenderer(varianttype,mode)
2283 {
2284 this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserIconAndTextType));
2285 }
2286
2287 bool wxDataViewIconTextRenderer::Render()
2288 {
2289 wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Icon & text renderer cannot render value; value type: ")) << this->GetValue().GetType());
2290
2291 wxDataViewIconText iconText;
2292
2293 iconText << this->GetValue();
2294
2295 wxCFStringRef cfString(iconText.GetText(),(this->GetView()->GetFont().Ok() ? this->GetView()->GetFont().GetEncoding() : wxLocale::GetSystemEncoding()));
2296
2297 if (iconText.GetIcon().IsOk())
2298 if (::SetDataBrowserItemDataIcon(this->GetNativeData()->GetItemDataRef(),MAC_WXHICON(iconText.GetIcon().GetHICON())) != noErr)
2299 return false;
2300 return (::SetDataBrowserItemDataText(this->GetNativeData()->GetItemDataRef(),cfString) == noErr);
2301 }
2302
2303 IMPLEMENT_ABSTRACT_CLASS(wxDataViewIconTextRenderer,wxDataViewRenderer)
2304
2305
2306 // ---------------------------------------------------------
2307 // wxDataViewToggleRenderer
2308 // ---------------------------------------------------------
2309 wxDataViewToggleRenderer::wxDataViewToggleRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
2310 :wxDataViewRenderer(varianttype,mode)
2311 {
2312 this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserCheckboxType));
2313 }
2314
2315 bool wxDataViewToggleRenderer::Render()
2316 {
2317 wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Toggle renderer cannot render value; value type: ")) << this->GetValue().GetType());
2318 return (::SetDataBrowserItemDataButtonValue(this->GetNativeData()->GetItemDataRef(),this->GetValue().GetBool()) == noErr);
2319 }
2320
2321 IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleRenderer,wxDataViewRenderer)
2322
2323 // ---------------------------------------------------------
2324 // wxDataViewProgressRenderer
2325 // ---------------------------------------------------------
2326 wxDataViewProgressRenderer::wxDataViewProgressRenderer(wxString const& label, wxString const& varianttype, wxDataViewCellMode mode, int align)
2327 :wxDataViewRenderer(varianttype,mode,align)
2328 {
2329 this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserProgressBarType));
2330 }
2331
2332 bool wxDataViewProgressRenderer::Render()
2333 {
2334 wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Progress renderer cannot render value type; value type: ")) << this->GetValue().GetType());
2335 return ((::SetDataBrowserItemDataMinimum(this->GetNativeData()->GetItemDataRef(), 0) == noErr) &&
2336 (::SetDataBrowserItemDataMaximum(this->GetNativeData()->GetItemDataRef(),100) == noErr) &&
2337 (::SetDataBrowserItemDataValue (this->GetNativeData()->GetItemDataRef(),this->GetValue().GetLong()) == noErr));
2338 }
2339
2340 IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressRenderer,wxDataViewRenderer)
2341
2342 // ---------------------------------------------------------
2343 // wxDataViewDateRenderer
2344 // ---------------------------------------------------------
2345 wxDataViewDateRenderer::wxDataViewDateRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align)
2346 :wxDataViewRenderer(varianttype,mode,align)
2347 {
2348 this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserDateTimeType));
2349 }
2350
2351 bool wxDataViewDateRenderer::Render()
2352 {
2353 wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Date renderer cannot render value; value type: ")) << this->GetValue().GetType());
2354 return (::SetDataBrowserItemDataDateTime(this->GetNativeData()->GetItemDataRef(),this->GetValue().GetDateTime().Subtract(wxDateTime(1,wxDateTime::Jan,1904)).GetSeconds().GetLo()) == noErr);
2355 }
2356
2357 IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer,wxDataViewRenderer)
2358
2359 // ---------------------------------------------------------
2360 // wxDataViewColumn
2361 // ---------------------------------------------------------
2362 wxDataViewColumn::wxDataViewColumn(const wxString& title, wxDataViewRenderer* renderer, unsigned int model_column, int width, wxAlignment align, int flags)
2363 :wxDataViewColumnBase(renderer, model_column), m_NativeDataPtr(new wxDataViewColumnNativeData()), m_title(title)
2364 {
2365 this->InitCommon(width, align, flags);
2366 if ((renderer != NULL) && (renderer->GetAlignment() == wxDVR_DEFAULT_ALIGNMENT))
2367 renderer->SetAlignment(align);
2368 }
2369
2370 wxDataViewColumn::wxDataViewColumn(const wxBitmap& bitmap, wxDataViewRenderer* renderer, unsigned int model_column, int width, wxAlignment align, int flags)
2371 :wxDataViewColumnBase(bitmap, renderer, model_column), m_NativeDataPtr(new wxDataViewColumnNativeData())
2372 {
2373 this->InitCommon(width, align, flags);
2374 if ((renderer != NULL) && (renderer->GetAlignment() == wxDVR_DEFAULT_ALIGNMENT))
2375 renderer->SetAlignment(align);
2376 }
2377
2378 wxDataViewColumn::~wxDataViewColumn(void)
2379 {
2380 delete this->m_NativeDataPtr;
2381 }
2382
2383 bool wxDataViewColumn::IsSortKey() const
2384 {
2385 wxDataViewCtrl * const dataViewCtrlPtr(GetOwner());
2386 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(
2387 dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(
2388 dataViewCtrlPtr->GetPeer()));
2389
2390 DataBrowserPropertyID propertyID;
2391 return (macDataViewListCtrlPtr->GetSortProperty(&propertyID) == noErr) &&
2392 (propertyID == this->GetNativeData()->GetPropertyID());
2393 }
2394
2395 void wxDataViewColumn::SetAlignment(wxAlignment align)
2396 {
2397 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2398
2399
2400 m_alignment = align;
2401 if (dataViewCtrlPtr != NULL)
2402 {
2403 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2404
2405 if (macDataViewListCtrlPtr != NULL)
2406 {
2407 DataBrowserListViewHeaderDesc headerDescription;
2408
2409 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
2410 switch (align)
2411 {
2412 case wxALIGN_CENTER:
2413 case wxALIGN_CENTER_HORIZONTAL:
2414 headerDescription.btnFontStyle.just = teCenter;
2415 break;
2416 case wxALIGN_LEFT:
2417 headerDescription.btnFontStyle.just = teFlushLeft;
2418 break;
2419 case wxALIGN_RIGHT:
2420 headerDescription.btnFontStyle.just = teFlushRight;
2421 break;
2422 default:
2423 headerDescription.btnFontStyle.just = teFlushDefault;
2424 }
2425 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not set alignment."));
2426 }
2427 }
2428 }
2429
2430 void wxDataViewColumn::SetBitmap(wxBitmap const& bitmap)
2431 {
2432 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2433
2434
2435 wxDataViewColumnBase::SetBitmap(bitmap);
2436 if (dataViewCtrlPtr != NULL)
2437 {
2438 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2439
2440 if (macDataViewListCtrlPtr != NULL)
2441 {
2442 DataBrowserListViewHeaderDesc headerDescription;
2443
2444 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
2445 if (this->GetBitmap().Ok())
2446 headerDescription.btnContentInfo.u.iconRef = this->GetBitmap().GetIconRef();
2447 else
2448 headerDescription.btnContentInfo.u.iconRef = NULL;
2449 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not set icon."));
2450 }
2451 }
2452 }
2453
2454 void wxDataViewColumn::SetMaxWidth(int maxWidth)
2455 {
2456 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2457
2458
2459 m_maxWidth = maxWidth;
2460 if (dataViewCtrlPtr != NULL)
2461 {
2462 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2463
2464 if (macDataViewListCtrlPtr != NULL)
2465 {
2466 DataBrowserListViewHeaderDesc headerDescription;
2467
2468 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
2469 headerDescription.maximumWidth = static_cast<UInt16>(maxWidth);
2470 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not set maximum width."));
2471 }
2472 }
2473 }
2474
2475 void wxDataViewColumn::SetMinWidth(int minWidth)
2476 {
2477 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2478
2479
2480 m_minWidth = minWidth;
2481 if (dataViewCtrlPtr != NULL)
2482 {
2483 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2484
2485 if (macDataViewListCtrlPtr != NULL)
2486 {
2487 DataBrowserListViewHeaderDesc headerDescription;
2488
2489 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
2490 headerDescription.minimumWidth = static_cast<UInt16>(minWidth);
2491 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not set minimum width."));
2492 }
2493 }
2494 }
2495
2496 void wxDataViewColumn::SetReorderable(bool reorderable)
2497 {
2498 // first set the internal flag of the column:
2499 if (reorderable)
2500 m_flags |= wxDATAVIEW_COL_REORDERABLE;
2501 else
2502 m_flags &= ~wxDATAVIEW_COL_REORDERABLE;
2503 // if the column is associated with a control change also immediately the flags of the control:
2504 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2505
2506 if (dataViewCtrlPtr != NULL)
2507 {
2508 DataBrowserPropertyFlags flags;
2509 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2510
2511 wxCHECK_RET(macDataViewListCtrlPtr != NULL, _("Valid pointer to native data view control does not exist"));
2512 wxCHECK_RET(macDataViewListCtrlPtr->GetPropertyFlags(this->GetNativeData()->GetPropertyID(),&flags) == noErr,_("Could not get property flags."));
2513 if (reorderable)
2514 flags |= kDataBrowserListViewMovableColumn;
2515 else
2516 flags &= ~kDataBrowserListViewMovableColumn;
2517 wxCHECK_RET(macDataViewListCtrlPtr->SetPropertyFlags(this->GetNativeData()->GetPropertyID(),flags) == noErr,_("Could not set property flags."));
2518 }
2519 }
2520
2521 void wxDataViewColumn::SetResizeable(bool resizeable)
2522 {
2523 // first set the internal flag of the column:
2524 if (resizeable)
2525 m_flags |= wxDATAVIEW_COL_RESIZABLE;
2526 else
2527 m_flags &= ~wxDATAVIEW_COL_RESIZABLE;
2528 // if the column is associated with a control change also immediately the flags of the control:
2529 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2530
2531 if (dataViewCtrlPtr != NULL)
2532 {
2533 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2534
2535 if (macDataViewListCtrlPtr != NULL)
2536 {
2537 DataBrowserListViewHeaderDesc headerDescription;
2538
2539 verify_noerr(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription));
2540 if (resizeable)
2541 {
2542 if (this->GetMinWidth() >= this->GetMaxWidth())
2543 {
2544 this->m_minWidth = 0;
2545 this->m_maxWidth = 30000;
2546 }
2547 headerDescription.minimumWidth = this->m_minWidth;
2548 headerDescription.maximumWidth = this->m_maxWidth;
2549 }
2550 else
2551 {
2552 headerDescription.minimumWidth = this->m_width;
2553 headerDescription.maximumWidth = this->m_width;
2554 }
2555 verify_noerr(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription));
2556 macDataViewListCtrlPtr->SetSortProperty(this->GetNativeData()->GetPropertyID());
2557 }
2558 }
2559 }
2560
2561 void wxDataViewColumn::SetSortable(bool sortable)
2562 {
2563 // first set the internal flag of the column:
2564 if (sortable)
2565 m_flags |= wxDATAVIEW_COL_SORTABLE;
2566 else
2567 m_flags &= ~wxDATAVIEW_COL_SORTABLE;
2568 // if the column is associated with a control change also immediately the flags of the control:
2569 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2570
2571 if (dataViewCtrlPtr != NULL)
2572 {
2573 DataBrowserPropertyFlags flags;
2574 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2575
2576 wxCHECK_RET(macDataViewListCtrlPtr != NULL, _("Valid pointer to native data view control does not exist"));
2577 wxCHECK_RET(macDataViewListCtrlPtr->GetPropertyFlags(this->GetNativeData()->GetPropertyID(),&flags) == noErr,_("Could not get property flags."));
2578 if (sortable)
2579 flags |= kDataBrowserListViewSortableColumn;
2580 else
2581 flags &= ~kDataBrowserListViewSortableColumn;
2582 wxCHECK_RET(macDataViewListCtrlPtr->SetPropertyFlags(this->GetNativeData()->GetPropertyID(),flags) == noErr,_("Could not set property flags."));
2583 }
2584 }
2585
2586 void wxDataViewColumn::SetSortOrder(bool ascending)
2587 {
2588 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2589
2590
2591 m_ascending = ascending;
2592 if (dataViewCtrlPtr != NULL)
2593 {
2594 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2595
2596 if (macDataViewListCtrlPtr != NULL)
2597 {
2598 DataBrowserListViewHeaderDesc headerDescription;
2599
2600 verify_noerr(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription));
2601 if (ascending)
2602 headerDescription.initialOrder = kDataBrowserOrderIncreasing;
2603 else
2604 headerDescription.initialOrder = kDataBrowserOrderDecreasing;
2605 verify_noerr(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription));
2606 macDataViewListCtrlPtr->SetSortProperty(this->GetNativeData()->GetPropertyID());
2607 }
2608 }
2609 }
2610
2611 void wxDataViewColumn::SetTitle(wxString const& title)
2612 {
2613 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2614
2615
2616 m_title = title;
2617 if (dataViewCtrlPtr != NULL)
2618 {
2619 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2620
2621 if (macDataViewListCtrlPtr != NULL)
2622 {
2623 DataBrowserListViewHeaderDesc headerDescription;
2624 wxCFStringRef cfTitle(title,(dataViewCtrlPtr->GetFont().Ok() ? dataViewCtrlPtr->GetFont().GetEncoding() : wxLocale::GetSystemEncoding()));
2625
2626 wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description."));
2627 headerDescription.titleString = cfTitle;
2628 wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not set header description."));
2629 }
2630 }
2631 }
2632
2633 void wxDataViewColumn::SetWidth(int width)
2634 {
2635 wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner());
2636
2637
2638 if ((width >= m_minWidth) && (width <= m_maxWidth))
2639 {
2640 m_width = width;
2641 if (dataViewCtrlPtr != NULL)
2642 {
2643 wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(dataViewCtrlPtr->GetPeer()));
2644
2645 if (macDataViewListCtrlPtr != NULL)
2646 wxCHECK_RET(macDataViewListCtrlPtr->SetColumnWidth(this->GetNativeData()->GetPropertyID(),static_cast<UInt16>(width)) == noErr,_("Could not set column width."));
2647 }
2648 }
2649 }
2650
2651 void wxDataViewColumn::SetAsSortKey(bool WXUNUSED(sort))
2652 {
2653 // see wxGTK native wxDataViewColumn implementation
2654 wxFAIL_MSG( "not implemented" );
2655 }
2656
2657 void wxDataViewColumn::SetNativeData(wxDataViewColumnNativeData* newNativeDataPtr)
2658 {
2659 delete this->m_NativeDataPtr;
2660 this->m_NativeDataPtr = newNativeDataPtr;
2661 }
2662
2663 #endif // wxUSE_DATAVIEWCTRL && !wxUSE_GENERICDATAVIEWCTRL