make wxChoice and wxComboBox sort in a case insensitive and locale adapted way, fixes #12351: Incorrect sort order in wxChoice / wxComboBox
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65342 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -17,6 +17,8 @@ class WXDLLIMPEXP_FWD_BASE wxArrayString;
|
|||||||
// wxChoice
|
// wxChoice
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class wxGtkCollatedArrayString;
|
||||||
|
|
||||||
class WXDLLIMPEXP_CORE wxChoice : public wxChoiceBase
|
class WXDLLIMPEXP_CORE wxChoice : public wxChoiceBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -84,7 +86,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
// this array is only used for controls with wxCB_SORT style, so only
|
// this array is only used for controls with wxCB_SORT style, so only
|
||||||
// allocate it if it's needed (hence using pointer)
|
// allocate it if it's needed (hence using pointer)
|
||||||
wxSortedArrayString *m_strings;
|
wxGtkCollatedArrayString *m_strings;
|
||||||
|
|
||||||
// contains the client data for the items
|
// contains the client data for the items
|
||||||
wxArrayPtrVoid m_clientData;
|
wxArrayPtrVoid m_clientData;
|
||||||
|
@@ -31,5 +31,90 @@ private:
|
|||||||
wxDECLARE_NO_COPY_CLASS(wxGtkString);
|
wxDECLARE_NO_COPY_CLASS(wxGtkString);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// list for sorting collated strings
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "wx/vector.h"
|
||||||
|
#include "wx/sharedptr.h"
|
||||||
|
|
||||||
|
class wxGtkCollatableString
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxGtkCollatableString( const wxString &label, gchar *key )
|
||||||
|
{
|
||||||
|
m_label = label;
|
||||||
|
m_key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
~wxGtkCollatableString()
|
||||||
|
{
|
||||||
|
if (m_key)
|
||||||
|
g_free( m_key );
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString m_label;
|
||||||
|
gchar *m_key;
|
||||||
|
};
|
||||||
|
|
||||||
|
class wxGtkCollatedArrayString
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxGtkCollatedArrayString() { }
|
||||||
|
|
||||||
|
int Add( const wxString &new_label )
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
gchar *new_key_lower = g_utf8_casefold( new_label.utf8_str(), -1);
|
||||||
|
gchar *new_key = g_utf8_collate_key( new_key_lower, -1);
|
||||||
|
g_free( new_key_lower );
|
||||||
|
|
||||||
|
wxSharedPtr<wxGtkCollatableString> new_ptr( new wxGtkCollatableString( new_label, new_key ) );
|
||||||
|
|
||||||
|
wxVector< wxSharedPtr<wxGtkCollatableString> >::iterator iter;
|
||||||
|
for (iter = m_list.begin(); iter != m_list.end(); ++iter)
|
||||||
|
{
|
||||||
|
wxSharedPtr<wxGtkCollatableString> ptr = *iter;
|
||||||
|
|
||||||
|
gchar *key = ptr->m_key;
|
||||||
|
if (strcmp(key,new_key) > 0)
|
||||||
|
{
|
||||||
|
m_list.insert( iter, new_ptr );
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
index ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_list.push_back( new_ptr );
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetCount()
|
||||||
|
{
|
||||||
|
return m_list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString At( size_t index )
|
||||||
|
{
|
||||||
|
return m_list[index]->m_label;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
m_list.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveAt( size_t index )
|
||||||
|
{
|
||||||
|
m_list.erase( m_list.begin() + index );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxVector< wxSharedPtr<wxGtkCollatableString> > m_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // _WX_GTK_PRIVATE_STRING_H_
|
#endif // _WX_GTK_PRIVATE_STRING_H_
|
||||||
|
|
||||||
|
@@ -75,7 +75,7 @@ bool wxChoice::Create( wxWindow *parent, wxWindowID id,
|
|||||||
{
|
{
|
||||||
// if our m_strings != NULL, Append() will check for it and insert
|
// if our m_strings != NULL, Append() will check for it and insert
|
||||||
// items in the correct order
|
// items in the correct order
|
||||||
m_strings = new wxSortedArrayString;
|
m_strings = new wxGtkCollatedArrayString;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_widget = gtk_combo_box_new_text();
|
m_widget = gtk_combo_box_new_text();
|
||||||
@@ -140,9 +140,9 @@ int wxChoice::DoInsertItems(const wxArrayStringsAdapter & items,
|
|||||||
n = pos + i;
|
n = pos + i;
|
||||||
// If sorted, use this wxSortedArrayStrings to determine
|
// If sorted, use this wxSortedArrayStrings to determine
|
||||||
// the right insertion point
|
// the right insertion point
|
||||||
if(m_strings)
|
if (m_strings)
|
||||||
n = m_strings->Add(items[i]);
|
n = m_strings->Add(items[i]);
|
||||||
|
|
||||||
GTKInsertComboBoxTextItem( n, items[i] );
|
GTKInsertComboBoxTextItem( n, items[i] );
|
||||||
|
|
||||||
m_clientData.Insert( NULL, n );
|
m_clientData.Insert( NULL, n );
|
||||||
|
@@ -118,7 +118,7 @@ bool wxComboBox::Create( wxWindow *parent, wxWindowID id, const wxString& value,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (HasFlag(wxCB_SORT))
|
if (HasFlag(wxCB_SORT))
|
||||||
m_strings = new wxSortedArrayString();
|
m_strings = new wxGtkCollatedArrayString();
|
||||||
|
|
||||||
GTKCreateComboBoxWidget();
|
GTKCreateComboBoxWidget();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user