1 /* PSPPIRE - a graphical user interface for PSPP.
2    Copyright (C) 2012, 2013  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-two-sample.h"
21 
22 #include "psppire-var-view.h"
23 
24 #include "psppire-selector.h"
25 #include "psppire-dialog.h"
26 #include "builder-wrapper.h"
27 
28 #include <gettext.h>
29 #define _(msgid) gettext (msgid)
30 #define N_(msgid) msgid
31 
32 
33 static void psppire_dialog_action_two_sample_init            (PsppireDialogActionTwoSample      *act);
34 static void psppire_dialog_action_two_sample_class_init      (PsppireDialogActionTwoSampleClass *class);
35 
36 G_DEFINE_TYPE (PsppireDialogActionTwoSample, psppire_dialog_action_two_sample, PSPPIRE_TYPE_DIALOG_ACTION);
37 
38 
39 static gboolean
dialog_state_valid(gpointer data)40 dialog_state_valid (gpointer data)
41 {
42   PsppireDialogActionTwoSample *pd = PSPPIRE_DIALOG_ACTION_TWO_SAMPLE (data);
43   gint n_rows = gtk_tree_model_iter_n_children  (GTK_TREE_MODEL (pd->list_store), NULL);
44   struct variable *v = NULL;
45   GtkTreeIter dest_iter;
46 
47   if (n_rows == 0)
48     return FALSE;
49 
50   /* Get the last row */
51   gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (pd->list_store), &dest_iter,
52 				 NULL, n_rows - 1);
53 
54   /* Get the last (2nd) column */
55   gtk_tree_model_get (GTK_TREE_MODEL (pd->list_store), &dest_iter, 1, &v, -1);
56 
57   if (v == NULL)
58     return FALSE;
59 
60 
61   /* Now check that at least one toggle button is selected */
62 
63   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (pd->nts[NT_WILCOXON].button)))
64     return TRUE;
65 
66   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (pd->nts[NT_SIGN].button)))
67     return TRUE;
68 
69   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (pd->nts[NT_MCNEMAR].button)))
70     return TRUE;
71 
72   return FALSE;
73 }
74 
75 static void
refresh(PsppireDialogAction * rd_)76 refresh (PsppireDialogAction *rd_)
77 {
78   PsppireDialogActionTwoSample *pd = PSPPIRE_DIALOG_ACTION_TWO_SAMPLE (rd_);
79 
80   gtk_list_store_clear (GTK_LIST_STORE (pd->list_store));
81 
82   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pd->nts[NT_WILCOXON].button), FALSE);
83   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pd->nts[NT_SIGN].button), FALSE);
84   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pd->nts[NT_MCNEMAR].button), FALSE);
85 }
86 
87 
88 static void
select_as_pair_member(GtkTreeIter source_iter,GtkWidget * dest,GtkTreeModel * source_model,gpointer data)89 select_as_pair_member (GtkTreeIter source_iter,
90 		       GtkWidget *dest,
91 		       GtkTreeModel *source_model,
92 		       gpointer data)
93 {
94   struct variable *v;
95   struct variable *v1;
96   gint n_rows;
97   GtkTreeIter dest_iter;
98   PsppireDialogActionTwoSample *tt_d = PSPPIRE_DIALOG_ACTION_TWO_SAMPLE (data);
99 
100 
101   gtk_tree_model_get (source_model, &source_iter,
102 		      DICT_TVM_COL_VAR, &v, -1);
103 
104   n_rows = gtk_tree_model_iter_n_children  (GTK_TREE_MODEL (tt_d->list_store), NULL);
105 
106   if (n_rows > 0)
107     {
108 
109       gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (tt_d->list_store),
110 				     &dest_iter, NULL, n_rows - 1);
111 
112       gtk_tree_model_get (GTK_TREE_MODEL (tt_d->list_store), &dest_iter, 1, &v1, -1);
113     }
114   else
115     v1 = NULL;
116 
117   if (n_rows == 0 || v1 != NULL)
118     {
119       gtk_list_store_append (tt_d->list_store, &dest_iter);
120 
121       gtk_list_store_set (tt_d->list_store, &dest_iter,
122 			  0, v,
123 			  1, NULL,
124 			  -1);
125     }
126   else
127     {
128       gtk_list_store_set (tt_d->list_store, &dest_iter,
129 			  1, v,
130 			  -1);
131     }
132 }
133 
134 
135 
136 static gchar *
generate_syntax(const PsppireDialogAction * pda)137 generate_syntax (const PsppireDialogAction *pda)
138 {
139   gint i;
140 
141   PsppireDialogActionTwoSample *d = PSPPIRE_DIALOG_ACTION_TWO_SAMPLE (pda);
142   gchar *text = NULL;
143 
144   GString *str = g_string_new ("NPAR TEST");
145 
146   for (i = 0 ; i < n_Tests; ++i)
147   {
148     if (! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (d->nts[i].button)))
149       continue;
150 
151     g_string_append (str, "\n\t");
152     g_string_append (str, d->nts[i].syntax);
153 
154     psppire_var_view_append_names (PSPPIRE_VAR_VIEW (d->pairs_treeview), 0, str);
155 
156     g_string_append (str, " WITH ");
157 
158     psppire_var_view_append_names (PSPPIRE_VAR_VIEW (d->pairs_treeview), 1, str);
159 
160     g_string_append (str, " (PAIRED)");
161   }
162 
163   g_string_append (str, ".\n");
164 
165   text = str->str;
166   g_string_free (str, FALSE);
167 
168   return text;
169 }
170 
171 static GtkBuilder *
psppire_dialog_action_two_sample_activate(PsppireDialogAction * a,GVariant * param)172 psppire_dialog_action_two_sample_activate (PsppireDialogAction *a, GVariant *param)
173 {
174   PsppireDialogAction *pda = PSPPIRE_DIALOG_ACTION (a);
175   PsppireDialogActionTwoSample *act = PSPPIRE_DIALOG_ACTION_TWO_SAMPLE (a);
176 
177   GtkBuilder *xml = builder_new ("paired-samples.ui");
178 
179   /* NPAR Specific options */
180   GtkWidget *frame = gtk_frame_new (_("Test Type"));
181   GtkWidget *bb = gtk_button_box_new (GTK_ORIENTATION_VERTICAL);
182   GtkWidget *box = get_widget_assert (xml, "dynamic-populate");
183 
184 
185   strcpy (act->nts[NT_WILCOXON].syntax, "/WILCOXON");
186   strcpy (act->nts[NT_SIGN].syntax, "/SIGN");
187   strcpy (act->nts[NT_MCNEMAR].syntax, "/MCNEMAR");
188 
189   act->nts[NT_WILCOXON].button = gtk_check_button_new_with_mnemonic (_("_Wilcoxon"));
190   act->nts[NT_SIGN].button = gtk_check_button_new_with_mnemonic (_("_Sign"));
191   act->nts[NT_MCNEMAR].button = gtk_check_button_new_with_mnemonic (_("_McNemar"));
192 
193   gtk_box_pack_start (GTK_BOX (bb), act->nts[NT_WILCOXON].button, FALSE, FALSE, 5);
194   gtk_box_pack_start (GTK_BOX (bb), act->nts[NT_SIGN].button,     FALSE, FALSE, 5);
195   gtk_box_pack_start (GTK_BOX (bb), act->nts[NT_MCNEMAR].button,  FALSE, FALSE, 5);
196 
197   gtk_container_add (GTK_CONTAINER (frame), bb);
198 
199   gtk_widget_show_all (frame);
200 
201   gtk_box_pack_start (GTK_BOX (box), frame, FALSE, FALSE,  5);
202 
203 
204   GtkWidget *selector = get_widget_assert (xml, "psppire-selector3");
205 
206   pda->dialog = get_widget_assert   (xml, "t-test-paired-samples-dialog");
207   pda->source = get_widget_assert   (xml, "paired-samples-t-test-treeview1");
208 
209   gtk_window_set_title (GTK_WINDOW (pda->dialog), _("Two-Related-Samples Tests"));
210 
211   act->pairs_treeview = get_widget_assert (xml, "paired-samples-t-test-treeview2");
212   act->list_store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (act->pairs_treeview)));
213 
214 
215   psppire_dialog_action_set_valid_predicate (pda, dialog_state_valid);
216   psppire_dialog_action_set_refresh (pda, refresh);
217 
218   g_object_set (pda->source,
219 		"predicate", var_is_numeric,
220 		NULL);
221 
222   psppire_selector_set_select_func (PSPPIRE_SELECTOR (selector),
223 				    select_as_pair_member,
224 				    act);
225   return xml;
226 }
227 
228 static void
psppire_dialog_action_two_sample_class_init(PsppireDialogActionTwoSampleClass * class)229 psppire_dialog_action_two_sample_class_init (PsppireDialogActionTwoSampleClass *class)
230 {
231   PSPPIRE_DIALOG_ACTION_CLASS (class)->initial_activate = psppire_dialog_action_two_sample_activate;
232   PSPPIRE_DIALOG_ACTION_CLASS (class)->generate_syntax = generate_syntax;
233 }
234 
235 
236 static void
psppire_dialog_action_two_sample_init(PsppireDialogActionTwoSample * act)237 psppire_dialog_action_two_sample_init (PsppireDialogActionTwoSample *act)
238 {
239 }
240 
241