]>
Commit | Line | Data |
---|---|---|
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 | // ============================================================================ | |
35 | DataBrowserGetContextualMenuUPP gDataBrowserTableViewGetContextualMenuUPP = NULL; | |
36 | DataBrowserItemCompareUPP gDataBrowserTableViewItemCompareUPP = NULL; | |
37 | DataBrowserItemDataUPP gDataBrowserTableViewItemDataUPP = NULL; | |
38 | DataBrowserItemNotificationUPP gDataBrowserTableViewItemNotificationUPP = NULL; | |
39 | ||
4a3d495c RR |
40 | DataBrowserAcceptDragUPP gDataBrowserTableViewAcceptDragUPP = NULL; |
41 | DataBrowserAddDragItemUPP gDataBrowserTableViewAddDragItemUPP = NULL; | |
42 | DataBrowserReceiveDragUPP gDataBrowserTableViewReceiveDragUPP = NULL; | |
43 | ||
489468fe SC |
44 | DataBrowserDrawItemUPP gDataBrowserTableViewDrawItemUPP = NULL; |
45 | DataBrowserEditItemUPP gDataBrowserTableViewEditItemUPP = NULL; | |
46 | DataBrowserHitTestUPP gDataBrowserTableViewHitTestUPP = NULL; | |
47 | DataBrowserTrackingUPP gDataBrowserTableViewTrackingUPP = NULL; | |
48 | ||
49 | // ============================================================================ | |
50 | // wxMacDataBrowserTableViewControl | |
51 | // ============================================================================ | |
52 | ||
53 | pascal 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 | ||
64 | pascal 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 | ||
73 | pascal 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 | ||
84 | pascal 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 | ||
93 | pascal 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 | ||
102 | pascal 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 | ||
110 | pascal 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 | ||
118 | pascal 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 |
129 | pascal 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 | ||
137 | pascal 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 | ||
145 | pascal 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 |
153 | wxMacDataBrowserTableViewControl::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 | // | |
243 | OSStatus wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks const* callbacks) | |
244 | { | |
245 | return ::SetDataBrowserCallbacks(this->m_controlRef,callbacks); | |
246 | } /* wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks const*) */ | |
247 | ||
248 | OSStatus wxMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks const* customCallbacks) | |
249 | { | |
250 | return ::SetDataBrowserCustomCallbacks(this->m_controlRef,customCallbacks); | |
251 | } /* xMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks const*) */ | |
252 | ||
253 | // | |
254 | // header handling | |
255 | // | |
256 | OSStatus 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 | ||
262 | OSStatus wxMacDataBrowserTableViewControl::SetHeaderDesc(DataBrowserPropertyID propertyID, DataBrowserListViewHeaderDesc* desc) | |
263 | { | |
264 | return ::SetDataBrowserListViewHeaderDesc(this->m_controlRef,propertyID,desc); | |
265 | } | |
266 | ||
267 | // | |
268 | // layout handling | |
269 | // | |
270 | OSStatus wxMacDataBrowserTableViewControl::AutoSizeColumns() | |
271 | { | |
272 | return AutoSizeDataBrowserListViewColumns(this->m_controlRef); | |
273 | } | |
274 | ||
275 | OSStatus wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool enableHeight, bool enableWidth) | |
276 | { | |
277 | return ::SetDataBrowserTableViewGeometry(this->GetControlRef(),enableWidth,enableHeight); | |
278 | } /* wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool, bool) */ | |
279 | ||
280 | OSStatus wxMacDataBrowserTableViewControl::GetAttributes(OptionBits* attributes) | |
281 | { | |
282 | return ::DataBrowserGetAttributes(this->GetControlRef(),attributes); | |
283 | } /* wxMacDataBrowserTableViewControl::GetAttributes(OptionBits*) */ | |
284 | ||
285 | OSStatus wxMacDataBrowserTableViewControl::GetColumnWidth(DataBrowserPropertyID propertyID, UInt16* width) const | |
286 | { | |
287 | return ::GetDataBrowserTableViewNamedColumnWidth(this->m_controlRef,propertyID,width); | |
288 | } | |
289 | ||
290 | OSStatus wxMacDataBrowserTableViewControl::GetDefaultColumnWidth( UInt16 *width ) const | |
291 | { | |
292 | return GetDataBrowserTableViewColumnWidth(this->m_controlRef, width ); | |
293 | } | |
294 | ||
295 | OSStatus wxMacDataBrowserTableViewControl::GetDefaultRowHeight(UInt16* height) const | |
296 | { | |
297 | return ::GetDataBrowserTableViewRowHeight(this->m_controlRef,height); | |
298 | } | |
299 | ||
300 | OSStatus wxMacDataBrowserTableViewControl::GetHeaderButtonHeight(UInt16 *height) | |
301 | { | |
302 | return ::GetDataBrowserListViewHeaderBtnHeight(this->m_controlRef,height); | |
303 | } | |
304 | ||
305 | OSStatus 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 | ||
310 | OSStatus wxMacDataBrowserTableViewControl::GetRowHeight(DataBrowserItemID item, UInt16* height) const | |
311 | { | |
312 | return ::GetDataBrowserTableViewItemRowHeight(this->m_controlRef,item,height); | |
313 | } /* wxMacDataBrowserTableViewControl::GetRowHeight(DataBrowserItemID, UInt16*) const */ | |
314 | ||
315 | OSStatus wxMacDataBrowserTableViewControl::GetScrollPosition( UInt32 *top , UInt32 *left ) const | |
316 | { | |
317 | return GetDataBrowserScrollPosition(this->m_controlRef, top , left ); | |
318 | } | |
319 | ||
320 | OSStatus wxMacDataBrowserTableViewControl::SetAttributes(OptionBits attributes) | |
321 | { | |
322 | return ::DataBrowserChangeAttributes(this->GetControlRef(),attributes,~attributes); | |
323 | } /* wxMacDataBrowserTableViewControl::SetAttributes(OptionBits) */ | |
324 | ||
325 | OSStatus wxMacDataBrowserTableViewControl::SetColumnWidth(DataBrowserPropertyID propertyID, UInt16 width) | |
326 | { | |
327 | return ::SetDataBrowserTableViewNamedColumnWidth(this->m_controlRef,propertyID,width); | |
328 | } | |
329 | ||
330 | OSStatus wxMacDataBrowserTableViewControl::SetDefaultColumnWidth(UInt16 width) | |
331 | { | |
332 | return ::SetDataBrowserTableViewColumnWidth(this->m_controlRef,width); | |
333 | } | |
334 | ||
335 | OSStatus wxMacDataBrowserTableViewControl::SetDefaultRowHeight(UInt16 height) | |
336 | { | |
337 | return ::SetDataBrowserTableViewRowHeight(this->m_controlRef,height); | |
338 | } | |
339 | ||
340 | OSStatus wxMacDataBrowserTableViewControl::SetHasScrollBars(bool horiz, bool vert) | |
341 | { | |
342 | return ::SetDataBrowserHasScrollBars(this->m_controlRef,horiz,vert); | |
343 | } /* wxMacDataBrowserTableViewControl::SetHasScrollBars(bool, bool) */ | |
344 | ||
345 | OSStatus wxMacDataBrowserTableViewControl::SetHeaderButtonHeight(UInt16 height) | |
346 | { | |
347 | return ::SetDataBrowserListViewHeaderBtnHeight(this->m_controlRef,height); | |
348 | } /* wxMacDataBrowserTableViewControl::SetHeaderButtonHeight(UInt16) */ | |
349 | ||
350 | OSStatus wxMacDataBrowserTableViewControl::SetHiliteStyle(DataBrowserTableViewHiliteStyle hiliteStyle) | |
351 | { | |
352 | return ::SetDataBrowserTableViewHiliteStyle(this->m_controlRef,hiliteStyle); | |
353 | } /*wxMacDataBrowserTableViewControl::SetHiliteStyle(DataBrowserTableViewHiliteStyle) */ | |
354 | ||
355 | OSStatus wxMacDataBrowserTableViewControl::SetIndent(float Indent) | |
356 | { | |
357 | return ::DataBrowserSetMetric(this->m_controlRef,kDataBrowserMetricDisclosureColumnPerDepthGap,true,Indent); | |
358 | } /* wxMacDataBrowserTableViewControl::SetIndent(float* Indent) */ | |
359 | ||
360 | OSStatus wxMacDataBrowserTableViewControl::SetRowHeight(DataBrowserItemID item, UInt16 height) | |
361 | { | |
362 | return ::SetDataBrowserTableViewItemRowHeight(this->m_controlRef,item,height); | |
363 | } | |
364 | ||
365 | OSStatus wxMacDataBrowserTableViewControl::SetScrollPosition(UInt32 top, UInt32 left) | |
366 | { | |
367 | return ::SetDataBrowserScrollPosition(this->m_controlRef,top,left); | |
368 | } | |
369 | ||
370 | // | |
371 | // column handling | |
372 | // | |
373 | OSStatus wxMacDataBrowserTableViewControl::GetColumnCount(UInt32* numColumns) const | |
374 | { | |
375 | return ::GetDataBrowserTableViewColumnCount(this->m_controlRef,numColumns); | |
376 | } | |
377 | ||
378 | OSStatus wxMacDataBrowserTableViewControl::GetColumnIndex(DataBrowserPropertyID propertyID, DataBrowserTableViewColumnIndex* index) const | |
379 | { | |
380 | return ::GetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,index); | |
381 | } /* wxMacDataBrowserTableViewControl::GetColumnIndex(DataBrowserPropertyID, DataBrowserTableViewColumnIndex*) const */ | |
382 | ||
383 | OSStatus 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 | ||
391 | OSStatus wxMacDataBrowserTableViewControl::GetPropertyFlags(DataBrowserPropertyID propertyID, DataBrowserPropertyFlags *flags) const | |
392 | { | |
393 | return ::GetDataBrowserPropertyFlags(this->m_controlRef,propertyID,flags); | |
394 | } | |
395 | ||
396 | OSStatus wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserItemDataRef itemData, DataBrowserPropertyID* propertyID) | |
397 | { | |
398 | return ::GetDataBrowserItemDataProperty(itemData,propertyID); | |
399 | } /* wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserItemDataRef, DataBrowserPropertyID*) */ | |
400 | ||
401 | OSStatus wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserTableViewColumnIndex index, DataBrowserTableViewColumnID* propertyID) | |
402 | { | |
403 | return ::GetDataBrowserTableViewColumnProperty(this->m_controlRef,index,propertyID); | |
404 | } /* wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserTableViewColumnIndex, DataBrowserTableViewColumnID*) */ | |
405 | ||
406 | OSStatus 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 | ||
416 | OSStatus wxMacDataBrowserTableViewControl::RemoveColumnByProperty(DataBrowserTableViewColumnID propertyID) | |
417 | { | |
418 | return ::RemoveDataBrowserTableViewColumn(this->m_controlRef,propertyID); | |
419 | } /* wxMacDataBrowserTableViewControl::RemoveColumnByProperty(DataBrowserTableViewColumnID) */ | |
420 | ||
421 | OSStatus 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 | ||
430 | OSStatus wxMacDataBrowserTableViewControl::SetColumnIndex(DataBrowserPropertyID propertyID, DataBrowserTableViewColumnIndex index) | |
431 | { | |
432 | return ::SetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,index); | |
433 | } /* wxMacDataBrowserTableViewControl::SetColumnIndex(DataBrowserPropertyID, DataBrowserTableViewColumnIndex) */ | |
434 | ||
435 | OSStatus wxMacDataBrowserTableViewControl::SetDisclosureColumn(DataBrowserPropertyID propertyID, Boolean expandableRows) | |
436 | { | |
437 | return ::SetDataBrowserListViewDisclosureColumn(this->m_controlRef,propertyID,expandableRows); | |
438 | } | |
439 | ||
440 | OSStatus 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 | // | |
448 | OSStatus 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 | ||
453 | OSStatus 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 | ||
483 | OSStatus 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 | ||
488 | OSStatus wxMacDataBrowserTableViewControl::GetItemID( DataBrowserTableViewRowIndex row, DataBrowserItemID * item ) const | |
489 | { | |
490 | return GetDataBrowserTableViewItemID(this->m_controlRef,row,item); | |
491 | } | |
492 | ||
493 | OSStatus 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 | ||
498 | OSStatus wxMacDataBrowserTableViewControl::GetItemRow(DataBrowserItemID item, DataBrowserTableViewRowIndex* row) const | |
499 | { | |
500 | return GetDataBrowserTableViewItemRow(this->m_controlRef,item,row); | |
501 | } | |
502 | ||
503 | OSStatus 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 | ||
513 | OSStatus wxMacDataBrowserTableViewControl::RemoveItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty) | |
514 | { | |
515 | return ::RemoveDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty); | |
516 | } | |
517 | ||
518 | OSStatus 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 | ||
523 | OSStatus 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 | // | |
532 | size_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 | ||
556 | OSStatus wxMacDataBrowserTableViewControl::GetSelectionAnchor(DataBrowserItemID* first, DataBrowserItemID* last) const | |
557 | { | |
558 | return ::GetDataBrowserSelectionAnchor(this->m_controlRef,first,last); | |
559 | } /* wxMacDataBrowserTableViewControl::GetSelectionAnchor(DataBrowserItemID*, DataBrowserItemID*) const */ | |
560 | ||
561 | OSStatus wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags* flags) const | |
562 | { | |
563 | return ::GetDataBrowserSelectionFlags(this->m_controlRef,flags); | |
564 | } /* wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags*) const */ | |
565 | ||
566 | bool wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID item) const | |
567 | { | |
568 | return ::IsDataBrowserItemSelected(this->m_controlRef,item); | |
569 | } /* wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID) const */ | |
570 | ||
571 | OSStatus wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags flags) | |
572 | { | |
573 | return ::SetDataBrowserSelectionFlags(this->m_controlRef,flags); | |
574 | } /* wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags) */ | |
575 | ||
576 | OSStatus 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 | ||
581 | OSStatus wxMacDataBrowserTableViewControl::GetSortOrder(DataBrowserSortOrder* order) const | |
582 | { | |
583 | return ::GetDataBrowserSortOrder(this->m_controlRef,order); | |
584 | } | |
585 | ||
586 | OSStatus wxMacDataBrowserTableViewControl::GetSortProperty(DataBrowserPropertyID* propertyID) const | |
587 | { | |
588 | return ::GetDataBrowserSortProperty(this->m_controlRef,propertyID); | |
589 | } | |
590 | ||
591 | OSStatus wxMacDataBrowserTableViewControl::Resort(DataBrowserItemID container, Boolean sortChildren) | |
592 | { | |
593 | return ::SortDataBrowserContainer(this->m_controlRef,container,sortChildren); | |
594 | } /* wxMacDataBrowserTableViewControl::Resort(DataBrowserItemID, Boolean) */ | |
595 | ||
596 | OSStatus wxMacDataBrowserTableViewControl::SetSortOrder(DataBrowserSortOrder order) | |
597 | { | |
598 | return ::SetDataBrowserSortOrder(this->m_controlRef,order); | |
599 | } | |
600 | ||
601 | OSStatus wxMacDataBrowserTableViewControl::SetSortProperty(DataBrowserPropertyID propertyID) | |
602 | { | |
603 | return ::SetDataBrowserSortProperty(this->m_controlRef,propertyID); | |
604 | } | |
605 | ||
606 | // | |
607 | // container handling | |
608 | // | |
609 | OSStatus wxMacDataBrowserTableViewControl::CloseContainer(DataBrowserItemID containerID) | |
610 | { | |
611 | return ::CloseDataBrowserContainer(this->m_controlRef,containerID); | |
612 | } /* wxMacDataBrowserTableViewControl::CloseContainer(DataBrowserItemID) */ | |
613 | ||
614 | OSStatus wxMacDataBrowserTableViewControl::OpenContainer(DataBrowserItemID containerID) | |
615 | { | |
616 | return ::OpenDataBrowserContainer(this->m_controlRef,containerID); | |
617 | } /* wxMacDataBrowserTableViewControl::OpenContainer(DataBrowserItemID) */ | |
618 | ||
619 | IMPLEMENT_ABSTRACT_CLASS(wxMacDataBrowserTableViewControl,wxMacControl) | |
620 | ||
621 | // ============================================================================ | |
622 | // wxMacDataBrowserListViewControl | |
623 | // ============================================================================ | |
624 | #pragma mark - | |
625 | // | |
626 | // column handling | |
627 | // | |
628 | OSStatus 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 | // | |
640 | wxMacDataViewDataBrowserListViewControl::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 | // | |
648 | Boolean 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 | ||
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. | |
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 | ||
700 | OSStatus 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 | ||
871 | void 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 | ||
1033 | void wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemState state, Rect const* rectangle, SInt16 bitDepth, Boolean colorDevice) | |
1034 | { | |
1035 | DataBrowserTableViewColumnIndex columnIndex; | |
1036 | ||
1037 | wxDataViewColumn* dataViewColumnPtr; | |
1038 | ||
1039 | wxDataViewCtrl* dataViewCtrlPtr; | |
1040 | ||
1041 | wxDataViewCustomRenderer* dataViewCustomRendererPtr; | |
1042 | ||
1043 | wxVariant dataToRender; | |
1044 | ||
b2680ced | 1045 | dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetWXPeer()); |
489468fe SC |
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); | |
1055 | ||
1056 | wxDataViewItem dataitem( reinterpret_cast<void*>(itemID) ); | |
1057 | dataViewCtrlPtr->GetModel()->GetValue(dataToRender,dataitem,dataViewColumnPtr->GetModelColumn()); | |
1058 | dataViewCustomRendererPtr->SetValue(dataToRender); | |
1059 | ||
1060 | // try to determine the content's size (drawable part): | |
1061 | Rect content; | |
f215225d SC |
1062 | HIShapeRef rgn = NULL; |
1063 | ||
489468fe SC |
1064 | UInt16 headerHeight; |
1065 | ||
f215225d SC |
1066 | if ( HIViewCopyShape(m_controlRef, kHIViewContentMetaPart, &rgn) == noErr) |
1067 | { | |
1068 | CGRect cgrect; | |
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 }; | |
1071 | CFRelease(rgn); | |
1072 | } | |
489468fe | 1073 | else |
b2680ced | 1074 | GetControlBounds(m_controlRef, &content); |
489468fe SC |
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) | |
1079 | content.top += 5; | |
1080 | content.left += 5; | |
1081 | content.right -= 3; | |
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); | |
1086 | ||
1087 | wxDC *dc = dataViewCustomRendererPtr->GetDC(); | |
1088 | ||
1089 | wxRect cellrect( static_cast<int>(rectangle->left), | |
3f407e4f | 1090 | static_cast<int>(rectangle->top), |
489468fe SC |
1091 | static_cast<int>(1+rectangle->right-rectangle->left), |
1092 | static_cast<int>(rectangle->bottom-rectangle->top) ); | |
1093 | ||
1094 | bool is_active = IsControlActive( this->m_controlRef ); | |
1095 | if (state == kDataBrowserItemIsSelected) | |
1096 | { | |
1097 | ||
1098 | wxColour col( wxMacCreateCGColorFromHITheme( (is_active) ? | |
1099 | kThemeBrushAlternatePrimaryHighlightColor | |
1100 | : kThemeBrushSecondaryHighlightColor ) ); | |
1101 | ||
1102 | wxRect rect = cellrect; | |
1103 | Rect itemrect; | |
1104 | GetDataBrowserItemPartBounds( this->m_controlRef, itemID, propertyID, | |
1105 | kDataBrowserPropertyEnclosingPart, &itemrect ); | |
1106 | rect.x = itemrect.left; | |
1107 | rect.width = itemrect.right-itemrect.left+1; | |
1108 | ||
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 ); | |
1117 | } | |
1118 | ||
1119 | wxDataViewModel *model = dataViewCtrlPtr->GetModel(); | |
1120 | if ((columnIndex == 0) || !model->IsContainer(dataitem) || model->HasContainerColumns(dataitem)) | |
1121 | { | |
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 | |
1127 | } | |
1128 | ||
1129 | dataViewCustomRendererPtr->SetDC(NULL); | |
1130 | } /* wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemState, Rect const*, SInt16, Boolean) */ | |
1131 | ||
1132 | Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserEditItemProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, CFStringRef theString, Rect* maxEditTextRect, Boolean* shrinkToFit) | |
1133 | { | |
1134 | return false; | |
1135 | } /* wxMacDataViewDataBrowserListViewControl::DataBrowserEditItemProc(DataBrowserItemID, DataBrowserPropertyID, CFStringRef, Rect*, Boolean*) */ | |
1136 | ||
1137 | Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserHitTestProc(DataBrowserItemID WXUNUSED(itemID), DataBrowserPropertyID WXUNUSED(property), Rect const* WXUNUSED(theRect), Rect const* WXUNUSED(mouseRect)) | |
1138 | { | |
1139 | return true; | |
1140 | } /* wxMacDataViewDataBrowserListViewControl::DataBrowserHitTestProc(DataBrowserItemID, DataBrowserPropertyID, Rect const*, Rect const*) */ | |
1141 | ||
1142 | DataBrowserTrackingResult wxMacDataViewDataBrowserListViewControl::DataBrowserTrackingProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, Rect const* theRect, Point WXUNUSED(startPt), EventModifiers WXUNUSED(modifiers)) | |
1143 | { | |
1144 | wxDataViewColumn* dataViewColumnPtr; | |
1145 | ||
1146 | wxDataViewCtrl* dataViewCtrlPtr; | |
1147 | ||
1148 | wxDataViewCustomRenderer* dataViewCustomRendererPtr; | |
1149 | ||
1150 | wxDataViewItem dataViewCustomRendererItem; | |
1151 | ||
1152 | ||
4a3d495c RR |
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.")); | |
489468fe SC |
1156 | dataViewCustomRendererItem = reinterpret_cast<void*>(itemID); |
1157 | wxCHECK_MSG(dataViewCustomRendererItem.IsOk(),kDataBrowserNothingHit,_("Invalid data view item")); | |
489468fe SC |
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) | |
1167 | { | |
1168 | dataViewCtrlPtr->GetCustomRendererPtr()->FinishEditing(); | |
1169 | dataViewCtrlPtr->SetCustomRendererItem(wxDataViewItem()); | |
1170 | dataViewCtrlPtr->SetCustomRendererPtr (NULL); | |
4a3d495c | 1171 | } |
489468fe SC |
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()) | |
1174 | { | |
1175 | // variable definition: | |
1176 | wxRect wxRectangle; | |
1177 | ||
1178 | ::wxMacNativeToRect(theRect,&wxRectangle); | |
1179 | dataViewCustomRendererPtr->StartEditing(dataViewCustomRendererItem,wxRectangle); | |
1180 | dataViewCtrlPtr->SetCustomRendererItem(dataViewCustomRendererItem); | |
1181 | dataViewCtrlPtr->SetCustomRendererPtr (dataViewCustomRendererPtr); | |
4a3d495c | 1182 | } |
489468fe SC |
1183 | return kDataBrowserContentHit; |
1184 | } /* wxMacDataViewDataBrowserListViewControl::DataBrowserTrackingProc(DataBrowserItemID, DataBrowserPropertyID, Rect const*, Point, EventModifiers) */ | |
1185 | ||
4a3d495c RR |
1186 | Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserAcceptDragProc(DragReference dragRef, DataBrowserItemID itemID) |
1187 | { | |
1188 | UInt16 noOfDraggedItems; | |
1189 | ||
1190 | wxDataViewCtrl* dataViewCtrlPtr; | |
1191 | ||
1192 | ||
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.")); | |
1196 | ||
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) | |
1200 | { | |
1201 | // collect native information: | |
1202 | ItemReference itemRef; | |
1203 | wxDataObjectComposite* dataObjects; | |
1204 | wxMemoryBuffer buffer; | |
1205 | ||
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()); | |
1210 | ||
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) | |
1218 | { | |
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()); | |
1223 | } | |
1224 | ||
1225 | // send event: | |
1226 | if (!(dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed())) | |
1227 | return false; | |
1228 | } | |
1229 | return true; | |
1230 | } /* wxMacDataViewDataBrowserListViewControl::DataBrowserAcceptDragProc(DragReference, DataBrowserItemID) */ | |
1231 | ||
1232 | Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserAddDragItemProc(DragReference dragRef, DataBrowserItemID itemID, ItemReference* itemRef) | |
1233 | { | |
1234 | wxDataViewCtrl* dataViewCtrlPtr; | |
1235 | ||
1236 | wxDataViewItem dataViewItem; | |
1237 | ||
1238 | ||
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")); | |
1244 | ||
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()); | |
1247 | ||
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 | |
1256 | ||
1257 | for (size_t i=0; i<dataViewCtrlPtr->GetColumnCount(); i++) | |
1258 | { | |
1259 | // variable definition: | |
1260 | wxVariant dataValue; | |
1261 | ||
1262 | dataViewCtrlPtr->GetModel()->GetValue(dataValue,dataViewItem,dataViewCtrlPtr->GetColumn(i)->GetModelColumn()); | |
1263 | if (i > 0) | |
1264 | dataString << wxT('\t'); | |
1265 | dataString << dataValue.MakeString(); | |
1266 | } | |
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()) | |
1271 | { | |
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) | |
1282 | { | |
1283 | // constant definition for abbreviational purposes: | |
1284 | size_t const noOfFormats = dataViewEvent.GetDataObject()->GetFormatCount(); | |
1285 | ||
1286 | if (noOfFormats > 0) | |
1287 | { | |
1288 | // variable definition: | |
1289 | wxDataFormat* dataFormats; | |
1290 | ||
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()) | |
1295 | { | |
1296 | case wxDF_INVALID: | |
1297 | wxFAIL_MSG(_("Data object has invalid data format")); | |
1298 | break; | |
1299 | case wxDF_TEXT: | |
1300 | { | |
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); | |
1305 | ||
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")); | |
1310 | } /* block */ | |
1311 | break; | |
1312 | case wxDF_UNICODETEXT: | |
1313 | { | |
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); | |
1318 | ||
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)); | |
1325 | ||
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")); | |
1331 | // clean up: | |
1332 | ::CFRelease(osxData); | |
1333 | ::CFRelease(osxString); | |
1334 | } /* block */ | |
1335 | break; | |
1336 | case wxDF_BITMAP: | |
1337 | case wxDF_METAFILE: | |
1338 | case wxDF_SYLK: | |
1339 | case wxDF_DIF: | |
1340 | case wxDF_TIFF: | |
1341 | case wxDF_OEMTEXT: | |
1342 | case wxDF_DIB: | |
1343 | case wxDF_PALETTE: | |
1344 | case wxDF_PENDATA: | |
1345 | case wxDF_RIFF: | |
1346 | case wxDF_WAVE: | |
1347 | case wxDF_ENHMETAFILE: | |
1348 | case wxDF_FILENAME: | |
1349 | case wxDF_LOCALE: | |
1350 | case wxDF_PRIVATE: | |
1351 | case wxDF_HTML: | |
1352 | break; // not (yet) supported data formats | |
1353 | default: | |
1354 | wxFAIL_MSG(_("Unknown data format")); | |
1355 | } | |
1356 | delete[] dataFormats; | |
1357 | } | |
1358 | } | |
1359 | return true; | |
1360 | } | |
1361 | else | |
1362 | return false; | |
1363 | } /* wxMacDataViewDataBrowserListViewControl::DataBrowserAddDragItemProc(DragReference, DataBrowserItemID, ItemReference*) */ | |
1364 | ||
1365 | Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserReceiveDragProc(DragReference dragRef, DataBrowserItemID itemID) | |
1366 | { | |
1367 | UInt16 noOfDraggedItems; | |
1368 | ||
1369 | wxDataViewCtrl* dataViewCtrlPtr; | |
1370 | ||
1371 | ||
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.")); | |
1375 | ||
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) | |
1379 | { | |
1380 | // collect native information: | |
1381 | ItemReference itemRef; | |
1382 | wxDataObjectComposite* dataObjects; | |
1383 | wxMemoryBuffer buffer; | |
1384 | ||
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()); | |
1389 | ||
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) | |
1397 | { | |
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()); | |
1402 | } | |
1403 | ||
1404 | // send event: | |
1405 | if (!(dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed())) | |
1406 | return false; | |
1407 | } | |
1408 | return true; | |
1409 | } /* wxMacDataViewDataBrowserListViewControl::DataBrowserReceiveDragProc(DragReference, DataBrowserItemID) */ | |
1410 | ||
1411 | // | |
1412 | // drag & drop helper methods | |
1413 | // | |
1414 | wxDataFormat wxMacDataViewDataBrowserListViewControl::GetDnDDataFormat(wxDataObjectComposite* dataObjects) | |
1415 | { | |
1416 | wxDataFormat resultFormat; | |
1417 | ||
1418 | ||
1419 | if (dataObjects != NULL) | |
1420 | { | |
1421 | bool compatible(true); | |
1422 | ||
1423 | size_t const noOfFormats = dataObjects->GetFormatCount(); | |
1424 | size_t indexFormat; | |
1425 | ||
1426 | wxDataFormat* formats; | |
1427 | ||
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); | |
1434 | indexFormat = 0; | |
1435 | while ((indexFormat < noOfFormats) && compatible) | |
1436 | { | |
1437 | switch (resultFormat.GetType()) | |
1438 | { | |
1439 | case wxDF_INVALID: | |
1440 | resultFormat.SetType(formats[indexFormat].GetType()); // first format (should only be reached if indexFormat == 0 | |
1441 | break; | |
1442 | case wxDF_TEXT: | |
1443 | if (formats[indexFormat].GetType() == wxDF_UNICODETEXT) | |
1444 | resultFormat.SetType(wxDF_UNICODETEXT); | |
1445 | else // incompatible | |
1446 | { | |
1447 | resultFormat.SetType(wxDF_INVALID); | |
1448 | compatible = false; | |
1449 | } | |
1450 | break; | |
1451 | case wxDF_UNICODETEXT: | |
1452 | if (formats[indexFormat].GetType() != wxDF_TEXT) | |
1453 | { | |
1454 | resultFormat.SetType(wxDF_INVALID); | |
1455 | compatible = false; | |
1456 | } | |
1457 | break; | |
1458 | default: | |
1459 | resultFormat.SetType(wxDF_INVALID); // not (yet) supported format | |
1460 | compatible = false; | |
1461 | } | |
1462 | ++indexFormat; | |
1463 | } /* while */ | |
1464 | // clean up: | |
1465 | delete[] formats; | |
1466 | } | |
1467 | return resultFormat; | |
1468 | } /* wxMacDataViewDataBrowserListViewControl::GetDnDDataFormat(wxDataObjectComposite*) */ | |
1469 | ||
1470 | wxDataObjectComposite* wxMacDataViewDataBrowserListViewControl::GetDnDDataObjects(DragReference dragRef, ItemReference itemRef) const | |
1471 | { | |
1472 | UInt16 noOfFlavors; | |
1473 | ||
1474 | wxDataObjectComposite* dataObject; | |
1475 | ||
1476 | ||
1477 | ::CountDragItemFlavors(dragRef,itemRef,&noOfFlavors); | |
1478 | if (noOfFlavors > 0) | |
1479 | { | |
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); | |
1482 | ||
1483 | dataObject = new wxDataObjectComposite(); | |
1484 | for (UInt16 indexFlavor=1; indexFlavor<=noOfFlavors; ++indexFlavor) | |
1485 | { | |
1486 | // variable definition: | |
1487 | FlavorType flavorDataObject; | |
1488 | ||
1489 | if (::GetFlavorType(dragRef,itemRef,indexFlavor,&flavorDataObject) == noErr) // GetFlavorType uses a 1 based index! | |
1490 | switch (flavorDataObject) | |
1491 | { | |
1492 | case 'TEXT': | |
1493 | if (textDataObject == NULL) // otherwise a 'utxt' flavor has already been found that gets priority compared to the 'TEXT' flavor | |
1494 | { | |
1495 | // variable definitions: | |
1496 | Size nativeDataSize; | |
1497 | wxMemoryBuffer nativeData; | |
1498 | ||
1499 | if ((::GetFlavorDataSize(dragRef,itemRef,'TEXT',&nativeDataSize) == noErr) && | |
1500 | (::GetFlavorData(dragRef,itemRef,'TEXT',nativeData.GetWriteBuf(nativeDataSize),&nativeDataSize,0) == noErr)) | |
1501 | { | |
1502 | nativeData.UngetWriteBuf(nativeDataSize); | |
1503 | textDataObject = new wxTextDataObject(); | |
1504 | if (textDataObject->SetData(nativeData.GetDataLen(),nativeData.GetData())) | |
1505 | dataObject->Add(textDataObject); | |
1506 | else | |
1507 | { | |
1508 | delete textDataObject; | |
1509 | textDataObject = NULL; | |
1510 | } | |
1511 | } | |
1512 | } /* block */ | |
1513 | break; | |
1514 | case 'utxt': | |
1515 | { | |
1516 | // variable definition: | |
1517 | Size nativeDataSize; | |
1518 | ||
1519 | if (::GetFlavorDataSize(dragRef,itemRef,'utxt',&nativeDataSize) == noErr) | |
1520 | { | |
1521 | CFMutableDataRef draggedData; | |
1522 | ||
1523 | draggedData = ::CFDataCreateMutable(kCFAllocatorDefault,nativeDataSize); | |
1524 | ::CFDataSetLength(draggedData,nativeDataSize); | |
1525 | if (::GetFlavorData(dragRef,itemRef,'utxt',::CFDataGetMutableBytePtr(draggedData),&nativeDataSize,0) == noErr) | |
1526 | { | |
1527 | // convert internally used UTF-16 representation to a UTF-8 representation: | |
1528 | CFDataRef osxData; | |
1529 | CFStringRef osxString; | |
1530 | ||
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) | |
1534 | { | |
1535 | textDataObject = new wxTextDataObject(); | |
1536 | if (textDataObject->SetData(::CFDataGetLength(osxData),::CFDataGetBytePtr(osxData))) | |
1537 | dataObject->Add(textDataObject); | |
1538 | else | |
1539 | { | |
1540 | delete textDataObject; | |
1541 | textDataObject = NULL; | |
1542 | } | |
1543 | } | |
1544 | else // overwrite data because the 'utxt' flavor has priority over the 'TEXT' flavor | |
1545 | (void) textDataObject->SetData(::CFDataGetLength(osxData),::CFDataGetBytePtr(osxData)); | |
1546 | // clean up: | |
1547 | ::CFRelease(osxData); | |
1548 | ::CFRelease(osxString); | |
1549 | } | |
1550 | // clean up: | |
1551 | ::CFRelease(draggedData); | |
1552 | } | |
1553 | } /* block */ | |
1554 | break; | |
1555 | } | |
1556 | } | |
1557 | } | |
1558 | else | |
1559 | dataObject = NULL; | |
1560 | return dataObject; | |
1561 | } /* wxMacDataViewDataBrowserListViewControl::GetDnDDataObjects(DragReference, ItemReference) const */ | |
1562 | ||
489468fe SC |
1563 | #endif // wxUSE_GENERICDATAVIEWCTRL |
1564 | #endif // wxUSE_DATAVIEWCTRL |