1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/databrow.cpp
3 // Purpose: Classes and functions for the Carbon data browser
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
14 #if wxUSE_DATAVIEWCTRL
15 #ifndef wxUSE_GENERICDATAVIEWCTRL
19 #include "wx/toplevel.h"
21 #include "wx/settings.h"
25 #include "wx/dataview.h"
26 #include "wx/osx/carbon/databrow.h"
27 #include "wx/osx/private.h"
28 #include "wx/osx/uma.h"
32 // ============================================================================
33 // Variables used globally in databrow.cpp
34 // ============================================================================
35 DataBrowserGetContextualMenuUPP gDataBrowserTableViewGetContextualMenuUPP
= NULL
;
36 DataBrowserItemCompareUPP gDataBrowserTableViewItemCompareUPP
= NULL
;
37 DataBrowserItemDataUPP gDataBrowserTableViewItemDataUPP
= NULL
;
38 DataBrowserItemNotificationUPP gDataBrowserTableViewItemNotificationUPP
= NULL
;
40 DataBrowserAcceptDragUPP gDataBrowserTableViewAcceptDragUPP
= NULL
;
41 DataBrowserAddDragItemUPP gDataBrowserTableViewAddDragItemUPP
= NULL
;
42 DataBrowserReceiveDragUPP gDataBrowserTableViewReceiveDragUPP
= NULL
;
44 DataBrowserDrawItemUPP gDataBrowserTableViewDrawItemUPP
= NULL
;
45 DataBrowserEditItemUPP gDataBrowserTableViewEditItemUPP
= NULL
;
46 DataBrowserHitTestUPP gDataBrowserTableViewHitTestUPP
= NULL
;
47 DataBrowserTrackingUPP gDataBrowserTableViewTrackingUPP
= NULL
;
49 // ============================================================================
50 // wxMacDataBrowserTableViewControl
51 // ============================================================================
53 pascal Boolean
wxMacDataBrowserTableViewControl::DataBrowserCompareProc(ControlRef browser
, DataBrowserItemID itemOneID
, DataBrowserItemID itemTwoID
, DataBrowserPropertyID sortProperty
)
55 wxMacDataBrowserTableViewControl
* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl
*>(wxMacControl::GetReferenceFromNativeControl(browser
)));
58 if (ControlPtr
!= NULL
)
59 return ControlPtr
->DataBrowserCompareProc(itemOneID
,itemTwoID
,sortProperty
);
61 return errDataBrowserPropertyNotSupported
;
62 } /* wxMacDataBrowserTableViewControl::DataBrowserCompareProc(ControlRef, DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID) */
64 pascal void wxMacDataBrowserTableViewControl::DataBrowserGetContextualMenuProc(ControlRef browser
, MenuRef
* menu
, UInt32
* helpType
, CFStringRef
* helpItemString
, AEDesc
* selection
)
66 wxMacDataBrowserTableViewControl
* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl
*>(wxMacControl::GetReferenceFromNativeControl(browser
)));
69 if (ControlPtr
!= NULL
)
70 ControlPtr
->DataBrowserGetContextualMenuProc(menu
,helpType
,helpItemString
,selection
);
71 } /* wxMacDataBrowserTableViewControl::DataBrowserGetContextualMenuProc(ControlRef, MenuRef*, UInt32*, CFStringRef*, AEDesc*) */
73 pascal OSStatus
wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc(ControlRef browser
, DataBrowserItemID itemID
, DataBrowserPropertyID propertyID
, DataBrowserItemDataRef itemData
, Boolean getValue
)
75 wxMacDataBrowserTableViewControl
* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl
*>(wxMacControl::GetReferenceFromNativeControl(browser
)));
78 if (ControlPtr
!= NULL
)
79 return ControlPtr
->DataBrowserGetSetItemDataProc(itemID
,propertyID
,itemData
,getValue
);
81 return errDataBrowserPropertyNotSupported
;
82 } /* wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemDataRef, Boolean) */
84 pascal void wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc(ControlRef browser
, DataBrowserItemID itemID
, DataBrowserItemNotification message
, DataBrowserItemDataRef itemData
)
86 wxMacDataBrowserTableViewControl
* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl
*>(wxMacControl::GetReferenceFromNativeControl(browser
)));
89 if (ControlPtr
!= NULL
)
90 ControlPtr
->DataBrowserItemNotificationProc(itemID
,message
,itemData
);
91 } /* wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc(ControlRef, DataBrowserItemID, DataBrowserItemNotification, DataBrowserItemDataRef) */
93 pascal void wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc(ControlRef browser
, DataBrowserItemID itemID
, DataBrowserPropertyID propertyID
, DataBrowserItemState state
, Rect
const* rectangle
, SInt16 bitDepth
, Boolean colorDevice
)
95 wxMacDataBrowserTableViewControl
* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl
*>(wxMacControl::GetReferenceFromNativeControl(browser
)));
98 if (ControlPtr
!= NULL
)
99 ControlPtr
->DataBrowserDrawItemProc(itemID
,propertyID
,state
,rectangle
,bitDepth
,colorDevice
);
100 } /* wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemState, Rect const*, SInt16, Boolean) */
102 pascal Boolean
wxMacDataBrowserTableViewControl::DataBrowserEditItemProc(ControlRef browser
, DataBrowserItemID itemID
, DataBrowserPropertyID propertyID
, CFStringRef theString
, Rect
* maxEditTextRect
, Boolean
* shrinkToFit
)
104 wxMacDataBrowserTableViewControl
* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl
*>(wxMacControl::GetReferenceFromNativeControl(browser
)));
107 return ((ControlPtr
!= NULL
) && ControlPtr
->DataBrowserEditItemProc(itemID
,propertyID
,theString
,maxEditTextRect
,shrinkToFit
));
108 } /* wxMacDataBrowserTableViewControl::DataBrowserEditItemProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, CFStringRef, Rect*, Boolean*) */
110 pascal Boolean
wxMacDataBrowserTableViewControl::DataBrowserHitTestProc(ControlRef browser
, DataBrowserItemID itemID
, DataBrowserPropertyID propertyID
, Rect
const* theRect
, Rect
const* mouseRect
)
112 wxMacDataBrowserTableViewControl
* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl
*>(wxMacControl::GetReferenceFromNativeControl(browser
)));
115 return ((ControlPtr
!= NULL
) && ControlPtr
->DataBrowserHitTestProc(itemID
,propertyID
,theRect
,mouseRect
));
116 } /* wxMacDataBrowserTableViewControl::DataBrowserHitTestProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, Rect const*, Rect const*) */
118 pascal DataBrowserTrackingResult
wxMacDataBrowserTableViewControl::DataBrowserTrackingProc(ControlRef browser
, DataBrowserItemID itemID
, DataBrowserPropertyID propertyID
, Rect
const* theRect
, Point startPt
, EventModifiers modifiers
)
120 wxMacDataBrowserTableViewControl
* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl
*>(wxMacControl::GetReferenceFromNativeControl(browser
)));
123 if (ControlPtr
!= NULL
)
124 return ControlPtr
->DataBrowserTrackingProc(itemID
,propertyID
,theRect
,startPt
,modifiers
);
126 return kDataBrowserNothingHit
;
127 } /* wxMacDataBrowserTableViewControl::DataBrowserTrackingProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, Rect const*, Point, EventModifiers) */
129 pascal Boolean
wxMacDataBrowserTableViewControl::DataBrowserAcceptDragProc(ControlRef browser
, DragReference dragRef
, DataBrowserItemID itemID
)
131 wxMacDataBrowserTableViewControl
* controlPtr(dynamic_cast<wxMacDataBrowserTableViewControl
*>(wxMacControl::GetReferenceFromNativeControl(browser
)));
134 return ((controlPtr
!= NULL
) && controlPtr
->DataBrowserAcceptDragProc(dragRef
,itemID
));
135 } /* wxMacDataBrowserTableViewControl::DataBrowserAcceptDragProc(ControlRef, DragReference, DataBrowserItemID) */
137 pascal Boolean
wxMacDataBrowserTableViewControl::DataBrowserAddDragItemProc(ControlRef browser
, DragReference dragRef
, DataBrowserItemID itemID
, ItemReference
* itemRef
)
139 wxMacDataBrowserTableViewControl
* controlPtr(dynamic_cast<wxMacDataBrowserTableViewControl
*>(wxMacControl::GetReferenceFromNativeControl(browser
)));
142 return ((controlPtr
!= NULL
) && controlPtr
->DataBrowserAddDragItemProc(dragRef
,itemID
,itemRef
));
143 } /* wxMacDataBrowserTableViewControl::DataBrowserAddDragItemProc(ControlRef, DragReference, DataBrowserItemID, ItemReference*) */
145 pascal Boolean
wxMacDataBrowserTableViewControl::DataBrowserReceiveDragProc(ControlRef browser
, DragReference dragRef
, DataBrowserItemID itemID
)
147 wxMacDataBrowserTableViewControl
* controlPtr(dynamic_cast<wxMacDataBrowserTableViewControl
*>(wxMacControl::GetReferenceFromNativeControl(browser
)));
150 return ((controlPtr
!= NULL
) && controlPtr
->DataBrowserReceiveDragProc(dragRef
,itemID
));
151 } /* wxMacDataBrowserTableViewControl::DataBrowserReceiveDragProc(ControlRef, DragReference, DataBrowserItemID) */
153 wxMacDataBrowserTableViewControl::wxMacDataBrowserTableViewControl(wxWindow
* peer
, wxPoint
const& pos
, wxSize
const& size
, long style
)
156 Rect bounds
= wxMacGetBoundsForControl(peer
,pos
,size
);
157 OSStatus err
= ::CreateDataBrowserControl(MAC_WXHWND(peer
->MacGetTopLevelWindowRef()),&bounds
,kDataBrowserListView
,&(this->m_controlRef
));
160 SetReferenceInNativeControl();
162 // setup standard callbacks:
163 if (gDataBrowserTableViewGetContextualMenuUPP
== NULL
) gDataBrowserTableViewGetContextualMenuUPP
= NewDataBrowserGetContextualMenuUPP(wxMacDataBrowserTableViewControl::DataBrowserGetContextualMenuProc
);
164 if (gDataBrowserTableViewItemCompareUPP
== NULL
) gDataBrowserTableViewItemCompareUPP
= NewDataBrowserItemCompareUPP (wxMacDataBrowserTableViewControl::DataBrowserCompareProc
);
165 if (gDataBrowserTableViewItemDataUPP
== NULL
) gDataBrowserTableViewItemDataUPP
= NewDataBrowserItemDataUPP (wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc
);
166 if (gDataBrowserTableViewItemNotificationUPP
== NULL
)
168 gDataBrowserTableViewItemNotificationUPP
=
169 #if TARGET_API_MAC_OSX
170 (DataBrowserItemNotificationUPP
) NewDataBrowserItemNotificationWithItemUPP(wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc
);
172 NewDataBrowserItemNotificationUPP(wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc
);
175 // setup drag and drop callbacks:
176 if (gDataBrowserTableViewAcceptDragUPP
== NULL
) gDataBrowserTableViewAcceptDragUPP
= NewDataBrowserAcceptDragUPP (wxMacDataBrowserTableViewControl::DataBrowserAcceptDragProc
);
177 if (gDataBrowserTableViewAddDragItemUPP
== NULL
) gDataBrowserTableViewAddDragItemUPP
= NewDataBrowserAddDragItemUPP(wxMacDataBrowserTableViewControl::DataBrowserAddDragItemProc
);
178 if (gDataBrowserTableViewReceiveDragUPP
== NULL
) gDataBrowserTableViewReceiveDragUPP
= NewDataBrowserReceiveDragUPP(wxMacDataBrowserTableViewControl::DataBrowserReceiveDragProc
);
180 DataBrowserCallbacks callbacks
; // variable definition
182 InitializeDataBrowserCallbacks(&callbacks
,kDataBrowserLatestCallbacks
);
183 callbacks
.u
.v1
.getContextualMenuCallback
= gDataBrowserTableViewGetContextualMenuUPP
;
184 callbacks
.u
.v1
.itemDataCallback
= gDataBrowserTableViewItemDataUPP
;
185 callbacks
.u
.v1
.itemCompareCallback
= gDataBrowserTableViewItemCompareUPP
;
186 callbacks
.u
.v1
.itemNotificationCallback
= gDataBrowserTableViewItemNotificationUPP
;
187 callbacks
.u
.v1
.acceptDragCallback
= gDataBrowserTableViewAcceptDragUPP
;
188 callbacks
.u
.v1
.addDragItemCallback
= gDataBrowserTableViewAddDragItemUPP
;
189 callbacks
.u
.v1
.receiveDragCallback
= gDataBrowserTableViewReceiveDragUPP
;
190 this->SetCallbacks(&callbacks
);
192 // setup callbacks for customized items:
193 if (gDataBrowserTableViewDrawItemUPP
== NULL
) gDataBrowserTableViewDrawItemUPP
= NewDataBrowserDrawItemUPP(wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc
);
194 if (gDataBrowserTableViewEditItemUPP
== NULL
) gDataBrowserTableViewEditItemUPP
= NewDataBrowserEditItemUPP(wxMacDataBrowserTableViewControl::DataBrowserEditItemProc
);
195 if (gDataBrowserTableViewHitTestUPP
== NULL
) gDataBrowserTableViewHitTestUPP
= NewDataBrowserHitTestUPP (wxMacDataBrowserTableViewControl::DataBrowserHitTestProc
);
196 if (gDataBrowserTableViewTrackingUPP
== NULL
) gDataBrowserTableViewTrackingUPP
= NewDataBrowserTrackingUPP(wxMacDataBrowserTableViewControl::DataBrowserTrackingProc
);
198 DataBrowserCustomCallbacks customCallbacks
; // variable definition
200 InitializeDataBrowserCustomCallbacks(&customCallbacks
,kDataBrowserLatestCallbacks
);
201 customCallbacks
.u
.v1
.drawItemCallback
= gDataBrowserTableViewDrawItemUPP
;
202 customCallbacks
.u
.v1
.editTextCallback
= gDataBrowserTableViewEditItemUPP
;
203 customCallbacks
.u
.v1
.hitTestCallback
= gDataBrowserTableViewHitTestUPP
;
204 customCallbacks
.u
.v1
.trackingCallback
= gDataBrowserTableViewTrackingUPP
;
205 this->SetCustomCallbacks(&customCallbacks
);
208 this->EnableCellSizeModification( ((style
& wxDV_VARIABLE_LINE_HEIGHT
) != 0), true );
210 DataBrowserSelectionFlags flags
; // variable definition
212 if (this->GetSelectionFlags(&flags
) == noErr
) // get default settings
214 if ((style
& wxDV_MULTIPLE
) != 0)
215 flags
&= ~kDataBrowserSelectOnlyOne
;
217 flags
|= kDataBrowserSelectOnlyOne
;
218 (void) this->SetSelectionFlags(flags
);
221 OptionBits attributes
; // variable definition
223 if (this->GetAttributes(&attributes
) == noErr
) // get default settings
225 if ((style
& wxDV_VERT_RULES
) != 0)
226 attributes
|= kDataBrowserAttributeListViewDrawColumnDividers
;
228 attributes
&= ~kDataBrowserAttributeListViewDrawColumnDividers
;
229 if ((style
& wxDV_ROW_LINES
) != 0)
230 attributes
|= kDataBrowserAttributeListViewAlternatingRowColors
;
232 attributes
&= ~kDataBrowserAttributeListViewAlternatingRowColors
;
233 (void) this->SetAttributes(attributes
);
236 if ((style
& wxDV_NO_HEADER
) != 0)
237 this->SetHeaderButtonHeight(0);
238 } /* wxMacDataBrowserTableViewControl::wxMacDataBrowserTableViewControl(wxWindow*, wxPoint const&, wxSize const&, long) */
243 OSStatus
wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks
const* callbacks
)
245 return ::SetDataBrowserCallbacks(this->m_controlRef
,callbacks
);
246 } /* wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks const*) */
248 OSStatus
wxMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks
const* customCallbacks
)
250 return ::SetDataBrowserCustomCallbacks(this->m_controlRef
,customCallbacks
);
251 } /* xMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks const*) */
256 OSStatus
wxMacDataBrowserTableViewControl::GetHeaderDesc(DataBrowserPropertyID propertyID
, DataBrowserListViewHeaderDesc
* desc
) const
258 desc
->version
= kDataBrowserListViewLatestHeaderDesc
; // if this statement is missing the next call will fail (NOT DOCUMENTED!!)
259 return ::GetDataBrowserListViewHeaderDesc(this->m_controlRef
,propertyID
,desc
);
262 OSStatus
wxMacDataBrowserTableViewControl::SetHeaderDesc(DataBrowserPropertyID propertyID
, DataBrowserListViewHeaderDesc
* desc
)
264 return ::SetDataBrowserListViewHeaderDesc(this->m_controlRef
,propertyID
,desc
);
270 OSStatus
wxMacDataBrowserTableViewControl::AutoSizeColumns()
272 return AutoSizeDataBrowserListViewColumns(this->m_controlRef
);
275 OSStatus
wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool enableHeight
, bool enableWidth
)
277 return ::SetDataBrowserTableViewGeometry(this->GetControlRef(),enableWidth
,enableHeight
);
278 } /* wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool, bool) */
280 OSStatus
wxMacDataBrowserTableViewControl::GetAttributes(OptionBits
* attributes
)
282 return ::DataBrowserGetAttributes(this->GetControlRef(),attributes
);
283 } /* wxMacDataBrowserTableViewControl::GetAttributes(OptionBits*) */
285 OSStatus
wxMacDataBrowserTableViewControl::GetColumnWidth(DataBrowserPropertyID propertyID
, UInt16
* width
) const
287 return ::GetDataBrowserTableViewNamedColumnWidth(this->m_controlRef
,propertyID
,width
);
290 OSStatus
wxMacDataBrowserTableViewControl::GetDefaultColumnWidth( UInt16
*width
) const
292 return GetDataBrowserTableViewColumnWidth(this->m_controlRef
, width
);
295 OSStatus
wxMacDataBrowserTableViewControl::GetDefaultRowHeight(UInt16
* height
) const
297 return ::GetDataBrowserTableViewRowHeight(this->m_controlRef
,height
);
300 OSStatus
wxMacDataBrowserTableViewControl::GetHeaderButtonHeight(UInt16
*height
)
302 return ::GetDataBrowserListViewHeaderBtnHeight(this->m_controlRef
,height
);
305 OSStatus
wxMacDataBrowserTableViewControl::GetPartBounds(DataBrowserItemID item
, DataBrowserPropertyID propertyID
, DataBrowserPropertyPart part
, Rect
* bounds
)
307 return ::GetDataBrowserItemPartBounds(this->m_controlRef
,item
,propertyID
,part
,bounds
);
308 } /* wxMacDataBrowserTableViewControl::GetPartBounds(DataBrowserItemID, DataBrowswerPropertyID, DataBrowserPropertyPart, Rect*) */
310 OSStatus
wxMacDataBrowserTableViewControl::GetRowHeight(DataBrowserItemID item
, UInt16
* height
) const
312 return ::GetDataBrowserTableViewItemRowHeight(this->m_controlRef
,item
,height
);
313 } /* wxMacDataBrowserTableViewControl::GetRowHeight(DataBrowserItemID, UInt16*) const */
315 OSStatus
wxMacDataBrowserTableViewControl::GetScrollPosition( UInt32
*top
, UInt32
*left
) const
317 return GetDataBrowserScrollPosition(this->m_controlRef
, top
, left
);
320 OSStatus
wxMacDataBrowserTableViewControl::SetAttributes(OptionBits attributes
)
322 return ::DataBrowserChangeAttributes(this->GetControlRef(),attributes
,~attributes
);
323 } /* wxMacDataBrowserTableViewControl::SetAttributes(OptionBits) */
325 OSStatus
wxMacDataBrowserTableViewControl::SetColumnWidth(DataBrowserPropertyID propertyID
, UInt16 width
)
327 return ::SetDataBrowserTableViewNamedColumnWidth(this->m_controlRef
,propertyID
,width
);
330 OSStatus
wxMacDataBrowserTableViewControl::SetDefaultColumnWidth(UInt16 width
)
332 return ::SetDataBrowserTableViewColumnWidth(this->m_controlRef
,width
);
335 OSStatus
wxMacDataBrowserTableViewControl::SetDefaultRowHeight(UInt16 height
)
337 return ::SetDataBrowserTableViewRowHeight(this->m_controlRef
,height
);
340 OSStatus
wxMacDataBrowserTableViewControl::SetHasScrollBars(bool horiz
, bool vert
)
342 return ::SetDataBrowserHasScrollBars(this->m_controlRef
,horiz
,vert
);
343 } /* wxMacDataBrowserTableViewControl::SetHasScrollBars(bool, bool) */
345 OSStatus
wxMacDataBrowserTableViewControl::SetHeaderButtonHeight(UInt16 height
)
347 return ::SetDataBrowserListViewHeaderBtnHeight(this->m_controlRef
,height
);
348 } /* wxMacDataBrowserTableViewControl::SetHeaderButtonHeight(UInt16) */
350 OSStatus
wxMacDataBrowserTableViewControl::SetHiliteStyle(DataBrowserTableViewHiliteStyle hiliteStyle
)
352 return ::SetDataBrowserTableViewHiliteStyle(this->m_controlRef
,hiliteStyle
);
353 } /*wxMacDataBrowserTableViewControl::SetHiliteStyle(DataBrowserTableViewHiliteStyle) */
355 OSStatus
wxMacDataBrowserTableViewControl::SetIndent(float Indent
)
357 return ::DataBrowserSetMetric(this->m_controlRef
,kDataBrowserMetricDisclosureColumnPerDepthGap
,true,Indent
);
358 } /* wxMacDataBrowserTableViewControl::SetIndent(float* Indent) */
360 OSStatus
wxMacDataBrowserTableViewControl::SetRowHeight(DataBrowserItemID item
, UInt16 height
)
362 return ::SetDataBrowserTableViewItemRowHeight(this->m_controlRef
,item
,height
);
365 OSStatus
wxMacDataBrowserTableViewControl::SetScrollPosition(UInt32 top
, UInt32 left
)
367 return ::SetDataBrowserScrollPosition(this->m_controlRef
,top
,left
);
373 OSStatus
wxMacDataBrowserTableViewControl::GetColumnCount(UInt32
* numColumns
) const
375 return ::GetDataBrowserTableViewColumnCount(this->m_controlRef
,numColumns
);
378 OSStatus
wxMacDataBrowserTableViewControl::GetColumnIndex(DataBrowserPropertyID propertyID
, DataBrowserTableViewColumnIndex
* index
) const
380 return ::GetDataBrowserTableViewColumnPosition(this->m_controlRef
,propertyID
,index
);
381 } /* wxMacDataBrowserTableViewControl::GetColumnIndex(DataBrowserPropertyID, DataBrowserTableViewColumnIndex*) const */
383 OSStatus
wxMacDataBrowserTableViewControl::GetFreePropertyID(DataBrowserPropertyID
* propertyID
) const
385 for (*propertyID
=kMinPropertyID
; *propertyID
<std::numeric_limits
<DataBrowserPropertyID
>::max(); ++(*propertyID
))
386 if (this->IsUsedPropertyID(*propertyID
) == errDataBrowserPropertyNotFound
)
388 return errDataBrowserPropertyNotSupported
;
389 } /* wxMacDataBrowserTableViewControl::GetFreePropertyID(DataBrowserPropertyID*) const */
391 OSStatus
wxMacDataBrowserTableViewControl::GetPropertyFlags(DataBrowserPropertyID propertyID
, DataBrowserPropertyFlags
*flags
) const
393 return ::GetDataBrowserPropertyFlags(this->m_controlRef
,propertyID
,flags
);
396 OSStatus
wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserItemDataRef itemData
, DataBrowserPropertyID
* propertyID
)
398 return ::GetDataBrowserItemDataProperty(itemData
,propertyID
);
399 } /* wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserItemDataRef, DataBrowserPropertyID*) */
401 OSStatus
wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserTableViewColumnIndex index
, DataBrowserTableViewColumnID
* propertyID
)
403 return ::GetDataBrowserTableViewColumnProperty(this->m_controlRef
,index
,propertyID
);
404 } /* wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserTableViewColumnIndex, DataBrowserTableViewColumnID*) */
406 OSStatus
wxMacDataBrowserTableViewControl::IsUsedPropertyID(DataBrowserPropertyID propertyID
) const
408 // 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
409 // 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
410 // the column position for the property id:
411 DataBrowserTableViewColumnIndex index
;
413 return ::GetDataBrowserTableViewColumnPosition(this->m_controlRef
,propertyID
,&index
);
414 } /* wxMacDataBrowserTableViewControl::IsUsedPropertyId(DataBrowserPropertyID) const */
416 OSStatus
wxMacDataBrowserTableViewControl::RemoveColumnByProperty(DataBrowserTableViewColumnID propertyID
)
418 return ::RemoveDataBrowserTableViewColumn(this->m_controlRef
,propertyID
);
419 } /* wxMacDataBrowserTableViewControl::RemoveColumnByProperty(DataBrowserTableViewColumnID) */
421 OSStatus
wxMacDataBrowserTableViewControl::RemoveColumnByIndex(DataBrowserTableViewColumnIndex index
)
423 DataBrowserTableViewColumnID propertyID
;
426 this->GetPropertyID(index
,&propertyID
);
427 return ::RemoveDataBrowserTableViewColumn(this->m_controlRef
,propertyID
);
428 } /* wxMacDataBrowserTableViewControl::RemoveColumnByIndex(DataBrowserTableViewColumnIndex) */
430 OSStatus
wxMacDataBrowserTableViewControl::SetColumnIndex(DataBrowserPropertyID propertyID
, DataBrowserTableViewColumnIndex index
)
432 return ::SetDataBrowserTableViewColumnPosition(this->m_controlRef
,propertyID
,index
);
433 } /* wxMacDataBrowserTableViewControl::SetColumnIndex(DataBrowserPropertyID, DataBrowserTableViewColumnIndex) */
435 OSStatus
wxMacDataBrowserTableViewControl::SetDisclosureColumn(DataBrowserPropertyID propertyID
, Boolean expandableRows
)
437 return ::SetDataBrowserListViewDisclosureColumn(this->m_controlRef
,propertyID
,expandableRows
);
440 OSStatus
wxMacDataBrowserTableViewControl::SetPropertyFlags(DataBrowserPropertyID propertyID
, DataBrowserPropertyFlags flags
)
442 return ::SetDataBrowserPropertyFlags(this->m_controlRef
,propertyID
,flags
);
443 } /* wxMacDataBrowserTableViewControl::SetPropertyFlags(DataBrowserPropertyID, DataBrowserPropertyFlags) */
448 OSStatus
wxMacDataBrowserTableViewControl::AddItems(DataBrowserItemID container
, UInt32 numItems
, DataBrowserItemID
const* items
, DataBrowserPropertyID preSortProperty
)
450 return ::AddDataBrowserItems(this->m_controlRef
,container
,numItems
,items
,preSortProperty
);
451 } /* wxMacDataBrowserTableViewControl::AddItems(DataBrowserItemID, UInt32, DataBrowserItemID const*, DataBrowserPropertyID) */
453 OSStatus
wxMacDataBrowserTableViewControl::GetFreeItemID(DataBrowserItemID
* id
) const
460 status
= this->GetItemCount(&NoOfItems
);
461 wxCHECK_MSG(status
== noErr
,status
,_("Could not retrieve number of items"));
469 // 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
470 // as the number of items; therefore, start from the number of items to look for a new ID:
471 for (*id
=NoOfItems
; *id
<std::numeric_limits
<DataBrowserItemID
>::max(); ++(*id
))
472 if (this->IsUsedItemID(*id
) == errDataBrowserItemNotFound
)
474 // as the first approach was not successful, try from the beginning:
475 for (*id
=0; *id
<NoOfItems
; ++(*id
))
476 if (this->IsUsedItemID(*id
) == errDataBrowserItemNotFound
)
478 // sorry, data browser is full:
479 return errDataBrowserItemNotAdded
;
481 } /* wxMacDataBrowserTableViewControl::GetFreeItemID(DataBrowserItemID*) const */
483 OSStatus
wxMacDataBrowserTableViewControl::GetItemCount(DataBrowserItemID container
, Boolean recurse
, DataBrowserItemState state
, ItemCount
* numItems
) const
485 return GetDataBrowserItemCount(this->m_controlRef
,container
,recurse
,state
,numItems
);
486 } /* wxMacDataBrowserTableViewControl::GetItemCount(DataBrowserItemID, Boolean, DataBrowserItemState, ItemCount*) const */
488 OSStatus
wxMacDataBrowserTableViewControl::GetItemID( DataBrowserTableViewRowIndex row
, DataBrowserItemID
* item
) const
490 return GetDataBrowserTableViewItemID(this->m_controlRef
,row
,item
);
493 OSStatus
wxMacDataBrowserTableViewControl::GetItems(DataBrowserItemID container
, Boolean recurse
, DataBrowserItemState state
, Handle items
) const
495 return GetDataBrowserItems(this->m_controlRef
,container
,recurse
,state
,items
);
496 } /* wxMacDataBrowserTableViewControl::GetItems(DataBrowserItemID, Boolean, DataBrowserItemState, Handle) const */
498 OSStatus
wxMacDataBrowserTableViewControl::GetItemRow(DataBrowserItemID item
, DataBrowserTableViewRowIndex
* row
) const
500 return GetDataBrowserTableViewItemRow(this->m_controlRef
,item
,row
);
503 OSStatus
wxMacDataBrowserTableViewControl::IsUsedItemID(DataBrowserItemID itemID
) const
505 // 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
506 // 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
507 // the column position for the property id:
508 DataBrowserTableViewColumnIndex index
;
510 return ::GetDataBrowserTableViewItemRow(this->m_controlRef
,itemID
,&index
);
511 } /* wxMacDataBrowserTableViewControl::IsUsedItemID(DataBrowserItemID) const */
513 OSStatus
wxMacDataBrowserTableViewControl::RemoveItems(DataBrowserItemID container
, UInt32 numItems
, DataBrowserItemID
const* items
, DataBrowserPropertyID preSortProperty
)
515 return ::RemoveDataBrowserItems(this->m_controlRef
,container
,numItems
,items
,preSortProperty
);
518 OSStatus
wxMacDataBrowserTableViewControl::RevealItem(DataBrowserItemID item
, DataBrowserPropertyID propertyID
, DataBrowserRevealOptions options
) const
520 return ::RevealDataBrowserItem(this->m_controlRef
,item
,propertyID
,options
);
521 } /* wxMacDataBrowserTableViewControl::RevealItem(DataBrowserItemID item, DataBrowserPropertyID propertyID, DataBrowserRevealOptions options) const */
523 OSStatus
wxMacDataBrowserTableViewControl::UpdateItems(DataBrowserItemID container
, UInt32 numItems
, DataBrowserItemID
const* items
, DataBrowserPropertyID preSortProperty
,
524 DataBrowserPropertyID propertyID
) const
526 return UpdateDataBrowserItems(this->m_controlRef
,container
,numItems
,items
,preSortProperty
,propertyID
);
532 size_t wxMacDataBrowserTableViewControl::GetSelectedItemIDs(wxArrayDataBrowserItemID
& itemIDs
) const
534 DataBrowserItemID
* itemIDPtr
;
535 Handle
handle(::NewHandle(0));
540 wxCHECK_MSG(this->GetItems(kDataBrowserNoItem
,true,kDataBrowserItemIsSelected
,handle
) == noErr
,0,_("Could not get selected items."));
541 NoOfItems
= static_cast<size_t>(::GetHandleSize(handle
)/sizeof(DataBrowserItemID
));
543 itemIDs
.Alloc(NoOfItems
);
545 itemIDPtr
= (DataBrowserItemID
*) (*handle
);
546 for (size_t i
=0; i
<NoOfItems
; ++i
)
548 itemIDs
.Add(*itemIDPtr
);
552 DisposeHandle(handle
);
554 } /* wxMacDataBrowserTableViewControl::GetSelectedItemIDs(wxArrayDataBrowserItemID&) const*/
556 OSStatus
wxMacDataBrowserTableViewControl::GetSelectionAnchor(DataBrowserItemID
* first
, DataBrowserItemID
* last
) const
558 return ::GetDataBrowserSelectionAnchor(this->m_controlRef
,first
,last
);
559 } /* wxMacDataBrowserTableViewControl::GetSelectionAnchor(DataBrowserItemID*, DataBrowserItemID*) const */
561 OSStatus
wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags
* flags
) const
563 return ::GetDataBrowserSelectionFlags(this->m_controlRef
,flags
);
564 } /* wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags*) const */
566 bool wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID item
) const
568 return ::IsDataBrowserItemSelected(this->m_controlRef
,item
);
569 } /* wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID) const */
571 OSStatus
wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags flags
)
573 return ::SetDataBrowserSelectionFlags(this->m_controlRef
,flags
);
574 } /* wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags) */
576 OSStatus
wxMacDataBrowserTableViewControl::SetSelectedItems(UInt32 numItems
, DataBrowserItemID
const* items
, DataBrowserSetOption operation
)
578 return ::SetDataBrowserSelectedItems(this->m_controlRef
, numItems
, items
, operation
);
579 } /* wxMacDataBrowserTableViewControl::SetSelectedItems(UInt32, DataBrowserItemID const*, DataBrowserSetOption) */
581 OSStatus
wxMacDataBrowserTableViewControl::GetSortOrder(DataBrowserSortOrder
* order
) const
583 return ::GetDataBrowserSortOrder(this->m_controlRef
,order
);
586 OSStatus
wxMacDataBrowserTableViewControl::GetSortProperty(DataBrowserPropertyID
* propertyID
) const
588 return ::GetDataBrowserSortProperty(this->m_controlRef
,propertyID
);
591 OSStatus
wxMacDataBrowserTableViewControl::Resort(DataBrowserItemID container
, Boolean sortChildren
)
593 return ::SortDataBrowserContainer(this->m_controlRef
,container
,sortChildren
);
594 } /* wxMacDataBrowserTableViewControl::Resort(DataBrowserItemID, Boolean) */
596 OSStatus
wxMacDataBrowserTableViewControl::SetSortOrder(DataBrowserSortOrder order
)
598 return ::SetDataBrowserSortOrder(this->m_controlRef
,order
);
601 OSStatus
wxMacDataBrowserTableViewControl::SetSortProperty(DataBrowserPropertyID propertyID
)
603 return ::SetDataBrowserSortProperty(this->m_controlRef
,propertyID
);
607 // container handling
609 OSStatus
wxMacDataBrowserTableViewControl::CloseContainer(DataBrowserItemID containerID
)
611 return ::CloseDataBrowserContainer(this->m_controlRef
,containerID
);
612 } /* wxMacDataBrowserTableViewControl::CloseContainer(DataBrowserItemID) */
614 OSStatus
wxMacDataBrowserTableViewControl::OpenContainer(DataBrowserItemID containerID
)
616 return ::OpenDataBrowserContainer(this->m_controlRef
,containerID
);
617 } /* wxMacDataBrowserTableViewControl::OpenContainer(DataBrowserItemID) */
619 IMPLEMENT_ABSTRACT_CLASS(wxMacDataBrowserTableViewControl
,wxMacControl
)
621 // ============================================================================
622 // wxMacDataBrowserListViewControl
623 // ============================================================================
628 OSStatus
wxMacDataBrowserListViewControl::AddColumn(DataBrowserListViewColumnDesc
*columnDesc
, DataBrowserTableViewColumnIndex position
)
630 return AddDataBrowserListViewColumn(this->m_controlRef
,columnDesc
,position
);
631 } /* wxMacDataBrowserListViewControl::AddColumn(DataBrowserListViewColumnDesc*, DataBrowserTableViewColumnIndex) */
633 // ============================================================================
634 // wxMacDataViewDataBrowserListViewControl
635 // ============================================================================
638 // constructors / destructor
640 wxMacDataViewDataBrowserListViewControl::wxMacDataViewDataBrowserListViewControl(wxWindow
* peer
, wxPoint
const& pos
, wxSize
const& size
, long style
)
641 :wxMacDataBrowserListViewControl(peer
,pos
,size
,style
)
643 } /* wxMacDataViewDataBrowserListViewControl::wxMacDataViewDataBrowserListViewControl(wxWindow* , const wxPoint&, const wxSize&, long) */
646 // callback functions (inherited from wxMacDataBrowserTableViewControl)
648 Boolean
wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID itemOneID
, DataBrowserItemID itemTwoID
, DataBrowserPropertyID sortProperty
)
650 DataBrowserSortOrder sortOrder
;
652 DataBrowserTableViewColumnIndex modelColumnIndex
;
654 wxDataViewCtrl
* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl
*>(this->GetWXPeer()));
657 wxCHECK_MSG(dataViewCtrlPtr
!= NULL
, false,_("Pointer to data view control not set correctly."));
658 wxCHECK_MSG(dataViewCtrlPtr
->GetModel() != NULL
,false,_("Pointer to model not set correctly."));
659 if (sortProperty
>= kMinPropertyID
)
661 // variable definition and initialization:
662 wxDataViewColumn
* ColumnPtr(dataViewCtrlPtr
->GetColumnPtr(sortProperty
));
664 wxCHECK_MSG(ColumnPtr
!= NULL
,false,_("Could not determine column index."));
665 modelColumnIndex
= ColumnPtr
->GetModelColumn();
668 modelColumnIndex
= 0;
669 this->GetSortOrder(&sortOrder
);
670 return static_cast<Boolean
>(dataViewCtrlPtr
->GetModel()->Compare(wxDataViewItem(reinterpret_cast<void*>(itemOneID
)),wxDataViewItem(reinterpret_cast<void*>(itemTwoID
)),
671 modelColumnIndex
,sortOrder
!= kDataBrowserOrderDecreasing
) < 0);
672 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID) */
674 void wxMacDataViewDataBrowserListViewControl::DataBrowserGetContextualMenuProc(MenuRef
* menu
, UInt32
* helpType
, CFStringRef
* helpItemString
, AEDesc
* WXUNUSED(selection
))
675 // In this method we do not supply a contextual menu handler at all but only send a wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU.
677 wxArrayDataBrowserItemID itemIDs
;
679 wxDataViewCtrl
* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl
*>(this->GetWXPeer()));
682 wxCHECK_RET(dataViewCtrlPtr
!= NULL
,_("wxWidget control pointer is not a data view pointer"));
683 // initialize parameters so that no context menu will be displayed automatically by the native data browser:
685 *helpType
= kCMHelpItemNoHelp
;
686 *helpItemString
= NULL
;
687 // create information for a context menu event:
688 wxDataViewEvent
dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU
,dataViewCtrlPtr
->GetId());
690 dataViewEvent
.SetEventObject(dataViewCtrlPtr
);
691 dataViewEvent
.SetModel(dataViewCtrlPtr
->GetModel());
692 // get the item information;
693 // 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:
694 if (this->GetSelectedItemIDs(itemIDs
) > 0)
695 dataViewEvent
.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemIDs
[0])));
696 // finally send the equivalent wxWidget event:
697 dataViewCtrlPtr
->GetEventHandler()->ProcessEvent(dataViewEvent
);
698 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserGetContextualMenuProc(MenuRef*, UInt32*, CFStringRef*, AEDesc*) */
700 OSStatus
wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc(DataBrowserItemID itemID
, DataBrowserPropertyID propertyID
, DataBrowserItemDataRef itemData
, Boolean getValue
)
704 // variable definitions:
705 wxDataViewCtrl
* dataViewCtrlPtr
;
707 dataViewCtrlPtr
= dynamic_cast<wxDataViewCtrl
*>(this->GetWXPeer());
708 wxCHECK_MSG(dataViewCtrlPtr
!= NULL
,errDataBrowserNotConfigured
,_("Pointer to data view control not set correctly."));
709 if (dataViewCtrlPtr
->IsDeleting())
710 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
713 // variable definitions:
714 OSStatus errorStatus
;
715 wxDataViewColumn
* dataViewColumnPtr
;
717 wxCHECK_MSG(dataViewCtrlPtr
->GetModel() != NULL
,errDataBrowserNotConfigured
,_("Pointer to model not set correctly."));
718 dataViewColumnPtr
= dataViewCtrlPtr
->GetColumnPtr(propertyID
);
719 wxCHECK_MSG((dataViewColumnPtr
!= NULL
) && (dataViewColumnPtr
->GetRenderer() != NULL
),errDataBrowserNotConfigured
,_("There is no column or renderer for the specified column index."));
721 wxDataViewItem
dvItem(reinterpret_cast<void*>(itemID
));
722 unsigned int col
= dataViewColumnPtr
->GetModelColumn();
724 switch (dataViewColumnPtr
->GetRenderer()->GetPropertyType())
726 case kDataBrowserCheckboxType
:
728 // variable definition:
729 ThemeButtonValue buttonValue
;
731 errorStatus
= ::GetDataBrowserItemDataButtonValue(itemData
,&buttonValue
);
732 if (errorStatus
== noErr
)
734 if (buttonValue
== kThemeButtonOn
)
736 // variable definition and initialization:
737 wxVariant
modifiedData(true);
739 if (dataViewCtrlPtr
->GetModel()->SetValue(modifiedData
, dvItem
, col
) &&
740 dataViewCtrlPtr
->GetModel()->ValueChanged(dvItem
, col
))
743 return errDataBrowserInvalidPropertyData
;
745 else if (buttonValue
== kThemeButtonOff
)
747 // variable definition and initialization:
748 wxVariant
modifiedData(false);
750 if (dataViewCtrlPtr
->GetModel()->SetValue(modifiedData
, dvItem
, col
) &&
751 dataViewCtrlPtr
->GetModel()->ValueChanged(dvItem
, col
))
754 return errDataBrowserInvalidPropertyData
;
757 return errDataBrowserInvalidPropertyData
;
762 case kDataBrowserTextType
:
764 // variable definitions:
765 CFStringRef stringReference
;
767 errorStatus
= ::GetDataBrowserItemDataText(itemData
,&stringReference
);
768 if (errorStatus
== noErr
)
770 // variable definitions and initializations:
771 #if wxCHECK_VERSION(2,9,0)
772 wxCFStringRef
modifiedString(stringReference
);
774 wxMacCFStringHolder
modifiedString(stringReference
);
776 wxVariant
modifiedData(modifiedString
.AsString());
778 if (dataViewCtrlPtr
->GetModel()->SetValue(modifiedData
, dvItem
, col
) &&
779 dataViewCtrlPtr
->GetModel()->ValueChanged(dvItem
, col
))
782 return errDataBrowserInvalidPropertyData
;
788 return errDataBrowserPropertyNotSupported
;
794 if (propertyID
>= kMinPropertyID
) // in case data columns set the data
796 // variable definitions:
798 wxDataViewColumn
* dataViewColumnPtr
;
799 wxDataViewCtrl
* dataViewCtrlPtr
;
801 dataViewCtrlPtr
= dynamic_cast<wxDataViewCtrl
*>(this->GetWXPeer());
802 wxCHECK_MSG(dataViewCtrlPtr
!= NULL
,errDataBrowserNotConfigured
,_("Pointer to data view control not set correctly."));
803 wxCHECK_MSG(dataViewCtrlPtr
->GetModel() != NULL
,errDataBrowserNotConfigured
,_("Pointer to model not set correctly."));
804 dataViewColumnPtr
= dataViewCtrlPtr
->GetColumnPtr(propertyID
);
805 wxCHECK_MSG(dataViewColumnPtr
!= NULL
,errDataBrowserNotConfigured
,_("No column for the specified column position existing."));
806 wxCHECK_MSG(dataViewColumnPtr
->GetRenderer() != NULL
,errDataBrowserNotConfigured
,_("No renderer specified for column."));
807 dataViewCtrlPtr
->GetModel()->GetValue(variant
,wxDataViewItem(reinterpret_cast<void*>(itemID
)),dataViewColumnPtr
->GetModelColumn());
808 if (!(variant
.IsNull()))
810 dataViewColumnPtr
->GetRenderer()->SetDataReference(itemData
);
811 dataViewColumnPtr
->GetRenderer()->SetValue(variant
);
812 wxCHECK_MSG(dataViewColumnPtr
->GetRenderer()->Render(),errDataBrowserNotConfigured
,_("Rendering failed."));
816 else // react on special system requests
820 case kDataBrowserContainerIsClosableProperty
:
822 // variable definitions:
823 wxDataViewCtrl
* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl
*>(this->GetWXPeer()));
825 wxCHECK_MSG(dataViewCtrlPtr
!= NULL
,errDataBrowserNotConfigured
,_("Pointer to data view control not set correctly."));
826 // initialize wxWidget event:
827 wxDataViewEvent
dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING
,dataViewCtrlPtr
->GetId()); // variable definition
829 dataViewEvent
.SetEventObject(dataViewCtrlPtr
);
830 dataViewEvent
.SetItem (wxDataViewItem(reinterpret_cast<void*>(itemID
)));
831 dataViewEvent
.SetModel (dataViewCtrlPtr
->GetModel());
832 // finally send the equivalent wxWidget event:
833 dataViewCtrlPtr
->GetEventHandler()->ProcessEvent(dataViewEvent
);
834 // opening the container is allowed if not vetoed:
835 return ::SetDataBrowserItemDataBooleanValue(itemData
,dataViewEvent
.IsAllowed());
837 case kDataBrowserContainerIsOpenableProperty
:
839 // variable definitions:
840 wxDataViewCtrl
* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl
*>(this->GetWXPeer()));
842 wxCHECK_MSG(dataViewCtrlPtr
!= NULL
,errDataBrowserNotConfigured
,_("Pointer to data view control not set correctly."));
843 // initialize wxWidget event:
844 wxDataViewEvent
dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING
,dataViewCtrlPtr
->GetId()); // variable definition
846 dataViewEvent
.SetEventObject(dataViewCtrlPtr
);
847 dataViewEvent
.SetItem (wxDataViewItem(reinterpret_cast<void*>(itemID
)));
848 dataViewEvent
.SetModel (dataViewCtrlPtr
->GetModel());
849 // finally send the equivalent wxWidget event:
850 dataViewCtrlPtr
->GetEventHandler()->ProcessEvent(dataViewEvent
);
851 // opening the container is allowed if not vetoed:
852 return ::SetDataBrowserItemDataBooleanValue(itemData
,dataViewEvent
.IsAllowed());
854 case kDataBrowserItemIsContainerProperty
:
856 // variable definition:
857 wxDataViewCtrl
* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl
*>(this->GetWXPeer()));
859 wxCHECK_MSG(dataViewCtrlPtr
!= NULL
,errDataBrowserNotConfigured
,_("Pointer to data view control not set correctly."));
860 wxCHECK_MSG(dataViewCtrlPtr
->GetModel() != NULL
,errDataBrowserNotConfigured
,_("Pointer to model not set correctly."));
861 return ::SetDataBrowserItemDataBooleanValue(itemData
,dataViewCtrlPtr
->GetModel()->IsContainer(wxDataViewItem(reinterpret_cast<void*>(itemID
))));
863 case kDataBrowserItemIsEditableProperty
:
864 return ::SetDataBrowserItemDataBooleanValue(itemData
,true);
868 return errDataBrowserPropertyNotSupported
;
869 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc(DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemDataRef, Boolean) */
871 void wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID itemID
, DataBrowserItemNotification message
, DataBrowserItemDataRef itemData
)
873 wxDataViewCtrl
* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl
*>(this->GetWXPeer()));
876 // 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:
877 if (dataViewCtrlPtr
!= NULL
)
880 case kDataBrowserContainerClosed
:
881 dataViewCtrlPtr
->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
883 // initialize wxWidget event:
884 wxDataViewEvent
dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED
,dataViewCtrlPtr
->GetId()); // variable definition
886 dataViewEvent
.SetEventObject(dataViewCtrlPtr
);
887 dataViewEvent
.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID
)));
888 // finally send the equivalent wxWidget event:
889 dataViewCtrlPtr
->GetEventHandler()->ProcessEvent(dataViewEvent
);
892 case kDataBrowserContainerOpened
:
893 dataViewCtrlPtr
->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
895 // initialize wxWidget event:
896 wxDataViewEvent
dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED
,dataViewCtrlPtr
->GetId()); // variable definition
898 dataViewEvent
.SetEventObject(dataViewCtrlPtr
);
899 dataViewEvent
.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID
)));
900 // finally send the equivalent wxWidget event:
901 dataViewCtrlPtr
->GetEventHandler()->ProcessEvent(dataViewEvent
);
902 // add children to the expanded container:
903 dataViewCtrlPtr
->AddChildrenLevel(wxDataViewItem(reinterpret_cast<void*>(itemID
)));
906 case kDataBrowserEditStarted
:
907 dataViewCtrlPtr
->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
909 // initialize wxWidget event:
910 DataBrowserPropertyID propertyID
;
911 wxDataViewEvent
dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED
,dataViewCtrlPtr
->GetId()); // variable definition
913 dataViewEvent
.SetEventObject(dataViewCtrlPtr
);
914 dataViewEvent
.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID
)));
915 if (this->GetPropertyID(itemData
,&propertyID
) == noErr
)
917 // variable definition and initialization:
918 DataBrowserTableViewColumnIndex columnIndex
;
920 wxCHECK_RET(this->GetColumnIndex(propertyID
,&columnIndex
),_("Column index not found."));
921 dataViewEvent
.SetColumn(columnIndex
);
922 dataViewEvent
.SetDataViewColumn(dataViewCtrlPtr
->GetColumnPtr(propertyID
));
924 // finally send the equivalent wxWidget event:
925 dataViewCtrlPtr
->GetEventHandler()->ProcessEvent(dataViewEvent
);
928 case kDataBrowserEditStopped
:
930 // initialize wxWidget event:
931 DataBrowserPropertyID propertyID
;
932 wxDataViewEvent
dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE
,dataViewCtrlPtr
->GetId()); // variable definition
934 dataViewEvent
.SetEventObject(dataViewCtrlPtr
);
935 dataViewEvent
.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID
)));
936 if (this->GetPropertyID(itemData
,&propertyID
) == noErr
)
938 // variable definition and initialization:
939 DataBrowserTableViewColumnIndex columnIndex
;
941 wxCHECK_RET(this->GetColumnIndex(propertyID
,&columnIndex
),_("Column index not found."));
942 dataViewEvent
.SetColumn(columnIndex
);
943 dataViewEvent
.SetDataViewColumn(dataViewCtrlPtr
->GetColumnPtr(propertyID
));
945 // finally send the equivalent wxWidget event:
946 dataViewCtrlPtr
->GetEventHandler()->ProcessEvent(dataViewEvent
);
949 case kDataBrowserItemAdded
:
950 dataViewCtrlPtr
->FinishCustomItemEditing();
952 case kDataBrowserItemDeselected
:
953 dataViewCtrlPtr
->FinishCustomItemEditing();
955 case kDataBrowserItemDoubleClicked
:
957 // initialize wxWidget event:
958 wxDataViewEvent
dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED
,dataViewCtrlPtr
->GetId()); // variable definition
960 dataViewEvent
.SetEventObject(dataViewCtrlPtr
);
961 dataViewEvent
.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID
)));
962 // finally send the equivalent wxWidget event:
963 dataViewCtrlPtr
->GetEventHandler()->ProcessEvent(dataViewEvent
);
966 case kDataBrowserItemRemoved
:
967 dataViewCtrlPtr
->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
969 case kDataBrowserItemSelected
:
970 break; // not implemented by wxWidgets; see kDataBrowserSelectionSetChanged
971 case kDataBrowserSelectionSetChanged
:
973 // initialize wxWidget event:
974 wxDataViewEvent
dataViewEvent(wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED
,dataViewCtrlPtr
->GetId()); // variable definition
975 dataViewEvent
.SetItem( dataViewCtrlPtr
->GetSelection() );
976 dataViewEvent
.SetEventObject(dataViewCtrlPtr
);
977 dataViewEvent
.SetModel (dataViewCtrlPtr
->GetModel());
978 // finally send the equivalent wxWidget event:
979 dataViewCtrlPtr
->GetEventHandler()->ProcessEvent(dataViewEvent
);
982 case kDataBrowserTargetChanged
: // no idea if this notification is ever sent
984 case kDataBrowserUserStateChanged
:
986 // finish custom item editing if necessary:
987 dataViewCtrlPtr
->FinishCustomItemEditing();
988 // update column widths:
989 for (size_t i
=0; i
<dataViewCtrlPtr
->GetColumnCount(); ++i
)
991 // constant definition for abbreviational purposes:
992 wxDataViewColumn
* const columnPtr
= dataViewCtrlPtr
->GetColumn(i
);
993 // variable definition:
996 wxCHECK_RET(this->GetColumnWidth(columnPtr
->GetPropertyID(),&columnWidth
) == noErr
,_("Column width could not be determined"));
997 columnPtr
->SetWidthVariable(columnWidth
);
999 // update sorting orders:
1000 DataBrowserPropertyID propertyID
; // variable definition
1002 if ((this->GetSortProperty(&propertyID
) == noErr
) && (propertyID
>= kMinPropertyID
))
1004 DataBrowserSortOrder sortOrder
;
1005 DataBrowserTableViewColumnIndex columnIndex
;
1007 if ((this->GetSortOrder(&sortOrder
) == noErr
) && (this->GetColumnIndex(propertyID
,&columnIndex
) == noErr
))
1009 // variable definition and initialization:
1010 wxDataViewColumn
* columnPtr
;
1011 columnPtr
= dataViewCtrlPtr
->GetColumn(columnIndex
);
1012 // check if the sort order has changed:
1013 if ( columnPtr
->IsSortOrderAscending() && (sortOrder
== kDataBrowserOrderDecreasing
) ||
1014 !(columnPtr
->IsSortOrderAscending()) && (sortOrder
== kDataBrowserOrderIncreasing
))
1016 columnPtr
->SetSortOrder(!(columnPtr
->IsSortOrderAscending()));
1017 // initialize wxWidget event:
1018 wxDataViewEvent
dataViewEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED
,dataViewCtrlPtr
->GetId()); // variable defintion
1020 dataViewEvent
.SetEventObject(dataViewCtrlPtr
);
1021 dataViewEvent
.SetColumn(columnIndex
);
1022 dataViewEvent
.SetDataViewColumn(columnPtr
);
1023 // finally send the equivalent wxWidget event:
1024 dataViewCtrlPtr
->GetEventHandler()->ProcessEvent(dataViewEvent
);
1031 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID, DataBrowserItemNotification, DataBrowserItemDataRef) */
1033 void wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID itemID
, DataBrowserPropertyID propertyID
, DataBrowserItemState state
, Rect
const* rectangle
, SInt16 bitDepth
, Boolean colorDevice
)
1035 DataBrowserTableViewColumnIndex columnIndex
;
1037 wxDataViewColumn
* dataViewColumnPtr
;
1039 wxDataViewCtrl
* dataViewCtrlPtr
;
1041 wxDataViewCustomRenderer
* dataViewCustomRendererPtr
;
1043 wxVariant dataToRender
;
1045 dataViewCtrlPtr
= dynamic_cast<wxDataViewCtrl
*>(this->GetWXPeer());
1046 wxCHECK_RET(dataViewCtrlPtr
!= NULL
, _("Pointer to data view control not set correctly."));
1047 wxCHECK_RET(dataViewCtrlPtr
->GetModel() != NULL
,_("Pointer to model not set correctly."));
1048 wxCHECK_RET(this->GetColumnIndex(propertyID
,&columnIndex
) == noErr
,_("Could not determine column index."));
1049 dataViewColumnPtr
= dataViewCtrlPtr
->GetColumnPtr(propertyID
);
1050 wxCHECK_RET(dataViewColumnPtr
!= NULL
,_("No column for the specified column index existing."));
1051 dataViewCustomRendererPtr
= dynamic_cast<wxDataViewCustomRenderer
*>(dataViewColumnPtr
->GetRenderer());
1052 wxCHECK_RET(dataViewCustomRendererPtr
!= NULL
,_("No renderer or invalid renderer type specified for custom data column."));
1053 dataViewCtrlPtr
->GetModel()->GetValue(dataToRender
,wxDataViewItem(reinterpret_cast<void*>(itemID
)),dataViewColumnPtr
->GetModelColumn());
1054 dataViewCustomRendererPtr
->SetValue(dataToRender
);
1056 wxDataViewItem
dataitem( reinterpret_cast<void*>(itemID
) );
1057 dataViewCtrlPtr
->GetModel()->GetValue(dataToRender
,dataitem
,dataViewColumnPtr
->GetModelColumn());
1058 dataViewCustomRendererPtr
->SetValue(dataToRender
);
1060 // try to determine the content's size (drawable part):
1062 HIShapeRef rgn
= NULL
;
1064 UInt16 headerHeight
;
1066 if ( HIViewCopyShape(m_controlRef
, kHIViewContentMetaPart
, &rgn
) == noErr
)
1069 HIShapeGetBounds(rgn
, &cgrect
);
1070 content
= (Rect
){ cgrect
.origin
.y
, cgrect
.origin
.x
, cgrect
.origin
.y
+cgrect
.size
.height
, cgrect
.origin
.x
+cgrect
.size
.width
};
1074 GetControlBounds(m_controlRef
, &content
);
1075 // space for the header
1076 this->GetHeaderButtonHeight(&headerHeight
);
1077 content
.top
+= headerHeight
;
1078 // extra space for the frame (todo: do not how to determine the space automatically from the control)
1082 content
.bottom
-= 3;
1083 // extra space for the scrollbars:
1084 content
.bottom
-= wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y
);
1085 content
.right
-= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X
);
1087 wxDC
*dc
= dataViewCustomRendererPtr
->GetDC();
1089 wxRect
cellrect( static_cast<int>(rectangle
->left
),
1090 static_cast<int>(rectangle
->top
),
1091 static_cast<int>(1+rectangle
->right
-rectangle
->left
),
1092 static_cast<int>(rectangle
->bottom
-rectangle
->top
) );
1094 bool is_active
= IsControlActive( this->m_controlRef
);
1095 if (state
== kDataBrowserItemIsSelected
)
1098 wxColour
col( wxMacCreateCGColorFromHITheme( (is_active
) ?
1099 kThemeBrushAlternatePrimaryHighlightColor
1100 : kThemeBrushSecondaryHighlightColor
) );
1102 wxRect rect
= cellrect
;
1104 GetDataBrowserItemPartBounds( this->m_controlRef
, itemID
, propertyID
,
1105 kDataBrowserPropertyEnclosingPart
, &itemrect
);
1106 rect
.x
= itemrect
.left
;
1107 rect
.width
= itemrect
.right
-itemrect
.left
+1;
1109 wxBrush
selBrush( col
);
1110 wxPen
oldpen( dc
->GetPen() );
1111 wxBrush
oldbrush( dc
->GetBrush() );
1112 dc
->SetPen( *wxTRANSPARENT_PEN
);
1113 dc
->SetBrush( selBrush
);
1114 dc
->DrawRectangle(rect
);
1115 dc
->SetBrush( oldbrush
);
1116 dc
->SetPen( oldpen
);
1119 wxDataViewModel
*model
= dataViewCtrlPtr
->GetModel();
1120 if ((columnIndex
== 0) || !model
->IsContainer(dataitem
) || model
->HasContainerColumns(dataitem
))
1122 // make sure that 'Render' can draw only in the allowed area:
1123 dc
->SetClippingRegion(content
.left
,content
.top
,content
.right
-content
.left
+1,content
.bottom
-content
.top
+1);
1124 (void) (dataViewCustomRendererPtr
->Render( cellrect
, dc
,
1125 ((state
== kDataBrowserItemIsSelected
) ? wxDATAVIEW_CELL_SELECTED
: 0)));
1126 dc
->DestroyClippingRegion(); // probably not necessary
1129 dataViewCustomRendererPtr
->SetDC(NULL
);
1130 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemState, Rect const*, SInt16, Boolean) */
1132 Boolean
wxMacDataViewDataBrowserListViewControl::DataBrowserEditItemProc(DataBrowserItemID itemID
, DataBrowserPropertyID propertyID
, CFStringRef theString
, Rect
* maxEditTextRect
, Boolean
* shrinkToFit
)
1135 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserEditItemProc(DataBrowserItemID, DataBrowserPropertyID, CFStringRef, Rect*, Boolean*) */
1137 Boolean
wxMacDataViewDataBrowserListViewControl::DataBrowserHitTestProc(DataBrowserItemID
WXUNUSED(itemID
), DataBrowserPropertyID
WXUNUSED(property
), Rect
const* WXUNUSED(theRect
), Rect
const* WXUNUSED(mouseRect
))
1140 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserHitTestProc(DataBrowserItemID, DataBrowserPropertyID, Rect const*, Rect const*) */
1142 DataBrowserTrackingResult
wxMacDataViewDataBrowserListViewControl::DataBrowserTrackingProc(DataBrowserItemID itemID
, DataBrowserPropertyID propertyID
, Rect
const* theRect
, Point
WXUNUSED(startPt
), EventModifiers
WXUNUSED(modifiers
))
1144 wxDataViewColumn
* dataViewColumnPtr
;
1146 wxDataViewCtrl
* dataViewCtrlPtr
;
1148 wxDataViewCustomRenderer
* dataViewCustomRendererPtr
;
1150 wxDataViewItem dataViewCustomRendererItem
;
1153 dataViewCtrlPtr
= dynamic_cast<wxDataViewCtrl
*>(this->GetWXPeer());
1154 wxCHECK_MSG(dataViewCtrlPtr
!= NULL
, false,_("Pointer to data view control not set correctly."));
1155 wxCHECK_MSG(dataViewCtrlPtr
->GetModel() != NULL
,false,_("Pointer to model not set correctly."));
1156 dataViewCustomRendererItem
= reinterpret_cast<void*>(itemID
);
1157 wxCHECK_MSG(dataViewCustomRendererItem
.IsOk(),kDataBrowserNothingHit
,_("Invalid data view item"));
1158 dataViewColumnPtr
= dataViewCtrlPtr
->GetColumnPtr(propertyID
);
1159 wxCHECK_MSG(dataViewColumnPtr
!= NULL
,kDataBrowserNothingHit
,_("No column existing."));
1160 dataViewCustomRendererPtr
= dynamic_cast<wxDataViewCustomRenderer
*>(dataViewColumnPtr
->GetRenderer());
1161 wxCHECK_MSG(dataViewCustomRendererPtr
!= NULL
,kDataBrowserNothingHit
,_("No renderer or invalid renderer type specified for custom data column."));
1162 // 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):
1163 if (dataViewCtrlPtr
->GetCustomRendererItem() == dataViewCustomRendererItem
)
1164 return kDataBrowserContentHit
;
1165 // an(other) item is going to be edited and therefore the current editing - if existing - has to be finished:
1166 if (dataViewCtrlPtr
->GetCustomRendererPtr() != NULL
)
1168 dataViewCtrlPtr
->GetCustomRendererPtr()->FinishEditing();
1169 dataViewCtrlPtr
->SetCustomRendererItem(wxDataViewItem());
1170 dataViewCtrlPtr
->SetCustomRendererPtr (NULL
);
1172 // check if renderer has got a valid editor control for editing; if this is the case start editing of the new item:
1173 if (dataViewCustomRendererPtr
->HasEditorCtrl())
1175 // variable definition:
1178 ::wxMacNativeToRect(theRect
,&wxRectangle
);
1179 dataViewCustomRendererPtr
->StartEditing(dataViewCustomRendererItem
,wxRectangle
);
1180 dataViewCtrlPtr
->SetCustomRendererItem(dataViewCustomRendererItem
);
1181 dataViewCtrlPtr
->SetCustomRendererPtr (dataViewCustomRendererPtr
);
1183 return kDataBrowserContentHit
;
1184 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserTrackingProc(DataBrowserItemID, DataBrowserPropertyID, Rect const*, Point, EventModifiers) */
1186 Boolean
wxMacDataViewDataBrowserListViewControl::DataBrowserAcceptDragProc(DragReference dragRef
, DataBrowserItemID itemID
)
1188 UInt16 noOfDraggedItems
;
1190 wxDataViewCtrl
* dataViewCtrlPtr
;
1193 dataViewCtrlPtr
= dynamic_cast<wxDataViewCtrl
*>(this->GetWXPeer());
1194 wxCHECK_MSG(dataViewCtrlPtr
!= NULL
, false,_("Pointer to data view control not set correctly."));
1195 wxCHECK_MSG(dataViewCtrlPtr
->GetModel() != NULL
,false,_("Pointer to model not set correctly."));
1197 // send a drag possible event for each available item and proceed with it unless the event is vetoed:
1198 ::CountDragItems(dragRef
,&noOfDraggedItems
);
1199 for (UInt16 indexDraggedItem
=1; indexDraggedItem
<=noOfDraggedItems
; ++indexDraggedItem
)
1201 // collect native information:
1202 ItemReference itemRef
;
1203 wxDataObjectComposite
* dataObjects
;
1204 wxMemoryBuffer buffer
;
1206 ::GetDragItemReferenceNumber(dragRef
,indexDraggedItem
,&itemRef
); // the index begins with 1!
1207 dataObjects
= this->GetDnDDataObjects(dragRef
,itemRef
);
1208 // create wxWidget's event:
1209 wxDataViewEvent
dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE
,dataViewCtrlPtr
->GetId());
1211 dataViewEvent
.SetEventObject(dataViewCtrlPtr
);
1212 dataViewEvent
.SetItem(reinterpret_cast<void*>(itemID
)); // this is the item that receives the event
1213 // (can be an invalid item ID, this is especially useful if the dataview does not contain any items)
1214 dataViewEvent
.SetModel(dataViewCtrlPtr
->GetModel());
1215 dataViewEvent
.SetDataObject(dataObjects
);
1216 dataViewEvent
.SetDataFormat(this->GetDnDDataFormat(dataObjects
));
1217 if (dataViewEvent
.GetDataFormat().GetType() != wxDF_INVALID
)
1219 dataViewEvent
.SetDataSize(dataObjects
->GetDataSize(dataViewEvent
.GetDataFormat().GetType()));
1220 dataObjects
->GetDataHere(dataViewEvent
.GetDataFormat().GetType(),buffer
.GetWriteBuf(dataViewEvent
.GetDataSize()));
1221 buffer
.UngetWriteBuf(dataViewEvent
.GetDataSize());
1222 dataViewEvent
.SetDataBuffer(buffer
.GetData());
1226 if (!(dataViewCtrlPtr
->HandleWindowEvent(dataViewEvent
) && dataViewEvent
.IsAllowed()))
1230 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserAcceptDragProc(DragReference, DataBrowserItemID) */
1232 Boolean
wxMacDataViewDataBrowserListViewControl::DataBrowserAddDragItemProc(DragReference dragRef
, DataBrowserItemID itemID
, ItemReference
* itemRef
)
1234 wxDataViewCtrl
* dataViewCtrlPtr
;
1236 wxDataViewItem dataViewItem
;
1239 dataViewCtrlPtr
= dynamic_cast<wxDataViewCtrl
*>(this->GetWXPeer());
1240 wxCHECK_MSG(dataViewCtrlPtr
!= NULL
, false,_("Pointer to data view control not set correctly."));
1241 wxCHECK_MSG(dataViewCtrlPtr
->GetModel() != NULL
,false,_("Pointer to model not set correctly."));
1242 dataViewItem
= reinterpret_cast<void*>(itemID
);
1243 wxCHECK_MSG(dataViewItem
.IsOk(),false,_("Invalid data view item"));
1245 // send a begin drag event and proceed with dragging unless the event is vetoed:
1246 wxDataViewEvent
dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG
,dataViewCtrlPtr
->GetId());
1248 dataViewEvent
.SetEventObject(dataViewCtrlPtr
);
1249 dataViewEvent
.SetItem(dataViewItem
);
1250 dataViewEvent
.SetModel(dataViewCtrlPtr
->GetModel());
1251 // 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
1252 // the object a wxDataObjectComposite object is used;
1253 // currently, the composite object only contains a TAB concatenated string of all data:
1254 wxDataObjectComposite
* dataObject(new wxDataObjectComposite());
1255 wxString dataString
; // contains the TAB concatenated data
1257 for (size_t i
=0; i
<dataViewCtrlPtr
->GetColumnCount(); i
++)
1259 // variable definition:
1260 wxVariant dataValue
;
1262 dataViewCtrlPtr
->GetModel()->GetValue(dataValue
,dataViewItem
,dataViewCtrlPtr
->GetColumn(i
)->GetModelColumn());
1264 dataString
<< wxT('\t');
1265 dataString
<< dataValue
.MakeString();
1267 dataObject
->Add(new wxTextDataObject(dataString
));
1268 dataViewEvent
.SetDataObject(dataObject
);
1269 // check if event has not been vetoed:
1270 if (dataViewCtrlPtr
->HandleWindowEvent(dataViewEvent
) && dataViewEvent
.IsAllowed())
1272 // for the internal drag & drop functions create two flavors:
1273 // - the data browser's item id;
1274 // - the data contained the dataview event object (if available).
1275 // Definition: a flavor is the type dependent representation of identical data.
1276 // Example: a number can be represented by its value and by its value converted to a string. In this case the flavor
1277 // of the number's internal representation is typeSInt32 while its string representation has got the flavor 'TEXT'.
1278 // Item id is one of the flavors:
1279 wxCHECK_MSG(::AddDragItemFlavor(dragRef
,*itemRef
,typeUInt32
,&itemID
,sizeof(itemID
),0) == noErr
,false,_("Unable to handle native drag&drop data"));
1280 // if the dataview event object contains data it is used for additional flavors; all natively known flavors are supported:
1281 if (dataViewEvent
.GetDataObject() != NULL
)
1283 // constant definition for abbreviational purposes:
1284 size_t const noOfFormats
= dataViewEvent
.GetDataObject()->GetFormatCount();
1286 if (noOfFormats
> 0)
1288 // variable definition:
1289 wxDataFormat
* dataFormats
;
1291 dataFormats
= new wxDataFormat
[noOfFormats
];
1292 dataViewEvent
.GetDataObject()->GetAllFormats(dataFormats
,wxDataObject::Get
);
1293 for (size_t i
=0; i
<noOfFormats
; ++i
)
1294 switch (dataFormats
[i
].GetType())
1297 wxFAIL_MSG(_("Data object has invalid data format"));
1301 // constant definition for abbreviational purposes:
1302 size_t const dataSize
= dataViewEvent
.GetDataObject()->GetDataSize(wxDF_TEXT
);
1303 // variable definition and initialization:
1304 wxMemoryBuffer
dataObject(dataSize
);
1306 dataViewEvent
.GetDataObject()->GetDataHere(wxDF_TEXT
,dataObject
.GetWriteBuf(dataSize
));
1307 dataObject
.UngetWriteBuf(dataSize
);
1308 if (::AddDragItemFlavor(dragRef
,*itemRef
,'TEXT',dataObject
.GetData(),dataSize
,0) != noErr
)
1309 wxFAIL_MSG(_("Adding flavor TEXT failed"));
1312 case wxDF_UNICODETEXT
:
1314 // constant definition for abbreviational purposes:
1315 size_t const dataSize
= dataViewEvent
.GetDataObject()->GetDataSize(wxDF_TEXT
);
1316 // as there is no direct access to the data copy it to a memory buffer:
1317 wxMemoryBuffer
dataObject(dataSize
);
1319 dataViewEvent
.GetDataObject()->GetDataHere(wxDF_TEXT
,dataObject
.GetWriteBuf(dataSize
));
1320 dataObject
.UngetWriteBuf(dataSize
);
1321 // if the data is stored in unicode format the internal representation is utf-8 (not mentioned in the documentation but in the source code);
1322 // DnD uses fixed utf-16 representation -> use the OSX functions for a conversion:
1323 CFDataRef
osxData (::CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
,reinterpret_cast<UInt8
*>(dataObject
.GetData()),dataSize
,kCFAllocatorNull
));
1324 CFStringRef
osxString(::CFStringCreateFromExternalRepresentation(kCFAllocatorDefault
,osxData
,kCFStringEncodingUTF8
));
1326 // the osxString contains now the data and therefore the previously occupied memory can be released and re-used:
1327 ::CFRelease(osxData
);
1328 osxData
= ::CFStringCreateExternalRepresentation(kCFAllocatorDefault
,osxString
,kCFStringEncodingUTF16
,32);
1329 if (::AddDragItemFlavor(dragRef
,*itemRef
,'utxt',::CFDataGetBytePtr(osxData
),::CFDataGetLength(osxData
),0) != noErr
)
1330 wxFAIL_MSG(_("Adding flavor utxt failed"));
1332 ::CFRelease(osxData
);
1333 ::CFRelease(osxString
);
1347 case wxDF_ENHMETAFILE
:
1352 break; // not (yet) supported data formats
1354 wxFAIL_MSG(_("Unknown data format"));
1356 delete[] dataFormats
;
1363 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserAddDragItemProc(DragReference, DataBrowserItemID, ItemReference*) */
1365 Boolean
wxMacDataViewDataBrowserListViewControl::DataBrowserReceiveDragProc(DragReference dragRef
, DataBrowserItemID itemID
)
1367 UInt16 noOfDraggedItems
;
1369 wxDataViewCtrl
* dataViewCtrlPtr
;
1372 dataViewCtrlPtr
= dynamic_cast<wxDataViewCtrl
*>(this->GetWXPeer());
1373 wxCHECK_MSG(dataViewCtrlPtr
!= NULL
, false,_("Pointer to data view control not set correctly."));
1374 wxCHECK_MSG(dataViewCtrlPtr
->GetModel() != NULL
,false,_("Pointer to model not set correctly."));
1376 // send a drag possible event for each available and item und proceed with it unless the event is vetoed:
1377 ::CountDragItems(dragRef
,&noOfDraggedItems
);
1378 for (UInt16 indexDraggedItem
=1; indexDraggedItem
<=noOfDraggedItems
; ++indexDraggedItem
)
1380 // collect native information:
1381 ItemReference itemRef
;
1382 wxDataObjectComposite
* dataObjects
;
1383 wxMemoryBuffer buffer
;
1385 ::GetDragItemReferenceNumber(dragRef
,indexDraggedItem
,&itemRef
); // the index begins with 1!
1386 dataObjects
= this->GetDnDDataObjects(dragRef
,itemRef
);
1387 // create wxWidget's event:
1388 wxDataViewEvent
dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_DROP
,dataViewCtrlPtr
->GetId());
1390 dataViewEvent
.SetEventObject(dataViewCtrlPtr
);
1391 dataViewEvent
.SetItem(reinterpret_cast<void*>(itemID
)); // this is the item that receives the event
1392 // (can be an invalid item ID, this is especially useful if the dataview does not contain any items)
1393 dataViewEvent
.SetModel(dataViewCtrlPtr
->GetModel());
1394 dataViewEvent
.SetDataObject(dataObjects
);
1395 dataViewEvent
.SetDataFormat(this->GetDnDDataFormat(dataObjects
));
1396 if (dataViewEvent
.GetDataFormat().GetType() != wxDF_INVALID
)
1398 dataViewEvent
.SetDataSize(dataObjects
->GetDataSize(dataViewEvent
.GetDataFormat().GetType()));
1399 dataObjects
->GetDataHere(dataViewEvent
.GetDataFormat().GetType(),buffer
.GetWriteBuf(dataViewEvent
.GetDataSize()));
1400 buffer
.UngetWriteBuf(dataViewEvent
.GetDataSize());
1401 dataViewEvent
.SetDataBuffer(buffer
.GetData());
1405 if (!(dataViewCtrlPtr
->HandleWindowEvent(dataViewEvent
) && dataViewEvent
.IsAllowed()))
1409 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserReceiveDragProc(DragReference, DataBrowserItemID) */
1412 // drag & drop helper methods
1414 wxDataFormat
wxMacDataViewDataBrowserListViewControl::GetDnDDataFormat(wxDataObjectComposite
* dataObjects
)
1416 wxDataFormat resultFormat
;
1419 if (dataObjects
!= NULL
)
1421 bool compatible(true);
1423 size_t const noOfFormats
= dataObjects
->GetFormatCount();
1426 wxDataFormat
* formats
;
1428 // get all formats and check afterwards if the formats are compatible; if they are compatible the preferred format is returned otherwise
1429 // wxDF_INVALID is returned;
1430 // currently compatible types (ordered by priority are):
1431 // - wxDF_UNICODETEXT - wxDF_TEXT
1432 formats
= new wxDataFormat
[noOfFormats
];
1433 dataObjects
->GetAllFormats(formats
);
1435 while ((indexFormat
< noOfFormats
) && compatible
)
1437 switch (resultFormat
.GetType())
1440 resultFormat
.SetType(formats
[indexFormat
].GetType()); // first format (should only be reached if indexFormat == 0
1443 if (formats
[indexFormat
].GetType() == wxDF_UNICODETEXT
)
1444 resultFormat
.SetType(wxDF_UNICODETEXT
);
1445 else // incompatible
1447 resultFormat
.SetType(wxDF_INVALID
);
1451 case wxDF_UNICODETEXT
:
1452 if (formats
[indexFormat
].GetType() != wxDF_TEXT
)
1454 resultFormat
.SetType(wxDF_INVALID
);
1459 resultFormat
.SetType(wxDF_INVALID
); // not (yet) supported format
1467 return resultFormat
;
1468 } /* wxMacDataViewDataBrowserListViewControl::GetDnDDataFormat(wxDataObjectComposite*) */
1470 wxDataObjectComposite
* wxMacDataViewDataBrowserListViewControl::GetDnDDataObjects(DragReference dragRef
, ItemReference itemRef
) const
1474 wxDataObjectComposite
* dataObject
;
1477 ::CountDragItemFlavors(dragRef
,itemRef
,&noOfFlavors
);
1478 if (noOfFlavors
> 0)
1480 // 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:
1481 wxTextDataObject
* textDataObject(NULL
);
1483 dataObject
= new wxDataObjectComposite();
1484 for (UInt16 indexFlavor
=1; indexFlavor
<=noOfFlavors
; ++indexFlavor
)
1486 // variable definition:
1487 FlavorType flavorDataObject
;
1489 if (::GetFlavorType(dragRef
,itemRef
,indexFlavor
,&flavorDataObject
) == noErr
) // GetFlavorType uses a 1 based index!
1490 switch (flavorDataObject
)
1493 if (textDataObject
== NULL
) // otherwise a 'utxt' flavor has already been found that gets priority compared to the 'TEXT' flavor
1495 // variable definitions:
1496 Size nativeDataSize
;
1497 wxMemoryBuffer nativeData
;
1499 if ((::GetFlavorDataSize(dragRef
,itemRef
,'TEXT',&nativeDataSize
) == noErr
) &&
1500 (::GetFlavorData(dragRef
,itemRef
,'TEXT',nativeData
.GetWriteBuf(nativeDataSize
),&nativeDataSize
,0) == noErr
))
1502 nativeData
.UngetWriteBuf(nativeDataSize
);
1503 textDataObject
= new wxTextDataObject();
1504 if (textDataObject
->SetData(nativeData
.GetDataLen(),nativeData
.GetData()))
1505 dataObject
->Add(textDataObject
);
1508 delete textDataObject
;
1509 textDataObject
= NULL
;
1516 // variable definition:
1517 Size nativeDataSize
;
1519 if (::GetFlavorDataSize(dragRef
,itemRef
,'utxt',&nativeDataSize
) == noErr
)
1521 CFMutableDataRef draggedData
;
1523 draggedData
= ::CFDataCreateMutable(kCFAllocatorDefault
,nativeDataSize
);
1524 ::CFDataSetLength(draggedData
,nativeDataSize
);
1525 if (::GetFlavorData(dragRef
,itemRef
,'utxt',::CFDataGetMutableBytePtr(draggedData
),&nativeDataSize
,0) == noErr
)
1527 // convert internally used UTF-16 representation to a UTF-8 representation:
1529 CFStringRef osxString
;
1531 osxString
= ::CFStringCreateFromExternalRepresentation(kCFAllocatorDefault
,draggedData
,kCFStringEncodingUTF16
); // BOM character is handled by this function automatically
1532 osxData
= ::CFStringCreateExternalRepresentation(kCFAllocatorDefault
,osxString
,kCFStringEncodingUTF8
,32);
1533 if (textDataObject
== NULL
)
1535 textDataObject
= new wxTextDataObject();
1536 if (textDataObject
->SetData(::CFDataGetLength(osxData
),::CFDataGetBytePtr(osxData
)))
1537 dataObject
->Add(textDataObject
);
1540 delete textDataObject
;
1541 textDataObject
= NULL
;
1544 else // overwrite data because the 'utxt' flavor has priority over the 'TEXT' flavor
1545 (void) textDataObject
->SetData(::CFDataGetLength(osxData
),::CFDataGetBytePtr(osxData
));
1547 ::CFRelease(osxData
);
1548 ::CFRelease(osxString
);
1551 ::CFRelease(draggedData
);
1561 } /* wxMacDataViewDataBrowserListViewControl::GetDnDDataObjects(DragReference, ItemReference) const */
1563 #endif // wxUSE_GENERICDATAVIEWCTRL
1564 #endif // wxUSE_DATAVIEWCTRL