0a578caa20160ed7d1432fc86bba817e6c2ef426
[pspp] / src / ui / gui / psppire-dialog-action-k-independent.c
1 /* PSPPIRE - a graphical user interface for PSPP.
2    Copyright (C) 2017 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
18 #include <config.h>
19
20 #include "psppire-dialog-action-k-independent.h"
21
22 #include "psppire-var-view.h"
23 #include "psppire-value-entry.h"
24 #include "psppire-acr.h"
25
26 #include "psppire-dialog.h"
27 #include "builder-wrapper.h"
28 #include "helper.h"
29
30
31 #include "gettext.h"
32 #define _(msgid) gettext (msgid)
33 #define N_(msgid) msgid
34
35
36
37 static void psppire_dialog_action_k_independent_init            (PsppireDialogActionKIndependent      *act);
38 static void psppire_dialog_action_k_independent_class_init      (PsppireDialogActionKIndependentClass *class);
39
40 G_DEFINE_TYPE (PsppireDialogActionKIndependent, psppire_dialog_action_k_independent, PSPPIRE_TYPE_DIALOG_ACTION);
41
42 const static char *keyword[n_KIDS] =
43   {
44     "KRUSKAL-WALLIS",
45     "MEDIAN"
46   };
47
48 static char *
49 generate_syntax (const PsppireDialogAction *act)
50 {
51   gchar *text;
52   PsppireDialogActionKIndependent *kid = PSPPIRE_DIALOG_ACTION_K_INDEPENDENT (act);
53
54   GString *string = g_string_new ("NPAR TEST");
55   int i;
56   for (i = 0; i < n_KIDS; ++i)
57     {
58       g_string_append (string, "\n\t");
59
60       if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (kid->checkbutton[i])))
61         {
62           g_string_append_printf (string, "/%s = ", keyword[i]);
63           psppire_var_view_append_names (PSPPIRE_VAR_VIEW (kid->vars_treeview),
64                                          0, string);
65
66           g_string_append (string, " BY ");
67
68           g_string_append (string,
69                            gtk_entry_get_text (GTK_ENTRY (kid->groupvar_entry)));
70
71
72           g_string_append_printf (string, " (%g, %g)",
73                                   kid->lower_limit_value.f,
74                                   kid->upper_limit_value.f);
75         }
76     }
77   
78   g_string_append (string, ".\n");
79
80   text = string->str;
81
82   g_string_free (string, FALSE);
83
84   return text;
85 }
86
87
88 static gboolean
89 dialog_state_valid (gpointer data)
90 {
91   PsppireDialogActionKIndependent *kid = PSPPIRE_DIALOG_ACTION_K_INDEPENDENT (data);
92
93   GtkTreeModel *vars =
94     gtk_tree_view_get_model (GTK_TREE_VIEW (kid->vars_treeview));
95
96   GtkTreeIter notused;
97
98   if ( !gtk_tree_model_get_iter_first (vars, &notused) )
99     return FALSE;
100
101   if ( 0 == strcmp ("", gtk_entry_get_text (GTK_ENTRY (kid->groupvar_entry))))
102     return FALSE;
103
104   gboolean method_set = FALSE;
105   gint i;
106   for (i = 0; i < n_KIDS; ++i)
107     {
108       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (kid->checkbutton[i])))
109         method_set = TRUE;
110     }
111
112   return method_set;
113 }
114
115 static void
116 refresh (PsppireDialogAction *rd_)
117 {
118   PsppireDialogActionKIndependent *kid = PSPPIRE_DIALOG_ACTION_K_INDEPENDENT (rd_);
119
120   GtkTreeModel *model =
121     gtk_tree_view_get_model (GTK_TREE_VIEW (kid->vars_treeview));
122
123   gtk_entry_set_text (GTK_ENTRY (kid->groupvar_entry), "");
124
125   gtk_list_store_clear (GTK_LIST_STORE (model));
126
127   gint i;
128   for (i = 0; i < n_KIDS; ++i)
129     {
130       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (kid->checkbutton[i]),
131                                     FALSE);
132     }
133 }
134
135 static void
136 run_define_groups_dialog (PsppireDialogActionKIndependent *kid)
137 {
138   if (kid->lower_limit_value.f != SYSMIS)
139     psppire_value_entry_set_value (PSPPIRE_VALUE_ENTRY (kid->lower_limit_entry),
140                                    &kid->lower_limit_value, 0);
141
142   if (kid->upper_limit_value.f != SYSMIS)
143     psppire_value_entry_set_value (PSPPIRE_VALUE_ENTRY (kid->upper_limit_entry),
144                                    &kid->upper_limit_value, 0);
145
146   if (PSPPIRE_RESPONSE_CONTINUE == psppire_dialog_run (kid->subdialog))
147     {
148       psppire_value_entry_get_value (PSPPIRE_VALUE_ENTRY (kid->lower_limit_entry),
149                                      &kid->lower_limit_value, 0);
150
151       psppire_value_entry_get_value (PSPPIRE_VALUE_ENTRY (kid->upper_limit_entry),
152                                      &kid->upper_limit_value, 0);
153     }
154 }
155
156
157 static void
158 set_value_entry_variable (PsppireDialogActionKIndependent *kid, GtkEntry *entry)
159 {
160   PsppireDialogAction *da = PSPPIRE_DIALOG_ACTION (kid);
161   const gchar *text = gtk_entry_get_text (entry);
162
163   const struct variable *v = da->dict ?
164     psppire_dict_lookup_var (da->dict, text) : NULL;
165
166   psppire_value_entry_set_variable (kid->lower_limit_entry, v);
167   psppire_value_entry_set_variable (kid->upper_limit_entry, v);
168 }
169
170
171 static void
172 psppire_dialog_action_k_independent_activate (PsppireDialogAction *a)
173 {
174   PsppireDialogAction *pda = PSPPIRE_DIALOG_ACTION (a);
175   PsppireDialogActionKIndependent *kid = PSPPIRE_DIALOG_ACTION_K_INDEPENDENT (a);
176
177   GHashTable *thing = psppire_dialog_action_get_hash_table (pda);
178   GtkBuilder *xml = g_hash_table_lookup (thing, a);
179   if (!xml)
180     {
181       xml = builder_new ("k-independent.ui");
182       g_hash_table_insert (thing, a, xml);
183
184       pda->dialog = get_widget_assert   (xml, "k-independent-dialog");
185       pda->source = get_widget_assert   (xml, "k-independent-treeview1");
186
187       kid->vars_treeview =  get_widget_assert (xml, "k-independent-treeview2");
188       kid->groupvar_entry = get_widget_assert (xml, "k-independent-entry");
189
190       kid->subdialog = get_widget_assert (xml, "define-groups-dialog");
191
192       kid->lower_limit_entry = get_widget_assert (xml, "lower-limit-entry");
193       kid->upper_limit_entry = get_widget_assert (xml, "upper-limit-entry");
194
195       kid->checkbutton[KID_KRUSKAL_WALLIS] = get_widget_assert (xml,
196                                                                 "kruskal-wallis");
197
198       kid->checkbutton[KID_MEDIAN] = get_widget_assert (xml, "median");
199
200       g_signal_connect_swapped (get_widget_assert (xml, "define-groups-button"),
201                                 "clicked",
202                                 G_CALLBACK (run_define_groups_dialog), kid);
203
204       g_signal_connect_swapped (kid->groupvar_entry, "changed",
205                                 G_CALLBACK (set_value_entry_variable), kid);
206     }
207
208   psppire_dialog_action_set_valid_predicate (pda, dialog_state_valid);
209   psppire_dialog_action_set_refresh (pda, refresh);
210 }
211
212 static void
213 psppire_dialog_action_k_independent_class_init (PsppireDialogActionKIndependentClass *class)
214 {
215   psppire_dialog_action_set_activation (class, psppire_dialog_action_k_independent_activate);
216   PSPPIRE_DIALOG_ACTION_CLASS (class)->generate_syntax = generate_syntax;
217 }
218
219 static void
220 psppire_dialog_action_k_independent_init (PsppireDialogActionKIndependent *kid)
221 {
222   kid->lower_limit_value.f = SYSMIS;
223   kid->upper_limit_value.f = SYSMIS;
224 }