+ wxCArrayString chs(choices);
+
+ return Create( parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
+ style, validator, name );
+}
+
+bool wxListBox::Create( wxWindow *parent, wxWindowID id,
+ const wxPoint &pos, const wxSize &size,
+ int n, const wxString choices[],
+ long style, const wxValidator& validator,
+ const wxString &name )
+{
+ m_needParent = true;
+ m_acceptsFocus = true;
+ m_prevSelection = 0; // or -1 ??
+ m_blockEvent = false;
+
+ if (!PreCreation( parent, pos, size ) ||
+ !CreateBase( parent, id, pos, size, style, validator, name ))
+ {
+ wxFAIL_MSG( wxT("wxListBox creation failed") );
+ return false;
+ }
+
+ m_widget = gtk_scrolled_window_new( (GtkAdjustment*) NULL, (GtkAdjustment*) NULL );
+ if (style & wxLB_ALWAYS_SB)
+ {
+ gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS );
+ }
+ else
+ {
+ gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
+ }
+
+ m_list = GTK_LIST( gtk_list_new() );
+
+ GtkSelectionMode mode;
+ if (style & wxLB_MULTIPLE)
+ {
+ mode = GTK_SELECTION_MULTIPLE;
+ }
+ else if (style & wxLB_EXTENDED)
+ {
+ mode = GTK_SELECTION_EXTENDED;
+ }
+ else
+ {
+ // if style was 0 set single mode
+ m_windowStyle |= wxLB_SINGLE;
+ mode = GTK_SELECTION_SINGLE;
+ }
+
+ gtk_list_set_selection_mode( GTK_LIST(m_list), mode );
+
+ gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget), GTK_WIDGET(m_list) );
+
+ /* make list scroll when moving the focus down using cursor keys */
+ gtk_container_set_focus_vadjustment(
+ GTK_CONTAINER(m_list),
+ gtk_scrolled_window_get_vadjustment(
+ GTK_SCROLLED_WINDOW(m_widget)));
+
+ gtk_widget_show( GTK_WIDGET(m_list) );
+
+ gtk_signal_connect( GTK_OBJECT(m_list), "realize",
+ GTK_SIGNAL_FUNC(gtk_listbox_realized_callback), (gpointer) this );
+
+ if ( style & wxLB_SORT )
+ {
+ // this will change Append() behaviour
+ m_strings = new wxSortedArrayString;
+ }
+ else
+ {
+ m_strings = (wxSortedArrayString *)NULL;
+ }
+
+ Append(n, choices);
+
+ m_parent->DoAddChild( this );
+
+ PostCreation(size);
+ SetInitialSize(size); // need this too because this is a wxControlWithItems
+
+ return true;
+}
+
+wxListBox::~wxListBox()
+{
+ m_hasVMT = false;
+
+ Clear();
+
+ if (m_strings)
+ delete m_strings;
+}
+
+// ----------------------------------------------------------------------------
+// adding items
+// ----------------------------------------------------------------------------
+
+int wxListBox::DoInsertItems(const wxArrayStringsAdapter& items,
+ unsigned int pos,
+ void **clientData,
+ wxClientDataType type)
+{
+ wxCHECK_MSG( m_list != NULL, wxNOT_FOUND, wxT("invalid listbox") );
+
+ const unsigned count = GetCount();
+ wxCHECK_MSG( pos <= count, wxNOT_FOUND,
+ wxT("invalid index in wxListBox::InsertItems") );
+
+ // code elsewhere supposes we have as many items in m_clientList as items
+ // in the listbox
+ wxASSERT_MSG( m_clientList.GetCount() == count,
+ wxT("bug in client data management") );
+
+ InvalidateBestSize();
+
+ const unsigned numItems = items.GetCount();
+
+ for ( unsigned int n = 0; n < numItems; ++n, ++pos )
+ {
+ const wxString& item = items[n];
+
+ const unsigned idx = m_strings ? m_strings->Add(item)
+ : pos;
+
+ GtkAddItem(item, idx == GetCount() ? -1 : idx);
+
+ m_clientList.Insert(idx, NULL);
+
+ AssignNewItemClientData(idx, clientData, n, type);
+ }
+
+ wxASSERT_MSG( m_clientList.GetCount() == GetCount(),
+ wxT("bug in client data management") );
+
+ return pos - 1;
+}
+
+void wxListBox::GtkAddItem( const wxString &item, int pos )
+{
+ wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );