Fixed bug reporting the significance of paired value t-test.
[pspp-builds.git] / src / ui / gui / dialog-common.c
1 /* PSPPIRE - a graphical user interface for PSPP.
2    Copyright (C) 2007  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 "dialog-common.h"
20
21 #include "psppire-var-ptr.h"
22
23 #include "helper.h"
24
25
26 /* Append the names of selected variables to STRING.
27    TREEVIEW is the treeview containing the variables.
28    COLUMN is the column in the treeview containing the variables.
29    DICT is the dictionary for those variables.
30 */
31 gint
32 append_variable_names (GString *string,
33                        PsppireDict *dict, GtkTreeView *treeview, gint column)
34 {
35   gint n_vars = 0;
36   GtkTreeIter iter;
37
38   GtkTreeModel *list_store =
39     gtk_tree_view_get_model (treeview);
40
41   if ( gtk_tree_model_get_iter_first (list_store, &iter) )
42     {
43       do
44         {
45           GValue value = {0};
46           struct variable *var = NULL;
47           GtkTreePath *path = gtk_tree_model_get_path (list_store, &iter);
48
49           gtk_tree_model_get_value (list_store, &iter, column, &value);
50
51           /* FIXME:  G_TYPE_INT should be deprecated.
52              As well as being simpler, it'd be unecessary to pass dict */
53           if ( G_VALUE_TYPE (&value) == G_TYPE_INT )
54           var = psppire_dict_get_variable (dict, g_value_get_int (&value));
55
56           else if ( G_VALUE_TYPE (&value) == PSPPIRE_VAR_PTR_TYPE)
57             var = g_value_get_boxed (&value);
58
59           else
60             g_critical ("Unsupported type \"%s\", in variable name treeview.",
61                         G_VALUE_TYPE_NAME (&value));
62
63           g_value_unset (&value);
64
65           g_string_append (string, " ");
66           g_string_append (string, var_get_name (var));
67
68           gtk_tree_path_free (path);
69           n_vars++;
70         }
71       while (gtk_tree_model_iter_next (list_store, &iter));
72     }
73
74   return n_vars;
75 }
76
77
78
79 struct variable *
80 get_selected_variable (GtkTreeModel *treemodel,
81                        GtkTreeIter *iter,
82                        PsppireDict *dict)
83 {
84   struct variable *var;
85   GValue value = {0};
86
87   GtkTreePath *path = gtk_tree_model_get_path (treemodel, iter);
88
89   gtk_tree_model_get_value (treemodel, iter, 0, &value);
90
91   gtk_tree_path_free (path);
92
93   var =  psppire_dict_get_variable (dict, g_value_get_int (&value));
94
95   g_value_unset (&value);
96
97   return var;
98 }
99
100
101
102
103 /* A (*GtkTreeCellDataFunc) function.
104    This function expects TREEMODEL to hold G_TYPE_INT.  The ints it holds
105    are the indices of the variables in the dictionary, which DATA points to.
106    It renders the name of the variable into CELL.
107 */
108 void
109 cell_var_name (GtkTreeViewColumn *tree_column,
110                GtkCellRenderer *cell,
111                GtkTreeModel *tree_model,
112                GtkTreeIter *iter,
113                gpointer data)
114 {
115   PsppireDict *dict = data;
116   struct variable *var;
117   gchar *name;
118
119   var = get_selected_variable (tree_model, iter, dict);
120
121   name = pspp_locale_to_utf8 (var_get_name (var), -1, NULL);
122   g_object_set (cell, "text", name, NULL);
123   g_free (name);
124 }
125
126
127
128 /* Set a model for DEST, which is an GtkListStore of g_int's
129    whose values are the indices into DICT */
130 void
131 set_dest_model (GtkTreeView *dest, PsppireDict *dict)
132 {
133   GtkTreeViewColumn *col;
134   GtkListStore *dest_list = gtk_list_store_new (1, G_TYPE_INT);
135   GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
136
137   gtk_tree_view_set_model (GTK_TREE_VIEW (dest), GTK_TREE_MODEL (dest_list));
138
139   col = gtk_tree_view_column_new_with_attributes ("Var",
140                                                   renderer,
141                                                   "text",
142                                                   0,
143                                                   NULL);
144
145   gtk_tree_view_column_set_cell_data_func (col, renderer,
146                                            cell_var_name,
147                                            dict, 0);
148
149   /* FIXME: make this a value in terms of character widths */
150   g_object_set (col, "min-width",  100, NULL);
151
152   gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED);
153
154   gtk_tree_view_append_column (GTK_TREE_VIEW (dest), col);
155 }
156
157
158
159 /* Returns FALSE if the variables represented by the union of the rows
160    currently selected by SOURCE widget, and contents of the DEST
161    widget, are of different types.
162
163    In other words, this function when passed as the argument to
164    psppire_selector_set_allow, ensures that the selector selects only
165    string  variables, or only numeric variables, not a mixture.
166 */
167 gboolean
168 homogeneous_types (GtkWidget *source, GtkWidget *dest)
169 {
170   gboolean ok;
171   GtkTreeIter iter;
172   gboolean retval = TRUE;
173
174   GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (source));
175
176   PsppireDict *dict;
177   GtkTreeSelection *selection;
178   enum val_type type = -1;
179   GList *list, *l;
180
181   while (GTK_IS_TREE_MODEL_FILTER (model))
182     {
183       model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
184     }
185
186   dict = PSPPIRE_DICT (model);
187
188   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (source));
189
190   list = gtk_tree_selection_get_selected_rows (selection, &model);
191
192   /* Iterate through the selection of the source treeview */
193   for (l = list; l ; l = l->next)
194     {
195       GtkTreePath *path = l->data;
196
197       GtkTreePath *fpath =
198         gtk_tree_model_filter_convert_path_to_child_path (GTK_TREE_MODEL_FILTER (model), path);
199
200       gint *idx = gtk_tree_path_get_indices (fpath);
201
202       const struct variable *v = psppire_dict_get_variable (dict, idx[0]);
203
204       gtk_tree_path_free (fpath);
205
206       if ( type != -1 )
207         {
208           if ( var_get_type (v) != type )
209             {
210               retval = FALSE;
211               break;
212             }
213         }
214
215       type = var_get_type (v);
216     }
217
218   g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
219   g_list_free (list);
220
221   if ( retval == FALSE )
222     return FALSE;
223
224   /* now deal with the dest widget */
225   model = gtk_tree_view_get_model (GTK_TREE_VIEW (dest));
226
227   for (ok = gtk_tree_model_get_iter_first (model, &iter);
228        ok;
229        ok = gtk_tree_model_iter_next (model, &iter))
230     {
231       gint idx;
232       const struct variable *v;
233       gtk_tree_model_get (model, &iter, 0, &idx, -1);
234
235       v = psppire_dict_get_variable (dict, idx);
236
237       if ( type != -1 )
238         {
239           if ( var_get_type (v) != type )
240             {
241               retval = FALSE;
242               break;
243             }
244         }
245
246       type = var_get_type (v);
247     }
248
249
250   return retval;
251 }
252
253
254
255 /* Returns true iff the variable selected by SOURCE is numeric */
256 gboolean
257 numeric_only (GtkWidget *source, GtkWidget *dest)
258 {
259   gboolean retval = TRUE;
260
261   GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (source));
262
263   PsppireDict *dict;
264   GtkTreeSelection *selection;
265   GList *list, *l;
266
267   while (GTK_IS_TREE_MODEL_FILTER (model))
268     {
269       model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
270     }
271
272   dict = PSPPIRE_DICT (model);
273
274   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (source));
275
276   list = gtk_tree_selection_get_selected_rows (selection, &model);
277
278   /* Iterate through the selection of the source treeview */
279   for (l = list; l ; l = l->next)
280     {
281       GtkTreePath *path = l->data;
282       GtkTreePath *fpath = gtk_tree_model_filter_convert_path_to_child_path
283         (GTK_TREE_MODEL_FILTER (model), path);
284
285       gint *idx = gtk_tree_path_get_indices (fpath);
286
287       const struct variable *v = psppire_dict_get_variable (dict, idx[0]);
288
289       gtk_tree_path_free (fpath);
290
291       if ( var_is_alpha (v))
292         {
293           retval = FALSE;
294           break;
295         }
296     }
297
298   g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
299   g_list_free (list);
300
301   return retval;
302 }
303