psppire: add "Plots" subdialog for examine (Explore)
[pspp] / src / ui / gui / psppire-dialog-action-examine.c
index 12627bd7a5f76b7a72972b3c1e4d9a09a891958b..d8742703dd0ddcf3fe873933dbeb5c10be701a1c 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2012  Free Software Foundation
+   Copyright (C) 2012, 2020  Free Software Foundation
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -103,8 +103,108 @@ run_opts_dialog (PsppireDialogActionExamine *ed)
   }
 }
 
+static void
+run_plots_dialog (PsppireDialogActionExamine *ed)
+{
+  gint response;
 
+  switch (ed->boxplots)
+    {
+    case BOXPLOT_FACTORS:
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed->boxplot_factors_button), TRUE);
+      break;
+    case BOXPLOT_DEPENDENTS:
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed->boxplot_dependents_button), TRUE);
+      break;
+    case BOXPLOT_NONE:
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed->boxplot_none_button), TRUE);
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    };
 
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed->histogram_button), ed->histogram);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed->npplots_button), ed->npplots);
+
+  switch (ed->spreadlevel)
+    {
+    case SPREAD_NONE:
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed->spread_none_button), TRUE);
+      break;
+    case SPREAD_POWER:
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed->spread_power_button), TRUE);
+      break;
+    case SPREAD_TRANS:
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed->spread_trans_button), TRUE);
+      break;
+    case SPREAD_UNTRANS:
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ed->spread_untrans_button), TRUE);
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+
+  switch (ed->spreadpower)
+    {
+    case SPREADPOWER_NATLOG:
+      gtk_combo_box_set_active_id (GTK_COMBO_BOX (ed->spread_power_combo), "natlog");
+      break;
+    case SPREADPOWER_CUBE:
+      gtk_combo_box_set_active_id (GTK_COMBO_BOX (ed->spread_power_combo), "cube");
+      break;
+    case SPREADPOWER_SQUARE:
+      gtk_combo_box_set_active_id (GTK_COMBO_BOX (ed->spread_power_combo), "square");
+      break;
+    case SPREADPOWER_SQUAREROOT:
+      gtk_combo_box_set_active_id (GTK_COMBO_BOX (ed->spread_power_combo), "squareroot");
+      break;
+    case SPREADPOWER_RECROOT:
+      gtk_combo_box_set_active_id (GTK_COMBO_BOX (ed->spread_power_combo), "recroot");
+      break;
+    case SPREADPOWER_RECIPROCAL:
+      gtk_combo_box_set_active_id (GTK_COMBO_BOX (ed->spread_power_combo), "reciprocal");
+      break;
+    }
+
+  response = psppire_dialog_run (PSPPIRE_DIALOG (ed->plots_dialog));
+
+  if (response == PSPPIRE_RESPONSE_CONTINUE)
+    {
+      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed->boxplot_factors_button)))
+       ed->boxplots = BOXPLOT_FACTORS;
+      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed->boxplot_dependents_button)))
+       ed->boxplots = BOXPLOT_DEPENDENTS;
+      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed->boxplot_none_button)))
+       ed->boxplots = BOXPLOT_NONE;
+
+      ed->histogram = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed->histogram_button));
+      ed->npplots   = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed->npplots_button));
+
+      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed->spread_none_button)))
+       ed->spreadlevel = SPREAD_NONE;
+      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed->spread_power_button)))
+       ed->spreadlevel = SPREAD_POWER;
+      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed->spread_trans_button)))
+       ed->spreadlevel = SPREAD_TRANS;
+      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed->spread_untrans_button)))
+       ed->spreadlevel = SPREAD_UNTRANS;
+
+      if (0 == strcmp (gtk_combo_box_get_active_id (GTK_COMBO_BOX (ed->spread_power_combo)), "natlog"))
+       ed->spreadpower = SPREADPOWER_NATLOG;
+      else if (0 == strcmp (gtk_combo_box_get_active_id (GTK_COMBO_BOX (ed->spread_power_combo)), "cube"))
+       ed->spreadpower = SPREADPOWER_CUBE;
+      else if (0 == strcmp (gtk_combo_box_get_active_id (GTK_COMBO_BOX (ed->spread_power_combo)), "square"))
+       ed->spreadpower = SPREADPOWER_SQUARE;
+      else if (0 == strcmp (gtk_combo_box_get_active_id (GTK_COMBO_BOX (ed->spread_power_combo)), "squareroot"))
+       ed->spreadpower = SPREADPOWER_SQUAREROOT;
+      else if (0 == strcmp (gtk_combo_box_get_active_id (GTK_COMBO_BOX (ed->spread_power_combo)), "recroot"))
+       ed->spreadpower = SPREADPOWER_RECROOT;
+      else if (0 == strcmp (gtk_combo_box_get_active_id (GTK_COMBO_BOX (ed->spread_power_combo)), "reciprocal"))
+       ed->spreadpower = SPREADPOWER_RECIPROCAL;
+    }
+}
 
 static char *
 generate_syntax (const PsppireDialogAction *act)
@@ -114,6 +214,14 @@ generate_syntax (const PsppireDialogAction *act)
   const char *label;
   gchar *text = NULL;
   GString *str = g_string_new ("EXAMINE ");
+  bool show_stats = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed->display_stats_button));
+  bool show_plots = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed->display_plots_button));
+
+  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ed->display_both_button)))
+    {
+      show_stats = true;
+      show_plots = true;
+    }
 
   g_string_append (str, "\n\t/VARIABLES=");
   psppire_var_view_append_names (PSPPIRE_VAR_VIEW (ed->variables), 0, str);
@@ -132,20 +240,78 @@ generate_syntax (const PsppireDialogAction *act)
       g_string_append (str, label);
     }
 
-  if (ed->stats & (STAT_DESCRIPTIVES | STAT_EXTREMES))
+  if (show_stats)
     {
-      g_string_append (str, "\n\t/STATISTICS =");
+      if (ed->stats & (STAT_DESCRIPTIVES | STAT_EXTREMES))
+       {
+         g_string_append (str, "\n\t/STATISTICS =");
 
-      if (ed->stats & STAT_DESCRIPTIVES)
-       g_string_append (str, " DESCRIPTIVES");
+         if (ed->stats & STAT_DESCRIPTIVES)
+           g_string_append (str, " DESCRIPTIVES");
 
-      if (ed->stats & STAT_EXTREMES)
-       g_string_append (str, " EXTREME");
-    }
+         if (ed->stats & STAT_EXTREMES)
+           g_string_append (str, " EXTREME");
+       }
 
-  if (ed->stats & STAT_PERCENTILES)
-    g_string_append (str, "\n\t/PERCENTILES");
+      if (ed->stats & STAT_PERCENTILES)
+       g_string_append (str, "\n\t/PERCENTILES");
+    }
 
+  if (show_plots &&
+      ((ed->boxplots != BOXPLOT_NONE) ||
+       ed->histogram ||
+       ed->npplots ||
+       (ed->spreadlevel != SPREAD_NONE)))
+    {
+      g_string_append (str, "\n\t/PLOT =");
+
+      if (ed->boxplots != BOXPLOT_NONE)
+       g_string_append (str, " BOXPLOT");
+      if (ed->histogram)
+       g_string_append (str, " HISTOGRAM");
+      if (ed->npplots)
+       g_string_append (str, " NPPLOT");
+      if (ed->spreadlevel != SPREAD_NONE)
+       {
+         g_string_append (str, " SPREADLEVEL");
+         if (ed->spreadlevel != SPREAD_POWER)
+           {
+             gchar *power = NULL;
+             if (ed->spreadlevel == SPREAD_TRANS)
+               switch (ed->spreadpower)
+                 {
+                 case SPREADPOWER_NATLOG:
+                   power = "0";
+                   break;
+                 case SPREADPOWER_CUBE:
+                   power = "3";
+                   break;
+                 case SPREADPOWER_SQUARE:
+                   power = "2";
+                   break;
+                 case SPREADPOWER_SQUAREROOT:
+                   power = "0.5";
+                   break;
+                 case SPREADPOWER_RECROOT:
+                   power = "-0.5";
+                   break;
+                 case SPREADPOWER_RECIPROCAL:
+                   power = "-1";
+                   break;
+                 default:
+                   g_assert_not_reached ();
+                   break;
+                 }
+             else
+               power = "1";
+             g_string_append_printf(str, " (%s)",power);
+           }
+       }
+      if (ed->boxplots == BOXPLOT_FACTORS)
+       g_string_append (str, "\n\t/COMPARE = GROUPS");
+      if (ed->boxplots == BOXPLOT_DEPENDENTS)
+       g_string_append (str, "\n\t/COMPARE = VARIABLES");
+    }
 
   g_string_append (str, "\n\t/MISSING=");
   switch (ed->opts)
@@ -193,8 +359,15 @@ dialog_refresh (PsppireDialogAction *da)
   gtk_list_store_clear (GTK_LIST_STORE (liststore));
 
   gtk_entry_set_text (GTK_ENTRY (dae->id_var), "");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dae->display_both_button), TRUE);
+
   dae->stats = 0x00;
   dae->opts = OPT_LISTWISE;
+  dae->boxplots = BOXPLOT_FACTORS;
+  dae->histogram = TRUE;
+  dae->npplots = FALSE;
+  dae->spreadlevel = SPREAD_NONE;
+  dae->spreadpower = SPREADPOWER_NATLOG;
 }
 
 static GtkBuilder *
@@ -207,12 +380,15 @@ psppire_dialog_action_examine_activate (PsppireDialogAction *a, GVariant *param)
 
   GtkWidget *stats_button = get_widget_assert (xml, "stats-button");
   GtkWidget *opts_button = get_widget_assert (xml, "opts-button");
+  GtkWidget *plots_button = get_widget_assert (xml, "plots-button");
 
   g_signal_connect_swapped (stats_button, "clicked",
                            G_CALLBACK (run_stats_dialog), act);
 
   g_signal_connect_swapped (opts_button, "clicked",
                            G_CALLBACK (run_opts_dialog), act);
+  g_signal_connect_swapped (plots_button, "clicked",
+                           G_CALLBACK (run_plots_dialog), act);
 
   GtkWidget *dep_sel = get_widget_assert (xml, "psppire-selector1");
   GtkWidget *dep_sel2 = get_widget_assert (xml, "psppire-selector2");
@@ -224,6 +400,9 @@ psppire_dialog_action_examine_activate (PsppireDialogAction *a, GVariant *param)
   act->variables = get_widget_assert   (xml, "treeview2");
   act->factors   = get_widget_assert   (xml, "treeview3");
   act->id_var    = get_widget_assert   (xml, "entry1");
+  act->display_both_button  = get_widget_assert (xml, "display-both-button");
+  act->display_stats_button = get_widget_assert (xml, "display-stats-button");
+  act->display_plots_button = get_widget_assert (xml, "display-plots-button");
 
   /* Setting the focus chain like this is a pain.
      But the default focus order seems to be somewhat odd. */
@@ -249,6 +428,18 @@ psppire_dialog_action_examine_activate (PsppireDialogAction *a, GVariant *param)
   act->pairwise    = get_widget_assert (xml, "radiobutton2");
   act->report      = get_widget_assert (xml, "radiobutton3");
 
+  act->plots_dialog              = get_widget_assert (xml, "plots-dialog");
+  act->boxplot_factors_button    = get_widget_assert (xml, "boxplot-factors-button");
+  act->boxplot_dependents_button = get_widget_assert (xml, "boxplot-dependents-button");
+  act->boxplot_none_button       = get_widget_assert (xml, "boxplot-none-button");
+  act->histogram_button          = get_widget_assert (xml, "histogram-button");
+  act->npplots_button            = get_widget_assert (xml, "npplots-button");
+  act->spread_none_button        = get_widget_assert (xml, "spread-none-button");
+  act->spread_power_button       = get_widget_assert (xml, "spread-power-button");
+  act->spread_trans_button       = get_widget_assert (xml, "spread-trans-button");
+  act->spread_untrans_button     = get_widget_assert (xml, "spread-untrans-button");
+  act->spread_power_combo        = get_widget_assert (xml, "spread-power-combo");
+
   psppire_selector_set_allow (PSPPIRE_SELECTOR (dep_sel), numeric_only);
 
   psppire_dialog_action_set_valid_predicate (pda, (void *) dialog_state_valid);