data-in: Eliminate "implied_decimals" parameter from data_in().
[pspp] / src / ui / gui / text-data-import-dialog.c
index c674f17d1e1cd9279cdb472ae7e4d0ea6398d361..070c4f6b3cd3b05b3428994cb307326463599a6c 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2008, 2009  Free Software Foundation
+   Copyright (C) 2008, 2009, 2010  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
@@ -19,7 +19,7 @@
 #include <gtk/gtk.h>
 
 
-
+#include "widget-io.h"
 #include "checkbox-treeview.h"
 #include "descriptives-dialog.h"
 
@@ -233,7 +233,7 @@ static void pop_watch_cursor (struct import_assistant *);
 
 /* Pops up the Text Data Import assistant. */
 void
-text_data_import_assistant (GObject *o, GtkWindow *parent_window)
+text_data_import_assistant (GtkWindow *parent_window)
 {
   struct import_assistant *ia;
 
@@ -268,7 +268,7 @@ text_data_import_assistant (GObject *o, GtkWindow *parent_window)
     case PSPPIRE_RESPONSE_PASTE:
       {
        char *syntax = generate_syntax (ia);
-        paste_syntax_in_new_window (syntax);
+        paste_syntax_to_window (syntax);
        free (syntax);
       }
       break;
@@ -310,11 +310,9 @@ apply_dict (const struct dictionary *dict, struct string *s)
           syntax_gen_pspp (s, "MISSING VALUES %ss (", name);
           for (j = 0; j < mv_n_values (mv); j++)
             {
-              union value value;
               if (j)
                 ds_put_cstr (s, ", ");
-              mv_get_value (mv, &value, j);
-              syntax_gen_value (s, &value, width, format);
+              syntax_gen_value (s, mv_get_value (mv, j), width, format);
             }
 
           if (mv_has_range (mv))
@@ -330,18 +328,20 @@ apply_dict (const struct dictionary *dict, struct string *s)
       if (var_has_value_labels (var))
         {
           const struct val_labs *vls = var_get_value_labels (var);
-          struct val_labs_iterator *iter;
-          struct val_lab *vl;
+          const struct val_lab **labels = val_labs_sorted (vls);
+          size_t n_labels = val_labs_count (vls);
+          size_t i;
 
           syntax_gen_pspp (s, "VALUE LABELS %ss", name);
-          for (vl = val_labs_first_sorted (vls, &iter); vl != NULL;
-               vl = val_labs_next (vls, &iter))
+          for (i = 0; i < n_labels; i++)
             {
+              const struct val_lab *vl = labels[i];
               ds_put_cstr (s, "\n  ");
               syntax_gen_value (s, &vl->value, width, format);
               ds_put_char (s, ' ');
-              syntax_gen_string (s, ss_cstr (vl->label));
+              syntax_gen_string (s, ss_cstr (val_lab_get_label (vl)));
             }
+          free (labels);
           ds_put_cstr (s, ".\n");
         }
       if (var_has_label (var))
@@ -458,7 +458,7 @@ init_file (struct import_assistant *ia, GtkWindow *parent_window)
   stream = fopen (file->file_name, "r");
   if (stream == NULL)
     {
-      msg (ME, _("Could not open \"%s\": %s"),
+      msg (ME, _("Could not open `%s': %s"),
            file->file_name, strerror (errno));
       return false;
     }
@@ -474,10 +474,10 @@ init_file (struct import_assistant *ia, GtkWindow *parent_window)
           if (feof (stream))
             break;
           else if (ferror (stream))
-            msg (ME, _("Error reading \"%s\": %s"),
+            msg (ME, _("Error reading `%s': %s"),
                  file->file_name, strerror (errno));
           else
-            msg (ME, _("Failed to read \"%s\", because it contains a line "
+            msg (ME, _("Failed to read `%s', because it contains a line "
                        "over %d bytes long and therefore appears not to be "
                        "a text file."),
                  file->file_name, MAX_LINE_LEN);
@@ -491,7 +491,7 @@ init_file (struct import_assistant *ia, GtkWindow *parent_window)
 
   if (file->line_cnt == 0)
     {
-      msg (ME, _("\"%s\" is empty."), file->file_name);
+      msg (ME, _("`%s' is empty."), file->file_name);
       fclose (stream);
       destroy_file (ia);
       return false;
@@ -720,8 +720,7 @@ close_assistant (struct import_assistant *ia, int response)
 \f
 /* The "intro" page of the assistant. */
 
-static void on_intro_amount_changed (GtkToggleButton *button,
-                                     struct import_assistant *);
+static void on_intro_amount_changed (struct import_assistant *);
 
 /* Initializes IA's intro substructure. */
 static void
@@ -730,21 +729,47 @@ init_intro_page (struct import_assistant *ia)
   GtkBuilder *builder = ia->asst.builder;
   struct intro_page *p = &ia->intro;
   struct string s;
+  GtkWidget *hbox_n_cases ;
+  GtkWidget *hbox_percent ;
+  GtkWidget *table ;
+
+
+  p->n_cases_spin = gtk_spin_button_new_with_range (0, INT_MAX, 100);
+
+  hbox_n_cases = widget_scanf (_("Only the first %4d cases"), &p->n_cases_spin);
+
+  table  = get_widget_assert (builder, "button-table");
+
+  gtk_table_attach_defaults (GTK_TABLE (table), hbox_n_cases,
+                   1, 2,
+                   1, 2);
+
+  p->percent_spin = gtk_spin_button_new_with_range (0, 100, 10);
+
+  hbox_percent = widget_scanf (_("Only the first %3d %% of file (approximately)"), &p->percent_spin);
+
+  gtk_table_attach_defaults (GTK_TABLE (table), hbox_percent,
+                            1, 2,
+                            2, 3);
 
   p->page = add_page_to_assistant (ia, get_widget_assert (builder, "Intro"),
                                    GTK_ASSISTANT_PAGE_INTRO);
+
   p->all_cases_button = get_widget_assert (builder, "import-all-cases");
+
   p->n_cases_button = get_widget_assert (builder, "import-n-cases");
-  p->n_cases_spin = get_widget_assert (builder, "n-cases-spin");
+
   p->percent_button = get_widget_assert (builder, "import-percent");
-  p->percent_spin = get_widget_assert (builder, "percent-spin");
-  g_signal_connect (p->all_cases_button, "toggled",
+
+  g_signal_connect_swapped (p->all_cases_button, "toggled",
                     G_CALLBACK (on_intro_amount_changed), ia);
-  g_signal_connect (p->n_cases_button, "toggled",
+  g_signal_connect_swapped (p->n_cases_button, "toggled",
                     G_CALLBACK (on_intro_amount_changed), ia);
-  g_signal_connect (p->percent_button, "toggled",
+  g_signal_connect_swapped (p->percent_button, "toggled",
                     G_CALLBACK (on_intro_amount_changed), ia);
 
+  on_intro_amount_changed (ia);
+
   ds_init_empty (&s);
   ds_put_cstr (&s, _("This assistant will guide you through the process of "
                      "importing data into PSPP from a text file with one line "
@@ -790,8 +815,7 @@ reset_intro_page (struct import_assistant *ia)
 
 /* Called when one of the radio buttons is clicked. */
 static void
-on_intro_amount_changed (GtkToggleButton *button UNUSED,
-                         struct import_assistant *ia)
+on_intro_amount_changed (struct import_assistant *ia)
 {
   struct intro_page *p = &ia->intro;
 
@@ -799,7 +823,7 @@ on_intro_amount_changed (GtkToggleButton *button UNUSED,
                             gtk_toggle_button_get_active (
                               GTK_TOGGLE_BUTTON (p->n_cases_button)));
 
-  gtk_widget_set_sensitive (ia->intro.percent_spin,
+  gtk_widget_set_sensitive (p->percent_spin,
                             gtk_toggle_button_get_active (
                               GTK_TOGGLE_BUTTON (p->percent_button)));
 }
@@ -857,13 +881,16 @@ create_lines_tree_view (GtkContainer *parent, struct import_assistant *ia)
   size_t max_line_length;
   gint content_width, header_width;
   size_t i;
+  gchar *title = _("Text");
 
   make_tree_view (ia, 0, &tree_view);
 
-  column = gtk_tree_view_column_new_with_attributes (
-    "Text", ia->asst.fixed_renderer,
-    "text", TEXT_IMPORT_MODEL_COLUMN_LINE,
-    (void *) NULL);
+  column = gtk_tree_view_column_new_with_attributes 
+    (
+     title, ia->asst.fixed_renderer,
+     "text", TEXT_IMPORT_MODEL_COLUMN_LINE,
+     (void *) NULL
+     );
   gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
 
   max_line_length = 0;
@@ -875,7 +902,7 @@ create_lines_tree_view (GtkContainer *parent, struct import_assistant *ia)
 
   content_width = get_monospace_width (tree_view, ia->asst.fixed_renderer,
                                        max_line_length);
-  header_width = get_string_width (tree_view, ia->asst.prop_renderer, "Text");
+  header_width = get_string_width (tree_view, ia->asst.prop_renderer, title);
   gtk_tree_view_column_set_fixed_width (column, MAX (content_width,
                                                      header_width));
   gtk_tree_view_append_column (tree_view, column);
@@ -1543,6 +1570,7 @@ init_formats_page (struct import_assistant *ia)
   p->data_tree_view = GTK_TREE_VIEW (get_widget_assert (builder, "data"));
   p->modified_vars = NULL;
   p->modified_var_cnt = 0;
+  p->dict = NULL;
 }
 
 /* Frees IA's formats substructure. */
@@ -1614,7 +1642,7 @@ prepare_formats_page (struct import_assistant *ia)
           if (!dict_make_unique_var_name (dict, var_get_name (modified_var),
                                           &number, name))
             NOT_REACHED ();
-          dict_clone_var_assert (dict, modified_var, name);
+          dict_clone_var_as_assert (dict, modified_var, name);
         }
     }
   fmt_guesser_destroy (fg);
@@ -1732,7 +1760,7 @@ parse_field (struct import_assistant *ia,
              char **outputp, char **tooltipp)
 {
   struct substring field;
-  union value *val;
+  union value val;
   struct variable *var;
   const struct fmt_spec *in;
   struct fmt_spec out;
@@ -1741,19 +1769,20 @@ parse_field (struct import_assistant *ia,
 
   field = ia->separators.columns[column].contents[row];
   var = dict_get_var (ia->formats.dict, column);
-  val = value_create (var_get_width (var));
+  value_init (&val, var_get_width (var));
   in = var_get_print_format (var);
   out = fmt_for_output_from_input (in);
   tooltip = NULL;
   if (field.string != NULL)
     {
       msg_disable ();
-      if (!data_in (field, LEGACY_NATIVE, in->type, 0, 0, 0,
-                    val, var_get_width (var)))
+
+      if (!data_in (field, LEGACY_NATIVE, in->type, 0, 0, ia->formats.dict,
+                    &val, var_get_width (var)))
         {
           char fmt_string[FMT_STRING_LEN_MAX + 1];
           fmt_to_string (in, fmt_string);
-          tooltip = xasprintf (_("Field content \"%.*s\" cannot be parsed in "
+          tooltip = xasprintf (_("Field content `%.*s' cannot be parsed in "
                                  "format %s."),
                                (int) field.length, field.string,
                                fmt_string);
@@ -1764,16 +1793,13 @@ parse_field (struct import_assistant *ia,
     {
       tooltip = xstrdup (_("This input line has too few separators "
                            "to fill in this field."));
-      value_set_missing (val, var_get_width (var));
+      value_set_missing (&val, var_get_width (var));
     }
   if (outputp != NULL)
     {
-      char *output = xmalloc (out.w + 1);
-      data_out (val, &out, output);
-      output[out.w] = '\0';
-      *outputp = output;
+      *outputp = data_out (&val, dict_get_encoding (ia->formats.dict),  &out);
     }
-  free (val);
+  value_destroy (&val, var_get_width (var));
 
   ok = tooltip == NULL;
   if (tooltipp != NULL)
@@ -1909,7 +1935,7 @@ add_line_number_column (const struct import_assistant *ia,
   GtkTreeViewColumn *column;
 
   column = gtk_tree_view_column_new_with_attributes (
-    "Line", ia->asst.prop_renderer,
+                                                    _("Line"), ia->asst.prop_renderer,
     "text", TEXT_IMPORT_MODEL_COLUMN_LINE_NUMBER,
     (void *) NULL);
   gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);