1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * dialog-paste-special.c: The dialog for selecting non-standard
4 * behaviors when pasting.
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>
30 #include <clipboard.h>
31 #include <selection.h>
36 static char const * const paste_type_group
[] = {
39 "paste-type-as-value",
41 "paste-type-comments",
45 gboolean permit_cell_ops
;
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",
57 "cell-operation-subtract",
58 "cell-operation-multiply",
59 "cell-operation-divide",
64 } cell_operation_props
[] = {
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",
80 } region_operation_props
[] = {
91 GtkWidget
*cancel_button
;
92 GtkWidget
*link_button
;
93 GtkWidget
*help_button
;
94 char const *help_link
;
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. */
108 paste_link_set_sensitive (PasteSpecialState
*state
)
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
);
120 skip_blanks_set_sensitive (PasteSpecialState
*state
)
122 GtkWidget
*button
= go_gtk_builder_get_widget (state
->gui
,"skip-blanks");
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
);
130 dont_change_formulae_set_sensitive (PasteSpecialState
*state
)
132 GtkWidget
*button
= go_gtk_builder_get_widget (state
->gui
,"dont-change-formulae");
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
);
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
);
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
),
159 paste_link_set_sensitive (state
);
160 skip_blanks_set_sensitive (state
);
161 dont_change_formulae_set_sensitive (state
);
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
);
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
);
183 dialog_paste_special_skip_blanks_toggled_cb (GtkWidget
*button
, PasteSpecialState
*state
)
185 paste_link_set_sensitive (state
);
189 cb_tool_cancel_clicked (G_GNUC_UNUSED GtkWidget
*button
,
190 PasteSpecialState
*state
)
192 gtk_widget_destroy (state
->dialog
);
197 cb_tool_ok_clicked (G_GNUC_UNUSED GtkWidget
*button
,
198 PasteSpecialState
*state
)
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
);
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
);
241 dialog_paste_special (WBCGtk
*wbcg
)
243 PasteSpecialState
*state
;
245 char const * const *group
;
247 if (gnm_dialog_raise_if_exists (wbcg
, GNM_PASTE_SPECIAL_KEY
))
249 gui
= gnm_gtk_builder_load ("res:ui/paste-special.ui", NULL
, GO_CMD_CONTEXT (wbcg
));
253 state
= g_new0 (PasteSpecialState
, 1);
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
),
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
),
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
),
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
),
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
),
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
),
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"),
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
),
311 (GDestroyNotify
) cb_destroy
);
313 gtk_widget_show (state
->dialog
);