pspp-sheet-view: Rename GtkTreeSelectMode to PsppSheetSelectMode.
[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   struct string dss;
86
87   ds_init_cstr (&dss, "NPAR TEST\n\t/CHISQUARE=");
88
89   psppire_var_view_append_names_str (PSPPIRE_VAR_VIEW (scd->var_view), 0, &dss);
90
91   if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scd->range_button)))
92     {
93       ds_put_cstr (&dss, "(");
94       
95       ds_put_cstr (&dss, 
96                        gtk_entry_get_text (GTK_ENTRY (scd->value_lower)));
97
98       ds_put_cstr (&dss, ", ");
99
100       ds_put_cstr (&dss,
101                        gtk_entry_get_text (GTK_ENTRY (scd->value_upper)));
102
103       ds_put_cstr (&dss, ")");
104     }
105
106   if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scd->values_button)))
107     {
108       GtkListStore *ls = scd->expected_list;
109       GtkTreeIter iter;
110       gboolean ok;
111
112       ds_put_cstr (&dss, "\n\t");
113       ds_put_cstr (&dss, "/EXPECTED = ");
114
115       
116       for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(ls),
117                                                &iter);
118            ok;
119            ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (ls), &iter))
120         {
121           gdouble v;
122
123           gtk_tree_model_get (GTK_TREE_MODEL (ls), &iter, 0, &v, -1);
124
125           ds_put_c_format (&dss, " %g", v);
126         }
127     }
128
129   ds_put_cstr (&dss, ".\n");
130
131   text = ds_steal_cstr (&dss);
132
133   ds_destroy (&dss);
134
135   return text;
136 }
137
138
139
140 /* Pops up the Chi-Square dialog box */
141 void
142 chisquare_dialog (PsppireDataWindow *dw)
143 {
144   gint response;
145
146   struct chisquare_dialog csd;
147
148   GtkBuilder *xml = builder_new ("chi-square.ui");
149
150   GtkWidget *dialog = get_widget_assert   (xml, "chisquare-dialog");
151
152   GtkWidget *range_table = get_widget_assert   (xml, "range-table");
153
154
155
156   GtkWidget *values_acr = get_widget_assert   (xml, "psppire-acr1");
157   GtkWidget *expected_value_entry =
158     get_widget_assert   (xml, "expected-value-entry");
159
160
161   GtkWidget *dict_view = get_widget_assert   (xml, "dict-view");
162
163   csd.expected_list = gtk_list_store_new (1, G_TYPE_DOUBLE);
164
165   csd.button1 = get_widget_assert   (xml, "radiobutton1");
166   csd.button2 = get_widget_assert   (xml, "radiobutton3");
167   csd.var_view = get_widget_assert   (xml, "variables-treeview");
168
169   csd.range_button = get_widget_assert   (xml, "radiobutton4");
170   csd.value_lower = get_widget_assert   (xml, "entry1");
171   csd.value_upper = get_widget_assert   (xml, "entry2");
172
173   csd.values_button = get_widget_assert   (xml, "radiobutton2");
174
175   gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (dw));
176  
177
178   g_object_get (dw->data_editor, "dictionary", &csd.dict, NULL);
179   g_object_set (dict_view,
180                 "model", csd.dict, 
181                 "predicate", var_is_numeric,
182                 NULL);
183
184
185   g_signal_connect (csd.range_button, "toggled", G_CALLBACK (set_sensitivity_from_toggle), 
186                     range_table);
187
188
189   g_signal_connect (csd.values_button, "toggled", G_CALLBACK (set_sensitivity_from_toggle), 
190                     values_acr);
191
192   g_signal_connect (csd.values_button, "toggled", G_CALLBACK (set_sensitivity_from_toggle), 
193                     expected_value_entry);
194
195
196   psppire_acr_set_entry (PSPPIRE_ACR (values_acr),
197                          GTK_ENTRY (expected_value_entry));
198
199   psppire_acr_set_model(PSPPIRE_ACR (values_acr), csd.expected_list);
200
201   g_signal_connect_swapped (dialog, "refresh", G_CALLBACK (refresh),  &csd);
202
203   psppire_dialog_set_valid_predicate (PSPPIRE_DIALOG (dialog),
204                                       dialog_state_valid, &csd);
205
206   response = psppire_dialog_run (PSPPIRE_DIALOG (dialog));
207
208
209   switch (response)
210     {
211     case GTK_RESPONSE_OK:
212       g_free (execute_syntax_string (dw, generate_syntax (&csd)));
213       break;
214     case PSPPIRE_RESPONSE_PASTE:
215       g_free (paste_syntax_to_window (generate_syntax (&csd)));
216       break;
217     default:
218       break;
219     }
220
221   g_object_unref (csd.expected_list);
222   g_object_unref (xml);
223 }