Compilation: don't compile dialogs separately.
[gnumeric.git] / src / dialogs / dialog-fill-series.c
blobdbbd24ac03035322c2e7f4e479828562f56259e2
1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * dialog-fill-series.c: Fill according to a linear or exponential serie.
5 * Authors: Jukka-Pekka Iivonen (jiivonen@hutcs.cs.hut.fi)
6 * Andreas J. Guelzow (aguelzow@taliesin.ca)
8 * Copyright (C) 2003 Jukka-Pekka Iivonen (jiivonen@hutcs.cs.hut.fi)
9 * Copyright (C) Andreas J. Guelzow (aguelzow@taliesin.ca)
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * 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 "help.h"
29 #include "tool-dialogs.h"
31 #include <gui-util.h>
32 #include <selection.h>
33 #include <workbook.h>
34 #include <sheet.h>
35 #include <sheet-view.h>
36 #include <commands.h>
37 #include <ranges.h>
38 #include <cmd-edit.h>
39 #include <wbc-gtk.h>
40 #include <command-context.h>
41 #include <value.h>
42 #include <selection.h>
43 #include <rendered-value.h>
44 #include <cell.h>
45 #include <widgets/gnm-dao.h>
47 #include <dao-gui-utils.h>
49 #include <gtk/gtk.h>
50 #include "fill-series.h"
52 #define FILL_SERIES_KEY "fill-series-dialog"
54 typedef struct {
55 GnmGenericToolState base;
56 GtkWidget *start_entry;
57 GtkWidget *stop_entry;
58 GtkWidget *step_entry;
59 GtkWidget *date_steps_type;
60 } FillSeriesState;
62 static void
63 cb_fill_series_update_sensitivity (G_GNUC_UNUSED GtkWidget *dummy,
64 FillSeriesState *state)
66 gboolean ready;
67 gboolean step, stop;
68 gnm_float a_float;
70 step = !entry_to_float (GTK_ENTRY (state->step_entry),
71 &a_float, FALSE);
72 stop = !entry_to_float (GTK_ENTRY (state->stop_entry),
73 &a_float,FALSE);
75 ready = gnm_dao_is_ready (GNM_DAO (state->base.gdao)) &&
76 !entry_to_float (GTK_ENTRY (state->start_entry),
77 &a_float,
78 FALSE) &&
79 ((gnm_dao_is_finite (GNM_DAO (state->base.gdao))
80 && (step || stop)) ||
81 (step && stop));
83 gtk_widget_set_sensitive (state->base.ok_button, ready);
86 static void
87 cb_fill_series_ok_clicked (G_GNUC_UNUSED GtkWidget *button,
88 FillSeriesState *state)
90 GtkWidget *radio;
91 fill_series_t *fs;
92 data_analysis_output_t *dao;
94 fs = g_new0 (fill_series_t, 1);
95 dao = parse_output ((GnmGenericToolState *)state, NULL);
97 /* Read the `Series in' radio buttons. */
98 radio = go_gtk_builder_get_widget (state->base.gui, "series_in_rows");
99 fs->series_in_rows = ! gnm_gtk_radio_group_get_selected
100 (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)));
102 /* Read the `Type' radio buttons. */
103 radio = go_gtk_builder_get_widget (state->base.gui, "type_linear");
104 fs->type = gnm_gtk_radio_group_get_selected
105 (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)));
107 /* Read the `Date unit' radio buttons. */
108 radio = go_gtk_builder_get_widget (state->base.gui, "unit_day");
109 fs->date_unit = gnm_gtk_radio_group_get_selected
110 (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)));
112 fs->is_step_set = ! entry_to_float (GTK_ENTRY (state->step_entry),
113 &fs->step_value, TRUE);
114 fs->is_stop_set = ! entry_to_float (GTK_ENTRY (state->stop_entry),
115 &fs->stop_value, TRUE);
116 entry_to_float (GTK_ENTRY (state->start_entry),
117 &fs->start_value, TRUE);
119 if (!cmd_analysis_tool (GNM_WBC (state->base.wbcg),
120 state->base.sheet,
121 dao, fs, fill_series_engine, TRUE))
122 gtk_widget_destroy (state->base.dialog);
125 static void
126 cb_type_button_clicked (G_GNUC_UNUSED GtkWidget *button,
127 FillSeriesState *state)
129 GtkWidget *radio;
130 fill_series_type_t type;
133 /* Read the `Type' radio buttons. */
134 radio = go_gtk_builder_get_widget (state->base.gui, "type_linear");
135 type = gnm_gtk_radio_group_get_selected (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)));
137 if (type == FillSeriesTypeDate)
138 gtk_widget_set_sensitive (state->date_steps_type, TRUE);
139 else
140 gtk_widget_set_sensitive (state->date_steps_type, FALSE);
144 * dialog_fill_series_tool_init:
145 * @state:
147 * Create the dialog (guru).
150 static void
151 dialog_fill_series_tool_init (FillSeriesState *state)
153 GtkWidget *radio;
154 char const *button;
155 GnmRange const *sel;
156 gboolean prefer_rows = FALSE;
158 sel = selection_first_range (state->base.sv, NULL, NULL);
160 /* Set the sensitivity of Unit day. */
161 radio = go_gtk_builder_get_widget (state->base.gui,
162 "type_date");
163 g_signal_connect (G_OBJECT (radio), "clicked",
164 G_CALLBACK (cb_type_button_clicked), state);
166 state->stop_entry = go_gtk_builder_get_widget (state->base.gui, "stop_entry");
167 g_signal_connect_after (G_OBJECT (state->stop_entry),
168 "changed",
169 G_CALLBACK (cb_fill_series_update_sensitivity), state);
170 state->step_entry = go_gtk_builder_get_widget (state->base.gui, "step_entry");
171 g_signal_connect_after (G_OBJECT (state->step_entry),
172 "changed",
173 G_CALLBACK (cb_fill_series_update_sensitivity), state);
174 state->start_entry = go_gtk_builder_get_widget (state->base.gui, "start_entry");
175 g_signal_connect_after (G_OBJECT (state->start_entry),
176 "changed",
177 G_CALLBACK (cb_fill_series_update_sensitivity), state);
180 state->date_steps_type = go_gtk_builder_get_widget (state->base.gui,
181 "table-date-unit");
182 gtk_widget_set_sensitive (state->date_steps_type, FALSE);
184 button = (sel == NULL ||
185 (prefer_rows =
186 (range_width (sel) >= range_height (sel))))
187 ? "series_in_rows"
188 : "series_in_cols";
189 radio = go_gtk_builder_get_widget (state->base.gui, button);
190 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
192 if (sel != NULL) {
193 GnmCell *cell_start;
194 GnmCell *cell_end;
196 dialog_tool_preset_to_range (&state->base);
198 cell_start = sheet_cell_get (state->base.sheet,
199 sel->start.col, sel->start.row);
200 if (cell_start) {
201 char *content = gnm_cell_get_rendered_text (cell_start);
202 if (content) {
203 gtk_entry_set_text (GTK_ENTRY (state->start_entry),
204 content);
205 g_free (content);
208 cell_end = prefer_rows ?
209 sheet_cell_get (state->base.sheet,
210 sel->end.col, sel->start.row) :
211 sheet_cell_get (state->base.sheet,
212 sel->start.col, sel->end.row);
213 if (cell_end) {
214 char *content = gnm_cell_get_rendered_text (cell_end);
215 if (content) {
216 gtk_entry_set_text (GTK_ENTRY (state->stop_entry),
217 content);
218 g_free (content);
221 if (cell_start && cell_end) {
222 float_to_entry (GTK_ENTRY(state->step_entry),
223 (value_get_as_float(cell_end->value) -
224 value_get_as_float(cell_start->value))
225 / (prefer_rows ?
226 (sel->end.col-sel->start.col) :
227 (sel->end.row-sel->start.row)));
231 cb_fill_series_update_sensitivity (NULL, state);
234 void
235 dialog_fill_series (WBCGtk *wbcg)
237 FillSeriesState *state;
238 WorkbookControl *wbc = GNM_WBC (wbcg);
239 SheetView *sv = wb_control_cur_sheet_view (wbc);
241 g_return_if_fail (wbcg != NULL);
243 /* Only pop up one copy per workbook */
244 if (gnm_dialog_raise_if_exists (wbcg, FILL_SERIES_KEY)) {
245 return;
248 state = g_new (FillSeriesState, 1);
250 if (dialog_tool_init ((GnmGenericToolState *)state, wbcg, sv_sheet (sv),
251 GNUMERIC_HELP_LINK_FILL_SERIES,
252 "res:ui/fill-series.ui", "Fill_series",
253 _("Could not create the Fill Series dialog."),
254 FILL_SERIES_KEY,
255 G_CALLBACK (cb_fill_series_ok_clicked), NULL,
256 G_CALLBACK (cb_fill_series_update_sensitivity),
258 return;
260 gnm_dao_set_put (GNM_DAO (state->base.gdao), FALSE, FALSE);
261 dialog_fill_series_tool_init (state);
262 gtk_widget_show (state->base.dialog);
264 return;