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