PsppireValueEntry: New signal - edit-done
[pspp] / src / ui / gui / psppire-value-entry.c
index 91dcdd47931e1c93e6ebdeee5fe0751f95f2c582..30b18219d785cd74de6c159352ca7ebcddd78004 100644 (file)
@@ -28,7 +28,7 @@ static void psppire_value_entry_finalize (GObject *);
 
 G_DEFINE_TYPE (PsppireValueEntry,
                psppire_value_entry,
-               GTK_TYPE_COMBO_BOX_ENTRY);
+               GTK_TYPE_COMBO_BOX);
 
 enum
   {
@@ -48,6 +48,12 @@ enum
     PROP_WIDTH
   };
 
+enum  {EDIT_DONE, /* Emitted when the entry has changed and is ready to be fetched */
+       n_SIGNALS};
+
+static guint signals [n_SIGNALS];
+
+
 static void
 psppire_value_entry_set_property (GObject      *object,
                                   guint         prop_id,
@@ -129,15 +135,72 @@ psppire_value_entry_get_property (GObject      *object,
     }
 }
 
+static void
+psppire_value_entry_text_changed (GtkEntryBuffer *buffer,
+                                  GParamSpec *pspec,
+                                  PsppireValueEntry *obj)
+{
+  obj->cur_value = NULL;
+}
+
+static void
+on_entry_activate (GtkWidget *w)
+{
+  PsppireValueEntry *ve = PSPPIRE_VALUE_ENTRY (w);
+  g_signal_emit (w, signals [EDIT_DONE], 0);
+}
+
+static void
+on_realize (GtkWidget *w)
+{
+  GtkEntry *entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (w)));
+  GtkEntryBuffer *buffer = gtk_entry_get_buffer (entry);
+
+  gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (w), COL_LABEL);
+
+  g_signal_connect (buffer, "notify::text",
+                    G_CALLBACK (psppire_value_entry_text_changed), w);
+
+  g_signal_connect_swapped (entry, "activate",
+                    G_CALLBACK (on_entry_activate), w);
+
+  gtk_widget_set_can_focus (GTK_WIDGET (entry), TRUE);
+
+  GTK_WIDGET_CLASS (psppire_value_entry_parent_class)->realize (w);
+}
+
+
+/*
+ The "has-entry" property for the parent class (GTK_COMBO_BOX) is
+ a) Construct-only ; and b) defaults to FALSE.
+ We want it to default to TRUE.  So we override it here.
+*/
+static  GObject*
+my_constructor (GType                  type,
+               guint                  n_construct_properties,
+               GObjectConstructParam *construct_properties)
+{
+  GObject *o =
+    G_OBJECT_CLASS (psppire_value_entry_parent_class)->constructor
+    (type, n_construct_properties, construct_properties);
+
+  g_object_set (o, "has-entry", TRUE, NULL);
+
+  return o;
+}
+
 static void
 psppire_value_entry_class_init (PsppireValueEntryClass *class)
 {
-  GObjectClass *gobject_class;
-  gobject_class = G_OBJECT_CLASS (class);
+  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
 
   gobject_class->finalize = psppire_value_entry_finalize;
   gobject_class->set_property = psppire_value_entry_set_property;
   gobject_class->get_property = psppire_value_entry_get_property;
+  gobject_class->constructor = my_constructor;
+  widget_class->realize = on_realize;
 
   g_object_class_install_property (
     gobject_class, PROP_SHOW_VALUE_LABEL,
@@ -195,31 +258,26 @@ psppire_value_entry_class_init (PsppireValueEntryClass *class)
                       0, MAX_STRING,
                       0,
                       G_PARAM_READABLE | G_PARAM_WRITABLE));
-}
 
-static void
-psppire_value_entry_text_changed (GtkEntryBuffer *buffer,
-                                  GParamSpec *pspec,
-                                  PsppireValueEntry *obj)
-{
-  obj->cur_value = NULL;
+  signals [EDIT_DONE] =
+    g_signal_new ("edit-done",
+                 G_TYPE_FROM_CLASS (class),
+                 G_SIGNAL_RUN_FIRST,
+                 0,
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__VOID,
+                 G_TYPE_NONE,
+                 0);
 }
 
 static void
 psppire_value_entry_init (PsppireValueEntry *obj)
 {
-  GtkEntry *entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (obj)));
-  GtkEntryBuffer *buffer = gtk_entry_get_buffer (entry);
-
   obj->show_value_label = true;
   obj->val_labs = NULL;
   obj->format = F_8_0;
   obj->encoding = NULL;
   obj->cur_value = NULL;
-  gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (obj), COL_LABEL);
-
-  g_signal_connect (buffer, "notify::text",
-                    G_CALLBACK (psppire_value_entry_text_changed), obj);
 }
 
 static void
@@ -280,7 +338,7 @@ psppire_value_entry_refresh_model (PsppireValueEntry *obj)
     }
 
   gtk_combo_box_set_model (GTK_COMBO_BOX (obj), model);
-  if ((model != NULL) && (model != old_model))
+  if (model != NULL)
     g_object_unref (model);
 }
 
@@ -409,6 +467,10 @@ psppire_value_entry_set_value (PsppireValueEntry *obj,
   gchar *string;
 
   obj->cur_value = NULL;
+
+  if (value == NULL)
+    return;
+
   if (obj->show_value_label)
     {
       struct val_lab *vl = val_labs_lookup (obj->val_labs, value);