1 /* PSPPIRE - a graphical user interface for PSPP.
2 Copyright (C) 2012, 2020 Free Software Foundation
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.
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.
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/>. */
20 #include "psppire-dialog-action-examine.h"
22 #include "psppire-var-view.h"
23 #include "dialog-common.h"
24 #include "psppire-selector.h"
25 #include "psppire-dict.h"
26 #include "psppire-dialog.h"
27 #include "builder-wrapper.h"
30 #define _(msgid) gettext (msgid)
31 #define N_(msgid) msgid
33 static void psppire_dialog_action_examine_class_init (PsppireDialogActionExamineClass
*class);
35 G_DEFINE_TYPE (PsppireDialogActionExamine
, psppire_dialog_action_examine
, PSPPIRE_TYPE_DIALOG_ACTION
);
38 #define STAT_DESCRIPTIVES 0x01
39 #define STAT_EXTREMES 0x02
40 #define STAT_PERCENTILES 0x04
43 run_stats_dialog (PsppireDialogActionExamine
*ed
)
47 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed
->descriptives_button
),
48 ed
->stats
& STAT_DESCRIPTIVES
);
50 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed
->extremes_button
),
51 ed
->stats
& STAT_EXTREMES
);
53 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed
->percentiles_button
),
54 ed
->stats
& STAT_PERCENTILES
);
56 response
= psppire_dialog_run (PSPPIRE_DIALOG (ed
->stats_dialog
));
58 if (response
== PSPPIRE_RESPONSE_CONTINUE
)
61 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->descriptives_button
)))
62 ed
->stats
|= STAT_DESCRIPTIVES
;
64 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->extremes_button
)))
65 ed
->stats
|= STAT_EXTREMES
;
67 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->percentiles_button
)))
68 ed
->stats
|= STAT_PERCENTILES
;
73 run_opts_dialog (PsppireDialogActionExamine
*ed
)
80 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed
->listwise
), TRUE
);
83 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed
->pairwise
), TRUE
);
86 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed
->report
), TRUE
);
89 g_assert_not_reached ();
93 response
= psppire_dialog_run (PSPPIRE_DIALOG (ed
->opts_dialog
));
95 if (response
== PSPPIRE_RESPONSE_CONTINUE
)
97 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->listwise
)))
98 ed
->opts
= OPT_LISTWISE
;
99 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->pairwise
)))
100 ed
->opts
= OPT_PAIRWISE
;
101 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->report
)))
102 ed
->opts
= OPT_REPORT
;
107 run_plots_dialog (PsppireDialogActionExamine
*ed
)
111 switch (ed
->boxplots
)
113 case BOXPLOT_FACTORS
:
114 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed
->boxplot_factors_button
), TRUE
);
116 case BOXPLOT_DEPENDENTS
:
117 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed
->boxplot_dependents_button
), TRUE
);
120 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed
->boxplot_none_button
), TRUE
);
123 g_assert_not_reached ();
127 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed
->histogram_button
), ed
->histogram
);
128 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed
->npplots_button
), ed
->npplots
);
130 switch (ed
->spreadlevel
)
133 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed
->spread_none_button
), TRUE
);
136 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed
->spread_power_button
), TRUE
);
139 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed
->spread_trans_button
), TRUE
);
142 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed
->spread_untrans_button
), TRUE
);
145 g_assert_not_reached ();
149 switch (ed
->spreadpower
)
151 case SPREADPOWER_NATLOG
:
152 gtk_combo_box_set_active_id (GTK_COMBO_BOX (ed
->spread_power_combo
), "natlog");
154 case SPREADPOWER_CUBE
:
155 gtk_combo_box_set_active_id (GTK_COMBO_BOX (ed
->spread_power_combo
), "cube");
157 case SPREADPOWER_SQUARE
:
158 gtk_combo_box_set_active_id (GTK_COMBO_BOX (ed
->spread_power_combo
), "square");
160 case SPREADPOWER_SQUAREROOT
:
161 gtk_combo_box_set_active_id (GTK_COMBO_BOX (ed
->spread_power_combo
), "squareroot");
163 case SPREADPOWER_RECROOT
:
164 gtk_combo_box_set_active_id (GTK_COMBO_BOX (ed
->spread_power_combo
), "recroot");
166 case SPREADPOWER_RECIPROCAL
:
167 gtk_combo_box_set_active_id (GTK_COMBO_BOX (ed
->spread_power_combo
), "reciprocal");
171 response
= psppire_dialog_run (PSPPIRE_DIALOG (ed
->plots_dialog
));
173 if (response
== PSPPIRE_RESPONSE_CONTINUE
)
175 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->boxplot_factors_button
)))
176 ed
->boxplots
= BOXPLOT_FACTORS
;
177 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->boxplot_dependents_button
)))
178 ed
->boxplots
= BOXPLOT_DEPENDENTS
;
179 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->boxplot_none_button
)))
180 ed
->boxplots
= BOXPLOT_NONE
;
182 ed
->histogram
= gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->histogram_button
));
183 ed
->npplots
= gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->npplots_button
));
185 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->spread_none_button
)))
186 ed
->spreadlevel
= SPREAD_NONE
;
187 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->spread_power_button
)))
188 ed
->spreadlevel
= SPREAD_POWER
;
189 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->spread_trans_button
)))
190 ed
->spreadlevel
= SPREAD_TRANS
;
191 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->spread_untrans_button
)))
192 ed
->spreadlevel
= SPREAD_UNTRANS
;
194 if (0 == strcmp (gtk_combo_box_get_active_id (GTK_COMBO_BOX (ed
->spread_power_combo
)), "natlog"))
195 ed
->spreadpower
= SPREADPOWER_NATLOG
;
196 else if (0 == strcmp (gtk_combo_box_get_active_id (GTK_COMBO_BOX (ed
->spread_power_combo
)), "cube"))
197 ed
->spreadpower
= SPREADPOWER_CUBE
;
198 else if (0 == strcmp (gtk_combo_box_get_active_id (GTK_COMBO_BOX (ed
->spread_power_combo
)), "square"))
199 ed
->spreadpower
= SPREADPOWER_SQUARE
;
200 else if (0 == strcmp (gtk_combo_box_get_active_id (GTK_COMBO_BOX (ed
->spread_power_combo
)), "squareroot"))
201 ed
->spreadpower
= SPREADPOWER_SQUAREROOT
;
202 else if (0 == strcmp (gtk_combo_box_get_active_id (GTK_COMBO_BOX (ed
->spread_power_combo
)), "recroot"))
203 ed
->spreadpower
= SPREADPOWER_RECROOT
;
204 else if (0 == strcmp (gtk_combo_box_get_active_id (GTK_COMBO_BOX (ed
->spread_power_combo
)), "reciprocal"))
205 ed
->spreadpower
= SPREADPOWER_RECIPROCAL
;
210 generate_syntax (const PsppireDialogAction
*act
)
212 PsppireDialogActionExamine
*ed
= PSPPIRE_DIALOG_ACTION_EXAMINE (act
);
216 GString
*str
= g_string_new ("EXAMINE ");
217 bool show_stats
= gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->display_stats_button
));
218 bool show_plots
= gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->display_plots_button
));
220 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed
->display_both_button
)))
226 g_string_append (str
, "\n\t/VARIABLES=");
227 psppire_var_view_append_names (PSPPIRE_VAR_VIEW (ed
->variables
), 0, str
);
229 if (0 < gtk_tree_model_iter_n_children
230 (gtk_tree_view_get_model (GTK_TREE_VIEW (ed
->factors
)), NULL
))
232 g_string_append (str
, "\n\tBY ");
233 psppire_var_view_append_names (PSPPIRE_VAR_VIEW (ed
->factors
), 0, str
);
236 label
= gtk_entry_get_text (GTK_ENTRY (ed
->id_var
));
237 if (0 != strcmp (label
, ""))
239 g_string_append (str
, "\n\t/ID = ");
240 g_string_append (str
, label
);
245 if (ed
->stats
& (STAT_DESCRIPTIVES
| STAT_EXTREMES
))
247 g_string_append (str
, "\n\t/STATISTICS =");
249 if (ed
->stats
& STAT_DESCRIPTIVES
)
250 g_string_append (str
, " DESCRIPTIVES");
252 if (ed
->stats
& STAT_EXTREMES
)
253 g_string_append (str
, " EXTREME");
256 if (ed
->stats
& STAT_PERCENTILES
)
257 g_string_append (str
, "\n\t/PERCENTILES");
261 ((ed
->boxplots
!= BOXPLOT_NONE
) ||
264 (ed
->spreadlevel
!= SPREAD_NONE
)))
266 g_string_append (str
, "\n\t/PLOT =");
268 if (ed
->boxplots
!= BOXPLOT_NONE
)
269 g_string_append (str
, " BOXPLOT");
271 g_string_append (str
, " HISTOGRAM");
273 g_string_append (str
, " NPPLOT");
274 if (ed
->spreadlevel
!= SPREAD_NONE
)
276 g_string_append (str
, " SPREADLEVEL");
277 if (ed
->spreadlevel
!= SPREAD_POWER
)
280 if (ed
->spreadlevel
== SPREAD_TRANS
)
281 switch (ed
->spreadpower
)
283 case SPREADPOWER_NATLOG
:
286 case SPREADPOWER_CUBE
:
289 case SPREADPOWER_SQUARE
:
292 case SPREADPOWER_SQUAREROOT
:
295 case SPREADPOWER_RECROOT
:
298 case SPREADPOWER_RECIPROCAL
:
302 g_assert_not_reached ();
307 g_string_append_printf(str
, " (%s)",power
);
310 if (ed
->boxplots
== BOXPLOT_FACTORS
)
311 g_string_append (str
, "\n\t/COMPARE = GROUPS");
312 if (ed
->boxplots
== BOXPLOT_DEPENDENTS
)
313 g_string_append (str
, "\n\t/COMPARE = VARIABLES");
316 g_string_append (str
, "\n\t/MISSING=");
320 g_string_append (str
, "REPORT");
323 g_string_append (str
, "PAIRWISE");
326 g_string_append (str
, "LISTWISE");
330 g_string_append (str
, ".");
333 g_string_free (str
, FALSE
);
339 dialog_state_valid (PsppireDialogAction
*da
)
341 PsppireDialogActionExamine
*pae
= PSPPIRE_DIALOG_ACTION_EXAMINE (da
);
344 gtk_tree_view_get_model (GTK_TREE_VIEW (pae
->variables
));
346 return gtk_tree_model_get_iter_first (vars
, ¬used
);
350 dialog_refresh (PsppireDialogAction
*da
)
352 PsppireDialogActionExamine
*dae
= PSPPIRE_DIALOG_ACTION_EXAMINE (da
);
353 GtkTreeModel
*liststore
= NULL
;
355 liststore
= gtk_tree_view_get_model (GTK_TREE_VIEW (dae
->variables
));
356 gtk_list_store_clear (GTK_LIST_STORE (liststore
));
358 liststore
= gtk_tree_view_get_model (GTK_TREE_VIEW (dae
->factors
));
359 gtk_list_store_clear (GTK_LIST_STORE (liststore
));
361 gtk_entry_set_text (GTK_ENTRY (dae
->id_var
), "");
362 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dae
->display_both_button
), TRUE
);
365 dae
->opts
= OPT_LISTWISE
;
366 dae
->boxplots
= BOXPLOT_FACTORS
;
367 dae
->histogram
= TRUE
;
368 dae
->npplots
= FALSE
;
369 dae
->spreadlevel
= SPREAD_NONE
;
370 dae
->spreadpower
= SPREADPOWER_NATLOG
;
374 psppire_dialog_action_examine_activate (PsppireDialogAction
*a
, GVariant
*param
)
376 PsppireDialogAction
*pda
= PSPPIRE_DIALOG_ACTION (a
);
377 PsppireDialogActionExamine
*act
= PSPPIRE_DIALOG_ACTION_EXAMINE (a
);
379 GtkBuilder
*xml
= builder_new ("examine.ui");
381 GtkWidget
*stats_button
= get_widget_assert (xml
, "stats-button");
382 GtkWidget
*opts_button
= get_widget_assert (xml
, "opts-button");
383 GtkWidget
*plots_button
= get_widget_assert (xml
, "plots-button");
385 g_signal_connect_swapped (stats_button
, "clicked",
386 G_CALLBACK (run_stats_dialog
), act
);
388 g_signal_connect_swapped (opts_button
, "clicked",
389 G_CALLBACK (run_opts_dialog
), act
);
390 g_signal_connect_swapped (plots_button
, "clicked",
391 G_CALLBACK (run_plots_dialog
), act
);
393 GtkWidget
*dep_sel
= get_widget_assert (xml
, "psppire-selector1");
394 GtkWidget
*dep_sel2
= get_widget_assert (xml
, "psppire-selector2");
395 GtkWidget
*dep_sel3
= get_widget_assert (xml
, "psppire-selector3");
396 GtkWidget
*table
= get_widget_assert (xml
, "table1");
398 pda
->dialog
= get_widget_assert (xml
, "examine-dialog");
399 pda
->source
= get_widget_assert (xml
, "treeview1");
400 act
->variables
= get_widget_assert (xml
, "treeview2");
401 act
->factors
= get_widget_assert (xml
, "treeview3");
402 act
->id_var
= get_widget_assert (xml
, "entry1");
403 act
->display_both_button
= get_widget_assert (xml
, "display-both-button");
404 act
->display_stats_button
= get_widget_assert (xml
, "display-stats-button");
405 act
->display_plots_button
= get_widget_assert (xml
, "display-plots-button");
407 /* Setting the focus chain like this is a pain.
408 But the default focus order seems to be somewhat odd. */
410 list
= g_list_append (list
, get_widget_assert (xml
, "scrolledwindow1"));
411 list
= g_list_append (list
, dep_sel
);
412 list
= g_list_append (list
, get_widget_assert (xml
, "frame1"));
413 list
= g_list_append (list
, dep_sel2
);
414 list
= g_list_append (list
, get_widget_assert (xml
, "frame2"));
415 list
= g_list_append (list
, dep_sel3
);
416 list
= g_list_append (list
, get_widget_assert (xml
, "frame3"));
417 gtk_container_set_focus_chain (GTK_CONTAINER (table
), list
);
421 act
->stats_dialog
= get_widget_assert (xml
, "statistics-dialog");
422 act
->descriptives_button
= get_widget_assert (xml
, "descriptives-button");
423 act
->extremes_button
= get_widget_assert (xml
, "extremes-button");
424 act
->percentiles_button
= get_widget_assert (xml
, "percentiles-button");
426 act
->opts_dialog
= get_widget_assert (xml
, "options-dialog");
427 act
->listwise
= get_widget_assert (xml
, "radiobutton1");
428 act
->pairwise
= get_widget_assert (xml
, "radiobutton2");
429 act
->report
= get_widget_assert (xml
, "radiobutton3");
431 act
->plots_dialog
= get_widget_assert (xml
, "plots-dialog");
432 act
->boxplot_factors_button
= get_widget_assert (xml
, "boxplot-factors-button");
433 act
->boxplot_dependents_button
= get_widget_assert (xml
, "boxplot-dependents-button");
434 act
->boxplot_none_button
= get_widget_assert (xml
, "boxplot-none-button");
435 act
->histogram_button
= get_widget_assert (xml
, "histogram-button");
436 act
->npplots_button
= get_widget_assert (xml
, "npplots-button");
437 act
->spread_none_button
= get_widget_assert (xml
, "spread-none-button");
438 act
->spread_power_button
= get_widget_assert (xml
, "spread-power-button");
439 act
->spread_trans_button
= get_widget_assert (xml
, "spread-trans-button");
440 act
->spread_untrans_button
= get_widget_assert (xml
, "spread-untrans-button");
441 act
->spread_power_combo
= get_widget_assert (xml
, "spread-power-combo");
443 psppire_selector_set_allow (PSPPIRE_SELECTOR (dep_sel
), numeric_only
);
445 psppire_dialog_action_set_valid_predicate (pda
, (void *) dialog_state_valid
);
446 psppire_dialog_action_set_refresh (pda
, dialog_refresh
);
451 psppire_dialog_action_examine_class_init (PsppireDialogActionExamineClass
*class)
453 PSPPIRE_DIALOG_ACTION_CLASS (class)->initial_activate
= psppire_dialog_action_examine_activate
;
455 PSPPIRE_DIALOG_ACTION_CLASS (class)->generate_syntax
= generate_syntax
;
459 psppire_dialog_action_examine_init (PsppireDialogActionExamine
*act
)