2 * dialog-sheetobject-size.c:
5 * Andreas J. Guelzow <aguelzow@pyrshep.ca>
7 * (c) Copyright 2009 Andreas J. Guelzow <aguelzow@pyrshep.ca>
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>
26 #include <dialogs/dialogs.h>
27 #include <dialogs/help.h>
31 #include <workbook-control.h>
35 #include <sheet-view.h>
36 #include <application.h>
37 #include <workbook-cmd-format.h>
38 #include <sheet-object-widget.h>
39 #include <sheet-object-impl.h>
40 #include <sheet-control-gui.h>
41 #include <widgets/gnm-so-anchor-mode-chooser.h>
44 #define SO_SIZE_DIALOG_KEY "so-size-dialog"
54 GtkWidget
*apply_button
;
55 GtkWidget
*cancel_button
;
65 GtkWidget
*print_check
;
66 GnmSOAnchorModeChooser
*modecombo
;
69 SheetObjectAnchor
*old_anchor
;
70 SheetObjectAnchor
*active_anchor
;
73 gboolean so_size_needs_restore
;
74 gboolean so_pos_needs_restore
;
75 gboolean so_name_changed
;
76 gboolean so_print_check_changed
;
77 gboolean so_mode_changed
;
81 cb_dialog_so_size_value_changed_update_points (GtkSpinButton
*spinbutton
,
84 gint value
= gtk_spin_button_get_value_as_int (spinbutton
);
85 double size_points
= value
* 72./gnm_app_display_dpi_get (FALSE
);
86 gchar
*pts
= g_strdup_printf ("%.2f",size_points
);
87 gtk_label_set_text (points
, pts
);
92 dialog_so_size_button_sensitivity (SOSizeState
*state
)
94 gboolean sensitive
= state
->so_size_needs_restore
||
95 state
->so_pos_needs_restore
||
96 state
->so_name_changed
||
97 state
->so_print_check_changed
||
98 state
->so_mode_changed
;
99 gtk_widget_set_sensitive
100 (state
->ok_button
, sensitive
);
101 gtk_widget_set_sensitive
102 (state
->apply_button
, sensitive
);
106 cb_dialog_so_size_destroy (SOSizeState
*state
)
108 if (state
->so_size_needs_restore
|| state
->so_pos_needs_restore
)
109 sheet_object_set_anchor (state
->so
, state
->old_anchor
);
110 g_free (state
->old_anchor
);
111 g_free (state
->active_anchor
);
112 g_free (state
->old_name
);
113 if (state
->so
!= NULL
)
114 g_object_unref (state
->so
);
115 if (state
->gui
!= NULL
)
116 g_object_unref (state
->gui
);
121 cb_dialog_so_size_cancel_clicked (G_GNUC_UNUSED GtkWidget
*button
,
124 gtk_widget_destroy (state
->dialog
);
129 cb_dialog_so_size_value_changed (G_GNUC_UNUSED GtkSpinButton
*spinbutton
,
133 int new_width
, new_height
;
136 width
= state
->coords
[2] - state
->coords
[0];
137 height
= state
->coords
[3] - state
->coords
[1];
138 if (width
< 0) width
= - width
;
139 if (height
< 0) height
= - height
;
141 new_width
= gtk_spin_button_get_value_as_int (state
->wspin
);
142 new_height
= gtk_spin_button_get_value_as_int (state
->hspin
);
143 dx
= gtk_spin_button_get_value_as_int (state
->xspin
);
144 dy
= gtk_spin_button_get_value_as_int (state
->yspin
);
146 state
->so_size_needs_restore
= (new_width
!= width
) || (new_height
!= height
);
147 state
->so_pos_needs_restore
= (dx
!= 0) || (dy
!= 0);
149 *(state
->active_anchor
) = *(state
->old_anchor
);
151 if (state
->so_size_needs_restore
|| state
->so_pos_needs_restore
) {
152 gdouble new_coords
[4];
154 new_coords
[0] = state
->coords
[0] + dx
;
155 new_coords
[1] = state
->coords
[1] + dy
;
156 new_coords
[2] = state
->coords
[2] + dx
;
157 new_coords
[3] = state
->coords
[3] + dy
;
158 if (new_coords
[0] < new_coords
[2])
159 new_coords
[2] = new_coords
[0] + new_width
;
161 new_coords
[0] = new_coords
[2] + new_width
;
162 if (new_coords
[1] < new_coords
[3])
163 new_coords
[3] = new_coords
[1] + new_height
;
165 new_coords
[1] = new_coords
[3] + new_height
;
167 scg_object_coords_to_anchor (state
->scg
, new_coords
,
168 state
->active_anchor
);
171 sheet_object_set_anchor (state
->so
, state
->active_anchor
);
173 dialog_so_size_button_sensitivity (state
);
177 dialog_so_size_load (SOSizeState
*state
)
179 g_free (state
->old_anchor
);
180 state
->old_anchor
= sheet_object_anchor_dup
181 (sheet_object_get_anchor (state
->so
));
182 scg_object_anchor_to_coords (state
->scg
,
185 state
->so_size_needs_restore
= FALSE
;
186 state
->so_pos_needs_restore
= FALSE
;
190 set_params (SheetObject
*so
, char *name
)
192 return go_undo_binary_new
193 (g_object_ref (so
), name
,
194 (GOUndoBinaryFunc
)sheet_object_set_name
,
195 g_object_unref
, g_free
);
199 set_print_flag (SheetObject
*so
, gboolean print
)
201 gboolean
*p_print
= g_new (gboolean
, 1);
204 return go_undo_binary_new
205 (g_object_ref (so
), p_print
,
206 (GOUndoBinaryFunc
)sheet_object_set_print_flag
,
207 g_object_unref
, g_free
);
211 set_mode (SheetObject
*so
, GnmSOAnchorMode mode
)
213 GnmSOAnchorMode
*p_mode
= g_new (GnmSOAnchorMode
, 1);
216 return go_undo_binary_new
217 (g_object_ref (so
), p_mode
,
218 (GOUndoBinaryFunc
)sheet_object_set_anchor_mode
,
219 g_object_unref
, g_free
);
223 cb_dialog_so_size_apply_clicked (G_GNUC_UNUSED GtkWidget
*button
,
227 GOUndo
*undo
= NULL
, *redo
= NULL
;
228 char const *undo_name
= NULL
;
231 if (state
->so_size_needs_restore
|| state
->so_pos_needs_restore
) {
232 char const *label
= state
->so_pos_needs_restore
?
233 _("Move Object") : _("Resize Object");
234 sheet_object_set_anchor (state
->so
, state
->old_anchor
);
235 if (!cmd_objects_move (GNM_WBC (state
->wbcg
),
236 g_slist_prepend (NULL
, state
->so
),
238 (NULL
, sheet_object_anchor_dup
239 (state
->active_anchor
)),
241 dialog_so_size_load (state
);
244 name
= gtk_entry_get_text (state
->nameentry
);
247 if (strcmp (name
, state
->old_name
) != 0) {
248 char *old_name
, *new_name
;
250 g_object_get (G_OBJECT (state
->so
), "name", &old_name
, NULL
);
251 undo
= go_undo_combine (undo
, set_params (state
->so
, old_name
));
253 new_name
= (*name
== '\0') ? NULL
: g_strdup (name
);
254 redo
= go_undo_combine (redo
, set_params (state
->so
, new_name
));
256 undo_name
= _("Set Object Name");
259 if (state
->so_print_check_changed
) {
260 gboolean val
= ((state
->so
->flags
& SHEET_OBJECT_PRINT
) != 0);
261 undo
= go_undo_combine (undo
, set_print_flag
263 redo
= go_undo_combine (redo
, set_print_flag
265 undo_name
= _("Set Object Print Property");
268 if (state
->so_mode_changed
) {
269 int new_mode
= gnm_so_anchor_mode_chooser_get_mode (state
->modecombo
);
270 int old_mode
= state
->so
->anchor
.mode
;
271 undo
= go_undo_combine (undo
, set_mode (state
->so
, old_mode
));
272 redo
= go_undo_combine (redo
, set_mode (state
->so
, new_mode
));
273 undo_name
= _("Set Object Anchor Mode");
279 undo_name
= _("Set Object Properties");
280 state
->so_name_changed
= state
->so_print_check_changed
= state
->so_mode_changed
=
281 cmd_generic (GNM_WBC (state
->wbcg
),
282 undo_name
, undo
, redo
);
284 dialog_so_size_button_sensitivity (state
);
290 cb_dialog_so_size_ok_clicked (GtkWidget
*button
, SOSizeState
*state
)
292 cb_dialog_so_size_apply_clicked (button
, state
);
293 if (!state
->so_size_needs_restore
&& !state
->so_pos_needs_restore
&&
294 !state
->so_name_changed
&& !state
->so_print_check_changed
)
295 gtk_widget_destroy (state
->dialog
);
300 cb_dialog_so_size_name_changed (GtkEntry
*entry
,
301 GdkEventFocus
*event
,
304 char const *name
= gtk_entry_get_text (entry
);
307 state
->so_name_changed
308 = (strcmp (name
, state
->old_name
) != 0);
309 dialog_so_size_button_sensitivity (state
);
314 cb_dialog_so_size_print_check_toggled (GtkToggleButton
*togglebutton
,
317 gboolean new_print
= !gtk_toggle_button_get_active (togglebutton
);
318 gboolean old_print
= ((state
->so
->flags
& SHEET_OBJECT_PRINT
) != 0);
320 state
->so_print_check_changed
321 = (new_print
!= old_print
);
322 dialog_so_size_button_sensitivity (state
);
327 cb_dialog_so_size_mode_changed (GnmSOAnchorModeChooser
*chooser
, SOSizeState
*state
)
329 GnmSOAnchorMode new_mode
= gnm_so_anchor_mode_chooser_get_mode (chooser
);
330 GnmSOAnchorMode old_mode
= state
->so
->anchor
.mode
;
333 scg_object_anchor_to_coords (state
->scg
, state
->active_anchor
, coords
);
334 state
->active_anchor
->mode
= new_mode
;
335 scg_object_coords_to_anchor (state
->scg
, coords
, state
->active_anchor
);
336 state
->so_mode_changed
= new_mode
!= old_mode
;
337 dialog_so_size_button_sensitivity (state
);
341 dialog_so_size (WBCGtk
*wbcg
, GObject
*so
)
348 g_return_if_fail (wbcg
!= NULL
);
350 if (gnm_dialog_raise_if_exists (wbcg
, SO_SIZE_DIALOG_KEY
))
352 gui
= gnm_gtk_builder_load ("res:ui/sheetobject-size.ui", NULL
, GO_CMD_CONTEXT (wbcg
));
356 state
= g_new (SOSizeState
, 1);
358 state
->sv
= wb_control_cur_sheet_view (GNM_WBC (wbcg
));
359 state
->sheet
= sv_sheet (state
->sv
);
360 state
->scg
= wbcg_get_nth_scg (wbcg
, state
->sheet
->index_in_wb
);
362 state
->dialog
= go_gtk_builder_get_widget (state
->gui
, "object-size");
364 state
->so
= GNM_SO (so
);
367 state
->nameentry
= GTK_ENTRY (go_gtk_builder_get_widget (state
->gui
, "name-entry"));
368 state
->old_anchor
= NULL
;
369 state
->old_name
= NULL
;
370 g_object_get (so
, "name", &state
->old_name
, NULL
);
371 if (state
->old_name
== NULL
)
372 state
->old_name
= g_strdup ("");
373 gtk_entry_set_text (state
->nameentry
, state
->old_name
);
374 state
->so_name_changed
= FALSE
;
375 g_signal_connect (G_OBJECT (state
->nameentry
),
377 G_CALLBACK (cb_dialog_so_size_name_changed
),
379 state
->so_print_check_changed
= FALSE
;
381 state
->wpoints
= GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "w-pts-label"));
382 state
->wspin
= GTK_SPIN_BUTTON (go_gtk_builder_get_widget (state
->gui
, "w-spin"));
383 state
->hpoints
= GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "h-pts-label"));
384 state
->hspin
= GTK_SPIN_BUTTON (go_gtk_builder_get_widget (state
->gui
, "h-spin"));
385 state
->xpoints
= GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "x-pts-label"));
386 state
->xspin
= GTK_SPIN_BUTTON (go_gtk_builder_get_widget (state
->gui
, "x-spin"));
387 state
->ypoints
= GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "y-pts-label"));
388 state
->yspin
= GTK_SPIN_BUTTON (go_gtk_builder_get_widget (state
->gui
, "y-spin"));
389 state
->print_check
= GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
,
391 state
->modecombo
= GNM_SO_ANCHOR_MODE_CHOOSER (gnm_so_anchor_mode_chooser_new (sheet_object_can_resize (state
->so
)));
392 dialog_so_size_load (state
);
393 state
->active_anchor
= sheet_object_anchor_dup (sheet_object_get_anchor
395 width
= state
->coords
[2] - state
->coords
[0];
396 height
= state
->coords
[3] - state
->coords
[1];
398 gtk_spin_button_set_value (state
->wspin
, (width
< 0) ? - width
: width
);
399 gtk_spin_button_set_value (state
->hspin
, (height
< 0) ? - height
: height
);
400 gtk_spin_button_set_value (state
->xspin
, 0.);
401 gtk_spin_button_set_value (state
->yspin
, 0.);
402 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state
->print_check
),
403 !(state
->so
->flags
& SHEET_OBJECT_PRINT
));
404 gnm_so_anchor_mode_chooser_set_mode (state
->modecombo
,
405 state
->so
->anchor
.mode
);
406 grid
= GTK_GRID (gtk_builder_get_object (state
->gui
, "main-grid"));
407 gtk_grid_insert_row (grid
, 7);
408 gtk_grid_attach (grid
, GTK_WIDGET (state
->modecombo
), 0, 7, 2, 1);
409 gtk_widget_set_halign (GTK_WIDGET (state
->modecombo
), GTK_ALIGN_START
);
410 gtk_widget_show (GTK_WIDGET (state
->modecombo
));
411 g_signal_connect (G_OBJECT (state
->wspin
),
413 G_CALLBACK (cb_dialog_so_size_value_changed_update_points
),
415 g_signal_connect (G_OBJECT (state
->hspin
),
417 G_CALLBACK (cb_dialog_so_size_value_changed_update_points
),
419 g_signal_connect (G_OBJECT (state
->xspin
),
421 G_CALLBACK (cb_dialog_so_size_value_changed_update_points
),
423 g_signal_connect (G_OBJECT (state
->yspin
),
425 G_CALLBACK (cb_dialog_so_size_value_changed_update_points
),
427 g_signal_connect (G_OBJECT (state
->print_check
),
429 G_CALLBACK (cb_dialog_so_size_print_check_toggled
),
432 cb_dialog_so_size_value_changed_update_points (state
->wspin
, GTK_LABEL (state
->wpoints
));
433 cb_dialog_so_size_value_changed_update_points (state
->hspin
, GTK_LABEL (state
->hpoints
));
434 cb_dialog_so_size_value_changed_update_points (state
->xspin
, GTK_LABEL (state
->xpoints
));
435 cb_dialog_so_size_value_changed_update_points (state
->yspin
, GTK_LABEL (state
->ypoints
));
438 g_signal_connect (G_OBJECT (state
->wspin
),
440 G_CALLBACK (cb_dialog_so_size_value_changed
), state
);
441 g_signal_connect (G_OBJECT (state
->hspin
),
443 G_CALLBACK (cb_dialog_so_size_value_changed
), state
);
444 g_signal_connect (G_OBJECT (state
->xspin
),
446 G_CALLBACK (cb_dialog_so_size_value_changed
), state
);
447 g_signal_connect (G_OBJECT (state
->yspin
),
449 G_CALLBACK (cb_dialog_so_size_value_changed
), state
);
451 g_signal_connect (G_OBJECT (state
->modecombo
),
453 G_CALLBACK (cb_dialog_so_size_mode_changed
), state
);
455 state
->ok_button
= go_gtk_builder_get_widget (state
->gui
, "ok_button");
456 g_signal_connect (G_OBJECT (state
->ok_button
),
458 G_CALLBACK (cb_dialog_so_size_ok_clicked
), state
);
459 state
->apply_button
= go_gtk_builder_get_widget (state
->gui
, "apply_button");
460 g_signal_connect (G_OBJECT (state
->apply_button
),
462 G_CALLBACK (cb_dialog_so_size_apply_clicked
), state
);
464 state
->cancel_button
= go_gtk_builder_get_widget (state
->gui
, "cancel_button");
465 g_signal_connect (G_OBJECT (state
->cancel_button
),
467 G_CALLBACK (cb_dialog_so_size_cancel_clicked
), state
);
469 gnm_init_help_button (
470 go_gtk_builder_get_widget (state
->gui
, "help_button"),
471 GNUMERIC_HELP_LINK_SO_SIZE
);
473 gnm_dialog_setup_destroy_handlers (GTK_DIALOG (state
->dialog
),
475 GNM_DIALOG_DESTROY_CURRENT_SHEET_REMOVED
);
477 wbc_gtk_attach_guru (state
->wbcg
, state
->dialog
);
478 g_object_set_data_full (G_OBJECT (state
->dialog
),
479 "state", state
, (GDestroyNotify
) cb_dialog_so_size_destroy
);
481 gnm_keyed_dialog (wbcg
, GTK_WINDOW (state
->dialog
),
483 dialog_so_size_button_sensitivity (state
);
484 gtk_widget_show (state
->dialog
);