Update Spanish translation
[gnumeric.git] / src / dialogs / dialog-analysis-tools.c
blobc2a731997ef41868b94e4a037d91792da64ae061
1 /*
2 * dialog-analysis-tools.c:
4 * Authors:
5 * Jukka-Pekka Iivonen <jiivonen@hutcs.cs.hut.fi>
6 * Andreas J. Guelzow <aguelzow@taliesin.ca>
8 * (C) Copyright 2000, 2001 by Jukka-Pekka Iivonen <jiivonen@hutcs.cs.hut.fi>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <https://www.gnu.org/licenses/>.
24 #include <gnumeric-config.h>
25 #include <glib/gi18n-lib.h>
26 #include <gnumeric.h>
27 #include <dialogs/dialogs.h>
28 #include <tools/analysis-tools.h>
29 #include <tools/analysis-anova.h>
30 #include <tools/analysis-histogram.h>
31 #include <tools/analysis-exp-smoothing.h>
33 #include <workbook.h>
34 #include <workbook-control.h>
35 #include <wbc-gtk.h>
36 #include <workbook-view.h>
37 #include <gui-util.h>
38 #include <parse-util.h>
39 #include <gnm-format.h>
40 #include <dialogs/tool-dialogs.h>
41 #include <dialogs/dao-gui-utils.h>
42 #include <sheet.h>
43 #include <expr.h>
44 #include <number-match.h>
45 #include <ranges.h>
46 #include <selection.h>
47 #include <value.h>
48 #include <commands.h>
49 #include <dialogs/help.h>
51 #include <widgets/gnm-dao.h>
52 #include <widgets/gnm-expr-entry.h>
54 #include <string.h>
56 /**********************************************/
57 /* Generic guru items */
58 /**********************************************/
62 #define CORRELATION_KEY "analysistools-correlation-dialog"
63 #define COVARIANCE_KEY "analysistools-covariance-dialog"
64 #define DESCRIPTIVE_STATS_KEY "analysistools-descriptive-stats-dialog"
65 #define RANK_PERCENTILE_KEY "analysistools-rank-percentile-dialog"
66 #define TTEST_KEY "analysistools-ttest-dialog"
67 #define FTEST_KEY "analysistools-ftest-dialog"
68 #define SAMPLING_KEY "analysistools-sampling-dialog"
69 #define HISTOGRAM_KEY "analysistools-histogram-dialog"
70 #define FOURIER_KEY "analysistools-fourier-dialog"
71 #define AVERAGE_KEY "analysistools-moving-average-dialog"
72 #define EXP_SMOOTHING_KEY "analysistools-exp-smoothing-dialog"
73 #define REGRESSION_KEY "analysistools-regression-dialog"
74 #define ANOVA_TWO_FACTOR_KEY "analysistools-anova-two-factor-dialog"
75 #define ANOVA_SINGLE_KEY "analysistools-anova-single-factor-dialog"
78 static char const * const grouped_by_group[] = {
79 "grouped_by_row",
80 "grouped_by_col",
81 "grouped_by_area",
82 NULL
85 typedef struct {
86 GnmGenericToolState base;
87 GtkWidget *predetermined_button;
88 GtkWidget *calculated_button;
89 GtkEntry *n_entry;
90 GtkEntry *max_entry;
91 GtkEntry *min_entry;
92 } HistogramToolState;
94 static char const * const bin_type_group[] = {
95 "bintype_no_inf_lower",
96 "bintype_no_inf_upper",
97 "bintype_p_inf_lower",
98 "bintype_p_inf_upper",
99 "bintype_m_inf_lower",
100 "bintype_m_inf_upper",
101 "bintype_pm_inf_lower",
102 "bintype_pm_inf_upper",
103 NULL
106 static char const * const chart_group[] = {
107 "nochart-button",
108 "histogram-button",
109 "barchart-button",
110 "columnchart-button",
111 NULL
114 static char const * const n_group[] = {
115 "n-button",
116 "nm1-button",
117 "nm2-button",
118 "nm3-button",
119 NULL
122 /* Note: the items in this group need to match */
123 /* moving_average_type_t except that */
124 /* moving_average_type_central_sma is a */
125 /* subtype of moving_average_type_sma. */
126 static char const * const moving_average_group[] = {
127 "sma-button",
128 "cma-button",
129 "wma-button",
130 "spencer-ma-button",
131 NULL
134 static char const * const exp_smoothing_group[] = {
135 "ses-h-button",
136 "ses-r-button",
137 "des-button",
138 "ates-button",
139 "mtes-button",
140 NULL
145 typedef struct {
146 GnmGenericToolState base;
147 GtkWidget *summary_stats_button;
148 GtkWidget *mean_stats_button;
149 GtkWidget *kth_largest_button;
150 GtkWidget *kth_smallest_button;
151 GtkWidget *ss_button;
152 GtkWidget *c_entry;
153 GtkWidget *l_entry;
154 GtkWidget *s_entry;
155 } DescriptiveStatState;
157 typedef struct {
158 GnmGenericToolState base;
159 GtkWidget *paired_button;
160 GtkWidget *unpaired_button;
161 GtkWidget *known_button;
162 GtkWidget *unknown_button;
163 GtkWidget *equal_button;
164 GtkWidget *unequal_button;
165 GtkWidget *variablespaired_label;
166 GtkWidget *varianceknown_label;
167 GtkWidget *varianceequal_label;
168 GtkWidget *var1_variance_label;
169 GtkWidget *var2_variance_label;
170 GtkWidget *var1_variance;
171 GtkWidget *var2_variance;
172 GtkWidget *options_grid;
173 GtkWidget *mean_diff_entry;
174 GtkWidget *alpha_entry;
175 ttest_type invocation;
176 } TTestState;
178 typedef struct {
179 GnmGenericToolState base;
180 GtkWidget *options_grid;
181 GtkWidget *method_label;
182 GtkWidget *periodic_button;
183 GtkWidget *random_button;
184 GtkWidget *period_label;
185 GtkWidget *random_label;
186 GtkWidget *period_entry;
187 GtkWidget *random_entry;
188 GtkWidget *number_entry;
189 GtkWidget *offset_label;
190 GtkWidget *offset_entry;
191 GtkWidget *major_label;
192 GtkWidget *row_major_button;
193 GtkWidget *col_major_button;
194 } SamplingState;
196 typedef struct {
197 GnmGenericToolState base;
198 GtkWidget *interval_entry;
199 GtkWidget *show_std_errors;
200 GtkWidget *n_button;
201 GtkWidget *nm1_button;
202 GtkWidget *nm2_button;
203 GtkWidget *prior_button;
204 GtkWidget *central_button;
205 GtkWidget *offset_button;
206 GtkWidget *offset_spin;
207 GtkWidget *graph_button;
208 GtkWidget *sma_button;
209 GtkWidget *cma_button;
210 GtkWidget *wma_button;
211 GtkWidget *spencer_button;
212 } AverageToolState;
214 typedef struct {
215 GnmGenericToolState base;
216 GtkWidget *damping_fact_entry;
217 GtkWidget *g_damping_fact_entry;
218 GtkWidget *s_damping_fact_entry;
219 GtkWidget *s_period_entry;
220 GtkWidget *show_std_errors;
221 GtkWidget *n_button;
222 GtkWidget *nm1_button;
223 GtkWidget *nm2_button;
224 GtkWidget *nm3_button;
225 GtkWidget *graph_button;
226 GtkWidget *ses_h_button;
227 GtkWidget *ses_r_button;
228 GtkWidget *des_button;
229 GtkWidget *ates_button;
230 GtkWidget *mtes_button;
231 } ExpSmoothToolState;
233 typedef struct {
234 GnmGenericToolState base;
235 GtkWidget *confidence_entry;
236 GtkWidget *simple_linear_regression_radio;
237 GtkWidget *switch_variables_check;
238 GtkWidget *residuals_check;
239 } RegressionToolState;
241 typedef struct {
242 GnmGenericToolState base;
243 GtkWidget *alpha_entry;
244 } AnovaSingleToolState;
246 typedef struct {
247 GnmGenericToolState base;
248 GtkWidget *alpha_entry;
249 GtkWidget *replication_entry;
250 } AnovaTwoFactorToolState;
252 typedef struct {
253 GnmGenericToolState base;
254 GtkWidget *alpha_entry;
255 } FTestToolState;
258 /**********************************************/
259 /* Generic functions for the analysis tools. */
260 /* Functions in this section are being used */
261 /* by virtually all tools. */
262 /**********************************************/
266 * error_in_entry:
267 * @state:
268 * @entry:
269 * @err_str:
271 * Show an error dialog and select corresponding entry
273 void
274 error_in_entry (GnmGenericToolState *state, GtkWidget *entry, char const *err_str)
276 go_gtk_notice_nonmodal_dialog ((GtkWindow *) state->dialog,
277 &(state->warning_dialog),
278 GTK_MESSAGE_ERROR,
279 "%s", err_str);
281 if (GNM_EXPR_ENTRY_IS (entry))
282 gnm_expr_entry_grab_focus (GNM_EXPR_ENTRY (entry), TRUE);
283 else
284 focus_on_entry (GTK_ENTRY (entry));
287 static void
288 cb_tool_destroy (GnmGenericToolState *state)
290 if (state->gui != NULL)
291 g_object_unref (state->gui);
292 wbcg_edit_finish (state->wbcg, WBC_EDIT_REJECT, NULL);
293 if (state->state_destroy)
294 state->state_destroy (state);
295 g_free (state);
299 * cb_tool_cancel_clicked:
300 * @button:
301 * @state:
303 * Close (destroy) the dialog
305 static void
306 cb_tool_cancel_clicked (G_GNUC_UNUSED GtkWidget *button,
307 GnmGenericToolState *state)
309 gtk_widget_destroy (state->dialog);
310 return;
316 * dialog_tool_init_buttons:
317 * @state:
318 * @ok_function:
320 * Setup the buttons
323 static void
324 dialog_tool_init_buttons (GnmGenericToolState *state,
325 GCallback ok_function,
326 GCallback close_function)
328 state->ok_button = go_gtk_builder_get_widget (state->gui, "okbutton");
329 g_signal_connect (G_OBJECT (state->ok_button),
330 "clicked",
331 G_CALLBACK (ok_function), state);
333 state->cancel_button = go_gtk_builder_get_widget (state->gui,
334 "cancelbutton");
335 if (close_function == NULL)
336 g_signal_connect (G_OBJECT (state->cancel_button),
337 "clicked",
338 G_CALLBACK (cb_tool_cancel_clicked), state);
339 else
340 g_signal_connect (G_OBJECT (state->cancel_button),
341 "clicked",
342 G_CALLBACK (close_function), state);
344 state->apply_button = go_gtk_builder_get_widget (state->gui, "applybutton");
345 if (state->apply_button != NULL )
346 g_signal_connect (G_OBJECT (state->apply_button),
347 "clicked",
348 G_CALLBACK (ok_function), state);
349 state->help_button = go_gtk_builder_get_widget (state->gui, "helpbutton");
350 if (state->help_button != NULL )
351 gnm_init_help_button (state->help_button,
352 state->help_link);
357 * dialog_tool_init: (skip)
358 * @state:
359 * @gui_name:
360 * @dialog_name:
361 * @ok_function:
362 * @sensitivity_cb:
364 * Create the dialog (guru).
367 gboolean
368 dialog_tool_init (GnmGenericToolState *state,
369 WBCGtk *wbcg,
370 Sheet *sheet,
371 char const *help_file,
372 char const *gui_name,
373 char const *dialog_name,
374 char const *error_str,
375 char const *key,
376 GCallback ok_function,
377 GCallback close_function,
378 GCallback sensitivity_cb,
379 GnmExprEntryFlags flags)
381 GtkGrid *grid;
382 GtkWidget *widget;
384 state->wbcg = wbcg;
385 state->wb = wb_control_get_workbook (GNM_WBC (wbcg));
386 state->sheet = sheet;
387 state->sv = wb_control_cur_sheet_view (GNM_WBC (wbcg));
388 state->warning_dialog = NULL;
389 state->help_link = help_file;
390 state->state_destroy = NULL;
392 state->gui = gnm_gtk_builder_load (gui_name, NULL, GO_CMD_CONTEXT (wbcg));
393 if (state->gui == NULL)
394 goto dialog_tool_init_error;
396 state->dialog = go_gtk_builder_get_widget (state->gui, dialog_name);
397 if (state->dialog == NULL)
398 goto dialog_tool_init_error;
401 dialog_tool_init_buttons (state, ok_function, close_function);
403 widget = go_gtk_builder_get_widget (state->gui, "var1-label");
404 if (widget == NULL) {
405 state->input_entry = NULL;
406 } else {
407 guint left_attach, top_attach, width, height;
409 grid = GTK_GRID (gtk_widget_get_parent (widget));
410 state->input_entry = gnm_expr_entry_new (state->wbcg, TRUE);
411 g_object_set (G_OBJECT (state->input_entry), "hexpand", TRUE, NULL);
412 gnm_expr_entry_disable_tips (state->input_entry);
413 gnm_expr_entry_set_flags (state->input_entry,
414 flags | GNM_EE_FORCE_ABS_REF,
415 GNM_EE_MASK);
417 gtk_container_child_get (GTK_CONTAINER (grid), widget,
418 "left-attach", &left_attach,
419 "top-attach", &top_attach,
420 "width", &width,
421 "height", &height,
422 NULL);
424 gtk_grid_attach (grid, GTK_WIDGET (state->input_entry),
425 left_attach + width, top_attach,
426 1, height);
427 g_signal_connect_after (G_OBJECT (state->input_entry),
428 "changed",
429 G_CALLBACK (sensitivity_cb), state);
430 gnm_editable_enters (GTK_WINDOW (state->dialog),
431 GTK_WIDGET (state->input_entry));
432 gtk_label_set_mnemonic_widget (GTK_LABEL (widget),
433 GTK_WIDGET (state->input_entry));
434 go_atk_setup_label (widget, GTK_WIDGET (state->input_entry));
435 gtk_widget_show (GTK_WIDGET (state->input_entry));
439 /* */
440 /* If there is a var2-label, we need a second input field */
441 /* */
442 widget = go_gtk_builder_get_widget (state->gui, "var2-label");
443 if (widget == NULL) {
444 state->input_entry_2 = NULL;
445 } else {
446 guint left_attach, top_attach, width, height;
448 state->input_entry_2 = gnm_expr_entry_new (state->wbcg, TRUE);
449 g_object_set (G_OBJECT (state->input_entry_2), "hexpand", TRUE, NULL);
450 gnm_expr_entry_disable_tips (state->input_entry_2);
451 gnm_expr_entry_set_flags (state->input_entry_2,
452 GNM_EE_SINGLE_RANGE | GNM_EE_FORCE_ABS_REF, GNM_EE_MASK);
453 grid = GTK_GRID (gtk_widget_get_parent (widget));
455 gtk_container_child_get (GTK_CONTAINER (grid), widget,
456 "left-attach", &left_attach,
457 "top-attach", &top_attach,
458 "width", &width,
459 "height", &height,
460 NULL);
462 gtk_grid_attach (grid, GTK_WIDGET (state->input_entry_2),
463 left_attach + width, top_attach,
464 1, height);
465 g_signal_connect_after (G_OBJECT (state->input_entry_2),
466 "changed",
467 G_CALLBACK (sensitivity_cb), state);
468 gnm_editable_enters (GTK_WINDOW (state->dialog),
469 GTK_WIDGET (state->input_entry_2));
470 gtk_label_set_mnemonic_widget (GTK_LABEL (widget),
471 GTK_WIDGET (state->input_entry_2));
472 go_atk_setup_label (widget, GTK_WIDGET (state->input_entry_2));
473 gtk_widget_show (GTK_WIDGET (state->input_entry_2));
476 state->warning = go_gtk_builder_get_widget (state->gui, "warnings");
477 wbc_gtk_attach_guru (state->wbcg, state->dialog);
478 g_object_set_data_full (G_OBJECT (state->dialog),
479 "state", state, (GDestroyNotify) cb_tool_destroy);
481 dialog_tool_init_outputs (state, sensitivity_cb);
483 gnm_keyed_dialog (wbcg, GTK_WINDOW (state->dialog), key);
485 gnm_dialog_setup_destroy_handlers (GTK_DIALOG (state->dialog),
486 state->wbcg,
487 GNM_DIALOG_DESTROY_SHEET_REMOVED |
488 GNM_DIALOG_DESTROY_SHEET_RENAMED);
490 return FALSE;
492 dialog_tool_init_error:
493 go_gtk_notice_dialog (wbcg_toplevel (wbcg),
494 GTK_MESSAGE_ERROR,
495 "%s", error_str);
496 g_free (state);
497 return TRUE;
501 * tool_load_selection:
502 * @state:
504 * load the current selection in the output and input entries
505 * show the dialog and focus the input_entry
508 void
509 tool_load_selection (GnmGenericToolState *state, gboolean allow_multiple)
511 GnmRange const *first = selection_first_range (state->sv, NULL, NULL);
513 if (first != NULL) {
514 if (allow_multiple) {
515 char *text = selection_to_string (state->sv, TRUE);
516 gnm_expr_entry_load_from_text (state->input_entry,
517 text);
518 g_free (text);
519 } else
520 gnm_expr_entry_load_from_range (state->input_entry,
521 state->sheet, first);
522 if (state->gdao != NULL)
523 gnm_dao_load_range (GNM_DAO (state->gdao), first);
526 gtk_widget_show (state->dialog);
527 gnm_expr_entry_grab_focus (GNM_EXPR_ENTRY (state->input_entry),
528 TRUE);
533 * tool_setup_update: (skip)
535 GtkWidget *
536 tool_setup_update (GnmGenericToolState* state, char const *name, GCallback cb,
537 gpointer closure)
539 GtkWidget *w = go_gtk_builder_get_widget (state->gui, name);
540 if (GTK_IS_SPIN_BUTTON (w)) {
541 g_signal_connect_after (w, "value-changed", cb, closure);
542 gnm_editable_enters (GTK_WINDOW (state->dialog), w);
543 } else if (GTK_IS_ENTRY (w)) {
544 g_signal_connect_after (w, "changed", cb, closure);
545 gnm_editable_enters (GTK_WINDOW (state->dialog), w);
546 } else if (GTK_IS_TOGGLE_BUTTON (w))
547 g_signal_connect_after (w, "toggled", cb, closure);
548 else
549 g_warning ("tool_setup_update called with unknown type");
550 return w;
556 /**********************************************/
557 /* Generic functions for the analysis tools */
558 /* Functions in this section are being used */
559 /* some tools */
560 /**********************************************/
563 * tool_update_sensitivity_cb:
564 * @dummy:
565 * @state:
567 * Update the dialog widgets sensitivity if the only items of interest
568 * are one or two standard input and one output item, permitting multiple
569 * areas as first input.
571 * used by:
572 * Correlation
573 * Covariance
574 * RankPercentile
575 * FourierAnalysis
578 static void
579 tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
580 GnmGenericToolState *state)
582 GSList *input_range;
584 /* Checking Input Range */
585 input_range = gnm_expr_entry_parse_as_list (
586 GNM_EXPR_ENTRY (state->input_entry), state->sheet);
587 if (input_range == NULL) {
588 gtk_label_set_text (GTK_LABEL (state->warning),
589 _("The input range is invalid."));
590 gtk_widget_set_sensitive (state->ok_button, FALSE);
591 return;
592 } else
593 range_list_destroy (input_range);
595 /* Checking Output Page */
596 if (!gnm_dao_is_ready (GNM_DAO (state->gdao))) {
597 gtk_label_set_text (GTK_LABEL (state->warning),
598 _("The output specification "
599 "is invalid."));
600 gtk_widget_set_sensitive (state->ok_button, FALSE);
601 return;
604 gtk_label_set_text (GTK_LABEL (state->warning), "");
605 gtk_widget_set_sensitive (state->ok_button, TRUE);
607 return;
610 /**********************************************/
611 /* Begin of correlation tool code */
612 /**********************************************/
616 * corr_tool_ok_clicked_cb:
617 * @button:
618 * @state:
620 * Retrieve the information from the dialog and call the correlation_tool.
621 * Note that we assume that the ok_button is only active if the entry fields
622 * contain sensible data.
624 static void
625 corr_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
626 GnmGenericToolState *state)
628 data_analysis_output_t *dao;
629 analysis_tools_data_generic_t *data;
631 char *text;
632 GtkWidget *w;
634 if (state->warning_dialog != NULL)
635 gtk_widget_destroy (state->warning_dialog);
637 data = g_new0 (analysis_tools_data_generic_t, 1);
638 dao = parse_output (state, NULL);
640 data->input = gnm_expr_entry_parse_as_list (
641 GNM_EXPR_ENTRY (state->input_entry), state->sheet);
642 data->group_by = gnm_gui_group_value (state->gui, grouped_by_group);
644 w = go_gtk_builder_get_widget (state->gui, "labels_button");
645 data->labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
647 if (cmd_analysis_tool (GNM_WBC (state->wbcg), state->sheet,
648 dao, data, analysis_tool_correlation_engine, FALSE)) {
650 switch (data->err - 1) {
651 case GROUPED_BY_ROW:
652 error_in_entry ((GnmGenericToolState *) state,
653 GTK_WIDGET (state->input_entry),
654 _("The selected input rows must have equal size!"));
655 break;
656 case GROUPED_BY_COL:
657 error_in_entry ((GnmGenericToolState *) state,
658 GTK_WIDGET (state->input_entry),
659 _("The selected input columns must have equal size!"));
660 break;
661 case GROUPED_BY_AREA:
662 error_in_entry ((GnmGenericToolState *) state,
663 GTK_WIDGET (state->input_entry),
664 _("The selected input areas must have equal size!"));
665 break;
666 default:
667 text = g_strdup_printf (
668 _("An unexpected error has occurred: %d."), data->err);
669 error_in_entry ((GnmGenericToolState *) state,
670 GTK_WIDGET (state->input_entry), text);
671 g_free (text);
672 break;
674 range_list_destroy (data->input);
675 g_free (dao);
676 g_free (data);
677 } else
678 gtk_widget_destroy (state->dialog);
679 return;
685 * dialog_correlation_tool:
686 * @wbcg:
687 * @sheet:
689 * Show the dialog (guru).
693 dialog_correlation_tool (WBCGtk *wbcg, Sheet *sheet)
695 GnmGenericToolState *state;
696 char const * plugins[] = { "Gnumeric_fnstat",
697 NULL};
699 if ((wbcg == NULL) ||
700 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
701 return 1;
703 /* Only pop up one copy per workbook */
704 if (gnm_dialog_raise_if_exists (wbcg, CORRELATION_KEY))
705 return 0;
707 state = g_new0 (GnmGenericToolState, 1);
709 if (dialog_tool_init (state, wbcg, sheet,
710 GNUMERIC_HELP_LINK_CORRELATION,
711 "res:ui/correlation.ui", "Correlation",
712 _("Could not create the Correlation Tool dialog."),
713 CORRELATION_KEY,
714 G_CALLBACK (corr_tool_ok_clicked_cb), NULL,
715 G_CALLBACK (tool_update_sensitivity_cb),
717 return 0;
719 gnm_dao_set_put (GNM_DAO (state->gdao), TRUE, TRUE);
720 tool_update_sensitivity_cb (NULL, state);
721 tool_load_selection ((GnmGenericToolState *)state, TRUE);
723 return 0;
726 /**********************************************/
727 /* End of correlation tool code */
728 /**********************************************/
730 /**********************************************/
731 /* Begin of covariance tool code */
732 /**********************************************/
736 * cov_tool_ok_clicked_cb:
737 * @button:
738 * @state:
740 * Retrieve the information from the dialog and call the covariance_tool.
741 * Note that we assume that the ok_button is only active if the entry fields
742 * contain sensible data.
744 static void
745 cov_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
746 GnmGenericToolState *state)
748 data_analysis_output_t *dao;
749 analysis_tools_data_generic_t *data;
751 char *text;
752 GtkWidget *w;
754 if (state->warning_dialog != NULL)
755 gtk_widget_destroy (state->warning_dialog);
757 data = g_new0 (analysis_tools_data_generic_t, 1);
758 dao = parse_output (state, NULL);
760 data->input = gnm_expr_entry_parse_as_list (
761 GNM_EXPR_ENTRY (state->input_entry), state->sheet);
762 data->group_by = gnm_gui_group_value (state->gui, grouped_by_group);
764 w = go_gtk_builder_get_widget (state->gui, "labels_button");
765 data->labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
767 if (cmd_analysis_tool (GNM_WBC (state->wbcg), state->sheet,
768 dao, data, analysis_tool_covariance_engine, FALSE)) {
770 switch (data->err - 1) {
771 case GROUPED_BY_ROW:
772 error_in_entry ((GnmGenericToolState *) state,
773 GTK_WIDGET (state->input_entry),
774 _("The selected input rows must have equal size!"));
775 break;
776 case GROUPED_BY_COL:
777 error_in_entry ((GnmGenericToolState *) state,
778 GTK_WIDGET (state->input_entry),
779 _("The selected input columns must have equal size!"));
780 break;
781 case GROUPED_BY_AREA:
782 error_in_entry ((GnmGenericToolState *) state,
783 GTK_WIDGET (state->input_entry),
784 _("The selected input areas must have equal size!"));
785 break;
786 default:
787 text = g_strdup_printf (
788 _("An unexpected error has occurred: %d."), data->err);
789 error_in_entry ((GnmGenericToolState *) state,
790 GTK_WIDGET (state->input_entry), text);
791 g_free (text);
792 break;
794 range_list_destroy (data->input);
795 g_free (dao);
796 g_free (data);
797 } else
798 gtk_widget_destroy (state->dialog);
799 return;
805 * dialog_covariance_tool:
806 * @wbcg:
807 * @sheet:
809 * Show the dialog (guru).
813 dialog_covariance_tool (WBCGtk *wbcg, Sheet *sheet)
815 GnmGenericToolState *state;
816 char const * plugins[] = { "Gnumeric_fnstat",
817 NULL};
819 if ((wbcg == NULL) ||
820 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
821 return 1;
823 /* Only pop up one copy per workbook */
824 if (gnm_dialog_raise_if_exists (wbcg, COVARIANCE_KEY))
825 return 0;
827 state = g_new0 (GnmGenericToolState, 1);
829 if (dialog_tool_init (state, wbcg, sheet,
830 GNUMERIC_HELP_LINK_COVARIANCE,
831 "res:ui/covariance.ui", "Covariance",
832 _("Could not create the Covariance Tool dialog."),
833 COVARIANCE_KEY,
834 G_CALLBACK (cov_tool_ok_clicked_cb), NULL,
835 G_CALLBACK (tool_update_sensitivity_cb),
837 return 0;
839 gnm_dao_set_put (GNM_DAO (state->gdao), TRUE, TRUE);
840 tool_update_sensitivity_cb (NULL, state);
841 tool_load_selection ((GnmGenericToolState *)state, TRUE);
843 return 0;
846 /**********************************************/
847 /* End of covariance tool code */
848 /**********************************************/
850 /**********************************************/
851 /* Begin of rank and percentile tool code */
852 /**********************************************/
856 * rank_tool_ok_clicked_cb:
857 * @button:
858 * @state:
860 * Retrieve the information from the dialog and call the ranking_tool.
861 * Note that we assume that the ok_button is only active if the entry fields
862 * contain sensible data.
864 static void
865 rank_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
866 GnmGenericToolState *state)
868 data_analysis_output_t *dao;
869 analysis_tools_data_ranking_t *data;
871 GtkWidget *w;
873 data = g_new0 (analysis_tools_data_ranking_t, 1);
874 dao = parse_output (state, NULL);
876 data->base.input = gnm_expr_entry_parse_as_list (
877 GNM_EXPR_ENTRY (state->input_entry), state->sheet);
878 data->base.group_by = gnm_gui_group_value (state->gui, grouped_by_group);
880 w = go_gtk_builder_get_widget (state->gui, "labels_button");
881 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
883 w = go_gtk_builder_get_widget (state->gui, "rank_button");
884 data->av_ties = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
887 if (!cmd_analysis_tool (GNM_WBC (state->wbcg), state->sheet,
888 dao, data, analysis_tool_ranking_engine, TRUE))
889 gtk_widget_destroy (state->dialog);
890 return;
896 * dialog_ranking_tool:
897 * @wbcg:
898 * @sheet:
900 * Show the dialog (guru).
904 dialog_ranking_tool (WBCGtk *wbcg, Sheet *sheet)
906 GnmGenericToolState *state;
907 char const * plugins[] = { "Gnumeric_fnstat",
908 "Gnumeric_fnlookup",
909 NULL};
911 if ((wbcg == NULL) ||
912 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
913 return 1;
915 /* Only pop up one copy per workbook */
916 if (gnm_dialog_raise_if_exists (wbcg, RANK_PERCENTILE_KEY))
917 return 0;
919 state = g_new0 (GnmGenericToolState, 1);
921 if (dialog_tool_init (state, wbcg, sheet,
922 GNUMERIC_HELP_LINK_RANKING,
923 "res:ui/rank.ui", "RankPercentile",
924 _("Could not create the Rank and Percentile "
925 "Tools dialog."),
926 RANK_PERCENTILE_KEY,
927 G_CALLBACK (rank_tool_ok_clicked_cb), NULL,
928 G_CALLBACK (tool_update_sensitivity_cb),
930 return 0;
932 gnm_dao_set_put (GNM_DAO (state->gdao), TRUE, TRUE);
933 tool_update_sensitivity_cb (NULL, state);
934 tool_load_selection ((GnmGenericToolState *)state, TRUE);
936 return 0;
939 /**********************************************/
940 /* End of rank and percentile tool code */
941 /**********************************************/
943 /**********************************************/
944 /* Begin of Fourier analysis tool code */
945 /**********************************************/
948 * fourier_tool_ok_clicked_cb:
949 * @button:
950 * @state:
952 * Retrieve the information from the dialog and call the fourier_tool.
953 * Note that we assume that the ok_button is only active if the entry fields
954 * contain sensible data.
956 static void
957 fourier_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
958 GnmGenericToolState *state)
960 data_analysis_output_t *dao;
961 analysis_tools_data_fourier_t *data;
963 GtkWidget *w;
965 data = g_new0 (analysis_tools_data_fourier_t, 1);
966 dao = parse_output (state, NULL);
968 data->base.wbc = GNM_WBC (state->wbcg);
969 data->base.input = gnm_expr_entry_parse_as_list (
970 GNM_EXPR_ENTRY (state->input_entry), state->sheet);
971 data->base.group_by = gnm_gui_group_value (state->gui, grouped_by_group);
973 w = go_gtk_builder_get_widget (state->gui, "labels_button");
974 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
976 w = go_gtk_builder_get_widget (state->gui, "inverse_button");
977 data->inverse = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)) != 0;
979 if (!cmd_analysis_tool (GNM_WBC (state->wbcg), state->sheet,
980 dao, data, analysis_tool_fourier_engine, TRUE))
981 gtk_widget_destroy (state->dialog);
983 return;
989 * dialog_fourier_tool:
990 * @wbcg:
991 * @sheet:
993 * Show the dialog (guru).
997 dialog_fourier_tool (WBCGtk *wbcg, Sheet *sheet)
999 GnmGenericToolState *state;
1000 char const * plugins[] = { "Gnumeric_fnTimeSeriesAnalysis",
1001 "Gnumeric_fncomplex",
1002 NULL};
1004 if ((wbcg == NULL) ||
1005 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
1006 return 1;
1008 /* Only pop up one copy per workbook */
1009 if (gnm_dialog_raise_if_exists (wbcg, FOURIER_KEY))
1010 return 0;
1012 state = g_new0 (GnmGenericToolState, 1);
1014 if (dialog_tool_init (state, wbcg, sheet,
1015 GNUMERIC_HELP_LINK_FOURIER_ANALYSIS,
1016 "res:ui/fourier-analysis.ui", "FourierAnalysis",
1017 _("Could not create the Fourier Analysis Tool "
1018 "dialog."),
1019 FOURIER_KEY,
1020 G_CALLBACK (fourier_tool_ok_clicked_cb), NULL,
1021 G_CALLBACK (tool_update_sensitivity_cb),
1023 return 0;
1025 gnm_dao_set_put (GNM_DAO (state->gdao), TRUE, TRUE);
1026 tool_update_sensitivity_cb (NULL, state);
1027 tool_load_selection ((GnmGenericToolState *)state, TRUE);
1029 return 0;
1032 /**********************************************/
1033 /* End of Fourier analysis tool code */
1034 /**********************************************/
1036 /**********************************************/
1037 /* Begin of descriptive statistics tool code */
1038 /**********************************************/
1041 * cb_desc_stat_tool_ok_clicked:
1042 * @button:
1043 * @state:
1045 * Retrieve the information from the dialog and call the descriptive_stat_tool.
1046 * Note that we assume that the ok_button is only active if the entry fields
1047 * contain sensible data.
1049 static void
1050 cb_desc_stat_tool_ok_clicked (G_GNUC_UNUSED GtkWidget *button,
1051 DescriptiveStatState *state)
1053 data_analysis_output_t *dao;
1054 analysis_tools_data_descriptive_t *data;
1056 GtkWidget *w;
1058 data = g_new0 (analysis_tools_data_descriptive_t, 1);
1059 dao = parse_output ((GnmGenericToolState *)state, NULL);
1061 data->base.input = gnm_expr_entry_parse_as_list (
1062 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
1063 data->base.group_by = gnm_gui_group_value (state->base.gui, grouped_by_group);
1065 data->summary_statistics = gtk_toggle_button_get_active (
1066 GTK_TOGGLE_BUTTON (state->summary_stats_button));
1067 data->confidence_level = gtk_toggle_button_get_active (
1068 GTK_TOGGLE_BUTTON (state->mean_stats_button));
1069 data->kth_largest = gtk_toggle_button_get_active (
1070 GTK_TOGGLE_BUTTON (state->kth_largest_button));
1071 data->kth_smallest = gtk_toggle_button_get_active (
1072 GTK_TOGGLE_BUTTON (state->kth_smallest_button));
1073 data->use_ssmedian = gtk_toggle_button_get_active (
1074 GTK_TOGGLE_BUTTON (state->ss_button));
1076 if (data->confidence_level == 1)
1077 data->c_level = gtk_spin_button_get_value
1078 (GTK_SPIN_BUTTON (state->c_entry));
1080 if (data->kth_largest == 1)
1081 entry_to_int (GTK_ENTRY (state->l_entry), &data->k_largest, TRUE);
1082 if (data->kth_smallest == 1)
1083 entry_to_int (GTK_ENTRY (state->s_entry), &data->k_smallest, TRUE);
1085 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
1086 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
1088 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
1089 dao, data, analysis_tool_descriptive_engine, TRUE))
1090 gtk_widget_destroy (state->base.dialog);
1091 return;
1095 * desc_stat_tool_update_sensitivity_cb:
1096 * @state:
1098 * Update the dialog widgets sensitivity.
1099 * We cannot use tool_update_sensitivity_cb
1100 * since we are also considering whether in fact
1101 * a statistic is selected.
1103 static void
1104 desc_stat_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
1105 DescriptiveStatState *state)
1107 gboolean stats_button, ci_button, largest_button, smallest_button;
1108 GSList *input_range;
1110 /* Part 1: set the buttons on the statistics page. */
1112 stats_button = gtk_toggle_button_get_active
1113 (GTK_TOGGLE_BUTTON (state->summary_stats_button));
1114 gtk_widget_set_sensitive (state->ss_button, stats_button);
1116 ci_button = gtk_toggle_button_get_active
1117 (GTK_TOGGLE_BUTTON (state->mean_stats_button));
1118 gtk_widget_set_sensitive (state->c_entry, ci_button);
1120 largest_button = gtk_toggle_button_get_active
1121 (GTK_TOGGLE_BUTTON (state->kth_largest_button));
1122 gtk_widget_set_sensitive (state->l_entry, largest_button);
1124 smallest_button = gtk_toggle_button_get_active
1125 (GTK_TOGGLE_BUTTON (state->kth_smallest_button));
1126 gtk_widget_set_sensitive (state->s_entry, smallest_button);
1128 /* Part 2: set the okay button */
1130 /* Checking Input Page */
1131 input_range = gnm_expr_entry_parse_as_list (
1132 GNM_EXPR_ENTRY (state->base.input_entry),
1133 state->base.sheet);
1134 if (input_range == NULL) {
1135 gtk_label_set_text (GTK_LABEL (state->base.warning),
1136 _("The input range is invalid."));
1137 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1138 return;
1139 } else
1140 range_list_destroy (input_range);
1142 /* Checking Statistics Page */
1143 if (!(stats_button || ci_button || largest_button || smallest_button)) {
1144 gtk_label_set_text (GTK_LABEL (state->base.warning),
1145 _("No statistics are selected."));
1146 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1147 return;
1150 if (ci_button) {
1151 gdouble c_level = gtk_spin_button_get_value
1152 (GTK_SPIN_BUTTON (state->c_entry));
1153 if (!(c_level > 0 && c_level <1)) {
1154 gtk_label_set_text (GTK_LABEL (state->base.warning),
1155 _("The confidence level should be "
1156 "between 0 and 1."));
1157 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1158 return;
1162 if (largest_button) {
1163 int k;
1164 if ((0 != entry_to_int (GTK_ENTRY (state->l_entry), &k, FALSE))
1165 || !(k >0)) {
1166 gtk_label_set_text (GTK_LABEL (state->base.warning),
1167 _("K must be a positive integer."));
1168 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1169 return;
1173 if (smallest_button) {
1174 int k;
1175 if ((0 != entry_to_int (GTK_ENTRY (state->s_entry), &k, FALSE))
1176 || !(k >0)) {
1177 gtk_label_set_text (GTK_LABEL (state->base.warning),
1178 _("K must be a positive integer."));
1179 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1180 return;
1184 /* Checking Output Page */
1185 if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
1186 gtk_label_set_text (GTK_LABEL (state->base.warning),
1187 _("The output specification "
1188 "is invalid."));
1189 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1190 return;
1193 gtk_label_set_text (GTK_LABEL (state->base.warning), "");
1194 gtk_widget_set_sensitive (state->base.ok_button, TRUE);
1196 return;
1201 * dialog_descriptive_stat_tool:
1202 * @wbcg:
1203 * @sheet:
1205 * Show the dialog (guru).
1209 dialog_descriptive_stat_tool (WBCGtk *wbcg, Sheet *sheet)
1211 DescriptiveStatState *state;
1212 char const * plugins[] = {"Gnumeric_fnstat",
1213 "Gnumeric_fnmath",
1214 NULL};
1216 if ((wbcg == NULL) ||
1217 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
1218 return 1;
1220 /* Only pop up one copy per workbook */
1221 if (gnm_dialog_raise_if_exists (wbcg, DESCRIPTIVE_STATS_KEY))
1222 return 0;
1224 state = g_new0 (DescriptiveStatState, 1);
1226 if (dialog_tool_init (&state->base, wbcg, sheet,
1227 GNUMERIC_HELP_LINK_DESCRIPTIVE_STATS,
1228 "res:ui/descriptive-stats.ui", "DescStats",
1229 _("Could not create the Descriptive Statistics "
1230 "Tool dialog."),
1231 DESCRIPTIVE_STATS_KEY,
1232 G_CALLBACK (cb_desc_stat_tool_ok_clicked), NULL,
1233 G_CALLBACK (desc_stat_tool_update_sensitivity_cb),
1236 g_free(state);
1237 return 0;
1240 state->summary_stats_button = go_gtk_builder_get_widget
1241 (state->base.gui, "summary_stats_button");
1242 state->ss_button = go_gtk_builder_get_widget
1243 (state->base.gui, "ss_button");
1244 state->mean_stats_button = go_gtk_builder_get_widget
1245 (state->base.gui, "mean_stats_button");
1246 state->kth_largest_button = go_gtk_builder_get_widget
1247 (state->base.gui, "kth_largest_button");
1248 state->kth_smallest_button = go_gtk_builder_get_widget
1249 (state->base.gui, "kth_smallest_button");
1250 state->c_entry = go_gtk_builder_get_widget (state->base.gui, "c_entry");
1251 gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->c_entry), 0.95);
1252 state->l_entry = go_gtk_builder_get_widget (state->base.gui, "l_entry");
1253 int_to_entry (GTK_ENTRY (state->l_entry), 1);
1254 state->s_entry = go_gtk_builder_get_widget (state->base.gui, "s_entry");
1255 int_to_entry (GTK_ENTRY (state->s_entry), 1);
1258 g_signal_connect_after (G_OBJECT (state->summary_stats_button),
1259 "toggled",
1260 G_CALLBACK (desc_stat_tool_update_sensitivity_cb), state);
1261 g_signal_connect_after (G_OBJECT (state->mean_stats_button),
1262 "toggled",
1263 G_CALLBACK (desc_stat_tool_update_sensitivity_cb), state);
1264 g_signal_connect_after (G_OBJECT (state->kth_largest_button),
1265 "toggled",
1266 G_CALLBACK (desc_stat_tool_update_sensitivity_cb), state);
1267 g_signal_connect_after (G_OBJECT (state->kth_smallest_button),
1268 "toggled",
1269 G_CALLBACK (desc_stat_tool_update_sensitivity_cb), state);
1270 g_signal_connect_after (G_OBJECT (state->c_entry),
1271 "changed",
1272 G_CALLBACK (desc_stat_tool_update_sensitivity_cb), state);
1273 g_signal_connect_after (G_OBJECT (state->l_entry),
1274 "changed",
1275 G_CALLBACK (desc_stat_tool_update_sensitivity_cb), state);
1276 g_signal_connect_after (G_OBJECT (state->s_entry),
1277 "changed",
1278 G_CALLBACK (desc_stat_tool_update_sensitivity_cb), state);
1279 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
1280 GTK_WIDGET (state->c_entry));
1281 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
1282 GTK_WIDGET (state->l_entry));
1283 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
1284 GTK_WIDGET (state->s_entry));
1286 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
1287 desc_stat_tool_update_sensitivity_cb (NULL, state);
1288 tool_load_selection ((GnmGenericToolState *)state, TRUE);
1290 return 0;
1294 /**********************************************/
1295 /* End of descriptive statistics tool code */
1296 /**********************************************/
1299 /**********************************************/
1300 /* Begin of ttest tool code */
1301 /**********************************************/
1304 * ttest_tool_ok_clicked_cb:
1305 * @button:
1306 * @state:
1308 * Retrieve the information from the dialog and call the appropriate tool.
1309 * Note that we assume that the ok_button is only active if the entry fields
1310 * contain sensible data.
1312 static void
1313 ttest_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
1314 TTestState *state)
1316 data_analysis_output_t *dao;
1317 analysis_tools_data_ttests_t *data;
1319 GtkWidget *w;
1320 int err = 0;
1322 data = g_new0 (analysis_tools_data_ttests_t, 1);
1323 dao = parse_output ((GnmGenericToolState *)state, NULL);
1325 data->base.wbc = GNM_WBC (state->base.wbcg);
1327 if (state->base.warning_dialog != NULL)
1328 gtk_widget_destroy (state->base.warning_dialog);
1330 data->base.range_1 = gnm_expr_entry_parse_as_value
1331 (GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
1333 data->base.range_2 = gnm_expr_entry_parse_as_value
1334 (GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
1336 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
1337 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
1339 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->paired_button)) == 1) {
1340 state->invocation = TTEST_PAIRED;
1341 } else {
1342 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->known_button)) == 1) {
1343 state->invocation = TTEST_ZTEST;
1344 } else {
1345 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
1346 (state->equal_button)) == 1) {
1347 state->invocation = TTEST_UNPAIRED_EQUALVARIANCES;
1348 } else {
1349 state->invocation = TTEST_UNPAIRED_UNEQUALVARIANCES;
1354 err = entry_to_float (GTK_ENTRY (state->mean_diff_entry), &data->mean_diff, TRUE);
1355 err = entry_to_float (GTK_ENTRY (state->alpha_entry), &data->base.alpha, TRUE);
1357 switch (state->invocation) {
1358 case TTEST_PAIRED:
1359 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg),
1360 state->base.sheet,
1361 dao, data, analysis_tool_ttest_paired_engine,
1362 TRUE))
1363 gtk_widget_destroy (state->base.dialog);
1364 break;
1365 case TTEST_UNPAIRED_EQUALVARIANCES:
1366 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
1367 dao, data, analysis_tool_ttest_eqvar_engine, TRUE))
1368 gtk_widget_destroy (state->base.dialog);
1369 break;
1370 case TTEST_UNPAIRED_UNEQUALVARIANCES:
1371 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
1372 dao, data, analysis_tool_ttest_neqvar_engine, TRUE))
1373 gtk_widget_destroy (state->base.dialog);
1374 break;
1375 case TTEST_ZTEST:
1376 err = entry_to_float (GTK_ENTRY (state->var1_variance), &data->var1, TRUE);
1377 if (err != 0 || data->var1 <= 0.0) {
1378 error_in_entry ((GnmGenericToolState *) state, GTK_WIDGET (state->var1_variance),
1379 _("Please enter a valid\n"
1380 "population variance for variable 1."));
1381 g_free (data);
1382 g_free (dao);
1383 return;
1385 err = entry_to_float (GTK_ENTRY (state->var2_variance), &data->var2, TRUE);
1386 if (err != 0 || data->var2 <= 0.0) {
1387 error_in_entry ((GnmGenericToolState *) state, GTK_WIDGET (state->var2_variance),
1388 _("Please enter a valid\n"
1389 "population variance for variable 2."));
1390 g_free (data);
1391 g_free (dao);
1392 return;
1395 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
1396 dao, data, analysis_tool_ztest_engine, TRUE))
1397 gtk_widget_destroy (state->base.dialog);
1398 break;
1401 return;
1405 * ttest_update_sensitivity_cb:
1406 * @dummy:
1407 * @state:
1409 * Update the dialog widgets sensitivity if the only items of interest
1410 * are the standard input (one or two ranges) and output items.
1412 static void
1413 ttest_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
1414 TTestState *state)
1416 gboolean ready = FALSE;
1417 gboolean input_1_ready = FALSE;
1418 gboolean input_2_ready = FALSE;
1419 gboolean output_ready = FALSE;
1420 gboolean mean_diff_ready = FALSE;
1421 gboolean alpha_ready = FALSE;
1422 int err;
1423 gnm_float mean_diff, alpha;
1424 GnmValue *input_range;
1425 GnmValue *input_range_2;
1427 input_range = gnm_expr_entry_parse_as_value
1428 (GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
1429 input_range_2 = gnm_expr_entry_parse_as_value
1430 (GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
1432 err = entry_to_float (GTK_ENTRY (state->mean_diff_entry), &mean_diff, FALSE);
1433 mean_diff_ready = (err == 0);
1434 err = entry_to_float (GTK_ENTRY (state->alpha_entry), &alpha, FALSE);
1435 alpha_ready = (err == 0 && alpha > 0.0 && alpha < 1.0);
1436 input_1_ready = (input_range != NULL);
1437 input_2_ready = ((state->base.input_entry_2 == NULL) || (input_range_2 != NULL));
1438 output_ready = gnm_dao_is_ready (GNM_DAO (state->base.gdao));
1440 value_release (input_range);
1441 value_release (input_range_2);
1443 ready = input_1_ready && input_2_ready && output_ready && alpha_ready && mean_diff_ready;
1444 gtk_widget_set_sensitive (state->base.ok_button, ready);
1446 return;
1450 * ttest_known_toggled_cb:
1451 * @button:
1452 * @state:
1454 * The paired/unpaired variables status has changed.
1457 static void
1458 ttest_known_toggled_cb (GtkWidget *button, TTestState *state)
1460 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) == 1) {
1461 gtk_widget_hide (state->equal_button);
1462 gtk_widget_hide (state->unequal_button);
1463 gtk_widget_hide (state->varianceequal_label);
1464 gtk_widget_show (state->var2_variance_label);
1465 gtk_widget_show (state->var2_variance);
1466 gtk_widget_show (state->var1_variance_label);
1467 gtk_widget_show (state->var1_variance);
1468 } else {
1469 gtk_widget_hide (state->var2_variance_label);
1470 gtk_widget_hide (state->var2_variance);
1471 gtk_widget_hide (state->var1_variance_label);
1472 gtk_widget_hide (state->var1_variance);
1473 gtk_widget_show (state->equal_button);
1474 gtk_widget_show (state->unequal_button);
1475 gtk_widget_show (state->varianceequal_label);
1479 * ttest_paired_toggled_cb:
1480 * @button:
1481 * @state:
1483 * The paired/unpaired variables status has changed.
1486 static void
1487 ttest_paired_toggled_cb (GtkWidget *button, TTestState *state)
1489 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) == 1) {
1490 gtk_widget_hide (state->var2_variance_label);
1491 gtk_widget_hide (state->var2_variance);
1492 gtk_widget_hide (state->var1_variance_label);
1493 gtk_widget_hide (state->var1_variance);
1494 gtk_widget_hide (state->equal_button);
1495 gtk_widget_hide (state->unequal_button);
1496 gtk_widget_hide (state->varianceequal_label);
1497 gtk_widget_hide (state->known_button);
1498 gtk_widget_hide (state->unknown_button);
1499 gtk_widget_hide (state->varianceknown_label);
1500 } else {
1501 gtk_widget_show (state->known_button);
1502 gtk_widget_show (state->unknown_button);
1503 gtk_widget_show (state->varianceknown_label);
1504 ttest_known_toggled_cb (GTK_WIDGET (state->known_button), state);
1509 * dialog_ttest_adjust_to_invocation:
1510 * @state:
1512 * Set the options to match the invocation.
1515 static void
1516 dialog_ttest_adjust_to_invocation (TTestState *state)
1518 switch (state->invocation) {
1519 case TTEST_PAIRED:
1520 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->paired_button), TRUE);
1521 break;
1522 case TTEST_UNPAIRED_EQUALVARIANCES:
1523 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->equal_button), TRUE);
1524 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->unknown_button), TRUE);
1525 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->unpaired_button), TRUE);
1526 break;
1527 case TTEST_UNPAIRED_UNEQUALVARIANCES:
1528 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->unequal_button), TRUE);
1529 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->unknown_button), TRUE);
1530 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->unpaired_button), TRUE);
1531 break;
1532 case TTEST_ZTEST:
1533 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->known_button), TRUE);
1534 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->unpaired_button), TRUE);
1535 break;
1536 default:
1537 break;
1543 * dialog_ttest_realized:
1544 * @widget
1545 * @state:
1547 * Fix the size of the options table.
1550 static void
1551 dialog_ttest_realized (G_GNUC_UNUSED GtkWidget *widget,
1552 TTestState *state)
1554 GtkAllocation alloc;
1556 gtk_widget_get_allocation (state->options_grid, &alloc);
1557 gtk_widget_set_size_request (state->options_grid,
1558 alloc.width, alloc.height);
1560 gtk_widget_get_allocation (state->paired_button, &alloc);
1561 gtk_widget_set_size_request (state->paired_button,
1562 alloc.width, alloc.height);
1564 gtk_widget_get_allocation (state->unpaired_button, &alloc);
1565 gtk_widget_set_size_request (state->unpaired_button,
1566 alloc.width, alloc.height);
1568 gtk_widget_get_allocation (state->variablespaired_label, &alloc);
1569 gtk_widget_set_size_request (state->variablespaired_label,
1570 alloc.width, alloc.height);
1572 ttest_paired_toggled_cb (state->paired_button, state);
1573 dialog_ttest_adjust_to_invocation (state);
1577 * dialog_ttest_tool:
1578 * @wbcg:
1579 * @sheet:
1580 * @test:
1582 * Show the dialog (guru).
1586 dialog_ttest_tool (WBCGtk *wbcg, Sheet *sheet, ttest_type test)
1588 TTestState *state;
1589 GtkDialog *dialog;
1590 char const * plugins[] = {"Gnumeric_fnstat",
1591 "Gnumeric_fnmath",
1592 "Gnumeric_fninfo",
1593 "Gnumeric_fnlogical",
1594 NULL};
1596 if ((wbcg == NULL) ||
1597 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
1598 return 1;
1600 /* Only pop up one copy per workbook */
1601 dialog = gnm_dialog_raise_if_exists (wbcg, TTEST_KEY);
1602 if (dialog) {
1603 state = g_object_get_data (G_OBJECT (dialog), "state");
1604 state->invocation = test;
1605 dialog_ttest_adjust_to_invocation (state);
1606 return 0;
1609 state = g_new0 (TTestState, 1);
1610 state->invocation = test;
1612 if (dialog_tool_init (&state->base, wbcg, sheet,
1613 GNUMERIC_HELP_LINK_MEAN_TESTS,
1614 "res:ui/mean-tests.ui", "MeanTests",
1615 _("Could not create the Mean Tests Tool dialog."),
1616 TTEST_KEY,
1617 G_CALLBACK (ttest_tool_ok_clicked_cb), NULL,
1618 G_CALLBACK (ttest_update_sensitivity_cb),
1619 GNM_EE_SINGLE_RANGE))
1621 g_free(state);
1622 return 0;
1625 state->paired_button = go_gtk_builder_get_widget (state->base.gui, "paired-button");
1626 state->unpaired_button = go_gtk_builder_get_widget (state->base.gui, "unpaired-button");
1627 state->variablespaired_label = go_gtk_builder_get_widget (state->base.gui, "variablespaired-label");
1628 state->known_button = go_gtk_builder_get_widget (state->base.gui, "known-button");
1629 state->unknown_button = go_gtk_builder_get_widget (state->base.gui, "unknown-button");
1630 state->varianceknown_label = go_gtk_builder_get_widget (state->base.gui, "varianceknown-label");
1631 state->equal_button = go_gtk_builder_get_widget (state->base.gui, "equal-button");
1632 state->unequal_button = go_gtk_builder_get_widget (state->base.gui, "unequal-button");
1633 state->varianceequal_label = go_gtk_builder_get_widget (state->base.gui, "varianceequal-label");
1634 state->options_grid = go_gtk_builder_get_widget (state->base.gui, "options-grid");
1635 state->var1_variance_label = go_gtk_builder_get_widget (state->base.gui, "var1_variance-label");
1636 state->var1_variance = go_gtk_builder_get_widget (state->base.gui, "var1-variance");
1637 state->var2_variance_label = go_gtk_builder_get_widget (state->base.gui, "var2_variance-label");
1638 state->var2_variance = go_gtk_builder_get_widget (state->base.gui, "var2-variance");
1639 state->mean_diff_entry = go_gtk_builder_get_widget (state->base.gui, "meandiff");
1640 float_to_entry (GTK_ENTRY (state->mean_diff_entry), 0);
1641 state->alpha_entry = go_gtk_builder_get_widget (state->base.gui, "one_alpha");
1642 float_to_entry (GTK_ENTRY (state->alpha_entry), 0.05);
1644 g_signal_connect_after (G_OBJECT (state->paired_button),
1645 "toggled",
1646 G_CALLBACK (ttest_update_sensitivity_cb), state);
1647 g_signal_connect (G_OBJECT (state->paired_button),
1648 "toggled",
1649 G_CALLBACK (ttest_paired_toggled_cb), state);
1650 g_signal_connect_after (G_OBJECT (state->known_button),
1651 "toggled",
1652 G_CALLBACK (ttest_update_sensitivity_cb), state);
1653 g_signal_connect_after (G_OBJECT (state->mean_diff_entry),
1654 "changed",
1655 G_CALLBACK (ttest_update_sensitivity_cb), state);
1656 g_signal_connect_after (G_OBJECT (state->alpha_entry),
1657 "changed",
1658 G_CALLBACK (ttest_update_sensitivity_cb), state);
1659 g_signal_connect (G_OBJECT (state->known_button),
1660 "toggled",
1661 G_CALLBACK (ttest_known_toggled_cb), state);
1662 g_signal_connect (G_OBJECT (state->base.dialog),
1663 "realize",
1664 G_CALLBACK (dialog_ttest_realized), state);
1665 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
1666 GTK_WIDGET (state->var1_variance));
1667 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
1668 GTK_WIDGET (state->var2_variance));
1669 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
1670 GTK_WIDGET (state->mean_diff_entry));
1671 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
1672 GTK_WIDGET (state->alpha_entry));
1674 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
1675 ttest_update_sensitivity_cb (NULL, state);
1676 tool_load_selection ((GnmGenericToolState *)state, FALSE);
1678 return 0;
1681 /**********************************************/
1682 /* End of ttest tool code */
1683 /**********************************************/
1686 /**********************************************/
1687 /* Begin of ftest tool code */
1688 /**********************************************/
1692 * ftest_tool_ok_clicked_cb:
1693 * @button:
1694 * @state:
1696 * Retrieve the information from the dialog and call the correlation_tool.
1697 * Note that we assume that the ok_button is only active if the entry fields
1698 * contain sensible data.
1700 static void
1701 ftest_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
1702 FTestToolState *state)
1704 data_analysis_output_t *dao;
1705 analysis_tools_data_generic_b_t *data;
1707 GtkWidget *w;
1709 data = g_new0 (analysis_tools_data_generic_b_t, 1);
1710 dao = parse_output ((GnmGenericToolState *)state, NULL);
1712 data->wbc = GNM_WBC (state->base.wbcg);
1714 if (state->base.warning_dialog != NULL)
1715 gtk_widget_destroy (state->base.warning_dialog);
1717 data->range_1 = gnm_expr_entry_parse_as_value
1718 (GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
1720 data->range_2 = gnm_expr_entry_parse_as_value
1721 (GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
1723 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
1724 data->labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
1726 entry_to_float (GTK_ENTRY (state->alpha_entry), &data->alpha, TRUE);
1728 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
1729 dao, data, analysis_tool_ftest_engine, TRUE))
1730 gtk_widget_destroy (state->base.dialog);
1732 return;
1736 * ftest_update_sensitivity_cb:
1737 * @dummy:
1738 * @state:
1740 * Update the dialog widgets sensitivity if the only items of interest
1741 * are the standard input (one or two ranges) and output items.
1743 static void
1744 ftest_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
1745 FTestToolState *state)
1747 gboolean ready = FALSE;
1748 gboolean input_1_ready = FALSE;
1749 gboolean input_2_ready = FALSE;
1750 gboolean output_ready = FALSE;
1751 gboolean alpha_ready = FALSE;
1752 int err;
1753 gnm_float alpha;
1754 GnmValue *input_range;
1755 GnmValue *input_range_2;
1757 input_range = gnm_expr_entry_parse_as_value
1758 (GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
1759 input_range_2 = gnm_expr_entry_parse_as_value
1760 (GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
1762 err = entry_to_float (GTK_ENTRY (state->alpha_entry), &alpha, FALSE);
1763 alpha_ready = (err == 0 && alpha > 0.0 && alpha < 1.0);
1764 input_1_ready = (input_range != NULL);
1765 input_2_ready = ((state->base.input_entry_2 == NULL) || (input_range_2 != NULL));
1766 output_ready = gnm_dao_is_ready (GNM_DAO (state->base.gdao));
1768 value_release (input_range);
1769 value_release (input_range_2);
1771 ready = input_1_ready && input_2_ready && output_ready && alpha_ready;
1772 gtk_widget_set_sensitive (state->base.ok_button, ready);
1774 return;
1778 * dialog_ftest_tool:
1779 * @wbcg:
1780 * @sheet:
1782 * Show the dialog (guru).
1786 dialog_ftest_tool (WBCGtk *wbcg, Sheet *sheet)
1788 FTestToolState *state;
1789 char const * plugins[] = { "Gnumeric_fnstat",
1790 NULL};
1792 if ((wbcg == NULL) ||
1793 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
1794 return 1;
1796 /* Only pop up one copy per workbook */
1797 if (gnm_dialog_raise_if_exists (wbcg, FTEST_KEY))
1798 return 0;
1800 state = g_new0 (FTestToolState, 1);
1802 if (dialog_tool_init (&state->base, wbcg, sheet,
1803 GNUMERIC_HELP_LINK_F_TEST_TWO_SAMPLE,
1804 "res:ui/variance-tests.ui", "VarianceTests",
1805 _("Could not create the FTest Tool dialog."),
1806 FTEST_KEY,
1807 G_CALLBACK (ftest_tool_ok_clicked_cb), NULL,
1808 G_CALLBACK (ftest_update_sensitivity_cb),
1809 GNM_EE_SINGLE_RANGE))
1811 g_free(state);
1812 return 0;
1815 state->alpha_entry = go_gtk_builder_get_widget (state->base.gui, "one_alpha");
1816 float_to_entry (GTK_ENTRY (state->alpha_entry), 0.05);
1817 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
1818 GTK_WIDGET (state->alpha_entry));
1819 g_signal_connect_after (G_OBJECT (state->alpha_entry),
1820 "changed",
1821 G_CALLBACK (ftest_update_sensitivity_cb), state);
1823 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
1824 ftest_update_sensitivity_cb (NULL, state);
1825 tool_load_selection ((GnmGenericToolState *)state, FALSE);
1827 return 0;
1830 /**********************************************/
1831 /* End of ftest tool code */
1832 /**********************************************/
1834 /**********************************************/
1835 /* Begin of sampling tool code */
1836 /**********************************************/
1839 * sampling_tool_update_sensitivity:
1840 * @dummy:
1841 * @state:
1843 * Update the dialog widgets sensitivity if the only items of interest
1844 * are the standard input (one range) and output items.
1846 static void
1847 sampling_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
1848 SamplingState *state)
1850 int periodic, size, number, err;
1851 GSList *input_range;
1853 input_range = gnm_expr_entry_parse_as_list (
1854 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
1856 if (input_range == NULL) {
1857 gtk_label_set_text (GTK_LABEL (state->base.warning),
1858 _("The input range is invalid."));
1859 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1860 return;
1861 } else
1862 range_list_destroy (input_range);
1864 err = entry_to_int (GTK_ENTRY (state->number_entry), &number, FALSE);
1866 if (err != 0 || number < 1) {
1867 gtk_label_set_text (GTK_LABEL (state->base.warning),
1868 _("The requested number of samples is invalid."));
1869 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1870 return;
1873 periodic = gtk_toggle_button_get_active
1874 (GTK_TOGGLE_BUTTON (state->periodic_button));
1876 if (periodic) {
1877 err = entry_to_int
1878 (GTK_ENTRY (state->period_entry), &size, FALSE);
1879 if (err != 0 || size < 1) {
1880 gtk_label_set_text (GTK_LABEL (state->base.warning),
1881 _("The requested period is invalid."));
1882 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1883 return;
1885 err = entry_to_int
1886 (GTK_ENTRY (state->offset_entry), &number, FALSE);
1887 if (err != 0 || number < 0) {
1888 gtk_label_set_text (GTK_LABEL (state->base.warning),
1889 _("The requested offset is invalid."));
1890 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1891 return;
1893 } else {
1894 err = entry_to_int
1895 (GTK_ENTRY (state->random_entry), &size, FALSE);
1896 if (err != 0 || size < 1) {
1897 gtk_label_set_text (GTK_LABEL (state->base.warning),
1898 _("The requested sample size is invalid."));
1899 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1900 return;
1904 if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
1905 gtk_label_set_text (GTK_LABEL (state->base.warning),
1906 _("The output specification "
1907 "is invalid."));
1908 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1909 return;
1912 gtk_label_set_text (GTK_LABEL (state->base.warning), "");
1913 gtk_widget_set_sensitive (state->base.ok_button, TRUE);
1917 * sampling_tool_ok_clicked_cb:
1918 * @button:
1919 * @state:
1921 * Retrieve the information from the dialog and call the appropriate tool.
1922 * Note that we assume that the ok_button is only active if the entry fields
1923 * contain sensible data.
1925 static void
1926 sampling_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
1927 SamplingState *state)
1929 data_analysis_output_t *dao;
1930 analysis_tools_data_sampling_t *data;
1932 GtkWidget *w;
1934 data = g_new0 (analysis_tools_data_sampling_t, 1);
1935 dao = parse_output ((GnmGenericToolState *)state, NULL);
1937 data->base.wbc = GNM_WBC (state->base.wbcg);
1939 data->base.input = gnm_expr_entry_parse_as_list (
1940 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
1941 data->base.group_by = gnm_gui_group_value (state->base.gui, grouped_by_group);
1943 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
1944 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
1946 data->periodic = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->periodic_button));
1948 if (data->periodic) {
1949 entry_to_int (GTK_ENTRY (state->period_entry), &data->period, TRUE);
1950 entry_to_int (GTK_ENTRY (state->offset_entry), &data->offset, TRUE);
1951 data->row_major = gtk_toggle_button_get_active
1952 (GTK_TOGGLE_BUTTON (state->row_major_button));
1953 } else
1954 entry_to_int (GTK_ENTRY (state->random_entry), &data->size, TRUE);
1956 entry_to_int (GTK_ENTRY (state->number_entry), &data->number, TRUE);
1958 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
1959 dao, data, analysis_tool_sampling_engine, TRUE))
1960 gtk_widget_destroy (state->base.dialog);
1961 return;
1965 * sampling_method_toggled_cb:
1966 * @button:
1967 * @state:
1969 * The method status has changed.
1972 static void
1973 sampling_method_toggled_cb (GtkWidget *button, SamplingState *state)
1975 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) == 1) {
1976 gtk_widget_hide (state->random_label);
1977 gtk_widget_hide (state->random_entry);
1978 gtk_widget_show (state->period_label);
1979 gtk_widget_show (state->period_entry);
1980 gtk_widget_show (state->offset_label);
1981 gtk_widget_show (state->offset_entry);
1982 gtk_widget_show (state->major_label);
1983 gtk_widget_show (state->row_major_button);
1984 gtk_widget_show (state->col_major_button);
1985 } else {
1986 gtk_widget_hide (state->period_label);
1987 gtk_widget_hide (state->period_entry);
1988 gtk_widget_hide (state->period_entry);
1989 gtk_widget_hide (state->offset_label);
1990 gtk_widget_hide (state->offset_entry);
1991 gtk_widget_hide (state->major_label);
1992 gtk_widget_hide (state->row_major_button);
1993 gtk_widget_hide (state->col_major_button);
1994 gtk_widget_show (state->random_label);
1995 gtk_widget_show (state->random_entry);
2001 * dialog_sampling_realized:
2002 * @widget
2003 * @state:
2005 * Fix the size of the options table.
2008 static void
2009 dialog_sampling_realized (G_GNUC_UNUSED GtkWidget *widget,
2010 SamplingState *state)
2012 GtkAllocation alloc;
2014 gtk_widget_get_allocation (state->options_grid, &alloc);
2015 gtk_widget_set_size_request (state->options_grid,
2016 alloc.width, alloc.height);
2018 gtk_widget_get_allocation (state->random_button, &alloc);
2019 gtk_widget_set_size_request (state->random_button,
2020 alloc.width, alloc.height);
2022 gtk_widget_get_allocation (state->periodic_button, &alloc);
2023 gtk_widget_set_size_request (state->periodic_button,
2024 alloc.width, alloc.height);
2026 gtk_widget_get_allocation (state->method_label, &alloc);
2027 gtk_widget_set_size_request (state->method_label,
2028 alloc.width, alloc.height);
2030 sampling_method_toggled_cb (state->periodic_button, state);
2034 * dialog_sampling_tool:
2035 * @wbcg:
2036 * @sheet:
2038 * Show the dialog (guru).
2042 dialog_sampling_tool (WBCGtk *wbcg, Sheet *sheet)
2044 SamplingState *state;
2045 char const * plugins[] = { "Gnumeric_fnlookup",
2046 "Gnumeric_fnrandom",
2047 NULL};
2049 if ((wbcg == NULL) ||
2050 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
2051 return 1;
2053 /* Only pop up one copy per workbook */
2054 if (gnm_dialog_raise_if_exists (wbcg, SAMPLING_KEY)) {
2055 return 0;
2058 state = g_new0 (SamplingState, 1);
2060 if (dialog_tool_init (&state->base, wbcg, sheet,
2061 GNUMERIC_HELP_LINK_SAMPLING,
2062 "res:ui/sampling.ui", "Sampling",
2063 _("Could not create the Sampling Tool dialog."),
2064 SAMPLING_KEY,
2065 G_CALLBACK (sampling_tool_ok_clicked_cb), NULL,
2066 G_CALLBACK (sampling_tool_update_sensitivity_cb),
2069 g_free(state);
2070 return 0;
2073 state->periodic_button = go_gtk_builder_get_widget (state->base.gui, "periodic-button");
2074 state->random_button = go_gtk_builder_get_widget (state->base.gui, "random-button");
2075 state->method_label = go_gtk_builder_get_widget (state->base.gui, "method-label");
2076 state->options_grid = go_gtk_builder_get_widget (state->base.gui, "options-grid");
2077 state->period_label = go_gtk_builder_get_widget (state->base.gui, "period-label");
2078 state->random_label = go_gtk_builder_get_widget (state->base.gui, "random-label");
2079 state->period_entry = go_gtk_builder_get_widget (state->base.gui, "period-entry");
2080 state->random_entry = go_gtk_builder_get_widget (state->base.gui, "random-entry");
2081 state->number_entry = go_gtk_builder_get_widget (state->base.gui, "number-entry");
2082 state->offset_label = go_gtk_builder_get_widget (state->base.gui, "offset-label");
2083 state->offset_entry = go_gtk_builder_get_widget (state->base.gui, "offset-entry");
2084 state->major_label = go_gtk_builder_get_widget (state->base.gui, "pdir-label");
2085 state->row_major_button = go_gtk_builder_get_widget (state->base.gui, "row-major-button");
2086 state->col_major_button = go_gtk_builder_get_widget (state->base.gui, "col-major-button");
2088 int_to_entry (GTK_ENTRY (state->number_entry), 1);
2089 int_to_entry (GTK_ENTRY (state->offset_entry), 0);
2091 g_signal_connect_after (G_OBJECT (state->periodic_button),
2092 "toggled",
2093 G_CALLBACK (sampling_tool_update_sensitivity_cb), state);
2094 g_signal_connect (G_OBJECT (state->periodic_button),
2095 "toggled",
2096 G_CALLBACK (sampling_method_toggled_cb), state);
2097 g_signal_connect (G_OBJECT (state->base.dialog),
2098 "realize",
2099 G_CALLBACK (dialog_sampling_realized), state);
2100 g_signal_connect_after (G_OBJECT (state->period_entry),
2101 "changed",
2102 G_CALLBACK (sampling_tool_update_sensitivity_cb), state);
2103 g_signal_connect_after (G_OBJECT (state->random_entry),
2104 "changed",
2105 G_CALLBACK (sampling_tool_update_sensitivity_cb), state);
2106 g_signal_connect_after (G_OBJECT (state->number_entry),
2107 "changed",
2108 G_CALLBACK (sampling_tool_update_sensitivity_cb), state);
2109 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
2110 GTK_WIDGET (state->period_entry));
2111 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
2112 GTK_WIDGET (state->random_entry));
2113 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
2114 GTK_WIDGET (state->number_entry));
2116 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
2117 sampling_tool_update_sensitivity_cb (NULL, state);
2118 tool_load_selection ((GnmGenericToolState *)state, TRUE);
2120 return 0;
2122 /**********************************************/
2123 /* End of sampling tool code */
2124 /**********************************************/
2126 /**********************************************/
2127 /* Begin of Regression tool code */
2128 /**********************************************/
2130 static gint
2131 regression_tool_calc_height (GnmValue *val)
2133 GnmRange r;
2135 if (NULL == range_init_value (&r, val))
2136 return 0;
2137 return range_height (&r);
2140 static gint
2141 regression_tool_calc_width (GnmValue *val)
2143 GnmRange r;
2145 if (NULL == range_init_value (&r, val))
2146 return 0;
2147 return range_width (&r);
2152 * regression_tool_ok_clicked_cb:
2153 * @button:
2154 * @state:
2156 * Retrieve the information from the dialog and call the regression_tool.
2157 * Note that we assume that the ok_button is only active if the entry fields
2158 * contain sensible data.
2160 static void
2161 regression_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
2162 RegressionToolState *state)
2164 data_analysis_output_t *dao;
2165 analysis_tools_data_regression_t *data;
2167 GtkWidget *w;
2168 gnm_float confidence;
2169 gint y_h;
2171 if (state->base.warning_dialog != NULL)
2172 gtk_widget_destroy (state->base.warning_dialog);
2174 data = g_new0 (analysis_tools_data_regression_t, 1);
2175 dao = parse_output ((GnmGenericToolState *)state, NULL);
2177 data->base.wbc = GNM_WBC (state->base.wbcg);
2179 data->base.range_1 = gnm_expr_entry_parse_as_value (
2180 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
2181 data->base.range_2 = gnm_expr_entry_parse_as_value
2182 (GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
2184 y_h = regression_tool_calc_height(data->base.range_2);
2186 data->group_by = (y_h == 1) ? GROUPED_BY_ROW : GROUPED_BY_COL;
2188 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
2189 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
2191 entry_to_float (GTK_ENTRY (state->confidence_entry), &confidence, TRUE);
2192 data->base.alpha = 1 - confidence;
2194 w = go_gtk_builder_get_widget (state->base.gui, "intercept-button");
2195 data->intercept = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
2197 data->residual = gtk_toggle_button_get_active
2198 (GTK_TOGGLE_BUTTON (state->residuals_check));
2200 data->multiple_regression
2201 = !gtk_toggle_button_get_active
2202 (GTK_TOGGLE_BUTTON (state->simple_linear_regression_radio));
2204 data->multiple_y = gtk_toggle_button_get_active
2205 (GTK_TOGGLE_BUTTON (state->switch_variables_check));
2207 if (cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
2208 dao, data, analysis_tool_regression_engine, FALSE)) {
2209 char *text;
2211 text = g_strdup_printf (
2212 _("An unexpected error has occurred: %d."), data->base.err);
2213 error_in_entry ((GnmGenericToolState *) state,
2214 GTK_WIDGET (state->base.input_entry), text);
2215 g_free (text);
2217 value_release (data->base.range_1);
2218 value_release (data->base.range_2);
2219 g_free (dao);
2220 g_free (data);
2221 } else
2222 gtk_widget_destroy (state->base.dialog);
2227 * regression_tool_update_sensitivity_cb:
2228 * @state:
2230 * Update the dialog widgets sensitivity.
2231 * We cannot use tool_update_sensitivity_cb
2232 * since we are also considering whether in fact
2233 * an interval is given.
2235 static void
2236 regression_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
2237 RegressionToolState *state)
2239 int err;
2240 gnm_float confidence;
2241 GnmValue *input_range;
2242 GnmValue *input_range_2;
2243 gint y_h, y_w;
2244 gint x_h, x_w;
2245 gboolean switch_v;
2247 switch_v = gtk_toggle_button_get_active
2248 (GTK_TOGGLE_BUTTON (state->switch_variables_check));
2250 /* Checking Input Range */
2251 input_range_2 = gnm_expr_entry_parse_as_value (
2252 GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
2253 if (input_range_2 == NULL) {
2254 gtk_label_set_text (GTK_LABEL (state->base.warning),
2255 switch_v ?
2256 _("The x variable range is invalid.") :
2257 _("The y variable range is invalid.") );
2258 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2259 return;
2262 y_h = regression_tool_calc_height(input_range_2);
2263 y_w = regression_tool_calc_width (input_range_2);
2264 value_release (input_range_2);
2266 if (y_h == 0 || y_w == 0) {
2267 gtk_label_set_text (GTK_LABEL (state->base.warning),
2268 switch_v ?
2269 _("The x variable range is invalid.") :
2270 _("The y variable range is invalid."));
2271 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2272 return;
2274 if (y_h != 1 && y_w != 1) {
2275 gtk_label_set_text (GTK_LABEL (state->base.warning),
2276 switch_v ?
2277 _("The x variable range must be a vector (n by 1 or 1 by n).") :
2278 _("The y variable range must be a vector (n by 1 or 1 by n)."));
2279 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2280 return;
2282 if (y_h <= 2 && y_w <= 2) {
2283 gtk_label_set_text (GTK_LABEL (state->base.warning),
2284 switch_v ?
2285 _("The x variable range is too small") :
2286 _("The y variable range is too small"));
2287 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2288 return;
2291 input_range = gnm_expr_entry_parse_as_value
2292 (GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
2293 if (input_range == NULL) {
2294 gtk_label_set_text (GTK_LABEL (state->base.warning),
2295 switch_v ?
2296 _("The y variables range is invalid.") :
2297 _("The x variables range is invalid."));
2298 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2299 return;
2302 x_h = regression_tool_calc_height(input_range);
2303 x_w = regression_tool_calc_width (input_range);
2304 value_release (input_range);
2306 if (x_h == 0 || x_w == 0) {
2307 gtk_label_set_text (GTK_LABEL (state->base.warning),
2308 switch_v ?
2309 _("The y variables range is invalid.") :
2310 _("The x variables range is invalid."));
2311 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2312 return;
2315 if ((y_h == 1 && y_w != x_w) || (y_w == 1 && y_h != x_h)) {
2316 gtk_label_set_text (GTK_LABEL (state->base.warning),
2317 switch_v ?
2318 _("The sizes of the y variable and x variables ranges do not match.") :
2319 _("The sizes of the x variable and y variables ranges do not match."));
2320 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2321 return;
2324 err = entry_to_float (GTK_ENTRY (state->confidence_entry), &confidence, FALSE);
2326 if (err != 0 || (1 < confidence || confidence < 0)) {
2327 gtk_label_set_text (GTK_LABEL (state->base.warning),
2328 _("The confidence level is invalid."));
2329 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2330 return;
2333 if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
2334 gtk_label_set_text (GTK_LABEL (state->base.warning),
2335 _("The output specification "
2336 "is invalid."));
2337 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2338 return;
2341 gtk_label_set_text (GTK_LABEL (state->base.warning), "");
2342 gtk_widget_set_sensitive (state->base.ok_button, TRUE);
2345 static void
2346 regression_tool_regression_radio_toggled_cb (G_GNUC_UNUSED
2347 GtkToggleButton *togglebutton,
2348 RegressionToolState *state)
2350 gboolean simple = gtk_toggle_button_get_active
2351 (GTK_TOGGLE_BUTTON (state->simple_linear_regression_radio));
2352 if (!simple)
2353 gtk_toggle_button_set_active
2354 (GTK_TOGGLE_BUTTON (state->switch_variables_check),
2355 FALSE);
2357 gtk_toggle_button_set_active
2358 (GTK_TOGGLE_BUTTON (state->residuals_check), !simple);
2359 gtk_widget_set_sensitive (state->residuals_check, !simple);
2363 static void
2364 regression_tool_regression_check_toggled_cb (G_GNUC_UNUSED
2365 GtkToggleButton *togglebutton,
2366 RegressionToolState *state)
2368 GtkWidget *w1, *w2;
2370 w1 = go_gtk_builder_get_widget (state->base.gui, "var1-label");
2371 w2 = go_gtk_builder_get_widget (state->base.gui, "var2-label");
2373 if (gtk_toggle_button_get_active
2374 (GTK_TOGGLE_BUTTON (state->switch_variables_check))) {
2375 gtk_toggle_button_set_active
2376 (GTK_TOGGLE_BUTTON
2377 (state->simple_linear_regression_radio),
2378 TRUE);
2379 gtk_label_set_markup_with_mnemonic (GTK_LABEL (w1),
2380 _("_Y variables:"));
2381 gtk_label_set_markup_with_mnemonic (GTK_LABEL (w2),
2382 _("_X variable:"));
2383 } else {
2384 gtk_label_set_markup_with_mnemonic (GTK_LABEL (w1),
2385 _("_X variables:"));
2386 gtk_label_set_markup_with_mnemonic (GTK_LABEL (w2),
2387 _("_Y variable:"));
2389 regression_tool_update_sensitivity_cb (NULL, state);
2394 * dialog_regression_tool:
2395 * @wbcg:
2396 * @sheet:
2398 * Show the dialog (guru).
2402 dialog_regression_tool (WBCGtk *wbcg, Sheet *sheet)
2404 RegressionToolState *state;
2405 char const * plugins[] = { "Gnumeric_fnstat",
2406 "Gnumeric_fnlookup",
2407 "Gnumeric_fnmath",
2408 "Gnumeric_fninfo",
2409 "Gnumeric_fnstring",
2410 NULL};
2412 if ((wbcg == NULL) ||
2413 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
2414 return 1;
2416 /* Only pop up one copy per workbook */
2417 if (gnm_dialog_raise_if_exists (wbcg, REGRESSION_KEY))
2418 return 0;
2420 state = g_new0 (RegressionToolState, 1);
2422 if (dialog_tool_init (&state->base, wbcg, sheet,
2423 GNUMERIC_HELP_LINK_REGRESSION,
2424 "res:ui/regression.ui", "Regression",
2425 _("Could not create the Regression Tool dialog."),
2426 REGRESSION_KEY,
2427 G_CALLBACK (regression_tool_ok_clicked_cb), NULL,
2428 G_CALLBACK (regression_tool_update_sensitivity_cb),
2429 GNM_EE_SINGLE_RANGE))
2431 g_free(state);
2432 return 0;
2435 state->confidence_entry = go_gtk_builder_get_widget (state->base.gui, "confidence-entry");
2436 float_to_entry (GTK_ENTRY (state->confidence_entry), 0.95);
2437 g_signal_connect_after (G_OBJECT (state->confidence_entry),
2438 "changed",
2439 G_CALLBACK (regression_tool_update_sensitivity_cb), state);
2440 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
2441 GTK_WIDGET (state->confidence_entry));
2443 state->simple_linear_regression_radio
2444 = go_gtk_builder_get_widget
2445 (state->base.gui, "simple-regression-button");
2446 state->switch_variables_check
2447 = go_gtk_builder_get_widget
2448 (state->base.gui, "multiple-independent-check");
2449 state->residuals_check
2450 = go_gtk_builder_get_widget
2451 (state->base.gui, "residuals-button");
2452 gtk_toggle_button_set_active
2453 (GTK_TOGGLE_BUTTON (state->simple_linear_regression_radio),
2454 FALSE);
2455 gtk_toggle_button_set_active
2456 (GTK_TOGGLE_BUTTON (state->switch_variables_check),
2457 FALSE);
2458 gtk_toggle_button_set_active
2459 (GTK_TOGGLE_BUTTON (state->residuals_check),
2460 TRUE);
2461 g_signal_connect
2462 (G_OBJECT (state->simple_linear_regression_radio),
2463 "toggled",
2464 G_CALLBACK (regression_tool_regression_radio_toggled_cb),
2465 state);
2466 g_signal_connect
2467 (G_OBJECT (state->switch_variables_check),
2468 "toggled",
2469 G_CALLBACK (regression_tool_regression_check_toggled_cb),
2470 state);
2474 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
2475 regression_tool_update_sensitivity_cb (NULL, state);
2476 tool_load_selection ((GnmGenericToolState *)state, TRUE);
2478 return 0;
2481 /**********************************************/
2482 /* End of Regression tool code */
2483 /**********************************************/
2485 /**********************************************/
2486 /* Begin of Exponential smoothing tool code */
2487 /**********************************************/
2491 * exp_smoothing_tool_ok_clicked_cb:
2492 * @button:
2493 * @state:
2496 static void
2497 exp_smoothing_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
2498 ExpSmoothToolState *state)
2500 data_analysis_output_t *dao;
2501 analysis_tools_data_exponential_smoothing_t *data;
2503 GtkWidget *w;
2505 data = g_new0 (analysis_tools_data_exponential_smoothing_t, 1);
2506 dao = parse_output ((GnmGenericToolState *)state, NULL);
2508 data->base.input = gnm_expr_entry_parse_as_list (
2509 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
2510 data->base.group_by = gnm_gui_group_value (state->base.gui, grouped_by_group);
2512 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
2513 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
2515 entry_to_float (GTK_ENTRY (state->damping_fact_entry),
2516 &data->damp_fact, TRUE);
2517 entry_to_float (GTK_ENTRY (state->g_damping_fact_entry),
2518 &data->g_damp_fact, TRUE);
2519 entry_to_float (GTK_ENTRY (state->s_damping_fact_entry),
2520 &data->s_damp_fact, TRUE);
2521 entry_to_int (GTK_ENTRY (state->s_period_entry),
2522 &data->s_period, TRUE);
2524 data->std_error_flag = gtk_toggle_button_get_active
2525 (GTK_TOGGLE_BUTTON (state->show_std_errors));
2526 data->show_graph = gtk_toggle_button_get_active
2527 (GTK_TOGGLE_BUTTON (state->graph_button));
2528 data->df = gnm_gui_group_value (state->base.gui, n_group);
2530 data->es_type = gnm_gui_group_value (state->base.gui, exp_smoothing_group);
2532 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
2533 dao, data, analysis_tool_exponential_smoothing_engine,
2534 TRUE))
2535 gtk_widget_destroy (state->base.dialog);
2537 return;
2541 * exp_smoothing_tool_update_sensitivity_cb:
2542 * @state:
2544 * Update the dialog widgets sensitivity.
2545 * We cannot use tool_update_sensitivity_cb
2546 * since we are also considering whether in fact
2547 * a damping factor is given.
2549 static void
2550 exp_smoothing_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
2551 ExpSmoothToolState *state)
2553 int err, period;
2554 gnm_float damp_fact;
2555 GSList *input_range;
2557 input_range = gnm_expr_entry_parse_as_list (
2558 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
2559 if (input_range == NULL) {
2560 gtk_label_set_text (GTK_LABEL (state->base.warning),
2561 _("The input range is invalid."));
2562 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2563 return;
2564 } else
2565 range_list_destroy (input_range);
2567 switch (gnm_gui_group_value (state->base.gui, exp_smoothing_group)) {
2568 case exp_smoothing_type_mtes:
2569 case exp_smoothing_type_ates:
2570 err = entry_to_float (GTK_ENTRY (state->s_damping_fact_entry),
2571 &damp_fact, FALSE);
2572 if (err!= 0 || damp_fact < 0 || damp_fact > 1) {
2573 gtk_label_set_text (GTK_LABEL (state->base.warning),
2574 _("The given seasonal damping "
2575 "factor is invalid."));
2576 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2577 return;
2579 err = entry_to_int (GTK_ENTRY (state->s_period_entry),
2580 &period, FALSE);
2581 if (err!= 0 || period < 2) {
2582 gtk_label_set_text (GTK_LABEL (state->base.warning),
2583 _("The given seasonal period "
2584 "is invalid."));
2585 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2586 return;
2588 /* no break */
2589 case exp_smoothing_type_des:
2590 err = entry_to_float (GTK_ENTRY (state->g_damping_fact_entry),
2591 &damp_fact, FALSE);
2592 if (err!= 0 || damp_fact < 0 || damp_fact > 1) {
2593 gtk_label_set_text (GTK_LABEL (state->base.warning),
2594 _("The given growth "
2595 "damping factor is invalid."));
2596 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2597 return;
2599 /* no break */
2600 case exp_smoothing_type_ses_r:
2601 case exp_smoothing_type_ses_h:
2602 err = entry_to_float (GTK_ENTRY (state->damping_fact_entry),
2603 &damp_fact, FALSE);
2604 if (err!= 0 || damp_fact < 0 || damp_fact > 1) {
2605 gtk_label_set_text (GTK_LABEL (state->base.warning),
2606 _("The given damping factor is invalid."));
2607 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2608 return;
2610 break;
2613 if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
2614 gtk_label_set_text (GTK_LABEL (state->base.warning),
2615 _("The output specification "
2616 "is invalid."));
2617 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2618 return;
2621 gtk_label_set_text (GTK_LABEL (state->base.warning), "");
2622 gtk_widget_set_sensitive (state->base.ok_button, TRUE);
2625 static void
2626 exp_smoothing_tool_check_error_cb (G_GNUC_UNUSED GtkToggleButton *togglebutton, gpointer user_data)
2628 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (user_data), TRUE);
2632 static void
2633 exp_smoothing_ses_h_cb (GtkToggleButton *togglebutton, gpointer user_data)
2635 ExpSmoothToolState *state = (ExpSmoothToolState *)user_data;
2636 gboolean std_error;
2638 if (!gtk_toggle_button_get_active (togglebutton))
2639 return;
2641 gtk_widget_set_sensitive (state->g_damping_fact_entry, FALSE);
2642 gtk_widget_set_sensitive (state->s_damping_fact_entry, FALSE);
2643 gtk_widget_set_sensitive (state->s_period_entry, FALSE);
2645 std_error = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->show_std_errors));
2646 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->n_button), TRUE);
2647 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->show_std_errors), std_error);
2650 static void
2651 exp_smoothing_ses_r_cb (GtkToggleButton *togglebutton, gpointer user_data)
2653 ExpSmoothToolState *state = (ExpSmoothToolState *)user_data;
2654 gboolean std_error;
2656 if (!gtk_toggle_button_get_active (togglebutton))
2657 return;
2659 gtk_widget_set_sensitive (state->g_damping_fact_entry, FALSE);
2660 gtk_widget_set_sensitive (state->s_damping_fact_entry, FALSE);
2661 gtk_widget_set_sensitive (state->s_period_entry, FALSE);
2663 std_error = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->show_std_errors));
2664 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->nm1_button), TRUE);
2665 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->show_std_errors), std_error);
2668 static void
2669 exp_smoothing_des_cb (GtkToggleButton *togglebutton, gpointer user_data)
2671 ExpSmoothToolState *state = (ExpSmoothToolState *)user_data;
2672 gboolean std_error;
2674 if (!gtk_toggle_button_get_active (togglebutton))
2675 return;
2677 gtk_widget_set_sensitive (state->g_damping_fact_entry, TRUE);
2678 gtk_widget_set_sensitive (state->s_damping_fact_entry, FALSE);
2679 gtk_widget_set_sensitive (state->s_period_entry, FALSE);
2681 std_error = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->show_std_errors));
2682 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->nm2_button), TRUE);
2683 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->show_std_errors), std_error);
2686 static void
2687 exp_smoothing_tes_cb (GtkToggleButton *togglebutton, gpointer user_data)
2689 ExpSmoothToolState *state = (ExpSmoothToolState *)user_data;
2690 gboolean std_error;
2692 if (!gtk_toggle_button_get_active (togglebutton))
2693 return;
2695 gtk_widget_set_sensitive (state->g_damping_fact_entry, TRUE);
2696 gtk_widget_set_sensitive (state->s_damping_fact_entry, TRUE);
2697 gtk_widget_set_sensitive (state->s_period_entry, TRUE);
2699 std_error = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->show_std_errors));
2700 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->nm3_button), TRUE);
2701 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->show_std_errors), std_error);
2705 * dialog_exp_smoothing_tool:
2706 * @wbcg:
2707 * @sheet:
2709 * Show the dialog (guru).
2713 dialog_exp_smoothing_tool (WBCGtk *wbcg, Sheet *sheet)
2715 ExpSmoothToolState *state;
2716 char const * plugins[] = { "Gnumeric_fnstat",
2717 "Gnumeric_fnlookup",
2718 "Gnumeric_fnmath",
2719 "Gnumeric_fnlogical",
2720 NULL};
2722 if ((wbcg == NULL) ||
2723 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
2724 return 1;
2726 /* Only pop up one copy per workbook */
2727 if (gnm_dialog_raise_if_exists (wbcg, EXP_SMOOTHING_KEY))
2728 return 0;
2730 state = g_new0 (ExpSmoothToolState, 1);
2732 if (dialog_tool_init (&state->base, wbcg, sheet,
2733 GNUMERIC_HELP_LINK_EXP_SMOOTHING,
2734 "res:ui/exp-smoothing.ui",
2735 "ExpSmoothing",
2736 _("Could not create the Exponential Smoothing "
2737 "Tool dialog."),
2738 EXP_SMOOTHING_KEY,
2739 G_CALLBACK (exp_smoothing_tool_ok_clicked_cb),
2740 NULL,
2741 G_CALLBACK (exp_smoothing_tool_update_sensitivity_cb),
2744 g_free(state);
2745 return 0;
2748 state->damping_fact_entry = go_gtk_builder_get_widget (state->base.gui,
2749 "damping-fact-spin");
2750 gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->damping_fact_entry), 0.2);
2751 float_to_entry (GTK_ENTRY (state->damping_fact_entry), 0.2);
2752 state->g_damping_fact_entry = go_gtk_builder_get_widget (state->base.gui,
2753 "g-damping-fact-spin");
2754 gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->g_damping_fact_entry), 0.25);
2755 state->s_damping_fact_entry = go_gtk_builder_get_widget (state->base.gui,
2756 "s-damping-fact-spin");
2757 gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->s_damping_fact_entry), 0.3);
2758 state->s_period_entry = go_gtk_builder_get_widget (state->base.gui,
2759 "s-period-spin");
2760 gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->s_period_entry), 12.);
2763 state->n_button = go_gtk_builder_get_widget (state->base.gui, "n-button");
2764 state->nm1_button = go_gtk_builder_get_widget (state->base.gui, "nm1-button");
2765 state->nm2_button = go_gtk_builder_get_widget (state->base.gui, "nm2-button");
2766 state->nm3_button = go_gtk_builder_get_widget (state->base.gui, "nm3-button");
2768 state->show_std_errors = go_gtk_builder_get_widget (state->base.gui, "std-errors-button");
2769 state->graph_button = go_gtk_builder_get_widget (state->base.gui, "graph-check");
2771 state->ses_h_button = go_gtk_builder_get_widget (state->base.gui, "ses-h-button");
2772 state->ses_r_button = go_gtk_builder_get_widget (state->base.gui, "ses-r-button");
2773 state->des_button = go_gtk_builder_get_widget (state->base.gui, "des-button");
2774 state->ates_button = go_gtk_builder_get_widget (state->base.gui, "ates-button");
2775 state->mtes_button = go_gtk_builder_get_widget (state->base.gui, "mtes-button");
2777 g_signal_connect_after (G_OBJECT (state->n_button),
2778 "toggled",
2779 G_CALLBACK (exp_smoothing_tool_check_error_cb), state->show_std_errors);
2780 g_signal_connect_after (G_OBJECT (state->nm1_button),
2781 "toggled",
2782 G_CALLBACK (exp_smoothing_tool_check_error_cb), state->show_std_errors);
2783 g_signal_connect_after (G_OBJECT (state->nm2_button),
2784 "toggled",
2785 G_CALLBACK (exp_smoothing_tool_check_error_cb), state->show_std_errors);
2786 g_signal_connect_after (G_OBJECT (state->nm3_button),
2787 "toggled",
2788 G_CALLBACK (exp_smoothing_tool_check_error_cb), state->show_std_errors);
2789 g_signal_connect_after (G_OBJECT (state->damping_fact_entry),
2790 "changed",
2791 G_CALLBACK (exp_smoothing_tool_update_sensitivity_cb), state);
2793 g_signal_connect_after (G_OBJECT (state->ses_h_button),
2794 "toggled",
2795 G_CALLBACK (exp_smoothing_ses_h_cb), state);
2796 g_signal_connect_after (G_OBJECT (state->ses_r_button),
2797 "toggled",
2798 G_CALLBACK (exp_smoothing_ses_r_cb), state);
2799 g_signal_connect_after (G_OBJECT (state->des_button),
2800 "toggled",
2801 G_CALLBACK (exp_smoothing_des_cb), state);
2802 g_signal_connect_after (G_OBJECT (state->ates_button),
2803 "toggled",
2804 G_CALLBACK (exp_smoothing_tes_cb), state);
2805 g_signal_connect_after (G_OBJECT (state->mtes_button),
2806 "toggled",
2807 G_CALLBACK (exp_smoothing_tes_cb), state);
2809 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
2810 GTK_WIDGET (state->damping_fact_entry));
2811 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
2812 GTK_WIDGET (state->g_damping_fact_entry));
2813 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
2814 GTK_WIDGET (state->s_damping_fact_entry));
2816 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
2817 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->ses_h_button), TRUE);
2818 exp_smoothing_ses_h_cb (GTK_TOGGLE_BUTTON (state->ses_h_button), state);
2819 exp_smoothing_tool_update_sensitivity_cb (NULL, state);
2820 tool_load_selection ((GnmGenericToolState *)state, TRUE);
2822 return 0;
2825 /**********************************************/
2826 /* End of Exponential Smoothing tool code */
2827 /**********************************************/
2829 /**********************************************/
2830 /* Begin of Moving Averages tool code */
2831 /**********************************************/
2835 * average_tool_ok_clicked_cb:
2836 * @button:
2837 * @state:
2839 * Retrieve the information from the dialog and call the average_tool.
2840 * Note that we assume that the ok_button is only active if the entry fields
2841 * contain sensible data.
2843 static void
2844 average_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
2845 AverageToolState *state)
2847 data_analysis_output_t *dao;
2848 analysis_tools_data_moving_average_t *data;
2850 GtkWidget *w;
2852 data = g_new0 (analysis_tools_data_moving_average_t, 1);
2853 dao = parse_output ((GnmGenericToolState *)state, NULL);
2855 data->base.input = gnm_expr_entry_parse_as_list (
2856 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
2857 data->base.group_by = gnm_gui_group_value (state->base.gui, grouped_by_group);
2859 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
2860 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
2862 entry_to_int (GTK_ENTRY (state->interval_entry), &data->interval, TRUE);
2863 entry_to_int (GTK_ENTRY (state->offset_spin), &data->offset, TRUE);
2865 data->std_error_flag = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->show_std_errors));
2866 data->show_graph = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->graph_button));
2868 data->df = gnm_gui_group_value (state->base.gui, n_group);
2870 data->ma_type = gnm_gui_group_value (state->base.gui, moving_average_group);
2872 switch (data->ma_type) {
2873 case moving_average_type_sma:
2874 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->central_button))
2875 && (data->interval % 2 == 0))
2876 data->ma_type = moving_average_type_central_sma;
2877 break;
2878 case moving_average_type_cma:
2879 data->interval = 0;
2880 data->offset = 0;
2881 break;
2882 case moving_average_type_spencer_ma:
2883 data->interval = 15;
2884 data->offset = 7;
2885 break;
2886 case moving_average_type_wma:
2887 data->offset = 0;
2888 break;
2889 default:
2890 break;
2893 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
2894 dao, data, analysis_tool_moving_average_engine, TRUE))
2895 gtk_widget_destroy (state->base.dialog);
2897 return;
2901 * average_tool_update_sensitivity_cb:
2902 * @state:
2904 * Update the dialog widgets sensitivity.
2905 * We cannot use tool_update_sensitivity_cb
2906 * since we are also considering whether in fact
2907 * an interval is given.
2909 static void
2910 average_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
2911 AverageToolState *state)
2913 int interval, err, offset;
2914 GSList *input_range;
2915 moving_average_type_t type;
2918 input_range = gnm_expr_entry_parse_as_list (
2919 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
2920 if (input_range == NULL) {
2921 gtk_label_set_text (GTK_LABEL (state->base.warning),
2922 _("The input range is invalid."));
2923 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2924 return;
2925 } else
2926 range_list_destroy (input_range);
2928 type = gnm_gui_group_value (state->base.gui, moving_average_group);
2930 if ((type == moving_average_type_sma) || (type == moving_average_type_wma)) {
2931 err = entry_to_int (GTK_ENTRY (state->interval_entry),
2932 &interval, FALSE);
2933 if (err!= 0 || interval <= 0) {
2934 gtk_label_set_text (GTK_LABEL (state->base.warning),
2935 _("The given interval is invalid."));
2936 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2937 return;
2941 if (type == moving_average_type_sma) {
2942 err = entry_to_int (GTK_ENTRY (state->offset_spin), &offset, FALSE);
2943 if (err!= 0 || offset < 0 || offset > interval) {
2944 gtk_label_set_text (GTK_LABEL (state->base.warning),
2945 _("The given offset is invalid."));
2946 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2947 return;
2951 if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
2952 gtk_label_set_text (GTK_LABEL (state->base.warning),
2953 _("The output specification "
2954 "is invalid."));
2955 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2956 return;
2959 gtk_label_set_text (GTK_LABEL (state->base.warning), "");
2960 gtk_widget_set_sensitive (state->base.ok_button, TRUE);
2963 static void
2964 average_tool_check_error_cb (G_GNUC_UNUSED GtkToggleButton *togglebutton, gpointer user_data)
2966 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (user_data), TRUE);
2969 static void
2970 average_tool_central_cb (GtkToggleButton *togglebutton, gpointer user_data)
2972 AverageToolState *state = (AverageToolState *)user_data;
2973 int interval;
2974 int err;
2976 if (gtk_toggle_button_get_active (togglebutton)) {
2977 err = entry_to_int (GTK_ENTRY (state->interval_entry), &interval, TRUE);
2978 if (err == 0)
2979 gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->offset_spin), (interval/2));
2983 static void
2984 average_tool_prior_cb (GtkToggleButton *togglebutton, gpointer user_data)
2986 AverageToolState *state = (AverageToolState *)user_data;
2988 if (gtk_toggle_button_get_active (togglebutton))
2989 gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->offset_spin), 0.0);
2992 static void
2993 average_tool_interval_cb (G_GNUC_UNUSED GtkWidget *dummy, AverageToolState *state)
2995 int interval;
2996 int err;
2998 err = entry_to_int (GTK_ENTRY (state->interval_entry), &interval, TRUE);
3000 if (err == 0)
3001 gtk_spin_button_set_range (GTK_SPIN_BUTTON (state->offset_spin),
3002 0, interval - 1);
3003 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->central_button)))
3004 gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->offset_spin), interval/2);
3007 static void
3008 average_tool_offset_cb (GtkToggleButton *togglebutton, gpointer user_data)
3010 AverageToolState *state = (AverageToolState *)user_data;
3012 gtk_widget_set_sensitive (state->offset_spin, gtk_toggle_button_get_active (togglebutton));
3016 static void
3017 average_tool_sma_cb (GtkToggleButton *togglebutton, gpointer user_data)
3019 AverageToolState *state = (AverageToolState *)user_data;
3021 if (!gtk_toggle_button_get_active (togglebutton))
3022 return;
3024 gtk_widget_set_sensitive (state->prior_button, TRUE);
3025 gtk_widget_set_sensitive (state->central_button, TRUE);
3026 gtk_widget_set_sensitive (state->offset_button, TRUE);
3027 gtk_widget_set_sensitive (state->interval_entry, TRUE);
3028 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->prior_button), TRUE);
3029 average_tool_update_sensitivity_cb (NULL, state);
3032 static void
3033 average_tool_cma_cb (GtkToggleButton *togglebutton, gpointer user_data)
3035 AverageToolState *state = (AverageToolState *)user_data;
3037 if (!gtk_toggle_button_get_active (togglebutton))
3038 return;
3040 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->prior_button), TRUE);
3041 gtk_widget_set_sensitive (state->prior_button, FALSE);
3042 gtk_widget_set_sensitive (state->central_button, FALSE);
3043 gtk_widget_set_sensitive (state->offset_button, FALSE);
3044 gtk_widget_set_sensitive (state->interval_entry, FALSE);
3045 average_tool_update_sensitivity_cb (NULL, state);
3048 static void
3049 average_tool_wma_cb (GtkToggleButton *togglebutton, gpointer user_data)
3051 AverageToolState *state = (AverageToolState *)user_data;
3053 if (!gtk_toggle_button_get_active (togglebutton))
3054 return;
3055 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->prior_button), TRUE);
3056 gtk_widget_set_sensitive (state->prior_button, FALSE);
3057 gtk_widget_set_sensitive (state->central_button, FALSE);
3058 gtk_widget_set_sensitive (state->offset_button, FALSE);
3059 gtk_widget_set_sensitive (state->interval_entry, TRUE);
3060 average_tool_update_sensitivity_cb (NULL, state);
3063 static void
3064 average_tool_spencer_cb (GtkToggleButton *togglebutton, gpointer user_data)
3066 AverageToolState *state = (AverageToolState *)user_data;
3068 if (!gtk_toggle_button_get_active (togglebutton))
3069 return;
3070 int_to_entry (GTK_ENTRY (state->interval_entry), 15);
3071 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->central_button), TRUE);
3072 gtk_widget_set_sensitive (state->prior_button, FALSE);
3073 gtk_widget_set_sensitive (state->central_button, FALSE);
3074 gtk_widget_set_sensitive (state->offset_button, FALSE);
3075 gtk_widget_set_sensitive (state->interval_entry, FALSE);
3076 average_tool_update_sensitivity_cb (NULL, state);
3080 * dialog_average_tool:
3081 * @wbcg:
3082 * @sheet:
3084 * Show the dialog (guru).
3088 dialog_average_tool (WBCGtk *wbcg, Sheet *sheet)
3090 AverageToolState *state;
3091 char const * plugins[] = { "Gnumeric_fnstat",
3092 "Gnumeric_fnlookup",
3093 "Gnumeric_fnmath",
3094 NULL};
3096 if ((wbcg == NULL) ||
3097 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
3098 return 1;
3100 /* Only pop up one copy per workbook */
3101 if (gnm_dialog_raise_if_exists (wbcg, AVERAGE_KEY))
3102 return 0;
3104 state = g_new0 (AverageToolState, 1);
3106 if (dialog_tool_init (&state->base, wbcg, sheet,
3107 GNUMERIC_HELP_LINK_MOVING_AVERAGES,
3108 "res:ui/moving-averages.ui",
3109 "MovAverages",
3110 _("Could not create the Moving Average Tool "
3111 "dialog."),
3112 AVERAGE_KEY,
3113 G_CALLBACK (average_tool_ok_clicked_cb), NULL,
3114 G_CALLBACK (average_tool_update_sensitivity_cb),
3117 g_free(state);
3118 return 0;
3121 state->interval_entry = go_gtk_builder_get_widget (state->base.gui, "interval-entry");
3122 int_to_entry (GTK_ENTRY (state->interval_entry), 3);
3123 state->n_button = go_gtk_builder_get_widget (state->base.gui, "n-button");
3124 state->nm1_button = go_gtk_builder_get_widget (state->base.gui, "nm1-button");
3125 state->nm2_button = go_gtk_builder_get_widget (state->base.gui, "nm2-button");
3126 state->prior_button = go_gtk_builder_get_widget (state->base.gui, "prior-button");
3127 state->central_button = go_gtk_builder_get_widget (state->base.gui, "central-button");
3128 state->offset_button = go_gtk_builder_get_widget (state->base.gui, "offset-button");
3129 state->offset_spin = go_gtk_builder_get_widget (state->base.gui, "offset-spinbutton");
3130 state->show_std_errors = go_gtk_builder_get_widget (state->base.gui, "std-errors-button");
3131 state->graph_button = go_gtk_builder_get_widget (state->base.gui, "graph-check");
3132 state->sma_button = go_gtk_builder_get_widget (state->base.gui, "sma-button");
3133 state->cma_button = go_gtk_builder_get_widget (state->base.gui, "cma-button");
3134 state->wma_button = go_gtk_builder_get_widget (state->base.gui, "wma-button");
3135 state->spencer_button = go_gtk_builder_get_widget (state->base.gui, "spencer-ma-button");
3138 g_signal_connect_after (G_OBJECT (state->n_button),
3139 "toggled",
3140 G_CALLBACK (average_tool_check_error_cb), state->show_std_errors);
3141 g_signal_connect_after (G_OBJECT (state->nm1_button),
3142 "toggled",
3143 G_CALLBACK (average_tool_check_error_cb), state->show_std_errors);
3144 g_signal_connect_after (G_OBJECT (state->nm2_button),
3145 "toggled",
3146 G_CALLBACK (average_tool_check_error_cb), state->show_std_errors);
3148 g_signal_connect_after (G_OBJECT (state->prior_button),
3149 "toggled",
3150 G_CALLBACK (average_tool_prior_cb), state);
3151 g_signal_connect_after (G_OBJECT (state->central_button),
3152 "toggled",
3153 G_CALLBACK (average_tool_central_cb), state);
3154 g_signal_connect_after (G_OBJECT (state->offset_button),
3155 "toggled",
3156 G_CALLBACK (average_tool_offset_cb), state);
3158 g_signal_connect_after (G_OBJECT (state->sma_button),
3159 "toggled",
3160 G_CALLBACK (average_tool_sma_cb), state);
3161 g_signal_connect_after (G_OBJECT (state->cma_button),
3162 "toggled",
3163 G_CALLBACK (average_tool_cma_cb), state);
3164 g_signal_connect_after (G_OBJECT (state->wma_button),
3165 "toggled",
3166 G_CALLBACK (average_tool_wma_cb), state);
3167 g_signal_connect_after (G_OBJECT (state->spencer_button),
3168 "toggled",
3169 G_CALLBACK (average_tool_spencer_cb), state);
3172 g_signal_connect_after (G_OBJECT (state->interval_entry),
3173 "changed",
3174 G_CALLBACK (average_tool_update_sensitivity_cb), state);
3175 g_signal_connect_after (G_OBJECT (state->interval_entry),
3176 "changed",
3177 G_CALLBACK (average_tool_interval_cb), state);
3179 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
3180 GTK_WIDGET (state->interval_entry));
3182 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
3183 average_tool_update_sensitivity_cb (NULL, state);
3184 tool_load_selection ((GnmGenericToolState *)state, TRUE);
3186 return 0;
3189 /**********************************************/
3190 /* End of Moving Averages tool code */
3191 /**********************************************/
3193 /**********************************************/
3194 /* Begin of histogram tool code */
3195 /**********************************************/
3198 * histogram_tool_update_sensitivity_cb:
3199 * @dummy:
3200 * @state:
3202 * Update the dialog widgets sensitivity
3204 static void
3205 histogram_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
3206 HistogramToolState *state)
3208 int the_n;
3209 gboolean predetermined_bins;
3210 GSList *input_range;
3211 GnmValue *input_range_2 = NULL;
3213 input_range = gnm_expr_entry_parse_as_list
3214 (GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
3215 if (input_range == NULL) {
3216 gtk_label_set_text (GTK_LABEL (state->base.warning),
3217 _("The input range is invalid."));
3218 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3219 return;
3222 range_list_destroy (input_range);
3224 predetermined_bins = gtk_toggle_button_get_active (
3225 GTK_TOGGLE_BUTTON (state->predetermined_button));
3226 if (predetermined_bins) {
3227 input_range_2 = gnm_expr_entry_parse_as_value
3228 (GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
3229 if (input_range_2 == NULL) {
3230 gtk_label_set_text (GTK_LABEL (state->base.warning),
3231 _("The cutoff range is not valid."));
3232 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3233 return;
3235 value_release (input_range_2);
3236 } else if (entry_to_int(state->n_entry, &the_n,FALSE) != 0 || the_n <= 0) {
3237 gtk_label_set_text (GTK_LABEL (state->base.warning),
3238 _("The number of to be calculated cutoffs is invalid."));
3239 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3240 return;
3243 if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
3244 gtk_label_set_text (GTK_LABEL (state->base.warning),
3245 _("The output specification "
3246 "is invalid."));
3247 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3248 return;
3251 gtk_label_set_text (GTK_LABEL (state->base.warning), "");
3252 gtk_widget_set_sensitive (state->base.ok_button, TRUE);
3254 return;
3258 * histogram_tool_ok_clicked_cb:
3259 * @button:
3260 * @state:
3262 * Retrieve the information from the dialog and call the histogram_tool.
3263 * Note that we assume that the ok_button is only active if the entry fields
3264 * contain sensible data.
3266 static void
3267 histogram_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
3268 HistogramToolState *state)
3270 data_analysis_output_t *dao;
3271 analysis_tools_data_histogram_t *data;
3273 GtkWidget *w;
3275 data = g_new0 (analysis_tools_data_histogram_t, 1);
3276 dao = parse_output ((GnmGenericToolState *)state, NULL);
3278 data->base.input = gnm_expr_entry_parse_as_list (
3279 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
3280 data->base.group_by = gnm_gui_group_value (state->base.gui, grouped_by_group);
3282 data->predetermined = gtk_toggle_button_get_active (
3283 GTK_TOGGLE_BUTTON (state->predetermined_button));
3284 if (data->predetermined) {
3285 w = go_gtk_builder_get_widget (state->base.gui, "labels_2_button");
3286 data->bin = gnm_expr_entry_parse_as_value
3287 (GNM_EXPR_ENTRY (state->base.input_entry_2),
3288 state->base.sheet);
3289 } else {
3290 entry_to_int(state->n_entry, &data->n,TRUE);
3291 data->max_given = (0 == entry_to_float (state->max_entry,
3292 &data->max , TRUE));
3293 data->min_given = (0 == entry_to_float (state->min_entry,
3294 &data->min , TRUE));
3295 data->bin = NULL;
3298 data->bin_type = gnm_gui_group_value (state->base.gui, bin_type_group);
3299 data->chart = gnm_gui_group_value (state->base.gui, chart_group);
3301 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
3302 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
3303 w = go_gtk_builder_get_widget (state->base.gui, "percentage-button");
3304 data->percentage = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
3305 w = go_gtk_builder_get_widget (state->base.gui, "cum-button");
3306 data->cumulative = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
3307 w = go_gtk_builder_get_widget (state->base.gui, "only-num-button");
3308 data->only_numbers = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
3310 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
3311 dao, data, analysis_tool_histogram_engine, TRUE))
3312 gtk_widget_destroy (state->base.dialog);
3314 return;
3318 * histogram_tool_set_predetermined:
3319 * @widget:
3320 * @focus_widget:
3321 * @state:
3323 * Output range entry was focused. Switch to output range.
3326 static gboolean
3327 histogram_tool_set_predetermined (G_GNUC_UNUSED GtkWidget *widget,
3328 G_GNUC_UNUSED GdkEventFocus *event,
3329 HistogramToolState *state)
3331 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->predetermined_button), TRUE);
3332 return FALSE;
3336 * histogram_tool_set_calculated:
3337 * @widget:
3338 * @event:
3339 * @state:
3342 static gboolean
3343 histogram_tool_set_calculated (G_GNUC_UNUSED GtkWidget *widget,
3344 G_GNUC_UNUSED GdkEventFocus *event,
3345 HistogramToolState *state)
3347 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->calculated_button), TRUE);
3348 return FALSE;
3352 * dialog_histogram_tool:
3353 * @wbcg:
3354 * @sheet:
3356 * Show the dialog (guru).
3360 dialog_histogram_tool (WBCGtk *wbcg, Sheet *sheet)
3362 HistogramToolState *state;
3363 char const * plugins[] = {"Gnumeric_fnlogical",
3364 "Gnumeric_fnstat",
3365 "Gnumeric_fnlookup",
3366 NULL};
3368 if ((wbcg == NULL) ||
3369 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
3370 return 1;
3372 /* Only pop up one copy per workbook */
3373 if (gnm_dialog_raise_if_exists (wbcg, HISTOGRAM_KEY))
3374 return 0;
3376 state = g_new0 (HistogramToolState, 1);
3378 if (dialog_tool_init (&state->base, wbcg, sheet,
3379 GNUMERIC_HELP_LINK_HISTOGRAM,
3380 "res:ui/histogram.ui", "Histogram",
3381 _("Could not create the Histogram Tool dialog."),
3382 HISTOGRAM_KEY,
3383 G_CALLBACK (histogram_tool_ok_clicked_cb), NULL,
3384 G_CALLBACK (histogram_tool_update_sensitivity_cb),
3387 g_free(state);
3388 return 0;
3391 state->predetermined_button = GTK_WIDGET (go_gtk_builder_get_widget
3392 (state->base.gui,
3393 "pre_determined_button"));
3394 state->calculated_button = GTK_WIDGET (go_gtk_builder_get_widget
3395 (state->base.gui,
3396 "calculated_button"));
3397 state->n_entry = GTK_ENTRY(go_gtk_builder_get_widget (state->base.gui,
3398 "n_entry"));
3399 state->max_entry = GTK_ENTRY(go_gtk_builder_get_widget (state->base.gui,
3400 "max_entry"));
3401 state->min_entry = GTK_ENTRY(go_gtk_builder_get_widget (state->base.gui,
3402 "min_entry"));
3404 g_signal_connect_after (G_OBJECT (state->predetermined_button),
3405 "toggled",
3406 G_CALLBACK (histogram_tool_update_sensitivity_cb), state);
3407 g_signal_connect_after (G_OBJECT (state->calculated_button),
3408 "toggled",
3409 G_CALLBACK (histogram_tool_update_sensitivity_cb), state);
3410 g_signal_connect_after (G_OBJECT (state->n_entry),
3411 "changed",
3412 G_CALLBACK (histogram_tool_update_sensitivity_cb), state);
3413 g_signal_connect (G_OBJECT (state->n_entry),
3414 "key-press-event",
3415 G_CALLBACK (histogram_tool_set_calculated), state);
3416 g_signal_connect (G_OBJECT (state->min_entry),
3417 "key-press-event",
3418 G_CALLBACK (histogram_tool_set_calculated), state);
3419 g_signal_connect (G_OBJECT (state->max_entry),
3420 "key-press-event",
3421 G_CALLBACK (histogram_tool_set_calculated), state);
3422 g_signal_connect (G_OBJECT
3423 (gnm_expr_entry_get_entry (
3424 GNM_EXPR_ENTRY (state->base.input_entry_2))),
3425 "focus-in-event",
3426 G_CALLBACK (histogram_tool_set_predetermined), state);
3428 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
3429 histogram_tool_update_sensitivity_cb (NULL, state);
3430 tool_load_selection ((GnmGenericToolState *)state, TRUE);
3432 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->calculated_button), TRUE);
3433 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state->base.gui,"histogram-button")), TRUE);
3434 gtk_entry_set_text (GTK_ENTRY (state->n_entry), "12");
3436 return 0;
3439 /**********************************************/
3440 /* End of histogram tool code */
3441 /**********************************************/
3443 /**********************************************/
3444 /* Begin of ANOVA (single factor) tool code */
3445 /**********************************************/
3449 * anova_single_tool_ok_clicked_cb:
3450 * @button:
3451 * @state:
3453 * Retrieve the information from the dialog and call the fourier_tool.
3454 * Note that we assume that the ok_button is only active if the entry fields
3455 * contain sensible data.
3457 static void
3458 anova_single_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
3459 AnovaSingleToolState *state)
3461 data_analysis_output_t *dao;
3462 GtkWidget *w;
3463 analysis_tools_data_anova_single_t *data;
3465 data = g_new0 (analysis_tools_data_anova_single_t, 1);
3466 dao = parse_output ((GnmGenericToolState *)state, NULL);
3468 data->base.input = gnm_expr_entry_parse_as_list (
3469 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
3470 data->base.group_by = gnm_gui_group_value (state->base.gui, grouped_by_group);
3472 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
3473 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
3474 data->alpha = gtk_spin_button_get_value
3475 (GTK_SPIN_BUTTON (state->alpha_entry));
3477 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
3478 dao, data, analysis_tool_anova_single_engine, TRUE))
3479 gtk_widget_destroy (state->base.dialog);
3481 return;
3485 * anova_single_tool_update_sensitivity_cb:
3486 * @state:
3488 * Update the dialog widgets sensitivity.
3489 * We cannot use tool_update_sensitivity_cb
3490 * since we are also considering whether in fact
3491 * an alpha is given.
3493 static void
3494 anova_single_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
3495 AnovaSingleToolState *state)
3497 gnm_float alpha;
3498 GSList *input_range;
3500 input_range = gnm_expr_entry_parse_as_list (
3501 GNM_EXPR_ENTRY (state->base.input_entry),
3502 state->base.sheet);
3503 if (input_range == NULL) {
3504 gtk_label_set_text (GTK_LABEL (state->base.warning),
3505 _("The input range is invalid."));
3506 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3507 return;
3508 } else
3509 range_list_destroy (input_range);
3511 /* Checking Alpha*/
3512 alpha = gtk_spin_button_get_value
3513 (GTK_SPIN_BUTTON (state->alpha_entry));
3514 if (!(alpha > 0 && alpha < 1)) {
3515 gtk_label_set_text (GTK_LABEL (state->base.warning),
3516 _("The alpha value should "
3517 "be a number between 0 and 1."));
3518 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3519 return;
3522 /* Checking Output Page */
3523 if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
3524 gtk_label_set_text (GTK_LABEL (state->base.warning),
3525 _("The output specification "
3526 "is invalid."));
3527 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3528 return;
3531 gtk_label_set_text (GTK_LABEL (state->base.warning), "");
3532 gtk_widget_set_sensitive (state->base.ok_button, TRUE);
3538 * dialog_anova_single_tool:
3539 * @wbcg:
3540 * @sheet:
3542 * Show the dialog (guru).
3546 dialog_anova_single_factor_tool (WBCGtk *wbcg, Sheet *sheet)
3548 AnovaSingleToolState *state;
3549 char const * plugins[] = { "Gnumeric_fnstat",
3550 NULL};
3552 if ((wbcg == NULL) ||
3553 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
3554 return 1;
3556 /* Only pop up one copy per workbook */
3557 if (gnm_dialog_raise_if_exists (wbcg, ANOVA_SINGLE_KEY))
3558 return 0;
3560 state = g_new0 (AnovaSingleToolState, 1);
3562 if (dialog_tool_init (&state->base, wbcg, sheet,
3563 GNUMERIC_HELP_LINK_ANOVA_SINGLE_FACTOR,
3564 "res:ui/anova-one.ui", "ANOVA",
3565 _("Could not create the ANOVA (single factor) "
3566 "tool dialog."),
3567 ANOVA_SINGLE_KEY,
3568 G_CALLBACK (anova_single_tool_ok_clicked_cb),
3569 NULL,
3570 G_CALLBACK (anova_single_tool_update_sensitivity_cb),
3573 g_free(state);
3574 return 0;
3577 state->alpha_entry = go_gtk_builder_get_widget (state->base.gui,
3578 "alpha-entry");
3579 float_to_entry (GTK_ENTRY (state->alpha_entry), 0.05);
3580 g_signal_connect_after (G_OBJECT (state->alpha_entry),
3581 "changed",
3582 G_CALLBACK (anova_single_tool_update_sensitivity_cb), state);
3583 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
3584 GTK_WIDGET (state->alpha_entry));
3586 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
3587 anova_single_tool_update_sensitivity_cb (NULL, state);
3588 tool_load_selection ((GnmGenericToolState *)state, TRUE);
3590 return 0;
3593 /**********************************************/
3594 /* End of ANOVA (Single Factor) tool code */
3595 /**********************************************/
3597 /**********************************************/
3598 /* Begin of ANOVA (two factor) tool code */
3599 /**********************************************/
3603 * anova_two_factor_tool_ok_clicked_cb:
3604 * @button:
3605 * @state:
3607 * Retrieve the information from the dialog and call the fourier_tool.
3608 * Note that we assume that the ok_button is only active if the entry fields
3609 * contain sensible data.
3611 static void
3612 anova_two_factor_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
3613 AnovaTwoFactorToolState *state)
3615 data_analysis_output_t *dao;
3616 GtkWidget *w;
3617 analysis_tools_data_anova_two_factor_t *data;
3618 char *text;
3620 if (state->base.warning_dialog != NULL)
3621 gtk_widget_destroy (state->base.warning_dialog);
3623 data = g_new0 (analysis_tools_data_anova_two_factor_t, 1);
3624 dao = parse_output ((GnmGenericToolState *)state, NULL);
3626 data->input = gnm_expr_entry_parse_as_value
3627 (GNM_EXPR_ENTRY (state->base.input_entry),
3628 state->base.sheet);
3629 data->err = analysis_tools_noerr;
3630 data->wbc = GNM_WBC (state->base.wbcg);
3632 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
3633 data->labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
3635 data->alpha = gtk_spin_button_get_value
3636 (GTK_SPIN_BUTTON (state->alpha_entry));
3637 entry_to_int (GTK_ENTRY (state->replication_entry),
3638 &data->replication, TRUE);
3640 if (cmd_analysis_tool (GNM_WBC (state->base.wbcg),
3641 state->base.sheet,
3642 dao, data, analysis_tool_anova_two_factor_engine, FALSE)) {
3643 switch (data->err) {
3644 case analysis_tools_missing_data:
3645 error_in_entry ((GnmGenericToolState *) state,
3646 GTK_WIDGET (state->base.input_entry),
3647 data->labels ? _("The given input range should contain at "
3648 "least two columns and two rows of data and the "
3649 "labels.") :
3650 _("The given input range should contain at "
3651 "least two columns and two rows of data."));
3652 break;
3653 case analysis_tools_too_few_cols:
3654 error_in_entry ((GnmGenericToolState *) state,
3655 GTK_WIDGET (state->base.input_entry),
3656 data->labels ? _("The given input range should contain at "
3657 "least two columns of data and the "
3658 "labels.") :
3659 _("The given input range should contain at "
3660 "least two columns of data."));
3661 break;
3662 case analysis_tools_too_few_rows:
3663 error_in_entry ((GnmGenericToolState *) state,
3664 GTK_WIDGET (state->base.input_entry),
3665 data->labels ? _("The given input range should contain at "
3666 "least two rows of data and the "
3667 "labels.") :
3668 _("The given input range should "
3669 "contain at least two rows of "
3670 "data."));
3671 break;
3672 case analysis_tools_replication_invalid:
3673 error_in_entry ((GnmGenericToolState *) state,
3674 GTK_WIDGET (state->base.input_entry),
3675 _("The number of data rows must be a "
3676 "multiple of the replication "
3677 "number."));
3678 break;
3679 default:
3680 text = g_strdup_printf (
3681 _("An unexpected error has occurred: %d."),
3682 data->err);
3683 error_in_entry ((GnmGenericToolState *) state,
3684 GTK_WIDGET (state->base.input_entry),
3685 text);
3686 g_free (text);
3687 break;
3689 value_release (data->input);
3690 g_free (dao);
3691 g_free (data);
3692 } else
3693 gtk_widget_destroy (state->base.dialog);
3695 return;
3699 * anova_two_factor_tool_update_sensitivity_cb:
3700 * @state:
3702 * Update the dialog widgets sensitivity.
3703 * We cannot use tool_update_sensitivity_cb
3704 * since we are also considering whether in fact
3705 * an alpha and a replication is given.
3707 static void
3708 anova_two_factor_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
3709 AnovaTwoFactorToolState *state)
3711 int replication, err_replication;
3712 gnm_float alpha;
3713 GnmValue *input_range;
3715 /* Checking Input Range */
3716 input_range = gnm_expr_entry_parse_as_value
3717 (GNM_EXPR_ENTRY (state->base.input_entry),
3718 state->base.sheet);
3719 if (input_range == NULL) {
3720 gtk_label_set_text (GTK_LABEL (state->base.warning),
3721 _("The input range is invalid."));
3722 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3723 return;
3724 } else
3725 value_release (input_range);
3727 /* Checking Alpha*/
3728 alpha = gtk_spin_button_get_value
3729 (GTK_SPIN_BUTTON (state->alpha_entry));
3730 if (!(alpha > 0 && alpha < 1)) {
3731 gtk_label_set_text (GTK_LABEL (state->base.warning),
3732 _("The alpha value should "
3733 "be a number between 0 and 1."));
3734 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3735 return;
3739 /* Checking Replication*/
3740 err_replication = entry_to_int (GTK_ENTRY (state->replication_entry),
3741 &replication, FALSE);
3742 if (!(err_replication == 0 && replication > 0)) {
3743 gtk_label_set_text (GTK_LABEL (state->base.warning),
3744 _("The number of rows per sample "
3745 "should be a positive integer."));
3746 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3747 return;
3750 /* Checking Output Page */
3751 if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
3752 gtk_label_set_text (GTK_LABEL (state->base.warning),
3753 _("The output specification "
3754 "is invalid."));
3755 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3756 return;
3759 gtk_label_set_text (GTK_LABEL (state->base.warning), "");
3760 gtk_widget_set_sensitive (state->base.ok_button, TRUE);
3762 return;
3766 * dialog_anova_two_factor_tool:
3767 * @wbcg:
3768 * @sheet:
3770 * Show the dialog (guru).
3774 dialog_anova_two_factor_tool (WBCGtk *wbcg, Sheet *sheet)
3776 AnovaTwoFactorToolState *state;
3777 char const * plugins[] = { "Gnumeric_fnstat",
3778 "Gnumeric_fnlookup",
3779 "Gnumeric_fnmath",
3780 "Gnumeric_fninfo",
3781 "Gnumeric_fnlogical",
3782 NULL};
3784 if ((wbcg == NULL) ||
3785 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
3786 return 1;
3788 /* Only pop up one copy per workbook */
3789 if (gnm_dialog_raise_if_exists (wbcg, ANOVA_TWO_FACTOR_KEY))
3790 return 0;
3792 state = g_new0 (AnovaTwoFactorToolState, 1);
3794 if (dialog_tool_init (&state->base, wbcg, sheet,
3795 GNUMERIC_HELP_LINK_ANOVA_TWO_FACTOR,
3796 "res:ui/anova-two.ui", "ANOVA",
3797 _("Could not create the ANOVA (two factor) "
3798 "tool dialog."),
3799 ANOVA_TWO_FACTOR_KEY,
3800 G_CALLBACK (anova_two_factor_tool_ok_clicked_cb),
3801 NULL,
3802 G_CALLBACK (anova_two_factor_tool_update_sensitivity_cb),
3803 GNM_EE_SINGLE_RANGE))
3805 g_free(state);
3806 return 0;
3809 state->alpha_entry = go_gtk_builder_get_widget (state->base.gui,
3810 "alpha-entry");
3811 float_to_entry (GTK_ENTRY(state->alpha_entry), 0.05);
3812 state->replication_entry = go_gtk_builder_get_widget (state->base.gui,
3813 "replication-entry");
3814 int_to_entry (GTK_ENTRY(state->replication_entry), 1);
3816 g_signal_connect_after (G_OBJECT (state->alpha_entry),
3817 "changed",
3818 G_CALLBACK (anova_two_factor_tool_update_sensitivity_cb),
3819 state);
3820 g_signal_connect_after (G_OBJECT (state->replication_entry),
3821 "changed",
3822 G_CALLBACK (anova_two_factor_tool_update_sensitivity_cb),
3823 state);
3824 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
3825 GTK_WIDGET (state->alpha_entry));
3826 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
3827 GTK_WIDGET (state->replication_entry));
3829 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
3830 anova_two_factor_tool_update_sensitivity_cb (NULL, state);
3831 tool_load_selection ((GnmGenericToolState *)state, FALSE);
3833 return 0;
3836 /**********************************************/
3837 /* End of ANOVA (Two Factor) tool code */
3838 /**********************************************/