Merge remote branch 'origin/master' into import-gui
[pspp] / src / ui / gui / text-data-import-dialog.c
index 00e82a7035fac41d9e47f6cae37fcb9dbd10e14f..a9cf86054e907f7675f19ae2c1b93cd28c883963 100644 (file)
 
 #include "ui/gui/text-data-import-dialog.h"
 
+#include "page-intro.h"
+#include "page-sheet-spec.h"
+#include "page-first-line.h"
+#include "page-separators.h"
+#include "page-formats.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <gtk-contrib/psppire-sheet.h>
@@ -65,40 +71,54 @@ static char *generate_syntax (const struct import_assistant *);
 
 static void add_line_number_column (const struct import_assistant *,
                                     GtkTreeView *);
+
 /* Pops up the Text Data Import assistant. */
 void
 text_data_import_assistant (PsppireDataWindow *dw)
 {
   GtkWindow *parent_window = GTK_WINDOW (dw);
-  struct import_assistant *ia;
+  struct import_assistant *ia = init_assistant (parent_window);
+  struct sheet_spec_page *ssp ;
 
-  ia = xzalloc (sizeof *ia);
   if (!init_file (ia, parent_window))
     {
       free (ia);
       return;
     }
 
-  printf ("%s:%d %s\n", __FILE__, __LINE__, ia->file.file_name);
+  ssp = ia->sheet_spec;
 
-  init_assistant (ia, parent_window);
-  if ( ia->file.type == FTYPE_TEXT)
+  if (ia->spreadsheet)
     {
-      init_intro_page (ia);
-      init_first_line_page (ia);
-      init_separators_page (ia);
+      ia->sheet_spec = sheet_spec_page_create (ia);
     }
   else
     {
-      init_sheet_spec_page (ia);
-    }
+      ia->intro = intro_page_create (ia);
+      ia->separators = separators_page_create (ia);
+      ia->first_line = first_line_page_create (ia);
 
-  init_formats_page (ia);
+      printf ("%s:%d %p\n", __FILE__, __LINE__, ia->intro);
+    }
+  ia->formats = formats_page_create (ia);
 
   gtk_widget_show_all (GTK_WIDGET (ia->asst.assistant));
 
   ia->asst.main_loop = g_main_loop_new (NULL, false);
-  g_main_loop_run (ia->asst.main_loop);
+
+  {  
+  /*
+    Instead of this block,
+    A simple     g_main_loop_run (ia->asst.main_loop);  should work here.  But it seems to crash.
+    I have no idea why.
+  */
+    GMainContext *ctx = g_main_loop_get_context (ia->asst.main_loop);
+    ia->asst.loop_done = false;
+    while (! ia->asst.loop_done)
+      {
+       g_main_context_iteration (ctx, TRUE);
+      }
+  }
   g_main_loop_unref (ia->asst.main_loop);
 
   switch (ia->asst.response)
@@ -113,7 +133,7 @@ text_data_import_assistant (PsppireDataWindow *dw)
       break;
     }
 
-  if ( ia->file.type == FTYPE_TEXT)
+  if (ssp) 
     {
       destroy_formats_page (ia);
       destroy_separators_page (ia);
@@ -214,76 +234,33 @@ generate_syntax (const struct import_assistant *ia)
 {
   struct string s = DS_EMPTY_INITIALIZER;
 
-  if (ia->file.type == FTYPE_TEXT)
-  {
-    size_t var_cnt;
-    size_t i;
-    syntax_gen_pspp (&s,
-                    "GET DATA\n"
-                    "  /TYPE=TXT\n"
-                    "  /FILE=%sq\n",
-                    ia->file.file_name);
-    if (ia->file.encoding && strcmp (ia->file.encoding, "Auto"))
-      syntax_gen_pspp (&s, "  /ENCODING=%sq\n", ia->file.encoding);
-    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (
-                                                        ia->intro.n_cases_button)))
-      ds_put_format (&s, "  /IMPORTCASES=FIRST %d\n",
-                    gtk_spin_button_get_value_as_int (
-                                                      GTK_SPIN_BUTTON (ia->intro.n_cases_spin)));
-    else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (
-                                                             ia->intro.percent_button)))
-      ds_put_format (&s, "  /IMPORTCASES=PERCENT %d\n",
-                    gtk_spin_button_get_value_as_int (
-                                                      GTK_SPIN_BUTTON (ia->intro.percent_spin)));
-    else
-      ds_put_cstr (&s, "  /IMPORTCASES=ALL\n");
-    ds_put_cstr (&s,
-                "  /ARRANGEMENT=DELIMITED\n"
-                "  /DELCASE=LINE\n");
-    if (ia->first_line.skip_lines > 0)
-      ds_put_format (&s, "  /FIRSTCASE=%d\n", ia->first_line.skip_lines + 1);
-    ds_put_cstr (&s, "  /DELIMITERS=\"");
-    if (ds_find_byte (&ia->separators.separators, '\t') != SIZE_MAX)
-      ds_put_cstr (&s, "\\t");
-    if (ds_find_byte (&ia->separators.separators, '\\') != SIZE_MAX)
-      ds_put_cstr (&s, "\\\\");
-    for (i = 0; i < ds_length (&ia->separators.separators); i++)
-      {
-       char c = ds_at (&ia->separators.separators, i);
-       if (c == '"')
-         ds_put_cstr (&s, "\"\"");
-       else if (c != '\t' && c != '\\')
-         ds_put_byte (&s, c);
-      }
-    ds_put_cstr (&s, "\"\n");
-    if (!ds_is_empty (&ia->separators.quotes))
-      syntax_gen_pspp (&s, "  /QUALIFIER=%sq\n", ds_cstr (&ia->separators.quotes));
-    if (!ds_is_empty (&ia->separators.quotes) && ia->separators.escape)
-      ds_put_cstr (&s, "  /ESCAPE\n");
-    ds_put_cstr (&s, "  /VARIABLES=\n");
-
-    var_cnt = dict_get_var_cnt (ia->formats.dict);
-    for (i = 0; i < var_cnt; i++)
-      {
-       struct variable *var = dict_get_var (ia->formats.dict, i);
-       char format_string[FMT_STRING_LEN_MAX + 1];
-       fmt_to_string (var_get_print_format (var), format_string);
-       ds_put_format (&s, "    %s %s%s\n",
-                      var_get_name (var), format_string,
-                      i == var_cnt - 1 ? "." : "");
-      }
-
-    apply_dict (ia->formats.dict, &s);
-  }
-  else
+  if (ia->spreadsheet == NULL)
     {
       syntax_gen_pspp (&s,
-                      "GET DATA\n"
-                      "  /TYPE=GNM\n"
-                      "  /FILE=%sq\n",
+                      "GET DATA"
+                      "\n  /TYPE=TXT"
+                      "\n  /FILE=%sq\n",
                       ia->file.file_name);
-    }
+      if (ia->file.encoding && strcmp (ia->file.encoding, "Auto"))
+       syntax_gen_pspp (&s, "  /ENCODING=%sq\n", ia->file.encoding);
+
+
+      intro_append_syntax (ia->intro, &s);
+
 
+      ds_put_cstr (&s,
+                  "  /ARRANGEMENT=DELIMITED\n"
+                  "  /DELCASE=LINE\n");
+
+      first_line_append_syntax (ia, &s);
+      separators_append_syntax (ia, &s);
+      formats_append_syntax (ia, &s);
+      apply_dict (ia->dict, &s);
+    }
+  else
+    {
+      return sheet_spec_gen_syntax (ia);
+    }
 
   return ds_cstr (&s);
 }
@@ -316,8 +293,8 @@ render_input_cell (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell,
 
   column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tree_column),
                                                "column-number"));
-  row = empty_list_store_iter_to_row (iter) + ia->first_line.skip_lines;
-  field = ia->separators.columns[column].contents[row];
+  row = empty_list_store_iter_to_row (iter) + ia->skip_lines;
+  field = ia->columns[column].contents[row];
   if (field.string != NULL)
     {
       GValue text = {0, };
@@ -353,7 +330,7 @@ on_query_input_tooltip (GtkWidget *widget, gint wx, gint wy,
   if (!get_tooltip_location (widget, wx, wy, ia, &row, &column))
     return FALSE;
 
-  if (ia->separators.columns[column].contents[row].string != NULL)
+  if (ia->columns[column].contents[row].string != NULL)
     return FALSE;
 
   gtk_tooltip_set_text (tooltip,
@@ -375,16 +352,15 @@ parse_field (struct import_assistant *ia,
              size_t row, size_t column,
              char **outputp, char **tooltipp)
 {
-  struct substring field;
-  union value val;
-  struct variable *var;
   const struct fmt_spec *in;
   struct fmt_spec out;
   char *tooltip;
   bool ok;
 
-  field = ia->separators.columns[column].contents[row];
-  var = dict_get_var (ia->formats.dict, column);
+  struct substring field = ia->columns[column].contents[row];
+  struct variable *var = dict_get_var (ia->dict, column);
+  union value val;
+
   value_init (&val, var_get_width (var));
   in = var_get_print_format (var);
   out = fmt_for_output_from_input (in);
@@ -394,7 +370,7 @@ parse_field (struct import_assistant *ia,
       char *error;
 
       error = data_in (field, "UTF-8", in->type, &val, var_get_width (var),
-                       dict_get_encoding (ia->formats.dict));
+                       dict_get_encoding (ia->dict));
       if (error != NULL)
         {
           tooltip = xasprintf (_("Cannot parse field content `%.*s' as "
@@ -412,7 +388,7 @@ parse_field (struct import_assistant *ia,
     }
   if (outputp != NULL)
     {
-      *outputp = data_out (&val, dict_get_encoding (ia->formats.dict),  &out);
+      *outputp = data_out (&val, dict_get_encoding (ia->dict),  &out);
     }
   value_destroy (&val, var_get_width (var));
 
@@ -440,7 +416,7 @@ render_output_cell (GtkTreeViewColumn *tree_column,
 
   ok = parse_field (ia,
                     (empty_list_store_iter_to_row (iter)
-                     + ia->first_line.skip_lines),
+                     + ia->skip_lines),
                     GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tree_column),
                                                         "column-number")),
                     &output, NULL);
@@ -463,8 +439,8 @@ render_output_cell (GtkTreeViewColumn *tree_column,
    preview tree view. */
 static gboolean
 on_query_output_tooltip (GtkWidget *widget, gint wx, gint wy,
-                        gboolean keyboard_mode UNUSED,
-                        GtkTooltip *tooltip, struct import_assistant *ia)
+                        gboolean keyboard_mode UNUSED,
+                        GtkTooltip *tooltip, struct import_assistant *ia)
 {
   size_t row, column;
   char *text;
@@ -523,7 +499,7 @@ get_tooltip_location (GtkWidget *widget, gint wx, gint wy,
   if (!ok)
     return FALSE;
 
-  *row = empty_list_store_iter_to_row (&iter) + ia->first_line.skip_lines;
+  *row = empty_list_store_iter_to_row (&iter) + ia->skip_lines;
   return TRUE;
 }
 
@@ -536,7 +512,7 @@ make_tree_view (const struct import_assistant *ia,
 
   *tree_view = GTK_TREE_VIEW (gtk_tree_view_new ());
   model = GTK_TREE_MODEL (psppire_empty_list_store_new (
-                            ia->file.line_cnt - first_line));
+                                                       ia->file.line_cnt - first_line));
   g_object_set_data (G_OBJECT (model), "lines", ia->file.lines + first_line);
   g_object_set_data (G_OBJECT (model), "first-line",
                      GINT_TO_POINTER (first_line));
@@ -570,10 +546,10 @@ add_line_number_column (const struct import_assistant *ia,
   GtkTreeViewColumn *column;
 
   column = gtk_tree_view_column_new_with_attributes (
-    _("Line"), ia->asst.prop_renderer, (void *) NULL);
+                                                    _("Line"), ia->asst.prop_renderer, (void *) NULL);
   gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
   gtk_tree_view_column_set_fixed_width (
-    column, get_monospace_width (treeview, ia->asst.prop_renderer, 5));
+                                       column, get_monospace_width (treeview, ia->asst.prop_renderer, 5));
   gtk_tree_view_column_set_resizable (column, TRUE);
   gtk_tree_view_column_set_cell_data_func (column, ia->asst.prop_renderer,
                                            render_line_number, NULL, NULL);
@@ -619,9 +595,9 @@ make_data_column (struct import_assistant *ia, GtkTreeView *tree_view,
   char *name;
 
   if (input)
-    column = &ia->separators.columns[dict_idx];
+    column = &ia->columns[dict_idx];
   else
-    var = dict_get_var (ia->formats.dict, dict_idx);
+    var = dict_get_var (ia->dict, dict_idx);
 
   name = escape_underscores (input ? column->name : var_get_name (var));
   char_cnt = input ? column->width : var_get_print_format (var)->w;
@@ -637,8 +613,8 @@ make_data_column (struct import_assistant *ia, GtkTreeView *tree_view,
   gtk_tree_view_column_pack_start (tree_column, ia->asst.fixed_renderer,
                                    FALSE);
   gtk_tree_view_column_set_cell_data_func (
-    tree_column, ia->asst.fixed_renderer,
-    input ? render_input_cell : render_output_cell, ia, NULL);
+                                          tree_column, ia->asst.fixed_renderer,
+                                          input ? render_input_cell : render_output_cell, ia, NULL);
   gtk_tree_view_column_set_sizing (tree_column, GTK_TREE_VIEW_COLUMN_FIXED);
   gtk_tree_view_column_set_fixed_width (tree_column, MAX (content_width,
                                                           header_width));
@@ -655,11 +631,11 @@ create_data_tree_view (bool input, GtkContainer *parent,
   GtkTreeView *tree_view;
   gint i;
 
-  make_tree_view (ia, ia->first_line.skip_lines, &tree_view);
+  make_tree_view (ia, ia->skip_lines, &tree_view);
   gtk_tree_selection_set_mode (gtk_tree_view_get_selection (tree_view),
                                GTK_SELECTION_NONE);
 
-  for (i = 0; i < ia->separators.column_cnt; i++)
+  for (i = 0; i < ia->column_cnt; i++)
     gtk_tree_view_append_column (tree_view,
                                  make_data_column (ia, tree_view, input, i));