1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * dialog-analysis-tool-kaplan-meier.c:
6 * Andreas J. Guelzow <aguelzow@taliesin.ca>
8 * (C) Copyright 2008 by Andreas J. Guelzow <aguelzow@pyrshep.ca>
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>
28 #include "tools/analysis-kaplan-meier.h"
29 #include "tools/analysis-tools.h"
32 #include <workbook-control.h>
34 #include <workbook-view.h>
36 #include <parse-util.h>
37 #include <gnm-format.h>
38 #include <dialogs/tool-dialogs.h>
39 #include <dialogs/dao-gui-utils.h>
42 #include <number-match.h>
44 #include <selection.h>
49 #include <widgets/gnm-dao.h>
50 #include <widgets/gnumeric-expr-entry.h>
55 #define KAPLAN_MEIER_KEY "analysistools-kaplan-meier-dialog"
58 GnmGenericToolState base
;
59 GtkWidget
*censorship_button
;
60 GtkWidget
*censor_spin_from
;
61 GtkWidget
*censor_spin_to
;
62 GtkWidget
*graph_button
;
63 GtkWidget
*logrank_button
;
64 GtkWidget
*tick_button
;
65 GtkWidget
*add_group_button
;
66 GtkWidget
*remove_group_button
;
67 GtkWidget
*std_error_button
;
68 GtkWidget
*groups_check
;
69 GtkWidget
*groups_grid
;
70 GnmExprEntry
*groups_input
;
71 GtkTreeView
*groups_treeview
;
72 GtkListStore
*groups_list
;
73 } KaplanMeierToolState
;
80 GROUP_ADJUSTMENT_FROM
,
87 * kaplan_meier_tool_update_sensitivity_cb:
91 * Update the dialog widgets sensitivity
94 kaplan_meier_tool_update_sensitivity_cb (G_GNUC_UNUSED GtkWidget
*dummy
,
95 KaplanMeierToolState
*state
)
99 GnmValue
*input_range
;
100 GnmValue
*input_range_2
= NULL
;
103 censorship
= gtk_toggle_button_get_active (
104 GTK_TOGGLE_BUTTON (state
->censorship_button
));
105 groups
= gtk_toggle_button_get_active (
106 GTK_TOGGLE_BUTTON (state
->groups_check
));
108 gtk_widget_set_sensitive (state
->tick_button
, censorship
);
110 input_range
= gnm_expr_entry_parse_as_value
111 (GNM_EXPR_ENTRY (state
->base
.input_entry
), state
->base
.sheet
);
112 if (input_range
== NULL
) {
113 gtk_label_set_text (GTK_LABEL (state
->base
.warning
),
114 _("The time column is not valid."));
115 gtk_widget_set_sensitive (state
->base
.ok_button
, FALSE
);
119 height
= input_range
->v_range
.cell
.b
.row
- input_range
->v_range
.cell
.a
.row
;
120 width
= input_range
->v_range
.cell
.b
.col
- input_range
->v_range
.cell
.a
.col
;
122 value_release (input_range
);
125 gtk_label_set_text (GTK_LABEL (state
->base
.warning
),
126 _("The time column should be part of a single column."));
127 gtk_widget_set_sensitive (state
->base
.ok_button
, FALSE
);
132 input_range_2
= gnm_expr_entry_parse_as_value
133 (GNM_EXPR_ENTRY (state
->base
.input_entry_2
), state
->base
.sheet
);
134 if (input_range_2
== NULL
) {
135 gtk_label_set_text (GTK_LABEL (state
->base
.warning
),
136 _("The censorship column is not valid."));
137 gtk_widget_set_sensitive (state
->base
.ok_button
, FALSE
);
141 if (input_range_2
->v_range
.cell
.b
.col
!= input_range_2
->v_range
.cell
.a
.col
) {
142 gtk_label_set_text (GTK_LABEL (state
->base
.warning
),
143 _("The censorship column should be part of a single column."));
144 gtk_widget_set_sensitive (state
->base
.ok_button
, FALSE
);
145 value_release (input_range_2
);
148 if (input_range_2
->v_range
.cell
.b
.row
- input_range_2
->v_range
.cell
.a
.row
!= height
) {
149 gtk_label_set_text (GTK_LABEL (state
->base
.warning
),
150 _("The censorship and time columns should have the same height."));
151 gtk_widget_set_sensitive (state
->base
.ok_button
, FALSE
);
152 value_release (input_range_2
);
156 value_release (input_range_2
);
160 input_range_2
= gnm_expr_entry_parse_as_value
161 (GNM_EXPR_ENTRY (state
->groups_input
), state
->base
.sheet
);
163 if (input_range_2
== NULL
) {
164 gtk_label_set_text (GTK_LABEL (state
->base
.warning
),
165 _("The groups column is not valid."));
166 gtk_widget_set_sensitive (state
->base
.ok_button
, FALSE
);
169 if (input_range_2
->v_range
.cell
.b
.col
!= input_range_2
->v_range
.cell
.a
.col
) {
170 gtk_label_set_text (GTK_LABEL (state
->base
.warning
),
171 _("The groups column should be part of a single column."));
172 gtk_widget_set_sensitive (state
->base
.ok_button
, FALSE
);
173 value_release (input_range_2
);
176 if (input_range_2
->v_range
.cell
.b
.row
- input_range_2
->v_range
.cell
.a
.row
!= height
) {
177 gtk_label_set_text (GTK_LABEL (state
->base
.warning
),
178 _("The groups and time columns should have the same height."));
179 gtk_widget_set_sensitive (state
->base
.ok_button
, FALSE
);
180 value_release (input_range_2
);
184 value_release (input_range_2
);
187 if (!gnm_dao_is_ready (GNM_DAO (state
->base
.gdao
))) {
188 gtk_label_set_text (GTK_LABEL (state
->base
.warning
),
189 _("The output specification "
191 gtk_widget_set_sensitive (state
->base
.ok_button
, FALSE
);
195 gtk_label_set_text (GTK_LABEL (state
->base
.warning
), "");
196 gtk_widget_set_sensitive (state
->base
.ok_button
, TRUE
);
202 kaplan_meier_tool_get_groups_cb (GtkTreeModel
*model
,
203 G_GNUC_UNUSED GtkTreePath
*path
,
207 GSList
**list
= data
;
208 analysis_tools_kaplan_meier_group_t
*group_item
=
209 g_new0 (analysis_tools_kaplan_meier_group_t
, 1);
211 gtk_tree_model_get (model
, iter
,
212 GROUP_NAME
, &(group_item
->name
),
213 GROUP_FROM
, &(group_item
->group_from
),
214 GROUP_TO
, &(group_item
->group_to
),
216 *list
= g_slist_prepend (*list
, group_item
);
222 kaplan_meier_tool_get_groups (KaplanMeierToolState
*state
)
226 if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state
->groups_check
)))
229 gtk_tree_model_foreach (GTK_TREE_MODEL (state
->groups_list
),
230 kaplan_meier_tool_get_groups_cb
,
232 return g_slist_reverse (list
);
236 * kaplan_meier_tool_ok_clicked_cb:
240 * Retrieve the information from the dialog and call the kaplan_meier_tool.
241 * Note that we assume that the ok_button is only active if the entry fields
242 * contain sensible data.
245 kaplan_meier_tool_ok_clicked_cb (G_GNUC_UNUSED GtkWidget
*button
,
246 KaplanMeierToolState
*state
)
248 data_analysis_output_t
*dao
;
249 analysis_tools_data_kaplan_meier_t
*data
;
251 data
= g_new0 (analysis_tools_data_kaplan_meier_t
, 1);
252 dao
= parse_output ((GnmGenericToolState
*)state
, NULL
);
255 data
->base
.wbc
= GNM_WBC (state
->base
.wbcg
);
257 if (state
->base
.warning_dialog
!= NULL
)
258 gtk_widget_destroy (state
->base
.warning_dialog
);
260 data
->base
.range_1
= gnm_expr_entry_parse_as_value
261 (GNM_EXPR_ENTRY (state
->base
.input_entry
), state
->base
.sheet
);
263 data
->censored
= gtk_toggle_button_get_active (
264 GTK_TOGGLE_BUTTON (state
->censorship_button
));
267 data
->base
.range_2
= gnm_expr_entry_parse_as_value
268 (GNM_EXPR_ENTRY (state
->base
.input_entry_2
), state
->base
.sheet
);
270 data
->base
.range_2
= NULL
;
272 data
->censor_mark
= gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (state
->censor_spin_from
));
273 data
->censor_mark_to
= gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (state
->censor_spin_to
));
275 data
->group_list
= kaplan_meier_tool_get_groups (state
);
276 if (data
->group_list
== NULL
) {
277 data
->range_3
= NULL
;
278 data
->logrank_test
= FALSE
;
280 data
->range_3
= gnm_expr_entry_parse_as_value
281 (GNM_EXPR_ENTRY (state
->groups_input
), state
->base
.sheet
);
282 data
->logrank_test
= gtk_toggle_button_get_active (
283 GTK_TOGGLE_BUTTON (state
->logrank_button
));
286 data
->median
= gtk_toggle_button_get_active (
287 GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget
290 data
->chart
= gtk_toggle_button_get_active (
291 GTK_TOGGLE_BUTTON (state
->graph_button
));
292 data
->ticks
= gtk_toggle_button_get_active (
293 GTK_TOGGLE_BUTTON (state
->tick_button
));
294 data
->std_err
= gtk_toggle_button_get_active (
295 GTK_TOGGLE_BUTTON (state
->std_error_button
));
297 if (!cmd_analysis_tool (GNM_WBC (state
->base
.wbcg
),
299 dao
, data
, analysis_tool_kaplan_meier_engine
,
301 gtk_widget_destroy (state
->base
.dialog
);
307 * kaplan_meier_tool_set_graph:
315 kaplan_meier_tool_set_graph_cb (G_GNUC_UNUSED GtkWidget
*dummy
,
316 KaplanMeierToolState
*state
)
318 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state
->graph_button
), TRUE
);
319 kaplan_meier_tool_update_sensitivity_cb (NULL
, state
);
324 * kaplan_meier_tool_set_censorship:
331 kaplan_meier_tool_set_censorship_cb (G_GNUC_UNUSED GtkWidget
*widget
,
332 G_GNUC_UNUSED GdkEventFocus
*event
,
333 KaplanMeierToolState
*state
)
335 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state
->censorship_button
), TRUE
);
340 kaplan_meier_tool_set_groups_cb (G_GNUC_UNUSED GtkWidget
*widget
,
341 G_GNUC_UNUSED GdkEventFocus
*event
,
342 KaplanMeierToolState
*state
)
344 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state
->groups_check
), TRUE
);
350 kaplan_meier_tool_set_censor_from_cb (G_GNUC_UNUSED GtkWidget
*dummy
,
351 KaplanMeierToolState
*state
)
353 gtk_spin_button_set_range (GTK_SPIN_BUTTON (state
->censor_spin_to
),
354 gtk_spin_button_get_value (GTK_SPIN_BUTTON (state
->censor_spin_from
)),G_MAXSHORT
);
355 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state
->censorship_button
), TRUE
);
360 kaplan_meier_tool_set_censor_cb (G_GNUC_UNUSED GtkWidget
*dummy
,
361 KaplanMeierToolState
*state
)
363 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state
->censorship_button
), TRUE
);
369 cb_group_name_edited (GtkCellRendererText
*cell
,
372 KaplanMeierToolState
*state
)
378 path
= gtk_tree_path_new_from_string (path_string
);
379 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (state
->groups_list
),
381 gtk_list_store_set (state
->groups_list
, &iter
,
382 GROUP_NAME
, new_text
, -1);
384 g_warning ("Did not get a valid iterator");
385 gtk_tree_path_free (path
);
390 cb_change_to (GtkCellRendererText
*cell
,
393 KaplanMeierToolState
*state
)
397 guint val
= (guint
) (atoi (new_text
));
400 path
= gtk_tree_path_new_from_string (path_string
);
401 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (state
->groups_list
),
403 gtk_list_store_set (state
->groups_list
, &iter
,
406 g_warning ("Did not get a valid iterator");
407 gtk_tree_path_free (path
);
412 cb_change_from (GtkCellRendererText
*cell
,
415 KaplanMeierToolState
*state
)
420 guint val
= (guint
) (atoi (new_text
));
422 GObject
*adjustment_to
;
425 path
= gtk_tree_path_new_from_string (path_string
);
426 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (state
->groups_list
),
428 gtk_list_store_set (state
->groups_list
, &iter
,
432 g_warning ("Did not get a valid iterator");
433 gtk_tree_path_free (path
);
435 gtk_tree_model_get (GTK_TREE_MODEL (state
->groups_list
), &iter
,
437 GROUP_ADJUSTMENT_TO
, &adjustment_to
,
441 gtk_list_store_set (state
->groups_list
, &iter
,
444 g_object_set (adjustment_to
, "lower", (gdouble
) val
, NULL
);
450 cb_selection_changed (GtkTreeSelection
*selection
,
451 KaplanMeierToolState
*state
)
453 gtk_widget_set_sensitive (state
->remove_group_button
,
454 gtk_tree_selection_get_selected (selection
, NULL
, NULL
));
458 kaplan_meier_tool_update_groups_sensitivity_cb (G_GNUC_UNUSED GtkWidget
*dummy
,
459 KaplanMeierToolState
*state
)
461 gboolean groups
= gtk_toggle_button_get_active (
462 GTK_TOGGLE_BUTTON (state
->groups_check
));
463 GtkTreeSelection
*selection
= gtk_tree_view_get_selection (state
->groups_treeview
);
465 gtk_widget_set_sensitive (state
->add_group_button
, groups
);
466 gtk_widget_set_sensitive (GTK_WIDGET (state
->groups_treeview
), groups
);
469 cb_selection_changed (selection
, state
);
470 gtk_widget_set_sensitive (state
->logrank_button
, TRUE
);
472 gtk_tree_selection_unselect_all (selection
);
473 gtk_widget_set_sensitive (state
->remove_group_button
, FALSE
);
474 gtk_widget_set_sensitive (state
->logrank_button
, FALSE
);
479 dialog_kaplan_meier_tool_treeview_add_item (KaplanMeierToolState
*state
, guint i
)
482 char * name
= g_strdup_printf (_("Group %d"), i
);
483 GObject
*adjustment_to
=
484 G_OBJECT (gtk_adjustment_new (0, 0, G_MAXUSHORT
, 1, 1, 1));
485 GObject
*adjustment_from
=
486 G_OBJECT (gtk_adjustment_new (0, 0, G_MAXUSHORT
, 1, 1, 1));
487 gtk_list_store_append (state
->groups_list
, &iter
);
488 gtk_list_store_set (state
->groups_list
, &iter
,
490 GROUP_FROM
, (guint
) i
,
492 GROUP_ADJUSTMENT_FROM
, adjustment_from
,
493 GROUP_ADJUSTMENT_TO
, adjustment_to
,
499 dialog_kaplan_meier_tool_setup_treeview (KaplanMeierToolState
*state
)
502 GtkCellRenderer
*renderer
;
503 GtkWidget
*scrolled
= go_gtk_builder_get_widget (state
->base
.gui
, "groups-scrolled");
504 GtkTreeSelection
*selection
;
506 state
->groups_treeview
= GTK_TREE_VIEW (go_gtk_builder_get_widget
509 state
->groups_list
= gtk_list_store_new (GROUP_COLUMNS
,
510 G_TYPE_STRING
, G_TYPE_UINT
, G_TYPE_UINT
, G_TYPE_OBJECT
, G_TYPE_OBJECT
);
511 state
->groups_treeview
= GTK_TREE_VIEW (gtk_tree_view_new_with_model
512 (GTK_TREE_MODEL (state
->groups_list
)));
513 g_object_unref (state
->groups_list
);
514 selection
= gtk_tree_view_get_selection (state
->groups_treeview
);
515 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_SINGLE
);
517 for (i
= 0; i
<2; i
++)
518 dialog_kaplan_meier_tool_treeview_add_item (state
, i
);
520 g_signal_connect (selection
,
522 G_CALLBACK (cb_selection_changed
), state
);
524 renderer
= gtk_cell_renderer_text_new ();
525 g_object_set (G_OBJECT (renderer
),
528 gtk_tree_view_insert_column_with_attributes (state
->groups_treeview
,
533 g_signal_connect (G_OBJECT (renderer
), "edited",
534 G_CALLBACK (cb_group_name_edited
), state
);
536 renderer
= gtk_cell_renderer_spin_new ();
538 g_object_set (G_OBJECT (renderer
), "editable", TRUE
, "xalign", 1.0,
540 g_signal_connect (G_OBJECT (renderer
), "edited",
541 G_CALLBACK (cb_change_from
), state
);
542 gtk_tree_view_insert_column_with_attributes (state
->groups_treeview
,
546 "adjustment", GROUP_ADJUSTMENT_FROM
,
549 renderer
= gtk_cell_renderer_spin_new ();
550 g_object_set (G_OBJECT (renderer
), "editable", TRUE
, "xalign", 1.0,
552 g_signal_connect (G_OBJECT (renderer
), "edited",
553 G_CALLBACK (cb_change_to
), state
);
554 gtk_tree_view_insert_column_with_attributes (state
->groups_treeview
,
558 "adjustment", GROUP_ADJUSTMENT_TO
,
561 gtk_container_add (GTK_CONTAINER (scrolled
), GTK_WIDGET (state
->groups_treeview
));
563 cb_selection_changed (selection
, state
);
567 kaplan_meier_tool_add_group_cb (G_GNUC_UNUSED GtkWidget
*dummy
,
568 KaplanMeierToolState
*state
)
570 dialog_kaplan_meier_tool_treeview_add_item
571 (state
, gtk_tree_model_iter_n_children (GTK_TREE_MODEL (state
->groups_list
),
577 kaplan_meier_tool_remove_group_cb (G_GNUC_UNUSED GtkWidget
*dummy
,
578 KaplanMeierToolState
*state
)
580 GtkTreeSelection
*selection
;
583 selection
= gtk_tree_view_get_selection (state
->groups_treeview
);
585 if (gtk_tree_selection_get_selected (selection
, NULL
, &iter
)) {
586 gtk_list_store_remove ( state
->groups_list
, &iter
);
594 * dialog_kaplan_meier_tool:
598 * Show the dialog (guru).
602 dialog_kaplan_meier_tool (WBCGtk
*wbcg
, Sheet
*sheet
)
604 KaplanMeierToolState
*state
;
606 char const * plugins
[] = { "Gnumeric_fnstat",
610 "Gnumeric_fnlogical",
613 if ((wbcg
== NULL
) ||
614 gnm_check_for_plugins_missing (plugins
, wbcg_toplevel (wbcg
)))
617 /* Only pop up one copy per workbook */
618 if (gnm_dialog_raise_if_exists (wbcg
, KAPLAN_MEIER_KEY
))
621 state
= g_new0 (KaplanMeierToolState
, 1);
623 if (dialog_tool_init (&state
->base
, wbcg
, sheet
,
624 GNUMERIC_HELP_LINK_KAPLAN_MEIER
,
625 "res:ui/kaplan-meier.ui", "KaplanMeier",
626 _("Could not create the Kaplan Meier Tool dialog."),
628 G_CALLBACK (kaplan_meier_tool_ok_clicked_cb
), NULL
,
629 G_CALLBACK (kaplan_meier_tool_update_sensitivity_cb
),
638 state
->censorship_button
= GTK_WIDGET (go_gtk_builder_get_widget
641 state
->censor_spin_from
= GTK_WIDGET (go_gtk_builder_get_widget
643 "censored-spinbutton1"));
644 gtk_spin_button_set_range (GTK_SPIN_BUTTON (state
->censor_spin_from
), 0.,G_MAXSHORT
);
645 state
->censor_spin_to
= GTK_WIDGET (go_gtk_builder_get_widget
647 "censored-spinbutton2"));
648 gtk_spin_button_set_range (GTK_SPIN_BUTTON (state
->censor_spin_to
), 0.,G_MAXSHORT
);
649 state
->graph_button
= GTK_WIDGET (go_gtk_builder_get_widget
652 state
->tick_button
= GTK_WIDGET (go_gtk_builder_get_widget
655 state
->add_group_button
= GTK_WIDGET (go_gtk_builder_get_widget
658 state
->remove_group_button
= GTK_WIDGET (go_gtk_builder_get_widget
661 state
->std_error_button
= GTK_WIDGET (go_gtk_builder_get_widget
663 "std-error-button"));
664 state
->logrank_button
= GTK_WIDGET (go_gtk_builder_get_widget
668 state
->groups_check
= GTK_WIDGET (go_gtk_builder_get_widget
671 state
->groups_grid
= GTK_WIDGET (go_gtk_builder_get_widget
674 state
->groups_input
= gnm_expr_entry_new (state
->base
.wbcg
, TRUE
);
675 gnm_expr_entry_set_flags (state
->groups_input
, GNM_EE_FORCE_ABS_REF
,
677 gtk_grid_attach (GTK_GRID (state
->groups_grid
),
678 GTK_WIDGET (state
->groups_input
), 1, 1, 2, 1);
680 dialog_kaplan_meier_tool_setup_treeview (state
);
682 g_signal_connect_after (G_OBJECT (state
->groups_check
),
684 G_CALLBACK (kaplan_meier_tool_update_sensitivity_cb
), state
);
685 g_signal_connect_after (G_OBJECT (state
->censorship_button
),
687 G_CALLBACK (kaplan_meier_tool_update_sensitivity_cb
), state
);
688 g_signal_connect_after (G_OBJECT (state
->graph_button
),
690 G_CALLBACK (kaplan_meier_tool_update_sensitivity_cb
), state
);
691 g_signal_connect_after (G_OBJECT (state
->std_error_button
),
693 G_CALLBACK (kaplan_meier_tool_update_sensitivity_cb
), state
);
694 g_signal_connect_after (G_OBJECT (state
->groups_input
),
696 G_CALLBACK (kaplan_meier_tool_update_sensitivity_cb
),
699 g_signal_connect_after (G_OBJECT (state
->groups_check
),
701 G_CALLBACK (kaplan_meier_tool_update_groups_sensitivity_cb
), state
);
702 g_signal_connect_after (G_OBJECT (state
->tick_button
),
704 G_CALLBACK (kaplan_meier_tool_set_graph_cb
), state
);
705 g_signal_connect_after (G_OBJECT (state
->add_group_button
),
707 G_CALLBACK (kaplan_meier_tool_add_group_cb
), state
);
708 g_signal_connect_after (G_OBJECT (state
->remove_group_button
),
710 G_CALLBACK (kaplan_meier_tool_remove_group_cb
), state
);
711 g_signal_connect_after (G_OBJECT (state
->censor_spin_from
),
713 G_CALLBACK (kaplan_meier_tool_set_censor_from_cb
), state
);
714 g_signal_connect_after (G_OBJECT (state
->censor_spin_to
),
716 G_CALLBACK (kaplan_meier_tool_set_censor_cb
), state
);
717 g_signal_connect (G_OBJECT
718 (gnm_expr_entry_get_entry (
719 GNM_EXPR_ENTRY (state
->base
.input_entry_2
))),
721 G_CALLBACK (kaplan_meier_tool_set_censorship_cb
), state
);
722 g_signal_connect (G_OBJECT
723 (gnm_expr_entry_get_entry (
724 GNM_EXPR_ENTRY (state
->groups_input
))),
726 G_CALLBACK (kaplan_meier_tool_set_groups_cb
), state
);
728 gnm_editable_enters (GTK_WINDOW (state
->base
.dialog
),
729 GTK_WIDGET (state
->groups_input
));
731 widget
= go_gtk_builder_get_widget (state
->base
.gui
, "groups-label");
732 gtk_label_set_mnemonic_widget (GTK_LABEL (widget
),
733 GTK_WIDGET (state
->groups_input
));
734 go_atk_setup_label (widget
, GTK_WIDGET (state
->groups_input
));
736 gnm_dao_set_put (GNM_DAO (state
->base
.gdao
), TRUE
, TRUE
);
737 kaplan_meier_tool_update_sensitivity_cb (NULL
, state
);
738 kaplan_meier_tool_update_groups_sensitivity_cb (NULL
, state
);
739 tool_load_selection ((GnmGenericToolState
*)state
, TRUE
);
741 gtk_widget_show_all (GTK_WIDGET (state
->base
.dialog
));
742 /* And to hide the in-place button again */
743 gnm_dao_set_inplace ( GNM_DAO (state
->base
.gdao
), NULL
);