]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/databrow.cpp
added wxUSE_FONTENUM for wxFontEnumerator
[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 #ifndef wxUSE_GENERICDATAVIEWCTRL
13
14 #include <ctype.h>
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <stdarg.h>
20
21 #include "wx/wxprec.h"
22
23 #include "wx/utils.h"
24
25 #ifndef WX_PRECOMP
26 #include "wx/app.h"
27 #include "wx/toplevel.h"
28 #include "wx/font.h"
29 #endif
30
31 #include "wx/apptrait.h"
32
33 #include "wx/mac/uma.h"
34
35
36 #ifdef __DARWIN__
37 #include <Carbon/Carbon.h>
38 #else
39 #include <ATSUnicode.h>
40 #include <TextCommon.h>
41 #include <TextEncodingConverter.h>
42 #endif
43
44 #include "wx/mac/private.h"
45
46 #if defined(__MWERKS__) && wxUSE_UNICODE
47 #if __MWERKS__ < 0x4100 || !defined(__DARWIN__)
48 #include <wtime.h>
49 #endif
50 #endif
51
52 #include <limits>
53
54 #include "wx/mac/carbon/databrow.h"
55
56 #include "wx/dataview.h"
57
58 // ============================================================================
59 // DataBrowser Wrapper
60 // ============================================================================
61 //
62 // basing on DataBrowserItemIDs
63 //
64
65 pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserCompareProc(ControlRef browser, DataBrowserItemID itemOneID, DataBrowserItemID itemTwoID, DataBrowserPropertyID sortProperty)
66 {
67 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
68
69
70 if (ControlPtr != NULL)
71 return ControlPtr->DataBrowserCompareProc(itemOneID,itemTwoID,sortProperty);
72 else
73 return errDataBrowserPropertyNotSupported;
74 } /* wxMacDataBrowserTableViewControl::DataBrowserCompareProc(ControlRef, DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID) */
75
76 pascal void wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID property, DataBrowserItemState state, Rect const* rectangle, SInt16 bitDepth, Boolean colorDevice)
77 {
78 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
79
80
81 if (ControlPtr != NULL)
82 ControlPtr->DataBrowserDrawItemProc(itemID,property,state,rectangle,bitDepth,colorDevice);
83 } /* wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemState, Rect const*, SInt16, Boolean) */
84
85 pascal OSStatus wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID property, DataBrowserItemDataRef itemData, Boolean getValue)
86 {
87 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
88
89
90 if (ControlPtr != NULL)
91 return ControlPtr->DataBrowserGetSetItemDataProc(itemID,property,itemData,getValue);
92 else
93 return errDataBrowserPropertyNotSupported;
94 } /* wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemDataRef, Boolean) */
95
96 pascal void wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserItemNotification message, DataBrowserItemDataRef itemData)
97 {
98 wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl*>(wxMacControl::GetReferenceFromNativeControl(browser)));
99
100
101 if (ControlPtr != NULL)
102 ControlPtr->DataBrowserItemNotificationProc(itemID,message,itemData);
103 } /* wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc(ControlRef, DataBrowserItemID, DataBrowserItemNotification, DataBrowserItemDataRef) */
104
105 DataBrowserDrawItemUPP gDataBrowserTableViewDrawItemUPP = NULL;
106 DataBrowserItemCompareUPP gDataBrowserTableViewItemCompareUPP = NULL;
107 DataBrowserItemDataUPP gDataBrowserTableViewItemDataUPP = NULL;
108 DataBrowserItemNotificationUPP gDataBrowserTableViewItemNotificationUPP = NULL;
109
110 wxMacDataBrowserTableViewControl::wxMacDataBrowserTableViewControl(wxWindow* peer, wxPoint const& pos, wxSize const& size, long style)
111 :wxMacControl(peer)
112 {
113 Rect bounds = wxMacGetBoundsForControl(peer,pos,size);
114 OSStatus err = ::CreateDataBrowserControl(MAC_WXHWND(peer->MacGetTopLevelWindowRef()),&bounds,kDataBrowserListView,&(this->m_controlRef));
115
116
117 SetReferenceInNativeControl();
118 verify_noerr(err);
119 if (gDataBrowserTableViewDrawItemUPP == NULL) gDataBrowserTableViewDrawItemUPP = NewDataBrowserDrawItemUPP (DataBrowserDrawItemProc);
120 if (gDataBrowserTableViewItemCompareUPP == NULL) gDataBrowserTableViewItemCompareUPP = NewDataBrowserItemCompareUPP(wxMacDataBrowserTableViewControl::DataBrowserCompareProc);
121 if (gDataBrowserTableViewItemDataUPP == NULL) gDataBrowserTableViewItemDataUPP = NewDataBrowserItemDataUPP (wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc);
122 if (gDataBrowserTableViewItemNotificationUPP == NULL)
123 {
124 gDataBrowserTableViewItemNotificationUPP =
125 #if TARGET_API_MAC_OSX
126 (DataBrowserItemNotificationUPP) NewDataBrowserItemNotificationWithItemUPP(wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc);
127 #else
128 NewDataBrowserItemNotificationUPP(wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc);
129 #endif
130 }
131
132 DataBrowserCallbacks callbacks;
133 DataBrowserCustomCallbacks customCallbacks;
134
135 InitializeDataBrowserCallbacks (&callbacks, kDataBrowserLatestCallbacks);
136 InitializeDataBrowserCustomCallbacks(&customCallbacks,kDataBrowserLatestCallbacks);
137
138 callbacks.u.v1.itemDataCallback = gDataBrowserTableViewItemDataUPP;
139 callbacks.u.v1.itemCompareCallback = gDataBrowserTableViewItemCompareUPP;
140 callbacks.u.v1.itemNotificationCallback = gDataBrowserTableViewItemNotificationUPP;
141 this->SetCallbacks(&callbacks);
142
143 customCallbacks.u.v1.drawItemCallback = gDataBrowserTableViewDrawItemUPP;
144 this->SetCustomCallbacks(&customCallbacks);
145
146 // style setting:
147 this->EnableCellSizeModification();
148
149 DataBrowserSelectionFlags flags; // variable definition
150
151 if (this->GetSelectionFlags(&flags) == noErr) // get default settings
152 {
153 if ((style & wxDV_MULTIPLE) != 0)
154 flags &= ~kDataBrowserSelectOnlyOne;
155 else
156 flags |= kDataBrowserSelectOnlyOne;
157 (void) this->SetSelectionFlags(flags);
158 } /* if */
159 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
160 OptionBits attributes; // variable definition
161
162 if (this->GetAttributes(&attributes) == noErr) // get default settings
163 {
164 if ((style & wxDV_VERT_RULES) != 0)
165 attributes |= kDataBrowserAttributeListViewDrawColumnDividers;
166 else
167 attributes &= ~kDataBrowserAttributeListViewDrawColumnDividers;
168 (void) this->SetAttributes(attributes);
169 } /* if */
170 #endif
171 if ((style & wxDV_NO_HEADER) != 0)
172 this->SetHeaderButtonHeight(0);
173 } /* wxMacDataBrowserTableViewControl::wxMacDataBrowserTableViewControl(wxWindow*, wxPoint const&, wxSize const&, long) */
174
175 //
176 // callback handling
177 //
178 OSStatus wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks const* callbacks)
179 {
180 return ::SetDataBrowserCallbacks(this->m_controlRef,callbacks);
181 } /* wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks const*) */
182
183 OSStatus wxMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks const* customCallbacks)
184 {
185 return ::SetDataBrowserCustomCallbacks(this->m_controlRef,customCallbacks);
186 } /* xMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks const*) */
187
188 //
189 // header handling
190 //
191 OSStatus wxMacDataBrowserTableViewControl::GetHeaderDesc(DataBrowserPropertyID property, DataBrowserListViewHeaderDesc* desc) const
192 {
193 desc->version = kDataBrowserListViewLatestHeaderDesc; // if this statement is missing the next call will fail (NOT DOCUMENTED!!)
194 return ::GetDataBrowserListViewHeaderDesc(this->m_controlRef,property,desc);
195 }
196
197 OSStatus wxMacDataBrowserTableViewControl::SetHeaderDesc(DataBrowserPropertyID property, DataBrowserListViewHeaderDesc* desc)
198 {
199 return ::SetDataBrowserListViewHeaderDesc(this->m_controlRef,property,desc);
200 }
201
202 //
203 // layout handling
204 //
205 OSStatus wxMacDataBrowserTableViewControl::AutoSizeColumns()
206 {
207 return AutoSizeDataBrowserListViewColumns(this->m_controlRef);
208 }
209
210 OSStatus wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool enableHeight, bool enableWidth)
211 {
212 return ::SetDataBrowserTableViewGeometry(this->GetControlRef(),enableWidth,enableHeight);
213 } /* wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool, bool) */
214
215 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
216 OSStatus wxMacDataBrowserTableViewControl::GetAttributes(OptionBits* attributes)
217 {
218 return ::DataBrowserGetAttributes(this->GetControlRef(),attributes);
219 } /* wxMacDataBrowserTableViewControl::GetAttributes(OptionBits*) */
220 #endif
221
222 OSStatus wxMacDataBrowserTableViewControl::GetColumnWidth( DataBrowserPropertyID column , UInt16 *width ) const
223 {
224 return GetDataBrowserTableViewNamedColumnWidth( m_controlRef , column , width );
225 }
226
227 OSStatus wxMacDataBrowserTableViewControl::GetDefaultRowHeight( UInt16 * height ) const
228 {
229 return GetDataBrowserTableViewRowHeight( m_controlRef, height );
230 }
231
232 OSStatus wxMacDataBrowserTableViewControl::GetHeaderButtonHeight(UInt16 *height)
233 {
234 return GetDataBrowserListViewHeaderBtnHeight( m_controlRef, height );
235 }
236
237 OSStatus wxMacDataBrowserTableViewControl::GetDefaultColumnWidth( UInt16 *width ) const
238 {
239 return GetDataBrowserTableViewColumnWidth( m_controlRef , width );
240 }
241
242 OSStatus wxMacDataBrowserTableViewControl::GetRowHeight( DataBrowserItemID item , UInt16 *height) const
243 {
244 return GetDataBrowserTableViewItemRowHeight( m_controlRef, item , height);
245 }
246
247 OSStatus wxMacDataBrowserTableViewControl::GetScrollPosition( UInt32 *top , UInt32 *left ) const
248 {
249 return GetDataBrowserScrollPosition( m_controlRef , top , left );
250 }
251
252 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
253 OSStatus wxMacDataBrowserTableViewControl::SetAttributes(OptionBits attributes)
254 {
255 return ::DataBrowserChangeAttributes(this->GetControlRef(),attributes,~attributes);
256 } /* wxMacDataBrowserTableViewControl::SetAttributes(OptionBits) */
257 #endif
258
259 OSStatus wxMacDataBrowserTableViewControl::SetColumnWidth( DataBrowserPropertyID column , UInt16 width )
260 {
261 return SetDataBrowserTableViewNamedColumnWidth( m_controlRef , column , width );
262 }
263
264 OSStatus wxMacDataBrowserTableViewControl::SetDefaultColumnWidth( UInt16 width )
265 {
266 return SetDataBrowserTableViewColumnWidth( m_controlRef , width );
267 }
268
269 OSStatus wxMacDataBrowserTableViewControl::SetDefaultRowHeight( UInt16 height )
270 {
271 return SetDataBrowserTableViewRowHeight( m_controlRef , height );
272 }
273
274 OSStatus wxMacDataBrowserTableViewControl::SetHasScrollBars( bool horiz, bool vert )
275 {
276 return SetDataBrowserHasScrollBars( m_controlRef, horiz, vert );
277 }
278
279 OSStatus wxMacDataBrowserTableViewControl::SetHeaderButtonHeight(UInt16 height)
280 {
281 return SetDataBrowserListViewHeaderBtnHeight( m_controlRef, height );
282 }
283
284 OSStatus wxMacDataBrowserTableViewControl::SetHiliteStyle( DataBrowserTableViewHiliteStyle hiliteStyle )
285 {
286 return SetDataBrowserTableViewHiliteStyle( m_controlRef, hiliteStyle );
287 }
288
289 OSStatus wxMacDataBrowserTableViewControl::SetRowHeight(DataBrowserItemID item, UInt16 height)
290 {
291 return ::SetDataBrowserTableViewItemRowHeight(this->m_controlRef,item,height);
292 }
293
294 OSStatus wxMacDataBrowserTableViewControl::SetScrollPosition(UInt32 top, UInt32 left)
295 {
296 return ::SetDataBrowserScrollPosition(this->m_controlRef,top,left);
297 }
298
299 //
300 // column handling
301 //
302 OSStatus wxMacDataBrowserTableViewControl::GetColumnCount(UInt32* numColumns) const
303 {
304 return GetDataBrowserTableViewColumnCount(this->m_controlRef,numColumns);
305 }
306
307 OSStatus wxMacDataBrowserTableViewControl::GetColumnID(DataBrowserTableViewColumnIndex position, DataBrowserTableViewColumnID* id)
308 {
309 return GetDataBrowserTableViewColumnProperty(this->m_controlRef,position,id);
310 } /* wxMacDataBrowserTableViewControl::GetColumnID(DataBrowserTableViewColumnIndex position, DataBrowserTableViewColumnID* id) */
311
312 OSStatus wxMacDataBrowserTableViewControl::GetFreePropertyID(DataBrowserPropertyID* id) const
313 {
314 for (*id=kMinPropertyID; *id<std::numeric_limits<DataBrowserPropertyID>::max(); ++(*id))
315 if (this->IsUsedPropertyID(*id) == errDataBrowserPropertyNotFound)
316 return noErr;
317 return errDataBrowserPropertyNotSupported;
318 } /* wxMacDataBrowserTableViewControl::GetFreePropertyID(DataBrowserPropertyID*) const */
319
320 OSStatus wxMacDataBrowserTableViewControl::GetPropertyColumn(DataBrowserPropertyID propertyID, DataBrowserTableViewColumnIndex* column) const
321 {
322 return GetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,column);
323 } /* wxMacDataBrowserTableViewControl::GetPropertyColumn(DataBrowserPropertyID, DataBrowserTableViewColumnIndex*) const */
324
325 OSStatus wxMacDataBrowserTableViewControl::GetPropertyFlags(DataBrowserPropertyID property, DataBrowserPropertyFlags *flags) const
326 {
327 return GetDataBrowserPropertyFlags( m_controlRef , property , flags );
328 }
329
330 OSStatus wxMacDataBrowserTableViewControl::IsUsedPropertyID(DataBrowserPropertyID propertyID) const
331 {
332 // 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
333 // 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
334 // the column position for the property id:
335 DataBrowserTableViewColumnIndex index;
336
337 return ::GetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,&index);
338 } /* wxMacDataBrowserTableViewControl::IsUsedPropertyId(DataBrowserPropertyID) const */
339
340 OSStatus wxMacDataBrowserTableViewControl::RemoveColumn(DataBrowserTableViewColumnIndex position)
341 {
342 DataBrowserTableViewColumnID id;
343 GetColumnID( position, &id );
344 return RemoveDataBrowserTableViewColumn( m_controlRef, id );
345 }
346
347 OSStatus wxMacDataBrowserTableViewControl::SetColumnPosition(DataBrowserPropertyID column, DataBrowserTableViewColumnIndex position)
348 {
349 return ::SetDataBrowserTableViewColumnPosition(this->m_controlRef,column,position);
350 }
351
352 OSStatus wxMacDataBrowserTableViewControl::SetPropertyFlags(DataBrowserPropertyID property, DataBrowserPropertyFlags flags)
353 {
354 return ::SetDataBrowserPropertyFlags(this->m_controlRef,property,flags);
355 } /* wxMacDataBrowserTableViewControl::SetPropertyFlags(DataBrowserPropertyID, DataBrowserPropertyFlags) */
356
357 OSStatus wxMacDataBrowserTableViewControl::SetDisclosureColumn(DataBrowserPropertyID property, Boolean expandableRows)
358 {
359 return SetDataBrowserListViewDisclosureColumn( m_controlRef, property, expandableRows);
360 }
361
362 //
363 // item handling
364 //
365 OSStatus wxMacDataBrowserTableViewControl::AddItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty)
366 {
367 return ::AddDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty);
368 } /* wxMacDataBrowserTableViewControl::AddItems(DataBrowserItemID, UInt32, DataBrowserItemID const*, DataBrowserPropertyID) */
369
370 OSStatus wxMacDataBrowserTableViewControl::GetFreeItemID(DataBrowserItemID* id) const
371 {
372 ItemCount NoOfItems;
373
374
375 verify_noerr(this->GetItemCount(&NoOfItems));
376 if (NoOfItems == 0)
377 {
378 *id = 1;
379 return noErr;
380 } /* if */
381 else
382 {
383 // 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
384 // as the number of items; therefore, start from the number of items to look for a new ID:
385 for (*id=NoOfItems; *id<std::numeric_limits<DataBrowserItemID>::max(); ++(*id))
386 if (this->IsUsedItemID(*id) == errDataBrowserItemNotFound)
387 return noErr;
388 // as the first approach was not successful, try from the beginning:
389 for (*id=0; *id<NoOfItems; ++(*id))
390 if (this->IsUsedItemID(*id) == errDataBrowserItemNotFound)
391 return noErr;
392 // sorry, data browser is full:
393 return errDataBrowserItemNotAdded;
394 } /* if */
395 } /* wxMacDataBrowserTableViewControl::GetFreeItemID(DataBrowserItemID*) const */
396
397 OSStatus wxMacDataBrowserTableViewControl::GetItemCount(DataBrowserItemID container, Boolean recurse, DataBrowserItemState state, ItemCount* numItems) const
398 {
399 return GetDataBrowserItemCount(this->m_controlRef,container,recurse,state,numItems);
400 } /* wxMacDataBrowserTableViewControl::GetItemCount(DataBrowserItemID, Boolean, DataBrowserItemState, ItemCount*) const */
401
402 OSStatus wxMacDataBrowserTableViewControl::GetItemID( DataBrowserTableViewRowIndex row, DataBrowserItemID * item ) const
403 {
404 return GetDataBrowserTableViewItemID(this->m_controlRef,row,item);
405 }
406
407 OSStatus wxMacDataBrowserTableViewControl::GetItems(DataBrowserItemID container, Boolean recurse, DataBrowserItemState state, Handle items) const
408 {
409 return GetDataBrowserItems(this->m_controlRef,container,recurse,state,items);
410 } /* wxMacDataBrowserTableViewControl::GetItems(DataBrowserItemID, Boolean, DataBrowserItemState, Handle) const */
411
412 OSStatus wxMacDataBrowserTableViewControl::GetItemRow(DataBrowserItemID item, DataBrowserTableViewRowIndex* row) const
413 {
414 return GetDataBrowserTableViewItemRow(this->m_controlRef,item,row);
415 }
416
417 OSStatus wxMacDataBrowserTableViewControl::IsUsedItemID(DataBrowserItemID itemID) const
418 {
419 // 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
420 // 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
421 // the column position for the property id:
422 DataBrowserTableViewColumnIndex index;
423
424 return ::GetDataBrowserTableViewItemRow(this->m_controlRef,itemID,&index);
425 } /* wxMacDataBrowserTableViewControl::IsUsedItemID(DataBrowserItemID) const */
426
427 OSStatus wxMacDataBrowserTableViewControl::RemoveItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty)
428 {
429 return ::RemoveDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty);
430 }
431
432 OSStatus wxMacDataBrowserTableViewControl::RevealItem(DataBrowserItemID item, DataBrowserPropertyID propertyID, DataBrowserRevealOptions options) const
433 {
434 return ::RevealDataBrowserItem(this->m_controlRef,item,propertyID,options);
435 } /* wxMacDataBrowserTableViewControl::RevealItem(DataBrowserItemID item, DataBrowserPropertyID propertyID, DataBrowserRevealOptions options) const */
436
437 OSStatus wxMacDataBrowserTableViewControl::UpdateItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty,
438 DataBrowserPropertyID propertyID) const
439 {
440 return UpdateDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty,propertyID);
441 }
442
443 //
444 // item selection
445 //
446 size_t wxMacDataBrowserTableViewControl::GetSelectedItemIDs(wxArrayDataBrowserItemID& itemIDs) const
447 {
448 DataBrowserItemID* itemIDPtr;
449 Handle handle(::NewHandle(0));
450
451 size_t NoOfItems;
452
453
454 wxCHECK_MSG(this->GetItems(kDataBrowserNoItem,true,kDataBrowserItemIsSelected,handle) == noErr,0,_("Could not get selected items."));
455 NoOfItems = static_cast<size_t>(::GetHandleSize(handle)/sizeof(DataBrowserItemID));
456 itemIDs.Empty();
457 itemIDs.Alloc(NoOfItems);
458 HLock(handle);
459 itemIDPtr = (DataBrowserItemID*) (*handle);
460 for (size_t i=0; i<NoOfItems; ++i)
461 {
462 itemIDs.Add(*itemIDPtr);
463 ++itemIDPtr;
464 } /* for */
465 HUnlock(handle);
466 DisposeHandle(handle);
467 return NoOfItems;
468 } /* wxMacDataBrowserTableViewControl::GetSelectedItemIDs(wxArrayDataBrowserItemID&) const*/
469
470 OSStatus wxMacDataBrowserTableViewControl::GetSelectionAnchor( DataBrowserItemID *first, DataBrowserItemID *last ) const
471 {
472 return GetDataBrowserSelectionAnchor( m_controlRef, first, last );
473 }
474
475 OSStatus wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags* flags) const
476 {
477 return ::GetDataBrowserSelectionFlags(this->m_controlRef,flags);
478 } /* wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags*) const */
479
480 bool wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID item) const
481 {
482 return ::IsDataBrowserItemSelected(this->m_controlRef,item);
483 } /* wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID) const */
484
485 OSStatus wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags flags)
486 {
487 return ::SetDataBrowserSelectionFlags(this->m_controlRef,flags);
488 } /* wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags) */
489
490 OSStatus wxMacDataBrowserTableViewControl::SetSelectedItems(UInt32 numItems, DataBrowserItemID const* items, DataBrowserSetOption operation)
491 {
492 return ::SetDataBrowserSelectedItems( m_controlRef, numItems, items, operation );
493 } /* wxMacDataBrowserTableViewControl::SetSelectedItems(UInt32, DataBrowserItemID const*, DataBrowserSetOption) */
494
495 OSStatus wxMacDataBrowserTableViewControl::GetSortProperty( DataBrowserPropertyID *column ) const
496 {
497 return GetDataBrowserSortProperty( m_controlRef , column );
498 }
499
500 OSStatus wxMacDataBrowserTableViewControl::SetSortProperty( DataBrowserPropertyID column )
501 {
502 return SetDataBrowserSortProperty( m_controlRef , column );
503 }
504
505 OSStatus wxMacDataBrowserTableViewControl::GetSortOrder( DataBrowserSortOrder *order ) const
506 {
507 return GetDataBrowserSortOrder( m_controlRef , order );
508 }
509
510 OSStatus wxMacDataBrowserTableViewControl::SetSortOrder( DataBrowserSortOrder order )
511 {
512 return SetDataBrowserSortOrder( m_controlRef , order );
513 }
514
515 IMPLEMENT_ABSTRACT_CLASS(wxMacDataBrowserTableViewControl,wxMacControl)
516
517 // ============================================================================
518 // Databrowser class for the list view control
519 // ============================================================================
520 //
521 #pragma mark -
522 //
523 // column handling
524 //
525 OSStatus wxMacDataBrowserListViewControl::AddColumn(DataBrowserListViewColumnDesc *columnDesc, DataBrowserTableViewColumnIndex position)
526 {
527 return AddDataBrowserListViewColumn(this->m_controlRef,columnDesc,position);
528 } /* wxMacDataBrowserListViewControl::AddColumn(DataBrowserListViewColumnDesc*, DataBrowserTableViewColumnIndex) */
529
530 // ============================================================================
531 // Databrowser class for the data view control
532 // ============================================================================
533 //
534 #pragma mark -
535 //
536 // constructors / destructor
537 //
538 wxMacDataViewDataBrowserListViewControl::wxMacDataViewDataBrowserListViewControl(wxWindow* peer, wxPoint const& pos, wxSize const& size, long style)
539 :wxMacDataBrowserListViewControl(peer,pos,size,style)
540 {
541 } /* wxMacDataViewDataBrowserListViewControl::wxMacDataViewDataBrowserListViewControl(wxWindow* , const wxPoint&, const wxSize&, long) */
542
543 //
544 // item ID and model matching
545 //
546 void wxMacDataViewDataBrowserListViewControl::ClearItemIDRowPairs(void)
547 {
548 this->m_itemIDRowNumberMap.clear();
549 } /* wxMacDataViewDataBrowserListViewControl::ClearItemIDRowPairs(void) */
550
551 bool wxMacDataViewDataBrowserListViewControl::DeleteItemIDRowPair(DataBrowserItemID itemID)
552 {
553 return (this->m_itemIDRowNumberMap.erase(itemID) == 1);
554 } /* wxMacDataViewDataBrowserListViewControl::DeleteItemIDRowPair(DataBrowseritemID) */
555
556 bool wxMacDataViewDataBrowserListViewControl::GetRowIndex(unsigned long& rowIndex, DataBrowserItemID itemID) const
557 {
558 ItemIDRowNumberHashMap::const_iterator iteratorHashMap(this->m_itemIDRowNumberMap.find(itemID));
559
560
561 if (iteratorHashMap == this->m_itemIDRowNumberMap.end())
562 return false;
563 else
564 {
565 rowIndex = iteratorHashMap->second;
566 return true;
567 } /* if */
568 } /* wxMacDataViewDataBrowserListViewControl::GetRowIndex(unsigned int& rowIndex, DataBrowserItemID itemID) const */
569
570 bool wxMacDataViewDataBrowserListViewControl::InsertItemIDRowPair(DataBrowserItemID itemID, unsigned long rowIndex)
571 {
572 return this->m_itemIDRowNumberMap.insert(ItemIDRowNumberHashMap::value_type(itemID,rowIndex)).second;
573 } /* wxMacDataViewDataBrowserListViewControl::InsertItemIDRowPair(DataBrowserItemID, unsigned long) */
574
575 void wxMacDataViewDataBrowserListViewControl::RenumberItemIDRowIndices(unsigned int* newIndices)
576 {
577 ItemIDRowNumberHashMap::iterator hashMapIterator(this->m_itemIDRowNumberMap.begin());
578
579
580 while (hashMapIterator != this->m_itemIDRowNumberMap.end())
581 {
582 hashMapIterator->second = newIndices[hashMapIterator->second];
583 ++hashMapIterator;
584 } /* while */
585 } /* wxMacDataViewDataBrowserListViewControl::RenumberItemIDRowIndices(unsigned int*) */
586
587 void wxMacDataViewDataBrowserListViewControl::RenumberItemIDRowIndicesDeletion (unsigned long decreaseFromIndex)
588 {
589 ItemIDRowNumberHashMap::iterator hashMapIterator(this->m_itemIDRowNumberMap.begin());
590
591
592 while (hashMapIterator != this->m_itemIDRowNumberMap.end())
593 {
594 if (hashMapIterator->second >= decreaseFromIndex)
595 --(hashMapIterator->second);
596 ++hashMapIterator;
597 } /* while */
598 } /* wxMacDataViewDataBrowserListViewControl::RenumberItemIDRowIndicesDeletion (unsigned int) */
599
600 void wxMacDataViewDataBrowserListViewControl::RenumberItemIDRowIndicesInsertion(unsigned long increaseFromIndex)
601 {
602 ItemIDRowNumberHashMap::iterator hashMapIterator(this->m_itemIDRowNumberMap.begin());
603
604
605 while (hashMapIterator != this->m_itemIDRowNumberMap.end())
606 {
607 if (hashMapIterator->second >= increaseFromIndex)
608 ++(hashMapIterator->second);
609 ++hashMapIterator;
610 } /* while */
611 } /* wxMacDataViewDataBrowserListViewControl::RenumberItemIDRowIndicesInsertion(unsigned int) */
612
613 void wxMacDataViewDataBrowserListViewControl::ReverseRowIndexNumbering(void)
614 {
615 if (this->m_itemIDRowNumberMap.size() > 0)
616 {
617 size_t const maxIndex = this->m_itemIDRowNumberMap.size()-1;
618
619 ItemIDRowNumberHashMap::iterator hashMapIterator(this->m_itemIDRowNumberMap.begin());
620
621
622 while (hashMapIterator != this->m_itemIDRowNumberMap.end())
623 {
624 hashMapIterator->second = maxIndex-hashMapIterator->second;
625 ++hashMapIterator;
626 } /* while */
627 } /* if */
628 } /* wxMacDataViewDataBrowserListViewControl::ReverseRowIndexNumbering(void) */
629
630 //
631 // callback functions (inherited from wxMacDataBrowserTableViewControl)
632 //
633 Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID itemOneID, DataBrowserItemID itemTwoID, DataBrowserPropertyID WXUNUSED(sortProperty))
634 {
635 unsigned long rowIndex1, rowIndex2;
636
637 bool result = (this->GetRowIndex(rowIndex1,itemOneID) && this->GetRowIndex(rowIndex2,itemTwoID) && (rowIndex1 < rowIndex2));
638 return result;
639 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID) */
640
641 void wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID itemID, DataBrowserPropertyID property, DataBrowserItemState state, Rect const* rectangle, SInt16 bitDepth, Boolean colorDevice)
642 {
643 OSStatus errorStatus;
644
645 unsigned long column;
646 unsigned long row;
647
648 wxDataViewColumn* dataViewColumnPtr;
649
650 wxDataViewCtrl* dataViewCtrlPtr;
651
652 wxDataViewCustomRenderer* dataViewCustomRendererPtr;
653
654 wxVariant dataToRender;
655
656
657 wxCHECK_RET(this->GetPropertyColumn(property,&column) == noErr,_("Could not determine column index."));
658 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetPeer());
659 wxCHECK_RET(dataViewCtrlPtr != NULL, _("Pointer to data view control not set correctly."));
660 wxCHECK_RET(dataViewCtrlPtr->GetModel() != NULL,_("Pointer to model not set correctly."));
661 if (dynamic_cast<wxDataViewSortedListModel*>(dataViewCtrlPtr->GetModel()) == NULL)
662 {
663 wxCHECK_RET(this->GetRowIndex(row,itemID),_("Row index does not exist."));
664 } /* if */
665 else
666 {
667 wxCHECK_RET(this->GetItemRow(itemID,&row) == noErr,_("Row index does not exist."));
668 } /* if */
669 dataViewColumnPtr = dataViewCtrlPtr->GetColumn(column);
670 wxCHECK_RET(dataViewColumnPtr != NULL,_("No column for the specified column index existing."));
671 dataViewCustomRendererPtr = dynamic_cast<wxDataViewCustomRenderer*>(dataViewColumnPtr->GetRenderer());
672 wxCHECK_RET(dataViewCustomRendererPtr != NULL,_("No renderer or invalid renderer type specified for custom data column."));
673 dataViewCtrlPtr->GetModel()->GetValue(dataToRender,column,row);
674 dataViewCustomRendererPtr->SetValue(dataToRender);
675
676 // try to determine the content's size (drawable part):
677 Rect content;
678 RgnHandle rgn(NewRgn());
679 UInt16 headerHeight;
680
681 if (this->GetRegion(kControlContentMetaPart,rgn) == noErr)
682 GetRegionBounds(rgn,&content);
683 else
684 this->GetRect(&content);
685 ::DisposeRgn(rgn);
686 // space for the header
687 this->GetHeaderButtonHeight(&headerHeight);
688 content.top += headerHeight;
689 // extra space for the frame (todo: do not how to determine the space automatically from the control)
690 content.top += 5;
691 content.left += 5;
692 content.right -= 3;
693 content.bottom -= 3;
694 // extra space for the scrollbars:
695 content.bottom -= wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y);
696 content.right -= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
697
698 // make sure that 'Render' can draw only in the allowed area:
699 dataViewCustomRendererPtr->GetDC()->SetClippingRegion(content.left,content.top,content.right-content.left+1,content.bottom-content.top+1);
700 (void) (dataViewCustomRendererPtr->Render(wxRect(static_cast<int>(rectangle->left),static_cast<int>(rectangle->top),
701 static_cast<int>(1+rectangle->right-rectangle->left),static_cast<int>(1+rectangle->bottom-rectangle->top)),
702 dataViewCustomRendererPtr->GetDC(),((state == kDataBrowserItemIsSelected) ? wxDATAVIEW_CELL_SELECTED : 0)));
703 dataViewCustomRendererPtr->GetDC()->DestroyClippingRegion(); // probably not necessary
704 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemState, Rect const*, SInt16, Boolean) */
705
706 OSStatus wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc(DataBrowserItemID itemID, DataBrowserPropertyID property, DataBrowserItemDataRef itemData, Boolean getValue)
707 {
708 if (getValue)
709 {
710 // variable definition:
711 unsigned long column;
712 unsigned long row;
713 wxDataViewCtrl* dataViewCtrlPtr;
714 wxDataViewColumn* dataViewColumnPtr;
715
716 verify_noerr(this->GetPropertyColumn(property,&column));
717 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetPeer());
718 wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
719 if (dynamic_cast<wxDataViewSortedListModel*>(dataViewCtrlPtr->GetModel()) == NULL)
720 {
721 wxCHECK_MSG(this->GetRowIndex(row,itemID),errDataBrowserNotConfigured,_("Row index does not exist."));
722 } /* if */
723 else
724 {
725 wxCHECK_MSG(this->GetItemRow(itemID,&row) == noErr,errDataBrowserNotConfigured,_("Row index does not exist."));
726 } /* if */
727 dataViewColumnPtr = dataViewCtrlPtr->GetColumn(column);
728 wxCHECK_MSG((dataViewColumnPtr != NULL) && (dataViewColumnPtr->GetRenderer() != NULL),errDataBrowserNotConfigured,_("There is no column for the specified column index."));
729 switch (dataViewColumnPtr->GetRenderer()->GetPropertyType())
730 {
731 case kDataBrowserCheckboxType:
732 {
733 // variable definitions:
734 ThemeButtonValue buttonValue;
735 OSStatus errorStatus;
736
737 errorStatus = ::GetDataBrowserItemDataButtonValue(itemData,&buttonValue);
738 if (errorStatus == noErr)
739 {
740 if (buttonValue == kThemeButtonOn)
741 {
742 // variable definition and initialization:
743 wxVariant modifiedData(true);
744
745 return (dataViewCtrlPtr->GetModel()->SetValue(modifiedData,static_cast<unsigned int>(column),static_cast<unsigned int>(row)) ? noErr : errDataBrowserNotConfigured);
746 } /* if */
747 else if (buttonValue == kThemeButtonOff)
748 {
749 // variable definition and initialization:
750 wxVariant modifiedData(false);
751
752 return (dataViewCtrlPtr->GetModel()->SetValue(modifiedData,static_cast<unsigned int>(column),static_cast<unsigned int>(row)) ? noErr : errDataBrowserNotConfigured);
753 } /* if */
754 else
755 return errDataBrowserInvalidPropertyData;
756 } /* if */
757 else
758 return errorStatus;
759 } /* block */
760 case kDataBrowserTextType:
761 {
762 // variable definitions:
763 CFStringRef stringReference;
764 OSStatus errorStatus;
765
766 errorStatus = ::GetDataBrowserItemDataText(itemData,&stringReference);
767 if (errorStatus == noErr)
768 {
769 // variable definitions and initializations:
770 wxMacCFStringHolder modifiedString(stringReference);
771 wxVariant modifiedData(modifiedString.AsString());
772
773 if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData,static_cast<unsigned int>(column),static_cast<unsigned int>(row)))
774 return noErr;
775 else
776 return errDataBrowserNotConfigured;
777 } /* if */
778 else
779 return errorStatus;
780 } /* block */
781 default:
782 return errDataBrowserPropertyNotSupported;
783 } /* switch */
784 } /* if */
785 else
786 {
787 if (property >= kMinPropertyID) // in case of data columns set the data
788 {
789 // variable definitions:
790 OSStatus errorStatus;
791 unsigned long columnPosition;
792 unsigned long rowPosition;
793 wxVariant variant;
794 wxDataViewColumn* dataViewColumnPtr;
795 wxDataViewCtrl* dataViewCtrlPtr;
796
797 errorStatus = this->GetPropertyColumn(property,&columnPosition);
798 wxCHECK_MSG(errorStatus == noErr,errorStatus,_("Column index does not exist."));
799 dataViewCtrlPtr = dynamic_cast<wxDataViewCtrl*>(this->GetPeer());wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly."));
800 dataViewColumnPtr = dataViewCtrlPtr->GetColumn(columnPosition); wxCHECK_MSG(dataViewColumnPtr != NULL,errDataBrowserNotConfigured,_("No column for the specified column position existing."));
801 if (dynamic_cast<wxDataViewSortedListModel*>(dataViewCtrlPtr->GetModel()) == NULL)
802 {
803 wxCHECK_MSG(this->GetRowIndex(rowPosition,itemID),errDataBrowserNotConfigured,_("Row index does not exist."));
804 } /* if */
805 else
806 {
807 wxCHECK_MSG(this->GetItemRow(itemID,&rowPosition) == noErr,errDataBrowserNotConfigured,_("Row index does not exist."));
808 } /* if */
809 dataViewCtrlPtr->GetModel()->GetValue(variant,dataViewColumnPtr->GetModelColumn(),rowPosition);
810 wxCHECK_MSG(dataViewColumnPtr->GetRenderer() != NULL,errDataBrowserNotConfigured,_("No renderer specified for column."));
811 dataViewColumnPtr->GetRenderer()->SetDataReference(itemData);
812 dataViewColumnPtr->GetRenderer()->SetValue(variant);
813 wxCHECK_MSG(dataViewColumnPtr->GetRenderer()->Render(),errDataBrowserNotConfigured,_("Rendering failed."));
814 } /* if */
815 else // react on special system requests
816 switch (property)
817 {
818 case kDataBrowserItemIsContainerProperty:
819 return ::SetDataBrowserItemDataBooleanValue(itemData,false);
820 case kDataBrowserItemIsEditableProperty:
821 return ::SetDataBrowserItemDataBooleanValue(itemData,true);
822 } /* switch */
823 } /* if */
824 return errDataBrowserPropertyNotSupported;
825 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc(DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemDataRef, Boolean) */
826
827 void wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID itemID, DataBrowserItemNotification message, DataBrowserItemDataRef WXUNUSED(itemData))
828 {
829 switch (message)
830 {
831 case kDataBrowserItemDoubleClicked:
832 {
833 // variable definitions:
834 unsigned long row;
835 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetPeer()));
836
837 wxCHECK_RET(dataViewCtrlPtr != NULL, _("Pointer to data view control not set correctly."));
838 wxCHECK_RET(this->GetRowIndex(row,itemID),_("Row index does not exist."));
839 // initialize wxWidget event:
840 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ROW_ACTIVATED,dataViewCtrlPtr->GetId()); // variable defintion
841
842 dataViewEvent.SetEventObject(dataViewCtrlPtr);
843 dataViewEvent.SetRow(row);
844 // finally sent the equivalent wxWidget event:
845 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
846 } /* block */
847 break;
848 case kDataBrowserItemSelected:
849 {
850 // variable definitions:
851 unsigned long row;
852 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetPeer()));
853
854 wxCHECK_RET(dataViewCtrlPtr != NULL, _("Pointer to data view control not set correctly."));
855 if (dynamic_cast<wxDataViewSortedListModel*>(dataViewCtrlPtr->GetModel()) == NULL)
856 {
857 wxCHECK_RET(this->GetRowIndex(row,itemID),_("Row index does not exist."));
858 } /* if */
859 else
860 {
861 wxCHECK_RET(this->GetItemRow(itemID,&row) == noErr,_("Row index does not exist."));
862 } /* if */
863 // initialize wxWidget event:
864 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ROW_SELECTED,dataViewCtrlPtr->GetId()); // variable defintion
865
866 dataViewEvent.SetEventObject(dataViewCtrlPtr);
867 dataViewEvent.SetRow(row);
868 // finally sent the equivalent wxWidget event:
869 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
870 } /* block */
871 break;
872 case kDataBrowserUserStateChanged:
873 {
874 DataBrowserPropertyID propertyId;
875
876 if ((this->GetSortProperty(&propertyId) == noErr) && (propertyId >= kMinPropertyID))
877 {
878 DataBrowserSortOrder sortOrder;
879 unsigned long column;
880
881 if ((this->GetSortOrder(&sortOrder) == noErr) && (this->GetPropertyColumn(propertyId,&column) == noErr))
882 {
883 wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl*>(this->GetPeer()));
884
885 if ( dataViewCtrlPtr->GetColumn(column)->IsSortOrderAscending() && (sortOrder == kDataBrowserOrderDecreasing) ||
886 !(dataViewCtrlPtr->GetColumn(column)->IsSortOrderAscending()) && (sortOrder == kDataBrowserOrderIncreasing))
887 {
888 // initialize wxWidget event:
889 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED,dataViewCtrlPtr->GetId()); // variable defintion
890
891 dataViewEvent.SetEventObject(dataViewCtrlPtr);
892 dataViewEvent.SetColumn(column);
893 dataViewEvent.SetDataViewColumn(dataViewCtrlPtr->GetColumn(column));
894 // finally sent the equivalent wxWidget event:
895 dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent);
896 } /* if */
897 } /* if */
898 } /* if */
899 } /* block */
900 break;
901 } /* switch */
902 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID, DataBrowserItemNotification, DataBrowserItemDataRef) */
903
904
905 #endif
906 // wxUSE_GENERICDATAVIEWCTRL