From: Robert Roebling Date: Sat, 25 Aug 2007 13:15:16 +0000 (+0000) Subject: Hartwig's patch for OS X implementation of wxDataViewCtrl X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/07c51ff1fa68e0667f164cfa8b2317666c367642?hp=b74077ace2413000c5556cbe0c41ab210ac12c54 Hartwig's patch for OS X implementation of wxDataViewCtrl git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@48379 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/mac/carbon/databrow.h b/include/wx/mac/carbon/databrow.h index 298e6cc742..ea75a0755d 100644 --- a/include/wx/mac/carbon/databrow.h +++ b/include/wx/mac/carbon/databrow.h @@ -107,6 +107,7 @@ public: OSStatus GetDefaultColumnWidth(UInt16 *width ) const; // returns the default column width in pixels OSStatus GetDefaultRowHeight (UInt16 * height ) const; OSStatus GetHeaderButtonHeight(UInt16 *height ); + OSStatus GetPartBounds (DataBrowserItemID item, DataBrowserPropertyID property, DataBrowserPropertyPart part, Rect* bounds); OSStatus GetRowHeight (DataBrowserItemID item , UInt16 *height) const; OSStatus GetScrollPosition (UInt32* top, UInt32 *left) const; @@ -129,8 +130,9 @@ public: OSStatus GetColumnIndex (DataBrowserPropertyID propertyID, DataBrowserTableViewColumnIndex* index) const; // returns for the passed property the corresponding column index OSStatus GetFreePropertyID(DataBrowserPropertyID* propertyID) const; // this method returns a property id that is valid and currently not used; if it cannot be found 'errDataBrowerPropertyNotSupported' is returned OSStatus GetPropertyFlags (DataBrowserPropertyID propertyID, DataBrowserPropertyFlags *flags ) const; - OSStatus GetPropertyID (DataBrowserTableViewColumnIndex index, DataBrowserTableViewColumnID* propertyId); // returns for the passed column index the corresponding property ID - + OSStatus GetPropertyID (DataBrowserItemDataRef itemData, DataBrowserPropertyID* propertyID); // returns for the passed item data reference the corresponding property ID + OSStatus GetPropertyID (DataBrowserTableViewColumnIndex index, DataBrowserPropertyID* propertyID); // returns for the passed column index the corresponding property ID + OSStatus IsUsedPropertyID(DataBrowserPropertyID propertyID) const; // checks if passed property id is used by the control; no error is returned if the id exists OSStatus RemoveColumn(DataBrowserTableViewColumnIndex index); @@ -154,7 +156,7 @@ public: return this->GetItemCount(kDataBrowserNoItem,true,kDataBrowserItemAnyState,numItems); } OSStatus GetItemCount (DataBrowserItemID container, Boolean recurse, DataBrowserItemState state, ItemCount* numItems) const; - OSStatus GetItemID (DataBrowserTableViewRowIndex row, DataBrowserItemID * item) const; + OSStatus GetItemID (DataBrowserTableViewRowIndex row, DataBrowserItemID* item) const; OSStatus GetItems (DataBrowserItemID container, Boolean recurse, DataBrowserItemState state, Handle items) const; OSStatus GetItemRow (DataBrowserItemID item, DataBrowserTableViewRowIndex* row) const; @@ -200,6 +202,8 @@ public: OSStatus GetSortOrder (DataBrowserSortOrder* order) const; OSStatus GetSortProperty(DataBrowserPropertyID* propertyID) const; + OSStatus Resort(DataBrowserItemID container=kDataBrowserNoItem, Boolean sortChildren=true); + OSStatus SetSortOrder (DataBrowserSortOrder order); OSStatus SetSortProperty(DataBrowserPropertyID propertyID); diff --git a/include/wx/mac/carbon/dataview.h b/include/wx/mac/carbon/dataview.h index 960a176182..df2d9f0841 100644 --- a/include/wx/mac/carbon/dataview.h +++ b/include/wx/mac/carbon/dataview.h @@ -500,15 +500,37 @@ public: return this; } - virtual wxDataViewItem GetSelection(void); + virtual void EnsureVisible(wxDataViewItem const& item, wxDataViewColumn const* columnPtr=NULL); + + virtual wxRect GetItemRect(wxDataViewItem const& item, wxDataViewColumn const* columnPtr) const; + virtual wxDataViewItem GetSelection(void) const; + virtual int GetSelections(wxDataViewItemArray& sel) const; + + virtual void HitTest(wxPoint const& point, wxDataViewItem& item, wxDataViewColumn*& columnPtr) const; + + virtual bool IsSelected(wxDataViewItem const& item) const; + + virtual void SelectAll(void); + virtual void Select(wxDataViewItem const& item); + virtual void SetSelections(wxDataViewItemArray const& sel); + virtual void Unselect(wxDataViewItem const& item); + virtual void UnselectAll(void); + + // // implementation // - // adds all children of the passed parent to the control; if 'parentItem' is invalid the root(s) is/are added: + // adds all children of the passed parent to the control; if 'parentItem' is invalid the root(s) is/are added: void AddChildrenLevel(wxDataViewItem const& parentItem); + // checks if currently a delete process is running: + bool IsDeleting(void) const + { + return this->m_Deleting; + } + // with CG, we need to get the context from an kEventControlDraw event // unfortunately, the DataBrowser callbacks don't provide the context // and we need it, so we need to set/remove it before and after draw @@ -522,6 +544,12 @@ public: return this->m_cgContext; } + /// sets the flag indicating a deletion process: + void SetDeleting(bool deleting) + { + this->m_Deleting = deleting; + } + protected: // inherited methods from wxDataViewCtrlBase: virtual void DoSetExpanderColumn(void); @@ -538,9 +566,13 @@ private: // variables // - wxDataViewModelNotifier* m_NotifierPtr; // the notifier is NOT owned by this class but by the associated model + bool m_Deleting; // flag indicating if a delete process is running; this flag is necessary because the notifier indicating an item deletion in the model may be called + // after the actual deletion of the item; then, the callback function "wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc" may + // try to update data into variables that are already deleted; this flag will ignore all variable update requests during item deletion void* m_cgContext; // pointer to core graphics context + + wxDataViewModelNotifier* m_NotifierPtr; // the notifier is NOT owned by this class but by the associated model // wxWidget internal stuff: DECLARE_DYNAMIC_CLASS(wxDataViewCtrl) diff --git a/src/mac/carbon/databrow.cpp b/src/mac/carbon/databrow.cpp index bde0284cbf..9e8236b740 100644 --- a/src/mac/carbon/databrow.cpp +++ b/src/mac/carbon/databrow.cpp @@ -221,6 +221,11 @@ OSStatus wxMacDataBrowserTableViewControl::GetColumnWidth(DataBrowserPropertyID return ::GetDataBrowserTableViewNamedColumnWidth(this->m_controlRef,propertyID,width); } +OSStatus wxMacDataBrowserTableViewControl::GetDefaultColumnWidth( UInt16 *width ) const +{ + return GetDataBrowserTableViewColumnWidth(this->m_controlRef, width ); +} + OSStatus wxMacDataBrowserTableViewControl::GetDefaultRowHeight(UInt16* height) const { return ::GetDataBrowserTableViewRowHeight(this->m_controlRef,height); @@ -231,15 +236,15 @@ OSStatus wxMacDataBrowserTableViewControl::GetHeaderButtonHeight(UInt16 *height) return ::GetDataBrowserListViewHeaderBtnHeight(this->m_controlRef,height); } -OSStatus wxMacDataBrowserTableViewControl::GetDefaultColumnWidth( UInt16 *width ) const +OSStatus wxMacDataBrowserTableViewControl::GetPartBounds(DataBrowserItemID item, DataBrowserPropertyID property, DataBrowserPropertyPart part, Rect* bounds) { - return GetDataBrowserTableViewColumnWidth(this->m_controlRef, width ); -} + return ::GetDataBrowserItemPartBounds(this->m_controlRef,item,property,part,bounds); +} /* wxMacDataBrowserTableViewControl::GetPartBounds(DataBrowserItemID, DataBrowswerPropertyID, DataBrowserPropertyPart, Rect*) */ -OSStatus wxMacDataBrowserTableViewControl::GetRowHeight( DataBrowserItemID item , UInt16 *height) const +OSStatus wxMacDataBrowserTableViewControl::GetRowHeight(DataBrowserItemID item, UInt16* height) const { - return GetDataBrowserTableViewItemRowHeight( m_controlRef, item , height); -} + return ::GetDataBrowserTableViewItemRowHeight(this->m_controlRef,item,height); +} /* wxMacDataBrowserTableViewControl::GetRowHeight(DataBrowserItemID, UInt16*) const */ OSStatus wxMacDataBrowserTableViewControl::GetScrollPosition( UInt32 *top , UInt32 *left ) const { @@ -319,6 +324,11 @@ OSStatus wxMacDataBrowserTableViewControl::GetPropertyFlags(DataBrowserPropertyI return ::GetDataBrowserPropertyFlags(this->m_controlRef,propertyID,flags); } +OSStatus wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserItemDataRef itemData, DataBrowserPropertyID* propertyID) +{ + return ::GetDataBrowserItemDataProperty(itemData,propertyID); +} /* wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserItemDataRef, DataBrowserPropertyID*) */ + OSStatus wxMacDataBrowserTableViewControl::GetPropertyID(DataBrowserTableViewColumnIndex index, DataBrowserTableViewColumnID* propertyID) { return ::GetDataBrowserTableViewColumnProperty(this->m_controlRef,index,propertyID); @@ -491,26 +501,31 @@ OSStatus wxMacDataBrowserTableViewControl::SetSelectedItems(UInt32 numItems, Dat return ::SetDataBrowserSelectedItems(this->m_controlRef, numItems, items, operation ); } /* wxMacDataBrowserTableViewControl::SetSelectedItems(UInt32, DataBrowserItemID const*, DataBrowserSetOption) */ -OSStatus wxMacDataBrowserTableViewControl::GetSortProperty(DataBrowserPropertyID* propertyID) const +OSStatus wxMacDataBrowserTableViewControl::GetSortOrder(DataBrowserSortOrder* order) const { - return ::GetDataBrowserSortProperty(this->m_controlRef,propertyID); + return ::GetDataBrowserSortOrder(this->m_controlRef,order); } -OSStatus wxMacDataBrowserTableViewControl::SetSortProperty(DataBrowserPropertyID propertyID) +OSStatus wxMacDataBrowserTableViewControl::GetSortProperty(DataBrowserPropertyID* propertyID) const { - return ::SetDataBrowserSortProperty(this->m_controlRef,propertyID); + return ::GetDataBrowserSortProperty(this->m_controlRef,propertyID); } -OSStatus wxMacDataBrowserTableViewControl::GetSortOrder(DataBrowserSortOrder* order) const +OSStatus wxMacDataBrowserTableViewControl::Resort(DataBrowserItemID container, Boolean sortChildren) { - return ::GetDataBrowserSortOrder(this->m_controlRef,order); -} + return ::SortDataBrowserContainer(this->m_controlRef,container,sortChildren); +} /* wxMacDataBrowserTableViewControl::Resort(DataBrowserItemID, Boolean) */ OSStatus wxMacDataBrowserTableViewControl::SetSortOrder(DataBrowserSortOrder order) { return ::SetDataBrowserSortOrder(this->m_controlRef,order); } +OSStatus wxMacDataBrowserTableViewControl::SetSortProperty(DataBrowserPropertyID propertyID) +{ + return ::SetDataBrowserSortProperty(this->m_controlRef,propertyID); +} + IMPLEMENT_ABSTRACT_CLASS(wxMacDataBrowserTableViewControl,wxMacControl) // ============================================================================ @@ -542,6 +557,10 @@ wxMacDataViewDataBrowserListViewControl::wxMacDataViewDataBrowserListViewControl // Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID itemOneID, DataBrowserItemID itemTwoID, DataBrowserPropertyID sortProperty) { + DataBrowserSortOrder sortOrder; + + DataBrowserTableViewColumnIndex columnIndex; + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetPeer())); @@ -549,13 +568,13 @@ Boolean wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrow wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,false,_("Pointer to model not set correctly.")); if (sortProperty >= kMinPropertyID) { - // variable definition: - DataBrowserTableViewColumnIndex columnIndex; - wxCHECK_MSG(this->GetColumnIndex(sortProperty,&columnIndex) == noErr,false,_("Could not determine column index.")); - dataViewCtrlPtr->GetModel()->SetSortingColumn(columnIndex); } /* if */ - return static_cast(dataViewCtrlPtr->GetModel()->Compare(wxDataViewItem(reinterpret_cast(itemOneID)),wxDataViewItem(reinterpret_cast(itemTwoID))) < 0); + else + columnIndex = 0; + this->GetSortOrder(&sortOrder); + return static_cast(dataViewCtrlPtr->GetModel()->Compare(wxDataViewItem(reinterpret_cast(itemOneID)),wxDataViewItem(reinterpret_cast(itemTwoID)), + columnIndex,sortOrder != kDataBrowserOrderDecreasing) < 0); } /* wxMacDataViewDataBrowserListViewControl::DataBrowserCompareProc(DataBrowserItemID, DataBrowserItemID, DataBrowserPropertyID) */ void wxMacDataViewDataBrowserListViewControl::DataBrowserDrawItemProc(DataBrowserItemID itemID, DataBrowserPropertyID propertyID, DataBrowserItemState state, Rect const* rectangle, SInt16 bitDepth, Boolean colorDevice) @@ -617,75 +636,82 @@ OSStatus wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc( if (getValue) { // variable definitions: - DataBrowserTableViewColumnIndex columnIndex; - OSStatus errorStatus; - wxDataViewCtrl* dataViewCtrlPtr; - wxDataViewColumn* dataViewColumnPtr; + wxDataViewCtrl* dataViewCtrlPtr; dataViewCtrlPtr = dynamic_cast(this->GetPeer()); - 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.")); - errorStatus = this->GetColumnIndex(propertyID,&columnIndex); - wxCHECK_MSG(errorStatus == noErr,errorStatus,_("Could not determine column index")); - dataViewColumnPtr = dataViewCtrlPtr->GetColumn(columnIndex); - wxCHECK_MSG((dataViewColumnPtr != NULL) && (dataViewColumnPtr->GetRenderer() != NULL),errDataBrowserNotConfigured,_("There is no column or renderer for the specified column index.")); - switch (dataViewColumnPtr->GetRenderer()->GetPropertyType()) + 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 { - case kDataBrowserCheckboxType: - { - // variable definition: - ThemeButtonValue buttonValue; - - errorStatus = ::GetDataBrowserItemDataButtonValue(itemData,&buttonValue); - if (errorStatus == noErr) + // variable definitions: + DataBrowserTableViewColumnIndex columnIndex; + OSStatus errorStatus; + wxDataViewColumn* dataViewColumnPtr; + + wxCHECK_MSG(dataViewCtrlPtr->GetModel() != NULL,errDataBrowserNotConfigured,_("Pointer to model not set correctly.")); + errorStatus = this->GetColumnIndex(propertyID,&columnIndex); + wxCHECK_MSG(errorStatus == noErr,errorStatus,_("Could not determine column index")); + dataViewColumnPtr = dataViewCtrlPtr->GetColumn(columnIndex); + wxCHECK_MSG((dataViewColumnPtr != NULL) && (dataViewColumnPtr->GetRenderer() != NULL),errDataBrowserNotConfigured,_("There is no column or renderer for the specified column index.")); + switch (dataViewColumnPtr->GetRenderer()->GetPropertyType()) + { + case kDataBrowserCheckboxType: { - if (buttonValue == kThemeButtonOn) - { - // variable definition and initialization: - wxVariant modifiedData(true); + // variable definition: + ThemeButtonValue buttonValue; - return (dataViewCtrlPtr->GetModel()->SetValue(modifiedData,wxDataViewItem(reinterpret_cast(itemID)),static_cast(columnIndex)) ? OSStatus(noErr) : OSStatus(errDataBrowserNotConfigured)); - } /* if */ - else if (buttonValue == kThemeButtonOff) + errorStatus = ::GetDataBrowserItemDataButtonValue(itemData,&buttonValue); + if (errorStatus == noErr) { - // variable definition and initialization: - wxVariant modifiedData(false); - - return (dataViewCtrlPtr->GetModel()->SetValue(modifiedData,wxDataViewItem(reinterpret_cast(itemID)),static_cast(columnIndex)) ? OSStatus(noErr) : OSStatus(errDataBrowserNotConfigured)); + if (buttonValue == kThemeButtonOn) + { + // variable definition and initialization: + wxVariant modifiedData(true); + + return (dataViewCtrlPtr->GetModel()->SetValue(modifiedData,wxDataViewItem(reinterpret_cast(itemID)),static_cast(columnIndex)) ? OSStatus(noErr) : OSStatus(errDataBrowserNotConfigured)); + } /* if */ + else if (buttonValue == kThemeButtonOff) + { + // variable definition and initialization: + wxVariant modifiedData(false); + + return (dataViewCtrlPtr->GetModel()->SetValue(modifiedData,wxDataViewItem(reinterpret_cast(itemID)),static_cast(columnIndex)) ? OSStatus(noErr) : OSStatus(errDataBrowserNotConfigured)); + } /* if */ + else + return errDataBrowserInvalidPropertyData; } /* if */ else - return errDataBrowserInvalidPropertyData; - } /* if */ - else - return errorStatus; - } /* block */ - case kDataBrowserTextType: - { - // variable definitions: - CFStringRef stringReference; - - errorStatus = ::GetDataBrowserItemDataText(itemData,&stringReference); - if (errorStatus == noErr) + return errorStatus; + } /* block */ + case kDataBrowserTextType: { - // variable definitions and initializations: - wxMacCFStringHolder modifiedString(stringReference); - wxVariant modifiedData(modifiedString.AsString()); + // variable definitions: + CFStringRef stringReference; - if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData,wxDataViewItem(reinterpret_cast(itemID)),static_cast(columnIndex))) - return noErr; + errorStatus = ::GetDataBrowserItemDataText(itemData,&stringReference); + if (errorStatus == noErr) + { + // variable definitions and initializations: + wxMacCFStringHolder modifiedString(stringReference); + wxVariant modifiedData(modifiedString.AsString()); + + if (dataViewCtrlPtr->GetModel()->SetValue(modifiedData,wxDataViewItem(reinterpret_cast(itemID)),static_cast(columnIndex))) + return noErr; + else + return errDataBrowserNotConfigured; + } /* if */ else - return errDataBrowserNotConfigured; - } /* if */ - else - return errorStatus; - } /* block */ - default: - return errDataBrowserPropertyNotSupported; - } /* switch */ + return errorStatus; + } /* block */ + default: + return errDataBrowserPropertyNotSupported; + } /* switch */ + } /* if */ } /* if */ else { - if (propertyID >= kMinPropertyID) // in case of data columns set the data + if (propertyID >= kMinPropertyID) // in case data columns set the data { // variable definitions: DataBrowserTableViewColumnIndex columnIndex; @@ -706,10 +732,44 @@ OSStatus wxMacDataViewDataBrowserListViewControl::DataBrowserGetSetItemDataProc( dataViewColumnPtr->GetRenderer()->SetDataReference(itemData); dataViewColumnPtr->GetRenderer()->SetValue(variant); wxCHECK_MSG(dataViewColumnPtr->GetRenderer()->Render(),errDataBrowserNotConfigured,_("Rendering failed.")); + return noErr; } /* if */ else // react on special system requests switch (propertyID) { + case kDataBrowserContainerIsClosableProperty: + { + // variable definitions: + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetPeer())); + + 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))); + // finally send the equivalent wxWidget event: + dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); + // opening the container is allowed if not vetoed: + return ::SetDataBrowserItemDataBooleanValue(itemData,dataViewEvent.IsAllowed()); + } /* block */ + return noErr; + case kDataBrowserContainerIsOpenableProperty: + { + // variable definitions: + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetPeer())); + + 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))); + // 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: @@ -730,6 +790,23 @@ void wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(Da { switch (message) { + case kDataBrowserContainerClosed: + { + // variable definitions: + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetPeer())); + + if (dataViewCtrlPtr != NULL) // can become NULL when the window is being deleted (wxWidget has already disposed the data before receiving this event + { + // 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); + } /* if */ + } /* block */ + break; case kDataBrowserContainerOpened: { // variable definitions: @@ -737,6 +814,28 @@ void wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(Da wxCHECK_RET(dataViewCtrlPtr != NULL,_("Pointer to data view control not set correctly.")); dataViewCtrlPtr->AddChildrenLevel(wxDataViewItem(reinterpret_cast(itemID))); + // 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); + } /* block */ + break; + case kDataBrowserItemAdded: + { + // variable definitions: + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetPeer())); + + wxCHECK_RET(dataViewCtrlPtr != NULL,_("Pointer to data view control not set correctly.")); + // initialize wxWidget event: + wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_ADDED,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 kDataBrowserItemDoubleClicked: @@ -750,10 +849,27 @@ void wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(Da dataViewEvent.SetEventObject(dataViewCtrlPtr); dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast(itemID))); - // finally sent the equivalent wxWidget event: + // finally send the equivalent wxWidget event: dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); } /* block */ break; + case kDataBrowserItemRemoved: + { + // variable definitions: + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetPeer())); + + if (dataViewCtrlPtr != NULL) // can become NULL when the window is being deleted (wxWidget has already disposed the data before receiving this event + { + // initialize wxWidget event: + wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_DELETED,dataViewCtrlPtr->GetId()); // variable definition + + dataViewEvent.SetEventObject(dataViewCtrlPtr); + dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast(itemID))); + // finally send the equivalent wxWidget event: + dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); + } /* if */ + } /* block */ + break; case kDataBrowserItemSelected: { // variable definitions: @@ -765,7 +881,7 @@ void wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(Da dataViewEvent.SetEventObject(dataViewCtrlPtr); dataViewEvent.SetItem(wxDataViewItem(reinterpret_cast(itemID))); - // finally sent the equivalent wxWidget event: + // finally send the equivalent wxWidget event: dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); } /* block */ break; @@ -781,18 +897,23 @@ void wxMacDataViewDataBrowserListViewControl::DataBrowserItemNotificationProc(Da if ((this->GetSortOrder(&sortOrder) == noErr) && (this->GetColumnIndex(propertyID,&columnIndex) == noErr)) { // variable definition and initialization: - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetPeer())); - - if ( dataViewCtrlPtr->GetColumn(columnIndex)->IsSortOrderAscending() && (sortOrder == kDataBrowserOrderDecreasing) || - !(dataViewCtrlPtr->GetColumn(columnIndex)->IsSortOrderAscending()) && (sortOrder == kDataBrowserOrderIncreasing)) + wxDataViewColumn* columnPtr; + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->GetPeer())); + + wxCHECK_RET(dataViewCtrlPtr != NULL,_("Pointer to data vie wcontrol not set correctly.")); + 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(dataViewCtrlPtr->GetColumn(columnIndex)); - // finally sent the equivalent wxWidget event: + dataViewEvent.SetDataViewColumn(columnPtr); + // finally send the equivalent wxWidget event: dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); } /* if */ } /* if */ diff --git a/src/mac/carbon/dataview.cpp b/src/mac/carbon/dataview.cpp index 2d4085c91d..e72f733345 100644 --- a/src/mac/carbon/dataview.cpp +++ b/src/mac/carbon/dataview.cpp @@ -115,22 +115,8 @@ public: wxCHECK_MSG(item.IsOk(),false,_("Added item is invalid.")); - if (!(parent.IsOk()) && (this->m_dataViewControlPtr->AddItem(kDataBrowserNoItem, &itemID) == noErr) || - parent.IsOk() && (this->m_dataViewControlPtr->AddItem(reinterpret_cast(parent.GetID()),&itemID) == noErr)) - { - // variable definitions and initializations: - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->m_dataViewControlPtr->GetPeer())); - wxDataViewEvent dataViewEvent (wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_ADDED,dataViewCtrlPtr->GetId()); - - dataViewEvent.SetEventObject(dataViewCtrlPtr); - dataViewEvent.SetItem(item); - // sent the equivalent wxWidget event: - dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); - // done: - return true; - } /* if */ - else - return false; + return (!(parent.IsOk()) && (this->m_dataViewControlPtr->AddItem(kDataBrowserNoItem,&itemID) == noErr) || + parent.IsOk() && (this->m_dataViewControlPtr->AddItem(reinterpret_cast(parent.GetID()),&itemID) == noErr)); } /* ItemAdded(wxDataViewItem const&, wxDataViewItem const&) */ virtual bool ItemChanged(wxDataViewItem const& item) @@ -160,26 +146,24 @@ public: virtual bool ItemDeleted(wxDataViewItem const& parent, wxDataViewItem const& item) { - DataBrowserItemID itemID(reinterpret_cast(item.GetID())); - - - wxCHECK_MSG(item.IsOk(),false,_("Deleted item is invalid.")); - if (this->m_dataViewControlPtr->RemoveItem(reinterpret_cast(parent.GetID()),&itemID) == noErr) + if (item.IsOk()) { - // variable definitions and initializations: - wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->m_dataViewControlPtr->GetPeer())); - wxDataViewEvent dataViewEvent (wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_DELETED,dataViewCtrlPtr->GetId()); - - dataViewEvent.SetEventObject(dataViewCtrlPtr); - dataViewEvent.SetItem(item); - // sent the equivalent wxWidget event: - dataViewCtrlPtr->GetEventHandler()->ProcessEvent(dataViewEvent); - // done - return true; + // variable definition and initialization: + DataBrowserItemID itemID(reinterpret_cast(item.GetID())); + OSStatus errorStatus; + wxDataViewCtrl* dataViewCtrlPtr(dynamic_cast(this->m_dataViewControlPtr->GetPeer())); + + // 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); therefore, the control is informed that currently a deleting process + // is started and that variables can currently not be updated even when requested by the system: + dataViewCtrlPtr->SetDeleting(true); + errorStatus = this->m_dataViewControlPtr->RemoveItem(reinterpret_cast(parent.GetID()),&itemID); + dataViewCtrlPtr->SetDeleting(false); + return (errorStatus == noErr); } /* if */ else return false; - } /* ItemDeleted(wxDataViewItem const&) */ + } /* ItemDeleted(wxDataViewItem const&, wxDataViewItem const&) */ virtual bool ValueChanged(wxDataViewItem const& item, unsigned int col) { @@ -231,6 +215,11 @@ public: return false; } /* Cleared(void) */ + virtual void Resort(void) + { + this->m_dataViewControlPtr->Resort(); + } + protected: private: // @@ -679,6 +668,7 @@ IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumn,wxDataViewColumnBase) #pragma mark - void wxDataViewCtrl::Init(void) { + this->m_Deleting = false; this->m_macIsUserPane = false; this->m_NotifierPtr = NULL; this->m_cgContext = NULL; @@ -695,6 +685,7 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, this->m_peer = new wxMacDataViewDataBrowserListViewControl(this,pos,size,style); this->MacPostControlCreate(pos,size); + ::SetAutomaticControlDragTrackingEnabledForWindow(::GetControlOwner(this->m_peer->GetControlRef()),true); InstallControlEventHandler(this->m_peer->GetControlRef(),GetwxMacDataViewCtrlEventHandlerUPP(),GetEventTypeCount(eventList),eventList,this,NULL); @@ -711,7 +702,7 @@ bool wxDataViewCtrl::AppendColumn(wxDataViewColumn* dataViewColumnPtr) (dataViewColumnPtr->GetModelColumn() < this->GetModel()->GetColumnCount()),false,_("Column's model column has no equivalent in the associated model.")); if (this->wxDataViewCtrlBase::AppendColumn(dataViewColumnPtr)) { - // variable definition: + // variable definitions: DataBrowserPropertyID NewPropertyID; DataBrowserListViewColumnDesc columnDescription; wxMacCFStringHolder cfTitle(dataViewColumnPtr->GetTitle(),(this->m_font.Ok() ? this->m_font.GetEncoding() : wxLocale::GetSystemEncoding())); @@ -721,13 +712,17 @@ bool wxDataViewCtrl::AppendColumn(wxDataViewColumn* dataViewColumnPtr) wxCHECK_MSG(MacDataViewListCtrlPtr != NULL, false,_("m_peer is not or incorrectly initialized")); wxCHECK_MSG(MacDataViewListCtrlPtr->GetFreePropertyID(&NewPropertyID) == noErr,false,_("Maximum number of columns reached.")); dataViewColumnPtr->SetPropertyID(NewPropertyID); + if (dataViewColumnPtr->GetWidth() <= 0) + dataViewColumnPtr->SetWidth(wxDVC_DEFAULT_WIDTH); columnDescription.propertyDesc.propertyID = NewPropertyID; columnDescription.propertyDesc.propertyType = dataViewColumnPtr->GetRenderer()->GetPropertyType(); - columnDescription.propertyDesc.propertyFlags = kDataBrowserListViewSelectionColumn; + columnDescription.propertyDesc.propertyFlags = kDataBrowserListViewSelectionColumn; // make the column selectable if (dataViewColumnPtr->IsSortable()) columnDescription.propertyDesc.propertyFlags |= kDataBrowserListViewSortableColumn; - if (dataViewColumnPtr->IsResizeable()) +#if 0 + if (dataViewColumnPtr->IsMovable()) columnDescription.propertyDesc.propertyFlags |= kDataBrowserListViewMovableColumn; +#endif if (dataViewColumnPtr->GetRenderer()->GetMode() == wxDATAVIEW_CELL_EDITABLE) columnDescription.propertyDesc.propertyFlags |= kDataBrowserPropertyIsEditable; #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 @@ -740,8 +735,16 @@ bool wxDataViewCtrl::AppendColumn(wxDataViewColumn* dataViewColumnPtr) columnDescription.propertyDesc.propertyFlags |= kDataBrowserListViewNoGapForIconInHeaderButton; #endif columnDescription.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc; - columnDescription.headerBtnDesc.minimumWidth = 0; - columnDescription.headerBtnDesc.maximumWidth = 30000; + if (dataViewColumnPtr->IsResizable()) + { + columnDescription.headerBtnDesc.minimumWidth = 0; + columnDescription.headerBtnDesc.maximumWidth = 30000; + } /* if */ + else + { + columnDescription.headerBtnDesc.minimumWidth = dataViewColumnPtr->GetWidth(); + columnDescription.headerBtnDesc.maximumWidth = dataViewColumnPtr->GetWidth(); + } /* if */ columnDescription.headerBtnDesc.titleOffset = 0; columnDescription.headerBtnDesc.titleString = cfTitle; // we cannot directly use the wxMacCFStringHolder constructor call because then the CFStringRef is released // having called 'AddColumn' where the title (CFStringRef) is going to be used @@ -771,11 +774,11 @@ bool wxDataViewCtrl::AppendColumn(wxDataViewColumn* dataViewColumnPtr) wxCHECK_MSG(MacDataViewListCtrlPtr->AddColumn(&columnDescription,kDataBrowserListViewAppendColumn) == noErr,false,_("Column could not be added.")); // final adjustments for the layout: - if (dataViewColumnPtr->GetWidth() <= 0) - dataViewColumnPtr->SetWidth(wxDVC_DEFAULT_WIDTH); wxCHECK_MSG(MacDataViewListCtrlPtr->SetColumnWidth(NewPropertyID,dataViewColumnPtr->GetWidth()) == noErr,false,_("Column width could not be set.")); +#if 0 if (dataViewColumnPtr->IsSortable()) // if the current column is marked sortable this column will become the active sortable column, otherwise don't do anything MacDataViewListCtrlPtr->SetSortProperty(NewPropertyID); +#endif if (this->GetColumnCount()-1 == this->GetExpanderColumn()) // if the current column is marked expandable this column will become the active expandable column MacDataViewListCtrlPtr->SetDisclosureColumn(NewPropertyID,true); @@ -792,7 +795,57 @@ bool wxDataViewCtrl::AppendColumn(wxDataViewColumn* dataViewColumnPtr) return false; } /* wxDataViewCtrl::AppendColumn(wxDataViewColumn*) */ -wxDataViewItem wxDataViewCtrl::GetSelection(void) +bool wxDataViewCtrl::AssociateModel(wxDataViewModel* model) +{ + if (!wxDataViewCtrlBase::AssociateModel(model)) + return false; + + this->m_NotifierPtr = new wxMacDataViewModelNotifier(dynamic_cast(this->m_peer)); + model->AddNotifier(this->m_NotifierPtr); + + return true; +} /* wxDataViewCtrl::AssociateModel(wxDataViewModel*) */ + +void wxDataViewCtrl::EnsureVisible(wxDataViewItem const& item, wxDataViewColumn const* columnPtr) +{ + if (item.IsOk()) + { + // variable definition and initialization: + DataBrowserPropertyID propertyID; + wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(this->m_peer)); + + if (columnPtr != NULL) + propertyID = columnPtr->GetPropertyID(); + else + propertyID = kDataBrowserNoItem; + MacDataViewListCtrlPtr->RevealItem(reinterpret_cast(item.GetID()),propertyID,kDataBrowserRevealOnly); + } /* if */ +} /* wxDataViewCtrl::EnsureVisible(wxDataViewItem const&, wxDataViewColumn const*) */ + +wxRect wxDataViewCtrl::GetItemRect(wxDataViewItem const& item, wxDataViewColumn const* columnPtr) const +{ + if (item.IsOk() && (columnPtr != NULL)) + { + // variable definition: + Rect MacRectangle; + wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(this->m_peer)); + + if (MacDataViewListCtrlPtr->GetPartBounds(reinterpret_cast(item.GetID()),columnPtr->GetPropertyID(),kDataBrowserPropertyContentPart,&MacRectangle) == noErr) + { + // variable definition: + wxRect rectangle; + + ::wxMacNativeToRect(&MacRectangle,&rectangle); + return rectangle; + } /* if */ + else + return wxRect(); + } /* if */ + else + return wxRect(); +} /* wxDataViewCtrl::GetItemRect(wxDataViewItem const&, unsigned int) const */ + +wxDataViewItem wxDataViewCtrl::GetSelection(void) const { wxArrayDataBrowserItemID itemIDs; @@ -803,18 +856,118 @@ wxDataViewItem wxDataViewCtrl::GetSelection(void) return wxDataViewItem(reinterpret_cast(itemIDs[0])); else return wxDataViewItem(); -} /* wxDataViewCtrl::GetSelection(void) */ +} /* wxDataViewCtrl::GetSelection(void) const */ -bool wxDataViewCtrl::AssociateModel(wxDataViewModel* model) +int wxDataViewCtrl::GetSelections(wxDataViewItemArray& sel) const { - if (!wxDataViewCtrlBase::AssociateModel(model)) - return false; + size_t NoOfSelectedItems; + + wxArrayDataBrowserItemID itemIDs; - this->m_NotifierPtr = new wxMacDataViewModelNotifier(dynamic_cast(this->m_peer)); - model->AddNotifier(this->m_NotifierPtr); + wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(this->m_peer)); + + + NoOfSelectedItems = MacDataViewListCtrlPtr->GetSelectedItemIDs(itemIDs); + sel.Empty(); + sel.SetCount(NoOfSelectedItems); + for (size_t i=0; i(itemIDs[i])); + return static_cast(NoOfSelectedItems); +} /* wxDataViewCtrl::GetSelections(wxDataViewItemArray&) const */ + +void wxDataViewCtrl::HitTest(wxPoint const& point, wxDataViewItem& item, wxDataViewColumn*& columnPtr) const +{ + item = wxDataViewItem(); + columnPtr = NULL; +} /* wxDataViewCtrl::HitTest(wxPoint const&, wxDataViewItem&, wxDataViewColumn*&) const */ - return true; -} /* wxDataViewCtrl::AssociateModel(wxDataViewModel*) */ +bool wxDataViewCtrl::IsSelected(wxDataViewItem const& item) const +{ + wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(this->m_peer)); + + + return MacDataViewListCtrlPtr->IsItemSelected(reinterpret_cast(item.GetID())); +} /* wxDataViewCtrl::IsSelected(wxDataViewItem const&) const */ + +void wxDataViewCtrl::SelectAll(void) +{ + DataBrowserItemID* itemIDPtr; + + Handle handle(::NewHandle(0)); + + size_t NoOfItems; + + wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(this->m_peer)); + + + 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); +} /* wxDataViewCtrl::SelectAll(void) */ + +void wxDataViewCtrl::Select(wxDataViewItem const& item) +{ + if (item.IsOk()) + { + // variable definition and initialization: + DataBrowserItemID itemID(reinterpret_cast(item.GetID())); + wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(this->m_peer)); + + MacDataViewListCtrlPtr->SetSelectedItems(1,&itemID,kDataBrowserItemsAdd); + } /* if */ +} /* wxDataViewCtrl::Select(wxDataViewItem const&) */ + +void wxDataViewCtrl::SetSelections(wxDataViewItemArray const& sel) +{ + size_t const NoOfSelections = sel.GetCount(); + + DataBrowserItemID* itemIDs; + + wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(this->m_peer)); + + + itemIDs = new DataBrowserItemID[NoOfSelections]; + for (size_t i=0; i(sel[i].GetID()); + MacDataViewListCtrlPtr->SetSelectedItems(NoOfSelections,itemIDs,kDataBrowserItemsAssign); + delete[] itemIDs; +} /* wxDataViewCtrl::SetSelections(wxDataViewItemArray const&) */ + +void wxDataViewCtrl::Unselect(wxDataViewItem const& item) +{ + if (item.IsOk()) + { + // variable definition and initialization: + DataBrowserItemID itemID(reinterpret_cast(item.GetID())); + wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(this->m_peer)); + + MacDataViewListCtrlPtr->SetSelectedItems(1,&itemID,kDataBrowserItemsRemove); + } /* if */ +} /* wxDataViewCtrl::Unselect(wxDataViewItem const&) */ + +void wxDataViewCtrl::UnselectAll(void) +{ + DataBrowserItemID* itemIDPtr; + + Handle handle(::NewHandle(0)); + + size_t NoOfItems; + + wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast(this->m_peer)); + + + 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); +} /* wxDataViewCtrl::UnselectAll(void) */ // data handling: void wxDataViewCtrl::AddChildrenLevel(wxDataViewItem const& parentItem)