1.12.42
[gnumeric.git] / src / dialogs / dialog-sheet-resize.c
blob1a4dcf6a76771276e1106c46f43a3e036d1328c4
1 /*
2 * dialog-sheet-resize.c: Dialog to resize current or all sheets.
4 * Author:
5 * Morten Welinder <terra@gnome.org>
7 * (C) Copyright 2009 Morten Welinder <terra@gnome.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <https://www.gnu.org/licenses/>.
23 #include <gnumeric-config.h>
24 #include <glib/gi18n-lib.h>
25 #include <gnumeric.h>
26 #include <dialogs/dialogs.h>
27 #include <dialogs/help.h>
29 #include <gui-util.h>
30 #include <wbc-gtk.h>
31 #include <workbook-view.h>
32 #include <workbook.h>
33 #include <sheet.h>
34 #include <commands.h>
36 #define RESIZE_DIALOG_KEY "sheet-resize-dialog"
38 typedef struct {
39 WBCGtk *wbcg;
40 Sheet *sheet;
41 GtkWidget *dialog;
42 GtkWidget *columns_scale, *rows_scale;
43 GtkWidget *columns_label, *rows_label;
44 GtkWidget *ok_button, *cancel_button;
45 GtkWidget *all_sheets_button;
46 } ResizeState;
48 static void
49 get_sizes (ResizeState *state, int *cols, int *rows)
51 GtkAdjustment *adj;
53 adj = gtk_range_get_adjustment (GTK_RANGE (state->columns_scale));
54 *cols = 1 << (int)gtk_adjustment_get_value (adj);
56 adj = gtk_range_get_adjustment (GTK_RANGE (state->rows_scale));
57 *rows = 1 << (int)gtk_adjustment_get_value (adj);
60 static void
61 set_count (GtkWidget *l, int count)
63 char *text;
65 if (count >= (1 << 20))
66 text = g_strdup_printf ("%dM", count >> 20);
67 else
68 text = g_strdup_printf ("%d", count);
69 gtk_label_set_text (GTK_LABEL (l), text);
70 g_free (text);
73 static void
74 cb_scale_changed (ResizeState *state)
76 int cols, rows;
77 get_sizes (state, &cols, &rows);
78 set_count (state->columns_label, cols);
79 set_count (state->rows_label, rows);
80 gtk_widget_set_sensitive (state->ok_button,
81 gnm_sheet_valid_size (cols, rows));
84 static int
85 mylog2 (int N)
87 int l2 = 0;
88 while (N > 1)
89 N >>= 1, l2++;
90 return l2;
93 static void
94 init_scale (GtkWidget *scale, int N, int lo, int hi)
96 GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (scale));
97 g_object_set (G_OBJECT (adj),
98 "lower", (double)mylog2 (lo),
99 "upper", (double)mylog2 (hi) + 1.,
100 NULL);
101 gtk_adjustment_set_value (adj, mylog2 (N));
104 static void
105 cb_ok_clicked (ResizeState *state)
107 GSList *sheets, *l;
108 GSList *changed_sheets = NULL;
109 WorkbookControl *wbc;
110 Workbook *wb;
111 gboolean all_sheets;
112 int cols, rows;
114 get_sizes (state, &cols, &rows);
115 all_sheets = gtk_toggle_button_get_active
116 (GTK_TOGGLE_BUTTON (state->all_sheets_button));
118 wbc = GNM_WBC (state->wbcg);
120 if (all_sheets) {
121 wb = wb_control_get_workbook (wbc);
122 sheets = workbook_sheets (wb);
123 for (l = sheets; l; l = l->next) {
124 Sheet *this_sheet = l->data;
126 if (this_sheet == state->sheet)
127 continue;
129 if (cols == gnm_sheet_get_max_cols (this_sheet) &&
130 rows == gnm_sheet_get_max_rows (this_sheet))
131 continue;
133 changed_sheets = g_slist_prepend (changed_sheets, this_sheet);
135 g_slist_free (sheets);
138 if (changed_sheets ||
139 cols != gnm_sheet_get_max_cols (state->sheet) ||
140 rows != gnm_sheet_get_max_rows (state->sheet)) {
141 /* We also append the sheet if it isn't changed in size */
142 /* to ensure that the focus stays on the current sheet. */
143 changed_sheets = g_slist_prepend (changed_sheets, state->sheet);
148 if (changed_sheets)
149 cmd_resize_sheets (wbc, changed_sheets,
150 cols, rows);
152 gtk_widget_destroy (state->dialog);
155 void
156 dialog_sheet_resize (WBCGtk *wbcg)
158 GtkBuilder *gui;
159 ResizeState *state;
160 int slider_width;
162 if (gnm_dialog_raise_if_exists (wbcg, RESIZE_DIALOG_KEY))
163 return;
164 gui = gnm_gtk_builder_load ("res:ui/sheet-resize.ui", NULL, GO_CMD_CONTEXT (wbcg));
165 if (gui == NULL)
166 return;
168 state = g_new (ResizeState, 1);
169 state->wbcg = wbcg;
170 state->dialog = go_gtk_builder_get_widget (gui, "Resize");
171 state->sheet = wbcg_cur_sheet (wbcg);
172 g_return_if_fail (state->dialog != NULL);
174 slider_width = mylog2 (MAX (GNM_MAX_ROWS / GNM_MIN_ROWS,
175 GNM_MAX_COLS / GNM_MIN_COLS)) *
176 gnm_widget_measure_string (GTK_WIDGET (wbcg_toplevel (wbcg)),
177 "00");
179 state->columns_scale = go_gtk_builder_get_widget (gui, "columns_scale");
180 gtk_widget_set_size_request (state->columns_scale, slider_width, -1);
181 state->columns_label = go_gtk_builder_get_widget (gui, "columns_label");
182 state->rows_scale = go_gtk_builder_get_widget (gui, "rows_scale");
183 gtk_widget_set_size_request (state->rows_scale, slider_width, -1);
184 state->rows_label = go_gtk_builder_get_widget (gui, "rows_label");
185 state->all_sheets_button = go_gtk_builder_get_widget (gui, "all_sheets_button");
186 state->ok_button = go_gtk_builder_get_widget (gui, "ok_button");
187 state->cancel_button = go_gtk_builder_get_widget (gui, "cancel_button");
189 g_signal_connect_swapped (G_OBJECT (state->columns_scale),
190 "value-changed", G_CALLBACK (cb_scale_changed),
191 state);
192 init_scale (state->columns_scale,
193 gnm_sheet_get_max_cols (state->sheet),
194 GNM_MIN_COLS, GNM_MAX_COLS);
196 g_signal_connect_swapped (G_OBJECT (state->rows_scale),
197 "value-changed", G_CALLBACK (cb_scale_changed),
198 state);
199 init_scale (state->rows_scale,
200 gnm_sheet_get_max_rows (state->sheet),
201 GNM_MIN_ROWS, GNM_MAX_ROWS);
203 cb_scale_changed (state);
205 g_signal_connect_swapped (G_OBJECT (state->cancel_button),
206 "clicked", G_CALLBACK (gtk_widget_destroy),
207 state->dialog);
209 g_signal_connect_swapped (G_OBJECT (state->ok_button),
210 "clicked", G_CALLBACK (cb_ok_clicked),
211 state);
213 gnm_dialog_setup_destroy_handlers (GTK_DIALOG (state->dialog), wbcg,
214 GNM_DIALOG_DESTROY_SHEET_REMOVED);
216 gnm_keyed_dialog (wbcg, GTK_WINDOW (state->dialog),
217 RESIZE_DIALOG_KEY);
219 g_object_set_data_full (G_OBJECT (state->dialog),
220 "state", state,
221 (GDestroyNotify) g_free);
222 g_object_unref (gui);
224 gtk_widget_show (state->dialog);