/* PSPPIRE - a graphical user interface for PSPP.
- Copyright (C) 2007 Free Software Foundation
+ Copyright (C) 2007, 2009, 2010, 2011, 2012, 2014 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
#include "recode-dialog.h"
+#include "executor.h"
+
+#include "psppire-var-view.h"
+
#include <gtk/gtk.h>
-#include <language/syntax-string-source.h>
-#include <ui/gui/data-editor.h>
+#include <float.h>
+#include <xalloc.h>
+#include <ui/gui/psppire-data-window.h>
#include <ui/gui/dialog-common.h>
#include <ui/gui/dict-display.h>
-#include <ui/gui/helper.h>
+#include <ui/gui/builder-wrapper.h>
+#include "helper.h"
#include <ui/gui/psppire-dialog.h>
-#include <ui/gui/psppire-var-store.h>
-#include <ui/gui/syntax-editor.h>
-#include <libpspp/syntax-gen.h>
+
+#include "psppire-val-chooser.h"
+
+#include <ui/syntax-gen.h>
#include "psppire-acr.h"
struct new_value *copy = g_memdup (nv, sizeof (*copy));
if ( nv->type == NV_STRING )
- copy->v.s = strdup (nv->v.s);
+ copy->v.s = xstrdup (nv->v.s);
return copy;
}
{
case NV_NUMERIC:
{
- gchar *text = g_strdup_printf ("%g", nv->v.v);
+ gchar *text = g_strdup_printf ("%.*g", DBL_DIG + 1, nv->v.v);
g_value_set_string (dest, text);
g_free (text);
}
}
-\f
-
-
-/* A boxed type representing a value, or a range of values which may
- potentially be replaced by something */
-
-enum old_value_type
- {
- OV_NUMERIC,
- OV_STRING,
- OV_SYSMIS,
- OV_MISSING,
- OV_RANGE,
- OV_LOW_UP,
- OV_HIGH_DOWN,
- OV_ELSE
- };
-
-struct old_value
- {
- enum old_value_type type;
- union {
- double v;
- gchar *s;
- double range[2];
- } v;
- };
-
-
-static struct old_value *
-old_value_copy (struct old_value *ov)
-{
- struct old_value *copy = g_memdup (ov, sizeof (*copy));
-
- if ( ov->type == OV_STRING )
- copy->v.s = g_strdup (ov->v.s);
-
- return copy;
-}
-
-
-static void
-old_value_free (struct old_value *ov)
-{
- if (ov->type == OV_STRING)
- g_free (ov->v.s);
- g_free (ov);
-}
-
-static void
-old_value_to_string (const GValue *src, GValue *dest)
-{
- const struct old_value *ov = g_value_get_boxed (src);
-
- switch (ov->type)
- {
- case OV_NUMERIC:
- {
- gchar *text = g_strdup_printf ("%g", ov->v.v);
- g_value_set_string (dest, text);
- g_free (text);
- }
- break;
- case OV_STRING:
- g_value_set_string (dest, ov->v.s);
- break;
- case OV_MISSING:
- g_value_set_string (dest, "MISSING");
- break;
- case OV_SYSMIS:
- g_value_set_string (dest, "SYSMIS");
- break;
- case OV_ELSE:
- g_value_set_string (dest, "ELSE");
- break;
- case OV_RANGE:
- {
- gchar *text;
- char en_dash[6] = {0,0,0,0,0,0};
-
- g_unichar_to_utf8 (0x2013, en_dash);
-
- text = g_strdup_printf ("%g %s %g",
- ov->v.range[0],
- en_dash,
- ov->v.range[1]);
- g_value_set_string (dest, text);
- g_free (text);
- }
- break;
- case OV_LOW_UP:
- {
- gchar *text;
- char en_dash[6] = {0,0,0,0,0,0};
-
- g_unichar_to_utf8 (0x2013, en_dash);
-
- text = g_strdup_printf ("LOWEST %s %g",
- en_dash,
- ov->v.range[1]);
-
- g_value_set_string (dest, text);
- g_free (text);
- }
- break;
- case OV_HIGH_DOWN:
- {
- gchar *text;
- char en_dash[6] = {0,0,0,0,0,0};
-
- g_unichar_to_utf8 (0x2013, en_dash);
-
- text = g_strdup_printf ("%g %s HIGHEST",
- ov->v.range[0],
- en_dash);
-
- g_value_set_string (dest, text);
- g_free (text);
- }
- break;
- default:
- g_warning ("Invalid type in old recode value");
- g_value_set_string (dest, "???");
- break;
- };
-}
-
-static GType
-old_value_get_type (void)
-{
- static GType t = 0;
-
- if (t == 0 )
- {
- t = g_boxed_type_register_static ("psppire-recode-old-values",
- (GBoxedCopyFunc) old_value_copy,
- (GBoxedFreeFunc) old_value_free);
-
- g_value_register_transform_func (t, G_TYPE_STRING,
- old_value_to_string);
- }
-
- return t;
-}
-
\f
enum
BUTTON_NEW_VALUE,
BUTTON_NEW_COPY,
BUTTON_NEW_SYSMIS,
- BUTTON_OLD_VALUE,
- BUTTON_OLD_SYSMIS,
- BUTTON_OLD_MISSING,
- BUTTON_OLD_RANGE,
- BUTTON_OLD_LOW_UP,
- BUTTON_OLD_HIGH_DOWN,
- BUTTON_OLD_ELSE,
n_BUTTONS
};
GtkWidget *convert_button;
GtkWidget *new_copy_label;
- GtkWidget *ov_value_entry;
GtkWidget *new_value_entry;
- GtkWidget *ov_range_lower_entry;
- GtkWidget *ov_range_upper_entry;
- GtkWidget *ov_low_up_entry;
- GtkWidget *ov_high_down_entry;
+ GtkWidget *old_value_chooser;
GtkListStore *value_map;
gboolean input_var_is_string;
- GtkListStore *var_map;
GtkWidget *new_name_entry;
GtkWidget *new_label_entry;
GtkWidget *change_button;
GtkWidget *string_button;
GtkWidget *width_entry;
+
+ /* A hash table of struct nlp's indexed by variable */
+ GHashTable *varmap;
};
static void
refresh (PsppireDialog *dialog, struct recode_dialog *rd)
{
+ GtkTreeModel *vars =
+ gtk_tree_view_get_model (GTK_TREE_VIEW (rd->variable_treeview));
+
+ gtk_list_store_clear (GTK_LIST_STORE (vars));
+
gtk_widget_set_sensitive (rd->change_button, FALSE);
gtk_widget_set_sensitive (rd->new_name_entry, FALSE);
gtk_widget_set_sensitive (rd->new_label_entry, FALSE);
-
- if ( rd->different )
- gtk_list_store_clear (GTK_LIST_STORE (rd->var_map));
- else
- {
- GtkTreeModel *vars =
- gtk_tree_view_get_model (GTK_TREE_VIEW (rd->variable_treeview));
-
- gtk_list_store_clear (GTK_LIST_STORE (vars));
- }
+ if ( rd->different && rd->varmap )
+ g_hash_table_remove_all (rd->varmap);
gtk_list_store_clear (GTK_LIST_STORE (rd->value_map));
}
static char * generate_syntax (const struct recode_dialog *rd);
-enum {
- COL_OLD,
- COL_NEW_NAME,
- COL_NEW_LABEL,
- n_COL_VARS
-};
-
enum {
COL_VALUE_OLD,
COL_VALUE_NEW,
if ( rd->different )
{
- GtkTreeIter iter;
-
- gboolean ok;
-
- for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (rd->var_map),
- &iter);
- ok;
- ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (rd->var_map),
- &iter))
- {
- gchar *name = NULL;
-
- gtk_tree_model_get (GTK_TREE_MODEL (rd->var_map), &iter,
- COL_NEW_NAME, &name, -1);
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (rd->variable_treeview));
- if ( name == NULL )
- return FALSE;
-
- g_free (name);
- }
+ if (g_hash_table_size (rd->varmap) != gtk_tree_model_iter_n_children (model, NULL) )
+ return FALSE;
}
else
{
if ( !gtk_tree_model_get_iter_first (vars, ¬_used))
return FALSE;
-
}
return TRUE;
static void
on_old_new_show (struct recode_dialog *rd)
{
- gtk_toggle_button_set_active
- (GTK_TOGGLE_BUTTON (rd->toggle[BUTTON_OLD_VALUE]), TRUE);
-
- g_signal_emit_by_name (rd->toggle[BUTTON_OLD_VALUE], "toggled");
-
gtk_toggle_button_set_active
(GTK_TOGGLE_BUTTON (rd->toggle[BUTTON_NEW_VALUE]), TRUE);
gtk_widget_set_sensitive (target, state);
}
-static void recode_dialog (struct data_editor *de, gboolean diff);
+static void recode_dialog (PsppireDataWindow *de, gboolean diff);
/* Pops up the Recode Same version of the dialog box */
void
-recode_same_dialog (GObject *o, gpointer data)
+recode_same_dialog (PsppireDataWindow *de)
{
- struct data_editor *de = data;
-
recode_dialog (de, FALSE);
}
/* Pops up the Recode Different version of the dialog box */
void
-recode_different_dialog (GObject *o, gpointer data)
+recode_different_dialog (PsppireDataWindow *de)
{
- struct data_editor *de = data;
-
recode_dialog (de, TRUE);
}
-static void
-render_new_var_name (GtkTreeViewColumn *tree_column,
- GtkCellRenderer *cell,
- GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- gpointer data)
-{
- gchar *new_var_name = NULL;
-
- gtk_tree_model_get (tree_model, iter, COL_NEW_NAME, &new_var_name, -1);
-
- g_object_set (cell, "text", new_var_name, NULL);
-
- g_free (new_var_name);
-}
-
/* This might need to be changed to something less naive.
In particular, what happends with dates, etc?
static gchar *
num_to_string (gdouble x)
{
- return g_strdup_printf ("%g", x);
+ return g_strdup_printf ("%.*g", DBL_DIG + 1, x);
}
/* Callback which gets called when a new row is selected
g_value_unset (&nv_value);
}
- if ( ov )
- {
- switch (ov->type)
- {
- case OV_STRING:
- gtk_toggle_button_set_active
- (GTK_TOGGLE_BUTTON (rd->toggle [BUTTON_OLD_VALUE]), TRUE);
-
- gtk_entry_set_text (GTK_ENTRY (rd->ov_value_entry), ov->v.s);
- break;
-
- case OV_NUMERIC:
- {
- gchar *str;
-
- gtk_toggle_button_set_active
- (GTK_TOGGLE_BUTTON (rd->toggle [BUTTON_OLD_VALUE]), TRUE);
-
- str = num_to_string (ov->v.v);
-
- gtk_entry_set_text (GTK_ENTRY (rd->ov_value_entry), str);
-
- g_free (str);
- }
- break;
-
- case OV_SYSMIS:
- gtk_toggle_button_set_active
- (GTK_TOGGLE_BUTTON (rd->toggle [BUTTON_OLD_SYSMIS]), TRUE);
- break;
-
- case OV_MISSING:
- gtk_toggle_button_set_active
- (GTK_TOGGLE_BUTTON (rd->toggle [BUTTON_OLD_MISSING]), TRUE);
- break;
-
- case OV_RANGE:
- {
- gchar *str;
-
- gtk_toggle_button_set_active
- (GTK_TOGGLE_BUTTON (rd->toggle [BUTTON_OLD_RANGE]), TRUE);
-
- str = num_to_string (ov->v.range[0]);
-
- gtk_entry_set_text (GTK_ENTRY (rd->ov_range_lower_entry), str);
-
- g_free (str);
-
-
- str = num_to_string (ov->v.range[1]);
-
- gtk_entry_set_text (GTK_ENTRY (rd->ov_range_upper_entry), str);
-
- g_free (str);
- }
- break;
+ psppire_val_chooser_set_status (PSPPIRE_VAL_CHOOSER (rd->old_value_chooser), ov);
+}
- case OV_LOW_UP:
- {
- gchar *str = num_to_string (ov->v.range[1]);
+/* Name-Label pair */
+struct nlp
+{
+ char *name;
+ char *label;
+};
- gtk_toggle_button_set_active
- (GTK_TOGGLE_BUTTON (rd->toggle [BUTTON_OLD_LOW_UP]), TRUE);
+static struct nlp *
+nlp_create (const char *name, const char *label)
+{
+ struct nlp *nlp = xmalloc (sizeof *nlp);
- gtk_entry_set_text (GTK_ENTRY (rd->ov_low_up_entry), str);
+ nlp->name = g_strdup (name);
- g_free (str);
- }
- break;
+ nlp->label = NULL;
- case OV_HIGH_DOWN:
- {
- gchar *str = num_to_string (ov->v.range[0]);
+ if ( 0 != strcmp ("", label))
+ nlp->label = g_strdup (label);
- gtk_toggle_button_set_active
- (GTK_TOGGLE_BUTTON (rd->toggle [BUTTON_OLD_HIGH_DOWN]), TRUE);
+ return nlp;
+}
- gtk_entry_set_text (GTK_ENTRY (rd->ov_high_down_entry), str);
+static void
+nlp_destroy (gpointer data)
+{
+ struct nlp *nlp = data ;
+ if ( ! nlp )
+ return;
- g_free (str);
- }
- break;
-
- case OV_ELSE:
- gtk_toggle_button_set_active
- (GTK_TOGGLE_BUTTON (rd->toggle [BUTTON_OLD_ELSE]), TRUE);
- break;
-
- default:
- g_warning ("Unknown old value type");
- break;
- };
- g_value_unset (&ov_value);
- }
+ g_free (nlp->name);
+ g_free (nlp->label);
+ g_free (nlp);
}
+
/* Callback which gets called when a new row is selected
in the variable treeview.
It sets the name and label entry widgets to reflect the
on_selection_change (GtkTreeSelection *selection, gpointer data)
{
struct recode_dialog *rd = data;
- GtkTreeModel *model = GTK_TREE_MODEL (rd->var_map);
+
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (rd->variable_treeview));
GList *rows = gtk_tree_selection_get_selected_rows (selection, &model);
if ( rows && !rows->next)
{
/* Exactly one row is selected */
-
+ struct nlp *nlp;
+ struct variable *var;
gboolean ok;
GtkTreeIter iter;
- gchar *name = NULL;
- gchar *label = NULL;
gtk_widget_set_sensitive (rd->change_button, TRUE);
gtk_widget_set_sensitive (rd->new_name_entry, TRUE);
gtk_widget_set_sensitive (rd->new_label_entry, TRUE);
ok = gtk_tree_model_get_iter (model, &iter, (GtkTreePath*) rows->data);
+ g_return_if_fail (ok);
- gtk_tree_model_get (GTK_TREE_MODEL (rd->var_map), &iter,
- COL_NEW_NAME, &name,
- COL_NEW_LABEL, &label,
+ gtk_tree_model_get (model, &iter,
+ 0, &var,
-1);
- gtk_entry_set_text (GTK_ENTRY (rd->new_name_entry), name ? name : "");
- gtk_entry_set_text (GTK_ENTRY (rd->new_label_entry), label ? label : "");
+ nlp = g_hash_table_lookup (rd->varmap, var);
- g_free (name);
- g_free (label);
+ if (nlp)
+ {
+ gtk_entry_set_text (GTK_ENTRY (rd->new_name_entry), nlp->name ? nlp->name : "");
+ gtk_entry_set_text (GTK_ENTRY (rd->new_label_entry), nlp->label ? nlp->label : "");
+ }
+ else
+ {
+ gtk_entry_set_text (GTK_ENTRY (rd->new_name_entry), "");
+ gtk_entry_set_text (GTK_ENTRY (rd->new_label_entry), "");
+ }
}
else
{
gtk_entry_set_text (GTK_ENTRY (rd->new_label_entry), "");
}
+
g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
g_list_free (rows);
}
gtk_widget_set_sensitive (rd->string_button, !active);
}
-
static void
on_change_clicked (GObject *obj, gpointer data)
{
struct recode_dialog *rd = data;
- GtkTreeModel *model = GTK_TREE_MODEL (rd->var_map);
+ struct variable *var = NULL;
+ struct nlp *nlp;
+
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (rd->variable_treeview));
+
GtkTreeIter iter;
GtkTreeSelection *selection =
gtk_tree_view_get_selection (GTK_TREE_VIEW (rd->variable_treeview));
const gchar *dest_var_label =
gtk_entry_get_text (GTK_ENTRY (rd->new_label_entry));
- if ( NULL == rows )
- return;
+ if ( NULL == rows || rows->next != NULL)
+ goto finish;
gtk_tree_model_get_iter (model, &iter, rows->data);
- gtk_list_store_set (rd->var_map, &iter,
- COL_NEW_NAME, dest_var_name,
- COL_NEW_LABEL, dest_var_label,
- -1);
+ gtk_tree_model_get (model, &iter, 0, &var, -1);
+
+ g_hash_table_remove (rd->varmap, var);
+
+ nlp = nlp_create (dest_var_name, dest_var_label);
+
+ g_hash_table_insert (rd->varmap, var, nlp);
+ gtk_tree_model_row_changed (model, rows->data, &iter);
+
+ finish:
g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
g_list_free (rows);
}
-/* If there's nothing selected in the variable treeview,
- then automatically select the first item */
static void
-select_something (GtkTreeModel *treemodel,
- GtkTreePath *arg1,
- GtkTreeIter *arg2,
- gpointer data)
+focus_value_entry (GtkWidget *w, struct recode_dialog *rd)
{
- struct recode_dialog *rd = data;
- GtkTreeSelection *sel;
-
- sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (rd->variable_treeview));
-
- if ( gtk_tree_selection_count_selected_rows (sel) < 1)
- {
- GtkTreeIter iter;
-
- gtk_tree_model_get_iter_first (treemodel, &iter);
-
- gtk_tree_selection_select_iter (sel, &iter);
- }
+ if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)))
+ gtk_widget_grab_focus (rd->new_value_entry);
}
}
static void
-recode_dialog (struct data_editor *de, gboolean diff)
+render_new_var_name (GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gpointer data)
{
- gint response;
+ struct nlp *nlp = NULL;
+ struct recode_dialog *rd = data;
- struct recode_dialog rd;
+ struct variable *var = NULL;
+
+ gtk_tree_model_get (tree_model, iter,
+ 0, &var,
+ -1);
+
+ nlp = g_hash_table_lookup (rd->varmap, var);
- GladeXML *xml = XML_NEW ("recode.glade");
+ if ( nlp )
+ g_object_set (cell, "text", nlp->name, NULL);
+ else
+ g_object_set (cell, "text", "", NULL);
+}
- GtkWidget *selector = get_widget_assert (xml, "psppire-selector1");
- GtkWidget *oldandnew = get_widget_assert (xml, "button1");
+static void
+recode_dialog (PsppireDataWindow *de, gboolean diff)
+{
+ gint response;
+ struct recode_dialog rd;
- GtkWidget *output_variable_box = get_widget_assert (xml,"frame4");
+ GtkBuilder *builder = builder_new ("recode.ui");
+ GtkWidget *selector = get_widget_assert (builder, "psppire-selector1");
- PsppireVarStore *vs = NULL;
+ GtkWidget *oldandnew = get_widget_assert (builder, "button1");
- g_object_get (de->data_editor, "var-store", &vs, NULL);
- rd.change_button = get_widget_assert (xml, "change-button");
+ GtkWidget *output_variable_box = get_widget_assert (builder,"frame4");
- rd.dialog = get_widget_assert (xml, "recode-dialog");
- rd.dict_treeview = get_widget_assert (xml, "treeview1");
- rd.variable_treeview = get_widget_assert (xml, "treeview2");
- rd.new_name_entry = get_widget_assert (xml, "dest-name-entry");
- rd.new_label_entry = get_widget_assert (xml, "dest-label-entry");
+ rd.change_button = get_widget_assert (builder, "change-button");
+ rd.varmap = NULL;
+ rd.dialog = get_widget_assert (builder, "recode-dialog");
+ rd.dict_treeview = get_widget_assert (builder, "treeview1");
+ rd.variable_treeview = get_widget_assert (builder, "treeview2");
+ rd.new_name_entry = get_widget_assert (builder, "dest-name-entry");
+ rd.new_label_entry = get_widget_assert (builder, "dest-label-entry");
- rd.dict = vs->dict;
+ g_object_get (de->data_editor, "dictionary", &rd.dict, NULL);
rd.value_map = gtk_list_store_new (2,
old_value_get_type (),
rd.different = diff;
- gtk_window_set_transient_for (GTK_WINDOW (rd.dialog), de->parent.window);
-
-
- attach_dictionary_to_treeview (GTK_TREE_VIEW (rd.dict_treeview),
- vs->dict,
- GTK_SELECTION_MULTIPLE, NULL);
+ gtk_window_set_transient_for (GTK_WINDOW (rd.dialog), GTK_WINDOW (de));
+ g_object_set (rd.dict_treeview, "model", rd.dict, NULL);
- if ( ! rd.different )
- {
- set_dest_model (GTK_TREE_VIEW (rd.variable_treeview), vs->dict);
- }
- else
+ if (rd.different)
{
GtkTreeSelection *sel;
- GtkTreeViewColumn *col;
- GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
-
- rd.var_map = gtk_list_store_new (n_COL_VARS, G_TYPE_INT,
- G_TYPE_STRING,
- G_TYPE_STRING);
-
+ GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_set_model (GTK_TREE_VIEW (rd.variable_treeview),
- GTK_TREE_MODEL (rd.var_map));
-
- col = gtk_tree_view_column_new_with_attributes (_("Old"),
- renderer,
- "text", NULL,
- NULL);
+ GtkTreeViewColumn *col = gtk_tree_view_column_new_with_attributes (_("New"),
+ renderer,
+ "text", NULL,
+ NULL);
gtk_tree_view_column_set_cell_data_func (col, renderer,
- cell_var_name,
- vs->dict, 0);
+ render_new_var_name,
+ &rd, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (rd.variable_treeview), col);
- renderer = gtk_cell_renderer_text_new ();
-
- col = gtk_tree_view_column_new_with_attributes (_("New"),
- renderer,
- "text", NULL,
- NULL);
-
- gtk_tree_view_column_set_cell_data_func (col, renderer,
- render_new_var_name,
- NULL, NULL);
-
+ col = gtk_tree_view_get_column (GTK_TREE_VIEW (rd.variable_treeview), 0);
- gtk_tree_view_append_column (GTK_TREE_VIEW (rd.variable_treeview), col);
+ g_object_set (col, "title", _("Old"), NULL);
g_object_set (rd.variable_treeview, "headers-visible", TRUE, NULL);
- g_signal_connect (rd.change_button, "clicked",
- G_CALLBACK (on_change_clicked), &rd);
+ rd.varmap = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, nlp_destroy);
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (rd.variable_treeview));
+
g_signal_connect (sel, "changed",
G_CALLBACK (on_selection_change), &rd);
- g_signal_connect (rd.var_map, "row-inserted",
- G_CALLBACK (select_something), &rd);
- }
-
-
+ g_signal_connect (rd.change_button, "clicked",
+ G_CALLBACK (on_change_clicked), &rd);
- psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector),
- rd.dict_treeview,
- rd.variable_treeview,
- insert_source_row_into_tree_view,
- NULL,
- NULL);
+ }
psppire_selector_set_allow (PSPPIRE_SELECTOR (selector), homogeneous_types);
/* Set up the Old & New Values subdialog */
{
- rd.string_button = get_widget_assert (xml, "checkbutton1");
- rd.width_entry = get_widget_assert (xml, "spinbutton1");
+ rd.string_button = get_widget_assert (builder, "checkbutton1");
+ rd.width_entry = get_widget_assert (builder, "spinbutton1");
- rd.convert_button = get_widget_assert (xml, "checkbutton2");
+ rd.convert_button = get_widget_assert (builder, "checkbutton2");
- rd.ov_range_lower_entry = get_widget_assert (xml, "entry5");
- rd.ov_range_upper_entry = get_widget_assert (xml, "entry3");
- rd.ov_low_up_entry = get_widget_assert (xml, "entry6");
- rd.ov_high_down_entry = get_widget_assert (xml, "entry7");
+ rd.old_value_chooser = get_widget_assert (builder, "val-chooser");
- rd.new_value_entry = get_widget_assert (xml, "entry1");
- rd.ov_value_entry = get_widget_assert (xml, "entry2");
+ rd.new_value_entry = get_widget_assert (builder, "entry1");
- rd.toggle[BUTTON_NEW_VALUE] = get_widget_assert (xml, "radiobutton1");
- rd.toggle[BUTTON_NEW_SYSMIS] = get_widget_assert (xml, "radiobutton2");
- rd.toggle[BUTTON_NEW_COPY] = get_widget_assert (xml, "radiobutton3");
- rd.toggle[BUTTON_OLD_VALUE] = get_widget_assert (xml, "radiobutton4");
- rd.toggle[BUTTON_OLD_SYSMIS] = get_widget_assert (xml, "radiobutton6");
- rd.toggle[BUTTON_OLD_MISSING]= get_widget_assert (xml, "radiobutton7");
- rd.toggle[BUTTON_OLD_RANGE] = get_widget_assert (xml, "radiobutton8");
- rd.toggle[BUTTON_OLD_LOW_UP] = get_widget_assert (xml, "radiobutton10");
- rd.toggle[BUTTON_OLD_HIGH_DOWN] = get_widget_assert (xml, "radiobutton5");
- rd.toggle[BUTTON_OLD_ELSE] = get_widget_assert (xml, "radiobutton11");
- rd.new_copy_label = get_widget_assert (xml, "label3");
- rd.strings_box = get_widget_assert (xml, "table3");
+ rd.toggle[BUTTON_NEW_VALUE] = get_widget_assert (builder, "radiobutton1");
+ rd.toggle[BUTTON_NEW_SYSMIS] = get_widget_assert (builder, "radiobutton2");
+ rd.toggle[BUTTON_NEW_COPY] = get_widget_assert (builder, "radiobutton3");
+
+ rd.new_copy_label = get_widget_assert (builder, "label3");
+ rd.strings_box = get_widget_assert (builder, "table3");
rd.old_and_new_dialog =
- PSPPIRE_DIALOG (get_widget_assert (xml, "old-new-values-dialog"));
+ PSPPIRE_DIALOG (get_widget_assert (builder, "old-new-values-dialog"));
gtk_window_set_transient_for (GTK_WINDOW (rd.old_and_new_dialog),
- de->parent.window);
+ GTK_WINDOW (de));
- rd.acr = PSPPIRE_ACR (get_widget_assert (xml, "psppire-acr1"));
+ rd.acr = PSPPIRE_ACR (get_widget_assert (builder, "psppire-acr1"));
g_signal_connect_swapped (rd.toggle[BUTTON_NEW_VALUE], "toggled",
G_CALLBACK (set_acr), &rd);
+ g_signal_connect_after (rd.toggle[BUTTON_NEW_VALUE], "toggled",
+ G_CALLBACK (focus_value_entry), &rd);
+
g_signal_connect_swapped (rd.new_value_entry, "changed",
G_CALLBACK (set_acr), &rd);
g_signal_connect (rd.toggle[BUTTON_NEW_VALUE], "toggled",
G_CALLBACK (toggle_sensitivity), rd.new_value_entry);
- g_signal_connect (rd.toggle[BUTTON_OLD_VALUE], "toggled",
- G_CALLBACK (toggle_sensitivity), rd.ov_value_entry);
-
- g_signal_connect (rd.toggle[BUTTON_OLD_RANGE], "toggled",
- G_CALLBACK (toggle_sensitivity),
- get_widget_assert (xml, "entry3"));
-
- g_signal_connect (rd.toggle[BUTTON_OLD_RANGE], "toggled",
- G_CALLBACK (toggle_sensitivity),
- get_widget_assert (xml, "entry5"));
-
- g_signal_connect (rd.toggle[BUTTON_OLD_LOW_UP], "toggled",
- G_CALLBACK (toggle_sensitivity), rd.ov_low_up_entry);
-
- g_signal_connect (rd.toggle[BUTTON_OLD_HIGH_DOWN], "toggled",
- G_CALLBACK (toggle_sensitivity), rd.ov_high_down_entry);
-
g_signal_connect (rd.string_button, "toggled",
G_CALLBACK (toggle_sensitivity), rd.width_entry);
switch (response)
{
case GTK_RESPONSE_OK:
- {
- gchar *syntax = generate_syntax (&rd);
- struct getl_interface *sss = create_syntax_string_source (syntax);
- execute_syntax (sss);
-
- g_free (syntax);
- }
+ g_free (execute_syntax_string (de, generate_syntax (&rd)));
break;
case PSPPIRE_RESPONSE_PASTE:
- {
- gchar *syntax = generate_syntax (&rd);
-
- struct syntax_editor *se =
- (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
- gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
-
- g_free (syntax);
- }
+ g_free (paste_syntax_to_window (generate_syntax (&rd)));
break;
default:
break;
}
+ if (rd.varmap)
+ g_hash_table_destroy (rd.varmap);
gtk_list_store_clear (GTK_LIST_STORE (rd.value_map));
g_object_unref (rd.value_map);
- g_object_unref (xml);
+ g_object_unref (builder);
}
/* Initialise VAL to reflect the current status of RD */
static gboolean
set_old_value (GValue *val, const struct recode_dialog *rd)
{
- const gchar *text = NULL;
- struct old_value ov;
- if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
- (rd->toggle [BUTTON_OLD_VALUE])))
- {
- text = gtk_entry_get_text (GTK_ENTRY (rd->ov_value_entry));
- if ( rd->input_var_is_string )
- {
- ov.type = OV_STRING;
- ov.v.s = g_strdup (text);
- }
- else
- {
- ov.type = OV_NUMERIC;
- ov.v.v = g_strtod (text, 0);
- }
- }
- else if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
- (rd->toggle [BUTTON_OLD_MISSING])))
- {
- ov.type = OV_MISSING;
- }
- else if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
- (rd->toggle [BUTTON_OLD_SYSMIS])))
- {
- ov.type = OV_SYSMIS;
- }
- else if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
- (rd->toggle [BUTTON_OLD_ELSE])))
- {
- ov.type = OV_ELSE;
- }
- else if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
- (rd->toggle [BUTTON_OLD_RANGE])))
- {
- const gchar *text;
- text = gtk_entry_get_text (GTK_ENTRY (rd->ov_range_lower_entry));
+ PsppireValChooser *vc = PSPPIRE_VAL_CHOOSER (rd->old_value_chooser);
- ov.type = OV_RANGE;
- ov.v.range[0] = g_strtod (text, 0);
-
- text = gtk_entry_get_text (GTK_ENTRY (rd->ov_range_upper_entry));
- ov.v.range[1] = g_strtod (text, 0);
- }
- else if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
- (rd->toggle [BUTTON_OLD_LOW_UP])))
- {
- const gchar *text =
- gtk_entry_get_text (GTK_ENTRY (rd->ov_low_up_entry));
-
- ov.type = OV_LOW_UP;
- ov.v.range[1] = g_strtod (text, 0);
- }
- else if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
- (rd->toggle [BUTTON_OLD_HIGH_DOWN])))
- {
- const gchar *text =
- gtk_entry_get_text (GTK_ENTRY (rd->ov_high_down_entry));
+ struct old_value ov;
- ov.type = OV_HIGH_DOWN;
- ov.v.range[0] = g_strtod (text, 0);
- }
- else
- return FALSE;
+ psppire_val_chooser_get_status (vc, &ov);
g_value_init (val, old_value_get_type ());
g_value_set_boxed (val, &ov);
/* A function to set a value in a column in the ACR */
-gboolean
+static gboolean
set_value (gint col, GValue *val, gpointer data)
{
struct recode_dialog *rd = data;
/* Find the type of the first variable (it's invariant that
all variables are of the same type) */
const struct variable *v;
- gint idx;
GtkTreeIter iter;
GtkTreeModel *model =
gtk_tree_view_get_model (GTK_TREE_VIEW (rd->variable_treeview));
g_return_if_fail (not_empty);
- gtk_tree_model_get (model, &iter, 0, &idx, -1);
-
- v = psppire_dict_get_variable (rd->dict, idx);
+ gtk_tree_model_get (model, &iter, 0, &v, -1);
rd->input_var_is_string = var_is_alpha (v);
- gtk_widget_set_sensitive (rd->toggle [BUTTON_OLD_SYSMIS],
- var_is_numeric (v));
- gtk_widget_set_sensitive (rd->toggle [BUTTON_OLD_RANGE],
- var_is_numeric (v));
- gtk_widget_set_sensitive (rd->toggle [BUTTON_OLD_LOW_UP],
- var_is_numeric (v));
- gtk_widget_set_sensitive (rd->toggle [BUTTON_OLD_HIGH_DOWN],
- var_is_numeric (v));
+ g_object_set (rd->old_value_chooser, "is-string", rd->input_var_is_string, NULL);
+
gtk_widget_set_sensitive (rd->toggle [BUTTON_NEW_SYSMIS],
var_is_numeric (v));
/* Generate a syntax fragment for NV and append it to STR */
static void
-new_value_append_syntax (GString *str, const struct new_value *nv)
+new_value_append_syntax (struct string *dds, const struct new_value *nv)
{
switch (nv->type)
{
case NV_NUMERIC:
- g_string_append_printf (str, "%g", nv->v.v);
+ ds_put_c_format (dds, "%.*g", DBL_DIG + 1, nv->v.v);
break;
case NV_STRING:
- {
- struct string ds;
- ds_init_cstr (&ds, nv->v.s);
- gen_quoted_string (&ds);
- g_string_append (str, ds_cstr (&ds));
- ds_destroy (&ds);
- }
+ syntax_gen_string (dds, ss_cstr (nv->v.s));
break;
case NV_COPY:
- g_string_append (str, "COPY");
+ ds_put_cstr (dds, "COPY");
break;
case NV_SYSMIS:
- g_string_append (str, "SYSMIS");
+ ds_put_cstr (dds, "SYSMIS");
break;
default:
/* Shouldn't ever happen */
g_warning ("Invalid type in new recode value");
- g_string_append (str, "???");
+ ds_put_cstr (dds, "???");
break;
}
}
-/* Generate a syntax fragment for NV and append it to STR */
-static void
-old_value_append_syntax (GString *str, const struct old_value *ov)
-{
- switch (ov->type)
- {
- case OV_NUMERIC:
- g_string_append_printf (str, "%g", ov->v.v);
- break;
- case OV_STRING:
- {
- struct string ds;
- ds_init_cstr (&ds, ov->v.s);
- gen_quoted_string (&ds);
- g_string_append (str, ds_cstr (&ds));
- ds_destroy (&ds);
- }
- break;
- case OV_MISSING:
- g_string_append (str, "MISSING");
- break;
- case OV_SYSMIS:
- g_string_append (str, "SYSMIS");
- break;
- case OV_ELSE:
- g_string_append (str, "ELSE");
- break;
- case OV_RANGE:
- g_string_append_printf (str, "%g THRU %g",
- ov->v.range[0],
- ov->v.range[1]);
- break;
- case OV_LOW_UP:
- g_string_append_printf (str, "LOWEST THRU %g",
- ov->v.range[1]);
- break;
- case OV_HIGH_DOWN:
- g_string_append_printf (str, "%g THRU HIGHEST",
- ov->v.range[0]);
- break;
- default:
- g_warning ("Invalid type in old recode value");
- g_string_append (str, "???");
- break;
- };
-}
-
-
-
static char *
generate_syntax (const struct recode_dialog *rd)
{
gboolean ok;
GtkTreeIter iter;
gchar *text;
+ struct string dds;
+
+ ds_init_empty (&dds);
- GString *str = g_string_sized_new (100);
/* Declare new string variables if applicable */
if ( rd->different &&
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->string_button)))
{
- GtkTreeIter iter;
+ GHashTableIter iter;
+ struct variable *var = NULL;
+ struct nlp *nlp = NULL;
- for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (rd->var_map),
- &iter);
- ok;
- ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (rd->var_map), &iter))
+ g_hash_table_iter_init (&iter, rd->varmap);
+ while (g_hash_table_iter_next (&iter, (void**) &var, (void**) &nlp))
{
- gchar *name = NULL;
-
- gtk_tree_model_get (GTK_TREE_MODEL (rd->var_map), &iter,
- COL_NEW_NAME, &name, -1);
-
- g_string_append (str, "\nSTRING ");
- g_string_append (str, name);
- g_string_append_printf (str, " (A%d).",
+ ds_put_cstr (&dds, "\nSTRING ");
+ ds_put_cstr (&dds, nlp->name);
+ ds_put_c_format (&dds, " (A%d).",
(int)
gtk_spin_button_get_value (GTK_SPIN_BUTTON (rd->width_entry) )
);
-
- g_free (name);
}
}
- g_string_append (str, "\nRECODE ");
+ ds_put_cstr (&dds, "\nRECODE ");
- append_variable_names (str, rd->dict, GTK_TREE_VIEW (rd->variable_treeview), 0);
+ psppire_var_view_append_names_str (PSPPIRE_VAR_VIEW (rd->variable_treeview), 0, &dds);
- g_string_append (str, "\n\t");
+ ds_put_cstr (&dds, "\n\t");
if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->convert_button)))
{
- g_string_append (str, "(CONVERT) ");
+ ds_put_cstr (&dds, "(CONVERT) ");
}
for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (rd->value_map),
ov = g_value_get_boxed (&ov_value);
nv = g_value_get_boxed (&nv_value);
- g_string_append (str, "(");
+ ds_put_cstr (&dds, "(");
- old_value_append_syntax (str, ov);
- g_string_append (str, " = ");
- new_value_append_syntax (str, nv);
+ old_value_append_syntax (&dds, ov);
+ ds_put_cstr (&dds, " = ");
+ new_value_append_syntax (&dds, nv);
- g_string_append (str, ") ");
+ ds_put_cstr (&dds, ") ");
g_value_unset (&ov_value);
g_value_unset (&nv_value);
}
if ( rd->different )
{
+
GtkTreeIter iter;
- g_string_append (str, "\n\tINTO ");
+ ds_put_cstr (&dds, "\n\tINTO ");
- for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (rd->var_map),
- &iter);
+ for (ok = psppire_var_view_get_iter_first (PSPPIRE_VAR_VIEW (rd->variable_treeview), &iter);
ok;
- ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (rd->var_map), &iter))
- {
- gchar *name = NULL;
-
- gtk_tree_model_get (GTK_TREE_MODEL (rd->var_map), &iter,
- COL_NEW_NAME, &name, -1);
-
- g_string_append (str, name);
- g_string_append (str, " ");
+ ok = psppire_var_view_get_iter_next (PSPPIRE_VAR_VIEW (rd->variable_treeview), &iter))
+ {
+ struct nlp *nlp = NULL;
+ const struct variable *var = psppire_var_view_get_variable (PSPPIRE_VAR_VIEW (rd->variable_treeview), 0, &iter);
- g_free (name);
- }
+ nlp = g_hash_table_lookup (rd->varmap, var);
+
+ ds_put_cstr (&dds, nlp->name);
+ ds_put_cstr (&dds, " ");
+ }
}
- g_string_append (str, ".");
-
+ ds_put_cstr (&dds, ".");
/* If applicable, set labels for the new variables. */
if ( rd->different )
{
- GtkTreeIter iter;
+ GHashTableIter iter;
- for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (rd->var_map),
- &iter);
- ok;
- ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (rd->var_map), &iter))
- {
- struct string ls;
- gchar *label = NULL;
- gchar *name = NULL;
+ struct variable *var = NULL;
+ struct nlp *nlp = NULL;
- gtk_tree_model_get (GTK_TREE_MODEL (rd->var_map), &iter,
- COL_NEW_NAME, &name,
- COL_NEW_LABEL, &label, -1);
-
- if ( 0 == strcmp (label, "") )
+ g_hash_table_iter_init (&iter, rd->varmap);
+ while (g_hash_table_iter_next (&iter, (void**) &var, (void**) &nlp))
+ {
+ if (nlp->label)
{
- g_free (name);
- g_free (label);
- continue;
- }
-
- ds_init_cstr (&ls, label);
- g_free (label);
- gen_quoted_string (&ls);
-
- g_string_append_printf (str, "\nVARIABLE LABELS %s %s.",
- name, ds_cstr (&ls));
+ struct string sl;
+ ds_init_empty (&sl);
+ syntax_gen_string (&sl, ss_cstr (nlp->label));
+ ds_put_c_format (&dds, "\nVARIABLE LABELS %s %s.",
+ nlp->name, ds_cstr (&sl));
- g_free (name);
- ds_destroy (&ls);
+ ds_destroy (&sl);
+ }
}
}
-
- g_string_append (str, "\nEXECUTE.\n");
+ ds_put_cstr (&dds, "\nEXECUTE.\n");
- text = str->str;
+ text = ds_steal_cstr (&dds);
- g_string_free (str, FALSE);
+ ds_destroy (&dds);
return text;
}