GUI: Move .ui files from goffice resources to glib resources
[gnumeric.git] / src / dialogs / dialog-paste-special.c
blob7dabbe8425932bff02c902c72eb7a00226d4dcf6
1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * dialog-paste-special.c: The dialog for selecting non-standard
4 * behaviors when pasting.
6 * Author:
7 * MIguel de Icaza (miguel@gnu.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/>.
22 #include <gnumeric-config.h>
23 #include <glib/gi18n-lib.h>
24 #include <gnumeric.h>
25 #include "dialogs.h"
26 #include "help.h"
28 #include <wbc-gtk.h>
29 #include <gui-util.h>
30 #include <clipboard.h>
31 #include <selection.h>
32 #include <cmd-edit.h>
34 #include <gtk/gtk.h>
36 static char const * const paste_type_group[] = {
37 "paste-type-all",
38 "paste-type-content",
39 "paste-type-as-value",
40 "paste-type-formats",
41 "paste-type-comments",
42 NULL
44 static const struct {
45 gboolean permit_cell_ops;
46 int paste_enum;
47 } paste_type_group_props[] = {
48 {TRUE, PASTE_ALL_CELL},
49 {TRUE, PASTE_CONTENTS},
50 {TRUE, PASTE_AS_VALUES},
51 {FALSE, PASTE_FORMATS},
52 {FALSE, PASTE_COMMENTS},
54 static char const * const cell_operation_group[] = {
55 "cell-operation-none",
56 "cell-operation-add",
57 "cell-operation-subtract",
58 "cell-operation-multiply",
59 "cell-operation-divide",
60 NULL
62 static const struct {
63 int paste_enum;
64 } cell_operation_props[] = {
65 {0},
66 {PASTE_OPER_ADD},
67 {PASTE_OPER_SUB},
68 {PASTE_OPER_MULT},
69 {PASTE_OPER_DIV},
71 static char const * const region_operation_group[] = {
72 "region-operation-none",
73 "region-operation-transpose",
74 "region-operation-flip-h",
75 "region-operation-flip-v",
76 NULL
78 static const struct {
79 int paste_enum;
80 } region_operation_props[] = {
81 {0},
82 {PASTE_TRANSPOSE},
83 {PASTE_FLIP_H},
84 {PASTE_FLIP_V},
87 typedef struct {
88 GtkBuilder *gui;
89 GtkWidget *dialog;
90 GtkWidget *ok_button;
91 GtkWidget *cancel_button;
92 GtkWidget *link_button;
93 GtkWidget *help_button;
94 char const *help_link;
95 Sheet *sheet;
96 SheetView *sv;
97 Workbook *wb;
98 WBCGtk *wbcg;
99 } PasteSpecialState;
101 #define GNM_PASTE_SPECIAL_KEY "gnm-paste-special"
103 /* The "Paste Link" button should be grayed-out, unless type "All" is
104 selected, cell operation "None" is selected,
105 region operation "None" is selected, and "Skip
106 Blanks" is not selected. */
107 static void
108 paste_link_set_sensitive (PasteSpecialState *state)
110 gboolean sensitive =
111 (!gtk_toggle_button_get_active
112 (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state->gui,"skip-blanks")))
113 && 0 == gnm_gui_group_value (state->gui, paste_type_group)
114 && 0 == gnm_gui_group_value (state->gui, cell_operation_group)
115 && 0 == gnm_gui_group_value (state->gui, region_operation_group));
116 gtk_widget_set_sensitive (state->link_button, sensitive);
119 static void
120 skip_blanks_set_sensitive (PasteSpecialState *state)
122 GtkWidget *button = go_gtk_builder_get_widget (state->gui,"skip-blanks");
123 gboolean sensitive =
124 (3 > gnm_gui_group_value (state->gui, paste_type_group)
125 && 0 == gnm_gui_group_value (state->gui, cell_operation_group));
126 gtk_widget_set_sensitive (button, sensitive);
129 static void
130 dont_change_formulae_set_sensitive (PasteSpecialState *state)
132 GtkWidget *button = go_gtk_builder_get_widget (state->gui,"dont-change-formulae");
133 gboolean sensitive =
134 (2 > gnm_gui_group_value (state->gui, paste_type_group)
135 && 0 == gnm_gui_group_value (state->gui, cell_operation_group));
136 gtk_widget_set_sensitive (button, sensitive);
139 static void
140 cb_destroy (PasteSpecialState *state)
142 if (state->gui != NULL)
143 g_object_unref (state->gui);
144 wbcg_edit_finish (state->wbcg, WBC_EDIT_REJECT, NULL);
145 g_free (state);
148 static void
149 dialog_paste_special_type_toggled_cb (GtkWidget *button, PasteSpecialState *state)
151 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
152 int i = gnm_gui_group_value (state->gui, paste_type_group);
153 char const * const *group;
154 gboolean permit_cell_ops = paste_type_group_props[i].permit_cell_ops;
156 for (group = cell_operation_group; *group != NULL; group++)
157 gtk_widget_set_sensitive (go_gtk_builder_get_widget (state->gui,*group),
158 permit_cell_ops);
159 paste_link_set_sensitive (state);
160 skip_blanks_set_sensitive (state);
161 dont_change_formulae_set_sensitive (state);
165 static void
166 dialog_paste_special_cell_op_toggled_cb (GtkWidget *button, PasteSpecialState *state)
168 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
169 paste_link_set_sensitive (state);
170 skip_blanks_set_sensitive (state);
171 dont_change_formulae_set_sensitive (state);
175 static void
176 dialog_paste_special_region_op_toggled_cb (GtkWidget *button, PasteSpecialState *state)
178 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
179 paste_link_set_sensitive (state);
182 static void
183 dialog_paste_special_skip_blanks_toggled_cb (GtkWidget *button, PasteSpecialState *state)
185 paste_link_set_sensitive (state);
188 static void
189 cb_tool_cancel_clicked (G_GNUC_UNUSED GtkWidget *button,
190 PasteSpecialState *state)
192 gtk_widget_destroy (state->dialog);
193 return;
196 static void
197 cb_tool_ok_clicked (G_GNUC_UNUSED GtkWidget *button,
198 PasteSpecialState *state)
200 int result;
201 int paste_type = gnm_gui_group_value (state->gui, paste_type_group);
202 int region_op_type = gnm_gui_group_value (state->gui, region_operation_group);
204 result = paste_type_group_props[paste_type].paste_enum
205 | region_operation_props[region_op_type].paste_enum;
207 if (paste_type_group_props[paste_type].permit_cell_ops) {
208 int cell_op_type = gnm_gui_group_value (state->gui, cell_operation_group);
209 result |= cell_operation_props[cell_op_type].paste_enum;
212 if (gtk_toggle_button_get_active
213 (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state->gui,"skip-blanks"))))
214 result |= PASTE_SKIP_BLANKS;
215 if (gtk_toggle_button_get_active
216 (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state->gui,"dont-change-formulae"))))
217 result |= PASTE_EXPR_LOCAL_RELOCATE;
219 if (gtk_toggle_button_get_active
220 (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state->gui,"row-heights"))))
221 result |= PASTE_ROW_HEIGHTS;
222 if (gtk_toggle_button_get_active
223 (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state->gui,"column-widths"))))
224 result |= PASTE_COLUMN_WIDTHS;
226 cmd_paste_to_selection (GNM_WBC (state->wbcg), state->sv, result);
227 gtk_widget_destroy (state->dialog);
228 return;
231 static void
232 cb_tool_paste_link_clicked (G_GNUC_UNUSED GtkWidget *button,
233 PasteSpecialState *state)
235 cmd_paste_to_selection (GNM_WBC (state->wbcg), state->sv, PASTE_LINK);
236 gtk_widget_destroy (state->dialog);
237 return;
240 void
241 dialog_paste_special (WBCGtk *wbcg)
243 PasteSpecialState *state;
244 GtkBuilder *gui;
245 char const * const *group;
247 if (gnm_dialog_raise_if_exists (wbcg, GNM_PASTE_SPECIAL_KEY))
248 return;
249 gui = gnm_gtk_builder_load ("res:ui/paste-special.ui", NULL, GO_CMD_CONTEXT (wbcg));
250 if (gui == NULL)
251 return;
253 state = g_new0 (PasteSpecialState, 1);
254 state->wbcg = wbcg;
255 state->gui = gui;
256 state->dialog = go_gtk_builder_get_widget (state->gui, "paste-special");
257 state->sheet = wbcg_cur_sheet (wbcg);
258 state->sv = wb_control_cur_sheet_view (GNM_WBC (wbcg));
260 g_return_if_fail (state->dialog != NULL);
262 state->link_button = go_gtk_builder_get_widget (state->gui,"paste-link_button");
263 g_signal_connect (G_OBJECT (state->link_button),
264 "clicked",
265 G_CALLBACK (cb_tool_paste_link_clicked), state);
266 state->help_button = go_gtk_builder_get_widget (state->gui, "help_button");
267 gnm_init_help_button (state->help_button, GNUMERIC_HELP_LINK_PASTE_SPECIAL);
268 state->cancel_button = go_gtk_builder_get_widget (state->gui, "cancel_button");
269 g_signal_connect (G_OBJECT (state->cancel_button),
270 "clicked",
271 G_CALLBACK (cb_tool_cancel_clicked), state);
272 state->ok_button = go_gtk_builder_get_widget (state->gui, "ok_button");
273 g_signal_connect (G_OBJECT (state->ok_button),
274 "clicked",
275 G_CALLBACK (cb_tool_ok_clicked), state);
278 for (group = paste_type_group; *group != NULL; group++)
279 g_signal_connect_after (go_gtk_builder_get_widget (state->gui,*group),
280 "toggled",
281 G_CALLBACK (dialog_paste_special_type_toggled_cb), state);
282 for (group = cell_operation_group; *group != NULL; group++)
283 g_signal_connect_after (go_gtk_builder_get_widget (state->gui,*group),
284 "toggled",
285 G_CALLBACK (dialog_paste_special_cell_op_toggled_cb), state);
286 for (group = region_operation_group; *group != NULL; group++)
287 g_signal_connect_after (go_gtk_builder_get_widget (state->gui,*group),
288 "toggled",
289 G_CALLBACK (dialog_paste_special_region_op_toggled_cb), state);
290 g_signal_connect_after (go_gtk_builder_get_widget (state->gui, "skip-blanks"),
291 "toggled",
292 G_CALLBACK (dialog_paste_special_skip_blanks_toggled_cb), state);
293 paste_link_set_sensitive (state);
295 gtk_toggle_button_set_active
296 (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state->gui,"column-widths")),
297 sv_is_full_colrow_selected (state->sv, TRUE, -1));
298 gtk_toggle_button_set_active
299 (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state->gui,"row-heights")),
300 sv_is_full_colrow_selected (state->sv, FALSE, -1));
302 gnm_dialog_setup_destroy_handlers (GTK_DIALOG (state->dialog), wbcg,
303 GNM_DIALOG_DESTROY_SHEET_REMOVED);
305 gnm_keyed_dialog (wbcg, GTK_WINDOW (state->dialog),
306 GNM_PASTE_SPECIAL_KEY);
308 wbc_gtk_attach_guru (state->wbcg, state->dialog);
309 g_object_set_data_full (G_OBJECT (state->dialog),
310 "state", state,
311 (GDestroyNotify) cb_destroy);
313 gtk_widget_show (state->dialog);