X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=src%2Fui%2Fgui%2Fmissing-val-dialog.c;h=09e17c1aaff4046989f0866e7529ab5bb6e45dfb;hb=dca2c29703057e9b77302cd6241d0c36a0d3a63f;hp=030d0786709a9a1a5be9d434882d1941668856b0;hpb=881c891baa77be85b51bbaf4b4da124e72f4118b;p=pspp diff --git a/src/ui/gui/missing-val-dialog.c b/src/ui/gui/missing-val-dialog.c index 030d078670..09e17c1aaf 100644 --- a/src/ui/gui/missing-val-dialog.c +++ b/src/ui/gui/missing-val-dialog.c @@ -1,5 +1,6 @@ /* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2005, 2006, 2009, 2011, 2012 Free Software Foundation + Copyright (C) 2005, 2006, 2009, 2011, 2012, 2015, 2016, + 2020 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 @@ -147,12 +148,11 @@ psppire_missing_val_dialog_new (const struct variable *var) { return PSPPIRE_MISSING_VAL_DIALOG ( g_object_new (PSPPIRE_TYPE_MISSING_VAL_DIALOG, - "orientation", PSPPIRE_VERTICAL, "variable", var, NULL)); } -void +gint psppire_missing_val_dialog_run (GtkWindow *parent_window, const struct variable *var, struct missing_values *mv) @@ -164,12 +164,14 @@ psppire_missing_val_dialog_run (GtkWindow *parent_window, gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); gtk_widget_show (GTK_WIDGET (dialog)); - if (psppire_dialog_run (PSPPIRE_DIALOG (dialog)) == GTK_RESPONSE_OK) + gint result = psppire_dialog_run (PSPPIRE_DIALOG (dialog)); + if (result == GTK_RESPONSE_OK) mv_copy (mv, psppire_missing_val_dialog_get_missing_values (dialog)); else mv_copy (mv, var_get_missing_values (var)); gtk_widget_destroy (GTK_WIDGET (dialog)); + return result; } @@ -177,39 +179,52 @@ psppire_missing_val_dialog_run (GtkWindow *parent_window, static void err_dialog (const gchar *msg, GtkWindow *window) { - GtkWidget *hbox ; - GtkWidget *label = gtk_label_new (msg); - GtkWidget *dialog = - gtk_dialog_new_with_buttons ("PSPP", - window, - GTK_DIALOG_MODAL | - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_OK, - GTK_RESPONSE_ACCEPT, - NULL); - - - GtkWidget *icon = gtk_image_new_from_stock (GTK_STOCK_DIALOG_ERROR, - GTK_ICON_SIZE_DIALOG); - - g_signal_connect_swapped (dialog, - "response", - G_CALLBACK (gtk_widget_destroy), - dialog); - - hbox = gtk_hbox_new (FALSE, 10); - - gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), - hbox); + gtk_message_dialog_new (window, + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "%s",msg); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +} - gtk_box_pack_start (GTK_BOX (hbox), icon, TRUE, FALSE, 10); - gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 10); +/* Interpret text, display error dialog + If parsing is o.k., the value is initialized and it is the responsibility of + the caller to destroy the variable. */ +static gboolean +try_missing_value(const PsppireMissingValDialog *dialog, const gchar *text, union value *vp) +{ + const int var_width = fmt_var_width (&dialog->format); + char *error_txt = NULL; - gtk_widget_show_all (dialog); + value_init(vp, var_width); + error_txt = data_in (ss_cstr(text), "UTF-8", dialog->format.type, + vp, var_width, dialog->encoding); + if (error_txt) + { + err_dialog (error_txt, GTK_WINDOW (dialog)); + free (error_txt); + goto error; + } + else + { + if (mv_is_acceptable (vp, var_width)) + return TRUE; + else + { + err_dialog (_("The maximum length of a missing value" + " for a string variable is 8 in UTF-8."), + GTK_WINDOW (dialog)); + goto error; + } + } + error: + value_destroy (vp, var_width); + return FALSE; } - /* Acceptability predicate for PsppireMissingValDialog. This function is also the only place that dialog->mvl gets updated. */ @@ -217,100 +232,98 @@ static gboolean missing_val_dialog_acceptable (gpointer data) { PsppireMissingValDialog *dialog = data; + int var_width = fmt_var_width (&dialog->format); - if ( gtk_toggle_button_get_active (dialog->button_discrete)) + if (gtk_toggle_button_get_active (dialog->button_discrete)) { gint nvals = 0; - gint badvals = 0; gint i; + mv_clear(&dialog->mvl); - for(i = 0 ; i < 3 ; ++i ) + for(i = 0 ; i < 3 ; ++i) { gchar *text = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->mv[i]))); union value v; - if ( !text || strlen (g_strstrip (text)) == 0 ) + if (!text || strlen (g_strstrip (text)) == 0) { g_free (text); continue; } - if ( text_to_value__ (text, &dialog->format, dialog->encoding, &v)) + if (!try_missing_value (dialog, text, &v)) { - nvals++; - mv_add_value (&dialog->mvl, &v); + g_free (text); + gtk_widget_grab_focus (dialog->mv[i]); + return FALSE; } - else - badvals++; + mv_add_value (&dialog->mvl, &v); + nvals++; g_free (text); - value_destroy (&v, fmt_var_width (&dialog->format)); + value_destroy (&v, var_width); } - if ( nvals == 0 || badvals > 0 ) + if (nvals == 0) { - err_dialog (_("Incorrect value for variable type"), - GTK_WINDOW (dialog)); + err_dialog (_("At least one value must be specified"), + GTK_WINDOW (dialog)); + gtk_widget_grab_focus (dialog->mv[0]); return FALSE; } } if (gtk_toggle_button_get_active (dialog->button_range)) { - gchar *discrete_text ; - + gchar *discrete_text; union value low_val ; union value high_val; const gchar *low_text = gtk_entry_get_text (GTK_ENTRY (dialog->low)); const gchar *high_text = gtk_entry_get_text (GTK_ENTRY (dialog->high)); - gboolean low_ok; - gboolean high_ok; - gboolean ok; - - low_ok = text_to_value__ (low_text, &dialog->format, dialog->encoding, - &low_val) != NULL; - high_ok = text_to_value__ (high_text, &dialog->format, dialog->encoding, - &high_val) != NULL; - ok = low_ok && high_ok && low_val.f <= high_val.f; - if (!ok) - { - err_dialog (_("Incorrect range specification"), GTK_WINDOW (dialog)); - if (low_ok) - value_destroy (&low_val, fmt_var_width (&dialog->format)); - if (high_ok) - value_destroy (&high_val, fmt_var_width (&dialog->format)); - return FALSE; - } - - discrete_text = - g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->discrete))); + assert (var_width == 0); /* Ranges are only for numeric variables */ + + if (!try_missing_value(dialog, low_text, &low_val)) + { + gtk_widget_grab_focus (dialog->low); + return FALSE; + } + if (!try_missing_value (dialog, high_text, &high_val)) + { + gtk_widget_grab_focus (dialog->high); + value_destroy (&low_val, var_width); + return FALSE; + } + if (low_val.f > high_val.f) + { + err_dialog (_("Incorrect range specification"), + GTK_WINDOW (dialog)); + value_destroy (&low_val, var_width); + value_destroy (&high_val, var_width); + gtk_widget_grab_focus (dialog->low); + return FALSE; + } mv_clear (&dialog->mvl); mv_add_range (&dialog->mvl, low_val.f, high_val.f); + value_destroy (&low_val, var_width); + value_destroy (&high_val, var_width); - value_destroy (&low_val, fmt_var_width (&dialog->format)); - value_destroy (&high_val, fmt_var_width (&dialog->format)); + discrete_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->discrete))); - if ( discrete_text && strlen (g_strstrip (discrete_text)) > 0 ) + if (discrete_text && strlen (g_strstrip (discrete_text)) > 0) { union value discrete_val; - if ( !text_to_value__ (discrete_text, - &dialog->format, - dialog->encoding, - &discrete_val)) + if (!try_missing_value (dialog, discrete_text, &discrete_val)) { - err_dialog (_("Incorrect value for variable type"), - GTK_WINDOW (dialog) ); g_free (discrete_text); - value_destroy (&discrete_val, fmt_var_width (&dialog->format)); + gtk_widget_grab_focus (dialog->discrete); return FALSE; } mv_add_value (&dialog->mvl, &discrete_val); - value_destroy (&discrete_val, fmt_var_width (&dialog->format)); + value_destroy (&discrete_val, var_width); } g_free (discrete_text); } - if (gtk_toggle_button_get_active (dialog->button_none)) mv_clear (&dialog->mvl); @@ -325,7 +338,7 @@ discrete (GtkToggleButton *button, gpointer data) gint i; PsppireMissingValDialog *dialog = data; - for (i = 0 ; i < 3 ; ++i ) + for (i = 0 ; i < 3 ; ++i) { gtk_widget_set_sensitive (dialog->mv[i], gtk_toggle_button_get_active (button)); @@ -362,7 +375,9 @@ psppire_missing_val_dialog_constructor (GType type, type, n_properties, properties); dialog = PSPPIRE_MISSING_VAL_DIALOG (obj); - content_area = GTK_CONTAINER (PSPPIRE_DIALOG (dialog)->box); + g_object_set (dialog, "help_page", "Missing-Observations", NULL); + + content_area = GTK_CONTAINER (PSPPIRE_DIALOG (dialog)); xml = builder_new ("missing-val-dialog.ui"); gtk_container_add (GTK_CONTAINER (content_area), get_widget_assert (xml, "missing-values-dialog")); @@ -412,7 +427,11 @@ psppire_missing_val_dialog_set_variable (PsppireMissingValDialog *dialog, if (var != NULL) { - mv_copy (&dialog->mvl, var_get_missing_values (var)); + const struct missing_values *vmv = var_get_missing_values (var); + if (mv_is_empty(vmv)) + mv_init (&dialog->mvl, var_get_width(var)); + else + mv_copy (&dialog->mvl, vmv); dialog->encoding = g_strdup (var_get_encoding (var)); dialog->format = *var_get_print_format (var); } @@ -438,13 +457,13 @@ psppire_missing_val_dialog_set_variable (PsppireMissingValDialog *dialog, if (var == NULL) return; - for (i = 0 ; i < 3 ; ++i ) + for (i = 0 ; i < 3 ; ++i) { gtk_entry_set_text (GTK_ENTRY (dialog->mv[i]), ""); gtk_widget_set_sensitive (dialog->mv[i], FALSE); } - if ( mv_has_range (&dialog->mvl)) + if (mv_has_range (&dialog->mvl)) { union value low, high; gchar *low_text; @@ -460,7 +479,7 @@ psppire_missing_val_dialog_set_variable (PsppireMissingValDialog *dialog, g_free (low_text); g_free (high_text); - if ( mv_has_value (&dialog->mvl)) + if (mv_has_value (&dialog->mvl)) { gchar *text; text = value_to_text__ (*mv_get_value (&dialog->mvl, 0), @@ -475,13 +494,13 @@ psppire_missing_val_dialog_set_variable (PsppireMissingValDialog *dialog, gtk_widget_set_sensitive (dialog->discrete, TRUE); } - else if ( mv_has_value (&dialog->mvl)) + else if (mv_has_value (&dialog->mvl)) { const int n = mv_n_values (&dialog->mvl); - for (i = 0 ; i < 3 ; ++i ) + for (i = 0 ; i < 3 ; ++i) { - if ( i < n) + if (i < n) { gchar *text ; @@ -494,7 +513,7 @@ psppire_missing_val_dialog_set_variable (PsppireMissingValDialog *dialog, } gtk_toggle_button_set_active (dialog->button_discrete, TRUE); } - else if ( mv_is_empty (&dialog->mvl)) + else if (mv_is_empty (&dialog->mvl)) { gtk_toggle_button_set_active (dialog->button_none, TRUE); }