X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fpsppire-import-textfile.c;h=1b6a4d65bdd18163858b3aa19201d848d5895eab;hb=899ca177810116bc0ff1c4bcce9368d79cd71d42;hp=c6fdfccd527fdc936b7835f2fb81297e1a0848c2;hpb=65d602ed236d685ffec00ad1552a193cf47b2e4d;p=pspp diff --git a/src/ui/gui/psppire-import-textfile.c b/src/ui/gui/psppire-import-textfile.c index c6fdfccd52..1b6a4d65bd 100644 --- a/src/ui/gui/psppire-import-textfile.c +++ b/src/ui/gui/psppire-import-textfile.c @@ -47,123 +47,50 @@ /* Chooses a name for each column on the separators page */ static void choose_column_names (PsppireImportAssistant *ia); -/* Revises the contents of the fields tree view based on the - currently chosen set of separators. */ -static void -revise_fields_preview (PsppireImportAssistant *ia) +static gunichar +get_quote_character (const PsppireImportAssistant *ia) { - choose_column_names (ia); -} - - -struct separator_count_node -{ - struct hmap_node node; - int occurance; /* The number of times the separator occurs in a line */ - int quantity; /* The number of lines with this occurance */ -}; + GtkToggleButton *quote_single = GTK_TOGGLE_BUTTON (ia->quote_single); + GtkToggleButton *quote_double = GTK_TOGGLE_BUTTON (ia->quote_double); + GtkToggleButton *quote_custom = GTK_TOGGLE_BUTTON (ia->quote_custom); + if (gtk_toggle_button_get_active (quote_custom)) + { + GtkEntry *quote_custom_entry = GTK_ENTRY (ia->quote_custom_entry); + const gchar *text = gtk_entry_get_text (quote_custom_entry); + return text && text[0] ? g_utf8_get_char (text) : 0; + } + else + return (gtk_toggle_button_get_active (quote_single) ? '\'' + : gtk_toggle_button_get_active (quote_double) ? '"' + : 0); +} -/* Picks the most likely separator and quote characters based on - IA's file data. */ +/* Revises the contents of the fields tree view based on the + currently chosen set of separators and quotes. */ static void -choose_likely_separators (PsppireImportAssistant *ia) +revise_fields_preview (PsppireImportAssistant *ia) { - gint first_line = 0; - g_object_get (ia->delimiters_model, "first-line", &first_line, NULL); - - gboolean valid; - GtkTreeIter iter; - int j; - - struct hmap count_map[SEPARATOR_CNT]; - for (j = 0; j < SEPARATOR_CNT; ++j) - hmap_init (count_map + j); - - GtkTreePath *p = gtk_tree_path_new_from_indices (first_line, -1); - - for (valid = gtk_tree_model_get_iter (GTK_TREE_MODEL (ia->text_file), &iter, p); - valid; - valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (ia->text_file), &iter)) + GSList *delimiters = NULL; + for (int i = 0; i < N_SEPARATORS; i++) { - 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); - - 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) - { - if (character == separators[s].c) - counts[s]++; - } - } - - int j; - for (j = 0; j < SEPARATOR_CNT; ++j) + const struct separator *s = &separators[i]; + GtkWidget *button = get_widget_assert (ia->text_builder, s->name); + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) { - if (counts[j] > 0) - { - struct separator_count_node *cn = NULL; - unsigned int hash = hash_int (counts[j], 0); - HMAP_FOR_EACH_WITH_HASH (cn, struct separator_count_node, node, hash, &count_map[j]) - { - if (cn->occurance == counts[j]) - break; - } - - if (cn == NULL) - { - struct separator_count_node *new_cn = xzalloc (sizeof *new_cn); - new_cn->occurance = counts[j]; - new_cn->quantity = 1; - hmap_insert (&count_map[j], &new_cn->node, hash); - } - else - cn->quantity++; - } + delimiters = g_slist_prepend (delimiters, GINT_TO_POINTER (s->c)); } - - free (line_text); - free (counts); } - gtk_tree_path_free (p); - if (hmap_count (count_map) > 0) - { - int most_frequent = -1; - int largest = 0; - for (j = 0; j < SEPARATOR_CNT; ++j) - { - struct separator_count_node *cn; - struct separator_count_node *next; - HMAP_FOR_EACH_SAFE (cn, next, struct separator_count_node, node, &count_map[j]) - { - if (largest < cn->quantity) - { - largest = cn->quantity; - most_frequent = j; - } - free (cn); - } - hmap_destroy (&count_map[j]); - } - - g_return_if_fail (most_frequent >= 0); + g_object_set (ia->delimiters_model, + "delimiters", delimiters, + "quote", get_quote_character (ia), + NULL); - GtkWidget *toggle = - get_widget_assert (ia->text_builder, separators[most_frequent].name); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), TRUE); - } + choose_column_names (ia); } + static void repopulate_delimiter_columns (PsppireImportAssistant *ia) { @@ -421,8 +348,8 @@ intro_on_enter (PsppireImportAssistant *ia, GtkWidget *page, enum IMPORT_ASSISTA "preview purposes in the following screens. ", "Only the first %zu lines of the file will be shown for " "preview purposes in the following screens. ", - ia->text_file->line_cnt), - ia->text_file->line_cnt); + ia->text_file->n_lines), + ia->text_file->n_lines); } } @@ -534,20 +461,6 @@ static void on_separator_toggle (GtkToggleButton *toggle UNUSED, PsppireImportAssistant *ia) { - int i; - GSList *delimiters = NULL; - for (i = 0; i < SEPARATOR_CNT; i++) - { - const struct separator *s = &separators[i]; - GtkWidget *button = get_widget_assert (ia->text_builder, s->name); - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) - { - delimiters = g_slist_prepend (delimiters, GINT_TO_POINTER (s->c)); - } - } - - g_object_set (ia->delimiters_model, "delimiters", delimiters, NULL); - revise_fields_preview (ia); } @@ -573,51 +486,56 @@ on_separators_custom_cb_toggle (GtkToggleButton *custom_cb, revise_fields_preview (ia); } -/* Called when the user changes the selection in the combo box - that selects a quote character. */ +/* Called when the user changes any of the quote settings. */ static void -on_quote_combo_change (GtkComboBox *combo, PsppireImportAssistant *ia) +on_quote_change (GtkWidget *widget UNUSED, PsppireImportAssistant *ia) { + GtkToggleButton *quote_custom = GTK_TOGGLE_BUTTON (ia->quote_custom); + bool is_custom = gtk_toggle_button_get_active (quote_custom); + gtk_widget_set_sensitive (ia->quote_custom_entry, is_custom); revise_fields_preview (ia); } -/* Called when the user toggles the checkbox that enables - quoting. */ static void -on_quote_cb_toggle (GtkToggleButton *quote_cb, PsppireImportAssistant *ia) +on_quote_custom_entry_change (GObject *gobject UNUSED, + GParamSpec *arg1 UNUSED, + PsppireImportAssistant *ia) { - bool is_active = gtk_toggle_button_get_active (quote_cb); - gtk_widget_set_sensitive (ia->quote_combo, is_active); revise_fields_preview (ia); } - /* Called when the Reset button is clicked. */ static void reset_separators_page (PsppireImportAssistant *ia) { gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ia->custom_cb), FALSE); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ia->quote_cb), FALSE); gtk_entry_set_text (GTK_ENTRY (ia->custom_entry), ""); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ia->quote_double), TRUE); + gtk_entry_set_text (GTK_ENTRY (ia->quote_custom_entry), ""); - for (gint i = 0; i < SEPARATOR_CNT; i++) + for (gint i = 0; i < N_SEPARATORS; i++) { const struct separator *s = &separators[i]; GtkWidget *button = get_widget_assert (ia->text_builder, s->name); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), s->c == ','); } - repopulate_delimiter_columns (ia); + if (ia->delimiters_model) + { + repopulate_delimiter_columns (ia); - revise_fields_preview (ia); - choose_likely_separators (ia); + revise_fields_preview (ia); + } } /* Called just before the separators page becomes visible in the assistant. */ static void -prepare_separators_page (PsppireImportAssistant *ia) +prepare_separators_page (PsppireImportAssistant *ia, GtkWidget *new_page, enum IMPORT_ASSISTANT_DIRECTION dir) { + if (dir != IMPORT_ASSISTANT_FORWARDS) + return; + gtk_tree_view_set_model (GTK_TREE_VIEW (ia->fields_tree_view), GTK_TREE_MODEL (ia->delimiters_model)); @@ -646,13 +564,16 @@ 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_cb = get_widget_assert (builder, "quote-cb"); + ia->quote_none = get_widget_assert (builder, "quote-none"); + ia->quote_single = get_widget_assert (builder, "quote-single"); + ia->quote_double = get_widget_assert (builder, "quote-double"); + ia->quote_custom = get_widget_assert (builder, "quote-custom"); + ia->quote_custom_entry = get_widget_assert (builder, "quote-custom-entry"); gtk_widget_set_sensitive (ia->custom_entry, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->custom_cb))); - gtk_combo_box_set_active (GTK_COMBO_BOX (ia->quote_combo), 0); + gtk_entry_set_max_length (GTK_ENTRY (ia->quote_custom_entry), 1); if (ia->fields_tree_view == NULL) { @@ -663,15 +584,16 @@ separators_page_create (PsppireImportAssistant *ia) gtk_widget_show_all (scroller); } - g_signal_connect (ia->quote_combo, "changed", - G_CALLBACK (on_quote_combo_change), ia); - g_signal_connect (ia->quote_cb, "toggled", - G_CALLBACK (on_quote_cb_toggle), ia); + g_signal_connect (ia->quote_none, "toggled", G_CALLBACK (on_quote_change), ia); + g_signal_connect (ia->quote_single, "toggled", G_CALLBACK (on_quote_change), ia); + g_signal_connect (ia->quote_double, "toggled", G_CALLBACK (on_quote_change), ia); + g_signal_connect (ia->quote_custom, "toggled", G_CALLBACK (on_quote_change), ia); + g_signal_connect (ia->quote_custom_entry, "notify::text", G_CALLBACK (on_quote_custom_entry_change), ia); g_signal_connect (ia->custom_entry, "notify::text", G_CALLBACK (on_separators_custom_entry_notify), ia); g_signal_connect (ia->custom_cb, "toggled", G_CALLBACK (on_separators_custom_cb_toggle), ia); - for (i = 0; i < SEPARATOR_CNT; i++) + for (i = 0; i < N_SEPARATORS; i++) g_signal_connect (get_widget_assert (builder, separators[i].name), "toggled", G_CALLBACK (on_separator_toggle), ia); @@ -719,6 +641,7 @@ my_read (struct casereader *reader, void *aux, casenumber idx) char *xx = data_in (ss_cstr (ss), "UTF-8", var_get_write_format (var)->type, + settings_get_fmt_settings (), v, var_get_width (var), "UTF-8"); free (xx); @@ -739,7 +662,7 @@ my_destroy (struct casereader *reader, void *aux) } static void -my_advance (struct casereader *reader, void *aux, casenumber cnt) +my_advance (struct casereader *reader, void *aux, casenumber n) { g_print ("%s:%d\n", __FILE__, __LINE__); } @@ -747,7 +670,7 @@ my_advance (struct casereader *reader, void *aux, casenumber cnt) static struct casereader * textfile_create_reader (PsppireImportAssistant *ia) { - int n_vars = dict_get_var_cnt (ia->dict); + int n_vars = dict_get_n_vars (ia->dict); int i; @@ -821,7 +744,7 @@ ia_variable_changed_cb (GObject *obj, gint var_num, guint what, PsppireImportAssistant *ia = PSPPIRE_IMPORT_ASSISTANT (data); struct caseproto *proto = caseproto_create(); - for (int i = 0; i < dict_get_var_cnt (ia->dict); i++) + for (int i = 0; i < dict_get_n_vars (ia->dict); i++) { const struct variable *var = dict_get_var (ia->dict, i); int width = var_get_width (var); @@ -878,10 +801,9 @@ first_line_append_syntax (const PsppireImportAssistant *ia, struct string *s) static void apply_dict (const struct dictionary *dict, struct string *s) { - size_t var_cnt = dict_get_var_cnt (dict); - size_t i; + size_t n_vars = dict_get_n_vars (dict); - for (i = 0; i < var_cnt; i++) + for (size_t i = 0; i < n_vars; i++) { struct variable *var = dict_get_var (dict, i); const char *name = var_get_name (var); @@ -920,12 +842,11 @@ apply_dict (const struct dictionary *dict, struct string *s) const struct val_labs *vls = var_get_value_labels (var); 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 (i = 0; i < n_labels; i++) + for (size_t j = 0; j < n_labels; j++) { - const struct val_lab *vl = labels[i]; + const struct val_lab *vl = labels[j]; ds_put_cstr (s, "\n "); syntax_gen_value (s, &vl->value, width, format); ds_put_byte (s, ' '); @@ -937,7 +858,8 @@ apply_dict (const struct dictionary *dict, struct string *s) if (var_has_label (var)) syntax_gen_pspp (s, "VARIABLE LABELS %ss %sq.\n", name, var_get_label (var)); - if (measure != var_default_measure (type)) + if (measure != var_default_measure_for_type (type) + && measure != MEASURE_UNKNOWN) syntax_gen_pspp (s, "VARIABLE LEVEL %ss (%ss).\n", name, measure_to_syntax (measure)); if (role != ROLE_INPUT) @@ -971,22 +893,19 @@ intro_append_syntax (const PsppireImportAssistant *ia, struct string *s) static void formats_append_syntax (const PsppireImportAssistant *ia, struct string *s) { - int i; - int var_cnt; - g_return_if_fail (ia->dict); ds_put_cstr (s, " /VARIABLES=\n"); - var_cnt = dict_get_var_cnt (ia->dict); - for (i = 0; i < var_cnt; i++) + int n_vars = dict_get_n_vars (ia->dict); + for (int i = 0; i < n_vars; i++) { struct variable *var = dict_get_var (ia->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 ? "." : ""); + i == n_vars - 1 ? "." : ""); } } @@ -999,7 +918,7 @@ separators_append_syntax (const PsppireImportAssistant *ia, struct string *s) if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (get_widget_assert (ia->text_builder, "tab")))) ds_put_cstr (s, "\\t"); - for (i = 0; i < SEPARATOR_CNT; i++) + for (i = 0; i < N_SEPARATORS; i++) { const struct separator *seps = &separators[i]; GtkWidget *button = get_widget_assert (ia->text_builder, seps->name); @@ -1013,13 +932,13 @@ separators_append_syntax (const PsppireImportAssistant *ia, struct string *s) } ds_put_cstr (s, "\"\n"); - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->quote_cb))) + gunichar quote = get_quote_character (ia); + if (quote) { - 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); + GString *quote_s = g_string_new (NULL); + g_string_append_unichar (quote_s, quote); + syntax_gen_pspp (s, " /QUALIFIER=%sq\n", quote_s->str); + g_string_free (quote_s, TRUE); } }