]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/databrow.cpp
Call ValueChanged after SetValue so other views will be updated
[wxWidgets.git] / src / mac / carbon / databrow.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/databrow.cpp
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"
26 #include "wx/mac/carbon/databrow.h"
27 #include "wx/mac/private.h"
28 #include "wx/mac/uma.h"
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
40 DataBrowserDrawItemUPP gDataBrowserTableViewDrawItemUPP = NULL;
41 DataBrowserEditItemUPP gDataBrowserTableViewEditItemUPP = NULL;
42 DataBrowserHitTestUPP gDataBrowserTableViewHitTestUPP = NULL;
43 DataBrowserTrackingUPP gDataBrowserTableViewTrackingUPP = NULL;
44
45 // ============================================================================
46 // wxMacDataBrowserTableViewControl
47 // ============================================================================
48
49 pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserCompareProc(ControlRef browser, DataBrowserItemID itemOneID, DataBrowserItemID itemTwoID, DataBrowserPropertyID sortProperty)
50 {
51 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
52
53
54 if (ControlPtr != NULL)
55 return ControlPtr->DataBrowserCompareProc(itemOneID,itemTwoID,sortProperty);
56 else
57 return errDataBrowserPropertyNotSupported;
58 } /* wxMacDataBrowserTableViewControl::DataBrowserCompareProc(ControlRef, DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID) */
59
60 pascal void wxMacDataBrowserTableViewControl::DataBrowserGetContextualMenuProc(ControlRef browser, MenuRef* menu, UInt32* helpType, CFStringRef* helpItemString, AEDesc* selection)
61 {
62 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
63
64
65 if (ControlPtr != NULL)
66 ControlPtr->DataBrowserGetContextualMenuProc(menu,helpType,helpItemString,selection);
67 } /* wxMacDataBrowserTableViewControl::DataBrowserGetContextualMenuProc(ControlRef, MenuRef*, UInt32*, CFStringRef*, AEDesc*) */
68
69 pascal OSStatus wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemDataRef itemData, Boolean getValue)
70 {
71 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
72
73
74 if (ControlPtr != NULL)
75 return ControlPtr->DataBrowserGetSetItemDataProc(itemID,propertyID,itemData,getValue);
76 else
77 return errDataBrowserPropertyNotSupported;
78 } /* wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemDataRef, Boolean) */
79
80 pascal void wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserItemNotification message, DataBrowserItemDataRef itemData)
81 {
82 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
83
84
85 if (ControlPtr != NULL)
86 ControlPtr->DataBrowserItemNotificationProc(itemID,message,itemData);
87 } /* wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc(ControlRef, DataBrowserItemID, DataBrowserItemNotification, DataBrowserItemDataRef) */
88
89 pascal void wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemState state, Rect const* rectangle, SInt16 bitDepth, Boolean colorDevice)
90 {
91 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
92
93
94 if (ControlPtr != NULL)
95 ControlPtr->DataBrowserDrawItemProc(itemID,propertyID,state,rectangle,bitDepth,colorDevice);
96 } /* wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemState, Rect const*, SInt16, Boolean) */
97
98 pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserEditItemProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, CFStringRef theString, Rect* maxEditTextRect, Boolean* shrinkToFit)
99 {
100 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
101
102
103 return ((ControlPtr != NULL) && ControlPtr->DataBrowserEditItemProc(itemID,propertyID,theString,maxEditTextRect,shrinkToFit));
104 } /* wxMacDataBrowserTableViewControl::DataBrowserEditItemProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, CFStringRef, Rect*, Boolean*) */
105
106 pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserHitTestProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, Rect const* theRect, Rect const* mouseRect)
107 {
108 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
109
110
111 return ((ControlPtr != NULL) && ControlPtr->DataBrowserHitTestProc(itemID,propertyID,theRect,mouseRect));
112 } /* wxMacDataBrowserTableViewControl::DataBrowserHitTestProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, Rect const*, Rect const*) */
113
114 pascal DataBrowserTrackingResult wxMacDataBrowserTableViewControl::DataBrowserTrackingProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, Rect const* theRect, Point startPt, EventModifiers modifiers)
115 {
116 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
117
118
119 if (ControlPtr != NULL)
120 return ControlPtr->DataBrowserTrackingProc(itemID,propertyID,theRect,startPt,modifiers);
121 else
122 return kDataBrowserNothingHit;
123 } /* wxMacDataBrowserTableViewControl::DataBrowserTrackingProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, Rect const*, Point, EventModifiers) */
124
125 wxMacDataBrowserTableViewControl::wxMacDataBrowserTableViewControl(wxWindow* peer, wxPoint const& pos, wxSize const& size, long style)
126 :wxMacControl(peer)
127 {
128 Rect bounds = wxMacGetBoundsForControl(peer,pos,size);
129 OSStatus err = ::CreateDataBrowserControl(MAC_WXHWND(peer->MacGetTopLevelWindowRef()),&bounds,kDataBrowserListView,&(this->m_controlRef));
130
131
132 SetReferenceInNativeControl();
133 verify_noerr(err);
134 // setup standard callbacks:
135 if (gDataBrowserTableViewGetContextualMenuUPP == NULL) gDataBrowserTableViewGetContextualMenuUPP = NewDataBrowserGetContextualMenuUPP(wxMacDataBrowserTableViewControl::DataBrowserGetContextualMenuProc);
136 if (gDataBrowserTableViewItemCompareUPP == NULL) gDataBrowserTableViewItemCompareUPP = NewDataBrowserItemCompareUPP (wxMacDataBrowserTableViewControl::DataBrowserCompareProc);
137 if (gDataBrowserTableViewItemDataUPP == NULL) gDataBrowserTableViewItemDataUPP = NewDataBrowserItemDataUPP (wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc);
138 if (gDataBrowserTableViewItemNotificationUPP == NULL)
139 {
140 gDataBrowserTableViewItemNotificationUPP =
141 #if TARGET_API_MAC_OSX
142 (DataBrowserItemNotificationUPP) NewDataBrowserItemNotificationWithItemUPP(wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc);
143 #else
144 NewDataBrowserItemNotificationUPP(wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc);
145 #endif
146 }
147 DataBrowserCallbacks callbacks; // variable definition
148
149 InitializeDataBrowserCallbacks(&callbacks,kDataBrowserLatestCallbacks);
150 callbacks.u.v1.getContextualMenuCallback = gDataBrowserTableViewGetContextualMenuUPP;
151 callbacks.u.v1.itemDataCallback = gDataBrowserTableViewItemDataUPP;
152 callbacks.u.v1.itemCompareCallback = gDataBrowserTableViewItemCompareUPP;
153 callbacks.u.v1.itemNotificationCallback = gDataBrowserTableViewItemNotificationUPP;
154 this->SetCallbacks(&callbacks);
155
156 // setup callbacks for customized items:
157 if (gDataBrowserTableViewDrawItemUPP == NULL) gDataBrowserTableViewDrawItemUPP = NewDataBrowserDrawItemUPP(wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc);
158 if (gDataBrowserTableViewEditItemUPP == NULL) gDataBrowserTableViewEditItemUPP = NewDataBrowserEditItemUPP(wxMacDataBrowserTableViewControl::DataBrowserEditItemProc);
159 if (gDataBrowserTableViewHitTestUPP == NULL) gDataBrowserTableViewHitTestUPP = NewDataBrowserHitTestUPP (wxMacDataBrowserTableViewControl::DataBrowserHitTestProc);
160 if (gDataBrowserTableViewTrackingUPP == NULL) gDataBrowserTableViewTrackingUPP = NewDataBrowserTrackingUPP(wxMacDataBrowserTableViewControl::DataBrowserTrackingProc);
161
162 DataBrowserCustomCallbacks customCallbacks; // variable definition
163
164 InitializeDataBrowserCustomCallbacks(&customCallbacks,kDataBrowserLatestCallbacks);
165 customCallbacks.u.v1.drawItemCallback = gDataBrowserTableViewDrawItemUPP;
166 customCallbacks.u.v1.editTextCallback = gDataBrowserTableViewEditItemUPP;
167 customCallbacks.u.v1.hitTestCallback = gDataBrowserTableViewHitTestUPP;
168 customCallbacks.u.v1.trackingCallback = gDataBrowserTableViewTrackingUPP;
169 this->SetCustomCallbacks(&customCallbacks);
170
171 // style setting:
172 this->EnableCellSizeModification();
173
174 DataBrowserSelectionFlags flags; // variable definition
175
176 if (this->GetSelectionFlags(&flags) == noErr) // get default settings
177 {
178 if ((style & wxDV_MULTIPLE) != 0)
179 flags &= ~kDataBrowserSelectOnlyOne;
180 else
181 flags |= kDataBrowserSelectOnlyOne;
182 (void) this->SetSelectionFlags(flags);
183 } /* if */
184
185 OptionBits attributes; // variable definition
186
187 if (this->GetAttributes(&attributes) == noErr) // get default settings
188 {
189 if ((style & wxDV_VERT_RULES) != 0)
190 attributes |= kDataBrowserAttributeListViewDrawColumnDividers;
191 else
192 attributes &= ~kDataBrowserAttributeListViewDrawColumnDividers;
193 if ((style & wxDV_ROW_LINES) != 0)
194 attributes |= kDataBrowserAttributeListViewAlternatingRowColors;
195 else
196 attributes &= ~kDataBrowserAttributeListViewAlternatingRowColors;
197 (void) this->SetAttributes(attributes);
198 } /* if */
199
200 if ((style & wxDV_NO_HEADER) != 0)
201 this->SetHeaderButtonHeight(0);
202 } /* wxMacDataBrowserTableViewControl::wxMacDataBrowserTableViewControl(wxWindow*, wxPoint const&, wxSize const&, long) */
203
204 //
205 // callback handling
206 //
207 OSStatus wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks const* callbacks)
208 {
209 return ::SetDataBrowserCallbacks(this->m_controlRef,callbacks);
210 } /* wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks const*) */
211
212 OSStatus wxMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks const* customCallbacks)
213 {
214 return ::SetDataBrowserCustomCallbacks(this->m_controlRef,customCallbacks);
215 } /* xMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks const*) */
216
217 //
218 // header handling
219 //
220 OSStatus wxMacDataBrowserTableViewControl::GetHeaderDesc(DataBrowserPropertyID propertyID, DataBrowserListViewHeaderDesc* desc) const
221 {
222 desc->version = kDataBrowserListViewLatestHeaderDesc; // if this statement is missing the next call will fail (NOT DOCUMENTED!!)
223 return ::GetDataBrowserListViewHeaderDesc(this->m_controlRef,propertyID,desc);
224 }
225
226 OSStatus wxMacDataBrowserTableViewControl::SetHeaderDesc(DataBrowserPropertyID propertyID, DataBrowserListViewHeaderDesc* desc)
227 {
228 return ::SetDataBrowserListViewHeaderDesc(this->m_controlRef,propertyID,desc);
229 }
230
231 //
232 // layout handling
233 //
234 OSStatus wxMacDataBrowserTableViewControl::AutoSizeColumns()
235 {
236 return AutoSizeDataBrowserListViewColumns(this->m_controlRef);
237 }
238
239 OSStatus wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool enableHeight, bool enableWidth)
240 {
241 return ::SetDataBrowserTableViewGeometry(this->GetControlRef(),enableWidth,enableHeight);
242 } /* wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool, bool) */
243
244 OSStatus wxMacDataBrowserTableViewControl::GetAttributes(OptionBits* attributes)
245 {
246 return ::DataBrowserGetAttributes(this->GetControlRef(),attributes);
247 } /* wxMacDataBrowserTableViewControl::GetAttributes(OptionBits*) */
248
249 OSStatus wxMacDataBrowserTableViewControl::GetColumnWidth(DataBrowserPropertyID propertyID, UInt16* width) const
250 {
251 return ::GetDataBrowserTableViewNamedColumnWidth(this->m_controlRef,propertyID,width);
252 }
253
254 OSStatus wxMacDataBrowserTableViewControl::GetDefaultColumnWidth( UInt16 *width ) const
255 {
256 return GetDataBrowserTableViewColumnWidth(this->m_controlRef, width );
257 }
258
259 OSStatus wxMacDataBrowserTableViewControl::GetDefaultRowHeight(UInt16* height) const
260 {
261 return ::GetDataBrowserTableViewRowHeight(this->m_controlRef,height);
262 }
263
264 OSStatus wxMacDataBrowserTableViewControl::GetHeaderButtonHeight(UInt16 *height)
265 {
266 return ::GetDataBrowserListViewHeaderBtnHeight(this->m_controlRef,height);
267 }
268
269 OSStatus wxMacDataBrowserTableViewControl::GetPartBounds(DataBrowserItemID item, DataBrowserPropertyID propertyID, DataBrowserPropertyPart part, Rect* bounds)
270 {
271 return ::GetDataBrowserItemPartBounds(this->m_controlRef,item,propertyID,part,bounds);
272 } /* wxMacDataBrowserTableViewControl::GetPartBounds(DataBrowserItemID, DataBrowswerPropertyID, DataBrowserPropertyPart, Rect*) */
273
274 OSStatus wxMacDataBrowserTableViewControl::GetRowHeight(DataBrowserItemID item, UInt16* height) const
275 {
276 return ::GetDataBrowserTableViewItemRowHeight(this->m_controlRef,item,height);
277 } /* wxMacDataBrowserTableViewControl::GetRowHeight(DataBrowserItemID, UInt16*) const */
278
279 OSStatus wxMacDataBrowserTableViewControl::GetScrollPosition( UInt32 *top , UInt32 *left ) const
280 {
281 return GetDataBrowserScrollPosition(this->m_controlRef, top , left );
282 }
283
284 OSStatus wxMacDataBrowserTableViewControl::SetAttributes(OptionBits attributes)
285 {
286 return ::DataBrowserChangeAttributes(this->GetControlRef(),attributes,~attributes);
287 } /* wxMacDataBrowserTableViewControl::SetAttributes(OptionBits) */
288
289 OSStatus wxMacDataBrowserTableViewControl::SetColumnWidth(DataBrowserPropertyID propertyID, UInt16 width)
290 {
291 return ::SetDataBrowserTableViewNamedColumnWidth(this->m_controlRef,propertyID,width);
292 }
293
294 OSStatus wxMacDataBrowserTableViewControl::SetDefaultColumnWidth(UInt16 width)
295 {
296 return ::SetDataBrowserTableViewColumnWidth(this->m_controlRef,width);
297 }
298
299 OSStatus wxMacDataBrowserTableViewControl::SetDefaultRowHeight(UInt16 height)
300 {
301 return ::SetDataBrowserTableViewRowHeight(this->m_controlRef,height);
302 }
303
304 OSStatus wxMacDataBrowserTableViewControl::SetHasScrollBars(bool horiz, bool vert)
305 {
306 return ::SetDataBrowserHasScrollBars(this->m_controlRef,horiz,vert);
307 } /* wxMacDataBrowserTableViewControl::SetHasScrollBars(bool, bool) */
308
309 OSStatus wxMacDataBrowserTableViewControl::SetHeaderButtonHeight(UInt16 height)
310 {
311 return ::SetDataBrowserListViewHeaderBtnHeight(this->m_controlRef,height);
312 } /* wxMacDataBrowserTableViewControl::SetHeaderButtonHeight(UInt16) */
313
314 OSStatus wxMacDataBrowserTableViewControl::SetHiliteStyle(DataBrowserTableViewHiliteStyle hiliteStyle)
315 {
316 return ::SetDataBrowserTableViewHiliteStyle(this->m_controlRef,hiliteStyle);
317 } /*wxMacDataBrowserTableViewControl::SetHiliteStyle(DataBrowserTableViewHiliteStyle) */
318
319 OSStatus wxMacDataBrowserTableViewControl::SetIndent(float Indent)
320 {
321 return ::DataBrowserSetMetric(this->m_controlRef,kDataBrowserMetricDisclosureColumnPerDepthGap,true,Indent);
322 } /* wxMacDataBrowserTableViewControl::SetIndent(float* Indent) */
323
324 OSStatus wxMacDataBrowserTableViewControl::SetRowHeight(DataBrowserItemID item, UInt16 height)
325 {
326 return ::SetDataBrowserTableViewItemRowHeight(this->m_controlRef,item,height);
327 }
328
329 OSStatus wxMacDataBrowserTableViewControl::SetScrollPosition(UInt32 top, UInt32 left)
330 {
331 return ::SetDataBrowserScrollPosition(this->m_controlRef,top,left);
332 }
333
334 //
335 // column handling
336 //
337 OSStatus wxMacDataBrowserTableViewControl::GetColumnCount(UInt32* numColumns) const
338 {
339 return ::GetDataBrowserTableViewColumnCount(this->m_controlRef,numColumns);
340 }
341
342 OSStatus wxMacDataBrowserTableViewControl::GetColumnIndex(DataBrowserPropertyID propertyID, DataBrowserTableViewColumnIndex* index) const
343 {
344 return ::GetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,index);
345 } /* wxMacDataBrowserTableViewControl::GetColumnIndex(DataBrowserPropertyID, DataBrowserTableViewColumnIndex*) const */
346
347 OSStatus wxMacDataBrowserTableViewControl::GetFreePropertyID(DataBrowserPropertyID* propertyID) const
348 {
349 for (*propertyID=kMinPropertyID; *propertyID<std::numeric_limits<DataBrowserPropertyID>::max(); ++(*propertyID))
350 if (this->IsUsedPropertyID(*propertyID) == errDataBrowserPropertyNotFound)
351 return noErr;
352 return errDataBrowserPropertyNotSupported;
353 } /* wxMacDataBrowserTableViewControl::GetFreePropertyID(DataBrowserPropertyID*) const */
354
355 OSStatus wxMacDataBrowserTableViewControl::GetPropertyFlags(DataBrowserPropertyID propertyID, DataBrowserPropertyFlags *flags) const
356 {
357 return ::GetDataBrowserPropertyFlags(this->m_controlRef,propertyID,flags);
358 }
359
360 OSStatus wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserItemDataRef itemData, DataBrowserPropertyID* propertyID)
361 {
362 return ::GetDataBrowserItemDataProperty(itemData,propertyID);
363 } /* wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserItemDataRef, DataBrowserPropertyID*) */
364
365 OSStatus wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserTableViewColumnIndex index, DataBrowserTableViewColumnID* propertyID)
366 {
367 return ::GetDataBrowserTableViewColumnProperty(this->m_controlRef,index,propertyID);
368 } /* wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserTableViewColumnIndex, DataBrowserTableViewColumnID*) */
369
370 OSStatus wxMacDataBrowserTableViewControl::IsUsedPropertyID(DataBrowserPropertyID propertyID) const
371 {
372 // 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
373 // 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
374 // the column position for the property id:
375 DataBrowserTableViewColumnIndex index;
376
377 return ::GetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,&index);
378 } /* wxMacDataBrowserTableViewControl::IsUsedPropertyId(DataBrowserPropertyID) const */
379
380 OSStatus wxMacDataBrowserTableViewControl::RemoveColumnByProperty(DataBrowserTableViewColumnID propertyID)
381 {
382 return ::RemoveDataBrowserTableViewColumn(this->m_controlRef,propertyID);
383 } /* wxMacDataBrowserTableViewControl::RemoveColumnByProperty(DataBrowserTableViewColumnID) */
384
385 OSStatus wxMacDataBrowserTableViewControl::RemoveColumnByIndex(DataBrowserTableViewColumnIndex index)
386 {
387 DataBrowserTableViewColumnID propertyID;
388
389
390 this->GetPropertyID(index,&propertyID);
391 return ::RemoveDataBrowserTableViewColumn(this->m_controlRef,propertyID);
392 } /* wxMacDataBrowserTableViewControl::RemoveColumnByIndex(DataBrowserTableViewColumnIndex) */
393
394 OSStatus wxMacDataBrowserTableViewControl::SetColumnIndex(DataBrowserPropertyID propertyID, DataBrowserTableViewColumnIndex index)
395 {
396 return ::SetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,index);
397 } /* wxMacDataBrowserTableViewControl::SetColumnIndex(DataBrowserPropertyID, DataBrowserTableViewColumnIndex) */
398
399 OSStatus wxMacDataBrowserTableViewControl::SetDisclosureColumn(DataBrowserPropertyID propertyID, Boolean expandableRows)
400 {
401 return ::SetDataBrowserListViewDisclosureColumn(this->m_controlRef,propertyID,expandableRows);
402 }
403
404 OSStatus wxMacDataBrowserTableViewControl::SetPropertyFlags(DataBrowserPropertyID propertyID, DataBrowserPropertyFlags flags)
405 {
406 return ::SetDataBrowserPropertyFlags(this->m_controlRef,propertyID,flags);
407 } /* wxMacDataBrowserTableViewControl::SetPropertyFlags(DataBrowserPropertyID, DataBrowserPropertyFlags) */
408
409 //
410 // item handling
411 //
412 OSStatus wxMacDataBrowserTableViewControl::AddItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty)
413 {
414 return ::AddDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty);
415 } /* wxMacDataBrowserTableViewControl::AddItems(DataBrowserItemID, UInt32, DataBrowserItemID const*, DataBrowserPropertyID) */
416
417 OSStatus wxMacDataBrowserTableViewControl::GetFreeItemID(DataBrowserItemID* id) const
418 {
419 ItemCount NoOfItems;
420
421 OSStatus status;
422
423
424 status = this->GetItemCount(&NoOfItems);
425 wxCHECK_MSG(status == noErr,status,_("Could not retrieve number of items"));
426 if (NoOfItems == 0)
427 {
428 *id = 1;
429 return noErr;
430 } /* if */
431 else
432 {
433 // 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
434 // as the number of items; therefore, start from the number of items to look for a new ID:
435 for (*id=NoOfItems; *id<std::numeric_limits<DataBrowserItemID>::max(); ++(*id))
436 if (this->IsUsedItemID(*id) == errDataBrowserItemNotFound)
437 return noErr;
438 // as the first approach was not successful, try from the beginning:
439 for (*id=0; *id<NoOfItems; ++(*id))
440 if (this->IsUsedItemID(*id) == errDataBrowserItemNotFound)
441 return noErr;
442 // sorry, data browser is full:
443 return errDataBrowserItemNotAdded;
444 } /* if */
445 } /* wxMacDataBrowserTableViewControl::GetFreeItemID(DataBrowserItemID*) const */
446
447 OSStatus wxMacDataBrowserTableViewControl::GetItemCount(DataBrowserItemID container, Boolean recurse, DataBrowserItemState state, ItemCount* numItems) const
448 {
449 return GetDataBrowserItemCount(this->m_controlRef,container,recurse,state,numItems);
450 } /* wxMacDataBrowserTableViewControl::GetItemCount(DataBrowserItemID, Boolean, DataBrowserItemState, ItemCount*) const */
451
452 OSStatus wxMacDataBrowserTableViewControl::GetItemID( DataBrowserTableViewRowIndex row, DataBrowserItemID * item ) const
453 {
454 return GetDataBrowserTableViewItemID(this->m_controlRef,row,item);
455 }
456
457 OSStatus wxMacDataBrowserTableViewControl::GetItems(DataBrowserItemID container, Boolean recurse, DataBrowserItemState state, Handle items) const
458 {
459 return GetDataBrowserItems(this->m_controlRef,container,recurse,state,items);
460 } /* wxMacDataBrowserTableViewControl::GetItems(DataBrowserItemID, Boolean, DataBrowserItemState, Handle) const */
461
462 OSStatus wxMacDataBrowserTableViewControl::GetItemRow(DataBrowserItemID item, DataBrowserTableViewRowIndex* row) const
463 {
464 return GetDataBrowserTableViewItemRow(this->m_controlRef,item,row);
465 }
466
467 OSStatus wxMacDataBrowserTableViewControl::IsUsedItemID(DataBrowserItemID itemID) const
468 {
469 // 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
470 // 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
471 // the column position for the property id:
472 DataBrowserTableViewColumnIndex index;
473
474 return ::GetDataBrowserTableViewItemRow(this->m_controlRef,itemID,&index);
475 } /* wxMacDataBrowserTableViewControl::IsUsedItemID(DataBrowserItemID) const */
476
477 OSStatus wxMacDataBrowserTableViewControl::RemoveItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty)
478 {
479 return ::RemoveDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty);
480 }
481
482 OSStatus wxMacDataBrowserTableViewControl::RevealItem(DataBrowserItemID item, DataBrowserPropertyID propertyID, DataBrowserRevealOptions options) const
483 {
484 return ::RevealDataBrowserItem(this->m_controlRef,item,propertyID,options);
485 } /* wxMacDataBrowserTableViewControl::RevealItem(DataBrowserItemID item, DataBrowserPropertyID propertyID, DataBrowserRevealOptions options) const */
486
487 OSStatus wxMacDataBrowserTableViewControl::UpdateItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty,
488 DataBrowserPropertyID propertyID) const
489 {
490 return UpdateDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty,propertyID);
491 }
492
493 //
494 // item selection
495 //
496 size_t wxMacDataBrowserTableViewControl::GetSelectedItemIDs(wxArrayDataBrowserItemID& itemIDs) const
497 {
498 DataBrowserItemID* itemIDPtr;
499 Handle handle(::NewHandle(0));
500
501 size_t NoOfItems;
502
503
504 wxCHECK_MSG(this->GetItems(kDataBrowserNoItem,true,kDataBrowserItemIsSelected,handle) == noErr,0,_("Could not get selected items."));
505 NoOfItems = static_cast<size_t>(::GetHandleSize(handle)/sizeof(DataBrowserItemID));
506 itemIDs.Empty();
507 itemIDs.Alloc(NoOfItems);
508 HLock(handle);
509 itemIDPtr = (DataBrowserItemID*) (*handle);
510 for (size_t i=0; i<NoOfItems; ++i)
511 {
512 itemIDs.Add(*itemIDPtr);
513 ++itemIDPtr;
514 } /* for */
515 HUnlock(handle);
516 DisposeHandle(handle);
517 return NoOfItems;
518 } /* wxMacDataBrowserTableViewControl::GetSelectedItemIDs(wxArrayDataBrowserItemID&) const*/
519
520 OSStatus wxMacDataBrowserTableViewControl::GetSelectionAnchor(DataBrowserItemID* first, DataBrowserItemID* last) const
521 {
522 return ::GetDataBrowserSelectionAnchor(this->m_controlRef,first,last);
523 } /* wxMacDataBrowserTableViewControl::GetSelectionAnchor(DataBrowserItemID*, DataBrowserItemID*) const */
524
525 OSStatus wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags* flags) const
526 {
527 return ::GetDataBrowserSelectionFlags(this->m_controlRef,flags);
528 } /* wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags*) const */
529
530 bool wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID item) const
531 {
532 return ::IsDataBrowserItemSelected(this->m_controlRef,item);
533 } /* wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID) const */
534
535 OSStatus wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags flags)
536 {
537 return ::SetDataBrowserSelectionFlags(this->m_controlRef,flags);
538 } /* wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags) */
539
540 OSStatus wxMacDataBrowserTableViewControl::SetSelectedItems(UInt32 numItems, DataBrowserItemID const* items, DataBrowserSetOption operation)
541 {
542 return ::SetDataBrowserSelectedItems(this->m_controlRef, numItems, items, operation );
543 } /* wxMacDataBrowserTableViewControl::SetSelectedItems(UInt32, DataBrowserItemID const*, DataBrowserSetOption) */
544
545 OSStatus wxMacDataBrowserTableViewControl::GetSortOrder(DataBrowserSortOrder* order) const
546 {
547 return ::GetDataBrowserSortOrder(this->m_controlRef,order);
548 }
549
550 OSStatus wxMacDataBrowserTableViewControl::GetSortProperty(DataBrowserPropertyID* propertyID) const
551 {
552 return ::GetDataBrowserSortProperty(this->m_controlRef,propertyID);
553 }
554
555 OSStatus wxMacDataBrowserTableViewControl::Resort(DataBrowserItemID container, Boolean sortChildren)
556 {
557 return ::SortDataBrowserContainer(this->m_controlRef,container,sortChildren);
558 } /* wxMacDataBrowserTableViewControl::Resort(DataBrowserItemID, Boolean) */
559
560 OSStatus wxMacDataBrowserTableViewControl::SetSortOrder(DataBrowserSortOrder order)
561 {
562 return ::SetDataBrowserSortOrder(this->m_controlRef,order);
563 }
564
565 OSStatus wxMacDataBrowserTableViewControl::SetSortProperty(DataBrowserPropertyID propertyID)
566 {
567 return ::SetDataBrowserSortProperty(this->m_controlRef,propertyID);
568 }
569
570 //
571 // container handling
572 //
573 OSStatus wxMacDataBrowserTableViewControl::CloseContainer(DataBrowserItemID containerID)
574 {
575 return ::CloseDataBrowserContainer(this->m_controlRef,containerID);
576 } /* wxMacDataBrowserTableViewControl::CloseContainer(DataBrowserItemID) */
577
578 OSStatus wxMacDataBrowserTableViewControl::OpenContainer(DataBrowserItemID containerID)
579 {
580 return ::OpenDataBrowserContainer(this->m_controlRef,containerID);
581 } /* wxMacDataBrowserTableViewControl::OpenContainer(DataBrowserItemID) */
582
583 IMPLEMENT_ABSTRACT_CLASS(wxMacDataBrowserTableViewControl,wxMacControl)
584
585 // ============================================================================
586 // wxMacDataBrowserListViewControl
587 // ============================================================================
588 #pragma mark -
589 //
590 // column handling
591 //
592 OSStatus wxMacDataBrowserListViewControl::AddColumn(DataBrowserListViewColumnDesc *columnDesc, DataBrowserTableViewColumnIndex position)
593 {
594 return AddDataBrowserListViewColumn(this->m_controlRef,columnDesc,position);
595 } /* wxMacDataBrowserListViewControl::AddColumn(DataBrowserListViewColumnDesc*, DataBrowserTableViewColumnIndex) */
596
597 // ============================================================================
598 // wxMacDataViewDataBrowserListViewControl
599 // ============================================================================
600 #pragma mark -
601 //
602 // constructors / destructor
603 //
604 wxMacDataViewDataBrowserListViewControl::wxMacDataViewDataBrowserListViewControl(wxWindow* peer, wxPoint const& pos, wxSize const& size, long style)
605 :wxMacDataBrowserListViewControl(peer,pos,size,style)
606 {
607 } /* wxMacDataViewDataBrowserListViewControl::wxMacDataViewDataBrowserListViewControl(wxWindow* , const wxPoint&, const wxSize&, long) */
608
609 //
610 // callback functions (inherited from wxMacDataBrowserTableViewControl)
611 //
612 Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID itemOneID, DataBrowserItemID itemTwoID, DataBrowserPropertyID sortProperty)
613 {
614 DataBrowserSortOrder sortOrder;
615
616 DataBrowserTableViewColumnIndex modelColumnIndex;
617
618 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetPeer()));
619
620
621 wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly."));
622 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly."));
623 if (sortProperty >= kMinPropertyID)
624 {
625 // variable definition and initialization:
626 wxDataViewColumn* ColumnPtr(dataViewCtrlPtr->GetColumnPtr(sortProperty));
627
628 wxCHECK_MSG(ColumnPtr != NULL,false,_("Could not determine column index."));
629 modelColumnIndex = ColumnPtr->GetModelColumn();
630 } /* if */
631 else
632 modelColumnIndex = 0;
633 this->GetSortOrder(&sortOrder);
634 return static_cast<Boolean>(dataViewCtrlPtr->GetModel()->Compare(wxDataViewItem(reinterpret_cast<void*>(itemOneID)),wxDataViewItem(reinterpret_cast<void*>(itemTwoID)),
635 modelColumnIndex,sortOrder != kDataBrowserOrderDecreasing) < 0);
636 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID) */
637
638 void wxMacDataViewDataBrowserListViewControl::DataBrowserGetContextualMenuProc(MenuRef* menu, UInt32* helpType, CFStringRef* helpItemString, AEDesc* WXUNUSED(selection))
639 // In this method we do not supply a contextual menu handler at all but only send a wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU.
640 {
641 wxArrayDataBrowserItemID itemIDs;
642
643 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetPeer()));
644
645
646 wxCHECK_RET(dataViewCtrlPtr != NULL,_("wxWidget control pointer is not a data view pointer"));
647 // initialize parameters so that no context menu will be displayed automatically by the native data browser:
648 *menu = NULL;
649 *helpType = kCMHelpItemNoHelp;
650 *helpItemString = NULL;
651 // create information for a context menu event:
652 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU,dataViewCtrlPtr->GetId());
653
654 dataViewEvent.SetModel(dataViewCtrlPtr->GetModel());
655 // get the item information;
656 // 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:
657 if (this->GetSelectedItemIDs(itemIDs) > 0)
658 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemIDs[0])));
659 // finally send the equivalent wxWidget event:
660 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
661 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserGetContextualMenuProc(MenuRef*, UInt32*, CFStringRef*, AEDesc*) */
662
663 OSStatus wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemDataRef itemData, Boolean getValue)
664 {
665 if (getValue)
666 {
667 // variable definitions:
668 wxDataViewCtrl* dataViewCtrlPtr;
669
670 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetPeer());
671 wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
672 if (dataViewCtrlPtr->IsDeleting())
673 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
674 else
675 {
676 // variable definitions:
677 OSStatus errorStatus;
678 wxDataViewColumn* dataViewColumnPtr;
679
680 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,errDataBrowserNotConfigured,_("Pointer to model not set correctly."));
681 dataViewColumnPtr = dataViewCtrlPtr->GetColumnPtr(propertyID);
682 wxCHECK_MSG((dataViewColumnPtr != NULL) && (dataViewColumnPtr->GetRenderer() != NULL),errDataBrowserNotConfigured,_("There is no column or renderer for the specified column index."));
683
684 wxDataViewItem dvItem(reinterpret_cast<void*>(itemID));
685 unsigned int col = dataViewColumnPtr->GetModelColumn();
686
687 switch (dataViewColumnPtr->GetRenderer()->GetPropertyType())
688 {
689 case kDataBrowserCheckboxType:
690 {
691 // variable definition:
692 ThemeButtonValue buttonValue;
693
694 errorStatus = ::GetDataBrowserItemDataButtonValue(itemData,&buttonValue);
695 if (errorStatus == noErr)
696 {
697 if (buttonValue == kThemeButtonOn)
698 {
699 // variable definition and initialization:
700 wxVariant modifiedData(true);
701
702 if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData, dvItem, col))
703 {
704 dataViewCtrlPtr->GetModel()->ValueChanged(dvItem, col);
705 return noErr;
706 }
707 else
708 return errDataBrowserNotConfigured;
709 } /* if */
710 else if (buttonValue == kThemeButtonOff)
711 {
712 // variable definition and initialization:
713 wxVariant modifiedData(false);
714
715 if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData, dvItem, col))
716 {
717 dataViewCtrlPtr->GetModel()->ValueChanged(dvItem, col);
718 return noErr;
719 }
720 else
721 return errDataBrowserNotConfigured;
722 } /* if */
723 else
724 return errDataBrowserInvalidPropertyData;
725 } /* if */
726 else
727 return errorStatus;
728 } /* block */
729 case kDataBrowserTextType:
730 {
731 // variable definitions:
732 CFStringRef stringReference;
733
734 errorStatus = ::GetDataBrowserItemDataText(itemData,&stringReference);
735 if (errorStatus == noErr)
736 {
737 // variable definitions and initializations:
738 #if wxCHECK_VERSION(2,9,0)
739 wxCFStringRef modifiedString(stringReference);
740 #else
741 wxMacCFStringHolder modifiedString(stringReference);
742 #endif
743 wxVariant modifiedData(modifiedString.AsString());
744
745 if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData, dvItem, col))
746 {
747 dataViewCtrlPtr->GetModel()->ValueChanged(dvItem, col);
748 return noErr;
749 }
750 else
751 return errDataBrowserNotConfigured;
752 } /* if */
753 else
754 return errorStatus;
755 } /* block */
756 default:
757 return errDataBrowserPropertyNotSupported;
758 } /* switch */
759 } /* if */
760 } /* if */
761 else
762 {
763 if (propertyID >= kMinPropertyID) // in case data columns set the data
764 {
765 // variable definitions:
766 wxVariant variant;
767 wxDataViewColumn* dataViewColumnPtr;
768 wxDataViewCtrl* dataViewCtrlPtr;
769
770 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetPeer());
771 wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
772 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,errDataBrowserNotConfigured,_("Pointer to model not set correctly."));
773 dataViewColumnPtr = dataViewCtrlPtr->GetColumnPtr(propertyID);
774 wxCHECK_MSG(dataViewColumnPtr != NULL,errDataBrowserNotConfigured,_("No column for the specified column position existing."));
775 wxCHECK_MSG(dataViewColumnPtr->GetRenderer() != NULL,errDataBrowserNotConfigured,_("No renderer specified for column."));
776 dataViewCtrlPtr->GetModel()->GetValue(variant,wxDataViewItem(reinterpret_cast<void*>(itemID)),dataViewColumnPtr->GetModelColumn());
777 if (!(variant.IsNull()))
778 {
779 dataViewColumnPtr->GetRenderer()->SetDataReference(itemData);
780 dataViewColumnPtr->GetRenderer()->SetValue(variant);
781 wxCHECK_MSG(dataViewColumnPtr->GetRenderer()->Render(),errDataBrowserNotConfigured,_("Rendering failed."));
782 } /* if */
783 return noErr;
784 } /* if */
785 else // react on special system requests
786 {
787 switch (propertyID)
788 {
789 case kDataBrowserContainerIsClosableProperty:
790 {
791 // variable definitions:
792 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetPeer()));
793
794 wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
795 // initialize wxWidget event:
796 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING,dataViewCtrlPtr->GetId()); // variable definition
797
798 dataViewEvent.SetEventObject(dataViewCtrlPtr);
799 dataViewEvent.SetItem (wxDataViewItem(reinterpret_cast<void*>(itemID)));
800 dataViewEvent.SetModel (dataViewCtrlPtr->GetModel());
801 // finally send the equivalent wxWidget event:
802 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
803 // opening the container is allowed if not vetoed:
804 return ::SetDataBrowserItemDataBooleanValue(itemData,dataViewEvent.IsAllowed());
805 } /* block */
806 case kDataBrowserContainerIsOpenableProperty:
807 {
808 // variable definitions:
809 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetPeer()));
810
811 wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
812 // initialize wxWidget event:
813 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING,dataViewCtrlPtr->GetId()); // variable definition
814
815 dataViewEvent.SetEventObject(dataViewCtrlPtr);
816 dataViewEvent.SetItem (wxDataViewItem(reinterpret_cast<void*>(itemID)));
817 dataViewEvent.SetModel (dataViewCtrlPtr->GetModel());
818 // finally send the equivalent wxWidget event:
819 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
820 // opening the container is allowed if not vetoed:
821 return ::SetDataBrowserItemDataBooleanValue(itemData,dataViewEvent.IsAllowed());
822 } /* block */
823 case kDataBrowserItemIsContainerProperty:
824 {
825 // variable definition:
826 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetPeer()));
827
828 wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
829 wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,errDataBrowserNotConfigured,_("Pointer to model not set correctly."));
830 return ::SetDataBrowserItemDataBooleanValue(itemData,dataViewCtrlPtr->GetModel()->IsContainer(wxDataViewItem(reinterpret_cast<void*>(itemID))));
831 } /* block */
832 case kDataBrowserItemIsEditableProperty:
833 return ::SetDataBrowserItemDataBooleanValue(itemData,true);
834 } /* switch */
835 } /* if */
836 } /* if */
837 return errDataBrowserPropertyNotSupported;
838 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc(DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemDataRef, Boolean) */
839
840 void wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID itemID, DataBrowserItemNotification message, DataBrowserItemDataRef itemData)
841 {
842 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetPeer()));
843
844
845 // 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:
846 if (dataViewCtrlPtr != NULL)
847 switch (message)
848 {
849 case kDataBrowserContainerClosed:
850 dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
851 {
852 // initialize wxWidget event:
853 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED,dataViewCtrlPtr->GetId()); // variable definition
854
855 dataViewEvent.SetEventObject(dataViewCtrlPtr);
856 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
857 // finally send the equivalent wxWidget event:
858 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
859 } /* block */
860 break;
861 case kDataBrowserContainerOpened:
862 dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
863 {
864 // initialize wxWidget event:
865 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED,dataViewCtrlPtr->GetId()); // variable definition
866
867 dataViewEvent.SetEventObject(dataViewCtrlPtr);
868 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
869 // finally send the equivalent wxWidget event:
870 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
871 // add children to the expanded container:
872 dataViewCtrlPtr->AddChildrenLevel(wxDataViewItem(reinterpret_cast<void*>(itemID)));
873 } /* block */
874 break;
875 case kDataBrowserEditStarted:
876 dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
877 {
878 // initialize wxWidget event:
879 DataBrowserPropertyID propertyID;
880 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED,dataViewCtrlPtr->GetId()); // variable definition
881
882 dataViewEvent.SetEventObject(dataViewCtrlPtr);
883 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
884 if (this->GetPropertyID(itemData,&propertyID) == noErr)
885 {
886 // variable definition and initialization:
887 DataBrowserTableViewColumnIndex columnIndex;
888
889 wxCHECK_RET(this->GetColumnIndex(propertyID,&columnIndex),_("Column index not found."));
890 dataViewEvent.SetColumn(columnIndex);
891 dataViewEvent.SetDataViewColumn(dataViewCtrlPtr->GetColumnPtr(propertyID));
892 } /* if */
893 // finally send the equivalent wxWidget event:
894 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
895 } /* block */
896 break;
897 case kDataBrowserEditStopped:
898 {
899 // initialize wxWidget event:
900 DataBrowserPropertyID propertyID;
901 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE,dataViewCtrlPtr->GetId()); // variable definition
902
903 dataViewEvent.SetEventObject(dataViewCtrlPtr);
904 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
905 if (this->GetPropertyID(itemData,&propertyID) == noErr)
906 {
907 // variable definition and initialization:
908 DataBrowserTableViewColumnIndex columnIndex;
909
910 wxCHECK_RET(this->GetColumnIndex(propertyID,&columnIndex),_("Column index not found."));
911 dataViewEvent.SetColumn(columnIndex);
912 dataViewEvent.SetDataViewColumn(dataViewCtrlPtr->GetColumnPtr(propertyID));
913 } /* if */
914 // finally send the equivalent wxWidget event:
915 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
916 } /* block */
917 break;
918 case kDataBrowserItemAdded:
919 dataViewCtrlPtr->FinishCustomItemEditing();
920 break;
921 case kDataBrowserItemDeselected:
922 dataViewCtrlPtr->FinishCustomItemEditing();
923 break;
924 case kDataBrowserItemDoubleClicked:
925 {
926 // initialize wxWidget event:
927 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED,dataViewCtrlPtr->GetId()); // variable definition
928
929 dataViewEvent.SetEventObject(dataViewCtrlPtr);
930 dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast<void*>(itemID)));
931 // finally send the equivalent wxWidget event:
932 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
933 } /* block */
934 break;
935 case kDataBrowserItemRemoved:
936 dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary)
937 break;
938 case kDataBrowserItemSelected:
939 break; // not implemented by wxWidgets; see kDataBrowserSelectionSetChanged
940 case kDataBrowserSelectionSetChanged:
941 {
942 // initialize wxWidget event:
943 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED,dataViewCtrlPtr->GetId()); // variable definition
944
945 dataViewEvent.SetEventObject(dataViewCtrlPtr);
946 dataViewEvent.SetModel (dataViewCtrlPtr->GetModel());
947 // finally send the equivalent wxWidget event:
948 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
949 } /* block */
950 break;
951 case kDataBrowserTargetChanged: // no idea if this notification is ever sent
952 break;
953 case kDataBrowserUserStateChanged:
954 {
955 // finish custom item editing if necessary:
956 dataViewCtrlPtr->FinishCustomItemEditing();
957 // update column widths:
958 for (size_t i=0; i<dataViewCtrlPtr->GetColumnCount(); ++i)
959 {
960 // constant definition for abbreviational purposes:
961 wxDataViewColumn* const columnPtr = dataViewCtrlPtr->GetColumn(i);
962 // variable definition:
963 UInt16 columnWidth;
964
965 wxCHECK_RET(this->GetColumnWidth(columnPtr->GetPropertyID(),&columnWidth) == noErr,_("Column width could not be determined"));
966 columnPtr->SetWidthVariable(columnWidth);
967 } /* for */
968 // update sorting orders:
969 DataBrowserPropertyID propertyID; // variable definition
970
971 if ((this->GetSortProperty(&propertyID) == noErr) && (propertyID >= kMinPropertyID))
972 {
973 DataBrowserSortOrder sortOrder;
974 DataBrowserTableViewColumnIndex columnIndex;
975
976 if ((this->GetSortOrder(&sortOrder) == noErr) && (this->GetColumnIndex(propertyID,&columnIndex) == noErr))
977 {
978 // variable definition and initialization:
979 wxDataViewColumn* columnPtr;
980 columnPtr = dataViewCtrlPtr->GetColumn(columnIndex);
981 // check if the sort order has changed:
982 if ( columnPtr->IsSortOrderAscending() && (sortOrder == kDataBrowserOrderDecreasing) ||
983 !(columnPtr->IsSortOrderAscending()) && (sortOrder == kDataBrowserOrderIncreasing))
984 {
985 columnPtr->SetSortOrder(!(columnPtr->IsSortOrderAscending()));
986 // initialize wxWidget event:
987 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED,dataViewCtrlPtr->GetId()); // variable defintion
988
989 dataViewEvent.SetEventObject(dataViewCtrlPtr);
990 dataViewEvent.SetColumn(columnIndex);
991 dataViewEvent.SetDataViewColumn(columnPtr);
992 // finally send the equivalent wxWidget event:
993 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
994 } /* if */
995 } /* if */
996 } /* if */
997 } /* block */
998 break;
999 } /* switch */
1000 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID, DataBrowserItemNotification, DataBrowserItemDataRef) */
1001
1002 void wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemState state, Rect const* rectangle, SInt16 bitDepth, Boolean colorDevice)
1003 {
1004 DataBrowserTableViewColumnIndex columnIndex;
1005
1006 wxDataViewColumn* dataViewColumnPtr;
1007
1008 wxDataViewCtrl* dataViewCtrlPtr;
1009
1010 wxDataViewCustomRenderer* dataViewCustomRendererPtr;
1011
1012 wxVariant dataToRender;
1013
1014 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetPeer());
1015 wxCHECK_RET(dataViewCtrlPtr != NULL, _("Pointer to data view control not set correctly."));
1016 wxCHECK_RET(dataViewCtrlPtr->GetModel() != NULL,_("Pointer to model not set correctly."));
1017 wxCHECK_RET(this->GetColumnIndex(propertyID,&columnIndex) == noErr,_("Could not determine column index."));
1018 dataViewColumnPtr = dataViewCtrlPtr->GetColumnPtr(propertyID);
1019 wxCHECK_RET(dataViewColumnPtr != NULL,_("No column for the specified column index existing."));
1020 dataViewCustomRendererPtr = dynamic_cast<wxDataViewCustomRenderer*>(dataViewColumnPtr->GetRenderer());
1021 wxCHECK_RET(dataViewCustomRendererPtr != NULL,_("No renderer or invalid renderer type specified for custom data column."));
1022 dataViewCtrlPtr->GetModel()->GetValue(dataToRender,wxDataViewItem(reinterpret_cast<void*>(itemID)),dataViewColumnPtr->GetModelColumn());
1023 dataViewCustomRendererPtr->SetValue(dataToRender);
1024
1025 wxDataViewItem dataitem( reinterpret_cast<void*>(itemID) );
1026 dataViewCtrlPtr->GetModel()->GetValue(dataToRender,dataitem,columnIndex);
1027 dataViewCustomRendererPtr->SetValue(dataToRender);
1028
1029 // try to determine the content's size (drawable part):
1030 Rect content;
1031 RgnHandle rgn(NewRgn());
1032 UInt16 headerHeight;
1033
1034 if (this->GetRegion(kControlContentMetaPart,rgn) == noErr)
1035 GetRegionBounds(rgn,&content);
1036 else
1037 this->GetRect(&content);
1038 ::DisposeRgn(rgn);
1039 // space for the header
1040 this->GetHeaderButtonHeight(&headerHeight);
1041 content.top += headerHeight;
1042 // extra space for the frame (todo: do not how to determine the space automatically from the control)
1043 content.top += 5;
1044 content.left += 5;
1045 content.right -= 3;
1046 content.bottom -= 3;
1047 // extra space for the scrollbars:
1048 content.bottom -= wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y);
1049 content.right -= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
1050
1051 wxDC *dc = dataViewCustomRendererPtr->GetDC();
1052
1053 wxRect cellrect( static_cast<int>(rectangle->left),
1054 static_cast<int>(rectangle->top+2),
1055 static_cast<int>(1+rectangle->right-rectangle->left),
1056 static_cast<int>(rectangle->bottom-rectangle->top) );
1057
1058 bool is_active = IsControlActive( this->m_controlRef );
1059 if (state == kDataBrowserItemIsSelected)
1060 {
1061
1062 wxColour col( wxMacCreateCGColorFromHITheme( (is_active) ?
1063 kThemeBrushAlternatePrimaryHighlightColor
1064 : kThemeBrushSecondaryHighlightColor ) );
1065
1066 wxRect rect = cellrect;
1067 Rect itemrect;
1068 GetDataBrowserItemPartBounds( this->m_controlRef, itemID, propertyID,
1069 kDataBrowserPropertyEnclosingPart, &itemrect );
1070 rect.x = itemrect.left;
1071 rect.width = itemrect.right-itemrect.left+1;
1072
1073 wxBrush selBrush( col );
1074 wxPen oldpen( dc->GetPen() );
1075 wxBrush oldbrush( dc->GetBrush() );
1076 dc->SetPen( *wxTRANSPARENT_PEN );
1077 dc->SetBrush( selBrush );
1078 dc->DrawRectangle(rect);
1079 dc->SetBrush( oldbrush );
1080 dc->SetPen( oldpen );
1081 }
1082
1083 wxDataViewModel *model = dataViewCtrlPtr->GetModel();
1084 if ((columnIndex == 0) || !model->IsContainer(dataitem) || model->HasContainerColumns(dataitem))
1085 {
1086 // make sure that 'Render' can draw only in the allowed area:
1087 dc->SetClippingRegion(content.left,content.top,content.right-content.left+1,content.bottom-content.top+1);
1088 (void) (dataViewCustomRendererPtr->Render( cellrect, dc,
1089 ((state == kDataBrowserItemIsSelected) ? wxDATAVIEW_CELL_SELECTED : 0)));
1090 dc->DestroyClippingRegion(); // probably not necessary
1091 }
1092
1093 dataViewCustomRendererPtr->SetDC(NULL);
1094 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemState, Rect const*, SInt16, Boolean) */
1095
1096 Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserEditItemProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, CFStringRef theString, Rect* maxEditTextRect, Boolean* shrinkToFit)
1097 {
1098 return false;
1099 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserEditItemProc(DataBrowserItemID, DataBrowserPropertyID, CFStringRef, Rect*, Boolean*) */
1100
1101 Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserHitTestProc(DataBrowserItemID WXUNUSED(itemID), DataBrowserPropertyID WXUNUSED(property), Rect const* WXUNUSED(theRect), Rect const* WXUNUSED(mouseRect))
1102 {
1103 return true;
1104 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserHitTestProc(DataBrowserItemID, DataBrowserPropertyID, Rect const*, Rect const*) */
1105
1106 DataBrowserTrackingResult wxMacDataViewDataBrowserListViewControl::DataBrowserTrackingProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, Rect const* theRect, Point WXUNUSED(startPt), EventModifiers WXUNUSED(modifiers))
1107 {
1108 wxDataViewColumn* dataViewColumnPtr;
1109
1110 wxDataViewCtrl* dataViewCtrlPtr;
1111
1112 wxDataViewCustomRenderer* dataViewCustomRendererPtr;
1113
1114 wxDataViewItem dataViewCustomRendererItem;
1115
1116
1117 dataViewCustomRendererItem = reinterpret_cast<void*>(itemID);
1118 wxCHECK_MSG(dataViewCustomRendererItem.IsOk(),kDataBrowserNothingHit,_("Invalid data view item"));
1119 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetPeer());
1120 wxCHECK_MSG(dataViewCtrlPtr != NULL,kDataBrowserNothingHit,_("Pointer to data view control not set correctly."));
1121 dataViewColumnPtr = dataViewCtrlPtr->GetColumnPtr(propertyID);
1122 wxCHECK_MSG(dataViewColumnPtr != NULL,kDataBrowserNothingHit,_("No column existing."));
1123 dataViewCustomRendererPtr = dynamic_cast<wxDataViewCustomRenderer*>(dataViewColumnPtr->GetRenderer());
1124 wxCHECK_MSG(dataViewCustomRendererPtr != NULL,kDataBrowserNothingHit,_("No renderer or invalid renderer type specified for custom data column."));
1125 // 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):
1126 if (dataViewCtrlPtr->GetCustomRendererItem() == dataViewCustomRendererItem)
1127 return kDataBrowserContentHit;
1128 // an(other) item is going to be edited and therefore the current editing - if existing - has to be finished:
1129 if (dataViewCtrlPtr->GetCustomRendererPtr() != NULL)
1130 {
1131 dataViewCtrlPtr->GetCustomRendererPtr()->FinishEditing();
1132 dataViewCtrlPtr->SetCustomRendererItem(wxDataViewItem());
1133 dataViewCtrlPtr->SetCustomRendererPtr (NULL);
1134 } /* if */
1135 // check if renderer has got a valid editor control for editing; if this is the case start editing of the new item:
1136 if (dataViewCustomRendererPtr->HasEditorCtrl())
1137 {
1138 // variable definition:
1139 wxRect wxRectangle;
1140
1141 ::wxMacNativeToRect(theRect,&wxRectangle);
1142 dataViewCustomRendererPtr->StartEditing(dataViewCustomRendererItem,wxRectangle);
1143 dataViewCtrlPtr->SetCustomRendererItem(dataViewCustomRendererItem);
1144 dataViewCtrlPtr->SetCustomRendererPtr (dataViewCustomRendererPtr);
1145 } /* if */
1146 return kDataBrowserContentHit;
1147 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserTrackingProc(DataBrowserItemID, DataBrowserPropertyID, Rect const*, Point, EventModifiers) */
1148
1149 #endif // wxUSE_GENERICDATAVIEWCTRL
1150 #endif // wxUSE_DATAVIEWCTRL