+OSStatus wxMacDataBrowserListCtrlControl::GetSetItemData(DataBrowserItemID itemID,
+ DataBrowserPropertyID property,
+ DataBrowserItemDataRef itemData,
+ Boolean changeValue )
+{
+ wxString text;
+ int imgIndex = -1;
+ short listColumn = property - kMinColumnId;
+
+ OSStatus err = errDataBrowserPropertyNotSupported;
+ wxListCtrl* list = wxDynamicCast( GetPeer() , wxListCtrl );
+ wxMacListCtrlItem* lcItem;
+
+ if (listColumn >= 0)
+ {
+ if (!m_isVirtual)
+ {
+ lcItem = (wxMacListCtrlItem*) itemID;
+ if (lcItem && lcItem->HasColumnInfo(listColumn)){
+ wxListItem* item = lcItem->GetColumnInfo(listColumn);
+ if (item->GetMask() & wxLIST_MASK_TEXT)
+ text = item->GetText();
+ if (item->GetMask() & wxLIST_MASK_IMAGE)
+ imgIndex = item->GetImage();
+ }
+ }
+ else
+ {
+ long itemNum = (long)itemID-1;
+ if (itemNum >= 0 && itemNum < list->GetItemCount())
+ {
+ text = list->OnGetItemText( itemNum, listColumn );
+ imgIndex = list->OnGetItemColumnImage( itemNum, listColumn );
+ }
+ }
+ }
+
+ if ( !changeValue )
+ {
+ switch (property)
+ {
+ case kDataBrowserItemIsEditableProperty :
+ if ( list && list->HasFlag( wxLC_EDIT_LABELS ) )
+ {
+ verify_noerr(SetDataBrowserItemDataBooleanValue( itemData, true ));
+ }
+ break ;
+ default :
+ if ( property >= kMinColumnId )
+ {
+ wxMacCFStringHolder cfStr(text);
+ verify_noerr( ::SetDataBrowserItemDataText( itemData, cfStr) );
+
+
+
+ if ( imgIndex != -1 )
+ {
+ wxImageList* imageList = list->GetImageList(wxIMAGE_LIST_SMALL);
+ if (imageList && imageList->GetImageCount() > 0){
+ wxBitmap bmp = imageList->GetBitmap(imgIndex);
+ IconRef icon = bmp.GetBitmapData()->GetIconRef();
+ ::SetDataBrowserItemDataIcon(itemData, icon);
+ }
+ }
+
+ }
+ break ;
+ }
+
+ }
+ else
+ {
+ switch (property)
+ {
+ default:
+ if ( property >= kMinColumnId )
+ {
+ short listColumn = property - kMinColumnId;
+
+ // TODO probably send the 'end edit' from here, as we
+ // can then deal with the veto
+ CFStringRef sr ;
+ verify_noerr( GetDataBrowserItemDataText( itemData , &sr ) ) ;
+ wxMacCFStringHolder cfStr(sr) ;;
+ if (m_isVirtual)
+ list->SetItem( (long)itemData-1 , listColumn, cfStr.AsString() ) ;
+ else
+ {
+ if (lcItem)
+ lcItem->SetColumnTextValue( listColumn, cfStr.AsString() );
+ }
+ err = noErr ;
+ }
+ break;
+ }
+ }
+ return err;
+}
+
+void wxMacDataBrowserListCtrlControl::ItemNotification(DataBrowserItemID itemID,
+ DataBrowserItemNotification message,
+ DataBrowserItemDataRef itemData )
+{
+ // we want to depend on as little as possible to make sure tear-down of controls is safe
+ if ( message == kDataBrowserItemRemoved)
+ {
+ // make sure MacDelete does the proper teardown.
+ return;
+ }
+ else if ( message == kDataBrowserItemAdded )
+ {
+ // we don't issue events on adding, the item is not really stored in the list yet, so we
+ // avoid asserts by getting out now
+ return ;
+ }
+
+ wxListCtrl *list = wxDynamicCast( GetPeer() , wxListCtrl );
+ if ( list )
+ {
+ bool trigger = false;
+
+ wxListEvent event( wxEVT_COMMAND_LIST_ITEM_SELECTED, list->GetId() );
+ bool isSingle = (list->GetWindowStyle() & wxLC_SINGLE_SEL) != 0;
+
+ event.SetEventObject( list );
+ if ( !list->IsVirtual() )
+ {
+ DataBrowserTableViewRowIndex result = 0;
+ verify_noerr( GetItemRow( itemID, &result ) ) ;
+ event.m_itemIndex = result;
+ }
+ else
+ {
+ event.m_itemIndex = (long)itemID-1;
+ }
+ event.m_item.m_itemId = event.m_itemIndex;
+ list->GetItem(event.m_item);
+
+ switch (message)
+ {
+ case kDataBrowserItemDeselected:
+ event.SetEventType(wxEVT_COMMAND_LIST_ITEM_DESELECTED);
+ if ( !isSingle )
+ trigger = !IsSelectionSuppressed();
+ break;
+
+ case kDataBrowserItemSelected:
+ trigger = !IsSelectionSuppressed();
+
+ break;
+
+ case kDataBrowserItemDoubleClicked:
+ event.SetEventType( wxEVT_COMMAND_LIST_ITEM_ACTIVATED );
+ trigger = true;
+ break;
+
+ case kDataBrowserEditStarted :
+ // TODO : how to veto ?
+ event.SetEventType( wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT ) ;
+ trigger = true ;
+ break ;
+
+ case kDataBrowserEditStopped :
+ // TODO probably trigger only upon the value store callback, because
+ // here IIRC we cannot veto
+ event.SetEventType( wxEVT_COMMAND_LIST_END_LABEL_EDIT ) ;
+ trigger = true ;
+ break ;
+
+ default:
+ break;
+ }
+
+ if ( trigger )
+ {
+ // direct notification is not always having the listbox GetSelection() having in synch with event
+ wxPostEvent( list->GetEventHandler(), event );
+ }
+ }
+}
+
+Boolean wxMacDataBrowserListCtrlControl::CompareItems(DataBrowserItemID itemOneID,
+ DataBrowserItemID itemTwoID,
+ DataBrowserPropertyID sortProperty)
+{
+
+ bool retval = false;
+ wxString itemText;
+ wxString otherItemText;
+ long itemOrder;
+ long otherItemOrder;
+
+ int colId = sortProperty - kMinColumnId;
+
+ wxListCtrl* list = wxDynamicCast( GetPeer() , wxListCtrl );
+
+ DataBrowserSortOrder sort;
+ verify_noerr(GetSortOrder(&sort));
+
+ if (colId >= 0)
+ {
+ if (!m_isVirtual)
+ {
+ wxMacListCtrlItem* item = (wxMacListCtrlItem*)itemOneID;
+ wxMacListCtrlItem* otherItem = (wxMacListCtrlItem*)itemTwoID;
+
+ itemOrder = item->GetOrder();
+ otherItemOrder = item->GetOrder();
+
+ wxListCtrlCompare func = list->GetCompareFunc();
+ if (func != NULL)
+ {
+ long item1 = -1;
+ long item2 = -1;
+ if (item && item->HasColumnInfo(0))
+ item1 = item->GetColumnInfo(0)->GetData();
+ if (otherItem && otherItem->HasColumnInfo(0))
+ item2 = otherItem->GetColumnInfo(0)->GetData();
+
+ if (item1 > -1 && item2 > -1)
+ {
+ int result = func(item1, item2, list->GetCompareFuncData());
+ if (sort == kDataBrowserOrderIncreasing)
+ return result >= 0;
+ else
+ return result < 0;
+ }
+ }
+
+ // we can't use the native control's sorting abilities, so just
+ // sort by item id.
+ return itemOrder < otherItemOrder;
+ }
+ else
+ {
+
+ long itemNum = (long)itemOneID;
+ long otherItemNum = (long)itemTwoID;
+
+ // virtual listctrls don't support sorting
+ return itemNum < otherItemNum;
+ }
+ }
+ else{
+ // fallback for undefined cases
+ retval = itemOneID < itemTwoID;
+ }
+
+ return retval;
+}
+
+wxMacDataBrowserListCtrlControl::~wxMacDataBrowserListCtrlControl()
+{
+}
+
+void wxMacDataBrowserListCtrlControl::MacSetColumnInfo( unsigned int row, unsigned int column, wxListItem* item )
+{
+ wxMacDataItem* dataItem = GetItemFromLine(row);
+ wxASSERT_MSG( dataItem, _T("could not obtain wxMacDataItem for row in MacSetColumnInfo. Is row a valid wxListCtrl row?") );
+ if (item)
+ {
+ wxMacListCtrlItem* listItem = wx_static_cast(wxMacListCtrlItem*,dataItem);
+ bool hasInfo = listItem->HasColumnInfo( column );
+ listItem->SetColumnInfo( column, item );
+ listItem->SetOrder(row);
+ UpdateState(dataItem, item);
+
+ wxListCtrl* list = wxDynamicCast( GetPeer() , wxListCtrl );
+
+ // NB: When this call was made before a control was completely shown, it would
+ // update the item prematurely (i.e. no text would be listed) and, on show,
+ // only the sorted column would be refreshed, meaning only first column text labels
+ // would be shown. Making sure not to update items until the control is visible
+ // seems to fix this issue.
+ if (hasInfo && list->IsShown())
+ UpdateItem( wxMacDataBrowserRootContainer, listItem , kMinColumnId + column );
+ }
+}
+
+// apply changes that need to happen immediately, rather than when the
+// databrowser control fires a callback.
+void wxMacDataBrowserListCtrlControl::UpdateState(wxMacDataItem* dataItem, wxListItem* listItem)
+{
+ bool isSelected = IsItemSelected( dataItem );
+ bool isSelectedState = (listItem->GetState() == wxLIST_STATE_SELECTED);
+
+ // toggle the selection state if wxListInfo state and actual state don't match.
+ if ( isSelected != isSelectedState )
+ {
+ DataBrowserSetOption options = kDataBrowserItemsAdd;
+ if (!isSelectedState)
+ options = kDataBrowserItemsRemove;
+ SetSelectedItem(dataItem, options);
+ }
+ // TODO: Set column width if item width > than current column width
+}
+
+void wxMacDataBrowserListCtrlControl::MacGetColumnInfo( unsigned int row, unsigned int column, wxListItem& item )
+{
+ wxMacDataItem* dataItem = GetItemFromLine(row);
+ wxASSERT_MSG( dataItem, _T("could not obtain wxMacDataItem in MacGetColumnInfo. Is row a valid wxListCtrl row?") );
+ // CS should this guard against dataItem = 0 ? , as item is not a pointer if (item) is not appropriate
+ //if (item)
+ {
+ wxMacListCtrlItem* listItem =wx_static_cast(wxMacListCtrlItem*,dataItem);
+
+ if (!listItem->HasColumnInfo( column ))
+ return;
+
+ wxListItem* oldItem = listItem->GetColumnInfo( column );
+
+ if (oldItem)
+ {
+ long mask = item.GetMask();
+ if ( !mask )
+ // by default, get everything for backwards compatibility
+ mask = -1;
+
+ if ( mask & wxLIST_MASK_TEXT )
+ item.SetText(oldItem->GetText());
+ if ( mask & wxLIST_MASK_IMAGE )
+ item.SetImage(oldItem->GetImage());
+ if ( mask & wxLIST_MASK_DATA )
+ item.SetData(oldItem->GetData());
+ if ( mask & wxLIST_MASK_STATE )
+ item.SetState(oldItem->GetState());
+ if ( mask & wxLIST_MASK_WIDTH )
+ item.SetWidth(oldItem->GetWidth());
+ if ( mask & wxLIST_MASK_FORMAT )
+ item.SetAlign(oldItem->GetAlign());
+
+ item.SetTextColour(oldItem->GetTextColour());
+ item.SetBackgroundColour(oldItem->GetBackgroundColour());
+ item.SetFont(oldItem->GetFont());
+ }
+ }
+}
+
+void wxMacDataBrowserListCtrlControl::MacInsertItem( unsigned int n, wxListItem* item )
+{
+ wxMacDataItemBrowserControl::MacInsert(n, item->GetText());
+ MacSetColumnInfo(n, 0, item);
+}
+
+wxMacDataItem* wxMacDataBrowserListCtrlControl::CreateItem()