2 PSPPIRE --- A Graphical User Interface for PSPP
3 Copyright (C) 2007 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
22 #include "select-cases-dialog.h"
24 #include <glade/glade.h>
26 #include "psppire-dialog.h"
27 #include "data-editor.h"
28 #include "dialog-common.h"
29 #include "dict-display.h"
30 #include "widget-io.h"
31 #include <language/syntax-string-source.h>
32 #include "syntax-editor.h"
36 #define _(msgid) gettext (msgid)
37 #define N_(msgid) msgid
41 /* FIXME: These shouldn't be here */
42 #include <gtksheet/gtksheet.h>
43 #include "psppire-data-store.h"
46 struct select_cases_dialog
48 /* The XML that created the dialog */
51 GtkWidget *spinbutton ;
52 GtkWidget *spinbutton1 ;
53 GtkWidget *spinbutton2 ;
58 PsppireDataStore *data_store;
61 static gchar * generate_syntax (const struct select_cases_dialog *scd);
65 set_sensitivity_from_toggle (GtkToggleButton *togglebutton, gpointer data)
68 gboolean active = gtk_toggle_button_get_active (togglebutton);
70 gtk_widget_set_sensitive (w, active);
74 set_sensitivity_from_toggle_invert (GtkToggleButton *togglebutton,
78 gboolean active = gtk_toggle_button_get_active (togglebutton);
80 gtk_widget_set_sensitive (w, !active);
85 static const gchar label1[]=N_("Approximately %3d%% of all cases.");
86 static const gchar label2[]=N_("Exactly %3d cases from the first %3d cases.");
90 sample_subdialog (GtkButton *b, gpointer data)
93 struct select_cases_dialog *scd = data;
95 gint case_count = psppire_data_store_get_case_count (scd->data_store);
97 GtkWidget *parent_dialog = get_widget_assert (scd->xml,
98 "select-cases-dialog");
99 GtkWidget *dialog = get_widget_assert (scd->xml,
100 "select-cases-random-sample-dialog");
101 GtkWidget *percent = get_widget_assert (scd->xml,
102 "radiobutton-sample-percent");
103 GtkWidget *sample_n_cases = get_widget_assert (scd->xml,
104 "radiobutton-sample-n-cases");
105 GtkWidget *table = get_widget_assert (scd->xml,
106 "select-cases-random-sample-table");
110 scd->hbox1 = widget_scanf (gettext (label1), &scd->spinbutton);
112 gtk_widget_show (scd->hbox1);
114 gtk_table_attach_defaults (GTK_TABLE (table),
115 scd->hbox1, 1, 2, 0, 1);
117 g_signal_connect (G_OBJECT (percent), "toggled",
118 G_CALLBACK (set_sensitivity_from_toggle), scd->hbox1);
120 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (percent), TRUE);
127 widget_scanf (gettext (label2), &scd->spinbutton1, &scd->spinbutton2);
129 gtk_spin_button_set_range (GTK_SPIN_BUTTON (scd->spinbutton1),
132 gtk_spin_button_set_range (GTK_SPIN_BUTTON (scd->spinbutton2),
135 gtk_widget_show (scd->hbox2);
136 gtk_widget_set_sensitive (scd->hbox2, FALSE);
138 gtk_table_attach_defaults (GTK_TABLE (table),
139 scd->hbox2, 1, 2, 1, 2);
141 g_signal_connect (G_OBJECT (sample_n_cases), "toggled",
142 G_CALLBACK (set_sensitivity_from_toggle), scd->hbox2);
144 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_n_cases), FALSE);
148 gtk_window_set_transient_for (GTK_WINDOW (dialog),
149 GTK_WINDOW (parent_dialog));
151 response = psppire_dialog_run (PSPPIRE_DIALOG (dialog));
153 if ( response != PSPPIRE_RESPONSE_CONTINUE)
155 g_signal_handlers_disconnect_by_func
157 G_CALLBACK (set_sensitivity_from_toggle),
160 g_signal_handlers_disconnect_by_func
161 (G_OBJECT (sample_n_cases),
162 G_CALLBACK (set_sensitivity_from_toggle),
165 gtk_widget_destroy(scd->hbox1);
166 gtk_widget_destroy(scd->hbox2);
167 scd->hbox1 = scd->hbox2 = NULL;
172 GtkWidget *l0 = get_widget_assert (scd->xml, "random-sample-label");
174 if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (percent)))
176 text = widget_printf (gettext(label1), scd->spinbutton);
177 gtk_label_set_text (GTK_LABEL (l0), text);
182 widget_printf (gettext(label2), scd->spinbutton1, scd->spinbutton2);
183 gtk_label_set_text (GTK_LABEL (l0), text);
192 range_subdialog (GtkButton *b, gpointer data)
195 struct select_cases_dialog *scd = data;
197 gint n_cases = psppire_data_store_get_case_count (scd->data_store);
199 GtkWidget *parent_dialog = get_widget_assert (scd->xml,
200 "select-cases-dialog");
202 GtkWidget *dialog = get_widget_assert (scd->xml,
203 "select-cases-range-dialog");
205 GtkWidget *first = get_widget_assert (scd->xml,
206 "range-dialog-first");
208 GtkWidget *last = get_widget_assert (scd->xml,
209 "range-dialog-last");
212 gtk_spin_button_set_range (GTK_SPIN_BUTTON (last), 1, n_cases);
214 gtk_spin_button_set_range (GTK_SPIN_BUTTON (first), 1, n_cases);
216 gtk_window_set_transient_for (GTK_WINDOW (dialog),
217 GTK_WINDOW (parent_dialog));
220 response = psppire_dialog_run (PSPPIRE_DIALOG (dialog));
221 if ( response == PSPPIRE_RESPONSE_CONTINUE)
223 GtkWidget *first = get_widget_assert (scd->xml, "range-dialog-first");
224 GtkWidget *last = get_widget_assert (scd->xml, "range-dialog-last");
225 GtkWidget *l1 = get_widget_assert (scd->xml, "range-sample-label");
226 gchar *text = widget_printf (_("%d thru %d"), first, last);
228 gtk_label_set_text (GTK_LABEL (l1), text);
235 set_radiobutton (GtkWidget *button, gpointer data)
237 GtkToggleButton *toggle = data;
238 gtk_toggle_button_set_active (toggle, TRUE);
241 /* Pops up the Select Cases dialog box */
243 select_cases_dialog (GObject *o, gpointer data)
246 struct select_cases_dialog scd = {0,0,0,0,0,0};
248 struct data_editor *de = data;
249 GtkWidget *entry = NULL;
250 GtkWidget *selector ;
251 GtkWidget *button_range;
252 GtkWidget *button_sample;
254 scd.xml = XML_NEW ("psppire.glade");
256 g_object_get (de->data_editor, "data-store", &scd.data_store, NULL);
258 button_range = get_widget_assert (scd.xml, "button-range");
259 button_sample = get_widget_assert (scd.xml, "button-sample");
260 entry = get_widget_assert (scd.xml, "filter-variable-entry");
261 selector = get_widget_assert (scd.xml, "psppire-selector-filter");
264 GtkWidget *button_if =
265 get_widget_assert (scd.xml, "button-if");
267 GtkWidget *radiobutton_if =
268 get_widget_assert (scd.xml, "radiobutton-if");
270 GtkWidget *radiobutton_all =
271 get_widget_assert (scd.xml, "radiobutton-all");
273 GtkWidget *radiobutton_sample =
274 get_widget_assert (scd.xml, "radiobutton-sample");
276 GtkWidget *radiobutton_range =
277 get_widget_assert (scd.xml, "radiobutton-range");
279 GtkWidget *radiobutton_filter =
280 get_widget_assert (scd.xml, "radiobutton-filter-variable");
282 GtkWidget *range_label =
283 get_widget_assert (scd.xml, "range-sample-label");
285 GtkWidget *sample_label =
286 get_widget_assert (scd.xml, "random-sample-label");
288 g_signal_connect (radiobutton_all, "toggled",
289 G_CALLBACK (set_sensitivity_from_toggle_invert),
290 get_widget_assert (scd.xml, "filter-delete-button-box")
293 g_signal_connect (button_if, "clicked",
294 G_CALLBACK (set_radiobutton), radiobutton_if);
296 g_signal_connect (button_sample, "clicked",
297 G_CALLBACK (set_radiobutton), radiobutton_sample);
299 g_signal_connect (button_range, "clicked",
300 G_CALLBACK (set_radiobutton), radiobutton_range);
302 g_signal_connect (selector, "clicked",
303 G_CALLBACK (set_radiobutton), radiobutton_filter);
305 g_signal_connect (selector, "selected",
306 G_CALLBACK (set_radiobutton), radiobutton_filter);
308 g_signal_connect (radiobutton_range, "toggled",
309 G_CALLBACK (set_sensitivity_from_toggle),
313 g_signal_connect (radiobutton_sample, "toggled",
314 G_CALLBACK (set_sensitivity_from_toggle),
318 g_signal_connect (radiobutton_filter, "toggled",
319 G_CALLBACK (set_sensitivity_from_toggle),
326 dialog = get_widget_assert (scd.xml, "select-cases-dialog");
327 gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
330 GtkWidget *source = get_widget_assert (scd.xml, "select-cases-treeview");
332 attach_dictionary_to_treeview (GTK_TREE_VIEW (source),
333 scd.data_store->dict,
334 GTK_SELECTION_SINGLE, NULL);
336 psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector),
339 insert_source_row_into_entry,
340 is_currently_in_entry,
346 g_signal_connect (button_range,
347 "clicked", G_CALLBACK (range_subdialog), &scd);
350 g_signal_connect (button_sample,
351 "clicked", G_CALLBACK (sample_subdialog), &scd);
354 response = psppire_dialog_run (PSPPIRE_DIALOG (dialog));
358 case GTK_RESPONSE_OK:
360 gchar *syntax = generate_syntax (&scd);
361 struct getl_interface *sss = create_syntax_string_source (syntax);
362 execute_syntax (sss);
367 case PSPPIRE_RESPONSE_PASTE:
369 gchar *syntax = generate_syntax (&scd);
371 struct syntax_editor *se =
372 (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
374 gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
383 g_object_unref (scd.xml);
388 generate_syntax (const struct select_cases_dialog *scd)
391 GString *string = NULL;
393 if ( gtk_toggle_button_get_active
394 (GTK_TOGGLE_BUTTON (get_widget_assert (scd->xml,
395 "radiobutton-all"))))
397 return strdup ("\n");
400 string = g_string_new ("");
402 if ( gtk_toggle_button_get_active
403 (GTK_TOGGLE_BUTTON (get_widget_assert (scd->xml,
404 "radiobutton-sample"))))
406 GtkWidget *random_sample =
407 get_widget_assert (scd->xml,
408 "radiobutton-sample-percent");
410 g_string_append (string, "SAMPLE ");
412 if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (random_sample)))
414 const double percentage =
415 gtk_spin_button_get_value (GTK_SPIN_BUTTON (scd->spinbutton));
416 g_string_append_printf (string, "%g.", percentage / 100.0);
421 gtk_spin_button_get_value (GTK_SPIN_BUTTON (scd->spinbutton1));
422 const gint from_n_cases =
423 gtk_spin_button_get_value (GTK_SPIN_BUTTON (scd->spinbutton2));
425 g_string_append_printf (string, "%d FROM %d .", n_cases, from_n_cases);
429 else if ( gtk_toggle_button_get_active
430 (GTK_TOGGLE_BUTTON (get_widget_assert (scd->xml,
431 "radiobutton-range"))))
433 GtkSpinButton *first =
434 GTK_SPIN_BUTTON (get_widget_assert (scd->xml,
435 "range-dialog-first"));
437 GtkSpinButton *last =
438 GTK_SPIN_BUTTON (get_widget_assert (scd->xml,
439 "range-dialog-last"));
441 g_string_append_printf (string,
442 "COMPUTE filter_$ = ($CASENUM >= %ld "
443 "AND $CASENUM <= %ld).\n",
444 (long) gtk_spin_button_get_value (first),
445 (long) gtk_spin_button_get_value (last)
447 g_string_append (string, "EXECUTE.\n");
448 g_string_append_printf (string, "SELECT IF filter_$.\n");
451 else if ( gtk_toggle_button_get_active
453 (get_widget_assert (scd->xml,
454 "radiobutton-filter-variable"))))
457 GTK_ENTRY (get_widget_assert (scd->xml,
458 "filter-variable-entry"));
460 g_string_append_printf (string, "SELECT IF (%s <> 0).",
461 gtk_entry_get_text (entry));
465 g_string_append (string, "\n");
468 /* Are we filtering or deleting ? */
469 if ( gtk_toggle_button_get_active
470 (GTK_TOGGLE_BUTTON (get_widget_assert (scd->xml,
471 "radiobutton-delete"))))
473 g_string_append (string, "EXECUTE.\n");
475 if ( gtk_toggle_button_get_active
476 (GTK_TOGGLE_BUTTON (get_widget_assert (scd->xml,
477 "radiobutton-range"))))
479 g_string_append (string, "DELETE VARIABLES filter_$.\n");
485 g_string_free (string, FALSE);