]> git.saurik.com Git - wxWidgets.git/blame - src/osx/carbon/databrow.cpp
guaranteeing autorelease pools for overridden OnRun on OSX
[wxWidgets.git] / src / osx / carbon / databrow.cpp
CommitLineData
489468fe 1/////////////////////////////////////////////////////////////////////////////
524c47aa 2// Name: src/osx/carbon/databrow.cpp
489468fe
SC
3// Purpose: Classes and functions for the Carbon data browser
4// Author:
5// Modified by:
6// Created: 2007-05-18
7// RCS-ID: $Id$
8// Copyright: (c)
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
14#if wxUSE_DATAVIEWCTRL
15#ifndef wxUSE_GENERICDATAVIEWCTRL
16
17#ifndef WX_PRECOMP
18 #include "wx/app.h"
19 #include "wx/toplevel.h"
20 #include "wx/font.h"
21 #include "wx/settings.h"
22 #include "wx/utils.h"
23#endif
24
25#include "wx/dataview.h"
1f0c8f31
SC
26#include "wx/osx/carbon/databrow.h"
27#include "wx/osx/private.h"
28#include "wx/osx/uma.h"
489468fe
SC
29
30#include <limits>
31
32// ============================================================================
33// Variables used globally in databrow.cpp
34// ============================================================================
35DataBrowserGetContextualMenuUPP gDataBrowserTableViewGetContextualMenuUPP = NULL;
36DataBrowserItemCompareUPP gDataBrowserTableViewItemCompareUPP = NULL;
37DataBrowserItemDataUPP gDataBrowserTableViewItemDataUPP = NULL;
38DataBrowserItemNotificationUPP gDataBrowserTableViewItemNotificationUPP = NULL;
39
4a3d495c
RR
40DataBrowserAcceptDragUPP gDataBrowserTableViewAcceptDragUPP = NULL;
41DataBrowserAddDragItemUPP gDataBrowserTableViewAddDragItemUPP = NULL;
42DataBrowserReceiveDragUPP gDataBrowserTableViewReceiveDragUPP = NULL;
43
489468fe
SC
44DataBrowserDrawItemUPP gDataBrowserTableViewDrawItemUPP = NULL;
45DataBrowserEditItemUPP gDataBrowserTableViewEditItemUPP = NULL;
46DataBrowserHitTestUPP gDataBrowserTableViewHitTestUPP = NULL;
47DataBrowserTrackingUPP gDataBrowserTableViewTrackingUPP = NULL;
48
49// ============================================================================
50// wxMacDataBrowserTableViewControl
51// ============================================================================
52
53pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserCompareProc(ControlRef browser, DataBrowserItemID itemOneID, DataBrowserItemID itemTwoID, DataBrowserPropertyID sortProperty)
54{
55 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
56
57
58 if (ControlPtr != NULL)
59 return ControlPtr->DataBrowserCompareProc(itemOneID,itemTwoID,sortProperty);
60 else
61 return errDataBrowserPropertyNotSupported;
62} /* wxMacDataBrowserTableViewControl::DataBrowserCompareProc(ControlRef, DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID) */
63
64pascal void wxMacDataBrowserTableViewControl::DataBrowserGetContextualMenuProc(ControlRef browser, MenuRef* menu, UInt32* helpType, CFStringRef* helpItemString, AEDesc* selection)
65{
66 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
67
68
69 if (ControlPtr != NULL)
70 ControlPtr->DataBrowserGetContextualMenuProc(menu,helpType,helpItemString,selection);
71} /* wxMacDataBrowserTableViewControl::DataBrowserGetContextualMenuProc(ControlRef, MenuRef*, UInt32*, CFStringRef*, AEDesc*) */
72
73pascal OSStatus wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemDataRef itemData, Boolean getValue)
74{
75 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
76
77
78 if (ControlPtr != NULL)
79 return ControlPtr->DataBrowserGetSetItemDataProc(itemID,propertyID,itemData,getValue);
80 else
81 return errDataBrowserPropertyNotSupported;
82} /* wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemDataRef, Boolean) */
83
84pascal void wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserItemNotification message, DataBrowserItemDataRef itemData)
85{
86 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
87
88
89 if (ControlPtr != NULL)
90 ControlPtr->DataBrowserItemNotificationProc(itemID,message,itemData);
91} /* wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc(ControlRef, DataBrowserItemID, DataBrowserItemNotification, DataBrowserItemDataRef) */
92
93pascal void wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemState state, Rect const* rectangle, SInt16 bitDepth, Boolean colorDevice)
94{
95 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
96
97
98 if (ControlPtr != NULL)
99 ControlPtr->DataBrowserDrawItemProc(itemID,propertyID,state,rectangle,bitDepth,colorDevice);
100} /* wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemState, Rect const*, SInt16, Boolean) */
101
102pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserEditItemProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, CFStringRef theString, Rect* maxEditTextRect, Boolean* shrinkToFit)
103{
104 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
105
106
107 return ((ControlPtr != NULL) && ControlPtr->DataBrowserEditItemProc(itemID,propertyID,theString,maxEditTextRect,shrinkToFit));
108} /* wxMacDataBrowserTableViewControl::DataBrowserEditItemProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, CFStringRef, Rect*, Boolean*) */
109
110pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserHitTestProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, Rect const* theRect, Rect const* mouseRect)
111{
112 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
113
114
115 return ((ControlPtr != NULL) && ControlPtr->DataBrowserHitTestProc(itemID,propertyID,theRect,mouseRect));
116} /* wxMacDataBrowserTableViewControl::DataBrowserHitTestProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, Rect const*, Rect const*) */
117
118pascal DataBrowserTrackingResult wxMacDataBrowserTableViewControl::DataBrowserTrackingProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, Rect const* theRect, Point startPt, EventModifiers modifiers)
119{
120 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
121
122
123 if (ControlPtr != NULL)
124 return ControlPtr->DataBrowserTrackingProc(itemID,propertyID,theRect,startPt,modifiers);
125 else
126 return kDataBrowserNothingHit;
127} /* wxMacDataBrowserTableViewControl::DataBrowserTrackingProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, Rect const*, Point, EventModifiers) */
128
4a3d495c
RR
129pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserAcceptDragProc(ControlRef browser, DragReference dragRef, DataBrowserItemID itemID)
130{
131 wxMacDataBrowserTableViewControl* controlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
132
133
134 return ((controlPtr != NULL) && controlPtr->DataBrowserAcceptDragProc(dragRef,itemID));
135} /* wxMacDataBrowserTableViewControl::DataBrowserAcceptDragProc(ControlRef, DragReference, DataBrowserItemID) */
136
137pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserAddDragItemProc(ControlRef browser, DragReference dragRef, DataBrowserItemID itemID, ItemReference* itemRef)
138{
139 wxMacDataBrowserTableViewControl* controlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
140
141
142 return ((controlPtr != NULL) && controlPtr->DataBrowserAddDragItemProc(dragRef,itemID,itemRef));
143} /* wxMacDataBrowserTableViewControl::DataBrowserAddDragItemProc(ControlRef, DragReference, DataBrowserItemID, ItemReference*) */
144
145pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserReceiveDragProc(ControlRef browser, DragReference dragRef, DataBrowserItemID itemID)
146{
147 wxMacDataBrowserTableViewControl* controlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
148
149
150 return ((controlPtr != NULL) && controlPtr->DataBrowserReceiveDragProc(dragRef,itemID));
151} /* wxMacDataBrowserTableViewControl::DataBrowserReceiveDragProc(ControlRef, DragReference, DataBrowserItemID) */
152
489468fe
SC
153wxMacDataBrowserTableViewControl::wxMacDataBrowserTableViewControl(wxWindow* peer, wxPoint const& pos, wxSize const& size, long style)
154 :wxMacControl(peer)
155{
156 Rect bounds = wxMacGetBoundsForControl(peer,pos,size);
157 OSStatus err = ::CreateDataBrowserControl(MAC_WXHWND(peer->MacGetTopLevelWindowRef()),&bounds,kDataBrowserListView,&(this->m_controlRef));
158
159
160 SetReferenceInNativeControl();
161 verify_noerr(err);
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)
167 {
168 gDataBrowserTableViewItemNotificationUPP =
169#if TARGET_API_MAC_OSX
170 (DataBrowserItemNotificationUPP) NewDataBrowserItemNotificationWithItemUPP(wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc);
171#else
172 NewDataBrowserItemNotificationUPP(wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc);
173#endif
174 }
4a3d495c
RR
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);
179
489468fe
SC
180 DataBrowserCallbacks callbacks; // variable definition
181
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;
4a3d495c
RR
187 callbacks.u.v1.acceptDragCallback = gDataBrowserTableViewAcceptDragUPP;
188 callbacks.u.v1.addDragItemCallback = gDataBrowserTableViewAddDragItemUPP;
189 callbacks.u.v1.receiveDragCallback = gDataBrowserTableViewReceiveDragUPP;
489468fe
SC
190 this->SetCallbacks(&callbacks);
191
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);
197
198 DataBrowserCustomCallbacks customCallbacks; // variable definition
199
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);
206
207 // style setting:
208 this->EnableCellSizeModification( ((style & wxDV_VARIABLE_LINE_HEIGHT) != 0), true );
209
210 DataBrowserSelectionFlags flags; // variable definition
211
212 if (this->GetSelectionFlags(&flags) == noErr) // get default settings
213 {
214 if ((style & wxDV_MULTIPLE) != 0)
215 flags &= ~kDataBrowserSelectOnlyOne;
216 else
217 flags |= kDataBrowserSelectOnlyOne;
218 (void) this->SetSelectionFlags(flags);
219 } /* if */
220
221 OptionBits attributes; // variable definition
222
223 if (this->GetAttributes(&attributes) == noErr) // get default settings
224 {
225 if ((style & wxDV_VERT_RULES) != 0)
226 attributes |= kDataBrowserAttributeListViewDrawColumnDividers;
227 else
228 attributes &= ~kDataBrowserAttributeListViewDrawColumnDividers;
229 if ((style & wxDV_ROW_LINES) != 0)
230 attributes |= kDataBrowserAttributeListViewAlternatingRowColors;
231 else
232 attributes &= ~kDataBrowserAttributeListViewAlternatingRowColors;
233 (void) this->SetAttributes(attributes);
234 } /* if */
235
236 if ((style & wxDV_NO_HEADER) != 0)
237 this->SetHeaderButtonHeight(0);
238} /* wxMacDataBrowserTableViewControl::wxMacDataBrowserTableViewControl(wxWindow*, wxPoint const&, wxSize const&, long) */
239
240//
241// callback handling
242//
243OSStatus wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks const* callbacks)
244{
245 return ::SetDataBrowserCallbacks(this->m_controlRef,callbacks);
246} /* wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks const*) */
247
248OSStatus wxMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks const* customCallbacks)
249{
250 return ::SetDataBrowserCustomCallbacks(this->m_controlRef,customCallbacks);
251} /* xMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks const*) */
252
253//
254// header handling
255//
256OSStatus wxMacDataBrowserTableViewControl::GetHeaderDesc(DataBrowserPropertyID propertyID, DataBrowserListViewHeaderDesc* desc) const
257{
258 desc->version = kDataBrowserListViewLatestHeaderDesc; // if this statement is missing the next call will fail (NOT DOCUMENTED!!)
259 return ::GetDataBrowserListViewHeaderDesc(this->m_controlRef,propertyID,desc);
260}
261
262OSStatus wxMacDataBrowserTableViewControl::SetHeaderDesc(DataBrowserPropertyID propertyID, DataBrowserListViewHeaderDesc* desc)
263{
264 return ::SetDataBrowserListViewHeaderDesc(this->m_controlRef,propertyID,desc);
265}
266
267//
268// layout handling
269//
270OSStatus wxMacDataBrowserTableViewControl::AutoSizeColumns()
271{
272 return AutoSizeDataBrowserListViewColumns(this->m_controlRef);
273}
274
275OSStatus wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool enableHeight, bool enableWidth)
276{
277 return ::SetDataBrowserTableViewGeometry(this->GetControlRef(),enableWidth,enableHeight);
278} /* wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool, bool) */
279
280OSStatus wxMacDataBrowserTableViewControl::GetAttributes(OptionBits* attributes)
281{
282 return ::DataBrowserGetAttributes(this->GetControlRef(),attributes);
283} /* wxMacDataBrowserTableViewControl::GetAttributes(OptionBits*) */
284
285OSStatus wxMacDataBrowserTableViewControl::GetColumnWidth(DataBrowserPropertyID propertyID, UInt16* width) const
286{
287 return ::GetDataBrowserTableViewNamedColumnWidth(this->m_controlRef,propertyID,width);
288}
289
290OSStatus wxMacDataBrowserTableViewControl::GetDefaultColumnWidth( UInt16 *width ) const
291{
292 return GetDataBrowserTableViewColumnWidth(this->m_controlRef, width );
293}
294
295OSStatus wxMacDataBrowserTableViewControl::GetDefaultRowHeight(UInt16* height) const
296{
297 return ::GetDataBrowserTableViewRowHeight(this->m_controlRef,height);
298}
299
300OSStatus wxMacDataBrowserTableViewControl::GetHeaderButtonHeight(UInt16 *height)
301{
302 return ::GetDataBrowserListViewHeaderBtnHeight(this->m_controlRef,height);
303}
304
305OSStatus wxMacDataBrowserTableViewControl::GetPartBounds(DataBrowserItemID item, DataBrowserPropertyID propertyID, DataBrowserPropertyPart part, Rect* bounds)
306{
307 return ::GetDataBrowserItemPartBounds(this->m_controlRef,item,propertyID,part,bounds);
308} /* wxMacDataBrowserTableViewControl::GetPartBounds(DataBrowserItemID, DataBrowswerPropertyID, DataBrowserPropertyPart, Rect*) */
309
310OSStatus wxMacDataBrowserTableViewControl::GetRowHeight(DataBrowserItemID item, UInt16* height) const
311{
312 return ::GetDataBrowserTableViewItemRowHeight(this->m_controlRef,item,height);
313} /* wxMacDataBrowserTableViewControl::GetRowHeight(DataBrowserItemID, UInt16*) const */
314
315OSStatus wxMacDataBrowserTableViewControl::GetScrollPosition( UInt32 *top , UInt32 *left ) const
316{
317 return GetDataBrowserScrollPosition(this->m_controlRef, top , left );
318}
319
320OSStatus wxMacDataBrowserTableViewControl::SetAttributes(OptionBits attributes)
321{
322 return ::DataBrowserChangeAttributes(this->GetControlRef(),attributes,~attributes);
323} /* wxMacDataBrowserTableViewControl::SetAttributes(OptionBits) */
324
325OSStatus wxMacDataBrowserTableViewControl::SetColumnWidth(DataBrowserPropertyID propertyID, UInt16 width)
326{
327 return ::SetDataBrowserTableViewNamedColumnWidth(this->m_controlRef,propertyID,width);
328}
329
330OSStatus wxMacDataBrowserTableViewControl::SetDefaultColumnWidth(UInt16 width)
331{
332 return ::SetDataBrowserTableViewColumnWidth(this->m_controlRef,width);
333}
334
335OSStatus wxMacDataBrowserTableViewControl::SetDefaultRowHeight(UInt16 height)
336{
337 return ::SetDataBrowserTableViewRowHeight(this->m_controlRef,height);
338}
339
340OSStatus wxMacDataBrowserTableViewControl::SetHasScrollBars(bool horiz, bool vert)
341{
342 return ::SetDataBrowserHasScrollBars(this->m_controlRef,horiz,vert);
343} /* wxMacDataBrowserTableViewControl::SetHasScrollBars(bool, bool) */
344
345OSStatus wxMacDataBrowserTableViewControl::SetHeaderButtonHeight(UInt16 height)
346{
347 return ::SetDataBrowserListViewHeaderBtnHeight(this->m_controlRef,height);
348} /* wxMacDataBrowserTableViewControl::SetHeaderButtonHeight(UInt16) */
349
350OSStatus wxMacDataBrowserTableViewControl::SetHiliteStyle(DataBrowserTableViewHiliteStyle hiliteStyle)
351{
352 return ::SetDataBrowserTableViewHiliteStyle(this->m_controlRef,hiliteStyle);
353} /*wxMacDataBrowserTableViewControl::SetHiliteStyle(DataBrowserTableViewHiliteStyle) */
354
355OSStatus wxMacDataBrowserTableViewControl::SetIndent(float Indent)
356{
357 return ::DataBrowserSetMetric(this->m_controlRef,kDataBrowserMetricDisclosureColumnPerDepthGap,true,Indent);
358} /* wxMacDataBrowserTableViewControl::SetIndent(float* Indent) */
359
360OSStatus wxMacDataBrowserTableViewControl::SetRowHeight(DataBrowserItemID item, UInt16 height)
361{
362 return ::SetDataBrowserTableViewItemRowHeight(this->m_controlRef,item,height);
363}
364
365OSStatus wxMacDataBrowserTableViewControl::SetScrollPosition(UInt32 top, UInt32 left)
366{
367 return ::SetDataBrowserScrollPosition(this->m_controlRef,top,left);
368}
369
370//
371// column handling
372//
373OSStatus wxMacDataBrowserTableViewControl::GetColumnCount(UInt32* numColumns) const
374{
375 return ::GetDataBrowserTableViewColumnCount(this->m_controlRef,numColumns);
376}
377
378OSStatus wxMacDataBrowserTableViewControl::GetColumnIndex(DataBrowserPropertyID propertyID, DataBrowserTableViewColumnIndex* index) const
379{
380 return ::GetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,index);
381} /* wxMacDataBrowserTableViewControl::GetColumnIndex(DataBrowserPropertyID, DataBrowserTableViewColumnIndex*) const */
382
383OSStatus wxMacDataBrowserTableViewControl::GetFreePropertyID(DataBrowserPropertyID* propertyID) const
384{
385 for (*propertyID=kMinPropertyID; *propertyID<std::numeric_limits<DataBrowserPropertyID>::max(); ++(*propertyID))
386 if (this->IsUsedPropertyID(*propertyID) == errDataBrowserPropertyNotFound)
387 return noErr;
388 return errDataBrowserPropertyNotSupported;
389} /* wxMacDataBrowserTableViewControl::GetFreePropertyID(DataBrowserPropertyID*) const */
390
391OSStatus wxMacDataBrowserTableViewControl::GetPropertyFlags(DataBrowserPropertyID propertyID, DataBrowserPropertyFlags *flags) const
392{
393 return ::GetDataBrowserPropertyFlags(this->m_controlRef,propertyID,flags);
394}
395
396OSStatus wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserItemDataRef itemData, DataBrowserPropertyID* propertyID)
397{
398 return ::GetDataBrowserItemDataProperty(itemData,propertyID);
399} /* wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserItemDataRef, DataBrowserPropertyID*) */
400
401OSStatus wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserTableViewColumnIndex index, DataBrowserTableViewColumnID* propertyID)
402{
403 return ::GetDataBrowserTableViewColumnProperty(this->m_controlRef,index,propertyID);
404} /* wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserTableViewColumnIndex, DataBrowserTableViewColumnID*) */
405
406OSStatus wxMacDataBrowserTableViewControl::IsUsedPropertyID(DataBrowserPropertyID propertyID) const
407{
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;
412
413 return ::GetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,&index);
414} /* wxMacDataBrowserTableViewControl::IsUsedPropertyId(DataBrowserPropertyID) const */
415
416OSStatus wxMacDataBrowserTableViewControl::RemoveColumnByProperty(DataBrowserTableViewColumnID propertyID)
417{
418 return ::RemoveDataBrowserTableViewColumn(this->m_controlRef,propertyID);
419} /* wxMacDataBrowserTableViewControl::RemoveColumnByProperty(DataBrowserTableViewColumnID) */
420
421OSStatus wxMacDataBrowserTableViewControl::RemoveColumnByIndex(DataBrowserTableViewColumnIndex index)
422{
423 DataBrowserTableViewColumnID propertyID;
424
425
426 this->GetPropertyID(index,&propertyID);
427 return ::RemoveDataBrowserTableViewColumn(this->m_controlRef,propertyID);
428} /* wxMacDataBrowserTableViewControl::RemoveColumnByIndex(DataBrowserTableViewColumnIndex) */
429
430OSStatus wxMacDataBrowserTableViewControl::SetColumnIndex(DataBrowserPropertyID propertyID, DataBrowserTableViewColumnIndex index)
431{
432 return ::SetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,index);
433} /* wxMacDataBrowserTableViewControl::SetColumnIndex(DataBrowserPropertyID, DataBrowserTableViewColumnIndex) */
434
435OSStatus wxMacDataBrowserTableViewControl::SetDisclosureColumn(DataBrowserPropertyID propertyID, Boolean expandableRows)
436{
437 return ::SetDataBrowserListViewDisclosureColumn(this->m_controlRef,propertyID,expandableRows);
438}
439
440OSStatus wxMacDataBrowserTableViewControl::SetPropertyFlags(DataBrowserPropertyID propertyID, DataBrowserPropertyFlags flags)
441{
442 return ::SetDataBrowserPropertyFlags(this->m_controlRef,propertyID,flags);
443} /* wxMacDataBrowserTableViewControl::SetPropertyFlags(DataBrowserPropertyID, DataBrowserPropertyFlags) */
444
445//
446// item handling
447//
448OSStatus wxMacDataBrowserTableViewControl::AddItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty)
449{
450 return ::AddDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty);
451} /* wxMacDataBrowserTableViewControl::AddItems(DataBrowserItemID, UInt32, DataBrowserItemID const*, DataBrowserPropertyID) */
452
453OSStatus wxMacDataBrowserTableViewControl::GetFreeItemID(DataBrowserItemID* id) const
454{
455 ItemCount NoOfItems;
456
457 OSStatus status;
458
459
460 status = this->GetItemCount(&NoOfItems);
461 wxCHECK_MSG(status == noErr,status,_("Could not retrieve number of items"));
462 if (NoOfItems == 0)
463 {
464 *id = 1;
465 return noErr;
466 } /* if */
467 else
468 {
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)
473 return noErr;
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)
477 return noErr;
478 // sorry, data browser is full:
479 return errDataBrowserItemNotAdded;
480 } /* if */
481} /* wxMacDataBrowserTableViewControl::GetFreeItemID(DataBrowserItemID*) const */
482
483OSStatus wxMacDataBrowserTableViewControl::GetItemCount(DataBrowserItemID container, Boolean recurse, DataBrowserItemState state, ItemCount* numItems) const
484{
485 return GetDataBrowserItemCount(this->m_controlRef,container,recurse,state,numItems);
486} /* wxMacDataBrowserTableViewControl::GetItemCount(DataBrowserItemID, Boolean, DataBrowserItemState, ItemCount*) const */
487
488OSStatus wxMacDataBrowserTableViewControl::GetItemID( DataBrowserTableViewRowIndex row, DataBrowserItemID * item ) const
489{
490 return GetDataBrowserTableViewItemID(this->m_controlRef,row,item);
491}
492
493OSStatus wxMacDataBrowserTableViewControl::GetItems(DataBrowserItemID container, Boolean recurse, DataBrowserItemState state, Handle items) const
494{
495 return GetDataBrowserItems(this->m_controlRef,container,recurse,state,items);
496} /* wxMacDataBrowserTableViewControl::GetItems(DataBrowserItemID, Boolean, DataBrowserItemState, Handle) const */
497
498OSStatus wxMacDataBrowserTableViewControl::GetItemRow(DataBrowserItemID item, DataBrowserTableViewRowIndex* row) const
499{
500 return GetDataBrowserTableViewItemRow(this->m_controlRef,item,row);
501}
502
503OSStatus wxMacDataBrowserTableViewControl::IsUsedItemID(DataBrowserItemID itemID) const
504{
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;
509
510 return ::GetDataBrowserTableViewItemRow(this->m_controlRef,itemID,&index);
511} /* wxMacDataBrowserTableViewControl::IsUsedItemID(DataBrowserItemID) const */
512
513OSStatus wxMacDataBrowserTableViewControl::RemoveItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty)
514{
515 return ::RemoveDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty);
516}
517
518OSStatus wxMacDataBrowserTableViewControl::RevealItem(DataBrowserItemID item, DataBrowserPropertyID propertyID, DataBrowserRevealOptions options) const
519{
520 return ::RevealDataBrowserItem(this->m_controlRef,item,propertyID,options);
521} /* wxMacDataBrowserTableViewControl::RevealItem(DataBrowserItemID item, DataBrowserPropertyID propertyID, DataBrowserRevealOptions options) const */
522
523OSStatus wxMacDataBrowserTableViewControl::UpdateItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty,
524 DataBrowserPropertyID propertyID) const
525{
526 return UpdateDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty,propertyID);
527}
528
529//
530// item selection
531//
532size_t wxMacDataBrowserTableViewControl::GetSelectedItemIDs(wxArrayDataBrowserItemID& itemIDs) const
533{
534 DataBrowserItemID* itemIDPtr;
535 Handle handle(::NewHandle(0));
536
537 size_t NoOfItems;
538
539
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));
542 itemIDs.Empty();
543 itemIDs.Alloc(NoOfItems);
544 HLock(handle);
545 itemIDPtr = (DataBrowserItemID*) (*handle);
546 for (size_t i=0; i<NoOfItems; ++i)
547 {
548 itemIDs.Add(*itemIDPtr);
549 ++itemIDPtr;
550 } /* for */
551 HUnlock(handle);
552 DisposeHandle(handle);
553 return NoOfItems;
554} /* wxMacDataBrowserTableViewControl::GetSelectedItemIDs(wxArrayDataBrowserItemID&) const*/
555
556OSStatus wxMacDataBrowserTableViewControl::GetSelectionAnchor(DataBrowserItemID* first, DataBrowserItemID* last) const
557{
558 return ::GetDataBrowserSelectionAnchor(this->m_controlRef,first,last);
559} /* wxMacDataBrowserTableViewControl::GetSelectionAnchor(DataBrowserItemID*, DataBrowserItemID*) const */
560
561OSStatus wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags* flags) const
562{
563 return ::GetDataBrowserSelectionFlags(this->m_controlRef,flags);
564} /* wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags*) const */
565
566bool wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID item) const
567{
568 return ::IsDataBrowserItemSelected(this->m_controlRef,item);
569} /* wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID) const */
570
571OSStatus wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags flags)
572{
573 return ::SetDataBrowserSelectionFlags(this->m_controlRef,flags);
574} /* wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags) */
575
576OSStatus wxMacDataBrowserTableViewControl::SetSelectedItems(UInt32 numItems, DataBrowserItemID const* items, DataBrowserSetOption operation)
577{
578 return ::SetDataBrowserSelectedItems(this->m_controlRef, numItems, items, operation );
579} /* wxMacDataBrowserTableViewControl::SetSelectedItems(UInt32, DataBrowserItemID const*, DataBrowserSetOption) */
580
581OSStatus wxMacDataBrowserTableViewControl::GetSortOrder(DataBrowserSortOrder* order) const
582{
583 return ::GetDataBrowserSortOrder(this->m_controlRef,order);
584}
585
586OSStatus wxMacDataBrowserTableViewControl::GetSortProperty(DataBrowserPropertyID* propertyID) const
587{
588 return ::GetDataBrowserSortProperty(this->m_controlRef,propertyID);
589}
590
591OSStatus wxMacDataBrowserTableViewControl::Resort(DataBrowserItemID container, Boolean sortChildren)
592{
593 return ::SortDataBrowserContainer(this->m_controlRef,container,sortChildren);
594} /* wxMacDataBrowserTableViewControl::Resort(DataBrowserItemID, Boolean) */
595
596OSStatus wxMacDataBrowserTableViewControl::SetSortOrder(DataBrowserSortOrder order)
597{
598 return ::SetDataBrowserSortOrder(this->m_controlRef,order);
599}
600
601OSStatus wxMacDataBrowserTableViewControl::SetSortProperty(DataBrowserPropertyID propertyID)
602{
603 return ::SetDataBrowserSortProperty(this->m_controlRef,propertyID);
604}
605
606//
607// container handling
608//
609OSStatus wxMacDataBrowserTableViewControl::CloseContainer(DataBrowserItemID containerID)
610{
611 return ::CloseDataBrowserContainer(this->m_controlRef,containerID);
612} /* wxMacDataBrowserTableViewControl::CloseContainer(DataBrowserItemID) */
613
614OSStatus wxMacDataBrowserTableViewControl::OpenContainer(DataBrowserItemID containerID)
615{
616 return ::OpenDataBrowserContainer(this->m_controlRef,containerID);
617} /* wxMacDataBrowserTableViewControl::OpenContainer(DataBrowserItemID) */
618
619IMPLEMENT_ABSTRACT_CLASS(wxMacDataBrowserTableViewControl,wxMacControl)
620
621// ============================================================================
622// wxMacDataBrowserListViewControl
623// ============================================================================
624#pragma mark -
625//
626// column handling
627//
628OSStatus wxMacDataBrowserListViewControl::AddColumn(DataBrowserListViewColumnDesc *columnDesc, DataBrowserTableViewColumnIndex position)
629{
630 return AddDataBrowserListViewColumn(this->m_controlRef,columnDesc,position);
631} /* wxMacDataBrowserListViewControl::AddColumn(DataBrowserListViewColumnDesc*, DataBrowserTableViewColumnIndex) */
632
633// ============================================================================
634// wxMacDataViewDataBrowserListViewControl
635// ============================================================================
636#pragma mark -
637//
638// constructors / destructor
639//
640wxMacDataViewDataBrowserListViewControl::wxMacDataViewDataBrowserListViewControl(wxWindow* peer, wxPoint const& pos, wxSize const& size, long style)
641 :wxMacDataBrowserListViewControl(peer,pos,size,style)
642{
643} /* wxMacDataViewDataBrowserListViewControl::wxMacDataViewDataBrowserListViewControl(wxWindow* , const wxPoint&, const wxSize&, long) */
644
645//
646// callback functions (inherited from wxMacDataBrowserTableViewControl)
647//
648Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID itemOneID, DataBrowserItemID itemTwoID, DataBrowserPropertyID sortProperty)
649{
650 DataBrowserSortOrder sortOrder;
651
652 DataBrowserTableViewColumnIndex modelColumnIndex;
653
b2680ced 654 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
489468fe
SC
655
656
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)
660 {
661 // variable definition and initialization:
662 wxDataViewColumn* ColumnPtr(dataViewCtrlPtr->GetColumnPtr(sortProperty));
663
664 wxCHECK_MSG(ColumnPtr != NULL,false,_("Could not determine column index."));
665 modelColumnIndex = ColumnPtr->GetModelColumn();
666 } /* if */
667 else
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) */
673
674void 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.
676{
677 wxArrayDataBrowserItemID itemIDs;
678
b2680ced 679 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
489468fe
SC
680
681
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:
684 *menu = NULL;
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());
689
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*) */
699
700OSStatus wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemDataRef itemData, Boolean getValue)
701{
702 if (getValue)
703 {
704 // variable definitions:
705 wxDataViewCtrl* dataViewCtrlPtr;
706
b2680ced 707 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
489468fe
SC
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
711 else
712 {
713 // variable definitions:
714 OSStatus errorStatus;
715 wxDataViewColumn* dataViewColumnPtr;
716
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."));
720
721 wxDataViewItem dvItem(reinterpret_cast<void*>(itemID));
722 unsigned int col = dataViewColumnPtr->GetModelColumn();
723
724 switch (dataViewColumnPtr->GetRenderer()->GetPropertyType())
725 {
726 case kDataBrowserCheckboxType:
727 {
728 // variable definition:
729 ThemeButtonValue buttonValue;
730
731 errorStatus = ::GetDataBrowserItemDataButtonValue(itemData,&buttonValue);
732 if (errorStatus == noErr)
733 {
734 if (buttonValue == kThemeButtonOn)
735 {
736 // variable definition and initialization:
737 wxVariant modifiedData(true);
738
739 if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData, dvItem, col) &&
740 dataViewCtrlPtr->GetModel()->ValueChanged(dvItem, col))
741 return noErr;
742 else
743 return errDataBrowserInvalidPropertyData;
744 } /* if */
745 else if (buttonValue == kThemeButtonOff)
746 {
747 // variable definition and initialization:
748 wxVariant modifiedData(false);
749
750 if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData, dvItem, col) &&
751 dataViewCtrlPtr->GetModel()->ValueChanged(dvItem, col))
752 return noErr;
753 else
754 return errDataBrowserInvalidPropertyData;
755 } /* if */
756 else
757 return errDataBrowserInvalidPropertyData;
758 } /* if */
759 else
760 return errorStatus;
761 } /* block */
762 case kDataBrowserTextType:
763 {
764 // variable definitions:
765 CFStringRef stringReference;
766
767 errorStatus = ::GetDataBrowserItemDataText(itemData,&stringReference);
768 if (errorStatus == noErr)
769 {
770 // variable definitions and initializations:
771#if wxCHECK_VERSION(2,9,0)
772 wxCFStringRef modifiedString(stringReference);
773#else
774 wxMacCFStringHolder modifiedString(stringReference);
775#endif
776 wxVariant modifiedData(modifiedString.AsString());
777
778 if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData, dvItem, col) &&
779 dataViewCtrlPtr->GetModel()->ValueChanged(dvItem, col))
780 return noErr;
781 else
782 return errDataBrowserInvalidPropertyData;
783 } /* if */
784 else
785 return errorStatus;
786 } /* block */
787 default:
788 return errDataBrowserPropertyNotSupported;
789 } /* switch */
790 } /* if */
791 } /* if */
792 else
793 {
794 if (propertyID >= kMinPropertyID) // in case data columns set the data
795 {
796 // variable definitions:
797 wxVariant variant;
798 wxDataViewColumn* dataViewColumnPtr;
799 wxDataViewCtrl* dataViewCtrlPtr;
800
b2680ced 801 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
489468fe
SC
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()))
809 {
810 dataViewColumnPtr->GetRenderer()->SetDataReference(itemData);
811 dataViewColumnPtr->GetRenderer()->SetValue(variant);
812 wxCHECK_MSG(dataViewColumnPtr->GetRenderer()->Render(),errDataBrowserNotConfigured,_("Rendering failed."));
813 } /* if */
814 return noErr;
815 } /* if */
816 else // react on special system requests
817 {
818 switch (propertyID)
819 {
820 case kDataBrowserContainerIsClosableProperty:
821 {
822 // variable definitions:
b2680ced 823 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
489468fe
SC
824
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
828
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());
836 } /* block */
837 case kDataBrowserContainerIsOpenableProperty:
838 {
839 // variable definitions:
b2680ced 840 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
489468fe
SC
841
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
845
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());
853 } /* block */
854 case kDataBrowserItemIsContainerProperty:
855 {
856 // variable definition:
b2680ced 857 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
489468fe
SC
858
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))));
862 } /* block */
863 case kDataBrowserItemIsEditableProperty:
864 return ::SetDataBrowserItemDataBooleanValue(itemData,true);
865 } /* switch */
866 } /* if */
867 } /* if */
868 return errDataBrowserPropertyNotSupported;
869} /* wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc(DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemDataRef, Boolean) */
870
871void wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID itemID, DataBrowserItemNotification message, DataBrowserItemDataRef itemData)
872{
b2680ced 873 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()));
489468fe
SC
874
875
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)
878 switch (message)
879 {
880 case kDataBrowserContainerClosed:
881 dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
882 {
883 // initialize wxWidget event:
884 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED,dataViewCtrlPtr->GetId()); // variable definition
885
886 dataViewEvent.SetEventObject(dataViewCtrlPtr);
887 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
888 // finally send the equivalent wxWidget event:
889 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
890 } /* block */
891 break;
892 case kDataBrowserContainerOpened:
893 dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
894 {
895 // initialize wxWidget event:
896 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED,dataViewCtrlPtr->GetId()); // variable definition
897
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)));
904 } /* block */
905 break;
906 case kDataBrowserEditStarted:
907 dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
908 {
909 // initialize wxWidget event:
910 DataBrowserPropertyID propertyID;
911 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED,dataViewCtrlPtr->GetId()); // variable definition
912
913 dataViewEvent.SetEventObject(dataViewCtrlPtr);
914 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
915 if (this->GetPropertyID(itemData,&propertyID) == noErr)
916 {
917 // variable definition and initialization:
918 DataBrowserTableViewColumnIndex columnIndex;
919
920 wxCHECK_RET(this->GetColumnIndex(propertyID,&columnIndex),_("Column index not found."));
921 dataViewEvent.SetColumn(columnIndex);
922 dataViewEvent.SetDataViewColumn(dataViewCtrlPtr->GetColumnPtr(propertyID));
923 } /* if */
924 // finally send the equivalent wxWidget event:
925 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
926 } /* block */
927 break;
928 case kDataBrowserEditStopped:
929 {
930 // initialize wxWidget event:
931 DataBrowserPropertyID propertyID;
932 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE,dataViewCtrlPtr->GetId()); // variable definition
933
934 dataViewEvent.SetEventObject(dataViewCtrlPtr);
935 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
936 if (this->GetPropertyID(itemData,&propertyID) == noErr)
937 {
938 // variable definition and initialization:
939 DataBrowserTableViewColumnIndex columnIndex;
940
941 wxCHECK_RET(this->GetColumnIndex(propertyID,&columnIndex),_("Column index not found."));
942 dataViewEvent.SetColumn(columnIndex);
943 dataViewEvent.SetDataViewColumn(dataViewCtrlPtr->GetColumnPtr(propertyID));
944 } /* if */
945 // finally send the equivalent wxWidget event:
946 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
947 } /* block */
948 break;
949 case kDataBrowserItemAdded:
950 dataViewCtrlPtr->FinishCustomItemEditing();
951 break;
952 case kDataBrowserItemDeselected:
953 dataViewCtrlPtr->FinishCustomItemEditing();
954 break;
955 case kDataBrowserItemDoubleClicked:
956 {
957 // initialize wxWidget event:
958 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED,dataViewCtrlPtr->GetId()); // variable definition
959
960 dataViewEvent.SetEventObject(dataViewCtrlPtr);
961 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
962 // finally send the equivalent wxWidget event:
963 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
964 } /* block */
965 break;
966 case kDataBrowserItemRemoved:
967 dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
968 break;
969 case kDataBrowserItemSelected:
970 break; // not implemented by wxWidgets; see kDataBrowserSelectionSetChanged
971 case kDataBrowserSelectionSetChanged:
972 {
973 // initialize wxWidget event:
974 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED,dataViewCtrlPtr->GetId()); // variable definition
fdb45ab7 975 dataViewEvent.SetItem( dataViewCtrlPtr->GetSelection() );
489468fe
SC
976 dataViewEvent.SetEventObject(dataViewCtrlPtr);
977 dataViewEvent.SetModel (dataViewCtrlPtr->GetModel());
978 // finally send the equivalent wxWidget event:
979 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
980 } /* block */
981 break;
982 case kDataBrowserTargetChanged: // no idea if this notification is ever sent
983 break;
984 case kDataBrowserUserStateChanged:
985 {
986 // finish custom item editing if necessary:
987 dataViewCtrlPtr->FinishCustomItemEditing();
988 // update column widths:
989 for (size_t i=0; i<dataViewCtrlPtr->GetColumnCount(); ++i)
990 {
991 // constant definition for abbreviational purposes:
992 wxDataViewColumn* const columnPtr = dataViewCtrlPtr->GetColumn(i);
993 // variable definition:
994 UInt16 columnWidth;
995
996 wxCHECK_RET(this->GetColumnWidth(columnPtr->GetPropertyID(),&columnWidth) == noErr,_("Column width could not be determined"));
997 columnPtr->SetWidthVariable(columnWidth);
998 } /* for */
999 // update sorting orders:
1000 DataBrowserPropertyID propertyID; // variable definition
1001
1002 if ((this->GetSortProperty(&propertyID) == noErr) && (propertyID >= kMinPropertyID))
1003 {
1004 DataBrowserSortOrder sortOrder;
1005 DataBrowserTableViewColumnIndex columnIndex;
1006
1007 if ((this->GetSortOrder(&sortOrder) == noErr) && (this->GetColumnIndex(propertyID,&columnIndex) == noErr))
1008 {
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))
1015 {
1016 columnPtr->SetSortOrder(!(columnPtr->IsSortOrderAscending()));
1017 // initialize wxWidget event:
1018 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED,dataViewCtrlPtr->GetId()); // variable defintion
1019
1020 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1021 dataViewEvent.SetColumn(columnIndex);
1022 dataViewEvent.SetDataViewColumn(columnPtr);
1023 // finally send the equivalent wxWidget event:
1024 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
1025 } /* if */
1026 } /* if */
1027 } /* if */
1028 } /* block */
1029 break;
1030 } /* switch */
1031} /* wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID, DataBrowserItemNotification, DataBrowserItemDataRef) */
1032
a4fec5b4
SC
1033void wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID itemID,
1034 DataBrowserPropertyID propertyID,
1035 DataBrowserItemState state,
1036 Rect const* rectangle,
1037 SInt16 WXUNUSED(bitDepth),
1038 Boolean WXUNUSED(colorDevice))
489468fe
SC
1039{
1040 DataBrowserTableViewColumnIndex columnIndex;
1041
1042 wxDataViewColumn* dataViewColumnPtr;
1043
1044 wxDataViewCtrl* dataViewCtrlPtr;
1045
1046 wxDataViewCustomRenderer* dataViewCustomRendererPtr;
1047
1048 wxVariant dataToRender;
1049
b2680ced 1050 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
489468fe
SC
1051 wxCHECK_RET(dataViewCtrlPtr != NULL, _("Pointer to data view control not set correctly."));
1052 wxCHECK_RET(dataViewCtrlPtr->GetModel() != NULL,_("Pointer to model not set correctly."));
1053 wxCHECK_RET(this->GetColumnIndex(propertyID,&columnIndex) == noErr,_("Could not determine column index."));
1054 dataViewColumnPtr = dataViewCtrlPtr->GetColumnPtr(propertyID);
1055 wxCHECK_RET(dataViewColumnPtr != NULL,_("No column for the specified column index existing."));
1056 dataViewCustomRendererPtr = dynamic_cast<wxDataViewCustomRenderer*>(dataViewColumnPtr->GetRenderer());
1057 wxCHECK_RET(dataViewCustomRendererPtr != NULL,_("No renderer or invalid renderer type specified for custom data column."));
1058 dataViewCtrlPtr->GetModel()->GetValue(dataToRender,wxDataViewItem(reinterpret_cast<void*>(itemID)),dataViewColumnPtr->GetModelColumn());
1059 dataViewCustomRendererPtr->SetValue(dataToRender);
1060
1061 wxDataViewItem dataitem( reinterpret_cast<void*>(itemID) );
1062 dataViewCtrlPtr->GetModel()->GetValue(dataToRender,dataitem,dataViewColumnPtr->GetModelColumn());
1063 dataViewCustomRendererPtr->SetValue(dataToRender);
1064
1065 // try to determine the content's size (drawable part):
1066 Rect content;
f215225d
SC
1067 HIShapeRef rgn = NULL;
1068
489468fe
SC
1069 UInt16 headerHeight;
1070
f215225d
SC
1071 if ( HIViewCopyShape(m_controlRef, kHIViewContentMetaPart, &rgn) == noErr)
1072 {
1073 CGRect cgrect;
1074 HIShapeGetBounds(rgn, &cgrect);
1075 content = (Rect){ cgrect.origin.y, cgrect.origin.x, cgrect.origin.y+cgrect.size.height, cgrect.origin.x+cgrect.size.width };
1076 CFRelease(rgn);
1077 }
489468fe 1078 else
b2680ced 1079 GetControlBounds(m_controlRef, &content);
489468fe
SC
1080 // space for the header
1081 this->GetHeaderButtonHeight(&headerHeight);
1082 content.top += headerHeight;
1083 // extra space for the frame (todo: do not how to determine the space automatically from the control)
1084 content.top += 5;
1085 content.left += 5;
1086 content.right -= 3;
1087 content.bottom -= 3;
1088 // extra space for the scrollbars:
1089 content.bottom -= wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y);
1090 content.right -= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
1091
1092 wxDC *dc = dataViewCustomRendererPtr->GetDC();
1093
1094 wxRect cellrect( static_cast<int>(rectangle->left),
3f407e4f 1095 static_cast<int>(rectangle->top),
489468fe
SC
1096 static_cast<int>(1+rectangle->right-rectangle->left),
1097 static_cast<int>(rectangle->bottom-rectangle->top) );
1098
1099 bool is_active = IsControlActive( this->m_controlRef );
1100 if (state == kDataBrowserItemIsSelected)
1101 {
1102
1103 wxColour col( wxMacCreateCGColorFromHITheme( (is_active) ?
1104 kThemeBrushAlternatePrimaryHighlightColor
1105 : kThemeBrushSecondaryHighlightColor ) );
1106
1107 wxRect rect = cellrect;
1108 Rect itemrect;
1109 GetDataBrowserItemPartBounds( this->m_controlRef, itemID, propertyID,
1110 kDataBrowserPropertyEnclosingPart, &itemrect );
1111 rect.x = itemrect.left;
1112 rect.width = itemrect.right-itemrect.left+1;
1113
1114 wxBrush selBrush( col );
1115 wxPen oldpen( dc->GetPen() );
1116 wxBrush oldbrush( dc->GetBrush() );
1117 dc->SetPen( *wxTRANSPARENT_PEN );
1118 dc->SetBrush( selBrush );
1119 dc->DrawRectangle(rect);
1120 dc->SetBrush( oldbrush );
1121 dc->SetPen( oldpen );
1122 }
1123
1124 wxDataViewModel *model = dataViewCtrlPtr->GetModel();
1125 if ((columnIndex == 0) || !model->IsContainer(dataitem) || model->HasContainerColumns(dataitem))
1126 {
1127 // make sure that 'Render' can draw only in the allowed area:
1128 dc->SetClippingRegion(content.left,content.top,content.right-content.left+1,content.bottom-content.top+1);
1129 (void) (dataViewCustomRendererPtr->Render( cellrect, dc,
1130 ((state == kDataBrowserItemIsSelected) ? wxDATAVIEW_CELL_SELECTED : 0)));
1131 dc->DestroyClippingRegion(); // probably not necessary
1132 }
1133
1134 dataViewCustomRendererPtr->SetDC(NULL);
1135} /* wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemState, Rect const*, SInt16, Boolean) */
1136
a4fec5b4
SC
1137Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserEditItemProc(DataBrowserItemID WXUNUSED(itemID),
1138 DataBrowserPropertyID WXUNUSED(propertyID),
1139 CFStringRef WXUNUSED(theString),
1140 Rect* WXUNUSED(maxEditTextRect),
1141 Boolean* WXUNUSED(shrinkToFit))
489468fe
SC
1142{
1143 return false;
1144} /* wxMacDataViewDataBrowserListViewControl::DataBrowserEditItemProc(DataBrowserItemID, DataBrowserPropertyID, CFStringRef, Rect*, Boolean*) */
1145
1146Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserHitTestProc(DataBrowserItemID WXUNUSED(itemID), DataBrowserPropertyID WXUNUSED(property), Rect const* WXUNUSED(theRect), Rect const* WXUNUSED(mouseRect))
1147{
1148 return true;
1149} /* wxMacDataViewDataBrowserListViewControl::DataBrowserHitTestProc(DataBrowserItemID, DataBrowserPropertyID, Rect const*, Rect const*) */
1150
1151DataBrowserTrackingResult wxMacDataViewDataBrowserListViewControl::DataBrowserTrackingProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, Rect const* theRect, Point WXUNUSED(startPt), EventModifiers WXUNUSED(modifiers))
1152{
1153 wxDataViewColumn* dataViewColumnPtr;
1154
1155 wxDataViewCtrl* dataViewCtrlPtr;
1156
1157 wxDataViewCustomRenderer* dataViewCustomRendererPtr;
1158
1159 wxDataViewItem dataViewCustomRendererItem;
1160
1161
4a3d495c
RR
1162 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1163 wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly."));
1164 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
489468fe
SC
1165 dataViewCustomRendererItem = reinterpret_cast<void*>(itemID);
1166 wxCHECK_MSG(dataViewCustomRendererItem.IsOk(),kDataBrowserNothingHit,_("Invalid data view item"));
489468fe
SC
1167 dataViewColumnPtr = dataViewCtrlPtr->GetColumnPtr(propertyID);
1168 wxCHECK_MSG(dataViewColumnPtr != NULL,kDataBrowserNothingHit,_("No column existing."));
1169 dataViewCustomRendererPtr = dynamic_cast<wxDataViewCustomRenderer*>(dataViewColumnPtr->GetRenderer());
1170 wxCHECK_MSG(dataViewCustomRendererPtr != NULL,kDataBrowserNothingHit,_("No renderer or invalid renderer type specified for custom data column."));
1171 // 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):
1172 if (dataViewCtrlPtr->GetCustomRendererItem() == dataViewCustomRendererItem)
1173 return kDataBrowserContentHit;
1174 // an(other) item is going to be edited and therefore the current editing - if existing - has to be finished:
1175 if (dataViewCtrlPtr->GetCustomRendererPtr() != NULL)
1176 {
1177 dataViewCtrlPtr->GetCustomRendererPtr()->FinishEditing();
1178 dataViewCtrlPtr->SetCustomRendererItem(wxDataViewItem());
1179 dataViewCtrlPtr->SetCustomRendererPtr (NULL);
4a3d495c 1180 }
489468fe
SC
1181 // check if renderer has got a valid editor control for editing; if this is the case start editing of the new item:
1182 if (dataViewCustomRendererPtr->HasEditorCtrl())
1183 {
1184 // variable definition:
1185 wxRect wxRectangle;
1186
1187 ::wxMacNativeToRect(theRect,&wxRectangle);
1188 dataViewCustomRendererPtr->StartEditing(dataViewCustomRendererItem,wxRectangle);
1189 dataViewCtrlPtr->SetCustomRendererItem(dataViewCustomRendererItem);
1190 dataViewCtrlPtr->SetCustomRendererPtr (dataViewCustomRendererPtr);
4a3d495c 1191 }
489468fe
SC
1192 return kDataBrowserContentHit;
1193} /* wxMacDataViewDataBrowserListViewControl::DataBrowserTrackingProc(DataBrowserItemID, DataBrowserPropertyID, Rect const*, Point, EventModifiers) */
1194
4a3d495c
RR
1195Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserAcceptDragProc(DragReference dragRef, DataBrowserItemID itemID)
1196{
1197 UInt16 noOfDraggedItems;
1198
1199 wxDataViewCtrl* dataViewCtrlPtr;
1200
1201
1202 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1203 wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly."));
1204 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
1205
1206 // send a drag possible event for each available item and proceed with it unless the event is vetoed:
1207 ::CountDragItems(dragRef,&noOfDraggedItems);
1208 for (UInt16 indexDraggedItem=1; indexDraggedItem<=noOfDraggedItems; ++indexDraggedItem)
1209 {
1210 // collect native information:
1211 ItemReference itemRef;
1212 wxDataObjectComposite* dataObjects;
1213 wxMemoryBuffer buffer;
1214
1215 ::GetDragItemReferenceNumber(dragRef,indexDraggedItem,&itemRef); // the index begins with 1!
1216 dataObjects = this->GetDnDDataObjects(dragRef,itemRef);
1217 // create wxWidget's event:
1218 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE,dataViewCtrlPtr->GetId());
1219
1220 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1221 dataViewEvent.SetItem(reinterpret_cast<void*>(itemID)); // this is the item that receives the event
1222 // (can be an invalid item ID, this is especially useful if the dataview does not contain any items)
1223 dataViewEvent.SetModel(dataViewCtrlPtr->GetModel());
1224 dataViewEvent.SetDataObject(dataObjects);
1225 dataViewEvent.SetDataFormat(this->GetDnDDataFormat(dataObjects));
1226 if (dataViewEvent.GetDataFormat().GetType() != wxDF_INVALID)
1227 {
1228 dataViewEvent.SetDataSize(dataObjects->GetDataSize(dataViewEvent.GetDataFormat().GetType()));
1229 dataObjects->GetDataHere(dataViewEvent.GetDataFormat().GetType(),buffer.GetWriteBuf(dataViewEvent.GetDataSize()));
1230 buffer.UngetWriteBuf(dataViewEvent.GetDataSize());
1231 dataViewEvent.SetDataBuffer(buffer.GetData());
1232 }
1233
1234 // send event:
1235 if (!(dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed()))
1236 return false;
1237 }
1238 return true;
1239} /* wxMacDataViewDataBrowserListViewControl::DataBrowserAcceptDragProc(DragReference, DataBrowserItemID) */
1240
1241Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserAddDragItemProc(DragReference dragRef, DataBrowserItemID itemID, ItemReference* itemRef)
1242{
1243 wxDataViewCtrl* dataViewCtrlPtr;
1244
1245 wxDataViewItem dataViewItem;
1246
1247
1248 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1249 wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly."));
1250 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
1251 dataViewItem = reinterpret_cast<void*>(itemID);
1252 wxCHECK_MSG(dataViewItem.IsOk(),false,_("Invalid data view item"));
1253
1254 // send a begin drag event and proceed with dragging unless the event is vetoed:
1255 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG,dataViewCtrlPtr->GetId());
1256
1257 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1258 dataViewEvent.SetItem(dataViewItem);
1259 dataViewEvent.SetModel(dataViewCtrlPtr->GetModel());
1260 // 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
1261 // the object a wxDataObjectComposite object is used;
1262 // currently, the composite object only contains a TAB concatenated string of all data:
1263 wxDataObjectComposite* dataObject(new wxDataObjectComposite());
1264 wxString dataString; // contains the TAB concatenated data
1265
1266 for (size_t i=0; i<dataViewCtrlPtr->GetColumnCount(); i++)
1267 {
1268 // variable definition:
1269 wxVariant dataValue;
1270
1271 dataViewCtrlPtr->GetModel()->GetValue(dataValue,dataViewItem,dataViewCtrlPtr->GetColumn(i)->GetModelColumn());
1272 if (i > 0)
1273 dataString << wxT('\t');
1274 dataString << dataValue.MakeString();
1275 }
1276 dataObject->Add(new wxTextDataObject(dataString));
1277 dataViewEvent.SetDataObject(dataObject);
1278 // check if event has not been vetoed:
1279 if (dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed())
1280 {
1281 // for the internal drag & drop functions create two flavors:
1282 // - the data browser's item id;
1283 // - the data contained the dataview event object (if available).
1284 // Definition: a flavor is the type dependent representation of identical data.
1285 // Example: a number can be represented by its value and by its value converted to a string. In this case the flavor
1286 // of the number's internal representation is typeSInt32 while its string representation has got the flavor 'TEXT'.
1287 // Item id is one of the flavors:
1288 wxCHECK_MSG(::AddDragItemFlavor(dragRef,*itemRef,typeUInt32,&itemID,sizeof(itemID),0) == noErr,false,_("Unable to handle native drag&drop data"));
1289 // if the dataview event object contains data it is used for additional flavors; all natively known flavors are supported:
1290 if (dataViewEvent.GetDataObject() != NULL)
1291 {
1292 // constant definition for abbreviational purposes:
1293 size_t const noOfFormats = dataViewEvent.GetDataObject()->GetFormatCount();
1294
1295 if (noOfFormats > 0)
1296 {
1297 // variable definition:
1298 wxDataFormat* dataFormats;
1299
1300 dataFormats = new wxDataFormat[noOfFormats];
1301 dataViewEvent.GetDataObject()->GetAllFormats(dataFormats,wxDataObject::Get);
1302 for (size_t i=0; i<noOfFormats; ++i)
1303 switch (dataFormats[i].GetType())
1304 {
1305 case wxDF_INVALID:
1306 wxFAIL_MSG(_("Data object has invalid data format"));
1307 break;
1308 case wxDF_TEXT:
1309 {
1310 // constant definition for abbreviational purposes:
1311 size_t const dataSize = dataViewEvent.GetDataObject()->GetDataSize(wxDF_TEXT);
1312 // variable definition and initialization:
1313 wxMemoryBuffer dataObject(dataSize);
1314
1315 dataViewEvent.GetDataObject()->GetDataHere(wxDF_TEXT,dataObject.GetWriteBuf(dataSize));
1316 dataObject.UngetWriteBuf(dataSize);
1317 if (::AddDragItemFlavor(dragRef,*itemRef,'TEXT',dataObject.GetData(),dataSize,0) != noErr)
1318 wxFAIL_MSG(_("Adding flavor TEXT failed"));
1319 } /* block */
1320 break;
1321 case wxDF_UNICODETEXT:
1322 {
1323 // constant definition for abbreviational purposes:
1324 size_t const dataSize = dataViewEvent.GetDataObject()->GetDataSize(wxDF_TEXT);
1325 // as there is no direct access to the data copy it to a memory buffer:
1326 wxMemoryBuffer dataObject(dataSize);
1327
1328 dataViewEvent.GetDataObject()->GetDataHere(wxDF_TEXT,dataObject.GetWriteBuf(dataSize));
1329 dataObject.UngetWriteBuf(dataSize);
1330 // if the data is stored in unicode format the internal representation is utf-8 (not mentioned in the documentation but in the source code);
1331 // DnD uses fixed utf-16 representation -> use the OSX functions for a conversion:
1332 CFDataRef osxData (::CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,reinterpret_cast<UInt8*>(dataObject.GetData()),dataSize,kCFAllocatorNull));
1333 CFStringRef osxString(::CFStringCreateFromExternalRepresentation(kCFAllocatorDefault,osxData,kCFStringEncodingUTF8));
1334
1335 // the osxString contains now the data and therefore the previously occupied memory can be released and re-used:
1336 ::CFRelease(osxData);
1337 osxData = ::CFStringCreateExternalRepresentation(kCFAllocatorDefault,osxString,kCFStringEncodingUTF16,32);
1338 if (::AddDragItemFlavor(dragRef,*itemRef,'utxt',::CFDataGetBytePtr(osxData),::CFDataGetLength(osxData),0) != noErr)
1339 wxFAIL_MSG(_("Adding flavor utxt failed"));
1340 // clean up:
1341 ::CFRelease(osxData);
1342 ::CFRelease(osxString);
1343 } /* block */
1344 break;
1345 case wxDF_BITMAP:
1346 case wxDF_METAFILE:
1347 case wxDF_SYLK:
1348 case wxDF_DIF:
1349 case wxDF_TIFF:
1350 case wxDF_OEMTEXT:
1351 case wxDF_DIB:
1352 case wxDF_PALETTE:
1353 case wxDF_PENDATA:
1354 case wxDF_RIFF:
1355 case wxDF_WAVE:
1356 case wxDF_ENHMETAFILE:
1357 case wxDF_FILENAME:
1358 case wxDF_LOCALE:
1359 case wxDF_PRIVATE:
1360 case wxDF_HTML:
1361 break; // not (yet) supported data formats
1362 default:
1363 wxFAIL_MSG(_("Unknown data format"));
1364 }
1365 delete[] dataFormats;
1366 }
1367 }
1368 return true;
1369 }
1370 else
1371 return false;
1372} /* wxMacDataViewDataBrowserListViewControl::DataBrowserAddDragItemProc(DragReference, DataBrowserItemID, ItemReference*) */
1373
1374Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserReceiveDragProc(DragReference dragRef, DataBrowserItemID itemID)
1375{
1376 UInt16 noOfDraggedItems;
1377
1378 wxDataViewCtrl* dataViewCtrlPtr;
1379
1380
1381 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer());
1382 wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly."));
1383 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
1384
1385 // send a drag possible event for each available and item und proceed with it unless the event is vetoed:
1386 ::CountDragItems(dragRef,&noOfDraggedItems);
1387 for (UInt16 indexDraggedItem=1; indexDraggedItem<=noOfDraggedItems; ++indexDraggedItem)
1388 {
1389 // collect native information:
1390 ItemReference itemRef;
1391 wxDataObjectComposite* dataObjects;
1392 wxMemoryBuffer buffer;
1393
1394 ::GetDragItemReferenceNumber(dragRef,indexDraggedItem,&itemRef); // the index begins with 1!
1395 dataObjects = this->GetDnDDataObjects(dragRef,itemRef);
1396 // create wxWidget's event:
1397 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_DROP,dataViewCtrlPtr->GetId());
1398
1399 dataViewEvent.SetEventObject(dataViewCtrlPtr);
1400 dataViewEvent.SetItem(reinterpret_cast<void*>(itemID)); // this is the item that receives the event
1401 // (can be an invalid item ID, this is especially useful if the dataview does not contain any items)
1402 dataViewEvent.SetModel(dataViewCtrlPtr->GetModel());
1403 dataViewEvent.SetDataObject(dataObjects);
1404 dataViewEvent.SetDataFormat(this->GetDnDDataFormat(dataObjects));
1405 if (dataViewEvent.GetDataFormat().GetType() != wxDF_INVALID)
1406 {
1407 dataViewEvent.SetDataSize(dataObjects->GetDataSize(dataViewEvent.GetDataFormat().GetType()));
1408 dataObjects->GetDataHere(dataViewEvent.GetDataFormat().GetType(),buffer.GetWriteBuf(dataViewEvent.GetDataSize()));
1409 buffer.UngetWriteBuf(dataViewEvent.GetDataSize());
1410 dataViewEvent.SetDataBuffer(buffer.GetData());
1411 }
1412
1413 // send event:
1414 if (!(dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed()))
1415 return false;
1416 }
1417 return true;
1418} /* wxMacDataViewDataBrowserListViewControl::DataBrowserReceiveDragProc(DragReference, DataBrowserItemID) */
1419
1420//
1421// drag & drop helper methods
1422//
1423wxDataFormat wxMacDataViewDataBrowserListViewControl::GetDnDDataFormat(wxDataObjectComposite* dataObjects)
1424{
1425 wxDataFormat resultFormat;
1426
1427
1428 if (dataObjects != NULL)
1429 {
1430 bool compatible(true);
1431
1432 size_t const noOfFormats = dataObjects->GetFormatCount();
1433 size_t indexFormat;
1434
1435 wxDataFormat* formats;
1436
1437 // get all formats and check afterwards if the formats are compatible; if they are compatible the preferred format is returned otherwise
1438 // wxDF_INVALID is returned;
1439 // currently compatible types (ordered by priority are):
1440 // - wxDF_UNICODETEXT - wxDF_TEXT
1441 formats = new wxDataFormat[noOfFormats];
1442 dataObjects->GetAllFormats(formats);
1443 indexFormat = 0;
1444 while ((indexFormat < noOfFormats) && compatible)
1445 {
1446 switch (resultFormat.GetType())
1447 {
1448 case wxDF_INVALID:
1449 resultFormat.SetType(formats[indexFormat].GetType()); // first format (should only be reached if indexFormat == 0
1450 break;
1451 case wxDF_TEXT:
1452 if (formats[indexFormat].GetType() == wxDF_UNICODETEXT)
1453 resultFormat.SetType(wxDF_UNICODETEXT);
1454 else // incompatible
1455 {
1456 resultFormat.SetType(wxDF_INVALID);
1457 compatible = false;
1458 }
1459 break;
1460 case wxDF_UNICODETEXT:
1461 if (formats[indexFormat].GetType() != wxDF_TEXT)
1462 {
1463 resultFormat.SetType(wxDF_INVALID);
1464 compatible = false;
1465 }
1466 break;
1467 default:
1468 resultFormat.SetType(wxDF_INVALID); // not (yet) supported format
1469 compatible = false;
1470 }
1471 ++indexFormat;
1472 } /* while */
1473 // clean up:
1474 delete[] formats;
1475 }
1476 return resultFormat;
1477} /* wxMacDataViewDataBrowserListViewControl::GetDnDDataFormat(wxDataObjectComposite*) */
1478
1479wxDataObjectComposite* wxMacDataViewDataBrowserListViewControl::GetDnDDataObjects(DragReference dragRef, ItemReference itemRef) const
1480{
1481 UInt16 noOfFlavors;
1482
1483 wxDataObjectComposite* dataObject;
1484
1485
1486 ::CountDragItemFlavors(dragRef,itemRef,&noOfFlavors);
1487 if (noOfFlavors > 0)
1488 {
1489 // 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:
1490 wxTextDataObject* textDataObject(NULL);
1491
1492 dataObject = new wxDataObjectComposite();
1493 for (UInt16 indexFlavor=1; indexFlavor<=noOfFlavors; ++indexFlavor)
1494 {
1495 // variable definition:
1496 FlavorType flavorDataObject;
1497
1498 if (::GetFlavorType(dragRef,itemRef,indexFlavor,&flavorDataObject) == noErr) // GetFlavorType uses a 1 based index!
1499 switch (flavorDataObject)
1500 {
1501 case 'TEXT':
1502 if (textDataObject == NULL) // otherwise a 'utxt' flavor has already been found that gets priority compared to the 'TEXT' flavor
1503 {
1504 // variable definitions:
1505 Size nativeDataSize;
1506 wxMemoryBuffer nativeData;
1507
1508 if ((::GetFlavorDataSize(dragRef,itemRef,'TEXT',&nativeDataSize) == noErr) &&
1509 (::GetFlavorData(dragRef,itemRef,'TEXT',nativeData.GetWriteBuf(nativeDataSize),&nativeDataSize,0) == noErr))
1510 {
1511 nativeData.UngetWriteBuf(nativeDataSize);
1512 textDataObject = new wxTextDataObject();
1513 if (textDataObject->SetData(nativeData.GetDataLen(),nativeData.GetData()))
1514 dataObject->Add(textDataObject);
1515 else
1516 {
1517 delete textDataObject;
1518 textDataObject = NULL;
1519 }
1520 }
1521 } /* block */
1522 break;
1523 case 'utxt':
1524 {
1525 // variable definition:
1526 Size nativeDataSize;
1527
1528 if (::GetFlavorDataSize(dragRef,itemRef,'utxt',&nativeDataSize) == noErr)
1529 {
1530 CFMutableDataRef draggedData;
1531
1532 draggedData = ::CFDataCreateMutable(kCFAllocatorDefault,nativeDataSize);
1533 ::CFDataSetLength(draggedData,nativeDataSize);
1534 if (::GetFlavorData(dragRef,itemRef,'utxt',::CFDataGetMutableBytePtr(draggedData),&nativeDataSize,0) == noErr)
1535 {
1536 // convert internally used UTF-16 representation to a UTF-8 representation:
1537 CFDataRef osxData;
1538 CFStringRef osxString;
1539
1540 osxString = ::CFStringCreateFromExternalRepresentation(kCFAllocatorDefault,draggedData,kCFStringEncodingUTF16); // BOM character is handled by this function automatically
1541 osxData = ::CFStringCreateExternalRepresentation(kCFAllocatorDefault,osxString,kCFStringEncodingUTF8,32);
1542 if (textDataObject == NULL)
1543 {
1544 textDataObject = new wxTextDataObject();
1545 if (textDataObject->SetData(::CFDataGetLength(osxData),::CFDataGetBytePtr(osxData)))
1546 dataObject->Add(textDataObject);
1547 else
1548 {
1549 delete textDataObject;
1550 textDataObject = NULL;
1551 }
1552 }
1553 else // overwrite data because the 'utxt' flavor has priority over the 'TEXT' flavor
1554 (void) textDataObject->SetData(::CFDataGetLength(osxData),::CFDataGetBytePtr(osxData));
1555 // clean up:
1556 ::CFRelease(osxData);
1557 ::CFRelease(osxString);
1558 }
1559 // clean up:
1560 ::CFRelease(draggedData);
1561 }
1562 } /* block */
1563 break;
1564 }
1565 }
1566 }
1567 else
1568 dataObject = NULL;
1569 return dataObject;
1570} /* wxMacDataViewDataBrowserListViewControl::GetDnDDataObjects(DragReference, ItemReference) const */
1571
489468fe
SC
1572#endif // wxUSE_GENERICDATAVIEWCTRL
1573#endif // wxUSE_DATAVIEWCTRL