[gtk+/wip/ebassi/combo: 8/16] Some API changes



commit 7d3996235959c367a1343dcc30e62d826ee8bb62
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Jan 5 16:11:37 2015 -0500

    Some API changes
    
    Split out setting of sort keys and group keys from gtk_combo_add_item,
    and rename the placeholder property to placeholder-text.

 docs/reference/gtk/gtk3-sections.txt |    6 +-
 gtk/gtkcombo.c                       |  305 +++++++++++++++++++++-------------
 gtk/gtkcombo.h                       |   51 +++---
 tests/testnewcombo.c                 |  145 ++++++++++++-----
 4 files changed, 322 insertions(+), 185 deletions(-)
---
diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt
index 02dce15..0558f6c 100644
--- a/docs/reference/gtk/gtk3-sections.txt
+++ b/docs/reference/gtk/gtk3-sections.txt
@@ -994,11 +994,13 @@ GtkCombo
 gtk_combo_new
 gtk_combo_add_item
 gtk_combo_remove_item
+gtk_combo_item_set_sort_key
+gtk_combo_item_set_group_key
 gtk_combo_add_group
 gtk_combo_get_active
 gtk_combo_set_active
-gtk_combo_get_placeholder
-gtk_combo_set_placeholder
+gtk_combo_get_placeholder_text
+gtk_combo_set_placeholder_text
 gtk_combo_get_allow_custom
 gtk_combo_set_allow_custom
 
diff --git a/gtk/gtkcombo.c b/gtk/gtkcombo.c
index 259dd6d..9d9dd6c 100644
--- a/gtk/gtkcombo.c
+++ b/gtk/gtkcombo.c
@@ -48,7 +48,7 @@
  * @See_also: #GtkComboBoxText
  *
  * A GtkCombo is a simple variant of a combo box that hides the
- * model-view complexity of #GtkcomboBox and uses popovers.
+ * model-view complexity of #GtkComboBox and uses a popover.
  *
  * To create a GtkCombo, use gtk_combo_new().
  *
@@ -61,9 +61,9 @@
  * If you want to allow the user to enter custom values, use
  * gtk_combo_set_allow_custom().
  *
- * Items can optionally be grouped, by specifying a group id as the last
- * argument to gtk_combo_add_item(). Groups can have display text and sort
- * keys that are different from the group id, by using gtk_combo_box_add_group().
+ * Items can optionally be grouped, by using gtk_combo_item_set_group_key().
+ * Groups can have display text and sort keys that are different from the
+ * group ID, by using gtk_combo_box_add_group().
  *
  * # GtkCombo as GtkBuildable
  *
@@ -330,10 +330,9 @@ gtk_combo_row_set_inverted (GtkComboRow *row,
 
 static GtkWidget *
 gtk_combo_row_new_item (const gchar *id,
-                        const gchar *text,
-                        const gchar *sort)
+                        const gchar *text)
 {
-  return g_object_new (GTK_TYPE_COMBO_ROW, "id", id, "text", text, "sort", sort, NULL);
+  return g_object_new (GTK_TYPE_COMBO_ROW, "id", id, "text", text, NULL);
 }
 
 static GtkWidget *
@@ -472,7 +471,7 @@ struct _GtkComboClass
 
 enum {
   PROP_ACTIVE = 1,
-  PROP_PLACEHOLDER,
+  PROP_PLACEHOLDER_TEXT,
   PROP_ALLOW_CUSTOM
 };
 
@@ -523,8 +522,8 @@ gtk_combo_set_property (GObject      *object,
     case PROP_ACTIVE:
       gtk_combo_set_active (combo, g_value_get_string (value));
       break;
-    case PROP_PLACEHOLDER:
-      gtk_combo_set_placeholder (combo, g_value_get_string (value));
+    case PROP_PLACEHOLDER_TEXT:
+      gtk_combo_set_placeholder_text (combo, g_value_get_string (value));
       break;
     case PROP_ALLOW_CUSTOM:
       gtk_combo_set_allow_custom (combo, g_value_get_boolean (value));
@@ -547,8 +546,8 @@ gtk_combo_get_property (GObject    *object,
     case PROP_ACTIVE:
       g_value_set_string (value, gtk_combo_get_active (combo));
       break;
-    case PROP_PLACEHOLDER:
-      g_value_set_string (value, gtk_combo_get_placeholder (combo));
+    case PROP_PLACEHOLDER_TEXT:
+      g_value_set_string (value, gtk_combo_get_placeholder_text (combo));
       break;
     case PROP_ALLOW_CUSTOM:
       g_value_set_boolean (value, gtk_combo_get_allow_custom (combo));
@@ -578,20 +577,20 @@ gtk_combo_class_init (GtkComboClass *class)
                                    PROP_ACTIVE,
                                    g_param_spec_string ("active",
                                                         P_("Active"),
-                                                        P_("Active ID"),
+                                                        P_("The ID of the active item"),
                                                         NULL,
                                                         GTK_PARAM_READWRITE));
 
   /**
-   * GtkCombo:placeholder:
+   * GtkCombo:placeholder-text:
    *
-   * The text that is displayed if not item is selected.
+   * The text that is displayed if no item is selected.
    */
   g_object_class_install_property (object_class,
-                                   PROP_PLACEHOLDER,
-                                   g_param_spec_string ("placeholder",
-                                                        P_("Placeholder"),
+                                   PROP_PLACEHOLDER_TEXT,
+                                   g_param_spec_string ("placeholder-text",
                                                         P_("Placeholder text"),
+                                                        P_("Text to show when no item is selected"),
                                                         NULL,
                                                         GTK_PARAM_READWRITE));
 
@@ -731,7 +730,13 @@ combo_end_element (GMarkupParseContext *context,
       if (data->is_group)
         gtk_combo_add_group (GTK_COMBO (data->object), data->id, data->string->str, data->sort);
       else
-        gtk_combo_add_item (GTK_COMBO (data->object), data->id, data->string->str, data->sort, data->group);
+        {
+          gtk_combo_add_item (GTK_COMBO (data->object), data->id, data->string->str);
+          if (data->sort)
+            gtk_combo_item_set_sort_key (GTK_COMBO (data->object), data->id, data->sort);
+          if (data->group)
+            gtk_combo_item_set_group_key (GTK_COMBO (data->object), data->id, data->group);
+        }
     }
 
   data->translatable = FALSE;
@@ -965,8 +970,8 @@ typedef struct
 } ForeachData;
 
 static void
-find_item (GtkWidget *row,
-           gpointer   data)
+find_in_group_cb (GtkWidget *row,
+                  gpointer   data)
 {
   ForeachData *d = data;
   const gchar *id;
@@ -984,8 +989,8 @@ find_item (GtkWidget *row,
 }
 
 static void
-find_item_and_group (GtkWidget *row,
-                     gpointer   data)
+find_item_cb (GtkWidget *row,
+              gpointer   data)
 {
   ForeachData *d = data;
   const gchar *id;
@@ -1005,7 +1010,7 @@ find_item_and_group (GtkWidget *row,
       GtkWidget *list;
 
       list = group_get_list (d->combo, group);
-      gtk_container_foreach (GTK_CONTAINER (list), find_item, d);
+      gtk_container_foreach (GTK_CONTAINER (list), find_in_group_cb, d);
 
       if (d->row)
         d->group_row = row;
@@ -1019,32 +1024,26 @@ find_item_and_group (GtkWidget *row,
     d->row = row;
 }
 
-static void
-add_to_list (GtkWidget   *list,
-             const gchar *id,
-             const gchar *text,
-             const gchar *sort)
+static gboolean
+find_item (GtkCombo     *combo,
+           const gchar  *id,
+           GtkWidget   **item,
+           GtkWidget   **group)
 {
   ForeachData data;
 
-  if (text == NULL)
-    text = id;
-
+  data.combo = combo;
   data.id = id;
   data.row = NULL;
-  gtk_container_foreach (GTK_CONTAINER (list), find_item, &data);
+  data.group_row = NULL;
+  gtk_container_foreach (GTK_CONTAINER (combo->list), find_item_cb, &data);
 
-  if (data.row)
-    {
-      gtk_combo_row_set_text (GTK_COMBO_ROW (data.row), text);
-      gtk_combo_row_set_sort (GTK_COMBO_ROW (data.row), sort);
-      gtk_list_box_invalidate_sort (GTK_LIST_BOX (list));
-      gtk_list_box_invalidate_filter (GTK_LIST_BOX (list));
-    }
-  else
-    {
-      gtk_list_box_insert (GTK_LIST_BOX (list), gtk_combo_row_new_item (id, text, sort), -1);
-    }
+  if (item)
+    *item = data.row;
+  if (group)
+    *group = data.group_row;
+
+  return data.row != NULL;
 }
 
 static void
@@ -1062,79 +1061,68 @@ static gboolean
 remove_from_list (GtkCombo    *combo,
                   const gchar *id)
 {
-  ForeachData data;
-
-  data.id = id;
-  data.row = NULL;
-  data.group_row = NULL;
-  gtk_container_foreach (GTK_CONTAINER (combo->list), find_item_and_group, &data);
+  GtkWidget *item;
+  GtkWidget *group;
+  GtkWidget *list;
+  GtkWidget *tab;
 
-  if (data.row)
-    {
-      GtkWidget *list;
-      GtkWidget *tab;
+  if (!find_item (combo, id, &item, &group))
+    return FALSE;
 
-      list = gtk_widget_get_parent (data.row);
-      gtk_container_remove (GTK_CONTAINER (list), data.row);
+  list = gtk_widget_get_parent (item);
+  gtk_container_remove (GTK_CONTAINER (list), item);
 
-      if (data.group_row)
+  if (group)
+    {
+      gint count = 0;
+      gtk_container_foreach (GTK_CONTAINER (list), count_items, &count);
+      if (count == 0)
         {
-          gint count = 0;
-          gtk_container_foreach (GTK_CONTAINER (list), count_items, &count);
-          if (count == 0)
-            {
-              tab = gtk_widget_get_ancestor (list, GTK_TYPE_FRAME);
-              gtk_container_remove (GTK_CONTAINER (combo->stack), tab);
-              gtk_container_remove (GTK_CONTAINER (combo->list), data.group_row);
-            }
-          else
-            collapse (combo, list);
+          tab = gtk_widget_get_ancestor (list, GTK_TYPE_FRAME);
+          gtk_container_remove (GTK_CONTAINER (combo->stack), tab);
+          gtk_container_remove (GTK_CONTAINER (combo->list), group);
         }
       else
         collapse (combo, list);
+     }
+  else
+    collapse (combo, list);
 
-      return TRUE;
-    }
-
-  return FALSE;
+  return TRUE;
 }
 
 static void
 set_active (GtkCombo    *combo,
             const gchar *id)
 {
-  ForeachData data;
+  GtkWidget *item;
+  GtkWidget *group;
 
-  data.combo = combo;
-  data.id = combo->active;
-  data.row = NULL;
-  data.group_row = NULL;
   if (combo->active)
     {
-      gtk_container_foreach (GTK_CONTAINER (combo->list), find_item_and_group, &data);
-      if (data.row)
-        gtk_combo_row_set_active (GTK_COMBO_ROW (data.row), FALSE);
-      if (data.group_row)
-        gtk_combo_row_set_active (GTK_COMBO_ROW (data.group_row), FALSE);
+      find_item (combo, combo->active, &item, &group);
+      if (item)
+        gtk_combo_row_set_active (GTK_COMBO_ROW (item), FALSE);
+      if (group)
+        gtk_combo_row_set_active (GTK_COMBO_ROW (group), FALSE);
     }
 
-  data.id = id;
-  data.row = NULL;
-  data.group_row = NULL;
   if (id)
     {
-      gtk_container_foreach (GTK_CONTAINER (combo->list), find_item_and_group, &data);
-      if (data.row)
-        gtk_combo_row_set_active (GTK_COMBO_ROW (data.row), TRUE);
-      if (data.group_row)
-        gtk_combo_row_set_active (GTK_COMBO_ROW (data.group_row), TRUE);
+      find_item (combo, id, &item, &group);
+      if (item)
+        gtk_combo_row_set_active (GTK_COMBO_ROW (item), TRUE);
+      if (group)
+        gtk_combo_row_set_active (GTK_COMBO_ROW (group), TRUE);
     }
+  else
+    item = NULL;
 
-  if (data.row)
+  if (item)
     {
-      combo->active = gtk_combo_row_get_id (GTK_COMBO_ROW (data.row));
+      combo->active = gtk_combo_row_get_id (GTK_COMBO_ROW (item));
       gtk_label_set_text (GTK_LABEL (combo->active_label),
-                          gtk_combo_row_get_text (GTK_COMBO_ROW (data.row)));
+                          gtk_combo_row_get_text (GTK_COMBO_ROW (item)));
     }
   else
     {
@@ -1192,7 +1180,7 @@ custom_entry_done (GtkWidget *widget,
   text = gtk_entry_get_text (GTK_ENTRY (combo->custom_entry));
   if (text[0] != '\0')
     {
-      gtk_combo_add_item (combo, text, NULL, NULL, NULL);
+      gtk_combo_add_item (combo, text, text);
       gtk_combo_set_active (combo, text);
       gtk_entry_set_text (GTK_ENTRY (combo->custom_entry), "");
       gtk_widget_hide (combo->popover);
@@ -1530,7 +1518,7 @@ gtk_combo_get_active (GtkCombo *combo)
 /**
  * gtk_combo_set_active:
  * @combo: a #GtkCombo
- * @id: the ID to select
+ * @id: (allow-none): the ID to select, or %NULL
  *
  * Sets the active ID to @id. If @id is not the ID
  * of an item of combo, no item will be selected
@@ -1551,43 +1539,117 @@ gtk_combo_set_active (GtkCombo    *combo,
  * gtk_combo_add_item:
  * @combo: a #GtkCombo
  * @id: the ID for the item to add
- * @text: (allow-none): the text to display for the item
- * @sort: (allow-none): a sort key for the item
- * @group: (allow-none): the group for the item
+ * @text: the text to display for the item
  *
  * Adds an item to the combo.
  *
  * If an item with this ID already exists, its display text
- * and sort key will be updated with the new values.
- *
- * If @text is %NULL, the @id will be used to display the item.
- * If @sort is %NULL, the item will be sorted according to @text.
+ * will be updated with the new values.
  *
  * Since: 3.16
  */
 void
 gtk_combo_add_item (GtkCombo    *combo,
                     const gchar *id,
-                    const gchar *text,
-                    const gchar *sort,
-                    const gchar *group)
+                    const gchar *text)
 {
   GtkWidget *list;
+  GtkWidget *item;
 
   g_return_if_fail (GTK_IS_COMBO (combo));
+  g_return_if_fail (id != NULL);
+  g_return_if_fail (text != NULL);
 
-  if (group)
+  if (find_item (combo, id, &item, NULL))
     {
-      ensure_group (combo, group);
-      list = group_get_list (combo, group);
+      list = gtk_widget_get_parent (item);
+      gtk_combo_row_set_text (GTK_COMBO_ROW (item), text);
+      gtk_list_box_invalidate_filter (GTK_LIST_BOX (list));
     }
   else
-    list = combo->list;
-  add_to_list (list, id, text, sort);
+    {
+      list = combo->list;
+      item = gtk_combo_row_new_item (id, text);
+      gtk_list_box_insert (GTK_LIST_BOX (list), item, -1);
+    }
+
   collapse (combo, list);
 }
 
 /**
+ * gtk_combo_item_set_sort_key:
+ * @combo: a #GtkCombo
+ * @id: the ID of an item in @combo
+ * @sort: the sort key to use for the item
+ *
+ * Associates a sort key with the item identified by @id.
+ * If no sort key is set, items are sorted according to
+ * their display text.
+ *
+ * Since: 3.16
+ */
+void
+gtk_combo_item_set_sort_key (GtkCombo    *combo,
+                             const gchar *id,
+                             const gchar *sort)
+{
+  GtkWidget *item;
+
+  g_return_if_fail (GTK_IS_COMBO (combo));
+  g_return_if_fail (id != NULL);
+
+  if (find_item (combo, id, &item, NULL))
+    {
+      gtk_combo_row_set_sort (GTK_COMBO_ROW (item), sort);
+      gtk_list_box_invalidate_sort (GTK_LIST_BOX (gtk_widget_get_parent (item)));
+    }
+  else
+    {
+      g_warning ("GtkCombo: no item with ID '%s' found", id);
+    }
+}
+
+/**
+ * gtk_combo_item_set_group_key:
+ * @combo: a #GtkCombo
+ * @id: the ID of an item in @combo
+ * @group: the ID of the group to place the item in
+ *
+ * Places the item identified by @id in a group.
+ * By default, items are not grouped.
+ *
+ * Since: 3.16
+ */
+void
+gtk_combo_item_set_group_key (GtkCombo    *combo,
+                              const gchar *id,
+                              const gchar *group)
+{
+  GtkWidget *item;
+  GtkWidget *list;
+
+  g_return_if_fail (GTK_IS_COMBO (combo));
+  g_return_if_fail (id != NULL);
+
+  if (!find_item (combo, id, &item, NULL))
+    {
+      g_warning ("GtkCombo: no item with ID '%s' found", id);
+      return;
+    }
+
+  if (g_strcmp0 (GTK_COMBO_ROW (item)->group, group) == 0)
+    return;
+
+  g_object_ref (item);
+
+  remove_from_list (combo, id);
+  ensure_group (combo, group);
+  list = group_get_list (combo, group);
+  gtk_list_box_insert (GTK_LIST_BOX (list), item, -1);
+
+  g_object_unref (item);
+}
+/**
  * gtk_combo_remove_item:
  * @combo: a #GtkCombo
  * @id: the ID of the item to remove
@@ -1597,6 +1659,9 @@ gtk_combo_add_item (GtkCombo    *combo,
  * If the item with the this ID is currently selected,
  * no item will be selected after this call.
  *
+ * If the removed item was the last one in its group,
+ * the group will be removed as well.
+ *
  * Since: 3.16
  */
 void
@@ -1604,16 +1669,16 @@ gtk_combo_remove_item (GtkCombo    *combo,
                        const gchar *id)
 {
   g_return_if_fail (GTK_IS_COMBO (combo));
-
-  if (!remove_from_list (combo, id))
-    return;
+  g_return_if_fail (id != NULL);
 
   if (g_strcmp0 (id, combo->active) == 0)
     set_active (combo, NULL);
+
+  remove_from_list (combo, id);
 }
 
 /**
- * gtk_combo_set_placeholder:
+ * gtk_combo_set_placeholder_text:
  * @combo: a #GtkCombo
  * @text: (allow-none): the placeholder text to use, or %NULL
  *
@@ -1623,8 +1688,8 @@ gtk_combo_remove_item (GtkCombo    *combo,
  * Since: 3.16
  */
 void
-gtk_combo_set_placeholder (GtkCombo    *combo,
-                           const gchar *text)
+gtk_combo_set_placeholder_text (GtkCombo    *combo,
+                                const gchar *text)
 {
   g_return_if_fail (GTK_IS_COMBO (combo));
 
@@ -1634,11 +1699,11 @@ gtk_combo_set_placeholder (GtkCombo    *combo,
   if (combo->active == NULL)
     gtk_label_set_text (GTK_LABEL (combo->active_label), combo->placeholder);
 
-  g_object_notify (G_OBJECT (combo), "placeholder");
+  g_object_notify (G_OBJECT (combo), "placeholder-text");
 }
 
 /**
- * gtk_combo_get_placeholder:
+ * gtk_combo_get_placeholder_text:
  * @combo: a #GtkCombo
  *
  * Gets the placholder text that is displayed in the combo
@@ -1649,7 +1714,7 @@ gtk_combo_set_placeholder (GtkCombo    *combo,
  * Since: 3.16
  */
 const gchar *
-gtk_combo_get_placeholder (GtkCombo *combo)
+gtk_combo_get_placeholder_text (GtkCombo *combo)
 {
   g_return_val_if_fail (GTK_IS_COMBO (combo), NULL);
 
@@ -1705,7 +1770,7 @@ gtk_combo_get_allow_custom (GtkCombo *combo)
  * gtk_combo_add_group:
  * @combo: a #GtkCombo
  * @group: a group ID
- * @text: (allow-none): An optional display text for the group
+ * @text: An display text for the group
  * @sort: (allow-none): An optional sort key for the group
  *
  * Associates a display text and sort key with a group of items.
@@ -1721,6 +1786,8 @@ gtk_combo_add_group (GtkCombo    *combo,
   GtkWidget *header, *item;
 
   g_return_if_fail (GTK_IS_COMBO (combo));
+  g_return_if_fail (group != NULL);
+  g_return_if_fail (text != NULL);
 
   ensure_group (combo, group);
 
diff --git a/gtk/gtkcombo.h b/gtk/gtkcombo.h
index aaa9a85..2e88180 100644
--- a/gtk/gtkcombo.h
+++ b/gtk/gtkcombo.h
@@ -38,47 +38,52 @@ typedef struct _GtkCombo             GtkCombo;
 typedef struct _GtkComboClass        GtkComboClass;
 
 GDK_AVAILABLE_IN_3_16
-GType         gtk_combo_get_type         (void) G_GNUC_CONST;
+GType         gtk_combo_get_type                (void) G_GNUC_CONST;
 
 GDK_AVAILABLE_IN_3_16
-GtkWidget *   gtk_combo_new              (void);
+GtkWidget *   gtk_combo_new                     (void);
 
 GDK_AVAILABLE_IN_3_16
-const gchar * gtk_combo_get_active       (GtkCombo    *combo);
+const gchar * gtk_combo_get_active              (GtkCombo       *combo);
 
 GDK_AVAILABLE_IN_3_16
-void          gtk_combo_set_active       (GtkCombo    *combo,
-                                          const gchar *id);
+void          gtk_combo_set_active              (GtkCombo       *combo,
+                                                 const gchar    *id);
 
 GDK_AVAILABLE_IN_3_16
-void          gtk_combo_add_item         (GtkCombo    *combo,
-                                          const gchar *id,
-                                          const gchar *text,
-                                          const gchar *sort,
-                                          const gchar *group);
-
+void          gtk_combo_add_item                (GtkCombo       *combo,
+                                                 const gchar    *id,
+                                                 const gchar    *text);
 GDK_AVAILABLE_IN_3_16
-void          gtk_combo_remove_item      (GtkCombo    *combo,
-                                          const gchar *id);
+void          gtk_combo_remove_item             (GtkCombo       *combo,
+                                                 const gchar    *id);
 
 GDK_AVAILABLE_IN_3_16
-const gchar * gtk_combo_get_placeholder  (GtkCombo    *combo);
+void          gtk_combo_item_set_sort_key       (GtkCombo       *combo,
+                                                 const gchar    *id,
+                                                 const gchar    *sort);
+GDK_AVAILABLE_IN_3_16
+void          gtk_combo_item_set_group_key      (GtkCombo       *combo,
+                                                 const gchar    *id,
+                                                 const gchar    *group);
 
 GDK_AVAILABLE_IN_3_16
-void          gtk_combo_set_placeholder  (GtkCombo    *combo,
-                                          const gchar *text);
+void          gtk_combo_set_placeholder_text    (GtkCombo       *combo,
+                                                 const gchar    *text);
+GDK_AVAILABLE_IN_3_16
+const gchar * gtk_combo_get_placeholder_text    (GtkCombo       *combo);
 
 GDK_AVAILABLE_IN_3_16
-gboolean      gtk_combo_get_allow_custom (GtkCombo    *combo);
+void          gtk_combo_set_allow_custom        (GtkCombo       *combo,
+                                                 gboolean        allow);
 GDK_AVAILABLE_IN_3_16
-void          gtk_combo_set_allow_custom (GtkCombo    *combo,
-                                          gboolean     allow);
+gboolean      gtk_combo_get_allow_custom        (GtkCombo       *combo);
 
 GDK_AVAILABLE_IN_3_16
-void          gtk_combo_add_group        (GtkCombo    *combo,
-                                          const gchar *group,
-                                          const gchar *text,
-                                          const gchar *sort);
+void          gtk_combo_add_group               (GtkCombo       *combo,
+                                                 const gchar    *group,
+                                                 const gchar    *text,
+                                                 const gchar    *sort);
 
 G_END_DECLS
 
diff --git a/tests/testnewcombo.c b/tests/testnewcombo.c
index 236dabc..86d9f11 100644
--- a/tests/testnewcombo.c
+++ b/tests/testnewcombo.c
@@ -13,7 +13,8 @@ add_one (GtkButton *button, gpointer data)
   id = g_strdup_printf ("%d", count);
   text = g_strdup_printf ("Value %d", count);
   sort = g_strdup_printf ("Value %03d", count);
-  gtk_combo_add_item (GTK_COMBO (data), id, text, sort, NULL);
+  gtk_combo_add_item (GTK_COMBO (data), id, text);
+  gtk_combo_item_set_sort_key (GTK_COMBO (data), id, sort);
   gtk_combo_set_active (GTK_COMBO (data), id);
   g_free (id);
   g_free (text);
@@ -26,7 +27,8 @@ remove_active (GtkButton *button, gpointer data)
   const gchar *id;
 
   id = gtk_combo_get_active (GTK_COMBO (data));
-  gtk_combo_remove_item (GTK_COMBO (data), id);
+  if (id != NULL)
+    gtk_combo_remove_item (GTK_COMBO (data), id);
 }
 
 static void
@@ -40,7 +42,7 @@ const gchar data[] =
   "  <object class='GtkCombo' id='combo'>"
   "    <property name='visible'>True</property>"
   "    <property name='halign'>center</property>"
-  "    <property name='placeholder'>None</property>"
+  "    <property name='placeholder-text'>None</property>"
   "    <property name='active'>1</property>"
   "    <items>"
   "      <item translatable='yes' id='1' sort='Value 001'>Value 1</item>"
@@ -55,6 +57,16 @@ const gchar data[] =
   "  </object>"
   "</interface>";
 
+static gboolean
+string_to_bool (GBinding     *binding,
+                const GValue *from_value,
+                GValue       *to_value,
+                gpointer      data)
+{
+  g_value_set_boolean (to_value, g_value_get_string (from_value) != NULL);
+  return TRUE;
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -78,10 +90,10 @@ main (int argc, char *argv[])
   combo = gtk_combo_new ();
   gtk_widget_set_halign (combo, GTK_ALIGN_CENTER);
   gtk_container_add (GTK_CONTAINER (box), combo);
-  gtk_combo_add_item (GTK_COMBO (combo), "1", "Value 1", NULL, NULL);
-  gtk_combo_add_item (GTK_COMBO (combo), "2", "Value 2", NULL, NULL);
-  gtk_combo_add_item (GTK_COMBO (combo), "3", "Value 3", NULL, NULL);
-  gtk_combo_set_placeholder (GTK_COMBO (combo), "None");
+  gtk_combo_add_item (GTK_COMBO (combo), "1", "Value 1");
+  gtk_combo_add_item (GTK_COMBO (combo), "2", "Value 2");
+  gtk_combo_add_item (GTK_COMBO (combo), "3", "Value 3");
+  gtk_combo_set_placeholder_text (GTK_COMBO (combo), "None");
   gtk_combo_set_active (GTK_COMBO (combo), "1");
 
   gtk_container_add (GTK_CONTAINER (box), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
@@ -93,18 +105,29 @@ main (int argc, char *argv[])
   combo = gtk_combo_new ();
   gtk_widget_set_halign (combo, GTK_ALIGN_CENTER);
   gtk_container_add (GTK_CONTAINER (box), combo);
-  gtk_combo_add_item (GTK_COMBO (combo),  "1",  "Value 1", "Value 01", NULL);
-  gtk_combo_add_item (GTK_COMBO (combo),  "2",  "Value 2", "Value 02", NULL);
-  gtk_combo_add_item (GTK_COMBO (combo),  "3",  "Value 3", "Value 03", NULL);
-  gtk_combo_add_item (GTK_COMBO (combo),  "4",  "Value 4", "Value 04", NULL);
-  gtk_combo_add_item (GTK_COMBO (combo),  "5",  "Value 5", "Value 05", NULL);
-  gtk_combo_add_item (GTK_COMBO (combo),  "6",  "Value 6", "Value 06", NULL);
-  gtk_combo_add_item (GTK_COMBO (combo),  "7",  "Value 7", "Value 07", NULL);
-  gtk_combo_add_item (GTK_COMBO (combo),  "8",  "Value 8", "Value 08", NULL);
-  gtk_combo_add_item (GTK_COMBO (combo),  "9",  "Value 9", "Value 09", NULL);
-  gtk_combo_add_item (GTK_COMBO (combo), "10", "Value 10", "Value 10", NULL);
-  gtk_combo_add_item (GTK_COMBO (combo), "11", "Value 11", "Value 11", NULL);
-  gtk_combo_set_placeholder (GTK_COMBO (combo), "None");
+  gtk_combo_add_item (GTK_COMBO (combo),  "1",  "Value 1");
+  gtk_combo_add_item (GTK_COMBO (combo),  "2",  "Value 2");
+  gtk_combo_add_item (GTK_COMBO (combo),  "3",  "Value 3");
+  gtk_combo_add_item (GTK_COMBO (combo),  "4",  "Value 4");
+  gtk_combo_add_item (GTK_COMBO (combo),  "5",  "Value 5");
+  gtk_combo_add_item (GTK_COMBO (combo),  "6",  "Value 6");
+  gtk_combo_add_item (GTK_COMBO (combo),  "7",  "Value 7");
+  gtk_combo_add_item (GTK_COMBO (combo),  "8",  "Value 8");
+  gtk_combo_add_item (GTK_COMBO (combo),  "9",  "Value 9");
+  gtk_combo_add_item (GTK_COMBO (combo), "10", "Value 10");
+  gtk_combo_add_item (GTK_COMBO (combo), "11", "Value 11");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "1",  "Value 01");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "2",  "Value 02");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "3",  "Value 03");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "4",  "Value 04");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "5",  "Value 05");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "6",  "Value 06");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "7",  "Value 07");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "8",  "Value 08");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "9",  "Value 09");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo), "10",  "Value 10");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo), "11",  "Value 11");
+  gtk_combo_set_placeholder_text (GTK_COMBO (combo), "None");
   gtk_combo_set_active (GTK_COMBO (combo), "1");
 
   gtk_container_add (GTK_CONTAINER (box), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
@@ -116,10 +139,10 @@ main (int argc, char *argv[])
   combo = gtk_combo_new ();
   gtk_widget_set_halign (combo, GTK_ALIGN_CENTER);
   gtk_container_add (GTK_CONTAINER (box), combo);
-  gtk_combo_add_item (GTK_COMBO (combo), "1", "Value 1", NULL, NULL);
-  gtk_combo_add_item (GTK_COMBO (combo), "2", "Value 2", NULL, NULL);
-  gtk_combo_add_item (GTK_COMBO (combo), "3", "Value 3", NULL, NULL);
-  gtk_combo_set_placeholder (GTK_COMBO (combo), "None");
+  gtk_combo_add_item (GTK_COMBO (combo), "1", "Value 1");
+  gtk_combo_add_item (GTK_COMBO (combo), "2", "Value 2");
+  gtk_combo_add_item (GTK_COMBO (combo), "3", "Value 3");
+  gtk_combo_set_placeholder_text (GTK_COMBO (combo), "None");
   gtk_combo_set_allow_custom (GTK_COMBO (combo), TRUE);
   gtk_combo_set_active (GTK_COMBO (combo), "1");
 
@@ -133,29 +156,65 @@ main (int argc, char *argv[])
   gtk_widget_set_halign (combo, GTK_ALIGN_CENTER);
   gtk_container_add (GTK_CONTAINER (box), combo);
   gtk_combo_add_group (GTK_COMBO (combo), "Group 3", "G 3", "Group 3");
-  gtk_combo_add_item (GTK_COMBO (combo),  "1",  "Value 1", "Value 01", "Group 1");
-  gtk_combo_add_item (GTK_COMBO (combo),  "2",  "Value 2", "Value 02", "Group 1");
-  gtk_combo_add_item (GTK_COMBO (combo),  "3",  "Value 3", "Value 03", "Group 1");
-  gtk_combo_add_item (GTK_COMBO (combo),  "4",  "Value 4", "Value 04", "Group 1");
-  gtk_combo_add_item (GTK_COMBO (combo),  "5",  "Value 5", "Value 05", "Group 2");
-  gtk_combo_add_item (GTK_COMBO (combo),  "6",  "Value 6", "Value 06", "Group 2");
-  gtk_combo_add_item (GTK_COMBO (combo),  "7",  "Value 7", "Value 07", "Group 2");
-  gtk_combo_add_item (GTK_COMBO (combo),  "8",  "Value 8", "Value 08", "Group 2");
-  gtk_combo_add_item (GTK_COMBO (combo),  "9",  "Value 9", "Value 09", "Group 3");
-  gtk_combo_add_item (GTK_COMBO (combo), "10", "Value 10", "Value 10", "Group 3");
-  gtk_combo_add_item (GTK_COMBO (combo), "11", "Value 11", "Value 11", "Group 3");
-  gtk_combo_add_item (GTK_COMBO (combo), "12", "Value 12", "Value 12", "Group 3");
-  gtk_combo_add_item (GTK_COMBO (combo), "13", "Value 13", "Value 13", "Group 3");
-  gtk_combo_add_item (GTK_COMBO (combo), "14", "Value 14", "Value 14", "Group 3");
-  gtk_combo_add_item (GTK_COMBO (combo), "15", "Value 15", NULL,       "Group 3");
-  gtk_combo_add_item (GTK_COMBO (combo), "16", "Value 16", NULL,       "Group 3");
-  gtk_combo_add_item (GTK_COMBO (combo), "17", "Value 17", NULL,       "Group 3");
-  gtk_combo_add_item (GTK_COMBO (combo), "18", "Value 18", NULL,       "Group 3");
+  gtk_combo_add_item (GTK_COMBO (combo),  "1",  "Value 1");
+  gtk_combo_add_item (GTK_COMBO (combo),  "2",  "Value 2");
+  gtk_combo_add_item (GTK_COMBO (combo),  "3",  "Value 3");
+  gtk_combo_add_item (GTK_COMBO (combo),  "4",  "Value 4");
+  gtk_combo_add_item (GTK_COMBO (combo),  "5",  "Value 5");
+  gtk_combo_add_item (GTK_COMBO (combo),  "6",  "Value 6");
+  gtk_combo_add_item (GTK_COMBO (combo),  "7",  "Value 7");
+  gtk_combo_add_item (GTK_COMBO (combo),  "8",  "Value 8");
+  gtk_combo_add_item (GTK_COMBO (combo),  "9",  "Value 9");
+  gtk_combo_add_item (GTK_COMBO (combo), "10", "Value 10");
+  gtk_combo_add_item (GTK_COMBO (combo), "11", "Value 11");
+  gtk_combo_add_item (GTK_COMBO (combo), "12", "Value 12");
+  gtk_combo_add_item (GTK_COMBO (combo), "13", "Value 13");
+  gtk_combo_add_item (GTK_COMBO (combo), "14", "Value 14");
+  gtk_combo_add_item (GTK_COMBO (combo), "15", "Value 15");
+  gtk_combo_add_item (GTK_COMBO (combo), "16", "Value 16");
+  gtk_combo_add_item (GTK_COMBO (combo), "17", "Value 17");
+  gtk_combo_add_item (GTK_COMBO (combo), "18", "Value 18");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "1",  "Value 01");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "2",  "Value 02");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "3",  "Value 03");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "4",  "Value 04");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "5",  "Value 05");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "6",  "Value 06");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "7",  "Value 07");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "8",  "Value 08");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo),  "9",  "Value 09");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo), "10",  "Value 10");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo), "11",  "Value 11");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo), "12",  "Value 12");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo), "13",  "Value 13");
+  gtk_combo_item_set_sort_key (GTK_COMBO (combo), "14",  "Value 14");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo),  "1",  "Group 1");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo),  "2",  "Group 1");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo),  "3",  "Group 1");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo),  "4",  "Group 1");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo),  "5",  "Group 2");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo),  "6",  "Group 2");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo),  "7",  "Group 2");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo),  "8",  "Group 2");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo),  "9",  "Group 3");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo), "10",  "Group 3");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo), "11",  "Group 3");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo), "12",  "Group 3");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo), "13",  "Group 3");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo), "14",  "Group 3");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo), "15",  "Group 3");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo), "16",  "Group 3");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo), "17",  "Group 3");
+  gtk_combo_item_set_group_key (GTK_COMBO (combo), "18",  "Group 3");
   gtk_combo_set_active (GTK_COMBO (combo), "7");
   button = gtk_button_new_with_label ("Remove active");
   gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
   g_signal_connect (button, "clicked", G_CALLBACK (remove_active), combo);
   gtk_container_add (GTK_CONTAINER (box), button);
+  g_object_bind_property_full (combo, "active",
+                               button, "sensitive",
+                               G_BINDING_SYNC_CREATE,
+                               string_to_bool, NULL, NULL, NULL);
 
   gtk_container_add (GTK_CONTAINER (box), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
 
@@ -181,6 +240,10 @@ main (int argc, char *argv[])
   button = gtk_button_new_with_label ("Remove active");
   g_signal_connect (button, "clicked", G_CALLBACK (remove_active), combo);
   gtk_container_add (GTK_CONTAINER (box2), button);
+  g_object_bind_property_full (combo, "active",
+                               button, "sensitive",
+                               G_BINDING_SYNC_CREATE,
+                               string_to_bool, NULL, NULL, NULL);
   button = gtk_check_button_new_with_label ("Allow custom");
   gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
   g_object_bind_property (button, "active",


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]