3 * Dialog for making tables of function dependcies.
6 * COPYRIGHT (C) Morten Welinder (terra@gnome.org)
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) version 3.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
24 #include <gnumeric-config.h>
25 #include <glib/gi18n-lib.h>
27 #include <dialogs/dialogs.h>
28 #include <dialogs/help.h>
31 #include <widgets/gnm-expr-entry.h>
32 #include <tools/tabulate.h>
42 #include <gnm-format.h>
43 #include <number-match.h>
45 #include <style-border.h>
46 #include <sheet-style.h>
47 #include <style-color.h>
51 #define TABULATE_KEY "tabulate-dialog"
53 /* ------------------------------------------------------------------------- */
70 GnmExprEntry
*resultrangetext
;
73 static const char * const mode_group
[] = {
79 /* ------------------------------------------------------------------------- */
82 non_model_dialog (WBCGtk
*wbcg
,
86 gnm_keyed_dialog (wbcg
, GTK_WINDOW (dialog
), key
);
88 gtk_widget_show (GTK_WIDGET (dialog
));
92 single_cell (Sheet
*sheet
, GnmExprEntry
*gee
)
96 GnmValue
*v
= gnm_expr_entry_parse_as_value (gee
, sheet
);
100 col
= v
->v_range
.cell
.a
.col
;
101 row
= v
->v_range
.cell
.a
.row
;
102 issingle
= (col
== v
->v_range
.cell
.b
.col
&& row
== v
->v_range
.cell
.b
.row
);
107 return sheet_cell_fetch (sheet
, col
, row
);
113 get_grid_float_entry (GtkGrid
*g
, int y
, int x
, GnmCell
*cell
, gnm_float
*number
,
114 GtkEntry
**wp
, gboolean with_default
, gnm_float default_float
)
116 GOFormat
const *format
;
117 GtkWidget
*w
= gtk_grid_get_child_at (g
, x
, y
+ 1);
119 g_return_val_if_fail (GTK_IS_ENTRY (w
), 3);
122 format
= gnm_style_get_format (gnm_cell_get_style (cell
));
124 return (with_default
?
125 entry_to_float_with_format_default (*wp
, number
, TRUE
, format
,
127 entry_to_float_with_format (*wp
, number
, TRUE
, format
));
131 cb_dialog_destroy (DialogState
*dd
)
133 g_object_unref (dd
->gui
);
134 memset (dd
, 0, sizeof (*dd
));
139 cancel_clicked (G_GNUC_UNUSED GtkWidget
*widget
, DialogState
*dd
)
141 GtkDialog
*dialog
= dd
->dialog
;
142 gtk_widget_destroy (GTK_WIDGET (dialog
));
146 tabulate_ok_clicked (G_GNUC_UNUSED GtkWidget
*widget
, DialogState
*dd
)
148 GtkDialog
*dialog
= dd
->dialog
;
152 gboolean with_coordinates
;
153 GnmTabulateInfo
*data
;
154 /* we might get the 4 below from the positon of some of the widgets inside the grid */
157 gnm_float
*minima
, *maxima
, *steps
;
159 cells
= g_new (GnmCell
*, nrows
);
160 minima
= g_new (gnm_float
, nrows
);
161 maxima
= g_new (gnm_float
, nrows
);
162 steps
= g_new (gnm_float
, nrows
);
164 for (row
= 1; row
< nrows
; row
++) {
166 GnmExprEntry
*w
= GNM_EXPR_ENTRY (gtk_grid_get_child_at (dd
->grid
, COL_CELL
, row
+ 1));
168 if (!w
|| gnm_expr_entry_is_blank (w
))
171 cells
[dims
] = single_cell (dd
->sheet
, w
);
173 go_gtk_notice_dialog (GTK_WINDOW (dd
->dialog
),
175 _("You should introduce a single valid cell as dependency cell"));
176 gnm_expr_entry_grab_focus (GNM_EXPR_ENTRY (w
), TRUE
);
179 if (gnm_cell_has_expr (cells
[dims
])) {
180 go_gtk_notice_dialog (GTK_WINDOW (dd
->dialog
),
182 _("The dependency cells should not contain an expression"));
183 gnm_expr_entry_grab_focus (GNM_EXPR_ENTRY (w
), TRUE
);
187 if (get_grid_float_entry (dd
->grid
, row
, COL_MIN
, cells
[dims
],
188 &(minima
[dims
]), &e_w
, FALSE
, 0.0)) {
189 go_gtk_notice_dialog (GTK_WINDOW (dd
->dialog
),
191 _("You should introduce a valid number as minimum"));
192 focus_on_entry (e_w
);
196 if (get_grid_float_entry (dd
->grid
, row
, COL_MAX
, cells
[dims
],
197 &(maxima
[dims
]), &e_w
, FALSE
, 0.0)) {
198 go_gtk_notice_dialog (GTK_WINDOW (dd
->dialog
),
200 _("You should introduce a valid number as maximum"));
201 focus_on_entry (e_w
);
205 if (maxima
[dims
] < minima
[dims
]) {
206 go_gtk_notice_dialog (GTK_WINDOW (dd
->dialog
),
208 _("The maximum value should be bigger than the minimum"));
209 focus_on_entry (e_w
);
213 if (get_grid_float_entry (dd
->grid
, row
, COL_STEP
, cells
[dims
],
214 &(steps
[dims
]), &e_w
, TRUE
, 1.0)) {
215 go_gtk_notice_dialog (GTK_WINDOW (dd
->dialog
),
217 _("You should introduce a valid number as step size"));
218 focus_on_entry (e_w
);
222 if (steps
[dims
] <= 0) {
223 go_gtk_notice_dialog (GTK_WINDOW (dd
->dialog
),
225 _("The step size should be positive"));
226 focus_on_entry (e_w
);
234 go_gtk_notice_dialog (GTK_WINDOW (dd
->dialog
),
236 _("You should introduce one or more dependency cells"));
241 resultcell
= single_cell (dd
->sheet
, dd
->resultrangetext
);
244 go_gtk_notice_dialog (GTK_WINDOW (dd
->dialog
),
246 _("You should introduce a single valid cell as result cell"));
247 gnm_expr_entry_grab_focus (dd
->resultrangetext
, TRUE
);
251 if (!gnm_cell_has_expr (resultcell
)) {
252 go_gtk_notice_dialog (GTK_WINDOW (dd
->dialog
),
254 _("The target cell should contain an expression"));
255 gnm_expr_entry_grab_focus (dd
->resultrangetext
, TRUE
);
261 int i
= gnm_gui_group_value (dd
->gui
, mode_group
);
262 with_coordinates
= (i
== -1) ? TRUE
: (gboolean
)i
;
265 data
= g_new (GnmTabulateInfo
, 1);
266 data
->target
= resultcell
;
269 data
->minima
= minima
;
270 data
->maxima
= maxima
;
272 data
->with_coordinates
= with_coordinates
;
274 if (!cmd_tabulate (GNM_WBC (dd
->wbcg
), data
)) {
275 gtk_widget_destroy (GTK_WIDGET (dialog
));
288 dialog_tabulate (WBCGtk
*wbcg
, Sheet
*sheet
)
295 g_return_if_fail (wbcg
!= NULL
);
297 /* Only one guru per workbook. */
298 if (wbc_gtk_get_guru (wbcg
))
301 if (gnm_dialog_raise_if_exists (wbcg
, TABULATE_KEY
))
303 gui
= gnm_gtk_builder_load ("res:ui/tabulate.ui", NULL
, GO_CMD_CONTEXT (wbcg
));
307 dialog
= GTK_DIALOG (go_gtk_builder_get_widget (gui
, "tabulate_dialog"));
309 dd
= g_new (DialogState
, 1);
315 dd
->grid
= GTK_GRID (go_gtk_builder_get_widget (gui
, "main-grid"));
316 /* we might get the 4 below from the positon of some of the widgets inside the grid */
317 for (i
= 1; i
< 4; i
++) {
318 GnmExprEntry
*ge
= gnm_expr_entry_new (wbcg
, TRUE
);
319 gnm_expr_entry_set_flags (ge
,
320 GNM_EE_SINGLE_RANGE
| GNM_EE_SHEET_OPTIONAL
,
323 gtk_grid_attach (dd
->grid
, GTK_WIDGET (ge
), COL_CELL
, i
+ 1, 1, 1);
324 gtk_widget_set_margin_left (GTK_WIDGET (ge
), 18);
325 gtk_widget_show (GTK_WIDGET (ge
));
328 dd
->resultrangetext
= gnm_expr_entry_new (wbcg
, TRUE
);
329 gnm_expr_entry_set_flags (dd
->resultrangetext
,
330 GNM_EE_SINGLE_RANGE
| GNM_EE_SHEET_OPTIONAL
,
332 gtk_grid_attach (dd
->grid
, GTK_WIDGET (dd
->resultrangetext
), 0, 6, 4, 1);
333 gtk_widget_set_margin_left (GTK_WIDGET (dd
->resultrangetext
), 18);
334 gtk_widget_show (GTK_WIDGET (dd
->resultrangetext
));
336 g_signal_connect (G_OBJECT (go_gtk_builder_get_widget (gui
, "ok_button")),
338 G_CALLBACK (tabulate_ok_clicked
), dd
);
340 g_signal_connect (G_OBJECT (go_gtk_builder_get_widget (gui
, "cancel_button")),
342 G_CALLBACK (cancel_clicked
), dd
);
343 /* FIXME: Add correct helpfile address */
344 gnm_init_help_button (
345 go_gtk_builder_get_widget (gui
, "help_button"),
346 GNUMERIC_HELP_LINK_TABULATE
);
347 g_object_set_data_full (G_OBJECT (dialog
),
348 "state", dd
, (GDestroyNotify
) cb_dialog_destroy
);
350 gnm_dialog_setup_destroy_handlers (dialog
, wbcg
,
351 GNM_DIALOG_DESTROY_SHEET_REMOVED
);
353 gtk_widget_show_all (gtk_dialog_get_content_area (dialog
));
354 wbc_gtk_attach_guru (wbcg
, GTK_WIDGET (dialog
));
356 non_model_dialog (wbcg
, dialog
, TABULATE_KEY
);