X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fpsppire-import-assistant.c;h=edab2288f266a7a6ac50ca903f278cbd968a37ef;hb=e870838d34e5e0133997434d27035054c605fb4f;hp=b5d8bc713b43c426e56ab5fcdd7edd58ad86e99c;hpb=7e7f78374d9df2b7fa16306b5d78e6bfc9ef40df;p=pspp diff --git a/src/ui/gui/psppire-import-assistant.c b/src/ui/gui/psppire-import-assistant.c index b5d8bc713b..edab2288f2 100644 --- a/src/ui/gui/psppire-import-assistant.c +++ b/src/ui/gui/psppire-import-assistant.c @@ -1,5 +1,5 @@ /* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2015, 2016, 2017 Free Software Foundation + Copyright (C) 2015, 2016, 2017, 2018 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 @@ -16,10 +16,7 @@ #include -#include -#include #include -#include #include "data/casereader.h" #include "data/data-in.h" @@ -33,8 +30,6 @@ #include "data/value-labels.h" #include "data/casereader-provider.h" -#include "gl/intprops.h" - #include "libpspp/i18n.h" #include "libpspp/line-reader.h" #include "libpspp/message.h" @@ -43,18 +38,17 @@ #include "libpspp/str.h" #include "builder-wrapper.h" -#include "helper.h" -#include "psppire-import-assistant.h" -#include "psppire-scanf.h" + +#include "psppire-data-sheet.h" +#include "psppire-data-store.h" #include "psppire-dialog.h" -#include "psppire-empty-list-store.h" +#include "psppire-delimited-text.h" +#include "psppire-dict.h" #include "psppire-encoding-selector.h" +#include "psppire-import-assistant.h" +#include "psppire-scanf.h" #include "psppire-spreadsheet-model.h" #include "psppire-text-file.h" -#include "psppire-delimited-text.h" -#include "psppire-data-sheet.h" -#include "psppire-data-store.h" -#include "psppire-dict.h" #include "psppire-variable-sheet.h" #include "ui/syntax-gen.h" @@ -66,25 +60,15 @@ enum { MAX_LINE_LEN = 16384 }; /* Max length of an acceptable line. */ -/* Sets IA's separators substructure to match the widgets. */ -static void split_fields (PsppireImportAssistant *ia); - /* Chooses a name for each column on the separators page */ static void choose_column_names (PsppireImportAssistant *ia); - - static void intro_page_create (PsppireImportAssistant *ia); static void first_line_page_create (PsppireImportAssistant *ia); static void separators_page_create (PsppireImportAssistant *ia); static void formats_page_create (PsppireImportAssistant *ia); -static void push_watch_cursor (PsppireImportAssistant *ia); -static void pop_watch_cursor (PsppireImportAssistant *ia); - - - static void psppire_import_assistant_init (PsppireImportAssistant *act); static void psppire_import_assistant_class_init (PsppireImportAssistantClass *class); @@ -138,14 +122,18 @@ psppire_import_assistant_finalize (GObject *object) { PsppireImportAssistant *ia = PSPPIRE_IMPORT_ASSISTANT (object); - if (ia->spreadsheet) spreadsheet_unref (ia->spreadsheet); ds_destroy (&ia->quotes); + dict_unref (ia->dict); + g_object_unref (ia->builder); + ia->response = -1; + g_main_loop_unref (ia->main_loop); + if (G_OBJECT_CLASS (parent_class)->finalize) G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -203,16 +191,17 @@ struct separator /* All the separators in the dialog box. */ static const struct separator separators[] = { - {"space", ' '}, - {"tab", '\t'}, - {"bang", '!'}, - {"colon", ':'}, - {"comma", ','}, - {"hyphen", '-'}, - {"pipe", '|'}, + {"space", ' '}, + {"tab", '\t'}, + {"bang", '!'}, + {"colon", ':'}, + {"comma", ','}, + {"hyphen", '-'}, + {"pipe", '|'}, {"semicolon", ';'}, - {"slash", '/'}, + {"slash", '/'}, }; + #define SEPARATOR_CNT (sizeof separators / sizeof *separators) struct separator_count_node @@ -233,8 +222,6 @@ choose_likely_separators (PsppireImportAssistant *ia) gboolean valid; GtkTreeIter iter; - int i = 0; - int j; struct hmap count_map[SEPARATOR_CNT]; @@ -247,23 +234,27 @@ choose_likely_separators (PsppireImportAssistant *ia) valid; valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (ia->text_file), &iter)) { - int j; - gchar *line_text = NULL; gtk_tree_model_get (GTK_TREE_MODEL (ia->text_file), &iter, 1, &line_text, -1); gint *counts = xzalloc (sizeof *counts * SEPARATOR_CNT); - for (j = 0; j < strlen (line_text); ++j) + + struct substring cs = ss_cstr (line_text); + for (; + UINT32_MAX != ss_first_mb (cs); + ss_get_mb (&cs)) { + ucs4_t character = ss_first_mb (cs); + int s; for (s = 0; s < SEPARATOR_CNT; ++s) { - // FIXME do this in UTF8 encoding - if (line_text[j] == separators[s].c) + if (character == separators[s].c) counts[s]++; } } + int j; for (j = 0; j < SEPARATOR_CNT; ++j) { if (counts[j] > 0) @@ -322,7 +313,8 @@ repopulate_delimiter_columns (PsppireImportAssistant *ia) gtk_tree_view_remove_column (GTK_TREE_VIEW (ia->fields_tree_view), tvc); } - gint n_fields = gtk_tree_model_get_n_columns (ia->delimiters_model); + gint n_fields = + gtk_tree_model_get_n_columns (GTK_TREE_MODEL (ia->delimiters_model)); /* ... and put them back again. */ gint f; @@ -382,9 +374,10 @@ reset_tree_view_model (PsppireImportAssistant *ia) static void prepare_separators_page (PsppireImportAssistant *ia, GtkWidget *page) { - gtk_tree_view_set_model (GTK_TREE_VIEW (ia->fields_tree_view), ia->delimiters_model); + gtk_tree_view_set_model (GTK_TREE_VIEW (ia->fields_tree_view), + GTK_TREE_MODEL (ia->delimiters_model)); - g_signal_connect_swapped (ia->delimiters_model, "notify::delimiters", + g_signal_connect_swapped (GTK_TREE_MODEL (ia->delimiters_model), "notify::delimiters", G_CALLBACK (reset_tree_view_model), ia); @@ -570,7 +563,7 @@ on_chosen (PsppireImportAssistant *ia, GtkWidget *page) gtk_assistant_set_page_complete (GTK_ASSISTANT(ia), GTK_WIDGET (fc), FALSE); - if (f && !g_file_test (f, G_FILE_TEST_IS_DIR)) + if (f && g_file_test (f, G_FILE_TEST_IS_REGULAR)) { gtk_assistant_set_page_complete (GTK_ASSISTANT(ia), GTK_WIDGET (fc), TRUE); @@ -582,15 +575,15 @@ on_chosen (PsppireImportAssistant *ia, GtkWidget *page) if (!ia->spreadsheet) ia->spreadsheet = ods_probe (f, FALSE); - if (!ia->spreadsheet) + if (ia->spreadsheet) { - intro_page_create (ia); - first_line_page_create (ia); - separators_page_create (ia); + sheet_spec_page_create (ia); } else { - sheet_spec_page_create (ia); + intro_page_create (ia); + first_line_page_create (ia); + separators_page_create (ia); } formats_page_create (ia); @@ -624,7 +617,6 @@ chooser_page_enter (PsppireImportAssistant *ia, GtkWidget *page) static void chooser_page_leave (PsppireImportAssistant *ia, GtkWidget *page) { - g_print ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); g_free (ia->file_name); ia->file_name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (page)); gchar *encoding = psppire_encoding_selector_get_encoding (ia->encoding_selector); @@ -738,6 +730,8 @@ psppire_import_assistant_init (PsppireImportAssistant *ia) ia->spreadsheet = NULL; + ia->main_loop = g_main_loop_new (NULL, TRUE); + g_signal_connect (ia, "prepare", G_CALLBACK (on_prepare), ia); g_signal_connect (ia, "cancel", G_CALLBACK (on_cancel), ia); g_signal_connect (ia, "close", G_CALLBACK (on_close), ia); @@ -788,16 +782,14 @@ static void on_intro_amount_changed (PsppireImportAssistant *p) { gtk_widget_set_sensitive (p->n_cases_spin, - gtk_toggle_button_get_active ( - GTK_TOGGLE_BUTTON (p->n_cases_button))); + gtk_toggle_button_get_active + (GTK_TOGGLE_BUTTON (p->n_cases_button))); gtk_widget_set_sensitive (p->percent_spin, - gtk_toggle_button_get_active ( - GTK_TOGGLE_BUTTON (p->percent_button))); + gtk_toggle_button_get_active + (GTK_TOGGLE_BUTTON (p->percent_button))); } - - static void on_treeview_selection_change (PsppireImportAssistant *ia) { @@ -807,30 +799,44 @@ on_treeview_selection_change (PsppireImportAssistant *ia) GtkTreeIter iter; if (gtk_tree_selection_get_selected (selection, &model, &iter)) { + gint max_lines; int n; GtkTreePath *path = gtk_tree_model_get_path (model, &iter); gint *index = gtk_tree_path_get_indices (path); - n = *index; - gtk_tree_path_free (path); - - gtk_widget_set_sensitive (ia->variable_names_cb, n > 0); - - ia->delimiters_model - = psppire_delimited_text_new (GTK_TREE_MODEL (ia->text_file)); + g_object_get (model, "maximum-lines", &max_lines, NULL); + gtk_widget_set_sensitive (ia->variable_names_cb, + (n > 0 && n < max_lines)); + ia->delimiters_model = + psppire_delimited_text_new (GTK_TREE_MODEL (ia->text_file)); g_object_set (ia->delimiters_model, "first-line", n, NULL); - - g_print ("%s:%d DT %p first line %d\n", __FILE__, __LINE__, ia->delimiters_model, n); } } +static void +render_text_preview_line (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + /* + Set the text to a "insensitive" state if the row + is greater than what the user declared to be the maximum. + */ + GtkTreePath *path = gtk_tree_model_get_path (tree_model, iter); + gint *ii = gtk_tree_path_get_indices (path); + gint max_lines; + g_object_get (tree_model, "maximum-lines", &max_lines, NULL); + g_object_set (cell, "sensitive", (*ii < max_lines), NULL); + gtk_tree_path_free (path); +} /* Initializes IA's first_line substructure. */ static void first_line_page_create (PsppireImportAssistant *ia) { - g_print ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); GtkWidget *w = get_widget_assert (ia->builder, "FirstLine"); g_object_set_data (G_OBJECT (w), "on-entering", on_treeview_selection_change); @@ -843,6 +849,7 @@ first_line_page_create (PsppireImportAssistant *ia) if (ia->first_line_tree_view == NULL) { ia->first_line_tree_view = gtk_tree_view_new (); + g_object_set (ia->first_line_tree_view, "enable-search", FALSE, NULL); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (ia->first_line_tree_view), TRUE); @@ -850,24 +857,46 @@ first_line_page_create (PsppireImportAssistant *ia) GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes (_("Line"), renderer, "text", 0, NULL); + + gtk_tree_view_column_set_cell_data_func (column, renderer, render_text_preview_line, ia, 0); gtk_tree_view_append_column (GTK_TREE_VIEW (ia->first_line_tree_view), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (_("Text"), renderer, "text", 1, NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (ia->first_line_tree_view), column); + gtk_tree_view_column_set_cell_data_func (column, renderer, render_text_preview_line, ia, 0); - gtk_container_add (GTK_CONTAINER (scrolled_window), ia->first_line_tree_view); + gtk_tree_view_append_column (GTK_TREE_VIEW (ia->first_line_tree_view), column); g_signal_connect_swapped (ia->first_line_tree_view, "cursor-changed", - G_CALLBACK (on_treeview_selection_change), ia); + G_CALLBACK (on_treeview_selection_change), ia); + gtk_container_add (GTK_CONTAINER (scrolled_window), ia->first_line_tree_view); } + gtk_widget_show_all (scrolled_window); ia->variable_names_cb = get_widget_assert (ia->builder, "variable-names"); - } - +static void +intro_on_leave (PsppireImportAssistant *ia) +{ + gint lc = 0; + g_object_get (ia->text_file, "line-count", &lc, NULL); + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->n_cases_button))) + { + gint max_lines = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ia->n_cases_spin)); + g_object_set (ia->text_file, "maximum-lines", max_lines, NULL); + } + else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->percent_button))) + { + gdouble percent = gtk_spin_button_get_value (GTK_SPIN_BUTTON (ia->percent_spin)); + g_object_set (ia->text_file, "maximum-lines", (gint) (lc * percent / 100.0), NULL); + } + else + { + g_object_set (ia->text_file, "maximum-lines", lc, NULL); + } +} static void @@ -920,43 +949,26 @@ intro_on_enter (PsppireImportAssistant *ia) ds_cstr (&s)); ds_destroy (&s); - GtkWidget *w = gtk_grid_get_child_at (GTK_GRID (table), 1, 1); - int old_value = w ? gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ia->n_cases_spin)) : 1; - if (w) - gtk_container_remove (GTK_CONTAINER (table), w); - - w = gtk_grid_get_child_at (GTK_GRID (table), 1, 2); - if (w) - gtk_container_remove (GTK_CONTAINER (table), w); - - - GtkWidget *hbox_n_cases = psppire_scanf_new (_("Only the first %4d cases"), &ia->n_cases_spin); + if (gtk_grid_get_child_at (GTK_GRID (table), 1, 1) == NULL) + { + GtkWidget *hbox_n_cases = psppire_scanf_new (_("Only the first %4d cases"), &ia->n_cases_spin); + gtk_grid_attach (GTK_GRID (table), hbox_n_cases, + 1, 1, + 1, 1); + } GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (ia->n_cases_spin)); gtk_adjustment_set_lower (adj, 1.0); - if (ia->text_file) + if (gtk_grid_get_child_at (GTK_GRID (table), 1, 2) == NULL) { - if (psppire_text_file_get_total_exact (ia->text_file)) - { - gulong total_lines = psppire_text_file_get_n_lines (ia->text_file); - gtk_adjustment_set_upper (adj, total_lines); - gtk_adjustment_set_value (adj, old_value); - } - else - gtk_adjustment_set_upper (adj, DBL_MAX); - } - gtk_grid_attach (GTK_GRID (table), hbox_n_cases, - 1, 1, - 1, 1); - + GtkWidget *hbox_percent = psppire_scanf_new (_("Only the first %3d %% of file (approximately)"), + &ia->percent_spin); - GtkWidget *hbox_percent = psppire_scanf_new (_("Only the first %3d %% of file (approximately)"), - &ia->percent_spin); - - gtk_grid_attach (GTK_GRID (table), hbox_percent, - 1, 2, - 1, 1); + gtk_grid_attach (GTK_GRID (table), hbox_percent, + 1, 2, + 1, 1); + } gtk_widget_show_all (table); @@ -990,6 +1002,7 @@ intro_page_create (PsppireImportAssistant *ia) G_CALLBACK (on_intro_amount_changed), ia); + g_object_set_data (G_OBJECT (w), "on-forward", intro_on_leave); g_object_set_data (G_OBJECT (w), "on-entering", intro_on_enter); g_object_set_data (G_OBJECT (w), "on-reset", reset_intro_page); } @@ -1011,65 +1024,33 @@ psppire_import_assistant_new (GtkWindow *toplevel) -static void -set_quote_list (GtkComboBox *cb) -{ - GtkListStore *list = gtk_list_store_new (1, G_TYPE_STRING); - GtkTreeIter iter; - gint i; - const gchar *separator[3] = {"'\"", "\'", "\""}; - - for (i = 0; i < 3; i++) - { - const gchar *s = separator[i]; - - /* Add a new row to the model */ - gtk_list_store_append (list, &iter); - gtk_list_store_set (list, &iter, - 0, s, - -1); - - } - - gtk_combo_box_set_model (GTK_COMBO_BOX (cb), GTK_TREE_MODEL (list)); - g_object_unref (list); - - gtk_combo_box_set_entry_text_column (cb, 0); -} - - - /* Chooses a name for each column on the separators page */ static void choose_column_names (PsppireImportAssistant *ia) { - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->variable_names_cb))) + int i; + unsigned long int generated_name_count = 0; + dict_clear (ia->dict); + + for (i = 0; + i < gtk_tree_model_get_n_columns (GTK_TREE_MODEL (ia->delimiters_model)) - 1; + ++i) { - int i; - unsigned long int generated_name_count = 0; - dict_clear (ia->dict); + const gchar *candidate_name = NULL; - g_print ("%s:%d XXX %d\n", __FILE__, __LINE__, gtk_tree_model_get_n_columns (ia->delimiters_model)); - - for (i = 0; i < gtk_tree_model_get_n_columns (ia->delimiters_model) - 1; ++i) + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->variable_names_cb))) { - const gchar *candidate_name = - psppire_delimited_text_get_header_title - (PSPPIRE_DELIMITED_TEXT (ia->delimiters_model), i); - - g_print ("%s:%d CN is %s\n", __FILE__, __LINE__, candidate_name); - - char *name = dict_make_unique_var_name (ia->dict, - candidate_name, - &generated_name_count); - - dict_create_var_assert (ia->dict, name, 0); - free (name); + candidate_name = psppire_delimited_text_get_header_title (PSPPIRE_DELIMITED_TEXT (ia->delimiters_model), i); } - } -} + char *name = dict_make_unique_var_name (ia->dict, + candidate_name, + &generated_name_count); + dict_create_var_assert (ia->dict, name, 0); + free (name); + } +} /* Called when the user toggles one of the separators checkboxes. */ @@ -1152,15 +1133,15 @@ separators_page_create (PsppireImportAssistant *ia) ia->custom_cb = get_widget_assert (builder, "custom-cb"); ia->custom_entry = get_widget_assert (builder, "custom-entry"); ia->quote_combo = get_widget_assert (builder, "quote-combo"); - ia->quote_entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (ia->quote_combo))); ia->quote_cb = get_widget_assert (builder, "quote-cb"); - set_quote_list (GTK_COMBO_BOX (ia->quote_combo)); + gtk_combo_box_set_active (GTK_COMBO_BOX (ia->quote_combo), 0); if (ia->fields_tree_view == NULL) { GtkWidget *scroller = get_widget_assert (ia->builder, "fields-scroller"); ia->fields_tree_view = gtk_tree_view_new (); + g_object_set (ia->fields_tree_view, "enable-search", FALSE, NULL); gtk_container_add (GTK_CONTAINER (scroller), GTK_WIDGET (ia->fields_tree_view)); gtk_widget_show_all (scroller); } @@ -1210,16 +1191,18 @@ my_read (struct casereader *reader, void *aux, casenumber idx) const struct variable *var = dict_get_var (ia->dict, i); const gchar *ss = g_value_get_string (&value); - - union value *v = case_data_rw (c, var); - char *xx = data_in (ss_cstr (ss), - "UTF-8", - var_get_write_format (var)->type, - v, var_get_width (var), "UTF-8"); - - /* if (xx) */ - /* g_print ("%s:%d Err %s\n", __FILE__, __LINE__, xx); */ - free (xx); + if (ss) + { + union value *v = case_data_rw (c, var); + char *xx = data_in (ss_cstr (ss), + "UTF-8", + var_get_write_format (var)->type, + v, var_get_width (var), "UTF-8"); + + /* if (xx) */ + /* g_print ("%s:%d Err %s\n", __FILE__, __LINE__, xx); */ + free (xx); + } g_value_unset (&value); } } @@ -1241,74 +1224,39 @@ my_advance (struct casereader *reader, void *aux, casenumber cnt) g_print ("%s:%d\n", __FILE__, __LINE__); } -static void -foo (struct dictionary *dict, void *aux) -{ - PsppireImportAssistant *ia = PSPPIRE_IMPORT_ASSISTANT (aux); - g_print ("%s:%d\n", __FILE__, __LINE__); - - struct caseproto *proto = caseproto_create (); - - int i; - for (i = 0 ; i < dict_get_var_cnt (ia->dict); ++i) - { - const struct variable *var = dict_get_var (ia->dict, i); - proto = caseproto_add_width (proto, var_get_width (var)); - } - - - gint n_rows = gtk_tree_model_iter_n_children (ia->delimiters_model, NULL); - - struct casereader *reader = - casereader_create_random (proto, n_rows, &my_casereader_class, ia); - - - PsppireDataStore *store = NULL; - - g_object_get (ia->data_sheet, "data-model", &store, NULL); - - psppire_data_store_set_reader (store, reader); -} - -/* Called just before the formats page of the assistant is - displayed. */ -static void -prepare_formats_page (PsppireImportAssistant *ia) +static struct casereader * +textfile_create_reader (PsppireImportAssistant *ia) { - PsppireDict *dict = psppire_dict_new_from_dict (ia->dict); - g_object_set (ia->var_sheet, "data-model", dict, NULL); - - my_casereader_class.read = my_read; - my_casereader_class.destroy = my_destroy; - my_casereader_class.advance = my_advance; + int n_vars = dict_get_var_cnt (ia->dict); - struct caseproto *proto = caseproto_create (); int i; - struct fmt_guesser **fg = xcalloc (sizeof *fg, dict_get_var_cnt (ia->dict)); - for (i = 0 ; i < dict_get_var_cnt (ia->dict); ++i) + struct fmt_guesser **fg = xcalloc (sizeof *fg, n_vars); + for (i = 0 ; i < n_vars; ++i) { fg[i] = fmt_guesser_create (); } - gint n_rows = gtk_tree_model_iter_n_children (ia->delimiters_model, NULL); + gint n_rows = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (ia->delimiters_model), NULL); GtkTreeIter iter; gboolean ok; - for (ok = gtk_tree_model_get_iter_first (ia->delimiters_model, &iter); + for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ia->delimiters_model), &iter); ok; - ok = gtk_tree_model_iter_next (ia->delimiters_model, &iter)) + ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (ia->delimiters_model), &iter)) { - for (i = 0 ; i < dict_get_var_cnt (ia->dict); ++i) + for (i = 0 ; i < n_vars; ++i) { gchar *s = NULL; - gtk_tree_model_get (ia->delimiters_model, &iter, i+1, &s, -1); - fmt_guesser_add (fg[i], ss_cstr (s)); + gtk_tree_model_get (GTK_TREE_MODEL (ia->delimiters_model), &iter, i+1, &s, -1); + if (s) + fmt_guesser_add (fg[i], ss_cstr (s)); free (s); } } - for (i = 0 ; i < dict_get_var_cnt (ia->dict); ++i) + struct caseproto *proto = caseproto_create (); + for (i = 0 ; i < n_vars; ++i) { struct fmt_spec fs; fmt_guesser_guess (fg[i], &fs); @@ -1328,16 +1276,54 @@ prepare_formats_page (PsppireImportAssistant *ia) free (fg); - // dict_set_change_callback (ia->dict, foo, ia); + struct casereader *cr = casereader_create_random (proto, n_rows, &my_casereader_class, ia); + caseproto_unref (proto); + return cr; +} - struct casereader *reader = - casereader_create_random (proto, n_rows, &my_casereader_class, ia); - PsppireDataStore *store = psppire_data_store_new (dict); - psppire_data_store_set_reader (store, reader); +/* Called just before the formats page of the assistant is + displayed. */ +static void +prepare_formats_page (PsppireImportAssistant *ia) +{ + my_casereader_class.read = my_read; + my_casereader_class.destroy = my_destroy; + my_casereader_class.advance = my_advance; - g_object_set (ia->data_sheet, "data-model", store, NULL); + if (ia->spreadsheet) + { + GtkBuilder *builder = ia->builder; + GtkWidget *range_entry = get_widget_assert (builder, "cell-range-entry"); + GtkWidget *rnc = get_widget_assert (builder, "readnames-checkbox"); + GtkWidget *combo_box = get_widget_assert (builder, "sheet-entry"); + + struct spreadsheet_read_options opts; + opts.sheet_name = NULL; + opts.sheet_index = gtk_combo_box_get_active (GTK_COMBO_BOX (combo_box)) + 1; + opts.read_names = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rnc)); + opts.cell_range = g_strdup (gtk_entry_get_text (GTK_ENTRY (range_entry))); + opts.asw = 8; + + struct casereader *reader = spreadsheet_make_reader (ia->spreadsheet, &opts); + + PsppireDict *dict = psppire_dict_new_from_dict (ia->spreadsheet->dict); + PsppireDataStore *store = psppire_data_store_new (dict); + psppire_data_store_set_reader (store, reader); + g_object_set (ia->data_sheet, "data-model", store, NULL); + g_object_set (ia->var_sheet, "data-model", dict, NULL); + } + else + { + struct casereader *reader = textfile_create_reader (ia); + PsppireDict *dict = psppire_dict_new_from_dict (ia->dict); + PsppireDataStore *store = psppire_data_store_new (dict); + psppire_data_store_set_reader (store, reader); + + g_object_set (ia->data_sheet, "data-model", store, NULL); + g_object_set (ia->var_sheet, "data-model", dict, NULL); + } gint pmax; g_object_get (get_widget_assert (ia->builder, "vpaned1"), @@ -1374,6 +1360,7 @@ formats_page_create (PsppireImportAssistant *ia) if (ia->data_sheet == NULL) { ia->data_sheet = psppire_data_sheet_new (); + g_object_set (ia->data_sheet, "editable", FALSE, NULL); gtk_container_add (GTK_CONTAINER (data_scroller), ia->data_sheet); @@ -1409,8 +1396,15 @@ separators_append_syntax (const PsppireImportAssistant *ia, struct string *s) } } ds_put_cstr (s, "\"\n"); - if (!ds_is_empty (&ia->quotes)) - syntax_gen_pspp (s, " /QUALIFIER=%sq\n", ds_cstr (&ia->quotes)); + + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->quote_cb))) + { + GtkComboBoxText *cbt = GTK_COMBO_BOX_TEXT (ia->quote_combo); + gchar *quotes = gtk_combo_box_text_get_active_text (cbt); + if (quotes && *quotes) + syntax_gen_pspp (s, " /QUALIFIER=%sq\n", quotes); + free (quotes); + } } static void @@ -1448,9 +1442,12 @@ first_line_append_syntax (const PsppireImportAssistant *ia, struct string *s) static void intro_append_syntax (const PsppireImportAssistant *ia, struct string *s) { + gint first_line = 0; + g_object_get (ia->delimiters_model, "first-line", &first_line, NULL); + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->n_cases_button))) - ds_put_format (s, "N OF CASES %d.\n", - gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ia->n_cases_spin))); + ds_put_format (s, "SELECT IF ($CASENUM <= %d).\n", + gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ia->n_cases_spin)) - first_line); else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->percent_button))) ds_put_format (s, "SAMPLE %.4g.\n", gtk_spin_button_get_value (GTK_SPIN_BUTTON (ia->percent_spin)) / 100.0); @@ -1539,8 +1536,8 @@ apply_dict (const struct dictionary *dict, struct string *s) -static char * -sheet_spec_gen_syntax (PsppireImportAssistant *ia) +static void +sheet_spec_gen_syntax (PsppireImportAssistant *ia, struct string *s) { GtkBuilder *builder = ia->builder; GtkWidget *range_entry = get_widget_assert (builder, "cell-range-entry"); @@ -1550,11 +1547,13 @@ sheet_spec_gen_syntax (PsppireImportAssistant *ia) int sheet_index = 1 + gtk_combo_box_get_active (GTK_COMBO_BOX (sheet_entry)); gboolean read_names = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rnc)); - struct string s = DS_EMPTY_INITIALIZER; char *filename; - g_object_get (ia->text_file, "file-name", &filename, NULL); - syntax_gen_pspp (&s, + if (ia->spreadsheet) + filename = ia->spreadsheet->file_name; + else + g_object_get (ia->text_file, "file-name", &filename, NULL); + syntax_gen_pspp (s, "GET DATA" "\n /TYPE=%ss" "\n /FILE=%sq" @@ -1567,20 +1566,17 @@ sheet_spec_gen_syntax (PsppireImportAssistant *ia) if (range && 0 != strcmp ("", range)) { - syntax_gen_pspp (&s, + syntax_gen_pspp (s, "\n /CELLRANGE=RANGE %sq", range); } else { - syntax_gen_pspp (&s, + syntax_gen_pspp (s, "\n /CELLRANGE=FULL"); } - syntax_gen_pspp (&s, "."); - - - return ds_cstr (&s); + syntax_gen_pspp (s, ".\n"); } @@ -1622,8 +1618,16 @@ psppire_import_assistant_generate_syntax (PsppireImportAssistant *ia) } else { - return sheet_spec_gen_syntax (ia); + sheet_spec_gen_syntax (ia, &s); } return ds_cstr (&s); } + + +int +psppire_import_assistant_run (PsppireImportAssistant *asst) +{ + g_main_loop_run (asst->main_loop); + return asst->response; +}