7472b5708fa99294de1a102ae541572b1669f2c2
[pspp] / src / ui / gui / dialog-common.c
1 /* PSPPIRE - a graphical user interface for PSPP.
2    Copyright (C) 2007, 2014  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 <libpspp/i18n.h>
20 #include "dialog-common.h"
21
22 #include "psppire-var-ptr.h"
23
24 #include "helper.h"
25
26
27 /* Returns FALSE if the variables represented by the union of the rows
28    currently selected by SOURCE widget, and contents of the DEST
29    widget, are of different types.
30
31    In other words, this function when passed as the argument to
32    psppire_selector_set_allow, ensures that the selector selects only
33    string  variables, or only numeric variables, not a mixture.
34 */
35 gboolean
36 homogeneous_types (GtkWidget *source, GtkWidget *dest)
37 {
38   gboolean ok;
39   GtkTreeIter iter;
40   gboolean retval = TRUE;
41
42   GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (source));
43
44   PsppireDict *dict;
45   GtkTreeSelection *selection;
46   enum val_type type;
47   GList *list, *l;
48   bool have_type;
49
50   while (GTK_IS_TREE_MODEL_FILTER (model))
51     {
52       model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
53     }
54
55   dict = PSPPIRE_DICT (model);
56
57   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (source));
58
59   list = gtk_tree_selection_get_selected_rows (selection, &model);
60
61   /* Iterate through the selection of the source treeview */
62   have_type = false;
63   for (l = list; l ; l = l->next)
64     {
65       GtkTreePath *path = l->data;
66
67       GtkTreePath *fpath =
68         gtk_tree_model_filter_convert_path_to_child_path (GTK_TREE_MODEL_FILTER (model), path);
69
70       gint *idx = gtk_tree_path_get_indices (fpath);
71
72       const struct variable *v = psppire_dict_get_variable (dict, idx[0]);
73
74       gtk_tree_path_free (fpath);
75
76       if (have_type && var_get_type (v) != type)
77         {
78           retval = FALSE;
79           break;
80         }
81
82       type = var_get_type (v);
83       have_type = true;
84     }
85
86   g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
87   g_list_free (list);
88
89   if ( retval == FALSE )
90     return FALSE;
91
92   /* now deal with the dest widget */
93   model = gtk_tree_view_get_model (GTK_TREE_VIEW (dest));
94
95   for (ok = gtk_tree_model_get_iter_first (model, &iter);
96        ok;
97        ok = gtk_tree_model_iter_next (model, &iter))
98     {
99       const struct variable *v;
100       gtk_tree_model_get (model, &iter, 0, &v, -1);
101
102       if ( have_type && var_get_type (v) != type )
103         {
104           retval = FALSE;
105           break;
106         }
107
108       type = var_get_type (v);
109       have_type = true;
110     }
111
112   return retval;
113 }
114
115
116
117 /* Returns true iff the variable selected by SOURCE is numeric */
118 gboolean
119 numeric_only (GtkWidget *source, GtkWidget *dest)
120 {
121   gboolean retval = TRUE;
122
123   GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (source));
124
125   PsppireDict *dict;
126   GtkTreeSelection *selection;
127   GList *list, *l;
128
129   while (GTK_IS_TREE_MODEL_FILTER (model))
130     {
131       model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
132     }
133
134   dict = PSPPIRE_DICT (model);
135
136   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (source));
137
138   list = gtk_tree_selection_get_selected_rows (selection, &model);
139
140   /* Iterate through the selection of the source treeview */
141   for (l = list; l ; l = l->next)
142     {
143       GtkTreePath *path = l->data;
144       GtkTreePath *fpath = gtk_tree_model_filter_convert_path_to_child_path
145         (GTK_TREE_MODEL_FILTER (model), path);
146
147       gint *idx = gtk_tree_path_get_indices (fpath);
148
149       const struct variable *v = psppire_dict_get_variable (dict, idx[0]);
150
151       gtk_tree_path_free (fpath);
152
153       if ( var_is_alpha (v))
154         {
155           retval = FALSE;
156           break;
157         }
158     }
159
160   g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
161   g_list_free (list);
162
163   return retval;
164 }
165
166 /*
167   A pair of functions intended to be used as callbacks for the "toggled" signal
168   of a GtkToggleButton widget.  They make the sensitivity of W follow the status
169   of the togglebutton.
170 */
171 void
172 set_sensitivity_from_toggle (GtkToggleButton *togglebutton,  GtkWidget *w)
173 {
174   gboolean active = gtk_toggle_button_get_active (togglebutton);
175
176   gtk_widget_set_sensitive (w, active);
177   if (active)
178     gtk_widget_grab_focus (w);
179 }
180
181 /* */
182 void
183 set_sensitivity_from_toggle_invert (GtkToggleButton *togglebutton,
184                                     GtkWidget *w)
185 {
186   gboolean active = gtk_toggle_button_get_active (togglebutton);
187
188   gtk_widget_set_sensitive (w, !active);
189 }
190
191
192