X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f1c40652a0c2d6752c57df1b8aed22fae7e118dd..1d3dfc57e77c64a4691fae47b566bcfb99eceb48:/src/osx/carbon/dataview.cpp diff --git a/src/osx/carbon/dataview.cpp b/src/osx/carbon/dataview.cpp index f4a2c7fdd4..a08481951f 100644 --- a/src/osx/carbon/dataview.cpp +++ b/src/osx/carbon/dataview.cpp @@ -1,50 +1,78 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: src/osx/carbon/datavgen.cpp -// Purpose: wxDataViewCtrl native mac implementation +// Name: src/osx/carbon/dataview.cpp +// Purpose: wxDataViewCtrl native carbon implementation // Author: -// Id: $Id$ -// Copyright: (c) 2007 +// Id: $Id: dataview.cpp 58317 2009-01-23 +// Copyright: (c) 2009 // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" -#if wxUSE_DATAVIEWCTRL +#if (wxUSE_DATAVIEWCTRL == 1) && !defined(wxUSE_GENERICDATAVIEWCTRL) -#include "wx/dataview.h" +#ifndef WX_PRECOMP + #include "wx/app.h" + #include "wx/toplevel.h" + #include "wx/font.h" + #include "wx/settings.h" + #include "wx/utils.h" +#endif -#if !defined(wxUSE_GENERICDATAVIEWCTRL) || (wxUSE_GENERICDATAVIEWCTRL == 0) +#include "wx/osx/carbon/dataview.h" +#include "wx/osx/private.h" +#include "wx/osx/uma.h" +#include "wx/renderer.h" #include -#include "wx/osx/carbon/databrow.h" +// ============================================================================ +// Variables used locally in dataview.cpp +// ============================================================================ +static DataBrowserGetContextualMenuUPP gDataBrowserTableViewGetContextualMenuUPP = NULL; +static DataBrowserItemCompareUPP gDataBrowserTableViewItemCompareUPP = NULL; +static DataBrowserItemDataUPP gDataBrowserTableViewItemDataUPP = NULL; +static DataBrowserItemNotificationUPP gDataBrowserTableViewItemNotificationUPP = NULL; + +static DataBrowserAcceptDragUPP gDataBrowserTableViewAcceptDragUPP = NULL; +static DataBrowserAddDragItemUPP gDataBrowserTableViewAddDragItemUPP = NULL; +static DataBrowserReceiveDragUPP gDataBrowserTableViewReceiveDragUPP = NULL; + +static DataBrowserDrawItemUPP gDataBrowserTableViewDrawItemUPP = NULL; +static DataBrowserEditItemUPP gDataBrowserTableViewEditItemUPP = NULL; +static DataBrowserHitTestUPP gDataBrowserTableViewHitTestUPP = NULL; +static DataBrowserTrackingUPP gDataBrowserTableViewTrackingUPP = NULL; + +// ============================================================================ +// Functions used locally in dataview.cpp +// ============================================================================ +static DataBrowserItemID* CreateDataBrowserItemIDArray(size_t& noOfEntries, wxDataViewItemArray const& items) // returns a newly allocated pointer to valid data browser item IDs +{ + size_t const noOfItems = items.GetCount(); -#ifndef WX_PRECOMP - #include "wx/timer.h" - #include "wx/settings.h" - #include "wx/dcclient.h" - #include "wx/icon.h" -#endif + DataBrowserItemID* itemIDs(new DataBrowserItemID[noOfItems]); -#include "wx/renderer.h" -//----------------------------------------------------------------------------- -// local constants -//----------------------------------------------------------------------------- + // convert all valid data view items to data browser items + noOfEntries = 0; + for (size_t i=0; i(items[i].GetID()); + ++noOfEntries; + } + // done: + return itemIDs; +} -// a list of all catchable events: -static EventTypeSpec const eventList[] = +static const EventTypeSpec eventList[] = { - {kEventClassControl, kEventControlDraw}, - {kEventClassControl, kEventControlHit} + { kEventClassControl, kEventControlHit }, + { kEventClassControl, kEventControlDraw } }; -//----------------------------------------------------------------------------- -// local functions -//----------------------------------------------------------------------------- - -static pascal OSStatus wxMacDataViewCtrlEventHandler(EventHandlerCallRef handler, EventRef EventReference, void* Data) +static pascal OSStatus DataBrowserCtrlEventHandler(EventHandlerCallRef handler, EventRef EventReference, void* Data) { wxDataViewCtrl* DataViewCtrlPtr((wxDataViewCtrl*) Data); // the 'Data' variable always contains a pointer to the data view control that installed the handler @@ -67,7 +95,9 @@ static pascal OSStatus wxMacDataViewCtrlEventHandler(EventHandlerCallRef handler { ControlRef controlReference; DataBrowserPropertyID columnPropertyID; + DataBrowserSortOrder order; unsigned long columnIndex; + wxDataViewColumn* column; OSStatus status; wxDataViewEvent DataViewEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK,DataViewCtrlPtr->GetId()); @@ -79,10 +109,15 @@ static pascal OSStatus wxMacDataViewCtrlEventHandler(EventHandlerCallRef handler if (status == errDataBrowserPropertyNotFound) // user clicked into part of the header that does not have a property return ::CallNextEventHandler(handler,EventReference); wxCHECK(status == noErr,status); + column = DataViewCtrlPtr->GetColumn(columnIndex); + // set the column sort order: + status = ::GetDataBrowserSortOrder(controlReference,&order); + wxCHECK(status == noErr,status); + column->SetSortOrderVariable(order == kDataBrowserOrderIncreasing); // initialize wxWidget event handler: DataViewEvent.SetEventObject(DataViewCtrlPtr); DataViewEvent.SetColumn(columnIndex); - DataViewEvent.SetDataViewColumn(DataViewCtrlPtr->GetColumn(columnIndex)); + DataViewEvent.SetDataViewColumn(column); // finally sent the equivalent wxWidget event: DataViewCtrlPtr->HandleWindowEvent(DataViewEvent); return ::CallNextEventHandler(handler,EventReference); @@ -90,34 +125,14 @@ static pascal OSStatus wxMacDataViewCtrlEventHandler(EventHandlerCallRef handler else return eventNotHandledErr; } - return eventNotHandledErr; } -static DataBrowserItemID* CreateDataBrowserItemIDArray(size_t& noOfEntries, wxDataViewItemArray const& items) // returns a newly allocated pointer to valid data browser item IDs -{ - size_t const noOfItems = items.GetCount(); - - DataBrowserItemID* itemIDs(new DataBrowserItemID[noOfItems]); - - - // convert all valid data view items to data browser items - noOfEntries = 0; - for (size_t i=0; i(items[i].GetID()); - ++noOfEntries; - } - // done: - return itemIDs; -} - -static bool InitializeColumnDescription(DataBrowserListViewColumnDesc& columnDescription, wxDataViewColumn const* columnPtr, DataBrowserPropertyID columnPropertyID, wxCFStringRef const& title) +static bool InitializeColumnDescription(DataBrowserListViewColumnDesc& columnDescription, wxDataViewColumn const* columnPtr, wxCFStringRef const& title) { // set properties for the column: - columnDescription.propertyDesc.propertyID = columnPropertyID; - columnDescription.propertyDesc.propertyType = columnPtr->GetRenderer()->GetPropertyType(); + columnDescription.propertyDesc.propertyID = columnPtr->GetNativeData()->GetPropertyID(); + columnDescription.propertyDesc.propertyType = columnPtr->GetRenderer()->GetNativeData()->GetPropertyType(); columnDescription.propertyDesc.propertyFlags = kDataBrowserListViewSelectionColumn; // make the column selectable if (columnPtr->IsReorderable()) columnDescription.propertyDesc.propertyFlags |= kDataBrowserListViewMovableColumn; @@ -133,7 +148,7 @@ static bool InitializeColumnDescription(DataBrowserListViewColumnDesc& columnDes } if (columnPtr->IsSortable()) columnDescription.propertyDesc.propertyFlags |= kDataBrowserListViewSortableColumn; - if ((columnPtr->GetRenderer()->GetMode() == wxDATAVIEW_CELL_EDITABLE) || + if ((columnPtr->GetRenderer()->GetMode() == wxDATAVIEW_CELL_EDITABLE) || (columnPtr->GetRenderer()->GetMode() == wxDATAVIEW_CELL_ACTIVATABLE)) columnDescription.propertyDesc.propertyFlags |= kDataBrowserPropertyIsEditable; if ((columnDescription.propertyDesc.propertyType == kDataBrowserCustomType) || @@ -145,9 +160,9 @@ static bool InitializeColumnDescription(DataBrowserListViewColumnDesc& columnDes columnDescription.propertyDesc.propertyFlags |= kDataBrowserListViewNoGapForIconInHeaderButton; #endif // set header's properties: - columnDescription.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc; - columnDescription.headerBtnDesc.titleOffset = 0; - columnDescription.headerBtnDesc.titleString = ::CFStringCreateCopy(kCFAllocatorDefault,title); + columnDescription.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc; + columnDescription.headerBtnDesc.titleOffset = 0; + columnDescription.headerBtnDesc.titleString = ::CFStringCreateCopy(kCFAllocatorDefault,title); columnDescription.headerBtnDesc.initialOrder = kDataBrowserOrderIncreasing; // choose one of the orders as "undefined" is not supported anyway (s. ControlDefs.h in the HIToolbox framework) columnDescription.headerBtnDesc.btnFontStyle.flags = kControlUseFontMask | kControlUseJustMask; switch (columnPtr->GetAlignment()) @@ -184,1382 +199,2485 @@ static bool InitializeColumnDescription(DataBrowserListViewColumnDesc& columnDes return true; } -//----------------------------------------------------------------------------- -// local function pointers -//----------------------------------------------------------------------------- - -DEFINE_ONE_SHOT_HANDLER_GETTER(wxMacDataViewCtrlEventHandler) +// ============================================================================ +// Type definitions of locally used function pointers +// ============================================================================ +DEFINE_ONE_SHOT_HANDLER_GETTER(DataBrowserCtrlEventHandler) -// --------------------------------------------------------- -// wxMacDataViewModelNotifier -// --------------------------------------------------------- -class wxMacDataViewModelNotifier : public wxDataViewModelNotifier +// ============================================================================ +// Helper functions for dataview implementation on OSX +// ============================================================================ +wxWidgetImplType* CreateDataView(wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(parent), wxWindowID WXUNUSED(id), wxPoint const& pos, wxSize const& size, + long style, long WXUNUSED(extraStyle)) { -public: - wxMacDataViewModelNotifier(wxMacDataViewDataBrowserListViewControl* initDataViewControlPtr) : m_dataViewControlPtr(initDataViewControlPtr) - { - } - - virtual bool ItemAdded(const wxDataViewItem &parent, const wxDataViewItem &item) - { - DataBrowserItemID itemID(reinterpret_cast(item.GetID())); + return new wxMacDataViewDataBrowserListViewControl(wxpeer,pos,size,style); +} - wxCHECK_MSG(item.IsOk(),false,_("Added item is invalid.")); - bool noFailureFlag = (!(parent.IsOk()) && (m_dataViewControlPtr->AddItem(kDataBrowserNoItem,&itemID) == noErr) || - parent.IsOk() && (m_dataViewControlPtr->AddItem(reinterpret_cast(parent.GetID()),&itemID) == noErr)); +// ============================================================================ +// wxMacDataBrowserTableViewControl +// ============================================================================ +pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserCompareProc(ControlRef browser, DataBrowserItemID itemOneID, DataBrowserItemID itemTwoID, DataBrowserPropertyID sortProperty) +{ + wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast(wxMacControl::GetReferenceFromNativeControl(browser))); - wxDataViewCtrl *dvc = (wxDataViewCtrl*) m_dataViewControlPtr->GetWXPeer(); - if (dvc->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT) - { - wxDataViewModel *model = GetOwner(); - int height = 20; // TODO find out standard height - unsigned int num = dvc->GetColumnCount(); - unsigned int col; - for (col = 0; col < num; col++) - { - wxDataViewColumn *column = dvc->GetColumn( col ); - if (column->IsHidden()) - continue; + if (ControlPtr != NULL) + return ControlPtr->DataBrowserCompareProc(itemOneID,itemTwoID,sortProperty); + else + return FALSE; +} /* wxMacDataBrowserTableViewControl::DataBrowserCompareProc(ControlRef, DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID) */ - wxDataViewCustomRenderer *renderer = wxDynamicCast( column->GetRenderer(), wxDataViewCustomRenderer ); - if (renderer) - { - wxVariant value; - model->GetValue( value, item, column->GetModelColumn() ); - renderer->SetValue( value ); - height = wxMax( height, renderer->GetSize().y ); - } +pascal void wxMacDataBrowserTableViewControl::DataBrowserGetContextualMenuProc(ControlRef browser, MenuRef* menu, UInt32* helpType, CFStringRef* helpItemString, AEDesc* selection) +{ + wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast(wxMacControl::GetReferenceFromNativeControl(browser))); - } - if (height > 20) - m_dataViewControlPtr->SetRowHeight( itemID, height ); - } + if (ControlPtr != NULL) + ControlPtr->DataBrowserGetContextualMenuProc(menu,helpType,helpItemString,selection); +} /* wxMacDataBrowserTableViewControl::DataBrowserGetContextualMenuProc(ControlRef, MenuRef*, UInt32*, CFStringRef*, AEDesc*) */ - return noFailureFlag; - } +pascal OSStatus wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemDataRef itemData, Boolean getValue) +{ + wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast(wxMacControl::GetReferenceFromNativeControl(browser))); - virtual bool ItemsAdded(wxDataViewItem const& parent, wxDataViewItemArray const& items) - { - bool noFailureFlag; - DataBrowserItemID* itemIDs; + if (ControlPtr != NULL) + return ControlPtr->DataBrowserGetSetItemDataProc(itemID,propertyID,itemData,getValue); + else + return errDataBrowserPropertyNotSupported; +} /* wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemDataRef, Boolean) */ - size_t noOfEntries; +pascal void wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserItemNotification message, DataBrowserItemDataRef itemData) +{ + wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast(wxMacControl::GetReferenceFromNativeControl(browser))); - // convert all valid data view items to data browser items: - itemIDs = ::CreateDataBrowserItemIDArray(noOfEntries,items); - // insert all valid items into control: - noFailureFlag = ((noOfEntries == 0) || - !(parent.IsOk()) && (m_dataViewControlPtr->AddItems(kDataBrowserNoItem,noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr) || - parent.IsOk() && (m_dataViewControlPtr->AddItems(reinterpret_cast(parent.GetID()),noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr)); - // give allocated array space free again: - delete[] itemIDs; + if (ControlPtr != NULL) + ControlPtr->DataBrowserItemNotificationProc(itemID,message,itemData); +} /* wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc(ControlRef, DataBrowserItemID, DataBrowserItemNotification, DataBrowserItemDataRef) */ - wxDataViewCtrl *dvc = (wxDataViewCtrl*) m_dataViewControlPtr->GetWXPeer(); - if (dvc->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT) - { - wxDataViewModel *model = GetOwner(); - unsigned int colnum = dvc->GetColumnCount(); +pascal void wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemState state, Rect const* rectangle, SInt16 bitDepth, Boolean colorDevice) +{ + wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast(wxMacControl::GetReferenceFromNativeControl(browser))); - size_t i; - size_t count = items.GetCount(); - for (i = 0; i < count; i++) - { - wxDataViewItem item = items[i]; - DataBrowserItemID itemID(reinterpret_cast(item.GetID())); - int height = 20; // TODO find out standard height - unsigned int col; - for (col = 0; col < colnum; col++) - { - wxDataViewColumn *column = dvc->GetColumn( col ); - if (column->IsHidden()) - continue; // skip it! + if (ControlPtr != NULL) + ControlPtr->DataBrowserDrawItemProc(itemID,propertyID,state,rectangle,bitDepth,colorDevice); +} /* wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemState, Rect const*, SInt16, Boolean) */ - if ((col != 0) && model->IsContainer(item) && !model->HasContainerColumns(item)) - continue; // skip it! +pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserEditItemProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, CFStringRef theString, Rect* maxEditTextRect, Boolean* shrinkToFit) +{ + wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast(wxMacControl::GetReferenceFromNativeControl(browser))); - wxDataViewCustomRenderer *renderer = wxDynamicCast( column->GetRenderer(), wxDataViewCustomRenderer ); - if (renderer) - { - wxVariant value; - model->GetValue( value, item, column->GetModelColumn() ); - renderer->SetValue( value ); - height = wxMax( height, renderer->GetSize().y ); - } - } - if (height > 20) - m_dataViewControlPtr->SetRowHeight( itemID, height ); - } - } + return ((ControlPtr != NULL) && ControlPtr->DataBrowserEditItemProc(itemID,propertyID,theString,maxEditTextRect,shrinkToFit)); +} /* wxMacDataBrowserTableViewControl::DataBrowserEditItemProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, CFStringRef, Rect*, Boolean*) */ - // done: - return noFailureFlag; - } +pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserHitTestProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, Rect const* theRect, Rect const* mouseRect) +{ + wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast(wxMacControl::GetReferenceFromNativeControl(browser))); - virtual bool ItemChanged(wxDataViewItem const& item) - { - DataBrowserItemID itemID(reinterpret_cast(item.GetID())); + return ((ControlPtr != NULL) && ControlPtr->DataBrowserHitTestProc(itemID,propertyID,theRect,mouseRect)); +} /* wxMacDataBrowserTableViewControl::DataBrowserHitTestProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, Rect const*, Rect const*) */ - wxCHECK_MSG(item.IsOk(),false,_("Changed item is invalid.")); - if (m_dataViewControlPtr->UpdateItems(&itemID) == noErr) - { - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(m_dataViewControlPtr->GetWXPeer())); +pascal DataBrowserTrackingResult wxMacDataBrowserTableViewControl::DataBrowserTrackingProc(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID propertyID, Rect const* theRect, Point startPt, EventModifiers modifiers) +{ + wxMacDataBrowserTableViewControl* ControlPtr(dynamic_cast(wxMacControl::GetReferenceFromNativeControl(browser))); - // sent the equivalent wxWidget event: - wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED,dataViewCtrlPtr->GetId()); - dataViewEvent.SetEventObject(dataViewCtrlPtr); - dataViewEvent.SetItem(item); - // sent the equivalent wxWidget event: - dataViewCtrlPtr->HandleWindowEvent(dataViewEvent); - // done - return true; - } - else - return false; - } + if (ControlPtr != NULL) + return ControlPtr->DataBrowserTrackingProc(itemID,propertyID,theRect,startPt,modifiers); + else + return kDataBrowserNothingHit; +} /* wxMacDataBrowserTableViewControl::DataBrowserTrackingProc(ControlRef, DataBrowserItemID, DataBrowserPropertyID, Rect const*, Point, EventModifiers) */ - virtual bool ItemsChanged(wxDataViewItemArray const& items) - { - bool noFailureFlag; +pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserAcceptDragProc(ControlRef browser, DragReference dragRef, DataBrowserItemID itemID) +{ + wxMacDataBrowserTableViewControl* controlPtr(dynamic_cast(wxMacControl::GetReferenceFromNativeControl(browser))); - DataBrowserItemID* itemIDs; - size_t noOfEntries; + return ((controlPtr != NULL) && controlPtr->DataBrowserAcceptDragProc(dragRef,itemID)); +} /* wxMacDataBrowserTableViewControl::DataBrowserAcceptDragProc(ControlRef, DragReference, DataBrowserItemID) */ +pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserAddDragItemProc(ControlRef browser, DragReference dragRef, DataBrowserItemID itemID, ItemReference* itemRef) +{ + wxMacDataBrowserTableViewControl* controlPtr(dynamic_cast(wxMacControl::GetReferenceFromNativeControl(browser))); - // convert all valid data view items to data browser items: - itemIDs = ::CreateDataBrowserItemIDArray(noOfEntries,items); - // change items (ATTENTION: ONLY ITEMS OF THE ROOT ARE CHANGED BECAUSE THE PARENT PARAMETER IS MISSING): - noFailureFlag = (m_dataViewControlPtr->UpdateItems(kDataBrowserNoItem,noOfEntries,itemIDs,kDataBrowserItemNoProperty,kDataBrowserItemNoProperty) == noErr); - if (noFailureFlag) - { - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(m_dataViewControlPtr->GetWXPeer())); - // send for all changed items a wxWidget event: - wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED,dataViewCtrlPtr->GetId()); + return ((controlPtr != NULL) && controlPtr->DataBrowserAddDragItemProc(dragRef,itemID,itemRef)); +} /* wxMacDataBrowserTableViewControl::DataBrowserAddDragItemProc(ControlRef, DragReference, DataBrowserItemID, ItemReference*) */ - dataViewEvent.SetEventObject(dataViewCtrlPtr); - for (size_t i=0; i(itemIDs[i])); - dataViewCtrlPtr->HandleWindowEvent(dataViewEvent); - } - } - // release allocated array space: - delete[] itemIDs; - // done: - return noFailureFlag; - } +pascal Boolean wxMacDataBrowserTableViewControl::DataBrowserReceiveDragProc(ControlRef browser, DragReference dragRef, DataBrowserItemID itemID) +{ + wxMacDataBrowserTableViewControl* controlPtr(dynamic_cast(wxMacControl::GetReferenceFromNativeControl(browser))); - virtual bool ItemDeleted(wxDataViewItem const& parent, wxDataViewItem const& item) - { - if (item.IsOk()) - { - DataBrowserItemID itemID(reinterpret_cast(item.GetID())); - OSStatus errorStatus; - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(m_dataViewControlPtr->GetWXPeer())); - - // when this method is called and currently an item is being edited this item may have already been deleted in the model (the passed item and the being edited item have - // not to be identical because the being edited item might be below the passed item in the hierarchy); - // to prevent the control trying to ask the model to update an already deleted item the control is informed that currently a deleting process - // has been started and that variables can currently not be updated even when requested by the system: - dataViewCtrlPtr->SetDeleting(true); - errorStatus = m_dataViewControlPtr->RemoveItem(reinterpret_cast(parent.GetID()),&itemID); - // enable automatic updating again: - dataViewCtrlPtr->SetDeleting(false); - return (errorStatus == noErr); - } - else - return false; - } - virtual bool ItemsDeleted(wxDataViewItem const& parent, wxDataViewItemArray const& items) - { - bool noFailureFlag; - - DataBrowserItemID* itemIDs; - - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(m_dataViewControlPtr->GetWXPeer())); - - size_t noOfEntries; - - - wxCHECK_MSG(dataViewCtrlPtr != NULL,false,_("Data view control is not correctly initialized")); - // convert all valid data view items to data browser items: - itemIDs = ::CreateDataBrowserItemIDArray(noOfEntries,items); - // when this method is called and currently an item is being edited this item may have already been deleted in the model (the passed item and the being edited item have - // not to be identical because the being edited item might be below the passed item in the hierarchy); - // to prevent the control trying to ask the model to update an already deleted item the control is informed that currently a deleting process - // has been started and that variables can currently not be updated even when requested by the system: - dataViewCtrlPtr->SetDeleting(true); - // insert all valid items into control: - noFailureFlag = ((noOfEntries == 0) || - !(parent.IsOk()) && (m_dataViewControlPtr->RemoveItems(kDataBrowserNoItem,noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr) || - parent.IsOk() && (m_dataViewControlPtr->RemoveItems(reinterpret_cast(parent.GetID()),noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr)); - // enable automatic updating again: - dataViewCtrlPtr->SetDeleting(false); - // give allocated array space free again: - delete[] itemIDs; - // done: - return noFailureFlag; - } + return ((controlPtr != NULL) && controlPtr->DataBrowserReceiveDragProc(dragRef,itemID)); +} /* wxMacDataBrowserTableViewControl::DataBrowserReceiveDragProc(ControlRef, DragReference, DataBrowserItemID) */ - virtual bool ValueChanged(wxDataViewItem const& item, unsigned int col) - { - DataBrowserItemID itemID(reinterpret_cast(item.GetID())); - DataBrowserItemID parentID; +wxMacDataBrowserTableViewControl::wxMacDataBrowserTableViewControl(wxWindow* peer, wxPoint const& pos, wxSize const& size, long style) + :wxMacControl(peer) +{ + Rect bounds = wxMacGetBoundsForControl(peer,pos,size); + OSStatus err = ::CreateDataBrowserControl(MAC_WXHWND(peer->MacGetTopLevelWindowRef()),&bounds,kDataBrowserListView,&(this->m_controlRef)); - DataBrowserPropertyID propertyID; - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(m_dataViewControlPtr->GetWXPeer())); + SetReferenceInNativeControl(); + verify_noerr(err); + ::InstallControlEventHandler(this->m_controlRef, GetDataBrowserCtrlEventHandlerUPP(), GetEventTypeCount(eventList), eventList, peer, (EventHandlerRef *)&m_macDataViewCtrlEventHandler); - wxCHECK_MSG(item.IsOk(), false,_("Passed item is invalid.")); - wxCHECK_MSG(this->GetOwner() != NULL,false,_("Owner not initialized.")); - wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Control is wrongly initialized.")); - parentID = reinterpret_cast(this->GetOwner()->GetParent(item).GetID()); - if ((m_dataViewControlPtr->GetPropertyID(col,&propertyID) == noErr) && - (m_dataViewControlPtr->UpdateItems(parentID,1,&itemID,dataViewCtrlPtr->GetColumn(col)->GetPropertyID(),propertyID) == noErr)) - { - wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED,dataViewCtrlPtr->GetId()); - - dataViewEvent.SetEventObject(dataViewCtrlPtr); - dataViewEvent.SetColumn(col); - dataViewEvent.SetItem(item); - // send the equivalent wxWidget event: - dataViewCtrlPtr->HandleWindowEvent(dataViewEvent); - // done - return true; - } - else - return false; + // setup standard callbacks: + if (gDataBrowserTableViewGetContextualMenuUPP == NULL) gDataBrowserTableViewGetContextualMenuUPP = NewDataBrowserGetContextualMenuUPP(wxMacDataBrowserTableViewControl::DataBrowserGetContextualMenuProc); + if (gDataBrowserTableViewItemCompareUPP == NULL) gDataBrowserTableViewItemCompareUPP = NewDataBrowserItemCompareUPP (wxMacDataBrowserTableViewControl::DataBrowserCompareProc); + if (gDataBrowserTableViewItemDataUPP == NULL) gDataBrowserTableViewItemDataUPP = NewDataBrowserItemDataUPP (wxMacDataBrowserTableViewControl::DataBrowserGetSetItemDataProc); + if (gDataBrowserTableViewItemNotificationUPP == NULL) + { + gDataBrowserTableViewItemNotificationUPP = +#if TARGET_API_MAC_OSX + (DataBrowserItemNotificationUPP) NewDataBrowserItemNotificationWithItemUPP(wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc); +#else + NewDataBrowserItemNotificationUPP(wxMacDataBrowserTableViewControl::DataBrowserItemNotificationProc); +#endif } - - virtual bool Cleared() + // setup drag and drop callbacks: + if (gDataBrowserTableViewAcceptDragUPP == NULL) gDataBrowserTableViewAcceptDragUPP = NewDataBrowserAcceptDragUPP (wxMacDataBrowserTableViewControl::DataBrowserAcceptDragProc); + if (gDataBrowserTableViewAddDragItemUPP == NULL) gDataBrowserTableViewAddDragItemUPP = NewDataBrowserAddDragItemUPP(wxMacDataBrowserTableViewControl::DataBrowserAddDragItemProc); + if (gDataBrowserTableViewReceiveDragUPP == NULL) gDataBrowserTableViewReceiveDragUPP = NewDataBrowserReceiveDragUPP(wxMacDataBrowserTableViewControl::DataBrowserReceiveDragProc); + + DataBrowserCallbacks callbacks; // variable definition + + InitializeDataBrowserCallbacks(&callbacks,kDataBrowserLatestCallbacks); + callbacks.u.v1.getContextualMenuCallback = gDataBrowserTableViewGetContextualMenuUPP; + callbacks.u.v1.itemDataCallback = gDataBrowserTableViewItemDataUPP; + callbacks.u.v1.itemCompareCallback = gDataBrowserTableViewItemCompareUPP; + callbacks.u.v1.itemNotificationCallback = gDataBrowserTableViewItemNotificationUPP; + callbacks.u.v1.acceptDragCallback = gDataBrowserTableViewAcceptDragUPP; + callbacks.u.v1.addDragItemCallback = gDataBrowserTableViewAddDragItemUPP; + callbacks.u.v1.receiveDragCallback = gDataBrowserTableViewReceiveDragUPP; + this->SetCallbacks(&callbacks); + + // setup callbacks for customized items: + if (gDataBrowserTableViewDrawItemUPP == NULL) gDataBrowserTableViewDrawItemUPP = NewDataBrowserDrawItemUPP(wxMacDataBrowserTableViewControl::DataBrowserDrawItemProc); + if (gDataBrowserTableViewEditItemUPP == NULL) gDataBrowserTableViewEditItemUPP = NewDataBrowserEditItemUPP(wxMacDataBrowserTableViewControl::DataBrowserEditItemProc); + if (gDataBrowserTableViewHitTestUPP == NULL) gDataBrowserTableViewHitTestUPP = NewDataBrowserHitTestUPP (wxMacDataBrowserTableViewControl::DataBrowserHitTestProc); + if (gDataBrowserTableViewTrackingUPP == NULL) gDataBrowserTableViewTrackingUPP = NewDataBrowserTrackingUPP(wxMacDataBrowserTableViewControl::DataBrowserTrackingProc); + + DataBrowserCustomCallbacks customCallbacks; // variable definition + + InitializeDataBrowserCustomCallbacks(&customCallbacks,kDataBrowserLatestCallbacks); + customCallbacks.u.v1.drawItemCallback = gDataBrowserTableViewDrawItemUPP; + customCallbacks.u.v1.editTextCallback = gDataBrowserTableViewEditItemUPP; + customCallbacks.u.v1.hitTestCallback = gDataBrowserTableViewHitTestUPP; + customCallbacks.u.v1.trackingCallback = gDataBrowserTableViewTrackingUPP; + this->SetCustomCallbacks(&customCallbacks); + + // style setting: + this->EnableCellSizeModification( ((style & wxDV_VARIABLE_LINE_HEIGHT) != 0), true ); + + DataBrowserSelectionFlags flags; // variable definition + + if (this->GetSelectionFlags(&flags) == noErr) // get default settings { - bool noFailureFlag = (m_dataViewControlPtr->RemoveItems() == noErr); - wxDataViewItem item; - wxDataViewItemArray array; - GetOwner()->GetChildren( item, array ); - ItemsAdded( item, array ); - m_dataViewControlPtr->SetScrollPosition(0, 0); - return noFailureFlag; + if ((style & wxDV_MULTIPLE) != 0) + flags &= ~kDataBrowserSelectOnlyOne; + else + flags |= kDataBrowserSelectOnlyOne; + (void) this->SetSelectionFlags(flags); } - virtual void Resort() + OptionBits attributes; // variable definition + + if (this->GetAttributes(&attributes) == noErr) // get default settings { - m_dataViewControlPtr->Resort(); + if ((style & wxDV_VERT_RULES) != 0) + attributes |= kDataBrowserAttributeListViewDrawColumnDividers; + else + attributes &= ~kDataBrowserAttributeListViewDrawColumnDividers; + if ((style & wxDV_ROW_LINES) != 0) + attributes |= kDataBrowserAttributeListViewAlternatingRowColors; + else + attributes &= ~kDataBrowserAttributeListViewAlternatingRowColors; + (void) this->SetAttributes(attributes); } -private: - wxMacDataViewDataBrowserListViewControl* m_dataViewControlPtr; -}; + if ((style & wxDV_NO_HEADER) != 0) + this->SetHeaderButtonHeight(0); +} /* wxMacDataBrowserTableViewControl::wxMacDataBrowserTableViewControl(wxWindow*, wxPoint const&, wxSize const&, long) */ -// --------------------------------------------------------- -// wxDataViewRenderer -// --------------------------------------------------------- -wxDataViewRenderer::wxDataViewRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align) - :wxDataViewRendererBase(varianttype,mode,align), m_alignment(align), m_mode(mode) +wxMacDataBrowserTableViewControl::~wxMacDataBrowserTableViewControl(void) { -} + ::RemoveEventHandler((EventHandlerRef) m_macDataViewCtrlEventHandler); +} /* wxMacDataBrowserTableViewControl::~wxMacDataBrowserTableViewControl(void) */ -void wxDataViewRenderer::SetMode(wxDataViewCellMode mode) +// +// callback handling +// +OSStatus wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks const* callbacks) { - wxDataViewColumn* dataViewColumnPtr; - + return ::SetDataBrowserCallbacks(this->m_controlRef,callbacks); +} /* wxMacDataBrowserTableViewControl::SetCallbacks(DataBrowserCallbacks const*) */ - m_mode = mode; - dataViewColumnPtr = this->GetOwner(); - if (dataViewColumnPtr != NULL) - { - wxDataViewCtrl* dataViewCtrlPtr(dataViewColumnPtr->GetOwner()); - - if (dataViewCtrlPtr != NULL) - { - wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); - - if (macDataViewListCtrlPtr != NULL) - { - DataBrowserPropertyFlags flags; +OSStatus wxMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks const* customCallbacks) +{ + return ::SetDataBrowserCustomCallbacks(this->m_controlRef,customCallbacks); +} /* xMacDataBrowserTableViewControl::SetCustomCallbacks(DataBrowserCustomCallbacks const*) */ - verify_noerr(macDataViewListCtrlPtr->GetPropertyFlags(dataViewColumnPtr->GetPropertyID(),&flags)); - if ((mode == wxDATAVIEW_CELL_EDITABLE) || (mode == wxDATAVIEW_CELL_ACTIVATABLE)) - flags |= kDataBrowserPropertyIsEditable; - else - flags &= ~kDataBrowserPropertyIsEditable; - verify_noerr(macDataViewListCtrlPtr->SetPropertyFlags(dataViewColumnPtr->GetPropertyID(),flags)); - } - } - } +// +// DnD handling +// +OSStatus wxMacDataBrowserTableViewControl::EnableAutomaticDragTracking(bool enable) +{ + return ::SetAutomaticControlDragTrackingEnabledForWindow(::GetControlOwner(this->m_controlRef),enable); } -IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer,wxDataViewRendererBase) - -// --------------------------------------------------------- -// wxDataViewCustomRenderer -// --------------------------------------------------------- -wxDataViewCustomRenderer::wxDataViewCustomRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align) - :wxDataViewRenderer(varianttype,mode,align), m_editorCtrlPtr(NULL), m_DCPtr(NULL) +// +// header handling +// +OSStatus wxMacDataBrowserTableViewControl::GetHeaderDesc(DataBrowserPropertyID propertyID, DataBrowserListViewHeaderDesc* desc) const { + desc->version = kDataBrowserListViewLatestHeaderDesc; // if this statement is missing the next call will fail (NOT DOCUMENTED!!) + return ::GetDataBrowserListViewHeaderDesc(this->m_controlRef,propertyID,desc); } -wxDataViewCustomRenderer::~wxDataViewCustomRenderer() +OSStatus wxMacDataBrowserTableViewControl::SetHeaderDesc(DataBrowserPropertyID propertyID, DataBrowserListViewHeaderDesc* desc) { - delete m_DCPtr; + return ::SetDataBrowserListViewHeaderDesc(this->m_controlRef,propertyID,desc); } -void wxDataViewCustomRenderer::RenderText( const wxString &text, int xoffset, wxRect cell, wxDC *dc, int state ) +// +// layout handling +// +OSStatus wxMacDataBrowserTableViewControl::AutoSizeColumns() { - wxDataViewCtrl *view = GetOwner()->GetOwner(); -// wxColour col = (state & wxDATAVIEW_CELL_SELECTED) ? wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) : view->GetForegroundColour(); - wxColour col = (state & wxDATAVIEW_CELL_SELECTED) ? *wxWHITE : view->GetForegroundColour(); - dc->SetTextForeground(col); - dc->DrawText( text, cell.x + xoffset, cell.y + ((cell.height - dc->GetCharHeight()) / 2)); + return AutoSizeDataBrowserListViewColumns(this->m_controlRef); } -wxDC* wxDataViewCustomRenderer::GetDC() +OSStatus wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool enableHeight, bool enableWidth) { - if (m_DCPtr == NULL) - { - if ((GetOwner() == NULL) || (GetOwner()->GetOwner() == NULL)) - return NULL; - m_DCPtr = new wxWindowDC(this->GetOwner()->GetOwner()); - } - return m_DCPtr; + return ::SetDataBrowserTableViewGeometry(this->GetControlRef(),enableWidth,enableHeight); +} /* wxMacDataBrowserTableViewControl::EnableCellSizeModification(bool, bool) */ + +OSStatus wxMacDataBrowserTableViewControl::GetAttributes(OptionBits* attributes) +{ + return ::DataBrowserGetAttributes(this->GetControlRef(),attributes); +} /* wxMacDataBrowserTableViewControl::GetAttributes(OptionBits*) */ + +OSStatus wxMacDataBrowserTableViewControl::GetColumnWidth(DataBrowserPropertyID propertyID, UInt16* width) const +{ + return ::GetDataBrowserTableViewNamedColumnWidth(this->m_controlRef,propertyID,width); } -bool wxDataViewCustomRenderer::Render() +OSStatus wxMacDataBrowserTableViewControl::GetDefaultColumnWidth( UInt16 *width ) const { - return true; + return GetDataBrowserTableViewColumnWidth(this->m_controlRef, width ); } -void wxDataViewCustomRenderer::SetDC(wxDC* newDCPtr) +OSStatus wxMacDataBrowserTableViewControl::GetDefaultRowHeight(UInt16* height) const { - delete m_DCPtr; - m_DCPtr = newDCPtr; + return ::GetDataBrowserTableViewRowHeight(this->m_controlRef,height); } -WXDataBrowserPropertyType wxDataViewCustomRenderer::GetPropertyType() const +OSStatus wxMacDataBrowserTableViewControl::GetHeaderButtonHeight(UInt16 *height) { - return kDataBrowserCustomType; + return ::GetDataBrowserListViewHeaderBtnHeight(this->m_controlRef,height); } -IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomRenderer, wxDataViewRenderer) +OSStatus wxMacDataBrowserTableViewControl::GetPartBounds(DataBrowserItemID item, DataBrowserPropertyID propertyID, DataBrowserPropertyPart part, Rect* bounds) +{ + return ::GetDataBrowserItemPartBounds(this->m_controlRef,item,propertyID,part,bounds); +} /* wxMacDataBrowserTableViewControl::GetPartBounds(DataBrowserItemID, DataBrowswerPropertyID, DataBrowserPropertyPart, Rect*) */ -// --------------------------------------------------------- -// wxDataViewTextRenderer -// --------------------------------------------------------- -wxDataViewTextRenderer::wxDataViewTextRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align) - :wxDataViewRenderer(varianttype,mode,align) +OSStatus wxMacDataBrowserTableViewControl::GetRowHeight(DataBrowserItemID item, UInt16* height) const +{ + return ::GetDataBrowserTableViewItemRowHeight(this->m_controlRef,item,height); +} /* wxMacDataBrowserTableViewControl::GetRowHeight(DataBrowserItemID, UInt16*) const */ + +OSStatus wxMacDataBrowserTableViewControl::GetScrollPosition( UInt32 *top , UInt32 *left ) const { + return GetDataBrowserScrollPosition(this->m_controlRef, top , left ); } -bool wxDataViewTextRenderer::Render() +OSStatus wxMacDataBrowserTableViewControl::SetAttributes(OptionBits attributes) { - wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Text renderer cannot render value; value type: ")) << this->GetValue().GetType()); + return ::DataBrowserChangeAttributes(this->GetControlRef(),attributes,~attributes); +} /* wxMacDataBrowserTableViewControl::SetAttributes(OptionBits) */ - wxCFStringRef cfString(this->GetValue().GetString(),(this->GetView()->GetFont().Ok() ? this->GetView()->GetFont().GetEncoding() : wxLocale::GetSystemEncoding())); - return (::SetDataBrowserItemDataText(this->GetDataReference(),cfString) == noErr); +OSStatus wxMacDataBrowserTableViewControl::SetColumnWidth(DataBrowserPropertyID propertyID, UInt16 width) +{ + return ::SetDataBrowserTableViewNamedColumnWidth(this->m_controlRef,propertyID,width); } -WXDataBrowserPropertyType wxDataViewTextRenderer::GetPropertyType() const +OSStatus wxMacDataBrowserTableViewControl::SetDefaultColumnWidth(UInt16 width) { - return kDataBrowserTextType; + return ::SetDataBrowserTableViewColumnWidth(this->m_controlRef,width); } -IMPLEMENT_CLASS(wxDataViewTextRenderer,wxDataViewRenderer) - -// --------------------------------------------------------- -// wxDataViewTextRendererAttr -// --------------------------------------------------------- -wxDataViewTextRendererAttr::wxDataViewTextRendererAttr(wxString const& varianttype, wxDataViewCellMode mode, int align) - :wxDataViewTextRenderer(varianttype,mode,align) +OSStatus wxMacDataBrowserTableViewControl::SetDefaultRowHeight(UInt16 height) { + return ::SetDataBrowserTableViewRowHeight(this->m_controlRef,height); } -IMPLEMENT_CLASS(wxDataViewTextRendererAttr,wxDataViewTextRenderer) +OSStatus wxMacDataBrowserTableViewControl::SetHasScrollBars(bool horiz, bool vert) +{ + return ::SetDataBrowserHasScrollBars(this->m_controlRef,horiz,vert); +} /* wxMacDataBrowserTableViewControl::SetHasScrollBars(bool, bool) */ -// --------------------------------------------------------- -// wxDataViewBitmapRenderer -// --------------------------------------------------------- -wxDataViewBitmapRenderer::wxDataViewBitmapRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align) - :wxDataViewRenderer(varianttype,mode,align) +OSStatus wxMacDataBrowserTableViewControl::SetHeaderButtonHeight(UInt16 height) { -} + return ::SetDataBrowserListViewHeaderBtnHeight(this->m_controlRef,height); +} /* wxMacDataBrowserTableViewControl::SetHeaderButtonHeight(UInt16) */ -bool wxDataViewBitmapRenderer::Render() - // This method returns 'true' if - // - the passed bitmap is valid and it could be assigned to the native data browser; - // - the passed bitmap is invalid (or is not initialized); this case simulates a non-existing bitmap. - // In all other cases the method returns 'false'. +OSStatus wxMacDataBrowserTableViewControl::SetHiliteStyle(DataBrowserTableViewHiliteStyle hiliteStyle) { - wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Bitmap renderer cannot render value; value type: ")) << this->GetValue().GetType()); + return ::SetDataBrowserTableViewHiliteStyle(this->m_controlRef,hiliteStyle); +} /*wxMacDataBrowserTableViewControl::SetHiliteStyle(DataBrowserTableViewHiliteStyle) */ - wxBitmap bitmap; +OSStatus wxMacDataBrowserTableViewControl::SetIndent(float Indent) +{ + return ::DataBrowserSetMetric(this->m_controlRef,kDataBrowserMetricDisclosureColumnPerDepthGap,true,Indent); +} /* wxMacDataBrowserTableViewControl::SetIndent(float* Indent) */ - bitmap << this->GetValue(); - if (bitmap.Ok()) - return (::SetDataBrowserItemDataIcon(this->GetDataReference(),bitmap.GetIconRef()) == noErr); - else - return true; +OSStatus wxMacDataBrowserTableViewControl::SetItemRowHeight(DataBrowserItemID item, UInt16 height) +{ + return ::SetDataBrowserTableViewItemRowHeight(this->m_controlRef,item,height); } -WXDataBrowserPropertyType wxDataViewBitmapRenderer::GetPropertyType() const +OSStatus wxMacDataBrowserTableViewControl::SetScrollPosition(UInt32 top, UInt32 left) { - return kDataBrowserIconType; + return ::SetDataBrowserScrollPosition(this->m_controlRef,top,left); } -IMPLEMENT_CLASS(wxDataViewBitmapRenderer,wxDataViewRenderer) +// +// column handling +// +OSStatus wxMacDataBrowserTableViewControl::GetColumnCount(UInt32* numColumns) const +{ + return ::GetDataBrowserTableViewColumnCount(this->m_controlRef,numColumns); +} -// --------------------------------------------------------- -// wxDataViewIconTextRenderer -// --------------------------------------------------------- -wxDataViewIconTextRenderer::wxDataViewIconTextRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align) - :wxDataViewRenderer(varianttype,mode) +OSStatus wxMacDataBrowserTableViewControl::GetColumnIndex(DataBrowserPropertyID propertyID, DataBrowserTableViewColumnIndex* index) const +{ + return ::GetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,index); +} /* wxMacDataBrowserTableViewControl::GetColumnIndex(DataBrowserPropertyID, DataBrowserTableViewColumnIndex*) const */ + +OSStatus wxMacDataBrowserTableViewControl::GetFreePropertyID(DataBrowserPropertyID* propertyID) const +{ + for (*propertyID=kMinPropertyID; *propertyID::max(); ++(*propertyID)) + if (this->IsUsedPropertyID(*propertyID) == errDataBrowserPropertyNotFound) + return noErr; + return errDataBrowserPropertyNotSupported; +} /* wxMacDataBrowserTableViewControl::GetFreePropertyID(DataBrowserPropertyID*) const */ + +OSStatus wxMacDataBrowserTableViewControl::GetPropertyFlags(DataBrowserPropertyID propertyID, DataBrowserPropertyFlags *flags) const { + return ::GetDataBrowserPropertyFlags(this->m_controlRef,propertyID,flags); } -bool wxDataViewIconTextRenderer::Render() +OSStatus wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserItemDataRef itemData, DataBrowserPropertyID* propertyID) const { - wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Icon & text renderer cannot render value; value type: ")) << this->GetValue().GetType()); + return ::GetDataBrowserItemDataProperty(itemData,propertyID); +} /* wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserItemDataRef, DataBrowserPropertyID*) */ - wxDataViewIconText iconText; +OSStatus wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserTableViewColumnIndex index, DataBrowserTableViewColumnID* propertyID) const +{ + return ::GetDataBrowserTableViewColumnProperty(this->m_controlRef,index,propertyID); +} /* wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserTableViewColumnIndex, DataBrowserTableViewColumnID*) */ - iconText << this->GetValue(); +OSStatus wxMacDataBrowserTableViewControl::IsUsedPropertyID(DataBrowserPropertyID propertyID) const +{ + // 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 + // 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 + // the column position for the property id: + DataBrowserTableViewColumnIndex index; - wxCFStringRef cfString(iconText.GetText(),(this->GetView()->GetFont().Ok() ? this->GetView()->GetFont().GetEncoding() : wxLocale::GetSystemEncoding())); + return ::GetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,&index); +} /* wxMacDataBrowserTableViewControl::IsUsedPropertyId(DataBrowserPropertyID) const */ - if (iconText.GetIcon().IsOk()) - if (::SetDataBrowserItemDataIcon(this->GetDataReference(),MAC_WXHICON(iconText.GetIcon().GetHICON())) != noErr) - return false; - return (::SetDataBrowserItemDataText(this->GetDataReference(),cfString) == noErr); -} +OSStatus wxMacDataBrowserTableViewControl::RemoveColumnByProperty(DataBrowserTableViewColumnID propertyID) +{ + return ::RemoveDataBrowserTableViewColumn(this->m_controlRef,propertyID); +} /* wxMacDataBrowserTableViewControl::RemoveColumnByProperty(DataBrowserTableViewColumnID) */ -WXDataBrowserPropertyType wxDataViewIconTextRenderer::GetPropertyType() const +OSStatus wxMacDataBrowserTableViewControl::RemoveColumnByIndex(DataBrowserTableViewColumnIndex index) { - return kDataBrowserIconAndTextType; -} + DataBrowserTableViewColumnID propertyID; -IMPLEMENT_ABSTRACT_CLASS(wxDataViewIconTextRenderer,wxDataViewRenderer) + this->GetPropertyID(index,&propertyID); + return ::RemoveDataBrowserTableViewColumn(this->m_controlRef,propertyID); +} /* wxMacDataBrowserTableViewControl::RemoveColumnByIndex(DataBrowserTableViewColumnIndex) */ -// --------------------------------------------------------- -// wxDataViewToggleRenderer -// --------------------------------------------------------- -wxDataViewToggleRenderer::wxDataViewToggleRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align) - :wxDataViewRenderer(varianttype,mode) +OSStatus wxMacDataBrowserTableViewControl::SetColumnIndex(DataBrowserPropertyID propertyID, DataBrowserTableViewColumnIndex index) { -} + return ::SetDataBrowserTableViewColumnPosition(this->m_controlRef,propertyID,index); +} /* wxMacDataBrowserTableViewControl::SetColumnIndex(DataBrowserPropertyID, DataBrowserTableViewColumnIndex) */ -bool wxDataViewToggleRenderer::Render() +OSStatus wxMacDataBrowserTableViewControl::SetDisclosureColumn(DataBrowserPropertyID propertyID, Boolean expandableRows) { - wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Toggle renderer cannot render value; value type: ")) << this->GetValue().GetType()); - return (::SetDataBrowserItemDataButtonValue(this->GetDataReference(),this->GetValue().GetBool()) == noErr); + return ::SetDataBrowserListViewDisclosureColumn(this->m_controlRef,propertyID,expandableRows); } -WXDataBrowserPropertyType wxDataViewToggleRenderer::GetPropertyType() const +OSStatus wxMacDataBrowserTableViewControl::SetPropertyFlags(DataBrowserPropertyID propertyID, DataBrowserPropertyFlags flags) { - return kDataBrowserCheckboxType; -} + return ::SetDataBrowserPropertyFlags(this->m_controlRef,propertyID,flags); +} /* wxMacDataBrowserTableViewControl::SetPropertyFlags(DataBrowserPropertyID, DataBrowserPropertyFlags) */ -IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleRenderer,wxDataViewRenderer) +// +// item handling +// +OSStatus wxMacDataBrowserTableViewControl::AddItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty) +{ + return ::AddDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty); +} /* wxMacDataBrowserTableViewControl::AddItems(DataBrowserItemID, UInt32, DataBrowserItemID const*, DataBrowserPropertyID) */ -// --------------------------------------------------------- -// wxDataViewProgressRenderer -// --------------------------------------------------------- -wxDataViewProgressRenderer::wxDataViewProgressRenderer(wxString const& label, wxString const& varianttype, wxDataViewCellMode mode, int align) - :wxDataViewRenderer(varianttype,mode,align) +OSStatus wxMacDataBrowserTableViewControl::GetFreeItemID(DataBrowserItemID* id) const { -} + ItemCount noOfItems; + + OSStatus status; + + + status = this->GetItemCount(&noOfItems); + wxCHECK_MSG(status == noErr,status,_("Could not retrieve number of items")); + if (noOfItems == 0) + { + *id = 1; + return noErr; + } + else + { + // 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 + // as the number of items; therefore, start from the number of items to look for a new ID: + for (*id=noOfItems; *id::max(); ++(*id)) + if (this->IsUsedItemID(*id) == errDataBrowserItemNotFound) + return noErr; + // as the first approach was not successful, try from the beginning: + for (*id=0; *idIsUsedItemID(*id) == errDataBrowserItemNotFound) + return noErr; + // sorry, data browser is full: + return errDataBrowserItemNotAdded; + } +} /* wxMacDataBrowserTableViewControl::GetFreeItemID(DataBrowserItemID*) const */ -bool wxDataViewProgressRenderer::Render() +OSStatus wxMacDataBrowserTableViewControl::GetItemCount(DataBrowserItemID container, Boolean recurse, DataBrowserItemState state, ItemCount* numItems) const { - wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Progress renderer cannot render value type; value type: ")) << this->GetValue().GetType()); - return ((::SetDataBrowserItemDataMinimum(this->GetDataReference(), 0) == noErr) && - (::SetDataBrowserItemDataMaximum(this->GetDataReference(),100) == noErr) && - (::SetDataBrowserItemDataValue (this->GetDataReference(),this->GetValue().GetLong()) == noErr)); -} + return GetDataBrowserItemCount(this->m_controlRef,container,recurse,state,numItems); +} /* wxMacDataBrowserTableViewControl::GetItemCount(DataBrowserItemID, Boolean, DataBrowserItemState, ItemCount*) const */ -WXDataBrowserPropertyType wxDataViewProgressRenderer::GetPropertyType() const +OSStatus wxMacDataBrowserTableViewControl::GetItemID( DataBrowserTableViewRowIndex row, DataBrowserItemID * item ) const { - return kDataBrowserProgressBarType; + return GetDataBrowserTableViewItemID(this->m_controlRef,row,item); } -IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressRenderer,wxDataViewRenderer) +OSStatus wxMacDataBrowserTableViewControl::GetItems(DataBrowserItemID container, Boolean recurse, DataBrowserItemState state, Handle items) const +{ + return GetDataBrowserItems(this->m_controlRef,container,recurse,state,items); +} /* wxMacDataBrowserTableViewControl::GetItems(DataBrowserItemID, Boolean, DataBrowserItemState, Handle) const */ -// --------------------------------------------------------- -// wxDataViewDateRenderer -// --------------------------------------------------------- -wxDataViewDateRenderer::wxDataViewDateRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align) - :wxDataViewRenderer(varianttype,mode,align) +OSStatus wxMacDataBrowserTableViewControl::GetItemRow(DataBrowserItemID item, DataBrowserTableViewRowIndex* row) const { + return GetDataBrowserTableViewItemRow(this->m_controlRef,item,row); } -bool wxDataViewDateRenderer::Render() +OSStatus wxMacDataBrowserTableViewControl::GetItemState(DataBrowserItemID item, DataBrowserItemState* state) const { - wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Date renderer cannot render value; value type: ")) << this->GetValue().GetType()); - return (::SetDataBrowserItemDataDateTime(this->GetDataReference(),this->GetValue().GetDateTime().Subtract(wxDateTime(1,wxDateTime::Jan,1904)).GetSeconds().GetLo()) == noErr); + return ::GetDataBrowserItemState(this->m_controlRef,item,state); } -WXDataBrowserPropertyType wxDataViewDateRenderer::GetPropertyType() const +OSStatus wxMacDataBrowserTableViewControl::IsUsedItemID(DataBrowserItemID itemID) const { - return kDataBrowserDateTimeType; -} + // 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 + // 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 + // the column position for the property id: + DataBrowserTableViewColumnIndex index; -IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer,wxDataViewRenderer) + return ::GetDataBrowserTableViewItemRow(this->m_controlRef,itemID,&index); +} /* wxMacDataBrowserTableViewControl::IsUsedItemID(DataBrowserItemID) const */ -// --------------------------------------------------------- -// wxDataViewColumn -// --------------------------------------------------------- +OSStatus wxMacDataBrowserTableViewControl::RemoveItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty) +{ + return ::RemoveDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty); +} -void wxDataViewColumn::SetAlignment(wxAlignment align) +OSStatus wxMacDataBrowserTableViewControl::RevealItem(DataBrowserItemID item, DataBrowserPropertyID propertyID, DataBrowserRevealOptions options) const { - wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + return ::RevealDataBrowserItem(this->m_controlRef,item,propertyID,options); +} /* wxMacDataBrowserTableViewControl::RevealItem(DataBrowserItemID item, DataBrowserPropertyID propertyID, DataBrowserRevealOptions options) const */ +OSStatus wxMacDataBrowserTableViewControl::UpdateItems(DataBrowserItemID container, UInt32 numItems, DataBrowserItemID const* items, DataBrowserPropertyID preSortProperty, + DataBrowserPropertyID propertyID) const +{ + return UpdateDataBrowserItems(this->m_controlRef,container,numItems,items,preSortProperty,propertyID); +} - m_alignment = align; - if (dataViewCtrlPtr != NULL) - { - wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); +// +// item selection +// +size_t wxMacDataBrowserTableViewControl::GetSelectedItemIDs(wxArrayDataBrowserItemID& itemIDs) const +{ + DataBrowserItemID* itemIDPtr; + Handle handle(::NewHandle(0)); - if (macDataViewListCtrlPtr != NULL) - { - DataBrowserListViewHeaderDesc headerDescription; + size_t noOfItems; - wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description.")); - switch (align) - { - case wxALIGN_CENTER: - case wxALIGN_CENTER_HORIZONTAL: - headerDescription.btnFontStyle.just = teCenter; - break; - case wxALIGN_LEFT: - headerDescription.btnFontStyle.just = teFlushLeft; - break; - case wxALIGN_RIGHT: - headerDescription.btnFontStyle.just = teFlushRight; - break; - default: - headerDescription.btnFontStyle.just = teFlushDefault; - } - wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not set alignment.")); - } + + wxCHECK_MSG(this->GetItems(kDataBrowserNoItem,true,kDataBrowserItemIsSelected,handle) == noErr,0,_("Could not get selected items.")); + noOfItems = static_cast(::GetHandleSize(handle)/sizeof(DataBrowserItemID)); + itemIDs.Empty(); + itemIDs.Alloc(noOfItems); + HLock(handle); + itemIDPtr = (DataBrowserItemID*) (*handle); + for (size_t i=0; iGetOwner()); + return ::GetDataBrowserSelectionAnchor(this->m_controlRef,first,last); +} /* wxMacDataBrowserTableViewControl::GetSelectionAnchor(DataBrowserItemID*, DataBrowserItemID*) const */ +OSStatus wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags* flags) const +{ + return ::GetDataBrowserSelectionFlags(this->m_controlRef,flags); +} /* wxMacDataBrowserTableViewControl::GetSelectionFlags(DataBrowserSelectionFlags*) const */ - wxDataViewColumnBase::SetBitmap(bitmap); - if (dataViewCtrlPtr != NULL) - { - wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); +bool wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID item) const +{ + return ::IsDataBrowserItemSelected(this->m_controlRef,item); +} /* wxMacDataBrowserTableViewControl::IsItemSelected(DataBrowserItemID) const */ - if (macDataViewListCtrlPtr != NULL) - { - DataBrowserListViewHeaderDesc headerDescription; +OSStatus wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags flags) +{ + return ::SetDataBrowserSelectionFlags(this->m_controlRef,flags); +} /* wxMacDataBrowserTableViewControl::SetSelectionFlags(DataBrowserSelectionFlags) */ - wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description.")); - if (this->GetBitmap().Ok()) - headerDescription.btnContentInfo.u.iconRef = this->GetBitmap().GetIconRef(); - else - headerDescription.btnContentInfo.u.iconRef = NULL; - wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not set icon.")); - } - } -} +OSStatus wxMacDataBrowserTableViewControl::SetSelectedItems(UInt32 numItems, DataBrowserItemID const* items, DataBrowserSetOption operation) +{ + return ::SetDataBrowserSelectedItems(this->m_controlRef, numItems, items, operation ); +} /* wxMacDataBrowserTableViewControl::SetSelectedItems(UInt32, DataBrowserItemID const*, DataBrowserSetOption) */ -void wxDataViewColumn::SetMaxWidth(int maxWidth) +OSStatus wxMacDataBrowserTableViewControl::GetSortOrder(DataBrowserSortOrder* order) const { - wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + return ::GetDataBrowserSortOrder(this->m_controlRef,order); +} +OSStatus wxMacDataBrowserTableViewControl::GetSortProperty(DataBrowserPropertyID* propertyID) const +{ + return ::GetDataBrowserSortProperty(this->m_controlRef,propertyID); +} - m_maxWidth = maxWidth; - if (dataViewCtrlPtr != NULL) - { - wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); +OSStatus wxMacDataBrowserTableViewControl::Resort(DataBrowserItemID container, Boolean sortChildren) +{ + return ::SortDataBrowserContainer(this->m_controlRef,container,sortChildren); +} /* wxMacDataBrowserTableViewControl::Resort(DataBrowserItemID, Boolean) */ - if (macDataViewListCtrlPtr != NULL) - { - DataBrowserListViewHeaderDesc headerDescription; +OSStatus wxMacDataBrowserTableViewControl::SetSortOrder(DataBrowserSortOrder order) +{ + return ::SetDataBrowserSortOrder(this->m_controlRef,order); +} - wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description.")); - headerDescription.maximumWidth = static_cast(maxWidth); - wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not set maximum width.")); - } - } +OSStatus wxMacDataBrowserTableViewControl::SetSortProperty(DataBrowserPropertyID propertyID) +{ + return ::SetDataBrowserSortProperty(this->m_controlRef,propertyID); } -void wxDataViewColumn::SetMinWidth(int minWidth) +// +// container handling +// +OSStatus wxMacDataBrowserTableViewControl::CloseContainer(DataBrowserItemID containerID) { - wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + return ::CloseDataBrowserContainer(this->m_controlRef,containerID); +} /* wxMacDataBrowserTableViewControl::CloseContainer(DataBrowserItemID) */ +OSStatus wxMacDataBrowserTableViewControl::OpenContainer(DataBrowserItemID containerID) +{ + return ::OpenDataBrowserContainer(this->m_controlRef,containerID); +} /* wxMacDataBrowserTableViewControl::OpenContainer(DataBrowserItemID) */ - m_minWidth = minWidth; - if (dataViewCtrlPtr != NULL) - { - wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); +IMPLEMENT_ABSTRACT_CLASS(wxMacDataBrowserTableViewControl,wxMacControl) - if (macDataViewListCtrlPtr != NULL) - { - DataBrowserListViewHeaderDesc headerDescription; +// ============================================================================ +// wxMacDataBrowserListViewControl +// ============================================================================ +#pragma mark - +// +// column handling +// +OSStatus wxMacDataBrowserListViewControl::AddColumn(DataBrowserListViewColumnDesc *columnDesc, DataBrowserTableViewColumnIndex position) +{ + return AddDataBrowserListViewColumn(this->m_controlRef,columnDesc,position); +} /* wxMacDataBrowserListViewControl::AddColumn(DataBrowserListViewColumnDesc*, DataBrowserTableViewColumnIndex) */ - wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description.")); - headerDescription.minimumWidth = static_cast(minWidth); - wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not set minimum width.")); - } - } -} +// ============================================================================ +// wxMacDataViewDataBrowserListViewControl +// ============================================================================ +#pragma mark - +// +// constructors / destructor +// +wxMacDataViewDataBrowserListViewControl::wxMacDataViewDataBrowserListViewControl(wxWindow* peer, wxPoint const& pos, wxSize const& size, long style) + :wxMacDataBrowserListViewControl(peer,pos,size,style) +{ + if ((style & wxBORDER_NONE) != 0) + this->SetData(kControlNoPart,kControlDataBrowserIncludesFrameAndFocusTag,(Boolean) false); + (void) this->EnableAutomaticDragTracking(); + (void) this->SetHiliteStyle(kDataBrowserTableViewFillHilite); +} /* wxMacDataViewDataBrowserListViewControl::wxMacDataViewDataBrowserListViewControl(wxWindow* , const wxPoint&, const wxSize&, long) */ -void wxDataViewColumn::SetReorderable(bool reorderable) +// +// column related methods (inherited from wxDataViewWidgetImpl) +// +bool wxMacDataViewDataBrowserListViewControl::ClearColumns(void) { - // first set the internal flag of the column: - if (reorderable) - m_flags |= wxDATAVIEW_COL_REORDERABLE; - else - m_flags &= ~wxDATAVIEW_COL_REORDERABLE; - // if the column is associated with a control change also immediately the flags of the control: - wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + UInt32 noOfColumns; - if (dataViewCtrlPtr != NULL) - { - DataBrowserPropertyFlags flags; - wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); - wxCHECK_RET(macDataViewListCtrlPtr != NULL, _("Valid pointer to native data view control does not exist")); - wxCHECK_RET(macDataViewListCtrlPtr->GetPropertyFlags(this->GetPropertyID(),&flags) == noErr,_("Could not get property flags.")); - if (reorderable) - flags |= kDataBrowserListViewMovableColumn; - else - flags &= ~kDataBrowserListViewMovableColumn; - wxCHECK_RET(macDataViewListCtrlPtr->SetPropertyFlags(this->GetPropertyID(),flags) == noErr,_("Could not set property flags.")); - } + wxCHECK_MSG(this->GetColumnCount(&noOfColumns) == noErr,false,_("Could not determine number of columns.")); + for (UInt32 i=0; iRemoveColumnByIndex(0) == noErr,false,_("Could not remove column.")); + return true; } -void wxDataViewColumn::SetResizeable(bool resizeable) +bool wxMacDataViewDataBrowserListViewControl::DeleteColumn(wxDataViewColumn* columnPtr) { - // first set the internal flag of the column: - if (resizeable) - m_flags |= wxDATAVIEW_COL_RESIZABLE; - else - m_flags &= ~wxDATAVIEW_COL_RESIZABLE; - // if the column is associated with a control change also immediately the flags of the control: - wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); - - if (dataViewCtrlPtr != NULL) - { - wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); - - if (macDataViewListCtrlPtr != NULL) - { - DataBrowserListViewHeaderDesc headerDescription; + return (this->RemoveColumnByProperty(columnPtr->GetNativeData()->GetPropertyID()) == noErr); +} - verify_noerr(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription)); - if (resizeable) { - headerDescription.minimumWidth = 0; - headerDescription.maximumWidth = 30000; - } - else { - headerDescription.minimumWidth = m_width; - headerDescription.maximumWidth = m_width; - } - verify_noerr(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription)); - macDataViewListCtrlPtr->SetSortProperty(this->GetPropertyID()); - } - } +void wxMacDataViewDataBrowserListViewControl::DoSetExpanderColumn(wxDataViewColumn const* columnPtr) +{ + this->SetDisclosureColumn(columnPtr->GetNativeData()->GetPropertyID(),false); // second parameter explicitely passed to ensure that arrow is centered } -void wxDataViewColumn::SetSortable(bool sortable) +wxDataViewColumn* wxMacDataViewDataBrowserListViewControl::GetColumn(unsigned int pos) const { - // first set the internal flag of the column: - if (sortable) - m_flags |= wxDATAVIEW_COL_SORTABLE; + DataBrowserPropertyID propertyID; + + + if (this->GetPropertyID(pos,&propertyID) == noErr) + return this->GetColumnPtr(propertyID); else - m_flags &= ~wxDATAVIEW_COL_SORTABLE; - // if the column is associated with a control change also immediately the flags of the control: - wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + return NULL; +} - if (dataViewCtrlPtr != NULL) +int wxMacDataViewDataBrowserListViewControl::GetColumnPosition(wxDataViewColumn const* columnPtr) const +{ + if (columnPtr != NULL) { - DataBrowserPropertyFlags flags; - wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); + DataBrowserTableViewColumnIndex Position; - wxCHECK_RET(macDataViewListCtrlPtr != NULL, _("Valid pointer to native data view control does not exist")); - wxCHECK_RET(macDataViewListCtrlPtr->GetPropertyFlags(this->GetPropertyID(),&flags) == noErr,_("Could not get property flags.")); - if (sortable) - flags |= kDataBrowserListViewSortableColumn; - else - flags &= ~kDataBrowserListViewSortableColumn; - wxCHECK_RET(macDataViewListCtrlPtr->SetPropertyFlags(this->GetPropertyID(),flags) == noErr,_("Could not set property flags.")); + wxCHECK_MSG(this->GetColumnIndex(columnPtr->GetNativeData()->GetPropertyID(),&Position) == noErr,wxNOT_FOUND,_("Could not determine column's position")); + return static_cast(Position); } + else + return wxNOT_FOUND; } -void wxDataViewColumn::SetSortOrder(bool ascending) +bool wxMacDataViewDataBrowserListViewControl::InsertColumn(unsigned int pos, wxDataViewColumn* columnPtr) { - wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + DataBrowserListViewColumnDesc columnDescription; + DataBrowserPropertyID newPropertyID; - m_ascending = ascending; - if (dataViewCtrlPtr != NULL) - { - wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); + UInt32 noOfColumns; - if (macDataViewListCtrlPtr != NULL) - { - DataBrowserListViewHeaderDesc headerDescription; + wxCFStringRef title(columnPtr->GetTitle(),m_font.Ok() ? dynamic_cast(this->GetWXPeer())->GetFont().GetEncoding() : wxLocale::GetSystemEncoding()); - verify_noerr(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription)); - if (ascending) - headerDescription.initialOrder = kDataBrowserOrderIncreasing; - else - headerDescription.initialOrder = kDataBrowserOrderDecreasing; - verify_noerr(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription)); - macDataViewListCtrlPtr->SetSortProperty(this->GetPropertyID()); - } + + // try to get new ID for the column: + wxCHECK_MSG(this->GetFreePropertyID(&newPropertyID) == noErr,false,_("Cannot create new column's ID. Probably max. number of columns reached.")); + // set native data: + columnPtr->GetNativeData()->SetPropertyID(newPropertyID); + // create a column description, add column to the native control and do some final layout adjustments: + wxCHECK_MSG(::InitializeColumnDescription(columnDescription,columnPtr,title), false,_("Column description could not be initialized.")); + wxCHECK_MSG(this->AddColumn(&columnDescription,pos) == noErr, false,_("Column could not be added.")); + wxCHECK_MSG(this->SetColumnWidth(newPropertyID,columnPtr->GetWidth()) == noErr,false,_("Column width could not be set.")); + wxCHECK_MSG(this->GetColumnCount(&noOfColumns) == noErr, false,_("Number of columns could not be determined.")); + if (noOfColumns == 1) + { + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetWXPeer())); + + wxCHECK_MSG(dataViewCtrlPtr != NULL,false,_("wxWidget's control not initialized.")); + dataViewCtrlPtr->AddChildren(wxDataViewItem()); + return true; } + else + return this->Update(columnPtr); } -void wxDataViewColumn::SetTitle(wxString const& title) +// +// item related methods (inherited from wxDataViewWidgetImpl) +// +bool wxMacDataViewDataBrowserListViewControl::Add(wxDataViewItem const& parent, wxDataViewItem const& item) { - wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); - - - m_title = title; - if (dataViewCtrlPtr != NULL) - { - wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); + DataBrowserItemID itemID(reinterpret_cast(item.GetID())); - if (macDataViewListCtrlPtr != NULL) - { - DataBrowserListViewHeaderDesc headerDescription; - wxCFStringRef cfTitle(title,(dataViewCtrlPtr->GetFont().Ok() ? dataViewCtrlPtr->GetFont().GetEncoding() : wxLocale::GetSystemEncoding())); - wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description.")); - headerDescription.titleString = cfTitle; - wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetPropertyID(),&headerDescription) == noErr,_("Could not set header description.")); - } - } + return (( parent.IsOk() && this->AddItem(reinterpret_cast(parent.GetID()),&itemID) == noErr) || + (!(parent.IsOk()) && this->AddItem(kDataBrowserNoItem,&itemID) == noErr)); } -void wxDataViewColumn::SetWidth(int width) +bool wxMacDataViewDataBrowserListViewControl::Add(wxDataViewItem const& parent, wxDataViewItemArray const& items) { - wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + bool noFailureFlag; + DataBrowserItemID* itemIDs; - if ((width >= m_minWidth) && (width <= m_maxWidth)) - { - m_width = width; - if (dataViewCtrlPtr != NULL) - { - wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); + size_t noOfEntries; - if (macDataViewListCtrlPtr != NULL) - wxCHECK_RET(macDataViewListCtrlPtr->SetColumnWidth(this->GetPropertyID(),static_cast(width)) == noErr,_("Could not set column width.")); - } - } -} -void wxDataViewColumn::SetAsSortKey(bool WXUNUSED(sort)) -{ - // see wxGTK native wxDataViewColumn implementation - wxFAIL_MSG( "not implemented" ); + // convert all valid data view items to data browser items: + itemIDs = ::CreateDataBrowserItemIDArray(noOfEntries,items); + // insert all valid items into control: + noFailureFlag = ((noOfEntries == 0) || + !(parent.IsOk()) && (this->AddItems(kDataBrowserNoItem,noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr) || + parent.IsOk() && (this->AddItems(reinterpret_cast(parent.GetID()),noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr)); + // give allocated array space free again: + delete[] itemIDs; + // done: + return noFailureFlag; } -bool wxDataViewColumn::IsSortKey() const +void wxMacDataViewDataBrowserListViewControl::Collapse(wxDataViewItem const& item) { - wxDataViewCtrl * const dataViewCtrlPtr(GetOwner()); - wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr( - dynamic_cast( - dataViewCtrlPtr->GetPeer())); - - DataBrowserPropertyID propertyID; - return macDataViewListCtrlPtr->GetSortProperty(&propertyID) == noErr && - propertyID == m_propertyID; + this->CloseContainer(reinterpret_cast(item.GetID())); } -//----------------------------------------------------------------------------- -// wxDataViewCtrl -//----------------------------------------------------------------------------- +void wxMacDataViewDataBrowserListViewControl::EnsureVisible(wxDataViewItem const& item, const wxDataViewColumn* columnPtr) +{ + DataBrowserPropertyID propertyID; -wxDataViewCtrl::~wxDataViewCtrl() -{ - ClearColumns(); + if (columnPtr != NULL) + propertyID = columnPtr->GetNativeData()->GetPropertyID(); + else + propertyID = kDataBrowserNoItem; + this->RevealItem(reinterpret_cast(item.GetID()),propertyID,kDataBrowserRevealOnly); } -void wxDataViewCtrl::Init() +void wxMacDataViewDataBrowserListViewControl::Expand(wxDataViewItem const& item) { - m_CustomRendererPtr = NULL; - m_Deleting = false; - m_macIsUserPane = false; - m_cgContext = NULL; + this->OpenContainer(reinterpret_cast(item.GetID())); } -bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator ) +unsigned int wxMacDataViewDataBrowserListViewControl::GetCount(void) const { - if (!(this->wxControl::Create(parent,id,pos,size,style & ~(wxHSCROLL | wxVSCROLL),validator))) - return false; - -#ifdef __WXMAC__ - MacSetClipChildren(true) ; -#endif + ItemCount noOfItems; - m_peer = new wxMacDataViewDataBrowserListViewControl(this,pos,size,style); - if ( style & wxBORDER_NONE ) - m_peer->SetData( kControlNoPart, kControlDataBrowserIncludesFrameAndFocusTag, (Boolean) false ) ; + wxCHECK_MSG(this->GetItemCount(&noOfItems) == noErr,0,_("Could not determine number of items")); + return noOfItems; +} - this->MacPostControlCreate(pos,size); - ::SetAutomaticControlDragTrackingEnabledForWindow(::GetControlOwner(m_peer->GetControlRef()),true); +wxRect wxMacDataViewDataBrowserListViewControl::GetRectangle(wxDataViewItem const& item, wxDataViewColumn const* columnPtr) +{ + Rect MacRectangle; - InstallControlEventHandler(m_peer->GetControlRef(),GetwxMacDataViewCtrlEventHandlerUPP(),GetEventTypeCount(eventList),eventList,this,NULL); - ::SetDataBrowserTableViewHiliteStyle( m_peer->GetControlRef(), kDataBrowserTableViewFillHilite ); + if (this->GetPartBounds(reinterpret_cast(item.GetID()),columnPtr->GetNativeData()->GetPropertyID(),kDataBrowserPropertyContentPart,&MacRectangle) == noErr) + { + wxRect rectangle; - return true; + ::wxMacNativeToRect(&MacRectangle,&rectangle); + return rectangle; + } + else + return wxRect(); } -wxSize wxDataViewCtrl::DoGetBestSize() const +bool wxMacDataViewDataBrowserListViewControl::IsExpanded(wxDataViewItem const& item) const { - wxSize best = wxControl::DoGetBestSize(); - best.y = 80; - - return best; + DataBrowserItemState state = 0; + + if (this->GetItemState(reinterpret_cast(item.GetID()),&state) != noErr) + return false; + + return ((state & kDataBrowserContainerIsOpen) != 0); } -/*static*/ -wxVisualAttributes wxDataViewCtrl::GetClassDefaultAttributes(wxWindowVariant variant) +bool wxMacDataViewDataBrowserListViewControl::Reload(void) { - wxVisualAttributes attr; + bool noFailureFlag; + + wxDataViewItemArray dataViewChildren; - attr.colFg = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ); - attr.colBg = wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX ); - //attr.font.CreateSystemFont(wxOSX_SYSTEM_FONT_VIEWS); - return attr; + noFailureFlag = (this->RemoveItems() == noErr); + this->SetScrollPosition(0,0); // even after having removed all items the scrollbars may remain at their old position -> reset them + this->GetDataViewCtrl()->GetModel()->GetChildren(wxDataViewItem(),dataViewChildren); + this->GetDataViewCtrl()->GetModel()->ItemsAdded(wxDataViewItem(),dataViewChildren); + + return noFailureFlag; } -bool wxDataViewCtrl::AssociateModel(wxDataViewModel* model) +bool wxMacDataViewDataBrowserListViewControl::Remove(wxDataViewItem const& parent, wxDataViewItem const& item) { - if (!wxDataViewCtrlBase::AssociateModel(model)) - return false; + DataBrowserItemID itemID(reinterpret_cast(item.GetID())); - model->AddNotifier(new wxMacDataViewModelNotifier(dynamic_cast(m_peer))); - return true; + return (this->RemoveItem(reinterpret_cast(parent.GetID()),&itemID) == noErr); } -bool wxDataViewCtrl::AppendColumn(wxDataViewColumn* columnPtr) +bool wxMacDataViewDataBrowserListViewControl::Remove(wxDataViewItem const& parent, wxDataViewItemArray const& items) { - return wxDataViewCtrl::InsertColumn( GetColumnCount(), columnPtr ); + bool noFailureFlag; + + DataBrowserItemID* itemIDs; + + size_t noOfEntries; + + + // convert all valid data view items to data browser items: + itemIDs = ::CreateDataBrowserItemIDArray(noOfEntries,items); + // insert all valid items into control: + noFailureFlag = ((noOfEntries == 0) || + !(parent.IsOk()) && (this->RemoveItems(kDataBrowserNoItem,noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr) || + parent.IsOk() && (this->RemoveItems(reinterpret_cast(parent.GetID()),noOfEntries,itemIDs,kDataBrowserItemNoProperty) == noErr)); + // give allocated array space free again: + delete[] itemIDs; + // done: + return noFailureFlag; } -bool wxDataViewCtrl::PrependColumn(wxDataViewColumn* columnPtr) +bool wxMacDataViewDataBrowserListViewControl::Update(wxDataViewColumn const* columnPtr) { - return wxDataViewCtrl::InsertColumn( 0, columnPtr ); + return (this->UpdateItems(kDataBrowserNoItem,0,NULL,kDataBrowserItemNoProperty,columnPtr->GetNativeData()->GetPropertyID()) == noErr); } -bool wxDataViewCtrl::InsertColumn(unsigned int pos, wxDataViewColumn* columnPtr) +bool wxMacDataViewDataBrowserListViewControl::Update(wxDataViewItem const& parent, wxDataViewItem const& item) { - DataBrowserListViewColumnDesc columnDescription; + DataBrowserItemID itemID(reinterpret_cast(item.GetID())); - DataBrowserPropertyID NewPropertyID; - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); + if (parent.IsOk()) + return (this->UpdateItem(reinterpret_cast(parent.GetID()),&itemID) == noErr); + else + return (this->UpdateItem(kDataBrowserNoItem,&itemID) == noErr); +} - wxCFStringRef title(columnPtr->GetTitle(),m_font.Ok() ? this->GetFont().GetEncoding() : wxLocale::GetSystemEncoding()); +bool wxMacDataViewDataBrowserListViewControl::Update(wxDataViewItem const& parent, wxDataViewItemArray const& items) +{ + bool noFailureFlag; + DataBrowserItemID* itemIDs; - // first, some error checking: - wxCHECK_MSG(MacDataViewListCtrlPtr != NULL, false,_("m_peer is not or incorrectly initialized")); - wxCHECK_MSG(columnPtr != NULL, false,_("Column pointer must not be NULL.")); - wxCHECK_MSG(columnPtr->GetRenderer() != NULL, false,_("Column does not have a renderer.")); - wxCHECK_MSG(this->GetModel() != NULL, false,_("No model associated with control.")); - wxCHECK_MSG((columnPtr->GetModelColumn() >= 0) && - (columnPtr->GetModelColumn() < this->GetModel()->GetColumnCount()),false,_("Column's model column has no equivalent in the associated model.")); + size_t noOfEntries; - // try to get new ID for the column: - wxCHECK_MSG(MacDataViewListCtrlPtr->GetFreePropertyID(&NewPropertyID) == noErr,false,_("Cannot create new column's ID. Probably max. number of columns reached.")); - // full column variable initialization: - columnPtr->SetPropertyID(NewPropertyID); - // add column to wxWidget's internal structure: - wxCHECK_MSG(this->wxDataViewCtrlBase::InsertColumn(pos,columnPtr) && - m_ColumnPointers.insert(ColumnPointerHashMapType::value_type(NewPropertyID,columnPtr)).second,false,_("Could not add column to internal structures.")); - // create a column description and add column to the native control: - wxCHECK_MSG(::InitializeColumnDescription(columnDescription,columnPtr,NewPropertyID,title), false,_("Column description could not be initialized.")); - wxCHECK_MSG(MacDataViewListCtrlPtr->AddColumn(&columnDescription,pos) == noErr,false,_("Column could not be added.")); - - // final adjustments for the layout: - wxCHECK_MSG(MacDataViewListCtrlPtr->SetColumnWidth(NewPropertyID,columnPtr->GetWidth()) == noErr,false,_("Column width could not be set.")); - - // make sure that the data is up-to-date... - // if the newly appended column is the first column add the initial data to the control and mark the column as an expander column, - // otherwise ask the control to 'update' the data in the newly appended column: - if (this->GetColumnCount() == 1) - { - this->SetExpanderColumn(columnPtr); - this->AddChildrenLevel(wxDataViewItem()); - } + + // convert all valid data view items to data browser items: + itemIDs = ::CreateDataBrowserItemIDArray(noOfEntries,items); + if (parent.IsOk()) + noFailureFlag = (this->UpdateItems(reinterpret_cast(parent.GetID()),noOfEntries,itemIDs,kDataBrowserItemNoProperty,kDataBrowserItemNoProperty) == noErr); else - MacDataViewListCtrlPtr->UpdateItems(kDataBrowserNoItem,0,NULL,kDataBrowserItemNoProperty,NewPropertyID); + noFailureFlag = (this->UpdateItems(kDataBrowserNoItem,noOfEntries,itemIDs,kDataBrowserItemNoProperty,kDataBrowserItemNoProperty) == noErr); + // release allocated array space: + delete[] itemIDs; // done: + return noFailureFlag; +} + +// +// model related methods +// +bool wxMacDataViewDataBrowserListViewControl::AssociateModel(wxDataViewModel* WXUNUSED(model)) +{ return true; } -bool wxDataViewCtrl::ClearColumns() +// +// selection related methods (inherited from wxDataViewWidgetImpl) +// +int wxMacDataViewDataBrowserListViewControl::GetSelections(wxDataViewItemArray& sel) const { - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); + size_t noOfSelectedItems; + wxArrayDataBrowserItemID itemIDs; - while (m_ColumnPointers.begin() != m_ColumnPointers.end()) - { - wxCHECK_MSG(MacDataViewListCtrlPtr->RemoveColumnByProperty(m_ColumnPointers.begin()->first) == noErr,false,_("Could not remove column.")); - delete m_ColumnPointers.begin()->second; - m_ColumnPointers.erase(m_ColumnPointers.begin()); - } - return true; + + noOfSelectedItems = this->GetSelectedItemIDs(itemIDs); + sel.Empty(); + sel.SetCount(noOfSelectedItems); + for (size_t i=0; i(itemIDs[i])); + return static_cast(noOfSelectedItems); } -bool wxDataViewCtrl::DeleteColumn(wxDataViewColumn* columnPtr) +bool wxMacDataViewDataBrowserListViewControl::IsSelected(wxDataViewItem const& item) const { - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); + return this->IsItemSelected(reinterpret_cast(item.GetID())); +} +void wxMacDataViewDataBrowserListViewControl::Select(wxDataViewItem const& item) +{ + DataBrowserItemID itemID(reinterpret_cast(item.GetID())); - if ((MacDataViewListCtrlPtr->RemoveColumnByProperty(columnPtr->GetPropertyID()) == noErr) && (m_ColumnPointers.erase(columnPtr->GetPropertyID()) > 0)) - { - delete columnPtr; - return true; - } - else - return false; + + this->SetSelectedItems(1,&itemID,kDataBrowserItemsAdd); } -wxDataViewColumn* wxDataViewCtrl::GetColumn(unsigned int pos) const +void wxMacDataViewDataBrowserListViewControl::SelectAll(void) { - DataBrowserPropertyID propertyID; + DataBrowserItemID* itemIDPtr; - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); + Handle handle(::NewHandle(0)); + size_t noOfItems; - if (MacDataViewListCtrlPtr->GetPropertyID(pos,&propertyID) == noErr) - { - ColumnPointerHashMapType::const_iterator Result(m_ColumnPointers.find(propertyID)); - if (Result != m_ColumnPointers.end()) - return Result->second; - else - return NULL; - } - else - return NULL; + wxCHECK_RET(this->GetItems(kDataBrowserNoItem,true,kDataBrowserItemAnyState,handle) == noErr,_("Could not get items.")); + noOfItems = static_cast(::GetHandleSize(handle)/sizeof(DataBrowserItemID)); + ::HLock(handle); + itemIDPtr = (DataBrowserItemID*) (*handle); + this->SetSelectedItems(noOfItems,itemIDPtr,kDataBrowserItemsAssign); + ::HUnlock(handle); + ::DisposeHandle(handle); } -unsigned int wxDataViewCtrl::GetColumnCount() const +void wxMacDataViewDataBrowserListViewControl::Unselect(wxDataViewItem const& item) { - return m_ColumnPointers.size(); -} + DataBrowserItemID itemID(reinterpret_cast(item.GetID())); -int wxDataViewCtrl::GetColumnPosition(wxDataViewColumn const* columnPtr) const -{ - if (columnPtr != NULL) - { - DataBrowserTableViewColumnIndex Position; - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); - wxCHECK_MSG(MacDataViewListCtrlPtr->GetColumnIndex(columnPtr->GetPropertyID(),&Position) == noErr,-1,_("Could not determine column's position")); - return static_cast(Position); - } - else - return wxNOT_FOUND; + this->SetSelectedItems(1,&itemID,kDataBrowserItemsRemove); } -void wxDataViewCtrl::Collapse(wxDataViewItem const& item) +void wxMacDataViewDataBrowserListViewControl::UnselectAll(void) { - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); + DataBrowserItemID* itemIDPtr; + + Handle handle(::NewHandle(0)); + size_t noOfItems; - MacDataViewListCtrlPtr->CloseContainer(reinterpret_cast(item.GetID())); + + wxCHECK_RET(this->GetItems(kDataBrowserNoItem,true,kDataBrowserItemAnyState,handle) == noErr,_("Could not get items.")); + noOfItems = static_cast(::GetHandleSize(handle)/sizeof(DataBrowserItemID)); + ::HLock(handle); + itemIDPtr = (DataBrowserItemID*) (*handle); + this->SetSelectedItems(noOfItems,itemIDPtr,kDataBrowserItemsRemove); + ::HUnlock(handle); + ::DisposeHandle(handle); } -void wxDataViewCtrl::EnsureVisible(wxDataViewItem const& item, wxDataViewColumn const* columnPtr) +// +// sorting related methods +// +wxDataViewColumn* wxMacDataViewDataBrowserListViewControl::GetSortingColumn(void) const { - ExpandAncestors(item); + DataBrowserPropertyID propertyID; - if (item.IsOk()) - { - DataBrowserPropertyID propertyID; - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); - if (columnPtr != NULL) - propertyID = columnPtr->GetPropertyID(); - else - propertyID = kDataBrowserNoItem; - MacDataViewListCtrlPtr->RevealItem(reinterpret_cast(item.GetID()),propertyID,kDataBrowserRevealOnly); - } + if (this->GetSortProperty(&propertyID) == noErr) + return this->GetColumnPtr(propertyID); + else + return NULL; } -void wxDataViewCtrl::Expand(wxDataViewItem const& item) +void wxMacDataViewDataBrowserListViewControl::Resort(void) { - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); - + (void) this->Resort(); +} - MacDataViewListCtrlPtr->OpenContainer(reinterpret_cast(item.GetID())); +// +// other methods (inherited from wxDataViewWidgetImpl) +// +void +wxMacDataViewDataBrowserListViewControl::HitTest(const wxPoint& WXUNUSED(point), + wxDataViewItem& item, + wxDataViewColumn*& columnPtr) const +{ + // not yet implemented: + item = wxDataViewItem(); + columnPtr = NULL; } -bool wxDataViewCtrl::IsExpanded( const wxDataViewItem & item ) const +void wxMacDataViewDataBrowserListViewControl::DoSetIndent(int indent) { - if (item.IsOk()) - { - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); - - DataBrowserItemState state = 0; - OSStatus err = ::GetDataBrowserItemState( - MacDataViewListCtrlPtr->GetControlRef(), - reinterpret_cast(item.GetID()), - &state ); - if ((err == 0) && (state & kDataBrowserContainerIsOpen)) - return true; - } - return false; + this->SetIndent(static_cast(indent)); } -wxDataViewColumn* wxDataViewCtrl::GetSortingColumn() const +void wxMacDataViewDataBrowserListViewControl::SetRowHeight(wxDataViewItem const& item, unsigned int height) { - DataBrowserPropertyID propertyID; + this->SetItemRowHeight(reinterpret_cast(item.GetID()),static_cast(height)); +} - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); +void wxMacDataViewDataBrowserListViewControl::OnSize(void) +{ + UInt32 noOfColumns; - if (MacDataViewListCtrlPtr->GetSortProperty(&propertyID) == noErr) - return this->GetColumnPtr(propertyID); - else - return NULL; + this->GetColumnCount(&noOfColumns); + if (noOfColumns <= 1) // no horizontal scroll bar and the only column expands to the width of the whole control + { + this->SetHasScrollBars(false,true); + this->AutoSizeColumns(); + } + else // otherwise keep the current column size and have scrollbars in both directions + this->SetHasScrollBars(true,true); } -unsigned int wxDataViewCtrl::GetCount() const +// +// callback functions (inherited from wxMacDataBrowserTableViewControl) +// +Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID itemOneID, DataBrowserItemID itemTwoID, DataBrowserPropertyID sortProperty) { - ItemCount noOfItems; + DataBrowserSortOrder sortOrder; + DataBrowserTableViewColumnIndex modelColumnIndex; - wxCHECK_MSG(dynamic_cast(m_peer)->GetItemCount(&noOfItems) == noErr,0,_("Could not determine number of items")); - return noOfItems; -} + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetWXPeer())); -wxRect wxDataViewCtrl::GetItemRect(wxDataViewItem const& item, wxDataViewColumn const* columnPtr) const -{ - if (item.IsOk() && (columnPtr != NULL)) - { - Rect MacRectangle; - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); - if (MacDataViewListCtrlPtr->GetPartBounds(reinterpret_cast(item.GetID()),columnPtr->GetPropertyID(),kDataBrowserPropertyContentPart,&MacRectangle) == noErr) - { - wxRect rectangle; + wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly.")); + wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly.")); + if (sortProperty >= kMinPropertyID) + { + // variable definition and initialization: + wxDataViewColumn* ColumnPtr(this->GetColumnPtr(sortProperty)); - ::wxMacNativeToRect(&MacRectangle,&rectangle); - return rectangle; - } - else - return wxRect(); + wxCHECK_MSG(ColumnPtr != NULL,false,_("Could not determine column index.")); + modelColumnIndex = ColumnPtr->GetModelColumn(); } else - return wxRect(); -} + modelColumnIndex = 0; + this->GetSortOrder(&sortOrder); + return static_cast(dataViewCtrlPtr->GetModel()->Compare(wxDataViewItem(reinterpret_cast(itemOneID)),wxDataViewItem(reinterpret_cast(itemTwoID)), + modelColumnIndex,sortOrder != kDataBrowserOrderDecreasing) < 0); +} /* wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID) */ -wxDataViewItem wxDataViewCtrl::GetSelection() const +void wxMacDataViewDataBrowserListViewControl::DataBrowserGetContextualMenuProc(MenuRef* menu, UInt32* helpType, CFStringRef* helpItemString, AEDesc* WXUNUSED(selection)) + // In this method we do not supply a contextual menu handler at all but only send a wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU. { wxArrayDataBrowserItemID itemIDs; - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetWXPeer())); - if (MacDataViewListCtrlPtr->GetSelectedItemIDs(itemIDs) > 0) - return wxDataViewItem(reinterpret_cast(itemIDs[0])); - else - return wxDataViewItem(); -} + wxCHECK_RET(dataViewCtrlPtr != NULL,_("wxWidget control pointer is not a data view pointer")); + // initialize parameters so that no context menu will be displayed automatically by the native data browser: + *menu = NULL; + *helpType = kCMHelpItemNoHelp; + *helpItemString = NULL; + // create information for a context menu event: + wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU,dataViewCtrlPtr->GetId()); + + dataViewEvent.SetEventObject(dataViewCtrlPtr); + dataViewEvent.SetModel(dataViewCtrlPtr->GetModel()); + // get the item information; + // 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: + if (this->GetSelectedItemIDs(itemIDs) > 0) + dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast(itemIDs[0]))); + // finally send the equivalent wxWidget event: + dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); +} /* wxMacDataViewDataBrowserListViewControl::DataBrowserGetContextualMenuProc(MenuRef*, UInt32*, CFStringRef*, AEDesc*) */ -int wxDataViewCtrl::GetSelections(wxDataViewItemArray& sel) const +OSStatus wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemDataRef itemData, Boolean getValue) { - size_t NoOfSelectedItems; + if (getValue) + { + // variable definitions: + wxDataViewCtrl* dataViewCtrlPtr; - wxArrayDataBrowserItemID itemIDs; + dataViewCtrlPtr = dynamic_cast(this->GetWXPeer()); + wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly.")); + if (dataViewCtrlPtr->IsDeleting()) + 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 + else + { + // variable definitions: + OSStatus errorStatus; + wxDataViewColumn* dataViewColumnPtr; - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); + wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,errDataBrowserNotConfigured,_("Pointer to model not set correctly.")); + dataViewColumnPtr = this->GetColumnPtr(propertyID); + wxCHECK_MSG((dataViewColumnPtr != NULL) && (dataViewColumnPtr->GetRenderer() != NULL),errDataBrowserNotConfigured,_("There is no column or renderer for the specified column index.")); + wxDataViewItem dvItem(reinterpret_cast(itemID)); + unsigned int col = dataViewColumnPtr->GetModelColumn(); - NoOfSelectedItems = MacDataViewListCtrlPtr->GetSelectedItemIDs(itemIDs); - sel.Empty(); - sel.SetCount(NoOfSelectedItems); - for (size_t i=0; i(itemIDs[i])); - return static_cast(NoOfSelectedItems); -} + switch (dataViewColumnPtr->GetRenderer()->GetNativeData()->GetPropertyType()) + { + case kDataBrowserCheckboxType: + { + // variable definition: + ThemeButtonValue buttonValue; -void wxDataViewCtrl::HitTest(wxPoint const& point, wxDataViewItem& item, wxDataViewColumn*& columnPtr) const -{ - item = wxDataViewItem(); - columnPtr = NULL; -} + errorStatus = ::GetDataBrowserItemDataButtonValue(itemData,&buttonValue); + if (errorStatus == noErr) + { + if (buttonValue == kThemeButtonOn) + { + // variable definition and initialization: + wxVariant modifiedData(true); + + if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData, dvItem, col) && + dataViewCtrlPtr->GetModel()->ValueChanged(dvItem, col)) + return noErr; + else + return errDataBrowserInvalidPropertyData; + } + else if (buttonValue == kThemeButtonOff) + { + // variable definition and initialization: + wxVariant modifiedData(false); + + if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData, dvItem, col) && + dataViewCtrlPtr->GetModel()->ValueChanged(dvItem, col)) + return noErr; + else + return errDataBrowserInvalidPropertyData; + } + else + return errDataBrowserInvalidPropertyData; + } + else + return errorStatus; + } /* block */ + case kDataBrowserTextType: + { + // variable definitions: + CFStringRef stringReference; + + errorStatus = ::GetDataBrowserItemDataText(itemData,&stringReference); + if (errorStatus == noErr) + { + // variable definitions and initializations: +#if wxCHECK_VERSION(2,9,0) + wxCFStringRef modifiedString(stringReference); +#else + wxMacCFStringHolder modifiedString(stringReference); +#endif + wxVariant modifiedData(modifiedString.AsString()); + + if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData, dvItem, col) && + dataViewCtrlPtr->GetModel()->ValueChanged(dvItem, col)) + return noErr; + else + return errDataBrowserInvalidPropertyData; + } + else + return errorStatus; + } /* block */ + default: + return errDataBrowserPropertyNotSupported; + } + } + } + else + { + if (propertyID >= kMinPropertyID) // in case data columns set the data + { + // variable definitions: + wxVariant variant; + wxDataViewColumn* dataViewColumnPtr; + wxDataViewCtrl* dataViewCtrlPtr; + + dataViewCtrlPtr = dynamic_cast(this->GetWXPeer()); + wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly.")); + wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,errDataBrowserNotConfigured,_("Pointer to model not set correctly.")); + dataViewColumnPtr = this->GetColumnPtr(propertyID); + wxCHECK_MSG(dataViewColumnPtr != NULL,errDataBrowserNotConfigured,_("No column for the specified column position existing.")); + wxCHECK_MSG(dataViewColumnPtr->GetRenderer() != NULL,errDataBrowserNotConfigured,_("No renderer specified for column.")); + dataViewCtrlPtr->GetModel()->GetValue(variant,wxDataViewItem(reinterpret_cast(itemID)),dataViewColumnPtr->GetModelColumn()); + if (!(variant.IsNull())) + { + dataViewColumnPtr->GetRenderer()->GetNativeData()->SetItemDataRef(itemData); + dataViewColumnPtr->GetRenderer()->SetValue(variant); + wxCHECK_MSG(dataViewColumnPtr->GetRenderer()->MacRender(),errDataBrowserNotConfigured,_("Rendering failed.")); + } + return noErr; + } + else // react on special system requests + { + switch (propertyID) + { + case kDataBrowserContainerIsClosableProperty: + { + // variable definitions: + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetWXPeer())); + + wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly.")); + // initialize wxWidget event: + wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING,dataViewCtrlPtr->GetId()); // variable definition + + dataViewEvent.SetEventObject(dataViewCtrlPtr); + dataViewEvent.SetItem (wxDataViewItem(reinterpret_cast(itemID))); + dataViewEvent.SetModel (dataViewCtrlPtr->GetModel()); + // finally send the equivalent wxWidget event: + dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); + // opening the container is allowed if not vetoed: + return ::SetDataBrowserItemDataBooleanValue(itemData,dataViewEvent.IsAllowed()); + } /* block */ + case kDataBrowserContainerIsOpenableProperty: + { + // variable definitions: + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetWXPeer())); + + wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly.")); + // initialize wxWidget event: + wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING,dataViewCtrlPtr->GetId()); // variable definition + + dataViewEvent.SetEventObject(dataViewCtrlPtr); + dataViewEvent.SetItem (wxDataViewItem(reinterpret_cast(itemID))); + dataViewEvent.SetModel (dataViewCtrlPtr->GetModel()); + // finally send the equivalent wxWidget event: + dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); + // opening the container is allowed if not vetoed: + return ::SetDataBrowserItemDataBooleanValue(itemData,dataViewEvent.IsAllowed()); + } /* block */ + case kDataBrowserItemIsContainerProperty: + { + // variable definition: + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetWXPeer())); + + wxCHECK_MSG(dataViewCtrlPtr != NULL,errDataBrowserNotConfigured,_("Pointer to data view control not set correctly.")); + wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,errDataBrowserNotConfigured,_("Pointer to model not set correctly.")); + return ::SetDataBrowserItemDataBooleanValue(itemData,dataViewCtrlPtr->GetModel()->IsContainer(wxDataViewItem(reinterpret_cast(itemID)))); + } /* block */ + case kDataBrowserItemIsEditableProperty: + return ::SetDataBrowserItemDataBooleanValue(itemData,true); + } + } + } + return errDataBrowserPropertyNotSupported; +} /* wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc(DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemDataRef, Boolean) */ -bool wxDataViewCtrl::IsSelected(wxDataViewItem const& item) const +void wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID itemID, DataBrowserItemNotification message, DataBrowserItemDataRef itemData) { - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetWXPeer())); - return MacDataViewListCtrlPtr->IsItemSelected(reinterpret_cast(item.GetID())); -} + // 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: + if (dataViewCtrlPtr != NULL) + switch (message) + { + case kDataBrowserContainerClosed: + dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary) + { + // initialize wxWidget event: + wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED,dataViewCtrlPtr->GetId()); // variable definition + + dataViewEvent.SetEventObject(dataViewCtrlPtr); + dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast(itemID))); + // finally send the equivalent wxWidget event: + dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); + } /* block */ + break; + case kDataBrowserContainerOpened: + dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary) + { + // initialize wxWidget event: + wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED,dataViewCtrlPtr->GetId()); // variable definition + + dataViewEvent.SetEventObject(dataViewCtrlPtr); + dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast(itemID))); + // finally send the equivalent wxWidget event: + dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); + // add children to the expanded container: + dataViewCtrlPtr->AddChildren(wxDataViewItem(reinterpret_cast(itemID))); + } /* block */ + break; + case kDataBrowserEditStarted: + dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary) + { + // initialize wxWidget event: + DataBrowserPropertyID propertyID; + wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED,dataViewCtrlPtr->GetId()); // variable definition + + dataViewEvent.SetEventObject(dataViewCtrlPtr); + dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast(itemID))); + if (this->GetPropertyID(itemData,&propertyID) == noErr) + { + // variable definition and initialization: + DataBrowserTableViewColumnIndex columnIndex; + + wxCHECK_RET(this->GetColumnIndex(propertyID,&columnIndex),_("Column index not found.")); + dataViewEvent.SetColumn(columnIndex); + dataViewEvent.SetDataViewColumn(this->GetColumnPtr(propertyID)); + } + // finally send the equivalent wxWidget event: + dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); + } /* block */ + break; + case kDataBrowserEditStopped: + { + // initialize wxWidget event: + DataBrowserPropertyID propertyID; + wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_DONE,dataViewCtrlPtr->GetId()); // variable definition + + dataViewEvent.SetEventObject(dataViewCtrlPtr); + dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast(itemID))); + if (this->GetPropertyID(itemData,&propertyID) == noErr) + { + // variable definition and initialization: + DataBrowserTableViewColumnIndex columnIndex; + + wxCHECK_RET(this->GetColumnIndex(propertyID,&columnIndex),_("Column index not found.")); + dataViewEvent.SetColumn(columnIndex); + dataViewEvent.SetDataViewColumn(this->GetColumnPtr(propertyID)); + } + // finally send the equivalent wxWidget event: + dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); + } /* block */ + break; + case kDataBrowserItemAdded: + dataViewCtrlPtr->FinishCustomItemEditing(); + break; + case kDataBrowserItemDeselected: + dataViewCtrlPtr->FinishCustomItemEditing(); + break; + case kDataBrowserItemDoubleClicked: + { + // initialize wxWidget event: + wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED,dataViewCtrlPtr->GetId()); // variable definition + + dataViewEvent.SetEventObject(dataViewCtrlPtr); + dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast(itemID))); + // finally send the equivalent wxWidget event: + dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); + } /* block */ + break; + case kDataBrowserItemRemoved: + dataViewCtrlPtr->FinishCustomItemEditing(); // stop editing of a custom item first (if necessary) + break; + case kDataBrowserItemSelected: + break; // not implemented by wxWidgets; see kDataBrowserSelectionSetChanged + case kDataBrowserSelectionSetChanged: + { + // initialize wxWidget event: + wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED,dataViewCtrlPtr->GetId()); // variable definition + + dataViewEvent.SetEventObject(dataViewCtrlPtr); + dataViewEvent.SetModel (dataViewCtrlPtr->GetModel()); + // finally send the equivalent wxWidget event: + dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); + } /* block */ + break; + case kDataBrowserTargetChanged: // no idea if this notification is ever sent + break; + case kDataBrowserUserStateChanged: + { + // finish custom item editing if necessary: + dataViewCtrlPtr->FinishCustomItemEditing(); + // update column widths: + for (size_t i=0; iGetColumnCount(); ++i) + { + // constant definition for abbreviational purposes: + wxDataViewColumn* const columnPtr = dataViewCtrlPtr->GetColumnPtr(i); + // variable definition: + UInt16 columnWidth; + + wxCHECK_RET(this->GetColumnWidth(columnPtr->GetNativeData()->GetPropertyID(),&columnWidth) == noErr,_("Column width could not be determined")); + columnPtr->SetWidthVariable(columnWidth); + } + // update sorting orders: + DataBrowserPropertyID propertyID; // variable definition + + if ((this->GetSortProperty(&propertyID) == noErr) && (propertyID >= kMinPropertyID)) + { + DataBrowserSortOrder sortOrder; + DataBrowserTableViewColumnIndex columnIndex; + + if ((this->GetSortOrder(&sortOrder) == noErr) && (this->GetColumnIndex(propertyID,&columnIndex) == noErr)) + { + // variable definition and initialization: + wxDataViewColumn* columnPtr; + columnPtr = dataViewCtrlPtr->GetColumn(columnIndex); + // check if the sort order has changed: + if ( columnPtr->IsSortOrderAscending() && (sortOrder == kDataBrowserOrderDecreasing) || + !(columnPtr->IsSortOrderAscending()) && (sortOrder == kDataBrowserOrderIncreasing)) + { + columnPtr->SetSortOrder(!(columnPtr->IsSortOrderAscending())); + // initialize wxWidget event: + wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED,dataViewCtrlPtr->GetId()); // variable defintion + + dataViewEvent.SetEventObject(dataViewCtrlPtr); + dataViewEvent.SetColumn(columnIndex); + dataViewEvent.SetDataViewColumn(columnPtr); + // finally send the equivalent wxWidget event: + dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); + } + } + } + } /* block */ + break; + } +} /* wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(DataBrowserItemID, DataBrowserItemNotification, DataBrowserItemDataRef) */ -void wxDataViewCtrl::SelectAll() +void +wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID itemID, + DataBrowserPropertyID propertyID, + DataBrowserItemState state, + Rect const* rectangle, + SInt16 WXUNUSED(bitDepth), + Boolean WXUNUSED(colorDevice)) { - DataBrowserItemID* itemIDPtr; + DataBrowserTableViewColumnIndex columnIndex; - Handle handle(::NewHandle(0)); + wxDataViewColumn* dataViewColumnPtr; - size_t NoOfItems; + wxDataViewCtrl* dataViewCtrlPtr; - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); + wxDataViewCustomRenderer* dataViewCustomRendererPtr; + wxVariant dataToRender; - wxCHECK_RET(MacDataViewListCtrlPtr->GetItems(kDataBrowserNoItem,true,kDataBrowserItemAnyState,handle) == noErr,_("Could not get items.")); - NoOfItems = static_cast(::GetHandleSize(handle)/sizeof(DataBrowserItemID)); - HLock(handle); - itemIDPtr = (DataBrowserItemID*) (*handle); - MacDataViewListCtrlPtr->SetSelectedItems(NoOfItems,itemIDPtr,kDataBrowserItemsAssign); - HUnlock(handle); - DisposeHandle(handle); -} + dataViewCtrlPtr = dynamic_cast(this->GetWXPeer()); + wxCHECK_RET(dataViewCtrlPtr != NULL, _("Pointer to data view control not set correctly.")); + wxCHECK_RET(dataViewCtrlPtr->GetModel() != NULL, _("Pointer to model not set correctly.")); + wxCHECK_RET(this->GetColumnIndex(propertyID,&columnIndex) == noErr,_("Could not determine column index.")); + dataViewColumnPtr = this->GetColumnPtr(propertyID); + wxCHECK_RET(dataViewColumnPtr != NULL,_("No column for the specified column existing.")); + dataViewCustomRendererPtr = dynamic_cast(dataViewColumnPtr->GetRenderer()); + wxCHECK_RET(dataViewCustomRendererPtr != NULL,_("No renderer or invalid renderer type specified for custom data column.")); + dataViewCtrlPtr->GetModel()->GetValue(dataToRender,wxDataViewItem(reinterpret_cast(itemID)),dataViewColumnPtr->GetModelColumn()); + dataViewCustomRendererPtr->SetValue(dataToRender); -void wxDataViewCtrl::Select(wxDataViewItem const& item) -{ - if (item.IsOk()) + wxDataViewItem dataItem( reinterpret_cast(itemID) ); + dataViewCtrlPtr->GetModel()->GetValue(dataToRender,dataItem,dataViewColumnPtr->GetModelColumn()); + dataViewCustomRendererPtr->SetValue(dataToRender); + + // try to determine the content's size (drawable part): + Rect content; + RgnHandle rgn(NewRgn()); + UInt16 headerHeight; + + if (GetControlRegion(m_controlRef,kControlContentMetaPart,rgn) == noErr) + GetRegionBounds(rgn,&content); + else + GetControlBounds(m_controlRef, &content); + ::DisposeRgn(rgn); + // space for the header + this->GetHeaderButtonHeight(&headerHeight); + content.top += headerHeight; + // extra space for the frame (todo: do not how to determine the space automatically from the control) + content.top += 5; + content.left += 5; + content.right -= 3; + content.bottom -= 3; + // extra space for the scrollbars: + content.bottom -= wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y); + content.right -= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X); + + wxDC *dc = dataViewCustomRendererPtr->GetDC(); + + int active_border_fudge = 0; + if (dataViewCtrlPtr->HasFocus() && !dataViewCtrlPtr->HasFlag( wxBORDER_NONE )) + active_border_fudge = 1; + else + active_border_fudge = -2; + + wxRect cellrect( static_cast(rectangle->left + active_border_fudge), + static_cast(rectangle->top + active_border_fudge), + static_cast(1+rectangle->right-rectangle->left), + static_cast(rectangle->bottom-rectangle->top) ); + + bool is_active = IsControlActive( this->m_controlRef ); + if (state == kDataBrowserItemIsSelected) { - ExpandAncestors(item); - - DataBrowserItemID itemID(reinterpret_cast(item.GetID())); - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); + wxColour col( wxMacCreateCGColorFromHITheme( (is_active) ? + kThemeBrushAlternatePrimaryHighlightColor + : kThemeBrushSecondaryHighlightColor ) ); + + wxRect rect = cellrect; + Rect itemrect; + GetDataBrowserItemPartBounds( this->m_controlRef, itemID, propertyID, + kDataBrowserPropertyEnclosingPart, &itemrect ); + rect.x = itemrect.left-2; + rect.width = itemrect.right-itemrect.left+3; + + wxDCPenChanger setPen(*dc, *wxTRANSPARENT_PEN); + wxDCBrushChanger setBrush(*dc, col); + dc->DrawRectangle(rect); + } - MacDataViewListCtrlPtr->SetSelectedItems(1,&itemID,kDataBrowserItemsAdd); + wxDataViewModel *model = dataViewCtrlPtr->GetModel(); + if ((columnIndex == 0) || !model->IsContainer(dataItem) || model->HasContainerColumns(dataItem)) + { + // make sure that 'Render' can draw only in the allowed area: + dc->SetClippingRegion(content.left,content.top,content.right-content.left+1,content.bottom-content.top+1); + (void) (dataViewCustomRendererPtr->Render( cellrect, dc, + ((state == kDataBrowserItemIsSelected) ? wxDATAVIEW_CELL_SELECTED : 0))); + dc->DestroyClippingRegion(); // probably not necessary } -} -void wxDataViewCtrl::SetSelections(wxDataViewItemArray const& sel) + dataViewCustomRendererPtr->SetDC(NULL); +} /* wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID, DataBrowserPropertyID, DataBrowserItemState, Rect const*, SInt16, Boolean) */ + +Boolean +wxMacDataViewDataBrowserListViewControl::DataBrowserEditItemProc( + DataBrowserItemID WXUNUSED(itemID), + DataBrowserPropertyID WXUNUSED(propertyID), + CFStringRef WXUNUSED(theString), + Rect* WXUNUSED(maxEditTextRect), + Boolean* WXUNUSED(shrinkToFit)) { - size_t const NoOfSelections = sel.GetCount(); + return false; +} /* wxMacDataViewDataBrowserListViewControl::DataBrowserEditItemProc(DataBrowserItemID, DataBrowserPropertyID, CFStringRef, Rect*, Boolean*) */ - wxDataViewItem last_parent; +Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserHitTestProc(DataBrowserItemID WXUNUSED(itemID), DataBrowserPropertyID WXUNUSED(property), Rect const* WXUNUSED(theRect), Rect const* WXUNUSED(mouseRect)) +{ + return true; +} /* wxMacDataViewDataBrowserListViewControl::DataBrowserHitTestProc(DataBrowserItemID, DataBrowserPropertyID, Rect const*, Rect const*) */ - size_t i; - for (i = 0; i < NoOfSelections; i++) - { - wxDataViewItem item = sel[i]; - wxDataViewItem parent = GetModel()->GetParent( item ); - if (parent) - { - if (parent != last_parent) - ExpandAncestors(item); - } - last_parent = parent; - } +DataBrowserTrackingResult wxMacDataViewDataBrowserListViewControl::DataBrowserTrackingProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, Rect const* theRect, Point WXUNUSED(startPt), EventModifiers WXUNUSED(modifiers)) +{ + wxDataViewColumn* dataViewColumnPtr; - DataBrowserItemID* itemIDs; - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); + wxDataViewCtrl* dataViewCtrlPtr; - itemIDs = new DataBrowserItemID[NoOfSelections]; - for (i=0; i(sel[i].GetID()); - MacDataViewListCtrlPtr->SetSelectedItems(NoOfSelections,itemIDs,kDataBrowserItemsAssign); - delete[] itemIDs; -} + wxDataViewCustomRenderer* dataViewCustomRendererPtr; -void wxDataViewCtrl::Unselect(wxDataViewItem const& item) -{ - if (item.IsOk()) + wxDataViewItem dataViewCustomRendererItem; + + + dataViewCtrlPtr = dynamic_cast(this->GetWXPeer()); + wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly.")); + wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly.")); + dataViewCustomRendererItem = reinterpret_cast(itemID); + wxCHECK_MSG(dataViewCustomRendererItem.IsOk(),kDataBrowserNothingHit,_("Invalid data view item")); + dataViewColumnPtr = this->GetColumnPtr(propertyID); + wxCHECK_MSG(dataViewColumnPtr != NULL,kDataBrowserNothingHit,_("No column existing.")); + dataViewCustomRendererPtr = dynamic_cast(dataViewColumnPtr->GetRenderer()); + wxCHECK_MSG(dataViewCustomRendererPtr != NULL,kDataBrowserNothingHit,_("No renderer or invalid renderer type specified for custom data column.")); + // 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): + if (dataViewCtrlPtr->GetCustomRendererItem() == dataViewCustomRendererItem) + return kDataBrowserContentHit; + // an(other) item is going to be edited and therefore the current editing - if existing - has to be finished: + if (dataViewCtrlPtr->GetCustomRendererPtr() != NULL) { - DataBrowserItemID itemID(reinterpret_cast(item.GetID())); - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); + dataViewCtrlPtr->GetCustomRendererPtr()->FinishEditing(); + dataViewCtrlPtr->SetCustomRendererItem(wxDataViewItem()); + dataViewCtrlPtr->SetCustomRendererPtr (NULL); + } + // check if renderer has got a valid editor control for editing; if this is the case start editing of the new item: + if (dataViewCustomRendererPtr->HasEditorCtrl()) + { + // variable definition: + wxRect wxRectangle; - MacDataViewListCtrlPtr->SetSelectedItems(1,&itemID,kDataBrowserItemsRemove); + ::wxMacNativeToRect(theRect,&wxRectangle); + dataViewCustomRendererPtr->StartEditing(dataViewCustomRendererItem,wxRectangle); + dataViewCtrlPtr->SetCustomRendererItem(dataViewCustomRendererItem); + dataViewCtrlPtr->SetCustomRendererPtr (dataViewCustomRendererPtr); } -} + return kDataBrowserContentHit; +} /* wxMacDataViewDataBrowserListViewControl::DataBrowserTrackingProc(DataBrowserItemID, DataBrowserPropertyID, Rect const*, Point, EventModifiers) */ -void wxDataViewCtrl::UnselectAll() +Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserAcceptDragProc(DragReference dragRef, DataBrowserItemID itemID) { - DataBrowserItemID* itemIDPtr; + bool acceptDrag; - Handle handle(::NewHandle(0)); + UInt16 noOfDraggedItems; - size_t NoOfItems; + wxDataViewCtrl* dataViewCtrlPtr; - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); + dataViewCtrlPtr = dynamic_cast(this->GetWXPeer()); + wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly.")); + wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly.")); - wxCHECK_RET(MacDataViewListCtrlPtr->GetItems(kDataBrowserNoItem,true,kDataBrowserItemAnyState,handle) == noErr,_("Could not get items.")); - NoOfItems = static_cast(::GetHandleSize(handle)/sizeof(DataBrowserItemID)); - HLock(handle); - itemIDPtr = (DataBrowserItemID*) (*handle); - MacDataViewListCtrlPtr->SetSelectedItems(NoOfItems,itemIDPtr,kDataBrowserItemsRemove); - HUnlock(handle); - DisposeHandle(handle); -} + // send a drag possible event for each available and item und proceed with it unless the event is vetoed: + ::CountDragItems(dragRef,&noOfDraggedItems); + for (UInt16 indexDraggedItem=1; indexDraggedItem<=noOfDraggedItems; ++indexDraggedItem) + { + // collect native information: + ItemReference itemRef; + wxDataObjectComposite* dataObjects; + wxMemoryBuffer buffer; + + ::GetDragItemReferenceNumber(dragRef,indexDraggedItem,&itemRef); // the index begins with 1! + dataObjects = this->GetDnDDataObjects(dragRef,itemRef); + // create wxWidget's event: + wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE,dataViewCtrlPtr->GetId()); + + dataViewEvent.SetEventObject(dataViewCtrlPtr); + dataViewEvent.SetItem(reinterpret_cast(itemID)); // this is the item that receives the event + // (can be an invalid item ID, this is especially useful if the dataview does not contain any items) + dataViewEvent.SetModel(dataViewCtrlPtr->GetModel()); + dataViewEvent.SetDataObject(dataObjects); + dataViewEvent.SetDataFormat(this->GetDnDDataFormat(dataObjects)); + if (dataViewEvent.GetDataFormat().GetType() != wxDF_INVALID) + { + dataViewEvent.SetDataSize(dataObjects->GetDataSize(dataViewEvent.GetDataFormat().GetType())); + dataObjects->GetDataHere(dataViewEvent.GetDataFormat().GetType(),buffer.GetWriteBuf(dataViewEvent.GetDataSize())); + buffer.UngetWriteBuf(dataViewEvent.GetDataSize()); + dataViewEvent.SetDataBuffer(buffer.GetData()); + } + + // send event: + acceptDrag = dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed(); + delete dataObjects; + if (!acceptDrag) + return false; + } + return true; +} /* wxMacDataViewDataBrowserListViewControl::DataBrowserAcceptDragProc(DragReference, DataBrowserItemID) */ -// data handling: -void wxDataViewCtrl::AddChildrenLevel(wxDataViewItem const& parentItem) +Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserAddDragItemProc(DragReference dragRef, DataBrowserItemID itemID, ItemReference* itemRef) { - int NoOfChildren; + Boolean addDragItem; - wxDataViewItemArray items; + wxDataViewCtrl* dataViewCtrlPtr; + wxDataViewItem dataViewItem; - wxCHECK_RET(this->GetModel() != NULL,_("Model pointer not initialized.")); - NoOfChildren = this->GetModel()->GetChildren(parentItem,items); -#if 0 - for (int i=0; iGetModel()->ItemAdded(parentItem,items[i]); -#else - (void) this->GetModel()->ItemsAdded(parentItem,items); -#endif -} -void wxDataViewCtrl::FinishCustomItemEditing() -{ - if (this->GetCustomRendererItem().IsOk()) + dataViewCtrlPtr = dynamic_cast(this->GetWXPeer()); + wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly.")); + wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly.")); + dataViewItem = reinterpret_cast(itemID); + wxCHECK_MSG(dataViewItem.IsOk(),false,_("Invalid data view item")); + + // send a begin drag event and proceed with dragging unless the event is vetoed: + wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG,dataViewCtrlPtr->GetId()); + + dataViewEvent.SetEventObject(dataViewCtrlPtr); + dataViewEvent.SetItem(dataViewItem); + dataViewEvent.SetModel(dataViewCtrlPtr->GetModel()); + // the dataview event object is also initialized with a default set of data; as it is a set of data and the user should be able to easily complete + // the object a wxDataObjectComposite object is used; + // currently, the composite object only contains a TAB concatenated string of all data: + wxDataObjectComposite* dataObject(new wxDataObjectComposite()); + + dataObject->Add(new wxTextDataObject(::ConcatenateDataViewItemValues(dataViewCtrlPtr,dataViewItem))); + dataViewEvent.SetDataObject(dataObject); + // check if event has not been vetoed: + addDragItem = dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed(); + if (addDragItem) { - this->GetCustomRendererPtr()->FinishEditing(); - this->SetCustomRendererItem(wxDataViewItem()); - this->SetCustomRendererPtr (NULL); + // for the internal drag & drop functions create two flavors: + // - the data browser's item id; + // - the data contained the dataview event object (if available). + // Definition: a flavor is the type dependent representation of identical data. + // Example: a number can be represented by its value and by its value converted to a string. In this case the flavor + // of the number's internal representation is typeSInt32 while its string representation has got the flavor 'TEXT'. + // Item id is one of the flavors: + wxCHECK_MSG(::AddDragItemFlavor(dragRef,*itemRef,typeUInt32,&itemID,sizeof(itemID),0) == noErr,false,_("Unable to handle native drag&drop data")); + // if the dataview event object contains data it is used for additional flavors; all natively known flavors are supported: + if (dataViewEvent.GetDataObject() != NULL) + { + // constant definition for abbreviational purposes: + size_t const noOfFormats = dataViewEvent.GetDataObject()->GetFormatCount(); + + if (noOfFormats > 0) + { + // variable definition: + wxDataFormat* dataFormats; + + dataFormats = new wxDataFormat[noOfFormats]; + dataViewEvent.GetDataObject()->GetAllFormats(dataFormats,wxDataObject::Get); + for (size_t i=0; iGetDataSize(wxDF_TEXT); + // variable definition and initialization: + wxMemoryBuffer dataObject(dataSize); + + dataViewEvent.GetDataObject()->GetDataHere(wxDF_TEXT,dataObject.GetWriteBuf(dataSize)); + dataObject.UngetWriteBuf(dataSize); + if (::AddDragItemFlavor(dragRef,*itemRef,'TEXT',dataObject.GetData(),dataSize,0) != noErr) + wxFAIL_MSG(_("Adding flavor TEXT failed")); + } /* block */ + break; + case wxDF_UNICODETEXT: + { + // constant definition for abbreviational purposes: + size_t const dataSize = dataViewEvent.GetDataObject()->GetDataSize(wxDF_TEXT); + // as there is no direct access to the data copy it to a memory buffer: + wxMemoryBuffer dataObject(dataSize); + + dataViewEvent.GetDataObject()->GetDataHere(wxDF_TEXT,dataObject.GetWriteBuf(dataSize)); + dataObject.UngetWriteBuf(dataSize); + // if the data is stored in unicode format the internal representation is utf-8 (not mentioned in the documentation but in the source code); + // DnD uses fixed utf-16 representation -> use the OSX functions for a conversion: + CFDataRef osxData (::CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,reinterpret_cast(dataObject.GetData()),dataSize,kCFAllocatorNull)); + CFStringRef osxString(::CFStringCreateFromExternalRepresentation(kCFAllocatorDefault,osxData,kCFStringEncodingUTF8)); + + // the osxString contains now the data and therefore the previously occupied memory can be released and re-used: + ::CFRelease(osxData); + osxData = ::CFStringCreateExternalRepresentation(kCFAllocatorDefault,osxString,kCFStringEncodingUTF16,32); + if (::AddDragItemFlavor(dragRef,*itemRef,'utxt',::CFDataGetBytePtr(osxData),::CFDataGetLength(osxData),0) != noErr) + wxFAIL_MSG(_("Adding flavor utxt failed")); + // clean up: + ::CFRelease(osxData); + ::CFRelease(osxString); + } /* block */ + break; + case wxDF_BITMAP: + case wxDF_METAFILE: + case wxDF_SYLK: + case wxDF_DIF: + case wxDF_TIFF: + case wxDF_OEMTEXT: + case wxDF_DIB: + case wxDF_PALETTE: + case wxDF_PENDATA: + case wxDF_RIFF: + case wxDF_WAVE: + case wxDF_ENHMETAFILE: + case wxDF_FILENAME: + case wxDF_LOCALE: + case wxDF_PRIVATE: + case wxDF_HTML: + break; // not (yet) supported data formats + default: + wxFAIL_MSG(_("Unknown data format")); + } + delete[] dataFormats; + } + } } -} + // clean-up and return result: + delete dataObject; + return addDragItem; +} /* wxMacDataViewDataBrowserListViewControl::DataBrowserAddDragItemProc(DragReference, DataBrowserItemID, ItemReference*) */ -wxDataViewColumn* wxDataViewCtrl::GetColumnPtr(WXDataBrowserPropertyID propertyID) const +Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserReceiveDragProc(DragReference dragRef, DataBrowserItemID itemID) { - ColumnPointerHashMapType::const_iterator Result(m_ColumnPointers.find(propertyID)); + UInt16 noOfDraggedItems; - if (Result != m_ColumnPointers.end()) - return Result->second; - else - return NULL; -} + wxDataViewCtrl* dataViewCtrlPtr; -// inherited methods from wxDataViewCtrlBase -void wxDataViewCtrl::DoSetExpanderColumn() -{ - if (this->GetExpanderColumn() != NULL) + + dataViewCtrlPtr = dynamic_cast(this->GetWXPeer()); + wxCHECK_MSG(dataViewCtrlPtr != NULL, false,_("Pointer to data view control not set correctly.")); + wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly.")); + + // send a drag possible event for each available and item und proceed with it unless the event is vetoed: + ::CountDragItems(dragRef,&noOfDraggedItems); + for (UInt16 indexDraggedItem=1; indexDraggedItem<=noOfDraggedItems; ++indexDraggedItem) { - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); + bool receiveDrag; + ItemReference itemRef; + wxDataObjectComposite* dataObjects; + wxMemoryBuffer buffer; + + // collect native information: + ::GetDragItemReferenceNumber(dragRef,indexDraggedItem,&itemRef); // the index begins with 1! + dataObjects = this->GetDnDDataObjects(dragRef,itemRef); + // create wxWidget's event: + wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_DROP,dataViewCtrlPtr->GetId()); + + dataViewEvent.SetEventObject(dataViewCtrlPtr); + dataViewEvent.SetItem(reinterpret_cast(itemID)); // this is the item that receives the event + // (can be an invalid item ID, this is especially useful if the dataview does not contain any items) + dataViewEvent.SetModel(dataViewCtrlPtr->GetModel()); + dataViewEvent.SetDataObject(dataObjects); + dataViewEvent.SetDataFormat(this->GetDnDDataFormat(dataObjects)); + if (dataViewEvent.GetDataFormat().GetType() != wxDF_INVALID) + { + dataViewEvent.SetDataSize(dataObjects->GetDataSize(dataViewEvent.GetDataFormat().GetType())); + dataObjects->GetDataHere(dataViewEvent.GetDataFormat().GetType(),buffer.GetWriteBuf(dataViewEvent.GetDataSize())); + buffer.UngetWriteBuf(dataViewEvent.GetDataSize()); + dataViewEvent.SetDataBuffer(buffer.GetData()); + } - (void) MacDataViewListCtrlPtr->SetDisclosureColumn(this->GetExpanderColumn()->GetPropertyID(),false); // second parameter explicitely passed to ensure that arrow is centered + // send event: + receiveDrag = dataViewCtrlPtr->HandleWindowEvent(dataViewEvent) && dataViewEvent.IsAllowed(); + delete dataObjects; + if (!receiveDrag) + return false; } -} + return true; +} /* wxMacDataViewDataBrowserListViewControl::DataBrowserReceiveDragProc(DragReference, DataBrowserItemID) */ -void wxDataViewCtrl::DoSetIndent() +// +// drag & drop helper methods +// +wxDataFormat wxMacDataViewDataBrowserListViewControl::GetDnDDataFormat(wxDataObjectComposite* dataObjects) { - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); + wxDataFormat resultFormat; - (void) MacDataViewListCtrlPtr->SetIndent(static_cast(this->GetIndent())); -} -// event handling: -void wxDataViewCtrl::OnMouse(wxMouseEvent& event) -{ - event.Skip(); - - if (GetModel() == NULL) - return; + if (dataObjects != NULL) + { + bool compatible(true); - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); + size_t const noOfFormats = dataObjects->GetFormatCount(); + size_t indexFormat; - int NoOfChildren; - wxDataViewItemArray items; - NoOfChildren = GetModel()->GetChildren( wxDataViewItem(), items); - if (NoOfChildren == 0) - return; - wxDataViewItem firstChild = items[0]; + wxDataFormat* formats; - UInt16 headerHeight = 0; - MacDataViewListCtrlPtr->GetHeaderButtonHeight(&headerHeight); - - - if (event.GetY() < headerHeight) + // get all formats and check afterwards if the formats are compatible; if they are compatible the preferred format is returned otherwise + // wxDF_INVALID is returned; + // currently compatible types (ordered by priority are): + // - wxDF_UNICODETEXT - wxDF_TEXT + formats = new wxDataFormat[noOfFormats]; + dataObjects->GetAllFormats(formats); + indexFormat = 0; + while ((indexFormat < noOfFormats) && compatible) { - unsigned int col_count = GetColumnCount(); - unsigned int col; - for (col = 0; col < col_count; col++) - { - wxDataViewColumn *column = GetColumn( col ); - if (column->IsHidden()) - continue; - - Rect itemrect; - ::GetDataBrowserItemPartBounds( MacDataViewListCtrlPtr->GetControlRef(), - reinterpret_cast(firstChild.GetID()), column->GetPropertyID(), - kDataBrowserPropertyEnclosingPart, &itemrect ); - - if (abs( event.GetX() - itemrect.right) < 3) - { - if (column->GetFlags() & wxDATAVIEW_COL_RESIZABLE) - SetCursor( wxCursor( wxCURSOR_SIZEWE ) ); - else - SetCursor( *wxSTANDARD_CURSOR ); - return; - } - } - - } - - SetCursor( *wxSTANDARD_CURSOR ); -} + switch (resultFormat.GetType()) + { + case wxDF_INVALID: + resultFormat.SetType(formats[indexFormat].GetType()); // first format (should only be reached if indexFormat == 0 + break; + case wxDF_TEXT: + if (formats[indexFormat].GetType() == wxDF_UNICODETEXT) + resultFormat.SetType(wxDF_UNICODETEXT); + else // incompatible + { + resultFormat.SetType(wxDF_INVALID); + compatible = false; + } + break; + case wxDF_UNICODETEXT: + if (formats[indexFormat].GetType() != wxDF_TEXT) + { + resultFormat.SetType(wxDF_INVALID); + compatible = false; + } + break; + default: + resultFormat.SetType(wxDF_INVALID); // not (yet) supported format + compatible = false; + } + ++indexFormat; + } /* while */ + // clean up: + delete[] formats; + } + else + resultFormat = wxDF_INVALID; + return resultFormat; +} /* wxMacDataViewDataBrowserListViewControl::GetDnDDataFormat(wxDataObjectComposite*) */ -void wxDataViewCtrl::OnSize(wxSizeEvent& event) +wxDataObjectComposite* wxMacDataViewDataBrowserListViewControl::GetDnDDataObjects(DragReference dragRef, ItemReference itemRef) const { - unsigned int const NoOfColumns = this->GetColumnCount(); + UInt16 noOfFlavors; + wxDataObjectComposite* dataObject; - for (unsigned int i=0; i 0) { - wxDataViewColumn* dataViewColumnPtr(this->GetColumn(i)); + // as the native drag data can be separated into TEXT and UTXT a pointer to a wxTextDataObject is used to track the existence of 'TEXT' and 'utxt' flavors: + wxTextDataObject* textDataObject(NULL); - if (dataViewColumnPtr != NULL) + dataObject = new wxDataObjectComposite(); + for (UInt16 indexFlavor=1; indexFlavor<=noOfFlavors; ++indexFlavor) { - wxDataViewCustomRenderer* dataViewCustomRendererPtr(dynamic_cast(dataViewColumnPtr->GetRenderer())); + // variable definition: + FlavorType flavorDataObject; + + if (::GetFlavorType(dragRef,itemRef,indexFlavor,&flavorDataObject) == noErr) // GetFlavorType uses a 1 based index! + switch (flavorDataObject) + { + case 'TEXT': + if (textDataObject == NULL) // otherwise a 'utxt' flavor has already been found that gets priority compared to the 'TEXT' flavor + { + // variable definitions: + Size nativeDataSize; + wxMemoryBuffer nativeData; + + if ((::GetFlavorDataSize(dragRef,itemRef,'TEXT',&nativeDataSize) == noErr) && + (::GetFlavorData(dragRef,itemRef,'TEXT',nativeData.GetWriteBuf(nativeDataSize),&nativeDataSize,0) == noErr)) + { + nativeData.UngetWriteBuf(nativeDataSize); + textDataObject = new wxTextDataObject(); + if (textDataObject->SetData(nativeData.GetDataLen(),nativeData.GetData())) + dataObject->Add(textDataObject); + else + { + delete textDataObject; + textDataObject = NULL; + } + } + } /* block */ + break; + case 'utxt': + { + // variable definition: + Size nativeDataSize; + + if (::GetFlavorDataSize(dragRef,itemRef,'utxt',&nativeDataSize) == noErr) + { + CFMutableDataRef draggedData; - if (dataViewCustomRendererPtr != NULL) - dataViewCustomRendererPtr->SetDC(NULL); // reset DC because DC has changed + draggedData = ::CFDataCreateMutable(kCFAllocatorDefault,nativeDataSize); + ::CFDataSetLength(draggedData,nativeDataSize); + if (::GetFlavorData(dragRef,itemRef,'utxt',::CFDataGetMutableBytePtr(draggedData),&nativeDataSize,0) == noErr) + { + // convert internally used UTF-16 representation to a UTF-8 representation: + CFDataRef osxData; + CFStringRef osxString; + + osxString = ::CFStringCreateFromExternalRepresentation(kCFAllocatorDefault,draggedData,kCFStringEncodingUTF16); // BOM character is handled by this function automatically + osxData = ::CFStringCreateExternalRepresentation(kCFAllocatorDefault,osxString,kCFStringEncodingUTF8,32); + if (textDataObject == NULL) + { + textDataObject = new wxTextDataObject(); + if (textDataObject->SetData(::CFDataGetLength(osxData),::CFDataGetBytePtr(osxData))) + dataObject->Add(textDataObject); + else + { + delete textDataObject; + textDataObject = NULL; + } + } + else // overwrite data because the 'utxt' flavor has priority over the 'TEXT' flavor + (void) textDataObject->SetData(::CFDataGetLength(osxData),::CFDataGetBytePtr(osxData)); + // clean up: + ::CFRelease(osxData); + ::CFRelease(osxString); + } + // clean up: + ::CFRelease(draggedData); + } + } /* block */ + break; + } } } + else + dataObject = NULL; + return dataObject; +} /* wxMacDataViewDataBrowserListViewControl::GetDnDDataObjects(DragReference, ItemReference) const */ - wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(m_peer)); - ControlRef ref = MacDataViewListCtrlPtr->GetControlRef(); - if (NoOfColumns == 1) - { - ::SetDataBrowserHasScrollBars( ref, false, true ); - ::AutoSizeDataBrowserListViewColumns( ref ); - } - if (NoOfColumns > 1) +// +// other methods +// +wxDataViewColumn* wxMacDataViewDataBrowserListViewControl::GetColumnPtr(DataBrowserPropertyID propertyID) const +{ + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetWXPeer())); + + if (dataViewCtrlPtr != NULL) { - ::SetDataBrowserHasScrollBars( ref, true, true ); + size_t const noOfColumns = dataViewCtrlPtr->GetColumnCount(); + + for (size_t i=0; iGetColumnPtr(i)->GetNativeData()->GetPropertyID() == propertyID) + return dataViewCtrlPtr->GetColumnPtr(i); } + return NULL; +} + +// --------------------------------------------------------- +// wxDataViewRenderer +// --------------------------------------------------------- +wxDataViewRenderer::wxDataViewRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align) + :wxDataViewRendererBase(varianttype,mode,align), m_alignment(align), m_mode(mode), m_NativeDataPtr(NULL) +{ +} - event.Skip(); +wxDataViewRenderer::~wxDataViewRenderer(void) +{ + delete this->m_NativeDataPtr; +} + +void wxDataViewRenderer::SetAlignment(int align) +{ + this->m_alignment = align; } -IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl,wxDataViewCtrlBase) +void wxDataViewRenderer::SetMode(wxDataViewCellMode mode) +{ + wxDataViewColumn* dataViewColumnPtr; + -BEGIN_EVENT_TABLE(wxDataViewCtrl,wxDataViewCtrlBase) - EVT_SIZE(wxDataViewCtrl::OnSize) - EVT_MOTION(wxDataViewCtrl::OnMouse) -END_EVENT_TABLE() + m_mode = mode; + dataViewColumnPtr = this->GetOwner(); + if (dataViewColumnPtr != NULL) + { + wxDataViewCtrl* dataViewCtrlPtr(dataViewColumnPtr->GetOwner()); -#endif // !wxUSE_GENERICDATAVIEWCTRL + if (dataViewCtrlPtr != NULL) + { + wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); -#endif // wxUSE_DATAVIEWCTRL + if (macDataViewListCtrlPtr != NULL) + { + DataBrowserPropertyFlags flags; + + verify_noerr(macDataViewListCtrlPtr->GetPropertyFlags(dataViewColumnPtr->GetNativeData()->GetPropertyID(),&flags)); + if ((mode == wxDATAVIEW_CELL_EDITABLE) || + (mode == wxDATAVIEW_CELL_ACTIVATABLE)) + flags |= kDataBrowserPropertyIsEditable; + else + flags &= ~kDataBrowserPropertyIsEditable; + verify_noerr(macDataViewListCtrlPtr->SetPropertyFlags(dataViewColumnPtr->GetNativeData()->GetPropertyID(),flags)); + } + } + } +} + +void wxDataViewRenderer::SetNativeData(wxDataViewRendererNativeData* newNativeDataPtr) +{ + delete this->m_NativeDataPtr; + this->m_NativeDataPtr = newNativeDataPtr; +} + +IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer,wxDataViewRendererBase) + +// --------------------------------------------------------- +// wxDataViewCustomRenderer +// --------------------------------------------------------- +wxDataViewCustomRenderer::wxDataViewCustomRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align) + :wxDataViewRenderer(varianttype,mode,align), m_editorCtrlPtr(NULL), m_DCPtr(NULL) +{ + this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserCustomType)); +} + +bool wxDataViewCustomRenderer::MacRender() +{ + return true; +} + +IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomRenderer, wxDataViewRenderer) + +// --------------------------------------------------------- +// wxDataViewTextRenderer +// --------------------------------------------------------- +wxDataViewTextRenderer::wxDataViewTextRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align) + :wxDataViewRenderer(varianttype,mode,align) +{ + this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserTextType)); +} + +bool wxDataViewTextRenderer::MacRender() +{ + wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Text renderer cannot render value; value type: ")) << this->GetValue().GetType()); + + wxCFStringRef cfString(this->GetValue().GetString(),(this->GetView()->GetFont().Ok() ? this->GetView()->GetFont().GetEncoding() : wxLocale::GetSystemEncoding())); + return (::SetDataBrowserItemDataText(this->GetNativeData()->GetItemDataRef(),cfString) == noErr); +} + +IMPLEMENT_CLASS(wxDataViewTextRenderer,wxDataViewRenderer) + +// --------------------------------------------------------- +// wxDataViewBitmapRenderer +// --------------------------------------------------------- +wxDataViewBitmapRenderer::wxDataViewBitmapRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align) + :wxDataViewRenderer(varianttype,mode,align) +{ + this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserIconType)); +} + +bool wxDataViewBitmapRenderer::MacRender() + // This method returns 'true' if + // - the passed bitmap is valid and it could be assigned to the native data browser; + // - the passed bitmap is invalid (or is not initialized); this case simulates a non-existing bitmap. + // In all other cases the method returns 'false'. +{ + wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Bitmap renderer cannot render value; value type: ")) << this->GetValue().GetType()); + + wxBitmap bitmap; + + bitmap << this->GetValue(); + return (!(bitmap.Ok()) || (::SetDataBrowserItemDataIcon(this->GetNativeData()->GetItemDataRef(),bitmap.GetIconRef()) == noErr)); +} + +IMPLEMENT_CLASS(wxDataViewBitmapRenderer,wxDataViewRenderer) + +// --------------------------------------------------------- +// wxDataViewIconTextRenderer +// --------------------------------------------------------- +wxDataViewIconTextRenderer::wxDataViewIconTextRenderer( + const wxString& varianttype, + wxDataViewCellMode mode, + int WXUNUSED(align)) + :wxDataViewRenderer(varianttype,mode) +{ + this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserIconAndTextType)); +} + +bool wxDataViewIconTextRenderer::MacRender() +{ + wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Icon & text renderer cannot render value; value type: ")) << this->GetValue().GetType()); + + wxDataViewIconText iconText; + + iconText << this->GetValue(); + + wxCFStringRef cfString(iconText.GetText(),(this->GetView()->GetFont().Ok() ? this->GetView()->GetFont().GetEncoding() : wxLocale::GetSystemEncoding())); + + if (iconText.GetIcon().IsOk()) + if (::SetDataBrowserItemDataIcon(this->GetNativeData()->GetItemDataRef(),MAC_WXHICON(iconText.GetIcon().GetHICON())) != noErr) + return false; + return (::SetDataBrowserItemDataText(this->GetNativeData()->GetItemDataRef(),cfString) == noErr); +} + +IMPLEMENT_ABSTRACT_CLASS(wxDataViewIconTextRenderer,wxDataViewRenderer) + + +// --------------------------------------------------------- +// wxDataViewToggleRenderer +// --------------------------------------------------------- +wxDataViewToggleRenderer::wxDataViewToggleRenderer( + const wxString& varianttype, + wxDataViewCellMode mode, + int WXUNUSED(align)) + :wxDataViewRenderer(varianttype,mode) +{ + this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserCheckboxType)); +} + +bool wxDataViewToggleRenderer::MacRender() +{ + wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Toggle renderer cannot render value; value type: ")) << this->GetValue().GetType()); + return (::SetDataBrowserItemDataButtonValue(this->GetNativeData()->GetItemDataRef(),this->GetValue().GetBool()) == noErr); +} + +IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleRenderer,wxDataViewRenderer) + +// --------------------------------------------------------- +// wxDataViewProgressRenderer +// --------------------------------------------------------- +wxDataViewProgressRenderer::wxDataViewProgressRenderer( + const wxString& WXUNUSED(label), + wxString const& varianttype, + wxDataViewCellMode mode, + int align) + :wxDataViewRenderer(varianttype,mode,align) +{ + this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserProgressBarType)); +} + +bool wxDataViewProgressRenderer::MacRender() +{ + wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Progress renderer cannot render value type; value type: ")) << this->GetValue().GetType()); + return ((::SetDataBrowserItemDataMinimum(this->GetNativeData()->GetItemDataRef(), 0) == noErr) && + (::SetDataBrowserItemDataMaximum(this->GetNativeData()->GetItemDataRef(),100) == noErr) && + (::SetDataBrowserItemDataValue (this->GetNativeData()->GetItemDataRef(),this->GetValue().GetLong()) == noErr)); +} + +IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressRenderer,wxDataViewRenderer) + +// --------------------------------------------------------- +// wxDataViewDateRenderer +// --------------------------------------------------------- +wxDataViewDateRenderer::wxDataViewDateRenderer(wxString const& varianttype, wxDataViewCellMode mode, int align) + :wxDataViewRenderer(varianttype,mode,align) +{ + this->SetNativeData(new wxDataViewRendererNativeData(kDataBrowserDateTimeType)); +} + +bool wxDataViewDateRenderer::MacRender() +{ + wxCHECK_MSG(this->GetValue().GetType() == this->GetVariantType(),false,wxString(_("Date renderer cannot render value; value type: ")) << this->GetValue().GetType()); + return (::SetDataBrowserItemDataDateTime(this->GetNativeData()->GetItemDataRef(),this->GetValue().GetDateTime().Subtract(wxDateTime(1,wxDateTime::Jan,1904)).GetSeconds().GetLo()) == noErr); +} + +IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer,wxDataViewRenderer) + +// --------------------------------------------------------- +// wxDataViewColumn +// --------------------------------------------------------- +wxDataViewColumn::wxDataViewColumn(const wxString& title, wxDataViewRenderer* renderer, unsigned int model_column, int width, wxAlignment align, int flags) + :wxDataViewColumnBase(renderer, model_column), m_NativeDataPtr(new wxDataViewColumnNativeData()), m_title(title) +{ + this->InitCommon(width, align, flags); + if ((renderer != NULL) && (renderer->GetAlignment() == wxDVR_DEFAULT_ALIGNMENT)) + renderer->SetAlignment(align); +} + +wxDataViewColumn::wxDataViewColumn(const wxBitmap& bitmap, wxDataViewRenderer* renderer, unsigned int model_column, int width, wxAlignment align, int flags) + :wxDataViewColumnBase(bitmap, renderer, model_column), m_NativeDataPtr(new wxDataViewColumnNativeData()) +{ + this->InitCommon(width, align, flags); + if ((renderer != NULL) && (renderer->GetAlignment() == wxDVR_DEFAULT_ALIGNMENT)) + renderer->SetAlignment(align); +} + +wxDataViewColumn::~wxDataViewColumn(void) +{ + delete this->m_NativeDataPtr; +} + +bool wxDataViewColumn::IsSortKey() const +{ + wxDataViewCtrl * const dataViewCtrlPtr(GetOwner()); + wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr( + dynamic_cast( + dataViewCtrlPtr->GetPeer())); + + DataBrowserPropertyID propertyID; + return (macDataViewListCtrlPtr->GetSortProperty(&propertyID) == noErr) && + (propertyID == this->GetNativeData()->GetPropertyID()); +} + +void wxDataViewColumn::SetAlignment(wxAlignment align) +{ + wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + + + m_alignment = align; + if (dataViewCtrlPtr != NULL) + { + wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); + + if (macDataViewListCtrlPtr != NULL) + { + DataBrowserListViewHeaderDesc headerDescription; + + wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description.")); + switch (align) + { + case wxALIGN_CENTER: + case wxALIGN_CENTER_HORIZONTAL: + headerDescription.btnFontStyle.just = teCenter; + break; + case wxALIGN_LEFT: + headerDescription.btnFontStyle.just = teFlushLeft; + break; + case wxALIGN_RIGHT: + headerDescription.btnFontStyle.just = teFlushRight; + break; + default: + headerDescription.btnFontStyle.just = teFlushDefault; + } + wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not set alignment.")); + } + } +} + +void wxDataViewColumn::SetBitmap(wxBitmap const& bitmap) +{ + wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + + + wxDataViewColumnBase::SetBitmap(bitmap); + if (dataViewCtrlPtr != NULL) + { + wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); + + if (macDataViewListCtrlPtr != NULL) + { + DataBrowserListViewHeaderDesc headerDescription; + + wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description.")); + if (this->GetBitmap().Ok()) + headerDescription.btnContentInfo.u.iconRef = this->GetBitmap().GetIconRef(); + else + headerDescription.btnContentInfo.u.iconRef = NULL; + wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not set icon.")); + } + } +} + +void wxDataViewColumn::SetMaxWidth(int maxWidth) +{ + wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + + + m_maxWidth = maxWidth; + if (dataViewCtrlPtr != NULL) + { + wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); + + if (macDataViewListCtrlPtr != NULL) + { + DataBrowserListViewHeaderDesc headerDescription; + + wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description.")); + headerDescription.maximumWidth = static_cast(maxWidth); + wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not set maximum width.")); + } + } +} + +void wxDataViewColumn::SetMinWidth(int minWidth) +{ + wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + + + m_minWidth = minWidth; + if (dataViewCtrlPtr != NULL) + { + wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); + + if (macDataViewListCtrlPtr != NULL) + { + DataBrowserListViewHeaderDesc headerDescription; + + wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description.")); + headerDescription.minimumWidth = static_cast(minWidth); + wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not set minimum width.")); + } + } +} + +void wxDataViewColumn::SetReorderable(bool reorderable) +{ + // first set the internal flag of the column: + if (reorderable) + m_flags |= wxDATAVIEW_COL_REORDERABLE; + else + m_flags &= ~wxDATAVIEW_COL_REORDERABLE; + // if the column is associated with a control change also immediately the flags of the control: + wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + + if (dataViewCtrlPtr != NULL) + { + DataBrowserPropertyFlags flags; + wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); + + wxCHECK_RET(macDataViewListCtrlPtr != NULL, _("Valid pointer to native data view control does not exist")); + wxCHECK_RET(macDataViewListCtrlPtr->GetPropertyFlags(this->GetNativeData()->GetPropertyID(),&flags) == noErr,_("Could not get property flags.")); + if (reorderable) + flags |= kDataBrowserListViewMovableColumn; + else + flags &= ~kDataBrowserListViewMovableColumn; + wxCHECK_RET(macDataViewListCtrlPtr->SetPropertyFlags(this->GetNativeData()->GetPropertyID(),flags) == noErr,_("Could not set property flags.")); + } +} + +void wxDataViewColumn::SetResizeable(bool resizeable) +{ + // first set the internal flag of the column: + if (resizeable) + m_flags |= wxDATAVIEW_COL_RESIZABLE; + else + m_flags &= ~wxDATAVIEW_COL_RESIZABLE; + // if the column is associated with a control change also immediately the flags of the control: + wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + + if (dataViewCtrlPtr != NULL) + { + wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); + + if (macDataViewListCtrlPtr != NULL) + { + DataBrowserListViewHeaderDesc headerDescription; + + verify_noerr(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription)); + if (resizeable) + { + if (this->GetMinWidth() >= this->GetMaxWidth()) + { + this->m_minWidth = 0; + this->m_maxWidth = 30000; + } + headerDescription.minimumWidth = this->m_minWidth; + headerDescription.maximumWidth = this->m_maxWidth; + } + else + { + headerDescription.minimumWidth = this->m_width; + headerDescription.maximumWidth = this->m_width; + } + verify_noerr(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription)); + macDataViewListCtrlPtr->SetSortProperty(this->GetNativeData()->GetPropertyID()); + } + } +} + +void wxDataViewColumn::SetSortable(bool sortable) +{ + // first set the internal flag of the column: + if (sortable) + m_flags |= wxDATAVIEW_COL_SORTABLE; + else + m_flags &= ~wxDATAVIEW_COL_SORTABLE; + // if the column is associated with a control change also immediately the flags of the control: + wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + + if (dataViewCtrlPtr != NULL) + { + DataBrowserPropertyFlags flags; + wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); + + wxCHECK_RET(macDataViewListCtrlPtr != NULL, _("Valid pointer to native data view control does not exist")); + wxCHECK_RET(macDataViewListCtrlPtr->GetPropertyFlags(this->GetNativeData()->GetPropertyID(),&flags) == noErr,_("Could not get property flags.")); + if (sortable) + flags |= kDataBrowserListViewSortableColumn; + else + flags &= ~kDataBrowserListViewSortableColumn; + wxCHECK_RET(macDataViewListCtrlPtr->SetPropertyFlags(this->GetNativeData()->GetPropertyID(),flags) == noErr,_("Could not set property flags.")); + } +} + +void wxDataViewColumn::SetSortOrder(bool ascending) +{ + wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + + + m_ascending = ascending; + if (dataViewCtrlPtr != NULL) + { + wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); + + if (macDataViewListCtrlPtr != NULL) + { + DataBrowserListViewHeaderDesc headerDescription; + + verify_noerr(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription)); + if (ascending) + headerDescription.initialOrder = kDataBrowserOrderIncreasing; + else + headerDescription.initialOrder = kDataBrowserOrderDecreasing; + verify_noerr(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription)); + macDataViewListCtrlPtr->SetSortProperty(this->GetNativeData()->GetPropertyID()); + } + } +} + +void wxDataViewColumn::SetTitle(wxString const& title) +{ + wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + + + m_title = title; + if (dataViewCtrlPtr != NULL) + { + wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); + + if (macDataViewListCtrlPtr != NULL) + { + DataBrowserListViewHeaderDesc headerDescription; + wxCFStringRef cfTitle(title,(dataViewCtrlPtr->GetFont().Ok() ? dataViewCtrlPtr->GetFont().GetEncoding() : wxLocale::GetSystemEncoding())); + + wxCHECK_RET(macDataViewListCtrlPtr->GetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not get header description.")); + headerDescription.titleString = cfTitle; + wxCHECK_RET(macDataViewListCtrlPtr->SetHeaderDesc(this->GetNativeData()->GetPropertyID(),&headerDescription) == noErr,_("Could not set header description.")); + } + } +} + +void wxDataViewColumn::SetWidth(int width) +{ + wxDataViewCtrl* dataViewCtrlPtr(this->GetOwner()); + + + if ((width >= m_minWidth) && (width <= m_maxWidth)) + { + m_width = width; + if (dataViewCtrlPtr != NULL) + { + wxMacDataViewDataBrowserListViewControlPointer macDataViewListCtrlPtr(dynamic_cast(dataViewCtrlPtr->GetPeer())); + + if (macDataViewListCtrlPtr != NULL) + wxCHECK_RET(macDataViewListCtrlPtr->SetColumnWidth(this->GetNativeData()->GetPropertyID(),static_cast(width)) == noErr,_("Could not set column width.")); + } + } +} + +void wxDataViewColumn::SetAsSortKey(bool WXUNUSED(sort)) +{ + // see wxGTK native wxDataViewColumn implementation + wxFAIL_MSG( "not implemented" ); +} + +void wxDataViewColumn::SetNativeData(wxDataViewColumnNativeData* newNativeDataPtr) +{ + delete this->m_NativeDataPtr; + this->m_NativeDataPtr = newNativeDataPtr; +} +#endif // wxUSE_DATAVIEWCTRL && !wxUSE_GENERICDATAVIEWCTRL