From: Włodzimierz Skiba Date: Fri, 19 Nov 2004 20:38:04 +0000 (+0000) Subject: Sorting fixes to wxUniv wxCombo/ListBox [part of bug #1040593]. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/e1d6e01c88876f9ff57056e2847eaaa91b074abb?ds=sidebyside Sorting fixes to wxUniv wxCombo/ListBox [part of bug #1040593]. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30652 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/changes.txt b/docs/changes.txt index 8d3876fed5..16be1cb0a8 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -55,6 +55,7 @@ wxUniv: - wxBU_... button align flags support - vertical notebook orientation support - 3rd state support for checkboxes +- wxLB_SORT and wxCB_SORT now cause case-insensitive sorting 2.5.3 diff --git a/include/wx/univ/listbox.h b/include/wx/univ/listbox.h index e47013efdd..d73708e06b 100644 --- a/include/wx/univ/listbox.h +++ b/include/wx/univ/listbox.h @@ -102,11 +102,13 @@ public: virtual void Clear(); virtual void Delete(int n); - virtual int GetCount() const { return (int)m_strings->GetCount(); } - virtual wxString GetString(int n) const { return (*m_strings)[n]; } + virtual int GetCount() const + { return (int)m_strings->GetCount(); } + virtual wxString GetString(int n) const + { return m_strings->Item(n); } virtual void SetString(int n, const wxString& s); virtual int FindString(const wxString& s) const - { return IsSorted() ? m_stringsSorted->Index(s) : m_strings->Index(s); } + { return m_strings->Index(s); } virtual bool IsSelected(int n) const { return m_selections.Index(n) != wxNOT_FOUND; } @@ -115,6 +117,7 @@ public: virtual int GetSelections(wxArrayInt& aSelections) const; protected: + virtual int DoAppendOnly(const wxString& item); virtual int DoAppend(const wxString& item); virtual void DoInsertItems(const wxArrayString& items, int pos); virtual void DoSetItems(const wxArrayString& items, void **clientData); @@ -238,14 +241,8 @@ protected: void UpdateItems(); // the array containing all items (it is sorted if the listbox has - // wxLB_SORT style). Note the evil trick: the pointers share the - // same location, hence we use m_strings when we don't care if the - // array is sorted or not, m_stringsSorted when we do - union - { - wxArrayString* m_strings; - wxSortedArrayString* m_stringsSorted; - }; + // wxLB_SORT style) + wxArrayString* m_strings; // this array contains the indices of the selected items (for the single // selection listboxes only the first element of it is used and contains diff --git a/src/univ/listbox.cpp b/src/univ/listbox.cpp index c586b15801..c7e00cee0c 100644 --- a/src/univ/listbox.cpp +++ b/src/univ/listbox.cpp @@ -141,10 +141,7 @@ bool wxListBox::Create(wxWindow *parent, SetWindow(this); - if ( style & wxLB_SORT ) - m_stringsSorted = new wxSortedArrayString; - else - m_strings = new wxArrayString; + m_strings = new wxArrayString; Set(n, choices); @@ -160,10 +157,7 @@ wxListBox::~wxListBox() // call this just to free the client data -- and avoid leaking memory DoClear(); - if ( IsSorted() ) - delete m_stringsSorted; - else - delete m_strings; + delete m_strings; m_strings = NULL; } @@ -172,13 +166,20 @@ wxListBox::~wxListBox() // adding/inserting strings // ---------------------------------------------------------------------------- -int wxListBox::DoAppend(const wxString& item) +int wxCMPFUNC_CONV wxListBoxSortNoCase(wxString* s1, wxString* s2) +{ + return s1->CmpNoCase(*s2); +} + +int wxListBox::DoAppendOnly(const wxString& item) { size_t index; if ( IsSorted() ) { - index = m_stringsSorted->Add(item); + m_strings->Add(item); + m_strings->Sort(wxListBoxSortNoCase); + index = m_strings->Index(item); } else { @@ -186,6 +187,13 @@ int wxListBox::DoAppend(const wxString& item) m_strings->Add(item); } + return index; +} + +int wxListBox::DoAppend(const wxString& item) +{ + size_t index = DoAppendOnly( item ); + m_itemsClientData.Insert(NULL, index); m_updateScrollbarY = true; @@ -243,20 +251,11 @@ void wxListBox::DoSetItems(const wxArrayString& items, void **clientData) return; m_strings->Alloc(count); + m_itemsClientData.Alloc(count); for ( size_t n = 0; n < count; n++ ) { - size_t index; - - if ( IsSorted() ) - { - index = m_stringsSorted->Add(items[n]); - } - else - { - index = m_strings->GetCount(); - m_strings->Add(items[n]); - } + size_t index = DoAppendOnly(items[n]); m_itemsClientData.Insert(clientData ? clientData[n] : NULL, index); } @@ -268,12 +267,16 @@ void wxListBox::DoSetItems(const wxArrayString& items, void **clientData) void wxListBox::SetString(int n, const wxString& s) { + wxCHECK_RET( !IsSorted(), _T("can't set string in sorted listbox") ); + + (*m_strings)[n] = s; + if ( HasHorzScrollbar() ) { // we need to update m_maxWidth as changing the string may cause the // horz scrollbar [dis]appear wxCoord width; - (*m_strings)[n] = s; + GetTextExtent(s, &width, NULL); // it might have increased if the new string is long @@ -289,10 +292,6 @@ void wxListBox::SetString(int n, const wxString& s) RefreshHorzScrollbar(); } } - else // no horz scrollbar - { - (*m_strings)[n] = s; - } RefreshItem(n); } @@ -785,7 +784,7 @@ wxCoord wxListBox::GetMaxWidth() const size_t count = m_strings->GetCount(); for ( size_t n = 0; n < count; n++ ) { - GetTextExtent((*m_strings)[n], &width, NULL); + GetTextExtent(this->GetString(n), &width, NULL); if ( width > m_maxWidth ) { self->m_maxWidth = width; @@ -843,7 +842,7 @@ wxSize wxListBox::DoGetBestClientSize() const for ( size_t n = 0; n < count; n++ ) { wxCoord w,h; - GetTextExtent((*m_strings)[n], &w, &h); + GetTextExtent(this->GetString(n), &w, &h); if ( w > width ) width = w; @@ -951,7 +950,7 @@ bool wxListBox::FindItem(const wxString& prefix, bool strictlyAfter) // loop over all items in the listbox for ( int item = first; item != last; item < count - 1 ? item++ : item = 0 ) { - if ( wxStrnicmp((*m_strings)[item], prefix, len) == 0 ) + if ( wxStrnicmp(this->GetString(item).c_str(), prefix, len) == 0 ) { SetCurrentItem(item);