+ m_list = NULL;
+#if wxUSE_CHECKLISTBOX
+ m_hasCheckBoxes = false;
+#endif // wxUSE_CHECKLISTBOX
+}
+
+bool wxListBox::Create( wxWindow *parent, wxWindowID id,
+ const wxPoint &pos, const wxSize &size,
+ const wxArrayString& choices,
+ long style, const wxValidator& validator,
+ const wxString &name )
+{
+ 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( NULL, 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 = 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();
+
+ 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() ? (unsigned) -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") );
+
+ GtkWidget *list_item;
+
+ wxString label(item);
+#if wxUSE_CHECKLISTBOX
+ if (m_hasCheckBoxes)
+ {
+ label.Prepend(wxCHECKLBOX_STRING);
+ }
+#endif // wxUSE_CHECKLISTBOX
+
+ list_item = gtk_list_item_new_with_label( wxGTK_CONV( label ) );
+
+ GList *gitem_list = g_list_alloc ();
+ gitem_list->data = list_item;
+
+ if (pos == -1)
+ gtk_list_append_items( GTK_LIST (m_list), gitem_list );
+ else
+ gtk_list_insert_items( GTK_LIST (m_list), gitem_list, pos );
+
+ gtk_signal_connect_after( GTK_OBJECT(list_item), "select",
+ GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this );
+
+ if (HasFlag(wxLB_MULTIPLE) || HasFlag(wxLB_EXTENDED))
+ gtk_signal_connect_after( GTK_OBJECT(list_item), "deselect",
+ GTK_SIGNAL_FUNC(gtk_listitem_deselect_callback), (gpointer)this );
+
+ gtk_signal_connect( GTK_OBJECT(list_item),
+ "button_press_event",
+ (GtkSignalFunc)gtk_listbox_button_press_callback,
+ (gpointer) this );
+
+ gtk_signal_connect_after( GTK_OBJECT(list_item),
+ "button_release_event",
+ (GtkSignalFunc)gtk_listbox_button_release_callback,
+ (gpointer) this );
+
+ gtk_signal_connect( GTK_OBJECT(list_item),
+ "key_press_event",
+ (GtkSignalFunc)gtk_listbox_key_press_callback,
+ (gpointer)this );
+
+
+ gtk_signal_connect( GTK_OBJECT(list_item), "focus_in_event",
+ GTK_SIGNAL_FUNC(gtk_listitem_focus_in_callback), (gpointer)this );
+
+ gtk_signal_connect( GTK_OBJECT(list_item), "focus_out_event",
+ GTK_SIGNAL_FUNC(gtk_listitem_focus_out_callback), (gpointer)this );
+
+ ConnectWidget( list_item );
+
+ if (GTK_WIDGET_REALIZED(m_widget))
+ {
+ gtk_widget_show( list_item );
+
+ gtk_widget_realize( list_item );
+ gtk_widget_realize( GTK_BIN(list_item)->child );
+
+#if wxUSE_TOOLTIPS
+ if (m_tooltip) m_tooltip->Apply( this );
+#endif
+ }
+
+ // Apply current widget style to the new list_item
+ GtkRcStyle *style = CreateWidgetStyle();
+ if (style)
+ {
+ gtk_widget_modify_style( GTK_WIDGET( list_item ), style );
+ GtkBin *bin = GTK_BIN( list_item );
+ gtk_widget_modify_style( GTK_WIDGET( bin->child ), style );
+ gtk_rc_style_unref( style );
+ }
+}
+
+// ----------------------------------------------------------------------------
+// deleting items
+// ----------------------------------------------------------------------------
+
+void wxListBox::DoClear()
+{
+ wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
+
+ gtk_list_clear_items( m_list, 0, (int)GetCount() );
+
+ if ( GTK_LIST(m_list)->last_focus_child != NULL )