From: Ben Pfaff Date: Fri, 27 May 2022 22:37:10 +0000 (-0700) Subject: gui: Make text import assistant accept only one quote character. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pspp;a=commitdiff_plain;h=66c5538861e0e29333b1b0ee83ea2c548c08fd8f gui: Make text import assistant accept only one quote character. This aligns with what SPSS does. --- diff --git a/src/ui/gui/psppire-delimited-text.c b/src/ui/gui/psppire-delimited-text.c index 6c8f0ae35b..59b423010e 100644 --- a/src/ui/gui/psppire-delimited-text.c +++ b/src/ui/gui/psppire-delimited-text.c @@ -32,7 +32,7 @@ enum PROP_0, PROP_CHILD, PROP_DELIMITERS, - PROP_QUOTES, + PROP_QUOTE, PROP_FIRST_LINE }; @@ -64,7 +64,7 @@ count_delims (PsppireDelimitedText *tf) if (c == quote) quote = -1; - else if (c == tf->quotes[0] || c == tf->quotes[1]) + else if (tf->quote && c == tf->quote) quote = c; if (quote == -1) @@ -116,17 +116,8 @@ psppire_delimited_text_set_property (GObject *object, g_slist_free (tf->delimiters); tf->delimiters = g_slist_copy (g_value_get_pointer (value)); break; - case PROP_QUOTES: - { - tf->quotes[0] = tf->quotes[1] = -1; - - const gchar *s = g_value_get_string (value); - for (size_t i = 0; i < 2 && s && s[0]; i++) - { - tf->quotes[i] = g_utf8_get_char (s); - s = g_utf8_find_next_char (s, NULL); - } - } + case PROP_QUOTE: + tf->quote = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -153,16 +144,8 @@ psppire_delimited_text_get_property (GObject *object, case PROP_DELIMITERS: g_value_set_pointer (value, text_file->delimiters); break; - case PROP_QUOTES: - { - GString *s = g_string_new (NULL); - for (size_t i = 0; i < 2; i++) - { - gunichar quote = text_file->quotes[i]; - if (quote && quote != -1) - g_string_append_unichar (s, quote); - } - } + case PROP_QUOTE: + g_value_set_uint (value, text_file->quote); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -387,7 +370,7 @@ split_row_into_fields (PsppireDelimitedText *file, gint n) gboolean char_is_quote = FALSE; if (quote == -1) { - if (character == file->quotes[0] || character == file->quotes[1]) + if (file->quote && character == file->quote) { quote = character; char_is_quote = TRUE; @@ -503,11 +486,11 @@ psppire_delimited_text_class_init (PsppireDelimitedTextClass *class) P_("A GSList of gunichars which delimit the fields."), G_PARAM_READWRITE); - GParamSpec *quotes_spec = - g_param_spec_string ("quotes", - "Field Quotes", - P_("A string of characters that quote the fields."), - P_(""), + GParamSpec *quote_spec = + g_param_spec_unichar ("quote", + "Quote Character", + P_("A character that quotes the field, or 0 to disable quoting."), + 0, G_PARAM_READWRITE); GParamSpec *child_spec = @@ -529,8 +512,8 @@ psppire_delimited_text_class_init (PsppireDelimitedTextClass *class) delimiters_spec); g_object_class_install_property (object_class, - PROP_QUOTES, - quotes_spec); + PROP_QUOTE, + quote_spec); g_object_class_install_property (object_class, PROP_FIRST_LINE, @@ -555,7 +538,7 @@ psppire_delimited_text_init (PsppireDelimitedText *text_file) text_file->max_delimiters = 0; - text_file->quotes[0] = text_file->quotes[1] = -1; + text_file->quote = 0; text_file->dispose_has_run = FALSE; text_file->stamp = g_random_int (); diff --git a/src/ui/gui/psppire-delimited-text.h b/src/ui/gui/psppire-delimited-text.h index 3e1094b777..b5c919f4fb 100644 --- a/src/ui/gui/psppire-delimited-text.h +++ b/src/ui/gui/psppire-delimited-text.h @@ -61,7 +61,7 @@ struct _PsppireDelimitedText GSList *delimiters; gint max_delimiters; - gunichar quotes[2]; + gunichar quote; /*< private >*/ gboolean dispose_has_run ; diff --git a/src/ui/gui/psppire-import-assistant.h b/src/ui/gui/psppire-import-assistant.h index 881fc5bad0..deec75c878 100644 --- a/src/ui/gui/psppire-import-assistant.h +++ b/src/ui/gui/psppire-import-assistant.h @@ -105,8 +105,11 @@ struct _PsppireImportAssistant GtkWidget *custom_cb; GtkWidget *custom_entry; - GtkWidget *quote_cb; - GtkWidget *quote_combo; + GtkWidget *quote_none; + GtkWidget *quote_single; + GtkWidget *quote_double; + GtkWidget *quote_custom; + GtkWidget *quote_custom_entry; GtkWidget *fields_tree_view; diff --git a/src/ui/gui/psppire-import-textfile.c b/src/ui/gui/psppire-import-textfile.c index 3034ed02f6..ec53d175ed 100644 --- a/src/ui/gui/psppire-import-textfile.c +++ b/src/ui/gui/psppire-import-textfile.c @@ -47,6 +47,25 @@ /* Chooses a name for each column on the separators page */ static void choose_column_names (PsppireImportAssistant *ia); +static gunichar +get_quote_character (const PsppireImportAssistant *ia) +{ + 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); +} + /* Revises the contents of the fields tree view based on the currently chosen set of separators and quotes. */ static void @@ -63,15 +82,9 @@ revise_fields_preview (PsppireImportAssistant *ia) } } - GtkComboBoxText *cbt = GTK_COMBO_BOX_TEXT (ia->quote_combo); - GtkToggleButton *quote_cb = GTK_TOGGLE_BUTTON (ia->quote_cb); - const gchar *quotes = (gtk_toggle_button_get_active (quote_cb) - ? gtk_combo_box_text_get_active_text (cbt) - : ""); - g_object_set (ia->delimiters_model, "delimiters", delimiters, - "quotes", quotes, + "quote", get_quote_character (ia), NULL); choose_column_names (ia); @@ -473,33 +486,32 @@ 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_entry_set_text (GTK_ENTRY (ia->custom_entry), ""); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ia->quote_cb), TRUE); - gtk_combo_box_set_active (GTK_COMBO_BOX (ia->quote_combo), 0); + 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 < N_SEPARATORS; i++) { @@ -552,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_entry_set_max_length (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (ia->quote_combo))), 1); + gtk_entry_set_max_length (GTK_ENTRY (ia->quote_custom_entry), 1); if (ia->fields_tree_view == NULL) { @@ -569,10 +584,11 @@ 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", @@ -915,13 +931,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); } } diff --git a/src/ui/gui/text-data-import.ui b/src/ui/gui/text-data-import.ui index ff830e3917..7bc38dbc88 100644 --- a/src/ui/gui/text-data-import.ui +++ b/src/ui/gui/text-data-import.ui @@ -289,6 +289,7 @@ 0 none + True False @@ -465,7 +466,7 @@ True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - <b>Separators</b> + <b>What characters separate fields?</b> True @@ -484,47 +485,98 @@ 0 none - + True False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 12 - 6 - 6 + vertical - + + None True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False - True - - " - ' - - - - False - - + True + False + start + True + True - 1 - 0 + False + True + 0 - - Quote separator characters with + + Single quote (') True True False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + start + True True + quote-none - 0 - 0 + False + True + 1 + + + + + Double quote (") + True + True + False + start + True + True + quote-none + + + False + True + 2 + + + + + True + False + + + Custom: + True + True + False + True + True + quote-none + + + False + True + 0 + + + + + True + True + 1 + 1 + + + False + True + 1 + + + + + False + True + 3 @@ -534,7 +586,7 @@ True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - <b>Quoting</b> + <b>What character quotes fields?</b> True