From 131b1fba9dbedc86a0b5d7861ca374800f3ad40d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 16 Sep 2007 23:12:27 +0000 Subject: [PATCH] fix access to client data of wxComboBox in wxUniv by virtualizing access to wxControlWithItems::m_clientDataItemsType git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@48728 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/ctrlsub.h | 49 +++++++++++++++++++++++++++----------- include/wx/univ/combobox.h | 10 ++++++++ src/common/ctrlsub.cpp | 23 +++++++++--------- src/generic/odcombo.cpp | 3 ++- src/univ/combobox.cpp | 11 +++++++-- 5 files changed, 67 insertions(+), 29 deletions(-) diff --git a/include/wx/ctrlsub.h b/include/wx/ctrlsub.h index 0393859bb5..c71a878352 100644 --- a/include/wx/ctrlsub.h +++ b/include/wx/ctrlsub.h @@ -121,7 +121,7 @@ private: int AppendItems(const wxArrayStringsAdapter& items, void **clientData) { - wxASSERT_MSG( m_clientDataItemsType != wxClientData_Object, + wxASSERT_MSG( GetClientDataType() != wxClientData_Object, _T("can't mix different types of client data") ); return AppendItems(items, clientData, wxClientData_Void); @@ -130,7 +130,7 @@ private: int AppendItems(const wxArrayStringsAdapter& items, wxClientData **clientData) { - wxASSERT_MSG( m_clientDataItemsType != wxClientData_Void, + wxASSERT_MSG( GetClientDataType() != wxClientData_Void, _T("can't mix different types of client data") ); return AppendItems(items, wx_reinterpret_cast(void **, clientData), @@ -166,7 +166,7 @@ private: unsigned int pos, void **clientData) { - wxASSERT_MSG( m_clientDataItemsType != wxClientData_Object, + wxASSERT_MSG( GetClientDataType() != wxClientData_Object, _T("can't mix different types of client data") ); return InsertItems(items, pos, clientData, wxClientData_Void); @@ -176,7 +176,7 @@ private: unsigned int pos, wxClientData **clientData) { - wxASSERT_MSG( m_clientDataItemsType != wxClientData_Void, + wxASSERT_MSG( GetClientDataType() != wxClientData_Void, _T("can't mix different types of client data") ); return InsertItems(items, pos, @@ -280,6 +280,16 @@ public: void Delete(unsigned int pos); + // various accessors + // ----------------- + + // The control may maintain its items in a sorted order in which case + // items are automatically inserted at the right position when they are + // inserted or appended. Derived classes have to override this method if + // they implement sorting, typically by returning HasFlag(wxXX_SORT) + virtual bool IsSorted() const { return false; } + + // client data stuff // ----------------- @@ -289,19 +299,23 @@ public: void SetClientObject(unsigned int n, wxClientData* clientData); wxClientData* GetClientObject(unsigned int n) const; + // return the type of client data stored in this control: usually it just + // returns m_clientDataItemsType but must be overridden in the controls + // which delegate their client data storage to another one (e.g. wxChoice + // in wxUniv which stores data in wxListBox which it uses anyhow); don't + // forget to override SetClientDataType() if you override this one + // + // NB: for this to work no code should ever access m_clientDataItemsType + // directly but only via this function! + virtual wxClientDataType GetClientDataType() const + { return m_clientDataItemsType; } + bool HasClientData() const - { return m_clientDataItemsType != wxClientData_None; } + { return GetClientDataType() != wxClientData_None; } bool HasClientObjectData() const - { return m_clientDataItemsType == wxClientData_Object; } + { return GetClientDataType() == wxClientData_Object; } bool HasClientUntypedData() const - { return m_clientDataItemsType == wxClientData_Void; } - - - // The control may maintain its items in a sorted order in which case - // items are automatically inserted at the right position when they are - // inserted or appended. Derived classes have to override this method if - // they implement sorting, typically by returning HasFlag(wxXX_SORT) - virtual bool IsSorted() const { return false; } + { return GetClientDataType() == wxClientData_Void; } protected: // there is usually no need to override this method but you can do it if it @@ -364,7 +378,14 @@ protected: // set it to NULL (must only be called if HasClientObjectData()) void ResetItemClientObject(unsigned int n); + // set the type of the client data stored in this control: override this if + // you override GetClientDataType() + virtual void SetClientDataType(wxClientDataType clientDataItemsType) + { + m_clientDataItemsType = clientDataItemsType; + } +private: // the type of the client data for the items wxClientDataType m_clientDataItemsType; }; diff --git a/include/wx/univ/combobox.h b/include/wx/univ/combobox.h index 48fc4225f4..a93f33a298 100644 --- a/include/wx/univ/combobox.h +++ b/include/wx/univ/combobox.h @@ -142,6 +142,15 @@ public: return GetStdInputHandler(handlerDef); } + // we delegate our client data handling to wxListBox which we use for the + // items, so override this and other methods dealing with the client data + virtual wxClientDataType GetClientDataType() const + { + return GetLBox()->GetClientDataType(); + } + + virtual void SetClientDataType(wxClientDataType clientDataItemsType); + protected: virtual int DoInsertItems(const wxArrayStringsAdapter& items, unsigned int pos, @@ -150,6 +159,7 @@ protected: virtual void DoSetItemClientData(unsigned int n, void* clientData); virtual void* DoGetItemClientData(unsigned int n) const; + // common part of all ctors void Init(); diff --git a/src/common/ctrlsub.cpp b/src/common/ctrlsub.cpp index ec05cae146..05440cd78f 100644 --- a/src/common/ctrlsub.cpp +++ b/src/common/ctrlsub.cpp @@ -102,7 +102,7 @@ void wxItemContainer::Clear() ResetItemClientObject(i); } - m_clientDataItemsType = wxClientData_None; + SetClientDataType(wxClientData_None); DoClear(); } @@ -118,7 +118,7 @@ void wxItemContainer::Delete(unsigned int pos) if ( IsEmpty() ) { - m_clientDataItemsType = wxClientData_None; + SetClientDataType(wxClientData_None); } } @@ -162,23 +162,22 @@ wxItemContainer::DoInsertOneItem(const wxString& WXUNUSED(item), void wxItemContainer::SetClientObject(unsigned int n, wxClientData *data) { - wxASSERT_MSG( m_clientDataItemsType == wxClientData_Object || - m_clientDataItemsType == wxClientData_None, + wxASSERT_MSG( !HasClientUntypedData(), wxT("can't have both object and void client data") ); - if ( m_clientDataItemsType == wxClientData_Object ) + if ( HasClientObjectData() ) { wxClientData * clientDataOld = wx_static_cast(wxClientData *, DoGetItemClientData(n)); if ( clientDataOld ) delete clientDataOld; } - else // m_clientDataItemsType == wxClientData_None + else // didn't have any client data so far { // now we have object client data DoInitItemClientData(); - m_clientDataItemsType = wxClientData_Object; + SetClientDataType(wxClientData_Object); } DoSetItemClientData(n, data); @@ -186,7 +185,7 @@ void wxItemContainer::SetClientObject(unsigned int n, wxClientData *data) wxClientData *wxItemContainer::GetClientObject(unsigned int n) const { - wxCHECK_MSG( m_clientDataItemsType == wxClientData_Object, NULL, + wxCHECK_MSG( HasClientObjectData(), NULL, wxT("this window doesn't have object client data") ); return wx_static_cast(wxClientData *, DoGetItemClientData(n)); @@ -194,13 +193,13 @@ wxClientData *wxItemContainer::GetClientObject(unsigned int n) const void wxItemContainer::SetClientData(unsigned int n, void *data) { - if ( m_clientDataItemsType == wxClientData_None ) + if ( !HasClientData() ) { DoInitItemClientData(); - m_clientDataItemsType = wxClientData_Void; + SetClientDataType(wxClientData_Void); } - wxASSERT_MSG( m_clientDataItemsType == wxClientData_Void, + wxASSERT_MSG( HasClientUntypedData(), wxT("can't have both object and void client data") ); DoSetItemClientData(n, data); @@ -208,7 +207,7 @@ void wxItemContainer::SetClientData(unsigned int n, void *data) void *wxItemContainer::GetClientData(unsigned int n) const { - wxCHECK_MSG( m_clientDataItemsType == wxClientData_Void, NULL, + wxCHECK_MSG( HasClientUntypedData(), NULL, wxT("this window doesn't have void client data") ); return DoGetItemClientData(n); diff --git a/src/generic/odcombo.cpp b/src/generic/odcombo.cpp index cecfb1ff2d..0df20a054b 100644 --- a/src/generic/odcombo.cpp +++ b/src/generic/odcombo.cpp @@ -1028,7 +1028,8 @@ void wxOwnerDrawnComboBox::DoSetItemClientData(unsigned int n, void* clientData) { EnsurePopupControl(); - GetVListBoxComboPopup()->SetItemClientData(n,clientData,m_clientDataItemsType); + GetVListBoxComboPopup()->SetItemClientData(n, clientData, + GetClientDataType()); } void* wxOwnerDrawnComboBox::DoGetItemClientData(unsigned int n) const diff --git a/src/univ/combobox.cpp b/src/univ/combobox.cpp index 1ca6ffd795..dadd741eae 100644 --- a/src/univ/combobox.cpp +++ b/src/univ/combobox.cpp @@ -92,6 +92,8 @@ protected: void OnLeftUp(wxMouseEvent& event); private: + friend class wxComboBox; // it accesses our DoGetItemClientData() + DECLARE_EVENT_TABLE() }; @@ -410,6 +412,11 @@ int wxComboBox::GetSelection() const #endif } +void wxComboBox::SetClientDataType(wxClientDataType clientDataItemsType) +{ + GetLBox()->SetClientDataType(clientDataItemsType); +} + int wxComboBox::DoInsertItems(const wxArrayStringsAdapter & items, unsigned int pos, void **clientData, wxClientDataType type) @@ -419,12 +426,12 @@ int wxComboBox::DoInsertItems(const wxArrayStringsAdapter & items, void wxComboBox::DoSetItemClientData(unsigned int n, void* clientData) { - GetLBox()->SetClientData(n, clientData); + GetLBox()->DoSetItemClientData(n, clientData); } void *wxComboBox::DoGetItemClientData(unsigned int n) const { - return GetLBox()->GetClientData(n); + return GetLBox()->DoGetItemClientData(n); } bool wxComboBox::IsEditable() const -- 2.45.2