/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * dialog-fill-series.c: Fill according to a linear or exponential serie. * * Authors: Jukka-Pekka Iivonen (jiivonen@hutcs.cs.hut.fi) * Andreas J. Guelzow (aguelzow@taliesin.ca) * * Copyright (C) 2003 Jukka-Pekka Iivonen (jiivonen@hutcs.cs.hut.fi) * Copyright (C) Andreas J. Guelzow (aguelzow@taliesin.ca) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include "dialogs.h" #include "help.h" #include "tool-dialogs.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fill-series.h" #define FILL_SERIES_KEY "fill-series-dialog" typedef struct { GenericToolState base; GtkWidget *start_entry; GtkWidget *stop_entry; GtkWidget *step_entry; GtkWidget *date_steps_type; } FillSeriesState; static void cb_fill_series_update_sensitivity (G_GNUC_UNUSED GtkWidget *dummy, FillSeriesState *state) { gboolean ready; gboolean step, stop; gnm_float a_float; step = !entry_to_float (GTK_ENTRY (state->step_entry), &a_float, FALSE); stop = !entry_to_float (GTK_ENTRY (state->stop_entry), &a_float,FALSE); ready = gnm_dao_is_ready (GNM_DAO (state->base.gdao)) && !entry_to_float (GTK_ENTRY (state->start_entry), &a_float, FALSE) && ((gnm_dao_is_finite (GNM_DAO (state->base.gdao)) && (step || stop)) || (step && stop)); gtk_widget_set_sensitive (state->base.ok_button, ready); } static void cb_fill_series_ok_clicked (G_GNUC_UNUSED GtkWidget *button, FillSeriesState *state) { GtkWidget *radio; fill_series_t *fs; data_analysis_output_t *dao; fs = g_new0 (fill_series_t, 1); dao = parse_output ((GenericToolState *)state, NULL); /* Read the `Series in' radio buttons. */ radio = glade_xml_get_widget (state->base.gui, "series_in_rows"); fs->series_in_rows = ! gtk_radio_group_get_selected (GTK_RADIO_BUTTON (radio)->group); /* Read the `Type' radio buttons. */ radio = glade_xml_get_widget (state->base.gui, "type_linear"); fs->type = gtk_radio_group_get_selected (GTK_RADIO_BUTTON (radio)->group); /* Read the `Date unit' radio buttons. */ radio = glade_xml_get_widget (state->base.gui, "unit_day"); fs->date_unit = gtk_radio_group_get_selected (GTK_RADIO_BUTTON (radio)->group); fs->is_step_set = ! entry_to_float (GTK_ENTRY (state->step_entry), &fs->step_value, TRUE); fs->is_stop_set = ! entry_to_float (GTK_ENTRY (state->stop_entry), &fs->stop_value, TRUE); entry_to_float (GTK_ENTRY (state->start_entry), &fs->start_value, TRUE); if (!cmd_analysis_tool (WORKBOOK_CONTROL (state->base.wbcg), state->base.sheet, dao, fs, fill_series_engine)) gtk_widget_destroy (state->base.dialog); } static void cb_type_button_clicked (G_GNUC_UNUSED GtkWidget *button, FillSeriesState *state) { GtkWidget *radio; fill_series_type_t type; /* Read the `Type' radio buttons. */ radio = glade_xml_get_widget (state->base.gui, "type_linear"); type = gtk_radio_group_get_selected (GTK_RADIO_BUTTON (radio)->group); if (type == FillSeriesTypeDate) gtk_widget_set_sensitive (state->date_steps_type, TRUE); else gtk_widget_set_sensitive (state->date_steps_type, FALSE); } /** * dialog_fill_series_tool_init: * @state: * * Create the dialog (guru). * **/ static void dialog_fill_series_tool_init (FillSeriesState *state) { GtkWidget *radio; char const *button; GnmRange const *sel; gboolean prefer_rows = FALSE; sel = selection_first_range (state->base.sv, NULL, NULL); /* Set the sensitivity of Unit day. */ radio = glade_xml_get_widget (state->base.gui, "type_date"); g_signal_connect (G_OBJECT (radio), "clicked", G_CALLBACK (cb_type_button_clicked), state); state->stop_entry = glade_xml_get_widget (state->base.gui, "stop_entry"); g_signal_connect_after (G_OBJECT (state->stop_entry), "changed", G_CALLBACK (cb_fill_series_update_sensitivity), state); state->step_entry = glade_xml_get_widget (state->base.gui, "step_entry"); g_signal_connect_after (G_OBJECT (state->step_entry), "changed", G_CALLBACK (cb_fill_series_update_sensitivity), state); state->start_entry = glade_xml_get_widget (state->base.gui, "start_entry"); g_signal_connect_after (G_OBJECT (state->start_entry), "changed", G_CALLBACK (cb_fill_series_update_sensitivity), state); state->date_steps_type = glade_xml_get_widget (state->base.gui, "table_date_unit"); gtk_widget_set_sensitive (state->date_steps_type, FALSE); button = (sel == NULL || (prefer_rows = (range_width (sel) >= range_height (sel)))) ? "series_in_rows" : "series_in_cols"; radio = glade_xml_get_widget (state->base.gui, button); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE); if (sel != NULL) { GnmCell *cell_start; GnmCell *cell_end; dialog_tool_preset_to_range (&state->base); cell_start = sheet_cell_get (state->base.sheet, sel->start.col, sel->start.row); if (cell_start) { char *content = cell_get_rendered_text (cell_start); if (content) { gtk_entry_set_text (GTK_ENTRY (state->start_entry), content); g_free (content); } } cell_end = prefer_rows ? sheet_cell_get (state->base.sheet, sel->end.col, sel->start.row) : sheet_cell_get (state->base.sheet, sel->start.col, sel->end.row); if (cell_end) { char *content = cell_get_rendered_text (cell_end); if (content) { gtk_entry_set_text (GTK_ENTRY (state->stop_entry), content); g_free (content); } } if (cell_start && cell_end) { float_to_entry (GTK_ENTRY(state->step_entry), (value_get_as_float(cell_end->value) - value_get_as_float(cell_start->value)) / (prefer_rows ? (sel->end.col-sel->start.col) : (sel->end.row-sel->start.row))); } } cb_fill_series_update_sensitivity (NULL, state); } void dialog_fill_series (WorkbookControlGUI *wbcg) { FillSeriesState *state; WorkbookControl *wbc = WORKBOOK_CONTROL (wbcg); SheetView *sv = wb_control_cur_sheet_view (wbc); g_return_if_fail (wbcg != NULL); /* Only pop up one copy per workbook */ if (gnumeric_dialog_raise_if_exists (wbcg, FILL_SERIES_KEY)) { return; } state = g_new (FillSeriesState, 1); if (dialog_tool_init ((GenericToolState *)state, wbcg, sv_sheet (sv), GNUMERIC_HELP_LINK_FILL_SERIES, "fill-series.glade", "Fill_series", _("Could not create the Fill Series dialog."), FILL_SERIES_KEY, G_CALLBACK (cb_fill_series_ok_clicked), NULL, G_CALLBACK (cb_fill_series_update_sensitivity), 0)) return; gnm_dao_set_put (GNM_DAO (state->base.gdao), FALSE, FALSE); dialog_fill_series_tool_init (state); gtk_widget_show (state->base.dialog); return; }