Commit 92232455 authored by Ryan Lortie's avatar Ryan Lortie

Bug 619148 - "active ID" properties (GtkComboBox)

Based on a patch by Matthias, add an "active-id" property for
GtkComboBox and add some convenience API for GtkComboBoxText.

Also, add a test case to gtk-demo.
parent 781d4faf
......@@ -437,7 +437,26 @@ do_combobox (GtkWidget *do_widget)
gtk_container_remove (GTK_CONTAINER (combo), gtk_bin_get_child (GTK_BIN (combo)));
gtk_container_add (GTK_CONTAINER (combo), entry);
/* A combobox with string IDs */
frame = gtk_frame_new ("String IDs");
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_set_border_width (GTK_CONTAINER (box), 5);
gtk_container_add (GTK_CONTAINER (frame), box);
combo = gtk_combo_box_text_new ();
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "never", "Not visible");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "when-active", "Visible when active");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "always", "Always visible");
gtk_container_add (GTK_CONTAINER (box), combo);
entry = gtk_entry_new ();
g_object_bind_property (combo, "active-id",
entry, "text",
G_BINDING_BIDIRECTIONAL);
gtk_container_add (GTK_CONTAINER (box), entry);
}
if (!gtk_widget_get_visible (window))
......
......@@ -801,6 +801,10 @@ gtk_combo_box_get_active
gtk_combo_box_set_active
gtk_combo_box_get_active_iter
gtk_combo_box_set_active_iter
gtk_combo_box_get_id_column
gtk_combo_box_set_id_column
gtk_combo_box_get_active_id
gtk_combo_box_set_active_id
gtk_combo_box_get_model
gtk_combo_box_set_model
gtk_combo_box_popup_for_device
......@@ -840,9 +844,12 @@ gtk_combo_box_get_type
GtkComboBoxText
gtk_combo_box_text_new
gtk_combo_box_text_new_with_entry
gtk_combo_box_text_append
gtk_combo_box_text_prepend
gtk_combo_box_text_insert
gtk_combo_box_text_append_text
gtk_combo_box_text_insert_text
gtk_combo_box_text_prepend_text
gtk_combo_box_text_insert_text
gtk_combo_box_text_remove
gtk_combo_box_text_remove_all
gtk_combo_box_text_get_active_text
......
......@@ -490,6 +490,7 @@ gtk_color_selection_set_previous_alpha
gtk_color_selection_set_previous_color
gtk_color_selection_set_previous_rgba
gtk_combo_box_get_active
gtk_combo_box_get_active_id
gtk_combo_box_get_active_iter
gtk_combo_box_get_add_tearoffs
gtk_combo_box_get_button_sensitivity
......@@ -497,6 +498,7 @@ gtk_combo_box_get_column_span_column
gtk_combo_box_get_entry_text_column
gtk_combo_box_get_focus_on_click
gtk_combo_box_get_has_entry
gtk_combo_box_get_id_column
gtk_combo_box_get_model
gtk_combo_box_get_popup_accessible
gtk_combo_box_get_popup_fixed_width
......@@ -513,24 +515,29 @@ gtk_combo_box_popdown
gtk_combo_box_popup
gtk_combo_box_popup_for_device
gtk_combo_box_set_active
gtk_combo_box_set_active_id
gtk_combo_box_set_active_iter
gtk_combo_box_set_add_tearoffs
gtk_combo_box_set_button_sensitivity
gtk_combo_box_set_column_span_column
gtk_combo_box_set_entry_text_column
gtk_combo_box_set_focus_on_click
gtk_combo_box_set_id_column
gtk_combo_box_set_model
gtk_combo_box_set_popup_fixed_width
gtk_combo_box_set_row_separator_func
gtk_combo_box_set_row_span_column
gtk_combo_box_set_title
gtk_combo_box_set_wrap_width
gtk_combo_box_text_append
gtk_combo_box_text_append_text
gtk_combo_box_text_get_active_text
gtk_combo_box_text_get_type G_GNUC_CONST
gtk_combo_box_text_insert
gtk_combo_box_text_insert_text
gtk_combo_box_text_new
gtk_combo_box_text_new_with_entry
gtk_combo_box_text_prepend
gtk_combo_box_text_prepend_text
gtk_combo_box_text_remove
gtk_combo_box_text_remove_all
......
......@@ -143,6 +143,8 @@ struct _GtkComboBoxPrivate
gint text_column;
GtkCellRenderer *text_renderer;
gint id_column;
GSList *cells;
guint popup_in_progress : 1;
......@@ -245,7 +247,9 @@ enum {
PROP_EDITING_CANCELED,
PROP_HAS_ENTRY,
PROP_ENTRY_TEXT_COLUMN,
PROP_POPUP_FIXED_WIDTH
PROP_POPUP_FIXED_WIDTH,
PROP_ID_COLUMN,
PROP_ACTIVE_ID
};
static guint combo_box_signals[LAST_SIGNAL] = {0,};
......@@ -948,6 +952,38 @@ gtk_combo_box_class_init (GtkComboBoxClass *klass)
-1, G_MAXINT, -1,
GTK_PARAM_READWRITE));
/**
* GtkComboBox:id-column:
*
* The column in the combo box's model that provides string
* IDs for the values in the model, if != -1.
*
* Since: 3.0
*/
g_object_class_install_property (object_class,
PROP_ID_COLUMN,
g_param_spec_int ("id-column",
P_("ID Column"),
P_("The column in the combo box's model that provides "
"string IDs for the values in the model"),
-1, G_MAXINT, -1,
GTK_PARAM_READWRITE));
/**
* GtkComboBox:active-id:
*
* The value of the ID column of the active row.
*
* Since: 3.0
*/
g_object_class_install_property (object_class,
PROP_ACTIVE_ID,
g_param_spec_string ("active-id",
P_("Active id"),
P_("The value of the id column "
"for the active row"),
NULL, GTK_PARAM_READWRITE));
/**
* GtkComboBox:popup-fixed-width:
*
......@@ -1077,6 +1113,7 @@ gtk_combo_box_init (GtkComboBox *combo_box)
priv->text_column = -1;
priv->text_renderer = NULL;
priv->id_column = -1;
gtk_combo_box_check_appearance (combo_box);
}
......@@ -1168,6 +1205,14 @@ gtk_combo_box_set_property (GObject *object,
gtk_combo_box_set_entry_text_column (combo_box, g_value_get_int (value));
break;
case PROP_ID_COLUMN:
gtk_combo_box_set_id_column (combo_box, g_value_get_int (value));
break;
case PROP_ACTIVE_ID:
gtk_combo_box_set_active_id (combo_box, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
......@@ -1245,6 +1290,14 @@ gtk_combo_box_get_property (GObject *object,
g_value_set_int (value, priv->text_column);
break;
case PROP_ID_COLUMN:
g_value_set_int (value, priv->id_column);
break;
case PROP_ACTIVE_ID:
g_value_set_string (value, gtk_combo_box_get_active_id (combo_box));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
......@@ -5200,6 +5253,8 @@ gtk_combo_box_set_active_internal (GtkComboBox *combo_box,
g_signal_emit (combo_box, combo_box_signals[CHANGED], 0);
g_object_notify (G_OBJECT (combo_box), "active");
if (combo_box->priv->id_column >= 0)
g_object_notify (G_OBJECT (combo_box), "active-id");
}
......@@ -6588,3 +6643,157 @@ gtk_combo_box_get_preferred_height_for_width (GtkWidget *widget,
if (natural_size)
*natural_size = nat_height;
}
/**
* gtk_combo_box_set_id_column:
* @combo_box: A #GtkComboBox
* @id_column: A column in @model to get string IDs for values from
*
* Sets the model column which @combo_box should use to get string IDs
* for values from. The column @id_column in the model of @combo_box
* must be of type %G_TYPE_STRING.
*
* Since: 3.0
*/
void
gtk_combo_box_set_id_column (GtkComboBox *combo_box,
gint id_column)
{
GtkComboBoxPrivate *priv = combo_box->priv;
GtkTreeModel *model;
g_return_if_fail (GTK_IS_COMBO_BOX (combo_box));
if (id_column != priv->id_column)
{
model = gtk_combo_box_get_model (combo_box);
g_return_if_fail (id_column >= 0);
g_return_if_fail (model == NULL ||
id_column < gtk_tree_model_get_n_columns (model));
priv->id_column = id_column;
g_object_notify (G_OBJECT (combo_box), "id-column");
g_object_notify (G_OBJECT (combo_box), "active-id");
}
}
/**
* gtk_combo_box_get_id_column:
* @combo_box: A #GtkComboBox
*
* Returns the column which @combo_box is using to get string IDs
* for values from.
*
* Return value: A column in the data source model of @combo_box.
*
* Since: 3.0
*/
gint
gtk_combo_box_get_id_column (GtkComboBox *combo_box)
{
g_return_val_if_fail (GTK_IS_COMBO_BOX (combo_box), 0);
return combo_box->priv->id_column;
}
/**
* gtk_combo_box_get_active_id:
* @combo_box: a #GtkComboBox
*
* Returns the ID of the active row of @combo_box. This value is taken
* from the active row and the column specified by the 'id-column'
* property of @combo_box (see gtk_combo_box_set_id_column()).
*
* The returned value is an interned string which means that you can
* compare the pointer by value to other interned strings and that you
* must not free it.
*
* If the 'id-column' property of @combo_box is not set or if no row is
* selected then %NULL is returned.
*
* Return value: the ID of the active row, or %NULL
*
* Since: 3.0
**/
const gchar *
gtk_combo_box_get_active_id (GtkComboBox *combo_box)
{
GtkTreeModel *model;
GtkTreeIter iter;
gint column;
g_return_val_if_fail (GTK_IS_COMBO_BOX (combo_box), 0);
column = combo_box->priv->id_column;
if (column < 0)
return NULL;
model = gtk_combo_box_get_model (combo_box);
g_return_val_if_fail (gtk_tree_model_get_column_type (model, column) ==
G_TYPE_STRING, NULL);
if (gtk_combo_box_get_active_iter (combo_box, &iter))
{
const gchar *interned;
gchar *id;
gtk_tree_model_get (model, &iter, column, &id, -1);
interned = g_intern_string (id);
g_free (id);
return interned;
}
return NULL;
}
/**
* gtk_combo_box_set_active_id:
* @combo_box: a #GtkComboBox
* @active_id: the ID of the row to select
*
* Changes the active row of @combo_box to the one that has an ID equal to @id.
*
* If the 'id-column' property of @combo_box is unset or if no row has
* the given ID then nothing happens.
*
* Since: 3.0
**/
void
gtk_combo_box_set_active_id (GtkComboBox *combo_box,
const gchar *active_id)
{
GtkTreeModel *model;
GtkTreeIter iter;
gint column;
g_return_if_fail (GTK_IS_COMBO_BOX (combo_box));
column = combo_box->priv->id_column;
if (column < 0)
return;
model = gtk_combo_box_get_model (combo_box);
g_return_if_fail (gtk_tree_model_get_column_type (model, column) ==
G_TYPE_STRING);
if (gtk_tree_model_get_iter_first (model, &iter))
do {
gboolean match;
gchar *id;
gtk_tree_model_get (model, &iter, column, &id, -1);
match = strcmp (id, active_id) == 0;
g_free (id);
if (match)
{
gtk_combo_box_set_active_iter (combo_box, &iter);
break;
}
} while (gtk_tree_model_iter_next (model, &iter));
}
......@@ -134,6 +134,12 @@ void gtk_combo_box_popup_for_device (GtkComboBox *combo_box,
void gtk_combo_box_popdown (GtkComboBox *combo_box);
AtkObject* gtk_combo_box_get_popup_accessible (GtkComboBox *combo_box);
gint gtk_combo_box_get_id_column (GtkComboBox *combo_box);
void gtk_combo_box_set_id_column (GtkComboBox *combo_box,
gint id_column);
const gchar * gtk_combo_box_get_active_id (GtkComboBox *combo_box);
void gtk_combo_box_set_active_id (GtkComboBox *combo_box,
const gchar *active_id);
G_END_DECLS
......
......@@ -72,7 +72,7 @@ gtk_combo_box_text_init (GtkComboBoxText *combo_box)
{
GtkListStore *store;
store = gtk_list_store_new (1, G_TYPE_STRING);
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store));
g_object_unref (store);
}
......@@ -102,6 +102,7 @@ gtk_combo_box_text_new (void)
{
return g_object_new (GTK_TYPE_COMBO_BOX_TEXT,
"entry-text-column", 0,
"id-column", 1,
NULL);
}
......@@ -121,6 +122,7 @@ gtk_combo_box_text_new_with_entry (void)
return g_object_new (GTK_TYPE_COMBO_BOX_TEXT,
"has-entry", TRUE,
"entry-text-column", 0,
"id-column", 1,
NULL);
}
......@@ -131,13 +133,16 @@ gtk_combo_box_text_new_with_entry (void)
*
* Appends @text to the list of strings stored in @combo_box.
*
* This is the same as calling gtk_combo_box_text_insert_text() with a
* position of -1.
*
* Since: 2.24
*/
void
gtk_combo_box_text_append_text (GtkComboBoxText *combo_box,
const gchar *text)
{
gtk_combo_box_text_insert_text (combo_box, G_MAXINT, text);
gtk_combo_box_text_insert (combo_box, -1, NULL, text);
}
/**
......@@ -147,13 +152,16 @@ gtk_combo_box_text_append_text (GtkComboBoxText *combo_box,
*
* Prepends @text to the list of strings stored in @combo_box.
*
* This is the same as calling gtk_combo_box_text_insert_text() with a
* position of 0.
*
* Since: 2.24
*/
void
gtk_combo_box_text_prepend_text (GtkComboBoxText *combo_box,
const gchar *text)
{
gtk_combo_box_text_insert_text (combo_box, 0, text);
gtk_combo_box_text_insert (combo_box, 0, NULL, text);
}
/**
......@@ -164,12 +172,84 @@ gtk_combo_box_text_prepend_text (GtkComboBoxText *combo_box,
*
* Inserts @text at @position in the list of strings stored in @combo_box.
*
* If @position is negative then @text is appended.
*
* This is the same as calling gtk_combo_box_text_insert() with a %NULL
* ID string.
*
* Since: 2.24
*/
void
gtk_combo_box_text_insert_text (GtkComboBoxText *combo_box,
gint position,
const gchar *text)
{
gtk_combo_box_text_insert (combo_box, position, NULL, text);
}
/**
* gtk_combo_box_text_append:
* @combo_box: A #GtkComboBoxText
* @text: A string
*
* Appends @text to the list of strings stored in @combo_box. If @id is
* non-%NULL then it is used as the ID of the row.
*
* This is the same as calling gtk_combo_box_text_insert() with a
* position of -1.
*
* Since: 2.24
*/
void
gtk_combo_box_text_append (GtkComboBoxText *combo_box,
const gchar *id,
const gchar *text)
{
gtk_combo_box_text_insert (combo_box, -1, id, text);
}
/**
* gtk_combo_box_text_prepend:
* @combo_box: A #GtkComboBox
* @text: A string
*
* Prepends @text to the list of strings stored in @combo_box. If @id
* is non-%NULL then it is used as the ID of the row.
*
* This is the same as calling gtk_combo_box_text_insert() with a
* position of 0.
*
* Since: 2.24
*/
void
gtk_combo_box_text_prepend (GtkComboBoxText *combo_box,
const gchar *id,
const gchar *text)
{
gtk_combo_box_text_insert (combo_box, 0, id, text);
}
/**
* gtk_combo_box_text_insert:
* @combo_box: A #GtkComboBoxText
* @position: An index to insert @text
* @id: a string ID for this value, or %NULL
* @text: A string to display
*
* Inserts @text at @position in the list of strings stored in @combo_box.
* If @id is non-%NULL then it is used as the ID of the row. See
* #GtkComboBox::id-column.
*
* If @position is negative then @text is appended.
*
* Since: 3.0
*/
void
gtk_combo_box_text_insert (GtkComboBoxText *combo_box,
gint position,
const gchar *id,
const gchar *text)
{
GtkListStore *store;
GtkTreeIter iter;
......@@ -177,9 +257,11 @@ gtk_combo_box_text_insert_text (GtkComboBoxText *combo_box,
gint column_type;
g_return_if_fail (GTK_IS_COMBO_BOX_TEXT (combo_box));
g_return_if_fail (position >= 0);
g_return_if_fail (text != NULL);
if (position < 0)
position = G_MAXINT;
store = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)));
g_return_if_fail (GTK_IS_LIST_STORE (store));
text_column = gtk_combo_box_get_entry_text_column (GTK_COMBO_BOX (combo_box));
......@@ -188,6 +270,17 @@ gtk_combo_box_text_insert_text (GtkComboBoxText *combo_box,
gtk_list_store_insert (store, &iter, position);
gtk_list_store_set (store, &iter, text_column, text, -1);
if (id != NULL)
{
gint id_column;
id_column = gtk_combo_box_get_id_column (GTK_COMBO_BOX (combo_box));
column_type = gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), id_column);
g_return_if_fail (column_type == G_TYPE_STRING);
gtk_list_store_set (store, &iter, id_column, id, -1);
}
}
/**
......
......@@ -72,6 +72,16 @@ void gtk_combo_box_text_remove (GtkComboBoxText *combo_box
void gtk_combo_box_text_remove_all (GtkComboBoxText *combo_box);
gchar *gtk_combo_box_text_get_active_text (GtkComboBoxText *combo_box);
void gtk_combo_box_text_insert (GtkComboBoxText *combo_box,
gint position,
const gchar *id,
const gchar *text);
void gtk_combo_box_text_append (GtkComboBoxText *combo_box,
const gchar *id,
const gchar *text);
void gtk_combo_box_text_prepend (GtkComboBoxText *combo_box,
const gchar *id,
const gchar *text);
G_END_DECLS
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment