+#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));
+}
+