missing-val-dialog: Convert to a GObject.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 19 Aug 2012 18:36:16 +0000 (11:36 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 19 Aug 2012 18:41:44 +0000 (11:41 -0700)
src/ui/gui/missing-val-dialog.c
src/ui/gui/missing-val-dialog.h
src/ui/gui/missing-val-dialog.ui
src/ui/gui/psppire-var-sheet.c
src/ui/gui/psppire-var-sheet.h

index 8c27cf366203a66f815e28b9b837cf67c2127aff..162dcd66d937005ee944fec1db845ed0cbb66407 100644 (file)
     used for input of the missing values in the variable sheet */
 
 #include <config.h>
-#include <gettext.h>
-#define _(msgid) gettext (msgid)
-#define N_(msgid) msgid
 
+#include "ui/gui/missing-val-dialog.h"
 
 #include "builder-wrapper.h"
 #include "helper.h"
 #include <data/variable.h>
 #include <data/data-in.h>
 
-
 #include <gtk/gtk.h>
 
 #include <string.h>
 
+#include <gettext.h>
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+static GObject *psppire_missing_val_dialog_constructor (
+  GType type, guint, GObjectConstructParam *);
+static void psppire_missing_val_dialog_finalize (GObject *);
+
+G_DEFINE_TYPE (PsppireMissingValDialog,
+               psppire_missing_val_dialog,
+               PSPPIRE_TYPE_DIALOG);
+enum
+  {
+    PROP_0,
+    PROP_VARIABLE,
+    PROP_MISSING_VALUES
+  };
+
+static void
+psppire_missing_val_dialog_set_property (GObject      *object,
+                                         guint         prop_id,
+                                         const GValue *value,
+                                         GParamSpec   *pspec)
+{
+  PsppireMissingValDialog *obj = PSPPIRE_MISSING_VAL_DIALOG (object);
+
+  switch (prop_id)
+    {
+    case PROP_VARIABLE:
+      psppire_missing_val_dialog_set_variable (obj,
+                                               g_value_get_pointer (value));
+      break;
+    case PROP_MISSING_VALUES:
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+psppire_missing_val_dialog_get_property (GObject      *object,
+                                         guint         prop_id,
+                                         GValue       *value,
+                                         GParamSpec   *pspec)
+{
+  PsppireMissingValDialog *obj = PSPPIRE_MISSING_VAL_DIALOG (object);
+
+  switch (prop_id)
+    {
+    case PROP_MISSING_VALUES:
+      g_value_set_pointer (value, &obj->mvl);
+      break;
+    case PROP_VARIABLE:
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+psppire_missing_val_dialog_class_init (PsppireMissingValDialogClass *class)
+{
+  GObjectClass *gobject_class;
+  gobject_class = G_OBJECT_CLASS (class);
+
+  gobject_class->constructor = psppire_missing_val_dialog_constructor;
+  gobject_class->finalize = psppire_missing_val_dialog_finalize;
+  gobject_class->set_property = psppire_missing_val_dialog_set_property;
+  gobject_class->get_property = psppire_missing_val_dialog_get_property;
+
+  g_object_class_install_property (
+    gobject_class, PROP_VARIABLE,
+    g_param_spec_pointer ("variable",
+                          "Variable",
+                          "Variable whose missing values are to be edited.  "
+                          "The variable's print format and encoding are also "
+                          "used for editing.",
+                          G_PARAM_WRITABLE));
+
+  g_object_class_install_property (
+    gobject_class, PROP_MISSING_VALUES,
+    g_param_spec_pointer ("missing-values",
+                          "Missing Values",
+                          "Edited missing values.",
+                          G_PARAM_READABLE));
+}
+
+static void
+psppire_missing_val_dialog_init (PsppireMissingValDialog *dialog)
+{
+  /* We do all of our work on widgets in the constructor function, because that
+     runs after the construction properties have been set.  Otherwise
+     PsppireDialog's "orientation" property hasn't been set and therefore we
+     have no box to populate. */
+  mv_init (&dialog->mvl, 0);
+  dialog->encoding = NULL;
+}
+
+static void
+psppire_missing_val_dialog_finalize (GObject *obj)
+{
+  PsppireMissingValDialog *dialog = PSPPIRE_MISSING_VAL_DIALOG (obj);
+
+  mv_destroy (&dialog->mvl);
+  g_free (dialog->encoding);
+
+  G_OBJECT_CLASS (psppire_missing_val_dialog_parent_class)->finalize (obj);
+}
+
+PsppireMissingValDialog *
+psppire_missing_val_dialog_new (const struct variable *var)
+{
+  return PSPPIRE_MISSING_VAL_DIALOG (
+    g_object_new (PSPPIRE_TYPE_MISSING_VAL_DIALOG,
+                  "orientation", PSPPIRE_VERTICAL,
+                  "variable", var,
+                  NULL));
+}
+
+void
+psppire_missing_val_dialog_run (GtkWindow *parent_window,
+                                const struct variable *var,
+                                struct missing_values *mv)
+{
+  PsppireMissingValDialog *dialog;
+
+  dialog = psppire_missing_val_dialog_new (var);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), parent_window);
+  gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+  gtk_widget_show (GTK_WIDGET (dialog));
+
+  if (psppire_dialog_run (PSPPIRE_DIALOG (dialog)) == GTK_RESPONSE_OK)
+    mv_copy (mv, psppire_missing_val_dialog_get_missing_values (dialog));
+  else
+    mv_copy (mv, var_get_missing_values (var));
+
+  gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
 
 /* A simple (sub) dialog box for displaying user input errors */
 static void
@@ -75,11 +211,13 @@ err_dialog (const gchar *msg, GtkWindow *window)
 }
 
 
-/* Callback which occurs when the OK button is clicked */
-static void
-missing_val_dialog_accept (GtkWidget *w, gpointer data)
+/* Acceptability predicate for PsppireMissingValDialog.
+
+   This function is also the only place that dialog->mvl gets updated. */
+static gboolean
+missing_val_dialog_acceptable (gpointer data)
 {
-  struct missing_val_dialog *dialog = data;
+  PsppireMissingValDialog *dialog = data;
 
   if ( gtk_toggle_button_get_active (dialog->button_discrete))
     {
@@ -99,7 +237,7 @@ missing_val_dialog_accept (GtkWidget *w, gpointer data)
              continue;
            }
 
-         if ( text_to_value (text, dialog->pv, &v))
+         if ( text_to_value__ (text, &dialog->format, dialog->encoding, &v))
            {
              nvals++;
              mv_add_value (&dialog->mvl, &v);
@@ -107,13 +245,13 @@ missing_val_dialog_accept (GtkWidget *w, gpointer data)
          else
              badvals++;
          g_free (text);
-         value_destroy (&v, var_get_width (dialog->pv));
+         value_destroy (&v, fmt_var_width (&dialog->format));
        }
       if ( nvals == 0 || badvals > 0 )
        {
          err_dialog (_("Incorrect value for variable type"),
-                    GTK_WINDOW (dialog->window));
-         return ;
+                      GTK_WINDOW (dialog));
+         return FALSE;
        }
     }
 
@@ -129,18 +267,19 @@ missing_val_dialog_accept (GtkWidget *w, gpointer data)
       gboolean high_ok;
       gboolean ok;
 
-      low_ok = text_to_value (low_text, dialog->pv, &low_val) != NULL;
-      high_ok = text_to_value (high_text, dialog->pv, &high_val) != NULL;
+      low_ok = text_to_value__ (low_text, &dialog->format, dialog->encoding,
+                                &low_val) != NULL;
+      high_ok = text_to_value__ (high_text, &dialog->format, dialog->encoding,
+                                 &high_val) != NULL;
       ok = low_ok && high_ok && low_val.f <= high_val.f;
       if (!ok)
         {
-          err_dialog (_("Incorrect range specification"),
-                      GTK_WINDOW (dialog->window));
+          err_dialog (_("Incorrect range specification"), GTK_WINDOW (dialog));
           if (low_ok)
-            value_destroy (&low_val, var_get_width (dialog->pv));
+            value_destroy (&low_val, fmt_var_width (&dialog->format));
           if (high_ok)
-            value_destroy (&high_val, var_get_width (dialog->pv));
-          return;
+            value_destroy (&high_val, fmt_var_width (&dialog->format));
+          return FALSE;
         }
 
       discrete_text =
@@ -149,24 +288,25 @@ missing_val_dialog_accept (GtkWidget *w, gpointer data)
       mv_clear (&dialog->mvl);
       mv_add_range (&dialog->mvl, low_val.f, high_val.f);
 
-      value_destroy (&low_val, var_get_width (dialog->pv));
-      value_destroy (&high_val, var_get_width (dialog->pv));
+      value_destroy (&low_val, fmt_var_width (&dialog->format));
+      value_destroy (&high_val, fmt_var_width (&dialog->format));
 
       if ( discrete_text && strlen (g_strstrip (discrete_text)) > 0 )
        {
          union value discrete_val;
-         if ( !text_to_value (discrete_text, 
-                              dialog->pv,
-                              &discrete_val))
+         if ( !text_to_value__ (discrete_text,
+                                 &dialog->format,
+                                 dialog->encoding,
+                                 &discrete_val))
            {
              err_dialog (_("Incorrect value for variable type"),
-                        GTK_WINDOW (dialog->window) );
+                        GTK_WINDOW (dialog) );
              g_free (discrete_text);
-             value_destroy (&discrete_val, var_get_width (dialog->pv));
-             return;
+             value_destroy (&discrete_val, fmt_var_width (&dialog->format));
+             return FALSE;
            }
          mv_add_value (&dialog->mvl, &discrete_val);
-         value_destroy (&discrete_val, var_get_width (dialog->pv));
+         value_destroy (&discrete_val, fmt_var_width (&dialog->format));
        }
       g_free (discrete_text);
     }
@@ -175,9 +315,7 @@ missing_val_dialog_accept (GtkWidget *w, gpointer data)
   if (gtk_toggle_button_get_active (dialog->button_none))
     mv_clear (&dialog->mvl);
 
-  var_set_missing_values (dialog->pv, &dialog->mvl);
-
-  gtk_widget_hide (dialog->window);
+  return TRUE;
 }
 
 
@@ -186,7 +324,7 @@ static void
 discrete (GtkToggleButton *button, gpointer data)
 {
   gint i;
-  struct missing_val_dialog *dialog = data;
+  PsppireMissingValDialog *dialog = data;
 
   for (i = 0 ; i < 3 ; ++i )
     {
@@ -199,7 +337,7 @@ discrete (GtkToggleButton *button, gpointer data)
 static void
 range (GtkToggleButton *button, gpointer data)
 {
-  struct missing_val_dialog *dialog = data;
+  PsppireMissingValDialog *dialog = data;
 
   const gboolean active = gtk_toggle_button_get_active (button);
 
@@ -210,40 +348,25 @@ range (GtkToggleButton *button, gpointer data)
 
 
 
-/* Callback for when the Missing Value dialog is closed using
-   the window delete button.*/
-static gint
-on_delete (GtkWidget *w, GdkEvent *e, gpointer data)
-{
-  struct missing_val_dialog *dialog = data;
-
-  gtk_widget_hide (dialog->window);
-
-  return TRUE;
-}
-
-
-/* Creates the dialog structure */
-struct missing_val_dialog *
-missing_val_dialog_create (GtkWindow *toplevel)
+/* Shows the dialog box and sets default values */
+static GObject *
+psppire_missing_val_dialog_constructor (GType                  type,
+                                        guint                  n_properties,
+                                        GObjectConstructParam *properties)
 {
-  GtkBuilder *xml = builder_new ("missing-val-dialog.ui");
-
-  struct missing_val_dialog *dialog = g_malloc (sizeof (*dialog));
-
-  dialog->window = get_widget_assert (xml, "missing_values_dialog");
-
-  gtk_window_set_transient_for
-    (GTK_WINDOW (dialog->window), toplevel);
+  PsppireMissingValDialog *dialog;
+  GtkContainer *content_area;
+  GtkBuilder *xml;
+  GObject *obj;
 
-  g_signal_connect_swapped (get_widget_assert (xml, "missing_val_cancel"),
-                  "clicked", G_CALLBACK (gtk_widget_hide), dialog->window);
+  obj = G_OBJECT_CLASS (psppire_missing_val_dialog_parent_class)->constructor (
+    type, n_properties, properties);
+  dialog = PSPPIRE_MISSING_VAL_DIALOG (obj);
 
-  g_signal_connect (get_widget_assert (xml, "missing_val_ok"),
-                  "clicked", G_CALLBACK (missing_val_dialog_accept), dialog);
-
-  g_signal_connect (dialog->window, "delete-event",
-                   G_CALLBACK (on_delete), dialog);
+  content_area = GTK_CONTAINER (PSPPIRE_DIALOG (dialog)->box);
+  xml = builder_new ("missing-val-dialog.ui");
+  gtk_container_add (GTK_CONTAINER (content_area),
+                     get_widget_assert (xml, "missing-values-dialog"));
 
   dialog->mv[0] = get_widget_assert (xml, "mv0");
   dialog->mv[1] = get_widget_assert (xml, "mv1");
@@ -263,6 +386,9 @@ missing_val_dialog_create (GtkWindow *toplevel)
   dialog->button_range    =
     GTK_TOGGLE_BUTTON (get_widget_assert (xml, "range_missing"));
 
+  psppire_dialog_set_accept_predicate (PSPPIRE_DIALOG (dialog),
+                                       missing_val_dialog_acceptable,
+                                       dialog);
 
   g_signal_connect (dialog->button_discrete, "toggled",
                   G_CALLBACK (discrete), dialog);
@@ -272,18 +398,31 @@ missing_val_dialog_create (GtkWindow *toplevel)
 
   g_object_unref (xml);
 
-  return dialog;
+  return obj;
 }
 
-/* Shows the dialog box and sets default values */
 void
-missing_val_dialog_show (struct missing_val_dialog *dialog)
+psppire_missing_val_dialog_set_variable (PsppireMissingValDialog *dialog,
+                                         const struct variable *var)
 {
+  enum val_type var_type;
   gint i;
-  g_return_if_fail (dialog);
-  g_return_if_fail (dialog->pv);
 
-  mv_copy (&dialog->mvl, var_get_missing_values (dialog->pv));
+  mv_destroy (&dialog->mvl);
+  g_free (dialog->encoding);
+
+  if (var != NULL)
+    {
+      mv_copy (&dialog->mvl, var_get_missing_values (var));
+      dialog->encoding = g_strdup (var_get_encoding (var));
+      dialog->format = *var_get_print_format (var);
+    }
+  else
+    {
+      mv_init (&dialog->mvl, 0);
+      dialog->encoding = NULL;
+      dialog->format = F_8_0;
+    }
 
   /* Blank all entry boxes and make them insensitive */
   gtk_entry_set_text (GTK_ENTRY (dialog->low), "");
@@ -293,9 +432,12 @@ missing_val_dialog_show (struct missing_val_dialog *dialog)
   gtk_widget_set_sensitive (dialog->high, FALSE);
   gtk_widget_set_sensitive (dialog->discrete, FALSE);
 
+  var_type = val_type_from_width (fmt_var_width (&dialog->format));
   gtk_widget_set_sensitive (GTK_WIDGET (dialog->button_range),
-                          var_is_numeric (dialog->pv));
+                           var_type == VAL_NUMERIC);
 
+  if (var == NULL)
+    return;
 
   for (i = 0 ; i < 3 ; ++i )
     {
@@ -311,8 +453,8 @@ missing_val_dialog_show (struct missing_val_dialog *dialog)
       mv_get_range (&dialog->mvl, &low.f, &high.f);
 
 
-      low_text = value_to_text (low, dialog->pv);
-      high_text = value_to_text (high, dialog->pv);
+      low_text = value_to_text__ (low, &dialog->format, dialog->encoding);
+      high_text = value_to_text__ (high, &dialog->format, dialog->encoding);
 
       gtk_entry_set_text (GTK_ENTRY (dialog->low), low_text);
       gtk_entry_set_text (GTK_ENTRY (dialog->high), high_text);
@@ -322,7 +464,8 @@ missing_val_dialog_show (struct missing_val_dialog *dialog)
       if ( mv_has_value (&dialog->mvl))
        {
          gchar *text;
-         text = value_to_text (*mv_get_value (&dialog->mvl, 0), dialog->pv);
+         text = value_to_text__ (*mv_get_value (&dialog->mvl, 0),
+                                  &dialog->format, dialog->encoding);
          gtk_entry_set_text (GTK_ENTRY (dialog->discrete), text);
          g_free (text);
        }
@@ -343,7 +486,8 @@ missing_val_dialog_show (struct missing_val_dialog *dialog)
            {
              gchar *text ;
 
-             text = value_to_text (*mv_get_value (&dialog->mvl, i), dialog->pv);
+             text = value_to_text__ (*mv_get_value (&dialog->mvl, i),
+                                      &dialog->format, dialog->encoding);
              gtk_entry_set_text (GTK_ENTRY (dialog->mv[i]), text);
              g_free (text);
            }
@@ -355,6 +499,11 @@ missing_val_dialog_show (struct missing_val_dialog *dialog)
     {
       gtk_toggle_button_set_active (dialog->button_none, TRUE);
     }
+}
 
-  gtk_widget_show (dialog->window);
+const struct missing_values *
+psppire_missing_val_dialog_get_missing_values (
+  const PsppireMissingValDialog *dialog)
+{
+  return &dialog->mvl;
 }
index 2322b84094b5632910efae7dcccfd2e68d0978ec..12bf110129d043bc369c5027ee481416bb5b34b8 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2005, 2011  Free Software Foundation
+   Copyright (C) 2005, 2011, 2012  Free Software Foundation
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
-#ifndef __PSPPIRE_MISSING_VAL_DIALOG_H
-#define __PSPPIRE_MISSING_VAL_DIALOG_H
+#ifndef PSPPIRE_MISSING_VAL_DIALOG_H
+#define PSPPIRE_MISSING_VAL_DIALOG_H 1
 
 /*  This module describes the behaviour of the Missing Values dialog box,
     used for input of the missing values in the variable sheet */
 
-
 #include <gtk/gtk.h>
+#include "data/format.h"
+#include "data/missing-values.h"
+#include "ui/gui/psppire-dialog.h"
+
+G_BEGIN_DECLS
 
-#include <data/missing-values.h>
+struct variable;
 
-struct missing_val_dialog
-{
-  GtkWidget *window;
+#define PSPPIRE_TYPE_MISSING_VAL_DIALOG             (psppire_missing_val_dialog_get_type())
+#define PSPPIRE_MISSING_VAL_DIALOG(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj),PSPPIRE_TYPE_MISSING_VAL_DIALOG,PsppireMissingValDialog))
+#define PSPPIRE_MISSING_VAL_DIALOG_CLASS(class)     (G_TYPE_CHECK_CLASS_CAST ((class),PSPPIRE_TYPE_MISSING_VAL_DIALOG,PsppireMissingValDialogClass))
+#define PSPPIRE_IS_MISSING_VAL_DIALOG(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj),PSPPIRE_TYPE_MISSING_VAL_DIALOG))
+#define PSPPIRE_IS_MISSING_VAL_DIALOG_CLASS(class)  (G_TYPE_CHECK_CLASS_TYPE ((class),PSPPIRE_TYPE_MISSING_VAL_DIALOG))
+#define PSPPIRE_MISSING_VAL_DIALOG_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj),PSPPIRE_TYPE_MISSING_VAL_DIALOG,PsppireMissingValDialogClass))
 
-  /* The variable whose missing values are to be updated */
-  struct variable *pv;
+typedef struct _PsppireMissingValDialog      PsppireMissingValDialog;
+typedef struct _PsppireMissingValDialogClass PsppireMissingValDialogClass;
+
+struct _PsppireMissingValDialog {
+  PsppireDialog parent;
 
-  /* local copy */
   struct missing_values mvl;
+  gchar *encoding;
+  struct fmt_spec format;
 
   /* Radio Buttons */
   GtkToggleButton *button_none;
@@ -47,8 +58,24 @@ struct missing_val_dialog
   GtkWidget *discrete;
 };
 
-struct missing_val_dialog * missing_val_dialog_create (GtkWindow *toplevel);
+struct _PsppireMissingValDialogClass {
+  PsppireDialogClass parent_class;
+};
+
+GType psppire_missing_val_dialog_get_type (void) G_GNUC_CONST;
+PsppireMissingValDialog* psppire_missing_val_dialog_new (
+  const struct variable *);
+
+void psppire_missing_val_dialog_set_variable (PsppireMissingValDialog *,
+                                              const struct variable *);
+const struct missing_values *psppire_missing_val_dialog_get_missing_values (
+  const PsppireMissingValDialog *);
+
+void psppire_missing_val_dialog_run (GtkWindow *parent_window,
+                                     const struct variable *,
+                                     struct missing_values *);
+
 
-void missing_val_dialog_show (struct missing_val_dialog *dialog);
+G_END_DECLS
 
-#endif
+#endif /* PSPPIRE_MISSING_VAL_DIALOG_H */
index eb0c1246682d745d360c493baa4e4e8a78b986a0..598ed24ba7a2c60052ea5985e372f24c1bc2b92f 100644 (file)
 <interface>
   <!-- interface-requires gtk+ 2.12 -->
   <!-- interface-naming-policy project-wide -->
-  <object class="GtkWindow" id="missing_values_dialog">
-    <property name="border_width">12</property>
-    <property name="title" translatable="yes">Missing Values</property>
-    <property name="resizable">False</property>
-    <property name="modal">True</property>
-    <property name="type_hint">dialog</property>
-    <property name="skip_taskbar_hint">True</property>
-    <property name="skip_pager_hint">True</property>
+  <object class="GtkVBox" id="missing-values-dialog">
+    <property name="visible">True</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">12</property>
     <child>
-      <object class="GtkVBox" id="vbox3">
-        <property name="visible">True</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">12</property>
-        <child>
-          <object class="GtkFrame" id="frame9">
-            <property name="visible">True</property>
-            <property name="label_xalign">0</property>
-            <property name="shadow_type">none</property>
-            <child>
-              <object class="GtkAlignment" id="alignment4">
-                <property name="visible">True</property>
-                <property name="left_padding">12</property>
-                <child>
-                  <placeholder/>
-                </child>
-              </object>
-            </child>
-            <child type="label">
-              <object class="GtkRadioButton" id="no_missing">
-                <property name="label" translatable="yes">_No missing values</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_underline">True</property>
-                <property name="active">True</property>
-                <property name="draw_indicator">True</property>
-              </object>
-            </child>
-          </object>
-          <packing>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkFrame" id="frame4">
-            <property name="visible">True</property>
-            <property name="label_xalign">0</property>
-            <property name="shadow_type">none</property>
-            <child>
-              <object class="GtkAlignment" id="alignment3">
-                <property name="visible">True</property>
-                <property name="left_padding">12</property>
-                <child>
-                  <object class="GtkHBox" id="hbox5">
-                    <property name="visible">True</property>
-                    <property name="border_width">5</property>
-                    <property name="spacing">6</property>
-                    <property name="homogeneous">True</property>
-                    <child>
-                      <object class="GtkEntry" id="mv0">
-                        <property name="width_request">75</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkEntry" id="mv1">
-                        <property name="width_request">75</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkEntry" id="mv2">
-                        <property name="width_request">75</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">2</property>
-                      </packing>
-                    </child>
-                  </object>
-                </child>
-              </object>
-            </child>
-            <child type="label">
-              <object class="GtkRadioButton" id="discrete_missing">
-                <property name="label" translatable="yes">_Discrete missing values</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_underline">True</property>
-                <property name="focus_on_click">False</property>
-                <property name="draw_indicator">True</property>
-                <property name="group">no_missing</property>
-              </object>
-            </child>
-          </object>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkFrame" id="frame10">
-            <property name="visible">True</property>
-            <property name="label_xalign">0</property>
-            <property name="shadow_type">none</property>
-            <child>
-              <object class="GtkAlignment" id="alignment5">
-                <property name="visible">True</property>
-                <property name="left_padding">12</property>
-                <child>
-                  <object class="GtkTable" id="table1">
-                    <property name="visible">True</property>
-                    <property name="n_rows">3</property>
-                    <property name="n_columns">2</property>
-                    <property name="column_spacing">6</property>
-                    <property name="row_spacing">6</property>
-                    <child>
-                      <object class="GtkLabel" id="label11">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">_Low:</property>
-                        <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">mv-low</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkEntry" id="mv-low">
-                        <property name="width_request">75</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label12">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">_High:</property>
-                        <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">mv-high</property>
-                      </object>
-                      <packing>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">2</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkEntry" id="mv-high">
-                        <property name="width_request">75</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">2</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label10">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">Di_screte value:</property>
-                        <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">mv-discrete</property>
-                      </object>
-                      <packing>
-                        <property name="top_attach">2</property>
-                        <property name="bottom_attach">3</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkEntry" id="mv-discrete">
-                        <property name="width_request">75</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">2</property>
-                        <property name="bottom_attach">3</property>
-                      </packing>
-                    </child>
-                  </object>
-                </child>
-              </object>
-            </child>
-            <child type="label">
-              <object class="GtkRadioButton" id="range_missing">
-                <property name="label" translatable="yes">_Range plus one optional discrete missing value</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_underline">True</property>
-                <property name="focus_on_click">False</property>
-                <property name="draw_indicator">True</property>
-                <property name="group">no_missing</property>
-              </object>
-            </child>
-          </object>
-          <packing>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkHButtonBox" id="hbuttonbox1">
-            <property name="visible">True</property>
-            <property name="spacing">6</property>
-            <property name="layout_style">end</property>
-            <child>
-              <object class="GtkButton" id="missing_val_cancel">
-                <property name="label">gtk-cancel</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="help_button_missing_values">
-                <property name="label">gtk-help</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="missing_val_ok">
-                <property name="label">gtk-ok</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="position">3</property>
-          </packing>
-        </child>
+      <object class="GtkFrame" id="frame9">
+       <property name="visible">True</property>
+       <property name="label_xalign">0</property>
+       <property name="shadow_type">none</property>
+       <child>
+         <object class="GtkAlignment" id="alignment4">
+           <property name="visible">True</property>
+           <property name="left_padding">12</property>
+           <child>
+             <placeholder/>
+           </child>
+         </object>
+       </child>
+       <child type="label">
+         <object class="GtkRadioButton" id="no_missing">
+           <property name="label" translatable="yes">_No missing values</property>
+           <property name="visible">True</property>
+           <property name="can_focus">True</property>
+           <property name="receives_default">False</property>
+           <property name="use_underline">True</property>
+           <property name="active">True</property>
+           <property name="draw_indicator">True</property>
+         </object>
+       </child>
       </object>
+      <packing>
+       <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkFrame" id="frame4">
+       <property name="visible">True</property>
+       <property name="label_xalign">0</property>
+       <property name="shadow_type">none</property>
+       <child>
+         <object class="GtkAlignment" id="alignment3">
+           <property name="visible">True</property>
+           <property name="left_padding">12</property>
+           <child>
+             <object class="GtkHBox" id="hbox5">
+               <property name="visible">True</property>
+               <property name="border_width">5</property>
+               <property name="spacing">6</property>
+               <property name="homogeneous">True</property>
+               <child>
+                 <object class="GtkEntry" id="mv0">
+                   <property name="width_request">75</property>
+                   <property name="visible">True</property>
+                   <property name="can_focus">True</property>
+                 </object>
+                 <packing>
+                   <property name="expand">False</property>
+                   <property name="fill">False</property>
+                   <property name="position">0</property>
+                 </packing>
+               </child>
+               <child>
+                 <object class="GtkEntry" id="mv1">
+                   <property name="width_request">75</property>
+                   <property name="visible">True</property>
+                   <property name="can_focus">True</property>
+                 </object>
+                 <packing>
+                   <property name="expand">False</property>
+                   <property name="fill">False</property>
+                   <property name="position">1</property>
+                 </packing>
+               </child>
+               <child>
+                 <object class="GtkEntry" id="mv2">
+                   <property name="width_request">75</property>
+                   <property name="visible">True</property>
+                   <property name="can_focus">True</property>
+                 </object>
+                 <packing>
+                   <property name="expand">False</property>
+                   <property name="fill">False</property>
+                   <property name="position">2</property>
+                 </packing>
+               </child>
+             </object>
+           </child>
+         </object>
+       </child>
+       <child type="label">
+         <object class="GtkRadioButton" id="discrete_missing">
+           <property name="label" translatable="yes">_Discrete missing values</property>
+           <property name="visible">True</property>
+           <property name="can_focus">True</property>
+           <property name="receives_default">False</property>
+           <property name="use_underline">True</property>
+           <property name="focus_on_click">False</property>
+           <property name="draw_indicator">True</property>
+           <property name="group">no_missing</property>
+         </object>
+       </child>
+      </object>
+      <packing>
+       <property name="position">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkFrame" id="frame10">
+       <property name="visible">True</property>
+       <property name="label_xalign">0</property>
+       <property name="shadow_type">none</property>
+       <child>
+         <object class="GtkAlignment" id="alignment5">
+           <property name="visible">True</property>
+           <property name="left_padding">12</property>
+           <child>
+             <object class="GtkTable" id="table1">
+               <property name="visible">True</property>
+               <property name="n_rows">3</property>
+               <property name="n_columns">2</property>
+               <property name="column_spacing">6</property>
+               <property name="row_spacing">6</property>
+               <child>
+                 <object class="GtkLabel" id="label11">
+                   <property name="visible">True</property>
+                   <property name="label" translatable="yes">_Low:</property>
+                   <property name="use_underline">True</property>
+                   <property name="mnemonic_widget">mv-low</property>
+                 </object>
+               </child>
+               <child>
+                 <object class="GtkEntry" id="mv-low">
+                   <property name="width_request">75</property>
+                   <property name="visible">True</property>
+                   <property name="can_focus">True</property>
+                 </object>
+                 <packing>
+                   <property name="left_attach">1</property>
+                   <property name="right_attach">2</property>
+                 </packing>
+               </child>
+               <child>
+                 <object class="GtkLabel" id="label12">
+                   <property name="visible">True</property>
+                   <property name="label" translatable="yes">_High:</property>
+                   <property name="use_underline">True</property>
+                   <property name="mnemonic_widget">mv-high</property>
+                 </object>
+                 <packing>
+                   <property name="top_attach">1</property>
+                   <property name="bottom_attach">2</property>
+                 </packing>
+               </child>
+               <child>
+                 <object class="GtkEntry" id="mv-high">
+                   <property name="width_request">75</property>
+                   <property name="visible">True</property>
+                   <property name="can_focus">True</property>
+                 </object>
+                 <packing>
+                   <property name="left_attach">1</property>
+                   <property name="right_attach">2</property>
+                   <property name="top_attach">1</property>
+                   <property name="bottom_attach">2</property>
+                 </packing>
+               </child>
+               <child>
+                 <object class="GtkLabel" id="label10">
+                   <property name="visible">True</property>
+                   <property name="label" translatable="yes">Di_screte value:</property>
+                   <property name="use_underline">True</property>
+                   <property name="mnemonic_widget">mv-discrete</property>
+                 </object>
+                 <packing>
+                   <property name="top_attach">2</property>
+                   <property name="bottom_attach">3</property>
+                 </packing>
+               </child>
+               <child>
+                 <object class="GtkEntry" id="mv-discrete">
+                   <property name="width_request">75</property>
+                   <property name="visible">True</property>
+                   <property name="can_focus">True</property>
+                 </object>
+                 <packing>
+                   <property name="left_attach">1</property>
+                   <property name="right_attach">2</property>
+                   <property name="top_attach">2</property>
+                   <property name="bottom_attach">3</property>
+                 </packing>
+               </child>
+             </object>
+           </child>
+         </object>
+       </child>
+       <child type="label">
+         <object class="GtkRadioButton" id="range_missing">
+           <property name="label" translatable="yes">_Range plus one optional discrete missing value</property>
+           <property name="visible">True</property>
+           <property name="can_focus">True</property>
+           <property name="receives_default">False</property>
+           <property name="use_underline">True</property>
+           <property name="focus_on_click">False</property>
+           <property name="draw_indicator">True</property>
+           <property name="group">no_missing</property>
+         </object>
+       </child>
+      </object>
+      <packing>
+       <property name="position">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="PsppireHButtonBox" id="hbuttonbox">
+       <property name="visible">True</property>
+       <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+       <property name="border_width">5</property>
+       <property name="buttons">PSPPIRE_BUTTON_CANCEL_MASK | PSPPIRE_BUTTON_OK_MASK | PSPPIRE_BUTTON_HELP_MASK</property>
+      </object>
+      <packing>
+       <property name="expand">False</property>
+       <property name="fill">False</property>
+       <property name="pack_type">end</property>
+       <property name="position">1</property>
+      </packing>
     </child>
   </object>
 </interface>
index d12617f6e39947da8a12ed20c348cba0d341fe6c..b02a0a03ec613b4b272b9d323bfb170be440f192 100644 (file)
@@ -35,8 +35,6 @@
 
 static void psppire_var_sheet_class_init  (PsppireVarSheetClass *klass);
 static void psppire_var_sheet_init        (PsppireVarSheet      *vs);
-static void psppire_var_sheet_realize     (GtkWidget *w);
-static void psppire_var_sheet_unrealize   (GtkWidget *w);
 
 
 enum
@@ -187,15 +185,12 @@ static void
 psppire_var_sheet_class_init (PsppireVarSheetClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
   GParamSpec *pspec;
 
   parent_class = g_type_class_peek_parent (klass);
 
   object_class->dispose = psppire_var_sheet_dispose;
   object_class->finalize = psppire_var_sheet_finalize;
-  widget_class->realize = psppire_var_sheet_realize;
-  widget_class->unrealize = psppire_var_sheet_unrealize;
   object_class->set_property = psppire_var_sheet_set_property;
   object_class->get_property = psppire_var_sheet_get_property;
 
@@ -335,6 +330,26 @@ var_sheet_show_val_labs_dialog (PsppireVarSheet *vs)
     }
 }
 
+static void
+var_sheet_show_miss_vals_dialog (PsppireVarSheet *vs)
+{
+  PsppireVarStore *var_store;
+  struct missing_values mv;
+  struct variable *var;
+  gint row;
+
+  var_store = PSPPIRE_VAR_STORE (psppire_sheet_get_model (PSPPIRE_SHEET (vs)));
+
+  psppire_sheet_get_active_cell (PSPPIRE_SHEET (vs), &row, NULL);
+  var = psppire_var_store_get_var (var_store, row);
+  g_return_if_fail (var != NULL);
+
+  psppire_missing_val_dialog_run (GTK_WINDOW (gtk_widget_get_toplevel (
+                                                GTK_WIDGET (vs))), var, &mv);
+  var_set_missing_values (var, &mv);
+  mv_destroy (&mv);
+}
+
 /*
    Callback whenever the active cell changes on the var sheet.
 */
@@ -428,13 +443,10 @@ var_sheet_change_active_cell (PsppireVarSheet *vs,
        customEntry =
          PSPPIRE_CUSTOM_ENTRY (psppire_sheet_get_entry (sheet));
 
-       vs->missing_val_dialog->pv =
-         psppire_var_store_get_var (var_store, row);
-
        g_signal_connect_swapped (customEntry,
                                  "clicked",
-                                 G_CALLBACK (missing_val_dialog_show),
-                                 vs->missing_val_dialog);
+                                 G_CALLBACK (var_sheet_show_miss_vals_dialog),
+                                 vs);
       }
       break;
 
@@ -514,32 +526,6 @@ var_sheet_change_active_cell (PsppireVarSheet *vs,
 }
 
 
-static void
-psppire_var_sheet_realize (GtkWidget *w)
-{
-  PsppireVarSheet *vs = PSPPIRE_VAR_SHEET (w);
-
-  GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (vs));
-
-  vs->missing_val_dialog = missing_val_dialog_create (GTK_WINDOW (toplevel));
-  
-  /* Chain up to the parent class */
-  GTK_WIDGET_CLASS (parent_class)->realize (w);
-}
-
-static void
-psppire_var_sheet_unrealize (GtkWidget *w)
-{
-  PsppireVarSheet *vs = PSPPIRE_VAR_SHEET (w);
-
-  g_free (vs->missing_val_dialog);
-
-  /* Chain up to the parent class */
-  GTK_WIDGET_CLASS (parent_class)->unrealize (w);
-}
-
-
-
 static void
 psppire_var_sheet_init (PsppireVarSheet *vs)
 {
index 1ea1559dd2b6170b25c8a6a205a53c9ab58104ad..058821b7b30d583236e36b2ae0817187148c0c42 100644 (file)
@@ -42,8 +42,6 @@ struct _PsppireVarSheet
 
   gboolean dispose_has_run;
   gboolean may_create_vars;
-
-  struct missing_val_dialog *missing_val_dialog ;
 };