1 /* PSPPIRE - a graphical user interface for PSPP.
2 Copyright (C) 2015 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-barchart.h"
21 #include "psppire-value-entry.h"
22
23 #include "dialog-common.h"
24 #include <ui/syntax-gen.h>
25 #include "psppire-var-view.h"
26
27 #include "psppire-dialog.h"
28 #include "builder-wrapper.h"
29
30 #include "psppire-dict.h"
31 #include "libpspp/str.h"
32
33 #include "language/stats/chart-category.h"
34
35 static void
36 psppire_dialog_action_barchart_class_init (PsppireDialogActionBarchartClass *class);
37
38 G_DEFINE_TYPE (PsppireDialogActionBarchart, psppire_dialog_action_barchart, PSPPIRE_TYPE_DIALOG_ACTION);
39
40 static gboolean
dialog_state_valid(gpointer rd_)41 dialog_state_valid (gpointer rd_)
42 {
43 PsppireDialogActionBarchart *rd = PSPPIRE_DIALOG_ACTION_BARCHART (rd_);
44
45 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->button_summary_func)))
46 {
47 if (0 == g_strcmp0 ("", gtk_entry_get_text (GTK_ENTRY (rd->var))))
48 return FALSE;
49 }
50
51 if (0 == g_strcmp0 ("", gtk_entry_get_text (GTK_ENTRY (rd->variable_xaxis))))
52 return FALSE;
53
54 return TRUE;
55 }
56
57 static void
refresh(PsppireDialogAction * rd_)58 refresh (PsppireDialogAction *rd_)
59 {
60 PsppireDialogActionBarchart *rd = PSPPIRE_DIALOG_ACTION_BARCHART (rd_);
61
62 gtk_entry_set_text (GTK_ENTRY (rd->var), "");
63 gtk_entry_set_text (GTK_ENTRY (rd->variable_xaxis), "");
64 gtk_entry_set_text (GTK_ENTRY (rd->variable_cluster), "");
65
66 /* Set summary_func to true, then let it get unset again.
67 This ensures that the signal handler gets called. */
68 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rd->button_summary_func), TRUE);
69 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rd->button_freq_func[0]), TRUE);
70
71 gtk_widget_set_sensitive (rd->combobox, FALSE);
72
73 gtk_combo_box_set_active (GTK_COMBO_BOX (rd->combobox), 0);
74 }
75
76 static void
on_summary_toggle(PsppireDialogActionBarchart * act)77 on_summary_toggle (PsppireDialogActionBarchart *act)
78 {
79 gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (act->button_summary_func));
80
81 gtk_widget_set_sensitive (act->summary_variables, status);
82 gtk_widget_set_sensitive (act->combobox, status);
83 }
84
85 static void
populate_combo_model(GtkComboBox * cb)86 populate_combo_model (GtkComboBox *cb)
87 {
88 int i;
89 GtkListStore *list = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT);
90 GtkTreeIter iter;
91 GtkCellRenderer *renderer ;
92
93 for (i = 0; i < N_AG_FUNCS; ++i)
94 {
95 const struct ag_func *af = ag_func + i;
96
97 if (af->arity == 0)
98 continue;
99
100 gtk_list_store_append (list, &iter);
101 gtk_list_store_set (list, &iter,
102 0, af->description,
103 1, af->name,
104 -1);
105 }
106
107 renderer = gtk_cell_renderer_text_new ();
108 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cb), renderer, FALSE);
109
110 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (cb), renderer, "text", 0);
111
112 gtk_combo_box_set_model (GTK_COMBO_BOX (cb), GTK_TREE_MODEL (list));
113 g_object_unref (list);
114 }
115
116
117 static GtkBuilder *
psppire_dialog_action_barchart_activate(PsppireDialogAction * a,GVariant * param)118 psppire_dialog_action_barchart_activate (PsppireDialogAction *a, GVariant *param)
119 {
120 PsppireDialogActionBarchart *act = PSPPIRE_DIALOG_ACTION_BARCHART (a);
121 PsppireDialogAction *pda = PSPPIRE_DIALOG_ACTION (a);
122
123 GtkBuilder *xml = builder_new ("barchart.ui");
124
125 pda->dialog = get_widget_assert (xml, "barchart-dialog");
126 pda->source = get_widget_assert (xml, "dict-view");
127
128 act->variable_xaxis = get_widget_assert (xml, "entry1");
129 act->variable_cluster = get_widget_assert (xml, "entry3");
130 act->var = get_widget_assert (xml, "entry2");
131 act->button_freq_func[0] = get_widget_assert (xml, "radiobutton-count");
132 act->button_freq_func[1] = get_widget_assert (xml, "radiobutton-percent");
133 act->button_freq_func[2] = get_widget_assert (xml, "radiobutton-cum-count");
134 act->button_freq_func[3] = get_widget_assert (xml, "radiobutton-cum-percent");
135
136 act->button_summary_func = get_widget_assert (xml, "radiobutton3");
137 act->summary_variables = get_widget_assert (xml, "hbox1");
138 act->combobox = get_widget_assert (xml, "combobox1");
139
140 populate_combo_model (GTK_COMBO_BOX(act->combobox));
141
142 g_signal_connect_swapped (act->button_summary_func, "toggled",
143 G_CALLBACK (on_summary_toggle), act);
144
145 psppire_dialog_action_set_refresh (pda, refresh);
146
147 psppire_dialog_action_set_valid_predicate (pda,
148 dialog_state_valid);
149
150 return xml;
151 }
152
153 static char *
generate_syntax(const PsppireDialogAction * a)154 generate_syntax (const PsppireDialogAction *a)
155 {
156 PsppireDialogActionBarchart *rd = PSPPIRE_DIALOG_ACTION_BARCHART (a);
157 gchar *text;
158 const gchar *var_name_xaxis = gtk_entry_get_text (GTK_ENTRY (rd->variable_xaxis));
159 const gchar *var_name_cluster = gtk_entry_get_text (GTK_ENTRY (rd->variable_cluster));
160
161 GString *string = g_string_new ("GRAPH /BAR = ");
162
163 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->button_summary_func)))
164 {
165 GtkTreeIter iter;
166 if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (rd->combobox), &iter))
167 {
168 GValue value = {0};
169 GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (rd->combobox));
170 gtk_tree_model_get_value (model, &iter, 1, &value);
171 g_string_append (string, g_value_get_string (&value));
172 g_value_unset (&value);
173 }
174 g_string_append (string, " (");
175 g_string_append (string, gtk_entry_get_text (GTK_ENTRY (rd->var)));
176 g_string_append (string, ")");
177 }
178 else
179 {
180 int b;
181 for (b = 0; b < 4; ++b)
182 {
183 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->button_freq_func[b])))
184 break;
185 }
186 switch (b)
187 {
188 case 0:
189 g_string_append (string, "COUNT");
190 break;
191 case 1:
192 g_string_append (string, "PCT");
193 break;
194 case 2:
195 g_string_append (string, "CUFREQ");
196 break;
197 case 3:
198 g_string_append (string, "CUPCT");
199 break;
200 default:
201 g_assert_not_reached ();
202 break;
203 }
204 }
205
206 g_string_append (string, " BY ");
207 g_string_append (string, var_name_xaxis);
208
209 if (g_strcmp0 (var_name_cluster, ""))
210 {
211 g_string_append (string, " BY ");
212 g_string_append (string, var_name_cluster);
213 }
214
215 g_string_append (string, ".\n");
216
217 text = string->str;
218
219 g_string_free (string, FALSE);
220
221 return text;
222 }
223
224 static void
psppire_dialog_action_barchart_class_init(PsppireDialogActionBarchartClass * class)225 psppire_dialog_action_barchart_class_init (PsppireDialogActionBarchartClass *class)
226 {
227 PSPPIRE_DIALOG_ACTION_CLASS (class)->initial_activate = psppire_dialog_action_barchart_activate;
228
229 PSPPIRE_DIALOG_ACTION_CLASS (class)->generate_syntax = generate_syntax;
230 }
231
232
233 static void
psppire_dialog_action_barchart_init(PsppireDialogActionBarchart * act)234 psppire_dialog_action_barchart_init (PsppireDialogActionBarchart *act)
235 {
236 }
237