From 56b202f4613d7dfd5c96fd1085d4fa312d2ee092 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 6 May 2004 03:49:15 +0000 Subject: [PATCH] Add gtk_combo_box_get_active_text() convenience function. (#136372, Wed May 5 23:42:42 2004 Matthias Clasen * gtk/gtkcombobox.h: * gtk/gtkcombobox.c (gtk_combo_box_get_active_text): Add gtk_combo_box_get_active_text() convenience function. (#136372, Christian Neumeir, patch by Olivier Andrieu) --- ChangeLog | 7 ++ ChangeLog.pre-2-10 | 7 ++ ChangeLog.pre-2-6 | 7 ++ ChangeLog.pre-2-8 | 7 ++ docs/reference/ChangeLog | 4 + docs/reference/gtk/gtk-sections.txt | 1 + gtk/gtkcombobox.c | 151 +++++++++++++++++++++++++++- gtk/gtkcombobox.h | 12 +++ 8 files changed, 194 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 359460a5ab..0133b14e35 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Wed May 5 23:42:42 2004 Matthias Clasen + + * gtk/gtkcombobox.h: + * gtk/gtkcombobox.c (gtk_combo_box_get_active_text): + Add gtk_combo_box_get_active_text() convenience + function. (#136372, Christian Neumeir, patch by Olivier Andrieu) + 2004-05-05 Elijah Newren Changes to support do-not-focus-on-map hint in conjunction with diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 359460a5ab..0133b14e35 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,10 @@ +Wed May 5 23:42:42 2004 Matthias Clasen + + * gtk/gtkcombobox.h: + * gtk/gtkcombobox.c (gtk_combo_box_get_active_text): + Add gtk_combo_box_get_active_text() convenience + function. (#136372, Christian Neumeir, patch by Olivier Andrieu) + 2004-05-05 Elijah Newren Changes to support do-not-focus-on-map hint in conjunction with diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 359460a5ab..0133b14e35 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,10 @@ +Wed May 5 23:42:42 2004 Matthias Clasen + + * gtk/gtkcombobox.h: + * gtk/gtkcombobox.c (gtk_combo_box_get_active_text): + Add gtk_combo_box_get_active_text() convenience + function. (#136372, Christian Neumeir, patch by Olivier Andrieu) + 2004-05-05 Elijah Newren Changes to support do-not-focus-on-map hint in conjunction with diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 359460a5ab..0133b14e35 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,10 @@ +Wed May 5 23:42:42 2004 Matthias Clasen + + * gtk/gtkcombobox.h: + * gtk/gtkcombobox.c (gtk_combo_box_get_active_text): + Add gtk_combo_box_get_active_text() convenience + function. (#136372, Christian Neumeir, patch by Olivier Andrieu) + 2004-05-05 Elijah Newren Changes to support do-not-focus-on-map hint in conjunction with diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index 94e881e7fd..0c1bf683f2 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,7 @@ +Wed May 5 23:46:19 2004 Matthias Clasen + + * gtk/gtk-sections.txt: Add gtk_combo_box_get_active_text(). + Wed May 5 23:12:36 2004 Matthias Clasen * gdk-pixbuf/gdk-pixbuf-sections.txt: Add diff --git a/docs/reference/gtk/gtk-sections.txt b/docs/reference/gtk/gtk-sections.txt index 51c453a8de..12bee55c71 100644 --- a/docs/reference/gtk/gtk-sections.txt +++ b/docs/reference/gtk/gtk-sections.txt @@ -685,6 +685,7 @@ gtk_combo_box_append_text gtk_combo_box_insert_text gtk_combo_box_prepend_text gtk_combo_box_remove_text +gtk_combo_box_get_active_text gtk_combo_box_popup gtk_combo_box_popdown diff --git a/gtk/gtkcombobox.c b/gtk/gtkcombobox.c index 4a3d74f034..e76a7218aa 100644 --- a/gtk/gtkcombobox.c +++ b/gtk/gtkcombobox.c @@ -100,6 +100,10 @@ struct _GtkComboBoxPrivate gint width; GSList *cells; + GtkComboBoxSelectionFunc selection_func; + gpointer selection_data; + GDestroyNotify selection_destroy; + guint popup_in_progress : 1; guint destroying : 1; }; @@ -254,6 +258,8 @@ static void gtk_combo_box_set_active_internal (GtkComboBox *combo_box, static gboolean gtk_combo_box_key_press (GtkWidget *widget, GdkEventKey *event, gpointer data); +static void cell_view_sync_cells (GtkComboBox *combo_box, + GtkCellView *cell_view); /* listening to the model */ static void gtk_combo_box_model_row_inserted (GtkTreeModel *model, @@ -1089,6 +1095,40 @@ gtk_combo_box_list_position (GtkComboBox *combo_box, *y -= *height; } +static void +update_menu_sensitivity (GtkComboBox *combo_box) +{ + gint i, items; + GtkWidget *menu; + GList *children; + + if (!combo_box->priv->model || !combo_box->priv->selection_func) + return; + + items = gtk_tree_model_iter_n_children (combo_box->priv->model, NULL); + menu = combo_box->priv->popup_widget; + + children = gtk_container_get_children (GTK_CONTAINER (menu)); + for (i = 0; i < items; i++, children = children->next) + { + GtkTreePath *path; + GtkWidget *item; + gboolean sensitive; + + path = gtk_tree_path_new_from_indices (i, -1); + item = GTK_WIDGET (children->data); + + sensitive = (*combo_box->priv->selection_func) (combo_box->priv->model, + path, + i == combo_box->priv->active_item, + combo_box->priv->selection_data); + + gtk_widget_set_sensitive (item, sensitive); + + gtk_tree_path_free (path); + } +} + /** * gtk_combo_box_popup: * @combo_box: a #GtkComboBox @@ -1112,6 +1152,8 @@ gtk_combo_box_popup (GtkComboBox *combo_box) if (GTK_IS_MENU (combo_box->priv->popup_widget)) { + update_menu_sensitivity (combo_box); + gtk_menu_set_active (GTK_MENU (combo_box->priv->popup_widget), combo_box->priv->active_item); @@ -1886,7 +1928,9 @@ gtk_combo_box_menu_button_press (GtkWidget *widget, if (event->type == GDK_BUTTON_PRESS && event->button == 1) { combo_box->priv->popup_in_progress = TRUE; - + + update_menu_sensitivity (combo_box); + gtk_menu_set_active (GTK_MENU (combo_box->priv->popup_widget), combo_box->priv->active_item); @@ -2114,6 +2158,24 @@ gtk_combo_box_menu_row_changed (GtkTreeModel *model, * list style */ +static gboolean +gtk_combo_box_selection_func (GtkTreeSelection *selection, + GtkTreeModel *model, + GtkTreePath *path, + gboolean currently_selected, + gpointer data) +{ + GtkComboBox *combo_box = GTK_COMBO_BOX (data); + + if (combo_box->priv->selection_func) + return (*combo_box->priv->selection_func) (model, + path, + currently_selected, + combo_box->priv->selection_data); + + return TRUE; +} + static void gtk_combo_box_list_setup (GtkComboBox *combo_box) { @@ -2186,6 +2248,11 @@ gtk_combo_box_list_setup (GtkComboBox *combo_box) gtk_tree_view_column_pack_end (combo_box->priv->column, info->cell, info->expand); + if (info->func) + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo_box->priv->column), + info->cell, info->func, + info->func_data, NULL); + for (j = info->attributes; j; j = j->next->next) { gtk_tree_view_column_add_attribute (combo_box->priv->column, @@ -2208,6 +2275,11 @@ gtk_combo_box_list_setup (GtkComboBox *combo_box) } } + gtk_tree_selection_set_select_function (gtk_tree_view_get_selection (GTK_TREE_VIEW (combo_box->priv->tree_view)), + gtk_combo_box_selection_func, + combo_box, + NULL); + /* set sample/popup widgets */ gtk_combo_box_set_popup_widget (combo_box, combo_box->priv->tree_view); @@ -2352,6 +2424,26 @@ gtk_combo_box_list_button_released (GtkWidget *widget, return TRUE; } +static gboolean +is_selectable (GtkComboBox *combo_box, + gint index) +{ + GtkTreePath *path; + gboolean result = TRUE; + + path = gtk_tree_path_new_from_indices (index, -1); + + if (combo_box->priv->selection_func) + result = (*combo_box->priv->selection_func) (combo_box->priv->model, + path, + FALSE, + combo_box->priv->selection_data); + + gtk_tree_path_free (path); + + return result; +} + static gboolean gtk_combo_box_key_press (GtkWidget *widget, GdkEventKey *event, @@ -2376,22 +2468,34 @@ gtk_combo_box_key_press (GtkWidget *widget, case GDK_Down: case GDK_KP_Down: new_index = index + 1; + while (new_index < items && !is_selectable (combo_box, new_index)) + new_index++; + if (new_index == items) + new_index = index; break; case GDK_Up: case GDK_KP_Up: new_index = index - 1; + while (new_index >= 0 && !is_selectable (combo_box, new_index)) + new_index--; + if (new_index < 0) + new_index = index; break; case GDK_Page_Up: case GDK_KP_Page_Up: case GDK_Home: case GDK_KP_Home: new_index = 0; + while (new_index < items - 1 && !is_selectable (combo_box, new_index)) + new_index++; break; case GDK_Page_Down: case GDK_KP_Page_Down: case GDK_End: case GDK_KP_End: new_index = items - 1; + while (new_index > 0 && !is_selectable (combo_box, new_index)) + new_index--; break; default: return FALSE; @@ -2737,7 +2841,7 @@ gtk_combo_box_cell_layout_set_cell_data_func (GtkCellLayout *layout, if (combo_box->priv->column) gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo_box->priv->column), cell, func, func_data, NULL); - + menu = combo_box->priv->popup_widget; if (GTK_IS_MENU (menu)) { @@ -3394,6 +3498,33 @@ gtk_combo_box_remove_text (GtkComboBox *combo_box, gtk_list_store_remove (store, &iter); } +/** + * gtk_combo_box_get_active_text: + * @combo_box: A #GtkComboBox constructed with gtk_combo_box_new_text(). + * + * Returns the currently active string in @combo_box or %NULL if none + * is selected. Note that you can only use this function with combo + * boxes constructed with gtk_combo_box_new_text(). + * + * Returns: a newly allocated string containing the currently active text. + * + * Since: 2.6 + */ +gchar * +gtk_combo_box_get_active_text (GtkComboBox *combo_box) +{ + GtkTreeIter iter; + gchar *text = NULL; + + g_return_if_fail (GTK_IS_COMBO_BOX (combo_box)); + g_return_if_fail (GTK_IS_LIST_STORE (combo_box->priv->model)); + + if (gtk_combo_box_get_active_iter (combo_box, &iter)) + gtk_tree_model_get (combo_box->priv->model, &iter, + 0, &text, -1); + + return text; +} static gboolean gtk_combo_box_mnemonic_activate (GtkWidget *widget, @@ -3462,3 +3593,19 @@ gtk_combo_box_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } + +void +gtk_combo_box_set_selection_func (GtkComboBox *combo_box, + GtkComboBoxSelectionFunc func, + gpointer func_data, + GDestroyNotify destroy) +{ + g_return_if_fail (GTK_IS_COMBO_BOX (combo_box)); + + if (combo_box->priv->selection_destroy) + combo_box->priv->selection_destroy (combo_box->priv->selection_data); + + combo_box->priv->selection_func = func; + combo_box->priv->selection_data = func_data; + combo_box->priv->selection_destroy = destroy; +} diff --git a/gtk/gtkcombobox.h b/gtk/gtkcombobox.h index 758acefff3..c444bbec0a 100644 --- a/gtk/gtkcombobox.h +++ b/gtk/gtkcombobox.h @@ -98,11 +98,23 @@ void gtk_combo_box_prepend_text (GtkComboBox *combo_box, const gchar *text); void gtk_combo_box_remove_text (GtkComboBox *combo_box, gint position); +gchar *gtk_combo_box_get_active_text (GtkComboBox *combo_box); /* programmatic control */ void gtk_combo_box_popup (GtkComboBox *combo_box); void gtk_combo_box_popdown (GtkComboBox *combo_box); +/* insensitive items */ +typedef gboolean (*GtkComboBoxSelectionFunc) (GtkTreeModel *model, + GtkTreePath *path, + gboolean currently_selected, + gpointer data); + +void gtk_combo_box_set_selection_func (GtkComboBox *combo_box, + GtkComboBoxSelectionFunc func, + gpointer data, + GtkDestroyNotify destroy); + G_END_DECLS #endif /* __GTK_COMBO_BOX_H__ */