2 PSPPIRE --- A Graphical User Interface for PSPP
3 Copyright (C) 2005, 2006 Free Software Foundation
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 /* This module describes the behaviour of the Missing Values dialog box,
21 used for input of the missing values in the variable sheet */
25 #define _(msgid) gettext (msgid)
26 #define N_(msgid) msgid
30 #include "missing-val-dialog.h"
31 #include <data/missing-values.h>
32 #include <data/variable.h>
33 #include <data/data-in.h>
37 #include <glade/glade.h>
42 /* A simple (sub) dialog box for displaying user input errors */
44 err_dialog (const gchar *msg, GtkWindow *window)
47 GtkWidget *label = gtk_label_new (msg);
50 gtk_dialog_new_with_buttons ("PSPP",
53 GTK_DIALOG_DESTROY_WITH_PARENT |
54 GTK_DIALOG_NO_SEPARATOR,
60 GtkWidget *icon = gtk_image_new_from_stock (GTK_STOCK_DIALOG_ERROR,
61 GTK_ICON_SIZE_DIALOG);
63 g_signal_connect_swapped (dialog,
65 G_CALLBACK (gtk_widget_destroy),
68 hbox = gtk_hbox_new (FALSE, 10);
70 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
73 gtk_box_pack_start (GTK_BOX (hbox), icon, TRUE, FALSE, 10);
74 gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 10);
76 gtk_widget_show_all (dialog);
80 /* Callback which occurs when the OK button is clicked */
82 missing_val_dialog_accept (GtkWidget *w, gpointer data)
84 struct missing_val_dialog *dialog = data;
86 const struct fmt_spec *write_spec = var_get_write_format (dialog->pv);
88 if ( gtk_toggle_button_get_active (dialog->button_discrete))
93 mv_clear (&dialog->mvl);
94 for (i = 0 ; i < 3 ; ++i )
97 g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->mv[i])));
100 if ( !text || strlen (g_strstrip (text)) == 0 )
106 if ( text_to_value (text, &v, *write_spec))
109 mv_add_value (&dialog->mvl, &v);
115 if ( nvals == 0 || badvals > 0 )
117 err_dialog (_("Incorrect value for variable type"),
118 GTK_WINDOW (dialog->window));
123 if (gtk_toggle_button_get_active (dialog->button_range))
125 gchar *discrete_text ;
127 union value low_val ;
128 union value high_val;
129 const gchar *low_text = gtk_entry_get_text (GTK_ENTRY (dialog->low));
130 const gchar *high_text = gtk_entry_get_text (GTK_ENTRY (dialog->high));
132 if ( text_to_value (low_text, &low_val, *write_spec)
134 text_to_value (high_text, &high_val, *write_spec) )
136 if ( low_val.f > high_val.f )
138 err_dialog (_("Incorrect range specification"),
139 GTK_WINDOW (dialog->window));
145 err_dialog (_("Incorrect range specification"),
146 GTK_WINDOW (dialog->window));
151 g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->discrete)));
153 mv_clear (&dialog->mvl);
154 mv_add_num_range (&dialog->mvl, low_val.f, high_val.f);
156 if ( discrete_text && strlen (g_strstrip (discrete_text)) > 0 )
158 union value discrete_val;
159 if ( !text_to_value (discrete_text, &discrete_val,
162 err_dialog (_("Incorrect value for variable type"),
163 GTK_WINDOW (dialog->window) );
164 g_free (discrete_text);
167 mv_add_value (&dialog->mvl, &discrete_val);
169 g_free (discrete_text);
173 if (gtk_toggle_button_get_active (dialog->button_none))
174 mv_clear (&dialog->mvl);
176 var_set_missing_values (dialog->pv, &dialog->mvl);
178 gtk_widget_hide (dialog->window);
182 /* Callback which occurs when the 'discrete' radiobutton is toggled */
184 discrete (GtkToggleButton *button, gpointer data)
187 struct missing_val_dialog *dialog = data;
189 for (i = 0 ; i < 3 ; ++i )
191 gtk_widget_set_sensitive (dialog->mv[i],
192 gtk_toggle_button_get_active (button));
196 /* Callback which occurs when the 'range' radiobutton is toggled */
198 range (GtkToggleButton *button, gpointer data)
200 struct missing_val_dialog *dialog = data;
202 const gboolean active = gtk_toggle_button_get_active (button);
204 gtk_widget_set_sensitive (dialog->low, active);
205 gtk_widget_set_sensitive (dialog->high, active);
206 gtk_widget_set_sensitive (dialog->discrete, active);
211 /* Callback for when the Missing Value dialog is closed using
212 the window delete button.*/
214 on_delete (GtkWidget *w, GdkEvent *e, gpointer data)
216 struct missing_val_dialog *dialog = data;
218 gtk_widget_hide (dialog->window);
224 /* Creates the dialog structure from the xml */
225 struct missing_val_dialog *
226 missing_val_dialog_create (GladeXML *xml)
228 struct missing_val_dialog *dialog = g_malloc (sizeof (*dialog));
232 dialog->window = get_widget_assert (xml, "missing_values_dialog");
234 gtk_window_set_transient_for
235 (GTK_WINDOW (dialog->window),
236 GTK_WINDOW (get_widget_assert (xml, "data_editor")));
239 g_signal_connect_swapped (get_widget_assert (xml, "missing_val_cancel"),
240 "clicked", G_CALLBACK (gtk_widget_hide), dialog->window);
242 g_signal_connect (get_widget_assert (xml, "missing_val_ok"),
243 "clicked", G_CALLBACK (missing_val_dialog_accept), dialog);
245 g_signal_connect (GTK_OBJECT (dialog->window), "delete-event",
246 G_CALLBACK (on_delete), dialog);
248 dialog->mv[0] = get_widget_assert (xml, "mv0");
249 dialog->mv[1] = get_widget_assert (xml, "mv1");
250 dialog->mv[2] = get_widget_assert (xml, "mv2");
252 dialog->low = get_widget_assert (xml, "mv-low");
253 dialog->high = get_widget_assert (xml, "mv-high");
254 dialog->discrete = get_widget_assert (xml, "mv-discrete");
257 dialog->button_none =
258 GTK_TOGGLE_BUTTON (get_widget_assert (xml, "no_missing"));
260 dialog->button_discrete =
261 GTK_TOGGLE_BUTTON (get_widget_assert (xml, "discrete_missing"));
263 dialog->button_range =
264 GTK_TOGGLE_BUTTON (get_widget_assert (xml, "range_missing"));
267 g_signal_connect (G_OBJECT (dialog->button_discrete), "toggled",
268 G_CALLBACK (discrete), dialog);
270 g_signal_connect (G_OBJECT (dialog->button_range), "toggled",
271 G_CALLBACK (range), dialog);
276 /* Shows the dialog box and sets default values */
278 missing_val_dialog_show (struct missing_val_dialog *dialog)
280 const struct fmt_spec *write_spec ;
283 g_return_if_fail (dialog);
284 g_return_if_fail (dialog->pv);
286 mv_copy (&dialog->mvl, var_get_missing_values (dialog->pv));
288 write_spec = var_get_write_format (dialog->pv);
290 /* Blank all entry boxes and make them insensitive */
291 gtk_entry_set_text (GTK_ENTRY (dialog->low), "");
292 gtk_entry_set_text (GTK_ENTRY (dialog->high), "");
293 gtk_entry_set_text (GTK_ENTRY (dialog->discrete), "");
294 gtk_widget_set_sensitive (dialog->low, FALSE);
295 gtk_widget_set_sensitive (dialog->high, FALSE);
296 gtk_widget_set_sensitive (dialog->discrete, FALSE);
298 gtk_widget_set_sensitive (GTK_WIDGET (dialog->button_range),
299 var_is_numeric (dialog->pv));
302 for (i = 0 ; i < 3 ; ++i )
304 gtk_entry_set_text (GTK_ENTRY (dialog->mv[i]), "");
305 gtk_widget_set_sensitive (dialog->mv[i], FALSE);
308 if ( mv_has_range (&dialog->mvl))
310 union value low, high;
313 mv_peek_range (&dialog->mvl, &low.f, &high.f);
315 low_text = value_to_text (low, *write_spec);
316 high_text = value_to_text (high, *write_spec);
318 gtk_entry_set_text (GTK_ENTRY (dialog->low), low_text);
319 gtk_entry_set_text (GTK_ENTRY (dialog->high), high_text);
323 if ( mv_has_value (&dialog->mvl))
327 mv_peek_value (&dialog->mvl, &value, 0);
328 text = value_to_text (value, *write_spec);
329 gtk_entry_set_text (GTK_ENTRY (dialog->discrete), text);
333 gtk_toggle_button_set_active (dialog->button_range, TRUE);
334 gtk_widget_set_sensitive (dialog->low, TRUE);
335 gtk_widget_set_sensitive (dialog->high, TRUE);
336 gtk_widget_set_sensitive (dialog->discrete, TRUE);
339 else if ( mv_has_value (&dialog->mvl))
341 const int n = mv_n_values (&dialog->mvl);
343 for (i = 0 ; i < 3 ; ++i )
350 mv_peek_value (&dialog->mvl, &value, i);
351 text = value_to_text (value, *write_spec);
352 gtk_entry_set_text (GTK_ENTRY (dialog->mv[i]), text);
355 gtk_widget_set_sensitive (dialog->mv[i], TRUE);
357 gtk_toggle_button_set_active (dialog->button_discrete, TRUE);
359 else if ( mv_is_empty (&dialog->mvl))
361 gtk_toggle_button_set_active (dialog->button_none, TRUE);
364 gtk_widget_show (dialog->window);