Merge 'master' into 'psppsheet'.
[pspp] / src / ui / gui / chi-square-dialog.c
1 /* PSPPIRE - a graphical user interface for PSPP.
2    Copyright (C) 2010, 2011, 2012  Free Software Foundation
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18
19 #include "chi-square-dialog.h"
20
21 #include "psppire-dialog.h"
22 #include "psppire-var-view.h"
23 #include "psppire-acr.h"
24 #include "dialog-common.h"
25
26 #include "builder-wrapper.h"
27 #include "executor.h"
28 #include "helper.h"
29
30 #include <gtk/gtk.h>
31
32 struct chisquare_dialog
33 {
34   PsppireDict *dict;
35   GtkWidget *var_view;
36
37   GtkWidget *button1;
38   GtkWidget *button2;
39
40   GtkWidget *range_button;
41   GtkWidget *value_lower;
42   GtkWidget *value_upper;
43
44   GtkWidget *values_button;
45
46   GtkListStore *expected_list;
47 };
48
49 static gboolean
50 dialog_state_valid (gpointer data)
51 {
52   struct chisquare_dialog *csd = data;
53
54   GtkTreeModel *vars =
55     gtk_tree_view_get_model (GTK_TREE_VIEW (csd->var_view));
56
57   GtkTreeIter notused;
58
59   if ( !gtk_tree_model_get_iter_first (vars, &notused) )
60     return FALSE;
61
62   return TRUE;
63 }
64
65
66 static void
67 refresh (struct chisquare_dialog *csd)
68 {
69   GtkTreeModel *liststore =
70     gtk_tree_view_get_model (GTK_TREE_VIEW (csd->var_view));
71
72   gtk_list_store_clear (GTK_LIST_STORE (liststore));
73
74   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (csd->button1), TRUE);
75
76   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (csd->button2), TRUE);
77 }
78
79
80
81 static char *
82 generate_syntax (const struct chisquare_dialog *scd)
83 {
84   gchar *text;
85   GString *string;
86
87
88   string = g_string_new ("NPAR TEST\n\t/CHISQUARE=");
89
90   psppire_var_view_append_names (PSPPIRE_VAR_VIEW (scd->var_view), 0, string);
91
92
93   if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scd->range_button)))
94     {
95       g_string_append (string, "(");
96       
97       g_string_append (string, 
98                        gtk_entry_get_text (GTK_ENTRY (scd->value_lower)));
99
100       g_string_append (string, ", ");
101
102       g_string_append (string,
103                        gtk_entry_get_text (GTK_ENTRY (scd->value_upper)));
104
105       g_string_append (string, ")");
106     }
107
108
109
110
111   if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scd->values_button)))
112     {
113       GtkListStore *ls = scd->expected_list;
114       GtkTreeIter iter;
115       gboolean ok;
116
117       g_string_append (string, "\n\t");
118       g_string_append (string, "/EXPECTED = ");
119
120       
121       for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(ls),
122                                                &iter);
123            ok;
124            ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (ls), &iter))
125         {
126           gdouble v;
127
128           gtk_tree_model_get (GTK_TREE_MODEL (ls), &iter, 0, &v, -1);
129
130           g_string_append_printf (string, " %g", v);
131         }
132
133
134
135     }
136
137   g_string_append (string, ".\n");
138
139   text = string->str;
140
141   g_string_free (string, FALSE);
142
143   return text;
144 }
145
146
147
148 /* Pops up the Chi-Square dialog box */
149 void
150 chisquare_dialog (PsppireDataWindow *dw)
151 {
152   gint response;
153
154   struct chisquare_dialog csd;
155
156   GtkBuilder *xml = builder_new ("chi-square.ui");
157
158   GtkWidget *dialog = get_widget_assert   (xml, "chisquare-dialog");
159
160   GtkWidget *range_table = get_widget_assert   (xml, "range-table");
161
162
163
164   GtkWidget *values_acr = get_widget_assert   (xml, "psppire-acr1");
165   GtkWidget *expected_value_entry =
166     get_widget_assert   (xml, "expected-value-entry");
167
168
169   GtkWidget *dict_view = get_widget_assert   (xml, "dict-view");
170
171   csd.expected_list = gtk_list_store_new (1, G_TYPE_DOUBLE);
172
173   csd.button1 = get_widget_assert   (xml, "radiobutton1");
174   csd.button2 = get_widget_assert   (xml, "radiobutton3");
175   csd.var_view = get_widget_assert   (xml, "variables-treeview");
176
177   csd.range_button = get_widget_assert   (xml, "radiobutton4");
178   csd.value_lower = get_widget_assert   (xml, "entry1");
179   csd.value_upper = get_widget_assert   (xml, "entry2");
180
181   csd.values_button = get_widget_assert   (xml, "radiobutton2");
182
183   gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (dw));
184  
185
186   g_object_get (dw->data_editor, "dictionary", &csd.dict, NULL);
187   g_object_set (dict_view,
188                 "model", csd.dict, 
189                 "predicate", var_is_numeric,
190                 NULL);
191
192
193   g_signal_connect (csd.range_button, "toggled", G_CALLBACK (set_sensitivity_from_toggle), 
194                     range_table);
195
196
197   g_signal_connect (csd.values_button, "toggled", G_CALLBACK (set_sensitivity_from_toggle), 
198                     values_acr);
199
200   g_signal_connect (csd.values_button, "toggled", G_CALLBACK (set_sensitivity_from_toggle), 
201                     expected_value_entry);
202
203
204   psppire_acr_set_entry (PSPPIRE_ACR (values_acr),
205                          GTK_ENTRY (expected_value_entry));
206
207   psppire_acr_set_model(PSPPIRE_ACR (values_acr), csd.expected_list);
208
209   g_signal_connect_swapped (dialog, "refresh", G_CALLBACK (refresh),  &csd);
210
211   psppire_dialog_set_valid_predicate (PSPPIRE_DIALOG (dialog),
212                                       dialog_state_valid, &csd);
213
214   response = psppire_dialog_run (PSPPIRE_DIALOG (dialog));
215
216
217   switch (response)
218     {
219     case GTK_RESPONSE_OK:
220       g_free (execute_syntax_string (dw, generate_syntax (&csd)));
221       break;
222     case PSPPIRE_RESPONSE_PASTE:
223       g_free (paste_syntax_to_window (generate_syntax (&csd)));
224       break;
225     default:
226       break;
227     }
228
229   g_object_unref (csd.expected_list);
230   g_object_unref (xml);
231 }