2 * dialog-random-generator.c:
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>
29 #include "dialogs/tool-dialogs.h"
30 #include "random-generator.h"
33 #include <workbook-control.h>
35 #include <workbook-view.h>
37 #include <parse-util.h>
38 #include <gnm-format.h>
39 #include <dialogs/dao-gui-utils.h>
42 #include <number-match.h>
44 #include <selection.h>
48 #include <widgets/gnumeric-expr-entry.h>
49 #include <widgets/gnm-dao.h>
55 /**********************************************/
56 /* Generic guru items */
57 /**********************************************/
60 #define RANDOM_KEY "analysistools-random-dialog"
63 GnmGenericToolState base
;
64 GtkWidget
*distribution_grid
;
65 GtkWidget
*distribution_combo
;
66 GtkWidget
*par1_label
;
67 GtkWidget
*par1_entry
;
68 GtkWidget
*par1_expr_entry
;
69 GtkWidget
*par2_label
;
70 GtkWidget
*par2_entry
;
71 GtkWidget
*vars_entry
;
72 GtkWidget
*count_entry
;
73 random_distribution_t distribution
;
77 /**********************************************/
78 /* Begin of random tool code */
79 /**********************************************/
83 GtkWidget
*distribution_grid
;
84 GtkWidget
*distribution_combo
;
85 GtkWidget
*par1_label
, *par1_entry
;
86 GtkWidget
*par2_label
, *par2_entry
;
87 } random_tool_callback_t
;
89 /* Name to show in list and parameter labels for a random distribution */
91 random_distribution_t dist
;
95 gboolean par1_is_range
;
98 /* Distribution strings for Random Number Generator */
99 static const DistributionStrs distribution_strs
[] = {
100 /* The most commonly used are listed first. I think uniform, gaussian
101 * and discrete are the most commonly used, or what do you think? */
103 { UniformDistribution
,
104 N_("Uniform"), N_("_Lower Bound:"), N_("_Upper Bound:"), FALSE
},
105 { UniformIntDistribution
,
106 N_("Uniform Integer"), N_("_Lower Bound:"), N_("_Upper Bound:"),
108 { NormalDistribution
,
109 N_("Normal"), N_("_Mean:"), N_("_Standard Deviation:"), FALSE
},
110 { DiscreteDistribution
,
111 N_("Discrete"), N_("_Value And Probability Input Range:"), NULL
,
114 /* The others are in alphabetical order. */
116 { BernoulliDistribution
,
117 N_("Bernoulli"), N_("_p Value:"), NULL
, FALSE
},
119 N_("Beta"), N_("_a Value:"), N_("_b Value:"), FALSE
},
120 { BinomialDistribution
,
121 N_("Binomial"), N_("_p Value:"), N_("N_umber of Trials:"), FALSE
},
122 { CauchyDistribution
,
123 N_("Cauchy"), N_("_a Value:"), NULL
, FALSE
},
125 N_("Chisq"), N_("_nu Value:"), NULL
, FALSE
},
126 { ExponentialDistribution
,
127 N_("Exponential"), N_("_b Value:"), NULL
, FALSE
},
128 { ExponentialPowerDistribution
,
129 N_("Exponential Power"), N_("_a Value:"), N_("_b Value:"), FALSE
},
131 N_("F"), N_("nu_1 Value:"), N_("nu_2 Value:"), FALSE
},
133 N_("Gamma"), N_("_a Value:"), N_("_b Value:"), FALSE
},
134 { GaussianTailDistribution
,
135 N_("Gaussian Tail"), N_("_a Value:"), N_("_Sigma"), FALSE
},
136 { GeometricDistribution
,
137 N_("Geometric"), N_("_p Value:"), NULL
, FALSE
},
138 { Gumbel1Distribution
,
139 N_("Gumbel (Type I)"), N_("_a Value:"), N_("_b Value:"), FALSE
},
140 { Gumbel2Distribution
,
141 N_("Gumbel (Type II)"), N_("_a Value:"), N_("_b Value:"), FALSE
},
142 { LandauDistribution
,
143 N_("Landau"), NULL
, NULL
, FALSE
},
144 { LaplaceDistribution
,
145 N_("Laplace"), N_("_a Value:"), NULL
, FALSE
},
147 N_("Levy alpha-Stable"), N_("_c Value:"), N_("_alpha:"), FALSE
},
148 { LogarithmicDistribution
,
149 N_("Logarithmic"), N_("_p Value:"), NULL
, FALSE
},
150 { LogisticDistribution
,
151 N_("Logistic"), N_("_a Value:"), NULL
, FALSE
},
152 { LognormalDistribution
,
153 N_("Lognormal"), N_("_Zeta Value:"), N_("_Sigma"), FALSE
},
154 { NegativeBinomialDistribution
,
155 N_("Negative Binomial"), N_("_p Value:"),
156 N_("N_umber of Failures"), FALSE
},
157 { ParetoDistribution
,
158 N_("Pareto"), N_("_a Value:"), N_("_b Value:"), FALSE
},
159 { PoissonDistribution
,
160 N_("Poisson"), N_("_Lambda:"), NULL
, FALSE
},
161 { RayleighDistribution
,
162 N_("Rayleigh"), N_("_Sigma:"), NULL
, FALSE
},
163 { RayleighTailDistribution
,
164 N_("Rayleigh Tail"), N_("_a Value:"), N_("_Sigma:"), FALSE
},
166 N_("Student t"), N_("nu Value:"), NULL
, FALSE
},
167 { WeibullDistribution
,
168 N_("Weibull"), N_("_a Value:"), N_("_b Value:"), FALSE
},
169 { 0, NULL
, NULL
, NULL
, FALSE
}
173 * distribution_strs_find
174 * @dist Distribution enum
176 * Find the strings record, given distribution enum.
177 * Returns pointer to strings record.
179 static const DistributionStrs
*
180 distribution_strs_find (random_distribution_t dist
)
184 for (i
= 0; distribution_strs
[i
].name
!= NULL
; i
++)
185 if (distribution_strs
[i
].dist
== dist
)
186 return &distribution_strs
[i
];
188 return &distribution_strs
[0];
192 * combo_get_distribution
193 * @combo combo widget with distribution list
195 * Find from combo the distribution the user selected
197 static random_distribution_t
198 combo_get_distribution (GtkWidget
*combo
)
200 return distribution_strs
[gtk_combo_box_get_active (GTK_COMBO_BOX (combo
))].dist
;
204 * random_tool_update_sensitivity:
208 * Update the dialog widgets sensitivity if the only items of interest
209 * are the standard input (one range) and output items.
212 random_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget
*dummy
,
213 RandomToolState
*state
)
215 gboolean ready
= FALSE
;
217 gnm_float a_float
, b_float
, from_val
, to_val
, p_val
;
218 GnmValue
*disc_prob_range
;
219 random_distribution_t the_dist
;
221 the_dist
= combo_get_distribution (state
->distribution_combo
);
223 ready
= ((entry_to_int (GTK_ENTRY (state
->vars_entry
), &vars
, FALSE
) == 0 &&
225 (entry_to_int (GTK_ENTRY (state
->count_entry
), &count
, FALSE
) == 0 &&
227 gnm_dao_is_ready (GNM_DAO (state
->base
.gdao
)));
230 case NormalDistribution
:
231 ready
= ready
&& entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
,
233 entry_to_float (GTK_ENTRY (state
->par2_entry
), &a_float
,
236 case BernoulliDistribution
:
238 entry_to_float (GTK_ENTRY (state
->par1_entry
), &p_val
, FALSE
) == 0 &&
239 p_val
<= 1.0 && p_val
> 0.0;
241 case BetaDistribution
:
243 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0;
245 entry_to_float (GTK_ENTRY (state
->par2_entry
), &b_float
, FALSE
) == 0;
247 case PoissonDistribution
:
249 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
252 case ExponentialDistribution
:
254 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
257 case ExponentialPowerDistribution
:
259 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
262 entry_to_float (GTK_ENTRY (state
->par2_entry
), &b_float
, FALSE
) == 0 &&
265 case CauchyDistribution
:
267 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
270 case ChisqDistribution
:
272 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
275 case LandauDistribution
:
278 case LaplaceDistribution
:
280 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
283 case GaussianTailDistribution
:
285 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
288 entry_to_float (GTK_ENTRY (state
->par2_entry
), &b_float
, FALSE
) == 0 &&
291 case RayleighDistribution
:
293 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
296 case RayleighTailDistribution
:
298 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
301 entry_to_float (GTK_ENTRY (state
->par2_entry
), &b_float
, FALSE
) == 0 &&
304 case ParetoDistribution
:
306 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
309 entry_to_float (GTK_ENTRY (state
->par2_entry
), &b_float
, FALSE
) == 0 &&
312 case LevyDistribution
:
314 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
317 entry_to_float (GTK_ENTRY (state
->par2_entry
), &b_float
, FALSE
) == 0 &&
320 case FdistDistribution
:
322 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
325 entry_to_float (GTK_ENTRY (state
->par2_entry
), &b_float
, FALSE
) == 0 &&
328 case LognormalDistribution
:
330 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
333 entry_to_float (GTK_ENTRY (state
->par2_entry
), &b_float
, FALSE
) == 0 &&
336 case TdistDistribution
:
338 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
341 case WeibullDistribution
:
343 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
346 entry_to_float (GTK_ENTRY (state
->par2_entry
), &b_float
, FALSE
) == 0 &&
349 case GeometricDistribution
:
351 entry_to_float (GTK_ENTRY (state
->par1_entry
), &p_val
, FALSE
) == 0 &&
352 p_val
>= 0.0 && p_val
<= 1;
354 case LogarithmicDistribution
:
356 entry_to_float (GTK_ENTRY (state
->par1_entry
), &p_val
, FALSE
) == 0 &&
357 p_val
>= 0.0 && p_val
<= 1;
359 case LogisticDistribution
:
361 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
364 case GammaDistribution
:
366 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
369 entry_to_float (GTK_ENTRY (state
->par2_entry
), &b_float
, FALSE
) == 0 &&
372 case Gumbel1Distribution
:
373 case Gumbel2Distribution
:
375 entry_to_float (GTK_ENTRY (state
->par1_entry
), &a_float
, FALSE
) == 0 &&
378 entry_to_float (GTK_ENTRY (state
->par2_entry
), &b_float
, FALSE
) == 0 &&
381 case BinomialDistribution
:
383 entry_to_float (GTK_ENTRY (state
->par1_entry
), &p_val
, FALSE
) == 0 &&
384 entry_to_int (GTK_ENTRY (state
->par2_entry
), &count
, FALSE
) == 0 &&
385 p_val
<= 1.0 && p_val
> 0.0 &&
388 case NegativeBinomialDistribution
:
390 entry_to_float (GTK_ENTRY (state
->par1_entry
), &p_val
, FALSE
) == 0 &&
391 entry_to_int (GTK_ENTRY (state
->par2_entry
), &count
, FALSE
) == 0 &&
392 p_val
<= 1.0 && p_val
> 0.0 &&
395 case DiscreteDistribution
:
396 disc_prob_range
= gnm_expr_entry_parse_as_value
397 (GNM_EXPR_ENTRY (state
->par1_expr_entry
), state
->base
.sheet
);
398 ready
= ready
&& disc_prob_range
!= NULL
;
399 value_release (disc_prob_range
);
401 case UniformIntDistribution
:
403 entry_to_float (GTK_ENTRY (state
->par1_entry
), &from_val
, FALSE
) == 0 &&
404 entry_to_float (GTK_ENTRY (state
->par2_entry
), &to_val
, FALSE
) == 0 &&
407 case UniformDistribution
:
410 entry_to_float (GTK_ENTRY (state
->par1_entry
), &from_val
, FALSE
) == 0 &&
411 entry_to_float (GTK_ENTRY (state
->par2_entry
), &to_val
, FALSE
) == 0 &&
416 gtk_widget_set_sensitive (state
->base
.apply_button
, ready
);
417 gtk_widget_set_sensitive (state
->base
.ok_button
, ready
);
421 * distribution_parbox_config
425 * Configure parameter widgets given random distribution.
427 * Set labels and accelerators, and hide/show entry fields as needed.
431 distribution_parbox_config (RandomToolState
*state
,
432 random_distribution_t dist
)
434 GtkWidget
*par1_entry
;
435 const DistributionStrs
*ds
= distribution_strs_find (dist
);
437 if (ds
->par1_is_range
) {
438 par1_entry
= state
->par1_expr_entry
;
439 gtk_widget_hide (state
->par1_entry
);
441 par1_entry
= state
->par1_entry
;
442 gtk_widget_hide (state
->par1_expr_entry
);
444 if (ds
->label1
!= NULL
) {
445 gtk_label_set_text_with_mnemonic (GTK_LABEL (state
->par1_label
),
447 gtk_label_set_mnemonic_widget (GTK_LABEL (state
->par1_label
),
449 gtk_widget_show (par1_entry
);
451 gtk_label_set_text (GTK_LABEL (state
->par1_label
), "");
452 gtk_widget_hide (par1_entry
);
455 if (ds
->label2
!= NULL
) {
456 gtk_label_set_text_with_mnemonic (GTK_LABEL (state
->par2_label
),
458 gtk_label_set_mnemonic_widget (GTK_LABEL (state
->par2_label
),
460 gtk_widget_show (state
->par2_entry
);
462 gtk_label_set_text (GTK_LABEL (state
->par2_label
), "");
463 gtk_widget_hide (state
->par2_entry
);
468 * distribution_callback
472 * Configure the random distribution parameters widgets for the distribution
473 * which was selected.
476 distribution_callback (G_GNUC_UNUSED GtkWidget
*widget
,
477 RandomToolState
*state
)
479 random_distribution_t dist
;
481 dist
= combo_get_distribution (state
->distribution_combo
);
482 distribution_parbox_config (state
, dist
);
487 * dialog_random_realized:
491 * Make initial geometry of distribution table permanent.
493 * The dialog is constructed with the distribution_grid containing the widgets
494 * which need the most space. At construction time, we do not know how large
495 * the distribution_grid needs to be, but we do know when the dialog is
496 * realized. This callback for "realized" makes this size the user specified
497 * size so that the table will not shrink when we later change label texts and
502 dialog_random_realized (GtkWidget
*widget
, RandomToolState
*state
)
504 GtkWidget
*t
= state
->distribution_grid
;
505 GtkWidget
*l
= state
->par1_label
;
508 gtk_widget_get_allocation (t
, &a
);
509 gtk_widget_set_size_request (t
, a
.width
, a
.height
);
511 gtk_widget_get_allocation (l
, &a
);
512 gtk_widget_set_size_request (l
, a
.width
, a
.height
);
514 distribution_callback (widget
, state
);
519 * random_tool_ok_clicked_cb:
523 * Retrieve the information from the dialog and call the appropriate tool.
524 * Note that we assume that the ok_button is only active if the entry fields
525 * contain sensible data.
528 random_tool_ok_clicked_cb (GtkWidget
*button
, RandomToolState
*state
)
530 data_analysis_output_t
*dao
;
531 tools_data_random_t
*data
;
535 data
= g_new0 (tools_data_random_t
, 1);
536 dao
= parse_output ((GnmGenericToolState
*)state
, NULL
);
538 data
->wbc
= GNM_WBC (state
->base
.wbcg
);
540 err
= entry_to_int (GTK_ENTRY (state
->vars_entry
), &data
->n_vars
, FALSE
);
541 err
= entry_to_int (GTK_ENTRY (state
->count_entry
), &data
->count
, FALSE
);
543 data
->distribution
= state
->distribution
=
544 combo_get_distribution (state
->distribution_combo
);
545 switch (state
->distribution
) {
546 case NormalDistribution
:
547 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
548 &data
->param
.normal
.mean
, TRUE
);
549 err
= entry_to_float (GTK_ENTRY (state
->par2_entry
),
550 &data
->param
.normal
.stdev
, TRUE
);
552 case BernoulliDistribution
:
553 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
554 &data
->param
.bernoulli
.p
, TRUE
);
556 case BetaDistribution
:
557 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
558 &data
->param
.beta
.a
, TRUE
);
559 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
560 &data
->param
.beta
.b
, TRUE
);
562 case PoissonDistribution
:
563 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
564 &data
->param
.poisson
.lambda
, TRUE
);
566 case ExponentialDistribution
:
567 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
568 &data
->param
.exponential
.b
, TRUE
);
570 case ExponentialPowerDistribution
:
571 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
572 &data
->param
.exppow
.a
, TRUE
);
573 err
= entry_to_float (GTK_ENTRY (state
->par2_entry
),
574 &data
->param
.exppow
.b
, TRUE
);
576 case CauchyDistribution
:
577 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
578 &data
->param
.cauchy
.a
, TRUE
);
580 case LandauDistribution
:
582 case LaplaceDistribution
:
583 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
584 &data
->param
.laplace
.a
, TRUE
);
586 case GaussianTailDistribution
:
587 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
588 &data
->param
.gaussian_tail
.a
, TRUE
);
589 err
= entry_to_float (GTK_ENTRY (state
->par2_entry
),
590 &data
->param
.gaussian_tail
.sigma
, TRUE
);
592 case ChisqDistribution
:
593 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
594 &data
->param
.chisq
.nu
, TRUE
);
596 case LogarithmicDistribution
:
597 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
598 &data
->param
.logarithmic
.p
, TRUE
);
600 case LogisticDistribution
:
601 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
602 &data
->param
.logistic
.a
, TRUE
);
604 case RayleighDistribution
:
605 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
606 &data
->param
.rayleigh
.sigma
, TRUE
);
608 case RayleighTailDistribution
:
609 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
610 &data
->param
.rayleigh_tail
.a
, TRUE
);
611 err
= entry_to_float (GTK_ENTRY (state
->par2_entry
),
612 &data
->param
.rayleigh_tail
.sigma
, TRUE
);
614 case LognormalDistribution
:
615 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
616 &data
->param
.lognormal
.zeta
, TRUE
);
617 err
= entry_to_float (GTK_ENTRY (state
->par2_entry
),
618 &data
->param
.lognormal
.sigma
, TRUE
);
620 case LevyDistribution
:
621 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
622 &data
->param
.levy
.c
, TRUE
);
623 err
= entry_to_float (GTK_ENTRY (state
->par2_entry
),
624 &data
->param
.levy
.alpha
, TRUE
);
626 case FdistDistribution
:
627 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
628 &data
->param
.fdist
.nu1
, TRUE
);
629 err
= entry_to_float (GTK_ENTRY (state
->par2_entry
),
630 &data
->param
.fdist
.nu2
, TRUE
);
632 case ParetoDistribution
:
633 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
634 &data
->param
.pareto
.a
, TRUE
);
635 err
= entry_to_float (GTK_ENTRY (state
->par2_entry
),
636 &data
->param
.pareto
.b
, TRUE
);
638 case TdistDistribution
:
639 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
640 &data
->param
.tdist
.nu
, TRUE
);
642 case WeibullDistribution
:
643 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
644 &data
->param
.weibull
.a
, TRUE
);
645 err
= entry_to_float (GTK_ENTRY (state
->par2_entry
),
646 &data
->param
.weibull
.b
, TRUE
);
648 case GeometricDistribution
:
649 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
650 &data
->param
.geometric
.p
, TRUE
);
652 case GammaDistribution
:
653 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
654 &data
->param
.gamma
.a
, TRUE
);
655 err
= entry_to_float (GTK_ENTRY (state
->par2_entry
),
656 &data
->param
.gamma
.b
, TRUE
);
658 case Gumbel1Distribution
:
659 case Gumbel2Distribution
:
660 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
661 &data
->param
.gumbel
.a
, TRUE
);
662 err
= entry_to_float (GTK_ENTRY (state
->par2_entry
),
663 &data
->param
.gumbel
.b
, TRUE
);
665 case BinomialDistribution
:
666 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
667 &data
->param
.binomial
.p
, TRUE
);
668 err
= entry_to_int (GTK_ENTRY (state
->par2_entry
),
669 &data
->param
.binomial
.trials
, TRUE
);
671 case NegativeBinomialDistribution
:
672 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
673 &data
->param
.negbinom
.p
, TRUE
);
674 err
= entry_to_int (GTK_ENTRY (state
->par2_entry
),
675 &data
->param
.negbinom
.f
, TRUE
);
677 case DiscreteDistribution
:
678 data
->param
.discrete
.range
= gnm_expr_entry_parse_as_value (
679 GNM_EXPR_ENTRY (state
->par1_expr_entry
),
682 case UniformIntDistribution
:
683 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
684 &data
->param
.uniform
.lower_limit
, TRUE
);
685 err
= entry_to_float (GTK_ENTRY (state
->par2_entry
),
686 &data
->param
.uniform
.upper_limit
, TRUE
);
688 case UniformDistribution
:
690 err
= entry_to_float (GTK_ENTRY (state
->par1_entry
),
691 &data
->param
.uniform
.lower_limit
, TRUE
);
692 err
= entry_to_float (GTK_ENTRY (state
->par2_entry
),
693 &data
->param
.uniform
.upper_limit
, TRUE
);
697 if (!cmd_analysis_tool (GNM_WBC (state
->base
.wbcg
),
699 dao
, data
, tool_random_engine
, TRUE
) &&
700 (button
== state
->base
.ok_button
))
701 gtk_widget_destroy (state
->base
.dialog
);
705 * dialog_random_tool_init:
708 * Create the dialog (guru).
712 dialog_random_tool_init (RandomToolState
*state
)
715 const DistributionStrs
*ds
;
716 /* GList *distribution_type_strs = NULL;*/
720 GtkCellRenderer
*renderer
;
721 GnmRange
const *first
;
723 state
->distribution
= UniformDistribution
;
725 state
->distribution_grid
= go_gtk_builder_get_widget (state
->base
.gui
,
726 "distribution-grid");
727 state
->distribution_combo
= go_gtk_builder_get_widget (state
->base
.gui
,
728 "distribution_combo");
729 state
->par1_entry
= go_gtk_builder_get_widget (state
->base
.gui
, "par1_entry");
730 state
->par1_label
= go_gtk_builder_get_widget (state
->base
.gui
, "par1_label");
731 state
->par2_label
= go_gtk_builder_get_widget (state
->base
.gui
, "par2_label");
732 state
->par2_entry
= go_gtk_builder_get_widget (state
->base
.gui
, "par2_entry");
733 state
->vars_entry
= go_gtk_builder_get_widget (state
->base
.gui
, "vars_entry");
734 state
->count_entry
= go_gtk_builder_get_widget (state
->base
.gui
, "count_entry");
735 int_to_entry (GTK_ENTRY (state
->count_entry
), 1);
737 renderer
= (GtkCellRenderer
*) gtk_cell_renderer_text_new();
738 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (state
->distribution_combo
), renderer
, TRUE
);
739 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (state
->distribution_combo
), renderer
,
742 store
= gtk_list_store_new (1, G_TYPE_STRING
);
743 gtk_combo_box_set_model (GTK_COMBO_BOX (state
->distribution_combo
),
744 GTK_TREE_MODEL (store
));
745 g_object_unref (store
);
746 for (i
= 0, dist_str_no
= 0; distribution_strs
[i
].name
!= NULL
; i
++) {
747 gtk_list_store_append (store
, &iter
);
748 gtk_list_store_set (store
, &iter
,
749 0, _(distribution_strs
[i
].name
),
751 if (distribution_strs
[i
].dist
== state
->distribution
)
754 gtk_combo_box_set_active (GTK_COMBO_BOX (state
->distribution_combo
),
757 ds
= distribution_strs_find (UniformDistribution
);
758 gtk_label_set_text_with_mnemonic (GTK_LABEL (state
->par1_label
),
761 g_signal_connect (state
->distribution_combo
,
763 G_CALLBACK (distribution_callback
), state
);
764 g_signal_connect (state
->distribution_combo
,
766 G_CALLBACK (random_tool_update_sensitivity_cb
), state
);
768 grid
= GTK_GRID (go_gtk_builder_get_widget (state
->base
.gui
, "distribution-grid"));
769 state
->par1_expr_entry
= GTK_WIDGET (gnm_expr_entry_new (state
->base
.wbcg
, TRUE
));
770 gnm_expr_entry_set_flags (GNM_EXPR_ENTRY (state
->par1_expr_entry
),
771 GNM_EE_SINGLE_RANGE
, GNM_EE_MASK
);
772 gtk_widget_set_hexpand (state
->par1_expr_entry
, TRUE
);
773 gtk_grid_attach (grid
, state
->par1_expr_entry
, 1, 1, 1, 1);
774 gnm_editable_enters (GTK_WINDOW (state
->base
.dialog
),
775 GTK_WIDGET (state
->par1_expr_entry
));
777 gnm_editable_enters (GTK_WINDOW (state
->base
.dialog
),
778 GTK_WIDGET (state
->par1_entry
));
779 gnm_editable_enters (GTK_WINDOW (state
->base
.dialog
),
780 GTK_WIDGET (state
->par2_entry
));
781 gnm_editable_enters (GTK_WINDOW (state
->base
.dialog
),
782 GTK_WIDGET (state
->vars_entry
));
783 gnm_editable_enters (GTK_WINDOW (state
->base
.dialog
),
784 GTK_WIDGET (state
->count_entry
));
786 g_signal_connect (G_OBJECT (state
->base
.dialog
),
788 G_CALLBACK (dialog_random_realized
), state
);
789 g_signal_connect_after (G_OBJECT (state
->vars_entry
),
791 G_CALLBACK (random_tool_update_sensitivity_cb
), state
);
792 g_signal_connect_after (G_OBJECT (state
->count_entry
),
794 G_CALLBACK (random_tool_update_sensitivity_cb
), state
);
795 g_signal_connect_after (G_OBJECT (state
->par1_entry
),
797 G_CALLBACK (random_tool_update_sensitivity_cb
), state
);
798 g_signal_connect_after (G_OBJECT (state
->par2_entry
),
800 G_CALLBACK (random_tool_update_sensitivity_cb
), state
);
801 g_signal_connect_after (G_OBJECT (state
->par1_expr_entry
),
803 G_CALLBACK (random_tool_update_sensitivity_cb
), state
);
805 first
= selection_first_range (state
->base
.sv
, NULL
, NULL
);
807 dialog_tool_preset_to_range (&state
->base
);
808 int_to_entry (GTK_ENTRY (state
->count_entry
),
809 first
->end
.row
- first
->start
.row
+ 1);
810 int_to_entry (GTK_ENTRY (state
->vars_entry
),
811 first
->end
.col
- first
->start
.col
+ 1);
814 random_tool_update_sensitivity_cb (NULL
, state
);
819 * dialog_random_tool:
823 * Show the dialog (guru).
827 dialog_random_tool (WBCGtk
*wbcg
, Sheet
*sheet
)
829 RandomToolState
*state
;
836 /* Only pop up one copy per workbook */
837 if (gnm_dialog_raise_if_exists (wbcg
, RANDOM_KEY
)) {
841 state
= g_new (RandomToolState
, 1);
843 if (dialog_tool_init ((GnmGenericToolState
*)state
, wbcg
, sheet
,
844 GNUMERIC_HELP_LINK_RANDOM_GENERATOR
,
845 "res:ui/random-generation.ui", "Random",
846 _("Could not create the Random Tool dialog."),
848 G_CALLBACK (random_tool_ok_clicked_cb
), NULL
,
849 G_CALLBACK (random_tool_update_sensitivity_cb
),
854 gnm_dao_set_put (GNM_DAO (state
->base
.gdao
), FALSE
, FALSE
);
855 dialog_random_tool_init (state
);
856 gtk_widget_show (state
->base
.dialog
);