diff --git a/include/wx/ctrlsub.h b/include/wx/ctrlsub.h index dba63cca7b..82a98dfdfb 100644 --- a/include/wx/ctrlsub.h +++ b/include/wx/ctrlsub.h @@ -296,8 +296,13 @@ public: void SetClientData(unsigned int n, void* clientData); void* GetClientData(unsigned int n) const; + // SetClientObject() takes ownership of the pointer, GetClientObject() + // returns it but keeps the ownership while DetachClientObject() expects + // the caller to delete the pointer and also resets the internally stored + // one to NULL for this item void SetClientObject(unsigned int n, wxClientData* clientData); wxClientData* GetClientObject(unsigned int n) const; + wxClientData* DetachClientObject(unsigned int n); // return the type of client data stored in this control: usually it just // returns m_clientDataItemsType but must be overridden in the controls diff --git a/interface/wx/ctrlsub.h b/interface/wx/ctrlsub.h index f23616e4e0..33652cb461 100644 --- a/interface/wx/ctrlsub.h +++ b/interface/wx/ctrlsub.h @@ -348,20 +348,45 @@ public: void Delete(unsigned int n); + /** + Returns the client object associated with the given item and transfers + its ownership to the caller. + + This method, unlike GetClientObject(), expects the caller to delete the + returned pointer. It also replaces the internally stored pointer with + @NULL, i.e. completely detaches the client object pointer from the + control. + + It's an error to call this method unless HasClientObjectData() returns + @true. + + @param n + The zero-based item index. + @return The associated client object pointer to be deleted by caller or + @NULL. + + @since 2.9.2 + */ + wxClientData *DetachClientObject(unsigned int n); + /** Returns true, if either untyped data (@c void*) or object data (wxClientData*) is associated with the items of the control. */ bool HasClientData() const; - + /** - Returns true, if object data (wxClientData*) - is associated with the items of the control. + Returns true, if object data is associated with the items of the + control. + + Object data pointers have the type @c wxClientData* instead of @c void* + and, importantly, are owned by the control, i.e. will be deleted by it, + unlike their untyped counterparts. */ bool HasClientObjectData() const; /** - Returns true, if untyped data (@c void*) + Returns true, if untyped data (@c void*) is associated with the items of the control. */ bool HasClientUntypedData() const; @@ -390,6 +415,10 @@ public: given item doesn't have any client data associated with it (but other items do). + Notice that the returned pointer is still owned by the control and will + be deleted by it, use DetachClientObject() if you want to remove the + pointer from the control. + @param n The zero-based position of the item. diff --git a/src/common/ctrlsub.cpp b/src/common/ctrlsub.cpp index d0a197da1f..68d4b1a591 100644 --- a/src/common/ctrlsub.cpp +++ b/src/common/ctrlsub.cpp @@ -191,6 +191,18 @@ wxClientData *wxItemContainer::GetClientObject(unsigned int n) const return static_cast(DoGetItemClientData(n)); } +wxClientData *wxItemContainer::DetachClientObject(unsigned int n) +{ + wxClientData * const data = GetClientObject(n); + if ( data ) + { + // reset the pointer as we don't own it any more + DoSetItemClientData(n, NULL); + } + + return data; +} + void wxItemContainer::SetClientData(unsigned int n, void *data) { if ( !HasClientData() ) diff --git a/src/common/rearrangectrl.cpp b/src/common/rearrangectrl.cpp index 5f6bc2bf06..6027fd2fb3 100644 --- a/src/common/rearrangectrl.cpp +++ b/src/common/rearrangectrl.cpp @@ -150,8 +150,8 @@ void wxRearrangeList::Swap(int pos1, int pos2) case wxClientData_Object: { - wxClientData * const dataTmp = GetClientObject(pos1); - SetClientObject(pos1, GetClientObject(pos2)); + wxClientData * const dataTmp = DetachClientObject(pos1); + SetClientObject(pos1, DetachClientObject(pos2)); SetClientObject(pos2, dataTmp); } break;