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