Compilation: fix up tools includes.
[gnumeric.git] / src / dialogs / dialog-analysis-tools.c
blob1613be170618b31e3b9c070c8caed41d40b5a05f
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.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 "help.h"
51 #include <widgets/gnm-dao.h>
52 #include <widgets/gnumeric-expr-entry.h>
54 #include <string.h>
55 #include <gtk/gtk.h>
57 /**********************************************/
58 /* Generic guru items */
59 /**********************************************/
63 #define CORRELATION_KEY "analysistools-correlation-dialog"
64 #define COVARIANCE_KEY "analysistools-covariance-dialog"
65 #define DESCRIPTIVE_STATS_KEY "analysistools-descriptive-stats-dialog"
66 #define RANK_PERCENTILE_KEY "analysistools-rank-percentile-dialog"
67 #define TTEST_KEY "analysistools-ttest-dialog"
68 #define FTEST_KEY "analysistools-ftest-dialog"
69 #define SAMPLING_KEY "analysistools-sampling-dialog"
70 #define HISTOGRAM_KEY "analysistools-histogram-dialog"
71 #define FOURIER_KEY "analysistools-fourier-dialog"
72 #define AVERAGE_KEY "analysistools-moving-average-dialog"
73 #define EXP_SMOOTHING_KEY "analysistools-exp-smoothing-dialog"
74 #define REGRESSION_KEY "analysistools-regression-dialog"
75 #define ANOVA_TWO_FACTOR_KEY "analysistools-anova-two-factor-dialog"
76 #define ANOVA_SINGLE_KEY "analysistools-anova-single-factor-dialog"
79 static char const * const grouped_by_group[] = {
80 "grouped_by_row",
81 "grouped_by_col",
82 "grouped_by_area",
83 NULL
86 typedef struct {
87 GnmGenericToolState base;
88 GtkWidget *predetermined_button;
89 GtkWidget *calculated_button;
90 GtkEntry *n_entry;
91 GtkEntry *max_entry;
92 GtkEntry *min_entry;
93 } HistogramToolState;
95 static char const * const bin_type_group[] = {
96 "bintype_no_inf_lower",
97 "bintype_no_inf_upper",
98 "bintype_p_inf_lower",
99 "bintype_p_inf_upper",
100 "bintype_m_inf_lower",
101 "bintype_m_inf_upper",
102 "bintype_pm_inf_lower",
103 "bintype_pm_inf_upper",
104 NULL
107 static char const * const chart_group[] = {
108 "nochart-button",
109 "histogram-button",
110 "barchart-button",
111 "columnchart-button",
112 NULL
115 static char const * const n_group[] = {
116 "n-button",
117 "nm1-button",
118 "nm2-button",
119 "nm3-button",
120 NULL
123 /* Note: the items in this group need to match */
124 /* moving_average_type_t except that */
125 /* moving_average_type_central_sma is a */
126 /* subtype of moving_average_type_sma. */
127 static char const * const moving_average_group[] = {
128 "sma-button",
129 "cma-button",
130 "wma-button",
131 "spencer-ma-button",
132 NULL
135 static char const * const exp_smoothing_group[] = {
136 "ses-h-button",
137 "ses-r-button",
138 "des-button",
139 "ates-button",
140 "mtes-button",
141 NULL
146 typedef struct {
147 GnmGenericToolState base;
148 GtkWidget *summary_stats_button;
149 GtkWidget *mean_stats_button;
150 GtkWidget *kth_largest_button;
151 GtkWidget *kth_smallest_button;
152 GtkWidget *ss_button;
153 GtkWidget *c_entry;
154 GtkWidget *l_entry;
155 GtkWidget *s_entry;
156 } DescriptiveStatState;
158 typedef struct {
159 GnmGenericToolState base;
160 GtkWidget *paired_button;
161 GtkWidget *unpaired_button;
162 GtkWidget *known_button;
163 GtkWidget *unknown_button;
164 GtkWidget *equal_button;
165 GtkWidget *unequal_button;
166 GtkWidget *variablespaired_label;
167 GtkWidget *varianceknown_label;
168 GtkWidget *varianceequal_label;
169 GtkWidget *var1_variance_label;
170 GtkWidget *var2_variance_label;
171 GtkWidget *var1_variance;
172 GtkWidget *var2_variance;
173 GtkWidget *options_grid;
174 GtkWidget *mean_diff_entry;
175 GtkWidget *alpha_entry;
176 ttest_type invocation;
177 } TTestState;
179 typedef struct {
180 GnmGenericToolState base;
181 GtkWidget *options_grid;
182 GtkWidget *method_label;
183 GtkWidget *periodic_button;
184 GtkWidget *random_button;
185 GtkWidget *period_label;
186 GtkWidget *random_label;
187 GtkWidget *period_entry;
188 GtkWidget *random_entry;
189 GtkWidget *number_entry;
190 GtkWidget *offset_label;
191 GtkWidget *offset_entry;
192 GtkWidget *major_label;
193 GtkWidget *row_major_button;
194 GtkWidget *col_major_button;
195 } SamplingState;
197 typedef struct {
198 GnmGenericToolState base;
199 GtkWidget *interval_entry;
200 GtkWidget *show_std_errors;
201 GtkWidget *n_button;
202 GtkWidget *nm1_button;
203 GtkWidget *nm2_button;
204 GtkWidget *prior_button;
205 GtkWidget *central_button;
206 GtkWidget *offset_button;
207 GtkWidget *offset_spin;
208 GtkWidget *graph_button;
209 GtkWidget *sma_button;
210 GtkWidget *cma_button;
211 GtkWidget *wma_button;
212 GtkWidget *spencer_button;
213 } AverageToolState;
215 typedef struct {
216 GnmGenericToolState base;
217 GtkWidget *damping_fact_entry;
218 GtkWidget *g_damping_fact_entry;
219 GtkWidget *s_damping_fact_entry;
220 GtkWidget *s_period_entry;
221 GtkWidget *show_std_errors;
222 GtkWidget *n_button;
223 GtkWidget *nm1_button;
224 GtkWidget *nm2_button;
225 GtkWidget *nm3_button;
226 GtkWidget *graph_button;
227 GtkWidget *ses_h_button;
228 GtkWidget *ses_r_button;
229 GtkWidget *des_button;
230 GtkWidget *ates_button;
231 GtkWidget *mtes_button;
232 } ExpSmoothToolState;
234 typedef struct {
235 GnmGenericToolState base;
236 GtkWidget *confidence_entry;
237 GtkWidget *simple_linear_regression_radio;
238 GtkWidget *switch_variables_check;
239 GtkWidget *residuals_check;
240 } RegressionToolState;
242 typedef struct {
243 GnmGenericToolState base;
244 GtkWidget *alpha_entry;
245 } AnovaSingleToolState;
247 typedef struct {
248 GnmGenericToolState base;
249 GtkWidget *alpha_entry;
250 GtkWidget *replication_entry;
251 } AnovaTwoFactorToolState;
253 typedef struct {
254 GnmGenericToolState base;
255 GtkWidget *alpha_entry;
256 } FTestToolState;
259 /**********************************************/
260 /* Generic functions for the analysis tools. */
261 /* Functions in this section are being used */
262 /* by virtually all tools. */
263 /**********************************************/
267 * error_in_entry:
268 * @state:
269 * @entry:
270 * @err_str:
272 * Show an error dialog and select corresponding entry
274 void
275 error_in_entry (GnmGenericToolState *state, GtkWidget *entry, char const *err_str)
277 go_gtk_notice_nonmodal_dialog ((GtkWindow *) state->dialog,
278 &(state->warning_dialog),
279 GTK_MESSAGE_ERROR,
280 "%s", err_str);
282 if (GNM_EXPR_ENTRY_IS (entry))
283 gnm_expr_entry_grab_focus (GNM_EXPR_ENTRY (entry), TRUE);
284 else
285 focus_on_entry (GTK_ENTRY (entry));
288 static void
289 cb_tool_destroy (GnmGenericToolState *state)
291 if (state->gui != NULL)
292 g_object_unref (state->gui);
293 wbcg_edit_finish (state->wbcg, WBC_EDIT_REJECT, NULL);
294 if (state->state_destroy)
295 state->state_destroy (state);
296 g_free (state);
300 * cb_tool_cancel_clicked:
301 * @button:
302 * @state:
304 * Close (destroy) the dialog
306 static void
307 cb_tool_cancel_clicked (G_GNUC_UNUSED GtkWidget *button,
308 GnmGenericToolState *state)
310 gtk_widget_destroy (state->dialog);
311 return;
317 * dialog_tool_init_buttons:
318 * @state:
319 * @ok_function:
321 * Setup the buttons
324 static void
325 dialog_tool_init_buttons (GnmGenericToolState *state,
326 GCallback ok_function,
327 GCallback close_function)
329 state->ok_button = go_gtk_builder_get_widget (state->gui, "okbutton");
330 g_signal_connect (G_OBJECT (state->ok_button),
331 "clicked",
332 G_CALLBACK (ok_function), state);
334 state->cancel_button = go_gtk_builder_get_widget (state->gui,
335 "cancelbutton");
336 if (close_function == NULL)
337 g_signal_connect (G_OBJECT (state->cancel_button),
338 "clicked",
339 G_CALLBACK (cb_tool_cancel_clicked), state);
340 else
341 g_signal_connect (G_OBJECT (state->cancel_button),
342 "clicked",
343 G_CALLBACK (close_function), state);
345 state->apply_button = go_gtk_builder_get_widget (state->gui, "applybutton");
346 if (state->apply_button != NULL )
347 g_signal_connect (G_OBJECT (state->apply_button),
348 "clicked",
349 G_CALLBACK (ok_function), state);
350 state->help_button = go_gtk_builder_get_widget (state->gui, "helpbutton");
351 if (state->help_button != NULL )
352 gnm_init_help_button (state->help_button,
353 state->help_link);
358 * dialog_tool_init: (skip)
359 * @state:
360 * @gui_name:
361 * @dialog_name:
362 * @ok_function:
363 * @sensitivity_cb:
365 * Create the dialog (guru).
368 gboolean
369 dialog_tool_init (GnmGenericToolState *state,
370 WBCGtk *wbcg,
371 Sheet *sheet,
372 char const *help_file,
373 char const *gui_name,
374 char const *dialog_name,
375 char const *error_str,
376 char const *key,
377 GCallback ok_function,
378 GCallback close_function,
379 GCallback sensitivity_cb,
380 GnmExprEntryFlags flags)
382 GtkGrid *grid;
383 GtkWidget *widget;
385 state->wbcg = wbcg;
386 state->wb = wb_control_get_workbook (GNM_WBC (wbcg));
387 state->sheet = sheet;
388 state->sv = wb_control_cur_sheet_view (GNM_WBC (wbcg));
389 state->warning_dialog = NULL;
390 state->help_link = help_file;
391 state->state_destroy = NULL;
393 state->gui = gnm_gtk_builder_load (gui_name, NULL, GO_CMD_CONTEXT (wbcg));
394 if (state->gui == NULL)
395 goto dialog_tool_init_error;
397 state->dialog = go_gtk_builder_get_widget (state->gui, dialog_name);
398 if (state->dialog == NULL)
399 goto dialog_tool_init_error;
402 dialog_tool_init_buttons (state, ok_function, close_function);
404 widget = go_gtk_builder_get_widget (state->gui, "var1-label");
405 if (widget == NULL) {
406 state->input_entry = NULL;
407 } else {
408 guint left_attach, top_attach, width, height;
410 grid = GTK_GRID (gtk_widget_get_parent (widget));
411 state->input_entry = gnm_expr_entry_new (state->wbcg, TRUE);
412 g_object_set (G_OBJECT (state->input_entry), "hexpand", TRUE, NULL);
413 gnm_expr_entry_disable_tips (state->input_entry);
414 gnm_expr_entry_set_flags (state->input_entry,
415 flags | GNM_EE_FORCE_ABS_REF,
416 GNM_EE_MASK);
418 gtk_container_child_get (GTK_CONTAINER (grid), widget,
419 "left-attach", &left_attach,
420 "top-attach", &top_attach,
421 "width", &width,
422 "height", &height,
423 NULL);
425 gtk_grid_attach (grid, GTK_WIDGET (state->input_entry),
426 left_attach + width, top_attach,
427 1, height);
428 g_signal_connect_after (G_OBJECT (state->input_entry),
429 "changed",
430 G_CALLBACK (sensitivity_cb), state);
431 gnm_editable_enters (GTK_WINDOW (state->dialog),
432 GTK_WIDGET (state->input_entry));
433 gtk_label_set_mnemonic_widget (GTK_LABEL (widget),
434 GTK_WIDGET (state->input_entry));
435 go_atk_setup_label (widget, GTK_WIDGET (state->input_entry));
436 gtk_widget_show (GTK_WIDGET (state->input_entry));
440 /* */
441 /* If there is a var2-label, we need a second input field */
442 /* */
443 widget = go_gtk_builder_get_widget (state->gui, "var2-label");
444 if (widget == NULL) {
445 state->input_entry_2 = NULL;
446 } else {
447 guint left_attach, top_attach, width, height;
449 state->input_entry_2 = gnm_expr_entry_new (state->wbcg, TRUE);
450 g_object_set (G_OBJECT (state->input_entry_2), "hexpand", TRUE, NULL);
451 gnm_expr_entry_disable_tips (state->input_entry_2);
452 gnm_expr_entry_set_flags (state->input_entry_2,
453 GNM_EE_SINGLE_RANGE | GNM_EE_FORCE_ABS_REF, GNM_EE_MASK);
454 grid = GTK_GRID (gtk_widget_get_parent (widget));
456 gtk_container_child_get (GTK_CONTAINER (grid), widget,
457 "left-attach", &left_attach,
458 "top-attach", &top_attach,
459 "width", &width,
460 "height", &height,
461 NULL);
463 gtk_grid_attach (grid, GTK_WIDGET (state->input_entry_2),
464 left_attach + width, top_attach,
465 1, height);
466 g_signal_connect_after (G_OBJECT (state->input_entry_2),
467 "changed",
468 G_CALLBACK (sensitivity_cb), state);
469 gnm_editable_enters (GTK_WINDOW (state->dialog),
470 GTK_WIDGET (state->input_entry_2));
471 gtk_label_set_mnemonic_widget (GTK_LABEL (widget),
472 GTK_WIDGET (state->input_entry_2));
473 go_atk_setup_label (widget, GTK_WIDGET (state->input_entry_2));
474 gtk_widget_show (GTK_WIDGET (state->input_entry_2));
477 state->warning = go_gtk_builder_get_widget (state->gui, "warnings");
478 wbc_gtk_attach_guru (state->wbcg, state->dialog);
479 g_object_set_data_full (G_OBJECT (state->dialog),
480 "state", state, (GDestroyNotify) cb_tool_destroy);
482 dialog_tool_init_outputs (state, sensitivity_cb);
484 gnm_keyed_dialog (wbcg, GTK_WINDOW (state->dialog), key);
486 gnm_dialog_setup_destroy_handlers (GTK_DIALOG (state->dialog),
487 state->wbcg,
488 GNM_DIALOG_DESTROY_SHEET_REMOVED |
489 GNM_DIALOG_DESTROY_SHEET_RENAMED);
491 return FALSE;
493 dialog_tool_init_error:
494 go_gtk_notice_dialog (wbcg_toplevel (wbcg),
495 GTK_MESSAGE_ERROR,
496 "%s", error_str);
497 g_free (state);
498 return TRUE;
502 * tool_load_selection:
503 * @state:
505 * load the current selection in the output and input entries
506 * show the dialog and focus the input_entry
509 void
510 tool_load_selection (GnmGenericToolState *state, gboolean allow_multiple)
512 GnmRange const *first = selection_first_range (state->sv, NULL, NULL);
514 if (first != NULL) {
515 if (allow_multiple) {
516 char *text = selection_to_string (state->sv, TRUE);
517 gnm_expr_entry_load_from_text (state->input_entry,
518 text);
519 g_free (text);
520 } else
521 gnm_expr_entry_load_from_range (state->input_entry,
522 state->sheet, first);
523 if (state->gdao != NULL)
524 gnm_dao_load_range (GNM_DAO (state->gdao), first);
527 gtk_widget_show (state->dialog);
528 gnm_expr_entry_grab_focus (GNM_EXPR_ENTRY (state->input_entry),
529 TRUE);
534 * tool_setup_update: (skip)
536 GtkWidget *
537 tool_setup_update (GnmGenericToolState* state, char const *name, GCallback cb,
538 gpointer closure)
540 GtkWidget *w = go_gtk_builder_get_widget (state->gui, name);
541 if (GTK_IS_SPIN_BUTTON (w)) {
542 g_signal_connect_after (w, "value-changed", cb, closure);
543 gnm_editable_enters (GTK_WINDOW (state->dialog), w);
544 } else if (GTK_IS_ENTRY (w)) {
545 g_signal_connect_after (w, "changed", cb, closure);
546 gnm_editable_enters (GTK_WINDOW (state->dialog), w);
547 } else if (GTK_IS_TOGGLE_BUTTON (w))
548 g_signal_connect_after (w, "toggled", cb, closure);
549 else
550 g_warning ("tool_setup_update called with unknown type");
551 return w;
557 /**********************************************/
558 /* Generic functions for the analysis tools */
559 /* Functions in this section are being used */
560 /* some tools */
561 /**********************************************/
564 * tool_update_sensitivity_cb:
565 * @dummy:
566 * @state:
568 * Update the dialog widgets sensitivity if the only items of interest
569 * are one or two standard input and one output item, permitting multiple
570 * areas as first input.
572 * used by:
573 * Correlation
574 * Covariance
575 * RankPercentile
576 * FourierAnalysis
579 static void
580 tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
581 GnmGenericToolState *state)
583 GSList *input_range;
585 /* Checking Input Range */
586 input_range = gnm_expr_entry_parse_as_list (
587 GNM_EXPR_ENTRY (state->input_entry), state->sheet);
588 if (input_range == NULL) {
589 gtk_label_set_text (GTK_LABEL (state->warning),
590 _("The input range is invalid."));
591 gtk_widget_set_sensitive (state->ok_button, FALSE);
592 return;
593 } else
594 range_list_destroy (input_range);
596 /* Checking Output Page */
597 if (!gnm_dao_is_ready (GNM_DAO (state->gdao))) {
598 gtk_label_set_text (GTK_LABEL (state->warning),
599 _("The output specification "
600 "is invalid."));
601 gtk_widget_set_sensitive (state->ok_button, FALSE);
602 return;
605 gtk_label_set_text (GTK_LABEL (state->warning), "");
606 gtk_widget_set_sensitive (state->ok_button, TRUE);
608 return;
611 /**********************************************/
612 /* Begin of correlation tool code */
613 /**********************************************/
617 * corr_tool_ok_clicked_cb:
618 * @button:
619 * @state:
621 * Retrieve the information from the dialog and call the correlation_tool.
622 * Note that we assume that the ok_button is only active if the entry fields
623 * contain sensible data.
625 static void
626 corr_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
627 GnmGenericToolState *state)
629 data_analysis_output_t *dao;
630 analysis_tools_data_generic_t *data;
632 char *text;
633 GtkWidget *w;
635 if (state->warning_dialog != NULL)
636 gtk_widget_destroy (state->warning_dialog);
638 data = g_new0 (analysis_tools_data_generic_t, 1);
639 dao = parse_output (state, NULL);
641 data->input = gnm_expr_entry_parse_as_list (
642 GNM_EXPR_ENTRY (state->input_entry), state->sheet);
643 data->group_by = gnm_gui_group_value (state->gui, grouped_by_group);
645 w = go_gtk_builder_get_widget (state->gui, "labels_button");
646 data->labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
648 if (cmd_analysis_tool (GNM_WBC (state->wbcg), state->sheet,
649 dao, data, analysis_tool_correlation_engine, FALSE)) {
651 switch (data->err - 1) {
652 case GROUPED_BY_ROW:
653 error_in_entry ((GnmGenericToolState *) state,
654 GTK_WIDGET (state->input_entry),
655 _("The selected input rows must have equal size!"));
656 break;
657 case GROUPED_BY_COL:
658 error_in_entry ((GnmGenericToolState *) state,
659 GTK_WIDGET (state->input_entry),
660 _("The selected input columns must have equal size!"));
661 break;
662 case GROUPED_BY_AREA:
663 error_in_entry ((GnmGenericToolState *) state,
664 GTK_WIDGET (state->input_entry),
665 _("The selected input areas must have equal size!"));
666 break;
667 default:
668 text = g_strdup_printf (
669 _("An unexpected error has occurred: %d."), data->err);
670 error_in_entry ((GnmGenericToolState *) state,
671 GTK_WIDGET (state->input_entry), text);
672 g_free (text);
673 break;
675 range_list_destroy (data->input);
676 g_free (dao);
677 g_free (data);
678 } else
679 gtk_widget_destroy (state->dialog);
680 return;
686 * dialog_correlation_tool:
687 * @wbcg:
688 * @sheet:
690 * Show the dialog (guru).
694 dialog_correlation_tool (WBCGtk *wbcg, Sheet *sheet)
696 GnmGenericToolState *state;
697 char const * plugins[] = { "Gnumeric_fnstat",
698 NULL};
700 if ((wbcg == NULL) ||
701 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
702 return 1;
704 /* Only pop up one copy per workbook */
705 if (gnm_dialog_raise_if_exists (wbcg, CORRELATION_KEY))
706 return 0;
708 state = g_new0 (GnmGenericToolState, 1);
710 if (dialog_tool_init (state, wbcg, sheet,
711 GNUMERIC_HELP_LINK_CORRELATION,
712 "res:ui/correlation.ui", "Correlation",
713 _("Could not create the Correlation Tool dialog."),
714 CORRELATION_KEY,
715 G_CALLBACK (corr_tool_ok_clicked_cb), NULL,
716 G_CALLBACK (tool_update_sensitivity_cb),
718 return 0;
720 gnm_dao_set_put (GNM_DAO (state->gdao), TRUE, TRUE);
721 tool_update_sensitivity_cb (NULL, state);
722 tool_load_selection ((GnmGenericToolState *)state, TRUE);
724 return 0;
727 /**********************************************/
728 /* End of correlation tool code */
729 /**********************************************/
731 /**********************************************/
732 /* Begin of covariance tool code */
733 /**********************************************/
737 * cov_tool_ok_clicked_cb:
738 * @button:
739 * @state:
741 * Retrieve the information from the dialog and call the covariance_tool.
742 * Note that we assume that the ok_button is only active if the entry fields
743 * contain sensible data.
745 static void
746 cov_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
747 GnmGenericToolState *state)
749 data_analysis_output_t *dao;
750 analysis_tools_data_generic_t *data;
752 char *text;
753 GtkWidget *w;
755 if (state->warning_dialog != NULL)
756 gtk_widget_destroy (state->warning_dialog);
758 data = g_new0 (analysis_tools_data_generic_t, 1);
759 dao = parse_output (state, NULL);
761 data->input = gnm_expr_entry_parse_as_list (
762 GNM_EXPR_ENTRY (state->input_entry), state->sheet);
763 data->group_by = gnm_gui_group_value (state->gui, grouped_by_group);
765 w = go_gtk_builder_get_widget (state->gui, "labels_button");
766 data->labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
768 if (cmd_analysis_tool (GNM_WBC (state->wbcg), state->sheet,
769 dao, data, analysis_tool_covariance_engine, FALSE)) {
771 switch (data->err - 1) {
772 case GROUPED_BY_ROW:
773 error_in_entry ((GnmGenericToolState *) state,
774 GTK_WIDGET (state->input_entry),
775 _("The selected input rows must have equal size!"));
776 break;
777 case GROUPED_BY_COL:
778 error_in_entry ((GnmGenericToolState *) state,
779 GTK_WIDGET (state->input_entry),
780 _("The selected input columns must have equal size!"));
781 break;
782 case GROUPED_BY_AREA:
783 error_in_entry ((GnmGenericToolState *) state,
784 GTK_WIDGET (state->input_entry),
785 _("The selected input areas must have equal size!"));
786 break;
787 default:
788 text = g_strdup_printf (
789 _("An unexpected error has occurred: %d."), data->err);
790 error_in_entry ((GnmGenericToolState *) state,
791 GTK_WIDGET (state->input_entry), text);
792 g_free (text);
793 break;
795 range_list_destroy (data->input);
796 g_free (dao);
797 g_free (data);
798 } else
799 gtk_widget_destroy (state->dialog);
800 return;
806 * dialog_covariance_tool:
807 * @wbcg:
808 * @sheet:
810 * Show the dialog (guru).
814 dialog_covariance_tool (WBCGtk *wbcg, Sheet *sheet)
816 GnmGenericToolState *state;
817 char const * plugins[] = { "Gnumeric_fnstat",
818 NULL};
820 if ((wbcg == NULL) ||
821 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
822 return 1;
824 /* Only pop up one copy per workbook */
825 if (gnm_dialog_raise_if_exists (wbcg, COVARIANCE_KEY))
826 return 0;
828 state = g_new0 (GnmGenericToolState, 1);
830 if (dialog_tool_init (state, wbcg, sheet,
831 GNUMERIC_HELP_LINK_COVARIANCE,
832 "res:ui/covariance.ui", "Covariance",
833 _("Could not create the Covariance Tool dialog."),
834 COVARIANCE_KEY,
835 G_CALLBACK (cov_tool_ok_clicked_cb), NULL,
836 G_CALLBACK (tool_update_sensitivity_cb),
838 return 0;
840 gnm_dao_set_put (GNM_DAO (state->gdao), TRUE, TRUE);
841 tool_update_sensitivity_cb (NULL, state);
842 tool_load_selection ((GnmGenericToolState *)state, TRUE);
844 return 0;
847 /**********************************************/
848 /* End of covariance tool code */
849 /**********************************************/
851 /**********************************************/
852 /* Begin of rank and percentile tool code */
853 /**********************************************/
857 * rank_tool_ok_clicked_cb:
858 * @button:
859 * @state:
861 * Retrieve the information from the dialog and call the ranking_tool.
862 * Note that we assume that the ok_button is only active if the entry fields
863 * contain sensible data.
865 static void
866 rank_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
867 GnmGenericToolState *state)
869 data_analysis_output_t *dao;
870 analysis_tools_data_ranking_t *data;
872 GtkWidget *w;
874 data = g_new0 (analysis_tools_data_ranking_t, 1);
875 dao = parse_output (state, NULL);
877 data->base.input = gnm_expr_entry_parse_as_list (
878 GNM_EXPR_ENTRY (state->input_entry), state->sheet);
879 data->base.group_by = gnm_gui_group_value (state->gui, grouped_by_group);
881 w = go_gtk_builder_get_widget (state->gui, "labels_button");
882 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
884 w = go_gtk_builder_get_widget (state->gui, "rank_button");
885 data->av_ties = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
888 if (!cmd_analysis_tool (GNM_WBC (state->wbcg), state->sheet,
889 dao, data, analysis_tool_ranking_engine, TRUE))
890 gtk_widget_destroy (state->dialog);
891 return;
897 * dialog_ranking_tool:
898 * @wbcg:
899 * @sheet:
901 * Show the dialog (guru).
905 dialog_ranking_tool (WBCGtk *wbcg, Sheet *sheet)
907 GnmGenericToolState *state;
908 char const * plugins[] = { "Gnumeric_fnstat",
909 "Gnumeric_fnlookup",
910 NULL};
912 if ((wbcg == NULL) ||
913 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
914 return 1;
916 /* Only pop up one copy per workbook */
917 if (gnm_dialog_raise_if_exists (wbcg, RANK_PERCENTILE_KEY))
918 return 0;
920 state = g_new0 (GnmGenericToolState, 1);
922 if (dialog_tool_init (state, wbcg, sheet,
923 GNUMERIC_HELP_LINK_RANKING,
924 "res:ui/rank.ui", "RankPercentile",
925 _("Could not create the Rank and Percentile "
926 "Tools dialog."),
927 RANK_PERCENTILE_KEY,
928 G_CALLBACK (rank_tool_ok_clicked_cb), NULL,
929 G_CALLBACK (tool_update_sensitivity_cb),
931 return 0;
933 gnm_dao_set_put (GNM_DAO (state->gdao), TRUE, TRUE);
934 tool_update_sensitivity_cb (NULL, state);
935 tool_load_selection ((GnmGenericToolState *)state, TRUE);
937 return 0;
940 /**********************************************/
941 /* End of rank and percentile tool code */
942 /**********************************************/
944 /**********************************************/
945 /* Begin of Fourier analysis tool code */
946 /**********************************************/
949 * fourier_tool_ok_clicked_cb:
950 * @button:
951 * @state:
953 * Retrieve the information from the dialog and call the fourier_tool.
954 * Note that we assume that the ok_button is only active if the entry fields
955 * contain sensible data.
957 static void
958 fourier_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
959 GnmGenericToolState *state)
961 data_analysis_output_t *dao;
962 analysis_tools_data_fourier_t *data;
964 GtkWidget *w;
966 data = g_new0 (analysis_tools_data_fourier_t, 1);
967 dao = parse_output (state, NULL);
969 data->base.wbc = GNM_WBC (state->wbcg);
970 data->base.input = gnm_expr_entry_parse_as_list (
971 GNM_EXPR_ENTRY (state->input_entry), state->sheet);
972 data->base.group_by = gnm_gui_group_value (state->gui, grouped_by_group);
974 w = go_gtk_builder_get_widget (state->gui, "labels_button");
975 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
977 w = go_gtk_builder_get_widget (state->gui, "inverse_button");
978 data->inverse = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)) != 0;
980 if (!cmd_analysis_tool (GNM_WBC (state->wbcg), state->sheet,
981 dao, data, analysis_tool_fourier_engine, TRUE))
982 gtk_widget_destroy (state->dialog);
984 return;
990 * dialog_fourier_tool:
991 * @wbcg:
992 * @sheet:
994 * Show the dialog (guru).
998 dialog_fourier_tool (WBCGtk *wbcg, Sheet *sheet)
1000 GnmGenericToolState *state;
1001 char const * plugins[] = { "Gnumeric_fnTimeSeriesAnalysis",
1002 "Gnumeric_fncomplex",
1003 NULL};
1005 if ((wbcg == NULL) ||
1006 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
1007 return 1;
1009 /* Only pop up one copy per workbook */
1010 if (gnm_dialog_raise_if_exists (wbcg, FOURIER_KEY))
1011 return 0;
1013 state = g_new0 (GnmGenericToolState, 1);
1015 if (dialog_tool_init (state, wbcg, sheet,
1016 GNUMERIC_HELP_LINK_FOURIER_ANALYSIS,
1017 "res:ui/fourier-analysis.ui", "FourierAnalysis",
1018 _("Could not create the Fourier Analysis Tool "
1019 "dialog."),
1020 FOURIER_KEY,
1021 G_CALLBACK (fourier_tool_ok_clicked_cb), NULL,
1022 G_CALLBACK (tool_update_sensitivity_cb),
1024 return 0;
1026 gnm_dao_set_put (GNM_DAO (state->gdao), TRUE, TRUE);
1027 tool_update_sensitivity_cb (NULL, state);
1028 tool_load_selection ((GnmGenericToolState *)state, TRUE);
1030 return 0;
1033 /**********************************************/
1034 /* End of Fourier analysis tool code */
1035 /**********************************************/
1037 /**********************************************/
1038 /* Begin of descriptive statistics tool code */
1039 /**********************************************/
1042 * cb_desc_stat_tool_ok_clicked:
1043 * @button:
1044 * @state:
1046 * Retrieve the information from the dialog and call the descriptive_stat_tool.
1047 * Note that we assume that the ok_button is only active if the entry fields
1048 * contain sensible data.
1050 static void
1051 cb_desc_stat_tool_ok_clicked (G_GNUC_UNUSED GtkWidget *button,
1052 DescriptiveStatState *state)
1054 data_analysis_output_t *dao;
1055 analysis_tools_data_descriptive_t *data;
1057 GtkWidget *w;
1059 data = g_new0 (analysis_tools_data_descriptive_t, 1);
1060 dao = parse_output ((GnmGenericToolState *)state, NULL);
1062 data->base.input = gnm_expr_entry_parse_as_list (
1063 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
1064 data->base.group_by = gnm_gui_group_value (state->base.gui, grouped_by_group);
1066 data->summary_statistics = gtk_toggle_button_get_active (
1067 GTK_TOGGLE_BUTTON (state->summary_stats_button));
1068 data->confidence_level = gtk_toggle_button_get_active (
1069 GTK_TOGGLE_BUTTON (state->mean_stats_button));
1070 data->kth_largest = gtk_toggle_button_get_active (
1071 GTK_TOGGLE_BUTTON (state->kth_largest_button));
1072 data->kth_smallest = gtk_toggle_button_get_active (
1073 GTK_TOGGLE_BUTTON (state->kth_smallest_button));
1074 data->use_ssmedian = gtk_toggle_button_get_active (
1075 GTK_TOGGLE_BUTTON (state->ss_button));
1077 if (data->confidence_level == 1)
1078 data->c_level = gtk_spin_button_get_value
1079 (GTK_SPIN_BUTTON (state->c_entry));
1081 if (data->kth_largest == 1)
1082 entry_to_int (GTK_ENTRY (state->l_entry), &data->k_largest, TRUE);
1083 if (data->kth_smallest == 1)
1084 entry_to_int (GTK_ENTRY (state->s_entry), &data->k_smallest, TRUE);
1086 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
1087 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
1089 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
1090 dao, data, analysis_tool_descriptive_engine, TRUE))
1091 gtk_widget_destroy (state->base.dialog);
1092 return;
1096 * desc_stat_tool_update_sensitivity_cb:
1097 * @state:
1099 * Update the dialog widgets sensitivity.
1100 * We cannot use tool_update_sensitivity_cb
1101 * since we are also considering whether in fact
1102 * a statistic is selected.
1104 static void
1105 desc_stat_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
1106 DescriptiveStatState *state)
1108 gboolean stats_button, ci_button, largest_button, smallest_button;
1109 GSList *input_range;
1111 /* Part 1: set the buttons on the statistics page. */
1113 stats_button = gtk_toggle_button_get_active
1114 (GTK_TOGGLE_BUTTON (state->summary_stats_button));
1115 gtk_widget_set_sensitive (state->ss_button, stats_button);
1117 ci_button = gtk_toggle_button_get_active
1118 (GTK_TOGGLE_BUTTON (state->mean_stats_button));
1119 gtk_widget_set_sensitive (state->c_entry, ci_button);
1121 largest_button = gtk_toggle_button_get_active
1122 (GTK_TOGGLE_BUTTON (state->kth_largest_button));
1123 gtk_widget_set_sensitive (state->l_entry, largest_button);
1125 smallest_button = gtk_toggle_button_get_active
1126 (GTK_TOGGLE_BUTTON (state->kth_smallest_button));
1127 gtk_widget_set_sensitive (state->s_entry, smallest_button);
1129 /* Part 2: set the okay button */
1131 /* Checking Input Page */
1132 input_range = gnm_expr_entry_parse_as_list (
1133 GNM_EXPR_ENTRY (state->base.input_entry),
1134 state->base.sheet);
1135 if (input_range == NULL) {
1136 gtk_label_set_text (GTK_LABEL (state->base.warning),
1137 _("The input range is invalid."));
1138 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1139 return;
1140 } else
1141 range_list_destroy (input_range);
1143 /* Checking Statistics Page */
1144 if (!(stats_button || ci_button || largest_button || smallest_button)) {
1145 gtk_label_set_text (GTK_LABEL (state->base.warning),
1146 _("No statistics are selected."));
1147 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1148 return;
1151 if (ci_button) {
1152 gdouble c_level = gtk_spin_button_get_value
1153 (GTK_SPIN_BUTTON (state->c_entry));
1154 if (!(c_level > 0 && c_level <1)) {
1155 gtk_label_set_text (GTK_LABEL (state->base.warning),
1156 _("The confidence level should be "
1157 "between 0 and 1."));
1158 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1159 return;
1163 if (largest_button) {
1164 int k;
1165 if ((0 != entry_to_int (GTK_ENTRY (state->l_entry), &k, FALSE))
1166 || !(k >0)) {
1167 gtk_label_set_text (GTK_LABEL (state->base.warning),
1168 _("K must be a positive integer."));
1169 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1170 return;
1174 if (smallest_button) {
1175 int k;
1176 if ((0 != entry_to_int (GTK_ENTRY (state->s_entry), &k, FALSE))
1177 || !(k >0)) {
1178 gtk_label_set_text (GTK_LABEL (state->base.warning),
1179 _("K must be a positive integer."));
1180 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1181 return;
1185 /* Checking Output Page */
1186 if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
1187 gtk_label_set_text (GTK_LABEL (state->base.warning),
1188 _("The output specification "
1189 "is invalid."));
1190 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1191 return;
1194 gtk_label_set_text (GTK_LABEL (state->base.warning), "");
1195 gtk_widget_set_sensitive (state->base.ok_button, TRUE);
1197 return;
1202 * dialog_descriptive_stat_tool:
1203 * @wbcg:
1204 * @sheet:
1206 * Show the dialog (guru).
1210 dialog_descriptive_stat_tool (WBCGtk *wbcg, Sheet *sheet)
1212 DescriptiveStatState *state;
1213 char const * plugins[] = {"Gnumeric_fnstat",
1214 "Gnumeric_fnmath",
1215 NULL};
1217 if ((wbcg == NULL) ||
1218 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
1219 return 1;
1221 /* Only pop up one copy per workbook */
1222 if (gnm_dialog_raise_if_exists (wbcg, DESCRIPTIVE_STATS_KEY))
1223 return 0;
1225 state = g_new0 (DescriptiveStatState, 1);
1227 if (dialog_tool_init (&state->base, wbcg, sheet,
1228 GNUMERIC_HELP_LINK_DESCRIPTIVE_STATS,
1229 "res:ui/descriptive-stats.ui", "DescStats",
1230 _("Could not create the Descriptive Statistics "
1231 "Tool dialog."),
1232 DESCRIPTIVE_STATS_KEY,
1233 G_CALLBACK (cb_desc_stat_tool_ok_clicked), NULL,
1234 G_CALLBACK (desc_stat_tool_update_sensitivity_cb),
1237 g_free(state);
1238 return 0;
1241 state->summary_stats_button = go_gtk_builder_get_widget
1242 (state->base.gui, "summary_stats_button");
1243 state->ss_button = go_gtk_builder_get_widget
1244 (state->base.gui, "ss_button");
1245 state->mean_stats_button = go_gtk_builder_get_widget
1246 (state->base.gui, "mean_stats_button");
1247 state->kth_largest_button = go_gtk_builder_get_widget
1248 (state->base.gui, "kth_largest_button");
1249 state->kth_smallest_button = go_gtk_builder_get_widget
1250 (state->base.gui, "kth_smallest_button");
1251 state->c_entry = go_gtk_builder_get_widget (state->base.gui, "c_entry");
1252 gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->c_entry), 0.95);
1253 state->l_entry = go_gtk_builder_get_widget (state->base.gui, "l_entry");
1254 int_to_entry (GTK_ENTRY (state->l_entry), 1);
1255 state->s_entry = go_gtk_builder_get_widget (state->base.gui, "s_entry");
1256 int_to_entry (GTK_ENTRY (state->s_entry), 1);
1259 g_signal_connect_after (G_OBJECT (state->summary_stats_button),
1260 "toggled",
1261 G_CALLBACK (desc_stat_tool_update_sensitivity_cb), state);
1262 g_signal_connect_after (G_OBJECT (state->mean_stats_button),
1263 "toggled",
1264 G_CALLBACK (desc_stat_tool_update_sensitivity_cb), state);
1265 g_signal_connect_after (G_OBJECT (state->kth_largest_button),
1266 "toggled",
1267 G_CALLBACK (desc_stat_tool_update_sensitivity_cb), state);
1268 g_signal_connect_after (G_OBJECT (state->kth_smallest_button),
1269 "toggled",
1270 G_CALLBACK (desc_stat_tool_update_sensitivity_cb), state);
1271 g_signal_connect_after (G_OBJECT (state->c_entry),
1272 "changed",
1273 G_CALLBACK (desc_stat_tool_update_sensitivity_cb), state);
1274 g_signal_connect_after (G_OBJECT (state->l_entry),
1275 "changed",
1276 G_CALLBACK (desc_stat_tool_update_sensitivity_cb), state);
1277 g_signal_connect_after (G_OBJECT (state->s_entry),
1278 "changed",
1279 G_CALLBACK (desc_stat_tool_update_sensitivity_cb), state);
1280 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
1281 GTK_WIDGET (state->c_entry));
1282 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
1283 GTK_WIDGET (state->l_entry));
1284 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
1285 GTK_WIDGET (state->s_entry));
1287 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
1288 desc_stat_tool_update_sensitivity_cb (NULL, state);
1289 tool_load_selection ((GnmGenericToolState *)state, TRUE);
1291 return 0;
1295 /**********************************************/
1296 /* End of descriptive statistics tool code */
1297 /**********************************************/
1300 /**********************************************/
1301 /* Begin of ttest tool code */
1302 /**********************************************/
1305 * ttest_tool_ok_clicked_cb:
1306 * @button:
1307 * @state:
1309 * Retrieve the information from the dialog and call the appropriate tool.
1310 * Note that we assume that the ok_button is only active if the entry fields
1311 * contain sensible data.
1313 static void
1314 ttest_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
1315 TTestState *state)
1317 data_analysis_output_t *dao;
1318 analysis_tools_data_ttests_t *data;
1320 GtkWidget *w;
1321 int err = 0;
1323 data = g_new0 (analysis_tools_data_ttests_t, 1);
1324 dao = parse_output ((GnmGenericToolState *)state, NULL);
1326 data->base.wbc = GNM_WBC (state->base.wbcg);
1328 if (state->base.warning_dialog != NULL)
1329 gtk_widget_destroy (state->base.warning_dialog);
1331 data->base.range_1 = gnm_expr_entry_parse_as_value
1332 (GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
1334 data->base.range_2 = gnm_expr_entry_parse_as_value
1335 (GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
1337 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
1338 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
1340 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->paired_button)) == 1) {
1341 state->invocation = TTEST_PAIRED;
1342 } else {
1343 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->known_button)) == 1) {
1344 state->invocation = TTEST_ZTEST;
1345 } else {
1346 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
1347 (state->equal_button)) == 1) {
1348 state->invocation = TTEST_UNPAIRED_EQUALVARIANCES;
1349 } else {
1350 state->invocation = TTEST_UNPAIRED_UNEQUALVARIANCES;
1355 err = entry_to_float (GTK_ENTRY (state->mean_diff_entry), &data->mean_diff, TRUE);
1356 err = entry_to_float (GTK_ENTRY (state->alpha_entry), &data->base.alpha, TRUE);
1358 switch (state->invocation) {
1359 case TTEST_PAIRED:
1360 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg),
1361 state->base.sheet,
1362 dao, data, analysis_tool_ttest_paired_engine,
1363 TRUE))
1364 gtk_widget_destroy (state->base.dialog);
1365 break;
1366 case TTEST_UNPAIRED_EQUALVARIANCES:
1367 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
1368 dao, data, analysis_tool_ttest_eqvar_engine, TRUE))
1369 gtk_widget_destroy (state->base.dialog);
1370 break;
1371 case TTEST_UNPAIRED_UNEQUALVARIANCES:
1372 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
1373 dao, data, analysis_tool_ttest_neqvar_engine, TRUE))
1374 gtk_widget_destroy (state->base.dialog);
1375 break;
1376 case TTEST_ZTEST:
1377 err = entry_to_float (GTK_ENTRY (state->var1_variance), &data->var1, TRUE);
1378 if (err != 0 || data->var1 <= 0.0) {
1379 error_in_entry ((GnmGenericToolState *) state, GTK_WIDGET (state->var1_variance),
1380 _("Please enter a valid\n"
1381 "population variance for variable 1."));
1382 g_free (data);
1383 g_free (dao);
1384 return;
1386 err = entry_to_float (GTK_ENTRY (state->var2_variance), &data->var2, TRUE);
1387 if (err != 0 || data->var2 <= 0.0) {
1388 error_in_entry ((GnmGenericToolState *) state, GTK_WIDGET (state->var2_variance),
1389 _("Please enter a valid\n"
1390 "population variance for variable 2."));
1391 g_free (data);
1392 g_free (dao);
1393 return;
1396 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
1397 dao, data, analysis_tool_ztest_engine, TRUE))
1398 gtk_widget_destroy (state->base.dialog);
1399 break;
1402 return;
1406 * ttest_update_sensitivity_cb:
1407 * @dummy:
1408 * @state:
1410 * Update the dialog widgets sensitivity if the only items of interest
1411 * are the standard input (one or two ranges) and output items.
1413 static void
1414 ttest_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
1415 TTestState *state)
1417 gboolean ready = FALSE;
1418 gboolean input_1_ready = FALSE;
1419 gboolean input_2_ready = FALSE;
1420 gboolean output_ready = FALSE;
1421 gboolean mean_diff_ready = FALSE;
1422 gboolean alpha_ready = FALSE;
1423 int err;
1424 gnm_float mean_diff, alpha;
1425 GnmValue *input_range;
1426 GnmValue *input_range_2;
1428 input_range = gnm_expr_entry_parse_as_value
1429 (GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
1430 input_range_2 = gnm_expr_entry_parse_as_value
1431 (GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
1433 err = entry_to_float (GTK_ENTRY (state->mean_diff_entry), &mean_diff, FALSE);
1434 mean_diff_ready = (err == 0);
1435 err = entry_to_float (GTK_ENTRY (state->alpha_entry), &alpha, FALSE);
1436 alpha_ready = (err == 0 && alpha > 0.0 && alpha < 1.0);
1437 input_1_ready = (input_range != NULL);
1438 input_2_ready = ((state->base.input_entry_2 == NULL) || (input_range_2 != NULL));
1439 output_ready = gnm_dao_is_ready (GNM_DAO (state->base.gdao));
1441 value_release (input_range);
1442 value_release (input_range_2);
1444 ready = input_1_ready && input_2_ready && output_ready && alpha_ready && mean_diff_ready;
1445 gtk_widget_set_sensitive (state->base.ok_button, ready);
1447 return;
1451 * ttest_known_toggled_cb:
1452 * @button:
1453 * @state:
1455 * The paired/unpaired variables status has changed.
1458 static void
1459 ttest_known_toggled_cb (GtkWidget *button, TTestState *state)
1461 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) == 1) {
1462 gtk_widget_hide (state->equal_button);
1463 gtk_widget_hide (state->unequal_button);
1464 gtk_widget_hide (state->varianceequal_label);
1465 gtk_widget_show (state->var2_variance_label);
1466 gtk_widget_show (state->var2_variance);
1467 gtk_widget_show (state->var1_variance_label);
1468 gtk_widget_show (state->var1_variance);
1469 } else {
1470 gtk_widget_hide (state->var2_variance_label);
1471 gtk_widget_hide (state->var2_variance);
1472 gtk_widget_hide (state->var1_variance_label);
1473 gtk_widget_hide (state->var1_variance);
1474 gtk_widget_show (state->equal_button);
1475 gtk_widget_show (state->unequal_button);
1476 gtk_widget_show (state->varianceequal_label);
1480 * ttest_paired_toggled_cb:
1481 * @button:
1482 * @state:
1484 * The paired/unpaired variables status has changed.
1487 static void
1488 ttest_paired_toggled_cb (GtkWidget *button, TTestState *state)
1490 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) == 1) {
1491 gtk_widget_hide (state->var2_variance_label);
1492 gtk_widget_hide (state->var2_variance);
1493 gtk_widget_hide (state->var1_variance_label);
1494 gtk_widget_hide (state->var1_variance);
1495 gtk_widget_hide (state->equal_button);
1496 gtk_widget_hide (state->unequal_button);
1497 gtk_widget_hide (state->varianceequal_label);
1498 gtk_widget_hide (state->known_button);
1499 gtk_widget_hide (state->unknown_button);
1500 gtk_widget_hide (state->varianceknown_label);
1501 } else {
1502 gtk_widget_show (state->known_button);
1503 gtk_widget_show (state->unknown_button);
1504 gtk_widget_show (state->varianceknown_label);
1505 ttest_known_toggled_cb (GTK_WIDGET (state->known_button), state);
1510 * dialog_ttest_adjust_to_invocation:
1511 * @state:
1513 * Set the options to match the invocation.
1516 static void
1517 dialog_ttest_adjust_to_invocation (TTestState *state)
1519 switch (state->invocation) {
1520 case TTEST_PAIRED:
1521 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->paired_button), TRUE);
1522 break;
1523 case TTEST_UNPAIRED_EQUALVARIANCES:
1524 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->equal_button), TRUE);
1525 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->unknown_button), TRUE);
1526 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->unpaired_button), TRUE);
1527 break;
1528 case TTEST_UNPAIRED_UNEQUALVARIANCES:
1529 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->unequal_button), TRUE);
1530 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->unknown_button), TRUE);
1531 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->unpaired_button), TRUE);
1532 break;
1533 case TTEST_ZTEST:
1534 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->known_button), TRUE);
1535 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->unpaired_button), TRUE);
1536 break;
1537 default:
1538 break;
1544 * dialog_ttest_realized:
1545 * @widget
1546 * @state:
1548 * Fix the size of the options table.
1551 static void
1552 dialog_ttest_realized (G_GNUC_UNUSED GtkWidget *widget,
1553 TTestState *state)
1555 GtkAllocation alloc;
1557 gtk_widget_get_allocation (state->options_grid, &alloc);
1558 gtk_widget_set_size_request (state->options_grid,
1559 alloc.width, alloc.height);
1561 gtk_widget_get_allocation (state->paired_button, &alloc);
1562 gtk_widget_set_size_request (state->paired_button,
1563 alloc.width, alloc.height);
1565 gtk_widget_get_allocation (state->unpaired_button, &alloc);
1566 gtk_widget_set_size_request (state->unpaired_button,
1567 alloc.width, alloc.height);
1569 gtk_widget_get_allocation (state->variablespaired_label, &alloc);
1570 gtk_widget_set_size_request (state->variablespaired_label,
1571 alloc.width, alloc.height);
1573 ttest_paired_toggled_cb (state->paired_button, state);
1574 dialog_ttest_adjust_to_invocation (state);
1578 * dialog_ttest_tool:
1579 * @wbcg:
1580 * @sheet:
1581 * @test:
1583 * Show the dialog (guru).
1587 dialog_ttest_tool (WBCGtk *wbcg, Sheet *sheet, ttest_type test)
1589 TTestState *state;
1590 GtkDialog *dialog;
1591 char const * plugins[] = {"Gnumeric_fnstat",
1592 "Gnumeric_fnmath",
1593 "Gnumeric_fninfo",
1594 "Gnumeric_fnlogical",
1595 NULL};
1597 if ((wbcg == NULL) ||
1598 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
1599 return 1;
1601 /* Only pop up one copy per workbook */
1602 dialog = gnm_dialog_raise_if_exists (wbcg, TTEST_KEY);
1603 if (dialog) {
1604 state = g_object_get_data (G_OBJECT (dialog), "state");
1605 state->invocation = test;
1606 dialog_ttest_adjust_to_invocation (state);
1607 return 0;
1610 state = g_new0 (TTestState, 1);
1611 state->invocation = test;
1613 if (dialog_tool_init (&state->base, wbcg, sheet,
1614 GNUMERIC_HELP_LINK_MEAN_TESTS,
1615 "res:ui/mean-tests.ui", "MeanTests",
1616 _("Could not create the Mean Tests Tool dialog."),
1617 TTEST_KEY,
1618 G_CALLBACK (ttest_tool_ok_clicked_cb), NULL,
1619 G_CALLBACK (ttest_update_sensitivity_cb),
1620 GNM_EE_SINGLE_RANGE))
1622 g_free(state);
1623 return 0;
1626 state->paired_button = go_gtk_builder_get_widget (state->base.gui, "paired-button");
1627 state->unpaired_button = go_gtk_builder_get_widget (state->base.gui, "unpaired-button");
1628 state->variablespaired_label = go_gtk_builder_get_widget (state->base.gui, "variablespaired-label");
1629 state->known_button = go_gtk_builder_get_widget (state->base.gui, "known-button");
1630 state->unknown_button = go_gtk_builder_get_widget (state->base.gui, "unknown-button");
1631 state->varianceknown_label = go_gtk_builder_get_widget (state->base.gui, "varianceknown-label");
1632 state->equal_button = go_gtk_builder_get_widget (state->base.gui, "equal-button");
1633 state->unequal_button = go_gtk_builder_get_widget (state->base.gui, "unequal-button");
1634 state->varianceequal_label = go_gtk_builder_get_widget (state->base.gui, "varianceequal-label");
1635 state->options_grid = go_gtk_builder_get_widget (state->base.gui, "options-grid");
1636 state->var1_variance_label = go_gtk_builder_get_widget (state->base.gui, "var1_variance-label");
1637 state->var1_variance = go_gtk_builder_get_widget (state->base.gui, "var1-variance");
1638 state->var2_variance_label = go_gtk_builder_get_widget (state->base.gui, "var2_variance-label");
1639 state->var2_variance = go_gtk_builder_get_widget (state->base.gui, "var2-variance");
1640 state->mean_diff_entry = go_gtk_builder_get_widget (state->base.gui, "meandiff");
1641 float_to_entry (GTK_ENTRY (state->mean_diff_entry), 0);
1642 state->alpha_entry = go_gtk_builder_get_widget (state->base.gui, "one_alpha");
1643 float_to_entry (GTK_ENTRY (state->alpha_entry), 0.05);
1645 g_signal_connect_after (G_OBJECT (state->paired_button),
1646 "toggled",
1647 G_CALLBACK (ttest_update_sensitivity_cb), state);
1648 g_signal_connect (G_OBJECT (state->paired_button),
1649 "toggled",
1650 G_CALLBACK (ttest_paired_toggled_cb), state);
1651 g_signal_connect_after (G_OBJECT (state->known_button),
1652 "toggled",
1653 G_CALLBACK (ttest_update_sensitivity_cb), state);
1654 g_signal_connect_after (G_OBJECT (state->mean_diff_entry),
1655 "changed",
1656 G_CALLBACK (ttest_update_sensitivity_cb), state);
1657 g_signal_connect_after (G_OBJECT (state->alpha_entry),
1658 "changed",
1659 G_CALLBACK (ttest_update_sensitivity_cb), state);
1660 g_signal_connect (G_OBJECT (state->known_button),
1661 "toggled",
1662 G_CALLBACK (ttest_known_toggled_cb), state);
1663 g_signal_connect (G_OBJECT (state->base.dialog),
1664 "realize",
1665 G_CALLBACK (dialog_ttest_realized), state);
1666 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
1667 GTK_WIDGET (state->var1_variance));
1668 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
1669 GTK_WIDGET (state->var2_variance));
1670 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
1671 GTK_WIDGET (state->mean_diff_entry));
1672 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
1673 GTK_WIDGET (state->alpha_entry));
1675 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
1676 ttest_update_sensitivity_cb (NULL, state);
1677 tool_load_selection ((GnmGenericToolState *)state, FALSE);
1679 return 0;
1682 /**********************************************/
1683 /* End of ttest tool code */
1684 /**********************************************/
1687 /**********************************************/
1688 /* Begin of ftest tool code */
1689 /**********************************************/
1693 * ftest_tool_ok_clicked_cb:
1694 * @button:
1695 * @state:
1697 * Retrieve the information from the dialog and call the correlation_tool.
1698 * Note that we assume that the ok_button is only active if the entry fields
1699 * contain sensible data.
1701 static void
1702 ftest_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
1703 FTestToolState *state)
1705 data_analysis_output_t *dao;
1706 analysis_tools_data_generic_b_t *data;
1708 GtkWidget *w;
1710 data = g_new0 (analysis_tools_data_generic_b_t, 1);
1711 dao = parse_output ((GnmGenericToolState *)state, NULL);
1713 data->wbc = GNM_WBC (state->base.wbcg);
1715 if (state->base.warning_dialog != NULL)
1716 gtk_widget_destroy (state->base.warning_dialog);
1718 data->range_1 = gnm_expr_entry_parse_as_value
1719 (GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
1721 data->range_2 = gnm_expr_entry_parse_as_value
1722 (GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
1724 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
1725 data->labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
1727 entry_to_float (GTK_ENTRY (state->alpha_entry), &data->alpha, TRUE);
1729 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
1730 dao, data, analysis_tool_ftest_engine, TRUE))
1731 gtk_widget_destroy (state->base.dialog);
1733 return;
1737 * ftest_update_sensitivity_cb:
1738 * @dummy:
1739 * @state:
1741 * Update the dialog widgets sensitivity if the only items of interest
1742 * are the standard input (one or two ranges) and output items.
1744 static void
1745 ftest_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
1746 FTestToolState *state)
1748 gboolean ready = FALSE;
1749 gboolean input_1_ready = FALSE;
1750 gboolean input_2_ready = FALSE;
1751 gboolean output_ready = FALSE;
1752 gboolean alpha_ready = FALSE;
1753 int err;
1754 gnm_float alpha;
1755 GnmValue *input_range;
1756 GnmValue *input_range_2;
1758 input_range = gnm_expr_entry_parse_as_value
1759 (GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
1760 input_range_2 = gnm_expr_entry_parse_as_value
1761 (GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
1763 err = entry_to_float (GTK_ENTRY (state->alpha_entry), &alpha, FALSE);
1764 alpha_ready = (err == 0 && alpha > 0.0 && alpha < 1.0);
1765 input_1_ready = (input_range != NULL);
1766 input_2_ready = ((state->base.input_entry_2 == NULL) || (input_range_2 != NULL));
1767 output_ready = gnm_dao_is_ready (GNM_DAO (state->base.gdao));
1769 value_release (input_range);
1770 value_release (input_range_2);
1772 ready = input_1_ready && input_2_ready && output_ready && alpha_ready;
1773 gtk_widget_set_sensitive (state->base.ok_button, ready);
1775 return;
1779 * dialog_ftest_tool:
1780 * @wbcg:
1781 * @sheet:
1783 * Show the dialog (guru).
1787 dialog_ftest_tool (WBCGtk *wbcg, Sheet *sheet)
1789 FTestToolState *state;
1790 char const * plugins[] = { "Gnumeric_fnstat",
1791 NULL};
1793 if ((wbcg == NULL) ||
1794 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
1795 return 1;
1797 /* Only pop up one copy per workbook */
1798 if (gnm_dialog_raise_if_exists (wbcg, FTEST_KEY))
1799 return 0;
1801 state = g_new0 (FTestToolState, 1);
1803 if (dialog_tool_init (&state->base, wbcg, sheet,
1804 GNUMERIC_HELP_LINK_F_TEST_TWO_SAMPLE,
1805 "res:ui/variance-tests.ui", "VarianceTests",
1806 _("Could not create the FTest Tool dialog."),
1807 FTEST_KEY,
1808 G_CALLBACK (ftest_tool_ok_clicked_cb), NULL,
1809 G_CALLBACK (ftest_update_sensitivity_cb),
1810 GNM_EE_SINGLE_RANGE))
1812 g_free(state);
1813 return 0;
1816 state->alpha_entry = go_gtk_builder_get_widget (state->base.gui, "one_alpha");
1817 float_to_entry (GTK_ENTRY (state->alpha_entry), 0.05);
1818 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
1819 GTK_WIDGET (state->alpha_entry));
1820 g_signal_connect_after (G_OBJECT (state->alpha_entry),
1821 "changed",
1822 G_CALLBACK (ftest_update_sensitivity_cb), state);
1824 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
1825 ftest_update_sensitivity_cb (NULL, state);
1826 tool_load_selection ((GnmGenericToolState *)state, FALSE);
1828 return 0;
1831 /**********************************************/
1832 /* End of ftest tool code */
1833 /**********************************************/
1835 /**********************************************/
1836 /* Begin of sampling tool code */
1837 /**********************************************/
1840 * sampling_tool_update_sensitivity:
1841 * @dummy:
1842 * @state:
1844 * Update the dialog widgets sensitivity if the only items of interest
1845 * are the standard input (one range) and output items.
1847 static void
1848 sampling_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
1849 SamplingState *state)
1851 int periodic, size, number, err;
1852 GSList *input_range;
1854 input_range = gnm_expr_entry_parse_as_list (
1855 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
1857 if (input_range == NULL) {
1858 gtk_label_set_text (GTK_LABEL (state->base.warning),
1859 _("The input range is invalid."));
1860 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1861 return;
1862 } else
1863 range_list_destroy (input_range);
1865 err = entry_to_int (GTK_ENTRY (state->number_entry), &number, FALSE);
1867 if (err != 0 || number < 1) {
1868 gtk_label_set_text (GTK_LABEL (state->base.warning),
1869 _("The requested number of samples is invalid."));
1870 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1871 return;
1874 periodic = gtk_toggle_button_get_active
1875 (GTK_TOGGLE_BUTTON (state->periodic_button));
1877 if (periodic) {
1878 err = entry_to_int
1879 (GTK_ENTRY (state->period_entry), &size, FALSE);
1880 if (err != 0 || size < 1) {
1881 gtk_label_set_text (GTK_LABEL (state->base.warning),
1882 _("The requested period is invalid."));
1883 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1884 return;
1886 err = entry_to_int
1887 (GTK_ENTRY (state->offset_entry), &number, FALSE);
1888 if (err != 0 || number < 0) {
1889 gtk_label_set_text (GTK_LABEL (state->base.warning),
1890 _("The requested offset is invalid."));
1891 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1892 return;
1894 } else {
1895 err = entry_to_int
1896 (GTK_ENTRY (state->random_entry), &size, FALSE);
1897 if (err != 0 || size < 1) {
1898 gtk_label_set_text (GTK_LABEL (state->base.warning),
1899 _("The requested sample size is invalid."));
1900 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1901 return;
1905 if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
1906 gtk_label_set_text (GTK_LABEL (state->base.warning),
1907 _("The output specification "
1908 "is invalid."));
1909 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
1910 return;
1913 gtk_label_set_text (GTK_LABEL (state->base.warning), "");
1914 gtk_widget_set_sensitive (state->base.ok_button, TRUE);
1918 * sampling_tool_ok_clicked_cb:
1919 * @button:
1920 * @state:
1922 * Retrieve the information from the dialog and call the appropriate tool.
1923 * Note that we assume that the ok_button is only active if the entry fields
1924 * contain sensible data.
1926 static void
1927 sampling_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
1928 SamplingState *state)
1930 data_analysis_output_t *dao;
1931 analysis_tools_data_sampling_t *data;
1933 GtkWidget *w;
1935 data = g_new0 (analysis_tools_data_sampling_t, 1);
1936 dao = parse_output ((GnmGenericToolState *)state, NULL);
1938 data->base.wbc = GNM_WBC (state->base.wbcg);
1940 data->base.input = gnm_expr_entry_parse_as_list (
1941 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
1942 data->base.group_by = gnm_gui_group_value (state->base.gui, grouped_by_group);
1944 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
1945 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
1947 data->periodic = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->periodic_button));
1949 if (data->periodic) {
1950 entry_to_int (GTK_ENTRY (state->period_entry), &data->period, TRUE);
1951 entry_to_int (GTK_ENTRY (state->offset_entry), &data->offset, TRUE);
1952 data->row_major = gtk_toggle_button_get_active
1953 (GTK_TOGGLE_BUTTON (state->row_major_button));
1954 } else
1955 entry_to_int (GTK_ENTRY (state->random_entry), &data->size, TRUE);
1957 entry_to_int (GTK_ENTRY (state->number_entry), &data->number, TRUE);
1959 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
1960 dao, data, analysis_tool_sampling_engine, TRUE))
1961 gtk_widget_destroy (state->base.dialog);
1962 return;
1966 * sampling_method_toggled_cb:
1967 * @button:
1968 * @state:
1970 * The method status has changed.
1973 static void
1974 sampling_method_toggled_cb (GtkWidget *button, SamplingState *state)
1976 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) == 1) {
1977 gtk_widget_hide (state->random_label);
1978 gtk_widget_hide (state->random_entry);
1979 gtk_widget_show (state->period_label);
1980 gtk_widget_show (state->period_entry);
1981 gtk_widget_show (state->offset_label);
1982 gtk_widget_show (state->offset_entry);
1983 gtk_widget_show (state->major_label);
1984 gtk_widget_show (state->row_major_button);
1985 gtk_widget_show (state->col_major_button);
1986 } else {
1987 gtk_widget_hide (state->period_label);
1988 gtk_widget_hide (state->period_entry);
1989 gtk_widget_hide (state->period_entry);
1990 gtk_widget_hide (state->offset_label);
1991 gtk_widget_hide (state->offset_entry);
1992 gtk_widget_hide (state->major_label);
1993 gtk_widget_hide (state->row_major_button);
1994 gtk_widget_hide (state->col_major_button);
1995 gtk_widget_show (state->random_label);
1996 gtk_widget_show (state->random_entry);
2002 * dialog_sampling_realized:
2003 * @widget
2004 * @state:
2006 * Fix the size of the options table.
2009 static void
2010 dialog_sampling_realized (G_GNUC_UNUSED GtkWidget *widget,
2011 SamplingState *state)
2013 GtkAllocation alloc;
2015 gtk_widget_get_allocation (state->options_grid, &alloc);
2016 gtk_widget_set_size_request (state->options_grid,
2017 alloc.width, alloc.height);
2019 gtk_widget_get_allocation (state->random_button, &alloc);
2020 gtk_widget_set_size_request (state->random_button,
2021 alloc.width, alloc.height);
2023 gtk_widget_get_allocation (state->periodic_button, &alloc);
2024 gtk_widget_set_size_request (state->periodic_button,
2025 alloc.width, alloc.height);
2027 gtk_widget_get_allocation (state->method_label, &alloc);
2028 gtk_widget_set_size_request (state->method_label,
2029 alloc.width, alloc.height);
2031 sampling_method_toggled_cb (state->periodic_button, state);
2035 * dialog_sampling_tool:
2036 * @wbcg:
2037 * @sheet:
2039 * Show the dialog (guru).
2043 dialog_sampling_tool (WBCGtk *wbcg, Sheet *sheet)
2045 SamplingState *state;
2046 char const * plugins[] = { "Gnumeric_fnlookup",
2047 "Gnumeric_fnrandom",
2048 NULL};
2050 if ((wbcg == NULL) ||
2051 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
2052 return 1;
2054 /* Only pop up one copy per workbook */
2055 if (gnm_dialog_raise_if_exists (wbcg, SAMPLING_KEY)) {
2056 return 0;
2059 state = g_new0 (SamplingState, 1);
2061 if (dialog_tool_init (&state->base, wbcg, sheet,
2062 GNUMERIC_HELP_LINK_SAMPLING,
2063 "res:ui/sampling.ui", "Sampling",
2064 _("Could not create the Sampling Tool dialog."),
2065 SAMPLING_KEY,
2066 G_CALLBACK (sampling_tool_ok_clicked_cb), NULL,
2067 G_CALLBACK (sampling_tool_update_sensitivity_cb),
2070 g_free(state);
2071 return 0;
2074 state->periodic_button = go_gtk_builder_get_widget (state->base.gui, "periodic-button");
2075 state->random_button = go_gtk_builder_get_widget (state->base.gui, "random-button");
2076 state->method_label = go_gtk_builder_get_widget (state->base.gui, "method-label");
2077 state->options_grid = go_gtk_builder_get_widget (state->base.gui, "options-grid");
2078 state->period_label = go_gtk_builder_get_widget (state->base.gui, "period-label");
2079 state->random_label = go_gtk_builder_get_widget (state->base.gui, "random-label");
2080 state->period_entry = go_gtk_builder_get_widget (state->base.gui, "period-entry");
2081 state->random_entry = go_gtk_builder_get_widget (state->base.gui, "random-entry");
2082 state->number_entry = go_gtk_builder_get_widget (state->base.gui, "number-entry");
2083 state->offset_label = go_gtk_builder_get_widget (state->base.gui, "offset-label");
2084 state->offset_entry = go_gtk_builder_get_widget (state->base.gui, "offset-entry");
2085 state->major_label = go_gtk_builder_get_widget (state->base.gui, "pdir-label");
2086 state->row_major_button = go_gtk_builder_get_widget (state->base.gui, "row-major-button");
2087 state->col_major_button = go_gtk_builder_get_widget (state->base.gui, "col-major-button");
2089 int_to_entry (GTK_ENTRY (state->number_entry), 1);
2090 int_to_entry (GTK_ENTRY (state->offset_entry), 0);
2092 g_signal_connect_after (G_OBJECT (state->periodic_button),
2093 "toggled",
2094 G_CALLBACK (sampling_tool_update_sensitivity_cb), state);
2095 g_signal_connect (G_OBJECT (state->periodic_button),
2096 "toggled",
2097 G_CALLBACK (sampling_method_toggled_cb), state);
2098 g_signal_connect (G_OBJECT (state->base.dialog),
2099 "realize",
2100 G_CALLBACK (dialog_sampling_realized), state);
2101 g_signal_connect_after (G_OBJECT (state->period_entry),
2102 "changed",
2103 G_CALLBACK (sampling_tool_update_sensitivity_cb), state);
2104 g_signal_connect_after (G_OBJECT (state->random_entry),
2105 "changed",
2106 G_CALLBACK (sampling_tool_update_sensitivity_cb), state);
2107 g_signal_connect_after (G_OBJECT (state->number_entry),
2108 "changed",
2109 G_CALLBACK (sampling_tool_update_sensitivity_cb), state);
2110 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
2111 GTK_WIDGET (state->period_entry));
2112 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
2113 GTK_WIDGET (state->random_entry));
2114 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
2115 GTK_WIDGET (state->number_entry));
2117 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
2118 sampling_tool_update_sensitivity_cb (NULL, state);
2119 tool_load_selection ((GnmGenericToolState *)state, TRUE);
2121 return 0;
2123 /**********************************************/
2124 /* End of sampling tool code */
2125 /**********************************************/
2127 /**********************************************/
2128 /* Begin of Regression tool code */
2129 /**********************************************/
2131 static gint
2132 regression_tool_calc_height (GnmValue *val)
2134 GnmRange r;
2136 if (NULL == range_init_value (&r, val))
2137 return 0;
2138 return range_height (&r);
2141 static gint
2142 regression_tool_calc_width (GnmValue *val)
2144 GnmRange r;
2146 if (NULL == range_init_value (&r, val))
2147 return 0;
2148 return range_width (&r);
2153 * regression_tool_ok_clicked_cb:
2154 * @button:
2155 * @state:
2157 * Retrieve the information from the dialog and call the regression_tool.
2158 * Note that we assume that the ok_button is only active if the entry fields
2159 * contain sensible data.
2161 static void
2162 regression_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
2163 RegressionToolState *state)
2165 data_analysis_output_t *dao;
2166 analysis_tools_data_regression_t *data;
2168 GtkWidget *w;
2169 gnm_float confidence;
2170 gint y_h;
2172 if (state->base.warning_dialog != NULL)
2173 gtk_widget_destroy (state->base.warning_dialog);
2175 data = g_new0 (analysis_tools_data_regression_t, 1);
2176 dao = parse_output ((GnmGenericToolState *)state, NULL);
2178 data->base.wbc = GNM_WBC (state->base.wbcg);
2180 data->base.range_1 = gnm_expr_entry_parse_as_value (
2181 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
2182 data->base.range_2 = gnm_expr_entry_parse_as_value
2183 (GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
2185 y_h = regression_tool_calc_height(data->base.range_2);
2187 data->group_by = (y_h == 1) ? GROUPED_BY_ROW : GROUPED_BY_COL;
2189 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
2190 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
2192 entry_to_float (GTK_ENTRY (state->confidence_entry), &confidence, TRUE);
2193 data->base.alpha = 1 - confidence;
2195 w = go_gtk_builder_get_widget (state->base.gui, "intercept-button");
2196 data->intercept = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
2198 data->residual = gtk_toggle_button_get_active
2199 (GTK_TOGGLE_BUTTON (state->residuals_check));
2201 data->multiple_regression
2202 = !gtk_toggle_button_get_active
2203 (GTK_TOGGLE_BUTTON (state->simple_linear_regression_radio));
2205 data->multiple_y = gtk_toggle_button_get_active
2206 (GTK_TOGGLE_BUTTON (state->switch_variables_check));
2208 if (cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
2209 dao, data, analysis_tool_regression_engine, FALSE)) {
2210 char *text;
2212 text = g_strdup_printf (
2213 _("An unexpected error has occurred: %d."), data->base.err);
2214 error_in_entry ((GnmGenericToolState *) state,
2215 GTK_WIDGET (state->base.input_entry), text);
2216 g_free (text);
2218 value_release (data->base.range_1);
2219 value_release (data->base.range_2);
2220 g_free (dao);
2221 g_free (data);
2222 } else
2223 gtk_widget_destroy (state->base.dialog);
2228 * regression_tool_update_sensitivity_cb:
2229 * @state:
2231 * Update the dialog widgets sensitivity.
2232 * We cannot use tool_update_sensitivity_cb
2233 * since we are also considering whether in fact
2234 * an interval is given.
2236 static void
2237 regression_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
2238 RegressionToolState *state)
2240 int err;
2241 gnm_float confidence;
2242 GnmValue *input_range;
2243 GnmValue *input_range_2;
2244 gint y_h, y_w;
2245 gint x_h, x_w;
2246 gboolean switch_v;
2248 switch_v = gtk_toggle_button_get_active
2249 (GTK_TOGGLE_BUTTON (state->switch_variables_check));
2251 /* Checking Input Range */
2252 input_range_2 = gnm_expr_entry_parse_as_value (
2253 GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
2254 if (input_range_2 == NULL) {
2255 gtk_label_set_text (GTK_LABEL (state->base.warning),
2256 switch_v ?
2257 _("The x variable range is invalid.") :
2258 _("The y variable range is invalid.") );
2259 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2260 return;
2263 y_h = regression_tool_calc_height(input_range_2);
2264 y_w = regression_tool_calc_width (input_range_2);
2265 value_release (input_range_2);
2267 if (y_h == 0 || y_w == 0) {
2268 gtk_label_set_text (GTK_LABEL (state->base.warning),
2269 switch_v ?
2270 _("The x variable range is invalid.") :
2271 _("The y variable range is invalid."));
2272 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2273 return;
2275 if (y_h != 1 && y_w != 1) {
2276 gtk_label_set_text (GTK_LABEL (state->base.warning),
2277 switch_v ?
2278 _("The x variable range must be a vector (n by 1 or 1 by n).") :
2279 _("The y variable range must be a vector (n by 1 or 1 by n)."));
2280 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2281 return;
2283 if (y_h <= 2 && y_w <= 2) {
2284 gtk_label_set_text (GTK_LABEL (state->base.warning),
2285 switch_v ?
2286 _("The x variable range is too small") :
2287 _("The y variable range is too small"));
2288 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2289 return;
2292 input_range = gnm_expr_entry_parse_as_value
2293 (GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
2294 if (input_range == NULL) {
2295 gtk_label_set_text (GTK_LABEL (state->base.warning),
2296 switch_v ?
2297 _("The y variables range is invalid.") :
2298 _("The x variables range is invalid."));
2299 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2300 return;
2303 x_h = regression_tool_calc_height(input_range);
2304 x_w = regression_tool_calc_width (input_range);
2305 value_release (input_range);
2307 if (x_h == 0 || x_w == 0) {
2308 gtk_label_set_text (GTK_LABEL (state->base.warning),
2309 switch_v ?
2310 _("The y variables range is invalid.") :
2311 _("The x variables range is invalid."));
2312 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2313 return;
2316 if ((y_h == 1 && y_w != x_w) || (y_w == 1 && y_h != x_h)) {
2317 gtk_label_set_text (GTK_LABEL (state->base.warning),
2318 switch_v ?
2319 _("The sizes of the y variable and x variables ranges do not match.") :
2320 _("The sizes of the x variable and y variables ranges do not match."));
2321 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2322 return;
2325 err = entry_to_float (GTK_ENTRY (state->confidence_entry), &confidence, FALSE);
2327 if (err != 0 || (1 < confidence || confidence < 0)) {
2328 gtk_label_set_text (GTK_LABEL (state->base.warning),
2329 _("The confidence level is invalid."));
2330 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2331 return;
2334 if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
2335 gtk_label_set_text (GTK_LABEL (state->base.warning),
2336 _("The output specification "
2337 "is invalid."));
2338 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2339 return;
2342 gtk_label_set_text (GTK_LABEL (state->base.warning), "");
2343 gtk_widget_set_sensitive (state->base.ok_button, TRUE);
2346 static void
2347 regression_tool_regression_radio_toggled_cb (G_GNUC_UNUSED
2348 GtkToggleButton *togglebutton,
2349 RegressionToolState *state)
2351 gboolean simple = gtk_toggle_button_get_active
2352 (GTK_TOGGLE_BUTTON (state->simple_linear_regression_radio));
2353 if (!simple)
2354 gtk_toggle_button_set_active
2355 (GTK_TOGGLE_BUTTON (state->switch_variables_check),
2356 FALSE);
2358 gtk_toggle_button_set_active
2359 (GTK_TOGGLE_BUTTON (state->residuals_check), !simple);
2360 gtk_widget_set_sensitive (state->residuals_check, !simple);
2364 static void
2365 regression_tool_regression_check_toggled_cb (G_GNUC_UNUSED
2366 GtkToggleButton *togglebutton,
2367 RegressionToolState *state)
2369 GtkWidget *w1, *w2;
2371 w1 = go_gtk_builder_get_widget (state->base.gui, "var1-label");
2372 w2 = go_gtk_builder_get_widget (state->base.gui, "var2-label");
2374 if (gtk_toggle_button_get_active
2375 (GTK_TOGGLE_BUTTON (state->switch_variables_check))) {
2376 gtk_toggle_button_set_active
2377 (GTK_TOGGLE_BUTTON
2378 (state->simple_linear_regression_radio),
2379 TRUE);
2380 gtk_label_set_markup_with_mnemonic (GTK_LABEL (w1),
2381 _("_Y variables:"));
2382 gtk_label_set_markup_with_mnemonic (GTK_LABEL (w2),
2383 _("_X variable:"));
2384 } else {
2385 gtk_label_set_markup_with_mnemonic (GTK_LABEL (w1),
2386 _("_X variables:"));
2387 gtk_label_set_markup_with_mnemonic (GTK_LABEL (w2),
2388 _("_Y variable:"));
2390 regression_tool_update_sensitivity_cb (NULL, state);
2395 * dialog_regression_tool:
2396 * @wbcg:
2397 * @sheet:
2399 * Show the dialog (guru).
2403 dialog_regression_tool (WBCGtk *wbcg, Sheet *sheet)
2405 RegressionToolState *state;
2406 char const * plugins[] = { "Gnumeric_fnstat",
2407 "Gnumeric_fnlookup",
2408 "Gnumeric_fnmath",
2409 "Gnumeric_fninfo",
2410 "Gnumeric_fnstring",
2411 NULL};
2413 if ((wbcg == NULL) ||
2414 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
2415 return 1;
2417 /* Only pop up one copy per workbook */
2418 if (gnm_dialog_raise_if_exists (wbcg, REGRESSION_KEY))
2419 return 0;
2421 state = g_new0 (RegressionToolState, 1);
2423 if (dialog_tool_init (&state->base, wbcg, sheet,
2424 GNUMERIC_HELP_LINK_REGRESSION,
2425 "res:ui/regression.ui", "Regression",
2426 _("Could not create the Regression Tool dialog."),
2427 REGRESSION_KEY,
2428 G_CALLBACK (regression_tool_ok_clicked_cb), NULL,
2429 G_CALLBACK (regression_tool_update_sensitivity_cb),
2430 GNM_EE_SINGLE_RANGE))
2432 g_free(state);
2433 return 0;
2436 state->confidence_entry = go_gtk_builder_get_widget (state->base.gui, "confidence-entry");
2437 float_to_entry (GTK_ENTRY (state->confidence_entry), 0.95);
2438 g_signal_connect_after (G_OBJECT (state->confidence_entry),
2439 "changed",
2440 G_CALLBACK (regression_tool_update_sensitivity_cb), state);
2441 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
2442 GTK_WIDGET (state->confidence_entry));
2444 state->simple_linear_regression_radio
2445 = go_gtk_builder_get_widget
2446 (state->base.gui, "simple-regression-button");
2447 state->switch_variables_check
2448 = go_gtk_builder_get_widget
2449 (state->base.gui, "multiple-independent-check");
2450 state->residuals_check
2451 = go_gtk_builder_get_widget
2452 (state->base.gui, "residuals-button");
2453 gtk_toggle_button_set_active
2454 (GTK_TOGGLE_BUTTON (state->simple_linear_regression_radio),
2455 FALSE);
2456 gtk_toggle_button_set_active
2457 (GTK_TOGGLE_BUTTON (state->switch_variables_check),
2458 FALSE);
2459 gtk_toggle_button_set_active
2460 (GTK_TOGGLE_BUTTON (state->residuals_check),
2461 TRUE);
2462 g_signal_connect
2463 (G_OBJECT (state->simple_linear_regression_radio),
2464 "toggled",
2465 G_CALLBACK (regression_tool_regression_radio_toggled_cb),
2466 state);
2467 g_signal_connect
2468 (G_OBJECT (state->switch_variables_check),
2469 "toggled",
2470 G_CALLBACK (regression_tool_regression_check_toggled_cb),
2471 state);
2475 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
2476 regression_tool_update_sensitivity_cb (NULL, state);
2477 tool_load_selection ((GnmGenericToolState *)state, TRUE);
2479 return 0;
2482 /**********************************************/
2483 /* End of Regression tool code */
2484 /**********************************************/
2486 /**********************************************/
2487 /* Begin of Exponential smoothing tool code */
2488 /**********************************************/
2492 * exp_smoothing_tool_ok_clicked_cb:
2493 * @button:
2494 * @state:
2497 static void
2498 exp_smoothing_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
2499 ExpSmoothToolState *state)
2501 data_analysis_output_t *dao;
2502 analysis_tools_data_exponential_smoothing_t *data;
2504 GtkWidget *w;
2506 data = g_new0 (analysis_tools_data_exponential_smoothing_t, 1);
2507 dao = parse_output ((GnmGenericToolState *)state, NULL);
2509 data->base.input = gnm_expr_entry_parse_as_list (
2510 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
2511 data->base.group_by = gnm_gui_group_value (state->base.gui, grouped_by_group);
2513 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
2514 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
2516 entry_to_float (GTK_ENTRY (state->damping_fact_entry),
2517 &data->damp_fact, TRUE);
2518 entry_to_float (GTK_ENTRY (state->g_damping_fact_entry),
2519 &data->g_damp_fact, TRUE);
2520 entry_to_float (GTK_ENTRY (state->s_damping_fact_entry),
2521 &data->s_damp_fact, TRUE);
2522 entry_to_int (GTK_ENTRY (state->s_period_entry),
2523 &data->s_period, TRUE);
2525 data->std_error_flag = gtk_toggle_button_get_active
2526 (GTK_TOGGLE_BUTTON (state->show_std_errors));
2527 data->show_graph = gtk_toggle_button_get_active
2528 (GTK_TOGGLE_BUTTON (state->graph_button));
2529 data->df = gnm_gui_group_value (state->base.gui, n_group);
2531 data->es_type = gnm_gui_group_value (state->base.gui, exp_smoothing_group);
2533 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
2534 dao, data, analysis_tool_exponential_smoothing_engine,
2535 TRUE))
2536 gtk_widget_destroy (state->base.dialog);
2538 return;
2542 * exp_smoothing_tool_update_sensitivity_cb:
2543 * @state:
2545 * Update the dialog widgets sensitivity.
2546 * We cannot use tool_update_sensitivity_cb
2547 * since we are also considering whether in fact
2548 * a damping factor is given.
2550 static void
2551 exp_smoothing_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
2552 ExpSmoothToolState *state)
2554 int err, period;
2555 gnm_float damp_fact;
2556 GSList *input_range;
2558 input_range = gnm_expr_entry_parse_as_list (
2559 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
2560 if (input_range == NULL) {
2561 gtk_label_set_text (GTK_LABEL (state->base.warning),
2562 _("The input range is invalid."));
2563 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2564 return;
2565 } else
2566 range_list_destroy (input_range);
2568 switch (gnm_gui_group_value (state->base.gui, exp_smoothing_group)) {
2569 case exp_smoothing_type_mtes:
2570 case exp_smoothing_type_ates:
2571 err = entry_to_float (GTK_ENTRY (state->s_damping_fact_entry),
2572 &damp_fact, FALSE);
2573 if (err!= 0 || damp_fact < 0 || damp_fact > 1) {
2574 gtk_label_set_text (GTK_LABEL (state->base.warning),
2575 _("The given seasonal damping "
2576 "factor is invalid."));
2577 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2578 return;
2580 err = entry_to_int (GTK_ENTRY (state->s_period_entry),
2581 &period, FALSE);
2582 if (err!= 0 || period < 2) {
2583 gtk_label_set_text (GTK_LABEL (state->base.warning),
2584 _("The given seasonal period "
2585 "is invalid."));
2586 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2587 return;
2589 /* no break */
2590 case exp_smoothing_type_des:
2591 err = entry_to_float (GTK_ENTRY (state->g_damping_fact_entry),
2592 &damp_fact, FALSE);
2593 if (err!= 0 || damp_fact < 0 || damp_fact > 1) {
2594 gtk_label_set_text (GTK_LABEL (state->base.warning),
2595 _("The given growth "
2596 "damping factor is invalid."));
2597 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2598 return;
2600 /* no break */
2601 case exp_smoothing_type_ses_r:
2602 case exp_smoothing_type_ses_h:
2603 err = entry_to_float (GTK_ENTRY (state->damping_fact_entry),
2604 &damp_fact, FALSE);
2605 if (err!= 0 || damp_fact < 0 || damp_fact > 1) {
2606 gtk_label_set_text (GTK_LABEL (state->base.warning),
2607 _("The given damping factor is invalid."));
2608 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2609 return;
2611 break;
2614 if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
2615 gtk_label_set_text (GTK_LABEL (state->base.warning),
2616 _("The output specification "
2617 "is invalid."));
2618 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2619 return;
2622 gtk_label_set_text (GTK_LABEL (state->base.warning), "");
2623 gtk_widget_set_sensitive (state->base.ok_button, TRUE);
2626 static void
2627 exp_smoothing_tool_check_error_cb (G_GNUC_UNUSED GtkToggleButton *togglebutton, gpointer user_data)
2629 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (user_data), TRUE);
2633 static void
2634 exp_smoothing_ses_h_cb (GtkToggleButton *togglebutton, gpointer user_data)
2636 ExpSmoothToolState *state = (ExpSmoothToolState *)user_data;
2637 gboolean std_error;
2639 if (!gtk_toggle_button_get_active (togglebutton))
2640 return;
2642 gtk_widget_set_sensitive (state->g_damping_fact_entry, FALSE);
2643 gtk_widget_set_sensitive (state->s_damping_fact_entry, FALSE);
2644 gtk_widget_set_sensitive (state->s_period_entry, FALSE);
2646 std_error = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->show_std_errors));
2647 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->n_button), TRUE);
2648 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->show_std_errors), std_error);
2651 static void
2652 exp_smoothing_ses_r_cb (GtkToggleButton *togglebutton, gpointer user_data)
2654 ExpSmoothToolState *state = (ExpSmoothToolState *)user_data;
2655 gboolean std_error;
2657 if (!gtk_toggle_button_get_active (togglebutton))
2658 return;
2660 gtk_widget_set_sensitive (state->g_damping_fact_entry, FALSE);
2661 gtk_widget_set_sensitive (state->s_damping_fact_entry, FALSE);
2662 gtk_widget_set_sensitive (state->s_period_entry, FALSE);
2664 std_error = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->show_std_errors));
2665 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->nm1_button), TRUE);
2666 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->show_std_errors), std_error);
2669 static void
2670 exp_smoothing_des_cb (GtkToggleButton *togglebutton, gpointer user_data)
2672 ExpSmoothToolState *state = (ExpSmoothToolState *)user_data;
2673 gboolean std_error;
2675 if (!gtk_toggle_button_get_active (togglebutton))
2676 return;
2678 gtk_widget_set_sensitive (state->g_damping_fact_entry, TRUE);
2679 gtk_widget_set_sensitive (state->s_damping_fact_entry, FALSE);
2680 gtk_widget_set_sensitive (state->s_period_entry, FALSE);
2682 std_error = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->show_std_errors));
2683 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->nm2_button), TRUE);
2684 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->show_std_errors), std_error);
2687 static void
2688 exp_smoothing_tes_cb (GtkToggleButton *togglebutton, gpointer user_data)
2690 ExpSmoothToolState *state = (ExpSmoothToolState *)user_data;
2691 gboolean std_error;
2693 if (!gtk_toggle_button_get_active (togglebutton))
2694 return;
2696 gtk_widget_set_sensitive (state->g_damping_fact_entry, TRUE);
2697 gtk_widget_set_sensitive (state->s_damping_fact_entry, TRUE);
2698 gtk_widget_set_sensitive (state->s_period_entry, TRUE);
2700 std_error = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->show_std_errors));
2701 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->nm3_button), TRUE);
2702 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->show_std_errors), std_error);
2706 * dialog_exp_smoothing_tool:
2707 * @wbcg:
2708 * @sheet:
2710 * Show the dialog (guru).
2714 dialog_exp_smoothing_tool (WBCGtk *wbcg, Sheet *sheet)
2716 ExpSmoothToolState *state;
2717 char const * plugins[] = { "Gnumeric_fnstat",
2718 "Gnumeric_fnlookup",
2719 "Gnumeric_fnmath",
2720 "Gnumeric_fnlogical",
2721 NULL};
2723 if ((wbcg == NULL) ||
2724 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
2725 return 1;
2727 /* Only pop up one copy per workbook */
2728 if (gnm_dialog_raise_if_exists (wbcg, EXP_SMOOTHING_KEY))
2729 return 0;
2731 state = g_new0 (ExpSmoothToolState, 1);
2733 if (dialog_tool_init (&state->base, wbcg, sheet,
2734 GNUMERIC_HELP_LINK_EXP_SMOOTHING,
2735 "res:ui/exp-smoothing.ui",
2736 "ExpSmoothing",
2737 _("Could not create the Exponential Smoothing "
2738 "Tool dialog."),
2739 EXP_SMOOTHING_KEY,
2740 G_CALLBACK (exp_smoothing_tool_ok_clicked_cb),
2741 NULL,
2742 G_CALLBACK (exp_smoothing_tool_update_sensitivity_cb),
2745 g_free(state);
2746 return 0;
2749 state->damping_fact_entry = go_gtk_builder_get_widget (state->base.gui,
2750 "damping-fact-spin");
2751 gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->damping_fact_entry), 0.2);
2752 float_to_entry (GTK_ENTRY (state->damping_fact_entry), 0.2);
2753 state->g_damping_fact_entry = go_gtk_builder_get_widget (state->base.gui,
2754 "g-damping-fact-spin");
2755 gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->g_damping_fact_entry), 0.25);
2756 state->s_damping_fact_entry = go_gtk_builder_get_widget (state->base.gui,
2757 "s-damping-fact-spin");
2758 gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->s_damping_fact_entry), 0.3);
2759 state->s_period_entry = go_gtk_builder_get_widget (state->base.gui,
2760 "s-period-spin");
2761 gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->s_period_entry), 12.);
2764 state->n_button = go_gtk_builder_get_widget (state->base.gui, "n-button");
2765 state->nm1_button = go_gtk_builder_get_widget (state->base.gui, "nm1-button");
2766 state->nm2_button = go_gtk_builder_get_widget (state->base.gui, "nm2-button");
2767 state->nm3_button = go_gtk_builder_get_widget (state->base.gui, "nm3-button");
2769 state->show_std_errors = go_gtk_builder_get_widget (state->base.gui, "std-errors-button");
2770 state->graph_button = go_gtk_builder_get_widget (state->base.gui, "graph-check");
2772 state->ses_h_button = go_gtk_builder_get_widget (state->base.gui, "ses-h-button");
2773 state->ses_r_button = go_gtk_builder_get_widget (state->base.gui, "ses-r-button");
2774 state->des_button = go_gtk_builder_get_widget (state->base.gui, "des-button");
2775 state->ates_button = go_gtk_builder_get_widget (state->base.gui, "ates-button");
2776 state->mtes_button = go_gtk_builder_get_widget (state->base.gui, "mtes-button");
2778 g_signal_connect_after (G_OBJECT (state->n_button),
2779 "toggled",
2780 G_CALLBACK (exp_smoothing_tool_check_error_cb), state->show_std_errors);
2781 g_signal_connect_after (G_OBJECT (state->nm1_button),
2782 "toggled",
2783 G_CALLBACK (exp_smoothing_tool_check_error_cb), state->show_std_errors);
2784 g_signal_connect_after (G_OBJECT (state->nm2_button),
2785 "toggled",
2786 G_CALLBACK (exp_smoothing_tool_check_error_cb), state->show_std_errors);
2787 g_signal_connect_after (G_OBJECT (state->nm3_button),
2788 "toggled",
2789 G_CALLBACK (exp_smoothing_tool_check_error_cb), state->show_std_errors);
2790 g_signal_connect_after (G_OBJECT (state->damping_fact_entry),
2791 "changed",
2792 G_CALLBACK (exp_smoothing_tool_update_sensitivity_cb), state);
2794 g_signal_connect_after (G_OBJECT (state->ses_h_button),
2795 "toggled",
2796 G_CALLBACK (exp_smoothing_ses_h_cb), state);
2797 g_signal_connect_after (G_OBJECT (state->ses_r_button),
2798 "toggled",
2799 G_CALLBACK (exp_smoothing_ses_r_cb), state);
2800 g_signal_connect_after (G_OBJECT (state->des_button),
2801 "toggled",
2802 G_CALLBACK (exp_smoothing_des_cb), state);
2803 g_signal_connect_after (G_OBJECT (state->ates_button),
2804 "toggled",
2805 G_CALLBACK (exp_smoothing_tes_cb), state);
2806 g_signal_connect_after (G_OBJECT (state->mtes_button),
2807 "toggled",
2808 G_CALLBACK (exp_smoothing_tes_cb), state);
2810 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
2811 GTK_WIDGET (state->damping_fact_entry));
2812 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
2813 GTK_WIDGET (state->g_damping_fact_entry));
2814 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
2815 GTK_WIDGET (state->s_damping_fact_entry));
2817 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
2818 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->ses_h_button), TRUE);
2819 exp_smoothing_ses_h_cb (GTK_TOGGLE_BUTTON (state->ses_h_button), state);
2820 exp_smoothing_tool_update_sensitivity_cb (NULL, state);
2821 tool_load_selection ((GnmGenericToolState *)state, TRUE);
2823 return 0;
2826 /**********************************************/
2827 /* End of Exponential Smoothing tool code */
2828 /**********************************************/
2830 /**********************************************/
2831 /* Begin of Moving Averages tool code */
2832 /**********************************************/
2836 * average_tool_ok_clicked_cb:
2837 * @button:
2838 * @state:
2840 * Retrieve the information from the dialog and call the average_tool.
2841 * Note that we assume that the ok_button is only active if the entry fields
2842 * contain sensible data.
2844 static void
2845 average_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
2846 AverageToolState *state)
2848 data_analysis_output_t *dao;
2849 analysis_tools_data_moving_average_t *data;
2851 GtkWidget *w;
2853 data = g_new0 (analysis_tools_data_moving_average_t, 1);
2854 dao = parse_output ((GnmGenericToolState *)state, NULL);
2856 data->base.input = gnm_expr_entry_parse_as_list (
2857 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
2858 data->base.group_by = gnm_gui_group_value (state->base.gui, grouped_by_group);
2860 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
2861 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
2863 entry_to_int (GTK_ENTRY (state->interval_entry), &data->interval, TRUE);
2864 entry_to_int (GTK_ENTRY (state->offset_spin), &data->offset, TRUE);
2866 data->std_error_flag = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->show_std_errors));
2867 data->show_graph = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->graph_button));
2869 data->df = gnm_gui_group_value (state->base.gui, n_group);
2871 data->ma_type = gnm_gui_group_value (state->base.gui, moving_average_group);
2873 switch (data->ma_type) {
2874 case moving_average_type_sma:
2875 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->central_button))
2876 && (data->interval % 2 == 0))
2877 data->ma_type = moving_average_type_central_sma;
2878 break;
2879 case moving_average_type_cma:
2880 data->interval = 0;
2881 data->offset = 0;
2882 break;
2883 case moving_average_type_spencer_ma:
2884 data->interval = 15;
2885 data->offset = 7;
2886 break;
2887 case moving_average_type_wma:
2888 data->offset = 0;
2889 break;
2890 default:
2891 break;
2894 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
2895 dao, data, analysis_tool_moving_average_engine, TRUE))
2896 gtk_widget_destroy (state->base.dialog);
2898 return;
2902 * average_tool_update_sensitivity_cb:
2903 * @state:
2905 * Update the dialog widgets sensitivity.
2906 * We cannot use tool_update_sensitivity_cb
2907 * since we are also considering whether in fact
2908 * an interval is given.
2910 static void
2911 average_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
2912 AverageToolState *state)
2914 int interval, err, offset;
2915 GSList *input_range;
2916 moving_average_type_t type;
2919 input_range = gnm_expr_entry_parse_as_list (
2920 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
2921 if (input_range == NULL) {
2922 gtk_label_set_text (GTK_LABEL (state->base.warning),
2923 _("The input range is invalid."));
2924 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2925 return;
2926 } else
2927 range_list_destroy (input_range);
2929 type = gnm_gui_group_value (state->base.gui, moving_average_group);
2931 if ((type == moving_average_type_sma) || (type == moving_average_type_wma)) {
2932 err = entry_to_int (GTK_ENTRY (state->interval_entry),
2933 &interval, FALSE);
2934 if (err!= 0 || interval <= 0) {
2935 gtk_label_set_text (GTK_LABEL (state->base.warning),
2936 _("The given interval is invalid."));
2937 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2938 return;
2942 if (type == moving_average_type_sma) {
2943 err = entry_to_int (GTK_ENTRY (state->offset_spin), &offset, FALSE);
2944 if (err!= 0 || offset < 0 || offset > interval) {
2945 gtk_label_set_text (GTK_LABEL (state->base.warning),
2946 _("The given offset is invalid."));
2947 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2948 return;
2952 if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
2953 gtk_label_set_text (GTK_LABEL (state->base.warning),
2954 _("The output specification "
2955 "is invalid."));
2956 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
2957 return;
2960 gtk_label_set_text (GTK_LABEL (state->base.warning), "");
2961 gtk_widget_set_sensitive (state->base.ok_button, TRUE);
2964 static void
2965 average_tool_check_error_cb (G_GNUC_UNUSED GtkToggleButton *togglebutton, gpointer user_data)
2967 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (user_data), TRUE);
2970 static void
2971 average_tool_central_cb (GtkToggleButton *togglebutton, gpointer user_data)
2973 AverageToolState *state = (AverageToolState *)user_data;
2974 int interval;
2975 int err;
2977 if (gtk_toggle_button_get_active (togglebutton)) {
2978 err = entry_to_int (GTK_ENTRY (state->interval_entry), &interval, TRUE);
2979 if (err == 0)
2980 gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->offset_spin), (interval/2));
2984 static void
2985 average_tool_prior_cb (GtkToggleButton *togglebutton, gpointer user_data)
2987 AverageToolState *state = (AverageToolState *)user_data;
2989 if (gtk_toggle_button_get_active (togglebutton))
2990 gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->offset_spin), 0.0);
2993 static void
2994 average_tool_interval_cb (G_GNUC_UNUSED GtkWidget *dummy, AverageToolState *state)
2996 int interval;
2997 int err;
2999 err = entry_to_int (GTK_ENTRY (state->interval_entry), &interval, TRUE);
3001 if (err == 0)
3002 gtk_spin_button_set_range (GTK_SPIN_BUTTON (state->offset_spin),
3003 0, interval - 1);
3004 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->central_button)))
3005 gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->offset_spin), interval/2);
3008 static void
3009 average_tool_offset_cb (GtkToggleButton *togglebutton, gpointer user_data)
3011 AverageToolState *state = (AverageToolState *)user_data;
3013 gtk_widget_set_sensitive (state->offset_spin, gtk_toggle_button_get_active (togglebutton));
3017 static void
3018 average_tool_sma_cb (GtkToggleButton *togglebutton, gpointer user_data)
3020 AverageToolState *state = (AverageToolState *)user_data;
3022 if (!gtk_toggle_button_get_active (togglebutton))
3023 return;
3025 gtk_widget_set_sensitive (state->prior_button, TRUE);
3026 gtk_widget_set_sensitive (state->central_button, TRUE);
3027 gtk_widget_set_sensitive (state->offset_button, TRUE);
3028 gtk_widget_set_sensitive (state->interval_entry, TRUE);
3029 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->prior_button), TRUE);
3030 average_tool_update_sensitivity_cb (NULL, state);
3033 static void
3034 average_tool_cma_cb (GtkToggleButton *togglebutton, gpointer user_data)
3036 AverageToolState *state = (AverageToolState *)user_data;
3038 if (!gtk_toggle_button_get_active (togglebutton))
3039 return;
3041 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->prior_button), TRUE);
3042 gtk_widget_set_sensitive (state->prior_button, FALSE);
3043 gtk_widget_set_sensitive (state->central_button, FALSE);
3044 gtk_widget_set_sensitive (state->offset_button, FALSE);
3045 gtk_widget_set_sensitive (state->interval_entry, FALSE);
3046 average_tool_update_sensitivity_cb (NULL, state);
3049 static void
3050 average_tool_wma_cb (GtkToggleButton *togglebutton, gpointer user_data)
3052 AverageToolState *state = (AverageToolState *)user_data;
3054 if (!gtk_toggle_button_get_active (togglebutton))
3055 return;
3056 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->prior_button), TRUE);
3057 gtk_widget_set_sensitive (state->prior_button, FALSE);
3058 gtk_widget_set_sensitive (state->central_button, FALSE);
3059 gtk_widget_set_sensitive (state->offset_button, FALSE);
3060 gtk_widget_set_sensitive (state->interval_entry, TRUE);
3061 average_tool_update_sensitivity_cb (NULL, state);
3064 static void
3065 average_tool_spencer_cb (GtkToggleButton *togglebutton, gpointer user_data)
3067 AverageToolState *state = (AverageToolState *)user_data;
3069 if (!gtk_toggle_button_get_active (togglebutton))
3070 return;
3071 int_to_entry (GTK_ENTRY (state->interval_entry), 15);
3072 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->central_button), TRUE);
3073 gtk_widget_set_sensitive (state->prior_button, FALSE);
3074 gtk_widget_set_sensitive (state->central_button, FALSE);
3075 gtk_widget_set_sensitive (state->offset_button, FALSE);
3076 gtk_widget_set_sensitive (state->interval_entry, FALSE);
3077 average_tool_update_sensitivity_cb (NULL, state);
3081 * dialog_average_tool:
3082 * @wbcg:
3083 * @sheet:
3085 * Show the dialog (guru).
3089 dialog_average_tool (WBCGtk *wbcg, Sheet *sheet)
3091 AverageToolState *state;
3092 char const * plugins[] = { "Gnumeric_fnstat",
3093 "Gnumeric_fnlookup",
3094 "Gnumeric_fnmath",
3095 NULL};
3097 if ((wbcg == NULL) ||
3098 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
3099 return 1;
3101 /* Only pop up one copy per workbook */
3102 if (gnm_dialog_raise_if_exists (wbcg, AVERAGE_KEY))
3103 return 0;
3105 state = g_new0 (AverageToolState, 1);
3107 if (dialog_tool_init (&state->base, wbcg, sheet,
3108 GNUMERIC_HELP_LINK_MOVING_AVERAGES,
3109 "res:ui/moving-averages.ui",
3110 "MovAverages",
3111 _("Could not create the Moving Average Tool "
3112 "dialog."),
3113 AVERAGE_KEY,
3114 G_CALLBACK (average_tool_ok_clicked_cb), NULL,
3115 G_CALLBACK (average_tool_update_sensitivity_cb),
3118 g_free(state);
3119 return 0;
3122 state->interval_entry = go_gtk_builder_get_widget (state->base.gui, "interval-entry");
3123 int_to_entry (GTK_ENTRY (state->interval_entry), 3);
3124 state->n_button = go_gtk_builder_get_widget (state->base.gui, "n-button");
3125 state->nm1_button = go_gtk_builder_get_widget (state->base.gui, "nm1-button");
3126 state->nm2_button = go_gtk_builder_get_widget (state->base.gui, "nm2-button");
3127 state->prior_button = go_gtk_builder_get_widget (state->base.gui, "prior-button");
3128 state->central_button = go_gtk_builder_get_widget (state->base.gui, "central-button");
3129 state->offset_button = go_gtk_builder_get_widget (state->base.gui, "offset-button");
3130 state->offset_spin = go_gtk_builder_get_widget (state->base.gui, "offset-spinbutton");
3131 state->show_std_errors = go_gtk_builder_get_widget (state->base.gui, "std-errors-button");
3132 state->graph_button = go_gtk_builder_get_widget (state->base.gui, "graph-check");
3133 state->sma_button = go_gtk_builder_get_widget (state->base.gui, "sma-button");
3134 state->cma_button = go_gtk_builder_get_widget (state->base.gui, "cma-button");
3135 state->wma_button = go_gtk_builder_get_widget (state->base.gui, "wma-button");
3136 state->spencer_button = go_gtk_builder_get_widget (state->base.gui, "spencer-ma-button");
3139 g_signal_connect_after (G_OBJECT (state->n_button),
3140 "toggled",
3141 G_CALLBACK (average_tool_check_error_cb), state->show_std_errors);
3142 g_signal_connect_after (G_OBJECT (state->nm1_button),
3143 "toggled",
3144 G_CALLBACK (average_tool_check_error_cb), state->show_std_errors);
3145 g_signal_connect_after (G_OBJECT (state->nm2_button),
3146 "toggled",
3147 G_CALLBACK (average_tool_check_error_cb), state->show_std_errors);
3149 g_signal_connect_after (G_OBJECT (state->prior_button),
3150 "toggled",
3151 G_CALLBACK (average_tool_prior_cb), state);
3152 g_signal_connect_after (G_OBJECT (state->central_button),
3153 "toggled",
3154 G_CALLBACK (average_tool_central_cb), state);
3155 g_signal_connect_after (G_OBJECT (state->offset_button),
3156 "toggled",
3157 G_CALLBACK (average_tool_offset_cb), state);
3159 g_signal_connect_after (G_OBJECT (state->sma_button),
3160 "toggled",
3161 G_CALLBACK (average_tool_sma_cb), state);
3162 g_signal_connect_after (G_OBJECT (state->cma_button),
3163 "toggled",
3164 G_CALLBACK (average_tool_cma_cb), state);
3165 g_signal_connect_after (G_OBJECT (state->wma_button),
3166 "toggled",
3167 G_CALLBACK (average_tool_wma_cb), state);
3168 g_signal_connect_after (G_OBJECT (state->spencer_button),
3169 "toggled",
3170 G_CALLBACK (average_tool_spencer_cb), state);
3173 g_signal_connect_after (G_OBJECT (state->interval_entry),
3174 "changed",
3175 G_CALLBACK (average_tool_update_sensitivity_cb), state);
3176 g_signal_connect_after (G_OBJECT (state->interval_entry),
3177 "changed",
3178 G_CALLBACK (average_tool_interval_cb), state);
3180 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
3181 GTK_WIDGET (state->interval_entry));
3183 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
3184 average_tool_update_sensitivity_cb (NULL, state);
3185 tool_load_selection ((GnmGenericToolState *)state, TRUE);
3187 return 0;
3190 /**********************************************/
3191 /* End of Moving Averages tool code */
3192 /**********************************************/
3194 /**********************************************/
3195 /* Begin of histogram tool code */
3196 /**********************************************/
3199 * histogram_tool_update_sensitivity_cb:
3200 * @dummy:
3201 * @state:
3203 * Update the dialog widgets sensitivity
3205 static void
3206 histogram_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
3207 HistogramToolState *state)
3209 int the_n;
3210 gboolean predetermined_bins;
3211 GSList *input_range;
3212 GnmValue *input_range_2 = NULL;
3214 input_range = gnm_expr_entry_parse_as_list
3215 (GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
3216 if (input_range == NULL) {
3217 gtk_label_set_text (GTK_LABEL (state->base.warning),
3218 _("The input range is invalid."));
3219 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3220 return;
3223 range_list_destroy (input_range);
3225 predetermined_bins = gtk_toggle_button_get_active (
3226 GTK_TOGGLE_BUTTON (state->predetermined_button));
3227 if (predetermined_bins) {
3228 input_range_2 = gnm_expr_entry_parse_as_value
3229 (GNM_EXPR_ENTRY (state->base.input_entry_2), state->base.sheet);
3230 if (input_range_2 == NULL) {
3231 gtk_label_set_text (GTK_LABEL (state->base.warning),
3232 _("The cutoff range is not valid."));
3233 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3234 return;
3236 value_release (input_range_2);
3237 } else if (entry_to_int(state->n_entry, &the_n,FALSE) != 0 || the_n <= 0) {
3238 gtk_label_set_text (GTK_LABEL (state->base.warning),
3239 _("The number of to be calculated cutoffs is invalid."));
3240 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3241 return;
3244 if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
3245 gtk_label_set_text (GTK_LABEL (state->base.warning),
3246 _("The output specification "
3247 "is invalid."));
3248 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3249 return;
3252 gtk_label_set_text (GTK_LABEL (state->base.warning), "");
3253 gtk_widget_set_sensitive (state->base.ok_button, TRUE);
3255 return;
3259 * histogram_tool_ok_clicked_cb:
3260 * @button:
3261 * @state:
3263 * Retrieve the information from the dialog and call the histogram_tool.
3264 * Note that we assume that the ok_button is only active if the entry fields
3265 * contain sensible data.
3267 static void
3268 histogram_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
3269 HistogramToolState *state)
3271 data_analysis_output_t *dao;
3272 analysis_tools_data_histogram_t *data;
3274 GtkWidget *w;
3276 data = g_new0 (analysis_tools_data_histogram_t, 1);
3277 dao = parse_output ((GnmGenericToolState *)state, NULL);
3279 data->base.input = gnm_expr_entry_parse_as_list (
3280 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
3281 data->base.group_by = gnm_gui_group_value (state->base.gui, grouped_by_group);
3283 data->predetermined = gtk_toggle_button_get_active (
3284 GTK_TOGGLE_BUTTON (state->predetermined_button));
3285 if (data->predetermined) {
3286 w = go_gtk_builder_get_widget (state->base.gui, "labels_2_button");
3287 data->bin = gnm_expr_entry_parse_as_value
3288 (GNM_EXPR_ENTRY (state->base.input_entry_2),
3289 state->base.sheet);
3290 } else {
3291 entry_to_int(state->n_entry, &data->n,TRUE);
3292 data->max_given = (0 == entry_to_float (state->max_entry,
3293 &data->max , TRUE));
3294 data->min_given = (0 == entry_to_float (state->min_entry,
3295 &data->min , TRUE));
3296 data->bin = NULL;
3299 data->bin_type = gnm_gui_group_value (state->base.gui, bin_type_group);
3300 data->chart = gnm_gui_group_value (state->base.gui, chart_group);
3302 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
3303 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
3304 w = go_gtk_builder_get_widget (state->base.gui, "percentage-button");
3305 data->percentage = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
3306 w = go_gtk_builder_get_widget (state->base.gui, "cum-button");
3307 data->cumulative = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
3308 w = go_gtk_builder_get_widget (state->base.gui, "only-num-button");
3309 data->only_numbers = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
3311 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
3312 dao, data, analysis_tool_histogram_engine, TRUE))
3313 gtk_widget_destroy (state->base.dialog);
3315 return;
3319 * histogram_tool_set_predetermined:
3320 * @widget:
3321 * @focus_widget:
3322 * @state:
3324 * Output range entry was focused. Switch to output range.
3327 static gboolean
3328 histogram_tool_set_predetermined (G_GNUC_UNUSED GtkWidget *widget,
3329 G_GNUC_UNUSED GdkEventFocus *event,
3330 HistogramToolState *state)
3332 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->predetermined_button), TRUE);
3333 return FALSE;
3337 * histogram_tool_set_calculated:
3338 * @widget:
3339 * @event:
3340 * @state:
3343 static gboolean
3344 histogram_tool_set_calculated (G_GNUC_UNUSED GtkWidget *widget,
3345 G_GNUC_UNUSED GdkEventFocus *event,
3346 HistogramToolState *state)
3348 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->calculated_button), TRUE);
3349 return FALSE;
3353 * dialog_histogram_tool:
3354 * @wbcg:
3355 * @sheet:
3357 * Show the dialog (guru).
3361 dialog_histogram_tool (WBCGtk *wbcg, Sheet *sheet)
3363 HistogramToolState *state;
3364 char const * plugins[] = {"Gnumeric_fnlogical",
3365 "Gnumeric_fnstat",
3366 "Gnumeric_fnlookup",
3367 NULL};
3369 if ((wbcg == NULL) ||
3370 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
3371 return 1;
3373 /* Only pop up one copy per workbook */
3374 if (gnm_dialog_raise_if_exists (wbcg, HISTOGRAM_KEY))
3375 return 0;
3377 state = g_new0 (HistogramToolState, 1);
3379 if (dialog_tool_init (&state->base, wbcg, sheet,
3380 GNUMERIC_HELP_LINK_HISTOGRAM,
3381 "res:ui/histogram.ui", "Histogram",
3382 _("Could not create the Histogram Tool dialog."),
3383 HISTOGRAM_KEY,
3384 G_CALLBACK (histogram_tool_ok_clicked_cb), NULL,
3385 G_CALLBACK (histogram_tool_update_sensitivity_cb),
3388 g_free(state);
3389 return 0;
3392 state->predetermined_button = GTK_WIDGET (go_gtk_builder_get_widget
3393 (state->base.gui,
3394 "pre_determined_button"));
3395 state->calculated_button = GTK_WIDGET (go_gtk_builder_get_widget
3396 (state->base.gui,
3397 "calculated_button"));
3398 state->n_entry = GTK_ENTRY(go_gtk_builder_get_widget (state->base.gui,
3399 "n_entry"));
3400 state->max_entry = GTK_ENTRY(go_gtk_builder_get_widget (state->base.gui,
3401 "max_entry"));
3402 state->min_entry = GTK_ENTRY(go_gtk_builder_get_widget (state->base.gui,
3403 "min_entry"));
3405 g_signal_connect_after (G_OBJECT (state->predetermined_button),
3406 "toggled",
3407 G_CALLBACK (histogram_tool_update_sensitivity_cb), state);
3408 g_signal_connect_after (G_OBJECT (state->calculated_button),
3409 "toggled",
3410 G_CALLBACK (histogram_tool_update_sensitivity_cb), state);
3411 g_signal_connect_after (G_OBJECT (state->n_entry),
3412 "changed",
3413 G_CALLBACK (histogram_tool_update_sensitivity_cb), state);
3414 g_signal_connect (G_OBJECT (state->n_entry),
3415 "key-press-event",
3416 G_CALLBACK (histogram_tool_set_calculated), state);
3417 g_signal_connect (G_OBJECT (state->min_entry),
3418 "key-press-event",
3419 G_CALLBACK (histogram_tool_set_calculated), state);
3420 g_signal_connect (G_OBJECT (state->max_entry),
3421 "key-press-event",
3422 G_CALLBACK (histogram_tool_set_calculated), state);
3423 g_signal_connect (G_OBJECT
3424 (gnm_expr_entry_get_entry (
3425 GNM_EXPR_ENTRY (state->base.input_entry_2))),
3426 "focus-in-event",
3427 G_CALLBACK (histogram_tool_set_predetermined), state);
3429 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
3430 histogram_tool_update_sensitivity_cb (NULL, state);
3431 tool_load_selection ((GnmGenericToolState *)state, TRUE);
3433 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->calculated_button), TRUE);
3434 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state->base.gui,"histogram-button")), TRUE);
3435 gtk_entry_set_text (GTK_ENTRY (state->n_entry), "12");
3437 return 0;
3440 /**********************************************/
3441 /* End of histogram tool code */
3442 /**********************************************/
3444 /**********************************************/
3445 /* Begin of ANOVA (single factor) tool code */
3446 /**********************************************/
3450 * anova_single_tool_ok_clicked_cb:
3451 * @button:
3452 * @state:
3454 * Retrieve the information from the dialog and call the fourier_tool.
3455 * Note that we assume that the ok_button is only active if the entry fields
3456 * contain sensible data.
3458 static void
3459 anova_single_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
3460 AnovaSingleToolState *state)
3462 data_analysis_output_t *dao;
3463 GtkWidget *w;
3464 analysis_tools_data_anova_single_t *data;
3466 data = g_new0 (analysis_tools_data_anova_single_t, 1);
3467 dao = parse_output ((GnmGenericToolState *)state, NULL);
3469 data->base.input = gnm_expr_entry_parse_as_list (
3470 GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);
3471 data->base.group_by = gnm_gui_group_value (state->base.gui, grouped_by_group);
3473 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
3474 data->base.labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
3475 data->alpha = gtk_spin_button_get_value
3476 (GTK_SPIN_BUTTON (state->alpha_entry));
3478 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg), state->base.sheet,
3479 dao, data, analysis_tool_anova_single_engine, TRUE))
3480 gtk_widget_destroy (state->base.dialog);
3482 return;
3486 * anova_single_tool_update_sensitivity_cb:
3487 * @state:
3489 * Update the dialog widgets sensitivity.
3490 * We cannot use tool_update_sensitivity_cb
3491 * since we are also considering whether in fact
3492 * an alpha is given.
3494 static void
3495 anova_single_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
3496 AnovaSingleToolState *state)
3498 gnm_float alpha;
3499 GSList *input_range;
3501 input_range = gnm_expr_entry_parse_as_list (
3502 GNM_EXPR_ENTRY (state->base.input_entry),
3503 state->base.sheet);
3504 if (input_range == NULL) {
3505 gtk_label_set_text (GTK_LABEL (state->base.warning),
3506 _("The input range is invalid."));
3507 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3508 return;
3509 } else
3510 range_list_destroy (input_range);
3512 /* Checking Alpha*/
3513 alpha = gtk_spin_button_get_value
3514 (GTK_SPIN_BUTTON (state->alpha_entry));
3515 if (!(alpha > 0 && alpha < 1)) {
3516 gtk_label_set_text (GTK_LABEL (state->base.warning),
3517 _("The alpha value should "
3518 "be a number between 0 and 1."));
3519 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3520 return;
3523 /* Checking Output Page */
3524 if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
3525 gtk_label_set_text (GTK_LABEL (state->base.warning),
3526 _("The output specification "
3527 "is invalid."));
3528 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3529 return;
3532 gtk_label_set_text (GTK_LABEL (state->base.warning), "");
3533 gtk_widget_set_sensitive (state->base.ok_button, TRUE);
3539 * dialog_anova_single_tool:
3540 * @wbcg:
3541 * @sheet:
3543 * Show the dialog (guru).
3547 dialog_anova_single_factor_tool (WBCGtk *wbcg, Sheet *sheet)
3549 AnovaSingleToolState *state;
3550 char const * plugins[] = { "Gnumeric_fnstat",
3551 NULL};
3553 if ((wbcg == NULL) ||
3554 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
3555 return 1;
3557 /* Only pop up one copy per workbook */
3558 if (gnm_dialog_raise_if_exists (wbcg, ANOVA_SINGLE_KEY))
3559 return 0;
3561 state = g_new0 (AnovaSingleToolState, 1);
3563 if (dialog_tool_init (&state->base, wbcg, sheet,
3564 GNUMERIC_HELP_LINK_ANOVA_SINGLE_FACTOR,
3565 "res:ui/anova-one.ui", "ANOVA",
3566 _("Could not create the ANOVA (single factor) "
3567 "tool dialog."),
3568 ANOVA_SINGLE_KEY,
3569 G_CALLBACK (anova_single_tool_ok_clicked_cb),
3570 NULL,
3571 G_CALLBACK (anova_single_tool_update_sensitivity_cb),
3574 g_free(state);
3575 return 0;
3578 state->alpha_entry = go_gtk_builder_get_widget (state->base.gui,
3579 "alpha-entry");
3580 float_to_entry (GTK_ENTRY (state->alpha_entry), 0.05);
3581 g_signal_connect_after (G_OBJECT (state->alpha_entry),
3582 "changed",
3583 G_CALLBACK (anova_single_tool_update_sensitivity_cb), state);
3584 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
3585 GTK_WIDGET (state->alpha_entry));
3587 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
3588 anova_single_tool_update_sensitivity_cb (NULL, state);
3589 tool_load_selection ((GnmGenericToolState *)state, TRUE);
3591 return 0;
3594 /**********************************************/
3595 /* End of ANOVA (Single Factor) tool code */
3596 /**********************************************/
3598 /**********************************************/
3599 /* Begin of ANOVA (two factor) tool code */
3600 /**********************************************/
3604 * anova_two_factor_tool_ok_clicked_cb:
3605 * @button:
3606 * @state:
3608 * Retrieve the information from the dialog and call the fourier_tool.
3609 * Note that we assume that the ok_button is only active if the entry fields
3610 * contain sensible data.
3612 static void
3613 anova_two_factor_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
3614 AnovaTwoFactorToolState *state)
3616 data_analysis_output_t *dao;
3617 GtkWidget *w;
3618 analysis_tools_data_anova_two_factor_t *data;
3619 char *text;
3621 if (state->base.warning_dialog != NULL)
3622 gtk_widget_destroy (state->base.warning_dialog);
3624 data = g_new0 (analysis_tools_data_anova_two_factor_t, 1);
3625 dao = parse_output ((GnmGenericToolState *)state, NULL);
3627 data->input = gnm_expr_entry_parse_as_value
3628 (GNM_EXPR_ENTRY (state->base.input_entry),
3629 state->base.sheet);
3630 data->err = analysis_tools_noerr;
3631 data->wbc = GNM_WBC (state->base.wbcg);
3633 w = go_gtk_builder_get_widget (state->base.gui, "labels_button");
3634 data->labels = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
3636 data->alpha = gtk_spin_button_get_value
3637 (GTK_SPIN_BUTTON (state->alpha_entry));
3638 entry_to_int (GTK_ENTRY (state->replication_entry),
3639 &data->replication, TRUE);
3641 if (cmd_analysis_tool (GNM_WBC (state->base.wbcg),
3642 state->base.sheet,
3643 dao, data, analysis_tool_anova_two_factor_engine, FALSE)) {
3644 switch (data->err) {
3645 case analysis_tools_missing_data:
3646 error_in_entry ((GnmGenericToolState *) state,
3647 GTK_WIDGET (state->base.input_entry),
3648 data->labels ? _("The given input range should contain at "
3649 "least two columns and two rows of data and the "
3650 "labels.") :
3651 _("The given input range should contain at "
3652 "least two columns and two rows of data."));
3653 break;
3654 case analysis_tools_too_few_cols:
3655 error_in_entry ((GnmGenericToolState *) state,
3656 GTK_WIDGET (state->base.input_entry),
3657 data->labels ? _("The given input range should contain at "
3658 "least two columns of data and the "
3659 "labels.") :
3660 _("The given input range should contain at "
3661 "least two columns of data."));
3662 break;
3663 case analysis_tools_too_few_rows:
3664 error_in_entry ((GnmGenericToolState *) state,
3665 GTK_WIDGET (state->base.input_entry),
3666 data->labels ? _("The given input range should contain at "
3667 "least two rows of data and the "
3668 "labels.") :
3669 _("The given input range should "
3670 "contain at least two rows of "
3671 "data."));
3672 break;
3673 case analysis_tools_replication_invalid:
3674 error_in_entry ((GnmGenericToolState *) state,
3675 GTK_WIDGET (state->base.input_entry),
3676 _("The number of data rows must be a "
3677 "multiple of the replication "
3678 "number."));
3679 break;
3680 default:
3681 text = g_strdup_printf (
3682 _("An unexpected error has occurred: %d."),
3683 data->err);
3684 error_in_entry ((GnmGenericToolState *) state,
3685 GTK_WIDGET (state->base.input_entry),
3686 text);
3687 g_free (text);
3688 break;
3690 value_release (data->input);
3691 g_free (dao);
3692 g_free (data);
3693 } else
3694 gtk_widget_destroy (state->base.dialog);
3696 return;
3700 * anova_two_factor_tool_update_sensitivity_cb:
3701 * @state:
3703 * Update the dialog widgets sensitivity.
3704 * We cannot use tool_update_sensitivity_cb
3705 * since we are also considering whether in fact
3706 * an alpha and a replication is given.
3708 static void
3709 anova_two_factor_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
3710 AnovaTwoFactorToolState *state)
3712 int replication, err_replication;
3713 gnm_float alpha;
3714 GnmValue *input_range;
3716 /* Checking Input Range */
3717 input_range = gnm_expr_entry_parse_as_value
3718 (GNM_EXPR_ENTRY (state->base.input_entry),
3719 state->base.sheet);
3720 if (input_range == NULL) {
3721 gtk_label_set_text (GTK_LABEL (state->base.warning),
3722 _("The input range is invalid."));
3723 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3724 return;
3725 } else
3726 value_release (input_range);
3728 /* Checking Alpha*/
3729 alpha = gtk_spin_button_get_value
3730 (GTK_SPIN_BUTTON (state->alpha_entry));
3731 if (!(alpha > 0 && alpha < 1)) {
3732 gtk_label_set_text (GTK_LABEL (state->base.warning),
3733 _("The alpha value should "
3734 "be a number between 0 and 1."));
3735 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3736 return;
3740 /* Checking Replication*/
3741 err_replication = entry_to_int (GTK_ENTRY (state->replication_entry),
3742 &replication, FALSE);
3743 if (!(err_replication == 0 && replication > 0)) {
3744 gtk_label_set_text (GTK_LABEL (state->base.warning),
3745 _("The number of rows per sample "
3746 "should be a positive integer."));
3747 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3748 return;
3751 /* Checking Output Page */
3752 if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
3753 gtk_label_set_text (GTK_LABEL (state->base.warning),
3754 _("The output specification "
3755 "is invalid."));
3756 gtk_widget_set_sensitive (state->base.ok_button, FALSE);
3757 return;
3760 gtk_label_set_text (GTK_LABEL (state->base.warning), "");
3761 gtk_widget_set_sensitive (state->base.ok_button, TRUE);
3763 return;
3767 * dialog_anova_two_factor_tool:
3768 * @wbcg:
3769 * @sheet:
3771 * Show the dialog (guru).
3775 dialog_anova_two_factor_tool (WBCGtk *wbcg, Sheet *sheet)
3777 AnovaTwoFactorToolState *state;
3778 char const * plugins[] = { "Gnumeric_fnstat",
3779 "Gnumeric_fnlookup",
3780 "Gnumeric_fnmath",
3781 "Gnumeric_fninfo",
3782 "Gnumeric_fnlogical",
3783 NULL};
3785 if ((wbcg == NULL) ||
3786 gnm_check_for_plugins_missing (plugins, wbcg_toplevel (wbcg)))
3787 return 1;
3789 /* Only pop up one copy per workbook */
3790 if (gnm_dialog_raise_if_exists (wbcg, ANOVA_TWO_FACTOR_KEY))
3791 return 0;
3793 state = g_new0 (AnovaTwoFactorToolState, 1);
3795 if (dialog_tool_init (&state->base, wbcg, sheet,
3796 GNUMERIC_HELP_LINK_ANOVA_TWO_FACTOR,
3797 "res:ui/anova-two.ui", "ANOVA",
3798 _("Could not create the ANOVA (two factor) "
3799 "tool dialog."),
3800 ANOVA_TWO_FACTOR_KEY,
3801 G_CALLBACK (anova_two_factor_tool_ok_clicked_cb),
3802 NULL,
3803 G_CALLBACK (anova_two_factor_tool_update_sensitivity_cb),
3804 GNM_EE_SINGLE_RANGE))
3806 g_free(state);
3807 return 0;
3810 state->alpha_entry = go_gtk_builder_get_widget (state->base.gui,
3811 "alpha-entry");
3812 float_to_entry (GTK_ENTRY(state->alpha_entry), 0.05);
3813 state->replication_entry = go_gtk_builder_get_widget (state->base.gui,
3814 "replication-entry");
3815 int_to_entry (GTK_ENTRY(state->replication_entry), 1);
3817 g_signal_connect_after (G_OBJECT (state->alpha_entry),
3818 "changed",
3819 G_CALLBACK (anova_two_factor_tool_update_sensitivity_cb),
3820 state);
3821 g_signal_connect_after (G_OBJECT (state->replication_entry),
3822 "changed",
3823 G_CALLBACK (anova_two_factor_tool_update_sensitivity_cb),
3824 state);
3825 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
3826 GTK_WIDGET (state->alpha_entry));
3827 gnm_editable_enters (GTK_WINDOW (state->base.dialog),
3828 GTK_WIDGET (state->replication_entry));
3830 gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
3831 anova_two_factor_tool_update_sensitivity_cb (NULL, state);
3832 tool_load_selection ((GnmGenericToolState *)state, FALSE);
3834 return 0;
3837 /**********************************************/
3838 /* End of ANOVA (Two Factor) tool code */
3839 /**********************************************/