X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fpsppire-import-assistant.c;h=9bdac0009f6d76c900e17d8b0d0694aecb190875;hb=c803992a141526ead8fcf857efa951783467f49a;hp=d8695706a317a4c3b9ff859c578bae2debf1ce15;hpb=50feac63e2fb9776f53e432f137311b4f5563ccf;p=pspp diff --git a/src/ui/gui/psppire-import-assistant.c b/src/ui/gui/psppire-import-assistant.c index d8695706a3..9bdac0009f 100644 --- a/src/ui/gui/psppire-import-assistant.c +++ b/src/ui/gui/psppire-import-assistant.c @@ -14,7 +14,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ - #include #include @@ -32,6 +31,7 @@ #include "data/ods-reader.h" #include "data/spreadsheet-reader.h" #include "data/value-labels.h" +#include "data/casereader-provider.h" #include "gl/intprops.h" @@ -50,6 +50,10 @@ #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" @@ -128,8 +132,6 @@ psppire_import_assistant_get_property (GObject *object, static GObjectClass * parent_class = NULL; -static void destroy_columns (PsppireImportAssistant *ia); - static void psppire_import_assistant_finalize (GObject *object) { @@ -139,8 +141,6 @@ psppire_import_assistant_finalize (GObject *object) if (ia->spreadsheet) spreadsheet_unref (ia->spreadsheet); - destroy_columns (ia); - ds_destroy (&ia->separators); ds_destroy (&ia->quotes); @@ -286,15 +286,33 @@ repopulate_delimiter_columns (PsppireImportAssistant *ia) f < n_fields; f++) { GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); + + const gchar *title = NULL; + + if (f == 0) + title = _("line"); + else + { + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->variable_names_cb))) + { + title = + psppire_delimited_text_get_header_title + (PSPPIRE_DELIMITED_TEXT (ia->delimiters_model), f - 1); + } + if (title == NULL) + title = _("var"); + } + GtkTreeViewColumn *column = - gtk_tree_view_column_new_with_attributes ("var", renderer, + gtk_tree_view_column_new_with_attributes (title, + renderer, "text", f, NULL); g_object_set (column, "resizable", TRUE, "sizing", GTK_TREE_VIEW_COLUMN_AUTOSIZE, NULL); - + gtk_tree_view_append_column (GTK_TREE_VIEW (ia->fields_tree_view), column); } } @@ -321,7 +339,7 @@ static void prepare_separators_page (PsppireImportAssistant *ia, GtkWidget *page) { gtk_tree_view_set_model (GTK_TREE_VIEW (ia->fields_tree_view), ia->delimiters_model); - + g_signal_connect_swapped (ia->delimiters_model, "notify::delimiters", G_CALLBACK (reset_tree_view_model), ia); @@ -710,9 +728,9 @@ on_chosen (PsppireImportAssistant *ia, GtkWidget *page) static void on_map (PsppireImportAssistant *ia, GtkWidget *page) { +#if TEXT_FILE GtkFileChooser *fc = GTK_FILE_CHOOSER (page); -#if TEXT_FILE if (ia->file_name) gtk_file_chooser_set_filename (fc, ia->file_name); #endif @@ -731,17 +749,18 @@ static void chooser_page_leave (PsppireImportAssistant *ia, GtkWidget *page) { g_print ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); - gchar *file_name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (page)); + 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); if (!ia->spreadsheet) { - ia->text_file = psppire_text_file_new (file_name, encoding); + ia->text_file = psppire_text_file_new (ia->file_name, encoding); gtk_tree_view_set_model (GTK_TREE_VIEW (ia->first_line_tree_view), GTK_TREE_MODEL (ia->text_file)); } - g_free (file_name); + g_free (encoding); } @@ -839,8 +858,10 @@ psppire_import_assistant_init (PsppireImportAssistant *ia) ia->builder = builder_new ("text-data-import.ui"); ia->current_page = -1 ; - ia->column_cnt = 0; - ia->columns = NULL; + /* ia->column_cnt = 0; */ + /* ia->columns = NULL; */ + + ia->file_name = NULL; ia->spreadsheet = NULL; ia->watch_cursor = 0; @@ -911,20 +932,6 @@ on_intro_amount_changed (PsppireImportAssistant *p) GTK_TOGGLE_BUTTON (p->percent_button))); } -/* Sets the widgets to match IA's first_line substructure. */ -static void -set_first_line (PsppireImportAssistant *ia) -{ - GtkTreePath *path = gtk_tree_path_new_from_indices (ia->skip_lines, -1); - - gtk_tree_path_free (path); - - gtk_toggle_button_set_active ( - GTK_TOGGLE_BUTTON (ia->variable_names_cb), - ia->variable_names); - gtk_widget_set_sensitive (ia->variable_names_cb, - ia->skip_lines > 0); -} #if SHEET_MERGE @@ -966,27 +973,29 @@ reset_first_line_page (PsppireImportAssistant *ia) #endif static void -on_cursor_change (GtkTreeView *treeview, gpointer user_data) +on_treeview_selection_change (PsppireImportAssistant *ia) { - PsppireImportAssistant *ia = PSPPIRE_IMPORT_ASSISTANT (user_data); - GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview); + GtkTreeSelection *selection = + gtk_tree_view_get_selection (GTK_TREE_VIEW (ia->first_line_tree_view)); GtkTreeModel *model = NULL; GtkTreeIter iter; if (gtk_tree_selection_get_selected (selection, &model, &iter)) { int n; - PsppireTextFile *tf = PSPPIRE_TEXT_FILE (model); GtkTreePath *path = gtk_tree_model_get_path (model, &iter); gint *index = gtk_tree_path_get_indices (path); - + n = *index; - + gtk_tree_path_free (path); - g_print ("%s:%d Setting first line to %d\n", __FILE__, __LINE__, n); + gtk_widget_set_sensitive (ia->variable_names_cb, n > 0); - ia->delimiters_model = psppire_delimited_text_new (ia->text_file); + ia->delimiters_model + = psppire_delimited_text_new (GTK_TREE_MODEL (ia->text_file)); g_object_set (ia->delimiters_model, "first-line", n, NULL); + + // ia->skip_lines = n; } } @@ -998,7 +1007,7 @@ 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", set_first_line); + g_object_set_data (G_OBJECT (w), "on-entering", on_treeview_selection_change); add_page_to_assistant (ia, w, GTK_ASSISTANT_PAGE_CONTENT, _("Select the First Line")); @@ -1023,15 +1032,14 @@ first_line_page_create (PsppireImportAssistant *ia) gtk_container_add (GTK_CONTAINER (scrolled_window), ia->first_line_tree_view); - g_signal_connect (ia->first_line_tree_view, "cursor-changed", - G_CALLBACK (on_cursor_change), ia); + g_signal_connect_swapped (ia->first_line_tree_view, "cursor-changed", + G_CALLBACK (on_treeview_selection_change), ia); } gtk_widget_show_all (scrolled_window); - + ia->variable_names_cb = get_widget_assert (ia->builder, "variable-names"); #if SHEET_MERGE - ia->variable_names_cb = get_widget_assert (ia->builder, "variable-names"); pspp_sheet_selection_set_mode ( pspp_sheet_view_get_selection (PSPP_SHEET_VIEW (ia->tree_view)), PSPP_SHEET_SELECTION_BROWSE); @@ -1044,7 +1052,6 @@ first_line_page_create (PsppireImportAssistant *ia) g_signal_connect_swapped (ia->variable_names_cb, "toggled", G_CALLBACK (set_first_line_options), ia); - g_object_set_data (G_OBJECT (w), "on-reset", reset_first_line_page); #endif } @@ -1181,7 +1188,11 @@ GtkWidget * psppire_import_assistant_new (GtkWindow *toplevel) { return GTK_WIDGET (g_object_new (PSPPIRE_TYPE_IMPORT_ASSISTANT, - "transient-for", toplevel, + /* Some window managers (notably ratpoison) + ignore the maximise command when a window is + transient. This causes problems for this + window. */ + /* "transient-for", toplevel, */ NULL)); } @@ -1213,20 +1224,6 @@ struct column struct substring *contents; }; - -static void -destroy_columns (PsppireImportAssistant *ia) -{ - struct column *col; - for (col = ia->columns; col < &ia->columns[ia->column_cnt]; col++) - { - free (col->name); - free (col->contents); - } - - free (ia->columns); -} - #if SHEET_MERGE /* Called to render one of the cells in the fields preview tree @@ -1262,8 +1259,6 @@ render_input_cell (PsppSheetViewColumn *tree_column, GtkCellRenderer *cell, (void *) NULL); } -#endif - /* Parses the contents of the field at (ROW,COLUMN) according to its variable format. If OUTPUTP is non-null, then *OUTPUTP receives the formatted output for that field (which must be @@ -1282,7 +1277,7 @@ parse_field (PsppireImportAssistant *ia, bool ok; struct substring field = ia->columns[column].contents[row]; - struct variable *var = dict_get_var (ia->dict, column); + const struct variable *var = dict_get_var (ia->dict, column); union value val; value_init (&val, var_get_width (var)); @@ -1322,8 +1317,6 @@ parse_field (PsppireImportAssistant *ia, return ok; } -#if SHEET_MERGE - /* Called to render one of the cells in the data preview tree view. */ static void @@ -1613,25 +1606,21 @@ split_fields (PsppireImportAssistant *ia) static void choose_column_names (PsppireImportAssistant *ia) { - struct dictionary *dict; - unsigned long int generated_name_count = 0; - struct column *col; - size_t name_row; - - dict = dict_create (get_default_encoding ()); - name_row = ia->variable_names && ia->skip_lines ? ia->skip_lines : 0; - for (col = ia->columns; col < &ia->columns[ia->column_cnt]; col++) + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->variable_names_cb))) { - char *hint, *name; - - hint = name_row ? ss_xstrdup (col->contents[name_row - 1]) : NULL; - name = dict_make_unique_var_name (dict, hint, &generated_name_count); - free (hint); + int i; + unsigned long int generated_name_count = 0; + dict_clear (ia->dict); + for (i = 0; i < gtk_tree_model_get_n_columns (ia->delimiters_model) - 1; ++i) + { + const gchar *candidate_name = + psppire_delimited_text_get_header_title (PSPPIRE_DELIMITED_TEXT (ia->delimiters_model), i); - col->name = name; - dict_create_var_assert (dict, name, 0); + char *name = dict_make_unique_var_name (ia->dict, candidate_name, &generated_name_count); + dict_create_var_assert (ia->dict, name, 0); + free (name); + } } - dict_destroy (dict); } @@ -1791,11 +1780,171 @@ on_variable_change (PsppireDict *dict, int dict_idx, #endif +static struct casereader_random_class my_casereader_class; + +static struct ccase * +my_read (struct casereader *reader, void *aux, casenumber idx) +{ + PsppireImportAssistant *ia = PSPPIRE_IMPORT_ASSISTANT (aux); + GtkTreeModel *tm = GTK_TREE_MODEL (ia->delimiters_model); + + GtkTreePath *tp = gtk_tree_path_new_from_indices (idx, -1); + + const struct caseproto *proto = casereader_get_proto (reader); + + GtkTreeIter iter; + struct ccase *c = NULL; + if (gtk_tree_model_get_iter (tm, &iter, tp)) + { + c = case_create (proto); + int i; + for (i = 0 ; i < caseproto_get_n_widths (proto); ++i) + { + GValue value = {0}; + gtk_tree_model_get_value (tm, &iter, i + 1, &value); + + 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); + g_value_unset (&value); + } + } + + gtk_tree_path_free (tp); + + return c; +} + +static void +my_destroy (struct casereader *reader, void *aux) +{ + g_print ("%s:%d %p\n", __FILE__, __LINE__, reader); +} + +static void +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) { + 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; + + 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) + { + fg[i] = fmt_guesser_create (); + } + + gint n_rows = gtk_tree_model_iter_n_children (ia->delimiters_model, NULL); + + GtkTreeIter iter; + gboolean ok; + for (ok = gtk_tree_model_get_iter_first (ia->delimiters_model, &iter); + ok; + ok = gtk_tree_model_iter_next (ia->delimiters_model, &iter)) + { + for (i = 0 ; i < dict_get_var_cnt (ia->dict); ++i) + { + gchar *s = NULL; + gtk_tree_model_get (ia->delimiters_model, &iter, i+1, &s, -1); + fmt_guesser_add (fg[i], ss_cstr (s)); + free (s); + } + } + + for (i = 0 ; i < dict_get_var_cnt (ia->dict); ++i) + { + struct fmt_spec fs; + fmt_guesser_guess (fg[i], &fs); + + fmt_fix (&fs, FMT_FOR_INPUT); + + struct variable *var = dict_get_var (ia->dict, i); + + int width = fmt_var_width (&fs); + + var_set_width_and_formats (var, width, + &fs, &fs); + + proto = caseproto_add_width (proto, width); + fmt_guesser_destroy (fg[i]); + } + + free (fg); + + // dict_set_change_callback (ia->dict, foo, ia); + + 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); + + g_object_set (ia->data_sheet, "data-model", store, NULL); + + + gint pmax; + g_object_get (get_widget_assert (ia->builder, "vpaned1"), + "max-position", &pmax, NULL); + + + g_object_set (get_widget_assert (ia->builder, "vpaned1"), + "position", pmax / 2, NULL); + + gtk_widget_show (ia->paste_button); } static void @@ -1803,15 +1952,34 @@ formats_page_create (PsppireImportAssistant *ia) { GtkBuilder *builder = ia->builder; - GtkWidget *w = get_widget_assert (builder, "Formats"); g_object_set_data (G_OBJECT (w), "on-entering", prepare_formats_page); g_object_set_data (G_OBJECT (w), "on-reset", reset_formats_page); + GtkWidget *vars_scroller = get_widget_assert (builder, "vars-scroller"); + if (ia->var_sheet == NULL) + { + ia->var_sheet = psppire_variable_sheet_new (); + + gtk_container_add (GTK_CONTAINER (vars_scroller), ia->var_sheet); + + ia->dict = dict_create (get_default_encoding ()); + + gtk_widget_show_all (vars_scroller); + } + GtkWidget *data_scroller = get_widget_assert (builder, "data-scroller"); + if (ia->data_sheet == NULL) + { + ia->data_sheet = psppire_data_sheet_new (); + + gtk_container_add (GTK_CONTAINER (data_scroller), ia->data_sheet); + + gtk_widget_show_all (data_scroller); + } + add_page_to_assistant (ia, w, GTK_ASSISTANT_PAGE_CONFIRM, _("Adjust Variable Formats")); - ia->data_tree_view = NULL; ia->modified_vars = NULL; ia->modified_var_cnt = 0; } @@ -1864,14 +2032,15 @@ formats_append_syntax (const PsppireImportAssistant *ia, struct string *s) } } - static void first_line_append_syntax (const PsppireImportAssistant *ia, struct string *s) { - if (ia->skip_lines > 0) - ds_put_format (s, " /FIRSTCASE=%d\n", ia->skip_lines + 1); -} + gint first_case = 0; + g_object_get (ia->delimiters_model, "first-line", &first_case, NULL); + if (first_case > 0) + ds_put_format (s, " /FIRSTCASE=%d\n", first_case + 1); +} static void intro_append_syntax (const PsppireImportAssistant *ia, struct string *s) @@ -2022,7 +2191,7 @@ psppire_import_assistant_generate_syntax (PsppireImportAssistant *ia) gchar *file_name = NULL; gchar *encoding = NULL; g_object_get (ia->text_file, - "filename", &file_name, + "file-name", &file_name, "encoding", &encoding, NULL);