+ GtkComboBox* combobox = GTK_COMBO_BOX( m_widget );
+ return gtk_combo_box_get_active( combobox );
+}
+
+int wxComboBox::GetCurrentSelection() const
+{
+ wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid combobox") );
+
+ GtkComboBox* combobox = GTK_COMBO_BOX( m_widget );
+ return gtk_combo_box_get_active( combobox );
+}
+
+wxString wxComboBox::GetString(unsigned int n) const
+{
+ wxCHECK_MSG( m_widget != NULL, wxEmptyString, wxT("invalid combobox") );
+
+ wxString str;
+
+ GtkComboBox* combobox = GTK_COMBO_BOX( m_widget );
+ GtkTreeModel *model = gtk_combo_box_get_model( combobox );
+ GtkTreeIter iter;
+ if (gtk_tree_model_iter_nth_child (model, &iter, NULL, n))
+ {
+ GValue value = { 0, };
+ gtk_tree_model_get_value( model, &iter, 0, &value );
+ wxString tmp = wxGTK_CONV_BACK( g_value_get_string( &value ) );
+ g_value_unset( &value );
+ return tmp;
+ }
+
+ return str;
+}
+
+unsigned int wxComboBox::GetCount() const
+{
+ wxCHECK_MSG( m_widget != NULL, 0, wxT("invalid combobox") );
+
+ GtkComboBox* combobox = GTK_COMBO_BOX( m_widget );
+ GtkTreeModel* model = gtk_combo_box_get_model( combobox );
+ GtkTreeIter iter;
+ gtk_tree_model_get_iter_first( model, &iter );
+ if (!gtk_list_store_iter_is_valid(GTK_LIST_STORE(model), &iter ))
+ return 0;
+ unsigned int ret = 1;
+ while (gtk_tree_model_iter_next( model, &iter ))
+ ret++;
+ return ret;
+}
+
+void wxComboBox::SetSelection( int n )
+{
+ wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
+
+ DisableEvents();
+
+ GtkComboBox* combobox = GTK_COMBO_BOX( m_widget );
+ gtk_combo_box_set_active( combobox, n );
+
+ EnableEvents();
+}
+
+void wxComboBox::OnChar( wxKeyEvent &event )
+{
+ switch ( event.GetKeyCode() )
+ {
+ case WXK_RETURN:
+ if ( HasFlag(wxTE_PROCESS_ENTER) )
+ {
+ // GTK automatically selects an item if its in the list
+ wxCommandEvent eventEnter(wxEVT_COMMAND_TEXT_ENTER, GetId());
+ eventEnter.SetString( GetValue() );
+ eventEnter.SetInt( GetSelection() );
+ eventEnter.SetEventObject( this );
+
+ if ( HandleWindowEvent(eventEnter) )
+ {
+ // Catch GTK event so that GTK doesn't open the drop
+ // down list upon RETURN.
+ return;
+ }
+ }
+
+ // On enter key press, we must give a signal to default control,
+ // Otherwise, nothing happens when pressing Enter from inside a
+ // combo box in a dialog.
+ wxWindow *top_frame = wxGetTopLevelParent(this);
+ if( top_frame && GTK_IS_WINDOW(top_frame->m_widget) )
+ {
+ GtkWindow *window = GTK_WINDOW(top_frame->m_widget);
+ if ( window->default_widget )
+ gtk_widget_activate( window->default_widget );
+ }
+ break;
+ }
+
+ event.Skip();
+}
+
+void wxComboBox::DisableEvents()
+{
+ g_signal_handlers_block_by_func(GTK_BIN(m_widget)->child,
+ (gpointer)gtkcombobox_text_changed_callback, this);
+
+ g_signal_handlers_block_by_func(m_widget,
+ (gpointer)gtkcombobox_changed_callback, this);
+}
+
+void wxComboBox::EnableEvents()
+{
+ g_signal_handlers_unblock_by_func(GTK_BIN(m_widget)->child,
+ (gpointer)gtkcombobox_text_changed_callback, this);
+
+ g_signal_handlers_unblock_by_func(m_widget,
+ (gpointer)gtkcombobox_changed_callback, this);
+}
+
+GtkWidget* wxComboBox::GetConnectWidget()
+{
+ return GTK_WIDGET( GetEntry() );
+}
+
+GdkWindow *wxComboBox::GTKGetWindow(wxArrayGdkWindows& windows) const
+{
+ wxUnusedVar(windows);
+
+ return GetEntry()->text_area;
+}
+
+wxSize wxComboBox::DoGetBestSize() const
+{
+ wxSize ret( wxControl::DoGetBestSize() );
+
+ // we know better our horizontal extent: it depends on the longest string
+ // in the combobox
+ if ( m_widget )
+ {
+ int width;
+ unsigned int count = GetCount();
+ for ( unsigned int n = 0; n < count; n++ )
+ {
+ GetTextExtent(GetString(n), &width, NULL, NULL, NULL );
+ if ( width > ret.x )
+ ret.x = width;
+ }
+ }
+
+ // empty combobox should have some reasonable default size too
+ if ( ret.x < 100 )
+ ret.x = 100;
+
+ CacheBestSize(ret);
+ return ret;
+}
+
+// static
+wxVisualAttributes
+wxComboBox::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
+{
+ return GetDefaultAttributesFromGTKWidget(gtk_combo_box_entry_new, true);
+}
+
+// ----------------------------------------------------------------------------
+// standard event handling
+// ----------------------------------------------------------------------------