2 PSPPIRE --- A Graphical User Interface for PSPP
3 Copyright (C) 2005, 2006 Free Software Foundation
4 Written by John Darrington
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 /* This module describes the behaviour of the Missing Values dialog box,
22 used for input of the missing values in the variable sheet */
26 #define _(msgid) gettext (msgid)
27 #define N_(msgid) msgid
31 #include "missing-val-dialog.h"
32 #include <data/missing-values.h>
33 #include <data/variable.h>
34 #include <data/data-in.h>
35 #include "psppire-variable.h"
38 #include <glade/glade.h>
43 /* A simple (sub) dialog box for displaying user input errors */
45 err_dialog(const gchar *msg, GtkWindow *window)
48 GtkWidget *label = gtk_label_new (msg);
51 gtk_dialog_new_with_buttons ("PSPP",
54 GTK_DIALOG_DESTROY_WITH_PARENT |
55 GTK_DIALOG_NO_SEPARATOR,
61 GtkWidget *icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_ERROR,
62 GTK_ICON_SIZE_DIALOG);
64 g_signal_connect_swapped (dialog,
66 G_CALLBACK (gtk_widget_destroy),
69 hbox = gtk_hbox_new(FALSE, 10);
71 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
74 gtk_box_pack_start(GTK_BOX(hbox), icon, TRUE, FALSE, 10);
75 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 10);
77 gtk_widget_show_all (dialog);
81 /* Callback which occurs when the OK button is clicked */
83 missing_val_dialog_accept(GtkWidget *w, gpointer data)
85 struct missing_val_dialog *dialog = data;
87 const struct fmt_spec *write_spec = psppire_variable_get_write_spec(dialog->pv);
89 if ( gtk_toggle_button_get_active(dialog->button_discrete))
94 mv_set_type(&dialog->mvl, MV_NONE);
95 for(i = 0 ; i < 3 ; ++i )
98 g_strdup(gtk_entry_get_text(GTK_ENTRY(dialog->mv[i])));
101 if ( !text || strlen(g_strstrip(text)) == 0 )
107 if ( text_to_value(text, &v, *write_spec))
110 mv_add_value (&dialog->mvl, &v);
116 if ( nvals == 0 || badvals > 0 )
118 err_dialog(_("Incorrect value for variable type"),
119 GTK_WINDOW(dialog->window));
124 if (gtk_toggle_button_get_active(dialog->button_range))
126 gchar *discrete_text ;
128 union value low_val ;
129 union value high_val;
130 const gchar *low_text = gtk_entry_get_text(GTK_ENTRY(dialog->low));
131 const gchar *high_text = gtk_entry_get_text(GTK_ENTRY(dialog->high));
133 if ( text_to_value(low_text, &low_val, *write_spec)
135 text_to_value(high_text, &high_val, *write_spec) )
137 if ( low_val.f > high_val.f )
139 err_dialog(_("Incorrect range specification"),
140 GTK_WINDOW(dialog->window));
146 err_dialog(_("Incorrect range specification"),
147 GTK_WINDOW(dialog->window));
152 g_strdup(gtk_entry_get_text(GTK_ENTRY(dialog->discrete)));
154 mv_set_type(&dialog->mvl, MV_NONE);
155 mv_add_num_range(&dialog->mvl, low_val.f, high_val.f);
157 if ( discrete_text && strlen(g_strstrip(discrete_text)) > 0 )
159 union value discrete_val;
160 if ( !text_to_value(discrete_text, &discrete_val,
163 err_dialog(_("Incorrect value for variable type"),
164 GTK_WINDOW(dialog->window) );
165 g_free(discrete_text);
168 mv_add_value(&dialog->mvl, &discrete_val);
170 g_free(discrete_text);
174 if (gtk_toggle_button_get_active(dialog->button_none))
175 mv_set_type(&dialog->mvl, MV_NONE);
177 psppire_variable_set_missing(dialog->pv, &dialog->mvl);
179 gtk_widget_hide(dialog->window);
183 /* Callback which occurs when the 'discrete' radiobutton is toggled */
185 discrete(GtkToggleButton *button, gpointer data)
188 struct missing_val_dialog *dialog = data;
190 for(i = 0 ; i < 3 ; ++i )
192 gtk_widget_set_sensitive(dialog->mv[i],
193 gtk_toggle_button_get_active(button));
197 /* Callback which occurs when the 'range' radiobutton is toggled */
199 range(GtkToggleButton *button, gpointer data)
201 struct missing_val_dialog *dialog = data;
203 const gboolean active = gtk_toggle_button_get_active (button);
205 gtk_widget_set_sensitive(dialog->low, active);
206 gtk_widget_set_sensitive(dialog->high, active);
207 gtk_widget_set_sensitive(dialog->discrete, active);
211 /* Creates the dialog structure from the xml */
212 struct missing_val_dialog *
213 missing_val_dialog_create(GladeXML *xml)
215 struct missing_val_dialog *dialog = g_malloc(sizeof(*dialog));
217 dialog->window = get_widget_assert(xml, "missing_values_dialog");
219 gtk_window_set_transient_for
220 (GTK_WINDOW(dialog->window),
221 GTK_WINDOW(get_widget_assert(xml, "data_editor")));
224 g_signal_connect_swapped(get_widget_assert(xml, "missing_val_cancel"),
225 "clicked", G_CALLBACK(gtk_widget_hide), dialog->window);
227 g_signal_connect(get_widget_assert(xml, "missing_val_ok"),
228 "clicked", G_CALLBACK(missing_val_dialog_accept), dialog);
231 dialog->mv[0] = get_widget_assert(xml, "mv0");
232 dialog->mv[1] = get_widget_assert(xml, "mv1");
233 dialog->mv[2] = get_widget_assert(xml, "mv2");
235 dialog->low = get_widget_assert(xml, "mv-low");
236 dialog->high = get_widget_assert(xml, "mv-high");
237 dialog->discrete = get_widget_assert(xml, "mv-discrete");
240 dialog->button_none =
241 GTK_TOGGLE_BUTTON(get_widget_assert(xml, "no_missing"));
243 dialog->button_discrete =
244 GTK_TOGGLE_BUTTON(get_widget_assert(xml, "discrete_missing"));
246 dialog->button_range =
247 GTK_TOGGLE_BUTTON(get_widget_assert(xml, "range_missing"));
250 g_signal_connect(G_OBJECT(dialog->button_discrete), "toggled",
251 G_CALLBACK(discrete), dialog);
253 g_signal_connect(G_OBJECT(dialog->button_range), "toggled",
254 G_CALLBACK(range), dialog);
259 /* Shows the dialog box and sets default values */
261 missing_val_dialog_show(struct missing_val_dialog *dialog)
263 const struct fmt_spec *write_spec ;
266 g_return_if_fail(dialog);
267 g_return_if_fail(dialog->pv);
269 mv_copy (&dialog->mvl, psppire_variable_get_missing(dialog->pv));
271 write_spec = psppire_variable_get_write_spec(dialog->pv);
273 /* Blank all entry boxes and make them insensitive */
274 gtk_entry_set_text(GTK_ENTRY(dialog->low), "");
275 gtk_entry_set_text(GTK_ENTRY(dialog->high), "");
276 gtk_entry_set_text(GTK_ENTRY(dialog->discrete), "");
277 gtk_widget_set_sensitive(dialog->low, FALSE);
278 gtk_widget_set_sensitive(dialog->high, FALSE);
279 gtk_widget_set_sensitive(dialog->discrete, FALSE);
281 gtk_widget_set_sensitive(GTK_WIDGET(dialog->button_range),
282 psppire_variable_get_type(dialog->pv) == NUMERIC);
284 for(i = 0 ; i < 3 ; ++i )
286 gtk_entry_set_text(GTK_ENTRY(dialog->mv[i]), "");
287 gtk_widget_set_sensitive(dialog->mv[i], FALSE);
290 if ( mv_has_range (&dialog->mvl))
292 union value low, high;
295 mv_peek_range(&dialog->mvl, &low.f, &high.f);
297 low_text = value_to_text(low, *write_spec);
298 high_text = value_to_text(high, *write_spec);
300 gtk_entry_set_text(GTK_ENTRY(dialog->low), low_text);
301 gtk_entry_set_text(GTK_ENTRY(dialog->high), high_text);
305 if ( mv_has_value(&dialog->mvl))
309 mv_peek_value(&dialog->mvl, &value, 0);
310 text = value_to_text(value, *write_spec);
311 gtk_entry_set_text(GTK_ENTRY(dialog->discrete), text);
315 gtk_toggle_button_set_active(dialog->button_range, TRUE);
316 gtk_widget_set_sensitive(dialog->low, TRUE);
317 gtk_widget_set_sensitive(dialog->high, TRUE);
318 gtk_widget_set_sensitive(dialog->discrete, TRUE);
321 else if ( mv_has_value (&dialog->mvl))
323 const int n = mv_n_values (&dialog->mvl);
325 for(i = 0 ; i < 3 ; ++i )
332 mv_peek_value(&dialog->mvl, &value, i);
333 text = value_to_text(value, *write_spec);
334 gtk_entry_set_text(GTK_ENTRY(dialog->mv[i]), text);
337 gtk_widget_set_sensitive(dialog->mv[i], TRUE);
339 gtk_toggle_button_set_active(dialog->button_discrete, TRUE);
341 else if ( mv_is_empty (&dialog->mvl))
343 gtk_toggle_button_set_active(dialog->button_none, TRUE);
346 gtk_widget_show(dialog->window);