1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/mac/carbon/databrow.cpp 
   3 // Purpose:     Classes and functions for the Carbon data browser 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #ifndef wxUSE_GENERICDATAVIEWCTRL 
  21 #include "wx/wxprec.h" 
  27     #include "wx/toplevel.h" 
  31 #include "wx/apptrait.h" 
  33 #include "wx/mac/uma.h" 
  37     #include <Carbon/Carbon.h> 
  39     #include <ATSUnicode.h> 
  40     #include <TextCommon.h> 
  41     #include <TextEncodingConverter.h> 
  44 #include "wx/mac/private.h" 
  46 #if defined(__MWERKS__) && wxUSE_UNICODE 
  47 #if __MWERKS__ < 0x4100 || !defined(__DARWIN__) 
  54 #include "wx/mac/carbon/databrow.h" 
  56 #include "wx/dataview.h" 
  58 // ============================================================================ 
  59 // DataBrowser Wrapper 
  60 // ============================================================================ 
  62 // basing on DataBrowserItemIDs 
  65 pascal Boolean 
wxMacDataBrowserTableViewControl::DataBrowserCompareProc(ControlRef browser
, DataBrowserItemID itemOneID
, DataBrowserItemID itemTwoID
, DataBrowserPropertyID sortProperty
) 
  67   wxMacDataBrowserTableViewControl
* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl
*>(wxMacControl::GetReferenceFromNativeControl(browser
))); 
  70   if (ControlPtr 
!= NULL
) 
  71     return ControlPtr
->DataBrowserCompareProc(itemOneID
,itemTwoID
,sortProperty
); 
  73     return errDataBrowserPropertyNotSupported
; 
  74 } /* wxMacDataBrowserTableViewControl::DataBrowserCompareProc(ControlRef, DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID) */ 
  76 pascal void wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc(ControlRef browser
, DataBrowserItemID itemID
, DataBrowserPropertyID property
, DataBrowserItemState state
, Rect 
const* rectangle
, SInt16 bitDepth
, Boolean colorDevice
) 
  78   wxMacDataBrowserTableViewControl
* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl
*>(wxMacControl::GetReferenceFromNativeControl(browser
))); 
  81   if (ControlPtr 
!= NULL
) 
  82     ControlPtr
->DataBrowserDrawItemProc(itemID
,property
,state
,rectangle
,bitDepth
,colorDevice
); 
  83 } /* wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemState, Rect const*, SInt16, Boolean) */ 
  85 pascal OSStatus 
wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc(ControlRef browser
, DataBrowserItemID itemID
, DataBrowserPropertyID property
, DataBrowserItemDataRef itemData
, Boolean getValue
) 
  87   wxMacDataBrowserTableViewControl
* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl
*>(wxMacControl::GetReferenceFromNativeControl(browser
))); 
  90   if (ControlPtr 
!= NULL
) 
  91     return ControlPtr
->DataBrowserGetSetItemDataProc(itemID
,property
,itemData
,getValue
); 
  93     return errDataBrowserPropertyNotSupported
; 
  94 } /* wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemDataRef, Boolean) */ 
  96 pascal void wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc(ControlRef browser
, DataBrowserItemID itemID
, DataBrowserItemNotification message
, DataBrowserItemDataRef itemData
) 
  98   wxMacDataBrowserTableViewControl
* ControlPtr(dynamic_cast<wxMacDataBrowserTableViewControl
*>(wxMacControl::GetReferenceFromNativeControl(browser
))); 
 101   if (ControlPtr 
!= NULL
) 
 102     ControlPtr
->DataBrowserItemNotificationProc(itemID
,message
,itemData
); 
 103 } /* wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc(ControlRef, DataBrowserItemID, DataBrowserItemNotification, DataBrowserItemDataRef) */ 
 105 DataBrowserDrawItemUPP         gDataBrowserTableViewDrawItemUPP         
= NULL
; 
 106 DataBrowserItemCompareUPP      gDataBrowserTableViewItemCompareUPP      
= NULL
; 
 107 DataBrowserItemDataUPP         gDataBrowserTableViewItemDataUPP         
= NULL
; 
 108 DataBrowserItemNotificationUPP gDataBrowserTableViewItemNotificationUPP 
= NULL
; 
 110 wxMacDataBrowserTableViewControl::wxMacDataBrowserTableViewControl(wxWindow
* peer
, wxPoint 
const& pos
, wxSize 
const& size
, long style
) 
 113   Rect bounds 
= wxMacGetBoundsForControl(peer
,pos
,size
); 
 114   OSStatus err 
= ::CreateDataBrowserControl(MAC_WXHWND(peer
->MacGetTopLevelWindowRef()),&bounds
,kDataBrowserListView
,&(this->m_controlRef
)); 
 117   SetReferenceInNativeControl(); 
 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
) 
 124     gDataBrowserTableViewItemNotificationUPP 
= 
 125 #if TARGET_API_MAC_OSX 
 126       (DataBrowserItemNotificationUPP
) NewDataBrowserItemNotificationWithItemUPP(wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc
); 
 128       NewDataBrowserItemNotificationUPP(wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc
); 
 132   DataBrowserCallbacks       callbacks
; 
 133   DataBrowserCustomCallbacks customCallbacks
; 
 135   InitializeDataBrowserCallbacks      (&callbacks
,      kDataBrowserLatestCallbacks
); 
 136   InitializeDataBrowserCustomCallbacks(&customCallbacks
,kDataBrowserLatestCallbacks
); 
 138   callbacks
.u
.v1
.itemDataCallback         
= gDataBrowserTableViewItemDataUPP
; 
 139   callbacks
.u
.v1
.itemCompareCallback      
= gDataBrowserTableViewItemCompareUPP
; 
 140   callbacks
.u
.v1
.itemNotificationCallback 
= gDataBrowserTableViewItemNotificationUPP
; 
 141   this->SetCallbacks(&callbacks
); 
 143   customCallbacks
.u
.v1
.drawItemCallback 
= gDataBrowserTableViewDrawItemUPP
; 
 144   this->SetCustomCallbacks(&customCallbacks
); 
 147   this->EnableCellSizeModification(); 
 149   DataBrowserSelectionFlags flags
; // variable definition 
 151   if (this->GetSelectionFlags(&flags
) == noErr
) // get default settings 
 153     if ((style 
& wxDV_MULTIPLE
) != 0) 
 154       flags 
&= ~kDataBrowserSelectOnlyOne
; 
 156       flags 
|= kDataBrowserSelectOnlyOne
; 
 157     (void) this->SetSelectionFlags(flags
); 
 159 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 
 160   OptionBits attributes
; // variable definition 
 162   if (this->GetAttributes(&attributes
) == noErr
) // get default settings 
 164     if ((style 
& wxDV_VERT_RULES
) != 0) 
 165       attributes 
|= kDataBrowserAttributeListViewDrawColumnDividers
; 
 167       attributes 
&= ~kDataBrowserAttributeListViewDrawColumnDividers
; 
 168     (void) this->SetAttributes(attributes
); 
 171   if ((style 
& wxDV_NO_HEADER
) != 0) 
 172     this->SetHeaderButtonHeight(0); 
 173 } /* wxMacDataBrowserTableViewControl::wxMacDataBrowserTableViewControl(wxWindow*, wxPoint const&, wxSize const&, long) */ 
 178 OSStatus 
wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks 
const* callbacks
) 
 180   return ::SetDataBrowserCallbacks(this->m_controlRef
,callbacks
); 
 181 } /* wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks const*) */ 
 183 OSStatus 
wxMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks 
const* customCallbacks
) 
 185   return ::SetDataBrowserCustomCallbacks(this->m_controlRef
,customCallbacks
); 
 186 } /* xMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks const*) */ 
 191 OSStatus 
wxMacDataBrowserTableViewControl::GetHeaderDesc(DataBrowserPropertyID property
, DataBrowserListViewHeaderDesc
* desc
) const 
 193   desc
->version 
= kDataBrowserListViewLatestHeaderDesc
; // if this statement is missing the next call will fail (NOT DOCUMENTED!!) 
 194   return ::GetDataBrowserListViewHeaderDesc(this->m_controlRef
,property
,desc
); 
 197 OSStatus 
wxMacDataBrowserTableViewControl::SetHeaderDesc(DataBrowserPropertyID property
, DataBrowserListViewHeaderDesc
* desc
) 
 199   return ::SetDataBrowserListViewHeaderDesc(this->m_controlRef
,property
,desc
); 
 205 OSStatus 
wxMacDataBrowserTableViewControl::AutoSizeColumns() 
 207   return AutoSizeDataBrowserListViewColumns(this->m_controlRef
); 
 210 OSStatus 
wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool enableHeight
, bool enableWidth
) 
 212   return ::SetDataBrowserTableViewGeometry(this->GetControlRef(),enableWidth
,enableHeight
); 
 213 } /* wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool, bool) */ 
 215 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 
 216 OSStatus 
wxMacDataBrowserTableViewControl::GetAttributes(OptionBits
* attributes
) 
 218   return ::DataBrowserGetAttributes(this->GetControlRef(),attributes
); 
 219 } /* wxMacDataBrowserTableViewControl::GetAttributes(OptionBits*) */ 
 222 OSStatus 
wxMacDataBrowserTableViewControl::GetColumnWidth( DataBrowserPropertyID column 
, UInt16 
*width 
) const 
 224     return GetDataBrowserTableViewNamedColumnWidth( m_controlRef 
, column 
, width 
); 
 227 OSStatus 
wxMacDataBrowserTableViewControl::GetDefaultRowHeight( UInt16 
* height 
) const 
 229     return GetDataBrowserTableViewRowHeight( m_controlRef
, height 
); 
 232 OSStatus 
wxMacDataBrowserTableViewControl::GetHeaderButtonHeight(UInt16 
*height
) 
 234     return GetDataBrowserListViewHeaderBtnHeight( m_controlRef
, height 
); 
 237 OSStatus 
wxMacDataBrowserTableViewControl::GetDefaultColumnWidth( UInt16 
*width 
) const 
 239     return GetDataBrowserTableViewColumnWidth( m_controlRef 
, width 
); 
 242 OSStatus 
wxMacDataBrowserTableViewControl::GetRowHeight( DataBrowserItemID item 
, UInt16 
*height
) const 
 244     return GetDataBrowserTableViewItemRowHeight( m_controlRef
, item 
, height
); 
 247 OSStatus 
wxMacDataBrowserTableViewControl::GetScrollPosition( UInt32 
*top 
, UInt32 
*left 
) const 
 249     return GetDataBrowserScrollPosition( m_controlRef 
, top 
, left 
); 
 252 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 
 253 OSStatus 
wxMacDataBrowserTableViewControl::SetAttributes(OptionBits attributes
) 
 255   return ::DataBrowserChangeAttributes(this->GetControlRef(),attributes
,~attributes
); 
 256 } /* wxMacDataBrowserTableViewControl::SetAttributes(OptionBits) */ 
 259 OSStatus 
wxMacDataBrowserTableViewControl::SetColumnWidth( DataBrowserPropertyID column 
, UInt16 width 
) 
 261     return SetDataBrowserTableViewNamedColumnWidth( m_controlRef 
, column 
, width 
); 
 264 OSStatus 
wxMacDataBrowserTableViewControl::SetDefaultColumnWidth( UInt16 width 
) 
 266     return SetDataBrowserTableViewColumnWidth( m_controlRef 
, width 
); 
 269 OSStatus 
wxMacDataBrowserTableViewControl::SetDefaultRowHeight( UInt16 height 
) 
 271     return SetDataBrowserTableViewRowHeight( m_controlRef 
, height 
); 
 274 OSStatus 
wxMacDataBrowserTableViewControl::SetHasScrollBars( bool horiz
, bool vert 
) 
 276     return SetDataBrowserHasScrollBars( m_controlRef
, horiz
, vert 
); 
 279 OSStatus 
wxMacDataBrowserTableViewControl::SetHeaderButtonHeight(UInt16 height
) 
 281     return SetDataBrowserListViewHeaderBtnHeight( m_controlRef
, height 
); 
 284 OSStatus 
wxMacDataBrowserTableViewControl::SetHiliteStyle( DataBrowserTableViewHiliteStyle hiliteStyle 
) 
 286     return SetDataBrowserTableViewHiliteStyle( m_controlRef
, hiliteStyle 
); 
 289 OSStatus 
wxMacDataBrowserTableViewControl::SetRowHeight(DataBrowserItemID item
, UInt16 height
) 
 291   return ::SetDataBrowserTableViewItemRowHeight(this->m_controlRef
,item
,height
); 
 294 OSStatus 
wxMacDataBrowserTableViewControl::SetScrollPosition(UInt32 top
, UInt32 left
) 
 296   return ::SetDataBrowserScrollPosition(this->m_controlRef
,top
,left
); 
 302 OSStatus 
wxMacDataBrowserTableViewControl::GetColumnCount(UInt32
* numColumns
) const 
 304   return GetDataBrowserTableViewColumnCount(this->m_controlRef
,numColumns
); 
 307 OSStatus 
wxMacDataBrowserTableViewControl::GetColumnID(DataBrowserTableViewColumnIndex position
, DataBrowserTableViewColumnID
* id
) 
 309   return GetDataBrowserTableViewColumnProperty(this->m_controlRef
,position
,id
); 
 310 } /* wxMacDataBrowserTableViewControl::GetColumnID(DataBrowserTableViewColumnIndex position, DataBrowserTableViewColumnID* id) */ 
 312 OSStatus 
wxMacDataBrowserTableViewControl::GetFreePropertyID(DataBrowserPropertyID
* id
) const 
 314   for (*id
=kMinPropertyID
; *id
<std::numeric_limits
<DataBrowserPropertyID
>::max(); ++(*id
)) 
 315     if (this->IsUsedPropertyID(*id
) == errDataBrowserPropertyNotFound
) 
 317   return errDataBrowserPropertyNotSupported
; 
 318 } /* wxMacDataBrowserTableViewControl::GetFreePropertyID(DataBrowserPropertyID*) const */ 
 320 OSStatus 
wxMacDataBrowserTableViewControl::GetPropertyColumn(DataBrowserPropertyID propertyID
, DataBrowserTableViewColumnIndex
* column
) const 
 322   return GetDataBrowserTableViewColumnPosition(this->m_controlRef
,propertyID
,column
); 
 323 } /* wxMacDataBrowserTableViewControl::GetPropertyColumn(DataBrowserPropertyID, DataBrowserTableViewColumnIndex*) const */ 
 325 OSStatus 
wxMacDataBrowserTableViewControl::GetPropertyFlags(DataBrowserPropertyID property
, DataBrowserPropertyFlags 
*flags
) const 
 327     return GetDataBrowserPropertyFlags( m_controlRef 
, property 
, flags 
); 
 330 OSStatus 
wxMacDataBrowserTableViewControl::IsUsedPropertyID(DataBrowserPropertyID propertyID
) const 
 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
; 
 337   return ::GetDataBrowserTableViewColumnPosition(this->m_controlRef
,propertyID
,&index
); 
 338 } /* wxMacDataBrowserTableViewControl::IsUsedPropertyId(DataBrowserPropertyID) const */ 
 340 OSStatus 
wxMacDataBrowserTableViewControl::RemoveColumn(DataBrowserTableViewColumnIndex position
) 
 342   DataBrowserTableViewColumnID id
; 
 343   GetColumnID( position
, &id 
); 
 344   return RemoveDataBrowserTableViewColumn( m_controlRef
, id 
); 
 347 OSStatus 
wxMacDataBrowserTableViewControl::SetColumnPosition(DataBrowserPropertyID column
, DataBrowserTableViewColumnIndex position
) 
 349   return ::SetDataBrowserTableViewColumnPosition(this->m_controlRef
,column
,position
); 
 352 OSStatus 
wxMacDataBrowserTableViewControl::SetPropertyFlags(DataBrowserPropertyID property
, DataBrowserPropertyFlags flags
) 
 354   return ::SetDataBrowserPropertyFlags(this->m_controlRef
,property
,flags
); 
 355 } /* wxMacDataBrowserTableViewControl::SetPropertyFlags(DataBrowserPropertyID, DataBrowserPropertyFlags) */ 
 357 OSStatus 
wxMacDataBrowserTableViewControl::SetDisclosureColumn(DataBrowserPropertyID property
, Boolean expandableRows
) 
 359   return SetDataBrowserListViewDisclosureColumn( m_controlRef
, property
, expandableRows
); 
 365 OSStatus 
wxMacDataBrowserTableViewControl::AddItems(DataBrowserItemID container
, UInt32 numItems
, DataBrowserItemID 
const* items
, DataBrowserPropertyID preSortProperty
) 
 367   return ::AddDataBrowserItems(this->m_controlRef
,container
,numItems
,items
,preSortProperty
); 
 368 } /* wxMacDataBrowserTableViewControl::AddItems(DataBrowserItemID, UInt32, DataBrowserItemID const*, DataBrowserPropertyID) */ 
 370 OSStatus 
wxMacDataBrowserTableViewControl::GetFreeItemID(DataBrowserItemID
* id
) const 
 375   verify_noerr(this->GetItemCount(&NoOfItems
)); 
 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
) 
 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
) 
 392    // sorry, data browser is full: 
 393     return errDataBrowserItemNotAdded
; 
 395 } /* wxMacDataBrowserTableViewControl::GetFreeItemID(DataBrowserItemID*) const */ 
 397 OSStatus 
wxMacDataBrowserTableViewControl::GetItemCount(DataBrowserItemID container
, Boolean recurse
, DataBrowserItemState state
, ItemCount
* numItems
) const 
 399   return GetDataBrowserItemCount(this->m_controlRef
,container
,recurse
,state
,numItems
); 
 400 } /* wxMacDataBrowserTableViewControl::GetItemCount(DataBrowserItemID, Boolean, DataBrowserItemState, ItemCount*) const */ 
 402 OSStatus 
wxMacDataBrowserTableViewControl::GetItemID( DataBrowserTableViewRowIndex row
, DataBrowserItemID 
* item 
) const 
 404   return GetDataBrowserTableViewItemID(this->m_controlRef
,row
,item
); 
 407 OSStatus 
wxMacDataBrowserTableViewControl::GetItems(DataBrowserItemID container
, Boolean recurse
, DataBrowserItemState state
, Handle items
) const 
 409   return GetDataBrowserItems(this->m_controlRef
,container
,recurse
,state
,items
); 
 410 } /* wxMacDataBrowserTableViewControl::GetItems(DataBrowserItemID, Boolean, DataBrowserItemState, Handle) const */ 
 412 OSStatus 
wxMacDataBrowserTableViewControl::GetItemRow(DataBrowserItemID item
, DataBrowserTableViewRowIndex
* row
) const 
 414   return GetDataBrowserTableViewItemRow(this->m_controlRef
,item
,row
); 
 417 OSStatus 
wxMacDataBrowserTableViewControl::IsUsedItemID(DataBrowserItemID itemID
) const 
 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
; 
 424   return ::GetDataBrowserTableViewItemRow(this->m_controlRef
,itemID
,&index
); 
 425 } /* wxMacDataBrowserTableViewControl::IsUsedItemID(DataBrowserItemID) const */ 
 427 OSStatus 
wxMacDataBrowserTableViewControl::RemoveItems(DataBrowserItemID container
, UInt32 numItems
, DataBrowserItemID 
const* items
, DataBrowserPropertyID preSortProperty
) 
 429   return ::RemoveDataBrowserItems(this->m_controlRef
,container
,numItems
,items
,preSortProperty
); 
 432 OSStatus 
wxMacDataBrowserTableViewControl::RevealItem(DataBrowserItemID item
, DataBrowserPropertyID propertyID
, DataBrowserRevealOptions options
) const 
 434   return ::RevealDataBrowserItem(this->m_controlRef
,item
,propertyID
,options
); 
 435 } /* wxMacDataBrowserTableViewControl::RevealItem(DataBrowserItemID item, DataBrowserPropertyID propertyID, DataBrowserRevealOptions options) const */ 
 437 OSStatus 
wxMacDataBrowserTableViewControl::UpdateItems(DataBrowserItemID container
, UInt32 numItems
, DataBrowserItemID 
const* items
, DataBrowserPropertyID preSortProperty
, 
 438                                                        DataBrowserPropertyID propertyID
) const 
 440   return UpdateDataBrowserItems(this->m_controlRef
,container
,numItems
,items
,preSortProperty
,propertyID
); 
 446 size_t wxMacDataBrowserTableViewControl::GetSelectedItemIDs(wxArrayDataBrowserItemID
& itemIDs
) const 
 448   DataBrowserItemID
* itemIDPtr
; 
 449   Handle 
handle(::NewHandle(0)); 
 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
)); 
 457   itemIDs
.Alloc(NoOfItems
); 
 459   itemIDPtr 
= (DataBrowserItemID
*) (*handle
); 
 460   for (size_t i
=0; i
<NoOfItems
; ++i
) 
 462     itemIDs
.Add(*itemIDPtr
); 
 466   DisposeHandle(handle
); 
 468 } /* wxMacDataBrowserTableViewControl::GetSelectedItemIDs(wxArrayDataBrowserItemID&) const*/ 
 470 OSStatus 
wxMacDataBrowserTableViewControl::GetSelectionAnchor( DataBrowserItemID 
*first
, DataBrowserItemID 
*last 
) const 
 472     return GetDataBrowserSelectionAnchor( m_controlRef
, first
, last 
); 
 475 OSStatus 
wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags
* flags
) const 
 477   return ::GetDataBrowserSelectionFlags(this->m_controlRef
,flags
); 
 478 } /* wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags*) const */ 
 480 bool wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID item
) const 
 482   return ::IsDataBrowserItemSelected(this->m_controlRef
,item
); 
 483 } /* wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID) const */ 
 485 OSStatus 
wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags flags
) 
 487   return ::SetDataBrowserSelectionFlags(this->m_controlRef
,flags
); 
 488 } /* wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags) */ 
 490 OSStatus 
wxMacDataBrowserTableViewControl::SetSelectedItems(UInt32 numItems
, DataBrowserItemID 
const* items
, DataBrowserSetOption operation
) 
 492   return ::SetDataBrowserSelectedItems( m_controlRef
, numItems
, items
, operation 
); 
 493 } /* wxMacDataBrowserTableViewControl::SetSelectedItems(UInt32, DataBrowserItemID const*, DataBrowserSetOption) */ 
 495 OSStatus 
wxMacDataBrowserTableViewControl::GetSortProperty( DataBrowserPropertyID 
*column 
) const 
 497     return GetDataBrowserSortProperty( m_controlRef 
, column 
); 
 500 OSStatus 
wxMacDataBrowserTableViewControl::SetSortProperty( DataBrowserPropertyID column 
) 
 502     return SetDataBrowserSortProperty( m_controlRef 
, column 
); 
 505 OSStatus 
wxMacDataBrowserTableViewControl::GetSortOrder( DataBrowserSortOrder 
*order 
) const 
 507     return GetDataBrowserSortOrder( m_controlRef 
, order 
); 
 510 OSStatus 
wxMacDataBrowserTableViewControl::SetSortOrder( DataBrowserSortOrder order 
) 
 512     return SetDataBrowserSortOrder( m_controlRef 
, order 
); 
 515 IMPLEMENT_ABSTRACT_CLASS(wxMacDataBrowserTableViewControl
,wxMacControl
) 
 517 // ============================================================================ 
 518 // Databrowser class for the list view control 
 519 // ============================================================================ 
 525 OSStatus 
wxMacDataBrowserListViewControl::AddColumn(DataBrowserListViewColumnDesc 
*columnDesc
, DataBrowserTableViewColumnIndex position
) 
 527   return AddDataBrowserListViewColumn(this->m_controlRef
,columnDesc
,position
); 
 528 } /* wxMacDataBrowserListViewControl::AddColumn(DataBrowserListViewColumnDesc*, DataBrowserTableViewColumnIndex) */ 
 530 // ============================================================================ 
 531 // Databrowser class for the data view control 
 532 // ============================================================================ 
 536 // constructors / destructor 
 538 wxMacDataViewDataBrowserListViewControl::wxMacDataViewDataBrowserListViewControl(wxWindow
* peer
, wxPoint 
const& pos
, wxSize 
const& size
, long style
) 
 539                                         :wxMacDataBrowserListViewControl(peer
,pos
,size
,style
) 
 541 } /* wxMacDataViewDataBrowserListViewControl::wxMacDataViewDataBrowserListViewControl(wxWindow* , const wxPoint&, const wxSize&, long) */ 
 544 // item ID and model matching 
 546 void wxMacDataViewDataBrowserListViewControl::ClearItemIDRowPairs(void) 
 548   this->m_itemIDRowNumberMap
.clear(); 
 549 } /* wxMacDataViewDataBrowserListViewControl::ClearItemIDRowPairs(void) */ 
 551 bool wxMacDataViewDataBrowserListViewControl::DeleteItemIDRowPair(DataBrowserItemID itemID
) 
 553   return (this->m_itemIDRowNumberMap
.erase(itemID
) == 1); 
 554 } /* wxMacDataViewDataBrowserListViewControl::DeleteItemIDRowPair(DataBrowseritemID) */ 
 556 bool wxMacDataViewDataBrowserListViewControl::GetRowIndex(unsigned long& rowIndex
, DataBrowserItemID itemID
) const 
 558   ItemIDRowNumberHashMap::const_iterator 
iteratorHashMap(this->m_itemIDRowNumberMap
.find(itemID
)); 
 561   if (iteratorHashMap 
== this->m_itemIDRowNumberMap
.end()) 
 565     rowIndex 
= iteratorHashMap
->second
; 
 568 } /* wxMacDataViewDataBrowserListViewControl::GetRowIndex(unsigned int& rowIndex, DataBrowserItemID itemID) const */ 
 570 bool wxMacDataViewDataBrowserListViewControl::InsertItemIDRowPair(DataBrowserItemID itemID
, unsigned long rowIndex
) 
 572   return this->m_itemIDRowNumberMap
.insert(ItemIDRowNumberHashMap::value_type(itemID
,rowIndex
)).second
; 
 573 } /* wxMacDataViewDataBrowserListViewControl::InsertItemIDRowPair(DataBrowserItemID, unsigned long) */ 
 575 void wxMacDataViewDataBrowserListViewControl::RenumberItemIDRowIndices(unsigned int* newIndices
) 
 577   ItemIDRowNumberHashMap::iterator 
hashMapIterator(this->m_itemIDRowNumberMap
.begin()); 
 580   while (hashMapIterator 
!= this->m_itemIDRowNumberMap
.end()) 
 582     hashMapIterator
->second 
= newIndices
[hashMapIterator
->second
]; 
 585 } /* wxMacDataViewDataBrowserListViewControl::RenumberItemIDRowIndices(unsigned int*) */ 
 587 void wxMacDataViewDataBrowserListViewControl::RenumberItemIDRowIndicesDeletion (unsigned long decreaseFromIndex
) 
 589   ItemIDRowNumberHashMap::iterator 
hashMapIterator(this->m_itemIDRowNumberMap
.begin()); 
 592   while (hashMapIterator 
!= this->m_itemIDRowNumberMap
.end()) 
 594     if (hashMapIterator
->second 
>= decreaseFromIndex
) 
 595       --(hashMapIterator
->second
); 
 598 } /* wxMacDataViewDataBrowserListViewControl::RenumberItemIDRowIndicesDeletion (unsigned int) */ 
 600 void wxMacDataViewDataBrowserListViewControl::RenumberItemIDRowIndicesInsertion(unsigned long increaseFromIndex
) 
 602   ItemIDRowNumberHashMap::iterator 
hashMapIterator(this->m_itemIDRowNumberMap
.begin()); 
 605   while (hashMapIterator 
!= this->m_itemIDRowNumberMap
.end()) 
 607     if (hashMapIterator
->second 
>= increaseFromIndex
) 
 608       ++(hashMapIterator
->second
); 
 611 } /* wxMacDataViewDataBrowserListViewControl::RenumberItemIDRowIndicesInsertion(unsigned int) */ 
 613 void wxMacDataViewDataBrowserListViewControl::ReverseRowIndexNumbering(void) 
 615   if (this->m_itemIDRowNumberMap
.size() > 0) 
 617     size_t const maxIndex 
= this->m_itemIDRowNumberMap
.size()-1; 
 619     ItemIDRowNumberHashMap::iterator 
hashMapIterator(this->m_itemIDRowNumberMap
.begin()); 
 622     while (hashMapIterator 
!= this->m_itemIDRowNumberMap
.end()) 
 624       hashMapIterator
->second 
= maxIndex
-hashMapIterator
->second
; 
 628 } /* wxMacDataViewDataBrowserListViewControl::ReverseRowIndexNumbering(void) */ 
 631 // callback functions (inherited from wxMacDataBrowserTableViewControl) 
 633 Boolean 
wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID itemOneID
, DataBrowserItemID itemTwoID
, DataBrowserPropertyID 
WXUNUSED(sortProperty
)) 
 635   unsigned long rowIndex1
, rowIndex2
; 
 637   bool result 
= (this->GetRowIndex(rowIndex1
,itemOneID
) && this->GetRowIndex(rowIndex2
,itemTwoID
) && (rowIndex1 
< rowIndex2
)); 
 639 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID) */ 
 641 void wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID itemID
, DataBrowserPropertyID property
, DataBrowserItemState state
, Rect 
const* rectangle
, SInt16 bitDepth
, Boolean colorDevice
) 
 643   OSStatus errorStatus
; 
 645   unsigned long column
; 
 648   wxDataViewColumn
* dataViewColumnPtr
; 
 650   wxDataViewCtrl
* dataViewCtrlPtr
; 
 652   wxDataViewCustomRenderer
* dataViewCustomRendererPtr
; 
 654   wxVariant dataToRender
; 
 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
) 
 663     wxCHECK_RET(this->GetRowIndex(row
,itemID
),_("Row index does not exist.")); 
 667     wxCHECK_RET(this->GetItemRow(itemID
,&row
) == noErr
,_("Row index does not exist.")); 
 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
); 
 676  // try to determine the content's size (drawable part): 
 678   RgnHandle 
rgn(NewRgn()); 
 681   if (this->GetRegion(kControlContentMetaPart
,rgn
) == noErr
) 
 682     GetRegionBounds(rgn
,&content
); 
 684     this->GetRect(&content
); 
 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) 
 694  // extra space for the scrollbars:  
 695   content
.bottom 
-= wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y
); 
 696   content
.right  
-= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X
); 
 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) */ 
 706 OSStatus 
wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc(DataBrowserItemID itemID
, DataBrowserPropertyID property
, DataBrowserItemDataRef itemData
, Boolean getValue
) 
 710    // variable definition: 
 711     unsigned long     column
; 
 713     wxDataViewCtrl
*   dataViewCtrlPtr
; 
 714     wxDataViewColumn
* dataViewColumnPtr
; 
 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
) 
 721       wxCHECK_MSG(this->GetRowIndex(row
,itemID
),errDataBrowserNotConfigured
,_("Row index does not exist.")); 
 725       wxCHECK_MSG(this->GetItemRow(itemID
,&row
) == noErr
,errDataBrowserNotConfigured
,_("Row index does not exist.")); 
 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()) 
 731       case kDataBrowserCheckboxType
: 
 733          // variable definitions: 
 734           ThemeButtonValue buttonValue
; 
 735           OSStatus         errorStatus
; 
 737           errorStatus 
= ::GetDataBrowserItemDataButtonValue(itemData
,&buttonValue
); 
 738           if (errorStatus 
== noErr
) 
 740             if (buttonValue 
== kThemeButtonOn
) 
 742              // variable definition and initialization: 
 743               wxVariant 
modifiedData(true); 
 745               return (dataViewCtrlPtr
->GetModel()->SetValue(modifiedData
,static_cast<unsigned int>(column
),static_cast<unsigned int>(row
)) ? noErr 
: errDataBrowserNotConfigured
); 
 747             else if (buttonValue 
== kThemeButtonOff
) 
 749              // variable definition and initialization: 
 750               wxVariant 
modifiedData(false); 
 752               return (dataViewCtrlPtr
->GetModel()->SetValue(modifiedData
,static_cast<unsigned int>(column
),static_cast<unsigned int>(row
)) ? noErr 
: errDataBrowserNotConfigured
); 
 755               return errDataBrowserInvalidPropertyData
; 
 760       case kDataBrowserTextType
: 
 762          // variable definitions: 
 763           CFStringRef stringReference
; 
 764           OSStatus    errorStatus
; 
 766           errorStatus 
= ::GetDataBrowserItemDataText(itemData
,&stringReference
); 
 767           if (errorStatus 
== noErr
) 
 769            // variable definitions and initializations: 
 770             wxMacCFStringHolder 
modifiedString(stringReference
); 
 771             wxVariant           
modifiedData(modifiedString
.AsString()); 
 773             if (dataViewCtrlPtr
->GetModel()->SetValue(modifiedData
,static_cast<unsigned int>(column
),static_cast<unsigned int>(row
))) 
 776               return errDataBrowserNotConfigured
; 
 782         return errDataBrowserPropertyNotSupported
; 
 787     if (property 
>= kMinPropertyID
) // in case of data columns set the data 
 789      // variable definitions: 
 790       OSStatus          errorStatus
; 
 791       unsigned long     columnPosition
; 
 792       unsigned long     rowPosition
; 
 794       wxDataViewColumn
* dataViewColumnPtr
; 
 795       wxDataViewCtrl
*   dataViewCtrlPtr
; 
 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
) 
 803         wxCHECK_MSG(this->GetRowIndex(rowPosition
,itemID
),errDataBrowserNotConfigured
,_("Row index does not exist.")); 
 807         wxCHECK_MSG(this->GetItemRow(itemID
,&rowPosition
) == noErr
,errDataBrowserNotConfigured
,_("Row index does not exist.")); 
 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.")); 
 815     else // react on special system requests 
 818         case kDataBrowserItemIsContainerProperty
: 
 819           return ::SetDataBrowserItemDataBooleanValue(itemData
,false); 
 820         case kDataBrowserItemIsEditableProperty
: 
 821           return ::SetDataBrowserItemDataBooleanValue(itemData
,true); 
 824   return errDataBrowserPropertyNotSupported
; 
 825 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc(DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemDataRef, Boolean) */ 
 827 void wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID itemID
, DataBrowserItemNotification message
, DataBrowserItemDataRef 
WXUNUSED(itemData
)) 
 831     case kDataBrowserItemDoubleClicked
: 
 833        // variable definitions: 
 835         wxDataViewCtrl
* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl
*>(this->GetPeer())); 
 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 
 842         dataViewEvent
.SetEventObject(dataViewCtrlPtr
); 
 843         dataViewEvent
.SetRow(row
); 
 844        // finally sent the equivalent wxWidget event: 
 845         dataViewCtrlPtr
->GetEventHandler()->ProcessEvent(dataViewEvent
); 
 848     case kDataBrowserItemSelected
: 
 850        // variable definitions: 
 852         wxDataViewCtrl
* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl
*>(this->GetPeer())); 
 854         wxCHECK_RET(dataViewCtrlPtr 
!= NULL
,      _("Pointer to data view control not set correctly.")); 
 855         if (dynamic_cast<wxDataViewSortedListModel
*>(dataViewCtrlPtr
->GetModel()) == NULL
) 
 857           wxCHECK_RET(this->GetRowIndex(row
,itemID
),_("Row index does not exist.")); 
 861           wxCHECK_RET(this->GetItemRow(itemID
,&row
) == noErr
,_("Row index does not exist.")); 
 863        // initialize wxWidget event: 
 864         wxDataViewEvent 
dataViewEvent(wxEVT_COMMAND_DATAVIEW_ROW_SELECTED
,dataViewCtrlPtr
->GetId()); // variable defintion 
 866         dataViewEvent
.SetEventObject(dataViewCtrlPtr
); 
 867         dataViewEvent
.SetRow(row
); 
 868        // finally sent the equivalent wxWidget event: 
 869         dataViewCtrlPtr
->GetEventHandler()->ProcessEvent(dataViewEvent
); 
 872     case kDataBrowserUserStateChanged
: 
 874         DataBrowserPropertyID propertyId
; 
 876         if ((this->GetSortProperty(&propertyId
) == noErr
) && (propertyId 
>= kMinPropertyID
)) 
 878           DataBrowserSortOrder sortOrder
; 
 879           unsigned long        column
; 
 881           if ((this->GetSortOrder(&sortOrder
) == noErr
) && (this->GetPropertyColumn(propertyId
,&column
) == noErr
)) 
 883             wxDataViewCtrl
* dataViewCtrlPtr(dynamic_cast<wxDataViewCtrl
*>(this->GetPeer())); 
 885             if (  dataViewCtrlPtr
->GetColumn(column
)->IsSortOrderAscending()  && (sortOrder 
== kDataBrowserOrderDecreasing
) || 
 886                 !(dataViewCtrlPtr
->GetColumn(column
)->IsSortOrderAscending()) && (sortOrder 
== kDataBrowserOrderIncreasing
)) 
 888              // initialize wxWidget event: 
 889               wxDataViewEvent 
dataViewEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED
,dataViewCtrlPtr
->GetId()); // variable defintion 
 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
); 
 902 } /* wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID, DataBrowserItemNotification, DataBrowserItemDataRef) */ 
 906  // wxUSE_GENERICDATAVIEWCTRL